Bläddra i källkod

优惠券处理

igl 3 månader sedan
förälder
incheckning
d4f2371c98
20 ändrade filer med 530 tillägg och 72 borttagningar
  1. 5 0
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/constant/PlatformConstant.java
  2. 18 0
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/dto/OrderPriceGroupDTO.java
  3. 133 6
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/dto/UserCouponDTO.java
  4. 2 2
      vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/param/OmsOrderModifyParam.java
  5. 1 1
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/GoodsAssessMapper.java
  6. 4 3
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/UserCouponMapper.java
  7. 2 1
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/OmsOrderItem.java
  8. 39 3
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/UserCoupon.java
  9. 12 1
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/BalanceDetailService.java
  10. 2 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/GoodsService.java
  11. 2 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OmsOrderService.java
  12. 2 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OrderHandleService.java
  13. 9 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/UserCouponService.java
  14. 15 8
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/AssessServiceImpl.java
  15. 12 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/BalanceDetailServiceImpl.java
  16. 6 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/GoodsServiceImpl.java
  17. 23 0
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OderHandleServiceImpl.java
  18. 137 16
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OmsOrderServiceImpl.java
  19. 58 21
      vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/UserCouponServiceImpl.java
  20. 48 10
      vehicle-server/src/main/resources/mapper/UserCouponMapper.xml

+ 5 - 0
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/constant/PlatformConstant.java

@@ -17,6 +17,11 @@ public interface PlatformConstant {
      */
     static Integer DEFAULT_USER_RATIO = 10;
 
+    /**
+     * 平台订单返利比例
+     */
+    static Integer ORDER_COUPON_RATIO = 20;
+
     /**
      * 异常提示
      */

+ 18 - 0
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/dto/OrderPriceGroupDTO.java

@@ -0,0 +1,18 @@
+package com.chelvc.cloud.vehicle.client.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class OrderPriceGroupDTO {
+
+    private Long merchantId;
+
+    private BigDecimal amount;
+
+    public OrderPriceGroupDTO(Long merchantId, BigDecimal amount){
+        this.merchantId = merchantId;
+        this.amount = amount;
+    }
+}

+ 133 - 6
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/dto/UserCouponDTO.java

@@ -1,12 +1,17 @@
 package com.chelvc.cloud.vehicle.client.dto;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.chelvc.cloud.vehicle.client.constant.CouponType;
+import com.chelvc.cloud.vehicle.client.constant.UserCouponStatus;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.SuperBuilder;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * 优惠卷领取记录
@@ -22,32 +27,154 @@ public class UserCouponDTO implements Serializable {
     /**
      * 主键
      */
+    @TableId(type = IdType.AUTO)
     private Long id;
 
     /**
-     * 用户id
+     * 用户ID
      */
-	private Long userId;
+    private Long userId;
 
     /**
-     * 优惠券id
+     * 优惠券ID
      */
-	private Long couponId;
+    private Long couponId;
 
     /**
      * 优惠券类型
      */
     private CouponType type;
 
+    /**
+     * 商户ID
+     */
+    private Long merchantId;
+
+    /**
+     * 优惠金额/折扣
+     */
+    private BigDecimal amount;
+
+    /**
+     * 门槛金额
+     */
+    private BigDecimal doorsillAmount;
+
     /**
      * 是否已使用
      */
     private Integer used;
 
     /**
-     * 优惠券
+     * 开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 核销时间
+     */
+    private Date consumptionTime;
+
+    /**
+     * 截止时间
+     */
+    private Date endTime;
+
+    /**
+     * 标识:0-新消息;1-已查看
+     */
+    private Integer flag;
+
+    /**
+     * 是否是平台优惠券
      */
-	private CouponDTO couponDTO;
+    private Integer platformFlag;
+
+    /**
+     * 优惠券描述
+     */
+    private String description;
+
+    /**
+     * 用户优惠券状态
+     */
+    private UserCouponStatus status;
+//    /**
+//     * 主键
+//     */
+//    @TableId(type = IdType.AUTO)
+//    private Long id;
+//
+//    /**
+//     * 用户ID
+//     */
+//    private Long userId;
+//
+//    /**
+//     * 优惠券ID
+//     */
+//    private Long couponId;
+//
+//    /**
+//     * 优惠券类型
+//     */
+//    private CouponType type;
+//
+//    /**
+//     * 商户ID
+//     */
+//    private Long merchantId;
+//
+//    /**
+//     * 优惠金额/折扣
+//     */
+//    private BigDecimal amount;
+//
+//    /**
+//     * 门槛金额
+//     */
+//    private BigDecimal doorsillAmount;
+//
+//    /**
+//     * 是否已使用
+//     */
+//    private Integer used;
+//
+//    /**
+//     * 开始时间
+//     */
+//    private Date startTime;
+//
+//    /**
+//     * 核销时间
+//     */
+//    private Date consumptionTime;
+//
+//    /**
+//     * 截止时间
+//     */
+//    private Date endTime;
+//
+//    /**
+//     * 标识:0-新消息;1-已查看
+//     */
+//    private Integer flag;
+//
+//    /**
+//     * 是否是平台优惠券
+//     */
+//    private Integer platformFlag;
+//
+//    /**
+//     * 用户优惠券状态
+//     */
+//    private UserCouponStatus status;
+//
+//    /**
+//     * 优惠券描述
+//     */
+//    private String description;
+
     /**
      * 是否显示
      */

+ 2 - 2
vehicle-client/src/main/java/com/chelvc/cloud/vehicle/client/param/OmsOrderModifyParam.java

@@ -25,9 +25,9 @@ public class OmsOrderModifyParam implements Serializable
      */
     private Long userReceiveAddressId;
     /**
-     * 优惠券ID
+     * 用户优惠券ID
      */
-    private Long couponId;
+    private Long userCouponId;
     /**
      * 使用的积分数
      */

+ 1 - 1
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/GoodsAssessMapper.java

@@ -41,7 +41,7 @@ public interface GoodsAssessMapper extends BaseMapper<GoodsAssess> {
     BigDecimal getGoodsAvgScore(Long goodsId);
 
     @Update("update oms_order set comment_status = 'Y' where id = #{orderId}")
-    void updatePersonalAssessStatus(@Param("orderId") Long orderId);
+    int updatePersonalAssessStatus(@Param("orderId") Long orderId);
 
     @Select("select * from employee where id = #{id}")
     EmployeeDTO queryEmployeeInfo(@Param("id") Long id);

+ 4 - 3
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/UserCouponMapper.java

@@ -1,6 +1,7 @@
 package com.chelvc.cloud.vehicle.server.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.chelvc.cloud.vehicle.client.dto.UserCouponDTO;
 import com.chelvc.cloud.vehicle.client.param.UserCouponQueryParam;
 import com.chelvc.cloud.vehicle.server.entity.UserCoupon;
 import org.apache.ibatis.annotations.Mapper;
@@ -23,7 +24,7 @@ public interface UserCouponMapper extends BaseMapper<UserCoupon> {
      * @param param 查询参数
      * @return 用户优惠券信息列表
      */
-    List<UserCoupon> listExpiredUserCoupons(@Param("userId") Long userId, @Param("param") UserCouponQueryParam param);
+    List<UserCouponDTO> listExpiredUserCoupons(@Param("userId") Long userId, @Param("param") UserCouponQueryParam param);
 
     /**
      * 查询用户优惠券
@@ -31,7 +32,7 @@ public interface UserCouponMapper extends BaseMapper<UserCoupon> {
      * @param param 查询参数
      * @return 用户优惠券信息列表
      */
-    List<UserCoupon> listUserCoupons(@Param("userId") Long userId, @Param("param") UserCouponQueryParam param);
+    List<UserCouponDTO> listUserCoupons(@Param("userId") Long userId, @Param("param") UserCouponQueryParam param);
 
     /**
      * 获取当前用户对于当前商品可使用的优惠券列表
@@ -39,5 +40,5 @@ public interface UserCouponMapper extends BaseMapper<UserCoupon> {
      * @param param 查询参数
      * @return 用户可用优惠券信息列表
      */
-    List<UserCoupon> listUserCanUseCoupons(@Param("userId") Long userId, @Param("param") UserCouponQueryParam param);
+    List<UserCouponDTO> listUserCanUseCoupons(@Param("userId") Long userId, @Param("param") UserCouponQueryParam param);
 }

+ 2 - 1
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/OmsOrderItem.java

@@ -16,7 +16,7 @@ import lombok.experimental.SuperBuilder;
 
 /**
  * 订单中所包含的商品对象 oms_order_item
- * 
+ *
  * @author liude
  * @date 2023-11-08
  */
@@ -94,4 +94,5 @@ public class OmsOrderItem extends ModifyEntity<Long> implements Serializable
 
     private String goodsAttr;
 
+    private Long merchantId;
 }

+ 39 - 3
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/UserCoupon.java

@@ -14,6 +14,8 @@ import lombok.ToString;
 import lombok.experimental.SuperBuilder;
 
 import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * 优惠券领取数据模型
@@ -49,22 +51,56 @@ public class UserCoupon extends ModifyEntity<Long> {
      */
     private CouponType type;
 
+    /**
+     * 商户ID
+     */
+    private Long merchantId;
+
+    /**
+     * 优惠金额/折扣
+     */
+    private BigDecimal amount;
+
+    /**
+     * 门槛金额
+     */
+    private BigDecimal doorsillAmount;
+
     /**
      * 是否已使用
      */
     private Integer used;
 
     /**
-     * 优惠券
+     * 开始时间
      */
-    @TableField(exist = false)
-    private Coupon coupon;
+    private Date startTime;
+
+    /**
+     * 核销时间
+     */
+    private Date consumptionTime;
+
+    /**
+     * 截止时间
+     */
+    private Date endTime;
 
     /**
      * 标识:0-新消息;1-已查看
      */
     private Integer flag;
 
+    /**
+     * 是否是平台优惠券
+     */
+    private Integer platformFlag;
+
+    /**
+     * 优惠券描述
+     */
+    private String description;
+
     /**
      * 用户优惠券状态
      */

+ 12 - 1
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/BalanceDetailService.java

@@ -2,6 +2,7 @@ package com.chelvc.cloud.vehicle.server.service;
 
 import com.chelvc.cloud.vehicle.client.dto.*;
 import com.chelvc.cloud.vehicle.client.param.QueryMerchantBalanceParam;
+import com.chelvc.cloud.vehicle.server.entity.BalanceDetail;
 import com.chelvc.framework.common.model.Pagination;
 import org.apache.ibatis.annotations.Param;
 
@@ -19,7 +20,7 @@ public interface BalanceDetailService {
      * @param realityAmount 实际金额
      * @param surplusAmount 当前余额
      * @param flowType 流水类型:0-收入;1-支出
-     * @param operateType 操作类型:0-商品出售;1-用户分佣;2-商户分佣;3-平台分佣;4-提现;5-用户支付;6-用户核销;7-转账;8-退款
+     * @param operateType 操作类型:0-商品出售;1-用户分佣;2-商户分佣;3-平台分佣;4-提现;5-用户支付;6-用户核销;7-转账;8-退款;9-平台优惠券补贴
      * @param sourceId 来源id
      */
     void recordFlow(Long orderId, Integer type,  Long userId, BigDecimal operateAmount, BigDecimal deduct,
@@ -42,4 +43,14 @@ public interface BalanceDetailService {
      * @return
      */
     EarningsDTO getBalanceRecord(Integer type);
+
+    /**
+     *
+     * @param orderId 订单id
+     * @param type 类型:0-平台;1-用户;2-商户
+     * @param userId 用户id
+     * @param flowType 流水类型:0-收入;1-支出
+     * @param operateType 操作类型:0-商品出售;1-用户分佣;2-商户分佣;3-平台分佣;4-提现;5-用户支付;6-用户核销;7-转账;8-退款;9-平台优惠券补贴
+     */
+    BalanceDetail queryBy(Long orderId, Integer type, Long userId, Integer flowType, Integer operateType);
 }

+ 2 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/GoodsService.java

@@ -98,4 +98,6 @@ public interface GoodsService extends IService<Goods> {
      * @return
      */
     List<Map<String,Object>> getGoodsAmount();
+
+    Long queryMerchantIdByGoodId(Long goodsId);
 }

+ 2 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OmsOrderService.java

@@ -150,4 +150,6 @@ public interface OmsOrderService extends EnhanceService<OmsOrder>
     void orderRefund(@RequestBody OrderRefundParam param);
 
     void orderRefundNotify(SxyNotifyParam param);
+
+    OmsOrder queryCheckOrder(Long orderId, Long id);
 }

+ 2 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/OrderHandleService.java

@@ -2,6 +2,8 @@ package com.chelvc.cloud.vehicle.server.service;
 
 import com.chelvc.cloud.vehicle.server.entity.OmsOrder;
 
+import java.math.BigDecimal;
+
 public interface OrderHandleService {
 
     void orderPay(Long orderId);

+ 9 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/UserCouponService.java

@@ -118,4 +118,13 @@ public interface UserCouponService extends IService<UserCoupon> {
      * @return 优惠券领取记录主键
      */
     Long claimCoupon(Long couponId);
+
+    /**
+     * 赠送平台订单返利优惠券
+     * @param platformAmount
+     * @param userId
+     */
+    void sendPlatformOrderCoupon(BigDecimal platformAmount, Long userId);
+
+    UserCoupon checkUseCoupon(Long userCouponId, Long userId);
 }

+ 15 - 8
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/AssessServiceImpl.java

@@ -23,13 +23,8 @@ import com.chelvc.cloud.vehicle.server.copier.GoodsAssessCopier;
 import com.chelvc.cloud.vehicle.server.dao.AssessRecoverMapper;
 import com.chelvc.cloud.vehicle.server.dao.AssessScoreMapper;
 import com.chelvc.cloud.vehicle.server.dao.GoodsAssessMapper;
-import com.chelvc.cloud.vehicle.server.entity.AssessRecover;
-import com.chelvc.cloud.vehicle.server.entity.AssessScore;
-import com.chelvc.cloud.vehicle.server.entity.Goods;
-import com.chelvc.cloud.vehicle.server.entity.GoodsAssess;
-import com.chelvc.cloud.vehicle.server.entity.OmsOrderItem;
-import com.chelvc.cloud.vehicle.server.service.AssessService;
-import com.chelvc.cloud.vehicle.server.service.OmsOrderItemService;
+import com.chelvc.cloud.vehicle.server.entity.*;
+import com.chelvc.cloud.vehicle.server.service.*;
 import com.chelvc.framework.base.context.Session;
 import com.chelvc.framework.base.context.SessionContextHolder;
 import com.chelvc.framework.common.model.Pagination;
@@ -65,6 +60,9 @@ public class AssessServiceImpl extends ServiceImpl<GoodsAssessMapper, GoodsAsses
     private final AssessRecoverMapper assessRecoverMapper;
     private final AssessScoreMapper assessScoreMapper;
     private final OmsOrderItemService omsOrderItemService;
+    private final UserCouponService userCouponService;
+    private final OmsOrderService orderService;
+    private final BalanceDetailService balanceDetailService;
 
     @Override
     public Long add(AssessModifyParam param) {
@@ -85,7 +83,16 @@ public class AssessServiceImpl extends ServiceImpl<GoodsAssessMapper, GoodsAsses
              }
          }
         this.saveBatch(goodsAssessList,goodsAssessList.size());
-        baseMapper.updatePersonalAssessStatus(param.getOrderId());
+        int i = baseMapper.updatePersonalAssessStatus(param.getOrderId());
+        OmsOrder omsOrder = orderService.queryCheckOrder(param.getOrderId(), user.getId());
+        if(omsOrder != null && i == 1){
+            //赠送优惠券
+            BalanceDetail balanceDetail = balanceDetailService.queryBy(omsOrder.getId(), 0, 0L, 0, 2);
+            if(balanceDetail != null){
+                BigDecimal realityAmount = balanceDetail.getRealityAmount();
+                userCouponService.sendPlatformOrderCoupon(realityAmount, omsOrder.getUserId());
+            }
+        }
         return param.getOrderId();
     }
 

+ 12 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/BalanceDetailServiceImpl.java

@@ -1,5 +1,6 @@
 package com.chelvc.cloud.vehicle.server.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -125,6 +126,17 @@ public class BalanceDetailServiceImpl extends ServiceImpl<BalanceDetailMapper, B
         return balanceRecord;
     }
 
+    @Override
+    public BalanceDetail queryBy(Long orderId, Integer type, Long userId, Integer flowType, Integer operateType) {
+        LambdaQueryWrapper<BalanceDetail> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(BalanceDetail::getOrderId, orderId);
+        wrapper.eq(BalanceDetail::getTargetId, userId);
+        wrapper.eq(BalanceDetail::getFlowType, flowType);
+        wrapper.eq(BalanceDetail::getType, type);
+        wrapper.eq(BalanceDetail::getOperateType, operateType);
+        return baseMapper.selectOne(wrapper);
+    }
+
     public QueryWrapper<BalanceDetail> queryWrapper(QueryMerchantBalanceParam param, Long merchantId, Integer type) {
         QueryWrapper<BalanceDetail> lqw = Wrappers.query();
         lqw.eq("t1.type", type);

+ 6 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/GoodsServiceImpl.java

@@ -198,4 +198,10 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
             return this.baseMapper.getGoodsAmount(merchants.get(0));
         }
     }
+
+    @Override
+    public Long queryMerchantIdByGoodId(Long goodsId) {
+        Goods goods = baseMapper.selectById(goodsId);
+        return goods == null ? null : goods.getMerchantId();
+    }
 }

+ 23 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OderHandleServiceImpl.java

@@ -3,6 +3,7 @@ package com.chelvc.cloud.vehicle.server.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.chelvc.cloud.vehicle.client.constant.PlatformConstant;
+import com.chelvc.cloud.vehicle.client.dto.UserCouponDTO;
 import com.chelvc.cloud.vehicle.server.dao.OmsOrderMapper;
 import com.chelvc.cloud.vehicle.server.entity.MerchantRelation;
 import com.chelvc.cloud.vehicle.server.entity.OmsOrder;
@@ -39,6 +40,7 @@ public class OderHandleServiceImpl implements OrderHandleService {
     private final BalanceDetailService balanceDetailService;
     private final OmsOrderOperateHistoryService omsOrderOperateHistoryService;
     private final MerchantRelationService merchantRelationService;
+    private final UserCouponService userCouponService;
 
     @Override
     public void orderPay(Long orderId) {
@@ -88,6 +90,27 @@ public class OderHandleServiceImpl implements OrderHandleService {
         BigDecimal userAmount = BigDecimal.ZERO;
         BigDecimal merchantAmount = BigDecimal.ZERO;
         BigDecimal operate = payAmount.subtract(omsOrder.getFeeAmount());
+        //计算优惠券
+        Long couponId = omsOrder.getCouponId();
+        UserCouponDTO userCoupon = userCouponService.getUserCoupon(couponId);
+        if(userCoupon != null){
+            Long couponMerchantId = userCoupon.getMerchantId();
+            if(couponMerchantId == 0L){
+                //平台补贴给商家
+                BigDecimal couponAmount = omsOrder.getCouponAmount();
+                //给商家转账
+                assetService.transfer(0L, merchantId, 2, couponAmount, "平台优惠券补贴");
+                //更新平台资产
+                BigDecimal platformTotal = assetService.updateAsset(1, couponAmount, 0L, 0, 1);
+                //记录平台余额明细
+                balanceDetailService.recordFlow(omsOrder.getId(), 0, 0L, couponAmount, BigDecimal.ZERO,
+                        couponAmount, platformTotal, 1, 9, merchantId);
+                BigDecimal surplusAmount = assetService.updateAsset(0, couponAmount, merchantId, 2, 1);
+                //商家记录余额明细
+                balanceDetailService.recordFlow(orderId, 2, merchantId, couponAmount, BigDecimal.ZERO,
+                        couponAmount, surplusAmount, 0, 9, 0L);
+            }
+        }
         //平台金额扣除商品金额
         BigDecimal bigDecimal = assetService.updateAsset(1, operate, 0L, 0, 1);
         balanceDetailService.recordFlow(orderId, 0, 0L, operate, BigDecimal.ZERO,

+ 137 - 16
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/OmsOrderServiceImpl.java

@@ -1,6 +1,7 @@
 package com.chelvc.cloud.vehicle.server.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -8,7 +9,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.chelvc.cloud.user.client.UserClient;
 import com.chelvc.cloud.user.client.dto.UserDTO;
 import com.chelvc.cloud.user.client.model.Scope;
+import com.chelvc.cloud.vehicle.client.constant.CouponType;
 import com.chelvc.cloud.vehicle.client.constant.ReserveStatus;
+import com.chelvc.cloud.vehicle.client.constant.UserCouponStatus;
 import com.chelvc.cloud.vehicle.client.dto.*;
 import com.chelvc.cloud.vehicle.client.param.OmsOrderModifyParam;
 import com.chelvc.cloud.vehicle.client.param.OrderPagingParam;
@@ -51,6 +54,8 @@ import java.security.SecureRandom;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
 
 /**
  * 订单Service业务层处理
@@ -78,6 +83,8 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
     private final BalanceDetailService balanceDetailService;
     private final OmsOrderRefundService orderRefundService;
 
+    private final GoodsService goodsService;
+
     // 定义字符池
     private static final String LOWER_CASE = "abcdefghijklmnopqrstuvwxyz";
     private static final String UPPER_CASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
@@ -138,6 +145,8 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
 //            orderItem.setPromotionName(cartPromotionItem.getPromotionMessage());
             orderItem.setGiftIntegration(0L);
             orderItem.setGiftGrowth(0);
+            Long merchantId = goodsService.queryMerchantIdByGoodId(orderItem.getGoodsId());
+            orderItem.setMerchantId(merchantId);
             orderItemList.add(orderItem);
         }else{
             cartPromotionItemList = omsCartItemService.listPromotion(orderParam.getCartIds());
@@ -159,6 +168,7 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
 //            orderItem.setPromotionName(cartPromotionItem.getPromotionMessage());
                 orderItem.setGiftIntegration(0L);
                 orderItem.setGiftGrowth(0);
+                orderItem.setMerchantId(cartPromotionItem.getMerchantId());
                 orderItemList.add(orderItem);
             }
         }
@@ -167,20 +177,20 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
 //            Asserts.fail("库存不足,无法下单");
 //        }
         //判断使用使用了优惠券
-        if (orderParam.getCouponId() == null) {
+        boolean flag = false;
+        if (orderParam.getUserCouponId() == null) {
             //不用优惠券
             for (OmsOrderItem orderItem : orderItemList) {
                 orderItem.setCouponAmount(new BigDecimal(0));
             }
         } else {
-            //使用优惠券
-//            UserCouponDTO userCouponDTO = getUseCoupon(cartPromotionItemList, orderParam.getCouponId());
-//            if (userCouponDTO == null) {
-//                Asserts.check(true, "该优惠券不可用");
-//            }
-//            //对下单商品的优惠券进行处理
-//            assert userCouponDTO != null;
-//            handleCouponAmount(orderItemList, userCouponDTO);
+            UserCoupon coupon = userCouponService.checkUseCoupon(orderParam.getUserCouponId(), userId);
+            if (coupon == null) {
+                Asserts.check(true, "该优惠券不可用");
+            }
+            //对下单商品的优惠券进行处理
+            assert coupon != null;
+            flag = handleCouponAmount(orderItemList, coupon);
         }
         //判断是否使用积分
         if (orderParam.getUseIntegration() == null || orderParam.getUseIntegration().equals(0)) {
@@ -216,10 +226,10 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
         order.setFreightAmount(new BigDecimal(0));
         order.setPromotionAmount(calcPromotionAmount(orderItemList));
         order.setPromotionInfo(getOrderPromotionInfo(orderItemList));
-        if (orderParam.getCouponId() == null) {
+        if (orderParam.getUserCouponId() == null || !flag) {
             order.setCouponAmount(new BigDecimal(0));
         } else {
-            order.setCouponId(orderParam.getCouponId());
+            order.setCouponId(orderParam.getUserCouponId());
             order.setCouponAmount(calcCouponAmount(orderItemList));
         }
         if (orderParam.getUseIntegration() == null) {
@@ -283,8 +293,8 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
         omsOrderItemService.add(orderItemList);
         omsOrderOperateHistoryService.insertOmsOrderOperateHistory(order.getId(), userId, order.getStatus());
         //如使用优惠券更新优惠券使用状态
-        if (orderParam.getCouponId() != null) {
-            updateCouponStatus(orderParam.getCouponId(), userId, 1);
+        if (orderParam.getUserCouponId() != null && flag) {
+            updateCouponStatus(orderParam.getUserCouponId(), userId, 1);
         }
         //如使用积分需要扣除积分
 //        if (orderParam.getUseIntegration() != null) {
@@ -630,6 +640,8 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
             return;
         }
         example.setUsed(useStatus);
+        example.setStatus(UserCouponStatus.USED);
+        example.setConsumptionTime(new Date());
         this.userCouponService.updateUserCouponUserd(example, couponId, userId);
     }
 
@@ -753,13 +765,19 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
 //        return integrationAmount;
 //    }
 
+    /**
+     * 对优惠券优惠进行处理
+     *
+     * @param orderItemList order_item列表
+     * @param userCoupon 可用优惠券详情
+     */
     /**
      * 对优惠券优惠进行处理
      *
      * @param orderItemList order_item列表
      * @param userCouponDTO 可用优惠券详情
      */
-    private void handleCouponAmount(List<OmsOrderItem> orderItemList, UserCouponDTO userCouponDTO) {
+    /*private void handleCouponAmount(List<OmsOrderItem> orderItemList, CouponDTO userCouponDTO) {
         if (userCouponDTO.getType().equals(0)) {
             //全场通用
             calcPerCouponAmount(orderItemList, userCouponDTO.getCouponDTO());
@@ -772,6 +790,101 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
             List<OmsOrderItem> couponOrderItemList = getCouponOrderItemByRelation(userCouponDTO, orderItemList, 1);
             calcPerCouponAmount(couponOrderItemList, userCouponDTO.getCouponDTO());
         }
+    }*/
+
+    /**
+     * 对优惠券优惠进行处理
+     *
+     * @param orderItemList order_item列表
+     * @param userCoupon 可用优惠券详情
+     */
+    private boolean handleCouponAmount(List<OmsOrderItem> orderItemList, UserCoupon userCoupon) {
+        boolean flag = false; //是否使用优惠券
+        BigDecimal amount = userCoupon.getAmount();
+        BigDecimal doorsillAmount = userCoupon.getDoorsillAmount();
+        Long merchantId = userCoupon.getMerchantId();
+        BigDecimal totalAmount = calcTotalAmount(orderItemList);
+        if (CouponType.GIVE.equals(userCoupon.getType())) {
+            //全场通用
+            for (OmsOrderItem orderItem : orderItemList) {
+                if(merchantId == 0L){
+                    if(totalAmount.compareTo(amount) > 0){
+                        orderItem.setCouponAmount(amount);
+                        return true;
+                    }
+                    break;
+                } else if(merchantId.equals(orderItem.getMerchantId())){
+                    Map<Long, BigDecimal> map = handle(orderItemList);
+                    BigDecimal merchantAmount = map.get(merchantId);
+                    if(merchantAmount.compareTo(amount) > 0){
+                        orderItem.setCouponAmount(amount);
+                        return true;
+                    } else if(merchantAmount.compareTo(amount) <= 0 && totalAmount.compareTo(amount) > 0){
+                        orderItem.setCouponAmount(merchantAmount);
+                        return true;
+                    }
+                    break;
+                }
+            }
+        } else if (CouponType.REDUCE.equals(userCoupon.getType())) {
+            //满减
+            for (OmsOrderItem orderItem : orderItemList) {
+                if(merchantId == 0L){
+                    if(totalAmount.compareTo(amount) <= 0){
+                        break;
+                    }
+                    if(totalAmount.compareTo(doorsillAmount) <= 0){
+                        break;
+                    }
+                    orderItem.setCouponAmount(amount);
+                    return true;
+                } else if(merchantId.equals(orderItem.getMerchantId())){
+                    Map<Long, BigDecimal> map = handle(orderItemList);
+                    BigDecimal merchantAmount = map.get(merchantId);
+                    if(merchantAmount.compareTo(doorsillAmount) <= 0){
+                        break;
+                    }
+                    if(merchantAmount.compareTo(amount) > 0){
+                        orderItem.setCouponAmount(amount);
+                    } else if(merchantAmount.compareTo(amount) <= 0 && totalAmount.compareTo(amount) > 0){
+                        orderItem.setCouponAmount(merchantAmount);
+                    } else {
+                        break;
+                    }
+                    return true;
+                }
+            }
+        } else if (CouponType.DISCOUNT.equals(userCoupon.getType())) {
+            //折扣
+            if(amount.compareTo(BigDecimal.ZERO) <= 0 || amount.compareTo(BigDecimal.TEN) >= 0){
+                return flag;
+            }
+            for (OmsOrderItem orderItem : orderItemList) {
+                if(merchantId == 0L){
+                    BigDecimal multiply = totalAmount.multiply(amount.divide(BigDecimal.TEN, 2, RoundingMode.UP));
+                    orderItem.setCouponAmount(totalAmount.subtract(multiply));
+                    return true;
+                } else if(merchantId.equals(orderItem.getMerchantId())){
+                    Map<Long, BigDecimal> map = handle(orderItemList);
+                    BigDecimal merchantAmount = map.get(merchantId);
+                    BigDecimal multiply = merchantAmount.multiply(amount.divide(BigDecimal.TEN, 2, RoundingMode.UP));
+                    orderItem.setCouponAmount(merchantAmount.subtract(multiply));
+                    return true;
+                }
+            }
+        }
+        return flag;
+    }
+
+    public Map<Long, BigDecimal> handle(List<OmsOrderItem> orderItemList){
+        List<OrderPriceGroupDTO> list = orderItemList.stream()
+                .map(e -> new OrderPriceGroupDTO(e.getMerchantId(),
+                        e.getGoodsPrice().multiply(new BigDecimal(e.getGoodsQuantity()))))
+                .collect(Collectors.toList());
+        return list.stream()
+                .collect(Collectors.groupingBy(OrderPriceGroupDTO::getMerchantId,
+                        Collectors.reducing(BigDecimal.ZERO, OrderPriceGroupDTO::getAmount,
+                                BigDecimal::add)));
     }
 
     /**
@@ -779,12 +892,12 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
      *
      * @param orderItemList 可用优惠券的下单商品商品
      */
-    private void calcPerCouponAmount(List<OmsOrderItem> orderItemList, CouponDTO coupon) {
+    private void calcPerCouponAmount(List<OmsOrderItem> orderItemList, UserCoupon coupon) {
         BigDecimal totalAmount = calcTotalAmount(orderItemList);
         for (OmsOrderItem orderItem : orderItemList) {
             //(商品价格/可用商品总价)*优惠券面额
             BigDecimal couponAmount =
-                    orderItem.getGoodsPrice().divide(totalAmount, 3, RoundingMode.HALF_EVEN).multiply(BigDecimal.valueOf(coupon.getAmount()));
+                    orderItem.getGoodsPrice().divide(totalAmount, 3, RoundingMode.HALF_EVEN).multiply(coupon.getAmount());
             orderItem.setCouponAmount(couponAmount);
         }
     }
@@ -1136,6 +1249,14 @@ public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> i
         });
     }
 
+    @Override
+    public OmsOrder queryCheckOrder(Long orderId, Long userId) {
+        LambdaQueryWrapper<OmsOrder> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(OmsOrder::getId, orderId);
+        wrapper.eq(OmsOrder::getUserId, userId);
+        return baseMapper.selectOne(wrapper);
+    }
+
     private int updateStatusById(Long id, Integer status) {
         UpdateWrapper<OmsOrder> update = Wrappers.update();
         update.set("status", status);

+ 58 - 21
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/UserCouponServiceImpl.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.chelvc.cloud.vehicle.client.constant.CouponClaimType;
 import com.chelvc.cloud.vehicle.client.constant.CouponType;
+import com.chelvc.cloud.vehicle.client.constant.PlatformConstant;
 import com.chelvc.cloud.vehicle.client.constant.UserCouponStatus;
 import com.chelvc.cloud.vehicle.client.dto.UserCouponDTO;
 import com.chelvc.cloud.vehicle.client.param.UserCouponModifyParam;
@@ -25,6 +26,7 @@ import com.chelvc.framework.common.exception.ResourceUnavailableException;
 import com.chelvc.framework.common.model.Pagination;
 import com.chelvc.framework.common.model.Paging;
 import com.chelvc.framework.common.util.AssertUtils;
+import com.chelvc.framework.common.util.DateUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.database.context.DatabaseContextHolder;
 import lombok.NonNull;
@@ -34,6 +36,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -54,24 +57,10 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
         Long userId = SessionContextHolder.getId();
         // 查询过期的优惠券
         if (UserCouponStatus.EXPIRED.equals(param.getStatus())) {
-            List<UserCoupon> userCoupons = this.baseMapper.listExpiredUserCoupons(userId, param);
-            if (CollectionUtils.isEmpty(userCoupons)) {
-                return Collections.emptyList();
-            }
-            return userCoupons
-                    .stream()
-                    .map(o -> UserCouponCopier.INSTANCE.copying(o, o.getCoupon()))
-                    .collect(Collectors.toList());
+            return this.baseMapper.listExpiredUserCoupons(userId, param);
         }
         // 查询未使用或已使用的优惠券
-        List<UserCoupon> userCoupons = this.baseMapper.listUserCoupons(userId, param);
-        if (CollectionUtils.isEmpty(userCoupons)) {
-            return Collections.emptyList();
-        }
-        return userCoupons
-                .stream()
-                .map(o -> UserCouponCopier.INSTANCE.copying(o, o.getCoupon()))
-                .collect(Collectors.toList());
+        return this.baseMapper.listUserCoupons(userId, param);
     }
 
     @Override
@@ -81,14 +70,15 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
         param.setMerchantIds(merchantIds);
         Long userId = SessionContextHolder.getId();
         // 当前用户对于当前商品可使用的优惠券列表
-        List<UserCoupon> userCoupons = this.baseMapper.listUserCanUseCoupons(userId, param);
+        return this.baseMapper.listUserCanUseCoupons(userId, param);
+        /*List<UserCoupon> userCoupons = this.baseMapper.listUserCanUseCoupons(userId, param);
         if (CollectionUtils.isEmpty(userCoupons)) {
             return Collections.emptyList();
         }
         return userCoupons
                 .stream()
                 .map(o -> UserCouponCopier.INSTANCE.copying(o, o.getCoupon()))
-                .collect(Collectors.toList());
+                .collect(Collectors.toList());*/
     }
 
     @Override
@@ -147,6 +137,54 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
         return userCoupon.getId();
     }
 
+    @Override
+    public void sendPlatformOrderCoupon(BigDecimal platformAmount, Long userId) {
+        if(platformAmount.compareTo(BigDecimal.ONE) < 0){
+            return;
+        }
+        BigDecimal amount = platformAmount
+                .multiply(new BigDecimal(PlatformConstant.ORDER_COUPON_RATIO)
+                        .divide(new BigDecimal("100"), 2, RoundingMode.UP))
+                .setScale(0, RoundingMode.DOWN);
+        if(amount.compareTo(BigDecimal.ZERO) < 1){
+            return;
+        }
+        UserCoupon userCoupon = new UserCoupon();
+        userCoupon.setUserId(userId);
+        userCoupon.setCouponId(0L);
+        userCoupon.setAmount(amount);
+        userCoupon.setDoorsillAmount(BigDecimal.ZERO);
+        userCoupon.setDescription("订单返利");
+        userCoupon.setType(CouponType.GIVE);
+        userCoupon.setFlag(0);
+        userCoupon.setPlatformFlag(0);
+        userCoupon.setStatus(UserCouponStatus.UNUSED);
+        userCoupon.setUsed(0);
+        userCoupon.setMerchantId(0L);
+        baseMapper.insert(userCoupon);
+    }
+
+    @Override
+    public UserCoupon checkUseCoupon(Long userCouponId, Long userId) {
+        LambdaQueryWrapper<UserCoupon> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(UserCoupon::getId, userCouponId);
+        wrapper.eq(UserCoupon::getUserId, userId);
+        wrapper.eq(UserCoupon::getUsed, 0);
+        wrapper.eq(UserCoupon::getStatus, UserCouponStatus.UNUSED);
+        UserCoupon userCoupon = baseMapper.selectOne(wrapper);
+        if(userCoupon == null){
+            return null;
+        }
+        Date endTime = userCoupon.getEndTime();
+        if(endTime != null && new Date().after(endTime)){
+            userCoupon.setStatus(UserCouponStatus.EXPIRED);
+            userCoupon.setUpdateTime(new Date());
+            baseMapper.updateById(userCoupon);
+            return null;
+        }
+        return userCoupon;
+    }
+
     @Override
     public Integer queryNewInformNum(Long userId) {
         LambdaQueryWrapper<UserCoupon> lwq = Wrappers.lambdaQuery();
@@ -238,9 +276,8 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
         List<UserCouponDTO> userCouponList = UserCouponCopier.INSTANCE.copying(baseMapper.selectList(lwq));
         if (userCouponList != null && userCouponList.size() > 0) {
             userCouponList.forEach(item -> {
-                item.setCouponDTO(CouponCopier.INSTANCE.copying(this.couponService.getById(item.getCouponId())));
-                if (CouponType.REDUCE.equals(item.getCouponDTO().getType())) {
-                    int comparison = amount.compareTo(new BigDecimal(item.getCouponDTO().getConsumeThreshold()));
+                if (CouponType.REDUCE.equals(item.getType())) {
+                    int comparison = amount.compareTo(item.getDoorsillAmount());
                     if (comparison == 0) {
                         item.setDisplay(true);
                     } else if (comparison < 0) {

+ 48 - 10
vehicle-server/src/main/resources/mapper/UserCouponMapper.xml

@@ -24,7 +24,19 @@
         </association>
     </resultMap>
 
-    <select id="listExpiredUserCoupons" resultMap="USERCOUPON_RESULT_MAP">
+    <select id="listExpiredUserCoupons" resultMap="com.chelvc.cloud.vehicle.client.dto.UserCouponDTO">
+        select *
+        from user_coupon u
+        where u.user_id = #{userId}
+        <if test="param.offset != null">
+            and u.id > #{param.offset}
+        </if>
+        and u.type = #{param.type}
+        and u.used = 0 and u.end_time > now()
+        order by u.create_time desc
+        limit #{param.size}
+    </select>
+    <!--<select id="listExpiredUserCoupons" resultMap="USERCOUPON_RESULT_MAP">
         select u.id,u.coupon_id,c.name,c.amount,c.reduce,c.discount,c.description,c.expiration,
         c.merchant_id
         from user_coupon u
@@ -37,24 +49,50 @@
         and u.used = 0 and c.expiration is not null and CURRENT_TIME > c.expiration
         order by u.create_time desc
         limit #{param.size}
-    </select>
+    </select>-->
 
-    <select id="listUserCoupons" resultMap="USERCOUPON_RESULT_MAP">
+    <select id="listUserCoupons" resultMap="com.chelvc.cloud.vehicle.client.dto.UserCouponDTO">
+        select *
+        from user_coupon u
+        where u.user_id = #{userId}
+        and u.type = #{param.type}
+        and u.used = #{param.status}
+        order by u.create_time desc
+        limit #{param.size}
+    </select>
+<!--    <select id="listUserCoupons" resultMap="USERCOUPON_RESULT_MAP">
         select u.id,u.coupon_id,c.name,c.amount,c.reduce,c.discount,c.description,c.expiration,
         c.merchant_id
         from user_coupon u
         inner join coupon c on u.coupon_id = c.id
         where u.user_id = #{userId}
-<!--        <if test="param.offset != null">-->
-<!--            and u.id > #{param.offset}-->
-<!--        </if>-->
+&lt;!&ndash;        <if test="param.offset != null">&ndash;&gt;
+&lt;!&ndash;            and u.id > #{param.offset}&ndash;&gt;
+&lt;!&ndash;        </if>&ndash;&gt;
         and u.type = #{param.type}
         and u.used = #{param.status}
         order by u.create_time desc
         limit #{param.size}
-    </select>
+    </select>-->
 
-    <select id="listUserCanUseCoupons" resultMap="USERCOUPON_RESULT_MAP">
+    <select id="listUserCanUseCoupons" resultMap="com.chelvc.cloud.vehicle.client.dto.UserCouponDTO">
+        select *
+        from `user_coupon` ucn
+        <where>
+            ucn.used = 0
+            and cn.merchant_id in
+            <foreach collection="merchantIds" item="id" open="(" close=")" separator=",">
+                #{id}
+            </foreach>
+            and ucn.end_time > now()
+            <if test="param.offset != null">
+                and ucn.id > #{param.offset}
+            </if>
+        </where>
+        order by ucn.create_time desc
+        limit #{param.size}
+    </select>
+    <!--<select id="listUserCanUseCoupons" resultMap="USERCOUPON_RESULT_MAP">
         select ucn.id, ucn.coupon_id, cn.name, cn.amount, cn.reduce, cn.discount, cn.description,cn.expiration,
         cn.merchant_id
         from `user_coupon` ucn
@@ -74,6 +112,6 @@
         </where>
         order by ucn.create_time desc
         limit #{param.size}
-    </select>
+    </select>-->
 
-</mapper>
+</mapper>