Commit 67436ea4c6599425f00eee75b497307f6f71d555

Authored by zhijiantianya@gmail.com
1 parent 952e6aa4

mall: 下单的代码 review

Showing 21 changed files with 48 additions and 56 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
... ... @@ -31,10 +31,11 @@ public interface ProductSkuApi {
31 31 List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
32 32  
33 33 /**
34   - * 批量扣减sku库存
  34 + * 批量扣减 SKU 库存
35 35 *
36 36 * @param batchReqDTO sku库存信息列表
37 37 */
  38 + // TODO @LeeYan9: decrementSkuStockBatch? 啊哈, 动名词;
38 39 void decrementStockBatch(SkuDecrementStockBatchReqDTO batchReqDTO);
39 40  
40 41 }
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/SkuDecrementStockBatchReqDTO.java
... ... @@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
7 7 import java.util.List;
8 8  
9 9 /**
  10 + * TODO @LeeYan9: 1) 类注释; 2) Product 开头哈;
10 11 * @author LeeYan9
11 12 * @since 2022-08-26
12 13 */
... ... @@ -15,7 +16,7 @@ import java.util.List;
15 16 @AllArgsConstructor
16 17 public class SkuDecrementStockBatchReqDTO {
17 18  
18   -
  19 + // TODO @LeeYan9: 参数校验
19 20 private List<Item> items;
20 21  
21 22 @Data
... ... @@ -24,6 +25,7 @@ public class SkuDecrementStockBatchReqDTO {
24 25 /**
25 26 * 商品 SPU 编号,自增
26 27 */
  28 + // TODO @LeeYan9: 是不是不用传递哈
27 29 private Long productId;
28 30  
29 31 /**
... ... @@ -38,6 +40,7 @@ public class SkuDecrementStockBatchReqDTO {
38 40  
39 41 }
40 42  
  43 + // TODO @LeeYan9: 构造方法, 是不是可以满足啦
41 44 public static SkuDecrementStockBatchReqDTO of(List<Item> items) {
42 45 return new SkuDecrementStockBatchReqDTO(items);
43 46 }
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/SpuInfoRespDTO.java
... ... @@ -7,6 +7,7 @@ import lombok.Data;
7 7  
8 8 import java.util.List;
9 9  
  10 +// TODO @LeeYan9: ProductSpuRespDTO
10 11 /**
11 12 * @author LeeYan9
12 13 * @since 2022-08-26
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java
... ... @@ -16,6 +16,7 @@ import java.util.Collections;
16 16 import java.util.List;
17 17  
18 18 /**
  19 + * TODO LeeYan9: 类注释;
19 20 * @author LeeYan9
20 21 * @since 2022-09-06
21 22 */
... ... @@ -28,6 +29,7 @@ public class ProductSkuApiImpl implements ProductSkuApi {
28 29  
29 30 @Override
30 31 public List<SkuInfoRespDTO> getSkusByIds(Collection<Long> skuIds) {
  32 + // TODO TODO LeeYan9: AllEmpty?
31 33 if (CollectionUtils.isAnyEmpty(skuIds)) {
32 34 return Collections.emptyList();
33 35 }
... ... @@ -38,6 +40,7 @@ public class ProductSkuApiImpl implements ProductSkuApi {
38 40 @Override
39 41 @Transactional(rollbackFor = Exception.class)
40 42 public void decrementStockBatch(SkuDecrementStockBatchReqDTO batchReqDTO) {
  43 + // TODO @LeeYan9: 最好 Service 去 for 循环;
41 44 productSkuMapper.decrementStockBatch(batchReqDTO.getItems());
42 45 }
43 46 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
... ... @@ -14,6 +14,8 @@ import java.util.Collections;
14 14 import java.util.List;
15 15  
16 16 /**
  17 + * TODO LeeYan9: 类注释;
  18 + *
17 19 * @author LeeYan9
18 20 * @since 2022-09-06
19 21 */
... ... @@ -26,6 +28,7 @@ public class ProductSpuApiImpl implements ProductSpuApi {
26 28  
27 29 @Override
28 30 public List<SpuInfoRespDTO> getSpuList(Collection<Long> spuIds) {
  31 + // TODO TODO LeeYan9: AllEmpty?
29 32 if (CollectionUtils.isAnyEmpty(spuIds)) {
30 33 return Collections.emptyList();
31 34 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
... ... @@ -38,5 +38,4 @@ public interface ProductSkuConvert {
38 38  
39 39 List<SkuInfoRespDTO> convertList03(List<ProductSkuDO> list);
40 40  
41   -
42 41 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
... ... @@ -36,6 +36,5 @@ public interface ProductSpuConvert {
36 36 AppSpuPageRespVO convertAppResp(ProductSpuDO list);
37 37  
38 38 List<SpuInfoRespDTO> convertList2(List<ProductSpuDO> list);
39   -
40   -
  39 +
41 40 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
... ... @@ -23,16 +23,13 @@ import javax.servlet.http.HttpServletRequest;
23 23 @Api(tags = "用户 App - 交易订单")
24 24 @RestController
25 25 @RequestMapping("/trade/order")
26   -@RequiredArgsConstructor
  26 +@RequiredArgsConstructor // TODO @LeeYan9: 先统一使用 @Resource 注入哈; 项目只有三层, 依赖注入会存在, 所以使用 @Resource; 也因此, 最好全局保持一致
27 27 @Validated
28 28 @Slf4j
29 29 public class AppTradeOrderController {
30 30  
31   - // TODO 在思考下;
32   -
33 31 private final TradeOrderService tradeOrderService;
34 32  
35   -
36 33 @GetMapping("/get-create-info")
37 34 @ApiOperation("基于商品,确认创建订单")
38 35 @PreAuthenticated
... ... @@ -46,15 +43,12 @@ public class AppTradeOrderController {
46 43 @PreAuthenticated
47 44 public CommonResult<Long> createTradeOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO,
48 45 HttpServletRequest servletRequest) {
49   -// return success(tradeOrderService.createTradeOrder(UserSecurityContextHolder.getUserId(),
50   -// HttpUtil.getIp(servletRequest), createReqVO));
51 46 // 获取登录用户
52 47 Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
53 48 // 获取用户ip地址
54 49 String clientIp = ServletUtil.getClientIP(servletRequest);
55 50 // 创建交易订单,预支付记录
56 51 Long result = tradeOrderService.createTradeOrder(loginUserId, clientIp, createReqVO);
57   -
58 52 return CommonResult.success(result);
59 53 }
60 54  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
... ... @@ -8,16 +8,11 @@ import org.mapstruct.Mapping;
8 8 import org.mapstruct.Mappings;
9 9 import org.mapstruct.factory.Mappers;
10 10  
11   -/**
12   - * @author LeeYan9
13   - * @since 2022-08-26
14   - */
15 11 @Mapper
16 12 public interface TradeOrderConvert {
17 13  
18 14 TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class);
19 15  
20   -
21 16 @Mappings({
22 17 @Mapping(source = "order.couponId", target = "couponId"),
23 18 @Mapping(target = "remark", ignore = true),
... ... @@ -25,4 +20,5 @@ public interface TradeOrderConvert {
25 20 @Mapping(source = "createVO.addressId", target = "receiverAreaId")
26 21 })
27 22 TradeOrderDO convert(AppTradeOrderCreateReqVO createVO, PriceCalculateRespDTO.Order order);
  23 +
28 24 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java
... ... @@ -7,18 +7,11 @@ import org.mapstruct.factory.Mappers;
7 7  
8 8 import java.util.List;
9 9  
10   -/**
11   - * @author LeeYan9
12   - * @since 2022-08-26
13   - */
14 10 @Mapper
15 11 public interface TradeOrderItemConvert {
16 12  
17 13 TradeOrderItemConvert INSTANCE = Mappers.getMapper(TradeOrderItemConvert.class);
18 14  
19   - /**
20   - * @param items sku列表价格
21   - * @return 订单项
22   - */
23 15 List<TradeOrderItemDO> convertList(List<PriceCalculateRespDTO.OrderItem> items);
  16 +
24 17 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/pay/PayOrderConvert.java
... ... @@ -11,10 +11,6 @@ import org.mapstruct.factory.Mappers;
11 11  
12 12 import java.util.Date;
13 13  
14   -/**
15   - * @author LeeYan9
16   - * @since 2022-08-26
17   - */
18 14 @Mapper
19 15 public interface PayOrderConvert {
20 16  
... ... @@ -30,4 +26,5 @@ public interface PayOrderConvert {
30 26 default Date convertCreateTimeToPayExpireTime(Date cancelTime) {
31 27 return DateUtil.offsetMinute(new Date(), 30);
32 28 }
  29 +
33 30 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/price/PriceConvert.java
... ... @@ -7,10 +7,6 @@ import org.mapstruct.Mapping;
7 7 import org.mapstruct.Mappings;
8 8 import org.mapstruct.factory.Mappers;
9 9  
10   -/**
11   - * @author LeeYan9
12   - * @since 2022-08-26
13   - */
14 10 @Mapper
15 11 public interface PriceConvert {
16 12  
... ... @@ -19,5 +15,6 @@ public interface PriceConvert {
19 15 @Mappings(
20 16 @Mapping(source = "userId" , target = "userId")
21 17 )
22   - PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO , Long userId);
  18 + PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO, Long userId);
  19 +
23 20 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/sku/ProductSkuConvert.java
... ... @@ -17,5 +17,6 @@ public interface ProductSkuConvert {
17 17  
18 18 ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class);
19 19  
20   - List<SkuDecrementStockBatchReqDTO.Item> convert(List<TradeOrderItemDO> tradeOrderItems);
  20 + List<SkuDecrementStockBatchReqDTO.Item> convert(List<TradeOrderItemDO> list);
  21 +
21 22 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java
... ... @@ -4,10 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 4 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
5 5 import org.apache.ibatis.annotations.Mapper;
6 6  
7   -/**
8   - * @author LeeYan9
9   - * @since 2022-08-26
10   - */
11 7 @Mapper
12 8 public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
13 9 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/orderitem/TradeOrderItemMapper.java
... ... @@ -4,10 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 4 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
5 5 import org.apache.ibatis.annotations.Mapper;
6 6  
7   -/**
8   - * @author LeeYan9
9   - * @since 2022-08-26
10   - */
11 7 @Mapper
12 8 public interface TradeOrderItemMapper extends BaseMapperX<TradeOrderItemDO> {
13 9 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.framework.order.config;
3 3 import org.springframework.boot.context.properties.EnableConfigurationProperties;
4 4 import org.springframework.context.annotation.Configuration;
5 5  
  6 +// TODO @LeeYan9: 可以直接给 TradeOrderProperties 一个 @Component生效哈
6 7 /**
7 8 * @author LeeYan9
8 9 * @since 2022-09-15
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
... ... @@ -3,15 +3,16 @@ package cn.iocoder.yudao.module.trade.service.order;
3 3 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
4 4  
5 5 /**
  6 + * TODO @LeeYan9: 类注释
6 7 * @author LeeYan9
7 8 * @since 2022-08-26
8 9 */
9 10 public interface TradeOrderService {
10 11  
11 12 /**
12   - * 创建交易订单
  13 + * 创建交易订单 TODO @LeeYan9: 方法注释, 和参数要空一行
13 14 * @param loginUserId 登录用户
14   - * @param clientIp 用户ip地址
  15 + * @param clientIp 用户ip地址 // TODO @LeeYan9: 中英文之间, 空一行哈
15 16 * @param createReqVO 创建交易订单请求模型
16 17 * @return 交易订单创建结果
17 18 */
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.order;
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.text.StrBuilder;
5 5 import cn.hutool.core.util.IdUtil;
  6 +import cn.hutool.core.util.StrUtil;
6 7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 8 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
8 9 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
... ... @@ -45,42 +46,41 @@ import java.util.Map;
45 46 import java.util.Objects;
46 47  
47 48 /**
  49 + * TODO @LeeYan9: 注释
48 50 * @author LeeYan9
49 51 * @since 2022-08-26
50 52 */
51 53 @Service
52 54 public class TradeOrderServiceImpl implements TradeOrderService {
53 55  
  56 + // TODO @LeeYan9: 相同类型的, 可以放在一起,不用空行; 例如说 Mapper 和 API 和 Properties
  57 +
54 58 @Resource
55 59 private TradeOrderMapper tradeOrderMapper;
56   -
57 60 @Resource
58 61 private TradeOrderItemMapper tradeOrderItemMapper;
59 62  
60 63 @Resource
61 64 private PriceApi priceApi;
62   -
63 65 @Resource
64 66 private ProductSkuApi productSkuApi;
65   -
66 67 @Resource
67 68 private ProductSpuApi productSpuApi;
68   -
69 69 @Resource
70 70 private PayOrderApi payOrderApi;
71 71  
72 72 @Resource
73 73 private TradeOrderProperties tradeOrderProperties;
74 74  
  75 + // TODO LeeYan9: 静态变量, 需要在最前面哈; 另外, 静态变量的注释最好写下;
75 76 private static final String BLANK_PLACEHOLDER = " ";
76 77 private static final String MULTIPLIER_PLACEHOLDER = "x";
77 78  
78   -
79 79 @Override
80 80 @Transactional(rollbackFor = Exception.class)
81 81 public Long createTradeOrder(Long loginUserId, String clientIp, AppTradeOrderCreateReqVO createReqVO) {
82 82  
83   - List<Item> items = createReqVO.getItems();
  83 + List<Item> items = createReqVO.getItems(); // TODO @LeeYan9: 方法第一行, 不用空哈;
84 84 // 商品SKU检查 sku可售状态,库存
85 85 List<ProductSkuRespDTO> skuInfos = productSkuApi.getSkuList(CollectionUtils.convertSet(items, Item::getSkuId));
86 86 Map<Long, ProductSkuRespDTO> skuInfoMap = CollectionUtils.convertMap(skuInfos, ProductSkuRespDTO::getId);
... ... @@ -93,33 +93,38 @@ public class TradeOrderServiceImpl implements TradeOrderService {
93 93 // 价格计算
94 94 PriceCalculateReqDTO priceCalculateReqDTO = PriceConvert.INSTANCE.convert(createReqVO, loginUserId);
95 95 PriceCalculateRespDTO priceResp = priceApi.calculatePrice(priceCalculateReqDTO);
  96 + // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
  97 +
96 98 // 订单信息记录
97 99 TradeOrderDO tradeOrderDO = TradeOrderConvert.INSTANCE.convert(createReqVO, priceResp.getOrder());
98   - fillTradeOrderInfoFromReqInfo(tradeOrderDO,createReqVO,loginUserId, clientIp);
  100 + fillTradeOrderInfoFromReqInfo(tradeOrderDO,createReqVO,loginUserId, clientIp); // TODO @LeeYan9: tradeOrderDO, createReqVO, loginUserId, clientIp
99 101 tradeOrderMapper.insert(tradeOrderDO);
100 102  
101 103 // 订单项信息记录
102 104 List<TradeOrderItemDO> tradeOrderItems = TradeOrderItemConvert.INSTANCE.convertList(priceResp.getOrder().getItems());
103   - //-填充订单项-SKU信息
  105 + // 填充订单项-SKU信息
104 106 fillItemsInfoFromSkuAndOrder(tradeOrderDO, tradeOrderItems, skuInfoMap);
105 107 tradeOrderItemMapper.insertBatch(tradeOrderItems);
106 108  
  109 + // TODO @LeeYan9: 先扣减库存哈; 可能会扣减失败; 毕竟 get 和 update 之间, 会有并发的可能性
107 110 // 库存扣减
108 111 List<SkuDecrementStockBatchReqDTO.Item> skuDecrementStockItems = ProductSkuConvert.INSTANCE.convert(tradeOrderItems);
109 112 productSkuApi.decrementStockBatch(SkuDecrementStockBatchReqDTO.of(skuDecrementStockItems));
110 113  
111 114 // 构建预支付请求参数
  115 + // TODO @LeeYan9: 需要更新到订单上
112 116 PayOrderInfoCreateReqDTO payOrderCreateReqDTO = PayOrderConvert.INSTANCE.convert(tradeOrderDO);
113 117 fillPayOrderInfoFromItems(payOrderCreateReqDTO, tradeOrderItems);
114 118 // 生成预支付
115 119 return payOrderApi.createPayOrder(payOrderCreateReqDTO);
116 120 }
117 121  
  122 + // TODO @LeeYan9: 填充就好, 不用 from 哈;
118 123 private void fillTradeOrderInfoFromReqInfo(TradeOrderDO tradeOrderDO, AppTradeOrderCreateReqVO createReqVO,
119 124 Long loginUserId, String clientIp) {
120 125 tradeOrderDO.setUserId(loginUserId);
121 126 tradeOrderDO.setUserIp(clientIp);
122   - tradeOrderDO.setSn(IdUtil.getSnowflakeNextId() + "");
  127 + tradeOrderDO.setSn(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的;
123 128 tradeOrderDO.setStatus(TradeOrderStatusEnum.WAITING_PAYMENT.getStatus());
124 129 tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType());
125 130 tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
... ... @@ -139,7 +144,6 @@ public class TradeOrderServiceImpl implements TradeOrderService {
139 144 // 填写商品信息
140 145 StrBuilder subject = new StrBuilder();
141 146 StrBuilder body = new StrBuilder();
142   -
143 147 for (TradeOrderItemDO tradeOrderItem : tradeOrderItems) {
144 148 // append subject
145 149 subject.append(BLANK_PLACEHOLDER);
... ... @@ -151,6 +155,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
151 155 body.append(tradeOrderItem.getCount());
152 156 }
153 157 // 设置 subject & body
  158 + // TODO @LeeYan9: 可以抽象一个 StrUtils 方法; 或者看看 hutool 有没自带的哈
154 159 payOrderInfoCreateReqDTO.setSubject(StrUtils.maxLength(subject.subString(1), 32));
155 160 payOrderInfoCreateReqDTO.setBody(StrUtils.maxLength(body.subString(1), 128));
156 161 }
... ... @@ -182,6 +187,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
182 187 }
183 188 }
184 189  
  190 + // TODO @LeeYan9: checkSpuXXX 会不会好点哈? ps: 这个貌似是 sku 哈
185 191 private void checkSaleableAndStockFromSpu(Map<Long, ProductSkuRespDTO> skuInfoMap,
186 192 List<Item> items) {
187 193 // sku 不存在
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java
... ... @@ -30,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
30 30 import static org.mockito.ArgumentMatchers.any;
31 31 import static org.mockito.Mockito.when;
32 32  
  33 +// TODO @芋艿: 单测的 review; 最后搞;
33 34 /**
34 35 * @author LeeYan9
35 36 * @since 2022-09-07
... ...
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApi.java
... ... @@ -3,12 +3,13 @@ package cn.iocoder.yudao.module.pay.api.order;
3 3 import javax.validation.Valid;
4 4  
5 5 /**
  6 + * 支付单 API 接口
  7 + *
6 8 * @author LeeYan9
7 9 * @since 2022-08-26
8 10 */
9 11 public interface PayOrderApi {
10 12  
11   -
12 13 /**
13 14 * 创建支付单
14 15 *
... ...
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderInfoCreateReqDTO.java
... ... @@ -9,8 +9,10 @@ import javax.validation.constraints.NotNull;
9 9 import java.io.Serializable;
10 10 import java.util.Date;
11 11  
  12 +// TODO @LeeYan9: 1) 新建一个 dto 包, 然后挪进去哈; 2) 在 order下; Info 可以去掉;
12 13 /**
13 14 * 支付单创建 Request DTO
  15 + *
14 16 * @author LeeYan9
15 17 */
16 18 @Data
... ... @@ -53,6 +55,7 @@ public class PayOrderInfoCreateReqDTO implements Serializable {
53 55 * 支付金额,单位:分
54 56 */
55 57 @NotNull(message = "支付金额不能为空")
  58 + // TODO @LeeYan9: 是不是 @Min 注解呀, 是 Integer 哈
56 59 @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
57 60 private Integer amount;
58 61  
... ...