shish 1 месяц назад
Родитель
Сommit
74d3eab7ee
1 измененных файлов с 249 добавлено и 55 удалено
  1. 249 55
      ghsApp/src/pagesPurchase/supplier.vue

+ 249 - 55
ghsApp/src/pagesPurchase/supplier.vue

@@ -4,18 +4,24 @@
     <view class="search-box">
       <AppSearchModule placeholder="输入拼音首字母搜索" @input="searchFn"/>
     </view>
-    <view class="add-btn-wrap">
-			<button class="admin-button-com middle blue add-btn" @click="addGhs()">添加供货商</button>
-		</view>
+    <view class="header-btns">
+      <view class="filter-btn-wrap">
+        <button class="admin-button-com middle" @click="openFilterPanel">筛选</button>
+        <view v-if="hasActiveFilters" class="filter-dot"></view>
+      </view>
+      <view class="add-btn-wrap">
+        <button class="admin-button-com middle blue" @click="addGhs()">添加</button>
+      </view>
+    </view>
   </view>
   <view class="app-tabs" @click.stop>
-		<Tabs :isFixed="false" :tabs="tabs" :top="50" :height="100" :currentTab="tabIndex" :size="30" @change="changeTabEvent" itemWidth="25%">
+		<Tabs :isFixed="false" :tabs="tabs" :top="50" :height="100" :currentTab="tabIndex" :size="30" @change="changeTabEvent" itemWidth="33.33%">
     </Tabs>
 	</view>
   <view class="order-page">
     <view class="order_list">
       <!-- 总欠款统计 -->
-      <view class="total-debt-header" v-if="tabs[tabIndex].delStatus === 0">
+      <view class="total-debt-header" v-if="isNormalList">
         <text class="debt-title">总欠款</text>
         <text class="debt-amount">¥{{info.totalDebtAmount?parseFloat(info.totalDebtAmount):0}}</text>
       </view>
@@ -41,7 +47,7 @@
             </view>
 
             <!-- 更多操作菜单 -->
-            <view class="more-menu-wrap" v-if="tabs[tabIndex].delStatus === 0">
+            <view class="more-menu-wrap" v-if="isNormalList">
               <view class="more-trigger" hover-class="none" @click.stop="toggleMenu(item)">
                 <text class="more-dots">•••</text>
               </view>
@@ -62,7 +68,7 @@
           <!-- 第二行:核心操作按钮 -->
           <view class="item-action-row">
             <!-- 操作按钮区(正常状态) -->
-            <view class="action-buttons" v-if="tabs[tabIndex].delStatus === 0">
+            <view class="action-buttons" v-if="isNormalList">
               <view class="action-btn search-btn" hover-class="none" @click.stop="goToSearchDebt(item)">搜索</view>
               <view class="action-btn cg-btn" hover-class="none" @click="goToCg(item)">采购</view>
             </view>
@@ -73,7 +79,7 @@
           </view>
 
           <!-- 记录信息区(中部,非删除状态显示) -->
-          <view class="record-section" v-if="tabs[tabIndex].delStatus === 0">
+          <view class="record-section" v-if="isNormalList">
             <view class="record-buttons">
               <view class="record-btn" hover-class="none" @click.stop="pageTo({ url: '/admin/clear/list?ghsId='+item.id})">结账记录</view>
               <view class="record-btn" hover-class="none" @click.stop="getBalanceList(item)">余额变动明细</view>
@@ -86,7 +92,7 @@
             class="pending-order-box"
             hover-class="none"
             @click.stop="goToDebtList(item)"
-            v-if="Number(item.debtAmount)>0 && tabs[tabIndex].delStatus === 0">
+            v-if="Number(item.debtAmount)>0 && isNormalList">
             <view class="pending-order-content">
               <image class="pending-icon" referrerpolicy="no-referrer" src="/static/lanhu_020105gongyingshangliebiao/ps2pvfa1l5i34w5vqj2k7b3kejml3i3nmrba1421bf-caa2-491b-8773-af413df7e96d.png" />
               <text class="pending-text">待结订单 {{item.debtNum}} 笔 ¥{{item.debtAmount?parseFloat(item.debtAmount):0}} 查看明细 &gt;</text>
@@ -104,6 +110,46 @@
     </view>
   </view>
 
+  <view v-if="showFilterPanel" class="filter-overlay" @click="closeFilterPanel">
+    <view class="filter-panel" @click.stop>
+      <view class="filter-header">筛选供货商</view>
+      <scroll-view class="filter-body" scroll-y>
+        <view class="filter-section">
+          <view class="filter-title">地区</view>
+          <view class="filter-options">
+            <view
+              v-for="(item, index) in locationOptions"
+              :key="index"
+              class="filter-option"
+              :class="{ active: filterLocation === item.value }"
+              @click="onSelectLocation(index)"
+            >
+              {{ item.label }}
+            </view>
+          </view>
+        </view>
+        <view class="filter-section">
+          <view class="filter-title">状态</view>
+          <view class="filter-options">
+            <view
+              v-for="(item, index) in delStatusOptions"
+              :key="index"
+              class="filter-option"
+              :class="{ active: filterDelStatus === item.value }"
+              @click="onSelectDelStatus(index)"
+            >
+              {{ item.label }}
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+      <view class="filter-actions">
+        <button class="filter-action-btn clear-btn" @click="clearFilters">重置</button>
+        <button class="filter-action-btn confirm-btn" @click="confirmFilters">确定</button>
+      </view>
+    </view>
+  </view>
+
 	<modal-module :show="modifyGhsShow" @click="modifyConfirm" :maskClosable="true" title="修改名称" padding="30rpx 30rpx" >
 	<template v-slot:content>
 		<view class="app-modal-input-wrap">
@@ -141,29 +187,32 @@ export default {
 			tabs: [
 				{
 					name: "全部",
-					key: "",
-          delStatus: 0,
-					value: "0"
-				},
-				{
-					name: "上游",
-					key: "0",
-          delStatus: 0,
+					sortType: "all",
 					value: "0"
 				},
 				{
-					name: "本地",
-					key: "1",
-          delStatus: 0,
+					name: "挂账排行",
+					sortType: "debt",
 					value: "0"
 				},
 				{
-					name: "已删除",
-					key: "",
-          delStatus: 1,
+					name: "采购排行",
+					sortType: "expend",
 					value: "0"
 				}
 			],
+      showFilterPanel: false,
+      filterLocation: -1,
+      filterDelStatus: 0,
+      locationOptions: [
+        { label: '全部', value: -1 },
+        { label: '上游', value: 0 },
+        { label: '本地', value: 1 },
+      ],
+      delStatusOptions: [
+        { label: '未删除', value: 0 },
+        { label: '已删除', value: 1 },
+      ],
       info: {},
       search: '',
       activeMenuId: null,
@@ -171,6 +220,14 @@ export default {
     }
   },
   mixins: [list],
+  computed: {
+    hasActiveFilters() {
+      return this.filterLocation !== -1 || this.filterDelStatus !== 0
+    },
+    isNormalList() {
+      return this.filterDelStatus === 0
+    }
+  },
   onPullDownRefresh() {
     this.resetList()
     this.getGhsList().then(res => {
@@ -253,7 +310,44 @@ export default {
     },
     init() {
       this.getGhsList()
-      this.loadTabCounts() // 页面初始化时先加载 Tab 数量(比主列表更快出现)
+    },
+    applyTabCounts(tabCounts) {
+      if (!tabCounts) {
+        return
+      }
+      this.tabs[0].value = tabCounts.all || 0
+      this.tabs[1].value = tabCounts.debtRank || 0
+      this.tabs[2].value = tabCounts.expendRank || 0
+    },
+    openFilterPanel() {
+      this.showFilterPanel = true
+    },
+    closeFilterPanel() {
+      this.showFilterPanel = false
+    },
+    onSelectLocation(index) {
+      const item = this.locationOptions[index]
+      if (item) {
+        this.filterLocation = item.value
+      }
+    },
+    onSelectDelStatus(index) {
+      const item = this.delStatusOptions[index]
+      if (item) {
+        this.filterDelStatus = item.value
+      }
+    },
+    clearFilters() {
+      this.filterLocation = -1
+      this.filterDelStatus = 0
+      this.closeFilterPanel()
+      this.resetList()
+      this.getGhsList()
+    },
+    confirmFilters() {
+      this.closeFilterPanel()
+      this.resetList()
+      this.getGhsList()
     },
     searchFn(e) {
       let that = this
@@ -272,37 +366,23 @@ export default {
       let params = {
         name: name,
         page: this.list.page,
-        location: currentTab.key,
-        delStatus: currentTab.delStatus
+        sortType: currentTab.sortType,
+        delStatus: this.filterDelStatus
+      }
+      if (this.filterLocation !== -1) {
+        params.location = this.filterLocation
       }
       return getList(params).then(res => {
         this.info = res.data
+        if (this.list.page === 1 && res.data && res.data.tabCounts) {
+          this.applyTabCounts(res.data.tabCounts)
+        }
         this.completes(res);
-        this.loadTabCounts(); // 刷新顶部 Tab 的数量统计
         if (this.$util.isEmpty(res.data)){
           return false
         }
       })
     },
-
-    // 加载 4 个 Tab 的供货商数量(不受搜索关键词影响,始终显示全量分类统计)
-    loadTabCounts() {
-      const that = this
-      const baseParams = { page: 1, pageSize: 1, name: '' }
-      Promise.all([
-        getList({ ...baseParams, delStatus: 0 }).then(res => (res.data && res.data.totalNum) || 0), // 全部(正常)
-        getList({ ...baseParams, delStatus: 0, location: 0 }).then(res => (res.data && res.data.totalNum) || 0), // 上游
-        getList({ ...baseParams, delStatus: 0, location: 1 }).then(res => (res.data && res.data.totalNum) || 0), // 本地
-        getList({ ...baseParams, delStatus: 1 }).then(res => (res.data && res.data.totalNum) || 0), // 已删除
-      ]).then(([allCount, upstreamCount, localCount, deletedCount]) => {
-        that.tabs[0].value = allCount
-        that.tabs[1].value = upstreamCount
-        that.tabs[2].value = localCount
-        that.tabs[3].value = deletedCount
-      }).catch(() => {
-        // 统计失败不影响主流程
-      })
-    },
     toggleMenu(item) {
       this.activeMenuId = this.activeMenuId === item.id ? null : item.id;
     },
@@ -380,16 +460,31 @@ export default {
       flex: 1;
     }
     
+    .header-btns {
+      flex-shrink: 0;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      margin-left: 16upx;
+    }
+    .filter-btn-wrap {
+      position: relative;
+      display: flex;
+      align-items: center;
+    }
     .add-btn-wrap {
-      padding: 0 10upx 0 20upx;
-      
-      .add-btn {
-        height: 78upx;
-        line-height: 78upx;
-        padding: 0 24upx;
-        font-size: 32upx;
-        border-radius: 8upx;
-      }
+      display: flex;
+      align-items: center;
+      margin-left: 28upx;
+    }
+    .filter-dot {
+      position: absolute;
+      top: 6upx;
+      right: 6upx;
+      width: 14upx;
+      height: 14upx;
+      border-radius: 50%;
+      background-color: #3385ff;
     }
   }
   
@@ -765,4 +860,103 @@ view[hover-class],
 button {
   -webkit-tap-highlight-color: transparent !important;
 }
+
+.filter-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 9999999;
+  display: flex;
+  align-items: flex-start;
+  justify-content: center;
+  background-color: rgba(0, 0, 0, 0.5);
+}
+.filter-panel {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  height: 90vh;
+  max-height: 90vh;
+  overflow: hidden;
+  border-radius: 0 0 24upx 24upx;
+  background: #fff;
+}
+.filter-header {
+  flex-shrink: 0;
+  padding: 24upx 0;
+  text-align: center;
+  color: #333;
+  font-size: 32upx;
+  font-weight: 700;
+  border-bottom: 1upx solid #f0f0f0;
+}
+.filter-body {
+  flex: 1;
+  min-height: 0;
+  height: 0;
+  width: 100%;
+  box-sizing: border-box;
+}
+.filter-section {
+  padding: 30upx 40upx;
+  border-bottom: 1upx solid #f0f0f0;
+}
+.filter-title {
+  margin-bottom: 20upx;
+  color: #333;
+  font-size: 28upx;
+  font-weight: 700;
+}
+.filter-options {
+  display: flex;
+  flex-wrap: wrap;
+}
+.filter-option {
+  min-width: 120upx;
+  padding: 15upx 28upx;
+  margin-right: 18upx;
+  margin-top: 18upx;
+  border: 1upx solid #dce2e0;
+  border-radius: 28upx;
+  color: #60666d;
+  background: #fff;
+  font-size: 26upx;
+  text-align: center;
+}
+.filter-option.active {
+  color: #3385ff;
+  border-color: #3385ff;
+  background: #eef5ff;
+  font-weight: 700;
+}
+.filter-actions {
+  flex-shrink: 0;
+  display: flex;
+  padding: 30upx 40upx 40upx;
+  padding-bottom: calc(40upx + constant(safe-area-inset-bottom));
+  padding-bottom: calc(40upx + env(safe-area-inset-bottom));
+  border-top: 1upx solid #f0f0f0;
+  background: #fff;
+}
+.filter-action-btn {
+  flex: 1;
+  height: 80upx;
+  line-height: 80upx;
+  font-size: 28upx;
+  border-radius: 40upx;
+}
+.filter-action-btn::after {
+  border: none;
+}
+.clear-btn {
+  margin-right: 20upx;
+  color: #666;
+  background: #f5f7f9;
+}
+.confirm-btn {
+  color: #fff;
+  background: #3385ff;
+}
 </style>