diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index a94c3fa35..b35439a36 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -170,4 +170,6 @@ public class Constants */ public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" }; + + public static final String UNDELETED = "0"; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java new file mode 100644 index 000000000..9ff1794bd --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java @@ -0,0 +1,66 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-02 22:31 + */ +@Data +public class StoreOrderAddDTO { + /** + * 档口ID + */ + private Long storeId; + /** + * 收货人-名称 + */ + private String destinationContactName; + /** + * 收货人-电话 + */ + private String destinationContactPhoneNumber; + /** + * 收货人-省编码 + */ + private String destinationProvinceCode; + /** + * 收货人-市编码 + */ + private String destinationCityCode; + /** + * 收货人-区县编码 + */ + private String destinationCountyCode; + /** + * 收货人-详细地址 + */ + private String destinationDetailAddress; + /** + * 发货方式[1:货其再发 2:有货先发] + */ + private Integer deliveryType; + /** + * 最晚发货时间 + */ + private Date deliveryEndTime; + /** + * 明细列表 + */ + private List detailList; + + @Data + public static class OrderDetail { + /** + * 商品颜色尺码ID + */ + private Long storeProdColorSizeId; + /** + * 商品数量 + */ + private Integer goodsQuantity; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailInfoDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailInfoDTO.java new file mode 100644 index 000000000..92e8efc6f --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailInfoDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-02 22:39 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderDetailInfoDTO extends StoreOrderDetailDTO { + + private List detailList; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java new file mode 100644 index 000000000..244066ac3 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java @@ -0,0 +1,17 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * @author liangyq + * @date 2025-04-02 22:37 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderInfoDTO extends StoreOrderDTO{ + + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EDeliveryType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EDeliveryType.java new file mode 100644 index 000000000..c09a26128 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EDeliveryType.java @@ -0,0 +1,28 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EDeliveryType { + + SHIP_COMPLETE(1, "货齐再发"), + PARTIAL_SHIPMENT(2, "有货先发"); + + private Integer value; + private String label; + + public static EDeliveryType of(String value) { + for (EDeliveryType e : EDeliveryType.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EExpressType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EExpressType.java new file mode 100644 index 000000000..bf453ba03 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EExpressType.java @@ -0,0 +1,28 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EExpressType { + + PLATFORM(1, "平台物流"), + STORE(2, "档口物流"); + + private Integer value; + private String label; + + public static EExpressType of(String value) { + for (EExpressType e : EExpressType.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java new file mode 100644 index 000000000..4b09076c0 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java @@ -0,0 +1,38 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EOrderStatus { + + //销售订单状态 + CANCELLED(10, "已取消"), + PENDING_PAYMENT(11, "待付款"), + PENDING_SHIPMENT(12, "待发货"), + SHIPPED(13, "已发货"), + COMPLETED(14, "已完成"), + + //售后订单状态 + AFTER_SALE_IN_PROGRESS(21, "售后中"), + AFTER_SALE_REJECTED(22, "售后拒绝"), + PLATFORM_INTERVENED(23, "平台介入"), + AFTER_SALE_COMPLETED(24, "售后完成"); + + private Integer value; + private String label; + + public static EOrderStatus of(String value) { + for (EOrderStatus e : EOrderStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderType.java new file mode 100644 index 000000000..cf40b66d9 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderType.java @@ -0,0 +1,28 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EOrderType { + + SALES_ORDER(1, "销售订单"), + RETURN_ORDER(2, "退货订单"); + + private Integer value; + private String label; + + public static EOrderType of(String value) { + for (EOrderType e : EOrderType.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EPayStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayStatus.java new file mode 100644 index 000000000..8ef8e8cef --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayStatus.java @@ -0,0 +1,29 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EPayStatus { + + INIT(1, "初始化"), + PAYING(2, "支付中"), + PAID(3, "已支付"); + + private Integer value; + private String label; + + public static EPayStatus of(String value) { + for (EPayStatus e : EPayStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EProductStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EProductStatus.java new file mode 100644 index 000000000..5cced216c --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EProductStatus.java @@ -0,0 +1,41 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EProductStatus { + + UN_PUBLISHED("UN_PUBLISHED", "未发布"), + ON_SALE("ON_SALE", "在售"), + TAIL_GOODS("TAIL_GOODS", "尾货"), + OFF_SALE("OFF_SALE", "已下架"), + REMOVED("REMOVED", "已删除"); + + private final String value; + private final String label; + + public static EProductStatus of(String value) { + for (EProductStatus e : EProductStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } + + /** + * 是否允许下单 + * + * @param value + * @return + */ + public static boolean accessOrder(String value) { + return ON_SALE.getValue().equals(value) || TAIL_GOODS.getValue().equals(value); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EVoucherSequenceType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EVoucherSequenceType.java new file mode 100644 index 000000000..7a95e61a5 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EVoucherSequenceType.java @@ -0,0 +1,30 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EVoucherSequenceType { + + STORE_SALE("STORE_SALE", ""), + STORAGE("STORAGE", ""), + DEMAND("DEMAND", ""), + STORE_ORDER("STORE_ORDER", "代发订单"); + + private final String value; + private final String label; + + public static EVoucherSequenceType of(String value) { + for (EVoucherSequenceType e : EVoucherSequenceType.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java index a453c4336..84c8f6ed9 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java @@ -1,8 +1,18 @@ package com.ruoyi.xkt.service; +import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; +import com.ruoyi.xkt.dto.order.StoreOrderDetailInfoDTO; + /** * @author liangyq * @date 2025-04-02 13:16 */ public interface IStoreOrderService { + /** + * 创建订单 + * + * @param storeOrderAddDTO + * @return + */ + StoreOrderDetailInfoDTO createOrder(StoreOrderAddDTO storeOrderAddDTO); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java index d10ed0722..e2ca8af73 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java @@ -1,12 +1,26 @@ package com.ruoyi.xkt.service.impl; -import com.ruoyi.xkt.mapper.StoreOrderDetailMapper; -import com.ruoyi.xkt.mapper.StoreOrderExpressTrackMapper; -import com.ruoyi.xkt.mapper.StoreOrderMapper; -import com.ruoyi.xkt.mapper.StoreOrderOperationRecordMapper; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Assert; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.xkt.domain.StoreProduct; +import com.ruoyi.xkt.domain.StoreProductColorSize; +import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; +import com.ruoyi.xkt.dto.order.StoreOrderDetailInfoDTO; +import com.ruoyi.xkt.enums.EProductStatus; +import com.ruoyi.xkt.enums.EVoucherSequenceType; +import com.ruoyi.xkt.mapper.*; import com.ruoyi.xkt.service.IStoreOrderService; +import com.ruoyi.xkt.service.IVoucherSequenceService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; /** * @author liangyq @@ -22,4 +36,60 @@ public class StoreOrderServiceImpl implements IStoreOrderService { private StoreOrderOperationRecordMapper storeOrderOperationRecordMapper; @Autowired private StoreOrderExpressTrackMapper storeOrderExpressTrackMapper; + @Autowired + private StoreProductMapper storeProductMapper; + @Autowired + private StoreProductColorSizeMapper storeProductColorSizeMapper; + @Autowired + private IVoucherSequenceService voucherSequenceService; + + @Transactional + @Override + public StoreOrderDetailInfoDTO createOrder(StoreOrderAddDTO storeOrderAddDTO) { + checkOrderDetail(storeOrderAddDTO.getStoreId(), storeOrderAddDTO.getDetailList()); + //生成订单号 + String orderNo = voucherSequenceService.generateCode(storeOrderAddDTO.getStoreId(), + EVoucherSequenceType.STORE_ORDER.getValue(), DateUtil.today()); + //TODO + return null; + } + + /** + * 检查订单明细 + * + * @param storeId + * @param detailList + */ + private void checkOrderDetail(Long storeId, List detailList) { + Assert.notNull(storeId, "档口不能为空"); + Assert.notEmpty(detailList, "商品不能为空"); + Set spcsIds = detailList.stream() + .map(StoreOrderAddDTO.OrderDetail::getStoreProdColorSizeId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + //下单商品颜色尺码 + Map spcsMap = storeProductColorSizeMapper.selectByIds(spcsIds).stream() + .collect(Collectors.toMap(StoreProductColorSize::getId, o -> o)); + List spIdList = spcsMap.values().stream() + .map(StoreProductColorSize::getStoreProdId) + .collect(Collectors.toList()); + //下单商品 + Map spMap = storeProductMapper.selectByIds(spIdList).stream() + .collect(Collectors.toMap(StoreProduct::getId, o -> o)); + for (StoreOrderAddDTO.OrderDetail detail : detailList) { + Assert.notNull(detail.getStoreProdColorSizeId(), "商品颜色尺码异常"); + Integer goodsQuantity = detail.getGoodsQuantity(); + if (Objects.isNull(goodsQuantity) || goodsQuantity == 0) { + throw new IllegalArgumentException("商品数量异常"); + } + StoreProductColorSize spcs = spcsMap.get(detail.getStoreProdColorSizeId()); + Assert.isTrue(Objects.nonNull(spcs) && Constants.UNDELETED.equals(spcs.getDelFlag()), + "商品颜色尺码不存在"); + StoreProduct sp = spMap.get(spcs.getStoreProdId()); + Assert.isTrue(Objects.nonNull(sp) && Constants.UNDELETED.equals(sp.getDelFlag()), + "商品不存在"); + Assert.isTrue(storeId.equals(sp.getStoreId()), "系统不支持跨档口下单"); + Assert.isTrue(EProductStatus.accessOrder(sp.getProdStatus()), "商品状态异常"); + } + } }