فهرست منبع

feat:2026-01-05功能需求开发

yingjian.wu 2 روز پیش
والد
کامیت
62c952ada3

+ 10 - 10
node_modules/uview-ui/components/u-calendar/u-calendar.vue

@@ -242,18 +242,18 @@ export default {
 		setMonth() {
 			// 最小日期的毫秒数
 			const minDate = this.innerMinDate || dayjs().valueOf()
-			// 如果没有指定最大日期,则往后推3个月
-			const maxDate =
-				this.innerMaxDate ||
-				dayjs(minDate)
+			let maxDate = this.innerMaxDate
+			let months = 0
+			if (maxDate) {
+				// 有明确的最大日期时,按最大最小日期之间的月数展示
+				months = this.getMonths(minDate, maxDate)
+			} else {
+				// 没有指定最大日期时,按monthNum展示
+				maxDate = dayjs(minDate)
 					.add(this.monthNum - 1, 'month')
 					.valueOf()
-			// 最大最小月份之间的共有多少个月份,
-			const months = uni.$u.range(
-				1,
-				this.monthNum,
-				this.getMonths(minDate, maxDate)
-			)
+				months = this.monthNum
+			}
 			// 先清空数组
 			this.months = []
 			for (let i = 0; i < months; i++) {

+ 1 - 1
node_modules/uview-ui/libs/config/props/calendar.js

@@ -37,6 +37,6 @@ export default {
         showRangePrompt: true,
         allowSameDay: false,
 		round: 0,
-		monthNum: 3
+		monthNum: 1200
     }
 }

+ 228 - 22
pages/hexiao/jxs/hexiao_record.vue

@@ -1,27 +1,6 @@
 <template>
   <view class="page-container">
     <view class="sticky-header">
-<!--      <view class="search-wrapper">-->
-<!--        <view class="query">-->
-<!--          <u-row customStyle="margin-bottom: 10px" gutter="20">-->
-<!--            <u-col span="9">-->
-<!--              <u&#45;&#45;input-->
-<!--                  @focus="timeShow = true"-->
-<!--                  v-model="startTimeXd"-->
-<!--                  placeholder="开始日期 ~ 结束日期"-->
-<!--                  prefixIcon="calendar"-->
-<!--                  prefixIconStyle="font-size: 22px;color: #909399"-->
-<!--                  @clear="handleSearch"-->
-<!--              ></u&#45;&#45;input>-->
-<!--            </u-col>-->
-<!--            <u-col span="3">-->
-<!--              <view class="query-btn" @click="clearSearch">-->
-<!--                <view class="query-btn-text">清空</view>-->
-<!--              </view>-->
-<!--            </u-col>-->
-<!--          </u-row>-->
-<!--        </view>-->
-<!--      </view>-->
       <view class="tabs-wrapper">
         <view
             v-for="tab in tabs"
@@ -34,6 +13,40 @@
         </view>
       </view>
     </view>
+    <view class="search-wrapper" v-if="currentTab === 5">
+      <view class="query">
+        <u-row customStyle="margin-bottom: 10px" gutter="20">
+          <u-col span="9">
+            <u--input
+                @focus="timeShow = true"
+                v-model="startTimeXd"
+                placeholder="开始日期 ~ 结束日期"
+                prefixIcon="calendar"
+                prefixIconStyle="font-size: 22px;color: #909399"
+                @clear="handleSearch"
+            ></u--input>
+          </u-col>
+          <u-col span="3">
+            <view class="query-btn" @click="clearSearch">
+              <view class="query-btn-text">清空</view>
+            </view>
+          </u-col>
+        </u-row>
+        <u-row customStyle="margin-bottom: 10px" gutter="20">
+          <u-col span="12">
+            <u--input
+                v-model="storeNameQuery"
+                placeholder="请输入门店名称"
+                prefixIcon="search"
+                prefixIconStyle="font-size: 22px;color: #909399"
+                @confirm="handleSearch"
+                @clear="handleSearch"
+                clearable
+            ></u--input>
+          </u-col>
+        </u-row>
+      </view>
+    </view>
     <view v-if="currentTab == 1">
       <scroll-view class="list-container" scroll-y="true" @scrolltolower="loadMore" >
         <view v-if="pendingList.length === 0 && loadStatus !== 'loading'" class="empty-list">
@@ -71,6 +84,48 @@
         <button class="add-btn" @click="verify(-1)">一键核销</button>
       </view>
     </view>
+    <view v-if="currentTab === 5" class="store-summary-container">
+      <scroll-view class="summary-list" scroll-y="true">
+        <view v-if="summaryList.length === 0" class="empty-list">
+          <text>暂无汇总数据</text>
+        </view>
+        <view v-else class="summary-table-wrapper">
+          <view class="table-header">
+            <view class="header-cell store-col">门店</view>
+            <view class="header-cell product-col">品相</view>
+            <view class="header-cell number-col">数量</view>
+          </view>
+          <view class="table-body">
+            <view class="table-row" v-for="(store, storeIndex) in summaryList" :key="storeIndex">
+              <view class="table-cell store-col">
+                <view class="store-name-cell">
+                  <uni-icons type="shop" size="16" color="#3c82f8"></uni-icons>
+                  <text class="store-name-text">{{ store.storeName }}</text>
+                </view>
+              </view>
+              <view>
+                <view class="table-row-cl2" v-for="(item, itemIndex) in store.writeOffRecordDetailVos" :key="itemIndex">
+                  <view class="table-cell product-col">
+                    <text>{{ item.item }}</text>
+                  </view>
+                  <view class="table-cell number-col">
+                    <text>{{ item.writeOffAmount }}</text>
+                  </view>
+                </view>
+                <view class="table-row-cl2">
+                  <view class="table-cell product-col">
+                    <text>汇总</text>
+                  </view>
+                  <view class="table-cell number-col">
+                    <text style="color: orange;">{{ store.summaryCount }}</text>
+                  </view>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
     <scroll-view class="list-container" scroll-y="true" @scrolltolower="loadMore" v-if="currentTab>1 && currentTab<4">
       <view v-if="recordList.length === 0 && loadStatus !== 'loading'" class="empty-list">
         <text>暂无相关记录</text>
@@ -152,7 +207,7 @@
 </template>
 
 <script>
-import {queryJxsAddRecord,doCommitToJxs,doCommitToChang, queryHexiaoRecord,queryPendingWriteOffRecord,queryWriteOffDetailByItem} from "@/api/hexiao";
+import {queryJxsAddRecord,doCommitToJxs,doCommitToChang, queryHexiaoRecord,queryPendingWriteOffRecord,queryWriteOffDetailByItem,queryStoreSummary} from "@/api/hexiao";
 
 export default {
   data() {
@@ -163,16 +218,20 @@ export default {
       startTimeXd:"",
       mode: 'range',
       searchQuery: '',
+      storeNameQuery: '',
       tabs: [
         { name: '待审核', key: 'pending',id: 1 },
         // { name: '核销中', key: 'verifying', id: 2},
         { name: '已提交', key: 'verified' , id :3},
         { name: '我的账户', key: 'zhanghu' , id :4},
+        { name: '门店汇总', key: 'storeSummary' , id :5},
       ],
       currentTab: 1,
       recordList: [],
       hexiaoList:[],
+      summaryList: [],
       pendingList:[],
+      grandTotal: 0,
       pagination: { page: 1, limit: 10 },
       loadStatus: 'more', // 'more', 'loading', 'noMore'
       isLoading: false,
@@ -182,6 +241,18 @@ export default {
     this.getReadyData(true);
   },
   onPullDownRefresh() {
+    if (this.currentTab === 1) {
+      this.getReadyData(true);
+      return;
+    }
+    if (this.currentTab === 4) {
+      this.itemByDetail();
+      return;
+    }
+    if (this.currentTab === 5) {
+      this.fetchStoreSummary(true);
+      return;
+    }
     this.fetchRecords(true);
   },
   methods: {
@@ -223,6 +294,10 @@ export default {
           this.itemByDetail();
           return;
         }
+        if (this.currentTab === 5) {
+          this.fetchStoreSummary(true);
+          return;
+        }
         this.fetchRecords(true); // 切换tab时重新加载数据
       }
     },
@@ -285,9 +360,14 @@ export default {
       this.startTime = "";
       this.endTime = "";
       this.startTimeXd = "";
+      this.storeNameQuery = "";
       this.handleSearch()
     },
     handleSearch() {
+      if (this.currentTab === 5) {
+        this.fetchStoreSummary(true);
+        return;
+      }
       this.fetchRecords(true);
     },
     verify(id) {
@@ -317,6 +397,32 @@ export default {
       queryWriteOffDetailByItem({}).then(res=>{
         this.hexiaoList = res.data;
       })
+    },
+    async fetchStoreSummary(isRefresh = false) {
+      if (this.isLoading) return;
+      this.isLoading = true;
+      try {
+        const params = {
+          startTime: this.startTime,
+          endTime: this.endTime,
+          storeName: this.storeNameQuery
+        };
+        const res = await queryStoreSummary(params);
+        if (res.code === 0) {
+          this.summaryList = res.data || [];
+          this.grandTotal = res.data.grandTotal || 0;
+        } else {
+          this.summaryList = [];
+          this.grandTotal = 0;
+          uni.showToast({ title: '获取汇总数据失败', icon: 'none' });
+        }
+      } catch (error) {
+        this.summaryList = [];
+        this.grandTotal = 0;
+      } finally {
+        this.isLoading = false;
+        uni.stopPullDownRefresh();
+      }
     }
   }
 }
@@ -482,6 +588,106 @@ export default {
   color: #F5F5F5;
 }
 
+.store-summary-container {
+  background-color: #f5f6fa;
+  overflow: auto;
+  height: 100%;
+}
+
+.summary-list {
+  height: 100%;
+}
+
+.summary-table-wrapper {
+  background-color: #ffffff;
+  border-radius: 16rpx;
+  margin: 20rpx;
+  overflow: hidden;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
+}
+
+.table-header {
+  display: flex;
+  background-color: #f8f9fa;
+  padding: 24rpx 20rpx;
+  border-bottom: 1rpx solid #e8e8e8;
+
+  .header-cell {
+    font-size: 28rpx;
+    font-weight: 600;
+    color: #333;
+    text-align: center;
+
+    &.store-col {
+      width: 220rpx;
+      flex-shrink: 0;
+    }
+
+    &.product-col {
+      flex: 1;
+    }
+
+    &.number-col {
+      width: 150rpx;
+      flex-shrink: 0;
+      text-align: center;
+    }
+  }
+}
+
+.table-body {
+  .table-row {
+    display: flex;
+    align-items: center;
+    padding: 0 20rpx;
+    min-height: 100rpx;
+    border-bottom: 1rpx solid #a5a5a5;
+
+    .table-cell {
+      font-size: 28rpx;
+      color: #333;
+      display: flex;
+      align-items: center;
+      padding: 20rpx 0;
+      min-height: 100rpx;
+      box-sizing: border-box;
+
+      &.store-col {
+        width: 220rpx;
+        flex-shrink: 0;
+
+        .store-name-cell {
+          display: flex;
+          align-items: center;
+
+          uni-icons {
+            margin-right: 10rpx;
+          }
+
+          .store-name-text {
+            font-weight: 500;
+          }
+        }
+      }
+
+      &.product-col {
+        flex: 1;
+      }
+
+      &.number-col {
+        width: 150rpx;
+        flex-shrink: 0;
+        text-align: right;
+        justify-content: flex-end;
+      }
+    }
+  }
+}
+
+.table-row-cl2{
+  display: flex;
+}
+
 .fixed-footer {
   position: fixed;
   bottom: 0;

+ 5 - 1
pages/hexiao/jxs/index.vue

@@ -35,7 +35,7 @@
       </view>
 
 
-      <view class="card stat-card mendian-card">
+      <view class="card stat-card mendian-card" @click="navigateTo('storeList')">
         <view class="stat-content">
           <view class="stat-title">门店统计</view>
           <view class="stat-value">{{ stats.storeCount }}</view>
@@ -149,6 +149,10 @@ export default {
         uni.navigateTo({ url: `/pages/hexiao/jxs/hexiao_record` });
         return;
       }
+      if("storeList" === page){
+        uni.navigateTo({ url: `/pages/hexiao/jxs/store_list` });
+        return;
+      }
       if("stockRecords" === page){
         uni.navigateTo({ url: `/pages/hexiao/ywy/add_goods_record` });
       }else if("pointsStats" === page){

+ 5 - 1
pages/hexiao/jxs/sale_detail.vue

@@ -138,7 +138,11 @@ export default {
 
       // 在这里替换成您真实的 uni.request API 调用
 
-      queryJxsSalesDetail({startTime:this.startTime,endTime:this.endTime}).then(res=>{
+      const params = { startTime: this.startTime, endTime: this.endTime };
+      if (this.retailId) {
+        params.storeId = this.retailId;
+      }
+      queryJxsSalesDetail(params).then(res=>{
         this.recordList = res.data.itemDetail;
         this.isLoading = false;
         this.totalInfo = {saleTotal:res.data.verificationTotal,activateTotal:res.data.orderTotal,qrCodeTotal:res.data.qrCodeTotal}

+ 210 - 0
pages/hexiao/jxs/store_expand_list.vue

@@ -0,0 +1,210 @@
+<template>
+  <view class="page-container">
+    <view class="search-wrapper">
+      <view class="query">
+        <u-row customStyle="margin-bottom: 10px" gutter="20">
+          <u-col span="9">
+            <u--input
+                @focus="timeShow = true"
+                v-model="startTimeXd"
+                placeholder="开始日期 ~ 结束日期"
+                prefixIcon="calendar"
+                prefixIconStyle="font-size: 22px;color: #909399"
+                @clear="handleSearch"
+            ></u--input>
+          </u-col>
+          <u-col span="3">
+            <view class="query-btn" @click="clearSearch">
+              <view class="query-btn-text">清空</view>
+            </view>
+          </u-col>
+        </u-row>
+      </view>
+    </view>
+
+    <scroll-view class="list-container" scroll-y="true">
+      <view v-if="recordList.length === 0 && !isLoading" class="empty-list">
+        <text>暂无数据</text>
+      </view>
+      <view class="data-display-container" v-else>
+        <view class="header-row">
+          <view class="header-item">日期</view>
+          <view class="header-item">数量</view>
+        </view>
+        <view class="data-body">
+          <view class="data-row" v-for="(item, index) in recordList" :key="index">
+            <view class="data-cell item-column">{{ getRowDate(item) }}</view>
+            <view class="data-cell">{{ getRowCount(item) }}</view>
+          </view>
+        </view>
+      </view>
+    </scroll-view>
+
+    <u-calendar min-date="2025-07-01" max-date="2030-07-01" @close="timeShow = false" :show="timeShow" :mode="mode" @confirm="confirm"></u-calendar>
+  </view>
+</template>
+
+<script>
+import {queryStoreExpandCount} from "@/api/hexiao";
+
+export default {
+  data() {
+    return {
+      startTime: '',
+      endTime: '',
+      timeShow: false,
+      startTimeXd:"",
+      mode: 'range',
+      isLoading: false,
+      recordList: [],
+      ywyId: 0
+    };
+  },
+  onLoad(opt) {
+    if (opt.ywyId) {
+      this.ywyId = Number(opt.ywyId);
+    }
+    this.fetchRecords();
+  },
+  methods: {
+    confirm(e) {
+      this.startTime = e[0];
+      this.endTime = e[e.length-1];
+      this.startTimeXd = e[0]+' ~ '+e[e.length-1];
+      this.timeShow = false;
+      this.handleSearch();
+    },
+    clearSearch(){
+      this.startTime = "";
+      this.endTime = "";
+      this.startTimeXd = "";
+      this.handleSearch();
+    },
+    handleSearch() {
+      this.fetchRecords();
+    },
+    fetchRecords() {
+      if (this.isLoading) {
+        return;
+      }
+      this.isLoading = true;
+      queryStoreExpandCount({
+        ywyId: this.ywyId,
+        startTime: this.startTime,
+        endTime: this.endTime
+      }).then(res=>{
+        this.recordList = res.data || [];
+        this.isLoading = false;
+      }).catch(() => {
+        this.isLoading = false;
+      });
+    },
+    getRowDate(item) {
+      return item.date || '';
+    },
+    getRowCount(item) {
+      return item.count !== undefined ? item.count : 0;
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.page-container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: #f5f6fa;
+}
+
+.search-wrapper {
+  padding: 20rpx;
+  background-color: #ffffff;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.list-container {
+  flex: 1;
+  height: 100%;
+}
+
+.empty-list {
+  text-align: center;
+  color: #999;
+  padding-top: 150rpx;
+}
+
+.query-btn {
+  background-color: #409eff;
+  color: #fff;
+  padding: 20rpx;
+  border-radius: 10rpx;
+  height: 34rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.query-btn-text {
+  font-weight: 400;
+  font-size: 30rpx;
+  color: #F5F5F5;
+}
+
+.data-display-container {
+  padding: 30rpx;
+  font-size: 28rpx;
+  color: #333;
+  min-height: 100vh;
+  box-sizing: border-box;
+}
+
+.header-row {
+  display: flex;
+  flex-direction: row;
+  background-color: #4A90E2;
+  color: #ffffff;
+  font-weight: bold;
+  padding: 24rpx 0;
+  border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
+  position: sticky;
+  top: 0;
+  z-index: 10;
+}
+
+.header-item {
+  flex: 1;
+  text-align: center;
+  padding: 0 10rpx;
+  font-size: 28rpx;
+}
+
+.data-row {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding: 20rpx 0;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.data-row:last-child {
+  border-bottom: none;
+}
+
+.data-cell {
+  flex: 1;
+  padding: 0 10rpx;
+  text-align: center;
+  font-size: 26rpx;
+  color: #555;
+  word-break: break-word;
+  line-height: 1.4;
+}
+
+.item-column {
+  text-align: left;
+  padding-left: 20rpx;
+  color: #333;
+  font-weight: 500;
+}
+</style>

+ 391 - 0
pages/hexiao/jxs/store_list.vue

@@ -0,0 +1,391 @@
+<template>
+  <view class="page-container">
+    <view class="search-wrapper">
+      <view class="search-bar">
+        <uni-icons type="search" size="20" color="#999"></uni-icons>
+        <input
+            class="search-input"
+            v-model="searchQuery"
+            placeholder="输入门店名称"
+            placeholder-class="placeholder"
+            @confirm="handleSearch"
+        />
+      </view>
+
+      <view class="filter-tabs">
+        <view
+            class="tab-item"
+            :class="{ active: auditFilter === 0 }"
+            @click="changeAuditFilter(0)"
+        >
+          <text>待审核</text>
+        </view>
+        <view
+            class="tab-item"
+            :class="{ active: auditFilter === 1 }"
+            @click="changeAuditFilter(1)"
+        >
+          <text>已审核</text>
+        </view>
+        <view
+            class="tab-item"
+            :class="{ active: auditFilter === 2 }"
+            @click="changeAuditFilter(2)"
+        >
+          <text>已驳回</text>
+        </view>
+      </view>
+    </view>
+
+    <scroll-view
+        scroll-y="true"
+        class="list-container"
+        @scrolltolower="handleScrollToLower"
+        :lower-threshold="100"
+    >
+      <view v-if="isLoading && pagination.page === 1" class="loading-wrapper">
+        <text>加载中...</text>
+      </view>
+
+      <view v-if="storeList.length === 0 && !isLoading" class="empty-list">
+        <text>没有找到相关门店</text>
+      </view>
+
+      <view v-for="store in storeList" :key="store.id" class="store-card">
+        <view v-if="store.audit_status" class="audit-tag" :class="store.audit_status">
+          <text v-if="store.audit_status === 'pending'">待审核</text>
+          <text v-if="store.audit_status === 'approved'">已审核</text>
+          <text v-if="store.audit_status === 'rejected'">已驳回</text>
+        </view>
+
+        <view class="card-decorator"></view>
+        <view class="card-content">
+          <view class="card-header">
+            <uni-icons type="shop-filled" size="20" color="#3c82f8"></uni-icons>
+            <text class="store-name">{{ store.store_name }}</text>
+          </view>
+          <view class="info-grid">
+            <view class="info-row">
+              <text class="info-label">店主名称:</text>
+              <text class="info-value">{{ store.contact_name }}</text>
+            </view>
+            <view class="info-row">
+              <text class="info-label">联系方式:</text>
+              <text class="info-value">{{ store.contact_phone }}</text>
+            </view>
+            <view class="info-row">
+              <text class="info-label">门店地址:</text>
+              <text class="info-value">{{ store.address }}</text>
+            </view>
+            <view class="info-row" v-if="store.review_status === 2">
+              <text class="info-label">驳回原因:</text>
+              <text class="info-value" style="color: red">{{ store.reject_reason }}</text>
+            </view>
+          </view>
+          <view class="action-buttons">
+            <view class="action-btn" @click="viewDetails(store.id)">
+              <uni-icons type="eye-filled" size="18" color="#3c82f8"></uni-icons>
+              <text>详情</text>
+            </view>
+            <view class="action-btn" @click="dataSummary(store.id)">
+              <uni-icons type="compose" size="18" color="#3c82f8"></uni-icons>
+              <text>数据汇总</text>
+            </view>
+          </view>
+        </view>
+      </view>
+      <view class="list-placeholder"></view>
+
+      <view v-if="isLoading && pagination.page > 1" class="load-more">
+        <text>加载更多...</text>
+      </view>
+      <view v-if="loadStatus === 'noMore' && storeList.length > 0" class="load-more">
+        <text>没有更多数据了</text>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script>
+import {getStoreList} from "@/api/hexiao";
+
+export default {
+  data() {
+    return {
+      searchQuery: '',
+      storeList: [],
+      pagination: {
+        page: 1,
+        limit: 10,
+      },
+      isLoading: false,
+      loadStatus: 'more',
+      auditFilter: 0,
+      scrollTimer: null,
+      isScrolling: false,
+    };
+  },
+  onShow(){
+    this.fetchStoreList(true);
+  },
+  onLoad() {
+    this.fetchStoreList(true);
+  },
+  methods: {
+    fetchStoreList(isRefresh = false) {
+      if (this.isLoading || (this.loadStatus === 'noMore' && !isRefresh)) {
+        return;
+      }
+      if (isRefresh) {
+        this.pagination.page = 1;
+        this.storeList = [];
+        this.loadStatus = 'more';
+      }
+
+      this.isLoading = true;
+      if (!isRefresh) {
+        this.loadStatus = 'loading';
+      }
+
+      getStoreList(this.pagination.page, this.pagination.limit, this.searchQuery, 0, this.auditFilter).then(res=>{
+        let data = res.data;
+        let list = data.records || [];
+        if (list.length > 0) {
+          this.storeList = [...this.storeList, ...list];
+          this.pagination.page++;
+          this.loadStatus = list.length < this.pagination.limit ? 'noMore' : 'more';
+        } else {
+          this.loadStatus = 'noMore';
+        }
+        this.isLoading = false;
+        this.isScrolling = false;
+      }).catch(() => {
+        this.isLoading = false;
+        this.isScrolling = false;
+      });
+    },
+    handleSearch() {
+      this.pagination.page = 1;
+      this.fetchStoreList(true);
+    },
+    changeAuditFilter(status) {
+      if (this.auditFilter !== status) {
+        this.auditFilter = status;
+        this.pagination.page = 1;
+        this.fetchStoreList(true);
+      }
+    },
+    handleScrollToLower() {
+      if (this.isScrolling || this.isLoading || this.loadStatus === 'noMore') {
+        return;
+      }
+      this.isScrolling = true;
+      if (this.scrollTimer) {
+        clearTimeout(this.scrollTimer);
+      }
+      this.scrollTimer = setTimeout(() => {
+        this.fetchStoreList(false);
+        this.scrollTimer = null;
+      }, 300);
+    },
+    viewDetails(id) {
+      uni.navigateTo({ url: '/pages/hexiao/ywy/add_retail?edit=0&id='+id });
+    },
+    dataSummary(id){
+      uni.navigateTo({ url: '/pages/hexiao/jxs/sale_detail?id='+id });
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.page-container {
+  background-color: #f5f6fa;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+}
+
+.search-wrapper {
+  padding: 20rpx;
+  background-color: #ffffff;
+  position: sticky;
+  top: 0;
+  z-index: 100;
+  flex-shrink: 0;
+}
+
+.search-bar {
+  display: flex;
+  align-items: center;
+  background-color: #f5f6fa;
+  border-radius: 50rpx;
+  padding: 0 25rpx;
+  height: 70rpx;
+}
+
+.search-input {
+  flex: 1;
+  font-size: 28rpx;
+  margin-left: 15rpx;
+}
+
+.placeholder {
+  color: #b0b0b0;
+}
+
+.filter-tabs {
+  display: flex;
+  background-color: #f5f6fa;
+  border-radius: 10rpx;
+  margin-top: 20rpx;
+  padding: 8rpx;
+  flex-shrink: 0;
+}
+
+.tab-item {
+  flex: 1;
+  text-align: center;
+  padding: 16rpx 0;
+  font-size: 26rpx;
+  color: #666;
+  border-radius: 8rpx;
+  transition: all 0.3s;
+}
+
+.tab-item.active {
+  background-color: #ffffff;
+  color: #3c82f8;
+  font-weight: bold;
+  box-shadow: 0 2rpx 8rpx rgba(60, 130, 248, 0.2);
+}
+
+.audit-tag {
+  position: absolute;
+  top: 10rpx;
+  right: 10rpx;
+  padding: 6rpx 16rpx;
+  border-radius: 20rpx;
+  font-size: 22rpx;
+  font-weight: bold;
+  z-index: 1;
+}
+
+.audit-tag.pending {
+  background-color: #fff8e1;
+  color: #ff9800;
+  border: 1rpx solid #ff9800;
+}
+
+.audit-tag.approved {
+  background-color: #e8f5e9;
+  color: #4caf50;
+  border: 1rpx solid #4caf50;
+}
+
+.audit-tag.rejected {
+  background-color: #ffebee;
+  color: #f44336;
+  border: 1rpx solid #f44336;
+}
+
+.list-container {
+  flex: 1;
+  padding: 0 20rpx;
+  box-sizing: border-box;
+  overflow: hidden;
+}
+
+.loading-wrapper {
+  text-align: center;
+  padding: 40rpx 0;
+  color: #999;
+  font-size: 28rpx;
+}
+
+.load-more {
+  text-align: center;
+  padding: 30rpx 0;
+  color: #999;
+  font-size: 26rpx;
+  border-top: 1rpx solid #f0f0f0;
+  margin-top: 20rpx;
+}
+
+.empty-list {
+  text-align: center;
+  color: #999;
+  padding-top: 100rpx;
+  font-size: 28rpx;
+}
+
+.store-card {
+  background-color: #ffffff;
+  border-radius: 16rpx;
+  margin-top: 20rpx;
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
+}
+
+.card-decorator {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  width: 8rpx;
+  background-color: #e3efff;
+}
+
+.card-content {
+  padding: 30rpx;
+  padding-left: 40rpx;
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+}
+
+.store-name {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  margin-left: 15rpx;
+}
+
+.info-grid {
+  margin-top: 20rpx;
+  font-size: 26rpx;
+  color: #666;
+}
+
+.info-row {
+  margin-top: 10rpx;
+}
+
+.action-buttons {
+  display: flex;
+  justify-content: space-around;
+  border-top: 1rpx solid #f5f5f5;
+  margin-top: 30rpx;
+  padding-top: 25rpx;
+}
+
+.action-btn {
+  display: flex;
+  align-items: center;
+  font-size: 26rpx;
+  color: #3c82f8;
+}
+
+.action-btn text {
+  margin-left: 8rpx;
+}
+
+.list-placeholder {
+  height: 80rpx;
+  width: 100%;
+}
+</style>

+ 10 - 0
pages/hexiao/jxs/ywy_list.vue

@@ -42,6 +42,13 @@
               <uni-icons type="right" size="14" color="#999"></uni-icons>
             </view>
           </view>
+          <view class="detail-row clickable" @click="viewExpandStoreCount(item.id)">
+            <text class="detail-label">拓店数量</text>
+            <view class="detail-value with-arrow">
+              <text class="view-text">查看</text>
+              <uni-icons type="right" size="14" color="#999"></uni-icons>
+            </view>
+          </view>
           <view class="detail-row">
             <text class="detail-label">创建时间</text>
             <text class="detail-value">{{ item.create_time }}</text>
@@ -175,6 +182,9 @@ export default {
       console.log('查看销售数据 ID:', id);
       uni.navigateTo({ url: '/pages/hexiao/ywy/hexiao_detail_ywy?id='+id });
     },
+    viewExpandStoreCount(id) {
+      uni.navigateTo({ url: '/pages/hexiao/jxs/store_expand_list?ywyId='+id });
+    },
     editSalesperson(id) {
       uni.navigateTo({ url: '/pages/hexiao/jxs/add_ywy?id='+id });
       console.log('编辑业务员 ID:', id); },