Pārlūkot izejas kodu

feat 管理端页面

wzh 4 mēneši atpakaļ
vecāks
revīzija
08a9fabc5b

+ 54 - 4
api/hexiao.js

@@ -160,12 +160,13 @@ export function getXundianDetail(id){
 }
 
 export function doCommitToChang(id){
+    let url = '/jxs/writeOffSubmit';
+    if(id != -1){
+        url = url + "?id="+id
+    }
     return request({
-        url: `/jxs/writeOffSubmit`,
+        url: url,
         method: 'post',
-        params: {
-            orderId:id
-        }
     })
 }
 export function active(data){
@@ -301,6 +302,18 @@ export function queryAddRecord(data){
     });
 }
 
+/**
+ * 经销商核销订单id
+ * @param data
+ * @returns {*}
+ */
+export function queryAddJxsRecordDetail(data){
+    return request({
+        url: `/jxs/queryWriteOffDetail`,
+        method: 'post',
+        data: data
+    });
+}
 /**
  * 核销记录的明细
  * @param id
@@ -316,6 +329,20 @@ export function queryAddRecordDetail(id){
     })
 }
 
+
+/**
+ * 经销商核销记录的明细
+ * @param id
+ * @returns {*}
+ */
+export function queryPendingWriteOffDetail(data){
+    return request({
+        url: `/jxs/queryPendingWriteOffDetail`,
+        method: 'post',
+        data:data
+    })
+}
+
 /**
  * 经销商查询核销记录
  * @param data
@@ -472,6 +499,29 @@ export function addPatrolRecord(data){
     })
 }
 
+/**
+ * 查询经销商待审核数据
+ * @returns {*}
+ */
+export function queryPendingWriteOffRecord(data){
+    return request({
+        url: `/jxs/queryPendingWriteOffRecord`,
+        method: 'post',
+        data: data
+    })
+}
+
+/**
+ * 查询经销商待审核数据
+ * @returns {*}
+ */
+export function queryPendingWriteOffRecordDetail(data){
+    return request({
+        url: `/jxs/queryPendingWriteOffDetail`,
+        method: 'post',
+        data: data
+    })
+}
 /**
  * 经销商销售总数查询
  * @param startDate

+ 8 - 0
pages.json

@@ -409,6 +409,14 @@
 						"navigationBarTitleText" : "上货详情",
 						"enablePullDownRefresh" : false
 					}
+				},
+				{
+					"path" : "jxs/hexiao_pending_detail",
+					"style" :
+					{
+						"navigationBarTitleText" : "核销详情",
+						"enablePullDownRefresh" : false
+					}
 				}
 	]
 		}

+ 13 - 1
pages/cjx/shop/shop.vue

@@ -1,16 +1,28 @@
 <template>
 	<view>
-		<web-view src="https://cjxmall.dnzc.vip/"></web-view>
+		<web-view :src="src"></web-view>
 	</view>
 </template>
 
 <script>
+const appId = "wxe25fed34f9f70ef4";
+import {getAdminInfo, getAdminToken, setAdminInfo, setAdminToken} from "@/utils/auth";
 	export default {
 		data() {
 			return {
 
+          src :""
 			}
 		},
+    onLoad(){
+      let info = getAdminInfo()
+      let userType = info.roleType;
+      let type = 0;
+      if(userType === 1){
+        type = 2;
+      }
+      this.src = "https://d.dnzc.vip/cache/wx?appid="+appId+"&redirect_uri=http%3A%2F%2Fcjxmall.dnzc.vip%2Fpages%2Fusers%2Fwechat_login%2Findex%3Fstate="+type+"&response_type=code&scope=snsapi_userinfo&connect_redirect=1#wechat_redirect"
+    },
 		methods: {
 
 		}

+ 32 - 26
pages/hexiao/jxs/hexiao_detail.vue

@@ -2,46 +2,51 @@
   <view class="page-container">
     <view class="info-card">
       <view class="info-row">
-        <text class="info-label">核销业务员</text>
-        <text class="info-value">{{ detail.ywyName }}</text>
+        <text class="info-label">申请时间</text>
+        <text class="info-value">{{ detail.applyTime }}</text>
       </view>
       <view class="info-row">
-        <text class="info-label">申请时间</text>
-        <text class="info-value">{{ detail.dealerApplyTime }}</text>
+        <text class="info-label">单号</text>
+        <text class="info-value">{{ detail.orderNo }}</text>
+      </view>
+      <view class="info-row" v-if="detail.status == 0">
+        <text class="info-label">状态</text>
+        <text class="info-value">审核中</text>
+      </view>
+
+      <view class="info-row" v-if="detail.status == 1">
+        <text class="info-label">状态</text>
+        <text class="info-value">已核销</text>
+      </view>
+      <view class="info-row" v-if="detail.status == 1">
+        <text class="info-label">核销时间</text>
+        <text class="info-value">{{ detail.finishTime }}</text>
+      </view>
+    </view>
+
+    <view class="info-card" v-for="item in detail.items">
+      <view class="info-row">
+        <text class="info-label">核销业务员</text>
+        <text class="info-value">{{ item.ywyName }}</text>
       </view>
       <view class="info-row" v-if="detail.status == 3">
         <text class="info-label">审核时间</text>
         <text class="info-value">{{ detail.finishTime }}</text>
       </view>
 
-    </view>
-
-    <view class="summary-card">
-      <view
-          class="summary-tab"
-          v-for="item in detail.totals"
-          :key="item.key"
-      >
-        <text class="tab-category">{{ item.categoryName }}</text>
-        <text class="tab-count">{{ item.num }}</text>
+      <view class="info-row"     v-for="shiwu in item.shiwuDetails">
+        <text class="info-label">{{ shiwu.categoryName }}</text>
+        <text class="info-value">{{ shiwu.num }}</text>
       </view>
     </view>
 
-    <scroll-view class="details-list" scroll-y="true" @scrolltolower="loadMore">
-      <view v-if="detail.items.length === 0 && loadStatus !== 'loading'" class="empty-tip">
-        暂无明细记录
-      </view>
-      <view v-for="(item, index) in detail.items" :key="index" class="detail-item-card">
-        <text class="item-name">{{ item.productName }}</text>
-        <text class="item-code">扫码编号:{{ item.qrCodeNum }}</text>
-      </view>
-      <uni-load-more :status="loadStatus"></uni-load-more>
-    </scroll-view>
+
+
   </view>
 </template>
 
 <script>
-import {queryAddRecordDetail} from "@/api/hexiao";
+import {queryAddJxsRecordDetail} from "@/api/hexiao";
 
 export default {
   data() {
@@ -75,7 +80,8 @@ export default {
   },
   methods: {
     getDetail(){
-      queryAddRecordDetail(this.id).then(res=>{
+      let data = {orderId:this.id};
+      queryAddJxsRecordDetail(data).then(res=>{
         this.detail = res.data;
       })
     },

+ 199 - 0
pages/hexiao/jxs/hexiao_pending_detail.vue

@@ -0,0 +1,199 @@
+<template>
+  <view class="page-container">
+    <view class="info-card" v-for="item in detail">
+      <view class="info-row">
+        <text class="info-label">核销业务员</text>
+        <text class="info-value">{{ item.ywyName }}</text>
+      </view>
+      <view class="info-row">
+        <text class="info-label">单号</text>
+        <text class="info-value">{{ item.orderNo }}</text>
+      </view>
+
+      <view class="info-row">
+        <text class="info-label">上传时间</text>
+        <text class="info-value">{{ item.uploadTime }}</text>
+      </view>
+
+      <view class="info-row">
+        <text class="info-label">申请时间</text>
+        <text class="info-value">{{ item.applyTime }}</text>
+      </view>
+
+      <view class="info-row"     v-for="shiwu in item.totals">
+        <text class="info-label">{{ shiwu.categoryName }}</text>
+        <text class="info-value">{{ shiwu.num }}</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import {queryPendingWriteOffDetail} from "@/api/hexiao";
+
+export default {
+  data() {
+    return {
+      id:"",
+      // 总览信息
+      recordInfo: {
+        storeName: '湖南长沙超吉炫旗舰店',
+        verificationTime: '2025-08-11 09:30:00',
+      },
+      // 分类汇总数据
+      summaryData: [
+      ],
+      // 所有明细的列表
+      detailsList: [],
+      // 分页加载相关
+      pagination: { page: 1, limit: 15 },
+      loadStatus: 'more', // 'more', 'loading', 'noMore'
+      isLoading: false,
+      detail:{totals:[]}
+    };
+  },
+  onLoad(opt) {
+    // 页面加载时,获取第一页数据
+    // options.id 可以用来从上个页面传递记录ID
+    this.id = opt.id
+    this.getDetail(true);
+  },
+  onPullDownRefresh() {
+    this.fetchDetails(true);
+  },
+  methods: {
+    getDetail(){
+      queryPendingWriteOffDetail({ywyId:this.id}).then(res=>{
+        this.detail = res.data;
+      })
+    },
+    // 模拟从API获取明细数据
+    async fetchDetails(isRefresh = false) {
+      if (this.isLoading || (this.loadStatus === 'noMore' && !isRefresh)) {
+        return;
+      }
+      if (isRefresh) {
+        this.pagination.page = 1;
+        this.detailsList = [];
+        this.loadStatus = 'more';
+      }
+      this.isLoading = true;
+      this.loadStatus = 'loading';
+
+      console.log(`请求第 ${this.pagination.page} 页明细...`);
+      await new Promise(resolve => setTimeout(resolve, 1000));
+
+      const mockData = Array.from({ length: this.pagination.limit }, (_, i) => {
+        const id = (this.pagination.page - 1) * this.pagination.limit + i + 1;
+        return {
+          name: `超吉炫10元精制槟榔 - ${id}`,
+          code: `BH2025010020${String(id).padStart(3, '0')}`
+        };
+      });
+      const noMoreData = this.pagination.page >= 5; // 模拟加载4页后没有更多
+
+      uni.stopPullDownRefresh();
+      if (mockData.length > 0 && !noMoreData) {
+        this.detailsList = [...this.detailsList, ...mockData];
+        this.pagination.page++;
+        this.loadStatus = 'more';
+      } else {
+        this.loadStatus = 'noMore';
+      }
+      this.isLoading = false;
+    },
+    // 滚动到底部加载更多
+    loadMore() {
+      this.fetchDetails();
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.page-container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background-color: #f5f6fa;
+}
+
+.info-card {
+  background-color: #ffffff;
+  border-radius: 16rpx;
+  margin: 20rpx;
+  padding: 20rpx 30rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
+}
+
+.info-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 28rpx;
+  padding: 15rpx 0;
+  .info-label { color: #666; }
+  .info-value { color: #333; }
+}
+
+.summary-card {
+  display: flex;
+  justify-content: space-around;
+  background: linear-gradient(to right, #6ca1ff, #3c82f8);
+  border-radius: 16rpx;
+  margin: 0 20rpx 20rpx;
+  padding: 20rpx 10rpx;
+  color: #ffffff;
+}
+
+.summary-tab {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 10rpx;
+
+  .tab-category {
+    font-size: 26rpx;
+    opacity: 0.9;
+  }
+  .tab-count {
+    font-size: 28rpx;
+    font-weight: bold;
+    margin-top: 10rpx;
+  }
+}
+
+.details-list {
+  flex: 1;
+  height: 100%;
+  padding: 0 20rpx;
+}
+
+.empty-tip {
+  text-align: center;
+  color: #999;
+  padding-top: 100rpx;
+}
+
+.detail-item-card {
+  background-color: #ffffff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
+
+  .item-name {
+    display: block;
+    font-size: 30rpx;
+    font-weight: bold;
+    color: #333;
+  }
+
+  .item-code {
+    display: block;
+    font-size: 26rpx;
+    color: #999;
+    margin-top: 15rpx;
+  }
+}
+</style>

+ 114 - 51
pages/hexiao/jxs/hexiao_record.vue

@@ -1,27 +1,27 @@
 <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--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>
+<!--      <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,8 +34,44 @@
         </view>
       </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">
+          <text>暂无相关记录</text>
+        </view>
+
+        <view v-for="(pendInfo) in pendingList" :key="pendInfo.ywyId" class="record-card">
+
 
-    <scroll-view class="list-container" scroll-y="true" @scrolltolower="loadMore">
+          <view class="card-header" @click="detail(pendInfo.ywyId,1)">
+            <uni-icons type="paperclip" size="20" color="#3c82f8"></uni-icons>
+            <text class="record-id" style="text-decoration: underline">{{ pendInfo.ywyName }}</text>
+            <view class="status-badge pending">
+              {{ getStatusText(0) }}
+            </view>
+          </view>
+
+
+          <view class="card-body">
+
+            <view class="detail-row product-item" v-for="(item, index) in pendInfo.detail" :key="index">
+              <text class="detail-label">{{ item.categoryName }}</text>
+              <text class="detail-value">{{ item.num }}</text>
+            </view>
+          </view>
+
+          <view class="card-footer">
+            <button class="verify-btn" @click="verify(pendInfo.ywyId)">核销</button>
+          </view>
+        </view>
+
+        <uni-load-more :status="loadStatus"></uni-load-more>
+      </scroll-view>
+      <view class="fixed-footer" v-if="pendingList.length>0">
+        <button class="add-btn" @click="verify(-1)">一键核销</button>
+      </view>
+    </view>
+    <scroll-view class="list-container" scroll-y="true" @scrolltolower="loadMore" v-if="currentTab>1">
       <view v-if="recordList.length === 0 && loadStatus !== 'loading'" class="empty-list">
         <text>暂无相关记录</text>
       </view>
@@ -43,14 +79,11 @@
       <view v-for="record in recordList" :key="record.orderNo" class="record-card">
         <view class="card-header">
           <uni-icons type="paperclip" size="20" color="#3c82f8"></uni-icons>
-          <text class="record-id" @click="detail(record.orderNo)" style="text-decoration: underline">{{ record.orderNo }}</text>
-          <view class="status-badge pending" v-if="record.status === 1">
-            {{ getStatusText(record.status) }}
-          </view>
-          <view class="status-badge verifying"  v-if="record.status === 2">
+          <text class="record-id" @click="detail(record.id)" style="text-decoration: underline">{{ record.orderNo }}</text>
+          <view class="status-badge verifying"  v-if="record.status === 0">
             {{ getStatusText(record.status) }}
           </view>
-          <view class="status-badge verified" style="background-color: #54CFAB"  v-if="record.status === 3">
+          <view class="status-badge verified" style="background-color: #54CFAB"  v-if="record.status === 1">
             {{ getStatusText(record.status) }}
           </view>
         </view>
@@ -59,18 +92,12 @@
             <text class="detail-label">业务员名称</text>
             <text class="detail-value">{{ record.ywyName }}</text>
           </view>
-
-
-          <view class="detail-row" v-if="record.status === 1">
-            <text class="detail-label" >业务员提交时间</text>
-            <text class="detail-value">{{ record. applyTime }}</text>
-          </view>
-          <view class="detail-row"  v-if="record.status === 2 || record.status === 3">
+          <view class="detail-row" >
             <text class="detail-label">申请时间</text>
             <text class="detail-value">{{ record. dealerApplyTime }}</text>
           </view>
 
-          <view class="detail-row" v-if="record.status === 3">
+          <view class="detail-row" v-if="record.status === 1">
             <text class="detail-label">审核时间</text>
             <text class="detail-value">{{ record.finishTime }}</text>
           </view>
@@ -87,9 +114,6 @@
 
         </view>
 
-        <view class="card-footer" v-if="record.status === 1">
-          <button class="verify-btn" @click="verify(record.id,record.orderNo)">一键审核</button>
-        </view>
       </view>
 
       <uni-load-more :status="loadStatus"></uni-load-more>
@@ -101,6 +125,7 @@
 
 <script>
 import {queryJxsAddRecord,doCommitToJxs,doCommitToChang, queryHexiaoRecord} from "@/api/hexiao";
+import {queryPendingWriteOffRecord} from "../../../api/hexiao";
 
 export default {
   data() {
@@ -112,20 +137,20 @@ export default {
       mode: 'range',
       searchQuery: '',
       tabs: [
-        { name: '全部', key: 'all' ,id:-1 },
         { name: '待审核', key: 'pending',id: 1 },
         { name: '核销中', key: 'verifying', id: 2},
         { name: '已核销', key: 'verified' , id :3},
       ],
-      currentTab: -1,
+      currentTab: 1,
       recordList: [],
+      pendingList:[],
       pagination: { page: 1, limit: 10 },
       loadStatus: 'more', // 'more', 'loading', 'noMore'
       isLoading: false,
     };
   },
   onLoad() {
-    this.fetchRecords(true);
+    this.getReadyData(true);
   },
   onPullDownRefresh() {
     this.fetchRecords(true);
@@ -151,16 +176,24 @@ export default {
     },
     getStatusText(status) {
       const statusMap = {
-        1: '待审核',
-        2: '核销中',
-        3: '已核销'
+        0: '核销中',
+        1: '已核销'
       };
       return statusMap[status] || '未知';
     },
     changeTab(tabKey) {
       if (this.currentTab === tabKey) return;
       this.currentTab = tabKey;
-      this.fetchRecords(true); // 切换tab时重新加载数据
+      if(this.currentTab  ==1){
+        this.getReadyData(true);
+      }else{
+        this.fetchRecords(true); // 切换tab时重新加载数据
+      }
+    },
+    getReadyData(isRefresh = false) {
+      queryPendingWriteOffRecord({pageIndex:this.pagination.page,pageSize:100,ywyName:this.searchQuery}).then(res=>{
+           this.pendingList = res.data.records?res.data.records:[];
+      })
     },
     async fetchRecords(isRefresh = false) {
       if (this.isLoading || (this.loadStatus === 'noMore' && !isRefresh)) {
@@ -177,7 +210,7 @@ export default {
 
       let data = {};
       if(this.currentTab !== -1){
-        data.status = this.currentTab;
+        data.status = this.currentTab-2;
       }
       data.startTime = this.startTime;
       data.endTime = this.endTime;
@@ -202,7 +235,11 @@ export default {
 
 
     },
-    detail(id){
+    detail(id,type){
+      if(type == 1){
+        uni.navigateTo({ url: `/pages/hexiao/jxs/hexiao_pending_detail?id=`+id });
+        return;
+      }
       uni.navigateTo({ url: `/pages/hexiao/jxs/hexiao_detail?id=`+id });
     },
     loadMore() {
@@ -217,15 +254,19 @@ export default {
     handleSearch() {
       this.fetchRecords(true);
     },
-    verify(id,orderNo) {
+    verify(id) {
+      let title = "确认核销该订单吗?";
+      if(id == -1){
+        title = "一键核销";
+      }
       uni.showModal({
         title: '提示',
-        content: `确认核销订单 ${orderNo} 吗?`,
+        content: title,
         success: (res) => {
           if (res.confirm) {
             doCommitToChang(id).then(res=>{
               if(res.code === 0){
-                this.fetchRecords(true);
+                this.getReadyData(true);
                 uni.showToast({ title: '核销成功' });
               }else{
                 uni.showToast({ title: '核销失败' });
@@ -399,4 +440,26 @@ export default {
   font-size: 30rpx;
   color: #F5F5F5;
 }
+
+.fixed-footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  background-color: #f5f6fa;
+  padding: 20rpx 30rpx;
+  padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  box-sizing: border-box;
+  z-index: 100;
+}
+.add-btn {
+  background-color: #3c82f8;
+  color: white;
+  border-radius: 50rpx;
+  font-size: 32rpx;
+  height: 90rpx;
+  line-height: 90rpx;
+  &::after { border: none; }
+}
 </style>

+ 1 - 2
pages/hexiao/ywy/hexiao_record.vue

@@ -110,12 +110,11 @@ export default {
       mode: 'range',
       searchQuery: '',
       tabs: [
-        { name: '全部', key: 'all' ,id:-1 },
         { name: '待核销', key: 'pending',id: 0 },
         { name: '核销中', key: 'verifying', id: 1},
         { name: '已核销', key: 'verified' , id :2},
       ],
-      currentTab: -1,
+      currentTab: 0,
       recordList: [],
       pagination: { page: 1, limit: 10 },
       loadStatus: 'more', // 'more', 'loading', 'noMore'