|
|
@@ -1,11 +1,250 @@
|
|
|
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.conditions.query.LambdaQueryWrapper;
|
|
|
+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.app.entity.UserEntity;
|
|
|
+import com.sqx.modules.app.service.UserService;
|
|
|
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.LoversSetOrderDeliveryInfo;
|
|
|
+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.LoversSetOrderDeliveryInfoService;
|
|
|
+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 com.sqx.modules.pay.dto.GetPayParamDTO;
|
|
|
+import com.sqx.modules.pay.enums.PayChannelEnum;
|
|
|
+import com.sqx.modules.pay.enums.PaySceneEnum;
|
|
|
+import com.sqx.modules.pay.service.NewPayService;
|
|
|
+import com.sqx.modules.pay.vo.WechatTransactionsParamVO;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.UUID;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.IntStream;
|
|
|
|
|
|
@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;
|
|
|
+ private final LoversSetOrderDeliveryInfoService loversSetOrderDeliveryInfoService;
|
|
|
+ private final NewPayService newPayService;
|
|
|
+ private final UserService userService;
|
|
|
+
|
|
|
+ @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;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public WechatTransactionsParamVO getPayParams(Long userId, Long orderId) {
|
|
|
+ LoversSetOrderInfo orderInfo = getById(orderId);
|
|
|
+
|
|
|
+ UserEntity userEntity = userService.queryByUserId(userId);
|
|
|
+
|
|
|
+ GetPayParamDTO dto = GetPayParamDTO.builder()
|
|
|
+ .orderNo(orderInfo.getOrderNumber())
|
|
|
+ .orderDesc("情侣套餐:" + orderInfo.getLoversSetName())
|
|
|
+ .amount(orderInfo.getPayAmount().setScale(2, RoundingMode.HALF_UP))
|
|
|
+ .userId(userId)
|
|
|
+ .userThirdId(userEntity.getOpenId())
|
|
|
+ .payChannel(PayChannelEnum.WECHAT_JS_API)
|
|
|
+ .paySceneEnum(PaySceneEnum.LOVERS_SET_ORDER_PAY)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ return newPayService.getWechatTransactionsParamVO(dto);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public void updateOrderAfterPaySuccess(String orderNo) {
|
|
|
+ LoversSetOrderInfo orderInfo = getOne(new LambdaQueryWrapper<LoversSetOrderInfo>()
|
|
|
+ .eq(LoversSetOrderInfo::getOrderNumber, orderNo));
|
|
|
+
|
|
|
+ orderInfo.setPayStatus(Constant.YES);
|
|
|
+ orderInfo.setActiveStatus(Constant.YES);
|
|
|
+ orderInfo.setUpdateTime(LocalDateTime.now());
|
|
|
+ updateById(orderInfo);
|
|
|
+
|
|
|
+ // 新增并保存配送信息
|
|
|
+ saveDeliveryInfo(orderInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveDeliveryInfo(LoversSetOrderInfo orderInfo) {
|
|
|
+ // 生成订单配送信息
|
|
|
+ List<LoversSetOrderDetail> orderDetails = loversSetOrderDetailService.getByOrderId(orderInfo.getId());
|
|
|
+ // 按shopId分组订单详情
|
|
|
+ Map<Long, List<LoversSetOrderDetail>> detailsByShopId = orderDetails.stream()
|
|
|
+ .collect(Collectors.groupingBy(LoversSetOrderDetail::getShopId));
|
|
|
+
|
|
|
+ // 配送起止时间
|
|
|
+ LocalDate startDate = orderInfo.getReceiveStartDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+ LocalDate endDate = orderInfo.getReceiveEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+
|
|
|
+ List<LoversSetOrderDeliveryInfo> deliveryInfoList = IntStream.range(0, (int) ChronoUnit.DAYS.between(startDate, endDate))
|
|
|
+ .mapToObj(i -> startDate.plusDays(i))
|
|
|
+ .flatMap(date -> {
|
|
|
+ LocalDateTime expectReceiveTime = LocalDateTime.parse(
|
|
|
+ date + " " + orderInfo.getExpectReceiveTime(),
|
|
|
+ DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
|
|
+ );
|
|
|
+
|
|
|
+ return detailsByShopId.values().stream()
|
|
|
+ .map(orderDetailList -> {
|
|
|
+ String content = orderDetailList.stream()
|
|
|
+ .map(e -> e.getGoodsName() + "x" + e.getNum())
|
|
|
+ .collect(Collectors.joining(";"));
|
|
|
+
|
|
|
+ return new LoversSetOrderDeliveryInfo() {
|
|
|
+ {
|
|
|
+ setLoversSetOrderId(orderInfo.getId());
|
|
|
+ setDeliveryContent(content);
|
|
|
+ setDeliveryTimeOfExpect(expectReceiveTime);
|
|
|
+ // 1等待生成配送单
|
|
|
+ setDeliveryStatus("1");
|
|
|
+ }
|
|
|
+ };
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 保存配送信息
|
|
|
+ loversSetOrderDeliveryInfoService.saveBatch(deliveryInfoList);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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,请刷新页面重新提交订单");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|