From c9f0611f690b3fb0cb120f5b6799f94977d3f129 Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期一, 20 四月 2026 11:34:23 +0800
Subject: [PATCH] 代码生成

---
 server/services/src/main/java/com/doumee/service/business/DriverInfoService.java          |    9 
 server/services/src/main/java/com/doumee/dao/dto/DriverGrabOrderDTO.java                  |   27 ++
 server/services/src/main/java/com/doumee/dao/vo/DriverOrderDetailVO.java                  |   89 ++++++++
 server/services/src/main/java/com/doumee/service/business/impl/DriverInfoServiceImpl.java |   87 ++++++++
 server/services/src/main/java/com/doumee/dao/vo/DriverGrabOrderVO.java                    |   71 +++++++
 server/services/src/main/resources/application-dev.yml                                    |   25 +
 server/web/src/main/java/com/doumee/api/web/ConfigApi.java                                |   11 +
 server/web/src/main/java/com/doumee/api/web/DriverInfoApi.java                            |   16 +
 server/services/src/main/java/com/doumee/dao/dto/DriverActiveOrderDTO.java                |   22 ++
 server/web/src/main/java/com/doumee/api/web/OrdersApi.java                                |   11 +
 server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java                   |   39 +++
 server/services/src/main/java/com/doumee/dao/vo/PriceCalculateVO.java                     |    6 
 server/services/src/main/resources/application-pro.yml                                    |   44 +---
 server/services/db/db_change.sql                                                          |    6 
 server/services/src/main/java/com/doumee/dao/business/model/Orders.java                   |    3 
 server/services/src/main/java/com/doumee/service/business/OrdersService.java              |    9 
 server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java     |   65 ++++++
 server/services/src/main/java/com/doumee/config/alipay/AlipayFundTransUniTransfer.java    |   11 -
 18 files changed, 501 insertions(+), 50 deletions(-)

diff --git a/server/services/db/db_change.sql b/server/services/db/db_change.sql
index 378ef3a..2afd4ab 100644
--- a/server/services/db/db_change.sql
+++ b/server/services/db/db_change.sql
@@ -5,6 +5,12 @@
 
 
 -- ============================================================
+-- 2026/04/20 璁㈠崟琛ㄥ鍔犵墿鍝佺骇鍒瓧娈�
+-- ============================================================
+ALTER TABLE `orders` ADD COLUMN `GOOD_LEVEL` INT DEFAULT NULL COMMENT '鐗╁搧绾у埆锛坈ategory涓婚敭锛宼ype=3锛�' AFTER `GOOD_TYPE`;
+
+
+-- ============================================================
 -- 2026/04/17 璁㈠崟棰勮閫佽揪鏃堕棿瀛楁
 -- ============================================================
 ALTER TABLE `orders` ADD COLUMN `ESTIMATED_DELIVERY_TIME` DATETIME DEFAULT NULL COMMENT '棰勮閫佽揪鏃堕棿' AFTER `CODE`;
diff --git a/server/services/src/main/java/com/doumee/config/alipay/AlipayFundTransUniTransfer.java b/server/services/src/main/java/com/doumee/config/alipay/AlipayFundTransUniTransfer.java
index def1a64..e495576 100644
--- a/server/services/src/main/java/com/doumee/config/alipay/AlipayFundTransUniTransfer.java
+++ b/server/services/src/main/java/com/doumee/config/alipay/AlipayFundTransUniTransfer.java
@@ -17,39 +17,29 @@
         ApiClient defaultClient = Configuration.getDefaultApiClient();
         // 鍒濆鍖朼lipay鍙傛暟锛堝叏灞�璁剧疆涓�娆★級
         defaultClient.setAlipayConfig(getAlipayConfig());
-
         // 鏋勯�犺姹傚弬鏁颁互璋冪敤鎺ュ彛
         AlipayFundTransUniApi api = new AlipayFundTransUniApi();
         AlipayFundTransUniTransferModel data = new AlipayFundTransUniTransferModel();
-
         // 璁剧疆鍟嗗渚у敮涓�璁㈠崟鍙�
         data.setOutBizNo("202606300001");
-
         // 璁剧疆璁㈠崟鎬婚噾棰�
         data.setTransAmount("1");
-
         // 璁剧疆鎻忚堪鐗瑰畾鐨勪笟鍔″満鏅�
         data.setBizScene("DIRECT_TRANSFER");
-
         // 璁剧疆涓氬姟浜у搧鐮�
         data.setProductCode("TRANS_ACCOUNT_NO_PWD");
-
         // 璁剧疆杞处涓氬姟鐨勬爣棰�
         data.setOrderTitle("201905浠e彂");
-
         // 璁剧疆鍘熸敮浠樺疂涓氬姟鍗曞彿
         data.setOriginalOrderId("20190620110075000006640000063056");
-
         // 璁剧疆鏀舵鏂逛俊鎭�
         Participant payeeInfo = new Participant();
         payeeInfo.setIdentity("15345690849");
         payeeInfo.setName("姹熻悕");
         payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
         data.setPayeeInfo(payeeInfo);
-
         // 璁剧疆涓氬姟澶囨敞
         data.setRemark("201905浠e彂");
-
         // 璁剧疆杞处鍦烘櫙鍚嶇О
         data.setTransferSceneName("浣i噾鎶ラ叕");
 
@@ -74,7 +64,6 @@
         signData.setOriCharSet("UTF-8");
         data.setSignData(signData);
 */
-
         try {
             AlipayFundTransUniTransferResponseModel response = api.transfer(data);
         } catch (ApiException e) {
diff --git a/server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java b/server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java
index 5c86de7..e4c45ba 100644
--- a/server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java
+++ b/server/services/src/main/java/com/doumee/config/wx/WxPayProperties.java
@@ -46,4 +46,43 @@
      */
     private String keyPath;
 
+
+
+    /**
+     * apiV3Key
+     */
+    private String apiV3Key;
+
+
+
+    /**
+     * 鍟嗘埛璇佷功搴忓垪鍙�
+     */
+    private String serialNumer;
+
+    /**
+     * 閫�娆惧洖璋�
+     */
+    private String refundNotifyUrl;
+
+    /**
+     * 鍟嗘埛鏀粯鍏挜
+     */
+    private String pubKeyPath;
+
+
+    /**
+     * 鏀粯绉橀挜
+     */
+    private String privateCertPath;
+
+
+
+    /**
+     * 鏀粯key
+     */
+    private String privateKeyPath;
+
+
+
 }
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 31f80a1..ab1ac3d 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
@@ -191,6 +191,9 @@
     @ExcelColumn(name = "鍟嗗搧绫诲瀷")
     private Integer goodType;
 
+    @ApiModelProperty(value = "鐗╁搧绾у埆锛坈ategory涓婚敭锛宼ype=3锛�")
+    private Integer goodLevel;
+
     @ApiModelProperty(value = "琛ュ厖淇℃伅")
     @ExcelColumn(name = "琛ュ厖淇℃伅")
     private String supplement;
diff --git a/server/services/src/main/java/com/doumee/dao/dto/DriverActiveOrderDTO.java b/server/services/src/main/java/com/doumee/dao/dto/DriverActiveOrderDTO.java
new file mode 100644
index 0000000..4b6bbe9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/dto/DriverActiveOrderDTO.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 鍙告満杩涜涓鍗曟煡璇㈣姹�
+ * @author rk
+ * @date 2026/04/17
+ */
+@Data
+@ApiModel("鍙告満杩涜涓鍗曟煡璇㈣姹�")
+public class DriverActiveOrderDTO {
+
+    @NotNull(message = "璁㈠崟鐘舵�佷笉鑳戒负绌�")
+    @ApiModelProperty(value = "璁㈠崟鐘舵�侊細3=宸叉姠鍗曪紱4=娲鹃�佷腑", example = "3", required = true)
+    private Integer status;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/dto/DriverGrabOrderDTO.java b/server/services/src/main/java/com/doumee/dao/dto/DriverGrabOrderDTO.java
new file mode 100644
index 0000000..36081b7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/dto/DriverGrabOrderDTO.java
@@ -0,0 +1,27 @@
+package com.doumee.dao.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 鍙告満鎶㈠崟澶у巺鏌ヨ璇锋眰
+ * @author rk
+ * @date 2026/04/17
+ */
+@Data
+@ApiModel("鍙告満鎶㈠崟澶у巺鏌ヨ璇锋眰")
+public class DriverGrabOrderDTO implements Serializable {
+
+    @ApiModelProperty(value = "鎺掑簭绫诲瀷锛�1=缁煎悎鎺掑簭锛堝垱寤烘椂闂村�掑簭锛夛紱2=璺濈鏈�杩戯紙璺濆瓨浠堕棬搴楄窛绂诲崌搴忥級", example = "1")
+    private Integer sortType;
+
+    @ApiModelProperty(value = "鐗╁搧绛夌骇ID锛坈ategory type=3锛夛紝绛涢�夎绛夌骇涓嬬殑鎵�鏈夌墿鍝佸垎绫�", example = "5")
+    private Integer gradeId;
+
+    @ApiModelProperty(value = "璺濈绛涢�夛紙鍗曚綅锛氱背锛夛紝鍙告満鍒板瓨浠堕棬搴楃殑鏈�澶ц窛绂�", example = "5000")
+    private Integer distance;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/vo/DriverGrabOrderVO.java b/server/services/src/main/java/com/doumee/dao/vo/DriverGrabOrderVO.java
new file mode 100644
index 0000000..926cb22
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/vo/DriverGrabOrderVO.java
@@ -0,0 +1,71 @@
+package com.doumee.dao.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 鍙告満鎶㈠崟澶у巺鍒楄〃椤�
+ * @author rk
+ * @date 2026/04/17
+ */
+@Data
+@ApiModel("鍙告満鎶㈠崟澶у巺鍒楄〃椤�")
+public class DriverGrabOrderVO implements Serializable {
+
+    @ApiModelProperty(value = "璁㈠崟涓婚敭")
+    private Integer id;
+
+    @ApiModelProperty(value = "璁㈠崟缂栧彿")
+    private String code;
+
+    @ApiModelProperty(value = "鍓╀綑鍒嗛挓鏁帮紙褰撳墠鏃堕棿鍒伴璁¢�佽揪鏃堕棿锛�")
+    private Long remainMinutes;
+
+    @ApiModelProperty(value = "鏄惁鍔犳�ワ細0=鍚︼紱1=鏄�")
+    private Integer isUrgent;
+
+    @ApiModelProperty(value = "瀛樹欢闂ㄥ簵鍚嶇О")
+    private String depositShopName;
+
+    @ApiModelProperty(value = "瀛樹欢闂ㄥ簵鍦板潃")
+    private String depositShopAddress;
+
+    @ApiModelProperty(value = "璺濆瓨浠堕棬搴楄窛绂伙紙濡� 500m銆�1.2km锛�")
+    private String depositDistance;
+
+    @ApiModelProperty(value = "鍙栦欢鍚嶇О锛堥棬搴楀悕绉版垨鑷畾涔夊湴鐐癸級")
+    private String takeName;
+
+    @ApiModelProperty(value = "鍙栦欢璺濈锛堝 500m銆�1.2km锛�")
+    private String takeDistance;
+
+    @ApiModelProperty(value = "鑱旂郴鐢佃瘽锛坰tatus=2鍙栦欢闂ㄥ簵鐢佃瘽锛泂tatus=3/4鏈夊彇浠堕棬搴楄繑鍥為棬搴楃數璇濓紝鏃犲垯杩斿洖鍙栦欢浜虹數璇濓級")
+    private String contactPhone;
+
+    @ApiModelProperty(value = "鍙告満钖叕锛堝垎锛�")
+    private Long driverFee;
+
+    @ApiModelProperty(value = "鍔犳�ヨ垂鐢紙鍒嗭級")
+    private Long urgentAmount;
+
+    @ApiModelProperty(value = "鐗╁搧鏄庣粏鍒楄〃")
+    private List<OrderItem> items;
+
+    @ApiModelProperty(value = "鏄惁璐甸噸鐗╁搧")
+    private Boolean isValuable;
+
+    @Data
+    @ApiModel("鎶㈠崟澶у巺鐗╁搧椤�")
+    public static class OrderItem implements Serializable {
+        @ApiModelProperty(value = "鐗╁搧鍚嶇О")
+        private String name;
+
+        @ApiModelProperty(value = "鏁伴噺")
+        private Integer quantity;
+    }
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/vo/DriverOrderDetailVO.java b/server/services/src/main/java/com/doumee/dao/vo/DriverOrderDetailVO.java
new file mode 100644
index 0000000..9506d34
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/vo/DriverOrderDetailVO.java
@@ -0,0 +1,89 @@
+package com.doumee.dao.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 鍙告満绔鍗曡鎯�
+ * @author rk
+ * @date 2026/04/17
+ */
+@Data
+@ApiModel("鍙告満绔鍗曡鎯�")
+public class DriverOrderDetailVO implements Serializable {
+
+    @ApiModelProperty(value = "璁㈠崟涓婚敭")
+    private Integer id;
+
+    @ApiModelProperty(value = "璁㈠崟缂栧彿")
+    private String code;
+
+    @ApiModelProperty(value = "璁㈠崟鐘舵��")
+    private Integer status;
+
+    @ApiModelProperty(value = "璁㈠崟鐘舵�佹弿杩�")
+    private String statusDesc;
+
+    @ApiModelProperty(value = "鍓╀綑鍒嗛挓鏁帮紙褰撳墠鏃堕棿鍒伴璁¢�佽揪鏃堕棿锛�")
+    private Long remainMinutes;
+
+    @ApiModelProperty(value = "鏄惁鍔犳�ワ細0=鍚︼紱1=鏄�")
+    private Integer isUrgent;
+
+    @ApiModelProperty(value = "瀛樹欢闂ㄥ簵鍚嶇О")
+    private String depositShopName;
+
+    @ApiModelProperty(value = "瀛樹欢闂ㄥ簵鍦板潃")
+    private String depositShopAddress;
+
+    @ApiModelProperty(value = "璺濆瓨浠堕棬搴楄窛绂伙紙濡� 500m銆�1.2km锛�")
+    private String depositDistance;
+
+    @ApiModelProperty(value = "鍙栦欢鍚嶇О锛堥棬搴楀悕绉版垨鑷畾涔夊湴鐐癸級")
+    private String takeName;
+
+    @ApiModelProperty(value = "鍙栦欢璺濈锛堝 500m銆�1.2km锛�")
+    private String takeDistance;
+
+    @ApiModelProperty(value = "鑱旂郴鐢佃瘽")
+    private String contactPhone;
+
+    @ApiModelProperty(value = "鍙告満钖叕锛堝垎锛�")
+    private Long driverFee;
+
+    @ApiModelProperty(value = "鍔犳�ヨ垂鐢紙鍒嗭級")
+    private Long urgentAmount;
+
+    @ApiModelProperty(value = "鐗╁搧鏄庣粏鍒楄〃")
+    private List<OrderItem> items;
+
+    @ApiModelProperty(value = "鏄惁璐甸噸鐗╁搧")
+    private Boolean isValuable;
+
+    @ApiModelProperty(value = "瀵艰埅绾害锛坰tatus=2瀛樹欢闂ㄥ簵绾害锛宻tatus=3/4鍙栦欢绾害锛�")
+    private Double navigateLat;
+
+    @ApiModelProperty(value = "瀵艰埅缁忓害锛坰tatus=2瀛樹欢闂ㄥ簵缁忓害锛宻tatus=3/4鍙栦欢缁忓害锛�")
+    private Double navigateLng;
+
+    @ApiModelProperty(value = "瀹㈡埛淇℃伅锛屽锛氬垬鍏堢敓锛堟墜鏈哄熬鍙�1234锛�")
+    private String customerInfo;
+
+    @ApiModelProperty(value = "涓嬪崟闄勪欢鍥剧墖鍏ㄨ矾寰勫垪琛�")
+    private List<String> orderImages;
+
+    @Data
+    @ApiModel("鐗╁搧椤�")
+    public static class OrderItem implements Serializable {
+        @ApiModelProperty(value = "鐗╁搧鍚嶇О")
+        private String name;
+
+        @ApiModelProperty(value = "鏁伴噺")
+        private Integer quantity;
+    }
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/vo/PriceCalculateVO.java b/server/services/src/main/java/com/doumee/dao/vo/PriceCalculateVO.java
index a42b9f2..dee37e7 100644
--- a/server/services/src/main/java/com/doumee/dao/vo/PriceCalculateVO.java
+++ b/server/services/src/main/java/com/doumee/dao/vo/PriceCalculateVO.java
@@ -35,6 +35,12 @@
     @ApiModelProperty("璺濈(km)")
     private BigDecimal distance;
 
+    @ApiModelProperty("鏍囬�熻揪棰勮鏃堕暱(灏忔椂锛屼笂鍙栨暣)")
+    private Integer standardHours;
+
+    @ApiModelProperty("鏋侀�熻揪棰勮鏃堕暱(灏忔椂锛屼笂鍙栨暣)")
+    private Integer urgentHours;
+
     @ApiModelProperty("澶╂暟")
     private Integer days;
 }
diff --git a/server/services/src/main/java/com/doumee/service/business/DriverInfoService.java b/server/services/src/main/java/com/doumee/service/business/DriverInfoService.java
index 24182d3..3c7f772 100644
--- a/server/services/src/main/java/com/doumee/service/business/DriverInfoService.java
+++ b/server/services/src/main/java/com/doumee/service/business/DriverInfoService.java
@@ -215,4 +215,13 @@
      */
     com.doumee.dao.vo.DriverOrderDetailVO driverOrderDetail(Integer driverId, Integer orderId);
 
+    /**
+     * 鍙告満鍙栨秷璁㈠崟锛堝凡鎺ュ崟status=2鏃跺彇娑堬紝閲婃斁鍥炴姠鍗曞ぇ鍘咃級
+     *
+     * @param driverId 鍙告満涓婚敭
+     * @param orderId  璁㈠崟涓婚敭
+     * @param reason   鍙栨秷鍘熷洜
+     */
+    void cancelOrder(Integer driverId, Integer orderId, String reason);
+
 }
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 0a1da27..91ecdf9 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
@@ -299,6 +299,15 @@
     void confirmStoreOut(Integer orderId, Integer shopId, List<String> images, String remark);
 
     /**
+     * 浼氬憳纭鏀惰揣
+     * 寮傚湴瀵勫瓨涓旀棤鍙栦欢闂ㄥ簵鐨勮鍗曪紝閫佽揪鍚�(status=5)锛屼細鍛樼‘璁ゆ敹璐ф爣璁拌鍗曞畬鎴�
+     *
+     * @param orderId  璁㈠崟涓婚敭
+     * @param memberId 褰撳墠鐧诲綍浼氬憳ID
+     */
+    void memberConfirmReceipt(Integer orderId, Integer memberId);
+
+    /**
      * 璁$畻骞舵洿鏂拌鍗曚笁鏂规敹鐩婏紙瀛樹欢闂ㄥ簵/鍙栦欢闂ㄥ簵/鍙告満锛�
      * 灏卞湴瀵勫瓨锛氫粎瀛樹欢闂ㄥ簵鏀剁泭
      * 寮傚湴瀵勫瓨锛氬瓨浠堕棬搴� + 鍙告満鏀剁泭锛涙湁鍙栦欢闂ㄥ簵鏃跺姞涓婂彇浠堕棬搴楁敹鐩�
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 5c292e9..8110145 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
@@ -21,8 +21,11 @@
 import com.doumee.dao.business.OrdersDetailMapper;
 import com.doumee.dao.business.RevenueMapper;
 import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.biz.system.OperationConfigBiz;
+import com.doumee.dao.business.OrderLogMapper;
 import com.doumee.dao.business.model.Category;
 import com.doumee.dao.business.model.DriverInfo;
+import com.doumee.dao.business.model.OrderLog;
 import com.doumee.dao.business.model.Member;
 import com.doumee.dao.business.model.Multifile;
 import com.doumee.dao.business.model.Smsrecord;
@@ -98,6 +101,12 @@
 
     @Autowired
     private SystemDictDataBiz systemDictDataBiz;
+
+    @Autowired
+    private OrderLogMapper orderLogMapper;
+
+    @Autowired
+    private OperationConfigBiz operationConfigBiz;
 
     @Override
     public Integer create(DriverInfo driverInfo) {
@@ -660,6 +669,9 @@
         if (driver == null) {
             throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鍙告満淇℃伅涓嶅瓨鍦�");
         }
+        if (!Constants.THREE.equals(driver.getAuditStatus())) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "璇峰厛瀹屾垚鎶奸噾鏀粯");
+        }
         driverInfoMapper.update(new UpdateWrapper<DriverInfo>().lambda()
                 .set(DriverInfo::getAcceptingStatus, status)
                 .eq(DriverInfo::getId, driver.getId()));
@@ -763,6 +775,10 @@
         if (driver == null || driver.getLatitude() == null || driver.getLongitude() == null) {
             throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鍙告満浣嶇疆淇℃伅缂哄け锛岃鍏堝紑鍚畾浣�");
         }
+        // 鏍¢獙鍙告満宸叉敮浠樻娂閲�
+        if (!Constants.THREE.equals(driver.getAuditStatus())) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "璇峰厛瀹屾垚鎶奸噾鏀粯");
+        }
         double driverLat = driver.getLatitude();
         double driverLng = driver.getLongitude();
 
@@ -807,6 +823,11 @@
         wrapper.eq(Orders::getType, Constants.ONE)
                 .eq(Orders::getStatus, Constants.TWO)
                 .eq(Orders::getDeleted, Constants.ZERO);
+
+        // 鍙告満绾у埆 >= 璁㈠崟鐗╁搧绾у埆
+        if (driver.getDriverLevel() != null) {
+            wrapper.apply("t.GOOD_LEVEL <= {0}", driver.getDriverLevel());
+        }
 
         // 鍔犳�� OR 鍦ㄩ厤閫佽寖鍥村唴
         wrapper.and(w -> w
@@ -1046,6 +1067,72 @@
         return vo;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void cancelOrder(Integer driverId, Integer orderId, String reason) {
+        // 1. 鏌ヨ鍙告満淇℃伅
+        DriverInfo driver = driverInfoMapper.selectById(driverId);
+        if (driver == null) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鍙告満淇℃伅涓嶅瓨鍦�");
+        }
+
+        // 2. 鏍¢獙璁㈠崟
+        Orders order = ordersMapper.selectById(orderId);
+        if (order == null || Constants.ONE.equals(order.getDeleted())) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "璁㈠崟涓嶅瓨鍦�");
+        }
+        if (!Constants.ONE.equals(order.getType())) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呭紓鍦板瘎瀛樿鍗曞彲鍙栨秷");
+        }
+        if (!Constants.TWO.equals(order.getStatus())) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽鍙栨秷");
+        }
+        if (!driverId.equals(order.getAcceptDriver())) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+        }
+
+        // 3. 姣忔棩鍙栨秷娆℃暟闄愬埗
+        String limitStr = operationConfigBiz.getConfig().getDriverDailyCancelLimit();
+        int limit = 3;
+        if (StringUtils.isNotBlank(limitStr)) {
+            try { limit = Integer.parseInt(limitStr); } catch (NumberFormatException ignored) {}
+        }
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        Date todayStart = cal.getTime();
+        Long todayCancelCount = orderLogMapper.selectCount(new QueryWrapper<OrderLog>().lambda()
+                .eq(OrderLog::getOptUserId, driver.getMemberId())
+                .eq(OrderLog::getObjType, Constants.ORDER_LOG_CANCEL)
+                .eq(OrderLog::getOptUserType, Constants.ONE)
+                .ge(OrderLog::getCreateTime, todayStart));
+        if (todayCancelCount != null && todayCancelCount >= limit) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "浠婃棩鍙栨秷娆℃暟宸茶揪涓婇檺");
+        }
+
+        // 4. 閲嶇疆璁㈠崟鍙告満瀛楁锛堜繚鎸乻tatus=2锛岄噴鏀惧洖鎶㈠崟澶у巺锛�
+        ordersMapper.update(new UpdateWrapper<Orders>().lambda()
+                .set(Orders::getAcceptDriver, null)
+                .set(Orders::getAcceptTime, null)
+                .set(Orders::getAcceptType, null)
+                .eq(Orders::getId, orderId));
+
+        // 5. 鍐欏叆鍙栨秷鏃ュ織
+        OrderLog log = new OrderLog();
+        log.setOrderId(orderId);
+        log.setTitle("鍙告満鍙栨秷璁㈠崟");
+        log.setLogInfo(StringUtils.isNotBlank(reason) ? reason : "鍙告満鍙栨秷鎺ュ崟");
+        log.setObjType(Constants.ORDER_LOG_CANCEL);
+        log.setOptUserId(driver.getMemberId());
+        log.setOptUserType(Constants.ONE);
+        log.setOrderStatus(order.getStatus());
+        log.setCreateTime(new Date());
+        log.setDeleted(Constants.ZERO);
+        orderLogMapper.insert(log);
+    }
+
     private List<String> getFileUrls(Integer orderId, int objType, String prefix) {
         List<Multifile> files = multifileMapper.selectList(
                 new QueryWrapper<Multifile>().lambda()
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 3e2c1ce..8fa0b27 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
@@ -536,6 +536,33 @@
         result.setUrgentFee(urgentFeeFen);
         result.setTotalPrice(totalPrice);
         result.setDistance(distanceKm);
+
+        // 7. 棰勮閫佽揪鏃堕暱锛歱ricing_rule type=2锛坒ieldA=1鏍囬�熻揪锛宖ieldA=2鏋侀�熻揪锛�
+        List<PricingRule> timeRules = pricingRuleMapper.selectList(new QueryWrapper<PricingRule>().lambda()
+                .eq(PricingRule::getDeleted, Constants.ZERO)
+                .eq(PricingRule::getType, Constants.TWO)
+                .eq(PricingRule::getCityId, dto.getCityId())
+                .in(PricingRule::getFieldA, Arrays.asList("1", "2")));
+        for (PricingRule tr : timeRules) {
+            BigDecimal baseKm = new BigDecimal(tr.getFieldB());
+            int baseHours = Integer.parseInt(tr.getFieldC());
+            BigDecimal extraKm = new BigDecimal(tr.getFieldD());
+            int extraHours = Integer.parseInt(tr.getFieldE());
+            int hours;
+            if (distanceKm.compareTo(baseKm) <= 0) {
+                hours = baseHours;
+            } else {
+                BigDecimal overDistance = distanceKm.subtract(baseKm);
+                int extraCount = overDistance.divide(extraKm, 0, RoundingMode.CEILING).intValue();
+                hours = baseHours + extraCount * extraHours;
+            }
+            if ("1".equals(tr.getFieldA())) {
+                result.setStandardHours(hours);
+            } else if ("2".equals(tr.getFieldA())) {
+                result.setUrgentHours(hours);
+            }
+        }
+
         return result;
     }
 
@@ -742,6 +769,7 @@
 
         // 鐗╁搧淇℃伅
         orders.setGoodType(dto.getGoodType());
+        orders.setGoodLevel(goodTypeCategory.getRelationId());
         // 鎷兼帴鐗╁搧淇℃伅锛氱墿鍝佺被鍨嬪悕绉般�佸昂瀵稿悕绉�*鏁伴噺锛堟暟缁勫瓧绗︿覆锛�
         List<String> goodsParts = new ArrayList<>();
         for (ItemPriceVO itemVO : priceResult.getItemList()) {
@@ -2339,6 +2367,43 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void memberConfirmReceipt(Integer orderId, Integer memberId) {
+        // 1. 鏌ヨ璁㈠崟
+        Orders order = ordersMapper.selectById(orderId);
+        if (order == null || Constants.equalsInteger(order.getDeleted(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "璁㈠崟涓嶅瓨鍦�");
+        }
+        // 2. 鏍¢獙褰掑睘
+        if (!memberId.equals(order.getMemberId())) {
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鏃犳潈鎿嶄綔璇ヨ鍗�");
+        }
+        // 3. 鏍¢獙璁㈠崟绫诲瀷锛氬紓鍦板瘎瀛�
+        if (!Constants.ONE.equals(order.getType())) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "浠呭紓鍦板瘎瀛樿鍗曞彲鎿嶄綔");
+        }
+        // 4. 鏍¢獙鏃犲彇浠堕棬搴�
+        if (order.getTakeShopId() != null) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "璇ヨ鍗曟湁鍙栦欢闂ㄥ簵锛岄渶闂ㄥ簵纭鍑哄簱");
+        }
+        // 5. 鏍¢獙鐘舵�侊細宸查�佽揪(5)
+        if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.arrived.getStatus())) {
+            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "褰撳墠璁㈠崟鐘舵�佷笉鍏佽纭鏀惰揣");
+        }
+
+        // 6. 鏇存柊璁㈠崟鐘舵�佷负宸插畬鎴�
+        Date now = new Date();
+        order.setStatus(Constants.OrderStatus.finished.getStatus());
+        order.setFinishTime(now);
+        order.setUpdateTime(now);
+        ordersMapper.updateById(order);
+
+        // 7. 鐢熸垚鏀剁泭璁板綍
+        calculateAndSaveOrderFees(orderId);
+        generateRevenueRecords(orderId);
+    }
+
+    @Override
     public void calculateAndSaveOrderFees(Integer orderId) {
         Orders order = ordersMapper.selectById(orderId);
         if (order == null || Constants.equalsInteger(order.getDeleted(), Constants.ONE)) {
diff --git a/server/services/src/main/resources/application-dev.yml b/server/services/src/main/resources/application-dev.yml
index b7583bb..fa3d1ce 100644
--- a/server/services/src/main/resources/application-dev.yml
+++ b/server/services/src/main/resources/application-dev.yml
@@ -83,12 +83,25 @@
 ########################寰俊鏀粯鐩稿叧閰嶇疆########################
 wx:
   pay:
-    appId: wxcd2b89fd2ff065f8
-    appSecret: 3462fa186da7cb06c544df8d8664b63a
-    mchId: 1229817002
-    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
-    notifyUrl: http://xiaopiqiu2.natapp1.cc/web/api/wxPayNotify
-    keyPath: D:\DouMee\dmkjWxcert\apiclient_cert.p12
+#    appId: wxcd2b89fd2ff065f8
+#    appSecret: 3462fa186da7cb06c544df8d8664b63a
+#    mchId: 1229817002
+#    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
+#    notifyUrl: http://xiaopiqiu2.natapp1.cc/web/api/wxPayNotify
+#    keyPath: D:\DouMee\dmkjWxcert\apiclient_cert.p12
+    appId: wxb1b59320e803dc6c
+    appSecret: eb93785c7bca3f0ff0364b0e26bfeb59
+    mchId: 1229817002    #鍟嗘埛鍙�
+    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM #鍟嗘埛绉橀挜
+    apiV3Key: 7tG4Vk9Zp2L8dXw5Jq0N3hR6yE1sF3cB #apiV3Key
+    serialNumer: 3FE90C2F3D40A56E1C51926F31B8A8D22426CCE0 #鍟嗘埛璇佷功搴忓垪鍙�
+    notifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxPayNotify
+    refundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxRefundNotify
+    keyPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.p12
+    privateCertPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.pem
+    privateKeyPath: D:\DouMee\1229817002_20220310_cert\apiclient_key.pem
+    pubKeyPath: D:\DouMee\1229817002_20220310_cert\pub_key.pem #鍟嗘埛鏀粯鍏挜
+
 #    appId: wx6264b4f3a697cbe8
 #    appSecret: 23734577e8978138c946b727f0394027
 #    mchId: 1629568742
diff --git a/server/services/src/main/resources/application-pro.yml b/server/services/src/main/resources/application-pro.yml
index bb5fcb0..d47e4ed 100644
--- a/server/services/src/main/resources/application-pro.yml
+++ b/server/services/src/main/resources/application-pro.yml
@@ -52,39 +52,19 @@
 ########################寰俊鏀粯鐩稿叧閰嶇疆########################
 wx:
   pay:
-    #鏈嶅姟鍟�---------start------- 鍙傛暟璇﹁В鍦板潃 https://pay.weixin.qq.com/doc/v3/partner/4013080340
-    mchId: 1700071922    #鏈嶅姟鍟嗗湪寰俊鏀粯渚х殑鍞竴韬唤鏍囪瘑
-    appId: wx6cc1087ca79db7f6    #鏈嶅姟鍟嗗湪寰俊寮�鏀惧钩鍙帮紙绉诲姩搴旂敤锛夋垨鍏紬骞冲彴锛堝叕浼楀彿/灏忕▼搴忥級涓婄敵璇风殑涓�涓敮涓�鏍囪瘑
-    apiV3Key: 0a056faa107c2b2944b9d6a9aa6d4142 #7tG4Vk9Zp2L8dXw5Jq0N3hR6yE1sF3cB
-    serialNumer: 6696086F6EFB8D6A4F821BD47DDBAF75C3BC1209 #38495CE0137D90E4DC4F64F7ECDE035A35470BE3 #鏈嶅姟鍟嗚瘉涔﹀簭鍒楀彿
-    payPublicKeyId: PUB_KEY_ID_0117000719222024112700219100000508 #鍟嗘埛/骞冲彴鏀粯鍏挜id
-    #mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S
-    notifyUrl: https://jinkuai.832smartfarm.com/jinkuai_admin/web/wxPayNotify
-    refundNotifyUrl: https://jinkuai.832smartfarm.com/jinkuai_admin/web/wxRefundNotify
-    keyPath: /usr/local/jars/payFile/apiclient_cert.p12
-    privateCertPath: /usr/local/jars/payFile/apiclient_cert.pem
-    privateKeyPath: /usr/local/jars/payFile/apiclient_key.pem
-    pubKeyPath: /usr/local/jars/payFile/pub_key.pem #鍟嗘埛鏀粯鍏挜
+    appId: wxb1b59320e803dc6c
+    appSecret: eb93785c7bca3f0ff0364b0e26bfeb59
+    mchId: 1229817002    #鍟嗘埛鍙�
+    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM #鍟嗘埛绉橀挜
+    apiV3Key: 7tG4Vk9Zp2L8dXw5Jq0N3hR6yE1sF3cB #apiV3Key
+    serialNumer: 3FE90C2F3D40A56E1C51926F31B8A8D22426CCE0 #鍟嗘埛璇佷功搴忓垪鍙�
+    notifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxPayNotify
+    refundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxRefundNotify
+    keyPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.p12
+    privateCertPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.pem
+    privateKeyPath: D:\DouMee\1229817002_20220310_cert\apiclient_key.pem
+    pubKeyPath: D:\DouMee\1229817002_20220310_cert\pub_key.pem #鍟嗘埛鏀粯鍏挜
 
-    #鏈嶅姟鍟�-------------end---
-
-    #鍟嗘埛淇℃伅
-    wechatSerialNumer: 12C0F0DD0F3D2B565B45586D3FEA225EBF723BEC
-    wechatPayPublicKeyId: PUB_KEY_ID_0117233260692025072500181939000603 #鍟嗘埛/骞冲彴鏀粯鍏挜id
-    wechatPubKeyPath: /usr/local/jars/payFile/shanghu/pub_key.pem #鍟嗘埛鏀粯鍏挜
-    wechatPrivateKeyPath: /usr/local/jars/payFile/shanghu/apiclient_key.pem #鍟嗘埛绉侀挜
-    wechatNotifyUrl: https://jinkuai.832smartfarm.com/jinkuai_admin/web/wechat/transferNotify #鍟嗘埛杞处鍥炶皟鍦板潃
-    wechatApiV3Key: 7tG4Vk9Zp2L8dXw5Jq0N3hR6yE1sF3cB
-
-
-    existsSub: 1
-    appSecret:
-    #瀛愬晢鎴�------------start----
-    subMchId: 1723326069    #瀛愬晢鎴峰彿
-    subAppId: wx332441ae5b12be7d #灏忕▼搴廼d
-    subAppSecret: add86d6406f5c14501ac5bbb1a60e004 #灏忕▼搴忕閽�
-    #瀛愬晢鎴�------------end----
-    #      mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
     typeId: jinkuai
 
 alipay:
diff --git a/server/web/src/main/java/com/doumee/api/web/ConfigApi.java b/server/web/src/main/java/com/doumee/api/web/ConfigApi.java
index af1e457..bc17bac 100644
--- a/server/web/src/main/java/com/doumee/api/web/ConfigApi.java
+++ b/server/web/src/main/java/com/doumee/api/web/ConfigApi.java
@@ -7,6 +7,7 @@
 import com.doumee.dao.business.model.Areas;
 import com.doumee.dao.business.model.Banner;
 import com.doumee.dao.business.model.Category;
+import com.doumee.dao.dto.AreasDto;
 import com.doumee.dao.dto.CalculateLocalPriceDTO;
 import com.doumee.dao.dto.CalculateRemotePriceDTO;
 import com.doumee.dao.dto.SameCityCheckDTO;
@@ -18,6 +19,7 @@
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -53,6 +55,15 @@
     @Autowired
     private MemberService memberService;
 
+    @ApiOperation("鍏ㄩ儴鍖哄垝鏍戝舰鏌ヨ")
+    @PostMapping("/treeList")
+    public ApiResponse<List<Areas>> treeList (@RequestBody AreasDto pageWrap) {
+        Areas a = new Areas();
+        BeanUtils.copyProperties(pageWrap,a);
+        areasService.cacheData();
+        return ApiResponse.success(areasService.findList(a));
+    }
+
     @ApiOperation(value = "鑾峰彇鍒嗙被鍒楄〃", notes = "灏忕▼搴忕")
     @GetMapping("/getCategoryList")
     @ApiImplicitParams({
diff --git a/server/web/src/main/java/com/doumee/api/web/DriverInfoApi.java b/server/web/src/main/java/com/doumee/api/web/DriverInfoApi.java
index f7794ea..2dc0bc4 100644
--- a/server/web/src/main/java/com/doumee/api/web/DriverInfoApi.java
+++ b/server/web/src/main/java/com/doumee/api/web/DriverInfoApi.java
@@ -6,6 +6,7 @@
 import com.doumee.core.model.ApiResponse;
 import com.doumee.core.model.PageData;
 import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.DriverInfo;
 import com.doumee.dao.dto.DriverActiveOrderDTO;
 import com.doumee.dao.dto.DriverGrabOrderDTO;
 import com.doumee.dao.dto.DriverLoginRequest;
@@ -86,7 +87,7 @@
     @ApiImplicitParams({
             @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true)
     })
-    public ApiResponse verifyDetail() {
+    public ApiResponse<DriverInfo> verifyDetail() {
         return ApiResponse.success(driverInfoService.getVerifyDetail(this.getDriverId()));
     }
 
@@ -162,4 +163,17 @@
         return ApiResponse.success("鎿嶄綔鎴愬姛", driverInfoService.driverOrderDetail(this.getDriverId(), orderId));
     }
 
+    @LoginDriverRequired
+    @Trace
+    @ApiOperation(value = "鍙告満鍙栨秷璁㈠崟", notes = "宸叉帴鍗�(status=2)鏃跺彇娑堬紝閲婃斁璁㈠崟鍥炴姠鍗曞ぇ鍘�")
+    @PostMapping("/cancelOrder")
+    @ApiImplicitParams({
+            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true)
+    })
+    public ApiResponse cancelOrder(@RequestParam Integer orderId,
+                                   @RequestParam(required = false) String reason) {
+        driverInfoService.cancelOrder(this.getDriverId(), orderId, reason);
+        return ApiResponse.success("鍙栨秷鎴愬姛");
+    }
+
 }
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 5292cb9..d966ade 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
@@ -214,5 +214,16 @@
         return ApiResponse.success("璇勪环鎴愬姛");
     }
 
+    @LoginRequired
+    @ApiOperation(value = "浼氬憳纭鏀惰揣", notes = "寮傚湴瀵勫瓨涓旀棤鍙栦欢闂ㄥ簵鐨勮鍗曪紝閫佽揪鍚庣‘璁ゆ敹璐ф爣璁拌鍗曞畬鎴�")
+    @PostMapping("/confirmReceipt")
+    @ApiImplicitParams({
+            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true)
+    })
+    public ApiResponse confirmReceipt(@RequestParam Integer orderId) {
+        ordersService.memberConfirmReceipt(orderId, getMemberId());
+        return ApiResponse.success("纭鏀惰揣鎴愬姛");
+    }
+
 
 }

--
Gitblit v1.9.3