From 04473738b72db53bd2b102bd1ab4616a2874600b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9D=BE?= <8605635+zhang3064194730@user.noreply.gitee.com> Date: Thu, 28 Nov 2024 13:57:21 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=80=80=E6=AC=BE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PayController.java | 21 +- .../dao/TbActivateInRecordMapper.java | 6 + .../dao/TbActivateOutRecordMapper.java | 6 + .../cashierservice/entity/TbMemberPoints.java | 72 +++ .../entity/TbMemberPointsLog.java | 70 +++ .../cashierservice/entity/TbOrderDetail.java | 5 + .../cashierservice/entity/TbOrderInfo.java | 7 + .../entity/dto/OrderInfoCouponInfoDTO.java | 14 + .../entity/dto/OrderInfoUserCouponVo.java | 11 + .../entity/dto/ReturnOrderDTO.java | 32 ++ .../entity/vo/TbUserCouponVo.java | 43 ++ .../mapper/MpProductStockDetailMapper.java | 7 + .../mapper/TbMemberPointsLogMapper.java | 16 + .../mapper/TbMemberPointsMapper.java | 16 + .../mybatis/MpShopUserMapper.java | 3 + .../rabbit/RabbitConstants.java | 8 + .../service/MpOrderDetailService.java | 10 + .../service/MpOrderInfoService.java | 4 + .../cashierservice/service/OrderService.java | 23 + .../cashierservice/service/PayService.java | 428 +++++++++++++++++- .../service/TbMemberPointsService.java | 30 ++ .../service/TbShopCouponService.java | 24 + .../impl/MpOrderDetailServiceImpl.java | 12 + .../service/impl/MpOrderInfoServiceImpl.java | 51 +++ .../impl/TbMemberPointsServiceImpl.java | 94 ++++ .../service/impl/TbShopCouponServiceImpl.java | 53 +++ .../cashierservice/util/RabbitMsgUtils.java | 7 + 27 files changed, 1044 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPoints.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPointsLog.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoCouponInfoDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoUserCouponVo.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/ReturnOrderDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/TbUserCouponVo.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/mapper/MpProductStockDetailMapper.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsLogMapper.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsMapper.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/TbMemberPointsService.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/TbShopCouponService.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbMemberPointsServiceImpl.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbShopCouponServiceImpl.java diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/controller/PayController.java b/src/main/java/com/chaozhanggui/system/cashierservice/controller/PayController.java index d7ece6c..87c7fa0 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/controller/PayController.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/controller/PayController.java @@ -16,6 +16,7 @@ import com.chaozhanggui.system.cashierservice.entity.TbOrderDetail; import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo; import com.chaozhanggui.system.cashierservice.entity.TbShopInfo; import com.chaozhanggui.system.cashierservice.entity.dto.ReturnGroupOrderDto; +import com.chaozhanggui.system.cashierservice.entity.dto.ReturnOrderDTO; import com.chaozhanggui.system.cashierservice.entity.dto.VipPayDTO; import com.chaozhanggui.system.cashierservice.model.PaymentReq; import com.chaozhanggui.system.cashierservice.service.PayService; @@ -34,10 +35,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.time.LocalDate; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; @CrossOrigin(origins = "*") @RestController @@ -247,7 +245,20 @@ public class PayController { @RequestBody List list, @RequestParam("pwd") String pwd, @RequestParam(defaultValue = "true") boolean isOnline) { - return payService.returnOrder(list, token, pwd, isOnline); + ReturnOrderDTO returnOrderDTO = new ReturnOrderDTO(); + returnOrderDTO.setOrderId(list.get(0).getOrderId()); + returnOrderDTO.setNote(list.get(0).getRemark()); + returnOrderDTO.setPwd(pwd); + ArrayList orderDetails = new ArrayList<>(); + list.forEach(item -> { + ReturnOrderDTO.OrderDetail orderDetail = new ReturnOrderDTO.OrderDetail(); + orderDetail.setId(item.getId()); + orderDetail.setNum(item.getNum()); + orderDetails.add(orderDetail); + }); + returnOrderDTO.setOrderDetails(orderDetails); + returnOrderDTO.setIsOnline(isOnline); + return Result.success(CodeEnum.SUCCESS, payService.returnOrder(returnOrderDTO)); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateInRecordMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateInRecordMapper.java index 945b156..b700813 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateInRecordMapper.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateInRecordMapper.java @@ -2,6 +2,7 @@ package com.chaozhanggui.system.cashierservice.dao; import com.chaozhanggui.system.cashierservice.entity.TbActivateInRecord; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; import org.springframework.data.domain.Pageable; import java.util.List; @@ -64,5 +65,10 @@ public interface TbActivateInRecordMapper { */ int deleteById(Integer id); + + @Update("update tb_activate_in_record" + + " set over_num = #{overNum}" + + " where id = #{id}") + int updateOverNum(@Param("id") Integer id, @Param("overNum") Integer overNum); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateOutRecordMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateOutRecordMapper.java index 82baf85..f595382 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateOutRecordMapper.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/dao/TbActivateOutRecordMapper.java @@ -2,6 +2,7 @@ package com.chaozhanggui.system.cashierservice.dao; import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; import org.springframework.data.domain.Pageable; import java.util.List; @@ -64,5 +65,10 @@ public interface TbActivateOutRecordMapper { */ int deleteById(Integer id); + + @Update("update tb_activate_out_record" + + " set ref_num = ref_num + #{refNum}" + + " where id = #{id}") + int updateRefNum(@Param("id") Integer id, @Param("refNum") Integer refNum); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPoints.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPoints.java new file mode 100644 index 0000000..74006ef --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPoints.java @@ -0,0 +1,72 @@ +package com.chaozhanggui.system.cashierservice.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 会员积分 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 2.0 2024-10-25 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("tb_shop_user") +public class TbMemberPoints { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 店铺id + */ + private Long shopId; + /** + * 会员id + */ + @TableField(value = "id", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER) + private Long memberId; + /** + * 会员名称 + */ + @TableField("name") + private String memberName; + /** + * 会员头像 + */ + @TableField("head_img") + private String avatarUrl; + /** + * 手机号码 + */ + @TableField("telephone") + private String mobile; + /** + * 账户积分 + */ + @TableField("account_points") + private Integer accountPoints; + /** + * 最近一次积分变动时间 + */ + @TableField("last_points_change_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date lastPointsChangeTime; + /** + * 最近一次浮动积分 + */ + @TableField("last_float_points") + private Integer lastFloatPoints; + /** + * 是否会员 1-是 0-否 + */ + @TableField("is_vip") + private Integer vip; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPointsLog.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPointsLog.java new file mode 100644 index 0000000..42c3612 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbMemberPointsLog.java @@ -0,0 +1,70 @@ +package com.chaozhanggui.system.cashierservice.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 会员积分变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 2.0 2024-10-25 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("tb_member_points_log") +public class TbMemberPointsLog { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 店铺id + */ + private Long shopId; + /** + * 会员id + */ + private Long memberId; + /** + * 会员名称 + */ + private String memberName; + /** + * 会员头像 + */ + private String avatarUrl; + /** + * 摘要信息(如:兑换某个商品/消费多少钱/充值多少钱/新会员赠送积分等) + */ + private String content; + /** + * 订单编号 + */ + private String orderNo; + /** + * 手机号码 + */ + private String mobile; + /** + * 浮动类型 add-累加 subtract-扣减 + */ + private String floatType; + /** + * 浮动积分(非0正负数) + */ + private Integer floatPoints; + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderDetail.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderDetail.java index 6b91d47..f109164 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderDetail.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderDetail.java @@ -53,5 +53,10 @@ public class TbOrderDetail implements Serializable { private Integer isMember; private Integer isTemporary; private Integer isThirdCoupon; + private Integer userCouponId; + private String useCouponInfo; + private BigDecimal canReturnAmount; + private BigDecimal returnAmount; + } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderInfo.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderInfo.java index afdf294..ffbf016 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderInfo.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbOrderInfo.java @@ -117,6 +117,11 @@ public class TbOrderInfo implements Serializable { private static final long serialVersionUID = 1L; private int isPostpaid; + private String couponInfoList; + private BigDecimal fullCouponDiscountAmount; + private BigDecimal pointsDiscountAmount; + private String refundRemark; + private Integer pointsNum; public TbOrderInfo(){ super(); @@ -181,4 +186,6 @@ public class TbOrderInfo implements Serializable { this.payType=payType; this.tableName=tableName; } + + } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoCouponInfoDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoCouponInfoDTO.java new file mode 100644 index 0000000..b961219 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoCouponInfoDTO.java @@ -0,0 +1,14 @@ +package com.chaozhanggui.system.cashierservice.entity.dto; + +import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord; +import lombok.Data; + +import java.util.Collection; +import java.util.List; + +@Data +public class OrderInfoCouponInfoDTO { + private List outRecordList; + private Collection fullReductionCoupon; + private Collection productCoupon; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoUserCouponVo.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoUserCouponVo.java new file mode 100644 index 0000000..c99a42e --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/OrderInfoUserCouponVo.java @@ -0,0 +1,11 @@ +package com.chaozhanggui.system.cashierservice.entity.dto; + +import com.chaozhanggui.system.cashierservice.entity.vo.TbUserCouponVo; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class OrderInfoUserCouponVo extends TbUserCouponVo { + private int returnNum = 0; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/ReturnOrderDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/ReturnOrderDTO.java new file mode 100644 index 0000000..47c8842 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/ReturnOrderDTO.java @@ -0,0 +1,32 @@ +package com.chaozhanggui.system.cashierservice.entity.dto; + +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.List; + +@Data +public class ReturnOrderDTO { + + @Data + public static class OrderDetail{ + @NotNull + private Integer id; + @NotNull + @Min(1) + private BigDecimal num; + } + @NotNull + private Integer orderId; + @NotEmpty + private String note; +// @NotEmpty + private String pwd; + @Valid + private List orderDetails; + private Boolean isOnline; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/TbUserCouponVo.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/TbUserCouponVo.java new file mode 100644 index 0000000..430e3ae --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/TbUserCouponVo.java @@ -0,0 +1,43 @@ +package com.chaozhanggui.system.cashierservice.entity.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class TbUserCouponVo { + private Integer id; + private BigDecimal fullAmount; + private BigDecimal discountAmount; + private Integer couponId; + private Integer proId; + // 商品名称 + private String productName; + private String productCover; + //优惠券名称 + private String name; + + //优惠券类型 1 满减 2 商品券 + private Integer type; + //数量 + private Integer num; + //到期时间 + private Date endTime; + private Long expireTime; + private String useRestrictions; + private boolean isUse = false; + //当前使用数量 + private BigDecimal currentUseNum; + private Integer finalUseNum; + private BigDecimal finalDiscountAmount = new BigDecimal(0); + + + public void setEndTime(Date endTime) { + this.endTime = endTime; + if(endTime!=null){ + expireTime=endTime.getTime(); + } + } + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/MpProductStockDetailMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/MpProductStockDetailMapper.java new file mode 100644 index 0000000..8482811 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/MpProductStockDetailMapper.java @@ -0,0 +1,7 @@ +package com.chaozhanggui.system.cashierservice.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.chaozhanggui.system.cashierservice.entity.TbProductStockDetail; + +public interface MpProductStockDetailMapper extends BaseMapper { +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsLogMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsLogMapper.java new file mode 100644 index 0000000..201fdb6 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsLogMapper.java @@ -0,0 +1,16 @@ +package com.chaozhanggui.system.cashierservice.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.chaozhanggui.system.cashierservice.entity.TbMemberPointsLog; +import org.apache.ibatis.annotations.Mapper; + +/** + * 会员积分变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 2.0 2024-10-25 + */ +@Mapper +public interface TbMemberPointsLogMapper extends BaseMapper { + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsMapper.java new file mode 100644 index 0000000..7b24d5c --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbMemberPointsMapper.java @@ -0,0 +1,16 @@ +package com.chaozhanggui.system.cashierservice.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.chaozhanggui.system.cashierservice.entity.TbMemberPoints; +import org.apache.ibatis.annotations.Mapper; + +/** + * 会员积分 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 2.0 2024-10-25 + */ +@Mapper +public interface TbMemberPointsMapper extends BaseMapper { + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mybatis/MpShopUserMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mybatis/MpShopUserMapper.java index 8ae5f05..2b6e9bb 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/mybatis/MpShopUserMapper.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mybatis/MpShopUserMapper.java @@ -10,4 +10,7 @@ import java.math.BigDecimal; public interface MpShopUserMapper extends BaseMapper { @Update("update tb_shop_user set amount=amount-#{orderAmount}, consume_amount=consume_amount+#{orderAmount} where id=#{vipUserId} and amount-#{orderAmount} >= 0") long decrBalance(@Param("vipUserId") Integer vipUserId, @Param("orderAmount") BigDecimal orderAmount); + + @Update("update tb_shop_user set amount=amount+#{returnAmount}, consume_amount=consume_amount-#{returnAmount}, updated_at=#{current} where id=#{userId}") + void incrBalance(@Param("userId") Integer userId, @Param("shopId") Integer shopId, @Param("returnAmount") BigDecimal returnAmount, @Param("current") long current); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/rabbit/RabbitConstants.java b/src/main/java/com/chaozhanggui/system/cashierservice/rabbit/RabbitConstants.java index 9b792b8..db1e8a5 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/rabbit/RabbitConstants.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/rabbit/RabbitConstants.java @@ -70,4 +70,12 @@ public interface RabbitConstants { // 排号打印 String QUEUE_PRINT_CALL_TABLE = "queue.print.call.table"; String ROUTING_KEY_CALL_TABLE = "routing.call.table"; + // 会员余额记录 + String EXCHANGE_BALANCE = "balance_put"; + String ROUTING_KEY_BALANCE = "balance_routingkey_put"; + + + // 耗材 + String EXCHANGE_CONS = "cons_collect_put"; + String ROUTING_KEY_CONS = "cons_collect_routingkey_put"; } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderDetailService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderDetailService.java index 7a0113a..9910a74 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderDetailService.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderDetailService.java @@ -49,5 +49,15 @@ public interface MpOrderDetailService extends IService { boolean updateFieldByCartId(SFunction field, Object val, List cartIds); + + /** + * 根据orderId和id修改detail状态 + * @param oldOrderStatusEnums 原始订单状态 + * @param orderStatusEnums 状态 + * @param orderId 订单id + * @param orderDetails detailIds + * @return 影响数量 + */ + boolean updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status oldOrderStatusEnums, TableConstant.OrderInfo.Status orderStatusEnums, Integer orderId, List orderDetails); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderInfoService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderInfoService.java index bc11665..519a76f 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderInfoService.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/MpOrderInfoService.java @@ -27,5 +27,9 @@ public interface MpOrderInfoService extends IService { boolean incrAmount(Integer orderId, BigDecimal subtract); + /** + * 储值卡退款 + */ + void depositReturn(Integer userId, Integer shopId, BigDecimal returnAmount); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/OrderService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/OrderService.java index 1ecb37c..06accc0 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/service/OrderService.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/OrderService.java @@ -44,6 +44,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -1051,6 +1052,7 @@ public class OrderService { orderDetail.setPackAmount(BigDecimal.ZERO); } } + updateOrderDetailCanReturn(orderDetails, orderInfo); mpOrderDetailService.saveOrUpdateBatch(orderDetails); // 删除已经移除购物车的商品 @@ -1111,6 +1113,27 @@ public class OrderService { return Result.success(CodeEnum.SUCCESS, orderInfo); } + private void updateOrderDetailCanReturn(List orderDetailList, TbOrderInfo orderInfo) { + orderDetailList = orderDetailList.stream().filter(item -> TableConstant.OrderInfo.Status.UNPAID.equalsVals(item.getStatus())).collect(Collectors.toList()); + BigDecimal totalAmount = BigDecimal.ZERO; + BigDecimal lastAmount = BigDecimal.ZERO; + BigDecimal lastReturnAmount = BigDecimal.ZERO; + BigDecimal orderAmount = orderInfo.getOrderAmount(); + for (TbOrderDetail orderDetail : orderDetailList) { + totalAmount = totalAmount.add(orderDetail.getPriceAmount()); + } + for (TbOrderDetail item : orderDetailList) { + if (StrUtil.isNotBlank(orderInfo.getCouponInfoList()) || orderInfo.getPointsNum() != null) { + BigDecimal canReturnAmount = item.getPriceAmount().divide(totalAmount.subtract(lastAmount), 10, RoundingMode.HALF_DOWN) + .multiply(orderAmount.subtract(lastReturnAmount)).setScale(2, RoundingMode.HALF_DOWN); + lastReturnAmount = canReturnAmount; + lastAmount = item.getPriceAmount(); + item.setCanReturnAmount(canReturnAmount); + } else { + item.setCanReturnAmount(item.getPriceAmount()); + } + } + } /** * 获取当前台桌当前下单次数 diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/PayService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/PayService.java index 181aa24..489a943 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/service/PayService.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/PayService.java @@ -1,5 +1,6 @@ package com.chaozhanggui.system.cashierservice.service; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.ObjectUtil; @@ -14,17 +15,18 @@ import com.chaozhanggui.system.cashierservice.bean.TableStateEnum; import com.chaozhanggui.system.cashierservice.bean.constant.TableConstant; import com.chaozhanggui.system.cashierservice.dao.*; import com.chaozhanggui.system.cashierservice.entity.*; +import com.chaozhanggui.system.cashierservice.entity.dto.OrderInfoCouponInfoDTO; import com.chaozhanggui.system.cashierservice.entity.dto.ReturnGroupOrderDto; +import com.chaozhanggui.system.cashierservice.entity.dto.ReturnOrderDTO; import com.chaozhanggui.system.cashierservice.entity.po.OrderDetailPo; import com.chaozhanggui.system.cashierservice.exception.MsgException; import com.chaozhanggui.system.cashierservice.exception.NotPrintException; +import com.chaozhanggui.system.cashierservice.mapper.MpProductStockDetailMapper; +import com.chaozhanggui.system.cashierservice.mapper.MpShopUnitMapper; import com.chaozhanggui.system.cashierservice.model.ReturnOrderReq; import com.chaozhanggui.system.cashierservice.model.ScanPayReq; import com.chaozhanggui.system.cashierservice.model.TradeQueryReq; -import com.chaozhanggui.system.cashierservice.mybatis.MPOrderDetailMapper; -import com.chaozhanggui.system.cashierservice.mybatis.MpShopTableMapper; -import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserFlowMapper; -import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserMapper; +import com.chaozhanggui.system.cashierservice.mybatis.*; import com.chaozhanggui.system.cashierservice.rabbit.RabbitProducer; import com.chaozhanggui.system.cashierservice.sign.CodeEnum; import com.chaozhanggui.system.cashierservice.sign.Result; @@ -55,6 +57,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static com.chaozhanggui.system.cashierservice.sign.CodeEnum.ACCOUNTEIXST; import static com.chaozhanggui.system.cashierservice.sign.CodeEnum.SUCCESS; @@ -137,13 +140,29 @@ public class PayService { private PlatformTransactionManager transactionManager; private final MpCashierCartService mpCashierCartService; + private final TbShopCouponService shopCouponService; + private final MpOrderDetailService mpOrderDetailService; + private final MpShopUnitMapper mpShopUnitMapper; + private final MpProductStockDetailMapper mpProductStockDetailMapper; + private final MpOrderInfoService mpOrderInfoService; + private final TbMemberPointsService memberPointsService; + + private final Utils utils; + @Autowired + private MPOrderInfoMapper mPOrderInfoMapper; - public PayService(RedisTemplate redisTemplate, MpCashierCartService mpCashierCartService, Utils utils) { + public PayService(RedisTemplate redisTemplate, MpCashierCartService mpCashierCartService, TbShopCouponService shopCouponService, MpOrderDetailService mpOrderDetailService, MpShopUnitMapper mpShopUnitMapper, MpProductStockDetailMapper mpProductStockDetailMapper, MpOrderInfoService mpOrderInfoService, Utils utils) { this.redisTemplate = redisTemplate; this.mpCashierCartService = mpCashierCartService; + this.shopCouponService = shopCouponService; + this.mpOrderDetailService = mpOrderDetailService; + this.mpShopUnitMapper = mpShopUnitMapper; + this.mpProductStockDetailMapper = mpProductStockDetailMapper; + this.mpOrderInfoService = mpOrderInfoService; this.utils = utils; + memberPointsService = null; } public static void main(String[] args) { @@ -151,7 +170,7 @@ public class PayService { } public Result queryPayType(String shopId) { - return Result.success(CodeEnum.SUCCESS, tbShopPayTypeMapper.selectByShopId(shopId)); + return Result.success(SUCCESS, tbShopPayTypeMapper.selectByShopId(shopId)); } private void clearTableInfoCache(TbOrderInfo orderInfo) { @@ -355,7 +374,7 @@ public class PayService { redisUtil.del(tableCartKey); clearTableInfoCache(orderInfo); - return Result.success(CodeEnum.SUCCESS, object.getJSONObject("data")); + return Result.success(SUCCESS, object.getJSONObject("data")); } else { String status = ObjectUtil.isNotEmpty(object.getJSONObject("data")) ? object.getJSONObject("data").getString("status") : null; if (ObjectUtil.isNotNull(status) && "7".equals(status)) { @@ -558,7 +577,7 @@ public class PayService { } } - return Result.success(CodeEnum.SUCCESS, orderInfo); + return Result.success(SUCCESS, orderInfo); } @@ -719,7 +738,7 @@ public class PayService { redisUtil.del(tableCartKey); clearTableInfoCache(orderInfo); - return Result.success(CodeEnum.SUCCESS); + return Result.success(SUCCESS); } @Transactional(rollbackFor = Exception.class) @@ -853,7 +872,7 @@ public class PayService { producer.balance(baObj.toString()); clearTableInfoCache(orderInfo); - return Result.success(CodeEnum.SUCCESS); + return Result.success(SUCCESS); } public Result vipPay(Integer orderId, String token, Integer vipUserId, BigDecimal payAmount, BigDecimal discountAmount) { @@ -963,7 +982,7 @@ public class PayService { redisUtil.del(tableCartKey); clearTableInfoCache(orderInfo); - return Result.success(CodeEnum.SUCCESS); + return Result.success(SUCCESS); } @@ -1058,7 +1077,7 @@ public class PayService { redisUtil.del(tableCartKey); clearTableInfoCache(orderInfo); - return Result.success(CodeEnum.SUCCESS); + return Result.success(SUCCESS); } @Transactional(rollbackFor = Exception.class) @@ -1146,7 +1165,368 @@ public class PayService { clearTableInfoCache(orderInfo); - return Result.success(CodeEnum.SUCCESS); + return Result.success(SUCCESS); + } + + private HashMap updateReturnOrderInfo(ReturnOrderDTO returnOrderDTO, TbOrderInfo oldOrderInfo, boolean isOnline) { + String couponInfoList = oldOrderInfo.getCouponInfoList(); + OrderInfoCouponInfoDTO couponInfoDTO = null; + if (StrUtil.isNotBlank(couponInfoList)) { + couponInfoDTO = JSONObject.parseObject(couponInfoList, OrderInfoCouponInfoDTO.class); + } + ArrayList detailIds = new ArrayList<>(); + HashMap returnNumMap = new HashMap<>(); + returnOrderDTO.getOrderDetails().forEach(item -> { + detailIds.add(item.getId()); + returnNumMap.put(item.getId().toString(), item.getNum()); + }); + List detailList = mPOrderDetailMapper.selectList(new LambdaQueryWrapper() +// .eq(TbOrderDetail::getShopId, returnOrderDTO.getShopId()) + .eq(TbOrderDetail::getStatus, "closed") + .eq(TbOrderDetail::getOrderId, returnOrderDTO.getOrderId()) + .in(TbOrderDetail::getId, detailIds) + .orderByDesc(TbOrderDetail::getUserCouponId)); + if (detailList.size() != returnOrderDTO.getOrderDetails().size()) { + throw new MsgException("订单明细数量不一致"); + } + + HashMap data = new HashMap<>(); + BigDecimal returnAmount = BigDecimal.ZERO; + BigDecimal packAMount = BigDecimal.ZERO; + BigDecimal saleAmount = BigDecimal.ZERO; + ArrayList remainOrderDetailList = new ArrayList<>(); + boolean hasNormalReturn = false; + for (TbOrderDetail orderDetail : detailList) { + // 原始金额 + BigDecimal originalAmount = orderDetail.getPriceAmount(); + BigDecimal originalPackAmount = orderDetail.getPackAmount(); + // 退款数量 + BigDecimal returnNum = returnNumMap.get(orderDetail.getId().toString()); + // 剩余数量 + BigDecimal remainNum = orderDetail.getNum().subtract(returnNum); + if (remainNum.compareTo(BigDecimal.ZERO) < 0) { + throw new MsgException(StrUtil.format("{}最多可退数量为: {}", orderDetail.getProductName(), orderDetail.getNum())); + } + + // 将未退款的剩余订单详情重新生成记录 + BigDecimal packFee = orderDetail.getPackAmount().divide(orderDetail.getNum(), RoundingMode.HALF_UP); + BigDecimal returnPackFee = packFee.multiply(returnNum); + BigDecimal currentDetailAMount = BigDecimal.ZERO; + // 优惠券抵扣商品直接退券 + if (StrUtil.isNotBlank(orderDetail.getUseCouponInfo())) { + data.put("isCouponDiscount", true); + TbActivateOutRecord outRecord = JSONObject.parseObject(orderDetail.getUseCouponInfo(), TbActivateOutRecord.class); + outRecord.setRefNum(returnNum.intValue()); + shopCouponService.refund(CollUtil.newArrayList(outRecord)); + currentDetailAMount = returnNum.multiply(orderDetail.getPrice()) + .add(returnPackFee); + // 移除使用的券 + couponInfoDTO.getProductCoupon().forEach(item -> { + if (Objects.equals(item.getId(), outRecord.getGiveId())) { + item.setReturnNum(item.getReturnNum() + outRecord.getRefNum()); + } + }); + + // 使用了满减或积分,获取普通付款商品计算退款比例,退部分现金 + } else if (oldOrderInfo.getFullCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0 || oldOrderInfo.getPointsDiscountAmount().compareTo(BigDecimal.ZERO) > 0) { + hasNormalReturn = true; + // 计算当前商品占比 + returnAmount = calcDetailReturnAmount(orderDetail, returnNum); + currentDetailAMount = orderDetail.getPriceAmount().divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP) + .multiply(returnNum).setScale(2, RoundingMode.HALF_DOWN); + if (oldOrderInfo.getRefundAmount() == null) { + oldOrderInfo.setRefundAmount(BigDecimal.ZERO); + } + +// if (ratio.compareTo(BigDecimal.ONE) == 0) { +// returnAmount = oldOrderInfo.getPayAmount().subtract(oldOrderInfo.getRefundAmount()); +// }else { +// returnAmount = returnAmount.add(oldOrderInfo.getPayAmount().subtract(oldOrderInfo.getRefundAmount()).multiply(ratio)); +// } + saleAmount = saleAmount.add(orderDetail.getPrice()); + packAMount = packAMount.add(orderDetail.getPackAmount() + .divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP) + .multiply(returnNum)).setScale(2, RoundingMode.HALF_UP); + + } else { + hasNormalReturn = true; + saleAmount = saleAmount.add(orderDetail.getPrice()); + if (remainNum.compareTo(BigDecimal.ZERO) <= 0) { + returnAmount = orderDetail.getPriceAmount(); + packAMount = orderDetail.getPackAmount(); + } else { + currentDetailAMount = orderDetail.getPriceAmount() + .divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP) + .multiply(returnNum).setScale(2, RoundingMode.HALF_UP); + returnAmount = returnAmount.add(currentDetailAMount); + packAMount = packAMount.add(orderDetail.getPackAmount() + .divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP) + .multiply(returnNum)).setScale(2, RoundingMode.HALF_UP); + } + } + returnAmount = returnAmount.setScale(2, RoundingMode.HALF_DOWN); + + if (remainNum.compareTo(BigDecimal.ZERO) > 0) { + // 单个打包费 + TbOrderDetail remainOrderDetail = new TbOrderDetail(); + BeanUtil.copyProperties(remainOrderDetail, orderDetail); + remainOrderDetail.setNum(remainNum); + remainOrderDetail.setPriceAmount(originalAmount.subtract(returnAmount)); + remainOrderDetail.setPackAmount(originalPackAmount.subtract(returnPackFee)); + remainOrderDetail.setReturnNum(BigDecimal.ZERO); + remainOrderDetail.setId(null); + remainOrderDetail.setCanReturnAmount(remainOrderDetail.getCanReturnAmount().subtract(returnAmount)); + remainOrderDetailList.add(remainOrderDetail); + orderDetail.setCanReturnAmount(returnAmount); + } + + orderDetail.setNum(returnNum); + orderDetail.setPriceAmount(currentDetailAMount); + orderDetail.setPackAmount(returnPackFee); + orderDetail.setReturnNum(returnNum); + orderDetail.setReturnAmount(returnAmount); +// orderDetail.setStatus(isOnline ? "refunding" : "refund"); + orderDetail.setStatus("refund"); + } + + if (returnAmount.compareTo(BigDecimal.ZERO) < 0) { + throw new MsgException("退款金额为负数有误"); + } + + if (hasNormalReturn && returnAmount.compareTo(new BigDecimal("0")) <= 0 && oldOrderInfo.getPayAmount().compareTo(BigDecimal.ZERO) != 0) { + throw new MsgException("退款金额必须大于0"); + } + + oldOrderInfo.setCouponInfoList(JSONObject.toJSONString(couponInfoDTO)); + + // 保存剩余未退款的订单详情 + if (!remainOrderDetailList.isEmpty()) { + mpOrderDetailService.saveBatch(remainOrderDetailList); + } + +// TbOrderInfo returnOrder = mpOrderInfoService.selectReturnOrderByOrderId(returnOrderDTO.getOrderId()); + TbOrderInfo returnOrder = new TbOrderInfo(); + String orderNo = generateOrderNumber(); + cn.hutool.core.bean.BeanUtil.copyProperties(oldOrderInfo, returnOrder); + returnOrder.setId(null); + returnOrder.setOrderNo(orderNo); + returnOrder.setRefundAmount(returnAmount); + returnOrder.setOrderType("return"); + returnOrder.setStatus(isOnline ? "refunding" : "refund"); + returnOrder.setUpdatedAt(null); + returnOrder.setSystemTime(DateUtil.date().getTime()); + returnOrder.setCreatedAt(DateUtil.date().getTime()); + returnOrder.setPayOrderNo(null); + returnOrder.setSource(oldOrderInfo.getId()); + returnOrder.setRefundRemark(returnOrderDTO.getNote()); + returnOrder.setOrderAmount(returnAmount); + returnOrder.setAmount(returnAmount); + returnOrder.setSettlementAmount(returnAmount); + returnOrder.setPayAmount(returnAmount); + mPOrderInfoMapper.insert(returnOrder); + + + updateStockAndRecord(detailList); + mpOrderDetailService.updateBatchById(detailList); + data.put("returnOrder", returnOrder); + data.put("returnAmount", returnAmount); + data.put("hasNormalReturn", hasNormalReturn); + return data; + } + + private void updateStockAndRecord(List orderDetailList) { + // 更新商品库存 + for (TbOrderDetail detail : orderDetailList) { + TbProductSku productSku = productSkuMapper.selectByPrimaryKey(detail.getProductSkuId()); + TbProduct product = productMapper.selectByPrimaryKey(detail.getProductId()); + + TbProductStockDetail tbProductStockDetail = new TbProductStockDetail(); + tbProductStockDetail.setCreatedAt(System.currentTimeMillis()); + tbProductStockDetail.setUpdatedAt(System.currentTimeMillis()); + tbProductStockDetail.setShopId(detail.getShopId().toString()); + tbProductStockDetail.setSourcePath("NORMAL"); + tbProductStockDetail.setType("退单"); + tbProductStockDetail.setSubType((byte) 1); + tbProductStockDetail.setRemark("退单: " + detail.getOrderId()); + tbProductStockDetail.setOrderId(String.valueOf(detail.getOrderId())); + + if (ObjectUtil.isNotEmpty(product)) { + TbShopUnit shopUnit = mpShopUnitMapper.selectById(product.getUnitId()); + tbProductStockDetail.setProductName(product.getName()); + tbProductStockDetail.setIsStock(Integer.valueOf(product.getIsStock())); + tbProductStockDetail.setStockSnap(product.getSelectSpec()); + tbProductStockDetail.setUnitName(shopUnit.getName()); + tbProductStockDetail.setProductId(product.getId().toString()); + + productMapper.incrStock(String.valueOf(product.getId()), detail.getNum()); + tbProductStockDetail.setLeftNumber(product.getStockNumber()); + tbProductStockDetail.setStockNumber(detail.getNum().doubleValue()); + + productSkuMapper.decrRealSalesNumber(productSku.getId(), detail.getNum().intValue()); + } + + mpProductStockDetailMapper.insert(tbProductStockDetail); + } + } + + private void returnCoupon(TbOrderInfo orderInfo, boolean resetInfo) { + // 返还优惠券 + if (StrUtil.isNotBlank(orderInfo.getCouponInfoList())) { + OrderInfoCouponInfoDTO couponInfoDTO = JSONObject.parseObject(orderInfo.getCouponInfoList(), OrderInfoCouponInfoDTO.class); + ArrayList couponIds = new ArrayList<>(); + couponInfoDTO.getProductCoupon().forEach(item -> { + if (item.getReturnNum() >= item.getFinalUseNum()) { + couponIds.add(item.getId()); + } + }); + // 券返还 + if (!couponInfoDTO.getOutRecordList().isEmpty()) { + ArrayList finalReturnList = new ArrayList<>(); + couponInfoDTO.getOutRecordList().forEach(item -> { + if (!couponIds.contains(item.getGiveId())) { + item.setRefNum(item.getUseNum()); + finalReturnList.add(item); + } + }); + shopCouponService.refund(finalReturnList); + if (resetInfo) { + couponInfoDTO.setOutRecordList(new ArrayList<>()); + orderInfo.setCouponInfoList(JSONObject.toJSONString(couponInfoDTO)); + } + } + } + + } + + + @Transactional + public Object returnOrder(ReturnOrderDTO returnOrderDTO) { + TbOrderInfo orderInfo = mPOrderInfoMapper.selectOne(new LambdaQueryWrapper() + .eq(TbOrderInfo::getId, returnOrderDTO.getOrderId()) + .in(TbOrderInfo::getStatus, TableConstant.OrderInfo.Status.REFUND.getValue(), + TableConstant.OrderInfo.Status.CLOSED.getValue()) +// .eq(TbOrderInfo::getStatus, "closed") + ); + if (orderInfo == null) { + throw new MsgException("订单不处于可退款状态"); + } + + TbShopInfo shopInfo = tbShopInfoMapper.selectByPrimaryKey(Integer.valueOf(orderInfo.getShopId())); + if (shopInfo == null) { + throw new MsgException("店铺信息不存在"); + } + + if ("1".equals(shopInfo.getIsReturn())) { + // TODO 密码校验 + } + String payType = orderInfo.getPayType(); + HashMap returnInfoData = updateReturnOrderInfo(returnOrderDTO, orderInfo, "scanCode".equals(payType) || "wx_lite".equals(payType)); + TbOrderInfo returnOrderInfo = (TbOrderInfo) returnInfoData.get("returnOrder"); + BigDecimal returnAmount = (BigDecimal) returnInfoData.get("returnAmount"); + boolean hasNormalReturn = (boolean) returnInfoData.get("hasNormalReturn"); + String shopId = orderInfo.getShopId(); + +// // 线上退款 + orderInfo.setRefundAmount(orderInfo.getRefundAmount().add(returnOrderInfo.getRefundAmount())); + orderInfo.setRefundRemark(returnOrderDTO.getNote()); + if (hasNormalReturn && ("scanCode".equals(payType) || "wx_lite".equals(payType))) { + if (returnOrderDTO.getIsOnline() != null && !returnOrderDTO.getIsOnline()) { + mpOrderDetailService.updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status.REFUNDING, TableConstant.OrderInfo.Status.REFUND, + returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList())); + + }else { + TbMerchantThirdApply thirdApply = tbMerchantThirdApplyMapper.selectByPrimaryKey(Integer.valueOf(orderInfo.getMerchantId())); + MsgException.checkNull(thirdApply, "支付参数配置错误"); + + if ("ysk".equals(thirdPayType)) { + ReturnOrderReq req = new ReturnOrderReq(); + req.setAppId(thirdApply.getAppId()); + req.setTimestamp(System.currentTimeMillis()); + req.setOrderNumber(orderInfo.getPayOrderNo()); + req.setAmount(String.format("%.2f", returnOrderInfo.getPayAmount().setScale(2, RoundingMode.DOWN))); + req.setMercRefundNo(orderInfo.getOrderNo()); + req.setRefundReason("退货"); + req.setPayPassword(thirdApply.getPayPassword()); + Map map = BeanUtil.transBean2Map(req); + req.setSign(MD5Util.encrypt(map, thirdApply.getAppToken(), true)); + log.info("merchantOrderReturn req:{}", JSONUtil.toJsonStr(req)); + ResponseEntity response = restTemplate.postForEntity(gateWayUrl.concat("merchantOrder/returnOrder"), req, String.class); + log.info("merchantOrderReturn:{}", response.getBody()); + if (response.getStatusCodeValue() == 200 && ObjectUtil.isNotEmpty(response.getBody())) { + JSONObject object = JSONObject.parseObject(response.getBody()); + if (!object.get("code").equals("0")) { + MsgException.check(true, "退款渠道调用失败"); + } +// newOrderInfo.setPayOrderNo(object.getJSONObject("data").getString("refundOrderNumber")); + } + } else { + + TbOrderPayment payment = tbOrderPaymentMapper.selectByOrderId(String.valueOf(orderInfo.getId())); + PublicResp publicResp = thirdPayService.returnOrder(url, thirdApply.getAppId(), + returnOrderInfo.getOrderNo(), payment.getTradeNumber(), null, "订单退款", + returnOrderInfo.getPayAmount().setScale(2, RoundingMode.DOWN).multiply(new BigDecimal(100)).longValue(), callBack, null, thirdApply.getAppToken()); + + if (ObjectUtil.isNotNull(publicResp) && ObjectUtil.isNotEmpty(publicResp)) { + if ("000000".equals(publicResp.getCode())) { + if (!"SUCCESS".equals(publicResp.getObjData().getState()) && !publicResp.getObjData().getState().equals("ING")) { + MsgException.check(true, "退款渠道调用失败"); + } + } else { + MsgException.check(true, "退款渠道调用失败"); + } + } + + } + returnOrderInfo.setStatus("refund"); + mPOrderInfoMapper.updateById(returnOrderInfo); + } + + // 储值卡支付退款 + } else if ("deposit".equals(payType)) { + mpOrderInfoService.depositReturn(Integer.valueOf(orderInfo.getUserId()), Integer.valueOf(orderInfo.getShopId()), returnAmount); + mpOrderDetailService.updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status.REFUNDING, TableConstant.OrderInfo.Status.REFUND, + returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList())); + } else if ("cash".equals(payType)) { + mpOrderDetailService.updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status.REFUNDING, TableConstant.OrderInfo.Status.REFUND, + returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList())); + } + orderInfo.setStatus(TableConstant.OrderInfo.Status.CLOSED.getValue()); + + // 订单金额全退,退优惠券以及积分 + if (orderInfo.getPayAmount().compareTo(orderInfo.getRefundAmount()) <= 0) { + long count = mpOrderDetailService.count(new LambdaQueryWrapper() + .eq(TbOrderDetail::getOrderId, orderInfo.getId()) + .eq(TbOrderDetail::getStatus, TableConstant.OrderInfo.Status.CLOSED)); + if (count == 0) { + returnCoupon(orderInfo, true); + // 返还积分 + memberPointsService.addPoints(Long.valueOf(orderInfo.getMemberId()), orderInfo.getPointsNum(), + "用户退款订单积分返还: " + orderInfo.getPointsNum() + "积分", Long.valueOf(orderInfo.getId())); + } + } + mPOrderInfoMapper.updateById(orderInfo); + // 打印退款小票 +// producer.printMechine(newOrderInfo.getId().toString()); + producer.printMechine(returnOrderInfo.getId().toString()); + + //修改耗材数据 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("orderId", returnOrderInfo.getId()); + jsonObject1.put("type", "delete"); + rabbitMsgUtils.updateCons(jsonObject1); + return true; + } + + private BigDecimal calcDetailReturnAmount(TbOrderDetail orderDetail, BigDecimal returnNum) { + if (orderDetail.getNum().compareTo(returnNum) == 0) { + return orderDetail.getCanReturnAmount(); + } + if (returnNum.compareTo(BigDecimal.ONE) == 0 && + orderDetail.getNum().compareTo(BigDecimal.ONE) > 0 && + orderDetail.getCanReturnAmount().compareTo(new BigDecimal("0.01")) <= 0) { + throw new MsgException(orderDetail.getProductName() + "总金额为0.01,请选择全部商品数量退回"); + } + return orderDetail.getCanReturnAmount().divide(orderDetail.getNum(), 10, RoundingMode.HALF_DOWN).multiply(returnNum).setScale(2, RoundingMode.HALF_DOWN); } @Transactional(rollbackFor = Exception.class) @@ -1177,7 +1557,7 @@ public class PayService { // // TbmerchantAccount account = tbmerchantAccountMapper.selectByPrimaryKey(Integer.valueOf(accountId)); // if (Objects.isNull(account)) { -// return Result.fail(CodeEnum.ACCOUNTEIXST); +// return Result.fail(ACCOUNTEIXST); // } // if (Objects.isNull(account.getPwd()) || ObjectUtil.isEmpty(account.getPwd())) { // return Result.fail(CodeEnum.PWDNOSET); @@ -1457,7 +1837,7 @@ public class PayService { // redisUtil.del("SHOP:CODE:USER:" + "pc" + ":" + orderInfo.getShopId() + ":" + DateUtils.getDay() + TokenUtil.parseParamFromToken(token).getString("accountId")); // // -// return Result.success(CodeEnum.SUCCESS); +// return Result.success(SUCCESS); return null; } @@ -1488,7 +1868,7 @@ public class PayService { jsonObject.put("amount", tbQuickPay.getAmount()); producer.putOrderCollect(jsonObject.toJSONString()); - return Result.success(CodeEnum.SUCCESS, tbQuickPay); + return Result.success(SUCCESS, tbQuickPay); } else { TbShopInfo tbShopInfo = tbShopInfoMapper.selectByPrimaryKey(Integer.valueOf(shopId)); @@ -1515,7 +1895,7 @@ public class PayService { tbQuickPay.setTradeNo(object.getJSONObject("data").get("orderNumber").toString()); tbQuickPayMapper.insert(tbQuickPay); - return Result.success(CodeEnum.SUCCESS, tbQuickPay); + return Result.success(SUCCESS, tbQuickPay); } String status = ObjectUtil.isNotEmpty(object.getJSONObject("data")) ? object.getJSONObject("data").getString("status") : null; @@ -1540,7 +1920,7 @@ public class PayService { jsonObject.put("type", "quick"); jsonObject.put("amount", tbQuickPay.getAmount()); producer.putOrderCollect(jsonObject.toJSONString()); - return Result.success(CodeEnum.SUCCESS, tbQuickPay); + return Result.success(SUCCESS, tbQuickPay); } if ("TRADE_AWAIT".equals(mainScanResp.getState())) { @@ -1610,7 +1990,7 @@ public class PayService { } } - return Result.success(CodeEnum.SUCCESS, tbQuickPay); + return Result.success(SUCCESS, tbQuickPay); } public Result queryQuickPay(String token, int pageNo, int pageSize) { @@ -1624,7 +2004,7 @@ public class PayService { List list = tbQuickPayMapper.selectByShopIdAndStaffId(Integer.valueOf(shopId), Integer.valueOf(staffId)); PageInfo pageInfo = new PageInfo(list); - return Result.success(CodeEnum.SUCCESS, pageInfo); + return Result.success(SUCCESS, pageInfo); } @@ -1710,7 +2090,7 @@ public class PayService { groupOrderInfo.setStatus("refund"); } tbGroupOrderInfoMapper.update(groupOrderInfo); - return Result.success(CodeEnum.SUCCESS); + return Result.success(SUCCESS); } public Result getOrderDiscount(String staffId, String orderId, String token) { @@ -1869,7 +2249,7 @@ public class PayService { ObjectMapper mapper = new ObjectMapper(); - return Result.success(CodeEnum.SUCCESS, mapper.readTree(scanpayResp.getPayInfo())); + return Result.success(SUCCESS, mapper.readTree(scanpayResp.getPayInfo())); } else if ("TRADE_AWAIT".equals(scanpayResp.getState())) { payment.setTradeNumber(scanpayResp.getPayOrderId()); @@ -2028,7 +2408,7 @@ public class PayService { ObjectMapper mapper = new ObjectMapper(); - return Result.success(CodeEnum.SUCCESS, mapper.readTree(scanpayResp.getPayInfo())); + return Result.success(SUCCESS, mapper.readTree(scanpayResp.getPayInfo())); } else if ("TRADE_AWAIT".equals(scanpayResp.getState())) { payment.setTradeNumber(scanpayResp.getPayOrderId()); @@ -2099,7 +2479,7 @@ public class PayService { } } - return Result.success(CodeEnum.SUCCESS, orderInfo); + return Result.success(SUCCESS, orderInfo); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/TbMemberPointsService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbMemberPointsService.java new file mode 100644 index 0000000..f425e8f --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbMemberPointsService.java @@ -0,0 +1,30 @@ +package com.chaozhanggui.system.cashierservice.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.chaozhanggui.system.cashierservice.entity.TbMemberPoints; + +import java.math.BigDecimal; +import java.util.Map; + +/** + * 会员积分 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 2.0 2024-10-25 + */ +public interface TbMemberPointsService extends IService { + + + /** + * 追加积分 + * + * @param memberId 会员id + * @param points 积分 + * @param content 摘要信息(如:兑换积分商品/积分抵扣账单/消费赠送积分/新会员送积分/储值赠送积分) + * @param orderId 订单id,可以为空 + * @throws Exception + */ + boolean addPoints(Long memberId, int points, String content, Long orderId); + + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/TbShopCouponService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbShopCouponService.java new file mode 100644 index 0000000..157803f --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbShopCouponService.java @@ -0,0 +1,24 @@ +package com.chaozhanggui.system.cashierservice.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord; +import com.chaozhanggui.system.cashierservice.entity.TbShopCoupon; +import org.springframework.http.ResponseEntity; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 优惠券(TbShopCoupon)表服务接口 + * + * @author ww + * @since 2024-10-22 15:43:25 + */ +public interface TbShopCouponService { + + boolean refund(List param); + +} + diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderDetailServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderDetailServiceImpl.java index 7476e39..2510fd6 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderDetailServiceImpl.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderDetailServiceImpl.java @@ -70,5 +70,17 @@ public class MpOrderDetailServiceImpl extends ServiceImpl orderDetails) { + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper() + .eq(TbOrderDetail::getOrderId, orderId) + .in(TbOrderDetail::getId, orderDetails) + .set(TbOrderDetail::getStatus, orderStatusEnums.getValue()); + if (oldOrderStatusEnums != null) { + wrapper.eq(TbOrderDetail::getStatus, oldOrderStatusEnums.getValue()); + } + return update(wrapper); + } } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderInfoServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderInfoServiceImpl.java index 9db8098..4c6c6c1 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderInfoServiceImpl.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/MpOrderInfoServiceImpl.java @@ -1,16 +1,25 @@ package com.chaozhanggui.system.cashierservice.service.impl; import cn.hutool.Hutool; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.chaozhanggui.system.cashierservice.bean.constant.TableConstant; import com.chaozhanggui.system.cashierservice.entity.TbOrderDetail; import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo; +import com.chaozhanggui.system.cashierservice.entity.TbShopUser; +import com.chaozhanggui.system.cashierservice.entity.TbShopUserFlow; +import com.chaozhanggui.system.cashierservice.exception.MsgException; import com.chaozhanggui.system.cashierservice.mybatis.MPOrderDetailMapper; import com.chaozhanggui.system.cashierservice.mybatis.MPOrderInfoMapper; +import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserFlowMapper; +import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserMapper; import com.chaozhanggui.system.cashierservice.service.MpOrderDetailService; import com.chaozhanggui.system.cashierservice.service.MpOrderInfoService; +import com.chaozhanggui.system.cashierservice.util.RabbitMsgUtils; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -25,6 +34,16 @@ import java.util.List; @Service public class MpOrderInfoServiceImpl extends ServiceImpl implements MpOrderInfoService { + private final MpShopUserMapper mpShopUserMapper; + private final MpShopUserFlowMapper mpShopUserFlowMapper; + private final RabbitMsgUtils rabbitMsgUtils; + + public MpOrderInfoServiceImpl(MpShopUserMapper mpShopUserMapper, MpShopUserFlowMapper mpShopUserFlowMapper, RabbitMsgUtils rabbitMsgUtils) { + this.mpShopUserMapper = mpShopUserMapper; + this.mpShopUserFlowMapper = mpShopUserFlowMapper; + this.rabbitMsgUtils = rabbitMsgUtils; + } + @Override public boolean updateStateById(Integer shopId, Integer orderId, TableConstant.Status status) { return update(new LambdaUpdateWrapper() @@ -45,5 +64,37 @@ public class MpOrderInfoServiceImpl extends ServiceImpl() + .eq(TbShopUser::getShopId, shopId) + .eq(TbShopUser::getUserId, userId)); + if (user == null) { + throw new MsgException("用户信息不存在"); + } + mpShopUserMapper.incrBalance(user.getId(), shopId, returnAmount, DateUtil.date().getTime()); + + TbShopUserFlow flow = new TbShopUserFlow(); + flow.setShopUserId(user.getId()); + flow.setBizCode("accountReturnPay"); + flow.setBizName("会员储值卡退款"); + flow.setType("+"); + flow.setAmount(returnAmount); + flow.setBalance(user.getAmount().add(returnAmount)); + flow.setCreateTime(cn.hutool.core.date.DateUtil.date().toTimestamp()); + flow.setIsReturn("0"); + mpShopUserFlowMapper.insert(flow); + + JSONObject baObj = new JSONObject(); + baObj.put("userId", user.getUserId()); + baObj.put("shopId", user.getShopId()); + baObj.put("amount", returnAmount); + baObj.put("balance", user.getAmount()); + baObj.put("type", "退款"); + baObj.put("time", flow.getCreateTime()); + rabbitMsgUtils.addBalanceRecord(baObj); +// producer.balance(baObj.toString()); + } } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbMemberPointsServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbMemberPointsServiceImpl.java new file mode 100644 index 0000000..55ac14e --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbMemberPointsServiceImpl.java @@ -0,0 +1,94 @@ +package com.chaozhanggui.system.cashierservice.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapProxy; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chaozhanggui.system.cashierservice.dao.TbOrderInfoMapper; +import com.chaozhanggui.system.cashierservice.entity.TbMemberPoints; +import com.chaozhanggui.system.cashierservice.entity.TbMemberPointsLog; +import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo; +import com.chaozhanggui.system.cashierservice.exception.MsgException; +import com.chaozhanggui.system.cashierservice.mapper.TbMemberPointsLogMapper; +import com.chaozhanggui.system.cashierservice.mapper.TbMemberPointsMapper; +import com.chaozhanggui.system.cashierservice.service.TbMemberPointsService; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Date; +import java.util.Map; + +/** + * 会员积分 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 2.0 2024-10-25 + */ +@Service +@Primary +public class TbMemberPointsServiceImpl extends ServiceImpl implements TbMemberPointsService { + + @Resource + private TbMemberPointsLogMapper tbMemberPointsLogMapper; + @Resource + private TbOrderInfoMapper tbOrderInfoMapper; + + + + public TbMemberPoints initMemberPoints(Long memberId) { + TbMemberPoints entity = super.getOne(Wrappers.lambdaQuery().eq(TbMemberPoints::getMemberId, memberId)); + if (entity == null) { + throw new MsgException("会员信息不存在"); + } + if (entity.getAccountPoints() == null) { + entity.setAccountPoints(0); + } + super.updateById(entity); + return entity; + } + + + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean addPoints(Long memberId, int points, String content, Long orderId) { + TbMemberPoints entity = initMemberPoints(memberId); + // 增加账户积分 + entity.setAccountPoints(entity.getAccountPoints() + points); + entity.setLastPointsChangeTime(new Date()); + entity.setLastFloatPoints(points); + // 记录积分变动记录 + TbMemberPointsLog log = new TbMemberPointsLog(); + log.setShopId(entity.getShopId()); + log.setMemberId(entity.getMemberId()); + log.setMemberName(entity.getMemberName()); + log.setAvatarUrl(entity.getAvatarUrl()); + log.setMobile(entity.getMobile()); + log.setContent(content); + log.setFloatType("add"); + log.setFloatPoints(points); + log.setCreateTime(new Date()); + // 有关联订单的需要回置订单表的相关积分使用字段 + if (orderId != null) { + TbOrderInfo orderInfo = tbOrderInfoMapper.selectById(Math.toIntExact(orderId)); + if (orderInfo != null) { + log.setOrderNo(orderInfo.getOrderNo()); + } + } + super.updateById(entity); + tbMemberPointsLogMapper.insert(log); + return true; + } + + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbShopCouponServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbShopCouponServiceImpl.java new file mode 100644 index 0000000..71f97a7 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbShopCouponServiceImpl.java @@ -0,0 +1,53 @@ +package com.chaozhanggui.system.cashierservice.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chaozhanggui.system.cashierservice.dao.TbActivateInRecordMapper; +import com.chaozhanggui.system.cashierservice.dao.TbActivateOutRecordMapper; +import com.chaozhanggui.system.cashierservice.dao.TbShopCouponMapper; +import com.chaozhanggui.system.cashierservice.entity.TbActivateInRecord; +import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord; +import com.chaozhanggui.system.cashierservice.entity.TbShopCoupon; +import com.chaozhanggui.system.cashierservice.service.TbShopCouponService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * 优惠券(TbShopCoupon)表服务实现类 + * + * @author ww + * @since 2024-10-22 15:43:25 + */ +@Service("tbShopCouponService") +@Primary +public class TbShopCouponServiceImpl implements TbShopCouponService { + + @Autowired + private TbActivateInRecordMapper inRecordMapper; + @Autowired + private TbActivateOutRecordMapper outRecordMapper; + + /** + * 退还券 + * + * @param param giveId和 refNum 必传 + * @return + */ + @Override + public boolean refund(List param) { + for (TbActivateOutRecord outRecord : param) { + outRecord.setUpdateTime(new Date()); + outRecordMapper.updateRefNum(outRecord.getId(), outRecord.getRefNum()); + TbActivateInRecord inRecord = inRecordMapper.queryById(outRecord.getGiveId()); + inRecord.setOverNum(inRecord.getOverNum() + outRecord.getRefNum()); + inRecordMapper.updateOverNum(inRecord.getId(), inRecord.getOverNum()); + } + return true; + } + + +} + diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java b/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java index 2d2d72e..e19da2d 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java @@ -73,4 +73,11 @@ public class RabbitMsgUtils implements RabbitTemplate.ConfirmCallback { } + public void addBalanceRecord(JSONObject baObj) { + sendMsg(RabbitConstants.EXCHANGE_BALANCE, RabbitConstants.ROUTING_KEY_BALANCE, baObj, "储值卡记录", true); + } + + public void updateCons(JSONObject jsonObject1) { + sendMsg(RabbitConstants.EXCHANGE_CONS, RabbitConstants.ROUTING_KEY_CONS, jsonObject1, "储值卡记录", true); + } }