Răsfoiți Sursa

律师端创建订单,计算收益

zhangchen 1 lună în urmă
părinte
comite
e75820e23f

+ 152 - 36
alien-store/src/main/java/shop/alien/store/service/impl/LawyerConsultationOrderServiceImpl.java

@@ -395,49 +395,165 @@ public class LawyerConsultationOrderServiceImpl extends ServiceImpl<LawyerConsul
     }*/
 
 
+    /**
+     * 默认佣金率(百分比)
+     */
+    private static final int DEFAULT_COMMISSION_RATE = 3;
+    
+    /**
+     * 订单号生成最大重试次数
+     */
+    private static final int MAX_ORDER_NUMBER_RETRY = 5;
+    
+    /**
+     * 订单支付超时时间(秒),30分钟
+     */
+    private static final long ORDER_PAYMENT_TIMEOUT_SECONDS = 30 * 60;
+
+    /**
+     * 立即咨询 - 创建咨询订单
+     * <p>
+     * 创建订单前会进行以下校验:
+     * 1. 参数校验:客户端用户ID、律师用户ID、订单金额不能为空
+     * 2. 律师信息校验:律师必须存在且未被删除
+     * 3. 订单号唯一性校验:确保生成的订单号唯一
+     * </p>
+     * <p>
+     * 创建订单后会:
+     * 1. 计算咨询费用(根据律师佣金率)
+     * 2. 设置订单支付超时监听(30分钟)
+     * </p>
+     *
+     * @param lawyerConsultationOrder 咨询订单信息
+     * @return 创建结果
+     */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R<LawyerConsultationOrderDto> consultNow(LawyerConsultationOrder lawyerConsultationOrder) {
-        log.info("LawyerConsultationOrderController.consultNow?lawyerConsultationOrder={}", lawyerConsultationOrder);
-         LawyerConsultationOrderDto order = new LawyerConsultationOrderDto();
-        order.setClientUserId(lawyerConsultationOrder.getClientUserId());
-        order.setLawyerUserId(lawyerConsultationOrder.getLawyerUserId());
-        order.setProblemScenarioId(lawyerConsultationOrder.getProblemScenarioId());
-        order.setProblemDescription(lawyerConsultationOrder.getProblemDescription());
-        order.setOrderAmount(lawyerConsultationOrder.getOrderAmount());
-        order.setOrderStatus(0);
-        order.setPaymentStatus(0);
-        order.setOrderTime(new Date());
-//        order.setValidityPeriod(DateUtils.addDays(new Date(), 7));
-        order.setCreatedTime(new Date());
-        order.setUpdatedTime(new Date());
-        order.setDeleteFlag(0);
-        order.setAlipayNo(lawyerConsultationOrder.getAlipayNo());
-        order.setOrderStr(lawyerConsultationOrder.getOrderStr());
-        //订单编号想要LAW+年月日(8位数字)+随机5位数字这种格式的
-        String orderNumber = "LAW" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + String.format("%05d", RandomUtils.nextInt(100000));
-        order.setOrderNumber(orderNumber);
-        //计算本单收益
-        LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerConsultationOrder.getLawyerUserId());
-        if(lawyerUser != null){
+        log.info("开始创建咨询订单,clientUserId={}, lawyerUserId={}, orderAmount={}", 
+                lawyerConsultationOrder.getClientUserId(), 
+                lawyerConsultationOrder.getLawyerUserId(),
+                lawyerConsultationOrder.getOrderAmount());
+        
+        try {
+            // 1. 参数校验
+            if (lawyerConsultationOrder.getClientUserId() == null) {
+                log.warn("创建咨询订单失败:客户端用户ID为空");
+                return R.fail("客户端用户ID不能为空");
+            }
+            if (lawyerConsultationOrder.getLawyerUserId() == null) {
+                log.warn("创建咨询订单失败:律师用户ID为空");
+                return R.fail("律师用户ID不能为空");
+            }
+            if (lawyerConsultationOrder.getOrderAmount() == null || 
+                lawyerConsultationOrder.getOrderAmount().compareTo(BigDecimal.ZERO) <= 0) {
+                log.warn("创建咨询订单失败:订单金额无效,orderAmount={}", lawyerConsultationOrder.getOrderAmount());
+                return R.fail("订单金额必须大于0");
+            }
+            
+            // 2. 校验律师信息
+            LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerConsultationOrder.getLawyerUserId());
+            if (lawyerUser == null) {
+                log.warn("创建咨询订单失败:律师不存在,lawyerUserId={}", lawyerConsultationOrder.getLawyerUserId());
+                return R.fail("律师不存在");
+            }
+            if (lawyerUser.getDeleteFlag() != null && lawyerUser.getDeleteFlag() == 1) {
+                log.warn("创建咨询订单失败:律师已被删除,lawyerUserId={}", lawyerConsultationOrder.getLawyerUserId());
+                return R.fail("律师已被删除");
+            }
+            
+            // 3. 创建订单对象
+            LawyerConsultationOrderDto order = new LawyerConsultationOrderDto();
+            BeanUtils.copyProperties(lawyerConsultationOrder, order);
+            
+            // 4. 设置订单基本信息
+            Date now = new Date();
+            order.setOrderStatus(LawyerStatusEnum.WAIT_PAY.getStatus()); // 待支付
+            order.setPaymentStatus(0); // 未支付
+            order.setOrderTime(now);
+            order.setCreatedTime(now);
+            order.setUpdatedTime(now);
+            order.setDeleteFlag(0);
+            
+            // 5. 生成唯一订单号
+            String orderNumber = generateUniqueOrderNumber();
+            order.setOrderNumber(orderNumber);
+            log.info("生成订单号:{}", orderNumber);
+            
+            // 6. 计算咨询费用(根据律师佣金率)
             Integer commissionRate = lawyerUser.getCommissionRate();
-            int rate = commissionRate!=null&&commissionRate>0?commissionRate:3;
-            BigDecimal orderAmount =  lawyerConsultationOrder.getOrderAmount();
-            BigDecimal result2 = orderAmount.multiply(new BigDecimal(rate/100))
+            int rate = (commissionRate != null && commissionRate > 0) ? commissionRate : DEFAULT_COMMISSION_RATE;
+            BigDecimal orderAmount = lawyerConsultationOrder.getOrderAmount();
+            // 修复计算逻辑:使用 BigDecimal 进行精确计算
+            BigDecimal rateDecimal = new BigDecimal(rate).divide(new BigDecimal(100), 4, RoundingMode.HALF_UP);
+            BigDecimal platformFee = orderAmount.multiply(rateDecimal)
                     .setScale(0, RoundingMode.HALF_UP);
-            order.setConsultationFee(result2.intValue());
-        }
-        int num = consultationOrderMapper.insertOrder(order);
-
+            BigDecimal consultationFee = orderAmount.subtract(platformFee);
 
-//        boolean result = this.save(order);
-//        if (result) {
-//            return R.data(order);
-//        }
-//        return R.fail("新增失败");
-        if (num >0){
+            order.setConsultationFee(consultationFee.intValue());
+            log.info("计算咨询费用:订单金额={}, 佣金率={}%, 咨询费用={}", 
+                    orderAmount, rate, consultationFee);
+            
+            // 7. 插入订单
+            int insertResult = consultationOrderMapper.insertOrder(order);
+            if (insertResult <= 0) {
+                log.error("创建咨询订单失败:数据库插入失败,订单号={}", orderNumber);
+                return R.fail("创建订单失败");
+            }
+            
+            // 8. 设置订单支付超时监听(30分钟)
+            try {
+                orderExpirationService.setOrderPaymentTimeout(orderNumber, ORDER_PAYMENT_TIMEOUT_SECONDS);
+                log.info("已设置订单支付超时监听,订单号={}, 超时时间={}秒", orderNumber, ORDER_PAYMENT_TIMEOUT_SECONDS);
+            } catch (Exception e) {
+                log.error("设置订单支付超时监听失败,订单号={}", orderNumber, e);
+                // 不影响订单创建,仅记录日志
+            }
+            
+            log.info("创建咨询订单成功,订单号={}, 订单ID={}", orderNumber, order.getId());
             return R.data(order);
+            
+        } catch (Exception e) {
+            log.error("创建咨询订单异常", e);
+            return R.fail("创建订单失败:" + e.getMessage());
         }
-        return R.fail("新增失败");
+    }
+    
+    /**
+     * 生成唯一的订单号
+     * 格式:LAW + 年月日(8位数字)+ 随机5位数字
+     * 如果订单号已存在,会重试生成(最多重试5次)
+     *
+     * @return 唯一的订单号
+     */
+    private String generateUniqueOrderNumber() {
+        String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
+        String prefix = "LAW" + dateStr;
+        
+        for (int i = 0; i < MAX_ORDER_NUMBER_RETRY; i++) {
+            // 生成5位随机数字
+            int randomNum = RandomUtils.nextInt(100000);
+            String orderNumber = prefix + String.format("%05d", randomNum);
+            
+            // 检查订单号是否已存在
+            LambdaQueryWrapper<LawyerConsultationOrder> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(LawyerConsultationOrder::getOrderNumber, orderNumber)
+                       .last("LIMIT 1");
+            LawyerConsultationOrder existingOrder = consultationOrderMapper.selectOne(queryWrapper);
+            
+            if (existingOrder == null) {
+                // 订单号唯一,返回
+                return orderNumber;
+            }
+            
+            log.warn("订单号已存在,重新生成,orderNumber={}, retry={}", orderNumber, i + 1);
+        }
+        
+        // 如果重试5次后仍然重复,使用时间戳确保唯一性
+        String timestamp = String.valueOf(System.currentTimeMillis());
+        String fallbackOrderNumber = prefix + timestamp.substring(timestamp.length() - 5);
+        log.warn("订单号生成重试{}次后仍重复,使用时间戳生成:{}", MAX_ORDER_NUMBER_RETRY, fallbackOrderNumber);
+        return fallbackOrderNumber;
     }