diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java index 5b515b0..c2c39fb 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -68,6 +68,12 @@ public class ProductSkuRespDTO { * 商品体积,单位:m^3 平米 */ private Double volume; + + /** + * 限购类型 + */ + private String purchaseBizType; + /** * 一级分销的佣金,单位:分 */ diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/sku/ProductSkuPurchaseBizTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/sku/ProductSkuPurchaseBizTypeEnum.java new file mode 100644 index 0000000..6f651f9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/sku/ProductSkuPurchaseBizTypeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.enums.sku; + + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 限购类型 + */ +@Getter +@AllArgsConstructor +public enum ProductSkuPurchaseBizTypeEnum implements ArrayValuable { + + NONE("0", "不限购"), + ONCE_A_DAY("1", "限购一天一次"), + ; + + + public static final String[] ARRAYS = Arrays.stream(values()).map(ProductSkuPurchaseBizTypeEnum::getStatus).toArray(String[]::new); + + /** + * 状态 + */ + private final String status; + /** + * 状态名 + */ + private final String name; + + @Override + public String[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java index 5c7c713..ea7b5b2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; +import cn.iocoder.yudao.module.product.enums.sku.ProductSkuPurchaseBizTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -39,6 +40,9 @@ public class ProductSkuRespVO { @Schema(description = "商品体积,单位:m^3 平米", example = "2.5") private Double volume; + @Schema(description = "限购类型(不能为空)", example = "0") + private String purchaseBizType; + @Schema(description = "一级分销的佣金,单位:分", example = "199") private Integer firstBrokeragePrice; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java index be5665e..78cfcd7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java @@ -44,6 +44,9 @@ public class ProductSkuSaveReqVO { @Schema(description = "商品体积,单位:m^3 平米", example = "2.5") private Double volume; + @Schema(description = "限购类型(不能为空)", example = "0") + private String purchaseBizType; + @Schema(description = "一级分销的佣金,单位:分", example = "199") private Integer firstBrokeragePrice; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java index 4940198..6566384 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.sku.ProductSkuPurchaseBizTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -35,7 +36,7 @@ public class ProductSkuDO extends BaseDO { private Long id; /** * SPU 编号 - * + *

* 关联 {@link ProductSpuDO#getId()} */ private Long spuId; @@ -103,6 +104,13 @@ public class ProductSkuDO extends BaseDO { */ private String cabinetType; + /** + * 限购类型(不能为空) + * + * @see ProductSkuPurchaseBizTypeEnum + */ + private String purchaseBizType; + /** * 商品属性 */ @@ -119,7 +127,7 @@ public class ProductSkuDO extends BaseDO { /** * 属性名字 * 冗余 {@link ProductPropertyDO#getName()} - * + *

* 注意:每次属性名字发生变化时,需要更新该冗余 */ private String propertyName; @@ -132,7 +140,7 @@ public class ProductSkuDO extends BaseDO { /** * 属性值名字 * 冗余 {@link ProductPropertyValueDO#getName()} - * + *

* 注意:每次属性值名字发生变化时,需要更新该冗余 */ private String valueName; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 4d07f7e..3632ae1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSkuSaveReqVO; import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; @@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; +import cn.iocoder.yudao.module.product.enums.sku.ProductSkuPurchaseBizTypeEnum; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index fce0bd3..9231b35 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -39,6 +39,7 @@ public interface ErrorCodeConstants { ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_034, "交易订单自提失败,原因:你没有核销该门店订单的权限"); ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_035, "交易订单创建失败,原因:用户积分不足"); ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_OVERPAY = new ErrorCode(1_011_000_036, "提货柜订单完成失败,订单不是【已支付】状态"); + ErrorCode ORDER_RECEIVE_FAIL_STATUS_PURCHASE = new ErrorCode(1_011_000_037, "您购买的商品:{},是{}"); // ========== After Sale 模块 1-011-000-100 ========== ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); 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 5da3130..742c4a0 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 @@ -31,6 +31,7 @@ import javax.annotation.security.PermitAll; import javax.validation.Valid; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -63,6 +64,14 @@ public class AppTradeOrderController { return success(tradeOrderUpdateService.settlementOrder(getLoginUserId(), settlementReqVO)); } + @PostMapping("/judgePurchase") + @Operation(summary = "判断是否为限购商品") + public CommonResult judgePurchase(@RequestBody @Valid AppTradeOrderJudgePurchaseRespVo settlementReqVO) { + List skuList = settlementReqVO.getItems().stream().map(AppTradeOrderJudgePurchaseRespVo.Item::getSkuId).collect(Collectors.toList()); + tradeOrderUpdateService.isSkuPurchaseLimit(getLoginUserId(), skuList); + return success(true); + } + @GetMapping("/settlement-product") @Operation(summary = "获得商品结算信息", description = "用于商品列表、商品详情,获得参与活动后的价格信息") @Parameter(name = "spuIds", description = "商品 SPU 编号数组") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderJudgePurchaseRespVo.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderJudgePurchaseRespVo.java new file mode 100644 index 0000000..8a63b50 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderJudgePurchaseRespVo.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class AppTradeOrderJudgePurchaseRespVo { + + @Schema(description = "商品项数组", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "商品不能为空") + private List items; + + @Data + @Schema(description = "用户 App - 商品项") + @Valid + public static class Item { + + @Schema(description = "商品 SKU 编号", example = "2048") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "购买数量", example = "1") + @Min(value = 1, message = "购买数量最小值为 {value}") + private Integer count; + + @Schema(description = "购物车项的编号", example = "1024") + private Long cartId; + + @AssertTrue(message = "商品不正确") + @JsonIgnore + public boolean isValid() { + // 组合一:skuId + count 使用商品 SKU + if (skuId != null && count != null) { + return true; + } + // 组合二:cartId 使用购物车项 + return cartId != null; + } + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java index b701b7f..5336a26 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java @@ -10,10 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; @Mapper public interface TradeOrderItemMapper extends BaseMapperX { @@ -52,5 +49,4 @@ public interface TradeOrderItemMapper extends BaseMapperX { // 获得数量 return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0; } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java index cd1cee7..03a48e7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java @@ -23,6 +23,8 @@ public interface TradeOrderUpdateService { // =================== Order =================== + void isSkuPurchaseLimit(Long payUserId, List skuIdList); + /** * 获得订单结算信息 * @@ -51,11 +53,11 @@ public interface TradeOrderUpdateService { /** * 同步订单的支付状态 - * + *

* 1. Quietly 表示,即使同步失败,也不会抛出异常 * 2. 什么时候回出现异常?因为是主动同步,可能和支付模块的回调通知 {@link #updateOrderPaid(Long, Long)} 存在并发冲突,导致抛出异常 * - * @param id 订单编号 + * @param id 订单编号 * @param payOrderId 支付订单编号 */ void syncOrderPayStatusQuietly(Long id, Long payOrderId); @@ -130,14 +132,14 @@ public interface TradeOrderUpdateService { * 【管理员】核销订单 * * @param userId 管理员编号 - * @param id 订单编号 + * @param id 订单编号 */ void pickUpOrderByAdmin(Long userId, Long id); /** * 【管理员】核销订单 * - * @param userId 管理员编号 + * @param userId 管理员编号 * @param pickUpVerifyCode 自提核销码 */ void pickUpOrderByAdmin(Long userId, String pickUpVerifyCode); @@ -203,9 +205,9 @@ public interface TradeOrderUpdateService { /** * 取消支付订单 * - * @param userId 用户编号 - * @param orderId 订单编号 - * @param cancelType 取消类型 + * @param userId 用户编号 + * @param orderId 订单编号 + * @param cancelType 取消类型 */ void cancelPaidOrder(Long userId, Long orderId, Integer cancelType); 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 3cae537..b9d7297 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 @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.service.order; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; @@ -13,6 +14,7 @@ import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; @@ -23,6 +25,9 @@ import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; 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.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.enums.sku.ProductSkuPurchaseBizTypeEnum; import cn.iocoder.yudao.module.system.api.social.SocialClientApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; @@ -57,6 +62,7 @@ import cn.iocoder.yudao.module.trade.service.price.TradePriceService; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -64,11 +70,13 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.validation.constraints.NotNull; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; @@ -119,12 +127,58 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { public SocialClientApi socialClientApi; @Resource public PayRefundApi payRefundApi; + @Resource + public ProductSkuApi productSkuApi; @Resource private TradeOrderProperties tradeOrderProperties; // =================== Order =================== + public List findUserSuccessOrderItem(Long payUserId, List skuIdList, ProductSkuPurchaseBizTypeEnum status) { + List statusList = new ArrayList<>(); + statusList.add(TradeOrderStatusEnum.UNPAID.getStatus()); + statusList.add(TradeOrderStatusEnum.UNDELIVERED.getStatus()); + statusList.add(TradeOrderStatusEnum.DELIVERED.getStatus()); + statusList.add(TradeOrderStatusEnum.COMPLETED.getStatus()); + // 查询用户订单 + LambdaQueryWrapperX orderQuery = new LambdaQueryWrapperX().eq(TradeOrderDO::getUserId, payUserId).in(TradeOrderDO::getStatus, statusList); + // 限购一天一次 + if (ObjectUtil.equals(status, ProductSkuPurchaseBizTypeEnum.ONCE_A_DAY)) { + orderQuery.between(TradeOrderDO::getCreateTime, LocalDate.now(), LocalDate.now().plusDays(1)); + } + List orderList = tradeOrderMapper.selectList(orderQuery); + if (ObjectUtil.isEmpty(orderList)) return null; + List orderIds = orderList.stream().map(TradeOrderDO::getId).collect(Collectors.toList()); + // 查询订单项 + List orderItemList = tradeOrderItemMapper.selectList(new LambdaQueryWrapperX() + .eq(TradeOrderItemDO::getUserId, payUserId) + .in(TradeOrderItemDO::getOrderId, orderIds) + ); + if (ObjectUtil.isEmpty(orderItemList)) return null; + orderItemList = orderItemList.stream().filter(v -> skuIdList.contains(v.getSkuId())).collect(Collectors.toList()); + return orderItemList; + } + + /** + * 判断sku是否限购 + */ + @Override + public void isSkuPurchaseLimit(Long payUserId, List skuIdList) { + List skuList = productSkuApi.getSkuList(skuIdList); + // 检查每天限购一次 + ProductSkuPurchaseBizTypeEnum onceADayStatus = ProductSkuPurchaseBizTypeEnum.ONCE_A_DAY; + List onceADay = skuList.stream().filter((v) -> ObjectUtil.equals(v.getPurchaseBizType(), onceADayStatus.getStatus())).collect(Collectors.toList()); + if (ObjectUtil.isNotEmpty(onceADay)) { + List targetIdList = onceADay.stream().map(ProductSkuRespDTO::getId).collect(Collectors.toList()); + List targetSkuList = findUserSuccessOrderItem(payUserId, targetIdList, onceADayStatus); + if (ObjectUtil.isNotEmpty(targetSkuList)) { + String spuName = targetSkuList.stream().map(TradeOrderItemDO::getSpuName).collect(Collectors.joining()); + throw exception(ORDER_RECEIVE_FAIL_STATUS_PURCHASE, "【" + spuName + "】", onceADayStatus.getName()); + } + } + } + @Override public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { // 1. 获得收货地址 @@ -133,6 +187,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { settlementReqVO.setAddressId(address.getId()); } + // TODO 新需求 查看商品有没有限购 + List skuList = settlementReqVO.getItems().stream().map(AppTradeOrderSettlementReqVO.Item::getSkuId).collect(Collectors.toList()); + isSkuPurchaseLimit(userId, skuList); + // 2. 计算价格 TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, settlementReqVO); @@ -251,7 +309,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // 3. 生成预支付 // 特殊情况:积分兑换时,可能支付金额为零 - if (order.getPayPrice() > 0) { + // TODO 特殊需求,价格可以为0 + if (order.getPayPrice() >= 0) { createPayOrder(order, orderItems); } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java index cce196b..8f3a6c8 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java @@ -53,7 +53,7 @@ public class PayOrderCreateReqDTO implements Serializable { * 支付金额,单位:分 */ @NotNull(message = "支付金额不能为空") - @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + @DecimalMin(value = "0", inclusive = true, message = "支付金额必须大于零") private Integer price; /** diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java index f269d2f..58fcaee 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderUnifiedReqDTO.java @@ -63,7 +63,7 @@ public class PayOrderUnifiedReqDTO { * 支付金额,单位:分 */ @NotNull(message = "支付金额不能为空") - @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + @DecimalMin(value = "0", inclusive = true, message = "支付金额必须大于零") private Integer price; /** diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 570ff9d..05ee6fd 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -79,8 +79,8 @@ spring: redis: host: 127.0.0.1 # 地址 port: 6379 # 端口 - database: 0 # 数据库索引 - password: 123456 # 密码,建议生产环境开启 + database: 10 # 数据库索引 + # password: 123456 # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### @@ -209,8 +209,12 @@ wx: # secret: 6f270509224a7ae1296bbf1c8cb97aed # appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的) # secret: 4a1a04e07f6a4a0751b39c3064a92c8b - appid: wx66186af0759f47c9 # 测试号(puhui 提供的) - secret: 3218bcbd112cbc614c7264ceb20144ac + # 测试 + # appid: wx66186af0759f47c9 + # secret: 3218bcbd112cbc614c7264ceb20144ac + # 正式 + appid: wx741ef9b42243284a + secret: 3b211e4bf0eeaaf27c8a369bcd10c9fb config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 key-prefix: wa # Redis Key 的前缀 diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 4f591b4..b60047e 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -3,8 +3,8 @@ spring: name: yudao-server profiles: - active: prod -# active: local + # active: prod + active: local main: allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 @@ -71,9 +71,9 @@ mybatis-plus: global-config: db-config: id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。 -# id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库 -# id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库 -# id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解 + # id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库 + # id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库 + # id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解 logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) banner: false # 关闭控制台的 Banner 打印 @@ -219,13 +219,13 @@ yudao: model: Baichuan4-Turbo midjourney: enable: true - # base-url: https://api.holdai.top/mj-relax/mj + # base-url: https://api.holdai.top/mj-relax/mj base-url: https://api.holdai.top/mj api-key: sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf notify-url: http://java.nat300.top/admin-api/ai/image/midjourney/notify suno: enable: true - # base-url: https://suno-55ishh05u-status2xxs-projects.vercel.app + # base-url: https://suno-55ishh05u-status2xxs-projects.vercel.app base-url: http://127.0.0.1:3001 --- #################### 芋道相关配置 ####################