From 2591ab5d36a19ece7b3acff1574410af80c4e3cd Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 6 Sep 2023 11:29:51 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E4=B8=AD=E5=BF=83+?= =?UTF-8?q?=E8=90=A5=E9=94=80=E6=B4=BB=E5=8A=A8=EF=BC=9A=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E9=83=A8=E5=88=86=20TODO=20=E6=8F=90=E5=88=B0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/pojo/CommonResult.java | 10 ++++- .../dto/BargainRecordCreateReqDTO.java | 25 +----------- .../api/combination/CombinationRecordApi.java | 26 ++++++++++--- .../CombinationRecordUpdateStatusReqDTO.java | 39 ------------------- .../promotion/enums/ErrorCodeConstants.java | 2 +- .../combination/CombinationRecordApiImpl.java | 21 ++++++---- .../combination/CombinationRecordDO.java | 6 +-- .../combination/CombinationRecordService.java | 15 ++++--- .../CombinationRecordServiceImpl.java | 21 +++++----- .../seckill/SeckillActivityServiceImpl.java | 12 ++---- .../module/promotion/util/PromotionUtils.java | 26 ------------- .../aftersale/TradeAfterSaleController.java | 10 ++++- .../vo/TradeAfterSaleDetailRespVO.java | 2 +- .../order/vo/TradeOrderDetailRespVO.java | 17 ++++---- .../aftersale/TradeAfterSaleConvert.java | 2 +- .../convert/order/TradeOrderConvert.java | 4 +- .../aftersale/TradeAfterSaleServiceImpl.java | 7 +--- .../order/TradeOrderUpdateServiceImpl.java | 4 +- 18 files changed, 97 insertions(+), 152 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordUpdateStatusReqDTO.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java index bfb291b6d..3a974456e 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java @@ -41,7 +41,7 @@ public class CommonResult implements Serializable { * 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。 * * @param result 传入的 result 对象 - * @param 返回的泛型 + * @param 返回的泛型 * @return 新的 CommonResult 对象 */ public static CommonResult error(CommonResult result) { @@ -68,6 +68,14 @@ public class CommonResult implements Serializable { return result; } + public static CommonResult success(T data, String msg) { + CommonResult result = new CommonResult<>(); + result.code = GlobalErrorCodeConstants.SUCCESS.getCode(); + result.data = data; + result.msg = msg; + return result; + } + public static boolean isSuccess(Integer code) { return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode()); } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java index 22ef80a1e..d7835b23c 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.api.bargain.dto; import lombok.Data; -import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; // TODO @芋艿:这块要在看看 @@ -40,17 +39,7 @@ public class BargainRecordCreateReqDTO { */ @NotNull(message = "订单编号不能为空") private Long orderId; - // TODO @puhui999:spuName、picUrl、 之类字段不用传递; - /** - * 商品名字 - */ - @NotEmpty(message = "商品名字不能为空") - private String spuName; - /** - * 商品图片 - */ - @NotEmpty(message = "商品图片不能为空") - private String picUrl; + /** * 砍价商品单价 */ @@ -61,17 +50,7 @@ public class BargainRecordCreateReqDTO { */ @NotNull(message = "商品原价不能为空") private Integer price; - // TODO @puhui999:nickname、avatar 不用传递,去查询; - /** - * 用户昵称 - */ - @NotEmpty(message = "用户昵称不能为空") - private String nickname; - /** - * 用户头像 - */ - @NotEmpty(message = "用户头像不能为空") - private String avatar; + /** * 开团状态:进行中 砍价成功 砍价失败 */ diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java index 631a70906..c03559785 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.promotion.api.combination; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; import javax.validation.Valid; +import java.time.LocalDateTime; import java.util.List; // TODO @芋艿:后面也再撸撸这几个接口 @@ -51,13 +51,29 @@ public interface CombinationRecordApi { */ void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount); - // TODO @puhui999:是不是搞成具体的方法,拼团成功,拼团失败,这种方法; + /** + * 更新拼团状态为 成功 + * + * @param userId 用户编号 + * @param orderId 订单编号 + */ + void updateRecordStatusToSuccess(Long userId, Long orderId); /** - * 更新开团记录状态 + * 更新拼团状态为 失败 * - * @param reqDTO 请求 DTO + * @param userId 用户编号 + * @param orderId 订单编号 */ - void updateCombinationRecordStatus(CombinationRecordUpdateStatusReqDTO reqDTO); + void updateRecordStatusToFailed(Long userId, Long orderId); + + /** + * 更新拼团状态为 进行中 + * + * @param userId 用户编号 + * @param orderId 订单编号 + * @param startTime 开始时间 + */ + void updateRecordStatusToInProgress(Long userId, Long orderId, LocalDateTime startTime); } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordUpdateStatusReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordUpdateStatusReqDTO.java deleted file mode 100644 index 3ba49ff36..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordUpdateStatusReqDTO.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.combination.dto; - -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -/** - * 拼团记录的更新状态 Request DTO - * - * @author HUIHUI - */ -@Data -public class CombinationRecordUpdateStatusReqDTO { - - /** - * 用户编号 - */ - @NotNull(message = "用户编号不能为空") - private Long userId; - - /** - * 订单编号 - */ - @NotNull(message = "订单编号不能为空") - private Long orderId; - - /** - * 开团状态:正在开团 拼团成功 拼团失败 - */ - @NotNull(message = "开团状态不能为空") - private Integer status; - - /** - * 团开始时间 - */ - private LocalDateTime startTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index 8f5b8c803..dd4389d5d 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -51,7 +51,7 @@ public interface ErrorCodeConstants { // ========== 秒杀活动 1013008000 ========== ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1013008000, "秒杀活动不存在"); - ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013008002, "存在商品参加了其它秒杀活动"); + ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013008002, "存在商品参加了其它秒杀活动,秒杀时段冲突"); ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改"); ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java index e9dd9d201..7f7ec6170 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.promotion.api.combination; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.time.LocalDateTime; import java.util.List; /** @@ -43,12 +43,19 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { } @Override - public void updateCombinationRecordStatus(CombinationRecordUpdateStatusReqDTO reqDTO) { - if (null == reqDTO.getStartTime()) { - recordService.updateCombinationRecordStatusByUserIdAndOrderId(reqDTO); - } else { - recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(reqDTO); - } + public void updateRecordStatusToSuccess(Long userId, Long orderId) { + recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId); + } + + @Override + public void updateRecordStatusToFailed(Long userId, Long orderId) { + recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.FAILED.getStatus(), userId, orderId); + } + + @Override + public void updateRecordStatusToInProgress(Long userId, Long orderId, LocalDateTime startTime) { + recordService.updateRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordStatusEnum.IN_PROGRESS.getStatus(), + userId, orderId, startTime); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java index f89c8f7ee..898d2a822 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java @@ -86,11 +86,11 @@ public class CombinationRecordDO extends BaseDO { */ private Boolean virtualGroup; /** - * 过期时间,单位:小时 + * 过期时间 * - * 关联 {@link CombinationActivityDO#getLimitDuration()} + * {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算 */ - private Integer expireTime; + private LocalDateTime expireTime; /** * 开始时间 (订单付款后开始的时间) */ diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java index 6c12cb551..fbc51c6b9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.promotion.service.combination; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; +import java.time.LocalDateTime; import java.util.List; /** @@ -16,9 +16,11 @@ public interface CombinationRecordService { /** * 更新拼团状态 * - * @param reqDTO 请求 DTO + * @param status 状态 + * @param userId 用户编号 + * @param orderId 订单编号 */ - void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO); + void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId); /** * 创建拼团记录 @@ -30,9 +32,12 @@ public interface CombinationRecordService { /** * 更新拼团状态和开始时间 * - * @param reqDTO 请求 DTO + * @param status 状态 + * @param userId 用户编号 + * @param orderId 订单编号 + * @param startTime 开始时间 */ - void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO); + void updateRecordStatusAndStartTimeByUserIdAndOrderId(Integer status, Long userId, Long orderId, LocalDateTime startTime); /** * 获得拼团状态 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java index 4e2f85e27..bc9c1df4c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.service.combination; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; @@ -21,6 +20,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; // TODO 芋艿:等拼团记录做完,完整 review 下 + /** * 拼团记录 Service 实现类 * @@ -38,27 +38,27 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @Override @Transactional(rollbackFor = Exception.class) - public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { + public void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId) { // 校验拼团是否存在 - CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); // 更新状态 - recordDO.setStatus(reqDTO.getStatus()); + recordDO.setStatus(status); recordMapper.updateById(recordDO); } @Override @Transactional(rollbackFor = Exception.class) - public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { - CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); + public void updateRecordStatusAndStartTimeByUserIdAndOrderId(Integer status, Long userId, Long orderId, LocalDateTime startTime) { + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); // 更新状态 - recordDO.setStatus(reqDTO.getStatus()); + recordDO.setStatus(status); // 更新开始时间 - recordDO.setStartTime(reqDTO.getStartTime()); + recordDO.setStartTime(startTime); recordMapper.updateById(recordDO); // 更新拼团参入人数 - List recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus()); + List recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status); if (CollUtil.isNotEmpty(recordDOs)) { recordDOs.forEach(item -> { item.setUserCount(recordDOs.size()); @@ -115,8 +115,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { // 2. 创建拼团记录 CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); record.setVirtualGroup(false); - // TODO @puhui999:过期时间,应该是 Date 哈; - record.setExpireTime(activity.getLimitDuration()); + record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration())); record.setUserSize(activity.getUserSize()); recordMapper.insert(record); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java index a3577a50b..531c35fcb 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java @@ -92,15 +92,9 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { if (activityId != null) { // 排除自己 activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId)); } - // TODO @puhui999:一个 spu,参与两个活动应该没关系,关键是活动时间不充能重叠; - // 2.2 过滤出所有 spuId 有交集的活动,判断是否存在重叠 - List activityDOs1 = filterList(activityList, s -> ObjectUtil.equal(s.getSpuId(), spuId)); - if (isNotEmpty(activityDOs1)) { - throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); - } - // 2.3 过滤出所有 configIds 有交集的活动,判断是否存在重叠 - List activityDOs2 = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds)); - if (isNotEmpty(activityDOs2)) { + // 2.2 过滤出所有 configIds 有交集的活动,判断是否存在重叠 + List activityDOs = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds)); + if (isNotEmpty(activityDOs)) { throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java index dd5551fe2..2ad362fe2 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java @@ -1,18 +1,9 @@ package cn.iocoder.yudao.module.promotion.util; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import java.time.LocalDateTime; -import java.util.List; -import java.util.Set; -import java.util.function.Function; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; /** * 活动工具类 @@ -31,21 +22,4 @@ public class PromotionUtils { return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus(); } - /** - * 校验商品 sku 是否都存在 - * - * @param skus 数据库中的商品 skus - * @param products 需要校验的商品 - * @param func 获取需要校验的商品的 skuId - */ - public static void validateProductSkuAllExists(List skus, List products, Function func) { - // 校验 sku 个数是否一致 - Set skuIdsSet = CollectionUtils.convertSet(products, func); - Set skuIdsSet1 = CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId); - // 校验 skuId 是否存在 - if (anyMatch(skuIdsSet, s -> !skuIdsSet1.contains(s))) { - throw exception(SKU_NOT_EXISTS); - } - } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java index 689f3540b..60afbc0ab 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java @@ -36,6 +36,7 @@ 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.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.AFTER_SALE_NOT_FOUND; @Tag(name = "管理后台 - 售后订单") @RestController @@ -76,6 +77,9 @@ public class TradeAfterSaleController { public CommonResult getOrderDetail(@RequestParam("id") Long id) { // 查询订单 TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id); + if (afterSale == null) { + return success(null, AFTER_SALE_NOT_FOUND.getMsg()); + } // 查询订单 TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId()); // 查询订单项 @@ -92,7 +96,11 @@ public class TradeAfterSaleController { TradeAfterSaleLogRespDTO respVO = new TradeAfterSaleLogRespDTO(); respVO.setId((long) i); respVO.setUserId((long) i); - respVO.setUserType(1); + respVO.setUserType(i % 2 == 0 ? 2 : 1); + // 模拟系统操作 + if (i == 2) { + respVO.setUserType(3); + } respVO.setAfterSaleId(id); respVO.setOrderId((long) i); respVO.setOrderItemId((long) i); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java index aff9f5087..af6db85c7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java @@ -35,7 +35,7 @@ public class TradeAfterSaleDetailRespVO extends TradeAfterSaleBaseVO { /** * 售后日志 */ - private List afterSaleLog; + private List logs; @Schema(description = "管理后台 - 交易订单的详情的订单项目") @Data diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java index fa1e77d0e..4ba8ed4f8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java @@ -26,24 +26,23 @@ public class TradeOrderDetailRespVO extends TradeOrderBaseVO { private MemberUserRespVO user; /** - * TODO 订单操作日志, 先模拟一波;返回 logs,简洁,然后复数哈 + * TODO 订单操作日志, 先模拟一波 */ - private List orderLog; + private List logs; - // TODO @puhui999:swagger 注解 + @Schema(description = "管理后台 - 交易订单的操作日志") @Data public static class OrderLog { - /** - * 内容 - */ + @Schema(description = "操作详情", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单发货") private String content; - /** - * 创建时间 - */ + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-06-01 10:50:20") private LocalDateTime createTime; + @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer userType; + } @Schema(description = "管理后台 - 交易订单的详情的订单项目") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java index d4f481c37..0c84c6967 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java @@ -78,7 +78,7 @@ public interface TradeAfterSaleConvert { // 处理订单信息 respVO.setOrder(convert(order)); // 处理售后日志 - respVO.setAfterSaleLog(convertList1(logs)); + respVO.setLogs(convertList1(logs)); return respVO; } List convertList1(List list); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index df7b296f0..07e9595fc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -93,6 +93,7 @@ public interface TradeOrderConvert { items.forEach(item -> item.setIncrCount(-item.getIncrCount())); return new ProductSkuUpdateStockReqDTO(items); } + List convertList(List list); @Mappings({ @@ -151,9 +152,10 @@ public interface TradeOrderConvert { TradeOrderDetailRespVO.OrderLog orderLog = new TradeOrderDetailRespVO.OrderLog(); orderLog.setContent("订单操作" + i); orderLog.setCreateTime(LocalDateTime.now()); + orderLog.setUserType(i % 2 == 0 ? 2 : 1); orderLogs.add(orderLog); } - orderVO.setOrderLog(orderLogs); + orderVO.setLogs(orderLogs); return orderVO; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java index eae983799..f54563d42 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java @@ -90,12 +90,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @Override public TradeAfterSaleDO getAfterSale(Long id) { - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); - // TODO @puhui999;读不到,不要这里报错哈;交给前端报错;一般是读取信息不到,message 提示,然后 close tab; - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - return afterSale; + return tradeAfterSaleMapper.selectById(id); } // TODO 芋艿:拼团失败,要不要发起售后的方式退款?还是走取消逻辑? 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 f887b71e8..c4cfaee83 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 @@ -28,7 +28,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; @@ -352,8 +351,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // 1、拼团活动 if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录 - combinationRecordApi.updateCombinationRecordStatus(new CombinationRecordUpdateStatusReqDTO().setUserId(order.getUserId()) - .setOrderId(order.getId()).setStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus()).setStartTime(LocalDateTime.now())); + combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now()); } // TODO 芋艿:发送订单变化的消息 From 0e8755972c3c97edbd2897f841634fa374566fe4 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 8 Sep 2023 00:35:54 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E8=90=A5=E9=94=80=E6=B4=BB=E5=8A=A8+?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=EF=BC=9A=E5=AE=8C=E5=96=84=E5=A4=A7=E9=83=A8?= =?UTF-8?q?=E5=88=86=20TODO=20=E6=8F=90=E5=88=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/bargain/BargainActivityApi.java | 18 +++ .../api/seckill/SeckillActivityApi.java | 20 ++++ .../dto/SeckillActivityUpdateStockReqDTO.java | 46 ++++++++ .../promotion/enums/ErrorCodeConstants.java | 1 + .../api/bargain/BargainActivityApiImpl.java | 39 +++++++ .../api/seckill/SeckillActivityApiImpl.java | 75 +++++++++++++ .../seckill/SeckillActivityService.java | 14 +++ .../seckill/SeckillActivityServiceImpl.java | 18 ++- .../yudao-module-trade-biz/pom.xml | 5 + .../admin/order/TradeOrderController.java | 4 + .../app/order/AppTradeOrderController.java | 4 +- .../vo/AppTradeOrderSettlementReqVO.java | 4 + .../dal/redis/no/TradeOrderNoRedisDAO.java | 35 ++++++ .../order/TradeOrderUpdateServiceImpl.java | 104 ++++++++++++------ .../module/pay/api/order/PayOrderApi.java | 7 ++ .../module/pay/enums/ErrorCodeConstants.java | 1 + .../module/pay/api/order/PayOrderApiImpl.java | 6 + .../pay/service/order/PayOrderService.java | 14 ++- .../service/order/PayOrderServiceImpl.java | 11 ++ 19 files changed, 381 insertions(+), 45 deletions(-) create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApi.java new file mode 100644 index 000000000..5e62d6e9e --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApi.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.promotion.api.bargain; + +/** + * 砍价活动 Api 接口 + * + * @author HUIHUI + */ +public interface BargainActivityApi { + + /** + * 更新砍价活动库存 + * + * @param activityId 砍价活动编号 + * @param count 购买数量 + */ + void updateBargainActivityStock(Long activityId, Integer count); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java new file mode 100644 index 000000000..09ec051a3 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.promotion.api.seckill; + +import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; + +/** + * 秒杀活动 API 接口 + * + * @author HUIHUI + */ +public interface SeckillActivityApi { + + + /** + * 更新秒杀库存 + * + * @param updateStockReqDTO 请求 + */ + void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java new file mode 100644 index 000000000..476ba8e15 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.promotion.api.seckill.dto; + +import lombok.Data; + +import java.util.List; + +/** + * 更新秒杀库存 request DTO + * + * @author HUIHUI + */ +@Data +public class SeckillActivityUpdateStockReqDTO { + + /** + * 活动编号 + */ + private Long activityId; + /** + * 总购买数量 + */ + private Integer count; + /** + * 活动商品 + */ + private List items; + + @Data + public static class Item { + + /** + * SPU 编号 + */ + private Long spuId; + /** + * SKU 编号 + */ + private Long skuId; + /** + * 购买数量 + */ + private Integer count; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index dd4389d5d..8c873b5ad 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -55,6 +55,7 @@ public interface ErrorCodeConstants { ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改"); ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); + ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "更新秒杀活动库存失败,原因秒杀库存不足"); // ========== 秒杀时段 1013009000 ========== ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java new file mode 100644 index 000000000..826b4b2aa --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.promotion.api.bargain; + +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; +import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.BARGAIN_ACTIVITY_NOT_EXISTS; + +/** + * 砍价活动 Api 接口实现类 + * + * @author HUIHUI + */ +@Service +public class BargainActivityApiImpl implements BargainActivityApi { + + @Resource + private BargainActivityService bargainActivityService; + + @Override + public void updateBargainActivityStock(Long activityId, Integer count) { + // 查询砍价活动 + BargainActivityDO activity = bargainActivityService.getBargainActivity(activityId); + if (activity == null) { + throw exception(BARGAIN_ACTIVITY_NOT_EXISTS); + } + + // 更新砍价库存 + BargainActivityUpdateReqVO reqVO = new BargainActivityUpdateReqVO(); + reqVO.setId(activityId); + reqVO.setStock(activity.getStock() - count); + bargainActivityService.updateBargainActivity(reqVO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java new file mode 100644 index 000000000..299316aa0 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.promotion.api.seckill; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_UPDATE_STOCK_FAIL; + +/** + * 秒杀活动接口 Api 接口实现类 + * + * @author HUIHUI + */ +@Service +public class SeckillActivityApiImpl implements SeckillActivityApi { + + @Resource + private SeckillActivityService activityService; + + @Override + public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) { + SeckillActivityDO seckillActivity = activityService.getSeckillActivity(updateStockReqDTO.getActivityId()); + if (seckillActivity.getStock() < updateStockReqDTO.getCount()) { + throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); + } + // 获取活动商品 + List productDOs = activityService.getSeckillProductListByActivityId(updateStockReqDTO.getActivityId()); + List items = updateStockReqDTO.getItems(); + Map> map = new HashMap<>(); + items.forEach(item -> { + if (map.containsKey(item.getSpuId())) { + List skuIds = map.get(item.getSpuId()); + skuIds.add(item.getSkuId()); + map.put(item.getSpuId(), skuIds); + } else { + List list = new ArrayList<>(); + list.add(item.getSkuId()); + map.put(item.getSpuId(), list); + } + }); + // 过滤出购买的商品 + List productDOList = CollectionUtils.filterList(productDOs, item -> map.get(item.getSpuId()).contains(item.getSkuId())); + Map productDOMap = CollectionUtils.convertMap(items, SeckillActivityUpdateStockReqDTO.Item::getSkuId, p -> p); + // 检查活动商品库存是否充足 + boolean b = CollectionUtils.anyMatch(productDOList, item -> { + SeckillActivityUpdateStockReqDTO.Item item1 = productDOMap.get(item.getSkuId()); + return (item.getStock() < item1.getCount()) || (item.getStock() - item1.getCount()) < 0; + }); + if (b) { + throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); + } + List doList = CollectionUtils.convertList(productDOList, item -> { + item.setStock(item.getStock() - productDOMap.get(item.getSkuId()).getCount()); + return item; + }); + + // 更新活动库存 + seckillActivity.setStock(seckillActivity.getStock() + updateStockReqDTO.getCount()); + seckillActivity.setTotalStock(seckillActivity.getTotalStock() - updateStockReqDTO.getCount()); + activityService.updateSeckillActivity(seckillActivity); + // 更新活动商品库存 + activityService.updateSeckillActivityProductByList(doList); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java index 2e33a944d..052b59561 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java @@ -33,6 +33,20 @@ public interface SeckillActivityService { */ void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO); + /** + * 更新秒杀活动 + * + * @param activityDO 秒杀活动 + */ + void updateSeckillActivity(SeckillActivityDO activityDO); + + /** + * 更新秒杀活动商品 + * + * @param productDOList 活动商品列表 + */ + void updateSeckillActivityProductByList(List productDOList); + /** * 关闭秒杀活动 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java index 531c35fcb..17fb9a90f 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java @@ -79,8 +79,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { * 1. 校验秒杀时段是否存在 * 2. 秒杀商品是否参加其它活动 * - * @param configIds 秒杀时段数组 - * @param spuId 商品 SPU 编号 + * @param configIds 秒杀时段数组 + * @param spuId 商品 SPU 编号 * @param activityId 秒杀活动编号 */ private void validateProductConflict(List configIds, Long spuId, Long activityId) { @@ -102,7 +102,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { /** * 校验秒杀商品是否都存在 * - * @param spuId 商品 SPU 编号 + * @param spuId 商品 SPU 编号 * @param products 秒杀商品 */ private void validateProductExists(Long spuId, List products) { @@ -144,11 +144,21 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { updateSeckillProduct(updateObj, updateReqVO.getProducts()); } + @Override + public void updateSeckillActivity(SeckillActivityDO activityDO) { + seckillActivityMapper.updateById(activityDO); + } + + @Override + public void updateSeckillActivityProductByList(List productDOList) { + seckillProductMapper.updateBatch(productDOList); + } + /** * 更新秒杀商品 * * @param activity 秒杀活动 - * @param products 该活动的最新商品配置 + * @param products 该活动的最新商品配置 */ private void updateSeckillProduct(SeckillActivityDO activity, List products) { // 第一步,对比新老数据,获得添加、修改、删除的列表 diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml index 810446fa9..fd105e31a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/pom.xml +++ b/yudao-module-mall/yudao-module-trade-biz/pom.xml @@ -82,6 +82,11 @@ yudao-spring-boot-starter-mybatis + + cn.iocoder.boot + yudao-spring-boot-starter-redis + + cn.iocoder.boot diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java index 926c2408c..728c70c67 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java @@ -25,6 +25,7 @@ import java.util.Map; 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.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; @Tag(name = "管理后台 - 交易订单") @RestController @@ -67,6 +68,9 @@ public class TradeOrderController { public CommonResult getOrderDetail(@RequestParam("id") Long id) { // 查询订单 TradeOrderDO order = tradeOrderQueryService.getOrder(id); + if (order == null) { + return success(null, ORDER_NOT_FOUND.getMsg()); + } // 查询订单项 List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id); // orderLog diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 5abb6a98c..a65836c33 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; -import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; @@ -34,6 +33,7 @@ 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.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; @Tag(name = "用户 App - 交易订单") @RestController @@ -83,7 +83,7 @@ public class AppTradeOrderController { // 查询订单 TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id); if (order == null) { - return success(null); + return success(null, ORDER_NOT_FOUND.getMsg()); } // 查询订单项 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java index 3e322c786..6b8c14725 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -56,6 +56,10 @@ public class AppTradeOrderSettlementReqVO { @Schema(description = "拼团团长编号", example = "2048") private Long combinationHeadId; + // ========== 砍价活动相关字段 ========== + @Schema(description = "砍价活动编号", example = "123") + private Long bargainActivityId; + @Data @Schema(description = "用户 App - 商品项") @Valid diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java new file mode 100644 index 000000000..781975aca --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.trade.dal.redis.no; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Repository; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +/** + * 订单序号的 Redis DAO + * + * @author HUIHUI + */ +@Repository +public class TradeOrderNoRedisDAO { + public static final String TRADE_ORDER_NO_PREFIX = "O"; + + @Resource + private StringRedisTemplate stringRedisTemplate; + + /** + * 生成序号 + * + * @param prefix 前缀 + * @return 序号 + */ + public String generate(String prefix) { + String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN); + Long no = stringRedisTemplate.opsForValue().increment(noPrefix); + return noPrefix + no; + } + +} 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 c4cfaee83..8b8ceef20 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 @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; @@ -25,11 +24,14 @@ import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi; import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; +import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO; @@ -45,6 +47,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; +import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO; import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.*; @@ -70,7 +73,7 @@ import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_EQUAL; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_PAID; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; @@ -88,6 +91,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { private TradeOrderMapper tradeOrderMapper; @Resource private TradeOrderItemMapper tradeOrderItemMapper; + @Resource + private TradeOrderNoRedisDAO orderNoRedisDAO; @Resource private CartService cartService; @@ -111,6 +116,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Resource private BargainRecordApi bargainRecordApi; @Resource + private SeckillActivityApi seckillActivityApi; + @Resource + private BargainActivityApi bargainActivityApi; + @Resource private MemberUserApi memberUserApi; @Resource private MemberLevelApi memberLevelApi; @@ -189,22 +198,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // TODO @puhui999:这个逻辑,先抽个小方法;未来要通过设计模式,把这些拼团之类的逻辑,抽象出去 // 拼团 if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { - MemberUserRespDTO user = memberUserApi.getUser(userId); - List recordRespDTOS = combinationRecordApi.getRecordListByUserIdAndActivityId(userId, createReqVO.getCombinationActivityId()); - // TODO 拼团一次应该只能选择一种规格的商品 - TradeOrderItemDO orderItemDO = orderItems.get(0); - if (CollUtil.isNotEmpty(recordRespDTOS)) { - List skuIds = convertList(recordRespDTOS, CombinationRecordRespDTO::getSkuId, item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())); - List tradeOrderItemDOS = tradeOrderItemMapper.selectListByOrderIdAnSkuId(convertList(recordRespDTOS, - CombinationRecordRespDTO::getOrderId, item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds); - combinationRecordApi.validateCombinationLimitCount(createReqVO.getCombinationActivityId(), - CollectionUtils.getSumValue(tradeOrderItemDOS, TradeOrderItemDO::getCount, Integer::sum), orderItemDO.getCount()); - } - - combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItemDO, createReqVO, user)); + createCombinationRecord(userId, createReqVO, orderItems, order); } // 3.2 秒杀的特殊逻辑 - // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除 if (Objects.equals(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) { } @@ -214,6 +210,22 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { return order; } + private void createCombinationRecord(Long userId, AppTradeOrderCreateReqVO createReqVO, List orderItems, TradeOrderDO order) { + MemberUserRespDTO user = memberUserApi.getUser(userId); + List recordRespDTOS = combinationRecordApi.getRecordListByUserIdAndActivityId(userId, createReqVO.getCombinationActivityId()); + // TODO 拼团一次应该只能选择一种规格的商品 + TradeOrderItemDO orderItemDO = orderItems.get(0); + if (CollUtil.isNotEmpty(recordRespDTOS)) { + List skuIds = convertList(recordRespDTOS, CombinationRecordRespDTO::getSkuId, item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())); + List tradeOrderItemDOS = tradeOrderItemMapper.selectListByOrderIdAnSkuId(convertList(recordRespDTOS, + CombinationRecordRespDTO::getOrderId, item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds); + combinationRecordApi.validateCombinationLimitCount(createReqVO.getCombinationActivityId(), + CollectionUtils.getSumValue(tradeOrderItemDOS, TradeOrderItemDO::getCount, Integer::sum), orderItemDO.getCount()); + } + + combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItemDO, createReqVO, user)); + } + // TODO @puhui999:订单超时,自动取消; /** @@ -240,8 +252,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { address = validateAddress(userId, createReqVO.getAddressId()); } TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address); + String no = orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX); order.setType(validateActivity(createReqVO)); - order.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @puhui999: 参考支付订单,的 no 生成哈; + order.setNo(no); order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); @@ -293,19 +306,23 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, TradeOrderDO tradeOrderDO, List orderItems, TradePriceCalculateRespBO calculateRespBO) { - // 下单时扣减商品库存 - // TODO @puhui999:扣库存,需要前置; + Integer count = getSumValue(orderItems, TradeOrderItemDO::getCount, Integer::sum); // 1)如果是秒杀商品:额外扣减秒杀的库存; - // 2)如果是拼团活动:额外扣减拼团的库存; - // 3)如果是砍价活动:额外扣减砍价的库存; - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); - - // 删除购物车商品 - Set cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); - if (CollUtil.isNotEmpty(cartIds)) { - cartService.deleteCart(userId, cartIds); + if (Objects.equals(TradeOrderTypeEnum.SECKILL.getType(), tradeOrderDO.getType())) { + SeckillActivityUpdateStockReqDTO updateStockReqDTO = new SeckillActivityUpdateStockReqDTO(); + updateStockReqDTO.setActivityId(createReqVO.getSeckillActivityId()); + updateStockReqDTO.setCount(count); + updateStockReqDTO.setItems(CollectionUtils.convertList(orderItems, item -> { + SeckillActivityUpdateStockReqDTO.Item item1 = new SeckillActivityUpdateStockReqDTO.Item(); + item1.setSpuId(item.getSpuId()); + item1.setSkuId(item.getSkuId()); + item1.setCount(item.getCount()); + return item1; + })); + seckillActivityApi.updateSeckillStock(updateStockReqDTO); } - + // 2)如果是砍价活动:额外扣减砍价的库存; + bargainActivityApi.updateBargainActivityStock(createReqVO.getBargainActivityId(), count); // 扣减积分 TODO 芋艿:待实现,需要前置; // 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣 @@ -315,6 +332,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { .setOrderId(tradeOrderDO.getId())); } + // 下单时扣减商品库存 + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); + + // 删除购物车商品 + Set cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); + if (CollUtil.isNotEmpty(cartIds)) { + cartService.deleteCart(userId, cartIds); + } + // 生成预支付 createPayOrder(tradeOrderDO, orderItems, calculateRespBO); @@ -464,11 +490,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { */ private TradeOrderDO validateOrderDeliverable(Long id) { TradeOrderDO order = validateOrderExists(id); - // 校验订单是否是待发货状态 - // TODO @puhui999:已经发货,可以重新发货,修改信息; - if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())) { - throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); - } // 校验订单是否退款 if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) { throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE); @@ -540,14 +561,25 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { if (order.getPayStatus()) { throw exception(ORDER_UPDATE_PRICE_FAIL_PAID); } - // TODO @puhui999:如果改价,需要校验下是否真的变化; + if (ObjectUtil.equal(order.getAdjustPrice(), reqVO.getAdjustPrice())) { + throw exception(ORDER_UPDATE_PRICE_FAIL_EQUAL); + } - // 更新 - // TODO @puhui999:TradeOrderItemDO 需要做 adjustPrice 的分摊;另外,支付订单那的价格,需要 update 下; + List itemDOs = tradeOrderItemMapper.selectListByOrderId(order.getId()); + // TradeOrderItemDO 需要做 adjustPrice 的分摊 + int price = reqVO.getAdjustPrice() / itemDOs.size(); + itemDOs.forEach(item -> { + item.setAdjustPrice(price); + }); + // 更新 TradeOrderItem + tradeOrderItemMapper.updateBatch(itemDOs); + // 更新订单 TradeOrderDO update = TradeOrderConvert.INSTANCE.convert(reqVO); update.setPayPrice(update.getPayPrice() + update.getAdjustPrice()); // TODO @芋艿:改价时,赠送的积分,要不要做改动??? tradeOrderMapper.updateById(update); + // 更新支付订单 + payOrderApi.updatePayOrderPriceById(order.getPayOrderId(), update.getPayPrice()); } @Override diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java index 5c1905ebe..94a79ea3d 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java @@ -29,4 +29,11 @@ public interface PayOrderApi { */ PayOrderRespDTO getOrder(Long id); + /** + * 更新支付订单价格 + * + * @param payOrderId 支付单编号 + * @param payPrice 支付单价格 + */ + void updatePayOrderPriceById(Long payOrderId, Integer payPrice); } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index ee8947286..2ee11f1be 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -28,6 +28,7 @@ public interface ErrorCodeConstants { ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}"); ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, "支付订单退款失败,原因:状态不是已支付或已退款"); ErrorCode ORDER_UPDATE_PRICE_FAIL_PAID = new ErrorCode(1007002006, "支付订单调价失败,原因:支付订单已付款,不能调价"); + ErrorCode ORDER_UPDATE_PRICE_FAIL_EQUAL = new ErrorCode(1007002007, "支付订单调价失败,原因:价格没有变化"); // ========== ORDER 模块(拓展单) 1007003000 ========== ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java index a245880ba..18c9ff3ef 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java @@ -31,4 +31,10 @@ public class PayOrderApiImpl implements PayOrderApi { return PayOrderConvert.INSTANCE.convert2(order); } + @Override + public void updatePayOrderPriceById(Long payOrderId, Integer payPrice) { + payOrderService.updatePayOrderPriceById(payOrderId, payPrice); + } + + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java index 3d66ae9b1..e03bda117 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java @@ -33,7 +33,7 @@ public interface PayOrderService { /** * 获得支付订单 * - * @param appId 应用编号 + * @param appId 应用编号 * @param merchantOrderId 商户订单编号 * @return 支付订单 */ @@ -75,7 +75,7 @@ public interface PayOrderService { * 提交支付 * 此时,会发起支付渠道的调用 * - * @param reqVO 提交请求 + * @param reqVO 提交请求 * @param userIp 提交 IP * @return 提交结果 */ @@ -93,11 +93,19 @@ public interface PayOrderService { /** * 更新支付订单的退款金额 * - * @param id 编号 + * @param id 编号 * @param incrRefundPrice 增加的退款金额 */ void updateOrderRefundPrice(Long id, Integer incrRefundPrice); + /** + * 更新支付订单价格 + * + * @param payOrderId 支付单编号 + * @param payPrice 支付单价格 + */ + void updatePayOrderPriceById(Long payOrderId, Integer payPrice); + /** * 获得支付订单 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java index d56035187..bb43295c2 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java @@ -410,6 +410,17 @@ public class PayOrderServiceImpl implements PayOrderService { } } + @Override + public void updatePayOrderPriceById(Long payOrderId, Integer payPrice) { + PayOrderDO order = orderMapper.selectById(payOrderId); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + + order.setPrice(payPrice); + orderMapper.updateById(order); + } + @Override public PayOrderExtensionDO getOrderExtension(Long id) { return orderExtensionMapper.selectById(id); From 3e09da012849bd45438344fe6a65eee78415dd92 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 8 Sep 2023 22:47:00 +0800 Subject: [PATCH 03/11] =?UTF-8?q?code=20review=EF=BC=9A=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E9=92=B1=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/order/PayOrderController.java | 21 ++- .../app/wallet/AppPayWalletController.java | 2 +- .../dal/dataobject/wallet/PayWalletDO.java | 2 + .../pay/dal/mysql/wallet/PayWalletMapper.java | 3 + .../framework/pay/wallet/WalletPayClient.java | 27 ++-- .../pay/service/wallet/PayWalletService.java | 24 +-- .../service/wallet/PayWalletServiceImpl.java | 145 +++++++++--------- .../PayWalletTransactionServiceImpl.java | 2 +- 8 files changed, 122 insertions(+), 104 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java index a47031a2a..896742636 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java @@ -6,14 +6,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.framework.pay.wallet.WalletPayClient; import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import com.google.common.collect.Maps; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -25,12 +26,17 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; 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.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; @Tag(name = "管理后台 - 支付订单") @RestController @@ -70,13 +76,16 @@ public class PayOrderController { @PostMapping("/submit") @Operation(summary = "提交支付订单") public CommonResult submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { - // 钱包支付需要 额外传 user_id 和 user_type + // 1. 钱包支付事,需要额外传 user_id 和 user_type if (Objects.equals(reqVO.getChannelCode(), PayChannelEnum.WALLET.getCode())) { - Map channelExtras = reqVO.getChannelExtras() == null ? new HashMap<>(8) : reqVO.getChannelExtras(); - channelExtras.put("user_id", String.valueOf(WebFrameworkUtils.getLoginUserId())); - channelExtras.put("user_type", String.valueOf(WebFrameworkUtils.getLoginUserType())); + Map channelExtras = reqVO.getChannelExtras() == null ? + Maps.newHashMapWithExpectedSize(2) : reqVO.getChannelExtras(); + channelExtras.put(WalletPayClient.USER_ID_KEY, String.valueOf(getLoginUserId())); + channelExtras.put(WalletPayClient.USER_TYPE_KEY, String.valueOf(getLoginUserType())); reqVO.setChannelExtras(channelExtras); } + + // 2. 提交支付 PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP()); return success(respVO); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java index 2c5f2d5f4..95c085cbc 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java @@ -37,7 +37,7 @@ public class AppPayWalletController { @Operation(summary = "获取钱包") @PreAuthenticated public CommonResult getPayWallet() { - PayWalletDO wallet = payWalletService.getOrCreatePayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); + PayWalletDO wallet = payWalletService.getOrCreateWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); return success(PayWalletConvert.INSTANCE.convert(wallet)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java index 92eb620da..4bf8e6151 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java @@ -37,6 +37,8 @@ public class PayWalletDO extends BaseDO { */ private Integer userType; + // TODO @jason:三个都搞 integer?应该要统一哈 + /** * 余额,单位分 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index ccacdd376..47717d04a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java @@ -15,6 +15,7 @@ public interface PayWalletMapper extends BaseMapperX { PayWalletDO::getUserType, userType); } + // TODO @jason:减少时,需要 update price -= ? where price >= ?,避免并发问题。现在基于 price 来过滤,虽然也能解决并发问题,但是冲突概率会高一点;可以看到 TradeBrokerageUserMapper 的做法; /** * 当余额减少时候更新 * @@ -27,6 +28,7 @@ public interface PayWalletMapper extends BaseMapperX { */ default int updateWhenDecBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge, Long totalExpense, Integer price, Long id) { + // TODO @jason:这种偏判断的,最红放在 service 层;mapper 可以写多个方法; PayWalletDO updateDO = new PayWalletDO().setBalance(balance - price); if(bizType == PayWalletBizTypeEnum.PAYMENT){ updateDO.setTotalExpense(totalExpense + price); @@ -40,6 +42,7 @@ public interface PayWalletMapper extends BaseMapperX { .ge(PayWalletDO::getBalance, price)); } + // TODO @jason:类似上面的修改建议哈; /** * 当余额增加时候更新 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java index 42da490d2..47e8217d3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java @@ -37,13 +37,13 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.REFUND_NOT_FO @Slf4j public class WalletPayClient extends AbstractPayClient { + public static final String USER_ID_KEY = "user_id"; + public static final String USER_TYPE_KEY = "user_type"; + private PayWalletService wallService; - private PayWalletTransactionService walletTransactionService; - - private PayOrderService payOrderService; - - private PayRefundService payRefundService; + private PayOrderService orderService; + private PayRefundService refundService; public WalletPayClient(Long channelId, NonePayClientConfig config) { super(channelId, PayChannelEnum.WALLET.getCode(), config); @@ -62,8 +62,9 @@ public class WalletPayClient extends AbstractPayClient { @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { try { - String userId = MapUtil.getStr(reqDTO.getChannelExtras(), "user_id"); - String userType = MapUtil.getStr(reqDTO.getChannelExtras(), "user_type"); + // TODO @jason:直接 getLong 和 getInt 会不会更简洁哈 + String userId = MapUtil.getStr(reqDTO.getChannelExtras(), USER_ID_KEY); + String userType = MapUtil.getStr(reqDTO.getChannelExtras(), USER_TYPE_KEY); Assert.notEmpty(userId, "用户 id 不能为空"); Assert.notEmpty(userType, "用户类型不能为空"); PayWalletTransactionDO transaction = wallService.orderPay(Long.valueOf(userId), Integer.valueOf(userType), @@ -92,10 +93,10 @@ public class WalletPayClient extends AbstractPayClient { @Override protected PayOrderRespDTO doGetOrder(String outTradeNo) { - if (payOrderService == null) { - payOrderService = SpringUtil.getBean(PayOrderService.class); + if (orderService == null) { + orderService = SpringUtil.getBean(PayOrderService.class); } - PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo); + PayOrderExtensionDO orderExtension = orderService.getOrderExtensionByNo(outTradeNo); // 支付交易拓展单不存在, 返回关闭状态 if (orderExtension == null) { return PayOrderRespDTO.closedOf(String.valueOf(ORDER_EXTENSION_NOT_FOUND.getCode()), @@ -147,10 +148,10 @@ public class WalletPayClient extends AbstractPayClient { @Override protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { - if (payRefundService == null) { - payRefundService = SpringUtil.getBean(PayRefundService.class); + if (refundService == null) { + refundService = SpringUtil.getBean(PayRefundService.class); } - PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo); + PayRefundDO payRefund = refundService.getRefundByNo(outRefundNo); // 支付退款单不存在, 返回退款失败状态 if (payRefund == null) { return PayRefundRespDTO.failureOf(String.valueOf(REFUND_NOT_FOUND), REFUND_NOT_FOUND.getMsg(), 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 3ea75ad09..28f9849b5 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 @@ -12,12 +12,14 @@ import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; public interface PayWalletService { /** - * 获取钱包信息,如果不存在创建钱包。由于用户注册时候不会创建钱包 + * 获取钱包信息 + * + * 如果不存在,则创建钱包。由于用户注册时候不会创建钱包 * * @param userId 用户编号 * @param userType 用户类型 */ - PayWalletDO getOrCreatePayWallet(Long userId, Integer userType); + PayWalletDO getOrCreateWallet(Long userId, Integer userType); /** * 钱包订单支付 @@ -29,6 +31,14 @@ public interface PayWalletService { */ PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price); + /** + * 钱包订单支付退款 + * + * @param outRefundNo 外部退款号 + * @param refundPrice 退款金额 + * @param reason 退款原因 + */ + PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason); /** * 扣减钱包余额 @@ -43,7 +53,6 @@ public interface PayWalletService { PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, Long bizId, PayWalletBizTypeEnum bizType, Integer price); - /** * 增加钱包余额 * @@ -57,13 +66,4 @@ public interface PayWalletService { PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, Long bizId, PayWalletBizTypeEnum bizType, Integer price); - /** - * 钱包订单支付退款 - * - * @param outRefundNo 外部退款号 - * @param refundPrice 退款金额 - * @param reason 退款原因 - */ - PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason); - } 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 ea607c0e8..d017e5332 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 @@ -43,81 +43,124 @@ public class PayWalletServiceImpl implements PayWalletService { private static final String WALLET_REFUND_NO_PREFIX = "WR"; @Resource - private PayWalletMapper payWalletMapper; + private PayWalletMapper walletMapper; @Resource private PayNoRedisDAO noRedisDAO; @Resource - private PayWalletTransactionService payWalletTransactionService; + private PayWalletTransactionService walletTransactionService; @Resource @Lazy - private PayOrderService payOrderService; + private PayOrderService orderService; @Resource @Lazy - private PayRefundService payRefundService; + private PayRefundService refundService; @Override - public PayWalletDO getOrCreatePayWallet(Long userId, Integer userType) { - PayWalletDO payWalletDO = payWalletMapper.selectByUserIdAndType(userId, userType); - if (payWalletDO == null) { - payWalletDO = new PayWalletDO(); - payWalletDO.setUserId(userId); - payWalletDO.setUserType(userType); - payWalletDO.setBalance(0); - payWalletDO.setTotalExpense(0L); - payWalletDO.setTotalRecharge(0L); - payWalletDO.setCreateTime(LocalDateTime.now()); - payWalletMapper.insert(payWalletDO); + public PayWalletDO getOrCreateWallet(Long userId, Integer userType) { + PayWalletDO wallet = walletMapper.selectByUserIdAndType(userId, userType); + if (wallet == null) { + wallet = new PayWalletDO().setUserId(userId).setUserType(userType) + .setBalance(0).setTotalExpense(0L).setTotalRecharge(0L); + wallet.setCreateTime(LocalDateTime.now()); + walletMapper.insert(wallet); } - return payWalletDO; + return wallet; } - @Override @Transactional(rollbackFor = Exception.class) public PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price) { - // 判断支付交易拓展单是否存 - PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo); + // 1. 判断支付交易拓展单是否存 + PayOrderExtensionDO orderExtension = orderService.getOrderExtensionByNo(outTradeNo); if (orderExtension == null) { throw exception(ORDER_EXTENSION_NOT_FOUND); } + // 2. 扣减余额 return reduceWalletBalance(userId, userType, orderExtension.getOrderId(), PAYMENT, price); } + @Override + @Transactional(rollbackFor = Exception.class) + public PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason) { + // 1.1 判断退款单是否存在 + PayRefundDO payRefund = refundService.getRefundByNo(outRefundNo); + if (payRefund == null) { + throw exception(REFUND_NOT_FOUND); + } + // 1.2 校验是否可以退款 + Long walletId = validateWalletCanRefund(payRefund.getId(), payRefund.getChannelOrderNo(), refundPrice); + PayWalletDO wallet = walletMapper.selectById(walletId); + Assert.notNull(wallet, "钱包 {} 不存在", walletId); + // 2. 增加余额 + return addWalletBalance(wallet.getUserId(), wallet.getUserType(), payRefund.getId(), PAYMENT_REFUND, refundPrice); + } + + /** + * 校验是否能退款 + * + * @param refundId 支付退款单 id + * @param walletPayNo 钱包支付 no + */ + private Long validateWalletCanRefund(Long refundId, String walletPayNo, Integer refundPrice) { + // 1. 校验钱包支付交易存在 + PayWalletTransactionDO walletTransaction = walletTransactionService.getWalletTransactionByNo(walletPayNo); + if (walletTransaction == null) { + throw exception(WALLET_TRANSACTION_NOT_FOUND); + } + // 原来的支付金额 + // TODO @jason:应该允许多次退款哈; + int amount = - walletTransaction.getPrice(); + if (refundPrice != amount) { + throw exception(WALLET_REFUND_AMOUNT_ERROR); + } + PayWalletTransactionDO refundTransaction = walletTransactionService.getWalletTransaction( + String.valueOf(refundId), PAYMENT_REFUND); + if (refundTransaction != null) { + throw exception(WALLET_REFUND_EXIST); + } + return walletTransaction.getWalletId(); + } + @Override public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, Long bizId, PayWalletBizTypeEnum bizType, Integer price) { // 1.1 获取钱包 - PayWalletDO payWallet = getOrCreatePayWallet(userId, userType); + PayWalletDO payWallet = getOrCreateWallet(userId, userType); // 1.2 判断余额是否足够 int afterBalance = payWallet.getBalance() - price; if (afterBalance < 0) { throw exception(WALLET_BALANCE_NOT_ENOUGH); } + // TODO jason:建议基于 where price >= 来做哈;然后抛出 WALLET_BALANCE_NOT_ENOUGH // 2.1 扣除余额 - int number = payWalletMapper.updateWhenDecBalance(bizType,payWallet.getBalance(), payWallet.getTotalRecharge(), - payWallet.getTotalExpense(), price, payWallet.getId()); + int number = walletMapper.updateWhenDecBalance(bizType, payWallet.getBalance(), + payWallet.getTotalRecharge(), payWallet.getTotalExpense(), price, payWallet.getId()); if (number == 0) { throw exception(TOO_MANY_REQUESTS); } + // 2.2 生成钱包流水 + // TODO @jason:walletNo 交给 payWalletTransactionService 自己生成哈; String walletNo = generateWalletNo(bizType); PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) .setNo(walletNo).setPrice(-price).setBalance(afterBalance) .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()).setTitle(bizType.getDescription()); - payWalletTransactionService.createWalletTransaction(walletTransaction); + // TODO @jason:是不是可以 createWalletTransaction 搞个 bo 参数,然后 PayWalletTransactionDO 交回给 walletTransactionService 更好;然后把参数简化下 + walletTransactionService.createWalletTransaction(walletTransaction); return walletTransaction; } @Override - public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, Long bizId, - PayWalletBizTypeEnum bizType, Integer price) { + public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, + Long bizId, PayWalletBizTypeEnum bizType, Integer price) { // 1.1 获取钱包 - PayWalletDO payWallet = getOrCreatePayWallet(userId, userType); + PayWalletDO payWallet = getOrCreateWallet(userId, userType); // 2.1 增加余额 - int number = payWalletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(), + // TODO @jason:类似上面的思路哈; + int number = walletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(), payWallet.getTotalExpense(), price, payWallet.getId()); if (number == 0) { throw exception(TOO_MANY_REQUESTS); @@ -129,63 +172,23 @@ public class PayWalletServiceImpl implements PayWalletService { .setNo(walletNo).setPrice(price).setBalance(payWallet.getBalance()+price) .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()) .setTitle(bizType.getDescription()); - payWalletTransactionService.createWalletTransaction(newWalletTransaction); + walletTransactionService.createWalletTransaction(newWalletTransaction); return newWalletTransaction; } private String generateWalletNo(PayWalletBizTypeEnum bizType) { + // TODO @jason:对于余额来说,是不是直接 W+序号就行了,它其实不关注业务;;;不然就耦合啦 String no = ""; switch(bizType){ - case PAYMENT : + case PAYMENT: no = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); break; - case PAYMENT_REFUND : + case PAYMENT_REFUND: no = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); break; default : - // TODO 待增加 } return no; } - @Override - @Transactional(rollbackFor = Exception.class) - public PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason) { - // 1.1 判断退款单是否存在 - PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo); - if (payRefund == null) { - throw exception(REFUND_NOT_FOUND); - } - // 1.2 校验是否可以退款 - Long walletId = validateWalletCanRefund(payRefund.getId(), payRefund.getChannelOrderNo(), refundPrice); - - PayWalletDO payWallet = payWalletMapper.selectById(walletId); - Assert.notNull(payWallet, "钱包 {} 不存在", walletId); - return addWalletBalance(payWallet.getUserId(), payWallet.getUserType(),payRefund.getId(), PAYMENT_REFUND, refundPrice); - } - - /** - * 校验是否能退款 - * - * @param refundId 支付退款单 id - * @param walletPayNo 钱包支付 no - */ - private Long validateWalletCanRefund(Long refundId, String walletPayNo, Integer refundPrice) { - // 查询钱包支付交易 - PayWalletTransactionDO payWalletTransaction = payWalletTransactionService.getWalletTransactionByNo(walletPayNo); - if (payWalletTransaction == null) { - throw exception(WALLET_TRANSACTION_NOT_FOUND); - } - // 原来的支付金额 - int amount = - payWalletTransaction.getPrice(); - if (refundPrice != amount) { - throw exception(WALLET_REFUND_AMOUNT_ERROR); - } - PayWalletTransactionDO refundTransaction = payWalletTransactionService.getWalletTransaction( - String.valueOf(refundId), PAYMENT_REFUND); - if (refundTransaction != null) { - throw exception(WALLET_REFUND_EXIST); - } - return payWalletTransaction.getWalletId(); - } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java index 971f59416..05a2a4800 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java @@ -28,7 +28,7 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ @Override public PageResult getWalletTransactionPage(Long userId, Integer userType, AppPayWalletTransactionPageReqVO pageVO) { - PayWalletDO wallet = payWalletService.getOrCreatePayWallet(userId, userType); + PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType); return payWalletTransactionMapper.selectPage(wallet.getId(), pageVO); } From 87c55784c4bd119c28a24c758c8d66b3dbb5fdca Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 9 Sep 2023 01:27:55 +0800 Subject: [PATCH 04/11] =?UTF-8?q?code=20review=EF=BC=9A=E8=90=A5=E9=94=80?= =?UTF-8?q?=E6=B4=BB=E5=8A=A8+=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/pojo/CommonResult.java | 8 -- .../api/combination/CombinationRecordApi.java | 4 +- .../api/seckill/SeckillActivityApi.java | 1 - .../dto/SeckillActivityUpdateStockReqDTO.java | 4 + .../api/bargain/BargainActivityApiImpl.java | 2 + .../api/seckill/SeckillActivityApiImpl.java | 11 ++- .../combination/CombinationRecordDO.java | 84 +++++++++++-------- .../seckill/SeckillActivityService.java | 4 +- .../seckill/SeckillActivityServiceImpl.java | 8 +- .../aftersale/TradeAfterSaleController.java | 9 +- .../admin/order/TradeOrderController.java | 9 +- .../app/order/AppTradeOrderController.java | 8 +- .../vo/AppTradeOrderSettlementReqVO.java | 2 + .../dal/redis/no/TradeOrderNoRedisDAO.java | 1 + .../order/TradeOrderUpdateServiceImpl.java | 4 + .../module/pay/api/order/PayOrderApi.java | 2 + .../module/pay/api/order/PayOrderApiImpl.java | 1 - .../service/order/PayOrderServiceImpl.java | 1 + 18 files changed, 96 insertions(+), 67 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java index 3a974456e..e29292dd8 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java @@ -68,14 +68,6 @@ public class CommonResult implements Serializable { return result; } - public static CommonResult success(T data, String msg) { - CommonResult result = new CommonResult<>(); - result.code = GlobalErrorCodeConstants.SUCCESS.getCode(); - result.data = data; - result.msg = msg; - return result; - } - public static boolean isSuccess(Integer code) { return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode()); } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java index c03559785..859eb5c7e 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java @@ -52,7 +52,7 @@ public interface CombinationRecordApi { void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount); /** - * 更新拼团状态为 成功 + * 更新拼团状态为成功 * * @param userId 用户编号 * @param orderId 订单编号 @@ -60,7 +60,7 @@ public interface CombinationRecordApi { void updateRecordStatusToSuccess(Long userId, Long orderId); /** - * 更新拼团状态为 失败 + * 更新拼团状态为失败 * * @param userId 用户编号 * @param orderId 订单编号 diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java index 09ec051a3..9c5cf1d35 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateSt */ public interface SeckillActivityApi { - /** * 更新秒杀库存 * diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java index 476ba8e15..df7c5649c 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java @@ -12,6 +12,10 @@ import java.util.List; @Data public class SeckillActivityUpdateStockReqDTO { + // TODO @puhui999:参数校验 + + // TODO @puhui999:秒杀的话,一次只能购买一种商品哈;不能多个哈; + /** * 活动编号 */ diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java index 826b4b2aa..02620c5ec 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java @@ -23,6 +23,7 @@ public class BargainActivityApiImpl implements BargainActivityApi { @Override public void updateBargainActivityStock(Long activityId, Integer count) { + // TODO @puhui999:可以整个实现到 bargainActivityService 中 // 查询砍价活动 BargainActivityDO activity = bargainActivityService.getBargainActivity(activityId); if (activity == null) { @@ -30,6 +31,7 @@ public class BargainActivityApiImpl implements BargainActivityApi { } // 更新砍价库存 + // TODO @puhui999:考虑下并发更新问题 BargainActivityUpdateReqVO reqVO = new BargainActivityUpdateReqVO(); reqVO.setId(activityId); reqVO.setStock(activity.getStock() - count); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java index 299316aa0..1f5c15755 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java @@ -27,14 +27,19 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { @Resource private SeckillActivityService activityService; + // TODO @puhui:建议这块弄到 activityService 实现哈; + // TODO @puhui:这个方法,要考虑事务性 @Override public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) { + // TODO @puhui999:长方法,最好有 1.1 1.2 2.1 这种步骤哈; SeckillActivityDO seckillActivity = activityService.getSeckillActivity(updateStockReqDTO.getActivityId()); if (seckillActivity.getStock() < updateStockReqDTO.getCount()) { throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); } // 获取活动商品 + // TODO @puhui999:在一个方法里,dos 和 dolist 最好保持一致,要么用 s,要么用 list 哈; List productDOs = activityService.getSeckillProductListByActivityId(updateStockReqDTO.getActivityId()); + // TODO @puhui999:这个是不是搞成 CollectionUtils.convertMultiMap() List items = updateStockReqDTO.getItems(); Map> map = new HashMap<>(); items.forEach(item -> { @@ -49,9 +54,11 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { } }); // 过滤出购买的商品 + // TODO @puhui999:productDOList 可以简化成 productList;一般来说,do 之类不用带着哈,在变量里; List productDOList = CollectionUtils.filterList(productDOs, item -> map.get(item.getSpuId()).contains(item.getSkuId())); Map productDOMap = CollectionUtils.convertMap(items, SeckillActivityUpdateStockReqDTO.Item::getSkuId, p -> p); // 检查活动商品库存是否充足 + // TODO @puhui999:避免 b 这种无业务含义的变量; boolean b = CollectionUtils.anyMatch(productDOList, item -> { SeckillActivityUpdateStockReqDTO.Item item1 = productDOMap.get(item.getSkuId()); return (item.getStock() < item1.getCount()) || (item.getStock() - item1.getCount()) < 0; @@ -59,17 +66,19 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { if (b) { throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); } + // TODO @puhui999:类似 doList,应该和下面的 update 逻辑粘的更紧密一点;so 在空行的时候,应该挪到 74 之后里去;甚至更合理,应该是 79 之后;说白了,逻辑要分块,每个模块涉及的代码要紧密在一起; List doList = CollectionUtils.convertList(productDOList, item -> { item.setStock(item.getStock() - productDOMap.get(item.getSkuId()).getCount()); return item; }); // 更新活动库存 + // TODO @puhui999:考虑下并发更新 seckillActivity.setStock(seckillActivity.getStock() + updateStockReqDTO.getCount()); seckillActivity.setTotalStock(seckillActivity.getTotalStock() - updateStockReqDTO.getCount()); activityService.updateSeckillActivity(seckillActivity); // 更新活动商品库存 - activityService.updateSeckillActivityProductByList(doList); + activityService.updateSeckillActivityProductList(doList); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java index 898d2a822..ea851d67e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java @@ -9,6 +9,7 @@ import lombok.*; import java.time.LocalDateTime; +// TODO 芋艿:把字段的顺序,和 do 顺序对齐下 /** * 拼团记录 DO * @@ -27,34 +28,28 @@ import java.time.LocalDateTime; @AllArgsConstructor public class CombinationRecordDO extends BaseDO { + /** + * 编号,主键自增 + */ @TableId private Long id; + /** * 拼团活动编号 + * + * 关联 {@link CombinationActivityDO#getId()} */ private Long activityId; + /** + * 拼团商品单价 + * + * 冗余 {@link CombinationProductDO#getCombinationPrice()} + */ + private Integer combinationPrice; /** * SPU 编号 */ private Long spuId; - /** - * SKU 编号 - */ - private Long skuId; - /** - * 用户编号 - */ - private Long userId; - /** - * 订单编号 - */ - private Long orderId; - /** - * 团长编号 - * - * 关联 {@link CombinationRecordDO#getId()} - */ - private Long headId; /** * 商品名字 */ @@ -64,9 +59,14 @@ public class CombinationRecordDO extends BaseDO { */ private String picUrl; /** - * 拼团商品单价 + * SKU 编号 */ - private Integer combinationPrice; + private Long skuId; + + /** + * 用户编号 + */ + private Long userId; /** * 用户昵称 */ @@ -75,6 +75,13 @@ public class CombinationRecordDO extends BaseDO { * 用户头像 */ private String avatar; + + /** + * 团长编号 + * + * 关联 {@link CombinationRecordDO#getId()} + */ + private Long headId; /** * 开团状态 * @@ -82,23 +89,9 @@ public class CombinationRecordDO extends BaseDO { */ private Integer status; /** - * 是否虚拟成团 + * 订单编号 */ - private Boolean virtualGroup; - /** - * 过期时间 - * - * {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算 - */ - private LocalDateTime expireTime; - /** - * 开始时间 (订单付款后开始的时间) - */ - private LocalDateTime startTime; - /** - * 结束时间(成团时间/失败时间) - */ - private LocalDateTime endTime; + private Long orderId; /** * 开团需要人数 * @@ -109,5 +102,24 @@ public class CombinationRecordDO extends BaseDO { * 已加入拼团人数 */ private Integer userCount; + /** + * 是否虚拟成团 + */ + private Boolean virtualGroup; + + /** + * 过期时间 + * + * 基于 {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算 + */ + private LocalDateTime expireTime; + /** + * 开始时间 (订单付款后开始的时间) + */ + private LocalDateTime startTime; + /** + * 结束时间(成团时间/失败时间) + */ + private LocalDateTime endTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java index 052b59561..079470814 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java @@ -43,9 +43,9 @@ public interface SeckillActivityService { /** * 更新秒杀活动商品 * - * @param productDOList 活动商品列表 + * @param productList 活动商品列表 */ - void updateSeckillActivityProductByList(List productDOList); + void updateSeckillActivityProductList(List productList); /** * 关闭秒杀活动 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java index 17fb9a90f..28f654049 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java @@ -93,8 +93,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId)); } // 2.2 过滤出所有 configIds 有交集的活动,判断是否存在重叠 - List activityDOs = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds)); - if (isNotEmpty(activityDOs)) { + List conflictActivityList = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds)); + if (isNotEmpty(conflictActivityList)) { throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); } } @@ -150,8 +150,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { } @Override - public void updateSeckillActivityProductByList(List productDOList) { - seckillProductMapper.updateBatch(productDOList); + public void updateSeckillActivityProductList(List productList) { + seckillProductMapper.updateBatch(productList); } /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java index 60afbc0ab..fec1fc1aa 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java @@ -36,7 +36,6 @@ 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.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.AFTER_SALE_NOT_FOUND; @Tag(name = "管理后台 - 售后订单") @RestController @@ -77,9 +76,11 @@ public class TradeAfterSaleController { public CommonResult getOrderDetail(@RequestParam("id") Long id) { // 查询订单 TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id); - if (afterSale == null) { - return success(null, AFTER_SALE_NOT_FOUND.getMsg()); - } + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理; +// if (afterSale == null) { +// return success(null, AFTER_SALE_NOT_FOUND.getMsg()); +// } + // 查询订单 TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId()); // 查询订单项 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java index 728c70c67..546519a1b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java @@ -25,7 +25,6 @@ import java.util.Map; 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.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; @Tag(name = "管理后台 - 交易订单") @RestController @@ -68,9 +67,11 @@ public class TradeOrderController { public CommonResult getOrderDetail(@RequestParam("id") Long id) { // 查询订单 TradeOrderDO order = tradeOrderQueryService.getOrder(id); - if (order == null) { - return success(null, ORDER_NOT_FOUND.getMsg()); - } + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理; +// if (order == null) { +// return success(null, ORDER_NOT_FOUND.getMsg()); +// } + // 查询订单项 List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id); // orderLog diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index a65836c33..a2ea2f79f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -33,7 +33,6 @@ 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.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; @Tag(name = "用户 App - 交易订单") @RestController @@ -82,9 +81,10 @@ public class AppTradeOrderController { public CommonResult getOrder(@RequestParam("id") Long id) { // 查询订单 TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id); - if (order == null) { - return success(null, ORDER_NOT_FOUND.getMsg()); - } + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理; +// if (order == null) { +// return success(null, ORDER_NOT_FOUND.getMsg()); +// } // 查询订单项 List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java index 6b8c14725..929a2ec19 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java @@ -50,6 +50,7 @@ public class AppTradeOrderSettlementReqVO { private Long seckillActivityId; // ========== 拼团活动相关字段 ========== + // TODO @puhui999:是不是拼团记录的编号哈? @Schema(description = "拼团活动编号", example = "1024") private Long combinationActivityId; @@ -57,6 +58,7 @@ public class AppTradeOrderSettlementReqVO { private Long combinationHeadId; // ========== 砍价活动相关字段 ========== + // TODO @puhui999:是不是砍价记录的编号哈? @Schema(description = "砍价活动编号", example = "123") private Long bargainActivityId; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java index 781975aca..8ad619269 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/redis/no/TradeOrderNoRedisDAO.java @@ -15,6 +15,7 @@ import java.time.LocalDateTime; */ @Repository public class TradeOrderNoRedisDAO { + public static final String TRADE_ORDER_NO_PREFIX = "O"; @Resource 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 56e887b42..94fdfe17e 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 @@ -561,6 +561,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { } @Override + // TODO @puhui999:考虑事务性 public void updateOrderPrice(TradeOrderUpdatePriceReqVO reqVO) { // 校验交易订单 TradeOrderDO order = validateOrderExists(reqVO.getId()); @@ -571,6 +572,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { throw exception(ORDER_UPDATE_PRICE_FAIL_EQUAL); } + // TODO @puhui999:应该是按照 payPrice 分配;并且要考虑取余问题;payPrice 也要考虑,item 里的 List itemDOs = tradeOrderItemMapper.selectListByOrderId(order.getId()); // TradeOrderItemDO 需要做 adjustPrice 的分摊 int price = reqVO.getAdjustPrice() / itemDOs.size(); @@ -578,8 +580,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { item.setAdjustPrice(price); }); // 更新 TradeOrderItem + // TODO @puhui999:不要整个对象去更新哈;应该 new 一下; tradeOrderItemMapper.updateBatch(itemDOs); // 更新订单 + // TODO @puhui999:要考虑多次修改价格,不能单单的 payPrice + 价格; TradeOrderDO update = TradeOrderConvert.INSTANCE.convert(reqVO); update.setPayPrice(update.getPayPrice() + update.getAdjustPrice()); // TODO @芋艿:改价时,赠送的积分,要不要做改动??? diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java index 94a79ea3d..b46f19534 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java @@ -29,6 +29,7 @@ public interface PayOrderApi { */ PayOrderRespDTO getOrder(Long id); + // TODO @puhui999:可以去掉 byId;然后 payOrderId 参数改成 id; /** * 更新支付订单价格 * @@ -36,4 +37,5 @@ public interface PayOrderApi { * @param payPrice 支付单价格 */ void updatePayOrderPriceById(Long payOrderId, Integer payPrice); + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java index 18c9ff3ef..1740e3bba 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java @@ -36,5 +36,4 @@ public class PayOrderApiImpl implements PayOrderApi { payOrderService.updatePayOrderPriceById(payOrderId, payPrice); } - } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java index 46d83d32c..2a6750e5d 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java @@ -413,6 +413,7 @@ public class PayOrderServiceImpl implements PayOrderService { @Override public void updatePayOrderPriceById(Long payOrderId, Integer payPrice) { + // TODO @puhui999:不能直接这样修改哈;应该只有未支付状态的订单才可以改;另外,如果价格如果没变,可以直接 return 哈; PayOrderDO order = orderMapper.selectById(payOrderId); if (order == null) { throw exception(ORDER_NOT_FOUND); From 557b09a15773733b7d3c1730059d222b37bfc508 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 9 Sep 2023 09:41:57 +0800 Subject: [PATCH 05/11] =?UTF-8?q?code=20review=EF=BC=9A=E5=88=86=E9=94=80?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/api/brokerage/BrokerageApiImpl.java | 1 + .../user/BrokerageUserController.java | 6 +-- .../AppBrokerageWithdrawCreateReqVO.java | 3 -- .../record/BrokerageRecordConvert.java | 18 +++----- .../brokerage/user/BrokerageUserConvert.java | 20 +++------ .../record/BrokerageRecordMapper.java | 1 + .../brokerage/user/BrokerageUserMapper.java | 1 + .../brokerage/bo/BrokerageAddReqBO.java | 2 + .../brokerage/bo/UserBrokerageSummaryBO.java | 2 + .../record/BrokerageRecordService.java | 2 +- .../record/BrokerageRecordServiceImpl.java | 7 +-- .../brokerage/user/BrokerageUserService.java | 8 ++-- .../user/BrokerageUserServiceImpl.java | 44 ++++++++++++------- .../order/TradeOrderUpdateServiceImpl.java | 12 ++--- .../yudao-module-member-biz/pom.xml | 5 --- .../app/user/AppMemberUserController.java | 12 +---- 16 files changed, 68 insertions(+), 76 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java index 4a534fa22..114ba39ac 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java @@ -20,6 +20,7 @@ public class BrokerageApiImpl implements BrokerageApi { @Resource private BrokerageUserService brokerageUserService; + @Override public BrokerageUserDTO getBrokerageUser(Long userId) { return BrokerageUserConvert.INSTANCE.convertDTO(brokerageUserService.getBrokerageUser(userId)); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java index f29e2c9a8..b0263f684 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java @@ -62,7 +62,7 @@ public class BrokerageUserController { @Operation(summary = "修改推广资格") @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-enable')") public CommonResult updateBrokerageEnabled(@Valid @RequestBody BrokerageUserUpdateBrokerageEnabledReqVO updateReqVO) { - brokerageUserService.updateBrokerageEnabled(updateReqVO.getId(), updateReqVO.getEnabled()); + brokerageUserService.updateBrokerageUserEnabled(updateReqVO.getId(), updateReqVO.getEnabled()); return success(true); } @@ -89,12 +89,12 @@ public class BrokerageUserController { // 合计分佣订单 Map userOrderSummaryMap = convertMap(userIds, userId -> userId, - userId -> brokerageRecordService.summaryByUserIdAndBizTypeAndStatus(userId, + userId -> brokerageRecordService.getUserBrokerageSummaryByUserId(userId, BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus())); // 合计推广用户数量 Map brokerageUserCountMap = convertMap(userIds, userId -> userId, - userId -> brokerageUserService.getCountByBindUserId(userId)); + userId -> brokerageUserService.getBrokerageUserCountByBindUserId(userId)); // todo 合计提现 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java index 752818130..a8b1523b2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java @@ -23,21 +23,18 @@ public class AppBrokerageWithdrawCreateReqVO { @Min(value = 1, message = "提现金额不能小于 1") private Integer price; - // ========== 银行卡、微信、支付宝 提现相关字段 ========== @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789") @NotBlank(message = "提现账号不能为空", groups = {Bank.class, Wechat.class, Alipay.class}) private String accountNo; - // ========== 微信、支付宝 提现相关字段 ========== @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png") @URL(message = "收款码的图片,必须是一个 URL") private String accountQrCodeUrl; - // ========== 银行卡 提现相关字段 ========== @Schema(description = "持卡人姓名", example = "张三") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java index 9307a4f55..f313fa39f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java @@ -30,25 +30,21 @@ public interface BrokerageRecordConvert { PageResult convertPage(PageResult page); + // TODO @疯狂:可能 title 不是很固化,会存在类似:沐晴成功购买《XXX JVM 实战》 default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId, - Integer brokerageFrozenDays, int brokerage, LocalDateTime unfreezeTime, + Integer brokerageFrozenDays, int brokeragePrice, LocalDateTime unfreezeTime, String title) { brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0); // 不冻结时,佣金直接就是结算状态 Integer status = brokerageFrozenDays > 0 ? BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus() : BrokerageRecordStatusEnum.SETTLEMENT.getStatus(); - return new BrokerageRecordDO() - .setUserId(user.getId()) - .setBizType(bizType.getType()) - .setBizId(bizId) - .setPrice(brokerage) - .setTotalPrice(user.getPrice()) + return new BrokerageRecordDO().setUserId(user.getId()) + .setBizType(bizType.getType()).setBizId(bizId) + .setPrice(brokeragePrice).setTotalPrice(user.getPrice()) .setTitle(title) - .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokerage / 100.0))) - .setStatus(status) - .setFrozenDays(brokerageFrozenDays) - .setUnfreezeTime(unfreezeTime); + .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokeragePrice / 100.0))) + .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java index 01d0be8c8..6f0222b5b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java @@ -37,24 +37,16 @@ public interface BrokerageUserConvert { PageResult result = convertPage(pageResult); for (BrokerageUserRespVO vo : result.getList()) { // 用户信息 - Optional.ofNullable(userMap.get(vo.getId())) - .ifPresent(user -> { - vo.setNickname(user.getNickname()); - vo.setAvatar(user.getAvatar()); - }); - + Optional.ofNullable(userMap.get(vo.getId())).ifPresent( + user -> vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); // 推广用户数量(一级) vo.setBrokerageUserCount(MapUtil.getInt(brokerageUserCountMap, vo.getId(), 0)); - + // 推广订单数量、推广订单金额 Optional orderSummaryOptional = Optional.ofNullable(userOrderSummaryMap.get(vo.getId())); - // 推广订单数量 - vo.setBrokerageOrderCount(orderSummaryOptional.map(UserBrokerageSummaryBO::getCount).orElse(0)); - // 推广订单金额 - vo.setBrokerageOrderPrice(orderSummaryOptional.map(UserBrokerageSummaryBO::getPrice).orElse(0)); - - // todo 已提现次数 + vo.setBrokerageOrderCount(orderSummaryOptional.map(UserBrokerageSummaryBO::getCount).orElse(0)) + .setBrokerageOrderPrice(orderSummaryOptional.map(UserBrokerageSummaryBO::getPrice).orElse(0)); + // todo 已提现次数、已提现金额 vo.setWithdrawCount(0); - // todo 已提现金额 vo.setWithdrawPrice(0); } return result; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java index 9f9aae824..b72b50ca7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java @@ -48,6 +48,7 @@ public interface BrokerageRecordMapper extends BaseMapperX { BrokerageRecordDO::getBizId, bizId); } + // TODO @疯狂:mysql 关键字,大写哈;这样看起来清晰点;例如说 SELECT COUNT(1) @Select("select count(1), sum(price) from trade_brokerage_record where user_id = #{userId} and biz_type = #{bizType} and status = #{status}") UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId, @Param("bizType") Integer bizType, diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java index ee90b3e7d..7fa3e415a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java @@ -111,4 +111,5 @@ public interface BrokerageUserMapper extends BaseMapperX { .eq(BrokerageUserDO::getId, id) .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null)); } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java index 07e07817e..ff16ba16a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java @@ -5,6 +5,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; /** * 佣金 增加 Request BO @@ -24,6 +25,7 @@ public class BrokerageAddReqBO { /** * 佣金基数 */ + @NotNull(message = "佣金基数不能为空") private Integer basePrice; /** * 一级佣金(固定) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java index ffbb3ed9a..4504290be 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java @@ -13,6 +13,7 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class UserBrokerageSummaryBO { + /** * 佣金数量 */ @@ -21,4 +22,5 @@ public class UserBrokerageSummaryBO { * 佣金总额 */ private Integer price; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordService.java index 64e5fe52f..a6ef0b659 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordService.java @@ -66,5 +66,5 @@ public interface BrokerageRecordService { * @param status 佣金状态 * @return 用户佣金汇总 */ - UserBrokerageSummaryBO summaryByUserIdAndBizTypeAndStatus(Long userId, Integer bizType, Integer status); + UserBrokerageSummaryBO getUserBrokerageSummaryByUserId(Long userId, Integer bizType, Integer status); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java index 960b45ae5..7740d7d06 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java @@ -89,6 +89,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { @Override @Transactional(rollbackFor = Exception.class) public void cancelBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId) { + // TODO @疯狂:userId 加进去查询,会不会更好一点?万一穿错参数; BrokerageRecordDO record = brokerageRecordMapper.selectByBizTypeAndBizId(bizType.getType(), bizId); if (record == null || ObjectUtil.notEqual(record.getUserId(), userId)) { log.error("[cancelBrokerage][userId({})][bizId({}) 更新为已失效失败:记录不存在]", userId, bizId); @@ -138,7 +139,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { * @param list 佣金增加参数列表 * @param brokerageFrozenDays 冻结天数 * @param brokeragePercent 佣金比例 - * @param fixedPriceFun 固定佣金 + * @param fixedPriceFun 固定佣金 // TODO 疯狂:这里是不是可以直接传递 fixedPrice 呀? * @param bizType 业务类型 */ private void addBrokerage(BrokerageUserDO user, List list, Integer brokerageFrozenDays, @@ -200,9 +201,9 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { } @Override - public UserBrokerageSummaryBO summaryByUserIdAndBizTypeAndStatus(Long userId, Integer bizType, Integer status) { + public UserBrokerageSummaryBO getUserBrokerageSummaryByUserId(Long userId, Integer bizType, Integer status) { UserBrokerageSummaryBO summaryBO = brokerageRecordMapper.selectCountAndSumPriceByUserIdAndBizTypeAndStatus(userId, bizType, status); - return summaryBO == null ? new UserBrokerageSummaryBO(0, 0) : summaryBO; + return summaryBO != null ? summaryBO : new UserBrokerageSummaryBO(0, 0); } @Transactional(rollbackFor = Exception.class) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java index f06bb7ffc..b3d265b29 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java @@ -52,7 +52,7 @@ public interface BrokerageUserService { * @param id 用户编号 * @param enabled 推广资格 */ - void updateBrokerageEnabled(Long id, Boolean enabled); + void updateBrokerageUserEnabled(Long id, Boolean enabled); /** * 获得用户的推广人 @@ -79,20 +79,21 @@ public interface BrokerageUserService { void updateUserFrozenPrice(Long id, Integer frozenPrice); /** - * 更新用户冻结佣金(减少), 更新用户佣金(增加) + * 更新用户冻结佣金(减少),更新用户佣金(增加) * * @param id 用户编号 * @param frozenPrice 减少冻结佣金(负数) */ void updateFrozenPriceDecrAndPriceIncr(Long id, Integer frozenPrice); + // TODO @疯狂:这个后面可能要支持下,二级 /** * 获得推广用户数量(一级) * * @param bindUserId 绑定的推广员编号 * @return 推广用户数量 */ - Long getCountByBindUserId(Long bindUserId); + Long getBrokerageUserCountByBindUserId(Long bindUserId); /** * 【会员】绑定推广员 @@ -103,4 +104,5 @@ public interface BrokerageUserService { * @return 是否绑定 */ boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java index 6d6d7d2ac..2dd7fb03b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java @@ -57,18 +57,22 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { public void updateBrokerageUserId(Long id, Long bindUserId) { // 校验存在 validateBrokerageUserExists(id); + + // 情况一:清除推广员 if (bindUserId == null) { // 清除推广员 brokerageUserMapper.updateBindUserIdAndBindUserTimeToNull(id); - } else { - // 修改推广员 - brokerageUserMapper.updateById(new BrokerageUserDO().setId(id) - .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now())); + return; } + + // 情况二:修改推广员 + // TODO @疯狂:要复用一些 validateCanBindUser 的校验哈; + brokerageUserMapper.updateById(new BrokerageUserDO().setId(id) + .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now())); } @Override - public void updateBrokerageEnabled(Long id, Boolean enabled) { + public void updateBrokerageUserEnabled(Long id, Boolean enabled) { // 校验存在 validateBrokerageUserExists(id); if (BooleanUtil.isTrue(enabled)) { @@ -124,36 +128,41 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { } @Override - public Long getCountByBindUserId(Long bindUserId) { + public Long getBrokerageUserCountByBindUserId(Long bindUserId) { + // TODO @疯狂:mapper 封装下哈;不直接在 service 调用这种基础 mapper 的基础方法 return brokerageUserMapper.selectCount(BrokerageUserDO::getBindUserId, bindUserId); } + // TODO @疯狂:因为现在 user 会存在使用验证码直接注册,所以 isNewUser 不太好传递;我们是不是可以约定绑定的时间,createTime 在 30 秒内,就认为新用户; @Override public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { + // TODO @疯狂:userId 为空,搞到参数校验里哇; if (userId == null) { throw exception(0); } - boolean isInsert = false; + // 1. 获得分销用户 + boolean isNewBrokerageUser = false; BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(userId); - // 分销用户不存在的情况:1.新注册 2.旧数据 3.分销功能关闭后又打开 - if (brokerageUser == null) { - isInsert = true; + if (brokerageUser == null) { // 分销用户不存在的情况:1. 新注册;2. 旧数据;3. 分销功能关闭后又打开 + isNewBrokerageUser = true; brokerageUser = new BrokerageUserDO().setId(userId).setBrokerageEnabled(false).setPrice(0).setFrozenPrice(0); } - // 校验能否绑定 + // 2.1 校验能否绑定 boolean validated = validateCanBindUser(brokerageUser, bindUserId, isNewUser); if (!validated) { return false; } - if (isInsert) { + // 2.2 绑定用户 + if (isNewBrokerageUser) { Integer enabledCondition = tradeConfigService.getTradeConfig().getBrokerageEnabledCondition(); - if (BrokerageEnabledConditionEnum.ALL.getCondition().equals(enabledCondition)) { - // 人人分销:用户默认就有分销资格 + if (BrokerageEnabledConditionEnum.ALL.getCondition().equals(enabledCondition)) { // 人人分销:用户默认就有分销资格 + // TODO @疯狂:应该设置下 brokerageTime,而不是 bindUserTime brokerageUser.setBrokerageEnabled(true).setBindUserTime(LocalDateTime.now()); } + // TODO @疯狂:这里是不是要设置 bindUserId、bindUserTime 字段哈; brokerageUserMapper.insert(brokerageUser); } else { brokerageUserMapper.updateById(new BrokerageUserDO().setId(userId) @@ -162,14 +171,16 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { return true; } + // TODO @疯狂:validate 方法,一般不返回 true false,而是抛出异常;如果要返回 true false 这种,方法名字可以改成 isUserCanBind private boolean validateCanBindUser(BrokerageUserDO user, Long bindUserId, Boolean isNewUser) { + // TODO @疯狂:bindUserId 为空,搞到参数校验里哇; if (bindUserId == null) { return false; } // 校验分销功能是否启用 TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig(); - if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) { + if (tradeConfig == null || BooleanUtil.isFalse(tradeConfig.getBrokerageEnabled())) { return false; } @@ -180,7 +191,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { // 校验要绑定的用户有无推广资格 BrokerageUserDO bindUser = brokerageUserMapper.selectById(bindUserId); - if (bindUser == null || !BooleanUtil.isTrue(bindUser.getBrokerageEnabled())) { + if (bindUser == null || BooleanUtil.isFalse(bindUser.getBrokerageEnabled())) { throw exception(BROKERAGE_BIND_USER_NOT_ENABLED); } @@ -200,6 +211,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { } } + // TODO @疯狂:这块是不是一直查询到根节点,中间不允许出现自己;就是不能形成环。虽然目前是 2 级,但是未来可能会改多级; = = 环的话,就会存在问题哈 // A->B->A:下级不能绑定自己的上级, A->B->C->A可以!! if (Objects.equals(user.getId(), bindUser.getBindUserId())) { throw exception(BROKERAGE_BIND_LOOP); 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 85d4caae0..7893d62a9 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 @@ -395,7 +395,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // 增加用户经验 getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId()); // 增加用户佣金 - getSelf().addBrokerageAsync(order.getUserId(), BrokerageRecordBizTypeEnum.ORDER, order.getId()); + getSelf().addBrokerageAsync(order.getUserId(), order.getId()); } /** @@ -675,7 +675,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // 扣减用户经验 getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId); // 更新分佣记录为已失效 - getSelf().cancelBrokerageAsync(order.getUserId(), BrokerageRecordBizTypeEnum.ORDER, id); + getSelf().cancelBrokerageAsync(order.getUserId(), id); } @Override @@ -785,16 +785,16 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @Async - protected void addBrokerageAsync(Long userId, BrokerageRecordBizTypeEnum bizType, Long orderId) { + protected void addBrokerageAsync(Long userId, Long orderId) { List orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); List list = convertList(orderItems, item -> TradeOrderConvert.INSTANCE.convert(item, productSkuApi.getSku(item.getSkuId()))); - brokerageRecordService.addBrokerage(userId, bizType, list); + brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, list); } @Async - protected void cancelBrokerageAsync(Long userId, BrokerageRecordBizTypeEnum bizType, Long orderItemId) { - brokerageRecordService.cancelBrokerage(userId, bizType, String.valueOf(orderItemId)); + protected void cancelBrokerageAsync(Long userId, Long orderItemId) { + brokerageRecordService.cancelBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, String.valueOf(orderItemId)); } /** diff --git a/yudao-module-member/yudao-module-member-biz/pom.xml b/yudao-module-member/yudao-module-member-biz/pom.xml index 1df7e7be8..a5eda05b0 100644 --- a/yudao-module-member/yudao-module-member-biz/pom.xml +++ b/yudao-module-member/yudao-module-member-biz/pom.xml @@ -33,11 +33,6 @@ yudao-module-infra-api ${revision} - - cn.iocoder.boot - yudao-module-trade-api - ${revision} - diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java index 461a1a5c5..9322f9146 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java @@ -8,8 +8,6 @@ import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.service.level.MemberLevelService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; -import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageApi; -import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; @@ -18,7 +16,6 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.Optional; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -32,23 +29,16 @@ public class AppMemberUserController { @Resource private MemberUserService userService; - @Resource private MemberLevelService levelService; - @Resource - private BrokerageApi brokerageApi; - @GetMapping("/get") @Operation(summary = "获得基本信息") @PreAuthenticated public CommonResult getUserInfo() { MemberUserDO user = userService.getUser(getLoginUserId()); MemberLevelDO level = levelService.getLevel(user.getLevelId()); - BrokerageUserDTO brokerageUser = brokerageApi.getBrokerageUser(user.getId()); - return success(MemberUserConvert.INSTANCE.convert(user, level) - .setBrokerageEnabled(Optional.ofNullable(brokerageUser).map(BrokerageUserDTO::getBrokerageEnabled).orElse(false)) - ); + return success(MemberUserConvert.INSTANCE.convert(user, level)); } @PutMapping("/update") From 5858f57fe91ed97693ed10a4bec399aa263bf757 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sat, 9 Sep 2023 18:32:53 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E9=92=B1=E5=8C=85=20review=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/pay_wallet.sql | 4 +- .../wallet/vo/wallet/AppPayWalletRespVO.java | 4 +- .../wallet/PayWalletTransactionConvert.java | 3 + .../dal/dataobject/wallet/PayWalletDO.java | 6 +- .../pay/dal/mysql/wallet/PayWalletMapper.java | 58 +++------- .../framework/pay/wallet/WalletPayClient.java | 13 ++- .../service/wallet/PayWalletServiceImpl.java | 101 ++++++------------ .../wallet/PayWalletTransactionService.java | 7 +- .../PayWalletTransactionServiceImpl.java | 18 +++- .../wallet/bo/CreateWalletTransactionBO.java | 48 +++++++++ 10 files changed, 132 insertions(+), 130 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java diff --git a/sql/mysql/pay_wallet.sql b/sql/mysql/pay_wallet.sql index bc2ad183e..7d092ef45 100644 --- a/sql/mysql/pay_wallet.sql +++ b/sql/mysql/pay_wallet.sql @@ -8,8 +8,8 @@ CREATE TABLE `pay_wallet` `user_id` bigint NOT NULL COMMENT '用户编号', `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', - `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', - `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', + `total_expense` int NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', + `total_recharge` 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 '更新者', diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java index c66cda871..bd0e0b9d7 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java @@ -11,9 +11,9 @@ public class AppPayWalletRespVO { private Integer balance; @Schema(description = "累计支出, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") - private Long totalExpense; + private Integer totalExpense; @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000") - private Long totalRecharge; + private Integer totalRecharge; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java index 9d1edaf6a..088bdecf3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.convert.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -12,4 +13,6 @@ public interface PayWalletTransactionConvert { PayWalletTransactionConvert INSTANCE = Mappers.getMapper(PayWalletTransactionConvert.class); PageResult convertPage(PageResult page); + + PayWalletTransactionDO convert(CreateWalletTransactionBO bo); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java index 4bf8e6151..4536ae635 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java @@ -37,8 +37,6 @@ public class PayWalletDO extends BaseDO { */ private Integer userType; - // TODO @jason:三个都搞 integer?应该要统一哈 - /** * 余额,单位分 */ @@ -47,10 +45,10 @@ public class PayWalletDO extends BaseDO { /** * 累计支出,单位分 */ - private Long totalExpense; + private Integer totalExpense; /** * 累计充值,单位分 */ - private Long totalRecharge; + private Integer totalRecharge; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index 47717d04a..9184621bd 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @Mapper @@ -15,56 +14,31 @@ public interface PayWalletMapper extends BaseMapperX { PayWalletDO::getUserType, userType); } - // TODO @jason:减少时,需要 update price -= ? where price >= ?,避免并发问题。现在基于 price 来过滤,虽然也能解决并发问题,但是冲突概率会高一点;可以看到 TradeBrokerageUserMapper 的做法; /** - * 当余额减少时候更新 + * 当消费退款时候, 更新钱包 * - * @param bizType 业务类型 - * @param balance 当前余额 - * @param totalRecharge 当前累计充值 - * @param totalExpense 当前累计支出 - * @param price 支出的金额 + * @param price 消费金额 * @param id 钱包 id */ - default int updateWhenDecBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge, - Long totalExpense, Integer price, Long id) { - // TODO @jason:这种偏判断的,最红放在 service 层;mapper 可以写多个方法; - PayWalletDO updateDO = new PayWalletDO().setBalance(balance - price); - if(bizType == PayWalletBizTypeEnum.PAYMENT){ - updateDO.setTotalExpense(totalExpense + price); - } - if (bizType == PayWalletBizTypeEnum.RECHARGE_REFUND) { - updateDO.setTotalRecharge(totalRecharge - price); - } - return update(updateDO, - new LambdaQueryWrapper().eq(PayWalletDO::getId, id) - .eq(PayWalletDO::getBalance, balance) - .ge(PayWalletDO::getBalance, price)); + default int updateWhenConsumptionRefund(Integer price, Long id){ + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" balance = balance + " + price + ", total_expense = total_expense - " + price) + .eq(PayWalletDO::getId, id); + return update(null, lambdaUpdateWrapper); } - // TODO @jason:类似上面的修改建议哈; /** - * 当余额增加时候更新 + * 当消费时候, 更新钱包 * - * @param bizType 业务类型 - * @param balance 当前余额 - * @param totalRecharge 当前累计充值 - * @param totalExpense 当前累计支出 - * @param price 金额 + * @param price 消费金额 * @param id 钱包 id */ - default int updateWhenIncBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge, - Long totalExpense, Integer price, Long id) { - PayWalletDO updateDO = new PayWalletDO().setBalance(balance + price); - if (bizType == PayWalletBizTypeEnum.PAYMENT_REFUND) { - updateDO.setTotalExpense(totalExpense - price); - } - if (bizType == PayWalletBizTypeEnum.RECHARGE) { - updateDO.setTotalExpense(totalRecharge + price); - } - return update(updateDO, - new LambdaQueryWrapper().eq(PayWalletDO::getId, id) - .eq(PayWalletDO::getBalance, balance)); + default int updateWhenConsumption(Integer price, Long id){ + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" balance = balance - " + price + ", total_expense = total_expense + " + price) + .eq(PayWalletDO::getId, id) + .ge(PayWalletDO::getBalance, price); // cas 逻辑 + return update(null, lambdaUpdateWrapper); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java index 47e8217d3..54681f815 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java @@ -62,13 +62,12 @@ public class WalletPayClient extends AbstractPayClient { @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { try { - // TODO @jason:直接 getLong 和 getInt 会不会更简洁哈 - String userId = MapUtil.getStr(reqDTO.getChannelExtras(), USER_ID_KEY); - String userType = MapUtil.getStr(reqDTO.getChannelExtras(), USER_TYPE_KEY); - Assert.notEmpty(userId, "用户 id 不能为空"); - Assert.notEmpty(userType, "用户类型不能为空"); - PayWalletTransactionDO transaction = wallService.orderPay(Long.valueOf(userId), Integer.valueOf(userType), - reqDTO.getOutTradeNo(), reqDTO.getPrice()); + Long userId = MapUtil.getLong(reqDTO.getChannelExtras(), USER_ID_KEY); + Integer userType = MapUtil.getInt(reqDTO.getChannelExtras(), USER_TYPE_KEY); + Assert.notNull(userId, "用户 id 不能为空"); + Assert.notNull(userType, "用户类型不能为空"); + PayWalletTransactionDO transaction = wallService.orderPay(userId, userType, reqDTO.getOutTradeNo(), + reqDTO.getPrice()); return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), transaction.getCreateTime(), reqDTO.getOutTradeNo(), transaction); 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 d017e5332..2d186b98e 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 @@ -6,10 +6,10 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; -import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -18,7 +18,6 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.time.LocalDateTime; -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.TOO_MANY_REQUESTS; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT; @@ -33,20 +32,8 @@ import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYM @Slf4j public class PayWalletServiceImpl implements PayWalletService { - /** - * 余额支付的 no 前缀 - */ - private static final String WALLET_PAY_NO_PREFIX = "WP"; - /** - * 余额退款的 no 前缀 - */ - private static final String WALLET_REFUND_NO_PREFIX = "WR"; - @Resource private PayWalletMapper walletMapper; - @Resource - private PayNoRedisDAO noRedisDAO; - @Resource private PayWalletTransactionService walletTransactionService; @Resource @@ -61,7 +48,7 @@ public class PayWalletServiceImpl implements PayWalletService { PayWalletDO wallet = walletMapper.selectByUserIdAndType(userId, userType); if (wallet == null) { wallet = new PayWalletDO().setUserId(userId).setUserType(userType) - .setBalance(0).setTotalExpense(0L).setTotalRecharge(0L); + .setBalance(0).setTotalExpense(0).setTotalRecharge(0); wallet.setCreateTime(LocalDateTime.now()); walletMapper.insert(wallet); } @@ -127,68 +114,50 @@ public class PayWalletServiceImpl implements PayWalletService { Long bizId, PayWalletBizTypeEnum bizType, Integer price) { // 1.1 获取钱包 PayWalletDO payWallet = getOrCreateWallet(userId, userType); - // 1.2 判断余额是否足够 - int afterBalance = payWallet.getBalance() - price; - if (afterBalance < 0) { + // 2.1 扣除余额 + int number = 0 ; + switch (bizType) { + case PAYMENT: { + number = walletMapper.updateWhenConsumption(price, payWallet.getId()); + break; + } + case RECHARGE_REFUND: { + // TODO + break; + } + } + if (number == 0) { throw exception(WALLET_BALANCE_NOT_ENOUGH); } - - // TODO jason:建议基于 where price >= 来做哈;然后抛出 WALLET_BALANCE_NOT_ENOUGH - // 2.1 扣除余额 - int number = walletMapper.updateWhenDecBalance(bizType, payWallet.getBalance(), - payWallet.getTotalRecharge(), payWallet.getTotalExpense(), price, payWallet.getId()); - if (number == 0) { - throw exception(TOO_MANY_REQUESTS); - } - + int afterBalance = payWallet.getBalance() - price; // 2.2 生成钱包流水 - // TODO @jason:walletNo 交给 payWalletTransactionService 自己生成哈; - String walletNo = generateWalletNo(bizType); - PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) - .setNo(walletNo).setPrice(-price).setBalance(afterBalance) - .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()).setTitle(bizType.getDescription()); - // TODO @jason:是不是可以 createWalletTransaction 搞个 bo 参数,然后 PayWalletTransactionDO 交回给 walletTransactionService 更好;然后把参数简化下 - walletTransactionService.createWalletTransaction(walletTransaction); - return walletTransaction; + CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) + .setPrice(-price).setBalance(afterBalance).setBizId(String.valueOf(bizId)) + .setBizType(bizType.getType()).setTitle(bizType.getDescription()); + return walletTransactionService.createWalletTransaction(bo); } @Override public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, Long bizId, PayWalletBizTypeEnum bizType, Integer price) { - // 1.1 获取钱包 + // 获取钱包 PayWalletDO payWallet = getOrCreateWallet(userId, userType); - - // 2.1 增加余额 - // TODO @jason:类似上面的思路哈; - int number = walletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(), - payWallet.getTotalExpense(), price, payWallet.getId()); - if (number == 0) { - throw exception(TOO_MANY_REQUESTS); + switch (bizType) { + case PAYMENT_REFUND: { + // 更新退款 + walletMapper.updateWhenConsumptionRefund(price, payWallet.getId()); + break; + } + case RECHARGE: { + //TODO + break; + } } - // 2.2 生成钱包流水 - String walletNo = generateWalletNo(bizType); - PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) - .setNo(walletNo).setPrice(price).setBalance(payWallet.getBalance()+price) - .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()) - .setTitle(bizType.getDescription()); - walletTransactionService.createWalletTransaction(newWalletTransaction); - return newWalletTransaction; - } - - private String generateWalletNo(PayWalletBizTypeEnum bizType) { - // TODO @jason:对于余额来说,是不是直接 W+序号就行了,它其实不关注业务;;;不然就耦合啦 - String no = ""; - switch(bizType){ - case PAYMENT: - no = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); - break; - case PAYMENT_REFUND: - no = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); - break; - default : - } - return no; + CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) + .setPrice(price).setBalance(payWallet.getBalance()+price).setBizId(String.valueOf(bizId)) + .setBizType(bizType.getType()).setTitle(bizType.getDescription()); + return walletTransactionService.createWalletTransaction(bo); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java index 432e2f2e0..db6f778f3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; /** * 钱包余额流水 Service 接口 @@ -25,10 +26,10 @@ public interface PayWalletTransactionService { /** * 新增钱包余额流水 * - * @param payWalletTransaction 余额流水 - * @return id + * @param bo 创建钱包流水 bo + * @return 新建的钱包 do */ - Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction); + PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo); /** * 根据 no,获取钱包余流水 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java index 05a2a4800..ba27392f0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletTransactionConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -19,11 +22,16 @@ import javax.annotation.Resource; @Service @Slf4j public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { - + /** + * 钱包流水的 no 前缀 + */ + private static final String WALLET_NO_PREFIX = "W"; @Resource private PayWalletService payWalletService; @Resource private PayWalletTransactionMapper payWalletTransactionMapper; + @Resource + private PayNoRedisDAO noRedisDAO; @Override public PageResult getWalletTransactionPage(Long userId, Integer userType, @@ -33,9 +41,11 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ } @Override - public Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction) { - payWalletTransactionMapper.insert(payWalletTransaction); - return payWalletTransaction.getId(); + public PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo) { + PayWalletTransactionDO transactionDO = PayWalletTransactionConvert.INSTANCE.convert(bo); + transactionDO.setNo(noRedisDAO.generate(WALLET_NO_PREFIX)); + payWalletTransactionMapper.insert(transactionDO); + return transactionDO; } @Override diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java new file mode 100644 index 000000000..2b7188606 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.pay.service.wallet.bo; + +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; +import lombok.Data; + +/** + * 创建钱包流水 BO + * + * @author jason + */ +@Data +public class CreateWalletTransactionBO { + + /** + * 钱包编号 + * + */ + private Long walletId; + + /** + * 交易金额,单位分 + * + * 正值表示余额增加,负值表示余额减少 + */ + private Integer price; + + /** + * 交易后余额,单位分 + */ + private Integer balance; + + /** + * 关联业务分类 + * + * 枚举 {@link PayWalletBizTypeEnum#getType()} + */ + private Integer bizType; + + /** + * 关联业务编号 + */ + private String bizId; + + /** + * 流水说明 + */ + private String title; +} From 426594ae001a2465a3476ad18202386a0979550f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 9 Sep 2023 19:34:50 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=20app=20=E7=9A=84=20price=20=E5=88=B0=20brokeragePric?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../brokerage/user/vo/BrokerageUserRespVO.java | 3 --- .../app/brokerage/AppBrokerageUserController.java | 15 ++++++++------- .../user/AppBrokerageUserChildSummaryRespVO.java | 2 +- .../vo/user/AppBrokerageUserMySummaryRespVO.java | 2 +- .../user/AppBrokerageUserRankByPriceRespVO.java | 2 +- .../brokerage/vo/user/AppBrokerageUserRespVO.java | 3 +++ .../brokerage/record/BrokerageRecordConvert.java | 2 +- .../brokerage/user/BrokerageUserDO.java | 4 ++-- .../brokerage/user/BrokerageUserServiceImpl.java | 2 +- 9 files changed, 18 insertions(+), 17 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserRespVO.java index c353b4614..ae7caf5ff 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserRespVO.java @@ -19,7 +19,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; - // ========== 用户信息 ========== @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") @@ -27,7 +26,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { @Schema(description = "用户昵称", example = "李四") private String nickname; - // ========== 推广信息 ========== @Schema(description = "推广用户数量(一级)", example = "20019") @@ -37,7 +35,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { @Schema(description = "推广订单金额", example = "20019") private Integer brokerageOrderPrice; - // ========== 提现信息 ========== @Schema(description = "已提现金额", example = "20019") 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 ef1634098..83a1b25e0 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 @@ -37,6 +37,7 @@ public class AppBrokerageUserController { @PreAuthenticated public CommonResult getBrokerageUser() { AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO() + .setBrokerageEnabled(true) .setPrice(2000) .setFrozenPrice(3000); return success(respVO); @@ -49,7 +50,7 @@ public class AppBrokerageUserController { public CommonResult getBrokerageUserSummary() { AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO() .setYesterdayPrice(1) - .setPrice(2) + .setBrokeragePrice(2) .setFrozenPrice(3) .setWithdrawPrice(4) .setFirstBrokerageUserCount(166) @@ -84,16 +85,16 @@ public class AppBrokerageUserController { public CommonResult> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) { AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO() .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") - .setPrice(10); + .setBrokeragePrice(10); AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO() .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") - .setPrice(6); + .setBrokeragePrice(6); AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO() .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") - .setPrice(4); + .setBrokeragePrice(4); AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO() .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") - .setPrice(4); + .setBrokeragePrice(4); return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L)); } @@ -105,11 +106,11 @@ public class AppBrokerageUserController { AppBrokerageUserChildSummaryPageReqVO pageReqVO) { AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO() .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") - .setPrice(10).setPrice(20).setBrokerageOrderCount(30) + .setBrokeragePrice(10).setBrokeragePrice(20).setBrokerageOrderCount(30) .setBrokerageTime(LocalDateTime.now()); AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO() .setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") - .setPrice(20).setPrice(30).setBrokerageOrderCount(40) + .setBrokeragePrice(20).setBrokeragePrice(30).setBrokerageOrderCount(40) .setBrokerageTime(LocalDateTime.now()); return success(new PageResult<>(asList(vo1, vo2), 10L)); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java index 55d88d74f..1beb1b5e2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java @@ -19,7 +19,7 @@ public class AppBrokerageUserChildSummaryRespVO { private String avatar; @Schema(description = "佣金金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - private Integer price; + private Integer brokeragePrice; @Schema(description = "分销订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") private Integer brokerageOrderCount; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java index 33a089cc6..cc9a03ebc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java @@ -14,7 +14,7 @@ public class AppBrokerageUserMySummaryRespVO { private Integer withdrawPrice; @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") - private Integer price; + private Integer brokeragePrice; @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234") private Integer frozenPrice; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java index d80fb67a2..91345ea78 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java @@ -17,6 +17,6 @@ public class AppBrokerageUserRankByPriceRespVO { private String avatar; @Schema(description = "佣金金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - private Integer price; + private Integer brokeragePrice; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java index 9db6e0cc2..40b70bed2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java @@ -7,6 +7,9 @@ import lombok.Data; @Data public class AppBrokerageUserRespVO { + @Schema(description = "是否有分销资格", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") + private Boolean brokerageEnabled; + @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") private Integer price; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java index f313fa39f..b55a76c88 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java @@ -41,7 +41,7 @@ public interface BrokerageRecordConvert { : BrokerageRecordStatusEnum.SETTLEMENT.getStatus(); return new BrokerageRecordDO().setUserId(user.getId()) .setBizType(bizType.getType()).setBizId(bizId) - .setPrice(brokeragePrice).setTotalPrice(user.getPrice()) + .setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice()) .setTitle(title) .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokeragePrice / 100.0))) .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java index 1773e41e7..4348fa195 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java @@ -43,7 +43,7 @@ public class BrokerageUserDO extends BaseDO { private LocalDateTime bindUserTime; /** - * 推广资格 + * 是否有分销资格 */ private Boolean brokerageEnabled; /** @@ -54,7 +54,7 @@ public class BrokerageUserDO extends BaseDO { /** * 可用佣金 */ - private Integer price; + private Integer brokeragePrice; /** * 冻结佣金 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java index 2dd7fb03b..47ad454ef 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java @@ -146,7 +146,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(userId); if (brokerageUser == null) { // 分销用户不存在的情况:1. 新注册;2. 旧数据;3. 分销功能关闭后又打开 isNewBrokerageUser = true; - brokerageUser = new BrokerageUserDO().setId(userId).setBrokerageEnabled(false).setPrice(0).setFrozenPrice(0); + brokerageUser = new BrokerageUserDO().setId(userId).setBrokerageEnabled(false).setBrokeragePrice(0).setFrozenPrice(0); } // 2.1 校验能否绑定 From cd51d57f122ad8d74c5ade811098472b17860ecb Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 9 Sep 2023 19:42:53 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E8=B0=83?= =?UTF-8?q?=E6=95=B4=20app=20=E7=9A=84=20price=20=E5=88=B0=20brokeragePric?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wallet/PayWalletTransactionConvert.java | 3 ++- .../pay/dal/mysql/wallet/PayWalletMapper.java | 6 ++++-- .../pay/service/wallet/PayWalletServiceImpl.java | 16 +++++++++------- .../wallet/PayWalletTransactionService.java | 5 ++++- .../wallet/PayWalletTransactionServiceImpl.java | 11 +++++++---- .../wallet/bo/CreateWalletTransactionBO.java | 2 ++ 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java index 088bdecf3..f806168c8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java @@ -14,5 +14,6 @@ public interface PayWalletTransactionConvert { PageResult convertPage(PageResult page); - PayWalletTransactionDO convert(CreateWalletTransactionBO bo); + PayWalletTransactionDO convert(CreateWalletTransactionBO bean); + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index 9184621bd..ef695c9fe 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java @@ -22,7 +22,8 @@ public interface PayWalletMapper extends BaseMapperX { */ default int updateWhenConsumptionRefund(Integer price, Long id){ LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .setSql(" balance = balance + " + price + ", total_expense = total_expense - " + price) + .setSql(" balance = balance + " + price + + ", total_expense = total_expense - " + price) .eq(PayWalletDO::getId, id); return update(null, lambdaUpdateWrapper); } @@ -35,7 +36,8 @@ public interface PayWalletMapper extends BaseMapperX { */ default int updateWhenConsumption(Integer price, Long id){ LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .setSql(" balance = balance - " + price + ", total_expense = total_expense + " + price) + .setSql(" balance = balance - " + price + + ", total_expense = total_expense + " + price) .eq(PayWalletDO::getId, id) .ge(PayWalletDO::getBalance, price); // cas 逻辑 return update(null, lambdaUpdateWrapper); 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 2d186b98e..f09dfc618 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 @@ -112,13 +112,14 @@ public class PayWalletServiceImpl implements PayWalletService { @Override public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, Long bizId, PayWalletBizTypeEnum bizType, Integer price) { - // 1.1 获取钱包 + // 1. 获取钱包 PayWalletDO payWallet = getOrCreateWallet(userId, userType); + // 2.1 扣除余额 - int number = 0 ; + int updateCounts = 0 ; switch (bizType) { case PAYMENT: { - number = walletMapper.updateWhenConsumption(price, payWallet.getId()); + updateCounts = walletMapper.updateWhenConsumption(price, payWallet.getId()); break; } case RECHARGE_REFUND: { @@ -126,11 +127,11 @@ public class PayWalletServiceImpl implements PayWalletService { break; } } - if (number == 0) { + if (updateCounts == 0) { throw exception(WALLET_BALANCE_NOT_ENOUGH); } - int afterBalance = payWallet.getBalance() - price; // 2.2 生成钱包流水 + Integer afterBalance = payWallet.getBalance() - price; CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) .setPrice(-price).setBalance(afterBalance).setBizId(String.valueOf(bizId)) .setBizType(bizType.getType()).setTitle(bizType.getDescription()); @@ -140,7 +141,7 @@ public class PayWalletServiceImpl implements PayWalletService { @Override public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, Long bizId, PayWalletBizTypeEnum bizType, Integer price) { - // 获取钱包 + // 1. 获取钱包 PayWalletDO payWallet = getOrCreateWallet(userId, userType); switch (bizType) { case PAYMENT_REFUND: { @@ -153,7 +154,8 @@ public class PayWalletServiceImpl implements PayWalletService { break; } } - // 2.2 生成钱包流水 + + // 2. 生成钱包流水 CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) .setPrice(price).setBalance(payWallet.getBalance()+price).setBizId(String.valueOf(bizId)) .setBizType(bizType.getType()).setTitle(bizType.getDescription()); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java index db6f778f3..52c84e159 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; +import javax.validation.Valid; + /** * 钱包余额流水 Service 接口 * @@ -29,7 +31,7 @@ public interface PayWalletTransactionService { * @param bo 创建钱包流水 bo * @return 新建的钱包 do */ - PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo); + PayWalletTransactionDO createWalletTransaction(@Valid CreateWalletTransactionBO bo); /** * 根据 no,获取钱包余流水 @@ -46,4 +48,5 @@ public interface PayWalletTransactionService { * @return 钱包流水 */ PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type); + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java index ba27392f0..6ef32a557 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java @@ -22,10 +22,12 @@ import javax.annotation.Resource; @Service @Slf4j public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { + /** * 钱包流水的 no 前缀 */ private static final String WALLET_NO_PREFIX = "W"; + @Resource private PayWalletService payWalletService; @Resource @@ -42,10 +44,10 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ @Override public PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo) { - PayWalletTransactionDO transactionDO = PayWalletTransactionConvert.INSTANCE.convert(bo); - transactionDO.setNo(noRedisDAO.generate(WALLET_NO_PREFIX)); - payWalletTransactionMapper.insert(transactionDO); - return transactionDO; + PayWalletTransactionDO transaction = PayWalletTransactionConvert.INSTANCE.convert(bo) + .setNo(noRedisDAO.generate(WALLET_NO_PREFIX)); + payWalletTransactionMapper.insert(transaction); + return transaction; } @Override @@ -57,4 +59,5 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ public PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type) { return payWalletTransactionMapper.selectByBiz(bizId, type.getType()); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java index 2b7188606..a1b7af8be 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java @@ -11,6 +11,8 @@ import lombok.Data; @Data public class CreateWalletTransactionBO { + // TODO @jason:bo 的话,最好加个参数校验哈; + /** * 钱包编号 * From a47d744f648cdd60165f757254d176dd5116d919 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 9 Sep 2023 21:05:44 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E5=88=86=E9=94=80=E7=9A=84=20url=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/api/brokerage/BrokerageApiImpl.java | 2 +- .../app/brokerage/AppBrokerageUserController.java | 15 ++++++++------- .../brokerage/user/BrokerageUserService.java | 2 +- .../brokerage/user/BrokerageUserServiceImpl.java | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java index 114ba39ac..4910f07a5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java @@ -27,7 +27,7 @@ public class BrokerageApiImpl implements BrokerageApi { @Override public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { - return brokerageUserService.bindUser(userId, bindUserId, isNewUser); + return brokerageUserService.bindBrokerageUser(userId, bindUserId, isNewUser); } } 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 83a1b25e0..208ecee2e 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 @@ -43,6 +43,13 @@ public class AppBrokerageUserController { return success(respVO); } + @PutMapping("/bind") + @Operation(summary = "绑定推广员") + @PreAuthenticated + public CommonResult bindBrokerageUser(@Valid @RequestBody AppBrokerageUserBindReqVO reqVO) { + return success(brokerageUserService.bindBrokerageUser(getLoginUserId(), reqVO.getBindUserId(), false)); + } + // TODO 芋艿:临时 mock => @GetMapping("/get-summary") @Operation(summary = "获得个人分销统计") @@ -119,15 +126,9 @@ public class AppBrokerageUserController { @GetMapping("/get-rank-by-price") @Operation(summary = "获得分销用户排行(基于佣金)") @Parameter(name = "times", description = "时间段", required = true) - public CommonResult getBrokerageUserRankByPrice( + public CommonResult bindBrokerageUser( @RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) { return success(1); } - @PutMapping("/bind-user") - @Operation(summary = "绑定推广员") - public CommonResult getBrokerageUserRankByPrice(@Valid AppBrokerageUserBindReqVO reqVO) { - return success(brokerageUserService.bindUser(getLoginUserId(), reqVO.getBindUserId(), false)); - } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java index b3d265b29..de9d0a2b7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java @@ -103,6 +103,6 @@ public interface BrokerageUserService { * @param isNewUser 是否为新用户 * @return 是否绑定 */ - boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser); + boolean bindBrokerageUser(Long userId, Long bindUserId, Boolean isNewUser); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java index 47ad454ef..1a168d966 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java @@ -135,7 +135,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { // TODO @疯狂:因为现在 user 会存在使用验证码直接注册,所以 isNewUser 不太好传递;我们是不是可以约定绑定的时间,createTime 在 30 秒内,就认为新用户; @Override - public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { + public boolean bindBrokerageUser(Long userId, Long bindUserId, Boolean isNewUser) { // TODO @疯狂:userId 为空,搞到参数校验里哇; if (userId == null) { throw exception(0); From 4265441e1daec669527b89a02e4e1a4850b4560c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 9 Sep 2023 22:28:01 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E5=88=86=E9=94=80=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=95=86=E5=93=81=E7=9A=84=E5=88=86=E4=BD=A3=E9=87=91?= =?UTF-8?q?=E9=A2=9D=E8=AE=A1=E7=AE=97=20api=20mock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppBrokerageRecordController.java | 12 ++++++++++++ .../AppBrokerageProductPriceRespVO.java | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageProductPriceRespVO.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java index d4c72028f..9569162cb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO; import io.swagger.v3.oas.annotations.Operation; @@ -11,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; @@ -40,4 +42,14 @@ public class AppBrokerageRecordController { return success(new PageResult<>(asList(vo1, vo2), 10L)); } + @GetMapping("/get-product-brokerage-price") + @Operation(summary = "获得商品的分销金额") + public CommonResult getProductBrokeragePrice(@RequestParam("spuId") Long spuId) { + AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO(); + respVO.setEnabled(true); // TODO @疯狂:需要开启分销 + 人允许分销 + respVO.setBrokerageMinPrice(1); + respVO.setBrokerageMaxPrice(2); + return success(respVO); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageProductPriceRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageProductPriceRespVO.java new file mode 100644 index 000000000..6b2191d5f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageProductPriceRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 App - 商品的分销金额 Response VO") +@Data +public class AppBrokerageProductPriceRespVO { + + @Schema(description = "是否开启", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Boolean enabled; + + @Schema(description = "分销最小金额,单位:分", example = "100") + private Integer brokerageMinPrice; + + @Schema(description = "分销最大金额,单位:分", example = "100") + private Integer brokerageMaxPrice; + +} From 40e1a879e3b38d830b25f81716986d485f115d61 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 10 Sep 2023 18:01:53 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E7=99=BB=E5=BD=95=EF=BC=9A=E7=A4=BE?= =?UTF-8?q?=E4=BA=A4=E7=99=BB=E5=BD=95=E6=97=B6=EF=BC=8C=E9=A2=9D=E5=A4=96?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=20openid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/auth/AppAuthController.http | 12 +++++++- .../app/auth/vo/AppAuthLoginRespVO.java | 8 +++++ .../member/convert/auth/AuthConvert.java | 2 +- .../service/auth/MemberAuthServiceImpl.java | 30 +++++++++++-------- .../system/api/social/SocialUserApi.java | 13 ++++---- .../api/social/dto/SocialUserRespDTO.java | 27 +++++++++++++++++ .../system/api/social/SocialUserApiImpl.java | 9 +++--- .../service/auth/AdminAuthServiceImpl.java | 7 +++-- .../service/social/SocialUserService.java | 13 ++++---- .../service/social/SocialUserServiceImpl.java | 8 +++-- .../auth/AdminAuthServiceImplTest.java | 5 ++-- .../social/SocialUserServiceImplTest.java | 17 ++++++----- .../src/main/resources/application-local.yaml | 6 ++-- 13 files changed, 111 insertions(+), 46 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserRespDTO.java diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http index 51252530b..648802b80 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http @@ -28,6 +28,17 @@ tenant-id: {{appTenentId}} "code": 9999 } +### 请求 /social-login 接口 => 成功 +POST {{appApi}}/member/auth/social-login +Content-Type: application/json +tenant-id: {{appTenentId}} + +{ + "type": 34, + "code": "0e1oc9000CTjFQ1oim200bhtb61oc90g", + "state": "default" +} + ### 请求 /weixin-mini-app-login 接口 => 成功 POST {{appApi}}/member/auth/weixin-mini-app-login Content-Type: application/json @@ -38,7 +49,6 @@ tenant-id: {{appTenentId}} "loginCode": "001frTkl21JUf94VGxol2hSlff1frTkR" } - ### 请求 /logout 接口 => 成功 POST {{appApi}}/member/auth/logout Content-Type: application/json diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java index 41318fe59..072ec9e4b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java @@ -27,4 +27,12 @@ public class AppAuthLoginRespVO { @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime expiresTime; + /** + * 仅社交登录、社交绑定时会返回 + * + * 为什么需要返回?微信公众号、微信小程序支付需要传递 openid 给支付接口 + */ + @Schema(description = "社交用户 openid", example = "qq768") + private String openid; + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java index 16a8e6d4c..08c9b59ea 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java @@ -25,7 +25,7 @@ public interface AuthConvert { SmsCodeUseReqDTO convert(AppMemberUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp); SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp); - AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean); + AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean, String openid); SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java index ed89d0a50..e8f816ea6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; @@ -65,13 +66,14 @@ public class MemberAuthServiceImpl implements MemberAuthService { MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword()); // 如果 socialType 非空,说明需要绑定社交用户 + String openid = null; if (reqVO.getSocialType() != null) { - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE); + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE, openid); } @Override @@ -86,32 +88,33 @@ public class MemberAuthServiceImpl implements MemberAuthService { Assert.notNull(user, "获取用户失败,结果为空"); // 如果 socialType 非空,说明需要绑定社交用户 + String openid = null; if (reqVO.getSocialType() != null) { - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS); + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, openid); } @Override public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 - Long userId = socialUserApi.getBindUserId(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), + SocialUserRespDTO socialUser = socialUserApi.getSocialUser(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState()); - if (userId == null) { + if (socialUser == null) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } // 自动登录 - MemberUserDO user = userService.getUser(userId); + MemberUserDO user = userService.getUser(socialUser.getUserId()); if (user == null) { throw exception(USER_NOT_EXISTS); } // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); + return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, socialUser.getOpenid()); } @Override @@ -129,14 +132,15 @@ public class MemberAuthServiceImpl implements MemberAuthService { Assert.notNull(user, "获取用户失败,结果为空"); // 绑定社交用户 - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), + String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), "")); // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); + return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, openid); } - private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType) { + private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, + LoginLogTypeEnum logType, String openid) { // 插入登陆日志 createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); // 创建 Token 令牌 @@ -144,7 +148,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { .setUserId(user.getId()).setUserType(getUserType().getValue()) .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); // 构建返回结果 - return AuthConvert.INSTANCE.convert(accessTokenRespDTO); + return AuthConvert.INSTANCE.convert(accessTokenRespDTO, openid); } @Override @@ -231,7 +235,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { public AppAuthLoginRespVO refreshToken(String refreshToken) { OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); - return AuthConvert.INSTANCE.convert(accessTokenDO); + return AuthConvert.INSTANCE.convert(accessTokenDO, null); } private void createLogoutLog(Long userId) { diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java index 5d42731c2..c7c2fe459 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.api.social; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; @@ -27,8 +28,9 @@ public interface SocialUserApi { * 绑定社交用户 * * @param reqDTO 绑定信息 + * @return 社交用户 openid */ - void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); + String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); /** * 取消绑定社交用户 @@ -38,16 +40,17 @@ public interface SocialUserApi { void unbindSocialUser(@Valid SocialUserUnbindReqDTO reqDTO); /** - * 获得社交用户的绑定用户编号 - * 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号! + * 获得社交用户 + * * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 * * @param userType 用户类型 * @param type 社交平台的类型 * @param code 授权码 * @param state state - * @return 绑定用户编号 + * @return 社交用户 */ - Long getBindUserId(Integer userType, Integer type, String code, String state); + SocialUserRespDTO getSocialUser(Integer userType, Integer type, + String code, String state); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserRespDTO.java new file mode 100644 index 000000000..ac25b148e --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserRespDTO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.system.api.social.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 社交用户 Response DTO + * + * @author 芋道源码 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SocialUserRespDTO { + + /** + * 社交用户 openid + */ + private String openid; + + /** + * 关联的用户编号 + */ + private Long userId; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java index ae8903135..d322952af 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.api.social; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; import cn.iocoder.yudao.module.system.service.social.SocialUserService; import org.springframework.stereotype.Service; @@ -26,8 +27,8 @@ public class SocialUserApiImpl implements SocialUserApi { } @Override - public void bindSocialUser(SocialUserBindReqDTO reqDTO) { - socialUserService.bindSocialUser(reqDTO); + public String bindSocialUser(SocialUserBindReqDTO reqDTO) { + return socialUserService.bindSocialUser(reqDTO); } @Override @@ -37,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi { } @Override - public Long getBindUserId(Integer userType, Integer type, String code, String state) { - return socialUserService.getBindUserId(userType, type, code, state); + public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { + return socialUserService.getSocialUser(userType, type, code, state); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java index ca34156eb..37fac0997 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; @@ -155,14 +156,14 @@ public class AdminAuthServiceImpl implements AdminAuthService { @Override public AuthLoginRespVO socialLogin(AuthSocialLoginReqVO reqVO) { // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 - Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(), + SocialUserRespDTO socialUser = socialUserService.getSocialUser(UserTypeEnum.ADMIN.getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState()); - if (userId == null) { + if (socialUser == null) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } // 获得用户 - AdminUserDO user = userService.getUser(userId); + AdminUserDO user = userService.getUser(socialUser.getUserId()); if (user == null) { throw exception(USER_NOT_EXISTS); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java index 6d89897bb..bc776ec60 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; @@ -50,8 +51,9 @@ public interface SocialUserService { * 绑定社交用户 * * @param reqDTO 绑定信息 + * @return 社交用户 openid */ - void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); + String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); /** * 取消绑定社交用户 @@ -64,15 +66,16 @@ public interface SocialUserService { void unbindSocialUser(Long userId, Integer userType, Integer type, String openid); /** - * 获得社交用户的绑定用户编号 - * 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号! + * 获得社交用户 + * * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 * * @param userType 用户类型 * @param type 社交平台的类型 * @param code 授权码 * @param state state - * @return 绑定用户编号 + * @return 社交用户 */ - Long getBindUserId(Integer userType, Integer type, String code, String state); + SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java index b6999bd01..bd5548af7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.util.http.HttpUtils; import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; @@ -98,7 +99,7 @@ public class SocialUserServiceImpl implements SocialUserService { @Override @Transactional - public void bindSocialUser(SocialUserBindReqDTO reqDTO) { + public String bindSocialUser(SocialUserBindReqDTO reqDTO) { // 获得社交用户 SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); Assert.notNull(socialUser, "社交用户不能为空"); @@ -115,6 +116,7 @@ public class SocialUserServiceImpl implements SocialUserService { .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); socialUserBindMapper.insert(socialUserBind); + return socialUser.getOpenid(); } @Override @@ -130,7 +132,7 @@ public class SocialUserServiceImpl implements SocialUserService { } @Override - public Long getBindUserId(Integer userType, Integer type, String code, String state) { + public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { // 获得社交用户 SocialUserDO socialUser = authSocialUser(type, code, state); Assert.notNull(socialUser, "社交用户不能为空"); @@ -141,7 +143,7 @@ public class SocialUserServiceImpl implements SocialUserService { if (socialUserBind == null) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } - return socialUserBind.getUserId(); + return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId()); } /** diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java index b0331cff2..1009e9220 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; @@ -235,8 +236,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class); // mock 方法(绑定的用户编号) Long userId = 1L; - when(socialUserService.getBindUserId(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), - eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(userId); + when(socialUserService.getSocialUser(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), + eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), userId)); // mock(用户) AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); when(userService.getUser(eq(userId))).thenReturn(user); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java index fcea1a864..bfbbd40aa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; @@ -195,10 +196,11 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); // 调用 - socialUserService.bindSocialUser(reqDTO); + String openid = socialUserService.bindSocialUser(reqDTO); // 断言 List socialUserBinds = socialUserBindMapper.selectList(); assertEquals(1, socialUserBinds.size()); + assertEquals(socialUser.getOpenid(), openid); } @Test @@ -232,25 +234,26 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { } @Test - public void testGetBindUserId() { + public void testGetSocialUser() { // 准备参数 Integer userType = UserTypeEnum.ADMIN.getValue(); Integer type = SocialTypeEnum.GITEE.getType(); String code = "tudou"; String state = "yuanma"; // mock 社交用户 - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); - socialUserMapper.insert(socialUser); + SocialUserDO socialUserDO = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); + socialUserMapper.insert(socialUserDO); // mock 社交用户的绑定 Long userId = randomLong(); SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) - .setSocialType(type).setSocialUserId(socialUser.getId()); + .setSocialType(type).setSocialUserId(socialUserDO.getId()); socialUserBindMapper.insert(socialUserBind); // 调用 - Long result = socialUserService.getBindUserId(userType, type, code, state); + SocialUserRespDTO socialUser = socialUserService.getSocialUser(userType, type, code, state); // 断言 - assertEquals(userId, result); + assertEquals(userId, socialUser.getUserId()); + assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid()); } } diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 5964261ce..4adfb0a9f 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -173,8 +173,10 @@ wx: key-prefix: wx # Redis Key 的前缀 http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 - appid: wx62056c0d5e8db250 - secret: 333ae72f41552af1e998fe1f54e1584a +# appid: wx62056c0d5e8db250 +# secret: 333ae72f41552af1e998fe1f54e1584a + appid: wx63c280fe3248a3e7 # wenhualian的接口测试号 + secret: 6f270509224a7ae1296bbf1c8cb97aed config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 key-prefix: wa # Redis Key 的前缀