Pārlūkot izejas kodu

修改图书库存的明细

Alex 9 mēneši atpakaļ
vecāks
revīzija
0a3526e09b

+ 126 - 0
src/views/recycle/inventory/components/recycle-detail.vue

@@ -0,0 +1,126 @@
+<!-- 回收明细弹窗 -->
+<template>
+  <ele-modal
+    v-model="visible"
+    title="回收明细"
+    width="80%"
+    @open="handleDialogOpen"
+  >
+    <!-- 使用抽取出的搜索组件 -->
+    <recycle-search
+      ref="searchRef"
+      @search="handleSearchParams"
+    ></recycle-search>
+
+    <common-table
+      ref="tableRef"
+      :pageConfig="pageConfig"
+      :columns="columns"
+      :tools="false"
+    >
+      <template #status="{ row }">
+        <dict-data code="order_status" type="text" :model-value="row.status" />
+      </template>
+
+      <template #recipientGodown="{ row }">
+        <div>{{ row.recipientGodown }} - {{ row.recipientName }}</div>
+      </template>
+    </common-table>
+
+    <template #footer>
+      <el-button @click="visible = false">关闭</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script setup>
+  import { ref, reactive, defineExpose } from 'vue';
+  import CommonTable from '@/components/CommonPage/CommonTable.vue';
+  import RecycleSearch from './recycle-search.vue';
+
+  defineOptions({ name: 'RecycleDetail' });
+
+  // 弹窗可见性
+  const visible = ref(false);
+  // 当前查看的图书信息
+  const currentBook = ref(null);
+  // 查询参数
+  const queryParams = reactive({
+    isbn: ''
+  });
+
+  // 表格组件实例
+  const tableRef = ref(null);
+  // 搜索组件实例
+  const searchRef = ref(null);
+
+  // 表格列配置
+  const columns = ref([
+    { label: '订单号', prop: 'orderId',align:'center' },
+    { label: '用户名', prop: 'userNick',align:'center' },
+    { label: '预估价格', prop: 'expectMoney',align:'center' },
+    { label: '预估本数', prop: 'totalNum',align:'center' },
+    { label: '回收本数', prop: 'recycleBookNum',align:'center' },
+    { label: '审核金额', prop: 'auditMoney',align:'center' },
+    { label: '发货人', prop: 'sendName',align:'center' },
+    { label: '手机号', prop: 'sendMobile',align:'center' },
+    { label: '发货地址', prop: 'sendSsq',minWidth: 120,align:'center' },
+    { label: '收货仓库', prop: 'recipientGodown', slot: 'recipientGodown',align:'center' },
+    { label: '订单状态', prop: 'status', slot: 'status',minWidth:120,align:'center' },
+    { label: '提交时间', prop: 'orderTime',width:160,align:'center' }
+  ]);
+
+  // 页面配置
+  const pageConfig = reactive({
+    pageUrl: '/order/orderInfo/getOrderInfoByIsbn',
+    fileName: '回收明细',
+    cacheKey: 'recycle-detail-data',
+    params: {
+      isbn: ''
+    }
+  });
+
+  // 处理搜索组件参数
+  function handleSearchParams(params) {
+    Object.assign(queryParams, params);
+    reload();
+  }
+
+  // 刷新表格
+  function reload() {
+    tableRef.value?.reload(queryParams);
+  }
+
+  // 新增弹窗打开处理函数
+  function handleDialogOpen() {
+    // 加载数据
+    reload();
+  }
+
+  // 打开弹窗
+  function handleOpen(row) {
+    if (!row) return;
+    currentBook.value = row;
+    queryParams.isbn = row.bookIsbn;
+    pageConfig.params.isbn = row.bookIsbn;
+    visible.value = true;
+
+    // 重置搜索组件
+    searchRef.value?.reset();
+
+    // 重置其他查询条件,但保留isbn
+    Object.keys(queryParams).forEach((key) => {
+      if (key !== 'isbn') {
+        queryParams[key] = '';
+      }
+    });
+  }
+
+  defineExpose({
+    handleOpen
+  });
+</script>
+
+<style lang="scss" scoped>
+  /* 移除原dialog样式 */
+</style>

+ 70 - 0
src/views/recycle/inventory/components/recycle-search.vue

@@ -0,0 +1,70 @@
+<!-- 回收明细搜索组件 -->
+<template>
+  <ele-card :body-style="{ paddingBottom: '8px' }">
+    <ProSearch
+      :items="formItems"
+      ref="searchRef"
+      @search="search"
+      :initKeys="initKeys"
+    ></ProSearch>
+  </ele-card>
+</template>
+
+<script setup>
+  import { reactive, ref, defineEmits, getCurrentInstance } from 'vue';
+  import ProSearch from '@/components/CommonPage/ProSearch2.vue';
+
+  defineOptions({ name: 'RecycleSearch' });
+  
+  let { proxy } = getCurrentInstance();
+  const emit = defineEmits(['search']);
+
+  const formItems = reactive([
+    { type: 'input', label: '发货人姓名', prop: 'sendName' },
+    { type: 'input', label: '发货人电话', prop: 'sendMobile' },
+    { type: 'input', label: '发货人地址', prop: 'sendSsq' },
+    {
+      type: 'daterange',
+      label: '日期范围',
+      prop: 'dateRange',
+      keys: ['startTime', 'endTime'],
+      colProps: { span: 6 },
+      props: {
+        format: 'YYYY-MM-DD',
+        valueFormat: 'YYYY-MM-DD',
+        onChange: (val) => {
+          searchRef.value?.setData({
+            startTime: val && val.length > 0 ? val[0] : '',
+            endTime: val && val.length > 0 ? val[1] : ''
+          });
+        }
+      }
+    }
+  ]);
+
+  const initKeys = reactive({
+    sendName: '',
+    sendMobile: '',
+    sendSsq: '',
+    startTime: '',
+    endTime: ''
+  });
+
+  const searchRef = ref(null);
+  
+  /** 搜索 */
+  const search = (data) => {
+    let params = JSON.parse(JSON.stringify(data));
+    delete params.dateRange;
+    emit('search', params);
+  };
+
+  /** 重置 */
+  const reset = () => {
+    searchRef.value?.reset();
+  };
+
+  defineExpose({
+    reset
+  });
+</script> 

+ 140 - 0
src/views/recycle/inventory/components/sale-detail.vue

@@ -0,0 +1,140 @@
+<!-- 销售明细弹窗 -->
+<template>
+  <ele-modal
+    v-model="visible"
+    title="销售明细"
+    :width="1440"
+    @open="handleDialogOpen"
+  >
+    <!-- 使用抽取出的搜索组件 -->
+    <sale-search ref="searchRef" @search="handleSearchParams"></sale-search>
+
+    <common-table
+      ref="tableRef"
+      :pageConfig="pageConfig"
+      :columns="columns"
+      :tools="false"
+    >
+      <template #receiverInfo="{ row }">
+        <div>{{ row.receiverName }}</div>
+        <div>{{ row.receiverPhone }}</div>
+      </template>
+
+      <template #receiverAddress="{ row }">
+        <div>{{
+          row.receiverProvince + row.receiverCity + row.receiverArea
+        }}</div>
+        <div>{{ row.receiverAddress }}</div>
+      </template>
+    </common-table>
+
+    <template #footer>
+      <el-button @click="visible = false">关闭</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script setup>
+  import { ref, reactive, defineExpose } from 'vue';
+  import CommonTable from '@/components/CommonPage/CommonTable.vue';
+  import SaleSearch from './sale-search.vue';
+
+  defineOptions({ name: 'SaleDetail' });
+
+  // 弹窗可见性
+  const visible = ref(false);
+  // 当前查看的图书信息
+  const currentBook = ref(null);
+  // 查询参数
+  const queryParams = reactive({
+    bookId: ''
+  });
+
+  // 表格组件实例
+  const tableRef = ref(null);
+  // 搜索组件实例
+  const searchRef = ref(null);
+
+  // 表格列配置
+  const columns = ref([
+    { label: '订单号', prop: 'orderNo', align: 'center' },
+    { label: '用户名', prop: 'userName', align: 'center' },
+    {
+      label: '单价',
+      prop: 'salePrice',
+      align: 'center',
+      formatter: (row) => '¥' + (row?.salePrice || 0)
+    },
+    { label: '数量', prop: 'saleCount', align: 'center' },
+    {
+      label: '收货人',
+      prop: 'receiverInfo',
+      slot: 'receiverInfo',
+      align: 'center'
+    },
+    { label: '手机号', prop: 'receiverPhone', align: 'center' },
+    {
+      label: '收货地址',
+      prop: 'receiverAddress',
+      slot: 'receiverAddress',
+      align: 'center',
+      minWidth: 120
+    },
+    { label: '订单状态', prop: 'orderStatus', align: 'center' },
+    { label: '提交时间', prop: 'createTime', align: 'center', width: 160 }
+  ]);
+
+  // 页面配置
+  const pageConfig = reactive({
+    pageUrl: '/book/sale/detail/pagelist',
+    fileName: '销售明细',
+    cacheKey: 'sale-detail-data',
+    params: {
+      bookId: ''
+    }
+  });
+
+  // 处理搜索组件参数
+  function handleSearchParams(params) {
+    Object.assign(queryParams, params);
+    reload();
+  }
+
+  // 刷新表格
+  function reload() {
+    tableRef.value?.reload(queryParams);
+  }
+
+  // 弹窗打开处理函数
+  function handleDialogOpen() {
+    // 加载数据
+    reload();
+  }
+
+  // 打开弹窗
+  function handleOpen(row) {
+    if (!row) return;
+    currentBook.value = row;
+    queryParams.bookId = row.id;
+    pageConfig.params.bookId = row.id;
+    visible.value = true;
+
+    // 重置搜索组件
+    searchRef.value?.reset();
+
+    // 重置其他查询条件,但保留bookId
+    Object.keys(queryParams).forEach((key) => {
+      if (key !== 'bookId') {
+        queryParams[key] = '';
+      }
+    });
+  }
+
+  defineExpose({
+    handleOpen
+  });
+</script>
+
+<style lang="scss" scoped>
+  /* 移除原dialog样式 */
+</style>

+ 70 - 0
src/views/recycle/inventory/components/sale-search.vue

@@ -0,0 +1,70 @@
+<!-- 销售明细搜索组件 -->
+<template>
+  <ele-card :body-style="{ paddingBottom: '8px' }">
+    <ProSearch
+      :items="formItems"
+      ref="searchRef"
+      @search="search"
+      :initKeys="initKeys"
+    ></ProSearch>
+  </ele-card>
+</template>
+
+<script setup>
+  import { reactive, ref, defineEmits, getCurrentInstance } from 'vue';
+  import ProSearch from '@/components/CommonPage/ProSearch2.vue';
+
+  defineOptions({ name: 'SaleSearch' });
+  
+  let { proxy } = getCurrentInstance();
+  const emit = defineEmits(['search']);
+
+  const formItems = reactive([
+    { type: 'input', label: '订单号', prop: 'orderNo' },
+    { type: 'input', label: '收货人', prop: 'receiverName' },
+    { type: 'input', label: '收货电话', prop: 'receiverPhone' },
+    {
+      type: 'daterange',
+      label: '下单时间',
+      prop: 'dateRange',
+      keys: ['createTimeStart', 'createTimeEnd'],
+      colProps: { span: 6 },
+      props: {
+        format: 'YYYY-MM-DD',
+        valueFormat: 'YYYY-MM-DD',
+        onChange: (val) => {
+          searchRef.value?.setData({
+            createTimeStart: val && val.length > 0 ? val[0] : '',
+            createTimeEnd: val && val.length > 0 ? val[1] : ''
+          });
+        }
+      }
+    }
+  ]);
+
+  const initKeys = reactive({
+    orderNo: '',
+    receiverName: '',
+    receiverPhone: '',
+    createTimeStart: '',
+    createTimeEnd: ''
+  });
+
+  const searchRef = ref(null);
+  
+  /** 搜索 */
+  const search = (data) => {
+    let params = JSON.parse(JSON.stringify(data));
+    delete params.dateRange;
+    emit('search', params);
+  };
+
+  /** 重置 */
+  const reset = () => {
+    searchRef.value?.reset();
+  };
+
+  defineExpose({
+    reset
+  });
+</script> 

+ 17 - 0
src/views/recycle/inventory/index.vue

@@ -87,6 +87,8 @@
       @done="reload()"
     ></books-import>
     <book-check-new ref="checkNewRef"></book-check-new>
+    <recycle-detail ref="recycleDetailRef"></recycle-detail>
+    <sale-detail ref="saleDetailRef"></sale-detail>
   </ele-page>
 </template>
 
@@ -97,6 +99,7 @@
     UploadOutlined,
     CloudUploadOutlined
   } from '@/components/icons';
+  import { ElMessage } from 'element-plus';
   import pageSearch from './components/page-search.vue';
   import CommonTable from '@/components/CommonPage/CommonTable.vue';
   import booksEdit from '@/views/data/books/components/books-edit.vue';
@@ -104,6 +107,8 @@
   import bookBaseInfo from './components/book-base-info.vue';
   import bookCheckNew from './components/book-check-new.vue';
   import bookStock from './components/book-stock.vue';
+  import recycleDetail from './components/recycle-detail.vue';
+  import saleDetail from './components/sale-detail.vue';
   import { useDictData } from '@/utils/use-dict-data';
 
   defineOptions({ name: 'recycleOrderCancelled' });
@@ -199,4 +204,16 @@
   function handleCheckNew() {
     checkNewRef.value?.handleOpen();
   }
+
+  //回收明细
+  const recycleDetailRef = ref(null);
+  function handleRecycleDetail(row) {
+    recycleDetailRef.value?.handleOpen(row);
+  }
+  
+  //销售明细
+  const saleDetailRef = ref(null);
+  function handleSaleDetail(row) {
+    saleDetailRef.value?.handleOpen(row);
+  }
 </script>

+ 1 - 1
src/views/recycleOrder/components/order-detail.vue

@@ -2,7 +2,7 @@
 <template>
   <ele-modal
     form
-    :width="1460"
+    :width="1560"
     v-model="visible"
     title="订单详情"
     @open="handleOpen"

+ 16 - 10
src/views/recycleOrder/detail/order-book-list.vue

@@ -17,9 +17,12 @@
           />
           <div class="base-info-left-con flex flex-col items-start ml-3">
             <div
-              ><el-text type="primary" style="cursor: pointer" @click="handleBooksEdit(row)">{{
-                row.bookName
-              }}</el-text></div
+              ><el-text
+                type="primary"
+                style="cursor: pointer"
+                @click="handleBooksEdit(row)"
+                >{{ row.bookName }}</el-text
+              ></div
             >
             <div
               ><el-text>ISBN:{{ row.isbn }}</el-text></div
@@ -71,7 +74,7 @@
             >
           </div>
         </div>
-        <div class="base-info-right w-36 shrink-0">
+        <div class="base-info-right w-50 shrink-0" style="min-width: 210px;">
           <div class="common-text flex">
             <el-text>定  价:</el-text>
             <el-text>¥ {{ row.bookPrice }}</el-text>
@@ -79,6 +82,9 @@
           <div class="common-text flex">
             <el-text>回收折扣:</el-text>
             <el-text>¥ {{ row.recycleDiscount }}折</el-text>
+            <el-text v-if="row.sugDiscountStr" style="color: #f56c6c;margin-left: 10px;"
+              >{{ row.sugDiscountStr }}</el-text
+            >
           </div>
           <div class="common-text flex">
             <el-text>预估金额:</el-text>
@@ -418,7 +424,7 @@
     {
       label: '数量',
       prop: 'num',
-      minWidth: 90,
+      minWidth: 80,
       align: 'center',
       formatter: (row) => {
         return `× ${row.num}`;
@@ -429,13 +435,13 @@
       prop: 'auditInfo',
       slot: 'auditInfo',
       align: 'center',
-      minWidth: 317
+      minWidth: 260
     },
     {
       label: '审核金额',
       prop: 'recyclePrice',
       align: 'center',
-      minWidth: 100,
+      minWidth: 90,
       formatter: (row) => {
         return row.sts == 1 ? `¥ ${row.recyclePrice}` : '0';
       }
@@ -577,11 +583,11 @@
 
   .class-red {
     :deep(.el-radio.is-checked .el-radio__inner) {
-      background: #F56C6C;
-      border-color: #F56C6C;
+      background: #f56c6c;
+      border-color: #f56c6c;
     }
     :deep(.el-radio__input.is-checked + .el-radio__label) {
-      color: #F56C6C;
+      color: #f56c6c;
     }
   }