|
|
@@ -62,6 +62,8 @@ import jakarta.servlet.http.HttpServletRequest;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.Setter;
|
|
|
import org.apache.http.util.TextUtils;
|
|
|
+import org.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
@@ -81,6 +83,7 @@ import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
@@ -136,6 +139,8 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
|
|
|
|
|
|
private final OrderStateListener orderStateListener;
|
|
|
|
|
|
+ private final RedissonClient redissonClient;
|
|
|
+
|
|
|
@Autowired
|
|
|
private InsOrdersQrcodeMapper insOrdersQrcodeMapper;
|
|
|
|
|
|
@@ -718,7 +723,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
|
|
|
List<InsOrdersPolicy> list = insOrdersPolicyService.list(wrapper);
|
|
|
if(list != null && !list.isEmpty()){
|
|
|
// 修改订单时,排除原订单的问题
|
|
|
- if(!list.get(0).getOrderNo().equals(insOrdersExternalPolicy.getOrderNo())){
|
|
|
+ if(!list.get(0).getOrderNo().equals(ordersEnd.getInsOrders().getId())){
|
|
|
return HttpResult.error("该交强险保单号信息已存在!");
|
|
|
}
|
|
|
}
|
|
|
@@ -728,7 +733,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
|
|
|
wrapper.eq(InsOrdersPolicy::getSyPolicyNo, insOrdersExternalPolicy.getSyPolicy());
|
|
|
List<InsOrdersPolicy> list = insOrdersPolicyService.list(wrapper);
|
|
|
if(list != null && !list.isEmpty()){
|
|
|
- if(!list.get(0).getOrderNo().equals(insOrdersExternalPolicy.getOrderNo())){
|
|
|
+ if(!list.get(0).getOrderNo().equals(ordersEnd.getInsOrders().getId())){
|
|
|
return HttpResult.error("该商业保单号信息已存在!");
|
|
|
}
|
|
|
}
|
|
|
@@ -1759,6 +1764,44 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 生成订单(带分布式锁):同车+同险种并发时串行,保证只有一个主订单,其余为子订单
|
|
|
+ * 锁粒度:车牌+车架+险种(不含保司,因为同车同险种只允许一个主订单)
|
|
|
+ * 锁释放在事务提交后(外层方法非事务,内层 generateOrders 事务返回时已提交)
|
|
|
+ *
|
|
|
+ * @param quoteVo 报价参数
|
|
|
+ * @param companyName 保司名称
|
|
|
+ * @param systemCode 系统编码
|
|
|
+ * @param productId 产品ID
|
|
|
+ * @return 子订单号
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String generateOrdersWithLock(QuoteVo quoteVo, String companyName, String systemCode, String productId) {
|
|
|
+ String licenseNo = quoteVo.getCarInfoVo().getLicenseNo();
|
|
|
+ String vinNo = quoteVo.getCarInfoVo().getVinNo();
|
|
|
+ // 锁 key:车+险种(同车同险种串行)
|
|
|
+ String lockKey = "order:generate:" + licenseNo + ":" + vinNo + ":" + productId;
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 等锁 3 秒,持锁 30 秒(覆盖事务提交)
|
|
|
+ boolean locked = lock.tryLock(10, 30, TimeUnit.SECONDS);
|
|
|
+ if (!locked) {
|
|
|
+ log.warn("生成订单获取锁失败,lockKey=[{}]", lockKey);
|
|
|
+ throw new SystemException("订单生成中,请稍后重试");
|
|
|
+ }
|
|
|
+ // 调用事务方法,return 后事务已提交,再释放锁
|
|
|
+ return this.generateOrders(quoteVo, companyName, systemCode, productId);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ throw new SystemException("生成订单被中断");
|
|
|
+ } finally {
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 生成一个主订单和多个子订单
|
|
|
*
|
|
|
@@ -2250,9 +2293,13 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
|
|
|
BigDecimal jqAddThrow = nvl(request.getJqAddThrow());
|
|
|
BigDecimal syAddThrow = nvl(request.getSyAddThrow());
|
|
|
BigDecimal jyAddThrow = nvl(request.getJyAddThrow());
|
|
|
- BigDecimal jqExport = this.calExportByIsRecordByLeader(request.isIsrecordByLeader(), nvl(request.getJqExport()));
|
|
|
- BigDecimal syExport = this.calExportByIsRecordByLeader(request.isIsrecordByLeader(), nvl(request.getSyExport()));
|
|
|
- BigDecimal jyExport = this.calExportByIsRecordByLeader(request.isIsrecordByLeader(), nvl(request.getJyExport()));
|
|
|
+ // 代课录单扣减1
|
|
|
+
|
|
|
+ BigDecimal jqExport = nvl(request.getJqExport());
|
|
|
+ BigDecimal syExport = nvl(request.getSyExport());
|
|
|
+ BigDecimal jyExport = nvl(request.getJyExport());
|
|
|
+
|
|
|
+
|
|
|
|
|
|
BigDecimal jqEKP = nvl(request.getJqKeepPointRatio());
|
|
|
BigDecimal syEKP = nvl(request.getSyKeepPointRatio());
|
|
|
@@ -2339,13 +2386,15 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
|
|
|
feeOrders.setSyKeepPointRatio(div100(nvl(feeOrders.getSyKeepPointRatio())));
|
|
|
feeOrders.setJyKeepPointRatio(div100(nvl(feeOrders.getJyKeepPointRatio())));
|
|
|
|
|
|
- // 出口比例 = 入口比例 +加投比例 - 分销比例 -留点比例
|
|
|
+ // 出口比例 = 入口比例 +加投比例 - 分销比例 -留点比例-代课录单比例
|
|
|
BigDecimal firstDist = nvl(feeOrders.getFirstDistributionRatio());
|
|
|
BigDecimal secondDist = nvl(feeOrders.getSecondDistributionRatio());
|
|
|
BigDecimal thirdDist = nvl(feeOrders.getThirdDistributionRatio());
|
|
|
- feeOrders.setJqExportRatio(jqInlet.compareTo(BigDecimal.ZERO) > 0 ? div100(jqInlet).add(div100(request.getJqAddThrow())).subtract(div100(firstDist)).subtract(div100(secondDist)).subtract(div100(thirdDist)).subtract(div100(jqEKP)) : BigDecimal.ZERO);
|
|
|
- feeOrders.setSyExportRatio(syInlet.compareTo(BigDecimal.ZERO) > 0 ? div100(syInlet).add(div100(request.getSyAddThrow())).subtract(div100(firstDist)).subtract(div100(secondDist)).subtract(div100(thirdDist)).subtract(div100(syEKP)) : BigDecimal.ZERO);
|
|
|
- feeOrders.setJyExportRatio(jyInlet.compareTo(BigDecimal.ZERO) > 0 ? div100(jyInlet).add(div100(request.getJyAddThrow())).subtract(div100(firstDist)).subtract(div100(secondDist)).subtract(div100(thirdDist)).subtract(div100(jyEKP)) : BigDecimal.ZERO);
|
|
|
+ // 代课录单比例
|
|
|
+ BigDecimal IsrecordByLeader = request.isIsrecordByLeader() ? new BigDecimal("0.01") :BigDecimal.ZERO;
|
|
|
+ feeOrders.setJqExportRatio(jqInlet.compareTo(BigDecimal.ZERO) > 0 ? div100(jqInlet).add(div100(request.getJqAddThrow())).subtract(div100(firstDist)).subtract(div100(secondDist)).subtract(div100(thirdDist)).subtract(div100(jqEKP)).subtract(IsrecordByLeader) : BigDecimal.ZERO);
|
|
|
+ feeOrders.setSyExportRatio(syInlet.compareTo(BigDecimal.ZERO) > 0 ? div100(syInlet).add(div100(request.getSyAddThrow())).subtract(div100(firstDist)).subtract(div100(secondDist)).subtract(div100(thirdDist)).subtract(div100(syEKP)).subtract(IsrecordByLeader) : BigDecimal.ZERO);
|
|
|
+ feeOrders.setJyExportRatio(jyInlet.compareTo(BigDecimal.ZERO) > 0 ? div100(jyInlet).add(div100(request.getJyAddThrow())).subtract(div100(firstDist)).subtract(div100(secondDist)).subtract(div100(thirdDist)).subtract(div100(jyEKP)).subtract(IsrecordByLeader) : BigDecimal.ZERO);
|
|
|
|
|
|
feeOrders.setJqExportKeepPointRatio(div100(request.getJqExportKeepPointRatio()!=null? request.getJqExportKeepPointRatio() : new BigDecimal(0)));
|
|
|
feeOrders.setSyExportKeepPointRatio(div100(request.getSyExportKeepPointRatio()!=null? request.getSyExportKeepPointRatio() : new BigDecimal(0)));
|