From 467fe3b3ec6aa9d449b094bdd9df4611323d88d1 Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期五, 24 四月 2026 21:43:50 +0800
Subject: [PATCH] 代码生成

---
 server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java | 1074 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 961 insertions(+), 113 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 4e9ea0d..888e25a 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
@@ -19,6 +19,7 @@
 import com.doumee.core.utils.DateUtil;
 import com.doumee.core.utils.geocode.MapUtil;
 import com.doumee.core.utils.Utils;
+import com.doumee.core.utils.aliyun.AliSmsService;
 import com.doumee.dao.business.*;
 import com.doumee.dao.business.model.*;
 import com.doumee.dao.system.SystemUserMapper;
@@ -43,6 +44,7 @@
 import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -59,6 +61,7 @@
  * @author rk
  * @date 2026/04/10
  */
+@Slf4j
 @Service
 public class OrdersServiceImpl implements OrdersService {
 
@@ -126,6 +129,9 @@
 
     @Autowired
     private NoticeService noticeService;
+
+    @Autowired
+    private SmsrecordMapper smsrecordMapper;
 
     @Autowired
     private WxPayV3Service wxPayV3Service;
@@ -223,6 +229,7 @@
         queryWrapper.eq(pageWrap.getModel().getTakeShopId() != null, Orders::getTakeShopId, pageWrap.getModel().getTakeShopId());
         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());
@@ -256,6 +263,7 @@
         queryWrapper.eq(pageWrap.getModel().getTakeShopId() != null, Orders::getTakeShopId, pageWrap.getModel().getTakeShopId());
         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.select(
                 "IFNULL(SUM(t.total_amount), 0) as total_amount_sum",
@@ -294,7 +302,7 @@
             return BigDecimal.ZERO;
         }
         String rateStr = systemDictDataBiz.queryByCode(Constants.OPERATION_CONFIG, Constants.OP_INSURANCE_RATE).getCode();
-        BigDecimal rate = new BigDecimal(rateStr);
+        BigDecimal rate = new BigDecimal(rateStr).divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP);
         return declaredValue.multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP);
     }
 
@@ -342,9 +350,11 @@
         List<Category> categories = categoryMapper.selectBatchIds(categoryIds);
         Map<Integer, String> categoryNameMap = new HashMap<>();
         Map<Integer, String> categoryDetailMap = new HashMap<>();
+        Map<Integer, String> categoryOtherFieldMap = new HashMap<>();
         for (Category c : categories) {
             categoryNameMap.put(c.getId(), c.getName());
             categoryDetailMap.put(c.getId(), c.getDetail());
+            categoryOtherFieldMap.put(c.getId(),c.getOtherField());
         }
 
         // 璁$畻姣忛」鐗╁搧璐圭敤锛氬皬璁� = 鍗曚环 脳 鏁伴噺 脳 澶╂暟
@@ -364,7 +374,7 @@
             ItemPriceVO vo = new ItemPriceVO();
             vo.setCategoryId(item.getCategoryId());
             vo.setCategoryName(categoryNameMap.getOrDefault(item.getCategoryId(), ""));
-            vo.setDetail(categoryDetailMap.get(item.getCategoryId()));
+            vo.setDetail(categoryOtherFieldMap.get(item.getCategoryId()));
             vo.setQuantity(item.getQuantity());
             vo.setUnitPrice(unitPrice);
             vo.setLocallyPrice(unitPrice);
@@ -420,8 +430,11 @@
         String to = dto.getToLat() + "," + dto.getToLgt();
         JSONObject distanceResult = MapUtil.direction("driving", from, to);
         BigDecimal distance = distanceResult.getBigDecimal("distance");
-        // distance 鍗曚綅涓虹背锛岃浆涓哄叕閲�
+        // distance 鍗曚綅涓虹背锛岃浆涓哄叕閲岋紙涓嶈冻1鍏噷鎸�1鍏噷璁$畻锛�
         BigDecimal distanceKm = distance.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
+        if (distanceKm.compareTo(BigDecimal.ONE) < 0) {
+            distanceKm = BigDecimal.ONE;
+        }
 
         // 鏀堕泦鎵�鏈夌墿鍝佺被鍨婭D
         List<Integer> categoryIds = new ArrayList<>();
@@ -459,9 +472,11 @@
         List<Category> categories = categoryMapper.selectBatchIds(categoryIds);
         Map<Integer, String> categoryNameMap = new HashMap<>();
         Map<Integer, String> categoryDetailMap = new HashMap<>();
+        Map<Integer, String> categoryOtherFieldMap = new HashMap<>();
         for (Category c : categories) {
             categoryNameMap.put(c.getId(), c.getName());
             categoryDetailMap.put(c.getId(), c.getDetail());
+            categoryOtherFieldMap.put(c.getId(),c.getOtherField());
         }
 
         // 3. 閫愰」璁$畻杩愯垂锛氳捣姝ヤ环 + 瓒呭嚭閮ㄥ垎闃舵浠�
@@ -500,7 +515,7 @@
             ItemPriceVO vo = new ItemPriceVO();
             vo.setCategoryId(item.getCategoryId());
             vo.setCategoryName(categoryNameMap.getOrDefault(item.getCategoryId(), ""));
-            vo.setDetail(categoryDetailMap.get(item.getCategoryId()));
+            vo.setDetail(categoryOtherFieldMap.get(item.getCategoryId()));
             vo.setQuantity(item.getQuantity());
             vo.setUnitPrice(unitPrice);
             vo.setLocallyPrice(locallyPrice);
@@ -645,8 +660,11 @@
 
         // ========== 3. 鏌ヨ瀵勪欢搴楅摵淇℃伅 ==========
         ShopInfo depositShop = shopInfoMapper.selectById(dto.getDepositShopId());
-        if (depositShop == null) {
+        if (depositShop == null || Constants.equalsInteger(depositShop.getDeleted(), Constants.ONE)) {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀵勪欢搴楅摵涓嶅瓨鍦�");
+        }
+        if (depositShop.getStatus() == null || !Constants.equalsInteger(depositShop.getStatus(), Constants.ZERO)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀵勪欢搴楅摵宸插仠涓氾紝璇烽�夋嫨鍏朵粬闂ㄥ簵");
         }
 
         // ========== 4. 璁$畻璐圭敤 ==========
@@ -663,9 +681,15 @@
             }
             // 鍙栦欢鐐癸細搴楅摵 or 鑷�夌偣锛岃嚦灏戞彁渚涗竴缁�
             if (dto.getTakeShopId() != null) {
+                if (dto.getTakeShopId().equals(dto.getDepositShopId())) {
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "寮傚湴瀵勫瓨璁㈠崟瀛樹欢闂ㄥ簵鍜屽彇浠堕棬搴椾笉鑳界浉鍚�");
+                }
                 takeShop = shopInfoMapper.selectById(dto.getTakeShopId());
-                if (takeShop == null) {
+                if (takeShop == null || Constants.equalsInteger(takeShop.getDeleted(), Constants.ONE)) {
                     throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鍙栦欢搴楅摵涓嶅瓨鍦�");
+                }
+                if (takeShop.getStatus() == null || Constants.equalsInteger(takeShop.getStatus(), Constants.ONE)) {
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鍙栦欢搴楅摵宸插仠涓氾紝璇烽�夋嫨鍏朵粬闂ㄥ簵");
                 }
                 takeLat = BigDecimal.valueOf(takeShop.getLatitude());
                 takeLgt = BigDecimal.valueOf(takeShop.getLongitude());
@@ -764,6 +788,7 @@
             orders.setTakeLat(takeLat);
             orders.setTakeLgt(takeLgt);
             orders.setIsUrgent(dto.getIsUrgent());
+            orders.setDistance(priceResult.getDistance());
         } else {
             // 灏卞湴锛氬彇浠剁偣鍚屽瘎浠跺簵閾�
             orders.setTakeShopId(dto.getDepositShopId());
@@ -775,7 +800,12 @@
 
         // 鐗╁搧淇℃伅
         orders.setGoodType(dto.getGoodType());
-        orders.setGoodLevel(goodTypeCategory.getRelationId());
+        // 鏌ヨ鐗╁搧绾у埆 type = 3
+        Category levelCategory = categoryMapper.selectById(goodTypeCategory.getRelationId());
+        if(Objects.isNull(levelCategory)){
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"鏈煡璇㈠埌鐗╁搧绛夌骇淇℃伅锛歿}"+goodTypeCategory.getName());
+        }
+        orders.setGoodLevel(Integer.valueOf(levelCategory.getDetail()));
         // 鎷兼帴鐗╁搧淇℃伅锛氱墿鍝佺被鍨嬪悕绉般�佸昂瀵稿悕绉�*鏁伴噺锛堟暟缁勫瓧绗︿覆锛�
         List<String> goodsParts = new ArrayList<>();
         for (ItemPriceVO itemVO : priceResult.getItemList()) {
@@ -797,9 +827,12 @@
         }
         orders.setDeclaredFee(priceResult.getInsuranceFee());
         orders.setPrice(priceResult.getItemPrice());
-
         // 钖叕璁$畻涓庡崰姣斿瓨鍌�
         calculateAndSetFeeAllocation(orders, depositShop, takeShop);
+
+        // 鏃犱汉鎺ュ崟閫氱煡鐩稿叧鍒濆鍖�
+        orders.setPlatformSmsNotified(Constants.ZERO);
+        orders.setPlatformSmsNotifiedTime(now);
 
         ordersMapper.insert(orders);
         Integer orderId = orders.getId();
@@ -871,6 +904,7 @@
         // 5. 閲嶆柊鐢熸垚绗笁鏂硅鍗曠紪鍙凤紙閬垮厤閲嶅锛�
         String orderTradeNo = generateOrderTradeNo();
         orders.setOutTradeNo(orderTradeNo);
+        orders.setPlatformSmsNotifiedTime(new Date());
         orders.setUpdateTime(new Date());
         ordersMapper.updateById(orders);
         // 6. 鍞よ捣寰俊鏀粯
@@ -1013,9 +1047,6 @@
         // 鍙栨秷/閫�娆剧姸鎬佹椂鏌ヨ閫�娆捐褰�
         Integer status = order.getStatus();
         if (status != null && (status == Constants.OrderStatus.overdue.getStatus()
-                || status == Constants.OrderStatus.closed.getStatus()
-                || status == Constants.OrderStatus.cancelOverdue.getStatus()
-                || status == Constants.OrderStatus.cancelling.getStatus()
                 || status == Constants.OrderStatus.cancelled.getStatus())) {
             OrdersRefund ordersRefund = ordersRefundMapper.selectOne(
                     new QueryWrapper<OrdersRefund>().lambda()
@@ -1080,13 +1111,12 @@
 
         String optUserName = getCurrentUserName();
 
-        // 鍔犳�ヨ垂鏃ュ織锛堟瘡娆″崟鐙褰曟湰娆″姞鎬ヨ垂锛�
-        Constants.OrderLogType urgentLogType = Constants.OrderLogType.urgent;
+        // 鍔犳�ヨ垂鏃ュ織
         OrderLog feeLog = new OrderLog();
         feeLog.setOrderId(order.getId());
-        feeLog.setTitle(urgentLogType.getTitle());
-        feeLog.setLogInfo(urgentLogType.getStatusInfo().replace("{param}", dto.getUrgentFee().toPlainString()));
-        feeLog.setObjType(urgentLogType.getStatus());
+        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);
@@ -1103,6 +1133,8 @@
                 .eq(Orders::getId, order.getId())
                 .set(Orders::getIsUrgent, Constants.ONE)
                 .set(Orders::getPlatformRewardAmount, urgentFeeFen)
+                .set(Orders::getPlatformSmsNotified, Constants.ZERO) // 閲嶇疆閫氱煡鐘舵�佷负鏈�氱煡
+                .set(Orders::getPlatformSmsNotifiedTime, new Date()) // 閲嶇疆閫氱煡鍩哄噯鏃堕棿涓哄綋鍓�
                 .set(Orders::getUpdateTime, new Date());
 
         // 寮傚湴瀵勫瓨涓旀湁鍙栦欢闂ㄥ簵鏃讹紝鐢熸垚鍙告満鏍搁攢鐮�
@@ -1123,18 +1155,37 @@
             Member driver = memberMapper.selectById(dto.getDriverId());
             String driverName = driver != null ? driver.getName() : String.valueOf(dto.getDriverId());
 
-            Constants.OrderLogType dispatchLogType = Constants.OrderLogType.dispatch;
             OrderLog driverLog = new OrderLog();
             driverLog.setOrderId(order.getId());
-            driverLog.setTitle(dispatchLogType.getTitle());
-            driverLog.setLogInfo(dispatchLogType.getStatusInfo().replace("{param}", driverName));
-            driverLog.setObjType(dispatchLogType.getStatus());
+            driverLog.setTitle(Constants.OrderLogType.assignDriver.getTitle());
+            driverLog.setLogInfo(Constants.OrderLogType.assignDriver.format(driverName, dto.getUrgentFee().toPlainString()));
+            driverLog.setObjType(Constants.OrderLogType.assignDriver.getStatus());
             driverLog.setOrderStatus(order.getStatus());
             driverLog.setOptUserType(3);
             driverLog.setOptUserName(optUserName);
             driverLog.setCreateTime(new Date());
             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));
+            }
         }
 
         ordersMapper.update(updateWrapper);
@@ -1172,9 +1223,9 @@
                 item.setLuggageName(d.getLuggageName());
                 item.setLuggageDetail(d.getLuggageDetail());
                 item.setNum(d.getNum());
-                double unitPriceYuan = d.getUnitPrice() != null ? Constants.getFormatMoney(d.getUnitPrice()) : 0;
-                item.setUnitPriceYuan(unitPriceYuan);
-                item.setSubtotal(unitPriceYuan * (d.getNum() != null ? d.getNum() : 0));
+                long unitPriceFen = d.getUnitPrice() != null ? d.getUnitPrice() : 0L;
+                item.setUnitPrice(unitPriceFen);
+                item.setSubtotal(unitPriceFen * (d.getNum() != null ? d.getNum() : 0));
                 items.add(item);
             }
         }
@@ -1307,8 +1358,9 @@
                 .eq(PricingRule::getCityId, cityId)
                 .eq(PricingRule::getFieldA, String.valueOf(fieldA))
                 .last("limit 1"));
-        if (rule != null && StringUtils.isNotBlank(rule.getFieldC())) {
-            return new BigDecimal(rule.getFieldC());
+        if (rule != null && StringUtils.isNotBlank(rule.getFieldB())) {
+            // fieldB 瀛樺偍鐨勬槸鐧惧垎姣旀暣鏁帮紙濡�15琛ㄧず15%锛夛紝杞崲涓哄皬鏁版瘮渚嬶紙0.15锛�
+            return new BigDecimal(rule.getFieldB()).divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP);
         }
         return BigDecimal.ZERO;
     }
@@ -1339,8 +1391,12 @@
                 .select("s1.link_phone", Orders::getDepositShopLinkPhone)
                 .select("s2.name", Orders::getTakeShopName)
                 .select("s2.address", Orders::getTakeShopAddress)
+                .select("s2.link_phone", Orders::getTakeShopLinkPhone)
+                .select("d.name", Orders::getDriverName)
+                .select("d.telephone", Orders::getDriverPhone)
                 .leftJoin("shop_info s1 on s1.id = t.DEPOSIT_SHOP_ID")
                 .leftJoin("shop_info s2 on s2.id = t.TAKE_SHOP_ID")
+                .leftJoin("driver_info d on d.id = t.ACCEPT_DRIVER")
                 .eq(Orders::getDeleted, Constants.ZERO)
                 .eq(Orders::getMemberId, memberId)
                 .eq(status != null, Orders::getStatus, status)
@@ -1357,22 +1413,33 @@
                 vo.setCode(o.getCode());
                 vo.setType(o.getType());
                 vo.setStatus(o.getStatus());
+                vo.setStatusName(Constants.OrderStatus.getDescByKey(o.getStatus(),
+                        Constants.equalsInteger(o.getType(), Constants.ZERO)?o.getType():Objects.nonNull(o.getTakeShopId())?Constants.ONE:Constants.TWO)
+                );
                 vo.setCreateTime(o.getCreateTime());
                 vo.setExpectedTakeTime(o.getExpectedTakeTime());
+                vo.setMemberVerifyCode(o.getMemberVerifyCode());
 
                 // 瀛樹欢闂ㄥ簵锛堝叧鑱旀煡璇㈢洿鎺ュ彇鍊硷級
+                vo.setDepositShopId(o.getDepositShopId());
                 vo.setDepositShopName(o.getDepositShopName());
                 vo.setDepositShopLinkName(o.getDepositShopLinkName());
                 vo.setDepositShopPhone(o.getDepositShopLinkPhone());
 
                 // 鍙栦欢淇℃伅锛氭湁鍙栦欢闂ㄥ簵鍙栭棬搴楋紝鏃犲垯鍙栫敤鎴疯嚜閫夊彇浠剁偣
                 if (o.getTakeShopId() != null) {
+                    vo.setTakeShopId(o.getTakeShopId());
                     vo.setTakeShopName(o.getTakeShopName());
                     vo.setTakeShopAddress(o.getTakeShopAddress());
+                    vo.setTakeShopPhone(o.getTakeShopLinkPhone());
                 } else {
                     vo.setTakeLocation(o.getTakeLocation());
                     vo.setTakeLocationRemark(o.getTakeLocationRemark());
                 }
+
+                // 鍙告満淇℃伅
+                vo.setDriverName(o.getDriverName());
+                vo.setDriverPhone(o.getDriverPhone());
 
                 // 鍙栦欢鑱旂郴浜�
                 vo.setTakeUser(o.getTakeUser());
@@ -1381,6 +1448,9 @@
                 // 璐圭敤锛堝垎锛�
                 vo.setDeclaredFee(o.getDeclaredFee());
                 vo.setEstimatedAmount(o.getEstimatedAmount());
+
+                // 璇勪环鐘舵��
+                vo.setCommentStatus(o.getCommentStatus());
 
                 // 鏌ヨ鐗╁搧鏄庣粏锛堜竴娆℃煡璇紝鍚屾椂鐢ㄤ簬鐗╁搧鍒楄〃鍜岄�炬湡璁$畻锛�
                 List<OrdersDetail> details = ordersDetailMapper.selectList(
@@ -1391,13 +1461,8 @@
                 // 鐗╁搧鏄庣粏
                 vo.setDetailList(buildDetailList(details));
 
-                // 閫炬湡淇℃伅锛堜粎寰呭彇浠剁姸鎬佽绠楋級
-                if (Integer.valueOf(Constants.OrderStatus.arrived.getStatus()).equals(o.getStatus())) {
-                    OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(o, details);
-                    vo.setOverdue(overdueInfo.getOverdue());
-                    vo.setOverdueDays(overdueInfo.getOverdueDays());
-                    vo.setOverdueFee(overdueInfo.getOverdueFee());
-                }
+                // 閫炬湡鐘舵��
+                fillOverdueStatus(vo, o, details);
                 voList.add(vo);
             }
         }
@@ -1437,12 +1502,30 @@
                 .select("s1.link_phone", Orders::getDepositShopLinkPhone)
                 .select("s2.name", Orders::getTakeShopName)
                 .select("s2.address", Orders::getTakeShopAddress)
+                .select("s2.link_phone", Orders::getTakeShopLinkPhone)
+                .select("d.name", Orders::getDriverName)
+                .select("d.telephone", Orders::getDriverPhone)
                 .leftJoin("shop_info s1 on s1.id = t.DEPOSIT_SHOP_ID")
                 .leftJoin("shop_info s2 on s2.id = t.TAKE_SHOP_ID")
-                .eq(Orders::getPayStatus, Constants.ONE)
-                .and(w -> w.eq(Orders::getDepositShopId, shopId).or().eq(Orders::getTakeShopId, shopId))
-                .eq(status != null, Orders::getStatus, status)
-                .in(statusList != null, Orders::getStatus, statusList)
+                .leftJoin("driver_info d on d.id = t.ACCEPT_DRIVER")
+                .eq(Orders::getPayStatus, Constants.ONE);
+
+        // 闂ㄥ簵寰呭鐞嗚鍗曪細鎸変笟鍔$幆鑺傚尯鍒嗛棬搴楄鑹�
+        if (combinedStatus != null && Constants.equalsInteger(combinedStatus, Constants.SEVEN)) {
+            wrapper.and(w -> w
+                    .and(w1 -> w1.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()))
+            );
+        } 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::getCreateTime);
 
         IPage<Orders> orderPage = ordersMapper.selectJoinPage(p, Orders.class, wrapper);
@@ -1454,7 +1537,11 @@
                 vo.setCode(o.getCode());
                 vo.setType(o.getType());
                 vo.setStatus(o.getStatus());
+                vo.setStatusName(Constants.OrderStatus.getDescByKey(o.getStatus(),
+                        Constants.equalsInteger(o.getType(), Constants.ZERO)?o.getType():Objects.nonNull(o.getTakeShopId())?Constants.ONE:Constants.TWO)
+                );
                 vo.setCreateTime(o.getCreateTime());
+                vo.setRemark(o.getRemark());
                 vo.setExpectedTakeTime(o.getExpectedTakeTime());
 
                 vo.setDepositShopName(o.getDepositShopName());
@@ -1471,10 +1558,15 @@
                 if (o.getTakeShopId() != null) {
                     vo.setTakeShopName(o.getTakeShopName());
                     vo.setTakeShopAddress(o.getTakeShopAddress());
+                    vo.setTakeShopPhone(o.getTakeShopLinkPhone());
                 } else {
                     vo.setTakeLocation(o.getTakeLocation());
                     vo.setTakeLocationRemark(o.getTakeLocationRemark());
                 }
+
+                // 鍙告満淇℃伅
+                vo.setDriverName(o.getDriverName());
+                vo.setDriverPhone(o.getDriverPhone());
 
                 vo.setTakeUser(o.getTakeUser());
                 vo.setTakePhone(o.getTakePhone());
@@ -1488,12 +1580,16 @@
 
                 vo.setDetailList(buildDetailList(details));
 
-                if (Integer.valueOf(Constants.OrderStatus.arrived.getStatus()).equals(o.getStatus())) {
-                    OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(o, details);
-                    vo.setOverdue(overdueInfo.getOverdue());
-                    vo.setOverdueDays(overdueInfo.getOverdueDays());
-                    vo.setOverdueFee(overdueInfo.getOverdueFee());
-                }
+
+                // 閫炬湡鐘舵��
+                fillOverdueStatus(vo, o, details);
+
+//                if (Integer.valueOf(Constants.OrderStatus.arrived.getStatus()).equals(o.getStatus())) {
+//                    OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(o, details);
+//                    vo.setOverdue(overdueInfo.getOverdue());
+//                    vo.setOverdueDays(overdueInfo.getOverdueDays());
+//                    vo.setOverdueFee(overdueInfo.getOverdueFee());
+//                }
                 voList.add(vo);
             }
         }
@@ -1539,7 +1635,7 @@
             }
         }
         if (order == null) {
-            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "璁㈠崟涓嶅瓨鍦�");
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鏍搁攢鐮佹棤鏁�");
         }
         return buildOrderDetailVO(order, false);
     }
@@ -1563,13 +1659,15 @@
         vo.setExpectedDepositTime(order.getExpectedDepositTime());
         vo.setExpectedTakeTime(order.getExpectedTakeTime());
         vo.setArriveTime(order.getArriveTime());
+        vo.setStatusName(Constants.OrderStatus.getDescByKey(order.getStatus(),order.getType()));
 
         // 璐圭敤锛堝垎锛�
         vo.setBasicAmount(order.getBasicAmount());
         vo.setDeclaredAmount(order.getDeclaredAmount());
         vo.setDeclaredFee(order.getDeclaredFee());
         vo.setUrgentAmount(order.getUrgentAmount());
-        vo.setActualPayAmount(order.getPayAmount());
+        vo.setIsUrgent(order.getIsUrgent());
+        vo.setActualPayAmount(Constants.equalsInteger(order.getPayStatus(), Constants.ONE)?order.getPayAmount():order.getEstimatedAmount());
 
         // 鏍囪
         vo.setExceptionStatus(order.getExceptionStatus());
@@ -1596,6 +1694,7 @@
 
         // 鍙栦欢淇℃伅
         if (order.getTakeShopId() != null) {
+            vo.setTakeShopId(order.getTakeShopId());
             ShopInfo takeShop = shopInfoMapper.selectById(order.getTakeShopId());
             if (takeShop != null) {
                 vo.setTakeShopName(takeShop.getName());
@@ -1609,6 +1708,16 @@
         // 鍙栦欢鑱旂郴浜�
         vo.setTakeUser(order.getTakeUser());
         vo.setTakePhone(order.getTakePhone());
+
+        // 鍙告満淇℃伅
+        if (order.getAcceptDriver() != null) {
+            DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
+            if (driver != null) {
+                vo.setDriverId(driver.getId());
+                vo.setDriverName(driver.getName());
+                vo.setDriverPhone(driver.getTelephone());
+            }
+        }
 
         // 鐗╁搧绫诲瀷鍚嶇О
         if (order.getGoodType() != null) {
@@ -1629,11 +1738,21 @@
                         .eq(OrdersDetail::getDeleted, Constants.ZERO));
         vo.setDetailList(buildDetailList(details));
 
-        // 閫炬湡淇℃伅
-        OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(order, details);
-        vo.setOverdue(overdueInfo.getOverdue());
-        vo.setOverdueDays(overdueInfo.getOverdueDays());
-        vo.setOverdueFee(overdueInfo.getOverdueFee());
+        // 閫炬湡鐘舵�侊細0=鏈埌搴楁湭閫炬湡 1=鏈埌搴楀瓨鍦ㄩ�炬湡 2=宸插埌搴楁湭閫炬湡 3=宸插埌搴楀緟鏀粯閫炬湡 4=閫炬湡宸叉敮浠�
+        fillOverdueStatus(vo, order, details);
+
+        // 閫�娆句俊鎭紙status=99鍙栨秷鏃惰繑鍥烇級
+        if (order.getStatus() != null &&
+                Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.cancelled.getStatus())) {
+            vo.setRefundApplyTime(order.getCancelTime());
+            OrdersRefund ordersRefund = ordersRefundMapper.selectOne(
+                    new QueryWrapper<OrdersRefund>().lambda()
+                            .eq(OrdersRefund::getOrderId, order.getId())
+                            .eq(OrdersRefund::getDeleted, Constants.ZERO)
+                            .orderByDesc(OrdersRefund::getCreateTime)
+                            .last("limit 1"));
+            vo.setRefundInfo(ordersRefund);
+        }
 
         // 鏍搁攢鐮�
         Integer status = order.getStatus();
@@ -1655,6 +1774,68 @@
             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.setCommentStatus(order.getCommentStatus());
+        if (Constants.equalsInteger(order.getCommentStatus(), Constants.ONE)) {
+            vo.setCommentTime(order.getCommentTime());
+            // 鏌ヨ璇勪环璁板綍锛岃幏鍙栧悇瀵硅薄璇勫垎
+            List<OrderComment> comments = orderCommentMapper.selectList(new QueryWrapper<OrderComment>().lambda()
+                    .eq(OrderComment::getOrderId, order.getId())
+                    .eq(OrderComment::getDeleted, Constants.ZERO));
+            for (OrderComment c : comments) {
+                if (Constants.equalsInteger(c.getTargetType(), Constants.ONE)) {
+                    vo.setDepositScore(c.getScore());
+                    vo.setCommentContent(c.getContent());
+                } else if (Constants.equalsInteger(c.getTargetType(), Constants.TWO)) {
+                    vo.setTakeScore(c.getScore());
+                } else if (Constants.equalsInteger(c.getTargetType(), Constants.THREE)) {
+                    vo.setDriverScore(c.getScore());
+                }
+            }
+            // 璇勪环闄勪欢鍥剧墖
+            vo.setCommentImages(getFileUrls(order.getId(), Constants.FileType.COMMENT_ATTACH.getKey(), imgPrefix));
+        }
+
         return vo;
     }
 
@@ -1669,11 +1850,6 @@
             throw new BusinessException(ResponseStatus.DATA_EMPTY);
         }
 
-        // 浠呭紓鍦板瘎瀛樺彲鍙栨秷
-        if (!Constants.equalsInteger(order.getType(), Constants.ONE)) {
-            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呭紓鍦板瘎瀛樿鍗曞彲鍙栨秷");
-        }
-
         Integer status = order.getStatus();
         if (status == null) {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璁㈠崟鐘舵�佸紓甯�");
@@ -1681,17 +1857,48 @@
 
         Date now = new Date();
 
-        // 寰呮敮浠橈細鐩存帴鍙栨秷
+        // 寰呮敮浠橈細鐩存帴鍙栨秷锛堜笉闄愯鍗曠被鍨嬶級
         if (Constants.equalsInteger(status, Constants.OrderStatus.waitPay.getStatus())) {
             order.setStatus(Constants.OrderStatus.cancelled.getStatus());
             order.setCancelTime(now);
             ordersMapper.updateById(order);
-            saveCancelLog(order, "浼氬憳鍙栨秷璁㈠崟锛堝緟鏀粯锛�", reason, memberId);
+            saveCancelLog(order, Constants.OrderLogType.memberCancel, "浼氬憳鍙栨秷璁㈠崟锛堝緟鏀粯锛�", memberId);
+            // 鐭俊閫氱煡浼氬憳锛氳鍗曞凡鍙栨秷
+            Member cancelMember1 = memberMapper.selectById(memberId);
+            sendSmsNotify(cancelMember1 != null ? cancelMember1.getTelephone() : null,
+                    Constants.SmsNotify.MEMBER_CANCELLED, "orderNo", order.getCode());
             return;
         }
 
-        // 寰呭瘎瀛橈細鐩存帴鍙栨秷锛屽叏棰濋��娆�
+        // 寰呭瘎瀛橈細鐩存帴鍙栨秷锛屽叏棰濋��娆撅紙涓嶉檺璁㈠崟绫诲瀷锛�
         if (Constants.equalsInteger(status, Constants.OrderStatus.waitDeposit.getStatus())) {
+            // 鍏堟爣璁拌鍗曞凡鍙栨秷
+            order.setStatus(Constants.OrderStatus.cancelled.getStatus());
+            order.setCancelTime(now);
+            order.setRefundAmount(order.getPayAmount());
+            ordersMapper.updateById(order);
+
+            saveCancelLog(order, Constants.OrderLogType.memberCancel, "浼氬憳鍙栨秷璁㈠崟锛堝緟瀵勫瓨锛屽叏棰濋��娆撅級", memberId);
+            // 閫氱煡浼氬憳锛氬凡鍙栨秷
+            sendOrderNotice(memberId, Constants.MemberOrderNotify.CANCELLED, orderId,
+                    "orderNo", order.getCode());
+            // 鐭俊閫氱煡浼氬憳锛氳鍗曞凡鍙栨秷
+            Member cancelMember2 = memberMapper.selectById(memberId);
+            sendSmsNotify(cancelMember2 != null ? cancelMember2.getTelephone() : null,
+                    Constants.SmsNotify.MEMBER_CANCELLED, "orderNo", order.getCode());
+
+            // 璋冪敤寰俊閫�娆綱3锛屽叏棰濋��娆�
+            com.wechat.pay.java.service.refund.model.Refund refundResult;
+            try {
+                refundResult = wxPayV3Service.refund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(),
+                        "璁㈠崟閫�娆�", wxPayProperties.getV3RefundNotifyUrl());
+            } catch (Exception e) {
+                log.error("寰呭瘎瀛樿鍗曢��娆捐皟鐢ㄥ紓甯�, orderId={}", orderId, e);
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆惧け璐ワ紝璇风◢鍚庨噸璇�");
+            }
+
+            com.wechat.pay.java.service.refund.model.Status refundStatus = refundResult.getStatus();
+
             // 璁板綍閫�娆句俊鎭�
             OrdersRefund refund = new OrdersRefund();
             refund.setOrderId(orderId);
@@ -1699,37 +1906,65 @@
             refund.setCancelInfo(reason);
             refund.setCreateTime(now);
             refund.setDeleted(Constants.ZERO);
-
-            // 璋冪敤寰俊閫�娆綱3锛屽叏棰濋��娆�
-            Refund refundResult = wxPayV3Service.refund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(),
-                    "璁㈠崟閫�娆�", wxPayProperties.getV3RefundNotifyUrl());
+            refund.setBeforeStatus(Constants.OrderStatus.waitDeposit.getStatus());
+            refund.setRefundAmount(order.getPayAmount());
             refund.setRefundCode(refundResult.getOutRefundNo());
-            refund.setStatus(Constants.ZERO); // 閫�娆句腑
+
+            if (com.wechat.pay.java.service.refund.model.Status.SUCCESS.equals(refundStatus)) {
+                // 閫�娆炬垚鍔�
+                refund.setStatus(Constants.ONE);
+            } else if (com.wechat.pay.java.service.refund.model.Status.PROCESSING.equals(refundStatus)) {
+                // 閫�娆句腑锛岀瓑鍥炶皟澶勭悊
+                refund.setStatus(Constants.ZERO);
+            } else {
+                // 閫�娆惧け璐�/寮傚父锛圕LOSED / ABNORMAL / 鍏朵粬锛�
+                log.error("寰呭瘎瀛樿鍗曢��娆惧け璐�, orderId={}, refundStatus={}", orderId, refundStatus);
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "閫�娆惧け璐ワ紝璇疯仈绯诲鏈嶅鐞�");
+            }
             ordersRefundMapper.insert(refund);
-
-            order.setStatus(Constants.OrderStatus.cancelled.getStatus());
-            order.setCancelTime(now);
-            order.setRefundAmount(order.getPayAmount());
-            ordersMapper.updateById(order);
-
-            saveCancelLog(order, "浼氬憳鍙栨秷璁㈠崟锛堝緟瀵勫瓨锛屽叏棰濋��娆撅級", reason, memberId);
-            // 閫氱煡浼氬憳锛氶��娆句腑
-            sendOrderNotice(memberId, Constants.MemberOrderNotify.REFUNDING, orderId,
-                    "orderNo", order.getCode());
             return;
         }
 
-        // 宸插瘎瀛�/宸叉帴鍗曪細杩涘叆鍙栨秷涓姸鎬�
+        // 宸插瘎瀛�/宸叉帴鍗曪細浠呭紓鍦板瘎瀛樺彲鍙栨秷
+        if (!Constants.equalsInteger(order.getType(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呭紓鍦板瘎瀛樿鍗曞彲鍙栨秷");
+        }
+
+        // 宸插瘎瀛�/宸叉帴鍗曪細鐩存帴灏嗚鍗曠被鍨嬫敼涓哄氨鍦板瘎瀛�
         if (Constants.equalsInteger(status, Constants.OrderStatus.deposited.getStatus())
                 || Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
-            order.setStatus(Constants.OrderStatus.cancelling.getStatus());
-            order.setCancelTime(now);
-            ordersMapper.updateById(order);
-            saveCancelLog(order, "浼氬憳鐢宠鍙栨秷璁㈠崟锛堝凡瀵勫瓨/宸叉帴鍗曪級", reason, memberId);
-            // 閫氱煡瀛樹欢闂ㄥ簵锛氶��娆剧敵璇�
-            if (order.getDepositShopId() != null) {
-                sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.REFUNDING, orderId,
+            // 鍏堜繚瀛樺師鍙告満淇℃伅锛岀敤浜庡悗缁�氱煡
+            Integer originalDriverId = order.getAcceptDriver();
+            DriverInfo originalDriver = originalDriverId != null ? driverInfoMapper.selectById(originalDriverId) : null;
+
+            ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
+            // 鍙栦欢鐐逛俊鎭洿鏂颁负瀛樹欢闂ㄥ簵锛屼娇鐢� UpdateWrapper 纭繚 null 瀛楁涔熻兘鐢熸晥
+            UpdateWrapper<Orders> updateWrapper = new UpdateWrapper<>();
+            updateWrapper.lambda()
+                    .eq(Orders::getId, order.getId())
+                    .set(Orders::getType, Constants.ZERO)
+                    .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());
+            if (Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
+                updateWrapper.lambda()
+                        .set(Orders::getAcceptDriver, null)
+                        .set(Orders::getAcceptType, null)
+                        .set(Orders::getAcceptTime, null);
+            }
+            ordersMapper.update(null, updateWrapper);
+            saveCancelLog(order, Constants.OrderLogType.memberCancelToConvert, "浼氬憳鍙栨秷寮傚湴瀵勫瓨璁㈠崟锛岃浆涓哄氨鍦板瘎瀛�", memberId);
+            // 閫氱煡鍙告満锛氳鍗曞凡鍙栨秷锛堝凡鎺ュ崟鎯呭喌涓嬪徃鏈洪渶鍋滄鏈嶅姟锛�
+            if (originalDriverId != null && Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
+                sendDriverNotice(originalDriverId, Constants.DriverOrderNotify.REFUNDING, orderId,
                         "orderNo", order.getCode());
+                sendSmsNotify(originalDriver != null ? originalDriver.getTelephone() : null,
+                        Constants.SmsNotify.DRIVER_REFUNDING, "orderNo", order.getCode());
             }
             return;
         }
@@ -1740,12 +1975,12 @@
     /**
      * 淇濆瓨鍙栨秷璁㈠崟鎿嶄綔鏃ュ織
      */
-    private void saveCancelLog(Orders order, String title, String reason, Integer memberId) {
+    private void saveCancelLog(Orders order, Constants.OrderLogType logType, String reason, Integer memberId) {
         OrderLog log = new OrderLog();
         log.setOrderId(order.getId());
-        log.setTitle(title);
-        log.setLogInfo(reason);
-        log.setObjType(Constants.ORDER_LOG_CANCEL);
+        log.setTitle(logType.getTitle());
+        log.setLogInfo(logType.format(reason));
+        log.setObjType(logType.getStatus());
         log.setOrderStatus(order.getStatus());
         log.setOptUserId(memberId);
         log.setOptUserType(0); // 0=鐢ㄦ埛
@@ -1757,12 +1992,13 @@
     /**
      * 淇濆瓨闂ㄥ簵鏍搁攢鏃ュ織
      */
-    private void saveShopVerifyLog(Orders order, String title, String logInfo, String remark, Integer shopId) {
+    private void saveShopVerifyLog(Orders order, Constants.OrderLogType logType, String logInfo, String remark, Integer shopId) {
         OrderLog log = new OrderLog();
         log.setOrderId(order.getId());
-        log.setTitle(title);
-        log.setLogInfo(logInfo);
+        log.setTitle(logType.getTitle());
+        log.setLogInfo(logInfo != null ? logInfo : logType.getStatusInfo());
         log.setRemark(remark);
+        log.setObjType(logType.getStatus());
         log.setOrderStatus(order.getStatus());
         log.setOptUserId(shopId);
         log.setOptUserType(2); // 2=闂ㄥ簵
@@ -1817,6 +2053,27 @@
         }
     }
 
+    /**
+     * 鍙戦�佸徃鏈虹珯鍐呬俊閫氱煡
+     */
+    private void sendDriverNotice(Integer driverId, Constants.DriverOrderNotify notify, Integer orderId, String... params) {
+        DriverInfo driver = driverInfoMapper.selectById(driverId);
+        if (driver == null || driver.getMemberId() == null) {
+            return;
+        }
+        Notice notice = new Notice();
+        notice.setUserType(1); // 1=鍙告満
+        notice.setUserId(driver.getMemberId());
+        notice.setTitle(notify.getTitle());
+        notice.setContent(notify.format(params));
+        notice.setObjId(orderId);
+        notice.setObjType(0); // 0=璁㈠崟
+        notice.setStatus(0);  // 0=鏈
+        notice.setIsdeleted(Constants.ZERO);
+        notice.setCreateDate(new Date());
+        noticeService.create(notice);
+    }
+
     @Override
     @Transactional(rollbackFor = {Exception.class, BusinessException.class})
     public void handleStorageOrderPayNotify(String outTradeNo, String wxTradeNo) {
@@ -1836,6 +2093,7 @@
         order.setPayStatus(Constants.ONE); // 宸叉敮浠�
         order.setPayTime(now);
         order.setWxExternalNo(wxTradeNo);
+        order.setPayAmount(order.getTotalAmount());
         order.setUpdateTime(now);
         // 鐢熸垚浼氬憳鏍搁攢鐮�
         order.setMemberVerifyCode(generateVerifyCode());
@@ -1868,6 +2126,15 @@
         if (Constants.ZERO.equals(order.getType()) && order.getDepositShopId() != null) {
             sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.WAIT_VERIFY, order.getId(),
                     "orderNo", order.getCode());
+        }
+
+        // 鐭俊閫氱煡瀛樹欢闂ㄥ簵锛氭湁鏂拌鍗曞緟鏍搁獙
+        if (order.getDepositShopId() != null) {
+            ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
+            if (depositShop != null) {
+                sendSmsNotify(depositShop.getLinkPhone(), Constants.SmsNotify.SHOP_WAIT_VERIFY,
+                        "orderNo", order.getCode());
+            }
         }
     }
 
@@ -1966,11 +2233,10 @@
         if (!Constants.equalsInteger(order.getMemberId(), memberId)) {
             throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鏃犳潈鎿嶄綔姝よ鍗�");
         }
-        // 浠呭凡瀹屾垚(7)銆佸凡鍙栨秷(99)銆佸凡閫�娆�(96)鍙垹闄�
+        // 浠呭凡瀹屾垚(7)銆佸凡鍙栨秷(99)
         int status = Constants.formatIntegerNum(order.getStatus());
         if (status != Constants.OrderStatus.finished.getStatus()
-                && status != Constants.OrderStatus.cancelled.getStatus()
-                && status != Constants.OrderStatus.closed.getStatus()) {
+                && status != Constants.OrderStatus.cancelled.getStatus()) {
             throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍙垹闄�");
         }
         ordersMapper.update(new UpdateWrapper<Orders>().lambda()
@@ -1981,9 +2247,10 @@
 
     @Override
     @Transactional(rollbackFor = {Exception.class, BusinessException.class})
-    public PayResponse payShopDeposit(Integer shopId) {
+    public PayResponse payShopDeposit(Integer memberId) {
         // 1. 鏌ヨ闂ㄥ簵淇℃伅
-        ShopInfo shopInfo = shopInfoMapper.selectById(shopId);
+        ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda()
+                .eq(ShopInfo::getRegionMemberId,memberId));
         if (shopInfo == null) {
             throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "闂ㄥ簵涓嶅瓨鍦�");
         }
@@ -2007,7 +2274,7 @@
         otherOrders.setMemberId(shopInfo.getRegionMemberId());
         otherOrders.setPayAccount(shopInfo.getDepositAmount());
         otherOrders.setPayStatus(Constants.ZERO);
-        otherOrders.setCode("SD" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(now) + shopId);
+        otherOrders.setCode("SD" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(now) + shopInfo.getId());
         otherOrders.setOutTradeNo(outTradeNo);
         otherOrders.setDeleted(Constants.ZERO);
         otherOrders.setCreateTime(now);
@@ -2061,6 +2328,15 @@
         }
         shopInfo.setUpdateTime(now);
         shopInfoMapper.updateById(shopInfo);
+
+        // 鐭俊閫氱煡闂ㄥ簵锛氭垚鍔熷叆椹�
+        String rawPassword = shopInfo.getTelephone() != null && shopInfo.getTelephone().length() >= 6
+                ? shopInfo.getTelephone().substring(shopInfo.getTelephone().length() - 6) + "@123456" : "";
+        sendSmsNotify(shopInfo.getTelephone(),
+                Constants.SmsNotify.SHOP_AUTH_SUCCESS,
+                "storeName", shopInfo.getName(),
+                "phone", shopInfo.getTelephone() != null ? shopInfo.getTelephone() : "",
+                "password", rawPassword);
 
         // 6. 鎶奸噾鏀粯瀹屾垚鍚庯紝鑻ュ煄甯傛湭寮�閫氬垯鑷姩寮�閫�
         if (shopInfo.getAreaId() != null) {
@@ -2158,6 +2434,14 @@
                     "orderNo", order.getCode(),
                     "amount", String.valueOf(Constants.getFormatMoney(
                             order.getTotalAmount() != null ? order.getTotalAmount() : 0L)));
+
+            // 閫氱煡鍙告満锛氳鍗曞凡缁撶畻
+            if (order.getAcceptDriver() != null) {
+                sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.SETTLED, order.getId(),
+                        "orderNo", order.getCode(),
+                        "amount", String.valueOf(Constants.getFormatMoney(
+                                order.getDriverFee() != null ? order.getDriverFee() : 0L)));
+            }
         }
     }
 
@@ -2246,6 +2530,9 @@
             orderCommentMapper.insert(driverComment);
         }
 
+        // 4.4 淇濆瓨璇勪环闄勪欢鍥剧墖锛坥bj_type=15锛屾渶澶�3寮狅級
+        saveVerifyImages(order.getId(), dto.getImages(), Constants.FileType.COMMENT_ATTACH.getKey(), null);
+
         // 5. 鏇存柊闂ㄥ簵/鍙告満骞冲潎璇勫垎
         updateTargetScore(Constants.ONE, order.getDepositShopId());
         if (isRemote && order.getTakeShopId() != null) {
@@ -2262,6 +2549,12 @@
         // 閫氱煡瀛樹欢闂ㄥ簵鍜屽彇浠堕棬搴楋細璁㈠崟宸茶瘎浠�
         notifyBothShops(order, Constants.ShopOrderNotify.EVALUATED,
                 "orderNo", order.getCode());
+
+        // 閫氱煡鍙告満锛氳鍗曞凡璇勪环
+        if (order.getAcceptDriver() != null) {
+            sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.EVALUATED, order.getId(),
+                    "orderNo", order.getCode());
+        }
     }
 
     /**
@@ -2326,6 +2619,129 @@
 
     @Override
     @Transactional(rollbackFor = {Exception.class, BusinessException.class})
+    public void verifyOrder(String verifyCode, Integer shopId, List<String> images, String remark) {
+        if (StringUtils.isBlank(verifyCode)) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏍搁攢鐮佷笉鑳戒负绌�");
+        }
+        // 鍏堟煡浼氬憳鏍搁攢鐮�
+        Orders query = new Orders();
+        query.setMemberVerifyCode(verifyCode);
+        query.setDeleted(Constants.ZERO);
+        Orders byMemberCode = findOne(query);
+        if (byMemberCode != null) {
+            shopVerifyOrder(verifyCode, shopId, images, remark);
+        } else {
+            driverVerifyOrder(verifyCode, images, remark, shopId);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = {Exception.class, BusinessException.class})
+    public void verifyOrderByShopId(Integer orderId, Integer shopId, List<String> images, String remark) {
+        if (orderId == null) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璁㈠崟涓婚敭涓嶈兘涓虹┖");
+        }
+        // 鏍规嵁璁㈠崟涓婚敭鏌ユ壘璁㈠崟
+        Orders order = ordersMapper.selectOne(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getId, orderId)
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .last("limit 1"));
+        if (order == null) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "璁㈠崟涓嶅瓨鍦�");
+        }
+
+        // 鏌ヨ闂ㄥ簵鍚嶇О鐢ㄤ簬鏃ュ織
+        String shopName = "";
+        ShopInfo shopInfo = shopInfoMapper.selectById(shopId);
+        if (shopInfo != null) {
+            shopName = shopInfo.getName() != null ? shopInfo.getName() : "";
+        }
+
+        Integer status = order.getStatus();
+        Date now = new Date();
+        if (Constants.equalsInteger(status, Constants.OrderStatus.waitDeposit.getStatus())) {
+            // 寰呭瘎瀛�(1) 鈫� 宸插瘎瀛�(2)锛屼袱绉嶇被鍨嬮�氱敤
+            // 鏍¢獙褰撳墠闂ㄥ簵鏄惁涓鸿鍗曠殑瀛樹欢闂ㄥ簵
+            if (!shopId.equals(order.getDepositShopId())) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曚笉灞炰簬褰撳墠闂ㄥ簵锛屾棤娉曟牳閿�");
+            }
+            order.setStatus(Constants.OrderStatus.deposited.getStatus());
+            order.setDepositTime(now);
+            // 閲婃斁褰撳墠鏍搁攢鐮侊紝鐢熸垚鏂扮殑鏍搁攢鐮佷緵鍙栦欢鏃朵娇鐢�
+            String verifyCode = order.getMemberVerifyCode();
+            if (StringUtils.isNotBlank(verifyCode)) {
+                releaseVerifyCode(verifyCode);
+            }
+            order.setMemberVerifyCode(generateVerifyCode());
+            ordersMapper.updateById(order);
+            // 淇濆瓨瀵勫瓨鍥剧墖锛坥bj_type=2 璁㈠崟瀵勫瓨鍥剧墖锛屾渶澶�3寮狅級
+            saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_DEPOSIT.getKey(), shopId);
+            // 璁板綍璁㈠崟鏃ュ織
+            saveShopVerifyLog(order, Constants.OrderLogType.shopDeposit, Constants.OrderLogType.shopDeposit.format(shopName), remark, shopId);
+            // 閫氱煡浼氬憳锛氶棬搴楁牳閿�鎴愬姛
+            if (Constants.equalsInteger(order.getType(), Constants.ONE)) {
+                // 寮傚湴瀵勫瓨 鈫� 寰呮姠鍗�
+                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(),
+                        "orderNo", order.getCode());
+            } else {
+                // 灏卞湴瀵勫瓨 鈫� 寰呭彇浠舵彁閱�
+                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(),
+                        "orderNo", order.getCode(), "shopName", shopName);
+            }
+        } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) {
+            // 寮傚湴瀵勫瓨 + 鏃犲彇浠堕棬搴� 鈫� 鏃犳硶鏍搁攢锛堝鎴疯嚜鍙栵紝鏃犻棬搴楁搷浣滐級
+            if (Constants.equalsInteger(order.getType(), Constants.ONE) && order.getTakeShopId() == null) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曟棤鍙栦欢闂ㄥ簵锛屾棤娉曟牳閿�");
+            }
+            // 鏍¢獙鍙栦欢闂ㄥ簵涓庡綋鍓嶇櫥褰曢棬搴椾竴鑷�
+            if (!shopId.equals(order.getTakeShopId())) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曚笉灞炰簬褰撳墠闂ㄥ簵锛屾棤娉曟牳閿�");
+            }
+            // 鏍¢獙鏄惁宸茬‘璁ら【瀹㈠埌搴�
+            if (order.getConfirmArriveTime() == null) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇峰厛纭椤惧鍒板簵");
+            }
+            // 鏍¢獙鏄惁瀛樺湪寰呭鐞嗙殑閫炬湡璐圭敤
+            if (Constants.equalsInteger(order.getOverdueStatus(), Constants.ONE)) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀛樺湪閫炬湡璐圭敤寰呭鐞嗭紝璇峰厛瀹屾垚閫炬湡璐圭敤鏀粯");
+            }
+            // 寰呭彇浠�(5) 鈫� 宸插畬鎴�(7)
+            order.setStatus(Constants.OrderStatus.finished.getStatus());
+            order.setConfirmArriveTime(now);
+            ordersMapper.updateById(order);
+            // 璁㈠崟瀹屾垚锛岄噴鏀炬牳閿�鐮�
+            String verifyCode = order.getMemberVerifyCode();
+            if (StringUtils.isNotBlank(verifyCode)) {
+                releaseVerifyCode(verifyCode);
+            }
+            // 淇濆瓨鍑哄簱鍥剧墖锛坥bj_type=13 闂ㄥ簵鍑哄簱鍥剧墖锛屾渶澶�3寮狅級
+            saveVerifyImages(order.getId(), images, Constants.FileType.STORE_OUT.getKey(), shopId);
+            // 鐢熸垚鏀剁泭璁板綍
+            calculateAndSaveOrderFees(order.getId());
+            generateRevenueRecords(order.getId());
+            // 璁板綍璁㈠崟鏃ュ織
+            saveShopVerifyLog(order, Constants.OrderLogType.shopTake, Constants.OrderLogType.shopTake.format(shopName), remark, shopId);
+            // 閫氱煡浼氬憳锛氳鍗曞凡瀹屾垚
+            sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(),
+                    "orderNo", order.getCode());
+            // 閫氱煡瀛樹欢闂ㄥ簵鍜屽彇浠堕棬搴楋細璁㈠崟宸插畬鎴�
+            String settleDays = operationConfigBiz.getConfig().getSettlementDate();
+            notifyBothShops(order, Constants.ShopOrderNotify.FINISHED,
+                    "orderNo", order.getCode(),
+                    "settleDays", settleDays != null ? settleDays : "7");
+            // 閫氱煡鍙告満锛氳鍗曞凡瀹屾垚
+            if (order.getAcceptDriver() != null) {
+                sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.FINISHED, order.getId(),
+                        "orderNo", order.getCode(),
+                        "settleDays", settleDays != null ? settleDays : "7");
+            }
+        } else {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽鏍搁攢");
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = {Exception.class, BusinessException.class})
     public void shopVerifyOrder(String verifyCode, Integer shopId, List<String> images, String remark) {
         if (StringUtils.isBlank(verifyCode)) {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏍搁攢鐮佷笉鑳戒负绌�");
@@ -2363,7 +2779,7 @@
             // 淇濆瓨瀵勫瓨鍥剧墖锛坥bj_type=2 璁㈠崟瀵勫瓨鍥剧墖锛屾渶澶�3寮狅級
             saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_DEPOSIT.getKey(), shopId);
             // 璁板綍璁㈠崟鏃ュ織
-            saveShopVerifyLog(order, "闂ㄥ簵纭瀵勫瓨", "闂ㄥ簵銆�" + shopName + "銆戠‘璁ゅ瘎瀛�", remark, shopId);
+            saveShopVerifyLog(order, Constants.OrderLogType.shopDeposit, Constants.OrderLogType.shopDeposit.format(shopName), remark, shopId);
             // 閫氱煡浼氬憳锛氶棬搴楁牳閿�鎴愬姛
             if (Constants.equalsInteger(order.getType(), Constants.ONE)) {
                 // 寮傚湴瀵勫瓨 鈫� 寰呮姠鍗�
@@ -2372,7 +2788,7 @@
             } else {
                 // 灏卞湴瀵勫瓨 鈫� 寰呭彇浠舵彁閱�
                 sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(),
-                        "orderNo", order.getCode());
+                        "orderNo", order.getCode(), "shopName", shopName);
             }
         } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) {
             // 寮傚湴瀵勫瓨 + 鏃犲彇浠堕棬搴� 鈫� 鏃犳硶鏍搁攢锛堝鎴疯嚜鍙栵紝鏃犻棬搴楁搷浣滐級
@@ -2382,6 +2798,14 @@
             // 鏍¢獙鍙栦欢闂ㄥ簵涓庡綋鍓嶇櫥褰曢棬搴椾竴鑷�
             if (!shopId.equals(order.getTakeShopId())) {
                 throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曚笉灞炰簬褰撳墠闂ㄥ簵锛屾棤娉曟牳閿�");
+            }
+            // 鏍¢獙鏄惁宸茬‘璁ら【瀹㈠埌搴�
+            if (order.getConfirmArriveTime() == null) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇峰厛纭椤惧鍒板簵");
+            }
+            // 鏍¢獙鏄惁瀛樺湪寰呭鐞嗙殑閫炬湡璐圭敤
+            if (Constants.equalsInteger(order.getOverdueStatus(), Constants.ONE)) {
+                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀛樺湪閫炬湡璐圭敤寰呭鐞嗭紝璇峰厛瀹屾垚閫炬湡璐圭敤鏀粯");
             }
             // 寰呭彇浠�(5) 鈫� 宸插畬鎴�(7)
             order.setStatus(Constants.OrderStatus.finished.getStatus());
@@ -2395,7 +2819,7 @@
             calculateAndSaveOrderFees(order.getId());
             generateRevenueRecords(order.getId());
             // 璁板綍璁㈠崟鏃ュ織
-            saveShopVerifyLog(order, "闂ㄥ簵纭鍙栦欢", "闂ㄥ簵銆�" + shopName + "銆戠‘璁ゅ彇浠讹紝璁㈠崟瀹屾垚", remark, shopId);
+            saveShopVerifyLog(order, Constants.OrderLogType.shopTake, Constants.OrderLogType.shopTake.format(shopName), remark, shopId);
             // 閫氱煡浼氬憳锛氳鍗曞凡瀹屾垚
             sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(),
                     "orderNo", order.getCode());
@@ -2404,6 +2828,12 @@
             notifyBothShops(order, Constants.ShopOrderNotify.FINISHED,
                     "orderNo", order.getCode(),
                     "settleDays", settleDays != null ? settleDays : "7");
+            // 閫氱煡鍙告満锛氳鍗曞凡瀹屾垚
+            if (order.getAcceptDriver() != null) {
+                sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.FINISHED, order.getId(),
+                        "orderNo", order.getCode(),
+                        "settleDays", settleDays != null ? settleDays : "7");
+            }
         } else {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽鏍搁攢");
         }
@@ -2477,7 +2907,9 @@
             refundRecord.setType(3); // 鍑哄簱閫�娆�
             refundRecord.setCreateTime(now);
             refundRecord.setRefundRemark(remark);
+            refundRecord.setRefundAmount(order.getRefundAmount());
             refundRecord.setDeleted(Constants.ZERO);
+            refundRecord.setBeforeStatus(order.getStatus());
             ordersRefundMapper.insert(refundRecord);
 
             // 璋冪敤寰俊閫�娆綱3锛堟斁鍦ㄦ渶鍚庯紝纭繚鍓嶇疆鎿嶄綔鍏ㄩ儴鎴愬姛锛�
@@ -2500,7 +2932,7 @@
         if (order.getRefundAmount() != null && order.getRefundAmount() > 0) {
             logInfo += "锛岄��娆�" + Constants.getFormatMoney(order.getRefundAmount()) + "鍏�";
         }
-        saveShopVerifyLog(order, "闂ㄥ簵纭鍑哄簱", logInfo, remark, shopId);
+        saveShopVerifyLog(order, Constants.OrderLogType.shopOutStock, logInfo, remark, shopId);
         // 閫氱煡浼氬憳锛氳鍗曞凡瀹屾垚
         sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(),
                 "orderNo", order.getCode());
@@ -2509,6 +2941,12 @@
         notifyBothShops(order, Constants.ShopOrderNotify.FINISHED,
                 "orderNo", order.getCode(),
                 "settleDays", settleDays != null ? settleDays : "7");
+        // 閫氱煡鍙告満锛氳鍗曞凡瀹屾垚
+        if (order.getAcceptDriver() != null) {
+            sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.FINISHED, order.getId(),
+                    "orderNo", order.getCode(),
+                    "settleDays", settleDays != null ? settleDays : "7");
+        }
     }
 
     @Override
@@ -2555,6 +2993,12 @@
         notifyBothShops(order, Constants.ShopOrderNotify.FINISHED,
                 "orderNo", order.getCode(),
                 "settleDays", settleDays != null ? settleDays : "7");
+        // 閫氱煡鍙告満锛氳鍗曞凡瀹屾垚
+        if (order.getAcceptDriver() != null) {
+            sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.FINISHED, order.getId(),
+                    "orderNo", order.getCode(),
+                    "settleDays", settleDays != null ? settleDays : "7");
+        }
     }
 
     @Override
@@ -2580,7 +3024,7 @@
         Long takeShopFee = 0L;
         Long driverFee = 0L;
 
-        if (Constants.equalsInteger(order.getType(), Constants.TWO)) {
+        if (Constants.equalsInteger(order.getType(), Constants.ONE)) {
             // 寮傚湴瀵勫瓨锛氬瓨浠堕棬搴� + 鍙告満
             driverFee = new BigDecimal(totalAmount)
                     .multiply(driverRate)
@@ -2726,6 +3170,15 @@
                     "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() : "");
+        }
     }
 
     /**
@@ -2811,9 +3264,9 @@
             ordersMapper.updateById(order);
 
             // 璁板綍璁㈠崟鏃ュ織
-            saveShopVerifyLog(order, "纭椤惧鍒板簵锛堥�炬湡锛�",
-                    "闂ㄥ簵銆�" + shopName + "銆戠‘璁ら【瀹㈠埌搴楋紝閫炬湡" + overdueInfo.getOverdueDays()
-                            + "澶╋紝閫炬湡璐圭敤" + Constants.getFormatMoney(overdueInfo.getOverdueFee()) + "鍏�",
+            String overdueLogInfo = "闂ㄥ簵銆�" + shopName + "銆戠‘璁ら【瀹㈠埌搴楋紝閫炬湡" + overdueInfo.getOverdueDays()
+                            + "澶╋紝閫炬湡璐圭敤" + Constants.getFormatMoney(overdueInfo.getOverdueFee()) + "鍏�";
+            saveShopVerifyLog(order, Constants.OrderLogType.shopConfirmArriveOverdue, overdueLogInfo,
                     null, shopId);
         } else {
             // 鏈�炬湡锛氭爣璁伴�炬湡鐘舵�佷负0锛岃鍗曚繚鎸佸綋鍓嶇姸鎬�
@@ -2857,7 +3310,7 @@
             if (order.getRefundAmount() != null && order.getRefundAmount() > 0) {
                 logInfo += "锛岄渶閫�娆�" + Constants.getFormatMoney(order.getRefundAmount()) + "鍏�";
             }
-            saveShopVerifyLog(order, "纭椤惧鍒板簵", logInfo, null, shopId);
+            saveShopVerifyLog(order, Constants.OrderLogType.shopConfirmArrive, logInfo, null, shopId);
         }
     }
 
@@ -2900,12 +3353,6 @@
         if (Constants.equalsInteger(status, Constants.OrderStatus.cancelled.getStatus())) {
             return "璁㈠崟宸插彇娑堬紝鎰熻阿鎮ㄧ殑鏀寔锛屾杩庝笅娆″啀浼氾紒";
         }
-        if (Constants.equalsInteger(status, Constants.OrderStatus.cancelling.getStatus())) {
-            return "閫�娆剧敵璇峰凡鎻愪氦锛屽钩鍙颁細灏藉揩涓烘偍澶勭悊閫�娆�";
-        }
-        if (Constants.equalsInteger(status, Constants.OrderStatus.closed.getStatus())) {
-            return "閫�娆惧凡鎴愬姛鍘熻矾杩斿洖锛岃娉ㄦ剰鏌ユ敹";
-        }
         return "";
     }
 
@@ -2940,6 +3387,62 @@
     }
 
     /**
+    /**
+     * 濉厖閫炬湡鐘舵�佸埌 VO锛圡yOrderVO锛�
+     * overdueStatus: 0=鏈埌搴楁湭閫炬湡 1=鏈埌搴楀瓨鍦ㄩ�炬湡 2=宸插埌搴楁湭閫炬湡 3=宸插埌搴楀緟鏀粯閫炬湡 4=閫炬湡宸叉敮浠�
+     */
+    private void fillOverdueStatus(MyOrderVO vo, Orders order, List<OrdersDetail> details) {
+        Integer[] result = calcOverdueStatus(order, details);
+        vo.setOverdueStatus(result[0]);
+        vo.setOverdue(result[1] == 1);
+        vo.setOverdueDays(result[2]);
+        vo.setOverdueFee(result[3].longValue());
+    }
+
+    /**
+     * 濉厖閫炬湡鐘舵�佸埌 VO锛圡yOrderDetailVO锛�
+     */
+    private void fillOverdueStatus(MyOrderDetailVO vo, Orders order, List<OrdersDetail> details) {
+        Integer[] result = calcOverdueStatus(order, details);
+        vo.setOverdueStatus(result[0]);
+        vo.setOverdue(result[1] == 1);
+        vo.setOverdueDays(result[2]);
+        vo.setOverdueFee(result[3].longValue());
+    }
+
+    /**
+     * 璁$畻閫炬湡鐘舵��
+     * @return [overdueStatus, isOverdue(0/1), overdueDays, overdueFee]
+     */
+    private Integer[] calcOverdueStatus(Orders order, List<OrdersDetail> details) {
+        // 4=閫炬湡宸叉敮浠橈紙璁㈠崟 overdueStatus=2锛�
+        if (Constants.equalsInteger(order.getOverdueStatus(), Constants.TWO)) {
+            return new Integer[]{4, 1, order.getOverdueDays(), order.getOverdueAmount() != null ? order.getOverdueAmount().intValue() : 0};
+        }
+        // 3=宸插埌搴楀緟鏀粯閫炬湡锛堣鍗� overdueStatus=1锛�
+        if (Constants.equalsInteger(order.getOverdueStatus(), Constants.ONE)) {
+            return new Integer[]{3, 1, order.getOverdueDays(), order.getOverdueAmount() != null ? order.getOverdueAmount().intValue() : 0};
+        }
+        // 璁$畻瀹炴椂閫炬湡
+        OverdueFeeVO overdueInfo = calculateOverdueFeeInternal(order, details);
+        boolean hasOverdue = overdueInfo.getOverdue() != null && overdueInfo.getOverdue()
+                && overdueInfo.getOverdueFee() != null && overdueInfo.getOverdueFee() > 0;
+        if (order.getConfirmArriveTime() != null) {
+            // 宸插埌搴�
+            int days = hasOverdue ? overdueInfo.getOverdueDays() : 0;
+            long fee = hasOverdue ? overdueInfo.getOverdueFee() : 0L;
+            return new Integer[]{2, hasOverdue ? 1 : 0, days, (int) fee};
+        } else {
+            // 鏈埌搴�
+            if (hasOverdue) {
+                return new Integer[]{1, 1, overdueInfo.getOverdueDays(), overdueInfo.getOverdueFee().intValue()};
+            } else {
+                return new Integer[]{0, 0, 0, 0};
+            }
+        }
+    }
+
+    /**
      * 閫炬湡璐圭敤鍐呴儴璁$畻锛堜笉鏌ュ簱锛屾帴鍙楅鏌ヨ鐨勬暟鎹級
      * 渚涘垎椤电瓑宸叉煡璇㈡槑缁嗙殑涓氬姟鍦烘櫙澶嶇敤锛岄伩鍏嶉噸澶嶆煡璇�
      */
@@ -2956,8 +3459,8 @@
         // 鐗╁搧鍩虹鏃ヨ垂鐢� = 危(鍗曚环 脳 鏁伴噺)
         long dailyBaseFee = 0L;
         for (OrdersDetail d : details) {
-            dailyBaseFee += (d.getUnitPrice() != null ? d.getUnitPrice() : 0L)
-                    * (d.getNum() != null ? d.getNum() : 0);
+            dailyBaseFee += (d.getLocallyPrice() != null ? d.getLocallyPrice() : 0L)
+                    * (d.getNum() != null ? d.getNum() : 1);
         }
 
         Date now = new Date();
@@ -3041,19 +3544,20 @@
 
     /**
      * 灏卞湴瀵勫瓨閫炬湡澶╂暟璁$畻
-     * 杩囦簡棰勮鍙栦欢鏃堕棿褰撳ぉ鐨�12鐐瑰悗鎵嶇畻涓�澶�
+     * 杩囦簡棰勮鍙栦欢鏃堕棿褰撳ぉ鐨�24:00锛堟鏃�00:00锛夊悗鎵嶇畻绗竴澶�
      */
     private int calcLocalOverdueDays(Date now, Date expectedTakeTime) {
         if (expectedTakeTime == null || !now.after(expectedTakeTime)) {
             return 0;
         }
-        // 鍩哄噯鏃堕棿 = 棰勮鍙栦欢鏃ユ湡鐨�12:00
+        // 鍩哄噯鏃堕棿 = 棰勮鍙栦欢鏃ユ湡鐨勬鏃� 00:00锛堝嵆褰撳ぉ24:00锛�
         Calendar baseCal = Calendar.getInstance();
         baseCal.setTime(expectedTakeTime);
-        baseCal.set(Calendar.HOUR_OF_DAY, 12);
+        baseCal.set(Calendar.HOUR_OF_DAY, 0);
         baseCal.set(Calendar.MINUTE, 0);
         baseCal.set(Calendar.SECOND, 0);
         baseCal.set(Calendar.MILLISECOND, 0);
+        baseCal.add(Calendar.DAY_OF_MONTH, 1); // 娆℃棩00:00 = 褰撳ぉ24:00
         Date baseTime = baseCal.getTime();
 
         if (!now.after(baseTime)) {
@@ -3121,6 +3625,61 @@
     }
 
     @Override
+    public ActiveOrderTipVO getActiveOrderTip(Integer memberId) {
+        // 鏌ヨ鐘舵�佷负 0~5 鐨勬渶鏂颁竴鏉¤鍗�
+        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
+        wrapper.eq("MEMBER_ID", memberId)
+                .in("STATUS", 0, 1, 2, 3, 4, 5)
+                .orderByDesc("CREATE_TIME")
+                .last("LIMIT 1");
+        Orders order = ordersMapper.selectOne(wrapper);
+        if (order == null) {
+            return null;
+        }
+
+        ActiveOrderTipVO vo = new ActiveOrderTipVO();
+        vo.setOrderId(order.getId());
+        vo.setStatus(order.getStatus());
+
+        // 鏋勫缓鎻愮ず鏂囨
+        boolean isLocal = Constants.equalsInteger(order.getType(), Constants.ZERO);
+        Integer status = order.getStatus();
+        String tip = null;
+
+        if (Constants.equalsInteger(status, Constants.OrderStatus.waitPay.getStatus())) {
+            // 寰呮敮浠橈細鎻愮ず鏀粯鍊掕鏃�
+            String minutes = "";
+            try {
+                minutes = operationConfigBiz.getConfig().getAutoCancelTime();
+            } catch (Exception ignored) {}
+            tip = "璇峰湪" + (StringUtils.isNotBlank(minutes) ? minutes : "") + "鍒嗛挓鍐呭畬鎴愭敮浠橈紝瓒呮椂璁㈠崟灏嗚嚜鍔ㄥ彇娑�";
+
+            // 璁$畻鏀粯鍊掕鏃�
+            if (StringUtils.isNotBlank(minutes) && order.getCreateTime() != null) {
+                long timeoutMs = Long.parseLong(minutes) * 60 * 1000;
+                long deadline = order.getCreateTime().getTime() + timeoutMs;
+                long remain = deadline - System.currentTimeMillis();
+                vo.setPayCountdown(remain > 0 ? remain : -1L);
+            } else {
+                vo.setPayCountdown(-1L);
+            }
+        } else if (Constants.equalsInteger(status, Constants.OrderStatus.waitDeposit.getStatus())) {
+            tip = "璁㈠崟宸叉敮浠橈紝璇峰墠寰�闂ㄥ簵瀵勫瓨";
+        } else if (Constants.equalsInteger(status, Constants.OrderStatus.deposited.getStatus())) {
+            tip = isLocal ? "琛屾潕宸插瘎瀛橈紝璇峰嚟鍙栦欢鐮佸墠寰�鎸囧畾闂ㄥ簵鍙栦欢" : "闂ㄥ簵宸叉帴鍗曪紝姝e湪涓烘偍瀹夋帓鍙栦欢鍙告満";
+        } else if (Constants.equalsInteger(status, Constants.OrderStatus.accepted.getStatus())) {
+            tip = isLocal ? "琛屾潕宸插瘎瀛橈紝璇峰嚟鍙栦欢鐮佸墠寰�鎸囧畾闂ㄥ簵鍙栦欢" : "宸叉湁鍙告満鎶㈠崟锛屾鍓嶅線鍙栦欢鍦扮偣";
+        } else if (Constants.equalsInteger(status, Constants.OrderStatus.delivering.getStatus())) {
+            tip = "鍙告満宸插彇浠讹紝姝h繍寰�鐩殑鍦�";
+        } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) {
+            tip = "琛屾潕宸查�佽揪鏈嶅姟鐐癸紝璇峰強鏃跺墠寰�鍙栦欢";
+        }
+
+        vo.setTip(tip);
+        return vo;
+    }
+
+    @Override
     public EstimatedDeliveryResultVO calculateEstimatedDelivery(Integer cityId,
                                                                 Double fromLat, Double fromLng,
                                                                 Double toLat, Double toLng) {
@@ -3145,4 +3704,293 @@
         return vo;
     }
 
+    @Override
+    public int cancelTimeoutUnpaidOrders() {
+        // 鑾峰彇瓒呮椂閰嶇疆锛堝垎閽燂級
+        String autoCancelTimeStr = operationConfigBiz.getConfig().getAutoCancelTime();
+        if (StringUtils.isBlank(autoCancelTimeStr)) {
+            log.info("鏈厤缃秴鏃跺彇娑堟椂闂达紝璺宠繃");
+            return 0;
+        }
+        int autoCancelMinutes;
+        try {
+            autoCancelMinutes = Integer.parseInt(autoCancelTimeStr);
+        } catch (NumberFormatException e) {
+            log.warn("瓒呮椂鍙栨秷鏃堕棿閰嶇疆寮傚父: {}", autoCancelTimeStr);
+            return 0;
+        }
+        if (autoCancelMinutes <= 0) {
+            return 0;
+        }
+
+        // 鏌ヨ鎵�鏈夎秴鏃舵湭鏀粯璁㈠崟锛歴tatus=0 涓� 鍒涘缓鏃堕棿 + 閰嶇疆鍒嗛挓鏁� < 褰撳墠鏃堕棿
+        Date deadline = new Date(System.currentTimeMillis() - (long) autoCancelMinutes * 60 * 1000);
+        List<Orders> timeoutOrders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getStatus, Constants.OrderStatus.waitPay.getStatus())
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .lt(Orders::getCreateTime, deadline));
+
+        if (timeoutOrders == null || timeoutOrders.isEmpty()) {
+            return 0;
+        }
+
+        int count = 0;
+        Date now = new Date();
+        for (Orders order : timeoutOrders) {
+            try {
+                order.setStatus(Constants.OrderStatus.cancelled.getStatus());
+                order.setCancelTime(now);
+                order.setUpdateTime(now);
+                ordersMapper.updateById(order);
+
+                // 鍐欏叆鎿嶄綔鏃ュ織
+                OrderLog orderLog = new OrderLog();
+                orderLog.setOrderId(order.getId());
+                orderLog.setTitle(Constants.OrderLogType.systemCancel.getTitle());
+                orderLog.setLogInfo(Constants.OrderLogType.systemCancel.format("璁㈠崟瓒呮椂" + autoCancelMinutes + "鍒嗛挓鏈敮浠橈紝绯荤粺鑷姩鍙栨秷"));
+                orderLog.setObjType(Constants.OrderLogType.systemCancel.getStatus());
+                orderLog.setOrderStatus(Constants.OrderStatus.cancelled.getStatus());
+                orderLog.setOptUserType(3); // 3=绯荤粺
+                orderLog.setCreateTime(now);
+                orderLog.setDeleted(Constants.ZERO);
+                orderLogService.create(orderLog);
+
+                // 鐭俊閫氱煡浼氬憳锛氳鍗曞凡鍙栨秷
+                if (order.getMemberId() != null) {
+                    Member member = memberMapper.selectById(order.getMemberId());
+                    sendSmsNotify(member != null ? member.getTelephone() : null,
+                            Constants.SmsNotify.MEMBER_CANCELLED, "orderNo", order.getCode());
+                }
+
+                count++;
+            } catch (Exception e) {
+                log.error("鍙栨秷瓒呮椂璁㈠崟寮傚父, orderId={}, error={}", order.getId(), e.getMessage());
+            }
+        }
+        log.info("瓒呮椂鏈敮浠樿鍗曡嚜鍔ㄥ彇娑堝畬鎴愶紝鍏卞彇娑坽}鍗�", count);
+        return count;
+    }
+
+    @Override
+    public int notifyUngrabbedOrders() {
+        // 鑾峰彇鏃犱汉鎶㈠崟閫氱煡鏃堕棿閰嶇疆锛堝垎閽燂級
+        String noGrabTimeStr = operationConfigBiz.getConfig().getNoGrabNotifyTime();
+        if (StringUtils.isBlank(noGrabTimeStr)) {
+            return 0;
+        }
+        int noGrabMinutes;
+        try {
+            noGrabMinutes = Integer.parseInt(noGrabTimeStr);
+        } catch (NumberFormatException e) {
+            log.warn("鏃犱汉鎶㈠崟閫氱煡鏃堕棿閰嶇疆寮傚父: {}", noGrabTimeStr);
+            return 0;
+        }
+        if (noGrabMinutes <= 0) {
+            return 0;
+        }
+
+        // 鑾峰彇閫氱煡浜哄憳涓婚敭鍒楄〃
+        String noGrabUsers = operationConfigBiz.getConfig().getNoGrabNotifyUsers();
+        if (StringUtils.isBlank(noGrabUsers)) {
+            return 0;
+        }
+        List<String> userIdStrList = Arrays.asList(noGrabUsers.split(","));
+        List<Integer> userIds = new ArrayList<>();
+        for (String idStr : userIdStrList) {
+            if (StringUtils.isNotBlank(idStr.trim())) {
+                userIds.add(Integer.parseInt(idStr.trim()));
+            }
+        }
+        if (userIds.isEmpty()) {
+            return 0;
+        }
+
+        // 鏌ヨ閫氱煡浜哄憳鎵嬫満鍙�
+        List<String> notifyPhones = new ArrayList<>();
+        for (Integer userId : userIds) {
+            SystemUser user = systemUserMapper.selectById(userId);
+            if (user != null && StringUtils.isNotBlank(user.getMobile())) {
+                notifyPhones.add(user.getMobile());
+            }
+        }
+        if (notifyPhones.isEmpty()) {
+            log.warn("鏃犱汉鎶㈠崟閫氱煡浜哄憳鍧囨棤鏈夋晥鎵嬫満鍙�");
+            return 0;
+        }
+
+        // 鏌ヨ寮傚湴宸插瘎瀛�(status=2)銆佹湭閫氱煡(platformSmsNotified=0鎴杗ull)銆佽秴鏃剁殑璁㈠崟
+        Date deadline = new Date(System.currentTimeMillis() - (long) noGrabMinutes * 60 * 1000);
+        List<Orders> ungrabbedOrders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getType, Constants.ONE) // 寮傚湴瀵勫瓨
+                .eq(Orders::getStatus, Constants.OrderStatus.deposited.getStatus()) // 宸插瘎瀛�
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .ne(Orders::getPlatformSmsNotified, Constants.ONE) // 鏈�氱煡
+                .lt(Orders::getPlatformSmsNotifiedTime, deadline)); // 閫氱煡鍩哄噯鏃堕棿瓒呰繃閰嶇疆鏃堕棿
+
+        if (ungrabbedOrders == null || ungrabbedOrders.isEmpty()) {
+            return 0;
+        }
+
+        int count = 0;
+        Date now = new Date();
+        for (Orders order : ungrabbedOrders) {
+            try {
+                // 缁欐墍鏈夐�氱煡浜哄憳鍙戠煭淇�
+                for (String phone : notifyPhones) {
+                    sendSmsNotify(phone, Constants.SmsNotify.PLATFORM_WAIT_GRAB,
+                            "orderNo", order.getCode(),
+                            "time", String.valueOf(noGrabMinutes));
+                }
+                // 鏍囪宸查�氱煡 + 璁板綍閫氱煡鏃堕棿
+                order.setPlatformSmsNotified(Constants.ONE);
+                order.setPlatformSmsNotifiedTime(now);
+                order.setUpdateTime(now);
+                ordersMapper.updateById(order);
+                count++;
+            } catch (Exception e) {
+                log.error("鏃犱汉鎶㈠崟鐭俊閫氱煡寮傚父, orderId={}, error={}", order.getId(), e.getMessage());
+            }
+        }
+        log.info("鏃犱汉鎶㈠崟鐭俊閫氱煡瀹屾垚锛屽叡閫氱煡{}鍗�", count);
+        return count;
+    }
+
+    @Override
+    public int autoCompleteOrders() {
+        // 鑾峰彇鑷姩纭鏀惰揣澶╂暟閰嶇疆
+        String autoConfirmDaysStr = operationConfigBiz.getConfig().getAutoConfirmReceipt();
+        if (StringUtils.isBlank(autoConfirmDaysStr)) {
+            return 0;
+        }
+        int autoConfirmDays;
+        try {
+            autoConfirmDays = Integer.parseInt(autoConfirmDaysStr);
+        } catch (NumberFormatException e) {
+            log.warn("鑷姩纭鏀惰揣澶╂暟閰嶇疆寮傚父: {}", autoConfirmDaysStr);
+            return 0;
+        }
+        if (autoConfirmDays <= 0) {
+            return 0;
+        }
+
+        // 鏌ヨ宸查�佽揪(status=5)涓旈�佽揪鏃堕棿瓒呰繃閰嶇疆澶╂暟鐨勮鍗�
+        Date deadline = new Date(System.currentTimeMillis() - (long) autoConfirmDays * 24 * 60 * 60 * 1000);
+        List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getStatus, Constants.OrderStatus.arrived.getStatus())
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .isNotNull(Orders::getArriveTime)
+                .lt(Orders::getArriveTime, deadline));
+
+        if (orders == null || orders.isEmpty()) {
+            return 0;
+        }
+
+        int count = 0;
+        Date now = new Date();
+        for (Orders order : orders) {
+            try {
+                // 閫炬湡鏈敮浠樼殑涓嶈嚜鍔ㄥ畬鎴�
+                if (Constants.equalsInteger(order.getOverdueStatus(), Constants.ONE)) {
+                    continue;
+                }
+
+                // 鏇存柊璁㈠崟鐘舵�佷负宸插畬鎴�
+                order.setStatus(Constants.OrderStatus.finished.getStatus());
+                order.setFinishTime(now);
+                order.setUpdateTime(now);
+                ordersMapper.updateById(order);
+
+                // 閲婃斁鏍搁攢鐮�
+                if (StringUtils.isNotBlank(order.getMemberVerifyCode())) {
+                    releaseVerifyCode(order.getMemberVerifyCode());
+                }
+
+                // 鐢熸垚鏀剁泭璁板綍
+                calculateAndSaveOrderFees(order.getId());
+                generateRevenueRecords(order.getId());
+
+                // 璁板綍鎿嶄綔鏃ュ織
+                OrderLog orderLog = new OrderLog();
+                orderLog.setOrderId(order.getId());
+                orderLog.setTitle(Constants.OrderLogType.systemComplete.getTitle());
+                orderLog.setLogInfo(Constants.OrderLogType.systemComplete.format("璁㈠崟宸查�佽揪瓒呰繃" + autoConfirmDays + "澶╂湭纭锛岀郴缁熻嚜鍔ㄥ畬鎴�"));
+                orderLog.setObjType(Constants.OrderLogType.systemComplete.getStatus());
+                orderLog.setOrderStatus(Constants.OrderStatus.finished.getStatus());
+                orderLog.setOptUserType(3); // 3=绯荤粺
+                orderLog.setCreateTime(now);
+                orderLog.setDeleted(Constants.ZERO);
+                orderLogService.create(orderLog);
+
+                // 閫氱煡浼氬憳锛氳鍗曞凡瀹屾垚
+                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(),
+                        "orderNo", order.getCode());
+                // 閫氱煡瀛樹欢闂ㄥ簵鍜屽彇浠堕棬搴�
+                String settleDays = operationConfigBiz.getConfig().getSettlementDate();
+                notifyBothShops(order, Constants.ShopOrderNotify.FINISHED,
+                        "orderNo", order.getCode(),
+                        "settleDays", settleDays != null ? settleDays : "7");
+                // 閫氱煡鍙告満
+                if (order.getAcceptDriver() != null) {
+                    sendDriverNotice(order.getAcceptDriver(), Constants.DriverOrderNotify.FINISHED, order.getId(),
+                            "orderNo", order.getCode(),
+                            "settleDays", settleDays != null ? settleDays : "7");
+                }
+
+                count++;
+            } catch (Exception e) {
+                log.error("鑷姩瀹屾垚璁㈠崟寮傚父, orderId={}, error={}", order.getId(), e.getMessage());
+            }
+        }
+        log.info("鑷姩瀹屾垚瓒呮椂璁㈠崟瀹屾垚锛屽叡瀹屾垚{}鍗�", count);
+        return count;
+    }
+
+    /**
+     * 鍙戦�佺煭淇¢�氱煡锛堝け璐ヤ笉褰卞搷涓讳笟鍔★級
+     * @param phone       鎺ユ敹鎵嬫満鍙�
+     * @param smsNotify   鐭俊妯℃澘鏋氫妇
+     * @param paramPairs  妯℃澘鍙傛暟锛宬ey-value 浜ゆ浛浼犲叆锛屽 "orderNo", "XL202604220001"
+     */
+    private void sendSmsNotify(String phone, Constants.SmsNotify smsNotify, String... paramPairs) {
+        if (StringUtils.isBlank(phone)) {
+            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(),
+                    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.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.setCreateTime(new Date());
+                record.setDeleted(Constants.ZERO);
+                smsrecordMapper.insert(record);
+            } catch (Exception ignored) {}
+        }
+    }
+
 }

--
Gitblit v1.9.3