diff --git a/docs/dev-ops/mysql/sql/0702group_buying_sys.sql b/docs/dev-ops/mysql/sql/0702group_buying_sys.sql
index d16361e..fabc86a 100644
--- a/docs/dev-ops/mysql/sql/0702group_buying_sys.sql
+++ b/docs/dev-ops/mysql/sql/0702group_buying_sys.sql
@@ -183,7 +183,7 @@ CREATE TABLE `group_buy_order_list` (
`channel` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '来源',
`original_price` decimal(8, 2) NOT NULL COMMENT '原始价格',
`deduction_price` decimal(8, 2) NOT NULL COMMENT '折扣金额',
- `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '状态;0初始锁定、1消费完成',
+ `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '状态;0初始锁定、1消费完成、2用户退单',
`out_trade_no` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '外部交易单号-确保外部调用唯一幂等',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
diff --git a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_list_mapper.xml b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_list_mapper.xml
index bcf63b8..666a93f 100644
--- a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_list_mapper.xml
+++ b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_list_mapper.xml
@@ -47,4 +47,13 @@
where user_id = #{userId} and activity_id = #{activityId}
+
+ update group_buy_order_list
+ set status = 1, update_time = now()
+ where out_trade_no = #{outTradeNo} and user_id = #{userId}
+
+
+
diff --git a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml
index f9ea1a7..b36e658 100644
--- a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml
+++ b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_order_mapper.xml
@@ -37,15 +37,34 @@
]]>
+
+
+
+
update group_buy_order
set lock_count = lock_count - 1, update_time= now()
where team_id = #{teamId} and lock_count > 0
+
+ update group_buy_order
+ set status = 1, update_time= now()
+ where team_id = #{teamId} and status = 0
+
+
+
+
diff --git a/group-buying-sys-app/src/main/resources/mybatis/mapper/notify_task_mapper.xml b/group-buying-sys-app/src/main/resources/mybatis/mapper/notify_task_mapper.xml
new file mode 100644
index 0000000..b843459
--- /dev/null
+++ b/group-buying-sys-app/src/main/resources/mybatis/mapper/notify_task_mapper.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ insert into notify_task(activity_id, team_id, notify_url, notify_count, notify_status, parameter_json,
+ create_time, update_time)
+ values(#{activityId}, #{teamId}, #{notifyUrl}, #{notifyCount}, #{notifyStatus}, #{parameterJson}, now(),now())
+
+
+
diff --git a/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/ITradeOrderServiceTest.java b/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/ITradeLockOrderServiceTest.java
similarity index 95%
rename from group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/ITradeOrderServiceTest.java
rename to group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/ITradeLockOrderServiceTest.java
index 4074927..7243058 100644
--- a/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/ITradeOrderServiceTest.java
+++ b/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/ITradeLockOrderServiceTest.java
@@ -8,7 +8,7 @@ import edu.whut.domain.trade.model.entity.MarketPayOrderEntity;
import edu.whut.domain.trade.model.entity.PayActivityEntity;
import edu.whut.domain.trade.model.entity.PayDiscountEntity;
import edu.whut.domain.trade.model.entity.UserEntity;
-import edu.whut.domain.trade.service.ITradeOrderService;
+import edu.whut.domain.trade.service.ITradeLockOrderService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -23,13 +23,13 @@ import javax.annotation.Resource;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
-public class ITradeOrderServiceTest {
+public class ITradeLockOrderServiceTest {
@Resource
private IIndexGroupBuyMarketService indexGroupBuyMarketService;
@Resource
- private ITradeOrderService tradeOrderService;
+ private ITradeLockOrderService tradeOrderService;
@Test
public void test_lockMarketPayOrder() throws Exception {
diff --git a/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java b/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java
new file mode 100644
index 0000000..5601e9a
--- /dev/null
+++ b/group-buying-sys-app/src/test/java/edu/whut/test/domain/trade/TradeSettlementOrderServiceTest.java
@@ -0,0 +1,38 @@
+package edu.whut.test.domain.trade;
+
+import com.alibaba.fastjson2.JSON;
+import edu.whut.domain.trade.model.entity.TradePaySettlementEntity;
+import edu.whut.domain.trade.model.entity.TradePaySuccessEntity;
+import edu.whut.domain.trade.service.ITradeSettlementOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+/**
+ * 拼团交易结算服务测试
+ */
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class TradeSettlementOrderServiceTest {
+
+ @Resource
+ private ITradeSettlementOrderService tradeSettlementOrderService;
+
+ @Test
+ public void test_settlementMarketPayOrder() {
+ TradePaySuccessEntity tradePaySuccessEntity = new TradePaySuccessEntity();
+ tradePaySuccessEntity.setSource("s01");
+ tradePaySuccessEntity.setChannel("c01");
+ tradePaySuccessEntity.setUserId("zy03");
+ tradePaySuccessEntity.setOutTradeNo("192426946598");
+ TradePaySettlementEntity tradePaySettlementEntity = tradeSettlementOrderService.settlementMarketPayOrder(tradePaySuccessEntity);
+ log.info("请求参数:{}", JSON.toJSONString(tradePaySuccessEntity));
+ log.info("测试结果:{}", JSON.toJSONString(tradePaySettlementEntity));
+ }
+
+}
diff --git a/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java b/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java
index a19dd7d..8053931 100644
--- a/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java
+++ b/group-buying-sys-app/src/test/java/edu/whut/test/trigger/MarketTradeControllerTest.java
@@ -28,7 +28,7 @@ public class MarketTradeControllerTest {
@Test
public void test_lockMarketPayOrder() {
LockMarketPayOrderRequestDTO lockMarketPayOrderRequestDTO = new LockMarketPayOrderRequestDTO();
- lockMarketPayOrderRequestDTO.setUserId("smile01");
+ lockMarketPayOrderRequestDTO.setUserId("zy01");
lockMarketPayOrderRequestDTO.setTeamId(null);
lockMarketPayOrderRequestDTO.setActivityId(100123L);
lockMarketPayOrderRequestDTO.setGoodsId("9890001");
@@ -44,8 +44,8 @@ public class MarketTradeControllerTest {
@Test
public void test_lockMarketPayOrder_teamId_not_null() {
LockMarketPayOrderRequestDTO lockMarketPayOrderRequestDTO = new LockMarketPayOrderRequestDTO();
- lockMarketPayOrderRequestDTO.setUserId("smile04");
- lockMarketPayOrderRequestDTO.setTeamId("80437493");
+ lockMarketPayOrderRequestDTO.setUserId("zy03");
+ lockMarketPayOrderRequestDTO.setTeamId("26432069");
lockMarketPayOrderRequestDTO.setActivityId(100123L);
lockMarketPayOrderRequestDTO.setGoodsId("9890001");
lockMarketPayOrderRequestDTO.setSource("s01");
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/tag/service/TagService.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/tag/service/TagService.java
index 611b5c5..5e23dd4 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/tag/service/TagService.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/tag/service/TagService.java
@@ -40,6 +40,8 @@ public class TagService implements ITagService {
add("smile01");
add("smile02");
add("smile03");
+ add("smile04");
+ add("smile05");
}};
// 4. 把用户写入标签明细表
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/adapter/repository/ITradeRepository.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/adapter/repository/ITradeRepository.java
index 364ca51..cc87e36 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/adapter/repository/ITradeRepository.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/adapter/repository/ITradeRepository.java
@@ -1,7 +1,9 @@
package edu.whut.domain.trade.adapter.repository;
import edu.whut.domain.trade.model.aggregate.GroupBuyOrderAggregate;
+import edu.whut.domain.trade.model.aggregate.GroupBuyTeamSettlementAggregate;
import edu.whut.domain.trade.model.entity.GroupBuyActivityEntity;
+import edu.whut.domain.trade.model.entity.GroupBuyTeamEntity;
import edu.whut.domain.trade.model.entity.MarketPayOrderEntity;
import edu.whut.domain.trade.model.valobj.GroupBuyProgressVO;
@@ -20,4 +22,9 @@ public interface ITradeRepository {
Integer queryOrderCountByActivityId(Long activityId, String userId);
+ GroupBuyTeamEntity queryGroupBuyTeamByTeamId(String teamId);
+
+ void settlementMarketPayOrder(GroupBuyTeamSettlementAggregate groupBuyTeamSettlementAggregate);
+
+
}
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/aggregate/GroupBuyTeamSettlementAggregate.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/aggregate/GroupBuyTeamSettlementAggregate.java
new file mode 100644
index 0000000..4d2442f
--- /dev/null
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/aggregate/GroupBuyTeamSettlementAggregate.java
@@ -0,0 +1,26 @@
+package edu.whut.domain.trade.model.aggregate;
+import edu.whut.domain.trade.model.entity.GroupBuyTeamEntity;
+import edu.whut.domain.trade.model.entity.TradePaySuccessEntity;
+import edu.whut.domain.trade.model.entity.UserEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 拼团组队结算聚合
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class GroupBuyTeamSettlementAggregate {
+
+ /** 用户实体对象 */
+ private UserEntity userEntity;
+ /** 拼团组队实体对象 */
+ private GroupBuyTeamEntity groupBuyTeamEntity;
+ /** 交易支付订单实体对象 */
+ private TradePaySuccessEntity tradePaySuccessEntity;
+
+}
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/GroupBuyTeamEntity.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/GroupBuyTeamEntity.java
new file mode 100644
index 0000000..74bd01c
--- /dev/null
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/GroupBuyTeamEntity.java
@@ -0,0 +1,30 @@
+package edu.whut.domain.trade.model.entity;
+import edu.whut.types.enums.GroupBuyOrderStatusEnumVO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 拼团组队实体对象
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class GroupBuyTeamEntity {
+
+ /** 拼单组队ID */
+ private String teamId;
+ /** 活动ID */
+ private Long activityId;
+ /** 目标数量 */
+ private Integer targetCount;
+ /** 完成数量 */
+ private Integer completeCount;
+ /** 锁单数量 */
+ private Integer lockCount;
+ /** 状态(0-拼单中、1-完成、2-失败) */
+ private GroupBuyOrderStatusEnumVO status;
+
+}
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/MarketPayOrderEntity.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/MarketPayOrderEntity.java
index b526777..e87cc11 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/MarketPayOrderEntity.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/MarketPayOrderEntity.java
@@ -16,6 +16,8 @@ import java.math.BigDecimal;
@NoArgsConstructor
public class MarketPayOrderEntity {
+ /** 拼单组队ID */
+ private String teamId;
/** 预购订单ID */
private String orderId;
/** 折扣金额 */
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/TradePaySettlementEntity.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/TradePaySettlementEntity.java
new file mode 100644
index 0000000..1ee2599
--- /dev/null
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/TradePaySettlementEntity.java
@@ -0,0 +1,30 @@
+package edu.whut.domain.trade.model.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 交易结算订单实体
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TradePaySettlementEntity {
+
+ /** 渠道 */
+ private String source;
+ /** 来源 */
+ private String channel;
+ /** 用户ID */
+ private String userId;
+ /** 拼单组队ID */
+ private String teamId;
+ /** 活动ID */
+ private Long activityId;
+ /** 外部交易单号 */
+ private String outTradeNo;
+
+}
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/TradePaySuccessEntity.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/TradePaySuccessEntity.java
new file mode 100644
index 0000000..5a0f370
--- /dev/null
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/model/entity/TradePaySuccessEntity.java
@@ -0,0 +1,26 @@
+package edu.whut.domain.trade.model.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 交易支付订单实体对象
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TradePaySuccessEntity {
+
+ /** 渠道 */
+ private String source;
+ /** 来源 */
+ private String channel;
+ /** 用户ID */
+ private String userId;
+ /** 外部交易单号 */
+ private String outTradeNo;
+
+}
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeOrderService.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeLockOrderService.java
similarity index 96%
rename from group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeOrderService.java
rename to group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeLockOrderService.java
index 4fb71df..ffd9b33 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeOrderService.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeLockOrderService.java
@@ -9,7 +9,7 @@ import edu.whut.domain.trade.model.valobj.GroupBuyProgressVO;
/**
* 交易订单服务接口
*/
-public interface ITradeOrderService {
+public interface ITradeLockOrderService {
/**
* 查询,未被支付消费完成的营销优惠订单
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeSettlementOrderService.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeSettlementOrderService.java
new file mode 100644
index 0000000..451ce48
--- /dev/null
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/ITradeSettlementOrderService.java
@@ -0,0 +1,18 @@
+package edu.whut.domain.trade.service;
+
+import edu.whut.domain.trade.model.entity.TradePaySettlementEntity;
+import edu.whut.domain.trade.model.entity.TradePaySuccessEntity;
+
+/**
+ * 拼团交易结算服务接口
+ */
+public interface ITradeSettlementOrderService {
+
+ /**
+ * 营销结算
+ * @param tradePaySuccessEntity 交易支付订单实体对象
+ * @return 交易结算订单实体
+ */
+ TradePaySettlementEntity settlementMarketPayOrder(TradePaySuccessEntity tradePaySuccessEntity);
+
+}
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/TradeOrderService.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/TradeLockLockOrderService.java
similarity index 90%
rename from group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/TradeOrderService.java
rename to group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/TradeLockLockOrderService.java
index b25dc39..9ee4246 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/TradeOrderService.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/TradeLockLockOrderService.java
@@ -1,10 +1,11 @@
-package edu.whut.domain.trade.service;
+package edu.whut.domain.trade.service.lock;
import edu.whut.domain.trade.adapter.repository.ITradeRepository;
import edu.whut.domain.trade.model.aggregate.GroupBuyOrderAggregate;
import edu.whut.domain.trade.model.entity.*;
import edu.whut.domain.trade.model.valobj.GroupBuyProgressVO;
-import edu.whut.domain.trade.service.factory.TradeRuleFilterFactory;
+import edu.whut.domain.trade.service.ITradeLockOrderService;
+import edu.whut.domain.trade.service.lock.factory.TradeRuleFilterFactory;
import edu.whut.types.design.framework.link.model2.chain.BusinessLinkedList;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -12,12 +13,12 @@ import org.springframework.stereotype.Service;
/**
- * 交易订单服务
+ * 交易锁单服务,但未支付
*/
@Slf4j
@Service
@RequiredArgsConstructor
-public class TradeOrderService implements ITradeOrderService {
+public class TradeLockLockOrderService implements ITradeLockOrderService {
private final ITradeRepository repository;
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/factory/TradeRuleFilterFactory.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/factory/TradeRuleFilterFactory.java
similarity index 89%
rename from group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/factory/TradeRuleFilterFactory.java
rename to group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/factory/TradeRuleFilterFactory.java
index 7119a07..8ded231 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/factory/TradeRuleFilterFactory.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/factory/TradeRuleFilterFactory.java
@@ -1,9 +1,9 @@
-package edu.whut.domain.trade.service.factory;
+package edu.whut.domain.trade.service.lock.factory;
import edu.whut.domain.trade.model.entity.GroupBuyActivityEntity;
import edu.whut.domain.trade.model.entity.TradeRuleCommandEntity;
import edu.whut.domain.trade.model.entity.TradeRuleFilterBackEntity;
-import edu.whut.domain.trade.service.filter.ActivityUsabilityRuleFilter;
-import edu.whut.domain.trade.service.filter.UserTakeLimitRuleFilter;
+import edu.whut.domain.trade.service.lock.filter.ActivityUsabilityRuleFilter;
+import edu.whut.domain.trade.service.lock.filter.UserTakeLimitRuleFilter;
import edu.whut.types.design.framework.link.model2.LinkArmory;
import edu.whut.types.design.framework.link.model2.chain.BusinessLinkedList;
import lombok.AllArgsConstructor;
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/filter/ActivityUsabilityRuleFilter.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/filter/ActivityUsabilityRuleFilter.java
similarity index 94%
rename from group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/filter/ActivityUsabilityRuleFilter.java
rename to group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/filter/ActivityUsabilityRuleFilter.java
index f8d7ee5..acc2ec2 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/filter/ActivityUsabilityRuleFilter.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/filter/ActivityUsabilityRuleFilter.java
@@ -1,9 +1,9 @@
-package edu.whut.domain.trade.service.filter;
+package edu.whut.domain.trade.service.lock.filter;
import edu.whut.domain.trade.adapter.repository.ITradeRepository;
import edu.whut.domain.trade.model.entity.GroupBuyActivityEntity;
import edu.whut.domain.trade.model.entity.TradeRuleCommandEntity;
import edu.whut.domain.trade.model.entity.TradeRuleFilterBackEntity;
-import edu.whut.domain.trade.service.factory.TradeRuleFilterFactory;
+import edu.whut.domain.trade.service.lock.factory.TradeRuleFilterFactory;
import edu.whut.types.design.framework.link.model2.handler.ILogicHandler;
import edu.whut.types.enums.ActivityStatusEnumVO;
import edu.whut.types.enums.ResponseCode;
@@ -12,7 +12,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
-import javax.annotation.Resource;
import java.util.Date;
/**
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/filter/UserTakeLimitRuleFilter.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/filter/UserTakeLimitRuleFilter.java
similarity index 93%
rename from group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/filter/UserTakeLimitRuleFilter.java
rename to group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/filter/UserTakeLimitRuleFilter.java
index 423abf2..0cbb3db 100644
--- a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/filter/UserTakeLimitRuleFilter.java
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/lock/filter/UserTakeLimitRuleFilter.java
@@ -1,9 +1,9 @@
-package edu.whut.domain.trade.service.filter;
+package edu.whut.domain.trade.service.lock.filter;
import edu.whut.domain.trade.adapter.repository.ITradeRepository;
import edu.whut.domain.trade.model.entity.GroupBuyActivityEntity;
import edu.whut.domain.trade.model.entity.TradeRuleCommandEntity;
import edu.whut.domain.trade.model.entity.TradeRuleFilterBackEntity;
-import edu.whut.domain.trade.service.factory.TradeRuleFilterFactory;
+import edu.whut.domain.trade.service.lock.factory.TradeRuleFilterFactory;
import edu.whut.types.design.framework.link.model2.handler.ILogicHandler;
import edu.whut.types.enums.ResponseCode;
import edu.whut.types.exception.AppException;
diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/settlement/TradeSettlementOrderService.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/settlement/TradeSettlementOrderService.java
new file mode 100644
index 0000000..f81211c
--- /dev/null
+++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/trade/service/settlement/TradeSettlementOrderService.java
@@ -0,0 +1,60 @@
+package edu.whut.domain.trade.service.settlement;
+import edu.whut.domain.trade.adapter.repository.ITradeRepository;
+import edu.whut.domain.trade.model.aggregate.GroupBuyTeamSettlementAggregate;
+import edu.whut.domain.trade.model.entity.*;
+import edu.whut.domain.trade.service.ITradeSettlementOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 拼团交易结算服务
+ */
+@Slf4j
+@Service
+public class TradeSettlementOrderService implements ITradeSettlementOrderService {
+
+ @Resource
+ private ITradeRepository repository;
+
+ /**
+ * 第三方支付渠道确认用户“支付成功”之后调用该函数,更新拼团订单状态为 已完成,并同步拼团人数。
+ * @param tradePaySuccessEntity 交易支付订单实体对象
+ * @return
+ */
+ @Override
+ public TradePaySettlementEntity settlementMarketPayOrder(TradePaySuccessEntity tradePaySuccessEntity) {
+ log.info("拼团交易-支付订单结算:{} outTradeNo:{}", tradePaySuccessEntity.getUserId(), tradePaySuccessEntity.getOutTradeNo());
+ // 1. 查询拼团信息
+ MarketPayOrderEntity marketPayOrderEntity = repository.queryMarketPayOrderEntityByOutTradeNo(tradePaySuccessEntity.getUserId(), tradePaySuccessEntity.getOutTradeNo());
+ if (null == marketPayOrderEntity) {
+ log.info("不存在的外部交易单号或用户已退单,不需要做支付订单结算:{} outTradeNo:{}", tradePaySuccessEntity.getUserId(), tradePaySuccessEntity.getOutTradeNo());
+ return null;
+ }
+
+ // 2. 查询组团信息
+ GroupBuyTeamEntity groupBuyTeamEntity = repository.queryGroupBuyTeamByTeamId(marketPayOrderEntity.getTeamId());
+
+ // 3. 构建聚合对象
+ GroupBuyTeamSettlementAggregate groupBuyTeamSettlementAggregate = GroupBuyTeamSettlementAggregate.builder()
+ .userEntity(UserEntity.builder().userId(tradePaySuccessEntity.getUserId()).build())
+ .groupBuyTeamEntity(groupBuyTeamEntity)
+ .tradePaySuccessEntity(tradePaySuccessEntity)
+ .build();
+
+ // 4. 更新数据库,拼团交易结算
+ repository.settlementMarketPayOrder(groupBuyTeamSettlementAggregate);
+
+ // 5. 返回结算信息 - 公司中开发这样的流程时候,会根据外部需要进行值的设置
+ return TradePaySettlementEntity.builder()
+ .source(tradePaySuccessEntity.getSource())
+ .channel(tradePaySuccessEntity.getChannel())
+ .userId(tradePaySuccessEntity.getUserId())
+ .teamId(marketPayOrderEntity.getTeamId())
+ .activityId(groupBuyTeamEntity.getActivityId())
+ .outTradeNo(tradePaySuccessEntity.getOutTradeNo())
+ .build();
+ }
+
+}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java
index d99692f..bd9e3d6 100644
--- a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/TradeRepository.java
@@ -1,18 +1,23 @@
package edu.whut.infrastructure.adapter.repository;
+import com.alibaba.fastjson2.JSON;
import edu.whut.domain.trade.adapter.repository.ITradeRepository;
import edu.whut.domain.trade.model.aggregate.GroupBuyOrderAggregate;
+import edu.whut.domain.trade.model.aggregate.GroupBuyTeamSettlementAggregate;
import edu.whut.domain.trade.model.entity.*;
import edu.whut.domain.trade.model.valobj.GroupBuyProgressVO;
import edu.whut.domain.trade.model.valobj.TradeOrderStatusEnumVO;
import edu.whut.infrastructure.dao.IGroupBuyActivityDao;
import edu.whut.infrastructure.dao.IGroupBuyOrderDao;
import edu.whut.infrastructure.dao.IGroupBuyOrderListDao;
+import edu.whut.infrastructure.dao.INotifyTaskDao;
import edu.whut.infrastructure.dao.po.GroupBuyActivity;
import edu.whut.infrastructure.dao.po.GroupBuyOrder;
import edu.whut.infrastructure.dao.po.GroupBuyOrderList;
+import edu.whut.infrastructure.dao.po.NotifyTask;
import edu.whut.types.common.Constants;
import edu.whut.types.enums.ActivityStatusEnumVO;
+import edu.whut.types.enums.GroupBuyOrderStatusEnumVO;
import edu.whut.types.enums.ResponseCode;
import edu.whut.types.exception.AppException;
import lombok.RequiredArgsConstructor;
@@ -23,6 +28,9 @@ import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
+import java.util.HashMap;
+import java.util.List;
+
/**
* 仓储实现:负责把领域对象 <-> 数据库 PO 的转换与持久化;
@@ -39,6 +47,8 @@ public class TradeRepository implements ITradeRepository {
private final IGroupBuyActivityDao groupBuyActivityDao;
+ private final INotifyTaskDao notifyTaskDao;
+
/**
* 根据外部交易号 & 用户id 查询未支付的锁单记录(用于幂等)
*/
@@ -54,8 +64,9 @@ public class TradeRepository implements ITradeRepository {
return null;
}
- // 只返回上层真正关心的属性
+ // // 组装领域对象返回,只返回上层真正关心的属性
return MarketPayOrderEntity.builder()
+ .teamId(po.getTeamId())
.orderId(po.getOrderId())
.deductionPrice(po.getDeductionPrice())
.tradeOrderStatusEnumVO(TradeOrderStatusEnumVO.valueOf(po.getStatus()))
@@ -113,6 +124,7 @@ public class TradeRepository implements ITradeRepository {
/* ---------- 2. 写入 group_buy_order_list(团单明细表) ---------- */
String orderId = RandomStringUtils.randomNumeric(12); // 订单号
+ //构建拼团明细单
GroupBuyOrderList orderListPo = GroupBuyOrderList.builder()
.userId(user.getUserId())
.teamId(teamId)
@@ -162,6 +174,9 @@ public class TradeRepository implements ITradeRepository {
.build();
}
+ /**
+ * 根据 activityId 查询拼团活动实体。
+ */
@Override
public GroupBuyActivityEntity queryGroupBuyActivityEntityByActivityId(Long activityId) {
GroupBuyActivity groupBuyActivity = groupBuyActivityDao.queryGroupBuyActivityByActivityId(activityId);
@@ -181,6 +196,9 @@ public class TradeRepository implements ITradeRepository {
.build();
}
+ /**
+ * 查询用户在某活动中已下单次数(用于限购校验)。
+ */
@Override
public Integer queryOrderCountByActivityId(Long activityId, String userId) {
GroupBuyOrderList groupBuyOrderListReq = new GroupBuyOrderList();
@@ -188,4 +206,80 @@ public class TradeRepository implements ITradeRepository {
groupBuyOrderListReq.setUserId(userId);
return groupBuyOrderListDao.queryOrderCountByActivityId(groupBuyOrderListReq);
}
+
+ /**
+ * 查询团队订单(主表)信息。
+ */
+ @Override
+ public GroupBuyTeamEntity queryGroupBuyTeamByTeamId(String teamId) {
+ GroupBuyOrder groupBuyOrder = groupBuyOrderDao.queryGroupBuyTeamByTeamId(teamId);
+ return GroupBuyTeamEntity.builder()
+ .teamId(groupBuyOrder.getTeamId())
+ .activityId(groupBuyOrder.getActivityId())
+ .targetCount(groupBuyOrder.getTargetCount())
+ .completeCount(groupBuyOrder.getCompleteCount())
+ .lockCount(groupBuyOrder.getLockCount())
+ .status(GroupBuyOrderStatusEnumVO.valueOf(groupBuyOrder.getStatus()))
+ .build();
+ }
+
+
+ /**
+ * 拼团支付成功后的结算逻辑
+ * 步骤:
+ * 更新明细表状态 → COMPLETE
+ * 更新主表 complete_count + 1
+ * 当达到 targetCount 时,更新主表状态 → COMPLETE 并写入回调任务
+ * 整体包裹在 500ms 事务内,任何一步失败都会回滚。
+ */
+ @Transactional(timeout = 500)
+ @Override
+ public void settlementMarketPayOrder(GroupBuyTeamSettlementAggregate agg) {
+
+ // ========= 1. 聚合拆分 =========
+ UserEntity user = agg.getUserEntity();
+ GroupBuyTeamEntity team = agg.getGroupBuyTeamEntity();
+ TradePaySuccessEntity payOK = agg.getTradePaySuccessEntity();
+
+ // ========= 2. 更新拼团订单明细状态 =========
+ GroupBuyOrderList req = new GroupBuyOrderList();
+ req.setUserId(user.getUserId());
+ req.setOutTradeNo(payOK.getOutTradeNo());
+ //更新订单状态到已完成
+ int rows = groupBuyOrderListDao.updateOrderStatus2COMPLETE(req);
+ if (rows != 1) {
+ throw new AppException(ResponseCode.UPDATE_ZERO);
+ }
+
+ // ========= 3. 更新拼团已完成人数 =========
+ int addCnt = groupBuyOrderDao.updateAddCompleteCount(team.getTeamId());
+ if (addCnt != 1) {
+ throw new AppException(ResponseCode.UPDATE_ZERO);
+ }
+
+ // ========= 4. 达标后收尾(状态改为 COMPLETE & 写入回调任务) =========
+ if (team.getTargetCount() - team.getCompleteCount() == 1) { // 刚好凑齐
+ int updStat = groupBuyOrderDao.updateOrderStatus2COMPLETE(team.getTeamId());
+ if (updStat != 1) {
+ throw new AppException(ResponseCode.UPDATE_ZERO);
+ }
+
+ // 查询已完成外部交易号列表,用于业务通知
+ List outTradeNoList = groupBuyOrderListDao.queryGroupBuyCompleteOrderOutTradeNoListByTeamId(team.getTeamId());
+
+ // 构造并写入通知任务(异步回调)
+ NotifyTask task = new NotifyTask();
+ task.setActivityId(team.getActivityId());
+ task.setTeamId(team.getTeamId());
+ task.setNotifyUrl("暂无"); // TODO:待配置回调地址
+ task.setNotifyCount(0);
+ task.setNotifyStatus(0);
+ task.setParameterJson(JSON.toJSONString(new HashMap() {{
+ put("teamId", team.getTeamId());
+ put("outTradeNoList", outTradeNoList);
+ }}));
+
+ notifyTaskDao.insert(task);
+ }
+ }
}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java
index ca39948..c664fb1 100644
--- a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderDao.java
@@ -31,4 +31,10 @@ public interface IGroupBuyOrderDao {
*/
GroupBuyOrder queryGroupBuyProgress(String teamId);
+ GroupBuyOrder queryGroupBuyTeamByTeamId(String teamId);
+
+ int updateAddCompleteCount(String teamId);
+
+ int updateOrderStatus2COMPLETE(String teamId);
+
}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderListDao.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderListDao.java
index 163b178..9d0b246 100644
--- a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderListDao.java
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/IGroupBuyOrderListDao.java
@@ -2,6 +2,8 @@ package edu.whut.infrastructure.dao;
import edu.whut.infrastructure.dao.po.GroupBuyOrderList;
import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
/**
* 用户拼单明细
*/
@@ -19,4 +21,9 @@ public interface IGroupBuyOrderListDao {
Integer queryOrderCountByActivityId(GroupBuyOrderList groupBuyOrderListReq);
+ int updateOrderStatus2COMPLETE(GroupBuyOrderList groupBuyOrderListReq);
+
+ List queryGroupBuyCompleteOrderOutTradeNoListByTeamId(String teamId);
+
+
}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/INotifyTaskDao.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/INotifyTaskDao.java
new file mode 100644
index 0000000..9e69322
--- /dev/null
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/INotifyTaskDao.java
@@ -0,0 +1,13 @@
+package edu.whut.infrastructure.dao;
+import edu.whut.infrastructure.dao.po.NotifyTask;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 回调任务
+ */
+@Mapper
+public interface INotifyTaskDao {
+
+ void insert(NotifyTask notifyTask);
+
+}
diff --git a/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/NotifyTask.java b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/NotifyTask.java
new file mode 100644
index 0000000..8568d3e
--- /dev/null
+++ b/group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/NotifyTask.java
@@ -0,0 +1,37 @@
+package edu.whut.infrastructure.dao.po;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 通知回调任务
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class NotifyTask {
+
+ /** 自增ID */
+ private Long id;
+ /** 活动ID */
+ private Long activityId;
+ /** 拼单组队ID */
+ private String teamId;
+ /** 回调接口 */
+ private String notifyUrl;
+ /** 回调次数 */
+ private Integer notifyCount;
+ /** 回调状态【0初始、1完成、2重试、3失败】 */
+ private Integer notifyStatus;
+ /** 参数对象 */
+ private String parameterJson;
+ /** 创建时间 */
+ private Date createTime;
+ /** 更新时间 */
+ private Date updateTime;
+
+}
diff --git a/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTradeController.java b/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTradeController.java
index dc5b1d6..cf6988b 100644
--- a/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTradeController.java
+++ b/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTradeController.java
@@ -14,7 +14,7 @@ import edu.whut.domain.trade.model.entity.PayActivityEntity;
import edu.whut.domain.trade.model.entity.PayDiscountEntity;
import edu.whut.domain.trade.model.entity.UserEntity;
import edu.whut.domain.trade.model.valobj.GroupBuyProgressVO;
-import edu.whut.domain.trade.service.ITradeOrderService;
+import edu.whut.domain.trade.service.ITradeLockOrderService;
import edu.whut.types.enums.ResponseCode;
import edu.whut.types.exception.AppException;
import lombok.RequiredArgsConstructor;
@@ -47,7 +47,7 @@ public class MarketTradeController implements IMarketTradeService {
private final IIndexGroupBuyMarketService indexGroupBuyMarketService;
- private final ITradeOrderService tradeOrderService;
+ private final ITradeLockOrderService tradeOrderService;
/**
* 锁定营销预支付订单(拼团 / 普通优惠)
diff --git a/group-buying-sys-types/src/main/java/edu/whut/types/enums/GroupBuyOrderStatusEnumVO.java b/group-buying-sys-types/src/main/java/edu/whut/types/enums/GroupBuyOrderStatusEnumVO.java
new file mode 100644
index 0000000..9f87e7e
--- /dev/null
+++ b/group-buying-sys-types/src/main/java/edu/whut/types/enums/GroupBuyOrderStatusEnumVO.java
@@ -0,0 +1,35 @@
+package edu.whut.types.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * 拼团订单枚举
+ */
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+public enum GroupBuyOrderStatusEnumVO {
+
+ PROGRESS(0, "拼单中"),
+ COMPLETE(1, "完成"),
+ FAIL(2, "失败"),
+ ;
+
+ private Integer code;
+ private String info;
+
+ public static GroupBuyOrderStatusEnumVO valueOf(Integer code) {
+ switch (code) {
+ case 0:
+ return PROGRESS;
+ case 1:
+ return COMPLETE;
+ case 2:
+ return FAIL;
+ }
+ throw new RuntimeException("err code not exist!");
+ }
+
+}
diff --git a/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java b/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java
index 6743f90..eb3662b 100644
--- a/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java
+++ b/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java
@@ -13,6 +13,8 @@ public enum ResponseCode {
UN_ERROR("0001", "未知失败"),
ILLEGAL_PARAMETER("0002", "非法参数"),
INDEX_EXCEPTION("0003", "唯一索引冲突"),
+ UPDATE_ZERO("0004", "更新记录为0"),
+
E0001("E0001", "不存在对应的折扣计算服务"),
E0002("E0002", "无拼团营销配置"),
E0003("E0003", "拼团活动降级拦截"),