From be6399238b7eaeb47f6816383ebfb00043a24828 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 12:40:22 +0800 Subject: [PATCH 01/15] =?UTF-8?q?=E4=BC=9A=E5=91=98=E8=AF=A6=E6=83=85?= =?UTF-8?q?=EF=BC=8C=E6=9F=A5=E8=AF=A2=E9=92=B1=E5=8C=85=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/wallet/PayWalletController.java | 39 ++++++++++++++++++ .../admin/wallet/vo/PayWalletBaseVO.java | 39 ++++++++++++++++++ .../admin/wallet/vo/PayWalletRespVO.java | 22 ++++++++++ .../admin/wallet/vo/PayWalletUserReqVO.java | 22 ++++++++++ .../pay/convert/wallet/PayWalletConvert.java | 3 ++ .../pay/service/wallet/PayWalletService.java | 40 ++++++++++++------- .../service/wallet/PayWalletServiceImpl.java | 5 +++ 7 files changed, 155 insertions(+), 15 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletController.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletBaseVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletUserReqVO.java diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletController.java new file mode 100644 index 000000000..5cffab255 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletController.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.controller.admin.wallet; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.PayWalletRespVO; +import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.PayWalletUserReqVO; +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 用户钱包") +@RestController +@RequestMapping("/pay/wallet") +@Validated +@Slf4j +public class PayWalletController { + + @Resource + private PayWalletService payWalletService; + + @GetMapping("/user-wallet") + @PreAuthorize("@ss.hasPermission('pay:wallet:query')") + @Operation(summary = "获得用户钱包明细") + public CommonResult getByUser(PayWalletUserReqVO reqVO) { + PayWalletDO wallet = payWalletService.getWalletByUserIdAndType(reqVO.getUserId(), reqVO.getUserType()); + return success(PayWalletConvert.INSTANCE.convert02(wallet)); + } +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletBaseVO.java new file mode 100644 index 000000000..f255c88fd --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletBaseVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 用户钱包 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class PayWalletBaseVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20020") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "用户类型不能为空") + private Byte userType; + + @Schema(description = "余额,单位分", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "余额,单位分不能为空") + private Integer balance; + + @Schema(description = "累计支出,单位分", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "累计支出,单位分不能为空") + private Integer totalExpense; + + @Schema(description = "累计充值,单位分", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "累计充值,单位分不能为空") + private Integer totalRecharge; + + @Schema(description = "冻结金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "20737") + @NotNull(message = "冻结金额,单位分不能为空") + private Integer freezePrice; + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletRespVO.java new file mode 100644 index 000000000..f7bc7822f --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 用户钱包 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayWalletRespVO extends PayWalletBaseVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29528") + private Long id; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletUserReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletUserReqVO.java new file mode 100644 index 000000000..7a9c9a7a1 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/PayWalletUserReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 用户钱包明细 Request VO") +@Data +public class PayWalletUserReqVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "用户类型不能为空") + @InEnum(value = UserTypeEnum.class, message = "用户类型必须是 {value}") + private Integer userType; +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java index 06255900b..7cdd8a81e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.pay.convert.wallet; +import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.PayWalletRespVO; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import org.mapstruct.Mapper; @@ -11,4 +12,6 @@ public interface PayWalletConvert { PayWalletConvert INSTANCE = Mappers.getMapper(PayWalletConvert.class); AppPayWalletRespVO convert(PayWalletDO bean); + + PayWalletRespVO convert02(PayWalletDO wallet); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java index 1703d8e1b..0a7476e11 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java @@ -13,10 +13,10 @@ public interface PayWalletService { /** * 获取钱包信息 - * + *

* 如果不存在,则创建钱包。由于用户注册时候不会创建钱包 * - * @param userId 用户编号 + * @param userId 用户编号 * @param userType 用户类型 */ PayWalletDO getOrCreateWallet(Long userId, Integer userType); @@ -31,10 +31,10 @@ public interface PayWalletService { /** * 钱包订单支付 * - * @param userId 用户 id - * @param userType 用户类型 + * @param userId 用户 id + * @param userType 用户类型 * @param outTradeNo 外部订单号 - * @param price 金额 + * @param price 金额 */ PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price); @@ -43,17 +43,17 @@ public interface PayWalletService { * * @param outRefundNo 外部退款号 * @param refundPrice 退款金额 - * @param reason 退款原因 + * @param reason 退款原因 */ PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason); /** * 扣减钱包余额 * - * @param walletId 钱包 id - * @param bizId 业务关联 id - * @param bizType 业务关联分类 - * @param price 扣减金额 + * @param walletId 钱包 id + * @param bizId 业务关联 id + * @param bizType 业务关联分类 + * @param price 扣减金额 * @return 钱包流水 */ PayWalletTransactionDO reduceWalletBalance(Long walletId, Long bizId, @@ -63,9 +63,9 @@ public interface PayWalletService { * 增加钱包余额 * * @param walletId 钱包 id - * @param bizId 业务关联 id - * @param bizType 业务关联分类 - * @param price 增加金额 + * @param bizId 业务关联 id + * @param bizType 业务关联分类 + * @param price 增加金额 * @return 钱包流水 */ PayWalletTransactionDO addWalletBalance(Long walletId, String bizId, @@ -74,15 +74,25 @@ public interface PayWalletService { /** * 冻结钱包部分余额 * - * @param id 钱包编号 + * @param id 钱包编号 * @param price 冻结金额 */ void freezePrice(Long id, Integer price); /** * 解冻钱包余额 - * @param id 钱包编号 + * + * @param id 钱包编号 * @param price 解冻金额 */ void unFreezePrice(Long id, Integer price); + + /** + * 获得用户的钱包明细 + * + * @param userId 用户编号 + * @param userType 用户类型 + * @return 用户的钱包明细 + */ + PayWalletDO getWalletByUserIdAndType(Long userId, Integer userType); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java index c14d20cfa..10e7ba3a2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java @@ -195,4 +195,9 @@ public class PayWalletServiceImpl implements PayWalletService { } } + @Override + public PayWalletDO getWalletByUserIdAndType(Long userId, Integer userType) { + return walletMapper.selectByUserIdAndType(userId, userType); + } + } From 497ea2eee856783fad17868fa51e3a021a849728 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 15:50:13 +0800 Subject: [PATCH 02/15] =?UTF-8?q?=E4=BC=9A=E5=91=98=E8=AF=A6=E6=83=85?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BC=9A=E5=91=98=E7=A7=AF=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/member.sql | 11 ++++++++ .../enums/point/MemberPointBizTypeEnum.java | 1 + .../admin/user/MemberUserController.java | 27 ++++++++++++++++--- .../user/vo/MemberUserUpdateLevelReqVO.java | 4 +-- .../user/vo/MemberUserUpdatePointReqVO.java | 22 +++++++++++++++ 5 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 sql/mysql/member.sql create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdatePointReqVO.java diff --git a/sql/mysql/member.sql b/sql/mysql/member.sql new file mode 100644 index 000000000..5231dbde7 --- /dev/null +++ b/sql/mysql/member.sql @@ -0,0 +1,11 @@ +-- 查询上级菜单、排序 +SELECT parent_id, sort +INTO @parentId, @sort +FROM system_menu +WHERE name = '用户等级修改' +LIMIT 1; +-- 新增 按钮权限 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) +VALUES ('用户积分修改', 'member:user:update-point', 3, @sort + 1, @parentId, '', '', '', 0); +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) +VALUES ('用户余额修改', 'member:user:update-balance', 3, @sort + 2, @parentId, '', '', '', 0); diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java index 931b09de3..3450a52aa 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java @@ -17,6 +17,7 @@ import java.util.Objects; public enum MemberPointBizTypeEnum implements IntArrayValuable { SIGN(1, "签到", "签到获得 {} 积分", true), + ADMIN(2, "管理员修改", "管理员修改 {} 积分", true), ORDER_GIVE(10, "订单奖励", "下单获得 {} 积分", true), // 支付订单时,赠送积分 ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 取消订单时,退回积分 ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 下单时,扣减积分 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java index e93aa0fde..b382c1caf 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java @@ -3,17 +3,16 @@ package cn.iocoder.yudao.module.member.controller.admin.user; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO; -import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserRespVO; -import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateLevelReqVO; -import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO; +import cn.iocoder.yudao.module.member.controller.admin.user.vo.*; import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; import cn.iocoder.yudao.module.member.dal.dataobject.tag.MemberTagDO; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; import cn.iocoder.yudao.module.member.service.group.MemberGroupService; import cn.iocoder.yudao.module.member.service.level.MemberLevelService; +import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; import cn.iocoder.yudao.module.member.service.tag.MemberTagService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; import io.swagger.v3.oas.annotations.Operation; @@ -33,6 +32,7 @@ import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - 会员用户") @RestController @@ -48,6 +48,8 @@ public class MemberUserController { private MemberLevelService memberLevelService; @Resource private MemberGroupService memberGroupService; + @Resource + private MemberPointRecordService memberPointRecordService; @PutMapping("/update") @Operation(summary = "更新会员用户") @@ -65,6 +67,23 @@ public class MemberUserController { return success(true); } + @PutMapping("/update-point") + @Operation(summary = "更新会员用户积分") + @PreAuthorize("@ss.hasPermission('member:user:update-point')") + public CommonResult updateUserPoint(@Valid @RequestBody MemberUserUpdatePointReqVO updateReqVO) { + memberPointRecordService.createPointRecord(updateReqVO.getId(), updateReqVO.getPoint(), + MemberPointBizTypeEnum.ADMIN, String.valueOf(getLoginUserId())); + return success(true); + } + + @PutMapping("/update-balance") + @Operation(summary = "更新会员用户余额") + @PreAuthorize("@ss.hasPermission('member:user:update-balance')") + public CommonResult updateUserBalance(@Valid @RequestBody Long id) { + // todo @jason:增加一个【修改余额】 + return success(true); + } + @GetMapping("/get") @Operation(summary = "获得会员用户") @Parameter(name = "id", description = "编号", required = true, example = "1024") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdateLevelReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdateLevelReqVO.java index a2ca91135..8e2eb6551 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdateLevelReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdateLevelReqVO.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.member.controller.admin.user.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotBlank; @@ -10,9 +9,8 @@ import javax.validation.constraints.NotNull; @Schema(description = "管理后台 - 会员用户 修改等级 Request VO") @Data -@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class MemberUserUpdateLevelReqVO extends MemberUserBaseVO { +public class MemberUserUpdateLevelReqVO { @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23788") @NotNull(message = "用户编号不能为空") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdatePointReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdatePointReqVO.java new file mode 100644 index 000000000..4a09772e3 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserUpdatePointReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.member.controller.admin.user.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 会员用户 修改积分 Request VO") +@Data +@ToString(callSuper = true) +public class MemberUserUpdatePointReqVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23788") + @NotNull(message = "用户编号不能为空") + private Long id; + + @Schema(description = "变动积分,正数为增加,负数为减少", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @NotNull(message = "变动积分不能为空") + private Integer point; + +} From fc432ba073485be7a292557dd8fe1bd492bfae90 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 17:29:32 +0800 Subject: [PATCH 03/15] =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=EF=BC=9A?= =?UTF-8?q?=E6=96=B0=E4=BA=BA=E5=88=B8=E4=BD=BF=E7=94=A8=20MQ=20=E5=8F=91?= =?UTF-8?q?=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/coupon/CouponTemplateMapper.java | 4 +++ .../coupon/RegisterCouponSendConsumer.java | 29 +++++++++++++++++ .../service/coupon/CouponService.java | 7 ++--- .../service/coupon/CouponServiceImpl.java | 9 +++++- .../service/coupon/CouponTemplateService.java | 9 ++++++ .../coupon/CouponTemplateServiceImpl.java | 8 +++++ .../yudao-module-member-api/pom.xml | 5 +++ .../user/RegisterCouponSendMessage.java | 29 +++++++++++++++++ .../producer/user/RegisterCouponProducer.java | 31 +++++++++++++++++++ .../service/user/MemberUserServiceImpl.java | 7 +++++ 10 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java index 3c575c4d4..05b0f0607 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.time.LocalDateTime; +import java.util.List; import java.util.function.Consumer; /** @@ -48,4 +49,7 @@ public interface CouponTemplateMapper extends BaseMapperX { void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount); + default List selectListByTakeType(Integer takeType) { + return selectList(CouponTemplateDO::getTakeType, takeType); + } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java new file mode 100644 index 000000000..5ad9751ec --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/RegisterCouponSendConsumer.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.promotion.mq.consumer.coupon; + +import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; +import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 针对 {@link RegisterCouponSendMessage} 的消费者 + * + * @author owen + */ +@Component +@Slf4j +public class RegisterCouponSendConsumer extends AbstractStreamMessageListener { + + @Resource + private CouponService couponService; + + @Override + public void onMessage(RegisterCouponSendMessage message) { + log.info("[onMessage][消息内容({})]", message); + couponService.takeCouponByRegister(message.getUserId()); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java index e9dda6c78..ca3d4bd1a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java @@ -119,12 +119,9 @@ public interface CouponService { /** * 【系统】给用户发送新人券 * - * @param templateId 优惠券模板编号 - * @param userId 用户编号列表 + * @param userId 用户编号 */ - default void takeCouponByRegister(Long templateId, Long userId) { - takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); - } + void takeCouponByRegister(Long userId); /** * 获取会员领取指定优惠券的数量 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java index a8258efb4..07d1f9e2c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -40,7 +40,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; import static java.util.Arrays.asList; -// TODO @疯狂:注册时,赠送用户优惠劵;为了解耦,可以考虑注册时发个 MQ 消息;然后营销这里监听后消费; /** * 优惠劵 Service 实现类 * @@ -183,6 +182,14 @@ public class CouponServiceImpl implements CouponService { couponTemplateService.updateCouponTemplateTakeCount(templateId, userIds.size()); } + @Override + public void takeCouponByRegister(Long userId) { + List templates = couponTemplateService.getCouponTemplateByTakeType(CouponTakeTypeEnum.REGISTER); + for (CouponTemplateDO template : templates) { + takeCoupon(template.getId(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); + } + } + @Override public List getTakeCountListByTemplateIds(Collection templateIds, Long userId) { if (CollUtil.isEmpty(templateIds)) { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java index 9f2d925a2..c8f2accb7 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java @@ -5,8 +5,10 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import javax.validation.Valid; +import java.util.List; /** * 优惠劵模板 Service 接口 @@ -69,4 +71,11 @@ public interface CouponTemplateService { */ void updateCouponTemplateTakeCount(Long id, int incrCount); + /** + * 获得指定领取方式的优惠券模板 + * + * @param takeType 领取方式 + * @return 优惠券模板列表 + */ + List getCouponTemplateByTakeType(CouponTakeTypeEnum takeType); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java index 202914780..159fd1144 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java @@ -8,11 +8,14 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.Cou import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.List; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL; @@ -93,4 +96,9 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { couponTemplateMapper.updateTakeCount(id, incrCount); } + @Override + public List getCouponTemplateByTakeType(CouponTakeTypeEnum takeType) { + return couponTemplateMapper.selectListByTakeType(takeType.getValue()); + } + } diff --git a/yudao-module-member/yudao-module-member-api/pom.xml b/yudao-module-member/yudao-module-member-api/pom.xml index 1f60cd0fc..308208123 100644 --- a/yudao-module-member/yudao-module-member-api/pom.xml +++ b/yudao-module-member/yudao-module-member-api/pom.xml @@ -22,6 +22,11 @@ yudao-common + + cn.iocoder.boot + yudao-spring-boot-starter-mq + compile + org.springframework.boot diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java new file mode 100644 index 000000000..5d9641a9e --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/RegisterCouponSendMessage.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.member.mq.message.user; + +import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; + +/** + * 新人券发放消息 + * + * @author owen + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class RegisterCouponSendMessage extends AbstractStreamMessage { + + /** + * 用户编号 + */ + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Override + public String getStreamKey() { + return "member.register-coupon.send"; + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java new file mode 100644 index 000000000..fc7f0d3b9 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/RegisterCouponProducer.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.member.mq.producer.user; + +import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; +import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 新人券发放 Producer + * + * @author owen + */ +@Slf4j +@Component +public class RegisterCouponProducer { + + @Resource + private RedisMQTemplate redisMQTemplate; + + /** + * 发送 {@link RegisterCouponSendMessage} 消息 + * + * @param userId 用户编号 + */ + public void sendMailSendMessage(Long userId) { + redisMQTemplate.send(new RegisterCouponSendMessage().setUserId(userId)); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java index 4735701be..6921fff8c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; +import cn.iocoder.yudao.module.member.mq.producer.user.RegisterCouponProducer; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; @@ -58,6 +59,9 @@ public class MemberUserServiceImpl implements MemberUserService { @Resource private PasswordEncoder passwordEncoder; + @Resource + private RegisterCouponProducer registerCouponProducer; + @Override public MemberUserDO getUserByMobile(String mobile) { return memberUserMapper.selectByMobile(mobile); @@ -89,6 +93,9 @@ public class MemberUserServiceImpl implements MemberUserService { user.setPassword(encodePassword(password)); // 加密密码 user.setRegisterIp(registerIp); memberUserMapper.insert(user); + + // 发送 MQ 消息,发放新人券 + registerCouponProducer.sendMailSendMessage(user.getId()); return user; } From 42a899c5d3090de8b35621b78137cdab45b1708f Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 17:49:38 +0800 Subject: [PATCH 04/15] =?UTF-8?q?=E4=BA=A4=E6=98=93=EF=BC=9A=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5=20=E6=8E=A8?= =?UTF-8?q?=E5=B9=BF=E4=BA=BA=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/trade_order.sql | 3 +++ .../trade/dal/dataobject/order/TradeOrderDO.java | 9 ++++++++- .../service/order/TradeOrderUpdateServiceImpl.java | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 sql/mysql/trade_order.sql diff --git a/sql/mysql/trade_order.sql b/sql/mysql/trade_order.sql new file mode 100644 index 000000000..066416079 --- /dev/null +++ b/sql/mysql/trade_order.sql @@ -0,0 +1,3 @@ +-- 增加字段 +ALTER TABLE trade_order + ADD COLUMN brokerage_user_id bigint NULL COMMENT '推广人编号' AFTER comment_status; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index ea3dd2f18..df23ded1a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; @@ -105,7 +107,12 @@ public class TradeOrderDO extends BaseDO { */ private Boolean commentStatus; - // TODO @疯狂:加一个推广人编号; + /** + * 推广人编号 + * {@link BrokerageUserDO#getId()} + * {@link MemberUserRespDTO#getId()} + */ + private Long brokerageUserId; // ========== 价格 + 支付基本信息 ========== diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index a6e3527f1..955254095 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -40,6 +40,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettle import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -54,6 +55,7 @@ import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils; import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; import cn.iocoder.yudao.module.trade.service.cart.CartService; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; @@ -108,6 +110,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { private DeliveryExpressService deliveryExpressService; @Resource private TradeMessageService tradeMessageService; + @Resource + private BrokerageUserService brokerageUserService; + @Resource + private BrokerageRecordService brokerageRecordService; @Resource private ProductSpuApi productSpuApi; @@ -130,8 +136,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Resource private MemberPointApi memberPointApi; @Resource - private BrokerageRecordService brokerageRecordService; - @Resource private ProductCommentApi productCommentApi; @Resource @@ -305,6 +309,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // 6. 插入订单日志 TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus()); + // 7. 设置订单推广人 + BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(order.getUserId()); + if (brokerageUser != null && brokerageUser.getBindUserId() != null) { + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setBrokerageUserId(brokerageUser.getBindUserId())); + } + // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! } From d0d21b27875c1093e94bc4c68d7adb8bab814fac Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 19:39:02 +0800 Subject: [PATCH 05/15] =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=EF=BC=9A?= =?UTF-8?q?=E6=96=B0=E5=A2=9E/=E4=BF=AE=E6=94=B9=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E5=AF=B9=E5=BA=94=E7=9A=84=E5=95=86=E5=93=81?= =?UTF-8?q?=E3=80=81=E5=88=86=E7=B1=BB=E6=98=AF=E5=90=A6=E5=AD=98=E5=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/category/ProductCategoryApi.java | 20 ++++++++++++++ .../module/product/api/spu/ProductSpuApi.java | 16 +++++++++++ .../product/enums/ErrorCodeConstants.java | 2 +- .../api/category/ProductCategoryApiImpl.java | 27 +++++++++++++++++++ .../product/api/spu/ProductSpuApiImpl.java | 13 ++++++--- .../category/ProductCategoryService.java | 9 +++++++ .../category/ProductCategoryServiceImpl.java | 24 +++++++++++++++++ .../service/spu/ProductSpuService.java | 10 +++++++ .../service/spu/ProductSpuServiceImpl.java | 23 ++++++++++++++++ .../coupon/CouponTemplateServiceImpl.java | 23 ++++++++++++++-- .../service/price/TradePriceServiceImpl.java | 17 +++--------- 11 files changed, 164 insertions(+), 20 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApi.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApiImpl.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApi.java new file mode 100644 index 000000000..38feb96d6 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApi.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.product.api.category; + +import java.util.Collection; + +/** + * 商品分类 API 接口 + * + * @author owen + */ +public interface ProductCategoryApi { + + /** + * 校验商品分类是否有效。如下情况,视为无效: + * 1. 商品分类编号不存在 + * 2. 商品分类被禁用 + * + * @param ids 商品分类编号数组 + */ + void validateCategoryList(Collection ids); +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java index 78c1154c1..fcb7b97af 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java @@ -21,6 +21,14 @@ public interface ProductSpuApi { */ List getSpuList(Collection ids); + /** + * 批量查询 SPU 数组,并且校验是否 SPU 是否有效 + * + * @param ids SPU 编号列表 + * @return SPU 数组 + */ + List getSpuListAndValidate(Collection ids); + /** * 获得 SPU * @@ -28,4 +36,12 @@ public interface ProductSpuApi { */ ProductSpuRespDTO getSpu(Long id); + /** + * 校验商品是否有效。如下情况,视为无效: + * 1. 商品编号不存在 + * 2. 商品被禁用 + * + * @param ids 商品编号数组 + */ + void validateSpuList(Collection ids); } diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index b32ae65e9..a7debcddf 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -34,7 +34,7 @@ public interface ErrorCodeConstants { // ========== 商品 SPU 1-008-005-000 ========== ErrorCode SPU_NOT_EXISTS = new ErrorCode(1_008_005_000, "商品 SPU 不存在"); ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1_008_005_001, "商品分类不正确,原因:必须使用第二级的商品分类及以下"); - ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU 不处于上架状态"); + ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU【[]】不处于上架状态"); ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_003, "商品 SPU 不处于回收站状态"); // ========== 商品 SKU 1-008-006-000 ========== diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApiImpl.java new file mode 100644 index 000000000..18f5c1d6c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApiImpl.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.product.api.category; + +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; + +/** + * 商品分类 API 接口实现类 + * + * @author owen + */ +@Service +@Validated +public class ProductCategoryApiImpl implements ProductCategoryApi { + + @Resource + private ProductCategoryService productCategoryService; + + @Override + public void validateCategoryList(Collection ids) { + productCategoryService.validateCategoryList(ids); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java index 5803c097a..88be2bca5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java @@ -3,9 +3,6 @@ package cn.iocoder.yudao.module.product.api.spu; import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -36,9 +33,19 @@ public class ProductSpuApiImpl implements ProductSpuApi { return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids)); } + @Override + public List getSpuListAndValidate(Collection ids) { + return ProductSpuConvert.INSTANCE.convertList2(spuService.validateSpuList(ids)); + } + @Override public ProductSpuRespDTO getSpu(Long id) { return ProductSpuConvert.INSTANCE.convert02(spuService.getSpu(id)); } + @Override + public void validateSpuList(Collection ids) { + spuService.validateSpuList(ids); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java index 32a4c030d..de1545bf9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import javax.validation.Valid; +import java.util.Collection; import java.util.List; /** @@ -75,4 +76,12 @@ public interface ProductCategoryService { */ List getEnableCategoryList(); + /** + * 校验商品分类是否有效。如下情况,视为无效: + * 1. 商品分类编号不存在 + * 2. 商品分类被禁用 + * + * @param ids 商品分类编号数组 + */ + void validateCategoryList(Collection ids); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 7709f21a1..f490ea17e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.product.service.category; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; @@ -13,7 +15,9 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -99,6 +103,26 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } } + @Override + public void validateCategoryList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return; + } + // 获得商品分类信息 + List categoryList = productCategoryMapper.selectBatchIds(ids); + Map categoryMap = CollectionUtils.convertMap(categoryList, ProductCategoryDO::getId); + // 校验 + ids.forEach(id -> { + ProductCategoryDO category = categoryMap.get(id); + if (category == null) { + throw exception(CATEGORY_NOT_EXISTS); + } + if (!CommonStatusEnum.ENABLE.getStatus().equals(category.getStatus())) { + throw exception(CATEGORY_DISABLED, category.getName()); + } + }); + } + @Override public ProductCategoryDO getCategory(Long id) { return productCategoryMapper.selectById(id); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index f381e6de6..25cf853a2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -136,4 +136,14 @@ public interface ProductSpuService { */ Long getSpuCountByCategoryId(Long categoryId); + + /** + * 校验商品是否有效。如下情况,视为无效: + * 1. 商品编号不存在 + * 2. 商品被禁用 + * + * @param ids 商品编号数组 + * @return 商品 SPU 列表 + */ + List validateSpuList(Collection ids); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 43421315f..725472e9d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.service.spu; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -139,6 +140,28 @@ public class ProductSpuServiceImpl implements ProductSpuService { } } + @Override + public List validateSpuList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + // 获得商品信息 + List spuList = productSpuMapper.selectBatchIds(ids); + Map spuMap = CollectionUtils.convertMap(spuList, ProductSpuDO::getId); + // 校验 + ids.forEach(id -> { + ProductSpuDO spu = spuMap.get(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { + throw exception(SPU_NOT_ENABLE, spu.getName()); + } + }); + + return spuList; + } + @Override @Transactional(rollbackFor = Exception.class) public void deleteSpu(Long id) { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java index 159fd1144..7a76e08d2 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java @@ -2,19 +2,22 @@ package cn.iocoder.yudao.module.promotion.service.coupon; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.api.category.ProductCategoryApi; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; - import java.util.List; +import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; @@ -32,9 +35,15 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { @Resource private CouponTemplateMapper couponTemplateMapper; - // TODO @疯狂:新增/修改时,需要校验对应的商品、分类是否存在 + @Resource + private ProductCategoryApi productCategoryApi; + @Resource + private ProductSpuApi productSpuApi; + @Override public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) { + // 校验商品范围 + validateProductScope(createReqVO.getProductScope(), createReqVO.getProductScopeValues()); // 插入 CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO) .setStatus(CommonStatusEnum.ENABLE.getStatus()); @@ -51,6 +60,8 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { if (updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) { throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount()); } + // 校验商品范围 + validateProductScope(updateReqVO.getProductScope(), updateReqVO.getProductScopeValues()); // 更新 CouponTemplateDO updateObj = CouponTemplateConvert.INSTANCE.convert(updateReqVO); @@ -81,6 +92,14 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { return couponTemplate; } + private void validateProductScope(Integer productScope, List productScopeValues) { + if (Objects.equals(PromotionProductScopeEnum.SPU.getScope(), productScope)) { + productSpuApi.validateSpuList(productScopeValues); + } else if (Objects.equals(PromotionProductScopeEnum.CATEGORY.getScope(), productScope)) { + productCategoryApi.validateCategoryList(productScopeValues); + } + } + @Override public CouponTemplateDO getCouponTemplate(Long id) { return couponTemplateMapper.selectById(id); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java index a6982c177..79041a530 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; @@ -20,7 +19,8 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; /** @@ -82,18 +82,7 @@ public class TradePriceServiceImpl implements TradePriceService { private List checkSpuList(List skuList) { // 获得商品 SPU 数组 - List spus = productSpuApi.getSpuList(convertSet(skuList, ProductSkuRespDTO::getSpuId)); - - // 校验商品 SPU - spus.forEach(spu -> { - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { - throw exception(SPU_NOT_ENABLE); - } - }); - return spus; + return productSpuApi.getSpuListAndValidate(convertSet(skuList, ProductSkuRespDTO::getSpuId)); } } From aaa01de21d5937451c3282ad58e4efc117a041aa Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 19:55:18 +0800 Subject: [PATCH 06/15] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=BD=A3=E9=87=91=E6=8E=92=E5=90=8D=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../brokerage/AppBrokerageUserController.java | 3 +- .../brokerage/BrokerageRecordMapper.java | 14 +++++++-- .../brokerage/BrokerageRecordService.java | 5 +++- .../brokerage/BrokerageRecordServiceImpl.java | 29 +++++++++---------- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java index d9d64e6fa..141ee68dd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageUserConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; @@ -84,7 +85,7 @@ public class AppBrokerageUserController { LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(yesterday); LocalDateTime endTime = LocalDateTimeUtil.endOfDay(yesterday); Integer yesterdayPrice = brokerageRecordService.getSummaryPriceByUserId(brokerageUser.getId(), - BrokerageRecordBizTypeEnum.ORDER.getType(), beginTime, endTime); + BrokerageRecordBizTypeEnum.ORDER, BrokerageRecordStatusEnum.SETTLEMENT, beginTime, endTime); // 统计用户提现的佣金 Integer withdrawPrice = brokerageWithdrawService.getWithdrawSummaryListByUserId(Collections.singleton(brokerageUser.getId()), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS).stream() diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java index e0414807c..cda81a195 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java @@ -80,10 +80,11 @@ public interface BrokerageRecordMapper extends BaseMapperX { } @Select("SELECT SUM(price) FROM trade_brokerage_record " + - "WHERE user_id = #{userId} AND biz_type = #{bizType} " + - "AND create_time BETWEEN #{beginTime} AND #{endTime} AND deleted = FALSE") + "WHERE user_id = #{userId} AND biz_type = #{bizType} AND status = #{status} " + + "AND unfreeze_time BETWEEN #{beginTime} AND #{endTime} AND deleted = FALSE") Integer selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(@Param("userId") Long userId, @Param("bizType") Integer bizType, + @Param("status") Integer status, @Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime); @@ -98,4 +99,13 @@ public interface BrokerageRecordMapper extends BaseMapperX { @Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime); + @Select("SELECT COUNT(1) FROM trade_brokerage_record " + + "WHERE biz_type = #{bizType} AND status = #{status} AND deleted = FALSE " + + "AND unfreeze_time BETWEEN #{beginTime} AND #{endTime} " + + "GROUP BY user_id HAVING SUM(price) > #{brokeragePrice}") + Integer selectCountByPriceGt(@Param("brokeragePrice") Integer brokeragePrice, + @Param("bizType") Integer bizType, + @Param("status") Integer status, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java index 2a6e95985..1cf1e2443 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokera import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryRespBO; @@ -120,11 +121,13 @@ public interface BrokerageRecordService { * * @param userId 用户编号 * @param bizType 业务类型 + * @param status 状态 * @param beginTime 开始时间 * @param endTime 截止时间 * @return 用户佣金合计 */ - Integer getSummaryPriceByUserId(Long userId, Integer bizType, LocalDateTime beginTime, LocalDateTime endTime); + Integer getSummaryPriceByUserId(Long userId, BrokerageRecordBizTypeEnum bizType, BrokerageRecordStatusEnum status, + LocalDateTime beginTime, LocalDateTime endTime); /** * 获得用户佣金排行分页列表(基于佣金总数) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java index fc36d07eb..8b60c4f6a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.BooleanUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.*; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; @@ -265,9 +262,10 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { } @Override - public Integer getSummaryPriceByUserId(Long userId, Integer bizType, LocalDateTime beginTime, LocalDateTime endTime) { - return brokerageRecordMapper.selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(userId, bizType, - beginTime, endTime); + public Integer getSummaryPriceByUserId(Long userId, BrokerageRecordBizTypeEnum bizType, BrokerageRecordStatusEnum status, + LocalDateTime beginTime, LocalDateTime endTime) { + return brokerageRecordMapper.selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(userId, + bizType.getType(), status.getStatus(), beginTime, endTime); } @Override @@ -279,17 +277,18 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); } - // TODO @疯狂:这个要不我们先做精准的?先查询自己的推广金额,然后查询比该金额多的有多少人? @Override public Integer getUserRankByPrice(Long userId, LocalDateTime[] times) { - AppBrokerageUserRankPageReqVO pageParam = new AppBrokerageUserRankPageReqVO().setTimes(times); - // 取前 100 名 - pageParam.setPageSize(100); - PageResult pageResult = getBrokerageUserChildSummaryPageByPrice(pageParam); - // 获得索引 - int index = CollUtil.indexOf(pageResult.getList(), user -> Objects.equals(userId, user.getId())); + // 用户的推广金额 + Integer price = brokerageRecordMapper.selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(userId, + BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), + ArrayUtil.get(times, 0), ArrayUtil.get(times, 1)); + // 排在用户前面的人数 + Integer greaterCount = brokerageRecordMapper.selectCountByPriceGt(price, + BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), + ArrayUtil.get(times, 0), ArrayUtil.get(times, 1)); // 获得排名 - return index + 1; + return ObjUtil.defaultIfNull(greaterCount, 0) + 1; } @Override From d2c5eaf916bd0d1f4d25fae1b20bf8b90545f9dd Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 22:05:11 +0800 Subject: [PATCH 07/15] =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=EF=BC=9A?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=98=AF=E5=90=A6=E9=A2=86=E5=8F=96=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coupon/AppCouponTemplateController.java | 83 +++++++------------ .../vo/template/AppCouponTemplateRespVO.java | 4 +- .../convert/coupon/CouponTemplateConvert.java | 30 ++++--- .../mysql/coupon/CouponTemplateMapper.java | 38 ++++++--- .../service/coupon/CouponService.java | 10 +++ .../service/coupon/CouponServiceImpl.java | 25 +++++- .../service/coupon/CouponTemplateService.java | 13 +++ .../coupon/CouponTemplateServiceImpl.java | 6 ++ 8 files changed, 128 insertions(+), 81 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java index a8d42da33..bc146dffc 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.promotion.controller.app.coupon; -import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; @@ -25,11 +24,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; @Tag(name = "用户 App - 优惠劵模板") @@ -46,7 +43,6 @@ public class AppCouponTemplateController { @Resource private ProductSpuApi productSpuApi; - // TODO 疯狂:这里应该还有个 list 接口哈;获得优惠劵模版列表,用于首页、商品页的优惠劵 @GetMapping("/list") @Operation(summary = "获得优惠劵模版列表") @Parameters({ @@ -56,46 +52,28 @@ public class AppCouponTemplateController { }) public CommonResult> getCouponTemplateList( @RequestParam(value = "spuId", required = false) Long spuId, - @RequestParam(value = "useType", required = false) Integer useType, + @RequestParam(value = "productScope", required = false) Integer productScope, @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { - List list = new ArrayList<>(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - AppCouponTemplateRespVO vo = new AppCouponTemplateRespVO(); - vo.setId(i + 1L); - vo.setName("优惠劵" + (i + 1)); - vo.setTakeLimitCount(random.nextInt(10) + 1); - vo.setUsePrice(random.nextInt(100) * 100); - vo.setValidityType(random.nextInt(2) + 1); - if (vo.getValidityType() == 1) { - vo.setValidStartTime(LocalDateTime.now().plusDays(random.nextInt(10))); - vo.setValidEndTime(LocalDateTime.now().plusDays(random.nextInt(20) + 10)); - } else { - vo.setFixedStartTerm(random.nextInt(10)); - vo.setFixedEndTerm(random.nextInt(10) + vo.getFixedStartTerm() + 1); - } - vo.setDiscountType(random.nextInt(2) + 1); - if (vo.getDiscountType() == 1) { - vo.setDiscountPercent(null); - vo.setDiscountPrice(random.nextInt(50) * 100); - vo.setDiscountLimitPrice(null); - } else { - vo.setDiscountPercent(random.nextInt(90) + 10); - vo.setDiscountPrice(null); - vo.setDiscountLimitPrice(random.nextInt(200) * 100); - } - // TODO @疯狂:是否已领取,要不在 TemplateService 搞个 static 方法,让它基于 countMap 这种去计算,这样好点? - vo.setTakeStatus(random.nextBoolean()); - list.add(vo); - } - return success(list); + // 1.1 处理查询条件:商品范围编号 + Long productScopeValue = getProductScopeValue(productScope, spuId); + // 1.2 处理查询条件:领取方式 = 直接领取 + List canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue()); + + // 2. 查询 + List list = couponTemplateService.getCouponTemplateList(canTakeTypes, productScope, + productScopeValue, count); + + // 3.1 领取数量 + Map canCanTakeMap = couponService.getUserCanCanTakeMap(getLoginUserId(), list); + // 3.2 拼接返回 + return success(CouponTemplateConvert.INSTANCE.convertAppList(list, canCanTakeMap)); } @GetMapping("/page") @Operation(summary = "获得优惠劵模版分页") public CommonResult> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) { // 1.1 处理查询条件:商品范围编号 - Long productScopeValue = getProductScopeValue(pageReqVO); + Long productScopeValue = getProductScopeValue(pageReqVO.getProductScope(), pageReqVO.getSpuId()); // 1.2 处理查询条件:领取方式 = 直接领取 List canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue()); @@ -104,35 +82,30 @@ public class AppCouponTemplateController { CouponTemplateConvert.INSTANCE.convert(pageReqVO, canTakeTypes, pageReqVO.getProductScope(), productScopeValue)); // 3.1 领取数量 - Map couponTakeCountMap = new HashMap<>(0); - Long userId = getLoginUserId(); - if (userId != null) { - List templateIds = convertList(pageResult.getList(), CouponTemplateDO::getId, - t -> ObjUtil.notEqual(t.getTakeLimitCount(), -1)); // 只查有设置“每人限领个数”的 - couponTakeCountMap = couponService.getTakeCountMapByTemplateIds(templateIds, userId); - } + Map canCanTakeMap = couponService.getUserCanCanTakeMap(getLoginUserId(), pageResult.getList()); // 3.2 拼接返回 - return success(CouponTemplateConvert.INSTANCE.convertAppPage(pageResult, couponTakeCountMap)); + return success(CouponTemplateConvert.INSTANCE.convertAppPage(pageResult, canCanTakeMap)); } /** - * 获得分页查询的商品范围 + * 获得商品的使用范围编号 * - * @param pageReqVO 分页查询 - * @return 商品范围 + * @param productScope 商品范围 + * @param spuId 商品 SPU 编号 + * @return 商品范围编号 */ - private Long getProductScopeValue(AppCouponTemplatePageReqVO pageReqVO) { - // 通用券:清除商品范围 - if (pageReqVO.getProductScope() == null || ObjectUtils.equalsAny(pageReqVO.getProductScope(), PromotionProductScopeEnum.ALL.getScope(), null)) { + private Long getProductScopeValue(Integer productScope, Long spuId) { + // 通用券:没有商品范围 + if (productScope == null || ObjectUtils.equalsAny(productScope, PromotionProductScopeEnum.ALL.getScope(), null)) { return null; } - // 品类券:查询商品的品类 - if (Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.CATEGORY.getScope()) && pageReqVO.getSpuId() != null) { - return Optional.ofNullable(productSpuApi.getSpu(pageReqVO.getSpuId())) + // 品类券:查询商品的品类编号 + if (Objects.equals(productScope, PromotionProductScopeEnum.CATEGORY.getScope()) && spuId != null) { + return Optional.ofNullable(productSpuApi.getSpu(spuId)) .map(ProductSpuRespDTO::getCategoryId).orElse(null); } // 商品卷:直接返回 - return pageReqVO.getSpuId(); + return spuId; } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java index be4a0c1f0..83b879acc 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java @@ -55,7 +55,7 @@ public class AppCouponTemplateRespVO { // ========== 用户相关字段 ========== - @Schema(description = "是否已领取", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - private Boolean takeStatus; + @Schema(description = "是否可以领取", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + private Boolean canTake; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java index 009a639a8..e09d0f013 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java @@ -37,21 +37,25 @@ public interface CouponTemplateConvert { PageResult convertAppPage(PageResult pageResult); - default PageResult convertAppPage(PageResult pageResult, Map couponTakeCountMap) { + List convertAppList(List list); + + default PageResult convertAppPage(PageResult pageResult, Map userCanTakeMap) { PageResult result = convertAppPage(pageResult); - if (MapUtil.isEmpty(couponTakeCountMap)) { - return result; - } - for (AppCouponTemplateRespVO template : result.getList()) { - // 每人领取数量无限制 - if (template.getTakeLimitCount() == -1) { - template.setTakeStatus(false); - continue; - } - // 检查已领取数量是否超过限领数量 - template.setTakeStatus(MapUtil.getInt(couponTakeCountMap, template.getId(), 0) >= template.getTakeLimitCount()); - } + copyTo(result.getList(), userCanTakeMap); return result; } + default List convertAppList(List list, Map userCanTakeMap) { + List result = convertAppList(list); + copyTo(result, userCanTakeMap); + return result; + } + + default void copyTo(List list, Map userCanTakeMap) { + for (AppCouponTemplateRespVO template : list) { + // 检查已领取数量是否超过限领数量 + template.setCanTake(MapUtil.getBool(userCanTakeMap, template.getId(), false)); + } + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java index 05b0f0607..f5715298d 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java @@ -24,16 +24,8 @@ import java.util.function.Consumer; public interface CouponTemplateMapper extends BaseMapperX { default PageResult selectPage(CouponTemplatePageReqVO reqVO) { - // 构建可领取的查询条件, 好啰嗦 ( ╯-_-)╯┴—┴ - Consumer> canTakeConsumer = null; - if (CollUtil.isNotEmpty(reqVO.getCanTakeTypes())) { - canTakeConsumer = w -> - w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的 - .in(CouponTemplateDO::getTakeType, reqVO.getCanTakeTypes()) // 2. 领取方式一致 - .and(ww -> ww.isNull(CouponTemplateDO::getValidEndTime) // 3. 未过期 - .or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now())) - .apply(" take_count < total_count "); // 4. 剩余数量大于 0 - } + // 构建可领取的查询条件 + Consumer> canTakeConsumer = buildCanTakeQueryConsumer(reqVO.getCanTakeTypes()); // 执行分页查询 return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(CouponTemplateDO::getName, reqVO.getName()) @@ -52,4 +44,30 @@ public interface CouponTemplateMapper extends BaseMapperX { default List selectListByTakeType(Integer takeType) { return selectList(CouponTemplateDO::getTakeType, takeType); } + + default List selectList(List canTakeTypes, Integer productScope, Long productScopeValue, Integer count) { + // 构建可领取的查询条件 + Consumer> canTakeConsumer = buildCanTakeQueryConsumer(canTakeTypes); + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(CouponTemplateDO::getProductScope, productScope) + .and(productScopeValue != null, w -> w.apply("FIND_IN_SET({0}, product_scope_values)", + productScopeValue)) + .and(canTakeConsumer != null, canTakeConsumer) + .last(" LIMIT " + count) + .orderByDesc(CouponTemplateDO::getId)); + } + + static Consumer> buildCanTakeQueryConsumer(List canTakeTypes) { + Consumer> canTakeConsumer = null; + if (CollUtil.isNotEmpty(canTakeTypes)) { + canTakeConsumer = w -> + w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的 + .in(CouponTemplateDO::getTakeType, canTakeTypes) // 2. 领取方式一致 + .and(ww -> ww.isNull(CouponTemplateDO::getValidEndTime) // 3. 未过期 + .or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now())) + .apply(" take_count < total_count "); // 4. 剩余数量大于 0 + } + return canTakeConsumer; + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java index ca3d4bd1a..7b7d1e1d9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponMatchReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; @@ -175,4 +176,13 @@ public interface CouponService { */ int expireCoupon(); + /** + * 获取用户是否可以领取优惠券 + * + * @param userId 用户编号 + * @param templates 优惠券列表 + * @return 是否可以领取 + */ + Map getUserCanCanTakeMap(Long userId, List templates); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java index 07d1f9e2c..68f5c53f8 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -36,7 +36,7 @@ import java.util.Set; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; import static java.util.Arrays.asList; @@ -229,6 +229,29 @@ public class CouponServiceImpl implements CouponService { return count; } + @Override + public Map getUserCanCanTakeMap(Long userId, List templates) { + Map userCanTakeMap = convertMap(templates, CouponTemplateDO::getId, templateId -> true); + // 未登录时,都显示可以领取 + if (userId == null) { + return userCanTakeMap; + } + + // 过滤领取数量无限制的 + Set templateIds = convertSet(templates, CouponTemplateDO::getId, template -> template.getTakeLimitCount() != -1); + + // 检查用户领取的数量是否超过限制 + if (CollUtil.isNotEmpty(templateIds)) { + Map couponTakeCountMap = this.getTakeCountMapByTemplateIds(templateIds, userId); + for (CouponTemplateDO template : templates) { + Integer takeCount = couponTakeCountMap.get(template.getId()); + userCanTakeMap.put(template.getId(), takeCount == null || takeCount < template.getTakeLimitCount()); + } + } + + return userCanTakeMap; + } + /** * 过期单个优惠劵 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java index c8f2accb7..cd16e3e54 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java @@ -78,4 +78,17 @@ public interface CouponTemplateService { * @return 优惠券模板列表 */ List getCouponTemplateByTakeType(CouponTakeTypeEnum takeType); + + /** + * 获得优惠券模板列表 + * + * @param canTakeTypes 可领取的类型列表 + * @param productScope 商品使用范围类型 + * @param productScopeValue 商品使用范围编号 + * @param count 查询数量 + * @return 优惠券模板列表 + */ + List getCouponTemplateList(List canTakeTypes, Integer productScope, + Long productScopeValue, Integer count); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java index 7a76e08d2..3f4c8ba76 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java @@ -120,4 +120,10 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { return couponTemplateMapper.selectListByTakeType(takeType.getValue()); } + @Override + public List getCouponTemplateList(List canTakeTypes, Integer productScope, + Long productScopeValue, Integer count) { + return couponTemplateMapper.selectList(canTakeTypes, productScope, productScopeValue, count); + } + } From cafa938ff4d4e619a911b3276af4bf713456ef85 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 22:21:47 +0800 Subject: [PATCH 08/15] =?UTF-8?q?common=EF=BC=9ALocalDateTimeUtils=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=B9=E6=B3=95=EF=BC=9A=E6=9C=88=E4=BB=BD?= =?UTF-8?q?=E5=BC=80=E5=A7=8B=E6=97=B6=E9=97=B4=E3=80=81=E6=9C=88=E4=BB=BD?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/date/LocalDateTimeUtils.java | 26 +++++++++++++++++++ .../trade/TradeStatisticsServiceImpl.java | 18 +++---------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index 6bbdcc7cf..527478941 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -6,6 +6,7 @@ import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.temporal.TemporalAdjusters; /** * 时间工具类,用于 {@link java.time.LocalDateTime} @@ -97,4 +98,29 @@ public class LocalDateTimeUtils { LocalDateTime.of(nowDate, startTime2), LocalDateTime.of(nowDate, endTime2)); } + /** + * 获取指定日期所在的月份的开始时间 + * 例如:2023-09-30 00:00:00,000 + * + * @param date 日期 + * @return 月份的开始时间 + */ + public static LocalDateTime beginOfMonth(LocalDateTime date) { + return date + .with(TemporalAdjusters.firstDayOfMonth()) + .with(LocalTime.MIN); + } + + /** + * 获取指定日期所在的月份的最后时间 + * 例如:2023-09-30 23:59:59,999 + * + * @param date 日期 + * @return 月份的结束时间 + */ + public static LocalDateTime endOfMonth(LocalDateTime date) { + return date + .with(TemporalAdjusters.lastDayOfMonth()) + .with(LocalTime.MAX); + } } diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java index 51db092ab..541120eb1 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.statistics.service.trade; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO; import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeSummaryRespVO; import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeTrendSummaryRespVO; @@ -13,8 +14,6 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.Duration; import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.temporal.TemporalAdjusters; import java.util.List; /** @@ -79,18 +78,9 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService { * @return 交易数据 */ private TradeSummaryRespBO getTradeSummaryByMonths(int months) { - // TODO @疯狂:可以在 LocalDateUtils 封装方法;获得月份的开始;以及结束两个方法;然后这里就可以直接调用了 - // 月份开始时间 - LocalDateTime beginOfMonth = LocalDateTime.now() - .plusMonths(months) - .with(TemporalAdjusters.firstDayOfMonth()) - .with(LocalTime.MIN); - // 月份截止时间 - LocalDateTime endOfToday = LocalDateTime.now() - .plusMonths(months) - .with(TemporalAdjusters.lastDayOfMonth()) - .with(LocalTime.MAX); - return tradeStatisticsMapper.selectOrderCreateCountSumAndOrderPayPriceSumByTimeBetween(beginOfMonth, endOfToday); + LocalDateTime monthDate = LocalDateTime.now().plusMonths(months); + return tradeStatisticsMapper.selectOrderCreateCountSumAndOrderPayPriceSumByTimeBetween( + LocalDateTimeUtils.beginOfMonth(monthDate), LocalDateTimeUtils.endOfMonth(monthDate)); } } From 7d68bdc7c83f97030134c5793516cc4da74ab038 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 23:30:06 +0800 Subject: [PATCH 09/15] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E4=B8=8B=E7=BA=A7=E5=88=86=E9=94=80=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../brokerage/BrokerageUserConvert.java | 5 +- .../mysql/brokerage/BrokerageUserMapper.java | 24 +++++- .../brokerage/BrokerageUserServiceImpl.java | 74 +++++++++++++++---- .../mapper/brokerage/BrokerageUserMapper.xml | 18 +++-- 4 files changed, 93 insertions(+), 28 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java index ef9daccca..aa4ba348d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokera import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryRespBO; -import com.baomidou.mybatisplus.core.metadata.IPage; import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.factory.Mappers; @@ -88,8 +87,8 @@ public interface BrokerageUserConvert { return respVO; } - default void copyTo(IPage pageResult, Map userMap) { - for (AppBrokerageUserChildSummaryRespVO vo : pageResult.getRecords()) { + default void copyTo(List list, Map userMap) { + for (AppBrokerageUserChildSummaryRespVO vo : list) { Optional.ofNullable(userMap.get(vo.getId())).ifPresent(user -> vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java index 3d07ea7c7..c17975677 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java @@ -138,13 +138,35 @@ public interface BrokerageUserMapper extends BaseMapperX { @Param("beginTime") LocalDateTime beginTime, @Param("endTime") LocalDateTime endTime); + /** + * 下级分销统计(分页) + * + * @param bizType 业务类型 + * @param status 状态 + * @param bindUserIds 绑定用户编号列表 + * @param sortingField 排序字段 + * @return 下级分销统计分页列表 + */ IPage selectSummaryPageByUserId(Page page, - @Param("ids") List ids, // BrokerageUser 的 ids 数组 @Param("bizType") Integer bizType, @Param("status") Integer status, @Param("bindUserIds") List bindUserIds, @Param("sortingField") SortingField sortingField); + /** + * 下级分销统计(不分页) + * + * @param bizType 业务类型 + * @param status 状态 + * @param bindUserIds 绑定用户编号列表 + * @param sortingField 排序字段 + * @return 下级分销统计列表 + */ + List selectSummaryListByUserId(@Param("bizType") Integer bizType, + @Param("status") Integer status, + @Param("bindUserIds") List bindUserIds, + @Param("sortingField") SortingField sortingField); + default List selectListByBindUserId(Long bindUserId) { return selectList(BrokerageUserDO::getBindUserId, bindUserId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java index 2cef31c5e..b24a5579b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java @@ -31,6 +31,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; @@ -225,25 +226,66 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @Override public PageResult getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) { - // 1.1 根据昵称过滤用户 - List ids = StrUtil.isBlank(pageReqVO.getNickname()) - ? Collections.emptyList() - : convertList(memberUserApi.getUserListByNickname(pageReqVO.getNickname()), MemberUserRespDTO::getId); - // 1.2 生成推广员编号列表 - // TODO @疯狂:是不是可以先 1.2 查询出来,然后查询对应的昵称,进行过滤?避免昵称过滤返回的 id 过多; + // 生成推广员编号列表 List bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel()); - // 2. 分页查询 - IPage pageResult = brokerageUserMapper.selectSummaryPageByUserId( - MyBatisUtils.buildPage(pageReqVO), ids, BrokerageRecordBizTypeEnum.ORDER.getType(), - BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField() - ); + // 情况一:没有昵称过滤条件时,直接使用数据库的分页查询 + if (StrUtil.isBlank(pageReqVO.getNickname())) { + // 1.1 分页查询 + IPage pageResult = brokerageUserMapper.selectSummaryPageByUserId( + MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(), + BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField() + ); - // 3. 拼接数据并返回 - List userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId); - Map userMap = memberUserApi.getUserMap(userIds); - BrokerageUserConvert.INSTANCE.copyTo(pageResult, userMap); - return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); + // 1.2 拼接数据并返回 + List userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId); + Map userMap = memberUserApi.getUserMap(userIds); + BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap); + return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); + } + + // 情况二:有昵称过滤条件时,需要跨模块(Member)过滤 + // 2.1 查询所有匹配的分销用户 + List list = brokerageUserMapper.selectSummaryListByUserId( + BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), + bindUserIds, pageReqVO.getSortingField() + ); + if (CollUtil.isEmpty(list)) { + return PageResult.empty(); + } + + // 2.2 查出对应的用户信息 + List users = memberUserApi.getUserList(convertList(list, AppBrokerageUserChildSummaryRespVO::getId)); + if (CollUtil.isEmpty(users)) { + return PageResult.empty(); + } + + // 2.3 根据昵称过滤出用户编号 + Map userMap = users.stream() + .filter(user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname())) + .collect(Collectors.toMap(MemberUserRespDTO::getId, dto -> dto)); + if (CollUtil.isEmpty(userMap)) { + return PageResult.empty(); + } + + // 2.4 根据用户编号过滤结果 + list.removeIf(vo -> !userMap.containsKey(vo.getId())); + if (CollUtil.isEmpty(list)) { + return PageResult.empty(); + } + + // 2.5 处理分页 + List result = list.stream() + .skip((long) (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize()) + .limit(pageReqVO.getPageSize()) + .collect(Collectors.toList()); + if (CollUtil.isEmpty(result)) { + return PageResult.empty(); + } + + // 2.6 拼接数据并返回 + BrokerageUserConvert.INSTANCE.copyTo(result, userMap); + return new PageResult<>(result, (long) list.size()); } private boolean isUserCanBind(BrokerageUserDO user) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml b/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml index aa22e4f14..362cf7621 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml @@ -2,8 +2,7 @@ - + + + From a04a3a27a9e79d3e6d5cb99a41b4134419fc164a Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 30 Sep 2023 23:41:11 +0800 Subject: [PATCH 10/15] =?UTF-8?q?Review=E4=BB=A3=E7=A0=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dal/mysql/coupon/CouponMapper.java | 20 +++++++++------ .../service/coupon/CouponService.java | 25 +++---------------- .../service/coupon/CouponServiceImpl.java | 11 +++----- .../service/coupon/bo/CouponTakeCountBO.java | 22 ---------------- .../trade/TradeStatisticsController.java | 2 -- 5 files changed, 19 insertions(+), 61 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java index f5a8ce4e8..e5f1daf6c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; -import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.github.yulichang.toolkit.MPJWrappers; import org.apache.ibatis.annotations.Mapper; @@ -16,9 +15,12 @@ import org.apache.ibatis.annotations.Mapper; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + /** * 优惠劵 Mapper * @@ -70,14 +72,16 @@ public interface CouponMapper extends BaseMapperX { ); } - // TODO @疯狂:这个是不是搞个 Map 就可以呀? - default List selectCountByUserIdAndTemplateIdIn(Long userId, Collection templateIds) { - return BeanUtil.copyToList(selectMaps(MPJWrappers.lambdaJoin(CouponDO.class) - .select(CouponDO::getTemplateId) - .selectCount(CouponDO::getId, CouponTakeCountBO::getCount) + default Map selectCountByUserIdAndTemplateIdIn(Long userId, Collection templateIds) { + String templateIdAlias = "templateId"; + String countAlias = "count"; + List> list = selectMaps(MPJWrappers.lambdaJoin(CouponDO.class) + .selectAs(CouponDO::getTemplateId, templateIdAlias) + .selectCount(CouponDO::getId, countAlias) .eq(CouponDO::getUserId, userId) .in(CouponDO::getTemplateId, templateIds) - .groupBy(CouponDO::getTemplateId)), CouponTakeCountBO.class); + .groupBy(CouponDO::getTemplateId)); + return convertMap(list, map -> MapUtil.getLong(map, templateIdAlias), map -> MapUtil.getInt(map, countAlias)); } default List selectListByUserIdAndStatusAndUsePriceLeAndProductScope( diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java index 7b7d1e1d9..7cc13e2ce 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java @@ -1,18 +1,16 @@ package cn.iocoder.yudao.module.promotion.service.coupon; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponMatchReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; -import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; import java.util.*; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - /** * 优惠劵 Service 接口 * @@ -132,11 +130,8 @@ public interface CouponService { * @return 领取优惠券的数量 */ default Integer getTakeCount(Long templateId, Long userId) { - return CollUtil.emptyIfNull(getTakeCountListByTemplateIds(Collections.singleton(templateId), userId)) - .stream() - .findFirst() - .map(CouponTakeCountBO::getCount) - .orElse(0); + Map map = getTakeCountMapByTemplateIds(Collections.singleton(templateId), userId); + return MapUtil.getInt(map, templateId, 0); } /** @@ -146,19 +141,7 @@ public interface CouponService { * @param userId 用户编号 * @return 领取优惠券的数量 */ - default Map getTakeCountMapByTemplateIds(Collection templateIds, Long userId) { - return convertMap(getTakeCountListByTemplateIds(templateIds, userId), - CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount); - } - - /** - * 统计会员领取优惠券的数量 - * - * @param templateIds 优惠券模板编号列表 - * @param userId 用户编号 - * @return 领取优惠券的数量 - */ - List getTakeCountListByTemplateIds(Collection templateIds, Long userId); + Map getTakeCountMapByTemplateIds(Collection templateIds, Long userId); /** * 获取用户匹配的优惠券列表 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java index 68f5c53f8..8be928476 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.service.coupon; import cn.hutool.core.collection.CollStreamUtil; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -21,7 +20,6 @@ import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponMapper; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; -import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,10 +27,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -191,9 +186,9 @@ public class CouponServiceImpl implements CouponService { } @Override - public List getTakeCountListByTemplateIds(Collection templateIds, Long userId) { + public Map getTakeCountMapByTemplateIds(Collection templateIds, Long userId) { if (CollUtil.isEmpty(templateIds)) { - return ListUtil.empty(); + return Collections.emptyMap(); } return couponMapper.selectCountByUserIdAndTemplateIdIn(userId, templateIds); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java deleted file mode 100644 index 6e563ffb5..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.coupon.bo; - -import lombok.Data; - -/** - * 优惠券领取数量 BO - * - * @author owen - */ -@Data -public class CouponTakeCountBO { - - /** - * 优惠劵模板编号 - */ - private Long templateId; - /** - * 领取数量 - */ - private Integer count; - -} diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java index 158e5ac95..aa5b711cb 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java @@ -32,7 +32,6 @@ public class TradeStatisticsController { @Resource private TradeStatisticsService tradeStatisticsService; - // TODO @疯狂:要不这个就是 /trend/summary 的特例,前端自己查询两次? @GetMapping("/summary") @Operation(summary = "获得交易统计") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") @@ -40,7 +39,6 @@ public class TradeStatisticsController { return success(tradeStatisticsService.getTradeSummaryComparison()); } - // TODO @疯狂:直接 comparison?主要 trend 和 comparison 二选一,一个是数据趋势,一个是数据对比哈; @GetMapping("/trend/summary") @Operation(summary = "获得交易状况统计") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") From 4f03635fcd71ed032ecb5e41ccfd5838223b1140 Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 1 Oct 2023 09:53:54 +0800 Subject: [PATCH 11/15] =?UTF-8?q?=E7=AD=BE=E5=88=B0=EF=BC=9A=E7=AD=BE?= =?UTF-8?q?=E5=88=B0=E5=90=8E=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E3=80=81=E7=BB=8F=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 34 +++++----- .../member/enums/ErrorCodeConstants.java | 1 + .../vo/config/MemberSignInConfigBaseVO.java | 7 ++ .../vo/record/MemberSignInRecordRespVO.java | 2 +- .../app/signin/AppMemberSignInController.java | 14 +--- .../AppMemberSignInRecordController.java | 9 +-- .../vo/AppMemberSignInRecordRespVO.java | 5 +- .../record/AppMemberSignInRecordRespVO.java | 3 + .../signin/MemberSignInConfigDO.java | 4 ++ .../signin/MemberSignInRecordDO.java | 8 ++- .../service/level/MemberLevelServiceImpl.java | 3 +- .../point/MemberPointRecordServiceImpl.java | 3 + .../signin/MemberSignInConfigServiceImpl.java | 19 ++++-- .../signin/MemberSignInRecordServiceImpl.java | 67 +++++++++++++------ 14 files changed, 112 insertions(+), 67 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 941694e3c..4c90d7130 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -788,7 +788,7 @@ CREATE TABLE `member_level_record` ( `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号', `level_id` bigint NOT NULL DEFAULT 0 COMMENT '等级编号', `level` int NOT NULL DEFAULT 0 COMMENT '会员等级', - `discount_percent` tinyint NOT NULL DEFAULT 100 COMMENT '享受折扣', + `discount_percent` int NOT NULL DEFAULT 100 COMMENT '享受折扣', `experience` int NOT NULL DEFAULT 0 COMMENT '升级经验', `user_experience` int NOT NULL DEFAULT 0 COMMENT '会员此时的经验', `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备注', @@ -888,7 +888,8 @@ DROP TABLE IF EXISTS `member_sign_in_config`; CREATE TABLE `member_sign_in_config` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '编号', `day` int NOT NULL COMMENT '第几天', - `point` int NOT NULL COMMENT '奖励积分', + `point` int NOT NULL DEFAULT 0 COMMENT '奖励积分', + `experience` int NOT NULL DEFAULT 0 COMMENT '奖励经验', `status` tinyint NOT NULL COMMENT '状态', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', @@ -903,18 +904,18 @@ CREATE TABLE `member_sign_in_config` ( -- Records of member_sign_in_config -- ---------------------------- BEGIN; -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 1, 10, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 2, 20, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 7, 1001, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 6, 12121, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 2, 12, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 10, 0, '1', '2023-08-20 19:20:42', '1', '2023-08-20 19:20:56', b'0', 1); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 7, 22, 0, '1', '2023-08-20 19:20:48', '1', '2023-08-20 19:20:48', b'0', 1); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 2, 3, 0, '1', '2023-08-21 20:22:44', '1', '2023-08-21 20:22:44', b'0', 1); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 3, 4, 0, '1', '2023-08-21 20:22:48', '1', '2023-08-21 20:22:48', b'0', 1); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 4, 5, 0, '1', '2023-08-21 20:22:51', '1', '2023-08-21 20:22:51', b'0', 1); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 5, 6, 0, '1', '2023-08-21 20:22:56', '1', '2023-08-21 20:22:56', b'0', 1); -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 6, 7, 0, '1', '2023-08-21 20:22:59', '1', '2023-08-21 20:22:59', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 1, 10, 10, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 2, 20, 20, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 7, 1001, 1001, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 6, 12121, 12121, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 3, 12, 12, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 10, 10, 0, '1', '2023-08-20 19:20:42', '1', '2023-08-20 19:20:56', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 7, 22, 22, 0, '1', '2023-08-20 19:20:48', '1', '2023-08-20 19:20:48', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 2, 3, 3, 0, '1', '2023-08-21 20:22:44', '1', '2023-08-21 20:22:44', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 3, 4, 4, 0, '1', '2023-08-21 20:22:48', '1', '2023-08-21 20:22:48', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 4, 5, 5, 0, '1', '2023-08-21 20:22:51', '1', '2023-08-21 20:22:51', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 5, 6, 6, 0, '1', '2023-08-21 20:22:56', '1', '2023-08-21 20:22:56', b'0', 1); +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 6, 7, 7, 0, '1', '2023-08-21 20:22:59', '1', '2023-08-21 20:22:59', b'0', 1); COMMIT; -- ---------------------------- @@ -925,7 +926,8 @@ CREATE TABLE `member_sign_in_record` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '签到自增id', `user_id` int NULL DEFAULT NULL COMMENT '签到用户', `day` int NULL DEFAULT NULL COMMENT '第几天签到', - `point` int NULL DEFAULT NULL COMMENT '签到的分数', + `point` int NOT NULL DEFAULT 0 COMMENT '签到的积分', + `experience` int NOT NULL DEFAULT 0 COMMENT '签到的经验', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -935,6 +937,8 @@ CREATE TABLE `member_sign_in_record` ( PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '签到记录'; +CREATE INDEX user_id_index ON member_sign_in_record (user_id); + -- ---------------------------- -- Records of member_sign_in_record -- ---------------------------- diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java index 7ac1dac95..ba5554bc4 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java @@ -38,6 +38,7 @@ public interface ErrorCodeConstants { //========== 签到配置 1-004-009-000 ========== ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在"); ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在"); + ErrorCode SIGN_IN_CONFIG_AWARD_EMPTY = new ErrorCode(1_004_009_002, "签到奖励积分和经验不能同时为空"); //========== 签到配置 1-004-010-000 ========== ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000,"今日已签到,请勿重复签到"); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java index c69f24d39..e83c487cf 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; +import javax.validation.constraints.PositiveOrZero; /** * 签到规则 Base VO,提供给添加、修改、详细的子 VO 使用 @@ -20,8 +21,14 @@ public class MemberSignInConfigBaseVO { @Schema(description = "奖励积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") @NotNull(message = "奖励积分不能为空") + @PositiveOrZero(message = "奖励积分不能小于 0") private Integer point; + @Schema(description = "奖励经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @NotNull(message = "奖励经验不能为空") + @PositiveOrZero(message = "奖励经验不能小于 0") + private Integer experience; + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "状态不能为空") @InEnum(CommonStatusEnum.class) diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/record/MemberSignInRecordRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/record/MemberSignInRecordRespVO.java index abe6eefed..b5755ba53 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/record/MemberSignInRecordRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/record/MemberSignInRecordRespVO.java @@ -21,7 +21,7 @@ public class MemberSignInRecordRespVO { @Schema(description = "第几天签到", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer day; - @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @Schema(description = "签到的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private Integer point; @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java index b3dcfa5f5..ec5e0a4a8 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java @@ -1,13 +1,10 @@ package cn.iocoder.yudao.module.member.controller.app.signin; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; import cn.iocoder.yudao.module.member.service.signin.MemberSignInRecordService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -29,17 +26,8 @@ public class AppMemberSignInController { // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 getSignInRecordSummary 里哈。 @Operation(summary = "个人签到信息") @GetMapping("/get-summary") - public CommonResult getUserSummary(){ + public CommonResult getUserSummary() { return success(signInRecordService.getSignInRecordSummary(getLoginUserId())); } - // TODO @xiaqing:泛型: - // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 createSignInRecord 里哈。 - @Operation(summary = "会员签到") - @PostMapping("/create") - public CommonResult create(){ - MemberSignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId()); - return success(MemberSignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO)); - } - } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java index 9f0c9604d..fa07d85ec 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java @@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -50,16 +49,12 @@ public class AppMemberSignInRecordController { return success(respVO); } - // TODO 芋艿:临时 mock => UserSignController.info @PostMapping("/create") @Operation(summary = "签到") @PreAuthenticated public CommonResult createSignInRecord() { - AppMemberSignInRecordRespVO respVO = new AppMemberSignInRecordRespVO() - .setPoint(10) - .setDay(10) - .setCreateTime(LocalDateTime.now()); - return success(respVO); + MemberSignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId()); + return success(MemberSignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO)); } @GetMapping("/page") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java index e7ea26c2d..c31e365ec 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java @@ -12,9 +12,12 @@ public class AppMemberSignInRecordRespVO { @Schema(description = "第几天签到", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer day; - @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @Schema(description = "签到的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private Integer point; + @Schema(description = "签到的经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + private Integer experience; + @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/record/AppMemberSignInRecordRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/record/AppMemberSignInRecordRespVO.java index 287408ce6..2d910d0c6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/record/AppMemberSignInRecordRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/record/AppMemberSignInRecordRespVO.java @@ -15,6 +15,9 @@ public class AppMemberSignInRecordRespVO { @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private Integer point; + @Schema(description = "签到的经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + private Integer experience; + @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInConfigDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInConfigDO.java index ec0137912..76d55c9bf 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInConfigDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInConfigDO.java @@ -35,6 +35,10 @@ public class MemberSignInConfigDO extends BaseDO { * 奖励积分 */ private Integer point; + /** + * 奖励经验 + */ + private Integer experience; /** * 状态 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInRecordDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInRecordDO.java index ccd61d7c4..b07b5efbc 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInRecordDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInRecordDO.java @@ -35,10 +35,12 @@ public class MemberSignInRecordDO extends BaseDO { */ private Integer day; /** - * 签到的分数 + * 签到的积分 */ private Integer point; - - // TODO 疯狂:签到的经验 + /** + * 签到的经验 + */ + private Integer experience; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java index 79674430e..c98dd4b97 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java @@ -239,7 +239,8 @@ public class MemberLevelServiceImpl implements MemberLevelService { // 1. 创建经验记录 MemberUserDO user = memberUserService.getUser(userId); - int userExperience = NumberUtil.max(user.getExperience() + experience, 0); // 防止扣出负数 + Integer userExperience = ObjUtil.defaultIfNull(user.getExperience(), 0); + userExperience = NumberUtil.max(userExperience + experience, 0); // 防止扣出负数 MemberLevelRecordDO levelRecord = new MemberLevelRecordDO() .setUserId(user.getId()) .setExperience(experience) diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java index da67a9ec2..e665bdf13 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java @@ -66,6 +66,9 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { @Override @Transactional(rollbackFor = Exception.class) public void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId) { + if (point == 0) { + return; + } // 1. 校验用户积分余额 MemberUserDO user = memberUserService.getUser(userId); Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java index 52f01d98e..1687ed404 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java @@ -11,10 +11,10 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Comparator; import java.util.List; +import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_EXISTS; -import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_NOT_EXISTS; +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; /** * 签到规则 Service 实现类 @@ -30,6 +30,8 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @Override public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) { + // 校验奖励积分、奖励经验 + validatePointAndExperience(createReqVO.getPoint(), createReqVO.getExperience()); // 判断是否重复插入签到天数 validateSignInConfigDayDuplicate(createReqVO.getDay(), null); @@ -42,6 +44,8 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @Override public void updateSignInConfig(MemberSignInConfigUpdateReqVO updateReqVO) { + // 校验奖励积分、奖励经验 + validatePointAndExperience(updateReqVO.getPoint(), updateReqVO.getExperience()); // 校验存在 validateSignInConfigExists(updateReqVO.getId()); // 判断是否重复插入签到天数 @@ -70,7 +74,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService * 校验 day 是否重复 * * @param day 天 - * @param id 编号,只有更新的时候会传递 + * @param id 编号,只有更新的时候会传递 */ private void validateSignInConfigDayDuplicate(Integer day, Long id) { MemberSignInConfigDO config = memberSignInConfigMapper.selectByDay(day); @@ -84,13 +88,20 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService } } + private void validatePointAndExperience(Integer point, Integer experience) { + // 奖励积分、经验 至少要配置一个,否则没有意义 + if (Objects.equals(point, 0) && Objects.equals(experience, 0)) { + throw exception(SIGN_IN_CONFIG_AWARD_EMPTY); + } + } + @Override public MemberSignInConfigDO getSignInConfig(Long id) { return memberSignInConfigMapper.selectById(id); } @Override - public List getSignInConfigList() { + public List getSignInConfigList() { List list = memberSignInConfigMapper.selectList(); list.sort(Comparator.comparing(MemberSignInConfigDO::getDay)); return list; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java index dc1646447..dca079dc2 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.signin; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; @@ -13,8 +14,13 @@ import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInConfigMapper; import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper; import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; +import cn.iocoder.yudao.module.member.service.level.MemberLevelService; +import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.validation.annotation.Validated; @@ -40,20 +46,24 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService private MemberSignInRecordMapper signInRecordMapper; @Resource private MemberSignInConfigMapper signInConfigMapper; + @Resource + private MemberPointRecordService pointRecordService; + @Resource + private MemberLevelService memberLevelService; @Resource private MemberUserApi memberUserApi; @Override public AppMemberSignInSummaryRespVO getSignInRecordSummary(Long userId) { - AppMemberSignInSummaryRespVO vo = new AppMemberSignInSummaryRespVO(); + AppMemberSignInSummaryRespVO vo = new AppMemberSignInSummaryRespVO(); vo.setTotalDay(0); vo.setContinuousDay(0); vo.setTodaySignIn(false); //获取用户签到的记录,按照天数倒序获取 - List signInRecordDOList = signInRecordMapper.selectListByUserId(userId); + List signInRecordDOList = signInRecordMapper.selectListByUserId(userId); // TODO @xiaqing:if 空的时候,直接 return;这样括号少,逻辑更简洁; - if(!CollectionUtils.isEmpty(signInRecordDOList)){ + if (!CollectionUtils.isEmpty(signInRecordDOList)) { //设置总签到天数 vo.setTotalDay(signInRecordDOList.size()); // TODO @xiaqing:是不是不用读取 signInRecordDOList 所有的,而是 count下,然后另外再读取一条最后一条; //判断当天是否有签到复用校验方法 @@ -61,11 +71,11 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService try { validSignDay(signInRecordDOList.get(0)); vo.setTodaySignIn(false); - }catch (Exception e){ + } catch (Exception e) { vo.setTodaySignIn(true); } //如果当天签到了则说明连续签到天数有意义,否则直接用默认值0 - if(vo.getTodaySignIn()){ + if (vo.getTodaySignIn()) { //下方计算连续签到从2天开始,此处直接设置一天连续签到 vo.setContinuousDay(1); //判断连续签到天数 @@ -73,10 +83,10 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService for (int i = 1; i < signInRecordDOList.size(); i++) { //前一天减1等于当前天数则说明连续,继续循环 LocalDate cur = signInRecordDOList.get(i).getCreateTime().toLocalDate(); - LocalDate pre = signInRecordDOList.get(i-1).getCreateTime().toLocalDate(); - if(1==daysBetween(cur,pre)){ - vo.setContinuousDay(i+1); - }else{ + LocalDate pre = signInRecordDOList.get(i - 1).getCreateTime().toLocalDate(); + if (1 == daysBetween(cur, pre)) { + vo.setContinuousDay(i + 1); + } else { break; } } @@ -87,16 +97,16 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService return vo; } - private long daysBetween(LocalDate date1,LocalDate date2){ + private long daysBetween(LocalDate date1, LocalDate date2) { return ChronoUnit.DAYS.between(date1, date2); } @Override - public PageResult getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { + public PageResult getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { // 根据用户昵称查询出用户ids - Set userIds = null; + Set userIds = null; if (StringUtils.isNotBlank(pageReqVO.getNickname())) { - List users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); + List users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); // 如果查询用户结果为空直接返回无需继续查询 if (CollectionUtils.isEmpty(users)) { return PageResult.empty(); @@ -113,50 +123,63 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService } @Override + @Transactional(rollbackFor = Exception.class) public MemberSignInRecordDO createSignRecord(Long userId) { // 获取当前用户签到的最大天数 // TODO @xiaqing:db 操作,dou封装到 mapper 中; // TODO @xiaqing:maxSignDay,是不是变量叫 lastRecord 会更容易理解哈; - MemberSignInRecordDO maxSignDay = signInRecordMapper.selectOne(new LambdaQueryWrapperX () + MemberSignInRecordDO maxSignDay = signInRecordMapper.selectOne(new LambdaQueryWrapperX() .eq(MemberSignInRecordDO::getUserId, userId) .orderByDesc(MemberSignInRecordDO::getDay) .last("limit 1")); // 判断是否重复签到 validSignDay(maxSignDay); - // TODO @xiaqing:可以使用 // 进行注释 - /**1.查询出当前签到的天数**/ + // 1. 查询出当前签到的天数 MemberSignInRecordDO sign = new MemberSignInRecordDO().setUserId(userId); // TODO @xiaqing:应该使用 record 变量,会更合适 sign.setDay(1); // 设置签到初始化天数 - sign.setPoint(0); // 设置签到分数默认为 0 + sign.setPoint(0); // 设置签到积分默认为 0 + sign.setExperience(0); // 设置签到经验默认为 0 // 如果不为空则修改当前签到对应的天数 // TODO @xiaqing:应该是要判断连续哈,就是昨天; if (maxSignDay != null) { sign.setDay(maxSignDay.getDay() + 1); } - /**2.获取签到对应的分数**/ + // 2. 获取签到对应的积分数 // 获取所有的签到规则,按照天数排序,只获取启用的 TODO @xiaqing:不要使用 signInConfigMapper 直接查询,而是要通过 SigninConfigService; - List configDOList = signInConfigMapper.selectList(new LambdaQueryWrapperX () + List configDOList = signInConfigMapper.selectList(new LambdaQueryWrapperX() .eq(MemberSignInConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) .orderByAsc(MemberSignInConfigDO::getDay)); - // 如果签到的天数大于最大启用的规则天数,直接给最大签到的分数 + // 如果签到的天数大于最大启用的规则天数,直接给最大签到的积分数 // TODO @xiaqing:超过最大配置的天数,应该直接重置到第一天哈; MemberSignInConfigDO lastConfig = configDOList.get(configDOList.size() - 1); if (sign.getDay() > lastConfig.getDay()) { sign.setPoint(lastConfig.getPoint()); + sign.setExperience(lastConfig.getExperience()); } else { configDOList.forEach(el -> { - // 循环匹配对应天数,设置对应分数 + // 循环匹配对应天数,设置对应积分数 // TODO @xiaqing:使用 equals;另外,这种不应该去遍历比较,从可读性来说,应该 CollUtil.findOne() if (el.getDay() == sign.getDay()) { sign.setPoint(el.getPoint()); + sign.setExperience(el.getExperience()); } }); } - // 3. 插入当前签到获取的分数 + // 3. 插入签到记录 signInRecordMapper.insert(sign); + + // 4. 增加积分 + if (!ObjectUtils.equalsAny(sign.getPoint(), null, 0)) { + pointRecordService.createPointRecord(userId, sign.getPoint(), MemberPointBizTypeEnum.SIGN, String.valueOf(sign.getId())); + } + // 5. 增加经验 + if (!ObjectUtils.equalsAny(sign.getPoint(), null, 0)) { + memberLevelService.addExperience(userId, sign.getExperience(), MemberExperienceBizTypeEnum.SIGN_IN, String.valueOf(sign.getId())); + } + return sign; } From ab35fcbe9b113dddb1205bd004c0b7fd77c89bf4 Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 1 Oct 2023 10:25:18 +0800 Subject: [PATCH 12/15] =?UTF-8?q?=E4=BC=9A=E5=91=98=EF=BC=9A=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E9=85=8D=E7=BD=AE=E6=94=B9=E4=B8=BA=E4=BC=9A=E5=91=98?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 23 +++++----- .../calculator/TradePointGiveCalculator.java | 10 ++--- .../TradePointUsePriceCalculator.java | 12 ++--- .../member/api/config/MemberConfigApi.java | 18 ++++++++ .../dto/MemberConfigRespDTO.java} | 4 +- .../member/api/point/MemberPointApi.java | 9 ---- .../api/config/MemberConfigApiImpl.java | 28 ++++++++++++ .../member/api/point/MemberPointApiImpl.java | 10 ----- .../admin/config/MemberConfigController.java | 45 +++++++++++++++++++ .../vo/MemberConfigBaseVO.java} | 6 +-- .../vo/MemberConfigRespVO.java} | 6 +-- .../config/vo/MemberConfigSaveReqVO.java | 13 ++++++ .../point/MemberPointConfigController.java | 45 ------------------- .../vo/config/MemberPointConfigSaveReqVO.java | 13 ------ .../convert/config/MemberConfigConvert.java | 25 +++++++++++ .../point/MemberPointConfigConvert.java | 25 ----------- .../MemberConfigDO.java} | 10 ++--- .../dal/mysql/config/MemberConfigMapper.java | 14 ++++++ .../mysql/point/MemberPointConfigMapper.java | 14 ------ .../service/config/MemberConfigService.java | 29 ++++++++++++ .../config/MemberConfigServiceImpl.java | 44 ++++++++++++++++++ .../point/MemberPointConfigService.java | 29 ------------ .../point/MemberPointConfigServiceImpl.java | 44 ------------------ 23 files changed, 251 insertions(+), 225 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApi.java rename yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/{point/dto/MemberPointConfigRespDTO.java => config/dto/MemberConfigRespDTO.java} (83%) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApiImpl.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/MemberConfigController.java rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/{point/vo/config/MemberPointConfigBaseVO.java => config/vo/MemberConfigBaseVO.java} (84%) rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/{point/vo/config/MemberPointConfigRespVO.java => config/vo/MemberConfigRespVO.java} (60%) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigSaveReqVO.java delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/config/MemberConfigConvert.java delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/{point/MemberPointConfigDO.java => config/MemberConfigDO.java} (69%) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/config/MemberConfigMapper.java delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigService.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigServiceImpl.java delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java delete mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 4c90d7130..d4b500e91 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -810,10 +810,10 @@ BEGIN; COMMIT; -- ---------------------------- --- Table structure for member_point_config +-- Table structure for member_config -- ---------------------------- -DROP TABLE IF EXISTS `member_point_config`; -CREATE TABLE `member_point_config` ( +DROP TABLE IF EXISTS `member_config`; +CREATE TABLE `member_config` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键', `trade_deduct_enable` bit(1) NOT NULL COMMENT '是否开启积分抵扣', `trade_deduct_unit_price` int NOT NULL COMMENT '积分抵扣(单位:分)', @@ -826,13 +826,13 @@ CREATE TABLE `member_point_config` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员积分配置表'; +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员配置表'; -- ---------------------------- --- Records of member_point_config +-- Records of member_config -- ---------------------------- BEGIN; -INSERT INTO `member_point_config` (`id`, `trade_deduct_enable`, `trade_deduct_unit_price`, `trade_deduct_max_price`, `trade_give_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, b'1', 100, 2, 3, '1', '2023-08-20 09:54:42', '1', '2023-08-20 09:54:42', b'0', 1); +INSERT INTO `member_config` (`id`, `trade_deduct_enable`, `trade_deduct_unit_price`, `trade_deduct_max_price`, `trade_give_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, b'1', 100, 2, 3, '1', '2023-08-20 09:54:42', '1', '2023-08-20 09:54:42', b'0', 1); COMMIT; -- ---------------------------- @@ -1957,20 +1957,19 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2184, '自提门店导出', 'trade:delivery:pick-up-store:export', 3, 5, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2209, '秒杀活动', '', 2, 3, 2030, 'seckill', 'ep:place', '', '', 0, b'1', b'1', b'1', '1', '2023-06-24 17:39:13', '1', '2023-06-24 18:55:15', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2262, '会员中心', '', 1, 55, 0, '/member', 'ep:bicycle', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-06-10 00:42:03', '1', '2023-08-20 09:23:56', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2275, '积分配置', '', 2, 0, 2299, 'config', 'fa:archive', 'member/point/config/index', 'PointConfig', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-08-20 12:01:20', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2276, '积分设置查询', 'point:config:query', 3, 1, 2275, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '', '2023-06-10 02:07:44', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2277, '积分设置创建', 'point:config:save', 3, 2, 2275, '', '', '', '', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-06-27 20:32:31', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2275, '会员配置', '', 2, 0, 2262, 'config', 'fa:archive', 'member/config/index', 'MemberConfig', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-08-20 12:01:20', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2276, '会员配置查询', 'member:config:query', 3, 1, 2275, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '', '2023-06-10 02:07:44', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2277, '会员配置创建', 'member:config:save', 3, 2, 2275, '', '', '', '', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-06-27 20:32:31', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2281, '签到配置', '', 2, 2, 2300, 'config', 'ep:calendar', 'member/signin/config/index', 'SignInConfig', 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '1', '2023-08-20 19:25:51', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2282, '积分签到规则查询', 'point:sign-in-config:query', 3, 1, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2283, '积分签到规则创建', 'point:sign-in-config:create', 3, 2, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2284, '积分签到规则更新', 'point:sign-in-config:update', 3, 3, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2285, '积分签到规则删除', 'point:sign-in-config:delete', 3, 4, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2287, '积分记录', '', 2, 1, 2299, 'record', 'fa:asterisk', 'member/point/record/index', 'PointRecord', 0, b'1', b'1', b'1', '', '2023-06-10 04:18:50', '1', '2023-08-20 12:01:42', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2288, '用户积分记录查询', 'point:record:query', 3, 1, 2287, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:18:50', '', '2023-06-10 04:18:50', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2287, '会员积分', '', 2, 1, 2262, 'point', 'ep:pointer', 'member/point/record/index', 'PointRecord', 0, b'1', b'1', b'1', '', '2023-06-10 04:18:50', '1', '2023-08-20 12:01:42', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2288, '会员积分记录查询', 'point:record:query', 3, 1, 2287, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:18:50', '', '2023-06-10 04:18:50', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2293, '签到记录', '', 2, 3, 2300, 'record', 'ep:chicken', 'member/signin/record/index', 'SignInRecord', 0, b'1', b'1', b'1', '', '2023-06-10 04:48:22', '1', '2023-08-20 19:26:02', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2294, '用户签到积分查询', 'point:sign-in-record:query', 3, 1, 2293, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:48:22', '', '2023-06-10 04:48:22', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2297, '用户签到积分删除', 'point:sign-in-record:delete', 3, 4, 2293, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:48:22', '', '2023-06-10 04:48:22', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2299, '会员积分', '', 1, 10, 2262, 'point', 'ep:pointer', '', '', 0, b'1', b'1', b'1', '1', '2023-06-27 22:48:51', '1', '2023-08-20 09:23:35', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2300, '会员签到', '', 1, 11, 2262, 'signin', 'ep:alarm-clock', '', '', 0, b'1', b'1', b'1', '1', '2023-06-27 22:49:53', '1', '2023-08-20 09:23:48', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2301, '回调通知', '', 2, 4, 1117, 'notify', 'example', 'pay/notify/index', 'PayNotify', 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '1', '2023-07-20 13:45:08', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2302, '支付通知查询', 'pay:notify:query', 3, 1, 2301, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '', '2023-07-20 04:41:32', b'0'); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java index d93d04582..7644272de 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; import cn.hutool.core.util.BooleanUtil; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; -import cn.iocoder.yudao.module.member.api.point.MemberPointApi; -import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO; +import cn.iocoder.yudao.module.member.api.config.MemberConfigApi; +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import lombok.extern.slf4j.Slf4j; @@ -28,14 +28,14 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. public class TradePointGiveCalculator implements TradePriceCalculator { @Resource - private MemberPointApi memberPointApi; + private MemberConfigApi memberConfigApi; @Override public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { // 1.1 校验积分功能是否开启 - int givePointPerYuan = Optional.ofNullable(memberPointApi.getConfig()) + int givePointPerYuan = Optional.ofNullable(memberConfigApi.getConfig()) .filter(config -> BooleanUtil.isTrue(config.getTradeDeductEnable())) - .map(MemberPointConfigRespDTO::getTradeGivePoint) + .map(MemberConfigRespDTO::getTradeGivePoint) .orElse(0); if (givePointPerYuan <= 0) { return; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java index 66fdb0fb0..ffba5b4ee 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.member.api.point.MemberPointApi; -import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO; +import cn.iocoder.yudao.module.member.api.config.MemberConfigApi; +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; 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.enums.common.PromotionTypeEnum; @@ -32,7 +32,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCU public class TradePointUsePriceCalculator implements TradePriceCalculator { @Resource - private MemberPointApi memberPointApi; + private MemberConfigApi memberConfigApi; @Resource private MemberUserApi memberUserApi; @@ -44,7 +44,7 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { return; } // 1.2 校验积分抵扣是否开启 - MemberPointConfigRespDTO config = memberPointApi.getConfig(); + MemberConfigRespDTO config = memberConfigApi.getConfig(); if (!isDeductPointEnable(config)) { return; } @@ -76,13 +76,13 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { TradePriceCalculatorHelper.recountAllPrice(result); } - private boolean isDeductPointEnable(MemberPointConfigRespDTO config) { + private boolean isDeductPointEnable(MemberConfigRespDTO config) { return config != null && !BooleanUtil.isTrue(config.getTradeDeductEnable()) && // 积分功能是否启用 config.getTradeDeductUnitPrice() != null && config.getTradeDeductUnitPrice() > 0; // 有没有配置:1 积分抵扣多少分 } - private Integer calculatePointPrice(MemberPointConfigRespDTO config, Integer usePoint, TradePriceCalculateRespBO result) { + private Integer calculatePointPrice(MemberConfigRespDTO config, Integer usePoint, TradePriceCalculateRespBO result) { // 每个订单最多可以使用的积分数量 if (config.getTradeDeductMaxPrice() != null && config.getTradeDeductMaxPrice() > 0) { usePoint = Math.min(usePoint, config.getTradeDeductMaxPrice()); diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApi.java new file mode 100644 index 000000000..dab7f6877 --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApi.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.member.api.config; + +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; + +/** + * 用户配置 API 接口 + * + * @author owen + */ +public interface MemberConfigApi { + + /** + * 获得积分配置 + * + * @return 积分配置 + */ + MemberConfigRespDTO getConfig(); +} diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/dto/MemberPointConfigRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java similarity index 83% rename from yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/dto/MemberPointConfigRespDTO.java rename to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java index aaa9a3fcf..8ce517964 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/dto/MemberPointConfigRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.member.api.point.dto; +package cn.iocoder.yudao.module.member.api.config.dto; import lombok.Data; @@ -8,7 +8,7 @@ import lombok.Data; * @author 芋道源码 */ @Data -public class MemberPointConfigRespDTO { +public class MemberConfigRespDTO { /** * 积分抵扣开关 diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java index 9cfbda0a1..3eb749fb6 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.member.api.point; -import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO; import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; import javax.validation.constraints.Min; @@ -12,14 +11,6 @@ import javax.validation.constraints.Min; */ public interface MemberPointApi { - // TODO @疯狂:这个我们要不要搞成通用的会员配置?MemberConfig? - /** - * 获得积分配置 - * - * @return 积分配置 - */ - MemberPointConfigRespDTO getConfig(); - /** * 增加用户积分 * diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApiImpl.java new file mode 100644 index 000000000..510f4fff7 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/config/MemberConfigApiImpl.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.member.api.config; + +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; +import cn.iocoder.yudao.module.member.convert.config.MemberConfigConvert; +import cn.iocoder.yudao.module.member.service.config.MemberConfigService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 用户配置 API 实现类 + * + * @author owen + */ +@Service +@Validated +public class MemberConfigApiImpl implements MemberConfigApi { + + @Resource + private MemberConfigService memberConfigService; + + @Override + public MemberConfigRespDTO getConfig() { + return MemberConfigConvert.INSTANCE.convert01(memberConfigService.getConfig()); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java index 51239388a..6e21e8546 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java @@ -1,10 +1,7 @@ package cn.iocoder.yudao.module.member.api.point; import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO; -import cn.iocoder.yudao.module.member.convert.point.MemberPointConfigConvert; import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; -import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService; import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -25,13 +22,6 @@ public class MemberPointApiImpl implements MemberPointApi { @Resource private MemberPointRecordService memberPointRecordService; - @Resource - private MemberPointConfigService memberPointConfigService; - - @Override - public MemberPointConfigRespDTO getConfig() { - return MemberPointConfigConvert.INSTANCE.convert01(memberPointConfigService.getPointConfig()); - } @Override public void addPoint(Long userId, Integer point, Integer bizType, String bizId) { diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/MemberConfigController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/MemberConfigController.java new file mode 100644 index 000000000..730358f9b --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/MemberConfigController.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.member.controller.admin.config; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.member.controller.admin.config.vo.MemberConfigRespVO; +import cn.iocoder.yudao.module.member.controller.admin.config.vo.MemberConfigSaveReqVO; +import cn.iocoder.yudao.module.member.convert.config.MemberConfigConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.config.MemberConfigDO; +import cn.iocoder.yudao.module.member.service.config.MemberConfigService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +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 static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 会员设置") +@RestController +@RequestMapping("/member/config") +@Validated +public class MemberConfigController { + + @Resource + private MemberConfigService memberConfigService; + + @PutMapping("/save") + @Operation(summary = "保存会员配置") + @PreAuthorize("@ss.hasPermission('member:config:save')") + public CommonResult saveConfig(@Valid @RequestBody MemberConfigSaveReqVO saveReqVO) { + memberConfigService.saveConfig(saveReqVO); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得会员配置") + @PreAuthorize("@ss.hasPermission('member:config:query')") + public CommonResult getConfig() { + MemberConfigDO config = memberConfigService.getConfig(); + return success(MemberConfigConvert.INSTANCE.convert(config)); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java similarity index 84% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java index f946e4a27..76ef53bbf 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.member.controller.admin.point.vo.config; +package cn.iocoder.yudao.module.member.controller.admin.config.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -6,11 +6,11 @@ import lombok.Data; import javax.validation.constraints.NotNull; /** - * 会员积分配置 Base VO,提供给添加、修改、详细的子 VO 使用 + * 会员配置 Base VO,提供给添加、修改、详细的子 VO 使用 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 */ @Data -public class MemberPointConfigBaseVO { +public class MemberConfigBaseVO { @Schema(description = "积分抵扣开关", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") @NotNull(message = "积分抵扣开发不能为空") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigRespVO.java similarity index 60% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigRespVO.java index 7b5125d1c..04f14f3d1 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigRespVO.java @@ -1,15 +1,15 @@ -package cn.iocoder.yudao.module.member.controller.admin.point.vo.config; +package cn.iocoder.yudao.module.member.controller.admin.config.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(description = "管理后台 - 会员积分配置 Response VO") +@Schema(description = "管理后台 - 会员配置 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class MemberPointConfigRespVO extends MemberPointConfigBaseVO { +public class MemberConfigRespVO extends MemberConfigBaseVO { @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigSaveReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigSaveReqVO.java new file mode 100644 index 000000000..8348f1f3c --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigSaveReqVO.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.member.controller.admin.config.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 会员配置保存 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MemberConfigSaveReqVO extends MemberConfigBaseVO { +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java deleted file mode 100644 index 1e55cee0b..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointConfigController.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.member.controller.admin.point; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO; -import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; -import cn.iocoder.yudao.module.member.convert.point.MemberPointConfigConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; -import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -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 static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 会员积分设置") -@RestController -@RequestMapping("/member/point/config") -@Validated -public class MemberPointConfigController { - - @Resource - private MemberPointConfigService memberPointConfigService; - - @PutMapping("/save") - @Operation(summary = "保存会员积分配置") - @PreAuthorize("@ss.hasPermission('point:config:save')") - public CommonResult savePointConfig(@Valid @RequestBody MemberPointConfigSaveReqVO saveReqVO) { - memberPointConfigService.savePointConfig(saveReqVO); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得会员积分配置") - @PreAuthorize("@ss.hasPermission('point:config:query')") - public CommonResult getPointConfig() { - MemberPointConfigDO config = memberPointConfigService.getPointConfig(); - return success(MemberPointConfigConvert.INSTANCE.convert(config)); - } - -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java deleted file mode 100644 index 729ab74b6..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/vo/config/MemberPointConfigSaveReqVO.java +++ /dev/null @@ -1,13 +0,0 @@ -package cn.iocoder.yudao.module.member.controller.admin.point.vo.config; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 会员积分配置保存 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class MemberPointConfigSaveReqVO extends MemberPointConfigBaseVO { -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/config/MemberConfigConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/config/MemberConfigConvert.java new file mode 100644 index 000000000..9847645f9 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/config/MemberConfigConvert.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.member.convert.config; + +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; +import cn.iocoder.yudao.module.member.controller.admin.config.vo.MemberConfigRespVO; +import cn.iocoder.yudao.module.member.controller.admin.config.vo.MemberConfigSaveReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.config.MemberConfigDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 会员配置 Convert + * + * @author QingX + */ +@Mapper +public interface MemberConfigConvert { + + MemberConfigConvert INSTANCE = Mappers.getMapper(MemberConfigConvert.class); + + MemberConfigRespVO convert(MemberConfigDO bean); + + MemberConfigDO convert(MemberConfigSaveReqVO bean); + + MemberConfigRespDTO convert01(MemberConfigDO config); +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java deleted file mode 100644 index c7f0e9881..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointConfigConvert.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.member.convert.point; - -import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO; -import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO; -import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 会员积分配置 Convert - * - * @author QingX - */ -@Mapper -public interface MemberPointConfigConvert { - - MemberPointConfigConvert INSTANCE = Mappers.getMapper(MemberPointConfigConvert.class); - - MemberPointConfigRespVO convert(MemberPointConfigDO bean); - - MemberPointConfigDO convert(MemberPointConfigSaveReqVO bean); - - MemberPointConfigRespDTO convert01(MemberPointConfigDO pointConfig); -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java similarity index 69% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java index 4a6354b03..5e7d99ab6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.member.dal.dataobject.point; +package cn.iocoder.yudao.module.member.dal.dataobject.config; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -7,19 +7,19 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; /** - * 会员积分配置 DO + * 会员配置 DO * * @author QingX */ -@TableName(value = "member_point_config", autoResultMap = true) -@KeySequence("member_point_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName(value = "member_config", autoResultMap = true) +@KeySequence("member_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Builder @NoArgsConstructor @AllArgsConstructor -public class MemberPointConfigDO extends BaseDO { +public class MemberConfigDO extends BaseDO { /** * 自增主键 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/config/MemberConfigMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/config/MemberConfigMapper.java new file mode 100644 index 000000000..e03938378 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/config/MemberConfigMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.member.dal.mysql.config; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.member.dal.dataobject.config.MemberConfigDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 积分设置 Mapper + * + * @author QingX + */ +@Mapper +public interface MemberConfigMapper extends BaseMapperX { +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java deleted file mode 100644 index e099c1714..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/point/MemberPointConfigMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.member.dal.mysql.point; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; -import org.apache.ibatis.annotations.Mapper; - -/** - * 积分设置 Mapper - * - * @author QingX - */ -@Mapper -public interface MemberPointConfigMapper extends BaseMapperX { -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigService.java new file mode 100644 index 000000000..fc4545425 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigService.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.member.service.config; + +import cn.iocoder.yudao.module.member.controller.admin.config.vo.MemberConfigSaveReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.config.MemberConfigDO; + +import javax.validation.Valid; + +/** + * 会员配置 Service 接口 + * + * @author QingX + */ +public interface MemberConfigService { + + /** + * 保存会员配置 + * + * @param saveReqVO 更新信息 + */ + void saveConfig(@Valid MemberConfigSaveReqVO saveReqVO); + + /** + * 获得会员配置 + * + * @return 积分配置 + */ + MemberConfigDO getConfig(); + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigServiceImpl.java new file mode 100644 index 000000000..be56f8a8a --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/config/MemberConfigServiceImpl.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.member.service.config; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.member.controller.admin.config.vo.MemberConfigSaveReqVO; +import cn.iocoder.yudao.module.member.convert.config.MemberConfigConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.config.MemberConfigDO; +import cn.iocoder.yudao.module.member.dal.mysql.config.MemberConfigMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 会员配置 Service 实现类 + * + * @author QingX + */ +@Service +@Validated +public class MemberConfigServiceImpl implements MemberConfigService { + + @Resource + private MemberConfigMapper memberConfigMapper; + + @Override + public void saveConfig(MemberConfigSaveReqVO saveReqVO) { + // 存在,则进行更新 + MemberConfigDO dbConfig = getConfig(); + if (dbConfig != null) { + memberConfigMapper.updateById(MemberConfigConvert.INSTANCE.convert(saveReqVO).setId(dbConfig.getId())); + return; + } + // 不存在,则进行插入 + memberConfigMapper.insert(MemberConfigConvert.INSTANCE.convert(saveReqVO)); + } + + @Override + public MemberConfigDO getConfig() { + List list = memberConfigMapper.selectList(); + return CollectionUtils.getFirst(list); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java deleted file mode 100644 index 68319fdd1..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigService.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.member.service.point; - -import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; -import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; - -import javax.validation.Valid; - -/** - * 会员积分配置 Service 接口 - * - * @author QingX - */ -public interface MemberPointConfigService { - - /** - * 保存会员积分配置 - * - * @param saveReqVO 更新信息 - */ - void savePointConfig(@Valid MemberPointConfigSaveReqVO saveReqVO); - - /** - * 获得会员积分配置 - * - * @return 积分配置 - */ - MemberPointConfigDO getPointConfig(); - -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java deleted file mode 100644 index f148097f1..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.member.service.point; - -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO; -import cn.iocoder.yudao.module.member.convert.point.MemberPointConfigConvert; -import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO; -import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointConfigMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.List; - -/** - * 会员积分配置 Service 实现类 - * - * @author QingX - */ -@Service -@Validated -public class MemberPointConfigServiceImpl implements MemberPointConfigService { - - @Resource - private MemberPointConfigMapper memberPointConfigMapper; - - @Override - public void savePointConfig(MemberPointConfigSaveReqVO saveReqVO) { - // 存在,则进行更新 - MemberPointConfigDO dbConfig = getPointConfig(); - if (dbConfig != null) { - memberPointConfigMapper.updateById(MemberPointConfigConvert.INSTANCE.convert(saveReqVO).setId(dbConfig.getId())); - return; - } - // 不存在,则进行插入 - memberPointConfigMapper.insert(MemberPointConfigConvert.INSTANCE.convert(saveReqVO)); - } - - @Override - public MemberPointConfigDO getPointConfig() { - List list = memberPointConfigMapper.selectList(); - return CollectionUtils.getFirst(list); - } - -} From 2168145c3e6c2f46a9ab9f9c46bb7784cbe1a3ab Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 1 Oct 2023 10:41:21 +0800 Subject: [PATCH 13/15] =?UTF-8?q?=E4=BC=9A=E5=91=98=EF=BC=9A=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E9=85=8D=E7=BD=AE=E7=9A=84=E7=A7=AF=E5=88=86=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=AD=97=E6=AE=B5=E5=8A=A0=E4=B8=8Apoint=E5=89=8D?= =?UTF-8?q?=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 10 +++++----- .../price/calculator/TradePointGiveCalculator.java | 4 ++-- .../calculator/TradePointUsePriceCalculator.java | 12 ++++++------ .../member/api/config/dto/MemberConfigRespDTO.java | 8 ++++---- .../admin/config/vo/MemberConfigBaseVO.java | 8 ++++---- .../member/dal/dataobject/config/MemberConfigDO.java | 8 ++++---- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index d4b500e91..f2d5f5046 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -815,10 +815,10 @@ COMMIT; DROP TABLE IF EXISTS `member_config`; CREATE TABLE `member_config` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键', - `trade_deduct_enable` bit(1) NOT NULL COMMENT '是否开启积分抵扣', - `trade_deduct_unit_price` int NOT NULL COMMENT '积分抵扣(单位:分)', - `trade_deduct_max_price` int NULL DEFAULT NULL COMMENT '积分抵扣最大值', - `trade_give_point` bigint NULL DEFAULT NULL COMMENT '1 元赠送多少分', + `point_trade_deduct_enable` bit(1) NOT NULL COMMENT '是否开启积分抵扣', + `point_trade_deduct_unit_price` int NOT NULL COMMENT '积分抵扣(单位:分)', + `point_trade_deduct_max_price` int NULL DEFAULT NULL COMMENT '积分抵扣最大值', + `point_trade_give_point` bigint NULL DEFAULT NULL COMMENT '1 元赠送多少分', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', @@ -832,7 +832,7 @@ CREATE TABLE `member_config` ( -- Records of member_config -- ---------------------------- BEGIN; -INSERT INTO `member_config` (`id`, `trade_deduct_enable`, `trade_deduct_unit_price`, `trade_deduct_max_price`, `trade_give_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, b'1', 100, 2, 3, '1', '2023-08-20 09:54:42', '1', '2023-08-20 09:54:42', b'0', 1); +INSERT INTO `member_config` (`id`, `point_trade_deduct_enable`, `point_trade_deduct_unit_price`, `point_trade_deduct_max_price`, `point_trade_give_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, b'1', 100, 2, 3, '1', '2023-08-20 09:54:42', '1', '2023-08-20 09:54:42', b'0', 1); COMMIT; -- ---------------------------- diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java index 7644272de..24e5ba0cf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java @@ -34,8 +34,8 @@ public class TradePointGiveCalculator implements TradePriceCalculator { public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { // 1.1 校验积分功能是否开启 int givePointPerYuan = Optional.ofNullable(memberConfigApi.getConfig()) - .filter(config -> BooleanUtil.isTrue(config.getTradeDeductEnable())) - .map(MemberConfigRespDTO::getTradeGivePoint) + .filter(config -> BooleanUtil.isTrue(config.getPointTradeDeductEnable())) + .map(MemberConfigRespDTO::getPointTradeGivePoint) .orElse(0); if (givePointPerYuan <= 0) { return; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java index ffba5b4ee..1ba0d3d19 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java @@ -78,18 +78,18 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { private boolean isDeductPointEnable(MemberConfigRespDTO config) { return config != null && - !BooleanUtil.isTrue(config.getTradeDeductEnable()) && // 积分功能是否启用 - config.getTradeDeductUnitPrice() != null && config.getTradeDeductUnitPrice() > 0; // 有没有配置:1 积分抵扣多少分 + !BooleanUtil.isTrue(config.getPointTradeDeductEnable()) && // 积分功能是否启用 + config.getPointTradeDeductUnitPrice() != null && config.getPointTradeDeductUnitPrice() > 0; // 有没有配置:1 积分抵扣多少分 } private Integer calculatePointPrice(MemberConfigRespDTO config, Integer usePoint, TradePriceCalculateRespBO result) { // 每个订单最多可以使用的积分数量 - if (config.getTradeDeductMaxPrice() != null && config.getTradeDeductMaxPrice() > 0) { - usePoint = Math.min(usePoint, config.getTradeDeductMaxPrice()); + if (config.getPointTradeDeductMaxPrice() != null && config.getPointTradeDeductMaxPrice() > 0) { + usePoint = Math.min(usePoint, config.getPointTradeDeductMaxPrice()); } // TODO @疯狂:这里应该是,抵扣到只剩下 0.01; // 积分优惠金额(分) - int pointPrice = usePoint * config.getTradeDeductUnitPrice(); + int pointPrice = usePoint * config.getPointTradeDeductUnitPrice(); if (result.getPrice().getPayPrice() <= pointPrice) { // 禁止 0 元购 throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); @@ -99,7 +99,7 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { // pointPrice = result.getPrice().getPayPrice(); // // 反推需要扣除的积分 // usePoint = NumberUtil.toBigDecimal(pointPrice) -// .divide(NumberUtil.toBigDecimal(config.getTradeDeductUnitPrice()), 0, RoundingMode.HALF_UP) +// .divide(NumberUtil.toBigDecimal(config.getPointTradeDeductUnitPrice()), 0, RoundingMode.HALF_UP) // .intValue(); // } // 记录使用的积分 diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java index 8ce517964..59aab53f9 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/config/dto/MemberConfigRespDTO.java @@ -13,20 +13,20 @@ public class MemberConfigRespDTO { /** * 积分抵扣开关 */ - private Boolean tradeDeductEnable; + private Boolean pointTradeDeductEnable; /** * 积分抵扣,单位:分 *

* 1 积分抵扣多少分 */ - private Integer tradeDeductUnitPrice; + private Integer pointTradeDeductUnitPrice; /** * 积分抵扣最大值 */ - private Integer tradeDeductMaxPrice; + private Integer pointTradeDeductMaxPrice; /** * 1 元赠送多少分 */ - private Integer tradeGivePoint; + private Integer pointTradeGivePoint; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java index 76ef53bbf..a9a6b3195 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java @@ -14,18 +14,18 @@ public class MemberConfigBaseVO { @Schema(description = "积分抵扣开关", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") @NotNull(message = "积分抵扣开发不能为空") - private Boolean tradeDeductEnable; + private Boolean pointTradeDeductEnable; @Schema(description = "积分抵扣,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "13506") @NotNull(message = "积分抵扣不能为空") - private Integer tradeDeductUnitPrice; + private Integer pointTradeDeductUnitPrice; @Schema(description = "积分抵扣最大值", requiredMode = Schema.RequiredMode.REQUIRED, example = "32428") @NotNull(message = "积分抵扣最大值不能为空") - private Integer tradeDeductMaxPrice; + private Integer pointTradeDeductMaxPrice; @Schema(description = "1 元赠送多少分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") @NotNull(message = "1 元赠送积分不能为空") - private Integer tradeGivePoint; + private Integer pointTradeGivePoint; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java index 5e7d99ab6..6efb4a1c0 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java @@ -29,20 +29,20 @@ public class MemberConfigDO extends BaseDO { /** * 积分抵扣开关 */ - private Boolean tradeDeductEnable; + private Boolean pointTradeDeductEnable; /** * 积分抵扣,单位:分 * * 1 积分抵扣多少分 */ - private Integer tradeDeductUnitPrice; + private Integer pointTradeDeductUnitPrice; /** * 积分抵扣最大值 */ - private Integer tradeDeductMaxPrice; + private Integer pointTradeDeductMaxPrice; /** * 1 元赠送多少分 */ - private Integer tradeGivePoint; + private Integer pointTradeGivePoint; } From afd306a71d9ddcfd2f96571f6ecc5a827f4dbd86 Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 1 Oct 2023 16:23:41 +0800 Subject: [PATCH 14/15] =?UTF-8?q?=E4=BA=A4=E6=98=93=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20=E8=B5=A0=E9=80=81=E7=A7=AF=E5=88=86=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E5=99=A8=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/TradePointGiveCalculator.java | 1 - .../TradePointGiveCalculatorTest.java | 97 +++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java index 24e5ba0cf..f3176e272 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculator.java @@ -16,7 +16,6 @@ import java.util.Optional; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; -// TODO @疯狂:这个可以搞个单测; /** * 赠送积分的 {@link TradePriceCalculator} 实现类 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java new file mode 100644 index 000000000..e203e6614 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java @@ -0,0 +1,97 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.member.api.config.MemberConfigApi; +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.ArrayList; + +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +/** + * {@link TradePointGiveCalculator} 的单元测试类 + * + * @author owen + */ +public class TradePointGiveCalculatorTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradePointGiveCalculator tradePointGiveCalculator; + + @Mock + private MemberConfigApi memberConfigApi; + + @Test + public void testCalculate() { + + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setUserId(233L).setCouponId(1024L) + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 全局积分 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 全局积分 + SKU 积分 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(false), // 全局积分,但是未选中 + new TradePriceCalculateReqBO.Item().setSkuId(40L).setCount(5).setSelected(false) // 全局积分 + SKU 积分,但是未选中 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setType(TradeOrderTypeEnum.NORMAL.getType()) + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L).setGivePoint(0), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L).setGivePoint(100), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(4).setSelected(false) + .setPrice(30).setSpuId(3L).setGivePoint(0), + new TradePriceCalculateRespBO.OrderItem().setSkuId(40L).setCount(5).setSelected(false) + .setPrice(60).setSpuId(1L).setGivePoint(100) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(积分配置 信息) + MemberConfigRespDTO memberConfig = randomPojo(MemberConfigRespDTO.class, o -> o.setPointTradeDeductEnable(true) + .setPointTradeGivePoint(100)); + when(memberConfigApi.getConfig()).thenReturn(memberConfig); + + // 调用 + tradePointGiveCalculator.calculate(param, result); + // 断言:Price 部分 + assertEquals(result.getGivePoint(), 2 * 100 + 3 * 50 + 100); + // 断言:SKU 1 + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getGivePoint(), 2 * 100); // 全局积分 + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getGivePoint(), 3 * 50 + 100); // 全局积分 + SKU 积分 + // 断言:SKU 3 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getPrice(), 30); + assertEquals(orderItem03.getGivePoint(), 0); // 全局积分,但是未选中 + // 断言:SKU 4 + TradePriceCalculateRespBO.OrderItem orderItem04 = result.getItems().get(3); + assertEquals(orderItem04.getSkuId(), 40L); + assertEquals(orderItem04.getCount(), 5); + assertEquals(orderItem04.getPrice(), 60); + assertEquals(orderItem04.getGivePoint(), 100); // 全局积分 + SKU 积分,但是未选中 + } +} \ No newline at end of file From abfebebdd5d3fd2f668dd5f71879d64f8bce1ebf Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 1 Oct 2023 17:12:33 +0800 Subject: [PATCH 15/15] =?UTF-8?q?=E4=BA=A4=E6=98=93=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20=E7=A7=AF=E5=88=86=E6=8A=B5=E6=89=A3=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E5=99=A8=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TradePointUsePriceCalculator.java | 5 +- .../TradePointGiveCalculatorTest.java | 7 +- .../TradePointUsePriceCalculatorTest.java | 332 ++++++++++++++++++ 3 files changed, 339 insertions(+), 5 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculatorTest.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java index 1ba0d3d19..aae6e5f53 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java @@ -20,7 +20,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; -// TODO @疯狂:搞个单测,嘿嘿; /** * 使用积分的 {@link TradePriceCalculator} 实现类 * @@ -38,6 +37,8 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { @Override public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 默认使用积分为 0 + result.setUsePoint(0); // 1.1 校验是否使用积分 if (!BooleanUtil.isTrue(param.getPointStatus())) { result.setUsePoint(0); @@ -78,7 +79,7 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator { private boolean isDeductPointEnable(MemberConfigRespDTO config) { return config != null && - !BooleanUtil.isTrue(config.getPointTradeDeductEnable()) && // 积分功能是否启用 + BooleanUtil.isTrue(config.getPointTradeDeductEnable()) && // 积分功能是否启用 config.getPointTradeDeductUnitPrice() != null && config.getPointTradeDeductUnitPrice() > 0; // 有没有配置:1 积分抵扣多少分 } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java index e203e6614..c0c21c36e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointGiveCalculatorTest.java @@ -35,7 +35,7 @@ public class TradePointGiveCalculatorTest extends BaseMockitoUnitTest { // 准备参数 TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() - .setUserId(233L).setCouponId(1024L) + .setUserId(233L) .setItems(asList( new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 全局积分 new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 全局积分 + SKU 积分 @@ -61,8 +61,9 @@ public class TradePointGiveCalculatorTest extends BaseMockitoUnitTest { TradePriceCalculatorHelper.recountAllPrice(result); // mock 方法(积分配置 信息) - MemberConfigRespDTO memberConfig = randomPojo(MemberConfigRespDTO.class, o -> o.setPointTradeDeductEnable(true) - .setPointTradeGivePoint(100)); + MemberConfigRespDTO memberConfig = randomPojo(MemberConfigRespDTO.class, + o -> o.setPointTradeDeductEnable(true) // 启用积分折扣 + .setPointTradeGivePoint(100)); // 1 元赠送多少分 when(memberConfigApi.getConfig()).thenReturn(memberConfig); // 调用 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculatorTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculatorTest.java new file mode 100644 index 000000000..5d59c781c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculatorTest.java @@ -0,0 +1,332 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.member.api.config.MemberConfigApi; +import cn.iocoder.yudao.module.member.api.config.dto.MemberConfigRespDTO; +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.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.ArrayList; + +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +/** + * {@link TradePointUsePriceCalculator } 的单元测试类 + * + * @author owen + */ +public class TradePointUsePriceCalculatorTest extends BaseMockitoUnitTest { + + @InjectMocks + private TradePointUsePriceCalculator tradePointUsePriceCalculator; + + @Mock + private MemberConfigApi memberConfigApi; + @Mock + private MemberUserApi memberUserApi; + + @Test + public void testCalculate_success() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setUserId(233L).setPointStatus(true) // 是否使用积分 + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(5).setSelected(false) // 未选中,不使用积分 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setType(TradeOrderTypeEnum.NORMAL.getType()) + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(5).setSelected(false) + .setPrice(30).setSpuId(3L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(积分配置 信息) + MemberConfigRespDTO memberConfig = randomPojo(MemberConfigRespDTO.class, + o -> o.setPointTradeDeductEnable(true) // 启用积分折扣 + .setPointTradeDeductUnitPrice(1) // 1 积分抵扣多少金额(单位分) + .setPointTradeDeductMaxPrice(100)); // 积分抵扣最大值 + when(memberConfigApi.getConfig()).thenReturn(memberConfig); + // mock 方法(会员 信息) + MemberUserRespDTO user = randomPojo(MemberUserRespDTO.class, o -> o.setId(param.getUserId()).setPoint(100)); + when(memberUserApi.getUser(user.getId())).thenReturn(user); + + // 调用 + tradePointUsePriceCalculator.calculate(param, result); + // 断言:使用了多少积分 + assertEquals(result.getUsePoint(), 100); + // 断言:Price 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 350); + assertEquals(price.getPayPrice(), 250); + assertEquals(price.getPointPrice(), 100); + // 断言:SKU 1 + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getPointPrice(), 57); + assertEquals(orderItem01.getPayPrice(), 143); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getPointPrice(), 43); + assertEquals(orderItem02.getPayPrice(), 107); + // 断言:SKU 3 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 5); + assertEquals(orderItem03.getPrice(), 30); + assertEquals(orderItem03.getPointPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 150); + // 断言:Promotion 部分 + assertEquals(result.getPromotions().size(), 1); + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); + assertEquals(promotion01.getId(), user.getId()); + assertEquals(promotion01.getName(), "积分抵扣"); + assertEquals(promotion01.getType(), PromotionTypeEnum.POINT.getType()); + assertEquals(promotion01.getTotalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 100); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "积分抵扣:省 1.00 元"); + assertEquals(promotion01.getItems().size(), 2); + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getTotalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 57); + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getTotalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 43); + } + + /** + * 当用户积分充足时,抵扣的金额为:配置表的“积分抵扣最大值” + */ + @Test + public void testCalculate_TradeDeductMaxPrice() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setUserId(233L).setPointStatus(true) // 是否使用积分 + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(5).setSelected(false) // 未选中,不使用积分 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setType(TradeOrderTypeEnum.NORMAL.getType()) + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(5).setSelected(false) + .setPrice(30).setSpuId(3L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(积分配置 信息) + MemberConfigRespDTO memberConfig = randomPojo(MemberConfigRespDTO.class, + o -> o.setPointTradeDeductEnable(true) // 启用积分折扣 + .setPointTradeDeductUnitPrice(1) // 1 积分抵扣多少金额(单位分) + .setPointTradeDeductMaxPrice(50)); // 积分抵扣最大值 + when(memberConfigApi.getConfig()).thenReturn(memberConfig); + // mock 方法(会员 信息) + MemberUserRespDTO user = randomPojo(MemberUserRespDTO.class, o -> o.setId(param.getUserId()).setPoint(100)); + when(memberUserApi.getUser(user.getId())).thenReturn(user); + + // 调用 + tradePointUsePriceCalculator.calculate(param, result); + // 断言:使用了多少积分 + assertEquals(result.getUsePoint(), 50); + // 断言:Price 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 350); + assertEquals(price.getPayPrice(), 300); + assertEquals(price.getPointPrice(), 50); + // 断言:SKU 1 + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getPointPrice(), 28); + assertEquals(orderItem01.getPayPrice(), 172); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getPointPrice(), 22); + assertEquals(orderItem02.getPayPrice(), 128); + // 断言:SKU 3 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 5); + assertEquals(orderItem03.getPrice(), 30); + assertEquals(orderItem03.getPointPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 150); + // 断言:Promotion 部分 + assertEquals(result.getPromotions().size(), 1); + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); + assertEquals(promotion01.getId(), user.getId()); + assertEquals(promotion01.getName(), "积分抵扣"); + assertEquals(promotion01.getType(), PromotionTypeEnum.POINT.getType()); + assertEquals(promotion01.getTotalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 50); + assertTrue(promotion01.getMatch()); + assertEquals(promotion01.getDescription(), "积分抵扣:省 0.50 元"); + assertEquals(promotion01.getItems().size(), 2); + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getTotalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 28); + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getTotalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 22); + } + + /** + * 订单不使用积分,不会产生优惠 + */ + @Test + public void testCalculate_PointStatusFalse() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setUserId(233L).setPointStatus(false) // 是否使用积分 + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(5).setSelected(false) // 未选中,不使用积分 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setType(TradeOrderTypeEnum.NORMAL.getType()) + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(5).setSelected(false) + .setPrice(30).setSpuId(3L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // 调用 + tradePointUsePriceCalculator.calculate(param, result); + // 断言:没有使用积分 + assertNotUsePoint(result); + } + + /** + * 会员积分不足,不会产生优惠 + */ + @Test + public void testCalculate_UserPointNotEnough() { + // 准备参数 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() + .setUserId(233L).setPointStatus(true) // 是否使用积分 + .setItems(asList( + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 使用积分 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(5).setSelected(false) // 未选中,不使用积分 + )); + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() + .setType(TradeOrderTypeEnum.NORMAL.getType()) + .setPrice(new TradePriceCalculateRespBO.Price()) + .setPromotions(new ArrayList<>()) + .setItems(asList( + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) + .setPrice(100).setSpuId(1L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) + .setPrice(50).setSpuId(2L), + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(5).setSelected(false) + .setPrice(30).setSpuId(3L) + )); + // 保证价格被初始化上 + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); + TradePriceCalculatorHelper.recountAllPrice(result); + + // mock 方法(积分配置 信息) + MemberConfigRespDTO memberConfig = randomPojo(MemberConfigRespDTO.class, + o -> o.setPointTradeDeductEnable(true) // 启用积分折扣 + .setPointTradeDeductUnitPrice(1) // 1 积分抵扣多少金额(单位分) + .setPointTradeDeductMaxPrice(100)); // 积分抵扣最大值 + when(memberConfigApi.getConfig()).thenReturn(memberConfig); + // mock 方法(会员 信息) + MemberUserRespDTO user = randomPojo(MemberUserRespDTO.class, o -> o.setId(param.getUserId()).setPoint(0)); + when(memberUserApi.getUser(user.getId())).thenReturn(user); + + // 调用 + tradePointUsePriceCalculator.calculate(param, result); + + // 断言:没有使用积分 + assertNotUsePoint(result); + } + + /** + * 断言:没有使用积分 + */ + private static void assertNotUsePoint(TradePriceCalculateRespBO result) { + // 断言:使用了多少积分 + assertEquals(result.getUsePoint(), 0); + // 断言:Price 部分 + TradePriceCalculateRespBO.Price price = result.getPrice(); + assertEquals(price.getTotalPrice(), 350); + assertEquals(price.getPayPrice(), 350); + assertEquals(price.getPointPrice(), 0); + // 断言:SKU 1 + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getPrice(), 100); + assertEquals(orderItem01.getPointPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + // 断言:SKU 2 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getPrice(), 50); + assertEquals(orderItem02.getPointPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + // 断言:SKU 3 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 5); + assertEquals(orderItem03.getPrice(), 30); + assertEquals(orderItem03.getPointPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 150); + // 断言:Promotion 部分 + assertEquals(result.getPromotions().size(), 0); + } +} \ No newline at end of file