From e7bbddfddae04195d3c87a58964598cee119181f Mon Sep 17 00:00:00 2001 From: 13233904609 <13233904609@163.cm> Date: Thu, 18 Jul 2024 15:23:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=BD=E5=A5=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/enums/ErrorCodeConstants.java | 6 + .../admin/prizedraw/PrizeDrawController.java | 121 ++++++++++++ .../prizedraw/vo/PrizeDrawPageReqVO.java | 49 +++++ .../admin/prizedraw/vo/PrizeDrawRespVO.java | 61 ++++++ .../prizedraw/vo/PrizeDrawSaveReqVO.java | 46 +++++ .../admin/prizelog/PrizeLogController.java | 115 +++++++++++ .../admin/prizelog/vo/PrizeLogPageReqVO.java | 49 +++++ .../admin/prizelog/vo/PrizeLogRespVO.java | 67 +++++++ .../admin/prizelog/vo/PrizeLogSaveReqVO.java | 42 ++++ .../app/prizedraw/AppPrizeDrawController.java | 180 ++++++++++++++++++ .../prizedraw/vo/AppPrizeDrawPageReqVO.java | 52 +++++ .../app/prizedraw/vo/AppPrizeDrawRespVO.java | 54 ++++++ .../prizedraw/vo/AppPrizeDrawSaveReqVO.java | 44 +++++ .../convert/prizedraw/PrizeDrawConvert.java | 36 ++++ .../convert/prizelog/PrizeLogConvert.java | 42 ++++ .../dataobject/prizedraw/ActivityPrizeDO.java | 55 ++++++ .../dal/dataobject/prizedraw/PrizeDrawDO.java | 61 ++++++ .../dal/dataobject/prizelog/PrizeLogDO.java | 67 +++++++ .../mysql/prizedraw/ActivityPrizeMapper.java | 28 +++ .../dal/mysql/prizedraw/PrizeDrawMapper.java | 32 ++++ .../dal/mysql/prizelog/PrizeLogMapper.java | 34 ++++ .../service/prizedraw/PrizeDrawService.java | 104 ++++++++++ .../prizedraw/PrizeDrawServiceImpl.java | 136 +++++++++++++ .../service/prizelog/PrizeLogService.java | 81 ++++++++ .../service/prizelog/PrizeLogServiceImpl.java | 103 ++++++++++ .../mapper/prizedraw/PrizeDrawMapper.xml | 12 ++ .../mapper/prizelog/PrizeLogMapper.xml | 12 ++ .../prizedraw/PrizeDrawServiceImplTest.java | 154 +++++++++++++++ .../prizelog/PrizeLogServiceImplTest.java | 162 ++++++++++++++++ .../src/test/resources/sql/clean.sql | 4 +- .../src/test/resources/sql/create_tables.sql | 37 +++- .../app/order/AppTradeOrderController.java | 6 + .../member/api/level/MemberLevelApi.java | 10 + .../module/member/api/user/MemberUserApi.java | 15 ++ .../member/api/level/MemberLevelApiImpl.java | 9 + .../member/api/user/MemberUserApiImpl.java | 11 ++ .../admin/demo/PayDemoOrderController.java | 3 + 37 files changed, 2098 insertions(+), 2 deletions(-) create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java create mode 100644 ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index 3b19d61..a0cb259 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -124,5 +124,11 @@ public interface ErrorCodeConstants { // ========== 装修页面 1-013-018-000 ========== ErrorCode DIY_PAGE_NOT_EXISTS = new ErrorCode(1_013_018_000, "装修页面不存在"); ErrorCode DIY_PAGE_NAME_USED = new ErrorCode(1_013_018_001, "装修页面名称({})已经被使用"); + ErrorCode PRIZE_DRAW_NOT_EXISTS = new ErrorCode(1_013_018_002, "抽奖活动不存在"); + ErrorCode PRIZE_DRAW_NOT_START = new ErrorCode(1_013_018_003, "抽奖活动暂未开启"); + ErrorCode PRIZE_DRAW_NOT_TIME = new ErrorCode(1_013_018_004, "抽奖活动未开始或已过期"); + ErrorCode PRIZE_LOG_NOT_EXISTS = new ErrorCode(1_013_018_005, "抽奖记录不存在"); + ErrorCode PRIZE_LOG_NOT_DRAWNUM = new ErrorCode(1_013_018_006, "抽奖次数已达上限"); + ErrorCode PRIZE_LOG_NOT_LEVEL = new ErrorCode(1_013_018_007, "分销等级不在权限范围"); } diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java new file mode 100644 index 0000000..79230eb --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/PrizeDrawController.java @@ -0,0 +1,121 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw; + +import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; +import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.convert.prizedraw.PrizeDrawConvert; +import cn.iocoder.yudao.module.promotion.convert.prizelog.PrizeLogConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.service.prizedraw.PrizeDrawService; + +@Tag(name = "管理后台 - 抽奖活动") +@RestController +@RequestMapping("/promotion/prize-draw") +@Validated +public class PrizeDrawController { + + @Resource + private PrizeDrawService prizeDrawService; + + @Resource + private MemberLevelApi memberLevelApi; + + @PostMapping("/create") + @Operation(summary = "创建抽奖活动") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:create')") + public CommonResult createPrizeDraw(@Valid @RequestBody PrizeDrawSaveReqVO createReqVO) { + return success(prizeDrawService.createPrizeDraw(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新抽奖活动") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:update')") + public CommonResult updatePrizeDraw(@Valid @RequestBody PrizeDrawSaveReqVO updateReqVO) { + prizeDrawService.updatePrizeDraw(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除抽奖活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:delete')") + public CommonResult deletePrizeDraw(@RequestParam("id") Long id) { + prizeDrawService.deletePrizeDraw(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得抽奖活动") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:query')") + public CommonResult getPrizeDraw(@RequestParam("id") Long id) { + PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(id); + return success(BeanUtils.toBean(prizeDraw, PrizeDrawRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得抽奖活动分页") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:query')") + public CommonResult> getPrizeDrawPage(@Valid PrizeDrawPageReqVO pageReqVO) { + PageResult pageResult = prizeDrawService.getPrizeDrawPage(pageReqVO); + // 处理用户级别返显 + List levels = memberLevelApi.getLevelList( + convertSet(pageResult.getList(), PrizeDrawDO::getMebLevel)); + return success(PrizeDrawConvert.INSTANCE.convertPage(pageResult, levels)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出抽奖活动 Excel") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportPrizeDrawExcel(@Valid PrizeDrawPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = prizeDrawService.getPrizeDrawPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "抽奖活动.xls", "数据", PrizeDrawRespVO.class, + BeanUtils.toBean(list, PrizeDrawRespVO.class)); + } + + // ==================== 子表(抽奖活动奖品) ==================== + + @GetMapping("/activity-prize/list-by-activity-id") + @Operation(summary = "获得抽奖活动奖品列表") + @Parameter(name = "activityId", description = "关联抽奖活动id") + @PreAuthorize("@ss.hasPermission('promotion:prize-draw:query')") + public CommonResult> getActivityPrizeListByActivityId(@RequestParam("activityId") Long activityId) { + return success(prizeDrawService.getActivityPrizeListByActivityId(activityId)); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java new file mode 100644 index 0000000..3b2a278 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawPageReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 抽奖活动分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PrizeDrawPageReqVO extends PageParam { + + @Schema(description = "活动名称", example = "李四") + private String name; + + @Schema(description = "活动规则") + private String activityRule; + + @Schema(description = "活动状态(0:开启;1关闭)", example = "1") + private String status; + + @Schema(description = "开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] startTime; + + @Schema(description = "截至时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] endTime; + + @Schema(description = "会员等级") + private Integer mebLevel; + + /** + * 单人次抽奖次数 + */ + @Schema(description = "单人次抽奖次数") + private Integer drawNum; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java new file mode 100644 index 0000000..465d5e0 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawRespVO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 抽奖活动 Response VO") +@Data +@ExcelIgnoreUnannotated +public class PrizeDrawRespVO { + + @Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166") + @ExcelProperty("id主键") + private Long id; + + @Schema(description = "活动名称", example = "李四") + @ExcelProperty("活动名称") + private String name; + + @Schema(description = "活动规则") + @ExcelProperty("活动规则") + private String activityRule; + + @Schema(description = "活动状态(0:开启;1关闭)", example = "1") + @ExcelProperty("活动状态(0:开启;1关闭)") + private String status; + + @Schema(description = "开始时间") + @ExcelProperty("开始时间") + private LocalDateTime startTime; + + @Schema(description = "截至时间") + @ExcelProperty("截至时间") + private LocalDateTime endTime; + + @Schema(description = "会员等级") + @ExcelProperty("会员等级") + private Long mebLevel; + + /** + * 单人次抽奖次数 + */ + @Schema(description = "单人次抽奖次数") + @ExcelProperty("单人次抽奖次数") + private Integer drawNum; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + /** + * 会员等级名称 + */ + @Schema(description = "会员等级名称") + @ExcelProperty("会员等级名称") + private String levelName; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java new file mode 100644 index 0000000..5165284 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizedraw/vo/PrizeDrawSaveReqVO.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 抽奖活动新增/修改 Request VO") +@Data +public class PrizeDrawSaveReqVO { + + @Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166") + private Long id; + + @Schema(description = "活动名称", example = "李四") + private String name; + + @Schema(description = "活动规则") + private String activityRule; + + @Schema(description = "活动状态(0:开启;1关闭)", example = "1") + private String status; + + @Schema(description = "开始时间") + private LocalDateTime startTime; + + @Schema(description = "截至时间") + private LocalDateTime endTime; + + @Schema(description = "会员等级") + private Integer mebLevel; + + /** + * 单人次抽奖次数 + */ + @Schema(description = "单人次抽奖次数") + private Integer drawNum; + + @Schema(description = "抽奖活动奖品列表") + private List activityPrizes; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java new file mode 100644 index 0000000..acf265f --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/PrizeLogController.java @@ -0,0 +1,115 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizelog; + +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.convert.bargain.BargainHelpConvert; +import cn.iocoder.yudao.module.promotion.convert.prizelog.PrizeLogConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.service.prizedraw.PrizeDrawService; +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import cn.iocoder.yudao.module.promotion.service.prizelog.PrizeLogService; + +@Tag(name = "管理后台 - 抽奖记录") +@RestController +@RequestMapping("/promotion/prize-log") +@Validated +public class PrizeLogController { + + @Resource + private PrizeLogService prizeLogService; + + @Resource + private MemberUserApi memberUserApi; + + @Resource + private PrizeDrawService prizeDrawService; + + @PostMapping("/create") + @Operation(summary = "创建抽奖记录") + @PreAuthorize("@ss.hasPermission('promotion:prize-log:create')") + public CommonResult createPrizeLog(@Valid @RequestBody PrizeLogSaveReqVO createReqVO) { + return success(prizeLogService.createPrizeLog(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新抽奖记录") + @PreAuthorize("@ss.hasPermission('promotion:prize-log:update')") + public CommonResult updatePrizeLog(@Valid @RequestBody PrizeLogSaveReqVO updateReqVO) { + prizeLogService.updatePrizeLog(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除抽奖记录") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:prize-log:delete')") + public CommonResult deletePrizeLog(@RequestParam("id") Long id) { + prizeLogService.deletePrizeLog(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得抽奖记录") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:prize-log:query')") + public CommonResult getPrizeLog(@RequestParam("id") Long id) { + PrizeLogDO prizeLog = prizeLogService.getPrizeLog(id); + return success(BeanUtils.toBean(prizeLog, PrizeLogRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得抽奖记录分页") + @PreAuthorize("@ss.hasPermission('promotion:prize-log:query')") + public CommonResult> getPrizeLogPage(@Valid PrizeLogPageReqVO pageReqVO) { + PageResult pageResult = prizeLogService.getPrizeLogPage(pageReqVO); + // 拼接用户数据 + Map userMap = memberUserApi.getUserMap( + convertSet(pageResult.getList(), PrizeLogDO::getMebId)); + // 拼接活动数据 + Map prizeMap = prizeDrawService.getPrizeDrawMap( + convertSet(pageResult.getList(), PrizeLogDO::getActivityId)); + return success(PrizeLogConvert.INSTANCE.convertPage(pageResult, userMap,prizeMap)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出抽奖记录 Excel") + @PreAuthorize("@ss.hasPermission('promotion:prize-log:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportPrizeLogExcel(@Valid PrizeLogPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = prizeLogService.getPrizeLogPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "抽奖记录.xls", "数据", PrizeLogRespVO.class, + BeanUtils.toBean(list, PrizeLogRespVO.class)); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java new file mode 100644 index 0000000..7db8eca --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogPageReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 抽奖记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PrizeLogPageReqVO extends PageParam { + + @Schema(description = "会员id", example = "26219") + private Long mebId; + + @Schema(description = "关联抽奖活动id", example = "17850") + private Long activityId; + + @Schema(description = "奖品id", example = "17850") + private Long prizeId; + + @Schema(description = "奖品名称", example = "李四") + private String name; + + @Schema(description = "奖品图片路径", example = "https://www.iocoder.cn") + private String imgUrl; + + @Schema(description = "获奖人数上限") + private Integer winNum; + + @Schema(description = "获奖概率") + private String prizeChance; + + @Schema(description = "获奖金额") + private String prizePoolAmount; + + @Schema(description = "兑奖状态(0:已兑奖;1:未兑奖)", example = "2") + private String status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java new file mode 100644 index 0000000..63aee16 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogRespVO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 抽奖记录 Response VO") +@Data +@ExcelIgnoreUnannotated +public class PrizeLogRespVO { + + @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "5655") + @ExcelProperty("主键id") + private Long id; + + @Schema(description = "会员id", example = "26219") + @ExcelProperty("会员id") + private Long mebId; + + @Schema(description = "关联抽奖活动id", example = "17850") + @ExcelProperty("关联抽奖活动id") + private Long activityId; + + @Schema(description = "奖品id", example = "17850") + @ExcelProperty("奖品id") + private Long prizeId; + + @Schema(description = "奖品名称", example = "李四") + @ExcelProperty("奖品名称") + private String name; + + @Schema(description = "奖品图片路径", example = "https://www.iocoder.cn") + @ExcelProperty("奖品图片路径") + private String imgUrl; + + @Schema(description = "获奖人数上限") + @ExcelProperty("获奖人数上限") + private Integer winNum; + + @Schema(description = "获奖概率") + @ExcelProperty("获奖概率") + private String prizeChance; + + @Schema(description = "获奖金额") + @ExcelProperty("获奖金额") + private String prizePoolAmount; + + @Schema(description = "兑奖状态(0:已兑奖;1:未兑奖)", example = "2") + @ExcelProperty("兑奖状态(0:已兑奖;1:未兑奖)") + private String status; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + // ========== 用户相关 ========== + + @Schema(description = "用户昵称", example = "老芋艿") + private String nickname; + + @Schema(description = "活动名称", example = "老芋艿") + private String activityName; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java new file mode 100644 index 0000000..1fc8442 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/prizelog/vo/PrizeLogSaveReqVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 抽奖记录新增/修改 Request VO") +@Data +public class PrizeLogSaveReqVO { + + @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "5655") + private Long id; + + @Schema(description = "会员id", example = "26219") + private Long mebId; + + @Schema(description = "关联抽奖活动id", example = "17850") + private Long activityId; + + @Schema(description = "奖品id", example = "17850") + private Long prizeId; + + @Schema(description = "奖品名称", example = "李四") + private String name; + + @Schema(description = "奖品图片路径", example = "https://www.iocoder.cn") + private String imgUrl; + + @Schema(description = "获奖人数上限") + private Integer winNum; + + @Schema(description = "获奖概率") + private String prizeChance; + + @Schema(description = "获奖金额") + private String prizePoolAmount; + + @Schema(description = "兑奖状态(0:已兑奖;1:未兑奖)", example = "2") + private String status; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java new file mode 100644 index 0000000..d5fa9c4 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/AppPrizeDrawController.java @@ -0,0 +1,180 @@ +package cn.iocoder.yudao.module.promotion.controller.app.prizedraw; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.WeightRandom; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; +import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogSaveReqVO; +import cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo.AppPrizeDrawRespVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import cn.iocoder.yudao.module.promotion.service.prizedraw.PrizeDrawService; +import cn.iocoder.yudao.module.promotion.service.prizelog.PrizeLogService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; + +@Tag(name = "用户APP - 抽奖活动") +@RestController +@RequestMapping("/promotion/prize-draw") +@Validated +public class AppPrizeDrawController { + + @Resource + private PrizeDrawService prizeDrawService; + + @Resource + private PrizeLogService prizeLogService; + + @Resource + private RedissonClient redissonClient; + + @Resource + private MemberUserApi memberUserApi; + + @Resource + private MemberLevelApi memberLevelApi; + + @GetMapping("/getOne") + @Operation(summary = "用户APP--获得抽奖活动规则") + public CommonResult getPrizeDraw() { + PrizeDrawDO prizeDraw = prizeDrawService.getOnePrizeDraw(); + if (prizeDraw == null) {//抽奖活动不存在 + throw exception(PRIZE_DRAW_NOT_EXISTS); + } + return success(BeanUtils.toBean(prizeDraw, AppPrizeDrawRespVO.class)); + } + @GetMapping("/activity-prize/list-by-activity-id") + @Operation(summary = "用户APP--获得抽奖活动奖品列表") + @Parameter(name = "activityId", description = "关联抽奖活动id") + public CommonResult> getActivityPrizeListByActivityId(@RequestParam("activityId") Long activityId) { + return success(prizeDrawService.getActivityPrizeListByActivityId(activityId)); + } + @GetMapping("/lottery") + @Operation(summary = "用户APP--抽奖") + @Parameter(name = "activityId", description = "关联抽奖活动id") + public CommonResult lottery(@RequestParam("activityId") Long activityId) { + //获取用户id + Long loginUserId = getLoginUserId(); + //查询用户信息 + MemberUserRespDTO user = memberUserApi.getUser(loginUserId); + //用户不存在 + if(user == null){ + throw exception(USER_NOT_EXISTS); + } + //获取活动信息 + PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(activityId); + if (prizeDraw == null) {//抽奖活动不存在 + throw exception(PRIZE_DRAW_NOT_EXISTS); + } + //判断活动状态 + if(!ObjectUtil.equal(prizeDraw.getStatus(),"0")){ + throw exception(PRIZE_DRAW_NOT_START); + } + //判断抽奖活动时间范围 + if(!DateUtil.isIn(new Date(),DateUtils.of(prizeDraw.getStartTime()),DateUtils.of(prizeDraw.getEndTime()))){ + throw exception(PRIZE_DRAW_NOT_TIME); + } + //判断抽奖活动会员等级 + MemberLevelRespDTO memberLevel = memberLevelApi.getMemberLevel(user.getLevelId()); + MemberLevelRespDTO activityLevel = memberLevelApi.getMemberLevel(Long.valueOf(prizeDraw.getMebLevel())); + if(memberLevel.getLevel()=prizeDraw.getDrawNum()){ + throw exception(PRIZE_LOG_NOT_DRAWNUM); + } + //抽奖 + ActivityPrizeDO activityPrizeDO = recursionLottery(prizeDraw); + return success(activityPrizeDO); + } + + private ActivityPrizeDO recursionLottery(PrizeDrawDO prizeDraw){ + //获取奖品信息 + List list = prizeDrawService.getActivityPrizeListByActivityId(prizeDraw.getId()); + //获取随机数 + int sortNum = (int) (Math.random() * ((8-list.size()) + 1)); + // TODO: 2023/8/16 0016 后台限制 + List> weightObjList = new ArrayList>(); + list.forEach(s -> { + weightObjList.add(new WeightRandom.WeightObj<>(s.getId().toString(), Double.valueOf(s.getPrizeChance()))); + }); + WeightRandom wr = RandomUtil.weightRandom(weightObjList); + String str = wr.next(); + RLock lock = redissonClient.getLock(str); + try { + if (lock.tryLock(1000, 10000, TimeUnit.MILLISECONDS)) { + ActivityPrizeDO activityPrize = prizeDrawService.getActivityPrize(Long.valueOf(str)); + //判断被抽中次数 + Long prizeLogNum = prizeLogService.getPrizeLogList(prizeDraw, activityPrize.getId()); + if (prizeLogNum >= activityPrize.getWinNum()) { + recursionLottery(prizeDraw); + } + //中奖 + //添加抽奖记录 + PrizeLogSaveReqVO createReqVO = new PrizeLogSaveReqVO(); + createReqVO.setMebId(getLoginUserId()); + createReqVO.setActivityId(prizeDraw.getId()); + createReqVO.setPrizeId(activityPrize.getId()); + createReqVO.setName(activityPrize.getName()); + createReqVO.setImgUrl(activityPrize.getImgUrl()); + createReqVO.setWinNum(activityPrize.getWinNum()); + createReqVO.setPrizeChance(activityPrize.getPrizeChance()); + createReqVO.setPrizePoolAmount(activityPrize.getPrizePoolAmount()); + createReqVO.setStatus("1"); + prizeLogService.createPrizeLog(createReqVO); + return activityPrize; + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + if (ObjectUtil.isNotEmpty(lock)){ + lock.unlock(); + } + } + return null; + } + + @GetMapping("/getMyPrizeLogDO") + @Operation(summary = "获得我的抽奖记录") + public CommonResult> getPrizeLogPage(@RequestParam("activityId") Long activityId) { + //获取活动信息 + PrizeDrawDO prizeDraw = prizeDrawService.getPrizeDraw(activityId); + List list = prizeLogService.getPrizeLogListByMebId(getLoginUserId(), prizeDraw); + return success(BeanUtils.toBean(list, PrizeLogRespVO.class)); + } +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java new file mode 100644 index 0000000..9116361 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawPageReqVO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "应用 App - 抽奖活动分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppPrizeDrawPageReqVO extends PageParam { + + @Schema(description = "活动名称", example = "李四") + private String name; + + @Schema(description = "活动规则") + private String activityRule; + + @Schema(description = "活动状态(0:开启;1关闭)", example = "1") + private String status; + + @Schema(description = "开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] startTime; + + @Schema(description = "截至时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] endTime; + + @Schema(description = "会员等级") + private Integer mebLevel; + + /** + * 单人次抽奖次数 + */ + @Schema(description = "单人次抽奖次数") + @ExcelProperty("单人次抽奖次数") + private Integer drawNum; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java new file mode 100644 index 0000000..b9cfbbf --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawRespVO.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "应用 App - 抽奖活动 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AppPrizeDrawRespVO { + + @Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166") + @ExcelProperty("id主键") + private Long id; + + @Schema(description = "活动名称", example = "李四") + @ExcelProperty("活动名称") + private String name; + + @Schema(description = "活动规则") + @ExcelProperty("活动规则") + private String activityRule; + + @Schema(description = "活动状态(0:开启;1关闭)", example = "1") + @ExcelProperty("活动状态(0:开启;1关闭)") + private String status; + + @Schema(description = "开始时间") + @ExcelProperty("开始时间") + private LocalDateTime startTime; + + @Schema(description = "截至时间") + @ExcelProperty("截至时间") + private LocalDateTime endTime; + + @Schema(description = "会员等级") + @ExcelProperty("会员等级") + private Integer mebLevel; + + /** + * 单人次抽奖次数 + */ + @Schema(description = "单人次抽奖次数") + @ExcelProperty("单人次抽奖次数") + private Integer drawNum; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java new file mode 100644 index 0000000..fab22fa --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/prizedraw/vo/AppPrizeDrawSaveReqVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "应用 App - 抽奖活动新增/修改 Request VO") +@Data +public class AppPrizeDrawSaveReqVO { + + @Schema(description = "id主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1166") + private Long id; + + @Schema(description = "活动名称", example = "李四") + private String name; + + @Schema(description = "活动规则") + private String activityRule; + + @Schema(description = "活动状态(0:开启;1关闭)", example = "1") + private String status; + + @Schema(description = "开始时间") + private LocalDateTime startTime; + + @Schema(description = "截至时间") + private LocalDateTime endTime; + + @Schema(description = "会员等级") + private Integer mebLevel; + + /** + * 单人次抽奖次数 + */ + @Schema(description = "单人次抽奖次数") + private Integer drawNum; + + @Schema(description = "抽奖活动奖品列表") + private List activityPrizes; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java new file mode 100644 index 0000000..952c582 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizedraw/PrizeDrawConvert.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.promotion.convert.prizedraw; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.PrizeDrawRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogRespVO; +import cn.iocoder.yudao.module.promotion.convert.prizelog.PrizeLogConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +@Mapper +public interface PrizeDrawConvert { + PrizeDrawConvert INSTANCE = Mappers.getMapper(PrizeDrawConvert.class); + + default PageResult convertPage(PageResult page, + List levels) { + PageResult pageResult = convertPage(page); + Map levelMap = convertMap(levels, MemberLevelRespDTO::getId, MemberLevelRespDTO::getName); + // 拼接数据 + pageResult.getList().forEach(record ->{ + MapUtils.findAndThen(levelMap, record.getMebLevel(), + level -> record.setLevelName(levelMap.get(record.getMebLevel()))); + }); + return pageResult; + } + PageResult convertPage(PageResult page); +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java new file mode 100644 index 0000000..58e3819 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/prizelog/PrizeLogConvert.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.promotion.convert.prizelog; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help.BargainHelpRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.PrizeLogRespVO; +import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.help.AppBargainHelpRespVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * 抽奖记录 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface PrizeLogConvert { + + PrizeLogConvert INSTANCE = Mappers.getMapper(PrizeLogConvert.class); + + default PageResult convertPage(PageResult page, + Map userMap, + Map prizeMap) { + PageResult pageResult = convertPage(page); + // 拼接数据 + pageResult.getList().forEach(record ->{ + MapUtils.findAndThen(userMap, record.getMebId(), + user -> record.setNickname(user.getNickname())); + MapUtils.findAndThen(prizeMap, record.getActivityId(), + activity -> record.setActivityName(activity.getName())); + }); + return pageResult; + } + PageResult convertPage(PageResult page); +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java new file mode 100644 index 0000000..9fc93f6 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/ActivityPrizeDO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 抽奖活动奖品 DO + * + * @author 芋道源码 + */ +@TableName("promotion_activity_prize") +@KeySequence("promotion_activity_prize_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ActivityPrizeDO extends BaseDO { + + /** + * id主键 + */ + @TableId + private Long id; + /** + * 关联抽奖活动id + */ + private Long activityId; + /** + * 奖品名称 + */ + private String name; + /** + * 奖品图片路径 + */ + private String imgUrl; + /** + * 获奖人数上限 + */ + private Integer winNum; + /** + * 获奖概率 + */ + private String prizeChance; + /** + * 获奖金额 + */ + private String prizePoolAmount; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java new file mode 100644 index 0000000..5d755e8 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizedraw/PrizeDrawDO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 抽奖活动 DO + * + * @author 芋道源码 + */ +@TableName("promotion_prize_draw") +@KeySequence("promotion_prize_draw_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PrizeDrawDO extends BaseDO { + + /** + * id主键 + */ + @TableId + private Long id; + /** + * 活动名称 + */ + private String name; + /** + * 活动规则 + */ + private String activityRule; + /** + * 活动状态(0:开启;1关闭) + */ + private String status; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 截至时间 + */ + private LocalDateTime endTime; + /** + * 会员等级 + */ + private Long mebLevel; + + /** + * 单人次抽奖次数 + */ + private Integer drawNum; +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java new file mode 100644 index 0000000..a543db0 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/prizelog/PrizeLogDO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 抽奖记录 DO + * + * @author 芋道源码 + */ +@TableName("promotion_prize_log") +@KeySequence("promotion_prize_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PrizeLogDO extends BaseDO { + + /** + * 主键id + */ + @TableId + private Long id; + /** + * 会员id + */ + private Long mebId; + /** + * 关联抽奖活动id + */ + private Long activityId; + /** + * 奖品id + */ + private Long prizeId; + /** + * 奖品名称 + */ + private String name; + /** + * 奖品图片路径 + */ + private String imgUrl; + /** + * 获奖人数上限 + */ + private Integer winNum; + /** + * 获奖概率 + */ + private String prizeChance; + /** + * 获奖金额 + */ + private String prizePoolAmount; + /** + * 兑奖状态(0:已兑奖;1:未兑奖) + */ + private String status; + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java new file mode 100644 index 0000000..67830a5 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/ActivityPrizeMapper.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 抽奖活动奖品 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface ActivityPrizeMapper extends BaseMapperX { + + default List selectListByActivityId(Long activityId) { + return selectList(ActivityPrizeDO::getActivityId, activityId); + } + + default int deleteByActivityId(Long activityId) { + return delete(ActivityPrizeDO::getActivityId, activityId); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java new file mode 100644 index 0000000..7b0f8d9 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizedraw/PrizeDrawMapper.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*; + +/** + * 抽奖活动 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface PrizeDrawMapper extends BaseMapperX { + + default PageResult selectPage(PrizeDrawPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(PrizeDrawDO::getName, reqVO.getName()) + .eqIfPresent(PrizeDrawDO::getActivityRule, reqVO.getActivityRule()) + .eqIfPresent(PrizeDrawDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(PrizeDrawDO::getStartTime, reqVO.getStartTime()) + .betweenIfPresent(PrizeDrawDO::getEndTime, reqVO.getEndTime()) + .eqIfPresent(PrizeDrawDO::getMebLevel, reqVO.getMebLevel()) + .betweenIfPresent(PrizeDrawDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(PrizeDrawDO::getId)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java new file mode 100644 index 0000000..650d62e --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/prizelog/PrizeLogMapper.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.prizelog; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*; + +/** + * 抽奖记录 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface PrizeLogMapper extends BaseMapperX { + + default PageResult selectPage(PrizeLogPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(PrizeLogDO::getMebId, reqVO.getMebId()) + .eqIfPresent(PrizeLogDO::getActivityId, reqVO.getActivityId()) + .likeIfPresent(PrizeLogDO::getName, reqVO.getName()) + .eqIfPresent(PrizeLogDO::getImgUrl, reqVO.getImgUrl()) + .eqIfPresent(PrizeLogDO::getWinNum, reqVO.getWinNum()) + .eqIfPresent(PrizeLogDO::getPrizeChance, reqVO.getPrizeChance()) + .eqIfPresent(PrizeLogDO::getPrizePoolAmount, reqVO.getPrizePoolAmount()) + .eqIfPresent(PrizeLogDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(PrizeLogDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(PrizeLogDO::getId)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java new file mode 100644 index 0000000..e57e2b8 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawService.java @@ -0,0 +1,104 @@ +package cn.iocoder.yudao.module.promotion.service.prizedraw; + +import java.util.*; +import javax.validation.*; + +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*; +import cn.iocoder.yudao.module.promotion.controller.app.prizedraw.vo.AppPrizeDrawRespVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +/** + * 抽奖活动 Service 接口 + * + * @author 芋道源码 + */ +public interface PrizeDrawService { + + /** + * 创建抽奖活动 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createPrizeDraw(@Valid PrizeDrawSaveReqVO createReqVO); + + /** + * 更新抽奖活动 + * + * @param updateReqVO 更新信息 + */ + void updatePrizeDraw(@Valid PrizeDrawSaveReqVO updateReqVO); + + /** + * 删除抽奖活动 + * + * @param id 编号 + */ + void deletePrizeDraw(Long id); + + /** + * 获得抽奖活动 + * + * @param id 编号 + * @return 抽奖活动 + */ + PrizeDrawDO getPrizeDraw(Long id); + + /** + * 获得抽奖活动分页 + * + * @param pageReqVO 分页查询 + * @return 抽奖活动分页 + */ + PageResult getPrizeDrawPage(PrizeDrawPageReqVO pageReqVO); + + // ==================== 子表(抽奖活动奖品) ==================== + + /** + * 获得抽奖活动奖品列表 + * + * @param activityId 关联抽奖活动id + * @return 抽奖活动奖品列表 + */ + List getActivityPrizeListByActivityId(Long activityId); + /** + * 获得抽奖活动奖品 + * + * @param id 奖品id + * @return 抽奖活动奖品列表 + */ + ActivityPrizeDO getActivityPrize(Long id); + + /** + * 获得已开启抽奖活动 + * + * @return 抽奖活动 + */ + PrizeDrawDO getOnePrizeDraw(); + + + /** + * 获得活动 Map + * + * @param ids 活动id的数组 + * @return 活动 Map + */ + default Map getPrizeDrawMap(Collection ids) { + List list = getPrizeDrawDOList(ids); + return convertMap(list, PrizeDrawDO::getId); + } + + /** + * 获得活动信息 + * + * @param ids 用户编号的数组 + * @return 用户信息们 + */ + List getPrizeDrawDOList(Collection ids); +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java new file mode 100644 index 0000000..7304758 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImpl.java @@ -0,0 +1,136 @@ +package cn.iocoder.yudao.module.promotion.service.prizedraw; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.ActivityPrizeDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.ActivityPrizeMapper; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.PrizeDrawMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; + +/** + * 抽奖活动 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class PrizeDrawServiceImpl implements PrizeDrawService { + + @Resource + private PrizeDrawMapper prizeDrawMapper; + @Resource + private ActivityPrizeMapper activityPrizeMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createPrizeDraw(PrizeDrawSaveReqVO createReqVO) { + // 插入 + PrizeDrawDO prizeDraw = BeanUtils.toBean(createReqVO, PrizeDrawDO.class); + prizeDrawMapper.insert(prizeDraw); + + // 插入子表 + createActivityPrizeList(prizeDraw.getId(), createReqVO.getActivityPrizes()); + // 返回 + return prizeDraw.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePrizeDraw(PrizeDrawSaveReqVO updateReqVO) { + // 校验存在 + validatePrizeDrawExists(updateReqVO.getId()); + // 更新 + PrizeDrawDO updateObj = BeanUtils.toBean(updateReqVO, PrizeDrawDO.class); + prizeDrawMapper.updateById(updateObj); + + // 更新子表 + updateActivityPrizeList(updateReqVO.getId(), updateReqVO.getActivityPrizes()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deletePrizeDraw(Long id) { + // 校验存在 + validatePrizeDrawExists(id); + // 删除 + prizeDrawMapper.deleteById(id); + + // 删除子表 + deleteActivityPrizeByActivityId(id); + } + + private void validatePrizeDrawExists(Long id) { + if (prizeDrawMapper.selectById(id) == null) { + throw exception(PRIZE_DRAW_NOT_EXISTS); + } + } + + @Override + public PrizeDrawDO getPrizeDraw(Long id) { + return prizeDrawMapper.selectById(id); + } + + @Override + public PageResult getPrizeDrawPage(PrizeDrawPageReqVO pageReqVO) { + return prizeDrawMapper.selectPage(pageReqVO); + } + + // ==================== 子表(抽奖活动奖品) ==================== + + @Override + public List getActivityPrizeListByActivityId(Long activityId) { + return activityPrizeMapper.selectListByActivityId(activityId); + } + + private void createActivityPrizeList(Long activityId, List list) { + list.forEach(o -> o.setActivityId(activityId)); + activityPrizeMapper.insertBatch(list); + } + + private void updateActivityPrizeList(Long activityId, List list) { + deleteActivityPrizeByActivityId(activityId); + list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新 + createActivityPrizeList(activityId, list); + } + + private void deleteActivityPrizeByActivityId(Long activityId) { + activityPrizeMapper.deleteByActivityId(activityId); + } + + + @Override + public PrizeDrawDO getOnePrizeDraw() { + return prizeDrawMapper.selectOne(new LambdaQueryWrapperX() + .eq(PrizeDrawDO::getStatus, 0) + ); + } + + @Override + public List getPrizeDrawDOList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return ListUtil.empty(); + } + return prizeDrawMapper.selectBatchIds(ids); + } + + @Override + public ActivityPrizeDO getActivityPrize(Long id) { + return activityPrizeMapper.selectById(id); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java new file mode 100644 index 0000000..d29ac07 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogService.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.module.promotion.service.prizelog; + +import java.util.*; +import javax.validation.*; + +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +/** + * 抽奖记录 Service 接口 + * + * @author 芋道源码 + */ +public interface PrizeLogService { + + /** + * 创建抽奖记录 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createPrizeLog(@Valid PrizeLogSaveReqVO createReqVO); + + /** + * 更新抽奖记录 + * + * @param updateReqVO 更新信息 + */ + void updatePrizeLog(@Valid PrizeLogSaveReqVO updateReqVO); + + /** + * 删除抽奖记录 + * + * @param id 编号 + */ + void deletePrizeLog(Long id); + + /** + * 获得抽奖记录 + * + * @param id 编号 + * @return 抽奖记录 + */ + PrizeLogDO getPrizeLog(Long id); + + /** + * 获得抽奖记录分页 + * + * @param pageReqVO 分页查询 + * @return 抽奖记录分页 + */ + PageResult getPrizeLogPage(PrizeLogPageReqVO pageReqVO); + /** + * 查询用户抽奖次数 + * + * @param mebId 用户id + * @return 抽奖记录分页 + */ + Long getPrizeLogByMebIdList(Long mebId,PrizeDrawDO prizeDraw); + /** + * 查询奖品被抽中次数 + * + * @param prizeDraw 活动 + * @return 抽奖记录分页 + */ + Long getPrizeLogList(PrizeDrawDO prizeDraw,Long prizeId); + /** + * 获取我的抽奖记录 + * + * @param prizeDraw 活动 + * @return 抽奖记录分页 + */ + List getPrizeLogListByMebId(Long mebId,PrizeDrawDO prizeDraw); + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java new file mode 100644 index 0000000..410f7e7 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImpl.java @@ -0,0 +1,103 @@ +package cn.iocoder.yudao.module.promotion.service.prizelog; + +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.promotion.dal.mysql.prizelog.PrizeLogMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; + +/** + * 抽奖记录 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class PrizeLogServiceImpl implements PrizeLogService { + + @Resource + private PrizeLogMapper prizeLogMapper; + + @Override + public Long createPrizeLog(PrizeLogSaveReqVO createReqVO) { + // 插入 + PrizeLogDO prizeLog = BeanUtils.toBean(createReqVO, PrizeLogDO.class); + prizeLogMapper.insert(prizeLog); + // 返回 + return prizeLog.getId(); + } + + @Override + public void updatePrizeLog(PrizeLogSaveReqVO updateReqVO) { + // 校验存在 + validatePrizeLogExists(updateReqVO.getId()); + // 更新 + PrizeLogDO updateObj = BeanUtils.toBean(updateReqVO, PrizeLogDO.class); + prizeLogMapper.updateById(updateObj); + } + + @Override + public void deletePrizeLog(Long id) { + // 校验存在 + validatePrizeLogExists(id); + // 删除 + prizeLogMapper.deleteById(id); + } + + private void validatePrizeLogExists(Long id) { + if (prizeLogMapper.selectById(id) == null) { + throw exception(PRIZE_LOG_NOT_EXISTS); + } + } + + @Override + public PrizeLogDO getPrizeLog(Long id) { + return prizeLogMapper.selectById(id); + } + + @Override + public PageResult getPrizeLogPage(PrizeLogPageReqVO pageReqVO) { + return prizeLogMapper.selectPage(pageReqVO); + } + + @Override + public Long getPrizeLogByMebIdList(Long mebId,PrizeDrawDO prizeDraw) { + return prizeLogMapper.selectCount(new LambdaQueryWrapperX() + .eq(PrizeLogDO::getMebId, mebId) + .ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime()) + .le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime()) + ); + } + + @Override + public Long getPrizeLogList(PrizeDrawDO prizeDraw,Long prizeId) { + return prizeLogMapper.selectCount(new LambdaQueryWrapperX() + .eq(PrizeLogDO::getPrizeId,prizeId) + .ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime()) + .le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime()) + ); + } + + @Override + public List getPrizeLogListByMebId(Long mebId,PrizeDrawDO prizeDraw) { + return prizeLogMapper.selectList(new LambdaQueryWrapperX() + .eq(PrizeLogDO::getMebId, mebId) + .ge(PrizeLogDO::getCreateTime, prizeDraw.getStartTime()) + .le(PrizeLogDO::getCreateTime, prizeDraw.getEndTime()) + ); + } + +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml new file mode 100644 index 0000000..3fa77d9 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizedraw/PrizeDrawMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml new file mode 100644 index 0000000..a96a198 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/prizelog/PrizeLogMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java new file mode 100644 index 0000000..e9395ce --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizedraw/PrizeDrawServiceImplTest.java @@ -0,0 +1,154 @@ +package cn.iocoder.yudao.module.promotion.service.prizedraw; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.PrizeDrawMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link PrizeDrawServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(PrizeDrawServiceImpl.class) +public class PrizeDrawServiceImplTest extends BaseDbUnitTest { + + @Resource + private PrizeDrawServiceImpl prizeDrawService; + + @Resource + private PrizeDrawMapper prizeDrawMapper; + + @Test + public void testCreatePrizeDraw_success() { + // 准备参数 + PrizeDrawSaveReqVO createReqVO = randomPojo(PrizeDrawSaveReqVO.class).setId(null); + + // 调用 + Long prizeDrawId = prizeDrawService.createPrizeDraw(createReqVO); + // 断言 + assertNotNull(prizeDrawId); + // 校验记录的属性是否正确 + PrizeDrawDO prizeDraw = prizeDrawMapper.selectById(prizeDrawId); + assertPojoEquals(createReqVO, prizeDraw, "id"); + } + + @Test + public void testUpdatePrizeDraw_success() { + // mock 数据 + PrizeDrawDO dbPrizeDraw = randomPojo(PrizeDrawDO.class); + prizeDrawMapper.insert(dbPrizeDraw);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PrizeDrawSaveReqVO updateReqVO = randomPojo(PrizeDrawSaveReqVO.class, o -> { + o.setId(dbPrizeDraw.getId()); // 设置更新的 ID + }); + + // 调用 + prizeDrawService.updatePrizeDraw(updateReqVO); + // 校验是否更新正确 + PrizeDrawDO prizeDraw = prizeDrawMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, prizeDraw); + } + + @Test + public void testUpdatePrizeDraw_notExists() { + // 准备参数 + PrizeDrawSaveReqVO updateReqVO = randomPojo(PrizeDrawSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> prizeDrawService.updatePrizeDraw(updateReqVO), PRIZE_DRAW_NOT_EXISTS); + } + + @Test + public void testDeletePrizeDraw_success() { + // mock 数据 + PrizeDrawDO dbPrizeDraw = randomPojo(PrizeDrawDO.class); + prizeDrawMapper.insert(dbPrizeDraw);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbPrizeDraw.getId(); + + // 调用 + prizeDrawService.deletePrizeDraw(id); + // 校验数据不存在了 + assertNull(prizeDrawMapper.selectById(id)); + } + + @Test + public void testDeletePrizeDraw_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> prizeDrawService.deletePrizeDraw(id), PRIZE_DRAW_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetPrizeDrawPage() { + // mock 数据 + PrizeDrawDO dbPrizeDraw = randomPojo(PrizeDrawDO.class, o -> { // 等会查询到 + o.setName(null); + o.setActivityRule(null); + o.setStatus(null); + o.setStartTime(null); + o.setEndTime(null); + o.setMebLevel(null); + o.setCreateTime(null); + }); + prizeDrawMapper.insert(dbPrizeDraw); + // 测试 name 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setName(null))); + // 测试 activityRule 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setActivityRule(null))); + // 测试 status 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setStatus(null))); + // 测试 startTime 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setStartTime(null))); + // 测试 endTime 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setEndTime(null))); + // 测试 mebLevel 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setMebLevel(null))); + // 测试 createTime 不匹配 + prizeDrawMapper.insert(cloneIgnoreId(dbPrizeDraw, o -> o.setCreateTime(null))); + // 准备参数 + PrizeDrawPageReqVO reqVO = new PrizeDrawPageReqVO(); + reqVO.setName(null); + reqVO.setActivityRule(null); + reqVO.setStatus(null); + reqVO.setStartTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setEndTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setMebLevel(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = prizeDrawService.getPrizeDrawPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbPrizeDraw, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java new file mode 100644 index 0000000..4f94756 --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/prizelog/PrizeLogServiceImplTest.java @@ -0,0 +1,162 @@ +package cn.iocoder.yudao.module.promotion.service.prizelog; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.promotion.controller.admin.prizelog.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.prizelog.PrizeLogDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.prizelog.PrizeLogMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import javax.annotation.Resource; +import org.springframework.context.annotation.Import; +import java.util.*; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * {@link PrizeLogServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(PrizeLogServiceImpl.class) +public class PrizeLogServiceImplTest extends BaseDbUnitTest { + + @Resource + private PrizeLogServiceImpl prizeLogService; + + @Resource + private PrizeLogMapper prizeLogMapper; + + @Test + public void testCreatePrizeLog_success() { + // 准备参数 + PrizeLogSaveReqVO createReqVO = randomPojo(PrizeLogSaveReqVO.class).setId(null); + + // 调用 + Long prizeLogId = prizeLogService.createPrizeLog(createReqVO); + // 断言 + assertNotNull(prizeLogId); + // 校验记录的属性是否正确 + PrizeLogDO prizeLog = prizeLogMapper.selectById(prizeLogId); + assertPojoEquals(createReqVO, prizeLog, "id"); + } + + @Test + public void testUpdatePrizeLog_success() { + // mock 数据 + PrizeLogDO dbPrizeLog = randomPojo(PrizeLogDO.class); + prizeLogMapper.insert(dbPrizeLog);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PrizeLogSaveReqVO updateReqVO = randomPojo(PrizeLogSaveReqVO.class, o -> { + o.setId(dbPrizeLog.getId()); // 设置更新的 ID + }); + + // 调用 + prizeLogService.updatePrizeLog(updateReqVO); + // 校验是否更新正确 + PrizeLogDO prizeLog = prizeLogMapper.selectById(updateReqVO.getId()); // 获取最新的 + assertPojoEquals(updateReqVO, prizeLog); + } + + @Test + public void testUpdatePrizeLog_notExists() { + // 准备参数 + PrizeLogSaveReqVO updateReqVO = randomPojo(PrizeLogSaveReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> prizeLogService.updatePrizeLog(updateReqVO), PRIZE_LOG_NOT_EXISTS); + } + + @Test + public void testDeletePrizeLog_success() { + // mock 数据 + PrizeLogDO dbPrizeLog = randomPojo(PrizeLogDO.class); + prizeLogMapper.insert(dbPrizeLog);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbPrizeLog.getId(); + + // 调用 + prizeLogService.deletePrizeLog(id); + // 校验数据不存在了 + assertNull(prizeLogMapper.selectById(id)); + } + + @Test + public void testDeletePrizeLog_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> prizeLogService.deletePrizeLog(id), PRIZE_LOG_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetPrizeLogPage() { + // mock 数据 + PrizeLogDO dbPrizeLog = randomPojo(PrizeLogDO.class, o -> { // 等会查询到 + o.setMebId(null); + o.setActivityId(null); + o.setName(null); + o.setImgUrl(null); + o.setWinNum(null); + o.setPrizeChance(null); + o.setPrizePoolAmount(null); + o.setStatus(null); + o.setCreateTime(null); + }); + prizeLogMapper.insert(dbPrizeLog); + // 测试 mebId 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setMebId(null))); + // 测试 activityId 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setActivityId(null))); + // 测试 name 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setName(null))); + // 测试 imgUrl 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setImgUrl(null))); + // 测试 winNum 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setWinNum(null))); + // 测试 prizeChance 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setPrizeChance(null))); + // 测试 prizePoolAmount 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setPrizePoolAmount(null))); + // 测试 status 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setStatus(null))); + // 测试 createTime 不匹配 + prizeLogMapper.insert(cloneIgnoreId(dbPrizeLog, o -> o.setCreateTime(null))); + // 准备参数 + PrizeLogPageReqVO reqVO = new PrizeLogPageReqVO(); + reqVO.setMebId(null); + reqVO.setActivityId(null); + reqVO.setName(null); + reqVO.setImgUrl(null); + reqVO.setWinNum(null); + reqVO.setPrizeChance(null); + reqVO.setPrizePoolAmount(null); + reqVO.setStatus(null); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + + // 调用 + PageResult pageResult = prizeLogService.getPrizeLogPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbPrizeLog, pageResult.getList().get(0)); + } + +} \ No newline at end of file diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql index 6a1a242..993e5d7 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql @@ -9,4 +9,6 @@ DELETE FROM "promotion_combination_activity"; DELETE FROM "promotion_article_category"; DELETE FROM "promotion_article"; DELETE FROM "promotion_diy_template"; -DELETE FROM "promotion_diy_page"; \ No newline at end of file +DELETE FROM "promotion_diy_page"; +DELETE FROM "promotion_prize_draw"; +DELETE FROM "promotion_prize_log"; diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql index 00ac3f9..6227cb4 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql @@ -253,4 +253,39 @@ CREATE TABLE IF NOT EXISTS "promotion_diy_page" "deleted" bit NOT NULL DEFAULT FALSE, "tenant_id" bigint NOT NULL, PRIMARY KEY ("id") -) COMMENT '装修页面'; \ No newline at end of file +) COMMENT '装修页面'; +CREATE TABLE IF NOT EXISTS "promotion_prize_draw" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar, + "activity_rule" varchar, + "status" varchar, + "start_time" varchar, + "end_time" varchar, + "meb_level" int, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL, + PRIMARY KEY ("id") + ) COMMENT '抽奖活动'; + +CREATE TABLE IF NOT EXISTS "promotion_prize_log" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "meb_id" bigint, + "activity_id" bigint, + "name" varchar, + "img_url" varchar, + "win_num" int, + "prize_chance" varchar, + "prize_pool_amount" varchar, + "status" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint NOT NULL, + PRIMARY KEY ("id") + ) COMMENT '抽奖记录表'; diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index aad011f..6c8b745 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; @@ -57,6 +58,9 @@ public class AppTradeOrderController { @Resource private TradeOrderProperties tradeOrderProperties; + @Resource + private MemberUserApi memberUserApi; + @GetMapping("/settlement") @Operation(summary = "获得订单结算信息") @PreAuthenticated @@ -80,6 +84,8 @@ public class AppTradeOrderController { public CommonResult updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { tradeOrderUpdateService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayOrderId()); +// memberUserApi.updateUserUpgradesLevel(); + return success(true); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java index 5876837..222e667 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java @@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.member.api.level; import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; +import java.util.Collection; +import java.util.List; + /** * 会员等级 API 接口 * @@ -38,4 +41,11 @@ public interface MemberLevelApi { */ void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId); + /** + * 获得会员等级列表 + * + * @param ids 编号 + * @return 会员等级列表 + */ + List getLevelList(Collection ids); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java index c9fb801..386b57f 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java @@ -57,4 +57,19 @@ public interface MemberUserApi { * @return 用户信息 */ MemberUserRespDTO getUserByMobile(String mobile); + + /** + * 注册帮扶人 + * + * @param userId 用户编号 + * @return 更新结果 + */ + boolean updateUserLevelId(Long userId); + /** + * 购买1188升级帮扶员 + * + * @param userId 用户编号 + * @return 更新结果 + */ + void updateUserUpgradesLevel(Long userId); } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java index 79fed98..8a6e566 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.member.api.level; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; import cn.iocoder.yudao.module.member.convert.level.MemberLevelConvert; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; @@ -9,6 +10,9 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.EXPERIENCE_BIZ_NOT_SUPPORT; @@ -43,4 +47,9 @@ public class MemberLevelApiImpl implements MemberLevelApi { addExperience(userId, -experience, bizType, bizId); } + @Override + public List getLevelList(Collection ids) { + return BeanUtils.toBean(memberLevelService.getLevelList(ids),MemberLevelRespDTO.class); + } + } diff --git a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java index 8da857c..a38703d 100644 --- a/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java @@ -44,4 +44,15 @@ public class MemberUserApiImpl implements MemberUserApi { return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile)); } + @Override + public boolean updateUserLevelId(Long userId) { + return userService.updateUserLevelId(userId); + } + + @Override + public void updateUserUpgradesLevel(Long userId) { + userService.updateUserUpgradesLevel(userId); + } + + } diff --git a/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 58834fb..6ca926c 100644 --- a/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/ruoyi-vue-pro-master/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java @@ -33,6 +33,7 @@ public class PayDemoOrderController { @Resource private PayDemoOrderService payDemoOrderService; + @PostMapping("/create") @Operation(summary = "创建示例订单") public CommonResult createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) { @@ -52,6 +53,8 @@ public class PayDemoOrderController { public CommonResult updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { payDemoOrderService.updateDemoOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayOrderId()); + + return success(true); }