批量收款接口开发;
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package com.mhd.bms.interfaces.facadeApi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -56,6 +58,11 @@ public class ReceiptManageApi extends BaseController{
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
/**
|
||||
* 排队批量收款-获取账单锁的最大等待时间(秒),等待期内排队获取锁,避免并发收款直接失败
|
||||
*/
|
||||
private static final long QUEUE_COLLECTION_LOCK_WAIT_SECONDS = 30L;
|
||||
|
||||
/**
|
||||
* 分页查询收款单管理列表
|
||||
*/
|
||||
@@ -115,6 +122,79 @@ public class ReceiptManageApi extends BaseController{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 排队批量收款
|
||||
* 接收多个批量收款请求参数集合,按顺序排队依次处理;
|
||||
* 同一账单分多次收款时前一笔处理完成后才处理下一笔,避免redis锁冲突导致收款失败
|
||||
*/
|
||||
@ApiOperation("排队批量收款")
|
||||
@RepeatSubmit
|
||||
@PostMapping("/queueBatchCollection")
|
||||
public AjaxResult queueBatchCollection(@RequestBody List<ReceiptManageDTO> receiptManageDTOList)
|
||||
{
|
||||
if(StringUtils.isEmpty(receiptManageDTOList)){
|
||||
throw new ServiceException("收款账单不能为空");
|
||||
}
|
||||
List<Map<String, Object>> collectionResultList = new ArrayList<>();
|
||||
for (ReceiptManageDTO receiptManageDTO : receiptManageDTOList) {
|
||||
collectionResultList.add(handleQueueBatchCollection(receiptManageDTO));
|
||||
}
|
||||
boolean allSuccess = collectionResultList.stream().allMatch(item -> Boolean.TRUE.equals(item.get("success")));
|
||||
if (allSuccess) {
|
||||
return AjaxResult.success("收款成功", collectionResultList);
|
||||
}
|
||||
return AjaxResult.error("部分收款失败,请查看收款结果明细", collectionResultList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 排队批量收款-处理单个收款请求(排队获取账单锁,每笔收款独立处理,单笔失败不影响后续请求)
|
||||
*/
|
||||
private Map<String, Object> handleQueueBatchCollection(ReceiptManageDTO receiptManageDTO) {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("billManageIds", receiptManageDTO.getBillManageIds());
|
||||
RedissonMultiLock redissonMultiLock = null;
|
||||
boolean payInfoDetailLock = false;
|
||||
try {
|
||||
if(!StringUtils.isNotEmpty(receiptManageDTO.getBillManageIds())){
|
||||
throw new ServiceException("收款账单不能为空");
|
||||
}
|
||||
RedisLockTypeEnum redisLockTypeEnum = RedisLockTypeEnum.BMS;
|
||||
List<RLock> locks = new ArrayList<>();
|
||||
Set<String> billingSet = Stream.of(receiptManageDTO.getBillManageIds().split(",")).collect(Collectors.toSet());
|
||||
billingSet.forEach(x -> {
|
||||
//获取唯一key值
|
||||
String key = redisLockTypeEnum.getUniqueKey(UniqueKeyUtil.getBillingKey(x.toString()));
|
||||
locks.add(redisLock.getRLock(key));
|
||||
});
|
||||
redissonMultiLock = new RedissonMultiLock(locks.toArray(new RLock[billingSet.size()]));
|
||||
//尝试获取锁 等待指定时间内排队获取 持有锁10分钟
|
||||
payInfoDetailLock = redissonMultiLock.tryLock(QUEUE_COLLECTION_LOCK_WAIT_SECONDS, 10, TimeUnit.MINUTES);
|
||||
if (!payInfoDetailLock) {
|
||||
redissonMultiLock = null;
|
||||
result.put("success", false);
|
||||
result.put("message", "账单正在处理,请稍后再试");
|
||||
return result;
|
||||
}
|
||||
log.info("排队批量收款-生成账单加锁成功");
|
||||
//转换实体
|
||||
ReceiptManageDO receiptManageDO = new ReceiptManageDO();
|
||||
BeanUtils.copyProperties(receiptManageDTO,receiptManageDO);
|
||||
Boolean flag = receiptManageApplicationService.batchCollection(receiptManageDO);
|
||||
result.put("success", Boolean.TRUE.equals(flag));
|
||||
result.put("message", Boolean.TRUE.equals(flag) ? "收款成功" : "收款失败");
|
||||
return result;
|
||||
}catch (Exception e){
|
||||
result.put("success", false);
|
||||
result.put("message", "收款失败" + e.getMessage());
|
||||
return result;
|
||||
}finally {
|
||||
if (redissonMultiLock != null && payInfoDetailLock) {
|
||||
redissonMultiLock.unlock();
|
||||
log.info("排队批量收款-生成账单释放了锁");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销收款
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user