From 9f8b3700ffbcc616a97e7ee2ea283ef4df3d666a Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期四, 04 六月 2026 08:43:55 +0800
Subject: [PATCH] 代码生成

---
 server/services/src/main/java/com/doumee/dao/vo/FinanceOverviewVO.java                     |    4 
 server/services/src/main/java/com/doumee/service/business/impl/DriverInfoServiceImpl.java  |    8 
 server/services/src/main/java/com/doumee/service/business/impl/PricingRuleServiceImpl.java |    6 
 server/services/src/main/java/com/doumee/service/business/impl/ShopInfoServiceImpl.java    |    2 
 server/web/src/main/java/com/doumee/api/web/PaymentCallback.java                           |    8 
 server/services/src/main/java/com/doumee/dao/dto/DataBoardQueryDTO.java                    |   28 ++
 server/services/src/main/java/com/doumee/dao/vo/OrdersExportVO.java                        |   46 +++-
 server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java   |  183 ++++++++++++++++++++
 server/services/src/main/java/com/doumee/config/wx/WxPayV3Service.java                     |    6 
 server/services/src/main/java/com/doumee/service/business/DataBoardService.java            |    3 
 server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java    |    4 
 server/admin/src/main/java/com/doumee/api/business/DriverInfoController.java               |    6 
 server/admin/src/main/java/com/doumee/api/business/DataBoardController.java                |    6 
 server/web/src/main/java/com/doumee/api/web/OrdersApi.java                                 |   31 +++
 server/services/src/main/java/com/doumee/dao/business/model/DriverInfo.java                |    5 
 server/services/src/main/java/com/doumee/core/constants/Constants.java                     |   12 
 server/services/src/main/java/com/doumee/dao/vo/OrderTimelineVO.java                       |   24 ++
 server/services/src/main/java/com/doumee/dao/business/model/Orders.java                    |    4 
 server/services/src/main/java/com/doumee/service/business/OrdersService.java               |    2 
 server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java      |  135 ++++++++++++++
 server/admin/src/main/java/com/doumee/api/business/OrdersController.java                   |    4 
 21 files changed, 482 insertions(+), 45 deletions(-)

diff --git a/server/admin/src/main/java/com/doumee/api/business/DataBoardController.java b/server/admin/src/main/java/com/doumee/api/business/DataBoardController.java
index 1eadd80..8b80a74 100644
--- a/server/admin/src/main/java/com/doumee/api/business/DataBoardController.java
+++ b/server/admin/src/main/java/com/doumee/api/business/DataBoardController.java
@@ -53,6 +53,12 @@
         return ApiResponse.success(dataBoardService.revenueTrend(query));
     }
 
+    @ApiOperation("钀ユ敹瓒嬪娍瀵煎嚭锛堟寜闂ㄥ簵鍒嗙粍锛�")
+    @PostMapping("/revenueTrendExport")
+    public void revenueTrendExport(@RequestBody TrendQueryDTO query, HttpServletResponse response) {
+        dataBoardService.revenueTrendExport(query, response);
+    }
+
     @ApiOperation("闂ㄥ簵涓氱哗缁熻")
     @PostMapping("/shopPerformance")
     public ApiResponse<ShopPerformanceVO> shopPerformance(@RequestBody DataBoardQueryDTO query) {
diff --git a/server/admin/src/main/java/com/doumee/api/business/DriverInfoController.java b/server/admin/src/main/java/com/doumee/api/business/DriverInfoController.java
index e1a220d..85ba296 100644
--- a/server/admin/src/main/java/com/doumee/api/business/DriverInfoController.java
+++ b/server/admin/src/main/java/com/doumee/api/business/DriverInfoController.java
@@ -3,6 +3,7 @@
 import com.doumee.api.BaseController;
 import com.doumee.core.annotation.excel.ExcelExporter;
 import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.constants.Constants;
 import com.doumee.core.model.ApiResponse;
 import com.doumee.core.model.PageData;
 import com.doumee.core.model.PageWrap;
@@ -85,6 +86,11 @@
     @RequiresPermissions("business:driverInfo:exportExcel")
     public void exportExcel(@RequestBody PageWrap<DriverInfo> pageWrap, HttpServletResponse response) {
         List<DriverInfo> driverInfoList = driverInfoService.findPage(pageWrap).getRecords();
+        for (DriverInfo d : driverInfoList) {
+            if (d.getMemberAmount() != null) {
+                d.setMemberAmountStr(String.valueOf(Constants.getFormatMoney(d.getMemberAmount())));
+            }
+        }
         String fileName = "鍙告満绠$悊瀵煎嚭_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
         ExcelExporter.build(DriverInfo.class).export(driverInfoList, fileName, response);
     }
diff --git a/server/admin/src/main/java/com/doumee/api/business/OrdersController.java b/server/admin/src/main/java/com/doumee/api/business/OrdersController.java
index c355d17..23163ed 100644
--- a/server/admin/src/main/java/com/doumee/api/business/OrdersController.java
+++ b/server/admin/src/main/java/com/doumee/api/business/OrdersController.java
@@ -96,6 +96,10 @@
             vo.setCode(o.getCode());
             vo.setRelationOrderCode(o.getRelationOrderCode());
             vo.setGoodsInfo(o.getGoodsInfo());
+            vo.setTakeUser(o.getTakeUser());
+            vo.setTakePhone(o.getTakePhone());
+            vo.setDepositShopName(o.getDepositShopName());
+            vo.setTakeShopName(o.getTakeShopName());
             vo.setTypeName(o.getType() != null ? (o.getType() == 0 ? "灏卞湴瀵勫瓨" : "鍚屽煄瀵勯��") : "");
             vo.setOrderLevel(StringUtils.isNotBlank(o.getOrderLevel()) ? Constants.getDriverLevelName(Integer.valueOf(o.getOrderLevel())) : Constants.getDriverLevelName(Constants.ZERO));
             vo.setDeclaredFee(String.valueOf(Constants.getFormatMoney(o.getDeclaredFee())));
diff --git a/server/services/src/main/java/com/doumee/config/wx/WxPayV3Service.java b/server/services/src/main/java/com/doumee/config/wx/WxPayV3Service.java
index 2224ae4..88383fd 100644
--- a/server/services/src/main/java/com/doumee/config/wx/WxPayV3Service.java
+++ b/server/services/src/main/java/com/doumee/config/wx/WxPayV3Service.java
@@ -59,7 +59,7 @@
 
             com.wechat.pay.java.service.payments.jsapi.model.Amount amount =
                     new com.wechat.pay.java.service.payments.jsapi.model.Amount();
-            amount.setTotal(totalCents.intValue());
+            amount.setTotal(2);//totalCents.intValue());
             amount.setCurrency("CNY");
             request.setAmount(amount);
 
@@ -109,8 +109,8 @@
             request.setNotifyUrl(notifyUrl);
 
             AmountReq amount = new AmountReq();
-            amount.setRefund(refundCents);
-            amount.setTotal(totalCents);
+            amount.setRefund(1L);//refundCents);
+            amount.setTotal(2L);//totalCents);
             amount.setCurrency("CNY");
             request.setAmount(amount);
 
diff --git a/server/services/src/main/java/com/doumee/core/constants/Constants.java b/server/services/src/main/java/com/doumee/core/constants/Constants.java
index e943d5c..6d2a6cf 100644
--- a/server/services/src/main/java/com/doumee/core/constants/Constants.java
+++ b/server/services/src/main/java/com/doumee/core/constants/Constants.java
@@ -43,8 +43,6 @@
     public static final String APPID ="APPID" ;
     public static final String SECRET ="SECRET" ;
     public static final String ACCESS_TOKEN ="ACCESS_TOKEN" ;
-    public static final String SERVER_INTRODUCE ="SERVER_INTRODUCE" ;
-    public static final String FEE_STANDARDS ="FEE_STANDARDS" ;
     public static final String ABOUT_US ="ABOUT_US" ;
     public static final String SERVER_PHONE ="SERVER_PHONE" ;
     public static final String ARRIVAL_PICK_UP_TIME ="ARRIVAL_PICK_UP_TIME" ;//鍗冲皢鍒拌揪鍙栦欢鏃堕棿閰嶇疆(鍒嗛挓)
@@ -385,10 +383,12 @@
     @Getter
     @AllArgsConstructor
     public enum OrdersAttach {
-        STORAGE_ORDER("storageOrder", "瀵勫瓨璁㈠崟"),
-        SHOP_DEPOSIT("shopDeposit", "搴楅摵鎶奸噾璁㈠崟"),
-        DRIVER_DEPOSIT("driverDeposit", "鍙告満鎶奸噾璁㈠崟"),
-        OVERDUE_FEE("overdueFee", "璁㈠崟閫炬湡璐圭敤")
+        STORAGE_ORDER("storageOrder", "瀹佺晠琛岃交鏉捐-瀵勫瓨璁㈠崟"),
+        DELIVERY_ORDER("deliveryOrder", "瀹佺晠琛岃交鏉捐-瀵勯�佽鍗�"),
+        SHOP_DEPOSIT("shopDeposit", "瀹佺晠琛岃交鏉捐-闂ㄥ簵鎶奸噾"),
+        DRIVER_DEPOSIT("driverDeposit", "瀹佺晠琛岃交鏉捐-鍙告満鎶奸噾璁㈠崟"),
+        OVERDUE_FEE("overdueFee", "瀹佺晠琛岃交鏉捐-瀵勫瓨閫炬湡璐圭敤"),
+        DELIVERY_OVERDUE_FEE("deliveryOverdueFee", "瀹佺晠琛岃交鏉捐-瀵勯�侀�炬湡璐圭敤")
         ;
 
         private final String key;
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/DriverInfo.java b/server/services/src/main/java/com/doumee/dao/business/model/DriverInfo.java
index ed0b1e8..c2defdf 100644
--- a/server/services/src/main/java/com/doumee/dao/business/model/DriverInfo.java
+++ b/server/services/src/main/java/com/doumee/dao/business/model/DriverInfo.java
@@ -182,10 +182,13 @@
 
     @TableField(exist = false)
     @ApiModelProperty(value = "褰撳墠浣欓(鍗曚綅:鍒�)", example = "10000")
-    @ExcelColumn(name = "璐︽埛浣欓", index = 5, width = 12)
     private Long memberAmount;
 
     @TableField(exist = false)
+    @ExcelColumn(name = "璐︽埛浣欓(鍏�)", index = 5, width = 12)
+    private String memberAmountStr;
+
+    @TableField(exist = false)
     @ApiModelProperty(value = "椹鹃┒杞﹁締绫诲瀷锛� 鏈哄姩杞� = driving 闈炴満鍔ㄨ溅 = bicycling")
     private String driverType;
 
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Orders.java b/server/services/src/main/java/com/doumee/dao/business/model/Orders.java
index 11286c2..340647f 100644
--- a/server/services/src/main/java/com/doumee/dao/business/model/Orders.java
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Orders.java
@@ -468,6 +468,10 @@
     @ApiModelProperty(value = "闂ㄥ簵涓婚敭锛堝悓鏃舵煡璇㈠瓨浠�/鍙栦欢闂ㄥ簵锛�")
     private Integer shopId;
 
+    @TableField(exist = false)
+    @ApiModelProperty(value = "鏀朵欢浜轰俊鎭紙妯$硦鏌ヨ鍚嶇О/鎵嬫満鍙凤級")
+    private String takeKeyword;
+
 
     @ApiModelProperty(value = "搴楅摵璁㈠崟搴忓彿")
     private Long autoNum;
diff --git a/server/services/src/main/java/com/doumee/dao/dto/DataBoardQueryDTO.java b/server/services/src/main/java/com/doumee/dao/dto/DataBoardQueryDTO.java
index 9220f7d..0c7d156 100644
--- a/server/services/src/main/java/com/doumee/dao/dto/DataBoardQueryDTO.java
+++ b/server/services/src/main/java/com/doumee/dao/dto/DataBoardQueryDTO.java
@@ -14,21 +14,43 @@
 @ApiModel("鏁版嵁鐪嬫澘鏌ヨ鏉′欢")
 public class DataBoardQueryDTO implements Serializable {
 
-    @ApiModelProperty(value = "鏃ユ湡娈电被鍨嬶細0=浠婃棩锛�1=杩戜竷澶╋紝2=杩�30澶╋紝3=杩戝崐骞达紝4=杩戜竴骞�", required = true)
+    @ApiModelProperty(value = "鏃ユ湡娈电被鍨嬶細0=浠婃棩锛�1=杩戜竷澶╋紝2=杩�30澶╋紝3=杩戝崐骞达紝4=杩戜竴骞达紝5=鑷畾涔�", required = true)
     private Integer dateType;
 
-    @JsonIgnore
     @JsonFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "鑷畾涔夊紑濮嬫棩鏈燂紙dateType=5鏃跺繀浼狅級")
     private Date startDate;
 
-    @JsonIgnore
     @JsonFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "鑷畾涔夌粨鏉熸棩鏈燂紙dateType=5鏃跺繀浼狅級")
     private Date endDate;
 
     @ApiModelProperty(value = "闂ㄥ簵涓婚敭锛堝彲閫夛級")
     private Integer shopId;
 
     public void resolveDateRange() {
+        if (dateType != null && dateType == 5) {
+            if (startDate != null) {
+                Calendar start = Calendar.getInstance();
+                start.setTime(startDate);
+                start.set(Calendar.HOUR_OF_DAY, 0);
+                start.set(Calendar.MINUTE, 0);
+                start.set(Calendar.SECOND, 0);
+                start.set(Calendar.MILLISECOND, 0);
+                this.startDate = start.getTime();
+            }
+            if (endDate != null) {
+                Calendar end = Calendar.getInstance();
+                end.setTime(endDate);
+                end.set(Calendar.HOUR_OF_DAY, 23);
+                end.set(Calendar.MINUTE, 59);
+                end.set(Calendar.SECOND, 59);
+                end.set(Calendar.MILLISECOND, 999);
+                this.endDate = end.getTime();
+            }
+            return;
+        }
+
         Calendar now = Calendar.getInstance();
         now.set(Calendar.MINUTE, 0);
         now.set(Calendar.SECOND, 0);
diff --git a/server/services/src/main/java/com/doumee/dao/vo/FinanceOverviewVO.java b/server/services/src/main/java/com/doumee/dao/vo/FinanceOverviewVO.java
index 5c17f4c..fd47215 100644
--- a/server/services/src/main/java/com/doumee/dao/vo/FinanceOverviewVO.java
+++ b/server/services/src/main/java/com/doumee/dao/vo/FinanceOverviewVO.java
@@ -40,11 +40,11 @@
     @ApiModelProperty(value = "閫�娆炬�婚噾棰濓紙鍏冿級")
     private BigDecimal refundAmount;
 
-    @ExcelColumn(name = "閫炬湡璐圭敤锛堝厓锛�", width = 18, index = 8)
+//    @ExcelColumn(name = "閫炬湡璐圭敤锛堝厓锛�", width = 18, index = 8)
     @ApiModelProperty(value = "閫炬湡璐圭敤锛堝厓锛�")
     private BigDecimal overdueAmount;
 
-    @ExcelColumn(name = "骞冲彴鍑�钀ユ敹锛堝厓锛�", width = 18, index = 9)
+    @ExcelColumn(name = "骞冲彴鍑�钀ユ敹锛堝厓锛�", width = 18, index = 8)
     @ApiModelProperty(value = "骞冲彴鍑�钀ユ敹锛堝厓锛�")
     private BigDecimal netRevenue;
 }
diff --git a/server/services/src/main/java/com/doumee/dao/vo/OrderTimelineVO.java b/server/services/src/main/java/com/doumee/dao/vo/OrderTimelineVO.java
new file mode 100644
index 0000000..b38edd4
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/vo/OrderTimelineVO.java
@@ -0,0 +1,24 @@
+package com.doumee.dao.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+@ApiModel("璁㈠崟鏃堕棿杞磋妭鐐�")
+public class OrderTimelineVO {
+
+    @ApiModelProperty("鏍囬鍐呭")
+    private String title;
+
+    @ApiModelProperty("鎿嶄綔鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date time;
+
+    @ApiModelProperty("闄勪欢鍥剧墖URL鍒楄〃")
+    private List<String> images;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/vo/OrdersExportVO.java b/server/services/src/main/java/com/doumee/dao/vo/OrdersExportVO.java
index 79754fd..8ebe433 100644
--- a/server/services/src/main/java/com/doumee/dao/vo/OrdersExportVO.java
+++ b/server/services/src/main/java/com/doumee/dao/vo/OrdersExportVO.java
@@ -17,54 +17,66 @@
     @ExcelColumn(name = "鐗╁搧淇℃伅", index = 2)
     private String goodsInfo;
 
-    @ExcelColumn(name = "绫诲瀷", index = 3)
+    @ExcelColumn(name = "鏀朵欢浜�", index = 3)
+    private String takeUser;
+
+    @ExcelColumn(name = "鏀朵欢浜虹數璇�", index = 4)
+    private String takePhone;
+
+    @ExcelColumn(name = "瀵勪欢闂ㄥ簵", index = 5)
+    private String depositShopName;
+
+    @ExcelColumn(name = "鍙栦欢闂ㄥ簵", index = 6)
+    private String takeShopName;
+
+    @ExcelColumn(name = "绫诲瀷", index = 7)
     private String typeName;
 
-    @ExcelColumn(name = "璁㈠崟绾у埆", index = 4)
+    @ExcelColumn(name = "璁㈠崟绾у埆", index = 8)
     private String orderLevel;
 
-    @ExcelColumn(name = "鐗╁搧淇濊垂(鍏�)", index = 5)
+    @ExcelColumn(name = "鐗╁搧淇濊垂(鍏�)", index = 9)
     private String declaredFee;
 
-    @ExcelColumn(name = "鍩虹鏈嶅姟璐�(鍏�)", index = 6)
+    @ExcelColumn(name = "鍩虹鏈嶅姟璐�(鍏�)", index = 10)
     private String basicAmount;
 
-    @ExcelColumn(name = "璁㈠崟鎬讳环(鍏�)", index = 7)
+    @ExcelColumn(name = "璁㈠崟鎬讳环(鍏�)", index = 11)
     private String totalAmount;
 
-    @ExcelColumn(name = "瀹炰粯鐜伴噾(鍏�)", index = 8)
+    @ExcelColumn(name = "瀹炰粯鐜伴噾(鍏�)", index = 12)
     private String payAmount;
 
-    @ExcelColumn(name = "鍔犳�ヨ垂(鍏�)", index = 9)
+    @ExcelColumn(name = "鍔犳�ヨ垂(鍏�)", index = 13)
     private String urgentAmount;
 
-    @ExcelColumn(name = "閫�娆鹃噾棰�(鍏�)", index = 10)
+    @ExcelColumn(name = "閫�娆鹃噾棰�(鍏�)", index = 14)
     private String refundAmount;
 
-    @ExcelColumn(name = "瓒呮椂閲戦(鍏�)", index = 11)
+    @ExcelColumn(name = "瓒呮椂閲戦(鍏�)", index = 15)
     private String overdueAmount;
 
-    @ExcelColumn(name = "寮傚父閲戦(鍏�)", index = 12)
+    @ExcelColumn(name = "寮傚父閲戦(鍏�)", index = 16)
     private String exceptionAmount;
 
-    @ExcelColumn(name = "浼樻儬鍒告姌鎵�(鍏�)", index = 13)
+    @ExcelColumn(name = "浼樻儬鍒告姌鎵�(鍏�)", index = 17)
     private String deductionAmount;
 
-    @ExcelColumn(name = "鍙告満琛ュ伩璐圭敤(鍏�)", index = 14)
+    @ExcelColumn(name = "鍙告満琛ュ伩璐圭敤(鍏�)", index = 18)
     private String exceptionFee;
 
-    @ExcelColumn(name = "闂ㄥ簵淇濈琛ヨ创(鍏�)", index = 15)
+    @ExcelColumn(name = "闂ㄥ簵淇濈琛ヨ创(鍏�)", index = 19)
     private String shopCompensationAmount;
 
-    @ExcelColumn(name = "璁㈠崟鐘舵��", index = 16)
+    @ExcelColumn(name = "璁㈠崟鐘舵��", index = 20)
     private String statusDesc;
 
-    @ExcelColumn(name = "缁撶畻鐘舵��", index = 17)
+    @ExcelColumn(name = "缁撶畻鐘舵��", index = 21)
     private String settlementDesc;
 
-    @ExcelColumn(name = "鏀粯鏃堕棿", index = 18, dateFormat = "yyyy-MM-dd HH:mm:ss", width = 16)
+    @ExcelColumn(name = "鏀粯鏃堕棿", index = 22, dateFormat = "yyyy-MM-dd HH:mm:ss", width = 16)
     private Date payTime;
 
-    @ExcelColumn(name = "鍒涘缓鏃堕棿", index = 19, dateFormat = "yyyy-MM-dd HH:mm:ss", width = 16)
+    @ExcelColumn(name = "鍒涘缓鏃堕棿", index = 23, dateFormat = "yyyy-MM-dd HH:mm:ss", width = 16)
     private Date createTime;
 }
diff --git a/server/services/src/main/java/com/doumee/service/business/DataBoardService.java b/server/services/src/main/java/com/doumee/service/business/DataBoardService.java
index 3157457..d71d1de 100644
--- a/server/services/src/main/java/com/doumee/service/business/DataBoardService.java
+++ b/server/services/src/main/java/com/doumee/service/business/DataBoardService.java
@@ -5,6 +5,7 @@
 import com.doumee.dao.dto.TrendQueryDTO;
 import com.doumee.dao.vo.*;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 public interface DataBoardService {
@@ -27,6 +28,8 @@
 
     List<DriverTopVO> driverTop(TrendQueryDTO query);
 
+    void revenueTrendExport(TrendQueryDTO query, HttpServletResponse response);
+
     /**
      * 鏍规嵁璁㈠崟ID鍒楄〃鏋勫缓琛屾潕绫诲瀷鍒嗗竷
      */
diff --git a/server/services/src/main/java/com/doumee/service/business/OrdersService.java b/server/services/src/main/java/com/doumee/service/business/OrdersService.java
index 340440b..d40d186 100644
--- a/server/services/src/main/java/com/doumee/service/business/OrdersService.java
+++ b/server/services/src/main/java/com/doumee/service/business/OrdersService.java
@@ -467,4 +467,6 @@
     Boolean checkOperationRadius(Integer orderId, Integer userId, Integer userType, Double lng, Double lat);
 
     ManualRefundDetailVO getManualRefundDetail(Integer orderId);
+
+    List<OrderTimelineVO> getOrderTimeline(Integer orderId);
 }
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
index 4bc82ed..025157d 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
@@ -172,7 +172,9 @@
         pageWrap.getModel().setDeleted(Constants.ZERO);
         queryWrapper.selectAll(Category.class)
                 .selectAs(SystemUser::getUsername, Category::getUpdateUserName)
-                .leftJoin(SystemUser.class,SystemUser::getId,Category::getUpdateUser);
+                .select("c2.name", Category::getRelationName)
+                .leftJoin(SystemUser.class,SystemUser::getId,Category::getUpdateUser)
+                .leftJoin("category c2 on c2.id = t.relation_id");
         if (pageWrap.getModel().getId() != null) {
             queryWrapper.eq(Category::getId, pageWrap.getModel().getId());
         }
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
index ce7f4a7..5e4cb53 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
@@ -13,7 +13,11 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -430,6 +434,7 @@
             vo.setNetRevenue(BigDecimal.valueOf(netRev).divide(hundred, 2, RoundingMode.HALF_UP));
             result.add(vo);
         }
+        Collections.reverse(result);
         return result;
     }
 
@@ -642,6 +647,184 @@
         return qw;
     }
 
+    @Override
+    public void revenueTrendExport(TrendQueryDTO query, HttpServletResponse response) {
+        TrendDateRange range = parseTrendDateRange(query);
+        SimpleDateFormat sdf = new SimpleDateFormat(range.pattern);
+
+        // 鏌ヨ璁㈠崟
+        List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .in(Orders::getStatus,
+                        Constants.OrderStatus.waitDeposit.getKey(),
+                        Constants.OrderStatus.deposited.getKey(),
+                        Constants.OrderStatus.accepted.getKey(),
+                        Constants.OrderStatus.delivering.getKey(),
+                        Constants.OrderStatus.arrived.getKey(),
+                        Constants.OrderStatus.overdue.getKey(),
+                        Constants.OrderStatus.finished.getKey())
+                .ge(Orders::getCreateTime, range.startDate)
+                .le(Orders::getCreateTime, range.endDate));
+
+        // 鏌ヨ閫炬湡璐圭敤
+        List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+        Map<Integer, Long> overduePaidMap = new HashMap<>();
+        if (!orderIds.isEmpty()) {
+            List<OtherOrders> overdueOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
+                    .eq(OtherOrders::getType, 2)
+                    .eq(OtherOrders::getPayStatus, Constants.ONE)
+                    .eq(OtherOrders::getDeleted, Constants.ZERO)
+                    .in(OtherOrders::getOrderId, orderIds));
+            for (OtherOrders oo : overdueOrders) {
+                long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
+                overduePaidMap.merge(oo.getOrderId(), amt, Long::sum);
+            }
+        }
+
+        // 鐢熸垚鏃ユ湡鍒楀ご
+        List<String> dateKeys = new ArrayList<>();
+        List<String> dateLabels = new ArrayList<>();
+        if (range.byMonth) {
+            Calendar loop = Calendar.getInstance();
+            loop.setTime(range.startDate);
+            Calendar end = Calendar.getInstance();
+            end.setTime(range.endDate);
+            while (!loop.after(end)) {
+                dateKeys.add(sdf.format(loop.getTime()));
+                dateLabels.add(sdf.format(loop.getTime()));
+                loop.add(Calendar.DAY_OF_MONTH, 1);
+            }
+        } else {
+            Calendar endCal = Calendar.getInstance();
+            endCal.setTime(range.endDate);
+            int endMonth = endCal.get(Calendar.MONTH);
+            for (int m = 0; m <= endMonth; m++) {
+                dateKeys.add(String.format("%02d", m + 1));
+                dateLabels.add((m + 1) + "鏈�");
+            }
+        }
+
+        // 鏀堕泦鎵�鏈夐棬搴�
+        Map<Integer, String> shopNameMap = new LinkedHashMap<>();
+        for (Orders o : orders) {
+            if (o.getDepositShopId() != null && !shopNameMap.containsKey(o.getDepositShopId())) {
+                ShopInfo shop = shopInfoMapper.selectById(o.getDepositShopId());
+                shopNameMap.put(o.getDepositShopId(), shop != null ? shop.getName() : "鏈煡闂ㄥ簵");
+            }
+        }
+
+        // 鎸夐棬搴�+鏃ユ湡鍒嗙粍璁$畻钀ユ敹
+        // key = shopId + "_" + dateKey
+        Map<String, Long> revenueMap = new HashMap<>();
+        for (Orders o : orders) {
+            String date = sdf.format(o.getCreateTime());
+            long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+            long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+            long overdue = overduePaidMap.getOrDefault(o.getId(), 0L);
+            long rev = pay - refund + overdue;
+            Integer shopId = o.getDepositShopId();
+            if (shopId != null) {
+                String key = shopId + "_" + date;
+                revenueMap.merge(key, rev, Long::sum);
+            }
+        }
+
+        // 鏋勫缓Excel
+        try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
+            Sheet sheet = wb.createSheet("钀ユ敹瓒嬪娍");
+
+            // 鍒涘缓鏍峰紡
+            CellStyle titleStyle = wb.createCellStyle();
+            Font titleFont = wb.createFont();
+            titleFont.setBold(true);
+            titleFont.setFontHeightInPoints((short) 16);
+            titleStyle.setFont(titleFont);
+            titleStyle.setAlignment(HorizontalAlignment.CENTER);
+
+            CellStyle headerStyle = wb.createCellStyle();
+            Font headerFont = wb.createFont();
+            headerFont.setBold(true);
+            headerFont.setFontHeightInPoints((short) 12);
+            headerStyle.setFont(headerFont);
+            headerStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+
+            CellStyle dataStyle = wb.createCellStyle();
+            dataStyle.setAlignment(HorizontalAlignment.RIGHT);
+
+            // 鐢熸垚鏍囬
+            String title;
+            int totalCols = dateLabels.size() + 1;
+            if (range.byMonth) {
+                String yearMonth = query.getMonth(); // yyyy-MM
+                String[] ym = yearMonth.split("-");
+                title = "琛屾潕瀵勫瓨闂ㄥ簵" + ym[0] + "骞�" + Integer.valueOf(ym[1]) + "鏈堟棩鎶ヨ〃";
+            } else {
+                title = "琛屾潕瀵勫瓨闂ㄥ簵" + query.getYear() + "骞存湀鎶ヨ〃";
+            }
+
+            // 鍐欐爣棰樿锛堢0琛岋紝鍚堝苟鎵�鏈夊垪锛�
+            Row titleRow = sheet.createRow(0);
+            titleRow.setHeight((short) 600);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue(title);
+            titleCell.setCellStyle(titleStyle);
+            sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, totalCols - 1));
+
+            // 鍐欏垪澶达紙绗�1琛岋級
+            Row headerRow = sheet.createRow(1);
+            Cell shopCell = headerRow.createCell(0);
+            shopCell.setCellValue("闂ㄥ簵鍚嶇О");
+            shopCell.setCellStyle(headerStyle);
+            sheet.setColumnWidth(0, 20 * 256);
+
+            for (int i = 0; i < dateLabels.size(); i++) {
+                Cell cell = headerRow.createCell(i + 1);
+                cell.setCellValue(dateLabels.get(i));
+                cell.setCellStyle(headerStyle);
+                sheet.setColumnWidth(i + 1, 14 * 256);
+            }
+
+            // 鍐欐暟鎹锛堢2琛岃捣锛�
+            BigDecimal hundred = BigDecimal.valueOf(100);
+            int rowIndex = 2;
+            for (Map.Entry<Integer, String> entry : shopNameMap.entrySet()) {
+                Row row = sheet.createRow(rowIndex++);
+                row.createCell(0).setCellValue(entry.getValue());
+                for (int i = 0; i < dateKeys.size(); i++) {
+                    String mapKey = entry.getKey() + "_" + dateKeys.get(i);
+                    long rev = revenueMap.getOrDefault(mapKey, 0L);
+                    Cell cell = row.createCell(i + 1);
+                    if (rev > 0) {
+                        cell.setCellValue(BigDecimal.valueOf(rev).divide(hundred, 2, RoundingMode.HALF_UP).toPlainString());
+                    } else {
+                        cell.setCellValue("");
+                    }
+                    cell.setCellStyle(dataStyle);
+                }
+            }
+
+            // 杈撳嚭
+            String fileName;
+            if (StringUtils.isNotBlank(query.getMonth())) {
+                fileName = "钀ユ敹瓒嬪娍瀵煎嚭_" + query.getMonth();
+            } else {
+                fileName = "钀ユ敹瓒嬪娍瀵煎嚭_" + query.getYear();
+            }
+            String encodeFileName = java.net.URLEncoder.encode(fileName, "UTF-8") + ".xlsx";
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
+            response.setHeader("doumee-opera-type", "download");
+            response.setHeader("doumee-download-filename", encodeFileName);
+            wb.write(response.getOutputStream());
+            response.getOutputStream().flush();
+        } catch (Exception e) {
+            log.error("钀ユ敹瓒嬪娍瀵煎嚭寮傚父", e);
+            throw new RuntimeException("瀵煎嚭澶辫触: " + e.getMessage());
+        }
+    }
+
     private TrendDateRange parseTrendDateRange(TrendQueryDTO query) {
         Calendar now = Calendar.getInstance();
         TrendDateRange range = new TrendDateRange();
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/DriverInfoServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/DriverInfoServiceImpl.java
index b90ecac..bd078aa 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/DriverInfoServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/DriverInfoServiceImpl.java
@@ -293,6 +293,14 @@
         if (pageWrap.getModel().getAuditStatus() != null) {
             queryWrapper.eq(DriverInfo::getAuditStatus, pageWrap.getModel().getAuditStatus());
         }
+        // 鎬у埆锛堟牴鎹韩浠借瘉绗�17浣嶅垽鏂級
+        if (pageWrap.getModel().getGender() != null) {
+            if (pageWrap.getModel().getGender() == 1) {
+                queryWrapper.apply("CAST(SUBSTRING(t.IDCARD, 17, 1) AS UNSIGNED) % 2 = 1");
+            } else if (pageWrap.getModel().getGender() == 2) {
+                queryWrapper.apply("CAST(SUBSTRING(t.IDCARD, 17, 1) AS UNSIGNED) % 2 = 0");
+            }
+        }
         // 鍒涘缓鏃ユ湡鑼冨洿
         if (pageWrap.getModel().getCreateTimeStart() != null) {
             queryWrapper.ge(DriverInfo::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTimeStart()));
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 06fe53c..5883343 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
@@ -237,6 +237,7 @@
                 .selectAs(Category::getDetail, Orders::getOrderLevel)
                 .select("s1.name", Orders::getDepositShopName)
                 .select("o2.code", Orders::getRelationOrderCode)
+                .select("s2.name", Orders::getTakeShopName)
                 .leftJoin(Category.class, Category::getId, Orders::getGoodLevel)
                 .leftJoin(DriverInfo.class, DriverInfo::getId, Orders::getAcceptDriver)
                 .leftJoin("shop_info s1 on s1.id = t.DEPOSIT_SHOP_ID")
@@ -248,6 +249,7 @@
         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.eq(StringUtils.isNotBlank(pageWrap.getModel().getTakeShopName()),  Orders::getType,Constants.ONE);
         queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getGoodsInfo()), Orders::getGoodsInfo, pageWrap.getModel().getGoodsInfo());
         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()));
@@ -259,6 +261,8 @@
                 .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().getTakeKeyword() != null, i -> i.like(Orders::getTakeUser, pageWrap.getModel().getTakeKeyword())
+                .or().like(Orders::getTakePhone, pageWrap.getModel().getTakeKeyword()));
         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);
@@ -1049,7 +1053,8 @@
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鐢ㄦ埛淇℃伅寮傚父锛屾棤娉曞彂璧锋敮浠�");
         }
         PayResponse payResponse = wxPayV3(orders.getOutTradeNo(), orders.getTotalAmount(), orders.getId(),
-                member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER);
+                member.getOpenid(), Constants.equalsInteger(orders.getType(), Constants.ONE)
+                        ? Constants.OrdersAttach.DELIVERY_ORDER : Constants.OrdersAttach.STORAGE_ORDER);
         payResponse.setLockKey(lockKey);
         return payResponse;
     }
@@ -1086,7 +1091,8 @@
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鐢ㄦ埛淇℃伅寮傚父锛屾棤娉曞彂璧锋敮浠�");
         }
         return wxPayV3(orders.getOutTradeNo(), orders.getTotalAmount(), orders.getId(),
-                member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER);
+                member.getOpenid(), Constants.equalsInteger(orders.getType(), Constants.ONE)
+                        ? Constants.OrdersAttach.DELIVERY_ORDER : Constants.OrdersAttach.STORAGE_ORDER);
     }
 
     /**
@@ -1480,6 +1486,13 @@
         }
     }
 
+    private void clearVerifyCodes(Integer orderId) {
+        ordersMapper.update(null, new UpdateWrapper<Orders>().lambda()
+                .eq(Orders::getId, orderId)
+                .set(Orders::getMemberVerifyCode, null)
+                .set(Orders::getDriverVerifyCode, null));
+    }
+
     private String getOrdersPrefix() {
         try {
             return systemDictDataBiz.queryByCode(Constants.OSS, Constants.RESOURCE_PATH).getCode()
@@ -1576,9 +1589,9 @@
         }
 
         // 璁$畻钖叕锛堝垎锛�
-        long driverFee = new BigDecimal(totalAmount).multiply(driverRata).longValue();
-        long depositShopFee = new BigDecimal(totalAmount).multiply(depositShopRata).longValue();
-        long takeShopFee = new BigDecimal(totalAmount).multiply(takeShopRata).longValue();
+        long driverFee = new BigDecimal(totalAmount).multiply(driverRata).setScale(0, RoundingMode.HALF_UP).longValue();
+        long depositShopFee = new BigDecimal(totalAmount).multiply(depositShopRata).setScale(0, RoundingMode.HALF_UP).longValue();
+        long takeShopFee = new BigDecimal(totalAmount).multiply(takeShopRata).setScale(0, RoundingMode.HALF_UP).longValue();
 
         orders.setDriverFee(driverFee);
         orders.setDepositShopFee(depositShopFee);
@@ -2834,7 +2847,8 @@
 
         // 5. 鍞よ捣寰俊鏀粯V3
         return wxPayV3(otherOrders.getOutTradeNo(), otherOrders.getPayAccount(), otherOrders.getId(),
-                member.getOpenid(), Constants.OrdersAttach.OVERDUE_FEE);
+                member.getOpenid(), Constants.equalsInteger(order.getType(), Constants.ONE)
+                        ? Constants.OrdersAttach.DELIVERY_OVERDUE_FEE : Constants.OrdersAttach.OVERDUE_FEE);
     }
 
     @Override
@@ -3385,6 +3399,7 @@
                     originalOrder.setFinishTime(now);
                     originalOrder.setUpdateTime(now);
                     ordersMapper.updateById(originalOrder);
+                    clearVerifyCodes(originalOrder.getId());
                     // 瑙﹀彂鍘熻鍗曟敹鐩婅绠�
                     calculateAndSaveOrderFees(originalOrder.getId());
                     generateRevenueRecords(originalOrder.getId());
@@ -3428,7 +3443,7 @@
             order.setFinishTime(now);
             order.setInvoiceStatus(Constants.ONE);
             ordersMapper.updateById(order);
-            // 灏卞湴瀵勫瓨(type=0)鍙栦欢鏃跺浘鐗囦笉蹇呭~锛屽叾浠栫被鍨嬪彇浠跺繀濉�
+            clearVerifyCodes(order.getId());
             if (!Constants.equalsInteger(order.getType(), Constants.ZERO)) {
                 if (images == null || images.isEmpty()) {
                     throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇蜂笂浼犲彇浠跺浘鐗�");
@@ -3597,6 +3612,7 @@
             order.setInvoiceStatus(Constants.ONE);
             order.setConfirmArriveTime(now);
             ordersMapper.updateById(order);
+            clearVerifyCodes(order.getId());
             // 璁㈠崟瀹屾垚锛岄噴鏀炬牳閿�鐮�
             releaseVerifyCode(verifyCode);
             // 淇濆瓨鍑哄簱鍥剧墖锛坥bj_type=13 闂ㄥ簵鍑哄簱鍥剧墖锛屾渶澶�3寮狅級
@@ -3675,6 +3691,7 @@
         order.setFinishTime(now);
         order.setUpdateTime(now);
         ordersMapper.updateById(order);
+        clearVerifyCodes(order.getId());
 
         // 8. 閲婃斁鏍搁攢鐮�
         if (StringUtils.isNotBlank(order.getMemberVerifyCode())) {
@@ -3773,6 +3790,7 @@
         order.setFinishTime(now);
         order.setUpdateTime(now);
         ordersMapper.updateById(order);
+        clearVerifyCodes(order.getId());
 
         // 7. 鐢熸垚鏀剁泭璁板綍
         calculateAndSaveOrderFees(orderId);
@@ -4895,6 +4913,7 @@
                 order.setFinishTime(now);
                 order.setUpdateTime(now);
                 ordersMapper.updateById(order);
+                clearVerifyCodes(order.getId());
 
                 // 閲婃斁鏍搁攢鐮�
                 if (StringUtils.isNotBlank(order.getMemberVerifyCode())) {
@@ -5476,4 +5495,106 @@
         return vo;
     }
 
+    @Override
+    public List<OrderTimelineVO> getOrderTimeline(Integer orderId) {
+        Orders order = ordersMapper.selectById(orderId);
+        if (order == null || Constants.equalsInteger(order.getDeleted(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        List<OrderTimelineVO> timeline = new ArrayList<>();
+        String imgPrefix = getOrdersPrefix();
+
+        // 闂ㄥ簵/鍙告満鍚嶇О
+        String depositShopName = "";
+        if (order.getDepositShopId() != null) {
+            ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId());
+            if (depositShop != null) {
+                depositShopName = depositShop.getName();
+            }
+        }
+        String takeShopName = "";
+        if (order.getTakeShopId() != null) {
+            ShopInfo takeShop = shopInfoMapper.selectById(order.getTakeShopId());
+            if (takeShop != null) {
+                takeShopName = takeShop.getName();
+            }
+        }
+        String driverName = "";
+        if (order.getAcceptDriver() != null) {
+            DriverInfo driver = driverInfoMapper.selectById(order.getAcceptDriver());
+            if (driver != null) {
+                driverName = driver.getName();
+            }
+        }
+
+        boolean isLocal = Constants.equalsInteger(order.getType(), Constants.ZERO);
+        boolean hasTakeShop = order.getTakeShopId() != null;
+        boolean isException = Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE);
+        int status = order.getStatus() != null ? order.getStatus() : 0;
+
+        // 1. 闂ㄥ簵瀵勫瓨 (status >= 2)
+        if (status >= Constants.OrderStatus.deposited.getKey() && order.getDepositTime() != null) {
+            OrderTimelineVO node = new OrderTimelineVO();
+            node.setTitle("闂ㄥ簵銆�" + depositShopName + "銆戠‘璁ゆ敹浠�");
+            node.setTime(order.getDepositTime());
+            node.setImages(getFileUrls(orderId, Constants.FileType.ORDER_DEPOSIT.getKey(), imgPrefix));
+            timeline.add(node);
+        }
+
+        if (!isLocal) {
+            // 2. 鍙告満鍙栦欢 (status >= 4)
+            if (status >= Constants.OrderStatus.delivering.getKey() && order.getDriverTakeTime() != null) {
+                OrderTimelineVO node = new OrderTimelineVO();
+                node.setTitle("鍙告満銆�" + driverName + "銆戠‘璁ゅ彇浠�");
+                node.setTime(order.getDriverTakeTime());
+                node.setImages(getFileUrls(orderId, Constants.FileType.DRIVER_TAKE.getKey(), imgPrefix));
+                timeline.add(node);
+            }
+
+            if (isException) {
+                // 寮傚父锛氬叧鑱旀煡璇㈠紓甯歌鍗�
+                Orders exceptionOrder = ordersMapper.selectOne(new QueryWrapper<Orders>().lambda()
+                        .eq(Orders::getRelationOrderId, orderId)
+                        .eq(Orders::getExceptionStatus, Constants.ONE)
+                        .last("limit 1"));
+                if (exceptionOrder != null) {
+                    OrderTimelineVO node = new OrderTimelineVO();
+                    node.setTitle("琛屾潕宸插紓甯歌浆瀛橈紝鏂拌鍗曞彿銆�" + exceptionOrder.getCode() + "銆�");
+                    node.setTime(exceptionOrder.getCreateTime());
+                    timeline.add(node);
+                }
+            } else {
+                // 3. 姝e父锛氬徃鏈洪�佽揪 (status >= 5)
+                if(StringUtils.isBlank(takeShopName)){
+                    if (status >= Constants.OrderStatus.arrived.getKey() && order.getArriveTime() != null) {
+                        OrderTimelineVO node = new OrderTimelineVO();
+                        node.setTitle("鍙告満銆�" + driverName + "銆戠‘璁ら�佽揪");
+                        node.setTime(order.getArriveTime());
+                        node.setImages(getFileUrls(orderId, Constants.FileType.DRIVER_DONE.getKey(), imgPrefix));
+                        timeline.add(node);
+                    }
+                }
+                // 4. 鏈夐棬搴楋細闂ㄥ簵鏀朵欢 (status >= 5)
+                if (hasTakeShop && status >= Constants.OrderStatus.arrived.getKey() && order.getArriveTime() != null) {
+                    OrderTimelineVO node = new OrderTimelineVO();
+                    node.setTitle("闂ㄥ簵銆�" + takeShopName + "銆戠‘璁ゆ敹浠�");
+                    node.setTime(order.getArriveTime());
+                    node.setImages(getFileUrls(orderId, Constants.FileType.ORDER_TAKE.getKey(), imgPrefix));
+                    timeline.add(node);
+                }
+            }
+        }
+
+        // 鏈�鍚庯細璁㈠崟瀹屾垚 (status = 7)
+        if (status == Constants.OrderStatus.finished.getKey() && order.getFinishTime() != null) {
+            OrderTimelineVO node = new OrderTimelineVO();
+            node.setTitle("璁㈠崟宸插畬鎴�");
+            node.setTime(order.getFinishTime());
+            timeline.add(node);
+        }
+
+        timeline.sort((a, b) -> b.getTime() != null && a.getTime() != null ? b.getTime().compareTo(a.getTime()) : 0);
+        return timeline;
+    }
+
 }
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/PricingRuleServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/PricingRuleServiceImpl.java
index da48d1e..c4189f6 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/PricingRuleServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/PricingRuleServiceImpl.java
@@ -228,7 +228,8 @@
         Category categoryQuery = new Category();
         categoryQuery.setType(Constants.FOUR);
         categoryQuery.setDeleted(Constants.ZERO);
-        List<Category> allCategories = categoryMapper.selectList(new QueryWrapper<>(categoryQuery));
+        List<Category> allCategories = categoryMapper.selectList(new QueryWrapper<>(categoryQuery)
+                .lambda().orderByAsc(Category::getSortnum));
         Map<Integer, String> categoryNameMap = allCategories.stream()
                 .collect(Collectors.toMap(Category::getId, Category::getName));
 
@@ -309,7 +310,8 @@
         Category categoryQuery = new Category();
         categoryQuery.setType(Constants.FOUR);
         categoryQuery.setDeleted(Constants.ZERO);
-        List<Category> allCategories = categoryMapper.selectList(new QueryWrapper<>(categoryQuery));
+        List<Category> allCategories = categoryMapper.selectList(new QueryWrapper<>(categoryQuery)
+                .lambda().orderByAsc(Category::getSortnum));
         Map<Integer, String> categoryNameMap = allCategories.stream()
                 .collect(Collectors.toMap(Category::getId, Category::getName));
 
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/ShopInfoServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/ShopInfoServiceImpl.java
index 089b6fd..4fe7cda 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/ShopInfoServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/ShopInfoServiceImpl.java
@@ -1358,7 +1358,7 @@
         List<String> tagNames = new ArrayList<>();
         for (String tagId : locationTagIds.split(",")) {
             Category tag = categoryMapper.selectById(Integer.valueOf(tagId.trim()));
-            if (tag != null) {
+            if (tag != null && tag.getDeleted() == Constants.ZERO && tag.getStatus() == Constants.ZERO ) {
                 tagNames.add(tag.getName());
             }
         }
diff --git a/server/web/src/main/java/com/doumee/api/web/OrdersApi.java b/server/web/src/main/java/com/doumee/api/web/OrdersApi.java
index b8d3cc0..69e89ab 100644
--- a/server/web/src/main/java/com/doumee/api/web/OrdersApi.java
+++ b/server/web/src/main/java/com/doumee/api/web/OrdersApi.java
@@ -2,6 +2,7 @@
 
 import com.doumee.core.annotation.LoginRequired;
 import com.doumee.core.annotation.LoginShopRequired;
+import com.doumee.core.annotation.LoginDriverRequired;
 import com.doumee.core.annotation.trace.Trace;
 import com.doumee.core.constants.Constants;
 import com.doumee.core.model.ApiResponse;
@@ -216,4 +217,34 @@
         return ApiResponse.success("纭鏀惰揣鎴愬姛");
     }
 
+    @LoginRequired
+    @ApiOperation(value = "浼氬憳鏌ヨ璁㈠崟鏃堕棿杞�")
+    @GetMapping("/timeline/{orderId}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true)
+    })
+    public ApiResponse timelineForMember(@PathVariable Integer orderId) {
+        return ApiResponse.success(ordersService.getOrderTimeline(orderId));
+    }
+
+    @LoginShopRequired
+    @ApiOperation(value = "闂ㄥ簵鏌ヨ璁㈠崟鏃堕棿杞�")
+    @GetMapping("/shop/timeline/{orderId}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true)
+    })
+    public ApiResponse timelineForShop(@PathVariable Integer orderId) {
+        return ApiResponse.success(ordersService.getOrderTimeline(orderId));
+    }
+
+    @LoginDriverRequired
+    @ApiOperation(value = "鍙告満鏌ヨ璁㈠崟鏃堕棿杞�")
+    @GetMapping("/driver/timeline/{orderId}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true)
+    })
+    public ApiResponse timelineForDriver(@PathVariable Integer orderId) {
+        return ApiResponse.success(ordersService.getOrderTimeline(orderId));
+    }
+
 }
diff --git a/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java b/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java
index e0b60ed..668c27b 100644
--- a/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java
+++ b/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java
@@ -81,7 +81,8 @@
 
             if (Constants.SUCCESS.equals(result.getReturnCode())) {
                 switch (result.getAttach()) {
-                    case "storageOrder": {
+                    case "storageOrder":
+                    case "deliveryOrder": {
                         ordersService.handleStorageOrderPayNotify(outTradeNo, paymentNo);
                         break;
                     }
@@ -89,7 +90,8 @@
                         ordersService.handleShopDepositPayNotify(outTradeNo, paymentNo);
                         break;
                     }
-                    case "overdueFee": {
+                    case "overdueFee":
+                    case "deliveryOverdueFee": {
                         ordersService.handleOverdueFeePayNotify(outTradeNo, paymentNo);
                         break;
                     }
@@ -130,12 +132,14 @@
                 if (StringUtils.isNotBlank(attach)) {
                     switch (attach) {
                         case "storageOrder":
+                        case "deliveryOrder":
                             ordersService.handleStorageOrderPayNotify(outTradeNo, paymentNo);
                             break;
                         case "shopDeposit":
                             ordersService.handleShopDepositPayNotify(outTradeNo, paymentNo);
                             break;
                         case "overdueFee":
+                        case "deliveryOverdueFee":
                             ordersService.handleOverdueFeePayNotify(outTradeNo, paymentNo);
                             break;
                     }

--
Gitblit v1.9.3