订单分账MQ支持重新发起分账接口;

This commit is contained in:
terrfly 2022-01-25 16:58:42 +08:00
parent 4ba0a56c3a
commit 121598e13c
6 changed files with 120 additions and 33 deletions

View File

@ -64,6 +64,9 @@ public class PayOrderDivisionMQ extends AbstractMQ {
* **/
private List<CustomerDivisionReceiver> receiverList;
/** 是否重新发送 ( 如分账失败,重新请求分账接口 ) 空表示false **/
private Boolean isResend;
}
@Override
@ -84,7 +87,12 @@ public class PayOrderDivisionMQ extends AbstractMQ {
/** 【!重要配置项!】 构造MQModel , 一般用于发送MQ时 **/
public static PayOrderDivisionMQ build(String payOrderId, Byte useSysAutoDivisionReceivers, List<CustomerDivisionReceiver> receiverList){
return new PayOrderDivisionMQ(new MsgPayload(payOrderId, useSysAutoDivisionReceivers, receiverList));
return new PayOrderDivisionMQ(new MsgPayload(payOrderId, useSysAutoDivisionReceivers, receiverList, false));
}
/** 【!重要配置项!】 构造MQModel , 一般用于发送MQ时 **/
public static PayOrderDivisionMQ build(String payOrderId, Byte useSysAutoDivisionReceivers, List<CustomerDivisionReceiver> receiverList, Boolean isResend){
return new PayOrderDivisionMQ(new MsgPayload(payOrderId, useSysAutoDivisionReceivers, receiverList, isResend));
}
/** 解析MQ消息 一般用于接收MQ消息时 **/

View File

@ -18,6 +18,8 @@ package com.jeequan.jeepay.mch.ctrl.division;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.PayOrderDivisionRecord;
@ -45,6 +47,7 @@ import org.springframework.web.bind.annotation.RestController;
public class PayOrderDivisionRecordController extends CommonCtrl {
@Autowired private PayOrderDivisionRecordService payOrderDivisionRecordService;
@Autowired private IMQSender mqSender;
/** list */
@ -112,4 +115,32 @@ public class PayOrderDivisionRecordController extends CommonCtrl {
return ApiRes.ok(record);
}
/** 分账接口重试 */
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECORD_RESEND' )")
@RequestMapping(value="/resend/{recordId}", method = RequestMethod.POST)
public ApiRes resend(@PathVariable("recordId") Long recordId) {
PayOrderDivisionRecord record = payOrderDivisionRecordService
.getOne(PayOrderDivisionRecord.gw()
.eq(PayOrderDivisionRecord::getMchNo, getCurrentMchNo())
.eq(PayOrderDivisionRecord::getRecordId, recordId));
if (record == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SELETE);
}
if(record.getState() != PayOrderDivisionRecord.STATE_FAIL){
throw new BizException("请选择失败的分账记录");
}
// 更新订单状态 & 记录状态
payOrderDivisionRecordService.updateResendState(record.getPayOrderId());
// 重发到MQ
mqSender.send(PayOrderDivisionMQ.build(record.getPayOrderId(), null, null, true));
return ApiRes.ok(record);
}
}

View File

@ -102,7 +102,7 @@ public class PayOrderDivisionExecController extends ApiController {
}
//处理分账请求
ChannelRetMsg channelRetMsg = payOrderDivisionProcessService.processPayOrderDivision(bizRQ.getPayOrderId(), bizRQ.getUseSysAutoDivisionReceivers(), receiverList);
ChannelRetMsg channelRetMsg = payOrderDivisionProcessService.processPayOrderDivision(bizRQ.getPayOrderId(), bizRQ.getUseSysAutoDivisionReceivers(), receiverList, false);
PayOrderDivisionExecRS bizRS = new PayOrderDivisionExecRS();
bizRS.setState(channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS ? PayOrderDivisionRecord.STATE_SUCCESS : PayOrderDivisionRecord.STATE_FAIL);

View File

@ -39,7 +39,7 @@ public class PayOrderDivisionMQReceiver implements PayOrderDivisionMQ.IMQReceive
try {
log.info("接收订单分账通知MQ, msg={}", payload.toString());
payOrderDivisionProcessService.processPayOrderDivision(payload.getPayOrderId(), payload.getUseSysAutoDivisionReceivers(), payload.getReceiverList());
payOrderDivisionProcessService.processPayOrderDivision(payload.getPayOrderId(), payload.getUseSysAutoDivisionReceivers(), payload.getReceiverList(), payload.getIsResend());
}catch (Exception e) {
log.error(e.getMessage(), e);

View File

@ -72,7 +72,13 @@ public class PayOrderDivisionProcessService {
* @site https://www.jeequan.com
* @date 2021/8/27 9:44
*/
public ChannelRetMsg processPayOrderDivision(String payOrderId, Byte useSysAutoDivisionReceivers, List<PayOrderDivisionMQ.CustomerDivisionReceiver> receiverList) {
public ChannelRetMsg processPayOrderDivision(String payOrderId, Byte useSysAutoDivisionReceivers, List<PayOrderDivisionMQ.CustomerDivisionReceiver> receiverList, Boolean isResend) {
// 是否重发分账接口 当分账失败 列表允许再次发送请求
if(isResend == null){
isResend = false;
}
String logPrefix = "订单["+payOrderId+"]执行分账";
@ -104,38 +110,49 @@ public class PayOrderDivisionProcessService {
throw new BizException("更新支付订单为分账处理中异常");
}
// 查询&过滤 所有的分账接收对象
List<MchDivisionReceiver> allReceiver = this.queryReceiver(useSysAutoDivisionReceivers, payOrder, receiverList);
//得到全部分账比例 (所有待分账账号的分账比例总和)
BigDecimal allDivisionProfit = BigDecimal.ZERO;
for (MchDivisionReceiver receiver : allReceiver) {
allDivisionProfit = allDivisionProfit.add(receiver.getDivisionProfit());
// 所有的分账列表
List<PayOrderDivisionRecord> recordList = null;
// 重发通知可直接查库
if(isResend){
recordList = payOrderDivisionRecordService.list(PayOrderDivisionRecord.gw().eq(PayOrderDivisionRecord::getPayOrderId, payOrderId));
}else{
// 查询&过滤 所有的分账接收对象
List<MchDivisionReceiver> allReceiver = this.queryReceiver(useSysAutoDivisionReceivers, payOrder, receiverList);
//得到全部分账比例 (所有待分账账号的分账比例总和)
BigDecimal allDivisionProfit = BigDecimal.ZERO;
for (MchDivisionReceiver receiver : allReceiver) {
allDivisionProfit = allDivisionProfit.add(receiver.getDivisionProfit());
}
//计算分账金额 = 商家实际入账金额
Long payOrderDivisionAmount = payOrderService.calMchIncomeAmount(payOrder);
//剩余待分账金额 (用作最后一个分账账号的 计算 避免出现分账金额超出最大) [结果向下取整 避免出现金额溢出的情况 ]
Long subDivisionAmount = AmountUtil.calPercentageFee(payOrderDivisionAmount, allDivisionProfit, BigDecimal.ROUND_FLOOR);
recordList = new ArrayList<>();
//计算订单分账金额, 并插入到记录表
String batchOrderId = SeqKit.genDivisionBatchId();
for (MchDivisionReceiver receiver : allReceiver) {
PayOrderDivisionRecord record = genRecord(batchOrderId, payOrder, receiver, payOrderDivisionAmount, subDivisionAmount);
//剩余金额
subDivisionAmount = subDivisionAmount - record.getCalDivisionAmount();
//入库保存
payOrderDivisionRecordService.save(record);
recordList.add(record);
}
}
//计算分账金额 = 商家实际入账金额
Long payOrderDivisionAmount = payOrderService.calMchIncomeAmount(payOrder);
//剩余待分账金额 (用作最后一个分账账号的 计算 避免出现分账金额超出最大) [结果向下取整 避免出现金额溢出的情况 ]
Long subDivisionAmount = AmountUtil.calPercentageFee(payOrderDivisionAmount, allDivisionProfit, BigDecimal.ROUND_FLOOR);
List<PayOrderDivisionRecord> recordList = new ArrayList<>();
//计算订单分账金额, 并插入到记录表
String batchOrderId = SeqKit.genDivisionBatchId();
for (MchDivisionReceiver receiver : allReceiver) {
PayOrderDivisionRecord record = genRecord(batchOrderId, payOrder, receiver, payOrderDivisionAmount, subDivisionAmount);
//剩余金额
subDivisionAmount = subDivisionAmount - record.getCalDivisionAmount();
//入库保存
payOrderDivisionRecordService.save(record);
recordList.add(record);
}
ChannelRetMsg channelRetMsg = null;

View File

@ -1,9 +1,14 @@
package com.jeequan.jeepay.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.PayOrderDivisionRecord;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.service.mapper.PayOrderDivisionRecordMapper;
import com.jeequan.jeepay.service.mapper.PayOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@ -19,6 +24,8 @@ import java.util.List;
@Service
public class PayOrderDivisionRecordService extends ServiceImpl<PayOrderDivisionRecordMapper, PayOrderDivisionRecord> {
@Autowired private PayOrderMapper payOrderMapper;
/** 更新分账记录为分账成功**/
public void updateRecordSuccessOrFail(List<PayOrderDivisionRecord> records, Byte state, String channelBatchOrderId, String channelRespResult){
@ -38,8 +45,32 @@ public class PayOrderDivisionRecordService extends ServiceImpl<PayOrderDivisionR
}
/** 更新分账订单为: 等待分账中的状态 **/
@Transactional
public void updateResendState(String payOrderId){
PayOrder updateRecord = new PayOrder();
updateRecord.setDivisionState(PayOrder.DIVISION_STATE_WAIT_TASK);
// 更新订单
int payOrderUpdateRow = payOrderMapper.update(updateRecord, PayOrder.gw().eq(PayOrder::getPayOrderId, payOrderId).eq(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_FINISH));
if(payOrderUpdateRow <= 0){
throw new BizException("更新订单分账状态失败");
}
PayOrderDivisionRecord updateRecordByDiv = new PayOrderDivisionRecord();
updateRecordByDiv.setState(PayOrderDivisionRecord.STATE_WAIT); //待分账
updateRecordByDiv.setChannelRespResult("");
updateRecordByDiv.setChannelBatchOrderId("");
boolean recordUpdateFlag = update(updateRecordByDiv,
PayOrderDivisionRecord.gw().eq(PayOrderDivisionRecord::getPayOrderId, payOrderId).eq(PayOrderDivisionRecord::getState, PayOrderDivisionRecord.STATE_FAIL)
);
if(!recordUpdateFlag){
throw new BizException("更新分账记录状态失败");
}
}
}