feat(transaction): 完善分账功能并更新订单状态
- 在订单表中添加分账状态- 新增分账规则校验逻辑 - 更新分账和订单状态处理流程 - 优化分账失败和异常处理
This commit is contained in:
parent
793c34a96a
commit
15690ac810
@ -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: 退款成功")
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<Order> {
|
||||
Map<String, Object> countOrder();
|
||||
|
||||
|
||||
@Update("update oms_order set status = #{status} where id = #{orderId}")
|
||||
void updateStatusById(@Param("orderId")Long orderId, @Param("status") Integer status);
|
||||
}
|
||||
|
@ -257,6 +257,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> 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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* 支付完成时间
|
||||
*/
|
||||
|
@ -49,6 +49,9 @@ public class SeparateRespInfoList {
|
||||
private Long sepaRatio;
|
||||
/**
|
||||
* 分账单状态,(处理中、成功、失败、已退款)
|
||||
* REFUNDED 分账已回退
|
||||
* SUCCESS 分账成功
|
||||
* PENDING 待处理
|
||||
*/
|
||||
private String sepaStatus;
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -67,5 +67,7 @@ public class DivideRule extends BaseEntity {
|
||||
@ExcelProperty(value ="类型", order = 8)
|
||||
private Integer type;
|
||||
|
||||
private String delFlag;
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<DivideDetail, DivideDetailVO> {
|
||||
|
||||
@Select("select * from trans_divide_detail where divide_id = #{divideId} and del_flag = '0' ")
|
||||
List<DivideDetail> selectByDivideId(@Param("divideId") Long divideId);
|
||||
}
|
||||
|
@ -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<Divide> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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<DivideRule> {
|
||||
|
||||
@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);
|
||||
}
|
||||
|
@ -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<DivideRule> {
|
||||
|
||||
@ -12,4 +16,6 @@ public interface IDivideRuleService extends IService<DivideRule> {
|
||||
DivideRuleVO getVOById(Long divideId);
|
||||
|
||||
DivideRuleVO getVOByOrderType(Integer orderType);
|
||||
|
||||
void checkRule(List<DivideRuleDetailVO> details, DivideRuleFeeType divideRuleFeeType);
|
||||
}
|
||||
|
@ -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<DivideRuleMapper, DivideR
|
||||
@Override
|
||||
public DivideRuleVO getVOByOrderType(Integer orderType) {
|
||||
List<DivideRule> divideRuleList = baseMapper.selectList(new QueryWrapper<DivideRule>().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<DivideRuleMapper, DivideR
|
||||
vo.setDetails(detailConvert.toVO(detailList));
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验分账规则详情和规则中的手续费承担类型是否一致
|
||||
*
|
||||
* @param details
|
||||
* @param divideRuleFeeType
|
||||
*/
|
||||
@Override
|
||||
public void checkRule(List<DivideRuleDetailVO> 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 + "]未配置相应的分账规则详情"));
|
||||
}
|
||||
}
|
||||
|
@ -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<DivideMapper, Divide> impleme
|
||||
private final IEasypayService easypayService;
|
||||
|
||||
private final ISysTenantService sysTenantService;
|
||||
|
||||
private final DivideMapper divideMapper;
|
||||
|
||||
|
||||
@Override
|
||||
@ -130,7 +131,8 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
|
||||
if (divide == null) {
|
||||
return null;
|
||||
}
|
||||
List<DivideDetail> detailList = detailMapper.selectList(new QueryWrapper<DivideDetail>().lambda().eq(DivideDetail::getDivideId, divideId));
|
||||
detailMapper.selectByDivideId(divideId);
|
||||
List<DivideDetail> detailList = detailMapper.selectByDivideId(divideId);
|
||||
divide.setDetails(detailConvert.toVO(detailList));
|
||||
return divide;
|
||||
}
|
||||
@ -163,23 +165,23 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
|
||||
Integer feeType = rule.getFeeType();
|
||||
DivideRuleFeeType divideRuleFeeType = DivideRuleFeeType.getByValue(feeType);
|
||||
List<DivideRuleDetailVO> 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<DivideDetail> detailList = new ArrayList<>();
|
||||
List<SeparateItemBO> separateItemBOList = new ArrayList<>();
|
||||
// 从租户信息得到商户的分账比例,先分给商户
|
||||
@ -191,13 +193,13 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> 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<DivideMapper, Divide> 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<DivideMapper, Divide> 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<DivideMapper, Divide> impleme
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验分账规则详情和规则中的手续费承担类型是否一致
|
||||
*
|
||||
* @param details
|
||||
* @param divideRuleFeeType
|
||||
*/
|
||||
private void checkRule(List<DivideRuleDetailVO> 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<DivideMapper, Divide> 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<DivideMapper, Divide> 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<DivideMapper, Divide> 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<DivideMapper, Divide> impleme
|
||||
.money(platformAmount)
|
||||
.moneyPercent(rule.getMoneyPercent())
|
||||
.type(DivideRuleDetailType.PLATFORM.getValue())
|
||||
.status(DivideStatus.PENDING.getCode())
|
||||
.build();
|
||||
detailMapper.insert(platformDetail);
|
||||
detailList.add(platformDetail);
|
||||
|
@ -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<String, SeparateItemBO> separateItemBOMap = separateApplyBO.getSeparateItemBOList().stream().collect(Collectors.toMap(SeparateItemBO::getSeparateTrade, o -> o));
|
||||
List<DivideDetail> updateDetailList = new ArrayList<>();
|
||||
List<SeparateRespInfoList> 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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user