Sfoglia il codice sorgente

feat: 活动领域的配置与状态

seamew 2 anni fa
parent
commit
3730feaf8e
51 ha cambiato i file con 1777 aggiunte e 56 eliminazioni
  1. 56 0
      lottery-common/src/main/java/com/seamew/lottery/common/Constants.java
  2. 10 2
      lottery-common/src/main/java/com/seamew/lottery/common/Result.java
  3. 4 5
      lottery-domain/pom.xml
  4. 39 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/aggregates/ActivityConfigRich.java
  5. 28 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/req/ActivityConfigReq.java
  6. 64 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/ActivityVO.java
  7. 32 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/AlterStateVO.java
  8. 39 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/AwardVO.java
  9. 50 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/StrategyDetailVO.java
  10. 56 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/StrategyVO.java
  11. 55 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/repository/IActivityRepository.java
  12. 26 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/deploy/IActivityDeploy.java
  13. 67 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/deploy/impl/ActivityDeployImpl.java
  14. 83 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/AbstractState.java
  15. 76 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/IStateHandler.java
  16. 46 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/StateConfig.java
  17. 55 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/ArraignmentState.java
  18. 54 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/CloseState.java
  19. 52 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/DoingState.java
  20. 55 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/EditingState.java
  21. 55 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/OpenState.java
  22. 56 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/PassState.java
  23. 55 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/RefuseState.java
  24. 54 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/impl/StateHandlerImpl.java
  25. 4 4
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/aggregates/StrategyRich.java
  26. 37 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/vo/AwardBriefVO.java
  27. 49 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/vo/StrategyBriefVO.java
  28. 50 0
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/vo/StrategyDetailBriefVO.java
  29. 2 2
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/repository/IStrategyRepository.java
  30. 8 10
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/service/draw/AbstractDrawBase.java
  31. 2 2
      lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/service/draw/DrawStrategySupport.java
  32. 6 0
      lottery-infrastructure/pom.xml
  33. 22 1
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IActivityDao.java
  34. 16 1
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IAwardDao.java
  35. 14 1
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IStrategyDao.java
  36. 8 1
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IStrategyDetailDao.java
  37. 5 0
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/po/StrategyDetail.java
  38. 83 0
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/repository/ActivityRepository.java
  39. 1 1
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/repository/AwardRepository.java
  40. 23 4
      lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/repository/StrategyRepository.java
  41. 3 0
      lottery-interfaces/src/main/java/com/seamew/lottery/LotteryApplication.java
  42. 2 3
      lottery-interfaces/src/main/java/com/seamew/lottery/interfaces/ActivityBooth.java
  43. 2 0
      lottery-interfaces/src/main/resources/application.yaml
  44. 8 5
      lottery-interfaces/src/main/resources/log4j.properties
  45. 7 0
      lottery-interfaces/src/main/resources/mybatis/mapper/Activity_Mapper.xml
  46. 22 3
      lottery-interfaces/src/main/resources/mybatis/mapper/Award_Mapper.xml
  47. 35 6
      lottery-interfaces/src/main/resources/mybatis/mapper/StrategyDetail_Mapper.xml
  48. 18 4
      lottery-interfaces/src/main/resources/mybatis/mapper/Strategy_Mapper.xml
  49. 1 1
      lottery-interfaces/src/test/java/com/seamew/lottery/test/ApiTest.java
  50. 178 0
      lottery-interfaces/src/test/java/com/seamew/lottery/test/domain/ActivityTest.java
  51. 4 0
      pom.xml

+ 56 - 0
lottery-common/src/main/java/com/seamew/lottery/common/Constants.java

@@ -32,6 +32,62 @@ public class Constants {
 
     }
 
+    /**
+     * 活动状态:1编辑、2提审、3撤审、4通过、5运行(审核通过后worker扫描状态)、6拒绝、7关闭、8开启
+     */
+    public enum ActivityState {
+
+        /**
+         * 1:编辑
+         */
+        EDIT(1, "编辑"),
+        /**
+         * 2:提审
+         */
+        ARRAIGNMENT(2, "提审"),
+        /**
+         * 3:撤审
+         */
+        REVOKE(3, "撤审"),
+        /**
+         * 4:通过
+         */
+        PASS(4, "通过"),
+        /**
+         * 5:运行(活动中)
+         */
+        DOING(5, "运行(活动中)"),
+        /**
+         * 6:拒绝
+         */
+        REFUSE(6, "拒绝"),
+        /**
+         * 7:关闭
+         */
+        CLOSE(7, "关闭"),
+        /**
+         * 8:开启
+         */
+        OPEN(8, "开启");
+
+        private final Integer code;
+        private final String info;
+
+        ActivityState(Integer code, String info) {
+            this.code = code;
+            this.info = info;
+        }
+
+        public Integer getCode() {
+            return code;
+        }
+
+        public String getInfo() {
+            return info;
+        }
+
+    }
+
     /**
      * 抽奖策略模式:总体概率、单项概率
      * 场景:两种抽奖算法描述,场景A20%、B30%、C50%

+ 10 - 2
lottery-common/src/main/java/com/seamew/lottery/common/Result.java

@@ -21,8 +21,12 @@ public class Result implements Serializable {
     private String code;
     private String info;
 
-    public static Result buildResult(String code, String info) {
-        return new Result(code, info);
+    public static Result buildResult(Constants.ResponseCode code, String info) {
+        return new Result(code.getCode(), info);
+    }
+
+    public static Result buildResult(Constants.ResponseCode code, Constants.ResponseCode info) {
+        return new Result(code.getCode(), info.getInfo());
     }
 
     public static Result buildSuccessResult() {
@@ -33,4 +37,8 @@ public class Result implements Serializable {
         return new Result(Constants.ResponseCode.UN_ERROR.getCode(), Constants.ResponseCode.UN_ERROR.getInfo());
     }
 
+    public static Result buildErrorResult(String info) {
+        return new Result(Constants.ResponseCode.UN_ERROR.getCode(), info);
+    }
+
 }

+ 4 - 5
lottery-domain/pom.xml

@@ -22,6 +22,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+        </dependency>
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
@@ -31,11 +35,6 @@
             <artifactId>fastjson</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>com.seamew</groupId>
-            <artifactId>lottery-infrastructure</artifactId>
-            <version>1.0-SNAPSHOT</version>
-        </dependency>
         <dependency>
             <groupId>com.seamew</groupId>
             <artifactId>lottery-common</artifactId>

+ 39 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/aggregates/ActivityConfigRich.java

@@ -0,0 +1,39 @@
+package com.seamew.lottery.domain.activity.model.aggregates;
+
+import com.seamew.lottery.domain.activity.model.vo.ActivityVO;
+import com.seamew.lottery.domain.activity.model.vo.AwardVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyVO;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @Author: seamew
+ * @Title: ActivityConfigRich
+ * @CreateTime: 2023年02月15日 20:35:00
+ * @Description: 活动配置聚合信息
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ActivityConfigRich {
+
+    /**
+     * 活动配置
+     */
+    private ActivityVO activity;
+
+    /**
+     * 策略配置(含策略明细)
+     */
+    private StrategyVO strategy;
+
+    /**
+     * 奖品配置
+     */
+    private List<AwardVO> awardList;
+
+}

+ 28 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/req/ActivityConfigReq.java

@@ -0,0 +1,28 @@
+package com.seamew.lottery.domain.activity.model.req;
+
+import com.seamew.lottery.domain.activity.model.aggregates.ActivityConfigRich;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: seamew
+ * @Title: ActivityConfigReq
+ * @CreateTime: 2023年02月15日 20:34:00
+ * @Description: 活动配置请求对象
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ActivityConfigReq {
+    /**
+     * 活动ID
+     */
+    private Long activityId;
+
+    /**
+     * 活动配置信息
+     */
+    private ActivityConfigRich activityConfigRich;
+}

+ 64 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/ActivityVO.java

@@ -0,0 +1,64 @@
+package com.seamew.lottery.domain.activity.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @Author: seamew
+ * @Title: ActivityVO
+ * @CreateTime: 2023年02月15日 20:35:00
+ * @Description: 活动信息配置
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ActivityVO {
+    /**
+     * 活动ID
+     */
+    private Long activityId;
+
+    /**
+     * 活动名称
+     */
+    private String activityName;
+
+    /**
+     * 活动描述
+     */
+    private String activityDesc;
+
+    /**
+     * 开始时间
+     */
+    private Date beginDateTime;
+
+    /**
+     * 结束时间
+     */
+    private Date endDateTime;
+
+    /**
+     * 库存
+     */
+    private Integer stockCount;
+
+    /**
+     * 每人可参与次数
+     */
+    private Integer takeCount;
+
+    /**
+     * 活动状态:编辑、提审、撤审、通过、运行、拒绝、关闭、开启
+     */
+    private Integer state;
+
+    /**
+     * 创建人
+     */
+    private String creator;
+}

+ 32 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/AlterStateVO.java

@@ -0,0 +1,32 @@
+package com.seamew.lottery.domain.activity.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: seamew
+ * @Title: AlterStateVO
+ * @CreateTime: 2023年02月15日 20:36:00
+ * @Description: 变更活动状态对象
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AlterStateVO {
+    /**
+     * 活动ID
+     */
+    private Long activityId;
+
+    /**
+     * 更新前状态
+     */
+    private Integer beforeState;
+
+    /**
+     * 更新后状态
+     */
+    private Integer afterState;
+}

+ 39 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/AwardVO.java

@@ -0,0 +1,39 @@
+package com.seamew.lottery.domain.activity.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: seamew
+ * @Title: AwardVO
+ * @CreateTime: 2023年02月15日 20:36:00
+ * @Description: 奖品信息配置
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AwardVO {
+
+    /**
+     * 奖品ID
+     */
+    private String awardId;
+
+    /**
+     * 奖品类型(1:文字描述、2:兑换码、3:优惠券、4:实物奖品)
+     */
+    private Integer awardType;
+
+    /**
+     * 奖品名称
+     */
+    private String awardName;
+
+    /**
+     * 奖品内容「描述、奖品码、sku」
+     */
+    private String awardContent;
+
+}

+ 50 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/StrategyDetailVO.java

@@ -0,0 +1,50 @@
+package com.seamew.lottery.domain.activity.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @Author: seamew
+ * @Title: StrategyDetailVO
+ * @CreateTime: 2023年02月15日 20:36:00
+ * @Description: 策略详情配置
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StrategyDetailVO {
+
+    /**
+     * 策略ID
+     */
+    private Long strategyId;
+
+    /**
+     * 奖品ID
+     */
+    private String awardId;
+
+    /**
+     * 奖品名称
+     */
+    private String awardName;
+
+    /**
+     * 奖品库存
+     */
+    private Integer awardCount;
+
+    /**
+     * 奖品剩余库存
+     */
+    private Integer awardSurplusCount;
+
+    /**
+     * 中奖概率
+     */
+    private BigDecimal awardRate;
+}

+ 56 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/model/vo/StrategyVO.java

@@ -0,0 +1,56 @@
+package com.seamew.lottery.domain.activity.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author: seamew
+ * @Title: StrategyVO
+ * @CreateTime: 2023年02月15日 20:37:00
+ * @Description: 策略信息配置
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StrategyVO {
+    /**
+     * 策略ID
+     */
+    private Long strategyId;
+
+    /**
+     * 策略描述
+     */
+    private String strategyDesc;
+
+    /**
+     * 策略方式「1:单项概率、2:总体概率」
+     */
+    private Integer strategyMode;
+
+    /**
+     * 发放奖品方式「1:即时、2:定时[含活动结束]、3:人工」
+     */
+    private Integer grantType;
+
+    /**
+     * 发放奖品时间
+     */
+    private Date grantDate;
+
+    /**
+     * 扩展信息
+     */
+    private String extInfo;
+
+
+    /**
+     * 策略详情配置
+     */
+    private List<StrategyDetailVO> strategyDetailList;
+}

+ 55 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/repository/IActivityRepository.java

@@ -0,0 +1,55 @@
+package com.seamew.lottery.domain.activity.repository;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.activity.model.vo.ActivityVO;
+import com.seamew.lottery.domain.activity.model.vo.AwardVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyDetailVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyVO;
+
+import java.util.List;
+
+/**
+ * @Author: seamew
+ * @Title: IActivityRepository
+ * @CreateTime: 2023年02月15日 20:44:00
+ * @Description: 活动仓库服务(活动表、奖品表、策略表、策略明细表)
+ * @Version: 1.0
+ */
+public interface IActivityRepository {
+    /**
+     * 添加活动配置
+     * @param activity 活动配置
+     */
+    void addActivity(ActivityVO activity);
+
+    /**
+     * 添加奖品配置集合
+     *
+     * @param awardList 奖品配置集合
+     */
+    void addAward(List<AwardVO> awardList);
+
+    /**
+     * 添加策略配置
+     *
+     * @param strategy 策略配置
+     */
+    void addStrategy(StrategyVO strategy);
+
+    /**
+     * 添加策略明细配置
+     *
+     * @param strategyDetailList 策略明细集合
+     */
+    void addStrategyDetailList(List<StrategyDetailVO> strategyDetailList);
+
+    /**
+     * 变更活动状态
+     *
+     * @param activityId    活动ID
+     * @param beforeState   修改前状态
+     * @param afterState    修改后状态
+     * @return              更新结果
+     */
+    boolean alterStatus(Long activityId, Constants.ActivityState beforeState, Constants.ActivityState afterState);
+}

+ 26 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/deploy/IActivityDeploy.java

@@ -0,0 +1,26 @@
+package com.seamew.lottery.domain.activity.service.deploy;
+
+import com.seamew.lottery.domain.activity.model.req.ActivityConfigReq;
+
+/**
+ * @Author: seamew
+ * @Title: IActivityDeploy
+ * @CreateTime: 2023年02月15日 20:34:00
+ * @Description: 部署活动配置接口
+ * @Version: 1.0
+ */
+public interface IActivityDeploy {
+    /**
+     * 创建活动信息
+     *
+     * @param req 活动配置信息
+     */
+    void createActivity(ActivityConfigReq req);
+
+    /**
+     * 修改活动信息
+     *
+     * @param req 活动配置信息
+     */
+    void updateActivity(ActivityConfigReq req);
+}

+ 67 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/deploy/impl/ActivityDeployImpl.java

@@ -0,0 +1,67 @@
+package com.seamew.lottery.domain.activity.service.deploy.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.seamew.lottery.domain.activity.model.aggregates.ActivityConfigRich;
+import com.seamew.lottery.domain.activity.model.req.ActivityConfigReq;
+import com.seamew.lottery.domain.activity.model.vo.ActivityVO;
+import com.seamew.lottery.domain.activity.model.vo.AwardVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyDetailVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyVO;
+import com.seamew.lottery.domain.activity.repository.IActivityRepository;
+import com.seamew.lottery.domain.activity.service.deploy.IActivityDeploy;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @Author: seamew
+ * @Title: ActivityDeployImpl
+ * @CreateTime: 2023年02月15日 20:42:00
+ * @Description: 部署活动配置服务
+ * @Version: 1.0
+ */
+@Service
+@Slf4j
+public class ActivityDeployImpl implements IActivityDeploy {
+
+    @Resource
+    private IActivityRepository activityRepository;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void createActivity(ActivityConfigReq req) {
+        log.info("创建活动配置开始,activityId:{}", req.getActivityId());
+        ActivityConfigRich activityConfigRich = req.getActivityConfigRich();
+        try {
+            // 添加活动配置
+            ActivityVO activity = activityConfigRich.getActivity();
+            activityRepository.addActivity(activity);
+
+            // 添加奖品配置
+            List<AwardVO> awardList = activityConfigRich.getAwardList();
+            activityRepository.addAward(awardList);
+
+            // 添加策略配置
+            StrategyVO strategy = activityConfigRich.getStrategy();
+            activityRepository.addStrategy(strategy);
+
+            // 添加策略明细配置
+            List<StrategyDetailVO> strategyDetailList = strategy.getStrategyDetailList();
+            activityRepository.addStrategyDetailList(strategyDetailList);
+
+            log.info("创建活动配置完成,activityId:{}", req.getActivityId());
+        } catch (DuplicateKeyException e) {
+            log.error("创建活动配置失败,唯一索引冲突 activityId:{} reqJson:{}", req.getActivityId(), JSON.toJSONString(req), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public void updateActivity(ActivityConfigReq req) {
+        // TODO: 非核心功能后续补充
+    }
+}

+ 83 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/AbstractState.java

@@ -0,0 +1,83 @@
+package com.seamew.lottery.domain.activity.service.stateflow;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.repository.IActivityRepository;
+
+import javax.annotation.Resource;
+
+/**
+ * @Author: seamew
+ * @Title: AbstractState
+ * @CreateTime: 2023年02月15日 21:12:00
+ * @Description: 活动状态抽象类
+ * @Version: 1.0
+ */
+public abstract class AbstractState {
+    @Resource
+    protected IActivityRepository activityRepository;
+
+    /**
+     * 活动提审
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result arraignment(Long activityId, Constants.ActivityState currentState);
+
+    /**
+     * 审核通过
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result checkPass(Long activityId, Constants.ActivityState currentState);
+
+    /**
+     * 审核拒绝
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result checkRefuse(Long activityId, Constants.ActivityState currentState);
+
+    /**
+     * 撤审撤销
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result checkRevoke(Long activityId, Constants.ActivityState currentState);
+
+    /**
+     * 活动关闭
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result close(Long activityId, Constants.ActivityState currentState);
+
+    /**
+     * 活动开启
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result open(Long activityId, Constants.ActivityState currentState);
+
+    /**
+     * 活动执行
+     *
+     * @param activityId   活动ID
+     * @param currentState 当前状态
+     * @return 执行结果
+     */
+    public abstract Result doing(Long activityId, Constants.ActivityState currentState);
+
+}

+ 76 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/IStateHandler.java

@@ -0,0 +1,76 @@
+package com.seamew.lottery.domain.activity.service.stateflow;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+
+/**
+ * @Author: seamew
+ * @Title: IStateHandler
+ * @CreateTime: 2023年02月15日 21:11:00
+ * @Description: 状态处理接口
+ * @Version: 1.0
+ */
+public interface IStateHandler {
+    /**
+     * 提审
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result arraignment(Long activityId, Constants.ActivityState currentStatus);
+
+    /**
+     * 审核通过
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result checkPass(Long activityId, Constants.ActivityState currentStatus);
+
+    /**
+     * 审核拒绝
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result checkRefuse(Long activityId, Constants.ActivityState currentStatus);
+
+    /**
+     * 撤销审核
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result checkRevoke(Long activityId, Constants.ActivityState currentStatus);
+
+    /**
+     * 关闭
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result close(Long activityId, Constants.ActivityState currentStatus);
+
+    /**
+     * 开启
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result open(Long activityId, Constants.ActivityState currentStatus);
+
+    /**
+     * 运行活动中
+     *
+     * @param activityId    活动ID
+     * @param currentStatus 当前状态
+     * @return 审核结果
+     */
+    Result doing(Long activityId, Constants.ActivityState currentStatus);
+}

+ 46 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/StateConfig.java

@@ -0,0 +1,46 @@
+package com.seamew.lottery.domain.activity.service.stateflow;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.activity.service.stateflow.event.*;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Author: seamew
+ * @Title: StateConfig
+ * @CreateTime: 2023年02月15日 21:19:00
+ * @Description: 状态流转配置
+ * @Version: 1.0
+ */
+public class StateConfig {
+    @Resource
+    private ArraignmentState arraignmentState;
+    @Resource
+    private CloseState closeState;
+    @Resource
+    private DoingState doingState;
+    @Resource
+    private EditingState editingState;
+    @Resource
+    private OpenState openState;
+    @Resource
+    private PassState passState;
+    @Resource
+    private RefuseState refuseState;
+
+    protected Map<Constants.ActivityState, AbstractState> stateGroup = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void init() {
+        stateGroup.put(Constants.ActivityState.ARRAIGNMENT, arraignmentState);
+        stateGroup.put(Constants.ActivityState.CLOSE, closeState);
+        stateGroup.put(Constants.ActivityState.DOING, doingState);
+        stateGroup.put(Constants.ActivityState.EDIT, editingState);
+        stateGroup.put(Constants.ActivityState.OPEN, openState);
+        stateGroup.put(Constants.ActivityState.PASS, passState);
+        stateGroup.put(Constants.ActivityState.REFUSE, refuseState);
+    }
+}

+ 55 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/ArraignmentState.java

@@ -0,0 +1,55 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: ArraignmentState
+ * @CreateTime: 2023年02月15日 21:14:00
+ * @Description: 提审状态
+ * @Version: 1.0
+ */
+@Component
+public class ArraignmentState extends AbstractState {
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "待审核状态不可重复提审");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.PASS);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核通过完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.REFUSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核拒绝完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.EDIT);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核撤销回到编辑中") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.CLOSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核关闭完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "非关闭活动不可开启");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "待审核活动不可执行活动中变更");
+    }
+}

+ 54 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/CloseState.java

@@ -0,0 +1,54 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: CloseState
+ * @CreateTime: 2023年02月15日 21:17:00
+ * @Description: 活动关闭状态
+ * @Version: 1.0
+ */
+@Component
+public class CloseState extends AbstractState {
+
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动关闭不可提审");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动关闭不可审核通过");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动关闭不可审核拒绝");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动关闭不可撤销审核");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动关闭不可重复关闭");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.OPEN);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动开启完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动关闭不可变更活动中");
+    }
+
+}

+ 52 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/DoingState.java

@@ -0,0 +1,52 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: DoingState
+ * @CreateTime: 2023年02月15日 21:17:00
+ * @Description: 运行(活动中)状态
+ * @Version: 1.0
+ */
+@Component
+public class DoingState extends AbstractState {
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动中不可提审");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动中不可审核通过");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动中不可审核拒绝");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动中不可撤销审核");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.CLOSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动关闭成功") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动中不可开启");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动中不可重复执行");
+    }
+}

+ 55 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/EditingState.java

@@ -0,0 +1,55 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: EditingState
+ * @CreateTime: 2023年02月15日 21:18:00
+ * @Description: 编辑状态
+ * @Version: 1.0
+ */
+@Component
+public class EditingState extends AbstractState {
+
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.ARRAIGNMENT);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动提审成功") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "编辑中不可审核通过");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "编辑中不可审核拒绝");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "编辑中不可撤销审核");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.CLOSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动关闭成功") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "非关闭活动不可开启");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "编辑中活动不可执行活动中变更");
+    }
+
+}

+ 55 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/OpenState.java

@@ -0,0 +1,55 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: OpenState
+ * @CreateTime: 2023年02月15日 21:18:00
+ * @Description: 活动开启状态
+ * @Version: 1.0
+ */
+@Component
+public class OpenState extends AbstractState {
+
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动开启不可提审");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动开启不可审核通过");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动开启不可审核拒绝");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动开启不可撤销审核");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.CLOSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动关闭完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动不可重复开启");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.DOING);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动变更活动中完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+}

+ 56 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/PassState.java

@@ -0,0 +1,56 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: PassState
+ * @CreateTime: 2023年02月15日 21:19:00
+ * @Description: 审核通过状态
+ * @Version: 1.0
+ */
+@Component
+public class PassState extends AbstractState {
+
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "已审核状态不可重复提审");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "已审核状态不可重复审核");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.REFUSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核拒绝完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "审核通过不可撤销(可先拒绝审核)");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.CLOSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核关闭完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "非关闭活动不可开启");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.DOING);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动变更活动中完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+}

+ 55 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/event/RefuseState.java

@@ -0,0 +1,55 @@
+package com.seamew.lottery.domain.activity.service.stateflow.event;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.AbstractState;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: RefuseState
+ * @CreateTime: 2023年02月15日 21:19:00
+ * @Description: 审核拒绝状态
+ * @Version: 1.0
+ */
+@Component
+public class RefuseState extends AbstractState {
+
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "已审核状态不可重复提审");
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "已审核状态不可重复审核");
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "活动审核拒绝不可重复审核");
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.EDIT);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "撤销审核完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentState) {
+        boolean isSuccess = activityRepository.alterStatus(activityId, currentState, Constants.ActivityState.CLOSE);
+        return isSuccess ? Result.buildResult(Constants.ResponseCode.SUCCESS, "活动审核关闭完成") : Result.buildErrorResult("活动状态变更失败");
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "非关闭活动不可开启");
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentState) {
+        return Result.buildResult(Constants.ResponseCode.UN_ERROR, "审核拒绝不可执行活动为进行中");
+    }
+
+}

+ 54 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/activity/service/stateflow/impl/StateHandlerImpl.java

@@ -0,0 +1,54 @@
+package com.seamew.lottery.domain.activity.service.stateflow.impl;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.common.Result;
+import com.seamew.lottery.domain.activity.service.stateflow.IStateHandler;
+import com.seamew.lottery.domain.activity.service.stateflow.StateConfig;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Author: seamew
+ * @Title: StateHandlerImpl
+ * @CreateTime: 2023年02月15日 21:20:00
+ * @Description: 状态处理服务
+ * @Version: 1.0
+ */
+@Service
+public class StateHandlerImpl extends StateConfig implements IStateHandler {
+
+    @Override
+    public Result arraignment(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).arraignment(activityId, currentStatus);
+    }
+
+    @Override
+    public Result checkPass(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).checkPass(activityId, currentStatus);
+    }
+
+    @Override
+    public Result checkRefuse(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).checkRefuse(activityId, currentStatus);
+    }
+
+    @Override
+    public Result checkRevoke(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).checkRevoke(activityId, currentStatus);
+    }
+
+    @Override
+    public Result close(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).close(activityId, currentStatus);
+    }
+
+    @Override
+    public Result open(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).open(activityId, currentStatus);
+    }
+
+    @Override
+    public Result doing(Long activityId, Constants.ActivityState currentStatus) {
+        return stateGroup.get(currentStatus).doing(activityId, currentStatus);
+    }
+
+}

+ 4 - 4
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/aggregates/StrategyRich.java

@@ -1,7 +1,7 @@
 package com.seamew.lottery.domain.strategy.model.aggregates;
 
-import com.seamew.lottery.infrastructure.po.Strategy;
-import com.seamew.lottery.infrastructure.po.StrategyDetail;
+import com.seamew.lottery.domain.strategy.model.vo.StrategyBriefVO;
+import com.seamew.lottery.domain.strategy.model.vo.StrategyDetailBriefVO;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -22,7 +22,7 @@ public class StrategyRich {
     // 策略ID
     private Long strategyId;
     // 策略配置
-    private Strategy strategy;
+    private StrategyBriefVO strategy;
     // 策略明细
-    private List<StrategyDetail> strategyDetailList;
+    private List<StrategyDetailBriefVO> strategyDetailList;
 }

+ 37 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/vo/AwardBriefVO.java

@@ -0,0 +1,37 @@
+package com.seamew.lottery.domain.strategy.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: seamew
+ * @Title: AwardBriefVO
+ * @CreateTime: 2023年02月15日 21:51:00
+ * @Description: 奖品简要信息
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AwardBriefVO {
+    /**
+     * 奖品ID
+     */
+    private String awardId;
+
+    /**
+     * 奖品类型(1:文字描述、2:兑换码、3:优惠券、4:实物奖品)
+     */
+    private Integer awardType;
+
+    /**
+     * 奖品名称
+     */
+    private String awardName;
+
+    /**
+     * 奖品内容「描述、奖品码、sku」
+     */
+    private String awardContent;
+}

+ 49 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/vo/StrategyBriefVO.java

@@ -0,0 +1,49 @@
+package com.seamew.lottery.domain.strategy.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @Author: seamew
+ * @Title: StrategyBriefVO
+ * @CreateTime: 2023年02月15日 21:52:00
+ * @Description: 策略简要信息
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StrategyBriefVO {
+    /**
+     * 策略ID
+     */
+    private Long strategyId;
+
+    /**
+     * 策略描述
+     */
+    private String strategyDesc;
+
+    /**
+     * 策略方式「1:单项概率、2:总体概率」
+     */
+    private Integer strategyMode;
+
+    /**
+     * 发放奖品方式「1:即时、2:定时[含活动结束]、3:人工」
+     */
+    private Integer grantType;
+
+    /**
+     * 发放奖品时间
+     */
+    private Date grantDate;
+
+    /**
+     * 扩展信息
+     */
+    private String extInfo;
+}

+ 50 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/model/vo/StrategyDetailBriefVO.java

@@ -0,0 +1,50 @@
+package com.seamew.lottery.domain.strategy.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @Author: seamew
+ * @Title: StrategyDetailBriefVO
+ * @CreateTime: 2023年02月15日 21:52:00
+ * @Description: 策略明细简要信息
+ * @Version: 1.0
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StrategyDetailBriefVO {
+
+    /**
+     * 策略ID
+     */
+    private Long strategyId;
+
+    /**
+     * 奖品ID
+     */
+    private String awardId;
+
+    /**
+     * 奖品名称
+     */
+    private String awardName;
+
+    /**
+     * 奖品库存
+     */
+    private Integer awardCount;
+
+    /**
+     * 奖品剩余库存
+     */
+    private Integer awardSurplusCount;
+
+    /**
+     * 中奖概率
+     */
+    private BigDecimal awardRate;
+}

+ 2 - 2
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/repository/IStrategyRepository.java

@@ -1,7 +1,7 @@
 package com.seamew.lottery.domain.strategy.repository;
 
 import com.seamew.lottery.domain.strategy.model.aggregates.StrategyRich;
-import com.seamew.lottery.infrastructure.po.Award;
+import com.seamew.lottery.domain.strategy.model.vo.AwardBriefVO;
 
 import java.util.List;
 
@@ -21,7 +21,7 @@ public interface IStrategyRepository {
      */
     StrategyRich queryStrategyRich(Long strategyId);
 
-    Award queryAwardInfo(String awardId);
+    AwardBriefVO queryAwardInfo(String awardId);
 
     List<String> queryNoStockStrategyAwardList(Long strategyId);
 

+ 8 - 10
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/service/draw/AbstractDrawBase.java

@@ -4,12 +4,8 @@ import com.seamew.lottery.common.Constants;
 import com.seamew.lottery.domain.strategy.model.aggregates.StrategyRich;
 import com.seamew.lottery.domain.strategy.model.req.DrawReq;
 import com.seamew.lottery.domain.strategy.model.res.DrawResult;
-import com.seamew.lottery.domain.strategy.model.vo.AwardRateInfo;
-import com.seamew.lottery.domain.strategy.model.vo.DrawAwardInfo;
+import com.seamew.lottery.domain.strategy.model.vo.*;
 import com.seamew.lottery.domain.strategy.service.algorithm.IDrawAlgorithm;
-import com.seamew.lottery.infrastructure.po.Award;
-import com.seamew.lottery.infrastructure.po.Strategy;
-import com.seamew.lottery.infrastructure.po.StrategyDetail;
 import lombok.extern.slf4j.Slf4j;
 
 import java.util.ArrayList;
@@ -28,7 +24,7 @@ public abstract class AbstractDrawBase extends DrawStrategySupport implements ID
     public DrawResult doDrawExec(DrawReq req) {
         // 1. 获取抽奖策略
         StrategyRich strategyRich = queryStrategyRich(req.getStrategyId());
-        Strategy strategy = strategyRich.getStrategy();
+        StrategyBriefVO strategy = strategyRich.getStrategy();
 
         // 2. 校验抽奖策略是否已经初始化到内存
         checkAndInitRateData(req.getStrategyId(), strategy.getStrategyMode(), strategyRich.getStrategyDetailList());
@@ -68,9 +64,10 @@ public abstract class AbstractDrawBase extends DrawStrategySupport implements ID
      * @param strategyMode       抽奖策略模式
      * @param strategyDetailList 抽奖策略详情
      */
-    private void checkAndInitRateData(Long strategyId, Integer strategyMode, List<StrategyDetail> strategyDetailList) {
+    private void checkAndInitRateData(Long strategyId, Integer strategyMode, List<StrategyDetailBriefVO> strategyDetailList) {
+
         // 非单项概率,不必存入缓存
-        // 暂时注释有BUG
+        // 暂时注释有BUG
         // if (!Constants.StrategyMode.SINGLE.getCode().equals(strategyMode)) {
         //     return;
         // }
@@ -84,7 +81,7 @@ public abstract class AbstractDrawBase extends DrawStrategySupport implements ID
 
         // 解析并初始化中奖概率数据到散列表
         List<AwardRateInfo> awardRateInfoList = new ArrayList<>(strategyDetailList.size());
-        for (StrategyDetail strategyDetail : strategyDetailList) {
+        for (StrategyDetailBriefVO strategyDetail : strategyDetailList) {
             awardRateInfoList.add(new AwardRateInfo(strategyDetail.getAwardId(), strategyDetail.getAwardRate()));
         }
 
@@ -106,9 +103,10 @@ public abstract class AbstractDrawBase extends DrawStrategySupport implements ID
             return new DrawResult(uId, strategyId, Constants.DrawState.FAIL.getCode());
         }
 
-        Award award = queryAwardInfoByAwardId(awardId);
+        AwardBriefVO award = super.queryAwardInfoByAwardId(awardId);
         DrawAwardInfo drawAwardInfo = new DrawAwardInfo(award.getAwardId(), award.getAwardType(), award.getAwardName(), award.getAwardContent());
         log.info("执行策略抽奖完成【已中奖】,用户:{} 策略ID:{} 奖品ID:{} 奖品名称:{}", uId, strategyId, awardId, award.getAwardName());
+
         return new DrawResult(uId, strategyId, Constants.DrawState.SUCCESS.getCode(), drawAwardInfo);
     }
 

+ 2 - 2
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/service/draw/DrawStrategySupport.java

@@ -1,8 +1,8 @@
 package com.seamew.lottery.domain.strategy.service.draw;
 
 import com.seamew.lottery.domain.strategy.model.aggregates.StrategyRich;
+import com.seamew.lottery.domain.strategy.model.vo.AwardBriefVO;
 import com.seamew.lottery.domain.strategy.repository.IStrategyRepository;
-import com.seamew.lottery.infrastructure.po.Award;
 
 import javax.annotation.Resource;
 
@@ -34,7 +34,7 @@ public class DrawStrategySupport extends DrawConfig {
      * @param awardId 奖品ID
      * @return 中奖详情
      */
-    protected Award queryAwardInfoByAwardId(String awardId){
+    protected AwardBriefVO queryAwardInfoByAwardId(String awardId){
         return strategyRepository.queryAwardInfo(awardId);
     }
 }

+ 6 - 0
lottery-infrastructure/pom.xml

@@ -22,6 +22,12 @@
             <groupId>org.mybatis.spring.boot</groupId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>com.seamew</groupId>
+            <artifactId>lottery-domain</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 22 - 1
lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IActivityDao.java

@@ -1,5 +1,6 @@
 package com.seamew.lottery.infrastructure.dao;
 
+import com.seamew.lottery.domain.activity.model.vo.AlterStateVO;
 import com.seamew.lottery.infrastructure.po.Activity;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -7,14 +8,34 @@ import org.apache.ibatis.annotations.Mapper;
  * @Author: seamew
  * @Title: IActivityDao
  * @CreateTime: 2023年02月07日 13:54:00
- * @Description:
+ * @Description: 活动基础信息表DAO
  * @Version: 1.0
  */
 @Mapper
 public interface IActivityDao {
 
+
+    /**
+     * 插入数据
+     *
+     * @param req 入参
+     */
     void insert(Activity req);
 
+    /**
+     * 根据活动号查询活动信息
+     *
+     * @param activityId 活动号
+     * @return 活动信息
+     */
     Activity queryActivityById(Long activityId);
 
+    /**
+     * 变更活动状态
+     *
+     * @param alterStateVO  [activityId、beforeState、afterState]
+     * @return 更新数量
+     */
+    int alterState(AlterStateVO alterStateVO);
+
 }

+ 16 - 1
lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IAwardDao.java

@@ -3,16 +3,31 @@ package com.seamew.lottery.infrastructure.dao;
 import com.seamew.lottery.infrastructure.po.Award;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
  * @Author: seamew
  * @Title: IAwardDao
  * @CreateTime: 2023年02月13日 21:03:00
- * @Description:
+ * @Description: 奖品信息表DAO
  * @Version: 1.0
  */
 @Mapper
 public interface IAwardDao {
 
+    /**
+     * 查询奖品信息
+     *
+     * @param awardId 奖品ID
+     * @return        奖品信息
+     */
     Award queryAwardInfo(String awardId);
 
+    /**
+     * 插入奖品配置
+     *
+     * @param list 奖品配置
+     */
+    void insertList(List<Award> list);
+
 }

+ 14 - 1
lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IStrategyDao.java

@@ -7,12 +7,25 @@ import org.apache.ibatis.annotations.Mapper;
  * @Author: seamew
  * @Title: IStrategyDao
  * @CreateTime: 2023年02月13日 21:03:00
- * @Description:
+ * @Description: 策略表DAO
  * @Version: 1.0
  */
 @Mapper
 public interface IStrategyDao {
 
+    /**
+     * 查询策略配置
+     *
+     * @param strategyId 策略ID
+     * @return           策略配置信息
+     */
     Strategy queryStrategy(Long strategyId);
 
+    /**
+     * 插入策略配置
+     *
+     * @param req 策略配置
+     */
+    void insert(Strategy req);
+
 }

+ 8 - 1
lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/dao/IStrategyDetailDao.java

@@ -9,7 +9,7 @@ import java.util.List;
  * @Author: seamew
  * @Title: IStrategyDetailDao
  * @CreateTime: 2023年02月13日 21:04:00
- * @Description: 策略表数据库操作
+ * @Description: 策略明细表DAO
  * @Version: 1.0
  */
 @Mapper
@@ -36,4 +36,11 @@ public interface IStrategyDetailDao {
      */
     int deductStock(StrategyDetail strategyDetailReq);
 
+    /**
+     * 插入策略配置组
+     *
+     * @param list 策略配置组
+     */
+    void insertList(List<StrategyDetail> list);
+
 }

+ 5 - 0
lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/po/StrategyDetail.java

@@ -32,6 +32,11 @@ public class StrategyDetail {
      */
     private String awardId;
 
+    /**
+     * 奖品名称
+     */
+    private String awardName;
+
     /**
      * 奖品库存
      */

+ 83 - 0
lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/repository/ActivityRepository.java

@@ -0,0 +1,83 @@
+package com.seamew.lottery.infrastructure.repository;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.activity.model.vo.*;
+import com.seamew.lottery.domain.activity.repository.IActivityRepository;
+import com.seamew.lottery.infrastructure.dao.IActivityDao;
+import com.seamew.lottery.infrastructure.dao.IAwardDao;
+import com.seamew.lottery.infrastructure.dao.IStrategyDao;
+import com.seamew.lottery.infrastructure.dao.IStrategyDetailDao;
+import com.seamew.lottery.infrastructure.po.Activity;
+import com.seamew.lottery.infrastructure.po.Award;
+import com.seamew.lottery.infrastructure.po.Strategy;
+import com.seamew.lottery.infrastructure.po.StrategyDetail;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: seamew
+ * @Title: ActivityRepository
+ * @CreateTime: 2023年02月15日 21:38:00
+ * @Description:
+ * @Version: 1.0
+ */
+@Component
+public class ActivityRepository implements IActivityRepository {
+
+    @Resource
+    private IActivityDao activityDao;
+    @Resource
+    private IAwardDao awardDao;
+    @Resource
+    private IStrategyDao strategyDao;
+    @Resource
+    private IStrategyDetailDao strategyDetailDao;
+
+    @Override
+    public void addActivity(ActivityVO activity) {
+        Activity req = new Activity();
+        BeanUtils.copyProperties(activity, req);
+        activityDao.insert(req);
+    }
+
+    @Override
+    public void addAward(List<AwardVO> awardList) {
+        List<Award> req = new ArrayList<>();
+        for (AwardVO awardVO : awardList) {
+            Award award = new Award();
+            BeanUtils.copyProperties(awardVO, award);
+            req.add(award);
+        }
+        awardDao.insertList(req);
+    }
+
+    @Override
+    public void addStrategy(StrategyVO strategy) {
+        Strategy req = new Strategy();
+        BeanUtils.copyProperties(strategy, req);
+        strategyDao.insert(req);
+    }
+
+    @Override
+    public void addStrategyDetailList(List<StrategyDetailVO> strategyDetailList) {
+        List<StrategyDetail> req = new ArrayList<>();
+        for (StrategyDetailVO strategyDetailVO : strategyDetailList) {
+            StrategyDetail strategyDetail = new StrategyDetail();
+            BeanUtils.copyProperties(strategyDetailVO, strategyDetail);
+            req.add(strategyDetail);
+        }
+        strategyDetailDao.insertList(req);
+    }
+
+    @Override
+    public boolean alterStatus(Long activityId, Constants.ActivityState beforeState, Constants.ActivityState afterState) {
+        AlterStateVO alterStateVO = new AlterStateVO(activityId, beforeState.getCode(), afterState.getCode());
+        int count = activityDao.alterState(alterStateVO);
+        return 1 == count;
+    }
+
+}

+ 1 - 1
lottery-domain/src/main/java/com/seamew/lottery/domain/award/repository/impl/AwardRepository.java → lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/repository/AwardRepository.java

@@ -1,4 +1,4 @@
-package com.seamew.lottery.domain.award.repository.impl;
+package com.seamew.lottery.infrastructure.repository;
 
 import com.seamew.lottery.domain.award.repository.IAwardRepository;
 import org.springframework.stereotype.Component;

+ 23 - 4
lottery-domain/src/main/java/com/seamew/lottery/domain/strategy/repository/impl/StrategyRepository.java → lottery-infrastructure/src/main/java/com/seamew/lottery/infrastructure/repository/StrategyRepository.java

@@ -1,6 +1,9 @@
-package com.seamew.lottery.domain.strategy.repository.impl;
+package com.seamew.lottery.infrastructure.repository;
 
 import com.seamew.lottery.domain.strategy.model.aggregates.StrategyRich;
+import com.seamew.lottery.domain.strategy.model.vo.AwardBriefVO;
+import com.seamew.lottery.domain.strategy.model.vo.StrategyBriefVO;
+import com.seamew.lottery.domain.strategy.model.vo.StrategyDetailBriefVO;
 import com.seamew.lottery.domain.strategy.repository.IStrategyRepository;
 import com.seamew.lottery.infrastructure.dao.IAwardDao;
 import com.seamew.lottery.infrastructure.dao.IStrategyDao;
@@ -8,9 +11,11 @@ import com.seamew.lottery.infrastructure.dao.IStrategyDetailDao;
 import com.seamew.lottery.infrastructure.po.Award;
 import com.seamew.lottery.infrastructure.po.Strategy;
 import com.seamew.lottery.infrastructure.po.StrategyDetail;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -35,12 +40,26 @@ public class StrategyRepository implements IStrategyRepository {
     public StrategyRich queryStrategyRich(Long strategyId) {
         Strategy strategy = strategyDao.queryStrategy(strategyId);
         List<StrategyDetail> strategyDetailList = strategyDetailDao.queryStrategyDetailList(strategyId);
-        return new StrategyRich(strategyId, strategy, strategyDetailList);
+
+        StrategyBriefVO strategyBriefVO = new StrategyBriefVO();
+        BeanUtils.copyProperties(strategy, strategyBriefVO);
+
+        List<StrategyDetailBriefVO> strategyDetailBriefVOList = new ArrayList<>();
+        for (StrategyDetail strategyDetail : strategyDetailList) {
+            StrategyDetailBriefVO strategyDetailBriefVO = new StrategyDetailBriefVO();
+            BeanUtils.copyProperties(strategyDetail, strategyDetailBriefVO);
+            strategyDetailBriefVOList.add(strategyDetailBriefVO);
+        }
+
+        return new StrategyRich(strategyId, strategyBriefVO, strategyDetailBriefVOList);
     }
 
     @Override
-    public Award queryAwardInfo(String awardId) {
-        return awardDao.queryAwardInfo(awardId);
+    public AwardBriefVO queryAwardInfo(String awardId) {
+        Award award = awardDao.queryAwardInfo(awardId);
+        AwardBriefVO awardBriefVO = new AwardBriefVO();
+        BeanUtils.copyProperties(award, awardBriefVO);
+        return awardBriefVO;
     }
 
     @Override

+ 3 - 0
lottery-interfaces/src/main/java/com/seamew/lottery/LotteryApplication.java

@@ -4,6 +4,8 @@ import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.springframework.beans.factory.annotation.Configurable;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
 /**
  * @Author: seamew
  * @Title: LotteryApplication
@@ -14,6 +16,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 @SpringBootApplication
 @Configurable
 @EnableDubbo
+@EnableTransactionManagement
 public class LotteryApplication {
     public static void main(String[] args) {
         SpringApplication.run(LotteryApplication.class, args);

+ 2 - 3
lottery-interfaces/src/main/java/com/seamew/lottery/interfaces/ActivityBooth.java

@@ -8,8 +8,7 @@ import com.seamew.lottery.rpc.IActivityBooth;
 import com.seamew.lottery.rpc.dto.ActivityDto;
 import com.seamew.lottery.rpc.req.ActivityReq;
 import com.seamew.lottery.rpc.res.ActivityRes;
-import org.apache.dubbo.config.annotation.Service;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.dubbo.config.annotation.DubboService;
 
 import javax.annotation.Resource;
 
@@ -20,7 +19,7 @@ import javax.annotation.Resource;
  * @Description: 活动展台
  * @Version: 1.0
  */
-@Service
+@DubboService
 public class ActivityBooth implements IActivityBooth {
 
     @Resource

+ 2 - 0
lottery-interfaces/src/main/resources/application.yaml

@@ -12,6 +12,8 @@ mybatis:
   mapper-locations: classpath:/mybatis/mapper/*.xml
   configuration:
     map-underscore-to-camel-case: true
+    # 开启sql日志
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 
 dubbo:
   application:

+ 8 - 5
lottery-interfaces/src/main/resources/log4j.properties

@@ -1,16 +1,19 @@
-log4j.rootLogger=WARN, stdout
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
+#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
+log4j.rootLogger=DEBUG,console
 
+#控制台输出的相关设置
 log4j.appender.console = org.apache.log4j.ConsoleAppender
 log4j.appender.console.Target = System.out
 log4j.appender.console.Threshold=DEBUG
 log4j.appender.console.layout = org.apache.log4j.PatternLayout
 log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
 
+#日志输出级别
 log4j.logger.org.mybatis=DEBUG
 log4j.logger.java.sql=DEBUG
 log4j.logger.java.sql.Statement=DEBUG
 log4j.logger.java.sql.ResultSet=DEBUG
-log4j.logger.java.sql.PreparedStatement=DEBUG
+log4j.logger.java.sql.PreparedStatement=DEBUG
+
+#扫描mapper包的配置
+log4j.logger.com.lwg.mybatis.mapper=DEBUG

+ 7 - 0
lottery-interfaces/src/main/resources/mybatis/mapper/Activity_Mapper.xml

@@ -18,5 +18,12 @@
         WHERE activity_id = #{activityId}
     </select>
 
+    <update id="alterState" parameterType="com.seamew.lottery.domain.activity.model.vo.AlterStateVO">
+        UPDATE activity
+        SET state = #{afterState}
+        WHERE activity_id = #{activityId}
+          AND state = #{beforeState}
+    </update>
+
 
 </mapper>

+ 22 - 3
lottery-interfaces/src/main/resources/mybatis/mapper/Award_Mapper.xml

@@ -2,11 +2,30 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.seamew.lottery.infrastructure.dao.IAwardDao">
 
-    <select id="queryAwardInfo" parameterType="java.lang.String" resultType="com.seamew.lottery.infrastructure.po.Award">
-        SELECT
-            id, award_id, award_type, award_name, award_content
+    <select id="queryAwardInfo" parameterType="java.lang.String"
+            resultType="com.seamew.lottery.infrastructure.po.Award">
+        SELECT id,
+               award_id,
+               award_type,
+               award_name,
+               award_content
         FROM award
         WHERE award_id = #{awardId}
     </select>
 
+    <insert id="insertList" parameterType="java.util.List">
+        INSERT INTO award(award_id, award_type, award_name, award_content, create_time, update_time)
+        VALUES
+        <foreach collection="list" item="item" index="index" separator=",">
+            (
+            #{item.awardId},
+            #{item.awardType},
+            #{item.awardName},
+            #{item.awardContent},
+            NOW(),
+            NOW()
+            )
+        </foreach>
+    </insert>
+
 </mapper>

+ 35 - 6
lottery-interfaces/src/main/resources/mybatis/mapper/StrategyDetail_Mapper.xml

@@ -2,9 +2,16 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.seamew.lottery.infrastructure.dao.IStrategyDetailDao">
 
-    <select id="queryStrategyDetailList" parameterType="java.lang.Long" resultType="com.seamew.lottery.infrastructure.po.StrategyDetail">
-        SELECT id, strategy_id, award_id, award_count, award_surplus_count,
-               award_rate, create_time, update_time
+    <select id="queryStrategyDetailList" parameterType="java.lang.Long"
+            resultType="com.seamew.lottery.infrastructure.po.StrategyDetail">
+        SELECT id,
+               strategy_id,
+               award_id,
+               award_count,
+               award_surplus_count,
+               award_rate,
+               create_time,
+               update_time
         FROM strategy_detail
         WHERE strategy_id = #{strategyId}
     </select>
@@ -12,12 +19,34 @@
     <select id="queryNoStockStrategyAwardList" parameterType="java.lang.Long" resultType="java.lang.String">
         SELECT award_id AS awardId
         FROM strategy_detail
-        WHERE strategy_id = #{strategyId} AND award_surplus_count = 0
+        WHERE strategy_id = #{strategyId}
+          AND award_surplus_count = 0
     </select>
 
     <update id="deductStock" parameterType="com.seamew.lottery.infrastructure.po.StrategyDetail">
-        UPDATE strategy_detail SET award_surplus_count = award_surplus_count - 1
-        WHERE strategy_id = #{strategyId} AND award_id = #{awardId} AND award_surplus_count > 0
+        UPDATE strategy_detail
+        SET award_surplus_count = award_surplus_count - 1
+        WHERE strategy_id = #{strategyId}
+          AND award_id = #{awardId}
+          AND award_surplus_count > 0
     </update>
 
+    <insert id="insertList" parameterType="java.util.List">
+        INSERT INTO strategy_detail(strategy_id, award_id, award_name, award_count, award_surplus_count,
+        award_rate, create_time, update_time)
+        VALUES
+        <foreach collection="list" item="item" index="index" separator=",">
+            (
+            #{item.strategyId},
+            #{item.awardId},
+            #{item.awardName},
+            #{item.awardCount},
+            #{item.awardSurplusCount},
+            #{item.awardRate},
+            NOW(),
+            NOW()
+            )
+        </foreach>
+    </insert>
+
 </mapper>

+ 18 - 4
lottery-interfaces/src/main/resources/mybatis/mapper/Strategy_Mapper.xml

@@ -2,12 +2,26 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.seamew.lottery.infrastructure.dao.IStrategyDao">
 
-    <select id="queryStrategy" parameterType="java.lang.Long" resultType="com.seamew.lottery.infrastructure.po.Strategy">
-        SELECT
-            id, strategy_id, strategy_desc, strategy_mode, grant_type,
-            grant_date, ext_info, create_time, update_time
+    <select id="queryStrategy" parameterType="java.lang.Long"
+            resultType="com.seamew.lottery.infrastructure.po.Strategy">
+        SELECT id,
+               strategy_id,
+               strategy_desc,
+               strategy_mode,
+               grant_type,
+               grant_date,
+               ext_info,
+               create_time,
+               update_time
         FROM strategy
         WHERE strategy_id = #{strategyId}
     </select>
 
+    <insert id="insert" parameterType="com.seamew.lottery.infrastructure.po.Strategy">
+        INSERT INTO strategy(strategy_id, strategy_desc, strategy_mode, grant_type,
+                             grant_date, ext_info, create_time, update_time)
+        VALUES (#{strategyId}, #{strategyDesc}, #{strategyMode}, #{grantType},
+                #{grantDate}, #{extInfo}, NOW(), NOW())
+    </insert>
+
 </mapper>

+ 1 - 1
lottery-interfaces/src/test/java/com/seamew/lottery/test/ApiTest.java

@@ -37,7 +37,7 @@ public class ApiTest {
         //
         // activityDao.insert(activity);
 
-        Activity activity = activityDao.queryActivityById(100002L);
+        Activity activity = activityDao.queryActivityById(100001L);
         System.out.println(activity);
     }
 

+ 178 - 0
lottery-interfaces/src/test/java/com/seamew/lottery/test/domain/ActivityTest.java

@@ -0,0 +1,178 @@
+package com.seamew.lottery.test.domain;
+
+import com.alibaba.fastjson2.JSON;
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.activity.model.aggregates.ActivityConfigRich;
+import com.seamew.lottery.domain.activity.model.req.ActivityConfigReq;
+import com.seamew.lottery.domain.activity.model.vo.ActivityVO;
+import com.seamew.lottery.domain.activity.model.vo.AwardVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyDetailVO;
+import com.seamew.lottery.domain.activity.model.vo.StrategyVO;
+import com.seamew.lottery.domain.activity.service.deploy.IActivityDeploy;
+import com.seamew.lottery.domain.activity.service.stateflow.IStateHandler;
+import com.seamew.lottery.infrastructure.dao.IAwardDao;
+import com.seamew.lottery.infrastructure.po.Award;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Before;
+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;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author: seamew
+ * @Title: ActivityTest
+ * @CreateTime: 2023年02月15日 21:25:00
+ * @Description: 活动领域测试
+ * @Version: 1.0
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@Slf4j
+public class ActivityTest {
+    @Resource
+    private IStateHandler stateHandler;
+
+    @Resource
+    private IActivityDeploy activityDeploy;
+
+
+    private ActivityConfigRich activityConfigRich;
+
+    /**
+     * TODO:后面编写ID生成策略
+     */
+    private Long activityId = 120981321L;
+
+
+
+    @Test
+    public void test_alterState() {
+        log.info("提交审核,测试:{}", JSON.toJSONString(stateHandler.arraignment(100001L, Constants.ActivityState.EDIT)));
+        log.info("审核通过,测试:{}", JSON.toJSONString(stateHandler.checkPass(100001L, Constants.ActivityState.ARRAIGNMENT)));
+        log.info("运行活动,测试:{}", JSON.toJSONString(stateHandler.doing(100001L, Constants.ActivityState.PASS)));
+        log.info("二次提审,测试:{}", JSON.toJSONString(stateHandler.checkPass(100001L, Constants.ActivityState.EDIT)));
+    }
+
+    @Before
+    public void init() {
+
+        ActivityVO activity = new ActivityVO();
+        activity.setActivityId(activityId);
+        activity.setActivityName("测试活动");
+        activity.setActivityDesc("测试活动描述");
+        activity.setBeginDateTime(new Date());
+        activity.setEndDateTime(new Date());
+        activity.setStockCount(100);
+        activity.setTakeCount(10);
+        activity.setState(Constants.ActivityState.EDIT.getCode());
+        activity.setCreator("seamew");
+
+        StrategyVO strategy = new StrategyVO();
+        strategy.setStrategyId(10002L);
+        strategy.setStrategyDesc("抽奖策略");
+        strategy.setStrategyMode(Constants.StrategyMode.SINGLE.getCode());
+        strategy.setGrantType(1);
+        strategy.setGrantDate(new Date());
+        strategy.setExtInfo("");
+
+        StrategyDetailVO strategyDetail_01 = new StrategyDetailVO();
+        strategyDetail_01.setStrategyId(strategy.getStrategyId());
+        strategyDetail_01.setAwardId("101");
+        strategyDetail_01.setAwardName("一等奖");
+        strategyDetail_01.setAwardCount(10);
+        strategyDetail_01.setAwardSurplusCount(10);
+        strategyDetail_01.setAwardRate(new BigDecimal("0.05"));
+
+        StrategyDetailVO strategyDetail_02 = new StrategyDetailVO();
+        strategyDetail_02.setStrategyId(strategy.getStrategyId());
+        strategyDetail_02.setAwardId("102");
+        strategyDetail_02.setAwardName("二等奖");
+        strategyDetail_02.setAwardCount(20);
+        strategyDetail_02.setAwardSurplusCount(20);
+        strategyDetail_02.setAwardRate(new BigDecimal("0.15"));
+
+        StrategyDetailVO strategyDetail_03 = new StrategyDetailVO();
+        strategyDetail_03.setStrategyId(strategy.getStrategyId());
+        strategyDetail_03.setAwardId("103");
+        strategyDetail_03.setAwardName("三等奖");
+        strategyDetail_03.setAwardCount(50);
+        strategyDetail_03.setAwardSurplusCount(50);
+        strategyDetail_03.setAwardRate(new BigDecimal("0.20"));
+
+        StrategyDetailVO strategyDetail_04 = new StrategyDetailVO();
+        strategyDetail_04.setStrategyId(strategy.getStrategyId());
+        strategyDetail_04.setAwardId("104");
+        strategyDetail_04.setAwardName("四等奖");
+        strategyDetail_04.setAwardCount(100);
+        strategyDetail_04.setAwardSurplusCount(100);
+        strategyDetail_04.setAwardRate(new BigDecimal("0.25"));
+
+        StrategyDetailVO strategyDetail_05 = new StrategyDetailVO();
+        strategyDetail_05.setStrategyId(strategy.getStrategyId());
+        strategyDetail_05.setAwardId("104");
+        strategyDetail_05.setAwardName("五等奖");
+        strategyDetail_05.setAwardCount(500);
+        strategyDetail_05.setAwardSurplusCount(500);
+        strategyDetail_05.setAwardRate(new BigDecimal("0.35"));
+
+        List<StrategyDetailVO> strategyDetailList = new ArrayList<>();
+        strategyDetailList.add(strategyDetail_01);
+        strategyDetailList.add(strategyDetail_02);
+        strategyDetailList.add(strategyDetail_03);
+        strategyDetailList.add(strategyDetail_04);
+        strategyDetailList.add(strategyDetail_05);
+
+        strategy.setStrategyDetailList(strategyDetailList);
+
+        AwardVO award_01 = new AwardVO();
+        award_01.setAwardId("101");
+        award_01.setAwardType(Constants.AwardType.DESC.getCode());
+        award_01.setAwardName("电脑");
+        award_01.setAwardContent("请联系活动组织者 admin");
+
+        AwardVO award_02 = new AwardVO();
+        award_02.setAwardId("102");
+        award_02.setAwardType(Constants.AwardType.DESC.getCode());
+        award_02.setAwardName("手机");
+        award_02.setAwardContent("请联系活动组织者 admin");
+
+        AwardVO award_03 = new AwardVO();
+        award_03.setAwardId("103");
+        award_03.setAwardType(Constants.AwardType.DESC.getCode());
+        award_03.setAwardName("平板");
+        award_03.setAwardContent("请联系活动组织者 admin");
+
+        AwardVO award_04 = new AwardVO();
+        award_04.setAwardId("104");
+        award_04.setAwardType(Constants.AwardType.DESC.getCode());
+        award_04.setAwardName("耳机");
+        award_04.setAwardContent("请联系活动组织者 admin");
+
+        AwardVO award_05 = new AwardVO();
+        award_05.setAwardId("105");
+        award_05.setAwardType(Constants.AwardType.DESC.getCode());
+        award_05.setAwardName("数据线");
+        award_05.setAwardContent("请联系活动组织者 admin");
+
+        List<AwardVO> awardList = new ArrayList<>();
+        awardList.add(award_01);
+        awardList.add(award_02);
+        awardList.add(award_03);
+        awardList.add(award_04);
+        awardList.add(award_05);
+
+        activityConfigRich = new ActivityConfigRich(activity, strategy, awardList);
+    }
+
+    @Test
+    public void test_createActivity() {
+        activityDeploy.createActivity(new ActivityConfigReq(activityId, activityConfigRich));
+    }
+}

+ 4 - 0
pom.xml

@@ -37,6 +37,10 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
     </dependencies>
 
     <dependencyManagement>