소스 검색

接口对接&修复bug

Alex 11 달 전
부모
커밋
26bd94d707

+ 6 - 4
src/components/CommonPage/CommonTable.vue

@@ -1,5 +1,8 @@
 <template>
-  <ele-card :body-style="{ paddingTop: '8px', ...bodyStyle }" :flex-table="flexTable">
+  <ele-card
+    :body-style="{ paddingTop: '8px', ...bodyStyle }"
+    :flex-table="flexTable"
+  >
     <!-- 表格 -->
     <ele-pro-table
       ref="tableRef"
@@ -70,8 +73,7 @@
 
   /** 搜索 */
   const reload = (where) => {
-    console.log('where', where);
-    tableRef.value?.reload?.({ where });
+    tableRef.value?.reload?.({ where, page: 1 });
   };
 
   /** 批量操作 */
@@ -144,7 +146,7 @@
         .then((res) => {
           if (res.data.code === 200) {
             EleMessage.success('操作成功,请前往导出记录下载');
-          }else{
+          } else {
             EleMessage.error(res.data.msg);
           }
           loading.close();

+ 180 - 0
src/utils/use-book-operation.js

@@ -0,0 +1,180 @@
+import { ElMessage } from 'element-plus';
+import { ref } from 'vue';
+
+/**
+ * 图书操作相关的混入方法
+ * @param {Object} pageRef - 页面表格组件实例
+ * @returns {Object} - 包含各种图书操作方法的对象
+ */
+export function useBookOperation(pageRef) {
+  // 弹窗组件引用
+  const blacklistRef = ref(null);
+  const discountRef = ref(null);
+  const paramsRef = ref(null);
+
+  /**
+   * 回收书单操作(添加/移除)
+   * @param {String} type - 操作类型:'add'添加,'remove'移除
+   * @param {Object} row - 单行数据,不传则为批量操作
+   */
+  function handleOptBooklist(type, row) {
+    let selections = row ? [row] : pageRef.value?.getSelections();
+    if (!selections || selections.length === 0) {
+      ElMessage.warning('请选择要操作的图书');
+      return;
+    }
+    const isbnList = selections.map((item) => item.isbn);
+
+    const url =
+      type === 'remove'
+        ? '/book/bookRecycleInfo/removeOut'
+        : '/book/bookRecycleInfo/addIn';
+
+    const title =
+      type === 'remove' ? '确认移除回收书单?' : '确认加入回收书单?';
+
+    pageRef.value?.operatBatch({
+      title,
+      method: 'post',
+      url,
+      data: { isbnList },
+      row,
+      success: (res) => {
+        if (typeof pageRef.value?.reload === 'function') {
+          pageRef.value.reload();
+        }
+      }
+    });
+  }
+
+  /**
+   * 黑名单操作(添加/移除)
+   * @param {String} type - 操作类型:'add'添加,'remove'移除
+   * @param {Object} row - 单行数据,不传则为批量操作
+   */
+  function handleOptBlacklist(type, row) {
+    let selections = row ? [row] : pageRef.value?.getSelections();
+    if (!selections || selections.length === 0) {
+      ElMessage.warning('请选择要操作的图书');
+      return;
+    }
+    const isbnList = selections.map((item) => item.isbn);
+
+    if (type == 'remove') {
+      // 移除黑名单
+      pageRef.value?.operatBatch({
+        title: '确认移除黑名单?',
+        method: 'post',
+        url: '/book/bookRecycleInfo/removeBlackList',
+        data: { isbnList },
+        row,
+        success: () => {
+          if (typeof pageRef.value?.reload === 'function') {
+            pageRef.value.reload();
+          }
+        }
+      });
+    } else {
+      // 加入黑名单,打开选择原因弹窗
+      blacklistRef.value?.handleOpen(isbnList);
+    }
+  }
+
+  /**
+   * 回收操作(开启/暂停)
+   * @param {Object} row - 单行数据,不传则为批量操作
+   */
+  function handleOptRecycle(type, row) {
+    let selections = row ? [row] : pageRef.value?.getSelections();
+    if (!selections || selections.length === 0) {
+      ElMessage.warning('请选择要操作的图书');
+      return;
+    }
+
+    const isbnList = selections.map((item) => item.isbn);
+
+    const url = type === 'pause'
+      ? '/book/bookRecycleInfo/stopRecycle'
+      : '/book/bookRecycleInfo/openRecycle';
+
+    const title = type === 'pause' ? '确认暂停回收?' : '确认开启回收?';
+
+    pageRef.value?.operatBatch({
+      title,
+      method: 'post',
+      url,
+      data: { isbnList },
+      row,
+      success: () => {
+        if (typeof pageRef.value?.reload === 'function') {
+          pageRef.value.reload();
+        }
+      }
+    });
+  }
+
+  /**
+   * 类型操作(社科库/教材库)
+   * @param {Number} type - 类型:1社科库,2教材库
+   */
+  function handleOptType(type) {
+    let selections = pageRef.value?.getSelections();
+    if (!selections || selections.length === 0) {
+      ElMessage.warning('请选择要操作的图书');
+      return;
+    }
+
+    const isbnList = selections.map((item) => item.isbn);
+    const url =
+      type == 1
+        ? '/book/bookRecycleInfo/changeBookTag2'
+        : '/book/bookRecycleInfo/changeBookTag1';
+    const title = type == 1 ? '确认加社科库?' : '确认加教材库?';
+
+    pageRef.value?.operatBatch({
+      title,
+      method: 'post',
+      url,
+      data: { isbnList },
+      success: () => {
+        if (typeof pageRef.value?.reload === 'function') {
+          pageRef.value.reload();
+        }
+      }
+    });
+  }
+
+  /**
+   * 指定折扣加入回收书单
+   */
+  function handleAddDiscount() {
+    let selections = pageRef.value?.getSelections();
+    if (!selections || selections.length === 0) {
+      ElMessage.warning('请选择要操作的图书');
+      return;
+    }
+
+    const isbnList = selections.map((item) => item.isbn);
+    discountRef.value?.handleOpen({ isbnList });
+  }
+
+  /**
+   * 设置独立参数
+   * @param {Object} row - 图书数据
+   */
+  function handleSetParams(row) {
+    paramsRef.value?.handleOpen(row);
+  }
+
+  return {
+    blacklistRef,
+    discountRef,
+    paramsRef,
+    handleOptBooklist,
+    handleOptBlacklist,
+    handleOptRecycle,
+    handleOptType,
+    handleAddDiscount,
+    handleSetParams
+  };
+}

+ 38 - 142
src/views/recycle/booklist/index.vue

@@ -2,7 +2,7 @@
     <ele-page flex-table>
         <book-search @search="reload"></book-search>
 
-        <common-table ref="pageRef" :pageConfig="pageConfig" :columns="columns" :tools="false">
+        <common-table ref="pageRef" :pageConfig="pageConfig" :columns="columns" :tools="false" @sort-change="handleSortChange">
             <template #toolbar>
                 <el-radio-group @change="handleStatusChange" v-model="searchType">
                     <el-radio-button label="全部" value="0" />
@@ -14,11 +14,11 @@
 
                 <span class="ml-8"></span>
                 <el-button type="warning" plain v-permission="'recycle:booklist:batchRemoveBooklist'"
-                    @click="handleOptBooklist()" v-if="['0', '1', '2'].includes(searchType)">
+                    @click="handleOptBooklist('remove')" v-if="['0', '1', '2'].includes(searchType)">
                     移除回收书单
                 </el-button>
                 <el-button type="success" plain v-permission="'recycle:booklist:batchAddBooklist'"
-                    @click="handleOptBooklist()" v-if="['3', '4'].includes(searchType)">
+                    @click="handleOptBooklist('add')" v-if="['3', '4'].includes(searchType)">
                     加入回收书单
                 </el-button>
                 <el-button type="warning" plain v-permission="'recycle:booklist:batchRemoveBlacklist'"
@@ -31,11 +31,11 @@
                 </el-button>
 
                 <el-button type="warning" plain v-permission="'recycle:booklist:batchPauseRecycle'"
-                    @click="handleOptRecycle()" v-if="searchType === '1'">
+                    @click="handleOptRecycle('pause')" v-if="searchType === '1'">
                     暂停回收
                 </el-button>
                 <el-button type="warning" plain v-permission="'recycle:booklist:batchStartRecycle'"
-                    @click="handleOptRecycle()" v-if="['0', '2'].includes(searchType)">
+                    @click="handleOptRecycle('start')" v-if="['0', '2'].includes(searchType)">
                     开启回收
                 </el-button>
                 <el-button type="primary" plain v-permission="'recycle:booklist:batchAddDiscount'"
@@ -80,19 +80,19 @@
                     [加入黑名单]
                 </el-button>
                 <el-button type="danger" link v-permission="'recycle:booklist:pauseRecycle'"
-                    @click="handleOptRecycle(row)" v-if="row.recycleStatus == 1">
+                    @click="handleOptRecycle('pause', row)" v-if="row.recycleStatus == 1">
                     [暂停回收]
                 </el-button>
                 <el-button type="success" link v-permission="'recycle:booklist:startRecycle'"
-                    @click="handleOptRecycle(row)" v-else>
+                    @click="handleOptRecycle('start', row)" v-else>
                     [开启回收]
                 </el-button>
                 <el-button type="success" link v-permission="'recycle:booklist:removeBooklist'"
-                    @click="handleOptBooklist(row)" v-if="row.bookStatus == 2">
+                    @click="handleOptBooklist('remove', row)" v-if="row.bookStatus == 2">
                     [移除回收书单]
                 </el-button>
                 <el-button type="danger" link v-permission="'recycle:booklist:addBooklist'"
-                    @click="handleOptBooklist(row)" v-if="row.bookStatus == 1">
+                    @click="handleOptBooklist('add', row)" v-if="row.bookStatus == 1">
                     [加入回收书单]
                 </el-button>
             </template>
@@ -111,12 +111,11 @@ import CommonTable from '@/components/CommonPage/CommonTable.vue';
 import booksEdit from '@/views/data/books/components/books-edit.vue';
 import bookSearch from '@/views/recycle/components/book-search.vue';
 import bookInfo from '@/views/recycle/components/book-info.vue';
-import bookOtherInfo from '@/views/recycle/components/book-other-info.vue';
 import bookStock from '@/views/recycle/components/book-stock.vue';
 import setParams from '@/views/recycle/components/set-params.vue';
 import addDiscount from '@/views/recycle/components/add-discount.vue';
 import orderBlacklist from '@/views/recycleOrder/detail/order-blacklist.vue';
-import { useDictData } from '@/utils/use-dict-data';
+import { useBookOperation } from '@/utils/use-book-operation';
 
 defineOptions({ name: 'recycleBooklist' });
 
@@ -151,13 +150,13 @@ const columns = ref([
         minWidth: 100,
         prop: 'recycleDiscount',
         sortable: true,
-        columnKey: 'recycleDiscount'
+        columnKey: '1'
     },
     {
         label: '回收价格',
         prop: 'recyclePrice',
         sortable: true,
-        columnKey: 'recyclePrice',
+        columnKey: '2',
         minWidth: 100
     },
     {
@@ -165,33 +164,33 @@ const columns = ref([
         minWidth: 120,
         prop: 'recycleMax',
         sortable: true,
-        columnKey: 'recycleMax'
+        columnKey: '3'
     },
     {
         label: '总回收数量',
         minWidth: 120,
         prop: 'recycleTotalNum',
         sortable: true,
-        columnKey: 'recycleTotalNum'
+        columnKey: '4'
     },
     {
         label: '当前剩余回收量',
         minWidth: 140,
         prop: 'restRecycleNum',
         sortable: true,
-        columnKey: 'restRecycleNum'
+        columnKey: '5'
     },
     {
         label: '销量',
         prop: 'salesNum',
         sortable: true,
-        columnKey: 'salesNum'
+        columnKey: '6'
     },
     {
         label: '库存',
         prop: 'stockTotalNum',
         sortable: true,
-        columnKey: 'stockTotalNum',
+        columnKey: '7',
         slot: 'stock',
         minWidth: 100
     },
@@ -214,6 +213,15 @@ const pageConfig = reactive({
     rowKey: 'isbn'
 });
 
+function handleSortChange({ column, order }) {
+    // 1 扫描次数 2总回收量 3最后一次扫描时间
+    reload({
+      orderType: column.columnKey,
+      orderWay: order === 'ascending' ? 'asc' : 'desc'
+    });
+  }
+
+
 //刷新表格
 function reload(where) {
     pageRef.value?.reload(where);
@@ -227,129 +235,17 @@ function handleUpdateBook(row) {
     };
     editRef.value?.handleOpen(params);
 }
-//设置参数
-const paramsRef = ref(null);
-function handleSetParams(row) {
-    paramsRef.value?.handleOpen(row);
-}
-
-//回收书单操作
-function handleOptBooklist(row) {
-    let selections = row ? [row] : pageRef.value?.getSelections();
-    if (!selections || selections.length === 0) {
-        ElMessage.warning('请选择要操作的图书');
-        return;
-    }
-
-    const isbnList = selections.map((item) => item.isbn);
-    const isInRecycleList = row ? row.bookStatus === '2' : selections[0].bookStatus === '2';
-
-    const url = isInRecycleList
-        ? '/book/bookRecycleInfo/removeOut'
-        : '/book/bookRecycleInfo/addIn';
-
-    const title = isInRecycleList ? '确认移除回收书单?' : '确认加入回收书单?';
-
-    pageRef.value?.operatBatch({
-        title,
-        method: 'post',
-        url,
-        data: { isbnList },
-        row,
-        success: () => {
-            reload();
-        }
-    });
-}
-//黑名单操作
-const blacklistRef = ref(null);
-function handleOptBlacklist(type, row) {
-    let selections = row ? [row] : pageRef.value?.getSelections();
-    if (!selections || selections.length === 0) {
-        ElMessage.warning('请选择要操作的图书');
-        return;
-    }
-    const isbnList = selections.map((item) => item.isbn);
-
-    if (type == 'remove') {
-        // 移除黑名单
-        pageRef.value?.operatBatch({
-            title: '确认移除黑名单?',
-            method: 'post',
-            url: '/book/bookRecycleInfo/removeBlackList',
-            data: { isbnList },
-            row,
-            success: () => {
-                reload();
-            }
-        });
-    } else {
-        // 加入黑名单,打开选择原因弹窗
-        blacklistRef.value?.handleOpen(isbnList);
-    }
-}
-//回收操作
-function handleOptRecycle(row) {
-    let selections = row ? [row] : pageRef.value?.getSelections();
-    if (!selections || selections.length === 0) {
-        ElMessage.warning('请选择要操作的图书');
-        return;
-    }
-
-    const isbnList = selections.map((item) => item.isbn);
-    const isStop = row ? row.recycleStatus === '1' : selections[0].recycleStatus === '1';
-
-    const url = isStop
-        ? '/book/bookRecycleInfo/stopRecycle'
-        : '/book/bookRecycleInfo/openRecycle';
 
-    const title = isStop ? '确认暂停回收?' : '确认开启回收?';
-
-    pageRef.value?.operatBatch({
-        title,
-        method: 'post',
-        url,
-        data: { isbnList },
-        row,
-        success: () => {
-            reload();
-        }
-    });
-}
-//类型操作
-function handleOptType(type) {
-    let selections = pageRef.value?.getSelections();
-    if (!selections || selections.length === 0) {
-        ElMessage.warning('请选择要操作的图书');
-        return;
-    }
-
-    const isbnList = selections.map((item) => item.isbn);
-    const url = type == 1
-        ? '/book/bookRecycleInfo/changeBookTag2'
-        : '/book/bookRecycleInfo/changeBookTag1';
-    const title = type == 1 ? '确认加社科库?' : '确认加教材库?';
-
-    pageRef.value?.operatBatch({
-        title,
-        method: 'post',
-        url,
-        data: { isbnList },
-        success: () => {
-            reload();
-        }
-    });
-}
-//指定折扣
-const discountRef = ref(null);
-function handleAddDiscount() {
-    let selections = pageRef.value?.getSelections();
-    if (!selections || selections.length === 0) {
-        ElMessage.warning('请选择要操作的图书');
-        return;
-    }
-
-    const isbnList = selections.map((item) => item.isbn);
-    discountRef.value?.handleOpen({ isbnList });
-}
+// 使用图书操作混入
+const {
+    blacklistRef,
+    discountRef,
+    paramsRef,
+    handleOptBooklist,
+    handleOptBlacklist,
+    handleOptRecycle,
+    handleOptType,
+    handleAddDiscount,
+    handleSetParams
+} = useBookOperation(pageRef);
 </script>

+ 9 - 9
src/views/recycle/inventory/components/book-base-info.vue

@@ -2,38 +2,38 @@
   <div class="recycle-order-number flex flex-col items-start ml-6">
     <div class="common-text cursor-pointer">
       <el-text type="primary" @click="handleClick(row)">{{
-        row.bookName
+        row?.bookName
       }}</el-text>
     </div>
     <div class="flex justify-between items-start">
-      <div class="flex flex-col items-start" style="min-width:240px">
+      <div class="flex flex-col items-start" style="min-width: 240px">
         <div class="common-text">
           <el-text>ISBN:</el-text>
-          <el-text>{{ row.isbn }}</el-text>
+          <el-text>{{ row?.isbn }}</el-text>
         </div>
         <div class="common-text">
           <el-text>作 者:</el-text>
-          <el-text>{{ row.author || '-' }} </el-text>
+          <el-text>{{ row?.author || '-' }} </el-text>
         </div>
         <div class="common-text">
           <el-text>出版社:</el-text>
-          <el-text>{{ row.publish || '-' }}</el-text>
+          <el-text>{{ row?.publish || '-' }}</el-text>
         </div>
       </div>
-      <div class="flex flex-col items-start ml-20">
+      <div class="flex flex-col items-start ml-5">
         <div class="common-text">
           <el-text>定价:</el-text>
-          <el-text>¥ {{ row.price }}</el-text>
+          <el-text>¥ {{ row?.price || 0 }}</el-text>
         </div>
         <div class="common-text">
           <el-text>出版时间:</el-text>
           <el-text
-            >{{ row.pubDate ? dayjs(row.pubDate).format('YYYY-MM-DD') : '-' }}
+            >{{ row?.pubDate ? dayjs(row?.pubDate).format('YYYY-MM-DD') : '-' }}
           </el-text>
         </div>
         <div class="common-text">
           <el-text>装帧:</el-text>
-          <el-text>{{ row.bookPack || '暂无' }}</el-text>
+          <el-text>{{ row?.bookPack || '暂无' }}</el-text>
         </div>
       </div>
     </div>

+ 6 - 3
src/views/recycle/inventory/index.vue

@@ -36,12 +36,15 @@
         <el-image
           style="width: 80px; height: 100px"
           fit="cover"
-          :src="row.cover"
+          :src="row?.bookInfo?.cover"
         />
       </template>
 
       <template #baseInfo="{ row }">
-        <book-base-info :row="row.bookInfo" @click="handleUpdate"></book-base-info>
+        <book-base-info
+          :row="row?.bookInfo"
+          @click="handleUpdate"
+        ></book-base-info>
       </template>
 
       <template #stock="{ row }">
@@ -140,7 +143,7 @@
       prop: 'salePrice',
       align: 'center',
       minWidth: 100,
-      formatter: (row) => '¥' + row.salePrice || 0
+      formatter: (row) => '¥' + (row?.salePrice ? row.salePrice : 0)
     },
     {
       label: '库存',

+ 125 - 68
src/views/recycle/scanLog/index.vue

@@ -7,22 +7,33 @@
       :pageConfig="pageConfig"
       :columns="columns"
       :tools="false"
+      @sort-change="handleSortChange"
     >
       <template #toolbar>
-        <el-radio-group @change="handleStatusChange" v-model="useStatus">
+        <el-radio-group @change="handleStatusChange" v-model="searchType">
           <el-radio-button label="已加入回收书单(正在回收)" value="1" />
           <el-radio-button label="已加入回收书单(暂停回收)" value="2" />
           <el-radio-button label="未加入回收书单" value="3" />
           <el-radio-button label="黑名单" value="4" />
-          <el-radio-button label="无数据信息" value="4" />
+          <el-radio-button label="无数据信息" value="5" />
         </el-radio-group>
 
         <span class="ml-8"></span>
+        <el-button
+          type="warning"
+          plain
+          v-permission="'recycle:scanLog:batchRemoveBooklist'"
+          @click="handleOptBooklist('remove')"
+          v-if="['1', '2'].includes(searchType)"
+        >
+          移除回收书单
+        </el-button>
         <el-button
           type="success"
           plain
           v-permission="'recycle:scanLog:batchAddBooklist'"
-          @click="handleOptBooklist()"
+          @click="handleOptBooklist('add')"
+          v-if="['3', '4'].includes(searchType)"
         >
           加入回收书单
         </el-button>
@@ -30,7 +41,8 @@
           type="warning"
           plain
           v-permission="'recycle:scanLog:batchRemoveBlacklist'"
-          @click="handleOptBlacklist()"
+          @click="handleOptBlacklist('remove')"
+          v-if="searchType === '4'"
         >
           移除黑名单
         </el-button>
@@ -38,7 +50,8 @@
           type="danger"
           plain
           v-permission="'recycle:scanLog:batchAddBlacklist'"
-          @click="handleOptBlacklist()"
+          @click="handleOptBlacklist('add')"
+          v-if="searchType !== '4'"
         >
           加黑名单
         </el-button>
@@ -47,10 +60,37 @@
           type="warning"
           plain
           v-permission="'recycle:scanLog:batchPauseRecycle'"
-          @click="handleOptRecycle()"
+          @click="handleOptRecycle('pause')"
+          v-if="searchType === '1'"
         >
           暂停回收
         </el-button>
+        <el-button
+          type="warning"
+          plain
+          v-permission="'recycle:scanLog:batchStartRecycle'"
+          @click="handleOptRecycle('start')"
+          v-if="searchType === '2'"
+        >
+          开启回收
+        </el-button>
+
+        <el-button
+          type="success"
+          plain
+          v-permission="'recycle:booklist:batchAddSocial'"
+          @click="handleOptType(1)"
+        >
+          加社科库
+        </el-button>
+        <el-button
+          type="primary"
+          plain
+          v-permission="'recycle:booklist:batchAddTeach'"
+          @click="handleOptType(2)"
+        >
+          加教材库
+        </el-button>
       </template>
 
       <template #cover="{ row }">
@@ -61,14 +101,7 @@
         />
       </template>
       <template #baseInfo="{ row }">
-        <div class="flex justify-start items-center">
-          <div style="flex: 2">
-            <book-info :row="row"></book-info>
-          </div>
-          <div style="flex: 1.5; margin-left: 15px">
-            <book-other-info :row="row"></book-other-info>
-          </div>
-        </div>
+        <book-info :row="row"></book-info>
       </template>
       <template #stock="{ row }">
         <book-stock :row="row"></book-stock>
@@ -93,26 +126,29 @@
           [设置独立参数]
         </el-button>
         <el-button
-          type="warning"
+          type="success"
           link
-          v-permission="'recycle:scanLog:addBlacklist'"
-          @click="handleOptBlacklist(row)"
+          v-permission="'recycle:scanLog:removeBlacklist'"
+          @click="handleOptBlacklist('remove', row)"
+          v-if="row.bookStatus == 3"
         >
-          [加入黑名单]
+          [移除黑名单]
         </el-button>
         <el-button
-          type="success"
+          type="warning"
           link
-          v-permission="'recycle:scanLog:removeBlacklist'"
-          @click="handleOptBlacklist(row)"
+          v-permission="'recycle:scanLog:addBlacklist'"
+          @click="handleOptBlacklist('add', row)"
+          v-if="row.bookStatus == 1 || row.bookStatus == 2"
         >
-          [移除黑名单]
+          [加入黑名单]
         </el-button>
         <el-button
           type="danger"
           link
           v-permission="'recycle:scanLog:pauseRecycle'"
-          @click="handleOptRecycle(row)"
+          @click="handleOptRecycle('pause', row)"
+          v-if="row.recycleStatus == 1"
         >
           [暂停回收]
         </el-button>
@@ -120,7 +156,8 @@
           type="success"
           link
           v-permission="'recycle:scanLog:startRecycle'"
-          @click="handleOptRecycle(row)"
+          @click="handleOptRecycle('start', row)"
+          v-else
         >
           [开启回收]
         </el-button>
@@ -128,7 +165,8 @@
           type="success"
           link
           v-permission="'recycle:scanLog:removeBooklist'"
-          @click="handleOptBooklist(row)"
+          @click="handleOptBooklist('remove', row)"
+          v-if="row.bookStatus == 2"
         >
           [移除回收书单]
         </el-button>
@@ -136,7 +174,8 @@
           type="danger"
           link
           v-permission="'recycle:scanLog:addBooklist'"
-          @click="handleOptBooklist(row)"
+          @click="handleOptBooklist('add', row)"
+          v-if="row.bookStatus == 1"
         >
           [加入回收书单]
         </el-button>
@@ -146,6 +185,8 @@
     <books-edit ref="editRef"></books-edit>
     <set-params ref="paramsRef"></set-params>
     <scan-log ref="logRef"></scan-log>
+    <add-discount ref="discountRef" @refresh="reload"></add-discount>
+    <order-blacklist ref="blacklistRef" @refresh="reload"></order-blacklist>
   </ele-page>
 </template>
 
@@ -155,18 +196,27 @@
   import booksEdit from '@/views/data/books/components/books-edit.vue';
   import bookSearch from '@/views/recycle/components/book-search.vue';
   import bookInfo from '@/views/recycle/components/book-info.vue';
-  import bookOtherInfo from '@/views/recycle/components/book-other-info.vue';
   import bookStock from '@/views/recycle/components/book-stock.vue';
   import setParams from '@/views/recycle/components/set-params.vue';
-  import scanLog from './components/scan-log.vue'
-  import { useDictData } from '@/utils/use-dict-data';
+  import scanLog from './components/scan-log.vue';
+  import addDiscount from '@/views/recycle/components/add-discount.vue';
+  import orderBlacklist from '@/views/recycleOrder/detail/order-blacklist.vue';
+  import { useBookOperation } from '@/utils/use-book-operation';
+  import { ElMessage } from 'element-plus';
 
   defineOptions({ name: 'scanLoglist' });
-  const [useStatusDicts] = useDictData(['use_status']);
 
-  const useStatus = ref('1');
+  const searchType = ref('1');
   function handleStatusChange(value) {
-    pageRef.value.reload({ useStatus: value });
+    pageRef.value.reload({ searchType: value });
+  }
+
+  function handleSortChange({ column, order }) {
+    // 1 扫描次数 2总回收量 3最后一次扫描时间
+    reload({
+      orderType: column.columnKey,
+      orderWay: order === 'ascending' ? 'asc' : 'desc'
+    });
   }
 
   /** 表格列配置 */
@@ -190,11 +240,31 @@
       width: 540,
       slot: 'baseInfo'
     },
-    { label: '回收折扣', prop: 'discount' },
-    { label: '预估金额', prop: 'amount' },
-    { label: '扫描次数', prop: 'scanNum' },
-    { label: '总回收数量', prop: 'totalRecycledAmount' },
-    { label: '最后一次扫描时间', prop: 'lastTime' },
+    { label: '回收折扣', prop: 'recycleDiscount' },
+    { label: '预估金额', prop: 'recyclePrice' },
+    {
+      label: '扫描次数',
+      prop: 'scanNum',
+      sortable: true,
+      columnKey: '1',
+      minWidth: 100,
+      formatter: (row) => row?.scanNum || 0
+    },
+    {
+      label: '总回收数量',
+      prop: 'recycleTotalNum',
+      sortable: true,
+      columnKey: '2',
+      minWidth: 120
+    },
+    {
+      label: '最后一次扫描时间',
+      prop: 'lastScanTime',
+      sortable: true,
+      columnKey: '3',
+      minWidth: 160,
+      formatter: (row) => (row?.lastScanTime ? row?.lastScanTime : '-')
+    },
     {
       columnKey: 'action',
       label: '操作',
@@ -208,9 +278,13 @@
   const pageRef = ref(null);
 
   const pageConfig = reactive({
-    pageUrl: '/book/bookInfo/list',
+    pageUrl: '/user/userScanLog/getBookScanLogList',
     fileName: '回收书单管理',
-    cacheKey: 'scanLoglistTable'
+    cacheKey: 'scanLoglistTable',
+    params: {
+      searchType: '1'
+    },
+    rowKey: 'isbn'
   });
 
   //刷新表格
@@ -223,36 +297,19 @@
   function handleUpdateBook(row) {
     editRef.value?.handleOpen(row);
   }
-  //设置参数
-  const paramsRef = ref(null);
-  function handleSetParams(row) {
-    paramsRef.value?.handleOpen(row);
-  }
 
-  //回收书单操作
-  function handleOptBooklist(row) {
-    let selections = row ? [row] : pageRef.value?.getSelections();
-    let ids = selections.map((item) => item.id).join(',');
-    let url = `/book/bookInfo/removeById/${ids}`;
-    let title = row ? '确认移除回收书单?' : '确认加入回收书单?';
-    pageRef.value?.operatBatch({ title, method: 'post', url, row });
-  }
-  //黑名单操作
-  function handleOptBlacklist(row) {
-    let selections = row ? [row] : pageRef.value?.getSelections();
-    let ids = selections.map((item) => item.id).join(',');
-    let url = `/book/bookInfo/removeBlacklist/${ids}`;
-    let title = row ? '确认移除黑名单?' : '确认加入黑名单?';
-    pageRef.value?.operatBatch({ title, method: 'post', url, row });
-  }
-  //回收操作
-  function handleOptRecycle(row) {
-    let selections = row ? [row] : pageRef.value?.getSelections();
-    let ids = selections.map((item) => item.id).join(',');
-    let url = `/book/bookInfo/recycle/${ids}`;
-    let title = '确认回收?';
-    pageRef.value?.operatBatch({ title, method: 'post', url, row });
-  }
+  // 使用图书操作混入
+  const {
+    blacklistRef,
+    discountRef,
+    paramsRef,
+    handleOptBooklist,
+    handleOptBlacklist,
+    handleAddDiscount,
+    handleSetParams,
+    handleOptType,
+    handleOptRecycle
+  } = useBookOperation(pageRef);
 
   //查看详情
   const logRef = ref(null);

+ 6 - 163
src/views/recycleAffairs/intercept/index.vue

@@ -1,177 +1,20 @@
 <template>
-  <order-page ref="pageRef" :pageConfig="pageConfig">
-    <template #toolbar>
-      <el-button
-        type="warning"
-        plain
-        v-permission="'recycleOrder:awaitDelivery:batchAudit'"
-        @click="handleBatchAudit"
-      >
-        批量初审
-      </el-button>
-      <el-button
-        type="success"
-        plain
-        v-permission="'recycleOrder:awaitDelivery:batchReceive'"
-        @click="handleBatchReceive()"
-      >
-        批量确认收货
-      </el-button>
-    </template>
-
-    <template #action="{ row }">
-      <div>
-        <el-button
-          type="success"
-          link
-          v-permission="'recycleOrder:awaitDelivery:detail'"
-          @click="toOrderDetail(row)"
-        >
-          [订单详情]
-        </el-button>
-        <el-button
-          type="warning"
-          link
-          v-permission="'recycleOrder:awaitDelivery:log'"
-          @click="openOrderLog(row)"
-        >
-          [订单日志]
-        </el-button>
-        <el-button
-          type="danger"
-          link
-          v-permission="'recycleOrder:awaitDelivery:cancel'"
-          @click="cancelOrder(row)"
-        >
-          [取消订单]
-        </el-button>
-        <el-button
-          type="primary"
-          link
-          v-permission="'recycleOrder:awaitDelivery:fallback'"
-          @click="fallbackOrder(row)"
-        >
-          [回退状态]
-        </el-button>
-        <el-button
-          type="warning"
-          link
-          v-permission="'recycleOrder:awaitDelivery:userTag'"
-          @click="openEditUserTag(row)"
-        >
-          [用户标签]
-        </el-button>
-        <el-button
-          type="success"
-          link
-          v-permission="'recycleOrder:awaitDelivery:receive'"
-          @click="handleBatchReceive(row)"
-        >
-          [确认收货]
-        </el-button>
-        <el-button
-          type="danger"
-          link
-          v-permission="'recycleOrder:awaitDelivery:interception'"
-          @click="applyForInterception(row)"
-        >
-          [申请拦截退回]
-        </el-button>
-      </div>
-    </template>
-
-    <order-log ref="orderLogRef" />
-    <userBindTag ref="userTagRef" />
+  <order-page ref="pageRef" :pageConfig="pageConfig" permissionKey="waitIntercept">
   </order-page>
 </template>
 
 <script setup>
   import { ref, reactive } from 'vue';
-  import { ElMessageBox } from 'element-plus/es';
-  import { EleMessage } from 'ele-admin-plus/es';
-  import { DownloadOutlined } from '@/components/icons';
-  import OrderPage from '@/views/recycleOrder/components/order-page.vue';
-  import { useDictData } from '@/utils/use-dict-data';
-  import { useRouter } from 'vue-router';
-
-  //订单日志
-  import orderLog from '@/views/recycleOrder/components/order-log.vue';
-  //用户标签
-  import userBindTag from '@/views/recycleOrder/components/user-bind-tag.vue';
+  import OrderPage from '@/views/recycleOrder/components/order-page-all.vue';
 
-  defineOptions({ name: 'recycleOrderawaitDelivery' });
+  defineOptions({ name: 'recycleOrderawaitIntercept' });
 
-  let router = useRouter();
   /** 页面组件实例 */
   const pageRef = ref(null);
 
   const pageConfig = reactive({
-    pageUrl: '',
-    exportUrl: '',
-    fileName: '待签收订单',
-    cacheKey: 'awaitDeliveryTable'
+    pageUrl: '/order/orderInfo/waitInterceptList',
+    fileName: '拦截退回订单',
+    cacheKey: 'awaitInterceptTable'
   });
-
-  //批量初审
-  function handleBatchAudit() {
-    pageRef.value?.operatBatch({
-      title: '确认批量审核?',
-      url: '/recycleOrder/batchAudit'
-    });
-  }
-
-  //批量取消订单
-  function handleBatchReceive(row) {
-    pageRef.value?.operatBatch({
-      title: '确认收货?',
-      row,
-      url: '/recycleOrder/batchAudit'
-    });
-  }
-
-  //订单详情
-  function toOrderDetail(row) {
-    router.push({ path: '/recycleOrder/detail', query: { id: row.postId } });
-  }
-
-  //订单日志
-  const orderLogRef = ref(null);
-  function openOrderLog(row) {
-    console.log(row, orderLogRef.value, 'row');
-
-    orderLogRef.value?.handleOpen(row);
-  }
-
-  //用户绑定标签
-  const userTagRef = ref(null);
-  function openEditUserTag(row) {
-    userTagRef.value?.handleOpen(row);
-  }
-
-  function messageBoxConfirm({ message, url, row }) {
-    ElMessageBox.confirm(message, '提示', {
-      confirmButtonText: '确定',
-      cancelButtonText: '关闭',
-      type: 'warning'
-    }).then(() => {
-      console.log(row, 'row');
-    });
-  }
-
-  //取消订单
-  function cancelOrder(row) {
-    messageBoxConfirm({ message: '确认取消?', url: '', row });
-  }
-  //回退状态
-  function fallbackOrder(row) {
-    messageBoxConfirm({ message: '确认回退状态?', url: '', row });
-  }
-  //确认收货
-  function materialPickup(row) {
-    messageBoxConfirm({ message: '确认收货?', url: '', row });
-  }
-  //申请拦截退回
-  function applyForInterception(row) {
-    messageBoxConfirm({ message: '确认申请拦截退回?', url: '', row });
-  }
 </script>

+ 4 - 3
src/views/recycleOrder/components/after-sales-payment.vue

@@ -43,7 +43,9 @@
         </el-input-number>
         <el-text style="margin: 0 16px 0 5px">元</el-text>
         <el-text size="small" type="info">
-          剩余可补款金额:<span style="color: red">{{ orderData.canBackMoney }}元</span>
+          剩余可补款金额:<span style="color: red"
+            >{{ orderData.canBackMoney }}元</span
+          >
           书籍补款金额≤预估金额-审核金额-理赔金额。大于0,可精确到小数点后两位。</el-text
         >
       </el-form-item>
@@ -183,8 +185,7 @@
 
   /** 弹窗打开事件 */
   const handleOpen = (row) => {
-    resetForm();
-    if (row.orderId) {
+    if (row && row.orderId) {
       visible.value = true;
       form.orderId = row.orderId;
       getPayInBackInfo(row.orderId);

+ 1 - 1
src/views/recycleOrder/components/applyfor-order-claim.vue

@@ -156,7 +156,7 @@
 
   /** 弹窗打开事件 */
   const handleOpen = (row) => {
-    if (row.orderId) {
+    if (row && row.orderId) {
       visible.value = true;
       form.orderId = row.orderId;
       getClaimRecords(row.orderId);

+ 2 - 0
src/views/recycleOrder/components/first-check-modal.vue

@@ -57,6 +57,8 @@ const baseUrl = reactive({
 });
 const formData = ref({
     orderIds: '',
+    godownId: 1,
+    finalExpress: '3',
     auditStatus: '1'
 });
 

+ 5 - 1
src/views/recycleOrder/components/order-page-all.vue

@@ -27,6 +27,10 @@
             type="tag"
             :model-value="row.status"
           />
+          <div v-if="row.status == 4 && row.auditRejectReason">
+            原因:
+            <el-text type="info">{{ row.auditRejectReason }}</el-text>
+          </div>
         </template>
         <template #orderNumber="{ row }">
           <order-number :row="row"></order-number>
@@ -365,7 +369,7 @@
       label: '状态',
       prop: 'status',
       slot: 'status',
-      width: '140'
+      width: '166'
     },
     { label: '时间', prop: 'time', slot: 'time', minWidth: 210 },
     { label: '备注', prop: 'remarks', slot: 'remarks' },

+ 15 - 1
src/views/recycleOrder/detail/index.vue

@@ -7,7 +7,13 @@
             <orderBaseInfo :detail="detail"  />
         </ele-card>
         <ele-card class="order-book-list" header="图书清单" :body-style="{ paddingTop: '15px' }">
-            <orderBookList :detail="detail" @refresh="emit('refresh')" ref="bookListRef" @close="emit('close')" />
+            <template #extra v-if="detail.status < 8">
+                <el-button type="danger" v-if="!isExpand" @click="handleExpand">展开列表>></el-button>
+                <el-button type="danger" v-else @click="handleCollapse">折叠列表>></el-button>
+            </template>
+
+            <orderBookList :isExpand="isExpand" :detail="detail" @refresh="emit('refresh')" ref="bookListRef"
+                @close="emit('close')" />
         </ele-card>
 
         <ele-card class="order-service" header="订单服务">
@@ -39,6 +45,14 @@ const props = defineProps({
     },
 });
 
+const isExpand = ref(false);
+const handleExpand = () => {
+    isExpand.value = true;
+};
+const handleCollapse = () => {
+    isExpand.value = false;
+};
+
 // 其余审核良好
 const bookListRef = ref(null);
 function handleOtherAuditGood() {

+ 65 - 14
src/views/recycleOrder/detail/order-book-list.vue

@@ -4,7 +4,7 @@
         <template #baseInfo="{ row }">
             <div class="base-info flex justify-between">
                 <div class="base-info-left flex flex-1">
-                    <el-image style="width: 80px; height: 100px" fit="cover" :src="row.cover" />
+                    <el-image style="min-width: 80px;width: 80px; height: 100px" fit="cover" :src="row.cover" />
                     <div class="base-info-left-con flex flex-col items-start ml-3">
                         <div><el-text type="primary">{{ row.bookName }}</el-text></div>
                         <div><el-text>ISBN:{{ row.isbn }}</el-text></div>
@@ -84,7 +84,7 @@
 </template>
 
 <script setup>
-import { ref, reactive, watch, nextTick } from 'vue';
+import { ref, reactive, watch, nextTick, onMounted } from 'vue';
 import orderModifyDiscount from '@/views/recycle/components/modify-discount.vue';
 import orderBlacklist from '@/views/recycleOrder/detail/order-blacklist.vue';
 import orderRecycleLog from '@/views/recycleOrder/detail/order-recycle-log.vue';
@@ -98,6 +98,10 @@ const props = defineProps({
         default: () => ({
             detailVoList: []
         })
+    },
+    isExpand: {
+        type: Boolean,
+        default: false
     }
 });
 const dataList = ref([]);
@@ -131,17 +135,63 @@ const processDetailList = (list) => {
     return result;
 };
 
-// 修改watch为immediate模式,并使用nextTick
+// 初始化数据
+const initData = () => {
+    const list = props.detail.detailVoList || [];
+    console.log('Initializing data with list:', list);
+
+    if (props.isExpand) {
+        dataList.value = processDetailList(list);
+    } else {
+        const processedList = [];
+        list.forEach(item => {
+            processedList.push({
+                ...item,
+                _index: 0,
+                _groupIndex: processedList.length,
+                _isFirstRow: true,
+                sts: item.auditCommentList && item.auditCommentList[0] ? item.auditCommentList[0].sts : 0,
+                com: item.auditCommentList && item.auditCommentList[0] && item.auditCommentList[0].com ?
+                    (typeof item.auditCommentList[0].com === 'string' ?
+                        item.auditCommentList[0].com.split(',').filter(Boolean) :
+                        item.auditCommentList[0].com) :
+                    []
+            });
+        });
+        dataList.value = processedList;
+    }
+
+    console.log('Initialized dataList:', dataList.value);
+};
+
+// 组件挂载时初始化数据
+onMounted(() => {
+    initData();
+});
+
+// 添加对detail.detailVoList的监听,确保弹窗打开时数据能正确显示
 watch(() => props.detail.detailVoList, (newVal) => {
     if (!newVal) return;
-    nextTick(() => {
-        dataList.value = processDetailList(newVal);
-    });
+    console.log('detail.detailVoList changed:', newVal);
+    initData();
+}, { immediate: true, deep: true });
+
+watch(() => props.isExpand, (newVal) => {
+    console.log('isExpand changed:', newVal);
+    initData();
 }, { deep: true, immediate: true });
 
 // 处理单元格合并
 const handleSpanMethod = ({ row, column, rowIndex }) => {
     if (column.property === 'num') {
+        // 确保行有必要的属性
+        if (!row._groupIndex && row._groupIndex !== 0) {
+            return {
+                rowspan: 1,
+                colspan: 1
+            };
+        }
+
         // 找到当前行所在组的所有行
         const currentGroup = dataList.value.filter(item => item._groupIndex === row._groupIndex);
         if (row._isFirstRow) {
@@ -235,7 +285,7 @@ function handleSelectReason(value, row) {
     }
 }
 
-const emit = defineEmits(['update:detail', 'refresh']);
+const emit = defineEmits(['update:detail', 'refresh', 'close']);
 
 const columns = ref([
     {
@@ -373,8 +423,15 @@ const handleRefresh = (type) => {
     }
 };
 
+// 手动刷新数据
+const refreshData = () => {
+    console.log('Manual refresh triggered');
+    initData();
+};
+
 defineExpose({
-    handleOtherAuditGood
+    handleOtherAuditGood,
+    refreshData
 });
 </script>
 
@@ -415,12 +472,6 @@ defineExpose({
                 border-bottom: none;
             }
         }
-
-        .first-row~tr {
-            td.el-table__cell:nth-child(4) {
-                display: none;
-            }
-        }
     }
 }
 </style>

+ 18 - 13
src/views/recycleOrder/needReturned/index.vue

@@ -14,8 +14,18 @@
         highlight-current-row
         :export-config="{ fileName: '需退回订单' }"
         cache-key="needReturnedTable"
-        :tools="false"
       >
+        <template #toolbar>
+          <!-- 0-创建(待付款) 1-已付款 2-已推送 3-已发货 4-已签收 5-已完成 6-已取消 7-超时取消 -->
+          <el-radio-group v-model="status" @change="handleStatusChange">
+            <el-radio-button label="全部" value="" />
+            <el-radio-button label="待发货" value="1" />
+            <el-radio-button label="已发货" value="3" />
+            <el-radio-button label="已完成" value="5" />
+            <el-radio-button label="已取消" value="6" />
+          </el-radio-group>
+        </template>
+
         <template #status="{ row }">
           <dict-data
             code="refund_status"
@@ -124,7 +134,7 @@
   import { ref, getCurrentInstance } from 'vue';
   import { EleMessage } from 'ele-admin-plus/es';
   import { ElMessageBox } from 'element-plus/es';
-  import { Flag, ChatDotSquare } from '@element-plus/icons-vue';
+  import { Flag } from '@element-plus/icons-vue';
   import returnSearch from './return-search.vue';
   import OrderNumber from '@/views/recycleOrder/components/order-number.vue';
   import RefundCustomer from '@/views/recycleOrder/components/refund-customer.vue';
@@ -136,9 +146,6 @@
   //订单详情
   import orderRefundDetail from '@/views/recycleOrder/needReturned/order-refund-detail.vue';
 
-  import { useRouter } from 'vue-router';
-  let router = useRouter();
-
   let props = defineProps({
     pageConfig: {
       type: Object,
@@ -147,8 +154,7 @@
         fileName: '需退回订单'
       })
     },
-    pageUrl: { type: String, default: '/order/orderInfo/refund/pageList' },
-    exportUrl: { type: String, default: '/system/post/export' }
+    pageUrl: { type: String, default: '/order/orderInfo/refund/pageList' }
   });
   let { proxy } = getCurrentInstance();
   /** 字典数据 */
@@ -157,6 +163,11 @@
   /** 表格实例 */
   const tableRef = ref(null);
 
+  const status = ref('');
+  function handleStatusChange(val) {
+    reload({ status: val });
+  }
+
   /** 表格列配置 */
   const columns = ref([
     {
@@ -203,12 +214,6 @@
   /** 表格选中数据 */
   const selections = ref([]);
 
-  /** 当前编辑数据 */
-  const current = ref(null);
-
-  /** 是否显示编辑弹窗 */
-  const showEdit = ref(false);
-
   async function queryPage(params) {
     const res = await proxy.$http.get(props.pageUrl, { params });
     if (res.data.code === 200) {