From c74a6f59490cfb9a0ee37f70427739b74e7fbd58 Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期三, 20 五月 2026 08:50:29 +0800
Subject: [PATCH] 代码生成

---
 server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java | 1689 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 1,505 insertions(+), 184 deletions(-)

diff --git a/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
index 98de8c6..3524470 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
@@ -1,15 +1,19 @@
 package com.doumee.service.business.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.doumee.biz.system.AreasBiz;
+import com.doumee.config.xyy.XyyConfig;
+import com.doumee.config.xyy.dto.PrintRequest;
 import com.doumee.biz.system.OperationConfigBiz;
 import com.doumee.biz.system.SystemDictDataBiz;
 import com.doumee.config.wx.WxMiniConfig;
 import com.doumee.config.wx.WxPayProperties;
 import com.doumee.config.wx.WxPayV3Service;
+import com.doumee.core.utils.jpush.JPushUtil;
 import com.wechat.pay.java.service.refund.model.Refund;
 import com.doumee.core.constants.Constants;
 import com.doumee.core.constants.ResponseStatus;
@@ -17,6 +21,8 @@
 import com.doumee.core.model.PageData;
 import com.doumee.core.model.PageWrap;
 import com.doumee.core.utils.DateUtil;
+import com.doumee.core.utils.GeoUtils;
+import com.doumee.core.utils.ID;
 import com.doumee.core.utils.geocode.MapUtil;
 import com.doumee.core.utils.Utils;
 import com.doumee.core.utils.aliyun.AliSmsService;
@@ -30,6 +36,8 @@
 import com.doumee.dao.dto.CommentOrderDTO;
 import com.doumee.dao.dto.CreateOrderDTO;
 import com.doumee.dao.dto.DispatchDTO;
+import com.doumee.dao.dto.HandleOrderExceptionDTO;
+import com.doumee.dao.dto.ManualRefundDTO;
 import com.doumee.dao.dto.MyOrderDTO;
 import com.doumee.dao.dto.OrderItemDTO;
 import com.doumee.dao.vo.*;
@@ -44,6 +52,7 @@
 import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,6 +63,7 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
+import java.text.SimpleDateFormat;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -104,6 +114,9 @@
     @Autowired
     private RevenueMapper revenueMapper;
 
+    @Autowired
+    private RewardRecordMapper rewardRecordMapper;
+
 
 
     @Autowired
@@ -119,6 +132,9 @@
     private RedisTemplate<String, Object> redisTemplate;
 
     @Autowired
+    private MemberCouponMapper memberCouponMapper;
+
+    @Autowired
     private AreasBiz areasBiz;
 
     @Autowired
@@ -126,6 +142,9 @@
 
     @Autowired
     private AreasService areasService;
+
+    @Autowired
+    private AreasMapper aareasMapper;
 
     @Autowired
     private NoticeService noticeService;
@@ -138,6 +157,12 @@
 
     @Autowired
     private WxPayProperties wxPayProperties;
+
+    @Autowired
+    private XyyConfig xyyConfig;
+
+    @Autowired
+    private PrintService printService;
 
     @Override
     public Integer create(Orders orders) {
@@ -212,16 +237,15 @@
                 .leftJoin(Category.class, Category::getId, Orders::getGoodType)
                 .leftJoin(DriverInfo.class, DriverInfo::getId, Orders::getAcceptDriver)
                 .leftJoin("shop_info s1 on s1.id = t.DEPOSIT_SHOP_ID")
-                .leftJoin("shop_info s2 on s2.id = t.TAKE_SHOP_ID");
+                .leftJoin("shop_info s2 on s2.id = t.TAKE_SHOP_ID") ;
                 ;
         Utils.MP.blankToNull(pageWrap.getModel());
-        pageWrap.getModel().setDeleted(Constants.ZERO);
         queryWrapper.eq(pageWrap.getModel().getDeleted() != null, Orders::getDeleted, pageWrap.getModel().getDeleted());
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCode()), Orders::getCode, pageWrap.getModel().getCode());
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getDepositShopName()), "s1.name", pageWrap.getModel().getDepositShopName());
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getTakeShopName()),  "s2.name",  pageWrap.getModel().getTakeShopName());
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getGoodsInfo()), Orders::getGoodsInfo, pageWrap.getModel().getGoodsInfo());
-        queryWrapper.ge(pageWrap.getModel().getCreateStartTime() != null, Orders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateStartTime()));
+        queryWrapper.ge(pageWrap.getModel().getCreateStartTime() != null, Orders::getCreateTime, pageWrap.getModel().getCreateStartTime());
         queryWrapper.le(pageWrap.getModel().getCreateEndTime() != null, Orders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateEndTime()));
         queryWrapper.eq(pageWrap.getModel().getDepositShopId() != null, Orders::getDepositShopId, pageWrap.getModel().getDepositShopId());
         queryWrapper.eq(pageWrap.getModel().getType() != null, Orders::getType, pageWrap.getModel().getType());
@@ -230,14 +254,26 @@
         queryWrapper.and(pageWrap.getModel().getDriverKeyword() != null, i->i.like(DriverInfo::getName, pageWrap.getModel().getDriverKeyword())
                 .or().like(DriverInfo::getTelephone, pageWrap.getModel().getDriverKeyword()));
         queryWrapper.eq(pageWrap.getModel().getSettlementStatus() != null, Orders::getSettlementStatus, pageWrap.getModel().getSettlementStatus());
-        for (PageWrap.SortData sortData : pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
+        queryWrapper.eq(pageWrap.getModel().getAcceptDriver() != null, Orders::getAcceptDriver, pageWrap.getModel().getAcceptDriver());
+        queryWrapper.and(pageWrap.getModel().getShopId() != null, i -> i.eq(Orders::getDepositShopId, pageWrap.getModel().getShopId())
+                .or().eq(Orders::getTakeShopId, pageWrap.getModel().getShopId()));
+        queryWrapper.orderByDesc(Orders::getId);
+        PageData<Orders> pageData = PageData.from(ordersMapper.selectJoinPage(page, Orders.class, queryWrapper));
+        for (Orders o : pageData.getRecords()) {
+            if (o.getStatus() != null) {
+                Constants.OrderStatus os = Constants.OrderStatus.getByKey(o.getStatus());
+                o.setStatusDesc(os != null ? os.getValue() : "");
             }
+            if(Constants.equalsInteger(o.getIsUrgent(),Constants.ZERO)){
+                o.setUrgentAmount(Constants.ZERO.longValue());
+            }
+            // 瀹炰粯閲戦 = 鏀粯閲戦 - 閫�娆鹃噾棰� + 閫炬湡璐圭敤
+            long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+            long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+            long overdue = o.getOverdueAmount() != null ? o.getOverdueAmount() : 0L;
+            o.setPayAmount(pay - refund + overdue);
         }
-        return PageData.from(ordersMapper.selectJoinPage(page, Orders.class, queryWrapper));
+        return pageData;
     }
 
     @Override
@@ -255,8 +291,8 @@
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getDepositShopName()), "s1.name", pageWrap.getModel().getDepositShopName());
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getTakeShopName()),  "s2.name",  pageWrap.getModel().getTakeShopName());
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getGoodsInfo()), Orders::getGoodsInfo, pageWrap.getModel().getGoodsInfo());
-        queryWrapper.ge(pageWrap.getModel().getCreateStartTime() != null, Orders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateStartTime()));
-        queryWrapper.le(pageWrap.getModel().getCreateEndTime() != null, Orders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateEndTime()));
+        queryWrapper.ge(pageWrap.getModel().getCreateStartTime() != null, Orders::getCreateTime, pageWrap.getModel().getCreateStartTime());
+        queryWrapper.le(pageWrap.getModel().getCreateEndTime() != null, Orders::getCreateTime, pageWrap.getModel().getCreateEndTime());
         queryWrapper.eq(pageWrap.getModel().getDepositShopId() != null, Orders::getDepositShopId, pageWrap.getModel().getDepositShopId());
         queryWrapper.eq(pageWrap.getModel().getType() != null, Orders::getType, pageWrap.getModel().getType());
         queryWrapper.eq(pageWrap.getModel().getStatus() != null, Orders::getStatus, pageWrap.getModel().getStatus());
@@ -264,6 +300,9 @@
         queryWrapper.and(pageWrap.getModel().getDriverKeyword() != null, i->i.like(DriverInfo::getName, pageWrap.getModel().getDriverKeyword())
                 .or().like(DriverInfo::getTelephone, pageWrap.getModel().getDriverKeyword()));
         queryWrapper.eq(pageWrap.getModel().getSettlementStatus() != null, Orders::getSettlementStatus, pageWrap.getModel().getSettlementStatus());
+        queryWrapper.eq(pageWrap.getModel().getAcceptDriver() != null, Orders::getAcceptDriver, pageWrap.getModel().getAcceptDriver());
+        queryWrapper.and(pageWrap.getModel().getShopId() != null, i -> i.eq(Orders::getDepositShopId, pageWrap.getModel().getShopId())
+                .or().eq(Orders::getTakeShopId, pageWrap.getModel().getShopId()));
 
         queryWrapper.select(
                 "IFNULL(SUM(t.total_amount), 0) as total_amount_sum",
@@ -354,7 +393,7 @@
         for (Category c : categories) {
             categoryNameMap.put(c.getId(), c.getName());
             categoryDetailMap.put(c.getId(), c.getDetail());
-            categoryOtherFieldMap.put(c.getId(),c.getOtherField());
+            categoryOtherFieldMap.put(c.getId(),c.getRemark());
         }
 
         // 璁$畻姣忛」鐗╁搧璐圭敤锛氬皬璁� = 鍗曚环 脳 鏁伴噺 脳 澶╂暟
@@ -401,6 +440,7 @@
         result.setTotalPrice(totalPrice);
         result.setDays(days);
         result.setUrgentFee(0L);
+        resolveCoupon(result, dto.getMemberId(), dto.getCouponId(), totalPrice);
         return result;
     }
 
@@ -476,12 +516,13 @@
         for (Category c : categories) {
             categoryNameMap.put(c.getId(), c.getName());
             categoryDetailMap.put(c.getId(), c.getDetail());
-            categoryOtherFieldMap.put(c.getId(),c.getOtherField());
+            categoryOtherFieldMap.put(c.getId(),c.getRemark());
         }
 
         // 3. 閫愰」璁$畻杩愯垂锛氳捣姝ヤ环 + 瓒呭嚭閮ㄥ垎闃舵浠�
         List<ItemPriceVO> itemList = new ArrayList<>();
         long itemPriceTotal = 0L;
+        long maxExtraFeeTotal = 0L; // 鏈�澶ц秴鍑鸿窛绂昏垂鐢紙鍗曚环脳鏁伴噺锛�
 
         for (OrderItemDTO item : dto.getItems()) {
             PricingRule rule = ruleMap.get(String.valueOf(item.getCategoryId()));
@@ -497,13 +538,15 @@
             long extraPricePerUnit = Long.parseLong(rule.getFieldE());
 
             // 闃舵璁′环锛氳窛绂� 鈮� 璧锋璺濈鍙栬捣姝ヤ环锛岃秴鍑烘寜 ceil(瓒呭嚭璺濈/鍗曚綅) 脳 鍗曚环绱姞
+            long extraFee = 0L;
             long unitPrice;
             if (distanceKm.compareTo(startDistance) <= 0) {
                 unitPrice = startPrice;
             } else {
                 BigDecimal extraKm = distanceKm.subtract(startDistance);
                 BigDecimal extraCount = extraKm.divide(extraDistanceUnit, 0, RoundingMode.CEILING);
-                unitPrice = startPrice + extraCount.longValue() * extraPricePerUnit;
+                extraFee = extraCount.longValue() * extraPricePerUnit;
+                unitPrice = startPrice + extraFee;
             }
 
             long subtotal = unitPrice * item.getQuantity();
@@ -526,8 +569,17 @@
             vo.setExtraPrice(extraPricePerUnit);
             itemList.add(vo);
 
-            itemPriceTotal += subtotal;
+            // 鎵�鏈夌墿鍝佺殑璧锋浠访楁暟閲� 绱姞
+            itemPriceTotal += startPrice * item.getQuantity();
+            // 璁板綍鏈�澶х殑瓒呭嚭璺濈璐圭敤
+            long extraFeeTotal = extraFee * item.getQuantity();
+            if (extraFeeTotal > maxExtraFeeTotal) {
+                maxExtraFeeTotal = extraFeeTotal;
+            }
         }
+
+        // 澶氱墿鍝佹椂鍙姞鏈�澶х殑瓒呭嚭璺濈璐圭敤
+        itemPriceTotal += maxExtraFeeTotal;
 
         // 4. 淇濅环璐圭敤锛氭姤浠烽噾棰� 脳 淇濅环璐圭巼(瀛楀吀 INSURANCE_RATE)锛屽厓鈫掑垎锛堜繚浠烽噾棰�>0鏃惰璐癸級
         long insuranceFeeFen = 0L;
@@ -536,18 +588,26 @@
             insuranceFeeFen = insuranceFeeYuan.multiply(new BigDecimal(100)).longValue();
         }
 
-        // 5. 鍔犳�ヨ垂鐢細鐗╁搧浠锋牸 脳 鍔犳�ョ郴鏁�(瀛楀吀 URGENT_COEFFICIENT)
+        // 5. 鍔犳�ヨ垂鐢細鐗╁搧浠锋牸 脳 (鍔犳�ョ郴鏁�-1)锛屽150%琛ㄧず澧炲姞50%
         long urgentFeeFen = 0L;
         String urgentRateStr = systemDictDataBiz.queryByCode(
                 Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode();
         BigDecimal urgentRate = new BigDecimal(urgentRateStr);
-        urgentFeeFen = new BigDecimal(itemPriceTotal).multiply(urgentRate)
+        BigDecimal urgentIncreaseRate = urgentRate.subtract(BigDecimal.ONE);
+        urgentFeeFen = new BigDecimal(itemPriceTotal).multiply(urgentIncreaseRate)
                 .setScale(0, RoundingMode.HALF_UP).longValue();
 
         // 6. 鎬讳环鏍� = 鐗╁搧浠锋牸 + 淇濅环璐圭敤 + 鍔犳�ヨ垂鐢紙鍔犳�ユ椂鎵嶅寘鍚姞鎬ヨ垂锛�
         long totalPrice = itemPriceTotal + insuranceFeeFen;
         if (Boolean.TRUE.equals(dto.getUrgent())) {
             totalPrice += urgentFeeFen;
+            // 鍔犳�ユ椂鏇存柊鐗╁搧鏄庣粏鍗曚环鍜屽皬璁�
+            for (ItemPriceVO vo : itemList) {
+                long adjustedUnitPrice = new BigDecimal(vo.getUnitPrice()).multiply(urgentRate)
+                        .setScale(0, RoundingMode.HALF_UP).longValue();
+                vo.setUnitPrice(adjustedUnitPrice);
+                vo.setSubtotal(adjustedUnitPrice * vo.getQuantity());
+            }
         }
 
         PriceCalculateVO result = new PriceCalculateVO();
@@ -584,7 +644,50 @@
             }
         }
 
+        resolveCoupon(result, dto.getMemberId(), dto.getCouponId(), totalPrice);
         return result;
+    }
+
+    private void resolveCoupon(PriceCalculateVO result, Integer memberId, Integer couponId, long totalPrice) {
+        if (memberId == null) {
+            result.setDeductionAmount(0L);
+            return;
+        }
+        // 鏌ヨ鍙敤浼樻儬鍒革細宸查鍙栥�佹湭杩囨湡銆佹弧瓒虫弧棰濋棬妲�
+        Date now = new Date();
+        List<MemberCoupon> availableCoupons = memberCouponMapper.selectList(new QueryWrapper<MemberCoupon>().lambda()
+                .eq(MemberCoupon::getMemberId, memberId)
+                .eq(MemberCoupon::getStatus, Constants.CouponStatus.claimed.getKey())
+                .eq(MemberCoupon::getIsdeleted, Constants.ZERO)
+                .le(MemberCoupon::getLimitPrice, totalPrice)
+                .ge(MemberCoupon::getEndDate, now)
+                .orderByDesc(MemberCoupon::getPrice)
+                .orderByAsc(MemberCoupon::getEndDate));
+        result.setAvailableCoupons(availableCoupons);
+
+        if (couponId == null) {
+            result.setDeductionAmount(0L);
+            return;
+        }
+
+        MemberCoupon selected;
+        if (couponId == -1) {
+            selected = availableCoupons.isEmpty() ? null : availableCoupons.get(0);
+        } else {
+            selected = availableCoupons.stream()
+                    .filter(mc -> mc.getId().equals(couponId))
+                    .findFirst().orElse(null);
+            if (selected == null) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浼樻儬鍒告棤鏁堟垨涓嶅彲鐢�");
+            }
+        }
+
+        if (selected != null) {
+            result.setDeductionAmount(selected.getPrice());
+            result.setSelectedCoupon(selected);
+        } else {
+            result.setDeductionAmount(0L);
+        }
     }
 
     @Override
@@ -698,7 +801,7 @@
                 // 鏃犲彇浠堕棬搴楋紝鏍¢獙瀛樹欢鐐逛笌鑷�夊彇浠剁偣鏄惁鍦ㄥ悓涓�鍩庡競
                 if (!MapUtil.isSameCity(depositShop.getLatitude(), depositShop.getLongitude(),
                         dto.getTakeLat().doubleValue(), dto.getTakeLgt().doubleValue())) {
-                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "寮傚湴瀵勫瓨璁㈠崟瀛樺彇鐐逛笉鍦ㄥ悓涓�鍩庡競锛屽闇�璇烽�夋嫨鍚屽煄闂ㄥ簵");
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀛樺彇鐐逛笉鍦ㄥ悓涓�鍩庡競锛�");
                 }
                 takeLat = dto.getTakeLat();
                 takeLgt = dto.getTakeLgt();
@@ -721,6 +824,8 @@
             priceDTO.setDepositEndTime(takeTime);
             priceDTO.setItems(dto.getItems());
             priceDTO.setDeclaredAmount(dto.getDeclaredAmount());
+            priceDTO.setMemberId(memberId);
+            priceDTO.setCouponId(dto.getCouponId());
             priceResult = calculateLocalPrice(priceDTO);
         } else {
             // 寮傚湴瀵勫瓨
@@ -733,6 +838,8 @@
             priceDTO.setItems(dto.getItems());
             priceDTO.setDeclaredAmount(dto.getDeclaredAmount());
             priceDTO.setUrgent(Constants.ONE.equals(dto.getIsUrgent()));
+            priceDTO.setMemberId(memberId);
+            priceDTO.setCouponId(dto.getCouponId());
             priceResult = calculateRemotePrice(priceDTO);
         }
 
@@ -756,6 +863,7 @@
         orders.setDeleted(Constants.ZERO);
         orders.setCreateTime(now);
         orders.setUpdateTime(now);
+        orders.setIsConverted(Constants.ZERO);
 
         // 瀵勪欢淇℃伅
         orders.setDepositShopId(dto.getDepositShopId());
@@ -785,6 +893,7 @@
             // 寮傚湴锛氬彇浠剁偣淇℃伅
             orders.setTakeShopId(dto.getTakeShopId());
             orders.setTakeLocation(takeLocationValue);
+            orders.setTakeLocationRemark(takeLocationValue);
             orders.setTakeLat(takeLat);
             orders.setTakeLgt(takeLgt);
             orders.setIsUrgent(dto.getIsUrgent());
@@ -793,6 +902,7 @@
             // 灏卞湴锛氬彇浠剁偣鍚屽瘎浠跺簵閾�
             orders.setTakeShopId(dto.getDepositShopId());
             orders.setTakeLocation(depositShop.getAddress());
+            orders.setTakeLocationRemark(depositShop.getAddress());
             orders.setTakeLat(BigDecimal.valueOf(depositShop.getLatitude()));
             orders.setTakeLgt(BigDecimal.valueOf(depositShop.getLongitude()));
             orders.setIsUrgent(Constants.ZERO);
@@ -818,8 +928,18 @@
         // 璐圭敤淇℃伅(鍒�)
         orders.setBasicAmount(priceResult.getItemPrice());
         orders.setEstimatedAmount(priceResult.getTotalPrice());
-        orders.setTotalAmount(priceResult.getTotalPrice());
+        long deductionAmount = priceResult.getDeductionAmount() != null ? priceResult.getDeductionAmount() : 0L;
+        orders.setTotalAmount(priceResult.getTotalPrice() - deductionAmount);
         orders.setUrgentAmount(priceResult.getUrgentFee());
+        orders.setCouponId(dto.getCouponId());
+        orders.setDeductionAmount(deductionAmount);
+        orders.setManualRefund(Constants.ZERO);
+        // 瀛樺偍鍔犳�ョ郴鏁�
+        if (Constants.ONE.equals(dto.getType()) && Constants.ONE.equals(dto.getIsUrgent())) {
+            String urgentRateStr = systemDictDataBiz.queryByCode(
+                    Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode();
+            orders.setUrgentRata(new BigDecimal(urgentRateStr));
+        }
         if (dto.getDeclaredAmount() != null && dto.getDeclaredAmount().compareTo(BigDecimal.ZERO) > 0) {
             orders.setDeclaredAmount(dto.getDeclaredAmount().multiply(new BigDecimal(100)).longValue());
         } else {
@@ -837,7 +957,37 @@
         ordersMapper.insert(orders);
         Integer orderId = orders.getId();
 
+        // 鏍囪浼樻儬鍒稿凡浣跨敤
+        MemberCoupon selectedCoupon = priceResult.getSelectedCoupon();
+        if (selectedCoupon != null) {
+            memberCouponMapper.update(new UpdateWrapper<MemberCoupon>().lambda()
+                    .set(MemberCoupon::getStatus, Constants.CouponStatus.used.getKey())
+                    .set(MemberCoupon::getUseDate, new Date())
+                    .set(MemberCoupon::getOrderId, orderId)
+                    .eq(MemberCoupon::getId, selectedCoupon.getId()));
+        }
+
+        // 鍒涘缓璁㈠崟鏃ュ織
+        OrderLog createLog = new OrderLog();
+        createLog.setOrderId(orderId);
+        createLog.setTitle(Constants.OrderLogType.createOrder.getTitle());
+        createLog.setLogInfo(Constants.OrderLogType.createOrder.format(orderCode));
+        createLog.setObjType(Constants.OrderLogType.createOrder.getStatus());
+        createLog.setOrderStatus(orders.getStatus());
+        createLog.setOptUserId(memberId);
+        createLog.setOptUserType(0);
+        createLog.setCreateTime(now);
+        createLog.setDeleted(Constants.ZERO);
+        orderLogService.create(createLog);
+
         // ========== 7. 鍒涘缓璁㈠崟鏄庣粏 ==========
+        // 寮傚湴瀵勫瓨鏋侀�熻揪鏃讹紝鎸夊姞鎬ユ瘮渚嬭绠楁槑缁嗚鍗曚环
+        BigDecimal urgentIncreaseRate = null;
+        if (Constants.ONE.equals(dto.getType()) && Constants.ONE.equals(dto.getIsUrgent())) {
+            String urgentRateStr = systemDictDataBiz.queryByCode(
+                    Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode();
+            urgentIncreaseRate = new BigDecimal(urgentRateStr).subtract(BigDecimal.ONE);
+        }
         for (ItemPriceVO itemVO : priceResult.getItemList()) {
             OrdersDetail detail = new OrdersDetail();
             detail.setOrderId(orderId);
@@ -845,11 +995,29 @@
             detail.setLuggageName(itemVO.getCategoryName());
             detail.setLuggageDetail(itemVO.getDetail());
             detail.setNum(itemVO.getQuantity());
-            detail.setUnitPrice(itemVO.getUnitPrice());
+            long detailUnitPrice = itemVO.getUnitPrice();
+            if (urgentIncreaseRate != null) {
+                detailUnitPrice = new BigDecimal(detailUnitPrice)
+                        .multiply(BigDecimal.ONE.add(urgentIncreaseRate))
+                        .setScale(0, RoundingMode.HALF_UP).longValue();
+            }
+            detail.setUnitPrice(detailUnitPrice);
             detail.setStartDistance(itemVO.getStartDistance());
-            detail.setStartPrice(itemVO.getStartPrice());
+            if (urgentIncreaseRate != null && itemVO.getStartPrice() != null) {
+                detail.setStartPrice(new BigDecimal(itemVO.getStartPrice())
+                        .multiply(BigDecimal.ONE.add(urgentIncreaseRate))
+                        .setScale(0, RoundingMode.HALF_UP).longValue());
+            } else {
+                detail.setStartPrice(itemVO.getStartPrice());
+            }
             detail.setExtraDistance(itemVO.getExtraDistance());
-            detail.setExtraPrice(itemVO.getExtraPrice());
+            if (urgentIncreaseRate != null && itemVO.getExtraPrice() != null) {
+                detail.setExtraPrice(new BigDecimal(itemVO.getExtraPrice())
+                        .multiply(BigDecimal.ONE.add(urgentIncreaseRate))
+                        .setScale(0, RoundingMode.HALF_UP).longValue());
+            } else {
+                detail.setExtraPrice(itemVO.getExtraPrice());
+            }
             detail.setLocallyPrice(itemVO.getLocallyPrice());
             detail.setDeleted(Constants.ZERO);
             detail.setCreateTime(now);
@@ -986,6 +1154,13 @@
 
         OrderDetailVO vo = new OrderDetailVO();
         vo.setOrder(order);
+        vo.setDeductionAmount(order.getDeductionAmount());
+
+        // 璁㈠崟鐘舵�佹弿杩�
+        if (order.getStatus() != null) {
+            Constants.OrderStatus os = Constants.OrderStatus.getByKey(order.getStatus());
+            vo.setStatusDesc(os != null ? os.getValue() : "");
+        }
 
         // 鍥剧墖璺緞鍓嶇紑
         String imgPrefix = getOrdersPrefix();
@@ -1111,19 +1286,6 @@
 
         String optUserName = getCurrentUserName();
 
-        // 鍔犳�ヨ垂鏃ュ織
-        OrderLog feeLog = new OrderLog();
-        feeLog.setOrderId(order.getId());
-        feeLog.setTitle(Constants.OrderLogType.urgent.getTitle());
-        feeLog.setLogInfo(Constants.OrderLogType.urgent.format(dto.getUrgentFee().toPlainString()));
-        feeLog.setObjType(Constants.OrderLogType.urgent.getStatus());
-        feeLog.setOrderStatus(order.getStatus());
-        feeLog.setOptUserType(3);
-        feeLog.setOptUserName(optUserName);
-        feeLog.setCreateTime(new Date());
-        feeLog.setDeleted(Constants.ZERO);
-        orderLogService.create(feeLog);
-
         // 鍔犳�ヨ垂鐢� 鍏冣啋鍒�
         long urgentFeeFen = dto.getUrgentFee().multiply(new BigDecimal(100)).longValue();
 
@@ -1131,7 +1293,6 @@
         com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<Orders> updateWrapper =
                 new UpdateWrapper<Orders>().lambda()
                 .eq(Orders::getId, order.getId())
-                .set(Orders::getIsUrgent, Constants.ONE)
                 .set(Orders::getPlatformRewardAmount, urgentFeeFen)
                 .set(Orders::getPlatformSmsNotified, Constants.ZERO) // 閲嶇疆閫氱煡鐘舵�佷负鏈�氱煡
                 .set(Orders::getPlatformSmsNotifiedTime, new Date()) // 閲嶇疆閫氱煡鍩哄噯鏃堕棿涓哄綋鍓�
@@ -1148,44 +1309,68 @@
             updateWrapper.set(Orders::getRemark, dto.getRemark());
         }
 
-        // 鎸囨淳鍙告満锛堥潪蹇呭~锛�
+        // 鏃ュ織锛氬彧瀛樹竴鏉★紝鏈夊徃鏈虹敤 assignDriver锛屾棤鍙告満鐢� urgent
         if (dto.getDriverId() != null) {
-            updateWrapper.set(Orders::getAssignDriverId, dto.getDriverId());
+            // 鏍¢獙鍙告満淇℃伅
+            DriverInfo driverInfo = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda()
+                    .eq(DriverInfo::getId, dto.getDriverId())
+                    .eq(DriverInfo::getVersionType, Constants.ZERO)
+                    .eq(DriverInfo::getDeleted, Constants.ZERO)
+                    .last("limit 1"));
+            if (driverInfo == null) {
+                throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鍙告満淇℃伅涓嶅瓨鍦�");
+            }
+            if (!Integer.valueOf(3).equals(driverInfo.getAuditStatus())) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鍙告満鏈敮浠樻娂閲戯紝鏃犳硶娲惧崟");
+            }
+            if (!Constants.ZERO.equals(driverInfo.getStatus())) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鍙告満宸茶绂佺敤锛屾棤娉曟淳鍗�");
+            }
 
-            Member driver = memberMapper.selectById(dto.getDriverId());
-            String driverName = driver != null ? driver.getName() : String.valueOf(dto.getDriverId());
+            // 鏇存柊鎺ュ崟鍙告満淇℃伅鍙婅鍗曠姸鎬�
+            Date now = new Date();
+            updateWrapper.set(Orders::getAssignDriverId, dto.getDriverId());
+            updateWrapper.set(Orders::getAcceptDriver, dto.getDriverId());
+            updateWrapper.set(Orders::getAcceptTime, now);
+            updateWrapper.set(Orders::getAcceptType, 1); // 1=绯荤粺娲惧崟
+            updateWrapper.set(Orders::getStatus, Constants.OrderStatus.accepted.getStatus());
 
             OrderLog driverLog = new OrderLog();
             driverLog.setOrderId(order.getId());
             driverLog.setTitle(Constants.OrderLogType.assignDriver.getTitle());
-            driverLog.setLogInfo(Constants.OrderLogType.assignDriver.format(driverName, dto.getUrgentFee().toPlainString()));
+            driverLog.setLogInfo(Constants.OrderLogType.assignDriver.format(driverInfo.getName(), dto.getUrgentFee().toPlainString()));
             driverLog.setObjType(Constants.OrderLogType.assignDriver.getStatus());
-            driverLog.setOrderStatus(order.getStatus());
+            driverLog.setOrderStatus(Constants.OrderStatus.accepted.getStatus());
             driverLog.setOptUserType(3);
             driverLog.setOptUserName(optUserName);
-            driverLog.setCreateTime(new Date());
+            driverLog.setCreateTime(now);
             driverLog.setDeleted(Constants.ZERO);
             orderLogService.create(driverLog);
 
             // 鐭俊閫氱煡鎸囨淳鍙告満锛堝姞鎬ユ淳鍗曪級
-            DriverInfo driverInfo = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda()
-                    .eq(DriverInfo::getMemberId, dto.getDriverId())
-                    .eq(DriverInfo::getDeleted, Constants.ZERO)
-                    .last("limit 1"));
-            if (driverInfo != null) {
-                String address1 = order.getDepositShopAddress() != null ? order.getDepositShopAddress() : order.getDepositShopName();
-                String address2 = order.getTakeShopAddress() != null ? order.getTakeShopAddress() :
-                        (order.getTakeLocation() != null ? order.getTakeLocation() : "");
-                // 閰嶉�佽垂 = 鍙告満閰嶉�佽垂 + 鍔犳�ヨ垂
-                long totalDriverFee = (order.getDriverFee() != null ? order.getDriverFee() : 0L) + urgentFeeFen;
-                sendSmsNotify(driverInfo.getTelephone(),
-                        Constants.SmsNotify.DRIVER_URGENT_DISPATCH,
-                        "orderNo", order.getCode(),
-                        "address1", address1,
-                        "address2", address2,
-                        "money1", String.valueOf(totalDriverFee / 100.0),
-                        "money2", String.valueOf(urgentFeeFen / 100.0));
-            }
+            String address1 = order.getDepositLocationRemark();
+            String address2 = order.getTakeLocationRemark();
+            long totalDriverFee = (order.getDriverFee() != null ? order.getDriverFee() : 0L) + urgentFeeFen;
+            sendSmsNotify(driverInfo.getTelephone(),
+                    Constants.SmsNotify.DRIVER_URGENT_DISPATCH,
+                    "orderNo", order.getCode(),
+                    "address1", address1,
+                    "address2", address2,
+                    "money1", String.valueOf(totalDriverFee / 100.0),
+                    "money2", String.valueOf(urgentFeeFen / 100.0));
+        } else {
+            // 鏈寚娲惧徃鏈猴紝鍙褰曞姞鎬ユ棩蹇�
+            OrderLog feeLog = new OrderLog();
+            feeLog.setOrderId(order.getId());
+            feeLog.setTitle(Constants.OrderLogType.urgent.getTitle());
+            feeLog.setLogInfo(Constants.OrderLogType.urgent.format(dto.getUrgentFee().toPlainString()));
+            feeLog.setObjType(Constants.OrderLogType.urgent.getStatus());
+            feeLog.setOrderStatus(order.getStatus());
+            feeLog.setOptUserType(3);
+            feeLog.setOptUserName(optUserName);
+            feeLog.setCreateTime(new Date());
+            feeLog.setDeleted(Constants.ZERO);
+            orderLogService.create(feeLog);
         }
 
         ordersMapper.update(updateWrapper);
@@ -1297,6 +1482,25 @@
         }
         return urls;
     }
+    private  List<Multifile> getFileUrlsByidList(List<Integer> orderId, int objType, String prefix) {
+        if(orderId ==null || orderId.size()==0){
+            return  null;
+        }
+        List<Multifile> files = multifileMapper.selectList(
+                new QueryWrapper<Multifile>().lambda()
+                        .in(Multifile::getObjId, orderId)
+                        .eq(Multifile::getObjType, objType)
+                        .eq(Multifile::getIsdeleted, Constants.ZERO)
+                        .orderByAsc(Multifile::getSortnum));
+        if (files != null) {
+            for (Multifile f : files) {
+                if (StringUtils.isNotBlank(f.getFileurl())) {
+                    f.setFileurl(prefix + f.getFileurl());
+                }
+            }
+        }
+        return files;
+    }
 
     /**
      * 璁$畻骞惰缃鍗曡柂閰垎閰嶏紙鍙告満銆佸瓨浠堕棬搴椼�佸彇浠堕棬搴楋級
@@ -1318,20 +1522,31 @@
             return;
         }
         Integer cityId = Integer.valueOf(orders.getCityId());
+        boolean isRemote = Constants.equalsInteger(orders.getType(), Constants.ONE);
+        boolean isCompany = Constants.equalsInteger(depositShop.getCompanyType(), Constants.ONE);
 
-        // 鍙告満鍗犳瘮锛歠ieldA=4锛堥厤閫佸憳锛�
+        // 鍙告満鍗犳瘮锛歠ieldA=4锛堥厤閫佸憳锛夛紝濮嬬粓浠庡煄甯傞厤缃彇
         BigDecimal driverRata = getRevenueShareRata(cityId, Constants.FOUR);
-        // 瀵勪欢闂ㄥ簵鍗犳瘮锛歠ieldA=0(浼佷笟瀵�)/1(涓汉瀵�)
-        int depositFieldA = Constants.equalsInteger(depositShop.getCompanyType(), Constants.ONE) ? Constants.ZERO : Constants.ONE;
-        BigDecimal depositShopRata = getRevenueShareRata(cityId, depositFieldA);
-        // 鍙栦欢闂ㄥ簵鍗犳瘮锛氭棤鍙栦欢闂ㄥ簵鏃舵瘮渚嬩负0
-        BigDecimal takeShopRata = BigDecimal.ZERO;
-        if (takeShop != null) {
-            int takeFieldA = Constants.equalsInteger(takeShop.getCompanyType(), Constants.ONE) ? Constants.TWO : Constants.THREE;
-            takeShopRata = getRevenueShareRata(cityId, takeFieldA);
+
+        // 瀛樹欢闂ㄥ簵鍗犳瘮
+        BigDecimal depositShopRata;
+        if (isRemote) {
+            int fallbackFieldA = isCompany ? Constants.ZERO : Constants.ONE;
+            depositShopRata = getShopRevenueShare(depositShop, "remoteDeposit", cityId, fallbackFieldA);
+        } else {
+            int fallbackFieldA = isCompany ? Constants.FIVE : Constants.SIX;
+            depositShopRata = getShopRevenueShare(depositShop, "localDeposit", cityId, fallbackFieldA);
         }
 
-        // 璁$畻钖叕锛堝垎锛夛細totalAmount 涓哄垎锛宺ata 涓烘瘮渚嬪�硷紙濡� 0.15 琛ㄧず 15%锛�
+        // 鍙栦欢闂ㄥ簵鍗犳瘮
+        BigDecimal takeShopRata = BigDecimal.ZERO;
+        if (isRemote && takeShop != null) {
+            boolean takeIsCompany = Constants.equalsInteger(takeShop.getCompanyType(), Constants.ONE);
+            int fallbackFieldA = takeIsCompany ? Constants.TWO : Constants.THREE;
+            takeShopRata = getShopRevenueShare(takeShop, "remoteTake", cityId, fallbackFieldA);
+        }
+
+        // 璁$畻钖叕锛堝垎锛�
         long driverFee = new BigDecimal(totalAmount).multiply(driverRata).longValue();
         long depositShopFee = new BigDecimal(totalAmount).multiply(depositShopRata).longValue();
         long takeShopFee = new BigDecimal(totalAmount).multiply(takeShopRata).longValue();
@@ -1348,7 +1563,7 @@
      * 浠� pricing_rule 琛ㄨ幏鍙栧垎鎴愭瘮渚嬶紙type=4锛�
      *
      * @param cityId   鍩庡競涓婚敭
-     * @param fieldA   绫诲瀷锛�0=浼佷笟瀵�, 1=涓汉瀵�, 2=浼佷笟鍙�, 3=涓汉鍙�, 4=閰嶉�佸憳
+     * @param fieldA   绫诲瀷锛�0=寮傚湴浼佷笟瀵�, 1=寮傚湴涓汉瀵�, 2=寮傚湴浼佷笟鍙�, 3=寮傚湴涓汉鍙�, 4=閰嶉�佸憳, 5=灏卞湴浼佷笟瀛�, 6=灏卞湴涓汉瀛�
      * @return 鍒嗘垚姣斾緥锛堝 0.15 琛ㄧず 15%锛�
      */
     private BigDecimal getRevenueShareRata(Integer cityId, int fieldA) {
@@ -1359,10 +1574,35 @@
                 .eq(PricingRule::getFieldA, String.valueOf(fieldA))
                 .last("limit 1"));
         if (rule != null && StringUtils.isNotBlank(rule.getFieldB())) {
-            // fieldB 瀛樺偍鐨勬槸鐧惧垎姣旀暣鏁帮紙濡�15琛ㄧず15%锛夛紝杞崲涓哄皬鏁版瘮渚嬶紙0.15锛�
+            // fieldB 瀛樺偍鐨勬槸鐧惧垎姣旀暟瀛楋紙濡�15琛ㄧず15%锛夛紝杞崲涓哄皬鏁版瘮渚嬶紙0.15锛�
             return new BigDecimal(rule.getFieldB()).divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP);
         }
         return BigDecimal.ZERO;
+    }
+
+    /**
+     * 鑾峰彇闂ㄥ簵鏀剁泭鍗犳瘮锛氫紭鍏堜粠闂ㄥ簵 revenueShareConfig 鍙栵紝鏃犲垯鍏滃簳鍩庡競 pricing_rule
+     *
+     * @param shop           闂ㄥ簵淇℃伅
+     * @param jsonKey        revenueShareConfig 涓殑閿悕
+     * @param cityId         鍩庡競涓婚敭锛堝厹搴曠敤锛�
+     * @param fallbackFieldA 鍏滃簳 pricing_rule fieldA 鍊�
+     * @return 鍒嗘垚姣斾緥
+     */
+    private BigDecimal getShopRevenueShare(ShopInfo shop, String jsonKey, Integer cityId, int fallbackFieldA) {
+        if (shop != null && StringUtils.isNotBlank(shop.getRevenueShareConfig())) {
+            try {
+                JSONObject config = JSONObject.parseObject(shop.getRevenueShareConfig());
+                if (config != null && config.containsKey(jsonKey)) {
+                    Double value = config.getDouble(jsonKey);
+                    if (value != null) {
+                        return new BigDecimal(value).divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP);
+                    }
+                }
+            } catch (Exception ignored) {
+            }
+        }
+        return getRevenueShareRata(cityId, fallbackFieldA);
     }
 
     @Override
@@ -1389,6 +1629,7 @@
                 .select("s1.name", Orders::getDepositShopName)
                 .select("s1.link_name", Orders::getDepositShopLinkName)
                 .select("s1.link_phone", Orders::getDepositShopLinkPhone)
+                .select("s1.address", Orders::getDepositShopAddress)
                 .select("s2.name", Orders::getTakeShopName)
                 .select("s2.address", Orders::getTakeShopAddress)
                 .select("s2.link_phone", Orders::getTakeShopLinkPhone)
@@ -1402,11 +1643,38 @@
                 .eq(status != null, Orders::getStatus, status)
                 .in(statusList != null, Orders::getStatus, statusList)
                 .orderByDesc(Orders::getCreateTime);
+        // 鍙紑绁ㄨ鍗曪細澧炲姞鏈堜唤闄愬埗
+        if (model != null && model.getInvoiceStatus() != null && Constants.equalsInteger(model.getInvoiceStatus(), Constants.ONE)) {
+            wrapper.in(Orders::getInvoiceStatus, Arrays.asList(Constants.ONE, 99));
+            String monthLimitStr = operationConfigBiz.getConfig().getInvoiceMonthLimit();
+            if (StringUtils.isNotBlank(monthLimitStr)) {
+                int monthLimit = Integer.parseInt(monthLimitStr);
+                Calendar cal = Calendar.getInstance();
+                cal.add(Calendar.MONTH, -monthLimit);
+                cal.set(Calendar.HOUR_OF_DAY, 0);
+                cal.set(Calendar.MINUTE, 0);
+                cal.set(Calendar.SECOND, 0);
+                cal.set(Calendar.MILLISECOND, 0);
+                wrapper.ge(Orders::getFinishTime, cal.getTime());
+            }
+        }
+        // 鍏抽敭璇嶆悳绱細鏀朵欢浜�/鏀朵欢浜虹數璇濇ā绯娿�佽鍗曞彿绮惧噯
+        if (model != null && StringUtils.isNotBlank(model.getKeyword())) {
+            String kw = model.getKeyword().trim();
+            wrapper.and(w -> w.like(Orders::getTakeUser, kw)
+                    .or().like(Orders::getTakePhone, kw)
+                    .or().eq(Orders::getCode, kw));
+        }
 
         IPage<Orders> orderPage = ordersMapper.selectJoinPage(p, Orders.class, wrapper);
         List<MyOrderVO> voList = new ArrayList<>();
-        if (orderPage != null && orderPage.getRecords() != null) {
-
+        if (orderPage != null && orderPage.getRecords() != null  && orderPage.getRecords().size()>0) {
+            String imgPrefix = getOrdersPrefix();
+            List<Integer> idList =new ArrayList<>();
+            for (Orders o : orderPage.getRecords()) {
+                idList.add(o.getId());
+            }
+            List<Multifile> files = getFileUrlsByidList(idList,Constants.FileType.ORDER_FILE.getKey(), imgPrefix);
             for (Orders o : orderPage.getRecords()) {
                 MyOrderVO vo = new MyOrderVO();
                 vo.setId(o.getId());
@@ -1425,7 +1693,7 @@
                 vo.setDepositShopName(o.getDepositShopName());
                 vo.setDepositShopLinkName(o.getDepositShopLinkName());
                 vo.setDepositShopPhone(o.getDepositShopLinkPhone());
-
+                vo.setDepositShopAddress(o.getDepositShopAddress());
                 // 鍙栦欢淇℃伅锛氭湁鍙栦欢闂ㄥ簵鍙栭棬搴楋紝鏃犲垯鍙栫敤鎴疯嚜閫夊彇浠剁偣
                 if (o.getTakeShopId() != null) {
                     vo.setTakeShopId(o.getTakeShopId());
@@ -1451,18 +1719,30 @@
 
                 // 璇勪环鐘舵��
                 vo.setCommentStatus(o.getCommentStatus());
+                //搴忓彿
+                vo.setSortnum(Constants.formatIntegerNum(o.getDepositShopId())+"-"+o.getId());
+                if(o.getTakeShopId()!=null){
+                    vo.setSortnumTake(Constants.formatIntegerNum(o.getTakeShopId())+"-"+o.getId());
+                }
 
                 // 鏌ヨ鐗╁搧鏄庣粏锛堜竴娆℃煡璇紝鍚屾椂鐢ㄤ簬鐗╁搧鍒楄〃鍜岄�炬湡璁$畻锛�
                 List<OrdersDetail> details = ordersDetailMapper.selectList(
                         new QueryWrapper<OrdersDetail>().lambda()
                                 .eq(OrdersDetail::getOrderId, o.getId())
                                 .eq(OrdersDetail::getDeleted, Constants.ZERO));
-
                 // 鐗╁搧鏄庣粏
                 vo.setDetailList(buildDetailList(details));
-
+                vo.setOrderImages(getFileUrlsFromList(o.getId(),files));
                 // 閫炬湡鐘舵��
                 fillOverdueStatus(vo, o, details);
+                // 浼樻儬鍒告姷鎵i噾棰�
+                vo.setDeductionAmount(o.getDeductionAmount());
+                // 鍙紑绁ㄩ噾棰濓紙鏀粯閲戦 - 閫�娆鹃噾棰濓級
+                if (model != null && model.getInvoiceStatus() != null && Constants.equalsInteger(model.getInvoiceStatus(), Constants.ONE)) {
+                    long payAmt = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+                    long refundAmt = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+                    vo.setInvoiceAmount(payAmt - refundAmt);
+                }
                 voList.add(vo);
             }
         }
@@ -1474,6 +1754,22 @@
         pageData.setPage(orderPage.getCurrent());
         pageData.setCapacity(orderPage.getSize());
         return pageData;
+    }
+
+    private List<String> getFileUrlsFromList(Integer id, List<Multifile> files) {
+        List<String> urls = new ArrayList<>();
+        try {
+            if(files!=null){
+                for(Multifile f : files){
+                    if(Constants.equalsInteger(f.getObjId(),id)){
+                        urls.add(f.getFileurl());
+                    }
+                }
+            }
+        }catch (Exception e){
+        }
+
+        return urls;
     }
 
     @Override
@@ -1513,20 +1809,33 @@
         // 闂ㄥ簵寰呭鐞嗚鍗曪細鎸変笟鍔$幆鑺傚尯鍒嗛棬搴楄鑹�
         if (combinedStatus != null && Constants.equalsInteger(combinedStatus, Constants.SEVEN)) {
             wrapper.and(w -> w
-                    .and(w1 -> w1.eq(Orders::getDepositShopId, shopId)
+                    .and(w1 -> w1.eq(Orders::getType, Constants.ZERO).eq(Orders::getDepositShopId, shopId)
                             .in(Orders::getStatus, Constants.OrderStatus.waitDeposit.getStatus(),
-                                    Constants.OrderStatus.deposited.getStatus()))
-                    .or(w2 -> w2.eq(Orders::getTakeShopId, shopId)
-                            .in(Orders::getStatus, Constants.OrderStatus.delivering.getStatus(),
-                                    Constants.OrderStatus.arrived.getStatus()))
+                                    Constants.OrderStatus.arrived.getStatus())
+                    .or(w3-> w3.eq(Orders::getType, Constants.ONE).eq(Orders::getDepositShopId, shopId)
+                            .eq(Orders::getStatus, Constants.OrderStatus.waitDeposit.getStatus()))
+                    .or(w2 -> w2.eq(Orders::getType, Constants.ONE).eq(Orders::getTakeShopId, shopId)
+                            .eq(Orders::getStatus, Constants.OrderStatus.arrived.getStatus())))
             );
         } else {
             wrapper.and(w -> w.eq(Orders::getDepositShopId, shopId).or().eq(Orders::getTakeShopId, shopId));
         }
 
         wrapper.eq(status != null, Orders::getStatus, status)
-                .in(statusList != null && !Constants.equalsInteger(combinedStatus, Constants.SEVEN), Orders::getStatus, statusList)
-                .orderByDesc(Orders::getId);
+                .in(statusList != null && !Constants.equalsInteger(combinedStatus, Constants.SEVEN), Orders::getStatus, statusList);
+        if(Objects.nonNull(model.getCombinedStatus())&&Constants.equalsInteger(model.getCombinedStatus(),Constants.OrderCombinedStatus.finished.getKey())){
+            wrapper.orderByDesc(Orders::getFinishTime);
+        }else{
+            wrapper.orderByDesc(Orders::getId);
+        }
+        // 鍏抽敭璇嶆悳绱細鏀朵欢浜�/鏀朵欢浜虹數璇濇ā绯娿�佽鍗曞彿绮惧噯
+        MyOrderDTO shopModel = pageWrap.getModel();
+        if (shopModel != null && StringUtils.isNotBlank(shopModel.getKeyword())) {
+            String kw = shopModel.getKeyword().trim();
+            wrapper.and(w -> w.like(Orders::getTakeUser, kw)
+                    .or().like(Orders::getTakePhone, kw)
+                    .or().eq(Orders::getCode, kw));
+        }
 
         IPage<Orders> orderPage = ordersMapper.selectJoinPage(p, Orders.class, wrapper);
         List<MyOrderVO> voList = new ArrayList<>();
@@ -1579,8 +1888,6 @@
                                 .eq(OrdersDetail::getDeleted, Constants.ZERO));
 
                 vo.setDetailList(buildDetailList(details));
-
-
                 // 閫炬湡鐘舵��
                 fillOverdueStatus(vo, o, details);
 
@@ -1680,7 +1987,14 @@
         if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.waitPay.getStatus())) {
             vo.setPayCountdownMs(calcPayCountdownMs(order));
         }
-
+        //搴忓彿
+        vo.setSortnum(Constants.formatIntegerNum(order.getDepositShopId())+"-"+order.getId());
+        if(order.getTakeShopId()!=null){
+            String dateStr = new SimpleDateFormat("dd").format(order.getPayTime() != null ? order.getPayTime() : new Date());
+            String autoNumStr = String.format("%03d", order.getAutoNum() != null ? order.getAutoNum() : 0);
+            String sort = order.getTakeShopId() + "-" + dateStr + "-" + autoNumStr;
+            vo.setSortnumTake(sort);
+        }
         // 瀛樹欢闂ㄥ簵
         if (order.getDepositShopId() != null) {
             ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
@@ -1774,46 +2088,17 @@
             vo.setMemberVerifyCode(order.getMemberVerifyCode());
         }
 
-        // 寮傚湴瀵勫瓨缁忕含搴︼紙灏卞湴瀵勫瓨涓嶈繑鍥烇級
-        if (Constants.ONE.equals(order.getType())) {
-            // status=3(宸叉帴鍗�)锛氳繑鍥炲瓨浠堕棬搴楃粡绾害 + 鍙告満缁忕含搴�
-            if (Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
-                ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
-                if (depositShop != null) {
-                    vo.setDepositShopLng(depositShop.getLongitude());
-                    vo.setDepositShopLat(depositShop.getLatitude());
-                }
-                if (order.getAcceptDriver() != null) {
-                    DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
-                    if (driver != null) {
-                        vo.setDriverLng(driver.getLongitude());
-                        vo.setDriverLat(driver.getLatitude());
-                    }
-                }
-            }
-            // status=4(閰嶉�佷腑)锛氳繑鍥炲彇浠剁偣缁忕含搴� + 鍙告満缁忕含搴�
-            if (Constants.equalsInteger(status, Constants.OrderStatus.delivering.getStatus())) {
-                // 鍙栦欢鐐圭粡绾害锛堜紭鍏堝彇浠堕棬搴楋紝鍚﹀垯璁㈠崟涓婄殑鍙栦欢鍧愭爣锛�
-                if (order.getTakeShopId() != null) {
-                    ShopInfo takeShop = shopInfoMapper.selectById(order.getTakeShopId());
-                    if (takeShop != null) {
-                        vo.setTakeLng(takeShop.getLongitude());
-                        vo.setTakeLat(takeShop.getLatitude());
-                    }
-                } else if (order.getTakeLgt() != null && order.getTakeLat() != null) {
-                    vo.setTakeLng(order.getTakeLgt().doubleValue());
-                    vo.setTakeLat(order.getTakeLat().doubleValue());
-                }
-                if (order.getAcceptDriver() != null) {
-                    DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
-                    if (driver != null) {
-                        vo.setDriverLng(driver.getLongitude());
-                        vo.setDriverLat(driver.getLatitude());
-                    }
-                }
-            }
+        vo.setDepositShopLng(order.getDepositLgt().doubleValue());
+        vo.setDepositShopLat(order.getDepositLat().doubleValue());
+        // 鍙栦欢鐐圭粡绾害
+        vo.setTakeLng(order.getTakeLgt().doubleValue());
+        vo.setTakeLat(order.getTakeLat().doubleValue());
+        //鍙告満缁忕含搴�
+        DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
+        if (driver != null) {
+            vo.setDriverLng(driver.getLongitude());
+            vo.setDriverLat(driver.getLatitude());
         }
-
         // 璇勪环淇℃伅
         vo.setCommentStatus(order.getCommentStatus());
         if (Constants.equalsInteger(order.getCommentStatus(), Constants.ONE)) {
@@ -1862,6 +2147,7 @@
             order.setStatus(Constants.OrderStatus.cancelled.getStatus());
             order.setCancelTime(now);
             ordersMapper.updateById(order);
+            restoreCoupon(order);
             saveCancelLog(order, Constants.OrderLogType.memberCancel, "浼氬憳鍙栨秷璁㈠崟锛堝緟鏀粯锛�", memberId);
             // 鐭俊閫氱煡浼氬憳锛氳鍗曞凡鍙栨秷
             Member cancelMember1 = memberMapper.selectById(memberId);
@@ -1888,9 +2174,10 @@
                     Constants.SmsNotify.MEMBER_CANCELLED, "orderNo", order.getCode());
 
             // 璋冪敤寰俊閫�娆綱3锛屽叏棰濋��娆�
+            String outRefundNo = ID.nextGUID();
             com.wechat.pay.java.service.refund.model.Refund refundResult;
             try {
-                refundResult = wxPayV3Service.refund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(),
+                refundResult = wxPayV3Service.refund(outRefundNo, order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(),
                         "璁㈠崟閫�娆�", wxPayProperties.getV3RefundNotifyUrl());
             } catch (Exception e) {
                 log.error("寰呭瘎瀛樿鍗曢��娆捐皟鐢ㄥ紓甯�, orderId={}", orderId, e);
@@ -1908,7 +2195,7 @@
             refund.setDeleted(Constants.ZERO);
             refund.setBeforeStatus(Constants.OrderStatus.waitDeposit.getStatus());
             refund.setRefundAmount(order.getPayAmount());
-            refund.setRefundCode(refundResult.getOutRefundNo());
+            refund.setRefundCode(outRefundNo);
 
             if (com.wechat.pay.java.service.refund.model.Status.SUCCESS.equals(refundStatus)) {
                 // 閫�娆炬垚鍔�
@@ -1922,6 +2209,7 @@
                 throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆惧け璐ワ紝璇疯仈绯诲鏈嶅鐞�");
             }
             ordersRefundMapper.insert(refund);
+            restoreCoupon(order);
             return;
         }
 
@@ -1938,20 +2226,37 @@
             DriverInfo originalDriver = originalDriverId != null ? driverInfoMapper.selectById(originalDriverId) : null;
 
             ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
-            // 鍙栦欢鐐逛俊鎭洿鏂颁负瀛樹欢闂ㄥ簵锛屼娇鐢� UpdateWrapper 纭繚 null 瀛楁涔熻兘鐢熸晥
+
+            // 璁$畻灏卞湴瀵勫瓨瀛樹欢闂ㄥ簵鍒嗘垚姣斾緥
+            Integer cityId = Integer.valueOf(order.getCityId());
+            boolean isCompany = depositShop != null && Constants.equalsInteger(depositShop.getCompanyType(), Constants.ONE);
+            int fallbackFieldA = isCompany ? Constants.FIVE : Constants.SIX;
+            BigDecimal localDepositRata = getShopRevenueShare(depositShop, "localDeposit", cityId, fallbackFieldA);
+            Long totalAmount = order.getTotalAmount() != null ? order.getTotalAmount() : 0L;
+            Long localDepositFee = new BigDecimal(totalAmount).multiply(localDepositRata)
+                    .setScale(0, RoundingMode.HALF_UP).longValue();
+
+            // 鍙栦欢鐐逛俊鎭洿鏂颁负瀛樹欢闂ㄥ簵锛岄噸绠楀垎鎴�
             UpdateWrapper<Orders> updateWrapper = new UpdateWrapper<>();
             updateWrapper.lambda()
                     .eq(Orders::getId, order.getId())
                     .set(Orders::getType, Constants.ZERO)
+                    .set(Orders::getStatus, Constants.OrderStatus.arrived.getKey())
+                    .set(Orders::getIsConverted, Constants.ONE)
                     .set(Orders::getTakeShopId, order.getDepositShopId())
-                    .set(Orders::getTakeShopName, order.getDepositShopName())
-                    .set(Orders::getTakeShopAddress, order.getDepositShopAddress())
-                    .set(Orders::getTakeShopLinkPhone, order.getDepositShopLinkPhone())
                     .set(Orders::getTakeLocation, order.getDepositLocation())
                     .set(Orders::getTakeLocationRemark, order.getDepositLocationRemark())
                     .set(Orders::getTakeLat, order.getDepositLat())
                     .set(Orders::getTakeLgt, order.getDepositLgt())
-                    .set(Orders::getExpectedTakeTime, new Date());
+                    .set(Orders::getExpectedTakeTime, new Date())
+                    // 瀛樹欢闂ㄥ簵鍒嗘垚鎸夊氨鍦板瘎瀛橀噸绠�
+                    .set(Orders::getDepositShopFeeRata, localDepositRata)
+                    .set(Orders::getDepositShopFee, localDepositFee)
+                    // 鍙告満銆佸彇浠堕棬搴楀垎鎴愬綊闆�
+                    .set(Orders::getDriverFeeRata, BigDecimal.ZERO)
+                    .set(Orders::getDriverFee, 0L)
+                    .set(Orders::getTakeShopFeeRata, BigDecimal.ZERO)
+                    .set(Orders::getTakeShopFee, 0L);
             if (Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
                 updateWrapper.lambda()
                         .set(Orders::getAcceptDriver, null)
@@ -1976,6 +2281,19 @@
     /**
      * 淇濆瓨鍙栨秷璁㈠崟鎿嶄綔鏃ュ織
      */
+    private void restoreCoupon(Orders order) {
+//        if (order.getCouponId() == null || order.getDeductionAmount() == null || order.getDeductionAmount() <= 0) {
+//            return;
+//        }
+//        memberCouponMapper.update(new UpdateWrapper<MemberCoupon>().lambda()
+//                .set(MemberCoupon::getStatus, Constants.CouponStatus.claimed.getKey())
+//                .set(MemberCoupon::getUseDate, null)
+//                .set(MemberCoupon::getOrderId, null)
+//                .eq(MemberCoupon::getId, order.getCouponId())
+//                .eq(MemberCoupon::getOrderId, order.getId())
+//                .eq(MemberCoupon::getStatus, Constants.CouponStatus.used.getKey()));
+    }
+
     private void saveCancelLog(Orders order, Constants.OrderLogType logType, String reason, Integer memberId) {
         OrderLog log = new OrderLog();
         log.setOrderId(order.getId());
@@ -1988,6 +2306,217 @@
         log.setCreateTime(new Date());
         log.setDeleted(Constants.ZERO);
         orderLogService.create(log);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void manualRefund(ManualRefundDTO dto, Integer userId) {
+        // 1. 鏍¢獙璁㈠崟
+        Orders order = ordersMapper.selectById(dto.getOrderId());
+        if (order == null || Constants.equalsInteger(order.getDeleted(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.finished.getStatus())) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呭凡瀹屾垚璁㈠崟鍙墜鍔ㄩ��娆�");
+        }
+        if (Constants.equalsInteger(order.getManualRefund(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曞凡鎵嬪姩閫�娆�");
+        }
+        // 寮傚父璁㈠崟涓嶅厑璁告墜鍔ㄩ��娆�
+        if (Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "寮傚父璁㈠崟涓嶆敮鎸佹墜鍔ㄩ��娆�");
+        }
+
+        // 2. 鏍¢獙閫�娆鹃噾棰�
+        long payAmount = order.getPayAmount() != null ? order.getPayAmount() : 0L;
+        long existingRefund = order.getRefundAmount() != null ? order.getRefundAmount() : 0L;
+        long maxRefund = payAmount - existingRefund;
+        if (dto.getRefundAmount() <= 0) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆鹃噾棰濆繀椤诲ぇ浜�0");
+        }
+        if (dto.getRefundAmount() > maxRefund) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆鹃噾棰濅笉鑳借秴杩囧彲閫�閲戦(" + maxRefund + "鍒�)");
+        }
+
+        // 3. 鏍¢獙骞舵竻鐞嗘墸娆鹃噾棰濓紙鏍规嵁璁㈠崟绫诲瀷锛�
+        boolean isRemote = Constants.equalsInteger(order.getType(), Constants.ONE);
+        Long depositShopDeduct = dto.getDepositShopDeduct();
+        Long takeShopDeduct = dto.getTakeShopDeduct();
+        Long driverDeduct = dto.getDriverDeduct();
+
+        if (!isRemote) {
+            takeShopDeduct = null;
+            driverDeduct = null;
+        } else {
+            if (order.getTakeShopId() == null) {
+                takeShopDeduct = null;
+            }
+        }
+        if (depositShopDeduct != null && depositShopDeduct < 0) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀛樹欢闂ㄥ簵鎵f閲戦涓嶈兘涓鸿礋");
+        }
+        if (takeShopDeduct != null && takeShopDeduct < 0) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鍙栦欢闂ㄥ簵鎵f閲戦涓嶈兘涓鸿礋");
+        }
+        if (driverDeduct != null && driverDeduct < 0) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鍙告満鎵f閲戦涓嶈兘涓鸿礋");
+        }
+
+        // 4. 鏋勫缓 deductInfo JSON
+        String deductInfo = null;
+        JSONObject deductJson = new JSONObject();
+        if (depositShopDeduct != null) {
+            deductJson.put("depositShopDeduct", depositShopDeduct);
+        }
+        if (takeShopDeduct != null) {
+            deductJson.put("takeShopDeduct", takeShopDeduct);
+        }
+        if (driverDeduct != null) {
+            deductJson.put("driverDeduct", driverDeduct);
+        }
+        if (deductJson.size() > 0) {
+            deductInfo = deductJson.toJSONString();
+        }
+
+        // 5. 鍒涘缓閫�娆捐褰�
+        Date now = new Date();
+        String outRefundNo = ID.nextGUID();
+        OrdersRefund refund = new OrdersRefund();
+        refund.setOrderId(order.getId());
+        refund.setType(Constants.FOUR); // 鎵嬪姩閫�娆�
+        refund.setRefundAmount(dto.getRefundAmount());
+        refund.setDeductInfo(deductInfo);
+        refund.setRefundRemark(dto.getRemark());
+        refund.setUserId(userId);
+        refund.setBeforeStatus(order.getStatus());
+        refund.setRefundCode(outRefundNo);
+        refund.setCreateTime(now);
+        refund.setDeleted(Constants.ZERO);
+        ordersRefundMapper.insert(refund);
+
+        // 6. 璋冪敤寰俊閫�娆�
+        try {
+            Refund refundResult = wxPayV3Service.refund(
+                    outRefundNo, order.getOutTradeNo(), payAmount, dto.getRefundAmount(),
+                    "鎵嬪姩閫�娆�", wxPayProperties.getV3RefundNotifyUrl());
+
+            com.wechat.pay.java.service.refund.model.Status refundStatus = refundResult.getStatus();
+            if (com.wechat.pay.java.service.refund.model.Status.SUCCESS.equals(refundStatus)) {
+                refund.setStatus(Constants.ONE);
+                refund.setRefundTime(now);
+                ordersRefundMapper.updateById(refund);
+                // 閫�娆炬垚鍔燂紝鎵ц鎵f
+                processManualRefundDeduction(order, depositShopDeduct, takeShopDeduct, driverDeduct);
+            } else if (com.wechat.pay.java.service.refund.model.Status.PROCESSING.equals(refundStatus)) {
+                refund.setStatus(Constants.ZERO); // 閫�娆句腑锛岀瓑鍥炶皟
+                ordersRefundMapper.updateById(refund);
+            } else {
+                refund.setStatus(Constants.TWO);
+                refund.setRefundRemark("寰俊閫�娆惧け璐�: " + refundStatus.name());
+                ordersRefundMapper.updateById(refund);
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆惧け璐ワ紝璇疯仈绯诲鏈嶅鐞�");
+            }
+        } catch (BusinessException e) {
+            throw e;
+        } catch (Exception e) {
+            log.error("鎵嬪姩閫�娆捐皟鐢ㄥ井淇¢��娆惧紓甯�, orderId={}", order.getId(), e);
+            refund.setStatus(Constants.TWO);
+            ordersRefundMapper.updateById(refund);
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆捐皟鐢ㄥ紓甯革紝璇风◢鍚庨噸璇�");
+        }
+
+        // 7. 鏇存柊璁㈠崟锛氭爣璁板凡鎵嬪姩閫�娆撅紝绱姞閫�娆鹃噾棰�
+        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
+                .set(Orders::getManualRefund, Constants.ONE)
+                .setSql(" REFUND_AMOUNT = IFNULL(REFUND_AMOUNT, 0) + " + dto.getRefundAmount())
+                .set(Orders::getUpdateTime, now)
+                .eq(Orders::getId, order.getId()));
+    }
+
+    /**
+     * 鎵嬪姩閫�娆炬垚鍔熷悗锛屾牴鎹墸娆句俊鎭墸闄ゅ搴旀柟浣欓骞剁敓鎴愭敹鏀褰�
+     */
+    private void processManualRefundDeduction(Orders order, Long depositShopDeduct, Long takeShopDeduct, Long driverDeduct) {
+        Date now = new Date();
+
+        // 瀛樹欢闂ㄥ簵鎵f
+        if (depositShopDeduct != null && depositShopDeduct > 0 && order.getDepositShopId() != null) {
+            ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
+            if (depositShop != null) {
+                shopInfoMapper.update(new UpdateWrapper<ShopInfo>().lambda()
+                        .setSql(" BALANCE = IFNULL(BALANCE, 0) - " + depositShopDeduct)
+                        .eq(ShopInfo::getId, depositShop.getId()));
+                revenueMapper.insert(buildDeductRevenue(depositShop.getId(), Constants.TWO,
+                        depositShopDeduct, order.getId(), order.getCode(), now));
+            }
+        }
+
+        // 鍙栦欢闂ㄥ簵鎵f
+        if (takeShopDeduct != null && takeShopDeduct > 0 && order.getTakeShopId() != null) {
+            ShopInfo takeShop = shopInfoMapper.selectById(order.getTakeShopId());
+            if (takeShop != null) {
+                shopInfoMapper.update(new UpdateWrapper<ShopInfo>().lambda()
+                        .setSql(" BALANCE = IFNULL(BALANCE, 0) - " + takeShopDeduct)
+                        .eq(ShopInfo::getId, takeShop.getId()));
+                revenueMapper.insert(buildDeductRevenue(takeShop.getId(), Constants.TWO,
+                        takeShopDeduct, order.getId(), order.getCode(), now));
+            }
+        }
+
+        // 鍙告満鎵f
+        if (driverDeduct != null && driverDeduct > 0 && order.getAcceptDriver() != null) {
+            DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
+            if (driver != null && driver.getMemberId() != null) {
+                driverInfoMapper.update(new UpdateWrapper<DriverInfo>().lambda()
+                        .setSql(" BALANCE = IFNULL(BALANCE, 0) - " + driverDeduct)
+                        .eq(DriverInfo::getId, driver.getId()));
+                revenueMapper.insert(buildDeductRevenue(driver.getMemberId(), Constants.ONE,
+                        driverDeduct, order.getId(), order.getCode(), now));
+            }
+        }
+    }
+
+    private Revenue buildDeductRevenue(Integer memberId, Integer memberType, Long amount, Integer orderId, String orderNo, Date now) {
+        Revenue revenue = new Revenue();
+        revenue.setMemberId(memberId);
+        revenue.setMemberType(memberType);
+        revenue.setType(Constants.FOUR); // 璐d换鎵f
+        revenue.setOptType(-Constants.ONE); // 鏀嚭
+        revenue.setAmount(amount);
+        revenue.setVaildStatus(Constants.ONE); // 宸插叆璐�
+        revenue.setObjId(orderId);
+        revenue.setObjType(Constants.ZERO); // 璁㈠崟涓氬姟
+        revenue.setOrderNo(orderNo);
+        revenue.setStatus(Constants.ZERO); // 鎴愬姛
+        revenue.setDeleted(Constants.ZERO);
+        revenue.setCreateTime(now);
+        return revenue;
+    }
+
+    @Override
+    public void processManualRefundCallback(OrdersRefund refundRecord) {
+        if (!Constants.equalsInteger(refundRecord.getType(), Constants.FOUR)) {
+            return;
+        }
+        if (StringUtils.isBlank(refundRecord.getDeductInfo())) {
+            return;
+        }
+        Orders order = ordersMapper.selectById(refundRecord.getOrderId());
+        if (order == null) {
+            return;
+        }
+        JSONObject deductJson = JSONObject.parseObject(refundRecord.getDeductInfo());
+        Long depositShopDeduct = deductJson.getLong("depositShopDeduct");
+        Long takeShopDeduct = deductJson.getLong("takeShopDeduct");
+        Long driverDeduct = deductJson.getLong("driverDeduct");
+        processManualRefundDeduction(order, depositShopDeduct, takeShopDeduct, driverDeduct);
+
+        // 鏍囪璁㈠崟宸叉墜鍔ㄩ��娆撅紝绱姞閫�娆鹃噾棰�
+        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
+                .set(Orders::getManualRefund, Constants.ONE)
+                .setSql(" REFUND_AMOUNT = IFNULL(REFUND_AMOUNT, 0) + " + refundRecord.getRefundAmount())
+                .set(Orders::getUpdateTime, new Date())
+                .eq(Orders::getId, order.getId()));
     }
 
     /**
@@ -2058,6 +2587,10 @@
      * 鍙戦�佸徃鏈虹珯鍐呬俊閫氱煡
      */
     private void sendDriverNotice(Integer driverId, Constants.DriverOrderNotify notify, Integer orderId, String... params) {
+        sendDriverNotice(driverId, notify, orderId, 0, params);
+    }
+
+    private void sendDriverNotice(Integer driverId, Constants.DriverOrderNotify notify, Integer objId, Integer objType, String... params) {
         DriverInfo driver = driverInfoMapper.selectById(driverId);
         if (driver == null || driver.getMemberId() == null) {
             return;
@@ -2067,8 +2600,8 @@
         notice.setUserId(driver.getMemberId());
         notice.setTitle(notify.getTitle());
         notice.setContent(notify.format(params));
-        notice.setObjId(orderId);
-        notice.setObjType(0); // 0=璁㈠崟
+        notice.setObjId(objId);
+        notice.setObjType(objType);
         notice.setStatus(0);  // 0=鏈
         notice.setIsdeleted(Constants.ZERO);
         notice.setCreateDate(new Date());
@@ -2096,6 +2629,14 @@
         order.setWxExternalNo(wxTradeNo);
         order.setPayAmount(order.getTotalAmount());
         order.setUpdateTime(now);
+        // 璁$畻搴楅摵璁㈠崟搴忓彿锛氬綋鍓嶅瓨浠堕棬搴楀綋澶╁凡鏀粯璁㈠崟鏁� + 1
+        Date todayStart = DateUtil.getStartOfDay(now);
+        Long currentCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getDepositShopId, order.getDepositShopId())
+                .eq(Orders::getPayStatus, Constants.ONE)
+                .ge(Orders::getPayTime, todayStart)
+                .eq(Orders::getDeleted, Constants.ZERO));
+        order.setAutoNum(currentCount + 1);
         // 鐢熸垚浼氬憳鏍搁攢鐮�
         order.setMemberVerifyCode(generateVerifyCode());
         // 寮傚湴瀵勫瓨锛氳绠楅璁¢�佽揪鏃堕棿
@@ -2117,6 +2658,20 @@
             }
         }
         ordersMapper.updateById(order);
+
+        // 鏀粯鎴愬姛鏃ュ織
+        OrderLog payLog = new OrderLog();
+        payLog.setOrderId(order.getId());
+        payLog.setTitle(Constants.OrderLogType.payOrder.getTitle());
+        payLog.setLogInfo(Constants.OrderLogType.payOrder.format(
+                String.valueOf(order.getTotalAmount() != null ? order.getTotalAmount() / 100.0 : 0)));
+        payLog.setObjType(Constants.OrderLogType.payOrder.getStatus());
+        payLog.setOrderStatus(order.getStatus());
+        payLog.setOptUserId(order.getMemberId());
+        payLog.setOptUserType(0);
+        payLog.setCreateTime(now);
+        payLog.setDeleted(Constants.ZERO);
+        orderLogService.create(payLog);
 
         // 閫氱煡浼氬憳锛氳鍗曞緟鏍搁獙
         sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_VERIFY, order.getId(),
@@ -2251,6 +2806,7 @@
     public PayResponse payShopDeposit(Integer memberId) {
         // 1. 鏌ヨ闂ㄥ簵淇℃伅
         ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda()
+                .eq(ShopInfo::getDeleted,Constants.ZERO)
                 .eq(ShopInfo::getRegionMemberId,memberId));
         if (shopInfo == null) {
             throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "闂ㄥ簵涓嶅瓨鍦�");
@@ -2309,26 +2865,37 @@
         otherOrders.setUpdateTime(now);
         otherOrdersMapper.updateById(otherOrders);
 
-        // 4. 鏌ヨ闂ㄥ簵淇℃伅锛堥�氳繃娉ㄥ唽浼氬憳涓婚敭鍏宠仈锛�
+        // 4. 鏌ヨ鍙樻洿鐗堟湰闂ㄥ簵淇℃伅锛堥�氳繃娉ㄥ唽浼氬憳涓婚敭鍏宠仈锛�
         ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda()
                 .eq(ShopInfo::getRegionMemberId, otherOrders.getMemberId())
                 .eq(ShopInfo::getDeleted, Constants.ZERO)
+                .eq(ShopInfo::getVersionType, Constants.ONE)
                 .last("limit 1"));
         if (shopInfo == null) {
-            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "闂ㄥ簵涓嶅瓨鍦�");
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "闂ㄥ簵鍙樻洿璁板綍涓嶅瓨鍦�");
         }
-        // 5. 鏇存柊闂ㄥ簵鐘舵�侊細宸叉敮浠樻娂閲�
-        shopInfo.setAuditStatus(Constants.THREE); // 3=宸叉敮浠樻娂閲�
+        // 5. 鏇存柊鍙樻洿鐗堟湰鏀粯鐘舵��
+        Member member = memberMapper.selectById(otherOrders.getMemberId());
+        shopInfo.setAuditStatus(Constants.THREE);
         shopInfo.setPayStatus(Constants.ONE);
         shopInfo.setPayTime(now);
         shopInfo.setWxExternalNo(wxTradeNo);
         shopInfo.setCode(otherOrders.getCode());
-        Member member = memberMapper.selectById(otherOrders.getMemberId());
         if (member != null) {
             shopInfo.setPayMemberOpenId(member.getOpenid());
         }
         shopInfo.setUpdateTime(now);
         shopInfoMapper.updateById(shopInfo);
+
+        // 6. 鍚屾鏇存柊姝e紡鐗堟湰鐘舵�佷负宸叉敮浠樻娂閲�
+        if (shopInfo.getRelationShopId() != null) {
+            ShopInfo officialShop = shopInfoMapper.selectById(shopInfo.getRelationShopId());
+            if (officialShop != null) {
+                officialShop.setAuditStatus(Constants.THREE);
+                officialShop.setUpdateTime(now);
+                shopInfoMapper.updateById(officialShop);
+            }
+        }
 
         // 鐭俊閫氱煡闂ㄥ簵锛氭垚鍔熷叆椹�
         String rawPassword = shopInfo.getTelephone() != null && shopInfo.getTelephone().length() >= 6
@@ -2336,18 +2903,17 @@
         sendSmsNotify(shopInfo.getTelephone(),
                 Constants.SmsNotify.SHOP_AUTH_SUCCESS,
                 "storeName", shopInfo.getName(),
-                "phone", shopInfo.getTelephone() != null ? shopInfo.getTelephone() : "",
                 "password", rawPassword);
 
         // 6. 鎶奸噾鏀粯瀹屾垚鍚庯紝鑻ュ煄甯傛湭寮�閫氬垯鑷姩寮�閫�
         if (shopInfo.getAreaId() != null) {
-            Areas shopArea = areasBiz.resolveArea(shopInfo.getAreaId());
+            Areas shopArea = aareasMapper.selectById(shopInfo.getAreaId());
             if (shopArea != null && shopArea.getParentId() != null) {
-                Areas cityArea = areasBiz.resolveArea(shopArea.getParentId());
+                Areas cityArea = aareasMapper.selectById(shopArea.getParentId());
                 if (cityArea != null && !Constants.equalsInteger(cityArea.getStatus(), Constants.ONE)) {
                     cityArea.setStatus(Constants.ONE);
                     cityArea.setEditDate(now);
-                    areasService.updateById(cityArea);
+                    aareasMapper.updateById(cityArea);
                     areasService.cacheData();
                 }
             }
@@ -2373,7 +2939,8 @@
                 .eq(Orders::getDeleted, Constants.ZERO)
                 .eq(Orders::getStatus, Constants.OrderStatus.finished.getStatus())
                 .eq(Orders::getSettlementStatus, Constants.ZERO)
-                .le(Orders::getFinishTime, deadline));
+                .le(Orders::getFinishTime, deadline)
+        );
         if (ordersList == null || ordersList.isEmpty()) {
             return;
         }
@@ -2418,7 +2985,7 @@
                 } else if (Constants.equalsInteger(revenue.getMemberType(), Constants.TWO)) {
                     // 闂ㄥ簵锛氶�氳繃 memberId 鏌� ShopInfo(regionMemberId)锛屾洿鏂� balance / totalBalance
                     ShopInfo shop = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda()
-                            .eq(ShopInfo::getRegionMemberId, revenue.getMemberId())
+                            .eq(ShopInfo::getId, revenue.getMemberId())
                             .eq(ShopInfo::getDeleted, Constants.ZERO)
                             .last("limit 1"));
                     if (shop != null) {
@@ -2675,6 +3242,10 @@
             }
             order.setMemberVerifyCode(generateVerifyCode());
             ordersMapper.updateById(order);
+            // 瀵勫瓨鏃跺浘鐗囧繀濉�
+//            if (images == null || images.isEmpty()) {
+//                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇蜂笂浼犲瘎瀛樺浘鐗�");
+//            }
             // 淇濆瓨瀵勫瓨鍥剧墖锛坥bj_type=2 璁㈠崟瀵勫瓨鍥剧墖锛屾渶澶�3寮狅級
             saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_DEPOSIT.getKey(), shopId);
             // 璁板綍璁㈠崟鏃ュ織
@@ -2684,6 +3255,8 @@
                 // 寮傚湴瀵勫瓨 鈫� 寰呮姠鍗�
                 sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(),
                         "orderNo", order.getCode());
+                // 鎺ㄩ�侀�氱煡鍙告満
+                pushDriverNewOrder(order);
             } else {
                 // 灏卞湴瀵勫瓨 鈫� 寰呭彇浠舵彁閱�
                 sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(),
@@ -2708,8 +3281,15 @@
             }
             // 寰呭彇浠�(5) 鈫� 宸插畬鎴�(7)
             order.setStatus(Constants.OrderStatus.finished.getStatus());
-            order.setConfirmArriveTime(now);
+            order.setFinishTime(now);
+            order.setInvoiceStatus(Constants.ONE);
             ordersMapper.updateById(order);
+            // 灏卞湴瀵勫瓨(type=0)鍙栦欢鏃跺浘鐗囦笉蹇呭~锛屽叾浠栫被鍨嬪彇浠跺繀濉�
+            if (!Constants.equalsInteger(order.getType(), Constants.ZERO)) {
+                if (images == null || images.isEmpty()) {
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇蜂笂浼犲彇浠跺浘鐗�");
+                }
+            }
             // 璁㈠崟瀹屾垚锛岄噴鏀炬牳閿�鐮�
             String verifyCode = order.getMemberVerifyCode();
             if (StringUtils.isNotBlank(verifyCode)) {
@@ -2736,7 +3316,64 @@
                         "orderNo", order.getCode(),
                         "settleDays", settleDays != null ? settleDays : "7");
             }
-        } else {
+        }else if(Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getKey())){
+            // 浠呭紓鍦板瘎瀛� + 鏈夊彇浠堕棬搴� + 娲鹃�佷腑(4) 鍙牳閿�
+            if (!Constants.equalsInteger(order.getType(), Constants.ONE)) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呭紓鍦板瘎瀛樿鍗曟敮鎸佸徃鏈烘牳閿�");
+            }
+            if (order.getTakeShopId() == null) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曟棤鍙栦欢闂ㄥ簵锛屾棤闇�鍙告満鏍搁攢");
+            }
+            if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getStatus())) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽鏍搁攢");
+            }
+            // 鏍¢獙鍙栦欢闂ㄥ簵涓庡綋鍓嶇櫥褰曢棬搴椾竴鑷�
+            if (!shopId.equals(order.getTakeShopId())) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曚笉灞炰簬褰撳墠闂ㄥ簵锛屾棤娉曟牳閿�");
+            }
+            // 娲鹃�佷腑(4) 鈫� 宸插埌搴�(5)
+            order.setStatus(Constants.OrderStatus.arrived.getStatus());
+            order.setArriveTime(new Date());
+            if (StringUtils.isNotBlank(remark)) {
+                order.setRemark(remark);
+            }
+            ordersMapper.updateById(order);
+
+            // 閲婃斁鍙告満鏍搁攢鐮�
+            releaseVerifyCode(order.getDriverVerifyCode());
+
+            // 淇濆瓨闄勪欢锛坥bj_type=3 闂ㄥ簵鍏ュ簱鍥剧墖锛屾渶澶�3寮狅級
+            saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_TAKE.getKey(), order.getAcceptDriver());
+
+            // 閫氱煡浼氬憳锛氳鍗曞凡閫佽揪
+            String destination = order.getTakeShopAddress() != null ? order.getTakeShopAddress() : "";
+            if (order.getMemberVerifyCode() != null) {
+                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.ARRIVED_HAS_SHOP, order.getId(),
+                        "orderNo", order.getCode(),
+                        "destination", destination,
+                        "pickupCode", order.getMemberVerifyCode());
+            } else {
+                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.ARRIVED_NO_SHOP, order.getId(),
+                        "orderNo", order.getCode(),
+                        "destination", destination);
+            }
+
+            // 閫氱煡鍙栦欢闂ㄥ簵锛氳鍗曞凡閫佽揪
+            if (order.getTakeShopId() != null) {
+                sendShopNotice(order.getTakeShopId(), Constants.ShopOrderNotify.ARRIVED, order.getId(),
+                        "orderNo", order.getCode(),
+                        "destination", destination);
+            }
+
+            // 鐭俊閫氱煡浼氬憳锛氳鏉庡凡閫佽揪
+            Member arrivedMember = memberMapper.selectById(order.getMemberId());
+            if (arrivedMember != null) {
+                sendSmsNotify(arrivedMember.getTelephone(), Constants.SmsNotify.MEMBER_ARRIVED,
+                        "orderNo", order.getCode(),
+                        "address", destination,
+                        "code", order.getMemberVerifyCode() != null ? order.getMemberVerifyCode() : "");
+            }
+        }else {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽鏍搁攢");
         }
     }
@@ -2786,10 +3423,36 @@
                 // 寮傚湴瀵勫瓨 鈫� 寰呮姠鍗�
                 sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(),
                         "orderNo", order.getCode());
+                // 鎺ㄩ�侀�氱煡鍙告満
+                pushDriverNewOrder(order);
             } else {
                 // 灏卞湴瀵勫瓨 鈫� 寰呭彇浠舵彁閱�
                 sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(),
                         "orderNo", order.getCode(), "shopName", shopName);
+            }
+            // 寮傚父璁㈠崟瀵勫瓨鏍搁攢锛氭爣璁板師璁㈠崟瀹屾垚
+            if (Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE) && order.getRelationOrderId() != null) {
+                Orders originalOrder = ordersMapper.selectById(order.getRelationOrderId());
+                if (originalOrder != null) {
+                    originalOrder.setStatus(Constants.OrderStatus.finished.getStatus());
+                    originalOrder.setInvoiceStatus(Constants.ONE);
+                    originalOrder.setFinishTime(now);
+                    originalOrder.setUpdateTime(now);
+                    ordersMapper.updateById(originalOrder);
+                    // 瑙﹀彂鍘熻鍗曟敹鐩婅绠�
+                    calculateAndSaveOrderFees(originalOrder.getId());
+                    generateRevenueRecords(originalOrder.getId());
+                    // 閫氱煡浼氬憳锛氳鍗曞凡瀹屾垚
+                    sendOrderNotice(originalOrder.getMemberId(), Constants.MemberOrderNotify.FINISHED, originalOrder.getId(),
+                            "orderNo", originalOrder.getCode());
+                    // 閫氱煡鍙告満锛氳鍗曞凡瀹屾垚
+                    if (originalOrder.getAcceptDriver() != null) {
+                        String settleDays = operationConfigBiz.getConfig().getSettlementDate();
+                        sendDriverNotice(originalOrder.getAcceptDriver(), Constants.DriverOrderNotify.FINISHED, originalOrder.getId(),
+                                "orderNo", originalOrder.getCode(),
+                                "settleDays", settleDays != null ? settleDays : "7");
+                    }
+                }
             }
         } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) {
             // 寮傚湴瀵勫瓨 + 鏃犲彇浠堕棬搴� 鈫� 鏃犳硶鏍搁攢锛堝鎴疯嚜鍙栵紝鏃犻棬搴楁搷浣滐級
@@ -2810,6 +3473,7 @@
             }
             // 寰呭彇浠�(5) 鈫� 宸插畬鎴�(7)
             order.setStatus(Constants.OrderStatus.finished.getStatus());
+            order.setInvoiceStatus(Constants.ONE);
             order.setConfirmArriveTime(now);
             ordersMapper.updateById(order);
             // 璁㈠崟瀹屾垚锛岄噴鏀炬牳閿�鐮�
@@ -2886,6 +3550,7 @@
         // 7. 鏇存柊璁㈠崟鐘舵�佷负宸插畬鎴�
         Date now = new Date();
         order.setStatus(Constants.OrderStatus.finished.getStatus());
+        order.setInvoiceStatus(Constants.ONE);
         order.setFinishTime(now);
         order.setUpdateTime(now);
         ordersMapper.updateById(order);
@@ -2914,12 +3579,13 @@
             ordersRefundMapper.insert(refundRecord);
 
             // 璋冪敤寰俊閫�娆綱3锛堟斁鍦ㄦ渶鍚庯紝纭繚鍓嶇疆鎿嶄綔鍏ㄩ儴鎴愬姛锛�
+            String outRefundNo2 = ID.nextGUID();
             Refund refundResult = wxPayV3Service.refund(
-                    order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount(),
+                    outRefundNo2, order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount(),
                     "璁㈠崟閫�娆�", wxPayProperties.getV3RefundNotifyUrl());
 
             // 閫�娆炬垚鍔熷悗鍥炲~閫�娆惧崟鍙凤紝鏍囪閫�娆句腑
-            refundRecord.setRefundCode(refundResult.getOutRefundNo());
+            refundRecord.setRefundCode(outRefundNo2);
             refundRecord.setStatus(Constants.ZERO); // 閫�娆句腑
             ordersRefundMapper.updateById(refundRecord);
         }
@@ -2974,10 +3640,15 @@
         if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.arrived.getStatus())) {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽纭鏀惰揣");
         }
+        // 5.1 鏍¢獙寮傚父鐘舵��
+        if (Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璁㈠崟寮傚父锛屽凡琚浆瀛橈紝璇疯仈绯荤鐞嗗憳鎴栨煡鐪嬬煭淇�");
+        }
 
         // 6. 鏇存柊璁㈠崟鐘舵�佷负宸插畬鎴�
         Date now = new Date();
         order.setStatus(Constants.OrderStatus.finished.getStatus());
+        order.setInvoiceStatus(Constants.ONE);
         order.setFinishTime(now);
         order.setUpdateTime(now);
         ordersMapper.updateById(order);
@@ -3014,7 +3685,6 @@
         BigDecimal depositRate = order.getDepositShopFeeRata() != null ? order.getDepositShopFeeRata() : BigDecimal.ZERO;
         BigDecimal takeRate = order.getTakeShopFeeRata() != null ? order.getTakeShopFeeRata() : BigDecimal.ZERO;
         BigDecimal driverRate = order.getDriverFeeRata() != null ? order.getDriverFeeRata() : BigDecimal.ZERO;
-        Long exceptionFeeVal = order.getExceptionFee() != null ? order.getExceptionFee() : 0L;
 
         //瀛樹欢闂ㄥ簵鏀剁泭
         Long depositShopFee = new BigDecimal(totalAmount)
@@ -3030,8 +3700,7 @@
             driverFee = new BigDecimal(totalAmount)
                     .multiply(driverRate)
                     .setScale(0, RoundingMode.HALF_UP)
-                    .longValue()
-                    + exceptionFeeVal;
+                    .longValue();
 
             // 寮傚湴瀵勫瓨涓旀湁鍙栦欢闂ㄥ簵锛氬姞涓婂彇浠堕棬搴楁敹鐩�
             if (order.getTakeShopId() != null) {
@@ -3067,8 +3736,8 @@
         // 瀛樹欢闂ㄥ簵鏀剁泭
         if (depositShopFee > 0 && order.getDepositShopId() != null) {
             ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
-            if (depositShop != null && depositShop.getRegionMemberId() != null) {
-                revenueMapper.insert(buildRevenue(depositShop.getRegionMemberId(), Constants.TWO,
+            if (depositShop != null && depositShop.getId() != null) {
+                revenueMapper.insert(buildRevenue(depositShop.getId(), Constants.TWO,
                         depositShopFee, orderId, order.getCode()));
             }
         }
@@ -3076,8 +3745,8 @@
         // 鍙栦欢闂ㄥ簵鏀剁泭锛堝紓鍦板瘎瀛樹笖鏈夊彇浠堕棬搴楋級
         if (takeShopFee > 0 && order.getTakeShopId() != null) {
             ShopInfo takeShop = shopInfoMapper.selectById(order.getTakeShopId());
-            if (takeShop != null && takeShop.getRegionMemberId() != null) {
-                revenueMapper.insert(buildRevenue(takeShop.getRegionMemberId(), Constants.TWO,
+            if (takeShop != null && takeShop.getId() != null) {
+                revenueMapper.insert(buildRevenue(takeShop.getId(), Constants.TWO,
                         takeShopFee, orderId, order.getCode()));
             }
         }
@@ -3090,6 +3759,91 @@
                         driverFee, orderId, order.getCode()));
             }
         }
+
+        // 寮傚父璁㈠崟锛氬徃鏈哄紓甯歌ˉ鍋匡紙寮傚湴 + 寮傚父鏍囪 + 鏈夊紓甯歌ˉ鍋块噾棰濓級
+        if (Constants.equalsInteger(order.getType(), Constants.ONE)
+                && Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE)
+                && order.getExceptionFee() != null && order.getExceptionFee() > 0
+                && order.getAcceptDriver() != null) {
+            DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
+            if (driver != null && driver.getMemberId() != null) {
+                Revenue exRevenue = new Revenue();
+                exRevenue.setMemberId(driver.getMemberId());
+                exRevenue.setMemberType(Constants.ONE); // 1=鍙告満
+                exRevenue.setType(5); // 5=寮傚父閲戦
+                exRevenue.setOptType(Constants.ONE); // 1=鏀跺叆
+                exRevenue.setAmount(order.getExceptionFee());
+                exRevenue.setVaildStatus(Constants.ZERO);
+                exRevenue.setObjId(orderId);
+                exRevenue.setObjType(Constants.ZERO);
+                exRevenue.setStatus(Constants.ZERO);
+                exRevenue.setOrderNo(order.getCode());
+                exRevenue.setDeleted(Constants.ZERO);
+                exRevenue.setCreateTime(now);
+                revenueMapper.insert(exRevenue);
+            }
+        }
+
+        // 鍙告満濂栧姳閲戯紙浠呯敓鎴愬鍔辫褰曪紝涓嶇洿鎺ュ叆璐︼級
+        generateDriverReward(order);
+    }
+
+    /**
+     * 鐢熸垚鍙告満濂栧姳璁板綍
+     * 瑙勫垯锛�
+     *   宸插鍔辨鏁� < registerRewardOrderCount 鈫� 娉ㄥ唽濂栧姳锛坱ype=0, amount=registerRewardAmount锛�
+     *   registerRewardOrderCount <= 宸插鍔辨鏁� < (registerRewardOrderCount + platformRewardOrderCount) 鈫� 骞冲彴濂栧姳锛坱ype=1, amount=platformRewardAmount锛�
+     *   瓒呭嚭鎬诲悕棰濅笉濂栧姳
+     */
+    private void generateDriverReward(Orders order) {
+        if (order.getAcceptDriver() == null) return;
+        DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
+        if (driver == null || driver.getId() == null) return;
+
+        // 璇诲彇濂栧姳閰嶇疆
+        String registerCountStr = operationConfigBiz.getConfig().getRegisterRewardOrderCount();
+        String registerAmountStr = operationConfigBiz.getConfig().getRegisterRewardAmount();
+        String platformCountStr = operationConfigBiz.getConfig().getPlatformRewardOrderCount();
+        String platformAmountStr = operationConfigBiz.getConfig().getPlatformRewardAmount();
+        if (StringUtils.isAnyBlank(registerCountStr, registerAmountStr, platformCountStr, platformAmountStr)) return;
+
+        int registerCount = Integer.parseInt(registerCountStr);
+        long registerAmount = new BigDecimal(registerAmountStr).multiply(BigDecimal.valueOf(100)).longValue();
+        int platformCount = Integer.parseInt(platformCountStr);
+        long platformAmount = new BigDecimal(platformAmountStr).multiply(BigDecimal.valueOf(100)).longValue();
+        int totalRewardSlots = registerCount + platformCount; // 鎬诲鍔卞悕棰�
+
+        // 鏌ヨ鍙告満宸插鍔辨鏁�
+        Long rewarded = rewardRecordMapper.selectCount(new QueryWrapper<RewardRecord>().lambda()
+                .eq(RewardRecord::getDriverId, driver.getId())
+                .eq(RewardRecord::getDeleted, Constants.ZERO));
+        int count = rewarded.intValue();
+        if (count >= totalRewardSlots) return; // 宸茶秴鍑哄鍔卞悕棰�
+
+        // 鍒ゆ柇鏈濂栧姳绫诲瀷鍜岄噾棰�
+        int rewardType;
+        long rewardAmount;
+        if (count < registerCount) {
+            // 娉ㄥ唽濂栧姳闃舵
+            rewardType = Constants.ZERO;
+            rewardAmount = registerAmount;
+        } else {
+            // 骞冲彴濂栧姳闃舵
+            rewardType = Constants.ONE;
+            rewardAmount = platformAmount;
+        }
+        if (rewardAmount <= 0) return;
+
+        // 鍒涘缓濂栧姳璁板綍锛堢姸鎬�=0寰呴鍙栵紝鍚庣画鐢卞徃鏈洪鍙栨椂鍏ヨ处锛�
+        RewardRecord record = new RewardRecord();
+        record.setOrderId(order.getId());
+        record.setDriverId(driver.getId());
+        record.setStatus(Constants.ZERO); // 0=寰呴鍙�
+        record.setType(rewardType);       // 0=娉ㄥ唽濂栧姳, 1=骞冲彴濂栧姳
+        record.setAmount(rewardAmount);
+        record.setDeleted(Constants.ZERO);
+        record.setCreateTime(new Date());
+        rewardRecordMapper.insert(record);
     }
 
     /**
@@ -3251,9 +4005,58 @@
                 new QueryWrapper<OrdersDetail>().lambda()
                         .eq(OrdersDetail::getOrderId, orderId)
                         .eq(OrdersDetail::getDeleted, Constants.ZERO));
-        OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(order, details);
 
         Date now = new Date();
+
+        // 寮傚父璁㈠崟閫炬湡閫昏緫
+        if (Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE)
+                && order.getRelationOrderId() != null) {
+            Orders originalOrder = ordersMapper.selectById(order.getRelationOrderId());
+            long driverExceptionFee = (originalOrder != null && originalOrder.getExceptionFee() != null)
+                    ? originalOrder.getExceptionFee() : 0L;
+            long shopExceptionFee = order.getShopCompensationAmount() != null ? order.getShopCompensationAmount() : 0L;
+            long totalExceptionFee = driverExceptionFee + shopExceptionFee;
+
+            // 鍒ゆ柇鏄惁褰撳ぉ鍙栦欢锛堟寜 expectedTakeTime 鏃ユ湡锛�
+            boolean sameDay = isSameDay(now, order.getExpectedTakeTime());
+
+            long overdueFee;
+            int overdueDays;
+            if (sameDay) {
+                // 褰撳ぉ鍙栦欢锛氶�炬湡璐圭敤 = 寮傚父璐圭敤鎬诲拰
+                overdueFee = totalExceptionFee;
+                overdueDays = totalExceptionFee > 0 ? 1 : 0;
+            } else {
+                // 闈炲綋澶╁彇浠讹細姝e父閫炬湡璁$畻 + 鍙告満寮傚父璐圭敤锛堜笉鍚棬搴楀紓甯歌垂鐢級
+                OverdueFeeVO normalOverdue = calculateOverdueFeeInternal(order, details);
+                long normalFee = (normalOverdue != null && normalOverdue.getOverdueFee() != null)
+                        ? normalOverdue.getOverdueFee() : 0L;
+                overdueFee = normalFee + driverExceptionFee;
+                overdueDays = (normalOverdue != null && normalOverdue.getOverdueDays() != null)
+                        ? normalOverdue.getOverdueDays() : 0;
+            }
+
+            order.setConfirmArriveTime(now);
+            order.setUpdateTime(now);
+            if (overdueFee > 0) {
+                order.setOverdueStatus(Constants.ONE);
+                order.setOverdueDays(overdueDays);
+                order.setOverdueAmount(overdueFee);
+                ordersMapper.updateById(order);
+                String overdueLogInfo = "闂ㄥ簵銆�" + shopName + "銆戠‘璁ら【瀹㈠埌搴楋紝閫炬湡" + overdueDays
+                        + "澶╋紝閫炬湡璐圭敤" + Constants.getFormatMoney(overdueFee) + "鍏�";
+                saveShopVerifyLog(order, Constants.OrderLogType.shopConfirmArriveOverdue, overdueLogInfo, null, shopId);
+            } else {
+                order.setOverdueStatus(Constants.ZERO);
+                ordersMapper.updateById(order);
+                saveShopVerifyLog(order, Constants.OrderLogType.shopConfirmArrive,
+                        "闂ㄥ簵銆�" + shopName + "銆戠‘璁ら【瀹㈠埌搴楋紝鏈�炬湡", null, shopId);
+            }
+            return;
+        }
+
+        // 鏅�氳鍗曢�炬湡璁$畻
+        OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(order, details);
 
         if (overdueInfo.getOverdue() && overdueInfo.getOverdueDays() > 0) {
             // 瀛樺湪閫炬湡锛氭爣璁伴�炬湡鐘舵�侊紝璁㈠崟淇濇寔褰撳墠鐘舵��
@@ -3279,17 +4082,26 @@
                 int actualDays = calcActualDepositDays(now, order.getDepositTime());
                 order.setDepositDays(actualDays);
 
-                int estimatedDays = order.getEstimatedDepositDays() != null ? order.getEstimatedDepositDays() : 1;
-                int refundDays = estimatedDays - actualDays;
-                if (refundDays > 0) {
-                    // 閫�娆鹃噾棰� = 閫�娆惧ぉ鏁� 脳 危(鐗╁搧鍗曚环 脳 鏁伴噺)
-                    long dailyBaseFee = 0L;
-                    for (OrdersDetail d : details) {
-                        dailyBaseFee += (d.getUnitPrice() != null ? d.getUnitPrice() : 0L)
-                                * (d.getNum() != null ? d.getNum() : 0);
+                long dailyBaseFee = 0L;
+                for (OrdersDetail d : details) {
+                    dailyBaseFee += (d.getLocallyPrice() != null ? d.getLocallyPrice() : 0L)
+                            * (d.getNum() != null ? d.getNum() : 0);
+                }
+
+                if (Constants.equalsInteger(order.getIsConverted(), Constants.ONE)) {
+                    // 杞崲璁㈠崟锛氬疄闄呰垂鐢ㄤ笌宸蹭粯閲戦瀵规瘮
+                    long actualFee = (long) actualDays * dailyBaseFee;
+                    long payAmount = order.getPayAmount() != null ? order.getPayAmount() : 0L;
+                    if (actualFee < payAmount) {
+                        order.setRefundAmount(payAmount - actualFee);
                     }
-                    long refundAmount = (long) refundDays * dailyBaseFee;
-                    order.setRefundAmount(refundAmount);
+                } else {
+                    // 鏅�氳鍗曪細鎸夐璁″ぉ鏁颁笌瀹為檯澶╂暟宸绠楅��娆�
+                    int estimatedDays = order.getEstimatedDepositDays() != null ? order.getEstimatedDepositDays() : 1;
+                    int refundDays = estimatedDays - actualDays;
+                    if (refundDays > 0) {
+                        order.setRefundAmount((long) refundDays * dailyBaseFee);
+                    }
                 }
             }
 
@@ -3343,7 +4155,12 @@
             return "鍙告満宸插彇浠讹紝姝h繍寰�鐩殑鍦�";
         }
         if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) {
-            return "琛屾潕宸查�佽揪鏈嶅姟鐐癸紝璇峰強鏃跺墠寰�鍙栦欢";
+            if(Constants.equalsInteger(order.getType(),Constants.ZERO)){
+                return "琛屾潕宸插瘎瀛橈紝璇峰嚟鍙栦欢鐮佸墠寰�鎸囧畾闂ㄥ簵鍙栦欢~";
+            }else{
+                return "琛屾潕宸查�佽揪鏈嶅姟鐐癸紝璇峰強鏃跺墠寰�鍙栦欢";
+            }
+
         }
         if (Constants.equalsInteger(status, Constants.OrderStatus.finished.getStatus())) {
             if (Constants.equalsInteger(order.getCommentStatus(), Constants.ONE)) {
@@ -3448,7 +4265,10 @@
      * 渚涘垎椤电瓑宸叉煡璇㈡槑缁嗙殑涓氬姟鍦烘櫙澶嶇敤锛岄伩鍏嶉噸澶嶆煡璇�
      */
     private OverdueFeeVO calculateOverdueFeeInternal(Orders order, List<OrdersDetail> details) {
-        if (CollectionUtils.isEmpty(details)) {
+        if (CollectionUtils.isEmpty(details)||
+                Constants.equalsInteger(order.getStatus(),Constants.ZERO)
+        || Constants.equalsInteger(order.getStatus(),Constants.ONE)
+        ) {
             OverdueFeeVO vo = new OverdueFeeVO();
             vo.setOverdue(false);
             vo.setOverdueDays(0);
@@ -3470,6 +4290,31 @@
 
         if (Constants.equalsInteger(order.getType(), Constants.ZERO)) {
             // ========== 灏卞湴瀵勫瓨 ==========
+
+            // 杞崲璁㈠崟锛堝紓鍦拌浆灏卞湴锛夛細鎸夊瘎瀛樻椂闂村埌褰撳墠鏃堕棿璁$畻瀹為檯璐圭敤
+            if (Constants.equalsInteger(order.getIsConverted(), Constants.ONE)) {
+                int actualDays = calcActualDepositDays(now, order.getDepositTime());
+                long actualFee = (long) actualDays * dailyBaseFee;
+                long payAmount = order.getPayAmount() != null ? order.getPayAmount() : 0L;
+
+                OverdueFeeVO vo = new OverdueFeeVO();
+                vo.setDailyBaseFee(dailyBaseFee);
+                if (actualFee <= payAmount) {
+                    // 瀹為檯璐圭敤 <= 宸蹭粯閲戦锛氭湭閫炬湡
+                    vo.setOverdue(false);
+                    vo.setOverdueDays(0);
+                    vo.setOverdueFee(0L);
+                } else {
+                    // 瀹為檯璐圭敤 > 宸蹭粯閲戦锛氶�炬湡锛屽樊浠蜂负閫炬湡璐圭敤
+                    int overDays = actualDays - (order.getEstimatedDepositDays() != null ? order.getEstimatedDepositDays() : 1);
+                    vo.setOverdue(true);
+                    vo.setOverdueDays(Math.max(overDays, 1));
+                    vo.setOverdueFee(actualFee - payAmount);
+                }
+                return vo;
+            }
+
+            // 鏅�氬氨鍦板瘎瀛�
             overdueDays = calcLocalOverdueDays(now, order.getExpectedTakeTime());
             overdueFee = (long) overdueDays * dailyBaseFee;
 
@@ -3543,6 +4388,16 @@
         return Math.max(days, 1);
     }
 
+    private boolean isSameDay(Date d1, Date d2) {
+        if (d1 == null || d2 == null) return false;
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(d1);
+        Calendar c2 = Calendar.getInstance();
+        c2.setTime(d2);
+        return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)
+                && c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR);
+    }
+
     /**
      * 灏卞湴瀵勫瓨閫炬湡澶╂暟璁$畻
      * 杩囦簡棰勮鍙栦欢鏃ユ湡鐨勬鏃ワ紙鍙瘮杈冨勾鏈堟棩锛夊悗寮�濮嬭閫炬湡澶╂暟
@@ -3614,7 +4469,7 @@
         QueryWrapper<Orders> wrapper = new QueryWrapper<>();
         wrapper.eq("MEMBER_ID", memberId)
                 .in("STATUS", 0, 1, 2, 3, 4, 5)
-                .orderByDesc("CREATE_TIME")
+                .orderByAsc("CREATE_TIME")
                 .last("LIMIT 1");
         Orders order = ordersMapper.selectOne(wrapper);
         if (order == null) {
@@ -3827,7 +4682,6 @@
                             "time", String.valueOf(noGrabMinutes));
                 }
                 // 鏍囪宸查�氱煡 + 璁板綍閫氱煡鏃堕棿
-                order.setPlatformSmsNotified(Constants.ONE);
                 order.setPlatformSmsNotifiedTime(now);
                 order.setUpdateTime(now);
                 ordersMapper.updateById(order);
@@ -3881,6 +4735,7 @@
 
                 // 鏇存柊璁㈠崟鐘舵�佷负宸插畬鎴�
                 order.setStatus(Constants.OrderStatus.finished.getStatus());
+                order.setInvoiceStatus(Constants.ONE);
                 order.setFinishTime(now);
                 order.setUpdateTime(now);
                 ordersMapper.updateById(order);
@@ -3940,37 +4795,37 @@
         if (StringUtils.isBlank(phone)) {
             return;
         }
+        if (!smsNotify.isEnabled()) {
+            return;
+        }
         String content = smsNotify.format(paramPairs);
         try {
             JSONObject templateParam = new JSONObject();
             for (int i = 0; i < paramPairs.length - 1; i += 2) {
                 templateParam.put(paramPairs[i], paramPairs[i + 1]);
             }
-            boolean result = AliSmsService.sendSms(phone, smsNotify.getTemplateCode(),
+            String error = AliSmsService.sendSms(phone, smsNotify.getTemplateCode(),
                     templateParam.toJSONString());
-            if (result) {
-                log.info("鐭俊鍙戦�佹垚鍔�: phone={}, template={}", phone, smsNotify.name());
-            } else {
-                log.warn("鐭俊鍙戦�佸け璐�: phone={}, template={}", phone, smsNotify.name());
-            }
-            // 瀛樺偍鐭俊璁板綍
             Smsrecord record = new Smsrecord();
             record.setPhone(phone);
             record.setContent(content);
-            record.setType(Constants.ONE); // 1=璁㈠崟閫氱煡
-            record.setStatus(result ? Constants.ONE : Constants.ZERO); // 1=宸插彂閫�, 0=鍙戦�佸け璐�
+            record.setType(Constants.ONE);
+            record.setStatus(error == null ? Constants.ONE : Constants.ZERO);
+            if (error != null) {
+                record.setRemark(error);
+            }
             record.setCreateTime(new Date());
             record.setDeleted(Constants.ZERO);
             smsrecordMapper.insert(record);
         } catch (Exception e) {
             log.error("鐭俊鍙戦�佸紓甯�: phone={}, template={}, error={}", phone, smsNotify.name(), e.getMessage());
-            // 寮傚父涔熻褰�
             try {
                 Smsrecord record = new Smsrecord();
                 record.setPhone(phone);
                 record.setContent(content);
                 record.setType(Constants.ONE);
-                record.setStatus(Constants.ZERO); // 鍙戦�佸け璐�
+                record.setStatus(Constants.ZERO);
+                record.setRemark(e.getMessage());
                 record.setCreateTime(new Date());
                 record.setDeleted(Constants.ZERO);
                 smsrecordMapper.insert(record);
@@ -3978,4 +4833,470 @@
         }
     }
 
+    @Override
+    public void printOrderLabel(Integer orderId, Integer shopId) {
+        Orders orders = ordersMapper.selectById(orderId);
+        if (orders == null) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "璁㈠崟涓嶅瓨鍦�");
+        }
+        if (!Constants.equalsInteger(orders.getDepositShopId(), shopId)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠闂ㄥ簵涓嶆槸璇ヨ鍗曠殑瀛樹欢闂ㄥ簵");
+        }
+        if (orders.getStatus() < 1 || orders.getStatus() > 7) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽鎵撳嵃");
+        }
+        ShopInfo shop = shopInfoMapper.selectById(shopId);
+        if (shop == null) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "瀛樹欢闂ㄥ簵涓嶅瓨鍦�");
+        }
+        if (StringUtils.isBlank(shop.getPrinterSn())) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀛樹欢闂ㄥ簵鏈粦瀹氭墦鍗版満");
+        }
+        List<OrdersDetail> detailList = ordersDetailMapper.selectList(
+                new QueryWrapper<OrdersDetail>().lambda().eq(OrdersDetail::getOrderId, orderId));
+        // 鎷兼帴瀹㈡埛淇℃伅
+        String userInfo = "";
+        if (StringUtils.isNotBlank(orders.getTakeUser())) {
+            String phone = orders.getTakePhone();
+            userInfo = orders.getTakeUser();
+            if (StringUtils.isNotBlank(phone) && phone.length() >= 4) {
+                userInfo += "锛�" + phone.substring(phone.length() - 4) + "锛�";
+            }
+        }
+
+        //搴忓彿锛氬晢閾篒D-鏃ユ湡-鑷闀垮簭鍙凤紙濡� 32-06-001锛�
+        String dateStr = new SimpleDateFormat("dd").format(orders.getPayTime() != null ? orders.getPayTime() : new Date());
+        String autoNumStr = String.format("%03d", orders.getAutoNum() != null ? orders.getAutoNum() : 0);
+        String sort = shopId + "-" + dateStr + "-" + autoNumStr;
+//        String content = printService.getPrintContent(shop.getName(), detailList, userInfo, orders.getCode(), orders.getRemark(),
+        String content = printService.getPrintContent(shop.getName(), detailList, userInfo, orders.getCode(), sort,
+                orders.getTakeLocationRemark(),
+                orders.getPayTime() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm").format(orders.getPayTime()) : "",
+                orders.getExpectedTakeTime() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm").format(orders.getExpectedTakeTime()) : "");
+        if (StringUtils.isBlank(content)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鎵撳嵃鍐呭涓虹┖");
+        }
+        PrintRequest request = new PrintRequest();
+        xyyConfig.createRequestHeader(request);
+        request.setSn(shop.getPrinterSn());
+        request.setContent(content);
+        request.setCopies(1);
+        request.setVoice(2);
+        request.setMode(0);
+        com.doumee.config.xyy.vo.ObjectRestResponse<String> resp = printService.printLabel(request);
+        if (resp.getCode() != 0) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鎵撳嵃澶辫触锛�" + resp.getMsg());
+        }
+        log.info("璁㈠崟鏍囩鎵撳嵃鎴愬姛: orderId={}, orderIndex={}", orderId, resp.getData());
+    }
+
+    /**
+     * 寮傚湴璁㈠崟瀵勫瓨鎴愬姛鍚庢帹閫侀�氱煡缁欏徃鏈�
+     * 1銆佹湭鍔犳�ワ細鎺ㄩ�佸悓鍩庝笖闂ㄥ簵閰嶉�佽寖鍥村唴鎺ュ崟涓殑鍙告満
+     * 2銆佸姞鎬ワ細鎺ㄩ�佸悓鍩庢墍鏈夋帴鍗曚腑鐨勫徃鏈�
+     * 鍩庡競鍖归厤锛氬徃鏈篈REA_ID鍏宠仈areas琛紝閫愮骇parent_id鎵惧埌鍩庡競绾э紝涓庤鍗昪ityId鍖归厤
+     */
+    private void pushDriverNewOrder(Orders order) {
+        ShopInfo shop = shopInfoMapper.selectById(order.getDepositShopId());
+        if (shop == null || shop.getLongitude() == null || shop.getLatitude() == null) {
+            return;
+        }
+        String orderCityId = order.getCityId();
+        if (StringUtils.isBlank(orderCityId)) {
+            return;
+        }
+        String distSql = "(ST_Distance_Sphere(POINT(t.LONGITUDE, t.LATITUDE), POINT(" + shop.getLongitude() + ", " + shop.getLatitude() + ")) / 1000)";
+        // MPJ鍏宠仈鏌ヨ锛氬徃鏈� 鈫� areas(鍖哄幙) 鈫� areas_city(鍩庡競)锛屽尮閰嶈鍗昪ityId
+        MPJLambdaWrapper<DriverInfo> wrapper = new MPJLambdaWrapper<>();
+        wrapper.selectAll(DriverInfo.class)
+                .leftJoin(Areas.class,Areas::getId,DriverInfo::getAreaId)
+                .eq(DriverInfo::getAcceptingStatus, Constants.ONE)
+                .eq(DriverInfo::getStatus, Constants.ZERO)
+                .eq(DriverInfo::getDeleted, Constants.ZERO)
+                .eq(DriverInfo::getAuditStatus, Constants.THREE)
+                .eq(Areas::getParentId, orderCityId);
+        if (!Constants.equalsInteger(order.getIsUrgent(), Constants.ONE)) {
+            // 鏈姞鎬ワ細闂ㄥ簵閰嶉�佽寖鍥村唴
+            double rangeKm = shop.getDeliveryArea() != null ? shop.getDeliveryArea().doubleValue() : 5.0;
+            wrapper.apply(distSql + " <= {0}", rangeKm);
+        }
+        List<DriverInfo> drivers = driverInfoMapper.selectJoinList(DriverInfo.class, wrapper);
+        if (drivers.isEmpty()) {
+            return;
+        }
+        List<String> aliases = new ArrayList<>();
+        for (DriverInfo d : drivers) {
+            aliases.add(org.springframework.util.DigestUtils.md5DigestAsHex(d.getTelephone().getBytes()));
+        }
+        String title = Constants.equalsInteger(order.getIsUrgent(), Constants.ONE) ? "鏂板姞鎬ヨ鍗�" : "鏂拌鍗�";
+        String content = "璁㈠崟鍙凤細" + order.getCode();
+        java.util.Map<String, String> extras = new java.util.HashMap<>();
+        extras.put("orderId", String.valueOf(order.getId()));
+        extras.put("orderCode", order.getCode());
+        extras.put("type", "new_order");
+        JPushUtil.sendByAliases(aliases, title, content, extras);
+    }
+
+    @Override
+    public int notifyArrivalPickUp() {
+        String timeStr = operationConfigBiz.getConfig().getArrivalPickUpTime();
+        if (StringUtils.isBlank(timeStr)) {
+            return 0;
+        }
+        int minutes;
+        try {
+            minutes = Integer.parseInt(timeStr);
+        } catch (NumberFormatException e) {
+            log.warn("鍗冲皢鍒拌揪鍙栦欢鏃堕棿閰嶇疆寮傚父: {}", timeStr);
+            return 0;
+        }
+        if (minutes <= 0) {
+            return 0;
+        }
+        // 璁$畻鏃堕棿绐楀彛锛氬綋鍓嶆椂闂� + minutes 灏辨槸"鍗冲皢鍒拌揪"鐨勪复鐣岀偣
+        Date now = new Date();
+        Date threshold = new Date(now.getTime() + (long) minutes * 60 * 1000);
+        // 鏌ヨ锛歴tatus=5銆佹湭閫氱煡銆佸氨鍦板瘎瀛� or 寮傚湴(鏈夊彇浠堕棬搴�)銆侀璁″彇浠舵椂闂村湪 now~threshold 涔嬮棿
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String nowStr = sdf.format(now);
+        String thresholdStr = sdf.format(threshold);
+        List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getStatus, Constants.OrderStatus.arrived.getStatus())
+                .eq(Orders::getPayStatus, Constants.ONE)
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .and(w -> w
+                        .eq(Orders::getType, Constants.ZERO)
+                        .or(w2 -> w2.eq(Orders::getType, Constants.ONE).isNotNull(Orders::getTakeShopId))
+                )
+                .ne(Orders::getPickUpNotifyStatus, Constants.ONE)
+                .isNotNull(Orders::getExpectedTakeTime)
+                .apply("DATE_FORMAT(EXPECTED_TAKE_TIME, '%Y-%m-%d %H:%i:%s') >= {0}", nowStr)
+                .apply("DATE_FORMAT(EXPECTED_TAKE_TIME, '%Y-%m-%d %H:%i:%s') <= {0}", thresholdStr));
+        if (orders == null || orders.isEmpty()) {
+            return 0;
+        }
+        int count = 0;
+        for (Orders order : orders) {
+            Member member = memberMapper.selectById(order.getMemberId());
+            if (member != null && StringUtils.isNotBlank(member.getTelephone())) {
+                sendSmsNotify(member.getTelephone(), Constants.SmsNotify.MEMBER_TIME_OUT,
+                        "orderNo", order.getCode());
+            }
+            order.setPickUpNotifyStatus(Constants.ONE);
+            ordersMapper.updateById(order);
+            count++;
+        }
+        return count;
+    }
+
+    @Override
+    public Boolean checkOperationRadius(Integer orderId, Integer userId, Integer userType, Double lng, Double lat) {
+        String radiusStr = operationConfigBiz.getConfig().getOperationRadius();
+        if (StringUtils.isBlank(radiusStr)) {
+            return true;
+        }
+        double radiusM;
+        try {
+            radiusM = Double.parseDouble(radiusStr);
+        } catch (NumberFormatException e) {
+            return true;
+        }
+        if (radiusM <= 0) {
+            return true;
+        }
+        Orders order = ordersMapper.selectById(orderId);
+        if (order == null) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璁㈠崟涓嶅瓨鍦�");
+        }
+        BigDecimal targetLat;
+        BigDecimal targetLgt;
+        if (Constants.equalsInteger(userType, Constants.ZERO)) {
+            // 闂ㄥ簵鎿嶄綔
+            if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.waitDeposit.getStatus())) {
+                // status=1 闂ㄥ簵瀵勫瓨鏍搁獙
+                if (!Constants.equalsInteger(order.getDepositShopId(), userId)) {
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+                }
+                targetLat = order.getDepositLat();
+                targetLgt = order.getDepositLgt();
+            } else if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.arrived.getStatus())) {
+                // status=5 闂ㄥ簵瀹屾垚鏍搁攢
+                if (Constants.equalsInteger(order.getType(), Constants.ZERO)) {
+                    // 灏卞湴瀛樺彇 鈫� 瀵规瘮瀛樹欢闂ㄥ簵
+                    if (!Constants.equalsInteger(order.getDepositShopId(), userId)) {
+                        throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+                    }
+                    targetLat = order.getDepositLat();
+                    targetLgt = order.getDepositLgt();
+                } else {
+                    // 寮傚湴瀛樺彇 鈫� 瀵规瘮鍙栦欢闂ㄥ簵
+                    if (!Constants.equalsInteger(order.getTakeShopId(), userId)) {
+                        throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+                    }
+                    targetLat = order.getTakeLat();
+                    targetLgt = order.getTakeLgt();
+                }
+            } else {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璁㈠崟鐘舵�佷笉鍏佽姝ゆ搷浣�");
+            }
+        } else if (Constants.equalsInteger(userType, Constants.ONE)) {
+            // 鍙告満鎿嶄綔
+            if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.deposited.getStatus())) {
+                // status=2 鍙告満鍙栦欢
+                if (!Constants.equalsInteger(order.getAcceptDriver(), userId)) {
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+                }
+                targetLat = order.getDepositLat();
+                targetLgt = order.getDepositLgt();
+            } else if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getStatus())) {
+                // status=4 鍙告満閫佽揪
+                if (!Constants.equalsInteger(order.getAcceptDriver(), userId)) {
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+                }
+                targetLat = order.getTakeLat();
+                targetLgt = order.getTakeLgt();
+            } else {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璁㈠崟鐘舵�佷笉鍏佽姝ゆ搷浣�");
+            }
+        } else {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鐢ㄦ埛绫诲瀷涓嶅悎娉�");
+        }
+        if (targetLat == null || targetLgt == null) {
+            return true;
+        }
+        double distanceKm = GeoUtils.haversineDistance(lat, lng, targetLat.doubleValue(), targetLgt.doubleValue());
+        return distanceKm * 1000 <= radiusM;
+    }
+
+    @Override
+    @Transactional(rollbackFor = {Exception.class, BusinessException.class})
+    public void handleOrderException(HandleOrderExceptionDTO dto) {
+        // ========== A. 鏍¢獙 ==========
+        Orders original = ordersMapper.selectById(dto.getOrderId());
+        if (original == null || Constants.equalsInteger(original.getDeleted(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "璁㈠崟涓嶅瓨鍦�");
+        }
+        if (!Constants.equalsInteger(original.getType(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呮敮鎸佸紓鍦拌鍗曞紓甯稿鐞�");
+        }
+        if (original.getTakeShopId() != null) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曞凡鍏宠仈鍙栦欢闂ㄥ簵锛屼笉鏀寔寮傚父澶勭悊");
+        }
+        if (!Constants.equalsInteger(original.getStatus(), Constants.FIVE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呮敮鎸佸凡閫佽揪鐘舵�佺殑璁㈠崟");
+        }
+        if (Constants.equalsInteger(original.getExceptionStatus(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曞凡澶勭悊杩囧紓甯革紝璇峰嬁閲嶅鎿嶄綔");
+        }
+
+        ShopInfo newShop = shopInfoMapper.selectById(dto.getDepositShopId());
+        if (newShop == null || Constants.equalsInteger(newShop.getStatus(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀛樻斁闂ㄥ簵涓嶅瓨鍦ㄦ垨宸茬鐢�");
+        }
+
+        Date now = new Date();
+
+        // ========== B. 鍒涘缓鏂拌鍗曪紙灏卞湴瀛樺彇锛� ==========
+        String orderCode = "JC" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(now)
+                + String.format("%04d", new java.util.Random().nextInt(10000));
+        String orderTradeNo = generateOrderTradeNo();
+
+        // 褰撳ぉ23:30
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, 23);
+        cal.set(Calendar.MINUTE, 30);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        Date expectedTakeTime = cal.getTime();
+
+        // 璁$畻鍩虹鍗曚环
+        Long price = 0L;
+        Long basicAmount = 0L;
+        // 鏌ヨ鍘熻鍗曟槑缁嗚幏鍙栫墿鍝佸垪琛�
+        List<OrdersDetail> originalDetails = ordersDetailMapper.selectList(
+                new QueryWrapper<OrdersDetail>().lambda()
+                        .eq(OrdersDetail::getOrderId, original.getId())
+                        .eq(OrdersDetail::getDeleted, Constants.ZERO));
+        if (!CollectionUtils.isEmpty(originalDetails)) {
+            CalculateLocalPriceDTO priceDTO = new CalculateLocalPriceDTO();
+            priceDTO.setCityId(Integer.valueOf(original.getCityId()));
+            priceDTO.setDepositStartTime(now);
+            priceDTO.setDepositEndTime(expectedTakeTime);
+            List<OrderItemDTO> items = new ArrayList<>();
+            for (OrdersDetail d : originalDetails) {
+                OrderItemDTO item = new OrderItemDTO();
+                item.setCategoryId(d.getLuggageId());
+                item.setQuantity(d.getNum());
+                items.add(item);
+            }
+            priceDTO.setItems(items);
+            PriceCalculateVO priceResult = calculateLocalPrice(priceDTO);
+            if (priceResult != null) {
+                price = priceResult.getItemPrice();
+                basicAmount = priceResult.getItemPrice();
+            }
+        }
+
+        // 瀛樹欢闂ㄥ簵鍒嗘垚鍗犳瘮锛堝氨鍦板瓨鍙栵級
+        Integer cityId = Integer.valueOf(original.getCityId());
+        boolean isCompany = Constants.equalsInteger(newShop.getCompanyType(), Constants.ONE);
+        int fallbackFieldA = isCompany ? Constants.FIVE : Constants.SIX;
+        BigDecimal depositShopFeeRate = getShopRevenueShare(newShop, "localDeposit", cityId, fallbackFieldA);
+
+        Orders newOrder = new Orders();
+        newOrder.setCode(orderCode);
+        newOrder.setOutTradeNo(orderTradeNo);
+        newOrder.setMemberId(original.getMemberId());
+        newOrder.setType(Constants.ZERO); // 灏卞湴瀛樺彇
+        newOrder.setCityId(original.getCityId());
+        newOrder.setStatus(Constants.ONE); // 寰呭瘎瀛�
+        newOrder.setPayStatus(Constants.ONE); // 宸叉敮浠�
+        newOrder.setPayTime(now);
+        newOrder.setCommentStatus(Constants.ZERO);
+        newOrder.setSettlementStatus(Constants.ZERO);
+        newOrder.setDeleted(Constants.ZERO);
+        newOrder.setCreateTime(now);
+        newOrder.setUpdateTime(now);
+        newOrder.setIsConverted(Constants.ZERO);
+
+        // 瀛樹欢淇℃伅锛堝叆鍙傞棬搴楋級
+        newOrder.setDepositShopId(dto.getDepositShopId());
+        newOrder.setDepositLocation(newShop.getAddress());
+        newOrder.setDepositLocationRemark(newShop.getAddress());
+        newOrder.setDepositLat(BigDecimal.valueOf(newShop.getLatitude()));
+        newOrder.setDepositLgt(BigDecimal.valueOf(newShop.getLongitude()));
+        // 鍙栦欢淇℃伅锛堝氨鍦�=瀛樹欢闂ㄥ簵锛�
+        newOrder.setTakeShopId(dto.getDepositShopId());
+        newOrder.setTakeLocation(newShop.getAddress());
+        newOrder.setTakeLocationRemark(newShop.getAddress());
+        newOrder.setTakeLat(BigDecimal.valueOf(newShop.getLatitude()));
+        newOrder.setTakeLgt(BigDecimal.valueOf(newShop.getLongitude()));
+
+        // 鏃堕棿
+        newOrder.setExpectedDepositTime(now);
+        newOrder.setExpectedTakeTime(expectedTakeTime);
+        newOrder.setEstimatedDepositDays(1);
+
+        // 鐗╁搧淇℃伅
+        newOrder.setGoodType(original.getGoodType());
+        newOrder.setGoodLevel(original.getGoodLevel());
+        newOrder.setGoodsInfo(original.getGoodsInfo());
+        newOrder.setSupplement(original.getSupplement());
+        newOrder.setSelfTake(original.getSelfTake());
+        newOrder.setTakeUser(original.getTakeUser());
+        newOrder.setTakePhone(original.getTakePhone());
+
+        // 寮傚父鏍囪
+        newOrder.setExceptionStatus(Constants.ONE);
+        newOrder.setRelationOrderId(original.getId());
+        newOrder.setExceptionInfo(dto.getRemark());
+
+        // 璐圭敤
+        newOrder.setIsUrgent(Constants.ZERO);
+        newOrder.setUrgentRata(BigDecimal.ONE);
+        newOrder.setUrgentAmount(0L);
+        newOrder.setDeclaredAmount(0L);
+        newOrder.setDeclaredFee(0L);
+        newOrder.setPrice(price);
+        newOrder.setBasicAmount(basicAmount);
+        newOrder.setEstimatedAmount(basicAmount);
+        newOrder.setTotalAmount(0L);
+        newOrder.setPayAmount(0L);
+        newOrder.setManualRefund(Constants.ZERO);
+
+        // 璐圭敤鍒嗛厤
+        newOrder.setDriverFee(0L);
+        newOrder.setDriverFeeRata(BigDecimal.ZERO);
+        newOrder.setDepositShopFee(0L);
+        newOrder.setDepositShopFeeRata(depositShopFeeRate);
+        newOrder.setTakeShopFee(0L);
+        newOrder.setTakeShopFeeRata(BigDecimal.ZERO);
+
+        // 闂ㄥ簵琛ュ伩閲戦
+        newOrder.setShopCompensationAmount(dto.getShopCompensation());
+
+        newOrder.setRemark(dto.getRemark());
+        newOrder.setPlatformSmsNotified(Constants.ZERO);
+        newOrder.setMemberVerifyCode(generateVerifyCode());
+        newOrder.setDriverVerifyCode(generateVerifyCode());
+        // 璁$畻搴楅摵璁㈠崟搴忓彿
+        Date todayStart = DateUtil.getStartOfDay(now);
+        Long currentCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getDepositShopId, dto.getDepositShopId())
+                .eq(Orders::getPayStatus, Constants.ONE)
+                .ge(Orders::getPayTime, todayStart)
+                .eq(Orders::getDeleted, Constants.ZERO));
+        newOrder.setAutoNum(currentCount + 1);
+        ordersMapper.insert(newOrder);
+
+        // ========== C. 鍒涘缓鏂拌鍗曟槑缁� ==========
+        if (!CollectionUtils.isEmpty(originalDetails)) {
+            for (OrdersDetail od : originalDetails) {
+                OrdersDetail detail = new OrdersDetail();
+                detail.setOrderId(newOrder.getId());
+                detail.setLuggageId(od.getLuggageId());
+                detail.setLuggageName(od.getLuggageName());
+                detail.setLuggageDetail(od.getLuggageDetail());
+                detail.setNum(od.getNum());
+                detail.setUnitPrice(od.getLocallyPrice());
+                detail.setLocallyPrice(od.getLocallyPrice());
+                detail.setDeleted(Constants.ZERO);
+                detail.setCreateTime(now);
+                ordersDetailMapper.insert(detail);
+            }
+        }
+
+        // ========== D. 鎷疯礉闄勪欢 ==========
+        List<Multifile> originalFiles = multifileMapper.selectList(
+                new QueryWrapper<Multifile>().lambda()
+                        .eq(Multifile::getObjId, original.getId())
+                        .eq(Multifile::getObjType, Constants.FileType.ORDER_FILE.getKey())
+                        .eq(Multifile::getIsdeleted, Constants.ZERO));
+        if (!CollectionUtils.isEmpty(originalFiles)) {
+            int sortNum = 1;
+            for (Multifile mf : originalFiles) {
+                Multifile newFile = new Multifile();
+                newFile.setObjId(newOrder.getId());
+                newFile.setObjType(Constants.FileType.ORDER_FILE.getKey());
+                newFile.setType(mf.getType());
+                newFile.setFileurl(mf.getFileurl());
+                newFile.setIsdeleted(Constants.ZERO);
+                newFile.setCreateDate(now);
+                newFile.setSortnum(sortNum++);
+                multifileMapper.insert(newFile);
+            }
+        }
+
+        // ========== E. 鏇存柊鍘熻鍗� ==========
+        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
+                .set(Orders::getExceptionStatus, Constants.ONE)
+                .set(Orders::getExceptionFee, dto.getDriverCompensation())
+                .set(Orders::getUpdateTime, now)
+                .eq(Orders::getId, original.getId()));
+
+        // ========== F. 鍙戦�佺煭淇¢�氱煡 ==========
+        // 鍙告満绔�-寮傚父娲惧崟
+        if (original.getAcceptDriver() != null) {
+            DriverInfo driver = driverInfoMapper.selectById(original.getAcceptDriver());
+            if (driver != null && StringUtils.isNotBlank(driver.getTelephone())) {
+                sendSmsNotify(driver.getTelephone(), Constants.SmsNotify.EXCEPTION_DISPATCH,
+                        "orderNo", original.getCode(),
+                        "address", newShop.getAddress(),
+                        "code", newOrder.getMemberVerifyCode());
+            }
+        }
+        // 浼氬憳绔�-寮傚父娲惧崟
+        String memberPhone = StringUtils.isNotBlank(original.getTakePhone()) ? original.getTakePhone() : null;
+        if (memberPhone == null) {
+            Member member = memberMapper.selectById(original.getMemberId());
+            if (member != null) {
+                memberPhone = member.getTelephone();
+            }
+        }
+        if (StringUtils.isNotBlank(memberPhone)) {
+            sendSmsNotify(memberPhone, Constants.SmsNotify.MEMBER_EXCEPTION_DISPATCH,
+                    "address", newShop.getAddress());
+        }
+    }
+
 }

--
Gitblit v1.9.3