Просмотр исходного кода

feat(shop): 商城商品列表增加按价格排序(综合/价格升/价格降)

任务号: cfc-frontend shop-price-sort (spec 2026-11-07-shop-price-sort.md)
- 模板新增排序栏(综合/价格↑/价格↓),位于 Level2 分类 chips 与商品列表之间
- data 新增 sortType:'default'
- 新增 buildSort()(price_asc/price_desc -> [{column:'price',order:'asc'|'desc'}],default -> [])
- 新增 onSortSelect()(切换排序重置 page=1/products=[]/noMore=false 并重新加载)
- loadProducts/onLoadMore 在 params 构建后追加 sort(滚动加载沿用当前排序)
- 新增 .sort-bar/.sort-item/.sort-item.active 样式(复用 \-space-*、\-violet 高亮)
- 后端 SortInterceptor 支持数组 sort,零后端改动;推荐商品逻辑不变
E2E Test Bot 5 дней назад
Родитель
Сommit
0db09f9de6
1 измененных файлов с 56 добавлено и 0 удалено
  1. 56 0
      cfc-frontend/pages/shop/index/index.vue

+ 56 - 0
cfc-frontend/pages/shop/index/index.vue

@@ -65,6 +65,22 @@
       </view>
     </scroll-view>
 
+    <!-- 排序栏:综合 / 价格↑ / 价格↓ -->
+    <view class="sort-bar">
+      <view
+        :class="['sort-item', sortType === 'default' ? 'active' : '']"
+        @click="onSortSelect('default')"
+      >综合</view>
+      <view
+        :class="['sort-item', sortType === 'price_asc' ? 'active' : '']"
+        @click="onSortSelect('price_asc')"
+      >价格↑</view>
+      <view
+        :class="['sort-item', sortType === 'price_desc' ? 'active' : '']"
+        @click="onSortSelect('price_desc')"
+      >价格↓</view>
+    </view>
+
     <!-- 商品列表 -->
     <scroll-view
       scroll-y
@@ -161,6 +177,7 @@ export default {
       categories: [],
       currentCat1: null,
       currentCat2: null,
+      sortType: 'default',
       products: [],
       page: 1,
       size: 20,
@@ -218,6 +235,19 @@ export default {
       this.noMore = false
       this.loadProducts()
     },
+    buildSort() {
+      if (this.sortType === 'price_asc') return [{ column: 'price', order: 'asc' }]
+      if (this.sortType === 'price_desc') return [{ column: 'price', order: 'desc' }]
+      return []
+    },
+    onSortSelect(type) {
+      if (type === this.sortType) return
+      this.sortType = type
+      this.page = 1
+      this.products = []
+      this.noMore = false
+      this.loadProducts()
+    },
     loadProducts() {
       if (this.loading) return
       this.loading = true
@@ -227,6 +257,8 @@ export default {
       } else if (this.currentCat1) {
         params.categoryId = this.currentCat1.id
       }
+      const sort = this.buildSort()
+      if (sort.length) params.sort = sort
       productList(params).then(res => {
         this.loading = false
         this.refreshing = false
@@ -261,6 +293,8 @@ export default {
       } else if (this.currentCat1) {
         params.categoryId = this.currentCat1.id
       }
+      const sort = this.buildSort()
+      if (sort.length) params.sort = sort
       productList(params).then(res => {
         this.loadingMore = false
         if (res.code === 200 && res.data) {
@@ -553,6 +587,28 @@ export default {
   color: $app-surface;
 }
 
+/* ==================== 排序栏 ==================== */
+.sort-bar {
+  display: flex;
+  align-items: center;
+  gap: $uni-space-lg;
+  padding: $uni-space-sm $uni-space-lg;
+  margin-bottom: $uni-space-sm;
+  background: $app-surface;
+  border-bottom: 1rpx solid $facade-hairline-2;
+}
+.sort-item {
+  display: inline-block;
+  padding: $uni-space-2xs $uni-space-xs;
+  font-size: calc(26rpx * var(--font-scale, 1));
+  color: $facade-text-body;
+  border-radius: $uni-space-xs;
+}
+.sort-item.active {
+  color: $facade-violet;
+  font-weight: 600;
+}
+
 /* ==================== 商品列表 ==================== */
 .product-list {
   flex: 1;