Commit 87c55784c4bd119c28a24c758c8d66b3dbb5fdca

Authored by YunaiV
1 parent 5235aff8

code review:营销活动+订单

Showing 18 changed files with 91 additions and 62 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
... ... @@ -68,14 +68,6 @@ public class CommonResult<T> implements Serializable {
68 68 return result;
69 69 }
70 70  
71   - public static <T> CommonResult<T> success(T data, String msg) {
72   - CommonResult<T> result = new CommonResult<>();
73   - result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
74   - result.data = data;
75   - result.msg = msg;
76   - return result;
77   - }
78   -
79 71 public static boolean isSuccess(Integer code) {
80 72 return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
81 73 }
... ...
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 {
52 52 void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount);
53 53  
54 54 /**
55   - * 更新拼团状态为 成功
  55 + * 更新拼团状态为成功
56 56 *
57 57 * @param userId 用户编号
58 58 * @param orderId 订单编号
... ... @@ -60,7 +60,7 @@ public interface CombinationRecordApi {
60 60 void updateRecordStatusToSuccess(Long userId, Long orderId);
61 61  
62 62 /**
63   - * 更新拼团状态为 失败
  63 + * 更新拼团状态为失败
64 64 *
65 65 * @param userId 用户编号
66 66 * @param orderId 订单编号
... ...
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
9 9 */
10 10 public interface SeckillActivityApi {
11 11  
12   -
13 12 /**
14 13 * 更新秒杀库存
15 14 *
... ...
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;
12 12 @Data
13 13 public class SeckillActivityUpdateStockReqDTO {
14 14  
  15 + // TODO @puhui999:参数校验
  16 +
  17 + // TODO @puhui999:秒杀的话,一次只能购买一种商品哈;不能多个哈;
  18 +
15 19 /**
16 20 * 活动编号
17 21 */
... ...
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 {
23 23  
24 24 @Override
25 25 public void updateBargainActivityStock(Long activityId, Integer count) {
  26 + // TODO @puhui999:可以整个实现到 bargainActivityService 中
26 27 // 查询砍价活动
27 28 BargainActivityDO activity = bargainActivityService.getBargainActivity(activityId);
28 29 if (activity == null) {
... ... @@ -30,6 +31,7 @@ public class BargainActivityApiImpl implements BargainActivityApi {
30 31 }
31 32  
32 33 // 更新砍价库存
  34 + // TODO @puhui999:考虑下并发更新问题
33 35 BargainActivityUpdateReqVO reqVO = new BargainActivityUpdateReqVO();
34 36 reqVO.setId(activityId);
35 37 reqVO.setStock(activity.getStock() - count);
... ...
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 {
27 27 @Resource
28 28 private SeckillActivityService activityService;
29 29  
  30 + // TODO @puhui:建议这块弄到 activityService 实现哈;
  31 + // TODO @puhui:这个方法,要考虑事务性
30 32 @Override
31 33 public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {
  34 + // TODO @puhui999:长方法,最好有 1.1 1.2 2.1 这种步骤哈;
32 35 SeckillActivityDO seckillActivity = activityService.getSeckillActivity(updateStockReqDTO.getActivityId());
33 36 if (seckillActivity.getStock() < updateStockReqDTO.getCount()) {
34 37 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
35 38 }
36 39 // 获取活动商品
  40 + // TODO @puhui999:在一个方法里,dos 和 dolist 最好保持一致,要么用 s,要么用 list 哈;
37 41 List<SeckillProductDO> productDOs = activityService.getSeckillProductListByActivityId(updateStockReqDTO.getActivityId());
  42 + // TODO @puhui999:这个是不是搞成 CollectionUtils.convertMultiMap()
38 43 List<SeckillActivityUpdateStockReqDTO.Item> items = updateStockReqDTO.getItems();
39 44 Map<Long, List<Long>> map = new HashMap<>();
40 45 items.forEach(item -> {
... ... @@ -49,9 +54,11 @@ public class SeckillActivityApiImpl implements SeckillActivityApi {
49 54 }
50 55 });
51 56 // 过滤出购买的商品
  57 + // TODO @puhui999:productDOList 可以简化成 productList;一般来说,do 之类不用带着哈,在变量里;
52 58 List<SeckillProductDO> productDOList = CollectionUtils.filterList(productDOs, item -> map.get(item.getSpuId()).contains(item.getSkuId()));
53 59 Map<Long, SeckillActivityUpdateStockReqDTO.Item> productDOMap = CollectionUtils.convertMap(items, SeckillActivityUpdateStockReqDTO.Item::getSkuId, p -> p);
54 60 // 检查活动商品库存是否充足
  61 + // TODO @puhui999:避免 b 这种无业务含义的变量;
55 62 boolean b = CollectionUtils.anyMatch(productDOList, item -> {
56 63 SeckillActivityUpdateStockReqDTO.Item item1 = productDOMap.get(item.getSkuId());
57 64 return (item.getStock() < item1.getCount()) || (item.getStock() - item1.getCount()) < 0;
... ... @@ -59,17 +66,19 @@ public class SeckillActivityApiImpl implements SeckillActivityApi {
59 66 if (b) {
60 67 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
61 68 }
  69 + // TODO @puhui999:类似 doList,应该和下面的 update 逻辑粘的更紧密一点;so 在空行的时候,应该挪到 74 之后里去;甚至更合理,应该是 79 之后;说白了,逻辑要分块,每个模块涉及的代码要紧密在一起;
62 70 List<SeckillProductDO> doList = CollectionUtils.convertList(productDOList, item -> {
63 71 item.setStock(item.getStock() - productDOMap.get(item.getSkuId()).getCount());
64 72 return item;
65 73 });
66 74  
67 75 // 更新活动库存
  76 + // TODO @puhui999:考虑下并发更新
68 77 seckillActivity.setStock(seckillActivity.getStock() + updateStockReqDTO.getCount());
69 78 seckillActivity.setTotalStock(seckillActivity.getTotalStock() - updateStockReqDTO.getCount());
70 79 activityService.updateSeckillActivity(seckillActivity);
71 80 // 更新活动商品库存
72   - activityService.updateSeckillActivityProductByList(doList);
  81 + activityService.updateSeckillActivityProductList(doList);
73 82 }
74 83  
75 84 }
... ...
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.*;
9 9  
10 10 import java.time.LocalDateTime;
11 11  
  12 +// TODO 芋艿:把字段的顺序,和 do 顺序对齐下
12 13 /**
13 14 * 拼团记录 DO
14 15 *
... ... @@ -27,34 +28,28 @@ import java.time.LocalDateTime;
27 28 @AllArgsConstructor
28 29 public class CombinationRecordDO extends BaseDO {
29 30  
  31 + /**
  32 + * 编号,主键自增
  33 + */
30 34 @TableId
31 35 private Long id;
  36 +
32 37 /**
33 38 * 拼团活动编号
  39 + *
  40 + * 关联 {@link CombinationActivityDO#getId()}
34 41 */
35 42 private Long activityId;
36 43 /**
37   - * SPU 编号
38   - */
39   - private Long spuId;
40   - /**
41   - * SKU 编号
42   - */
43   - private Long skuId;
44   - /**
45   - * 用户编号
46   - */
47   - private Long userId;
48   - /**
49   - * 订单编号
  44 + * 拼团商品单价
  45 + *
  46 + * 冗余 {@link CombinationProductDO#getCombinationPrice()}
50 47 */
51   - private Long orderId;
  48 + private Integer combinationPrice;
52 49 /**
53   - * 团长编号
54   - *
55   - * 关联 {@link CombinationRecordDO#getId()}
  50 + * SPU 编号
56 51 */
57   - private Long headId;
  52 + private Long spuId;
58 53 /**
59 54 * 商品名字
60 55 */
... ... @@ -64,9 +59,14 @@ public class CombinationRecordDO extends BaseDO {
64 59 */
65 60 private String picUrl;
66 61 /**
67   - * 拼团商品单价
  62 + * SKU 编号
68 63 */
69   - private Integer combinationPrice;
  64 + private Long skuId;
  65 +
  66 + /**
  67 + * 用户编号
  68 + */
  69 + private Long userId;
70 70 /**
71 71 * 用户昵称
72 72 */
... ... @@ -75,6 +75,13 @@ public class CombinationRecordDO extends BaseDO {
75 75 * 用户头像
76 76 */
77 77 private String avatar;
  78 +
  79 + /**
  80 + * 团长编号
  81 + *
  82 + * 关联 {@link CombinationRecordDO#getId()}
  83 + */
  84 + private Long headId;
78 85 /**
79 86 * 开团状态
80 87 *
... ... @@ -82,13 +89,28 @@ public class CombinationRecordDO extends BaseDO {
82 89 */
83 90 private Integer status;
84 91 /**
  92 + * 订单编号
  93 + */
  94 + private Long orderId;
  95 + /**
  96 + * 开团需要人数
  97 + *
  98 + * 关联 {@link CombinationActivityDO#getUserSize()}
  99 + */
  100 + private Integer userSize;
  101 + /**
  102 + * 已加入拼团人数
  103 + */
  104 + private Integer userCount;
  105 + /**
85 106 * 是否虚拟成团
86 107 */
87 108 private Boolean virtualGroup;
  109 +
88 110 /**
89 111 * 过期时间
90 112 *
91   - * {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算
  113 + * 基于 {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算
92 114 */
93 115 private LocalDateTime expireTime;
94 116 /**
... ... @@ -99,15 +121,5 @@ public class CombinationRecordDO extends BaseDO {
99 121 * 结束时间(成团时间/失败时间)
100 122 */
101 123 private LocalDateTime endTime;
102   - /**
103   - * 开团需要人数
104   - *
105   - * 关联 {@link CombinationActivityDO#getUserSize()}
106   - */
107   - private Integer userSize;
108   - /**
109   - * 已加入拼团人数
110   - */
111   - private Integer userCount;
112 124  
113 125 }
... ...
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 {
43 43 /**
44 44 * 更新秒杀活动商品
45 45 *
46   - * @param productDOList 活动商品列表
  46 + * @param productList 活动商品列表
47 47 */
48   - void updateSeckillActivityProductByList(List<SeckillProductDO> productDOList);
  48 + void updateSeckillActivityProductList(List<SeckillProductDO> productList);
49 49  
50 50 /**
51 51 * 关闭秒杀活动
... ...
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 {
93 93 activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
94 94 }
95 95 // 2.2 过滤出所有 configIds 有交集的活动,判断是否存在重叠
96   - List<SeckillActivityDO> activityDOs = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds));
97   - if (isNotEmpty(activityDOs)) {
  96 + List<SeckillActivityDO> conflictActivityList = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds));
  97 + if (isNotEmpty(conflictActivityList)) {
98 98 throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
99 99 }
100 100 }
... ... @@ -150,8 +150,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
150 150 }
151 151  
152 152 @Override
153   - public void updateSeckillActivityProductByList(List<SeckillProductDO> productDOList) {
154   - seckillProductMapper.updateBatch(productDOList);
  153 + public void updateSeckillActivityProductList(List<SeckillProductDO> productList) {
  154 + seckillProductMapper.updateBatch(productList);
155 155 }
156 156  
157 157 /**
... ...
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;
36 36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
37 37 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
38 38 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
39   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.AFTER_SALE_NOT_FOUND;
40 39  
41 40 @Tag(name = "管理后台 - 售后订单")
42 41 @RestController
... ... @@ -77,9 +76,11 @@ public class TradeAfterSaleController {
77 76 public CommonResult<TradeAfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
78 77 // 查询订单
79 78 TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id);
80   - if (afterSale == null) {
81   - return success(null, AFTER_SALE_NOT_FOUND.getMsg());
82   - }
  79 + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理;
  80 +// if (afterSale == null) {
  81 +// return success(null, AFTER_SALE_NOT_FOUND.getMsg());
  82 +// }
  83 +
83 84 // 查询订单
84 85 TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId());
85 86 // 查询订单项
... ...
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;
25 25  
26 26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
27 27 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
28   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
29 28  
30 29 @Tag(name = "管理后台 - 交易订单")
31 30 @RestController
... ... @@ -68,9 +67,11 @@ public class TradeOrderController {
68 67 public CommonResult<TradeOrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
69 68 // 查询订单
70 69 TradeOrderDO order = tradeOrderQueryService.getOrder(id);
71   - if (order == null) {
72   - return success(null, ORDER_NOT_FOUND.getMsg());
73   - }
  70 + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理;
  71 +// if (order == null) {
  72 +// return success(null, ORDER_NOT_FOUND.getMsg());
  73 +// }
  74 +
74 75 // 查询订单项
75 76 List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id);
76 77 // orderLog
... ...
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;
33 33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
34 34 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
35 35 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
36   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
37 36  
38 37 @Tag(name = "用户 App - 交易订单")
39 38 @RestController
... ... @@ -82,9 +81,10 @@ public class AppTradeOrderController {
82 81 public CommonResult<AppTradeOrderDetailRespVO> getOrder(@RequestParam("id") Long id) {
83 82 // 查询订单
84 83 TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id);
85   - if (order == null) {
86   - return success(null, ORDER_NOT_FOUND.getMsg());
87   - }
  84 + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理;
  85 +// if (order == null) {
  86 +// return success(null, ORDER_NOT_FOUND.getMsg());
  87 +// }
88 88  
89 89 // 查询订单项
90 90 List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId());
... ...
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 {
50 50 private Long seckillActivityId;
51 51  
52 52 // ========== 拼团活动相关字段 ==========
  53 + // TODO @puhui999:是不是拼团记录的编号哈?
53 54 @Schema(description = "拼团活动编号", example = "1024")
54 55 private Long combinationActivityId;
55 56  
... ... @@ -57,6 +58,7 @@ public class AppTradeOrderSettlementReqVO {
57 58 private Long combinationHeadId;
58 59  
59 60 // ========== 砍价活动相关字段 ==========
  61 + // TODO @puhui999:是不是砍价记录的编号哈?
60 62 @Schema(description = "砍价活动编号", example = "123")
61 63 private Long bargainActivityId;
62 64  
... ...
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;
15 15 */
16 16 @Repository
17 17 public class TradeOrderNoRedisDAO {
  18 +
18 19 public static final String TRADE_ORDER_NO_PREFIX = "O";
19 20  
20 21 @Resource
... ...
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 {
561 561 }
562 562  
563 563 @Override
  564 + // TODO @puhui999:考虑事务性
564 565 public void updateOrderPrice(TradeOrderUpdatePriceReqVO reqVO) {
565 566 // 校验交易订单
566 567 TradeOrderDO order = validateOrderExists(reqVO.getId());
... ... @@ -571,6 +572,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
571 572 throw exception(ORDER_UPDATE_PRICE_FAIL_EQUAL);
572 573 }
573 574  
  575 + // TODO @puhui999:应该是按照 payPrice 分配;并且要考虑取余问题;payPrice 也要考虑,item 里的
574 576 List<TradeOrderItemDO> itemDOs = tradeOrderItemMapper.selectListByOrderId(order.getId());
575 577 // TradeOrderItemDO 需要做 adjustPrice 的分摊
576 578 int price = reqVO.getAdjustPrice() / itemDOs.size();
... ... @@ -578,8 +580,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
578 580 item.setAdjustPrice(price);
579 581 });
580 582 // 更新 TradeOrderItem
  583 + // TODO @puhui999:不要整个对象去更新哈;应该 new 一下;
581 584 tradeOrderItemMapper.updateBatch(itemDOs);
582 585 // 更新订单
  586 + // TODO @puhui999:要考虑多次修改价格,不能单单的 payPrice + 价格;
583 587 TradeOrderDO update = TradeOrderConvert.INSTANCE.convert(reqVO);
584 588 update.setPayPrice(update.getPayPrice() + update.getAdjustPrice());
585 589 // TODO @芋艿:改价时,赠送的积分,要不要做改动???
... ...
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 {
29 29 */
30 30 PayOrderRespDTO getOrder(Long id);
31 31  
  32 + // TODO @puhui999:可以去掉 byId;然后 payOrderId 参数改成 id;
32 33 /**
33 34 * 更新支付订单价格
34 35 *
... ... @@ -36,4 +37,5 @@ public interface PayOrderApi {
36 37 * @param payPrice 支付单价格
37 38 */
38 39 void updatePayOrderPriceById(Long payOrderId, Integer payPrice);
  40 +
39 41 }
... ...
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 {
36 36 payOrderService.updatePayOrderPriceById(payOrderId, payPrice);
37 37 }
38 38  
39   -
40 39 }
... ...
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 {
413 413  
414 414 @Override
415 415 public void updatePayOrderPriceById(Long payOrderId, Integer payPrice) {
  416 + // TODO @puhui999:不能直接这样修改哈;应该只有未支付状态的订单才可以改;另外,如果价格如果没变,可以直接 return 哈;
416 417 PayOrderDO order = orderMapper.selectById(payOrderId);
417 418 if (order == null) {
418 419 throw exception(ORDER_NOT_FOUND);
... ...