Przeglądaj źródła

fix: 修复4个后台列表页点击排序失效,清理2个页面的死SortMixin代码

问题:SortInterceptor 从URL query读取sort,但前端统一在body发送,
导致 AdminRecipe、AdminCoupon、AdminAssessmentOrder、AdminTask、
AdminSubscription 五个接口排序不生效。

后端修复(5个文件):
- AdminRecipeController / AdminCouponController / AdminSubscriptionController:
  从@RequestBody读sortSpecs,调用SortUtil.applySort(wrapper, sortSpecs, null)
- AdminRecipeController / RecipeService:新增listByMealType(mealType, sortSpecs)重载,
  原无参方法保留供MealRecommendService调用
- AdminController.getTasks() / getAssessmentOrderList():同模式替换SortUtil.applySort(wrapper)
- CouponService:新增listAll(sortSpecs)重载,使用QueryWrapper+SortUtil

前端修复(2个文件):
- AssessmentOrders.vue / SubscriptionManagement.vue:
  移除死SortMixin(无排序触发逻辑),清理sort-header/sort-tag CSS
Sisyphus 2 tygodni temu
rodzic
commit
51a6790cf2

+ 10 - 2
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java

@@ -287,7 +287,11 @@ public class AdminController {
             wrapper.eq(Task::getFamilyId, familyId);
         }
         wrapper.orderByDesc(Task::getCreatedAt);
-        SortUtil.applySort(wrapper);
+        @SuppressWarnings("unchecked")
+        List<Map<String, String>> taskSortSpecs = params.get("sort") != null
+                ? (List<Map<String, String>>) params.get("sort")
+                : null;
+        SortUtil.applySort(wrapper, taskSortSpecs, null);
         Page<Task> result = taskMapper.selectPage(pageParam, wrapper);
 
         // 为每条任务填充执行者名称
@@ -1565,7 +1569,11 @@ public class AdminController {
         }
         wrapper.orderByDesc(AssessmentAppointment::getCreatedAt);
 
-        SortUtil.applySort(wrapper);
+        @SuppressWarnings("unchecked")
+        List<Map<String, String>> sortSpecs = params.get("sort") != null
+                ? (List<Map<String, String>>) params.get("sort")
+                : null;
+        SortUtil.applySort(wrapper, sortSpecs, null);
         Page<AssessmentAppointment> result = assessmentAppointmentMapper.selectPage(pageParam, wrapper);
 
         java.util.List<Map<String, Object>> list = new java.util.ArrayList<>();

+ 7 - 2
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminCouponController.java

@@ -45,11 +45,16 @@ public class AdminCouponController {
     private FamilyCouponMapper familyCouponMapper;
 
     @PostMapping("/list")
-    public Result<List<Coupon>> list(@RequestAttribute("role") String role) {
+    public Result<List<Coupon>> list(@RequestBody(required = false) Map<String, Object> params,
+                                     @RequestAttribute("role") String role) {
         if (!"admin".equals(role)) {
             return Result.error("无权限");
         }
-        return Result.success(couponService.listAll());
+        @SuppressWarnings("unchecked")
+        List<Map<String, String>> sortSpecs = params != null && params.get("sort") != null
+                ? (List<Map<String, String>>) params.get("sort")
+                : null;
+        return Result.success(couponService.listAll(sortSpecs));
     }
 
     @PostMapping("/create")

+ 5 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminRecipeController.java

@@ -24,7 +24,11 @@ public class AdminRecipeController {
     @PostMapping("/list")
     public Result<List<Recipe>> list(@RequestBody Map<String, Object> params) {
         String mealType = (String) params.get("mealType");
-        return Result.success(recipeService.listByMealType(mealType));
+        @SuppressWarnings("unchecked")
+        List<Map<String, String>> sortSpecs = params.get("sort") != null
+                ? (List<Map<String, String>>) params.get("sort")
+                : null;
+        return Result.success(recipeService.listByMealType(mealType, sortSpecs));
     }
 
     @Operation(summary = "\u65b0\u589e\u98df\u8c31")

+ 5 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminSubscriptionController.java

@@ -40,7 +40,11 @@ public class AdminSubscriptionController {
         }
         wrapper.orderByDesc(MemberSubscription::getCreatedAt);
 
-        SortUtil.applySort(wrapper);
+        @SuppressWarnings("unchecked")
+        List<Map<String, String>> sortSpecs = params.get("sort") != null
+                ? (List<Map<String, String>>) params.get("sort")
+                : null;
+        SortUtil.applySort(wrapper, sortSpecs, null);
         List<MemberSubscription> subs = subscriptionMapper.selectList(wrapper);
         List<Map<String, Object>> list = new ArrayList<>();
         for (MemberSubscription sub : subs) {

+ 11 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/CouponService.java

@@ -1,6 +1,7 @@
 package com.etotem.cfc.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.etotem.cfc.entity.Coupon;
 import com.etotem.cfc.entity.FamilyCoupon;
 import com.etotem.cfc.entity.FamilyCouponGrantLog;
@@ -21,6 +22,7 @@ import java.util.List;
 import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import com.etotem.cfc.util.SortUtil;
 
 @Service
 public class CouponService {
@@ -227,6 +229,15 @@ public class CouponService {
         return couponMapper.selectList(null);
     }
 
+    public List<Coupon> listAll(List<Map<String, String>> sortSpecs) {
+        if (sortSpecs == null || sortSpecs.isEmpty()) {
+            return listAll();
+        }
+        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
+        SortUtil.applySort(wrapper, sortSpecs, null);
+        return couponMapper.selectList(wrapper);
+    }
+
     public Coupon getById(Long couponId) {
         return couponMapper.selectById(couponId);
     }

+ 12 - 5
cfc-backend/src/main/java/com/etotem/cfc/service/RecipeService.java

@@ -6,8 +6,11 @@ import com.etotem.cfc.mapper.RecipeMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import com.etotem.cfc.util.SortUtil;
+
 import javax.annotation.Resource;
 import java.util.List;
+import java.util.Map;
 
 @Slf4j
 @Service
@@ -17,11 +20,15 @@ public class RecipeService {
     private RecipeMapper recipeMapper;
 
     public List<Recipe> listByMealType(String mealType) {
-        return recipeMapper.selectList(
-                new LambdaQueryWrapper<Recipe>()
-                        .eq(Recipe::getStatus, "active")
-                        .eq(mealType != null, Recipe::getMealType, mealType)
-        );
+        return listByMealType(mealType, null);
+    }
+
+    public List<Recipe> listByMealType(String mealType, List<Map<String, String>> sortSpecs) {
+        LambdaQueryWrapper<Recipe> wrapper = new LambdaQueryWrapper<Recipe>()
+                .eq(Recipe::getStatus, "active")
+                .eq(mealType != null, Recipe::getMealType, mealType);
+        SortUtil.applySort(wrapper, sortSpecs, null);
+        return recipeMapper.selectList(wrapper);
     }
 
     public Recipe getById(Long id) {

+ 1 - 26
cfc-web/src/views/admin/AssessmentOrders.vue

@@ -21,16 +21,6 @@
             <el-option label="已取消" :value="3" />
             <el-option label="未到" :value="4" />
           </el-select>
-          <el-tag
-                v-if="sortState.length > 0"
-                closable
-                size="mini"
-                class="sort-tag"
-                @close="clearSort"
-                @click="clearSort"
-              >
-                {{ sortLabel }}
-              </el-tag>
           <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
         </div>
       </div>
@@ -134,11 +124,9 @@
 </template>
 
 <script>
-import SortMixin from '@/mixins/SortMixin'
 import { getAssessmentOrderList, changeAssessmentGuide, getAvailableGuides } from '@/api/admin'
 
 export default {
-  mixins: [SortMixin],
   name: 'AssessmentOrders',
   computed: {
     tableHeight() {
@@ -268,18 +256,5 @@ export default {
   text-align: right;
 }
 
-.sort-header {
-  cursor: pointer;
-  user-select: none;
-  font-weight: 500;
-  font-size: 12px;
-}
-.sort-header:hover {
-  color: #409eff;
-}
-.sort-tag {
-  margin-left: 8px;
-  cursor: pointer;
-  white-space: nowrap;
-}
+
 </style>

+ 1 - 16
cfc-web/src/views/admin/SubscriptionManagement.vue

@@ -170,11 +170,9 @@
 </template>
 
 <script>
-import SortMixin from '@/mixins/SortMixin'
 import { getSubscriptionList, activateSubscription, cancelSubscriptionAdmin } from '@/api/admin'
 
 export default {
-  mixins: [SortMixin],
   name: 'SubscriptionManagement',
   computed: {
     tableHeight() {
@@ -348,18 +346,5 @@ export default {
   align-items: center;
 }
 
-.sort-header {
-  cursor: pointer;
-  user-select: none;
-  font-weight: 500;
-  font-size: 12px;
-}
-.sort-header:hover {
-  color: #409eff;
-}
-.sort-tag {
-  margin-left: 8px;
-  cursor: pointer;
-  white-space: nowrap;
-}
+
 </style>