Pārlūkot izejas kodu

feat(admin): 订单管理新增「按用户筛选」,支持昵称/手机号/用户ID

- AdminProductOrderController /admin/product/order/list 新增 buyerKeyword 参数
- ProductOrderService.adminOrderPage 按 buyerKeyword 查 users(nickname/phone/id)
  匹配 → product_orders.buyer_id IN (...) 过滤;无匹配返回空页
- OrderManage.vue 筛选栏新增「按用户筛选」输入框,随查询提交
- 与原有「搜索商品/订单号」keyword 互不干扰

验证: mvn compile EXIT=0;cfc-web npm run build EXIT=0。
Xiaogang Liao 1 nedēļu atpakaļ
vecāks
revīzija
2d8487a974

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminProductOrderController.java

@@ -31,6 +31,7 @@ public class AdminProductOrderController {
                                             @RequestAttribute(value = "roles", required = false) java.util.List<String> roleList) {
         String status = (String) params.get("status");
         String keyword = (String) params.get("keyword");
+        String buyerKeyword = (String) params.get("buyerKeyword");
         String startDate = (String) params.get("startDate");
         String endDate = (String) params.get("endDate");
         Integer page = params.get("page") != null ? ((Number) params.get("page")).intValue() : 1;
@@ -41,7 +42,7 @@ public class AdminProductOrderController {
                 : null;
         // B-5 行级隔离:纯供应商登录时仅能看到自己的订单
         Long supplierUserId = com.etotem.cfc.common.AdminRoles.isSupplierOnly(roleList) ? userId : null;
-        return orderService.adminOrderPage(page, size, status, keyword, startDate, endDate, sortSpecs, supplierUserId);
+        return orderService.adminOrderPage(page, size, status, keyword, buyerKeyword, startDate, endDate, sortSpecs, supplierUserId);
     }
 
     @Operation(summary = "订单详情")

+ 20 - 2
cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java

@@ -1840,13 +1840,13 @@ public class ProductOrderService {
     }
 
     public Result<Map<String, Object>> adminOrderPage(int page, int size, String status, String keyword, String startDate, String endDate, List<Map<String, String>> sortSpecs) {
-        return adminOrderPage(page, size, status, keyword, startDate, endDate, sortSpecs, null);
+        return adminOrderPage(page, size, status, keyword, null, startDate, endDate, sortSpecs, null);
     }
 
     /**
      * 管理端订单分页(B-5:supplierUserId 非空时按供应商行级隔离——自己名下 supplier_id 或自己商品产生的订单)
      */
-    public Result<Map<String, Object>> adminOrderPage(int page, int size, String status, String keyword, String startDate, String endDate, List<Map<String, String>> sortSpecs, Long supplierUserId) {
+    public Result<Map<String, Object>> adminOrderPage(int page, int size, String status, String keyword, String buyerKeyword, String startDate, String endDate, List<Map<String, String>> sortSpecs, Long supplierUserId) {
         Page<ProductOrder> pageParam = new Page<>(page, size);
         LambdaQueryWrapper<ProductOrder> wrapper = new LambdaQueryWrapper<ProductOrder>()
             .orderByDesc(ProductOrder::getCreatedAt);
@@ -1861,6 +1861,24 @@ public class ProductOrderService {
             String kw = keyword.trim();
             wrapper.and(w -> w.like(ProductOrder::getProductName, kw).or().like(ProductOrder::getOrderNo, kw));
         }
+        // 按用户筛选:匹配购买人昵称/手机号(纯数字再按用户ID),过滤 buyer_id
+        if (buyerKeyword != null && !buyerKeyword.trim().isEmpty()) {
+            String bkw = buyerKeyword.trim();
+            LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<User>()
+                    .like(User::getNickname, bkw)
+                    .or().like(User::getPhone, bkw);
+            if (bkw.matches("\\d+")) {
+                userWrapper.or().eq(User::getId, Long.valueOf(bkw));
+            }
+            List<User> matchedUsers = userMapper.selectList(userWrapper);
+            if (matchedUsers.isEmpty()) {
+                // 无匹配用户:强制空结果,避免 buyer_id IN () 语法错误
+                wrapper.in(ProductOrder::getBuyerId, -1L);
+            } else {
+                List<Long> buyerIds = matchedUsers.stream().map(User::getId).collect(Collectors.toList());
+                wrapper.in(ProductOrder::getBuyerId, buyerIds);
+            }
+        }
         if (startDate != null && !startDate.isEmpty()) {
             try {
                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

+ 5 - 0
cfc-web/src/views/admin/OrderManage.vue

@@ -3,6 +3,7 @@
     <PageHeader title="订单管理">
       <div class="filters filter-bar">
         <el-input v-model="keyword" placeholder="搜索商品/订单号..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" class="w-220" />
+        <el-input v-model="buyerKeyword" placeholder="按用户筛选(昵称/手机号/用户ID)" prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" class="w-220" />
         <el-date-picker
           v-model="dateRange"
           type="daterange"
@@ -222,6 +223,7 @@ export default {
 
       statusFilter: '',
       keyword: '',
+      buyerKeyword: '',
       dateRange: null,
       detailDialogVisible: false,
       detail: null,
@@ -253,6 +255,9 @@ export default {
         if (this.keyword) {
           params.keyword = this.keyword
         }
+        if (this.buyerKeyword) {
+          params.buyerKeyword = this.buyerKeyword
+        }
         if (this.dateRange && this.dateRange.length === 2) {
           params.startDate = this.dateRange[0]
           params.endDate = this.dateRange[1]