From 15690ac810b0a745db1a441c8caff1aa46d38e96 Mon Sep 17 00:00:00 2001 From: huk Date: Thu, 4 Sep 2025 14:57:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(transaction):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E5=88=86=E8=B4=A6=E5=8A=9F=E8=83=BD=E5=B9=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在订单表中添加分账状态- 新增分账规则校验逻辑 - 更新分账和订单状态处理流程 - 优化分账失败和异常处理 --- .../wzj/soopin/order/domain/entity/Order.java | 9 +- .../soopin/order/emum/OrderStatusEnum.java | 21 ++--- .../wzj/soopin/order/mapper/OrderMapper.java | 3 + .../order/service/impl/OrderServiceImpl.java | 4 + .../domain/bo/SeparateApplyBO.java | 8 ++ .../apply/resp/SeparateRespInfoList.java | 3 + .../soopin/transaction/domain/po/Divide.java | 3 + .../transaction/domain/po/DivideDetail.java | 5 +- .../transaction/domain/po/DivideRule.java | 2 + .../transaction/enums/DivideStatus.java | 12 ++- .../mapper/DivideDetailMapper.java | 6 ++ .../transaction/mapper/DivideMapper.java | 6 +- .../transaction/mapper/DivideRuleMapper.java | 6 ++ .../service/IDivideRuleService.java | 6 ++ .../service/impl/DivideRuleServiceImpl.java | 43 +++++++++- .../service/impl/DivideServiceImpl.java | 72 ++++++---------- .../service/impl/EasypayServiceImpl.java | 85 +++++++++++++++---- 17 files changed, 209 insertions(+), 85 deletions(-) diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java index 5b04d27cd..9dace55fc 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/domain/entity/Order.java @@ -76,8 +76,13 @@ public class Order extends BaseAudit { @Excel(name = "支付方式:0->未支付;1->支付宝;2->微信") private Integer payType; - @Schema(description = "订单状态:0->待支付;1->支付中;2->已支付;3->已关闭;4->已退款;10->无效订单") - @Excel(name = "订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") + @Schema(description = "订单状态:0->待支付;1->支付中;2->已支付;3->已关闭;4->已退款;9->已分账;10->无效订单") + @Excel(name = "订单状态:0->待支付;1->支付中;2->已支付;3->已关闭;4->已退款;9->已分账;10->无效订单") + + /** + * 订单状态:0->待支付;1->支付中;2->已支付;3->已关闭;4->已退款;9->已分账;10->无效订单 + * 枚举类型见{@link com.wzj.soopin.order.emum.OrderStatusEnum} + */ private Integer status; @Schema(description = "退款状态,枚举值:1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功") diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/emum/OrderStatusEnum.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/emum/OrderStatusEnum.java index ebd855f5b..24fbd8f2f 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/emum/OrderStatusEnum.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/emum/OrderStatusEnum.java @@ -1,29 +1,24 @@ package com.wzj.soopin.order.emum; +import lombok.AllArgsConstructor; +import lombok.Getter; + /** - * 订单状态:0->待支付;1->支付中;2->已支付;3->已关闭;4->已退款;10->无效订单 + * 订单状态:0->待支付;1->支付中;2->已支付;3->已关闭;4->已退款;9->已分账;10->无效订单 */ +@Getter +@AllArgsConstructor public enum OrderStatusEnum { UNPAID(0, "待支付"), PAYMENT(1, "支付中"), PAID(2, "已支付"), CLOSED(3, "已关闭"), REFUNDED(4, "已退款"), + DIVIDED(9, "已分账"), INVALID(10, "无效订单"); private final Integer value; + private final String info; - OrderStatusEnum(Integer value, String info) { - this.value = value; - this.info = info; - } - - public Integer getValue() { - return value; - } - - public String getInfo() { - return info; - } } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java index 9949f6120..515a7471b 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/mapper/OrderMapper.java @@ -11,6 +11,7 @@ import com.wzj.soopin.order.domain.form.ManagerOrderQueryForm; import com.wzj.soopin.order.domain.vo.*; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; import java.util.List; import java.util.Map; @@ -43,4 +44,6 @@ public interface OrderMapper extends BaseMapper { Map countOrder(); + @Update("update oms_order set status = #{status} where id = #{orderId}") + void updateStatusById(@Param("orderId")Long orderId, @Param("status") Integer status); } diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java index dc514d141..8374b680e 100644 --- a/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java +++ b/ruoyi-modules/ruoyi-order/src/main/java/com/wzj/soopin/order/service/impl/OrderServiceImpl.java @@ -257,6 +257,10 @@ public class OrderServiceImpl extends ServiceImpl implements @Override public void cancel(Long orderId) { + Order order = orderMapper.selectById(orderId); + LoginUser loginUser = LoginHelper.getLoginUser(); + Assert.isTrue(Objects.equals(loginUser.getUserId(), order.getMemberId()), () -> new ServiceException("无权限取消非本人订单")); + Assert.isTrue(OrderStatusEnum.UNPAID.getValue().equals(order.getStatus()), () -> new ServiceException("订单已支付,不能取消")); orderMapper.updateById(Order.builder().id(orderId).status(OrderStatusEnum.CLOSED.getValue()).build()); } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/SeparateApplyBO.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/SeparateApplyBO.java index 83e756aa2..01cce6046 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/SeparateApplyBO.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/SeparateApplyBO.java @@ -1,5 +1,7 @@ package com.wzj.soopin.transaction.domain.bo; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -27,6 +29,12 @@ public class SeparateApplyBO { */ private Long payId; + /** + * 分账id + */ + + private Long divideId; + /** * 支付完成时间 */ diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/easypay/separate/apply/resp/SeparateRespInfoList.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/easypay/separate/apply/resp/SeparateRespInfoList.java index 5b7e020fc..dfbfc6746 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/easypay/separate/apply/resp/SeparateRespInfoList.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/easypay/separate/apply/resp/SeparateRespInfoList.java @@ -49,6 +49,9 @@ public class SeparateRespInfoList { private Long sepaRatio; /** * 分账单状态,(处理中、成功、失败、已退款) + * REFUNDED 分账已回退 + * SUCCESS 分账成功 + * PENDING 待处理 */ private String sepaStatus; /** diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Divide.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Divide.java index 4e18306ce..61ce75a42 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Divide.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Divide.java @@ -61,6 +61,7 @@ public class Divide extends BaseEntity { /** * 状态 + * 枚举类型见 {@link com.wzj.soopin.transaction.enums.DivideStatus} */ @Schema(description = "状态") @ExcelProperty(value = "状态", order = 5) @@ -89,5 +90,7 @@ public class Divide extends BaseEntity { @ExcelProperty(value = "订单编号", order = 9) private String orderSn; + private String delFlag; + } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideDetail.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideDetail.java index e13599f08..4ef49fe76 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideDetail.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideDetail.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import org.dromara.common.mybatis.core.domain.BaseEntity; import java.math.BigDecimal; @@ -17,6 +18,7 @@ import java.math.BigDecimal; * @author wzj * @date 2023-03-07 */ +@EqualsAndHashCode(callSuper = true) @Schema(description = "订单分账明细") @Data @TableName("trans_divide_detail") @@ -78,10 +80,11 @@ public class DivideDetail extends BaseEntity { * */ private Integer type; + /** * 状态 + * 枚举类型见 {@link com.wzj.soopin.transaction.enums.DivideStatus} */ - @Schema(description = "状态 0 未分账 1 分账成功 2 分账失败") @ExcelProperty(value = "状态", order = 5) private Integer status; diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java index c9d5db0b6..b3d30461e 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/DivideRule.java @@ -67,5 +67,7 @@ public class DivideRule extends BaseEntity { @ExcelProperty(value ="类型", order = 8) private Integer type; + private String delFlag; + } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/DivideStatus.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/DivideStatus.java index 459dca02b..ae287a55e 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/DivideStatus.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/DivideStatus.java @@ -6,10 +6,14 @@ import lombok.Getter; public enum DivideStatus { PENDING(0, "待分账"), - SUCCESS(1, "分账成功"), - FAIL(2, "分账失败"); - private int code; - private String desc; + PROCESSING(1, "分账中"), + SUCCESS(2, "分账成功"), + FAIL(3, "分账失败"), + REFUNDED(4, "已退款"); + + private final int code; + + private final String desc; DivideStatus(int code, String desc) { this.code = code; diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideDetailMapper.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideDetailMapper.java index 0e0eb429a..fbf254932 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideDetailMapper.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideDetailMapper.java @@ -3,8 +3,12 @@ package com.wzj.soopin.transaction.mapper; import com.wzj.soopin.transaction.domain.po.DivideDetail; import com.wzj.soopin.transaction.domain.vo.DivideDetailVO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import java.util.List; + /** * 意见反馈Mapper接口 * @@ -13,4 +17,6 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; @Mapper public interface DivideDetailMapper extends BaseMapperPlus { + @Select("select * from trans_divide_detail where divide_id = #{divideId} and del_flag = '0' ") + List selectByDivideId(@Param("divideId") Long divideId); } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideMapper.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideMapper.java index b938304d2..39d8143eb 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideMapper.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideMapper.java @@ -6,6 +6,7 @@ import com.wzj.soopin.transaction.domain.vo.DivideVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; /** * 意见反馈Mapper接口 @@ -17,6 +18,9 @@ public interface DivideMapper extends BaseMapper { DivideVO getVOById(Long divideId); - @Select("select * from trans_divide where order_id = #{orderId}") + @Select("select * from trans_divide where order_id = #{orderId} and del_flag = '0'") Divide selectByOrderId(@Param("orderId") Long orderId); + + @Update("update trans_divide set status = #{divideStatus} where id = #{divideId}") + void updateStatus(@Param("divideId") Long divideId, @Param("divideStatus") int divideStatus); } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideRuleMapper.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideRuleMapper.java index d166062e7..c68545b6a 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideRuleMapper.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/mapper/DivideRuleMapper.java @@ -2,12 +2,18 @@ package com.wzj.soopin.transaction.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.wzj.soopin.transaction.domain.po.DivideRule; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; /** * 意见反馈Mapper接口 * * @author zcc */ +@Mapper public interface DivideRuleMapper extends BaseMapper { + @Select("select * from trans_divide_rule where type = #{type} and status = #{status} and del_flag = '0'") + DivideRule getByTypeAndStatus(@Param("type") Integer type, @Param("status") int status); } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IDivideRuleService.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IDivideRuleService.java index a9f633c54..70504b5c2 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IDivideRuleService.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IDivideRuleService.java @@ -3,7 +3,11 @@ package com.wzj.soopin.transaction.service; import com.baomidou.mybatisplus.extension.service.IService; import com.wzj.soopin.transaction.domain.bo.DivideRuleBO; import com.wzj.soopin.transaction.domain.po.DivideRule; +import com.wzj.soopin.transaction.domain.vo.DivideRuleDetailVO; import com.wzj.soopin.transaction.domain.vo.DivideRuleVO; +import com.wzj.soopin.transaction.enums.DivideRuleFeeType; + +import java.util.List; public interface IDivideRuleService extends IService { @@ -12,4 +16,6 @@ public interface IDivideRuleService extends IService { DivideRuleVO getVOById(Long divideId); DivideRuleVO getVOByOrderType(Integer orderType); + + void checkRule(List details, DivideRuleFeeType divideRuleFeeType); } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideRuleServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideRuleServiceImpl.java index 60131917b..45632b131 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideRuleServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideRuleServiceImpl.java @@ -1,6 +1,7 @@ package com.wzj.soopin.transaction.service.impl; import cn.hutool.core.lang.Assert; +import cn.hutool.core.text.StrBuilder; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wzj.soopin.transaction.convert.DivideRuleConvert; @@ -8,18 +9,19 @@ import com.wzj.soopin.transaction.convert.DivideRuleDetailConvert; import com.wzj.soopin.transaction.domain.bo.DivideRuleBO; import com.wzj.soopin.transaction.domain.po.DivideRule; import com.wzj.soopin.transaction.domain.po.DivideRuleDetail; +import com.wzj.soopin.transaction.domain.vo.DivideRuleDetailVO; import com.wzj.soopin.transaction.domain.vo.DivideRuleVO; +import com.wzj.soopin.transaction.enums.DivideRuleDetailType; +import com.wzj.soopin.transaction.enums.DivideRuleFeeType; import com.wzj.soopin.transaction.enums.DivideRuleStatus; import com.wzj.soopin.transaction.mapper.DivideRuleDetailMapper; import com.wzj.soopin.transaction.mapper.DivideRuleMapper; import com.wzj.soopin.transaction.service.IDivideRuleService; -import jodd.util.CollectionUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.exception.ServiceException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.List; @@ -103,8 +105,8 @@ public class DivideRuleServiceImpl extends ServiceImpl divideRuleList = baseMapper.selectList(new QueryWrapper().lambda() - .eq(DivideRule::getType,orderType) - .eq(DivideRule::getStatus,DivideRuleStatus.ON.getCode())); + .eq(DivideRule::getType, orderType) + .eq(DivideRule::getStatus, DivideRuleStatus.ON.getCode())); Assert.notEmpty(divideRuleList, () -> new ServiceException("未找到品类的分账规则")); Assert.isTrue(divideRuleList.size() == 1, () -> new ServiceException("品类分账规则不唯一")); DivideRule divideRule = divideRuleList.get(0); @@ -114,4 +116,37 @@ public class DivideRuleServiceImpl extends ServiceImpl details, DivideRuleFeeType divideRuleFeeType) { + String type = null; + if (DivideRuleFeeType.SELLER == divideRuleFeeType) { + if (details.stream().filter(item -> item.getType() == DivideRuleDetailType.SELLER.getValue()).count() != 1) { + type = DivideRuleDetailType.SELLER.getDesc(); + } + } + if (DivideRuleFeeType.PLATFORM == divideRuleFeeType) { + if (details.stream().filter(item -> item.getType() == DivideRuleDetailType.PLATFORM.getValue()).count() != 1) { + type = DivideRuleDetailType.PLATFORM.getDesc(); + } + } + if (DivideRuleFeeType.PROXY == divideRuleFeeType) { + if (details.stream().filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue()).count() != 1) { + type = DivideRuleDetailType.PROXY.getDesc(); + } + } + if (DivideRuleFeeType.REFERENCE == divideRuleFeeType) { + if (details.stream().filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue()).count() != 1) { + type = DivideRuleDetailType.REFERENCE.getDesc(); + } + } + String finalType = type; + Assert.isTrue(type == null, () -> new ServiceException("分账规则中的手续费承担者[" + finalType + "]未配置相应的分账规则详情")); + } } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java index 90cf1bce0..4d5664997 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/DivideServiceImpl.java @@ -3,6 +3,7 @@ package com.wzj.soopin.transaction.service.impl; import cn.hutool.core.lang.Assert; import cn.hutool.core.text.StrBuilder; import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -73,7 +74,7 @@ public class DivideServiceImpl extends ServiceImpl impleme private final IEasypayService easypayService; private final ISysTenantService sysTenantService; - + private final DivideMapper divideMapper; @Override @@ -130,7 +131,8 @@ public class DivideServiceImpl extends ServiceImpl impleme if (divide == null) { return null; } - List detailList = detailMapper.selectList(new QueryWrapper().lambda().eq(DivideDetail::getDivideId, divideId)); + detailMapper.selectByDivideId(divideId); + List detailList = detailMapper.selectByDivideId(divideId); divide.setDetails(detailConvert.toVO(detailList)); return divide; } @@ -163,23 +165,23 @@ public class DivideServiceImpl extends ServiceImpl impleme Integer feeType = rule.getFeeType(); DivideRuleFeeType divideRuleFeeType = DivideRuleFeeType.getByValue(feeType); List details = rule.getDetails(); - checkRule(details, divideRuleFeeType); - + ruleService.checkRule(details, divideRuleFeeType); //根据易生支付的合同查看手续费金额 BigDecimal totalAmount = order.getTotalAmount(); - //计算订单可分配金额,订单只考虑整单退,不考虑单独退,所以直接计算订单金额 //先生成主表信息 - Divide divide = Divide.builder() - .ruleId(rule.getId()) - .orderMoney(totalAmount) - .separateBatchTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString()) -// .fee(totalFee) -// .actualMoney(actualMoney) - .orderSn(order.getOrderSn()) - .status(DivideStatus.PENDING.getCode()) - .build(); - super.save(divide); + Divide divide = divideMapper.selectByOrderId(orderId); + if (divide == null) { + divide = Divide.builder() + .ruleId(rule.getId()) + .orderMoney(totalAmount) + .separateBatchTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString()) + .orderSn(order.getOrderSn()) + .status(DivideStatus.PENDING.getCode()) + .build(); + super.save(divide); + } + Long divideId = divide.getId(); List detailList = new ArrayList<>(); List separateItemBOList = new ArrayList<>(); // 从租户信息得到商户的分账比例,先分给商户 @@ -191,13 +193,13 @@ public class DivideServiceImpl extends ServiceImpl impleme .filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue()) .findFirst() .ifPresent(ruleDetailVO -> { - DivideDetail proxyDivideDetail = divideProxy(totalAmount, ruleDetailVO, divide.getId(), order.getTenantId(),divideRuleFeeType, detailList, separateItemBOList); + DivideDetail proxyDivideDetail = divideProxy(totalAmount, ruleDetailVO, divideId, order.getTenantId(), divideRuleFeeType, detailList, separateItemBOList); }); rule.getDetails().stream() .filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue()) .findFirst() .ifPresent(ruleDetailVO -> { - DivideDetail divideReference = divideReference(totalAmount, ruleDetailVO, divide.getId(), order.getMemberId(),divideRuleFeeType, detailList, separateItemBOList); + DivideDetail divideReference = divideReference(totalAmount, ruleDetailVO, divideId, order.getMemberId(), divideRuleFeeType, detailList, separateItemBOList); detailList.add(divideReference); }); @@ -205,7 +207,7 @@ public class DivideServiceImpl extends ServiceImpl impleme .filter(item -> item.getType() == DivideRuleDetailType.PLATFORM.getValue()) .findFirst() .ifPresent(ruleDetailVO -> { - DivideDetail dividePlatform = dividePlatform(totalAmount, ruleDetailVO, divide.getId(),divideRuleFeeType, detailList, separateItemBOList); + DivideDetail dividePlatform = dividePlatform(totalAmount, ruleDetailVO, divideId, divideRuleFeeType, detailList, separateItemBOList); detailList.add(dividePlatform); }); @@ -216,6 +218,7 @@ public class DivideServiceImpl extends ServiceImpl impleme SeparateApplyBO separateApplyBO = SeparateApplyBO.builder() .orderId(order.getId()) .payId(order.getPayId()) + .divideId(divide.getId()) .transDate(payOrder.getEndTransDate()) .transSumAmt(payOrder.getTransAmount()) .transSumCount((long) separateItemBOList.size()) @@ -226,32 +229,6 @@ public class DivideServiceImpl extends ServiceImpl impleme return true; } - /** - * 校验分账规则详情和规则中的手续费承担类型是否一致 - * - * @param details - * @param divideRuleFeeType - */ - private void checkRule(List details, DivideRuleFeeType divideRuleFeeType) { - if (DivideRuleFeeType.SELLER == divideRuleFeeType) { - long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.SELLER.getValue()).count(); - Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置商户承担手续费,但未配置商户分账规则详情")); - } - if (DivideRuleFeeType.PLATFORM == divideRuleFeeType) { - long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.PLATFORM.getValue()).count(); - Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置平台承担手续费,但未配置平台分账规则详情")); - } - if (DivideRuleFeeType.PROXY == divideRuleFeeType) { - long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.PROXY.getValue()).count(); - Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置代理承担手续费,但未配置代理分账规则详情")); - } - if (DivideRuleFeeType.REFERENCE == divideRuleFeeType) { - long count = details.stream().filter(item -> item.getType() == DivideRuleDetailType.REFERENCE.getValue()).count(); - Assert.isTrue(count == 1, () -> new ServiceException("分账总规则中已配置达人承担手续费,但未配置达人分账规则详情")); - } - - } - /** * 商户分账 * @@ -278,7 +255,9 @@ public class DivideServiceImpl extends ServiceImpl impleme .accountCode(mchtCode) .money(sellerAmount) .moneyPercent(divideRate) - .type(DivideRuleDetailType.SELLER.getValue()).build(); + .type(DivideRuleDetailType.SELLER.getValue()) + .status(DivideStatus.PENDING.getCode()) + .build(); detailMapper.insert(sellerDetail); detailList.add(sellerDetail); Integer sepaFeeAmount = 0; @@ -319,6 +298,7 @@ public class DivideServiceImpl extends ServiceImpl impleme .money(proxyAmount) .moneyPercent(rule.getMoneyPercent()) .type(DivideRuleDetailType.PROXY.getValue()) + .status(DivideStatus.PENDING.getCode()) .build(); detailMapper.insert(proxyDetail); detailList.add(proxyDetail); @@ -360,6 +340,7 @@ public class DivideServiceImpl extends ServiceImpl impleme .money(proxyAmount) .moneyPercent(rule.getMoneyPercent()) .type(DivideRuleDetailType.REFERENCE.getValue()) + .status(DivideStatus.PENDING.getCode()) .build(); detailMapper.insert(referenceDetail); detailList.add(referenceDetail); @@ -389,6 +370,7 @@ public class DivideServiceImpl extends ServiceImpl impleme .money(platformAmount) .moneyPercent(rule.getMoneyPercent()) .type(DivideRuleDetailType.PLATFORM.getValue()) + .status(DivideStatus.PENDING.getCode()) .build(); detailMapper.insert(platformDetail); detailList.add(platformDetail); diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java index d790cebcc..d2624b51c 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java @@ -24,6 +24,7 @@ import com.wzj.soopin.transaction.config.EasypayConfig; import com.wzj.soopin.transaction.config.WechatMiniProgramConfig; import com.wzj.soopin.transaction.domain.bo.PaymentBO; import com.wzj.soopin.transaction.domain.bo.SeparateApplyBO; +import com.wzj.soopin.transaction.domain.bo.SeparateItemBO; import com.wzj.soopin.transaction.domain.bo.easypay.*; import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundApplyReqBody; import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundReqOrderInfo; @@ -31,6 +32,7 @@ import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.resp.RefundAppl import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.req.SeparateApplyReqBody; import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.req.SeparateReqOrderInfo; import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.resp.SeparateApplyRespBody; +import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.resp.SeparateRespInfoList; import com.wzj.soopin.transaction.domain.bo.easypay.separate.apply.resp.SeparateRespOrderInfo; import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.req.*; import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsApiRespBody; @@ -41,18 +43,20 @@ import com.wzj.soopin.transaction.domain.bo.easypay.trade.query.resp.TradeQueryR import com.wzj.soopin.transaction.domain.bo.easypay.trade.query.resp.TradeQueryRespOrderInfo; import com.wzj.soopin.transaction.domain.entity.WxAuthResponse; import com.wzj.soopin.transaction.domain.po.Divide; +import com.wzj.soopin.transaction.domain.po.DivideDetail; +import com.wzj.soopin.transaction.domain.po.DivideRule; import com.wzj.soopin.transaction.domain.po.PayOrder; -import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO; -import com.wzj.soopin.transaction.domain.vo.EasypayTransResultVO; -import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO; +import com.wzj.soopin.transaction.domain.vo.*; +import com.wzj.soopin.transaction.enums.DivideRuleFeeType; +import com.wzj.soopin.transaction.enums.DivideRuleStatus; +import com.wzj.soopin.transaction.enums.DivideStatus; import com.wzj.soopin.transaction.enums.TransState; -import com.wzj.soopin.transaction.enums.easypay.DelaySettleFlag; -import com.wzj.soopin.transaction.enums.easypay.PatnerSettleFlag; -import com.wzj.soopin.transaction.enums.easypay.PayType; -import com.wzj.soopin.transaction.enums.easypay.SplitSettleFlag; +import com.wzj.soopin.transaction.enums.easypay.*; import com.wzj.soopin.transaction.mapper.DivideDetailMapper; import com.wzj.soopin.transaction.mapper.DivideMapper; +import com.wzj.soopin.transaction.mapper.DivideRuleMapper; import com.wzj.soopin.transaction.mapper.PayOrderMapper; +import com.wzj.soopin.transaction.service.IDivideRuleService; import com.wzj.soopin.transaction.service.IEasypayService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -64,8 +68,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.math.RoundingMode; import java.rmi.ServerException; import java.util.*; +import java.util.stream.Collectors; import static com.wzj.soopin.transaction.constans.EasypayConstants.*; @@ -91,7 +97,7 @@ public class EasypayServiceImpl implements IEasypayService { private final DivideMapper divideMapper; - private final DivideDetailMapper divideDetailMapper; + private final DivideRuleMapper divideRuleMapper; /** @@ -490,7 +496,20 @@ public class EasypayServiceImpl implements IEasypayService { .paymentTime(LocalDateTimeUtil.parse(StrBuilder.create(respOrderInfo.getDateEnd()).append(respOrderInfo.getTimeEnd()).toString(), "yyyyMMddHHmmss")) .payType(PayType.getByValue(payOrder.getPayType()).getChannel()) .build()); - }else{ + // 生产待分账信息 + DivideRule divideRule = divideRuleMapper.getByTypeAndStatus(order.getType(), DivideRuleStatus.ON.getCode()); + if (divideRule == null) { + log.warn("订单类型的分账规则不存在,暂不生成待分账记录"); + } else { + divideMapper.insert(Divide.builder() + .ruleId(divideRule.getId()) + .orderMoney(order.getTotalAmount()) + .separateBatchTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString()) + .orderSn(order.getOrderSn()) + .status(DivideStatus.PENDING.getCode()) + .build()); + } + } else { // 支付失败,支付状态重置为待支付 payOrderMapper.updateById(PayOrder.builder().id(payOrder.getId()).transState(TransState.PENDING.getCode()).build()); } @@ -553,7 +572,7 @@ public class EasypayServiceImpl implements IEasypayService { if (StrUtil.equalsAny(respStateInfo.getTransState(), RSP_BODY_TRANS_OK)) { // 更新支付单退款状态 payOrderMapper.updateById(PayOrder.builder().id(payOrder.getId()).transState(TransState.REFUNDED.getCode()).refundDate(new Date()).build()); - orderMapper.updateById(Order.builder().id(order.getId()).status(OrderStatusEnum.REFUNDED.getValue()).build()); + orderMapper.updateStatusById(order.getId(), OrderStatusEnum.REFUNDED.getValue()); } } else { log.error("易生退款失败:{}", respStateInfo.getRespDesc()); @@ -653,6 +672,7 @@ public class EasypayServiceImpl implements IEasypayService { .reqSign(reqSign) .build(); log.debug("调用易生请求分账接口请求:{}", JSONObject.toJSONString(easyRequest)); + divideMapper.updateStatus(separateApplyBO.getDivideId(), DivideStatus.PENDING.getCode()); String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/separate/orderApply").toString(); String body = HttpRequest.post(url) .timeout(3000) @@ -688,14 +708,49 @@ public class EasypayServiceImpl implements IEasypayService { * * @param respOrderInfo */ - private SeparateApplyBO handleSeparateInfo(SeparateApplyBO separateApplyBO, SeparateRespOrderInfo respOrderInfo) { + private void handleSeparateInfo(SeparateApplyBO separateApplyBO, SeparateRespOrderInfo respOrderInfo) { Long orderId = separateApplyBO.getOrderId(); - Divide divide = divideMapper.selectByOrderId(orderId); - - return separateApplyBO; + Map separateItemBOMap = separateApplyBO.getSeparateItemBOList().stream().collect(Collectors.toMap(SeparateItemBO::getSeparateTrade, o -> o)); + List updateDetailList = new ArrayList<>(); + List separateRespInfoList = respOrderInfo.getSeparateRespInfoList(); + separateRespInfoList.forEach(separateRespInfo -> { + String separateTrade = separateRespInfo.getSeparateTrade(); + SeparateItemBO separateItemBO = separateItemBOMap.get(separateTrade); + DivideDetail divideDetail = DivideDetail.builder() + .id(Long.valueOf(separateItemBO.getSeparateTrade())) + .separateTrade(separateRespInfo.getSeparateTrade()) + .build(); + if (separateRespInfo.getSepaFeeAmount() != null) { + divideDetail.setMoney(BigDecimal.valueOf(separateRespInfo.getSepaFeeAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); + } + if (separateRespInfo.getSepaFeeAmount() != null) { + divideDetail.setFee(BigDecimal.valueOf(separateRespInfo.getSepaFeeAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); + } + SepaStatus sepaStatus = SepaStatus.getByValue(separateRespInfo.getSepaStatus()); + switch (sepaStatus) { + case SUCCESS -> divideDetail.setStatus(DivideStatus.SUCCESS.getCode()); + case FAIL -> divideDetail.setStatus(DivideStatus.FAIL.getCode()); + case PENDING -> divideDetail.setStatus(DivideStatus.PENDING.getCode()); + case REFUNDED -> divideDetail.setStatus(DivideStatus.REFUNDED.getCode()); + case PROCESSING -> divideDetail.setStatus(DivideStatus.PROCESSING.getCode()); + default -> divideDetail.setStatus(DivideStatus.PROCESSING.getCode()); + } + updateDetailList.add(divideDetail); + }); + long itemOkCount = updateDetailList.stream().filter(item -> item.getStatus() == DivideStatus.SUCCESS.getCode()) + .count(); + int actualSeparate = separateItemBOMap.values().stream().mapToInt(SeparateItemBO::getSepaTransAmount).sum(); + Divide divideUpdate = Divide.builder() + .id(separateApplyBO.getDivideId()) + .actualMoney(BigDecimal.valueOf(actualSeparate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)) + .status(DivideStatus.PROCESSING.getCode()).build(); + if (itemOkCount == separateItemBOMap.size()) { + divideUpdate.setStatus(DivideStatus.SUCCESS.getCode()); + orderMapper.updateStatusById(orderId, OrderStatusEnum.DIVIDED.getValue()); + } + divideMapper.updateById(divideUpdate); } - @Override public EasypayAccountVO getEasypayAccount(Long memberId) { return EasypayAccountVO.builder().balance(new BigDecimal(1000)).build();