Browse Source

新增创建情侣订单接口

codingliang 10 months atrás
parent
commit
05bc27ef2c

+ 1 - 1
db/update_250824.sql

@@ -55,7 +55,7 @@ CREATE TABLE lovers_set_content_detail(
 DROP TABLE IF EXISTS lovers_set_order_detail;
 CREATE TABLE lovers_set_order_detail(
                                         `id` bigint NOT NULL AUTO_INCREMENT  COMMENT 'id' ,
-                                        `lovers_set_order_info_id` VARCHAR(32) NOT NULL   COMMENT '情侣套餐订单id' ,
+                                        `lovers_set_order_info_id` bigint NOT NULL   COMMENT '情侣套餐订单id' ,
                                         `goods_id` bigint NOT NULL   COMMENT '商品id' ,
                                         `goods_name` VARCHAR(32) NOT NULL   COMMENT '商品名称' ,
                                         `shop_id` bigint NOT NULL   COMMENT '店铺id' ,

+ 5 - 0
src/main/java/com/sqx/common/constant/RedisKey.java

@@ -102,4 +102,9 @@ public interface RedisKey {
      * 平台账单锁
      */
     String PLATFORM_BILL_LOCK = "wm:lock:platform-bill";
+
+    /**
+     * 情侣订单提交token
+     */
+    String LOVERS_SET_ORDER_SUBMIT_TOKEN = "wm:data:lovers-set-order:submit:token:%s";
 }

+ 6 - 0
src/main/java/com/sqx/common/utils/RedisUtils.java

@@ -2,9 +2,11 @@ package com.sqx.common.utils;
 
 import org.springframework.data.redis.core.HashOperations;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Map;
@@ -155,4 +157,8 @@ public class RedisUtils {
     public Object rightPop(String key) {
         return redisTemplate.opsForList().rightPop(key);
     }
+
+    public Long execute(String key, String script, Object... args) {
+        return redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList(key), args);
+    }
 }

+ 40 - 0
src/main/java/com/sqx/modules/lovers/controller/app/AppLoversSetOrderController.java

@@ -0,0 +1,40 @@
+package com.sqx.modules.lovers.controller.app;
+
+import com.sqx.common.utils.Result;
+import com.sqx.modules.app.annotation.Login;
+import com.sqx.modules.lovers.dto.LoversSetOrderSubmitDTO;
+import com.sqx.modules.lovers.service.LoversSetOrderInfoService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@Api(tags = {"移动端-情侣套餐订单"})
+@RestController
+@RequestMapping("app/lovers-set-order")
+@RequiredArgsConstructor
+public class AppLoversSetOrderController {
+
+    private final LoversSetOrderInfoService loversSetOrderInfoService;
+
+    @Login
+    @ApiOperation("创建订单")
+    @GetMapping
+    public Result createOrder(@RequestAttribute Long userId, @Valid LoversSetOrderSubmitDTO submitDTO){
+        Long orderId = loversSetOrderInfoService.createOrder(userId, submitDTO);
+        return Result.success().put("data", orderId);
+    }
+
+    @Login
+    @ApiOperation("获取提交订单token")
+    @GetMapping("submit-token")
+    public Result getSubmitToken(@RequestAttribute Long userId){
+        String token = loversSetOrderInfoService.getSubmitToken(userId);
+        return Result.success().put("data", token);
+    }
+}

+ 42 - 0
src/main/java/com/sqx/modules/lovers/dto/LoversSetMenstrualPeriodSettingDTO.java

@@ -0,0 +1,42 @@
+package com.sqx.modules.lovers.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+public class LoversSetMenstrualPeriodSettingDTO implements Serializable {
+
+    @ApiModelProperty("主键id")
+    private Long id;
+
+    @ApiModelProperty("用户id")
+    private Long userId;
+
+    @ApiModelProperty("持续天数")
+    private Integer durationDays;
+
+    @ApiModelProperty("间隔天数")
+    private Integer intervalDays;
+
+    @ApiModelProperty("上一次月经开始时间")
+    private Date lastStartDate;
+
+    @ApiModelProperty("上一次月经结束时间")
+    private Date lastEndDate;
+
+    @ApiModelProperty("预计下一次月经开始时间")
+    private Date nextStartDateOfExpect;
+
+    @ApiModelProperty("预计下一次月经结束时间")
+    private Date nextEndDateOfExpect;
+
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新时间")
+    private LocalDateTime updateTime;
+}

+ 13 - 6
src/main/java/com/sqx/modules/lovers/dto/LoversSetOrderSubmitDTO.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
 import java.math.BigDecimal;
 import java.util.Date;
 
@@ -17,10 +18,6 @@ import java.util.Date;
 @Data
 public class LoversSetOrderSubmitDTO {
 
-    @ApiModelProperty("用户id")
-    @NotNull(message = "用户id不能为空")
-    private Long userId;
-
     @ApiModelProperty("情侣套餐id")
     @NotNull(message = "情侣套餐id不能为空")
     private Long loversSetId;
@@ -44,29 +41,39 @@ public class LoversSetOrderSubmitDTO {
     private Integer intervalDays;
 
     @ApiModelProperty("上一次月经开始时间")
+    @NotNull(message = "上一次月经开始时间不能为空")
     private Date lastStartDate;
 
     @ApiModelProperty("上一次月经结束时间")
+    @NotNull(message = "上一次月经结束时间不能为空")
     private Date lastEndDate;
 
     @ApiModelProperty("预计下一次月经开始时间")
+    @NotNull(message = "预计下一次月经开始时间不能为空")
     private Date nextStartDateOfExpect;
 
     @ApiModelProperty("预计下一次月经结束时间")
+    @NotNull(message = "预计下一次月经结束时间不能为空")
     private Date nextEndDateOfExpect;
 
     @ApiModelProperty("收货人姓名")
+    @NotBlank(message = "收货人姓名不能为空")
     private String receiverName;
 
     @ApiModelProperty("收货人电话")
+    @NotBlank(message = "收货人电话不能为空")
     private String receiverPhone;
 
     @ApiModelProperty("接货开始时间")
-    private String receiveStartDate;
+    @NotBlank(message = "接货开始时间不能为空")
+    private Date receiveStartDate;
 
     @ApiModelProperty("接货结束时间")
+    @NotBlank(message = "接货结束时间不能为空")
     private Date receiveEndDate;
 
     @ApiModelProperty("期待接货时间;HH:mm:ss")
-    private Date expectReceiveTime;
+    @NotBlank(message = "期待接货时间不能为空")
+    @Pattern(regexp = "^([01]\\d|2[0-3]):([0-5]\\d):([0-5]\\d)$", message = "期待接货时间格式错误")
+    private String expectReceiveTime;
 }

+ 1 - 1
src/main/java/com/sqx/modules/lovers/entity/LoversSetOrderDetail.java

@@ -19,7 +19,7 @@ public class LoversSetOrderDetail implements Serializable {
     private Long id;
 
     @ApiModelProperty("情侣套餐订单id")
-    private String loversSetOrderInfoId;
+    private Long loversSetOrderInfoId;
 
     @ApiModelProperty("商品id")
     private Long goodsId;

+ 7 - 0
src/main/java/com/sqx/modules/lovers/service/LoversSetMenstrualPeriodSettingService.java

@@ -1,7 +1,14 @@
 package com.sqx.modules.lovers.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.sqx.modules.lovers.dto.LoversSetMenstrualPeriodSettingDTO;
 import com.sqx.modules.lovers.entity.LoversSetMenstrualPeriodSetting;
 
 public interface LoversSetMenstrualPeriodSettingService extends IService<LoversSetMenstrualPeriodSetting> {
+    /**
+     * 新增
+     *
+     * @param menstrualPeriodSettingDTO 情侣套餐经期信息
+     */
+    void add(LoversSetMenstrualPeriodSettingDTO menstrualPeriodSettingDTO);
 }

+ 18 - 0
src/main/java/com/sqx/modules/lovers/service/LoversSetOrderInfoService.java

@@ -1,7 +1,25 @@
 package com.sqx.modules.lovers.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.sqx.modules.lovers.dto.LoversSetOrderSubmitDTO;
 import com.sqx.modules.lovers.entity.LoversSetOrderInfo;
 
 public interface LoversSetOrderInfoService extends IService<LoversSetOrderInfo> {
+
+    /**
+     * 创建订单
+     *
+     * @param userId 用户id
+     * @param submitDTO 提交DTO
+     * @return 订单编号
+     */
+    Long createOrder(Long userId, LoversSetOrderSubmitDTO submitDTO);
+
+    /**
+     * 获取提交订单token
+     *
+     * @param userId 用户id
+     * @return token
+     */
+    String getSubmitToken(Long userId);
 }

+ 9 - 0
src/main/java/com/sqx/modules/lovers/service/impl/LoversSetMenstrualPeriodSettingServiceImpl.java

@@ -1,11 +1,20 @@
 package com.sqx.modules.lovers.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.modules.lovers.dao.LoversSetMenstrualPeriodSettingDao;
+import com.sqx.modules.lovers.dto.LoversSetMenstrualPeriodSettingDTO;
 import com.sqx.modules.lovers.entity.LoversSetMenstrualPeriodSetting;
 import com.sqx.modules.lovers.service.LoversSetMenstrualPeriodSettingService;
 import org.springframework.stereotype.Service;
 
 @Service
 public class LoversSetMenstrualPeriodSettingServiceImpl extends ServiceImpl<LoversSetMenstrualPeriodSettingDao,LoversSetMenstrualPeriodSetting> implements LoversSetMenstrualPeriodSettingService {
+
+    @Override
+    public void add(LoversSetMenstrualPeriodSettingDTO menstrualPeriodSettingDTO) {
+        LoversSetMenstrualPeriodSetting menstrualPeriodSetting = new LoversSetMenstrualPeriodSetting();
+        BeanUtil.copyProperties(menstrualPeriodSettingDTO, menstrualPeriodSetting);
+        save(menstrualPeriodSetting);
+    }
 }

+ 143 - 0
src/main/java/com/sqx/modules/lovers/service/impl/LoversSetOrderInfoServiceImpl.java

@@ -1,11 +1,154 @@
 package com.sqx.modules.lovers.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sqx.common.constant.RedisKey;
+import com.sqx.common.exception.SqxException;
+import com.sqx.common.utils.Constant;
+import com.sqx.common.utils.RedisUtils;
 import com.sqx.modules.lovers.dao.LoversSetOrderInfoDao;
+import com.sqx.modules.lovers.dto.LoversSetMenstrualPeriodSettingDTO;
+import com.sqx.modules.lovers.dto.LoversSetOrderSubmitDTO;
+import com.sqx.modules.lovers.entity.LoversSetOrderDetail;
 import com.sqx.modules.lovers.entity.LoversSetOrderInfo;
+import com.sqx.modules.lovers.service.LoversSetMenstrualPeriodSettingService;
+import com.sqx.modules.lovers.service.LoversSetOrderDetailService;
 import com.sqx.modules.lovers.service.LoversSetOrderInfoService;
+import com.sqx.modules.lovers.service.LoversSetService;
+import com.sqx.modules.lovers.vo.LoversSetVO;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
 
 @Service
+@RequiredArgsConstructor
 public class LoversSetOrderInfoServiceImpl extends ServiceImpl<LoversSetOrderInfoDao, LoversSetOrderInfo> implements LoversSetOrderInfoService {
+
+    private final RedisUtils redisUtils;
+    private final LoversSetService loversSetService;
+    private final LoversSetMenstrualPeriodSettingService loversSetMenstrualPeriodSettingService;
+    private final LoversSetOrderDetailService loversSetOrderDetailService;
+
+    @Override
+    @Transactional
+    public Long createOrder(Long userId, LoversSetOrderSubmitDTO submitDTO) {
+        // 校验令牌
+        checkToken(userId, submitDTO.getSubmitToken());
+
+        // 校验套餐信息
+        LoversSetVO loversSetVO = checkLoversSetInfo(submitDTO);
+
+        // 保存经期信息
+        LoversSetMenstrualPeriodSettingDTO menstrualPeriodSettingDTO = generateLoversSetMenstrualPeriodSettingDTO(userId, submitDTO);
+        loversSetMenstrualPeriodSettingService.add(menstrualPeriodSettingDTO);
+
+        // 保存情侣套餐订单
+        LoversSetOrderInfo loversSetOrderInfo = generateLoversSetOrder(userId, submitDTO, loversSetVO);
+
+        return loversSetOrderInfo.getId();
+    }
+
+    @Override
+    public String getSubmitToken(Long userId) {
+        String token = UUID.randomUUID().toString().replace("-", "");
+        String key = String.format(RedisKey.LOVERS_SET_ORDER_SUBMIT_TOKEN, userId.toString());
+
+        // 过期时间设置为5分钟
+        redisUtils.set(key, token, 60 * 5);
+
+        return token;
+    }
+
+    private LoversSetOrderInfo generateLoversSetOrder(Long userId, LoversSetOrderSubmitDTO submitDTO, LoversSetVO loversSetVO) {
+        LoversSetOrderInfo loversSetOrderInfo = new LoversSetOrderInfo();
+        loversSetOrderInfo.setOrderNumber(IdWorker.getTimeId());
+        loversSetOrderInfo.setUserId(userId);
+        loversSetOrderInfo.setLoversSetId(submitDTO.getLoversSetId());
+        loversSetOrderInfo.setLoversSetName(loversSetVO.getName());
+        loversSetOrderInfo.setLoversSetMasterImg(loversSetVO.getImgs().split(",")[0]);
+        loversSetOrderInfo.setLoversSetAmount(loversSetVO.getPrice());
+        loversSetOrderInfo.setPayAmount(submitDTO.getPayAmount());
+        loversSetOrderInfo.setReceiverName(submitDTO.getReceiverName());
+        loversSetOrderInfo.setReceiverPhone(submitDTO.getReceiverPhone());
+        loversSetOrderInfo.setExpectReceiveTime(submitDTO.getExpectReceiveTime());
+        loversSetOrderInfo.setReceiveStartDate(submitDTO.getReceiveStartDate());
+        loversSetOrderInfo.setReceiveEndDate(submitDTO.getReceiveEndDate());
+        loversSetOrderInfo.setActiveStatus(Constant.NO);
+        loversSetOrderInfo.setPayStatus(Constant.NO);
+        loversSetOrderInfo.setRefundStatus(Constant.NO);
+        loversSetOrderInfo.setCreateTime(LocalDateTime.now());
+        loversSetOrderInfo.setUpdateTime(LocalDateTime.now());
+
+        this.save(loversSetOrderInfo);
+
+        // 生成订单详情
+        List<LoversSetOrderDetail> orderDetailList = loversSetVO.getContentList()
+                .stream()
+                .flatMap(contentVO -> contentVO.getContentDetailList().stream())
+                .map(detailVO -> {
+                    LoversSetOrderDetail orderDetail = new LoversSetOrderDetail();
+                    BeanUtil.copyProperties(detailVO, orderDetail);
+                    orderDetail.setLoversSetOrderInfoId(loversSetOrderInfo.getId());
+                    return orderDetail;
+                })
+                .collect(Collectors.toList());
+
+        loversSetOrderDetailService.saveBatch(orderDetailList);
+
+        return loversSetOrderInfo;
+    }
+
+    private LoversSetMenstrualPeriodSettingDTO generateLoversSetMenstrualPeriodSettingDTO(Long userId, LoversSetOrderSubmitDTO submitDTO) {
+        LoversSetMenstrualPeriodSettingDTO dto = new LoversSetMenstrualPeriodSettingDTO();
+        BeanUtil.copyProperties(submitDTO, dto);
+        dto.setUserId(userId);
+        dto.setCreateTime(LocalDateTime.now());
+        dto.setUpdateTime(LocalDateTime.now());
+        return dto;
+    }
+
+    private LoversSetVO checkLoversSetInfo(LoversSetOrderSubmitDTO submitDTO) {
+        LoversSetVO loversSetVO = loversSetService.getDetailById(submitDTO.getLoversSetId());
+        if (ObjectUtil.isNull(loversSetVO)) {
+            throw new SqxException("无效的情侣套餐id");
+        }
+
+        // 校验套餐状态
+        if (!StrUtil.equals(loversSetVO.getSetStatus(), Constant.YES)) {
+            throw new SqxException("当前情侣套餐状态异常");
+        }
+
+        // 校验套餐金额
+        if (loversSetVO.getPrice().compareTo(submitDTO.getPayAmount()) != 0 ) {
+            throw new SqxException("订单价格发生变动,请刷新页面后重试");
+        }
+
+        // 校验套餐有效时间
+        LocalDateTime now = LocalDateTime.now();
+        if (now.isBefore(loversSetVO.getStartTime()) || now.isAfter(loversSetVO.getEndTime())) {
+            throw new SqxException("当前时间不在套餐有效时间内");
+        }
+
+        return loversSetVO;
+    }
+
+    private void checkToken(Long userId, String submitToken) {
+        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
+        String key = String.format(RedisKey.LOVERS_SET_ORDER_SUBMIT_TOKEN, userId.toString());
+
+        // 执行redis脚本,成功返回1,失败返回
+        Long result = redisUtils.execute(key, script, submitToken);
+        if (result == 0) {
+            // 令牌验证失败
+            throw new SqxException("无效的提交token,请刷新页面重新提交订单");
+        }
+    }
 }