Browse Source

Merge branch 'master' of http://server.kuaiyuman.cn:3000/evolve/car-wash-java

skyline 1 tuần trước cách đây
mục cha
commit
24e68a721a

+ 1 - 1
admin-web/src/views/admin/index.vue

@@ -211,7 +211,7 @@ const initLineChart = (dataList: Array<any>) => {
     item['seq'] = Number(item.statTime.join(""))
   })
 
-  state.homeOneExtra.totalIncome=dataList.reduce((k,v)=>k+v.totalAmount,0);
+  state.homeOneExtra.totalIncome=dataList.reduce((k,v)=>k+v.amountReceived,0);
   state.homeOneExtra.totalWashOrders=dataList.reduce((k,v)=>k+v.totalOrders,0);
   u.sort(dataList, "seq")
 

+ 28 - 51
car-wash-service/src/main/java/com/kym/service/awoara/event/handle/OrderCloseEventHandler.java

@@ -64,39 +64,38 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
 
         int rechargePayment;
         int grantsPayment = 0;
-        // 扣款更新余额(优先扣减充值款,不够则扣除赠款),新增资金流水
         var account = accountService.getAccountByUserId(washOrder.getUserId());
-        int amount = orderInfo.getAmount();
-        if (account.getRechargeBalance() >= amount) {
-            rechargePayment = amount;
+        // 以实收金额扣款(优先扣减充值款,不够则扣除赠款)
+        int amountReceived = orderInfo.getAmount_received();
+        if (account.getRechargeBalance() >= amountReceived) {
+            rechargePayment = amountReceived;
             accountService.lambdaUpdate()
                     .setSql("balance = balance - {0}, recharge_balance = recharge_balance - {1}",
-                            amount, rechargePayment)
+                            amountReceived, rechargePayment)
                     .eq(Account::getUserId, washOrder.getUserId())
                     .update();
         } else {
             // 充值款余额不足以支付订单,则扣赠款
             rechargePayment = account.getRechargeBalance();
-            grantsPayment = amount - account.getRechargeBalance();
+            grantsPayment = amountReceived - account.getRechargeBalance();
             accountService.lambdaUpdate()
                     .setSql("balance = balance - {0}, recharge_balance = 0, grants_balance = grants_balance - {1}",
-                            amount, grantsPayment)
+                            amountReceived, grantsPayment)
                     .eq(Account::getUserId, washOrder.getUserId())
                     .update();
         }
 
         washOrder
                 .setCloseType(orderInfo.getClose_type())
-                .setAmount(amount)
+                .setAmount(orderInfo.getAmount())
                 .setAmountReceivable(orderInfo.getAmount_receivable())
-                .setAmountReceived(orderInfo.getAmount_received())
+                .setAmountReceived(amountReceived)
                 .setDiscountMoney(orderInfo.getDiscount_money())
                 .setDetail(orderInfo.getDetail())
                 .setEndTime(LocalDateTime.now())
                 .setTotalSeconds(Duration.between(washOrder.getStartTime(), LocalDateTime.now()).toSecondsPart())
                 .setRechargePayment(rechargePayment)
                 .setGrantsPayment(grantsPayment)
-                .setOrderStatus(WashOrder.ORDER_STATUS_成功)
                 .setPayStatus(WashOrder.PAY_STATUS_已支付)
                 .setOrderStatus(WashOrder.ORDER_STATUS_成功);
 
@@ -107,23 +106,24 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
             return;
         }
 
-        // t_account减(上面已完成),t_station_account冻结户减,t_station_account商户加,t_split_record记录
-        // 需要判断是否跨网点,分开处理;跨网点结算比例是消费站点分订单额的30%,充值站点分70%
+        // 需要判断是否跨网点,分开处理;跨网点结算比例是消费站点分充值款实收的70%,充值站点保留30%
         if (washOrder.getIsCross()) {
-            // 跨网点订单结算比例是消费站点分订单额的30%,消费站点分70%
             doCrossSplit(washOrder, KymCache.INSTANCE.getUserStationId(washOrder.getUserId()));
         } else {
-            // 不跨网点订单结算比例是消费站点分订单额的100%,消费金额*商家消费分润比例30%-消费金额*平台分润10%=消费金额*(商家消费分润比例-平台分润)
             doLocalSplit(washOrder);
         }
 
+        // 记录资金流水(含赠款明细)
         var walletDetail = new WalletDetail();
         walletDetail.setUserId(washOrder.getUserId());
         walletDetail.setType(WalletDetail.TYPE_消费);
         walletDetail.setOrderNo(washOrder.getOrderId());
-        walletDetail.setAmount(orderInfo.getAmount());
+        walletDetail.setAmount(amountReceived);
+        walletDetail.setGrantsAmount(grantsPayment);
         walletDetail.setBeforeBalance(account.getBalance());
-        walletDetail.setAfterBalance(account.getBalance() - orderInfo.getAmount());
+        walletDetail.setAfterBalance(account.getBalance() - amountReceived);
+        walletDetail.setBeforeGrantsBalance(account.getGrantsBalance());
+        walletDetail.setAfterGrantsBalance(account.getGrantsBalance() - grantsPayment);
         walletDetail.setTransactionId(washOrder.getId().toString());
         walletDetail.setTransactionTime(LocalDateTime.now());
         walletDetail.setStatus(WalletDetail.STATUS_已确认);
@@ -135,9 +135,6 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
         // 更新订单优惠金额
         washOrderService.updateById(washOrder);
 
-        // 扣费等资金操作
-        deductions(washOrder, account);
-
         // 判断消费金额是否达标,达标发送领取停车优惠券消息
         if (orderInfo.getAmount() >= WashOrder.PARKING_COUPON_MIN_AMOUNT) {
             var parkingCouponUrl = KymCache.INSTANCE.getParkingQrCodeUrlByStationId(washOrder.getStationId());
@@ -152,31 +149,6 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
         }
     }
 
-    /**
-     * 扣费等资金操作
-     *
-     * @param washOrder
-     * @param account
-     */
-    @Transactional
-    protected void deductions(WashOrder washOrder, Account account) {
-        // 账户扣费
-        account.setBalance(account.getBalance() - washOrder.getAmountReceived());
-        accountService.updateById(account);
-
-        // 记录资金流水
-        var walletDetail = new WalletDetail();
-        walletDetail.setUserId(washOrder.getUserId());
-        walletDetail.setOrderNo(washOrder.getOrderId());
-        // 消费
-        walletDetail.setType(WalletDetail.TYPE_消费);
-        walletDetail.setAmount(washOrder.getAmountReceivable());
-        walletDetail.setTransactionTime(LocalDateTime.now());
-        // 已确认
-        walletDetail.setStatus(WalletDetail.STATUS_已确认);
-        walletDetailService.save(walletDetail);
-    }
-
     /**
      * 本店消费分账 — V2 结算方案
      * 同店消费不产生分账记录,资金不跨站,在周期结算时统一处理
@@ -191,20 +163,25 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
 
     /**
      * 跨店消费分账 — V2 结算方案
-     * 仅记录跨店支出(消费金额 × 70%)和跨店收入(消费金额 × 70%)
+     * 仅记录跨店支出(充值款实收 × 70%)和跨店收入(充值款实收 × 70%)
      * 平台服务费由结算日统一计算,70:30 拉新奖励比例在此体现
+     * 注意:按充值款实收金额 (rechargePayment) 计算,赠款为平台促销金,不参与站点间转账
      *
      * @param washOrder     洗车订单
      * @param userStationId 用户归属站点(充值方)
      */
     @Transactional
     protected void doCrossSplit(WashOrder washOrder, String userStationId) {
-        log.info("订单:{},执行跨店分账,归属站:{},消费站:{}", washOrder.getOrderId(), userStationId, washOrder.getStationId());
-        int amount = washOrder.getAmount();
+        // 仅以充值款实收金额为跨店转账基数,赠款为平台促销金,不参与站点间转账
+        int rechargePayment = washOrder.getRechargePayment();
+        if (rechargePayment == 0) {
+            log.info("订单:{},充值款支付为0(全部为赠款支付),不产生跨店转账", washOrder.getOrderId());
+            return;
+        }
         BigDecimal crossRate = new BigDecimal("0.7");
-
-        // 跨店转账金额 = 消费金额 × 70%(归属站留30%作为拉新奖励)
-        int crossAmount = crossRate.multiply(BigDecimal.valueOf(amount)).setScale(0, RoundingMode.DOWN).intValue();
+        int crossAmount = crossRate.multiply(BigDecimal.valueOf(rechargePayment)).setScale(0, RoundingMode.DOWN).intValue();
+        log.info("订单:{},执行跨店分账,归属站:{},消费站:{},充值款实收:{},转账金额:{}",
+                washOrder.getOrderId(), userStationId, washOrder.getStationId(), rechargePayment, crossAmount);
 
         // 归属站点跨店支出
         var crossExpend = new SplitRecord()
@@ -223,6 +200,6 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
                 .setType(SplitRecord.TYPE_CROSS_INCOME);
 
         splitRecordService.saveBatch(List.of(crossExpend, crossIncome));
-        log.info("订单:{},跨店分账完成,转账金额:{} 分", washOrder.getOrderId(), crossAmount);
+        log.info("订单:{},跨店分账完成", washOrder.getOrderId());
     }
 }

+ 11 - 5
car-wash-service/src/main/java/com/kym/service/impl/StatServiceImpl.java

@@ -134,8 +134,13 @@ public class StatServiceImpl implements StatService {
        var avgOrderDuration = todayOrders.isEmpty() ? 0 : (int)todayOrders.stream().mapToInt(WashOrder::getTotalSeconds).sum() / todayOrders.size();
 
         // 月度数据
-        var monthAmountMap = washOrderService.sumMonthAmount(LocalDate.now());
-        var monthIncome = monthAmountMap.getOrDefault(stationId, 0);
+        var monthOrders = washOrderService.lambdaQuery()
+                .eq(WashOrder::getStationId, stationId)
+                .ge(WashOrder::getStartTime, LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN))
+                .le(WashOrder::getStartTime, LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX))
+                .list();
+        var monthConsumptionAmount = monthOrders.stream().mapToInt(WashOrder::getAmount).sum();
+        var monthIncome = monthOrders.stream().mapToInt(WashOrder::getAmountReceived).sum();
         var monthRegistrations = userService.countMonthRegister(LocalDate.now());
         var monthOrdersMap = washOrderService.countMonthOrders(LocalDate.now());
 
@@ -143,7 +148,8 @@ public class StatServiceImpl implements StatService {
         var allOrders = washOrderService.lambdaQuery()
                 .eq(WashOrder::getStationId, stationId)
                 .list();
-        var totalIncome = allOrders.stream().mapToInt(WashOrder::getAmount).sum();
+        var totalIncome = allOrders.stream().mapToInt(WashOrder::getAmountReceived).sum();
+        var totalConsumptionAmount = allOrders.stream().mapToInt(WashOrder::getAmount).sum();
         var totalMembers = (int) userService.count();
 
         DashboardVo dashboardVo = new DashboardVo();
@@ -153,12 +159,12 @@ public class StatServiceImpl implements StatService {
         dashboardVo.setTodayRegisteredMembers(CommUtil.isEmptyOrNull(todayRegistrations) ? 0 : todayRegistrations.getOrDefault(stationId, 0));
 
         dashboardVo.setMonthIncome(monthIncome);
-        dashboardVo.setMonthConsumptionAmount(monthIncome);
+        dashboardVo.setMonthConsumptionAmount(monthConsumptionAmount);
         dashboardVo.setMonthRegisteredMembers(monthRegistrations.getOrDefault(stationId, 0));
         dashboardVo.setMonthWashOrders(monthOrdersMap.getOrDefault(stationId, 0));
 
         dashboardVo.setTotalIncome(totalIncome);
-        dashboardVo.setTotalConsumptionAmount(totalIncome);
+        dashboardVo.setTotalConsumptionAmount(totalConsumptionAmount);
         dashboardVo.setTotalWashOrders(allOrders.size());
         dashboardVo.setTotalRegisteredMembers(totalMembers);
 

+ 12 - 1
car-wash-service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

@@ -16,6 +16,7 @@ import com.kym.common.utils.OrderUtils;
 import com.kym.entity.Account;
 import com.kym.entity.*;
 import com.kym.service.*;
+import com.kym.service.cache.KymCache;
 import com.kym.service.wechat.WxPayService;
 import com.wechat.pay.java.core.Config;
 import com.wechat.pay.java.core.RSAAutoCertificateConfig;
@@ -616,6 +617,16 @@ public class WxPayServiceImpl implements WxPayService {
                         .eq(WalletDetail::getId, walletDetail.getId()).update();
                 LOGGER.info("微信退款回调{}:业务处理结束", notifyRes[2]);
 
+                // V2 结算方案:记录退款分账流水,结算时扣除
+                var stationId = KymCache.INSTANCE.getUserStationId(refundLog.getUserId());
+                var refundSplit = new SplitRecord()
+                        .setFromStationId(stationId)
+                        .setToStationId(stationId)
+                        .setTradeNo(refundNotification.getTransactionId())
+                        .setAmount(refundNotification.getAmount().getRefund().intValue())
+                        .setType(SplitRecord.TYPE_REFUND);
+                splitRecordService.save(refundSplit);
+
                 return ResponseEntity.status(HttpStatus.OK).build();
             } else {
                 // 退款失败
@@ -632,4 +643,4 @@ public class WxPayServiceImpl implements WxPayService {
     //================================================================发票=====================================================================
 
 
-}
+}