ソースを参照

物资使用说明修改h5编辑器 基础数据统计导出 领取归还统计导出

pm 8 ヶ月 前
コミット
2a67095c90

+ 1 - 0
src/api/mes/statisticians/index.js

@@ -76,3 +76,4 @@ export function getInventorySum(){
     method: 'get',
   })
 }
+

+ 1 - 1
src/components/tinymce/config.js

@@ -4,5 +4,5 @@ export const plugins = [
   'advlist anchor autolink autosave code codesample directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textpattern visualblocks visualchars wordcount'
 ]
 export const toolbar = [
-  'code searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote removeformat subscript superscript codesample hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'
+  'code searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent | fontselect fontsizeselect formatselect | blockquote removeformat subscript superscript codesample hr | bullist numlist  | link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'
 ]

+ 47 - 25
src/components/tinymce/example/Index.vue

@@ -1,54 +1,76 @@
 <template>
   <div>
-    <Tinymce v-model="defaultValue" :height="660" placeholder="在这里输入文字" />
+    <Tinymce v-model="defaultValue" :height="750" placeholder="在这里输入文字"/>
     <el-button type="primary" style="float:right;margin: 10px" @click="save">保存</el-button>
+    <el-button v-if="this.$route.query.instructionsId" style="float:right;margin-top: 10px" type="warning"
+               @click="goBack"
+    >返回
+    </el-button>
   </div>
 </template>
 
 <script>
 import Tinymce from '../index.vue'
-import {updateTechnology,getTechnologyInfo} from "../../../api/system/machinery"
+import { updateTechnology, getTechnologyInfo } from '../../../api/system/machinery'
+import { getInstructionsInfo, updateInstructions } from '../../../api/mes/instructions'
 
 export default {
   components: {
     Tinymce
-  },
-  props: {
-
   },
   data() {
     return {
       defaultValue: '',
-      form:null,
+      form: null
     }
   },
-  computed: {
-
-  },
-  watch: {
+  computed: {},
 
-  },
   created() {
-  this.getInfo()
+    this.getInfo()
   },
   mounted() {
 
   },
   methods: {
-    getInfo(){
-      getTechnologyInfo(this.$route.query.machineryId).then((response) => {
-        this.form=response.data
-        this.defaultValue=response.data.remark
-      })
+    getInfo() {
+      if (this.$route.query.machineryId) {
+        getTechnologyInfo(this.$route.query.machineryId).then((response) => {
+          this.form = response.data
+          this.defaultValue = response.data.remark
+        })
+      } else if (this.$route.query.instructionsId) {
+        getInstructionsInfo(this.$route.query.instructionsId).then((response) => {
+          console.log(response, '物资使用说明')
+          this.form = response.data
+          this.defaultValue = response.data.remark
+        })
+      }
+
+    },
+    save() {
+      console.log(this.defaultValue, '拿到的设备工艺 信息------')
+      if (this.$route.query.machineryId) {
+        this.form.remark = this.defaultValue
+        updateTechnology(this.form).then(response => {
+          console.log(response, '更新设备工艺')
+          if (response.data) {
+            this.$message.success('保存成功')
+          }
+        })
+      } else {
+        this.form.remark = this.defaultValue
+        updateInstructions(this.form).then(response => {
+          console.log(response, '更新物资使用说明')
+          if (response.data) {
+            this.$message.success('保存成功')
+          }
+        })
+      }
+
     },
-    save(){
-      this.form.remark=this.defaultValue
-      updateTechnology(this.form).then(response => {
-        console.log(response,'更新设备工艺')
-        if(response.data){
-          this.$message.success('保存成功')
-        }
-      })
+    goBack() {
+      this.$router.push('/material/instructions')
     }
   }
 }

+ 76 - 45
src/components/tinymce/index.vue

@@ -1,88 +1,119 @@
 <template>
-  <textarea :id="tinymceId" style="visibility: hidden;" />
+  <textarea  :id="tinymceId" style="visibility: hidden;"/>
 </template>
 
 <script>
-import loadTinymce from "@/utils/utilsJson/loadTinymce";
-import { plugins, toolbar } from "./config";
-import { debounce } from "throttle-debounce";
+import loadTinymce from '@/utils/utilsJson/loadTinymce'
+import { plugins, toolbar } from './config'
+import { debounce } from 'throttle-debounce'
+import { getToken } from '../../utils/auth'
 
-let num = 1;
+let num = 1
 
 export default {
   props: {
     id: {
       type: String,
       default: () => {
-        num === 10000 && (num = 1);
-        return `tinymce${+new Date()}${num++}`;
-      },
+        num === 10000 && (num = 1)
+        return `tinymce${+new Date()}${num++}`
+      }
     },
     value: {
-      default: "",
-    },
+      default: ''
+    }
   },
   data() {
     return {
-      tinymceId: this.id,
-    };
+      tinymceId: this.id
+    }
   },
   mounted() {
     loadTinymce((tinymce) => {
-      // eslint-disable-next-line global-require
-      require("./zh_CN");
+// eslint-disable-next-line global-require
+      require('./zh_CN')
       let conf = {
         selector: `#${this.tinymceId}`,
-        language: "zh_CN",
-        menubar: "file edit insert view format table",
-        plugins,
-        toolbar,
+        language: 'zh_CN',
+        // 字体列表
+        font_formats:
+          '微软雅黑=微软雅黑; 宋体=宋体; 黑体=黑体; 仿宋=仿宋; 楷体=楷体; 隶书=隶书; 幼圆=幼圆; Andale Mono=andale mono,times; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Symbol=symbol; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Webdings=webdings; Wingdings=wingdings,zapf dingbats',
+// 字体大小列表
+        fontsize_formats: '12px 14px 16px 18px 24px 36px 48px',
+        menubar: 'file edit insert view format table',
+        plugins: plugins + ' image', // 添加 image 插件
+        toolbar:toolbar ,
         height: 300,
         branding: false,
         object_resizing: false,
         end_container_on_empty_block: true,
-        powerpaste_word_import: "clean",
+        powerpaste_word_import: 'clean',
         code_dialog_height: 450,
         code_dialog_width: 1000,
-        advlist_bullet_styles: "square",
-        advlist_number_styles: "default",
-        default_link_target: "_blank",
+        advlist_bullet_styles: 'square',
+        advlist_number_styles: 'default',
+        default_link_target: '_blank',
         link_title: false,
         nonbreaking_force_tab: true,
-      };
-      conf = Object.assign(conf, this.$attrs);
+// 图片上传配置
+        images_upload_url: process.env.VUE_APP_BASE_API + '/common/upload',
+        images_upload_handler: (blobInfo, success, failure) => {
+          const formData = new FormData()
+          formData.append('file', blobInfo.blob(), blobInfo.filename())
+
+          fetch(process.env.VUE_APP_BASE_API + '/common/upload', {
+            method: 'POST',
+            headers: {
+              Authorization: 'Bearer ' + getToken()
+            },
+            body: formData
+          })
+            .then((response) => {
+              if (!response.ok) {
+                throw new Error('Network response was not ok ' + response.statusText)
+              }
+              return response.json()
+            })
+            .then((data) => {
+              success(data.url) // 假设服务器返回的 JSON 中包含图片的 URL
+            })
+            .catch((error) => {
+              failure('上传失败: ' + error.message)
+            })
+        }
+      }
+      conf = Object.assign(conf, this.$attrs)
       conf.init_instance_callback = (editor) => {
-        if (this.value) editor.setContent(this.value);
-        this.vModel(editor);
-      };
-      tinymce.init(conf);
-    });
+        if (this.value) editor.setContent(this.value)
+        this.vModel(editor)
+      }
+      tinymce.init(conf)
+    })
   },
   destroyed() {
-    this.destroyTinymce();
+    this.destroyTinymce()
   },
   methods: {
     vModel(editor) {
-      // 控制连续写入时setContent的触发频率
-      const debounceSetContent = debounce(250, editor.setContent);
-      this.$watch("value", (val, prevVal) => {
+      const debounceSetContent = debounce(250, editor.setContent)
+      this.$watch('value', (val, prevVal) => {
         if (editor && val !== prevVal && val !== editor.getContent()) {
-          if (typeof val !== "string") val = val.toString();
-          debounceSetContent.call(editor, val);
+          if (typeof val !== 'string') val = val.toString()
+          debounceSetContent.call(editor, val)
         }
-      });
+      })
 
-      editor.on("change keyup undo redo", () => {
-        this.$emit("input", editor.getContent());
-      });
+      editor.on('change keyup undo redo', () => {
+        this.$emit('input', editor.getContent())
+      })
     },
     destroyTinymce() {
-      if (!window.tinymce) return;
-      const tinymce = window.tinymce.get(this.tinymceId);
+      if (!window.tinymce) return
+      const tinymce = window.tinymce.get(this.tinymceId)
       if (tinymce) {
-        tinymce.destroy();
+        tinymce.destroy()
       }
-    },
-  },
-};
+    }
+  }
+}
 </script>

+ 1 - 1
src/layout/components/AppMain.vue

@@ -1,7 +1,7 @@
 <template>
   <section class="app-main">
     <transition name="fade-transform" mode="out-in">
-      <keep-alive :include="cachedViews">
+      <keep-alive :include="cachedViews" :exclude="['instructionsDetail']">
         <router-view :key="key" />
       </keep-alive>
     </transition>

+ 15 - 0
src/router/index.js

@@ -218,6 +218,21 @@ export const dynamicRoutes = [
       }
     ]
   },
+  // 物资使用说明详情
+  {
+    path: '/mes/material/instructions',
+    component: Layout,
+    hidden: true,
+    permissions: ['iscs:instructions:list'],
+    children: [
+      {
+        path: 'instructionsDetail',
+        component: () => import('@/views/mes/material/instructions/instructionsDetail'),
+        name: 'instructionsDetail',
+        meta: { title: '物资使用说明详情' }
+      }
+    ]
+  },
   // 设备详情
   {
     path: '/mes/dv/technology/technologyDetail',

+ 1 - 1
src/views/mes/Exceptions/Exception/index.vue

@@ -105,7 +105,7 @@
       :data="ExceptionList"
 
     >
-      <el-table-column label="编号" align="center" prop="exceptionId">
+      <el-table-column label="编号" align="center" prop="misplaceId">
       </el-table-column>
       <el-table-column label="物资柜" align="center" prop="loanFromName" />
 

+ 1 - 1
src/views/mes/Exceptions/doorException/index.vue

@@ -105,7 +105,7 @@
       :data="ExceptionList"
 
     >
-      <el-table-column label="编号" align="center" prop="exceptionId">
+      <el-table-column label="编号" align="center" prop="misplaceId">
       </el-table-column>
       <el-table-column label="物资柜" align="center" prop="loanFromName" />
 

+ 10 - 0
src/views/mes/material/instructions/index.vue

@@ -130,6 +130,11 @@
           >
         </template>
       </el-table-column>
+      <el-table-column label="详情" align="center" prop="fileUrl">
+        <template slot-scope="scope">
+          <el-button type="text" @click="detailCheck(scope.row)">查看</el-button>
+        </template>
+      </el-table-column>
       <el-table-column label="添加时间" prop="createTime" align="center">
       </el-table-column>
       <el-table-column
@@ -392,6 +397,11 @@ export default {
   },
 
   methods: {
+    // 物资使用说明详情
+    detailCheck(row){
+
+      this.$router.push("/mes/material/instructions/instructionsDetail?instructionsId=" + row.instructionsId);
+    },
     isVideo(url) {
       return url && (url.endsWith(".mp4") || url.includes("mp4"));
     },

+ 33 - 0
src/views/mes/material/instructions/instructionsDetail.vue

@@ -0,0 +1,33 @@
+<template>
+  <div>
+    <Tinymce  />
+
+  </div>
+</template>
+<script>
+import Tinymce from '@/components/tinymce/example/Index.vue';
+export default {
+  name: 'instructionsDetail',
+  components: {
+    Tinymce
+  },
+  data(){
+    return {
+
+    }
+  },
+  mounted() {
+
+  },
+  methods: {
+
+  }
+}
+
+</script>
+
+
+
+<style scoped lang="scss">
+
+</style>

+ 12 - 0
src/views/mes/material/inventory/index.vue

@@ -18,7 +18,14 @@
         </template>
       </el-radio-button>
     </el-radio-group>
+    <el-button v-no-more-click
+               type="warning"
+               plain
+               icon="el-icon-download"
+               size="mini"
+               @click="handleExport"
 
+    >导出</el-button>
     <!-- 表格部分 -->
     <div class="table-container">
       <table v-show="currentTab === '0' || currentTab === '1' || currentTab === '3'">
@@ -137,6 +144,11 @@ export default {
     this.getList()
   },
   methods: {
+    handleExport() {
+      this.download('iscs/statistics-api/exportMaterialInventory', {
+        ...this.queryParams
+      }, `物资盘点_${new Date().getTime()}.xlsx`)
+    },
     getList() {
 
       getMaterialInventory(this.currentTab).then(response => {

+ 9 - 2
src/views/mes/statisticians/LockerChange.vue

@@ -12,7 +12,7 @@
 <!--      end-placeholder="结束日期"-->
 <!--      :picker-options="pickerOptions" >-->
 <!--    </el-date-picker>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%; height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -162,7 +162,7 @@ export default {
         // },
         legend: {
           data: ['正常更换次数','过期更换次数','损坏更换次数'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -174,6 +174,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',

+ 11 - 4
src/views/mes/statisticians/LockerCollection.vue

@@ -12,7 +12,7 @@
 <!--      end-placeholder="结束日期"-->
 <!--      :picker-options="pickerOptions" >-->
 <!--    </el-date-picker>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%; height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -160,8 +160,8 @@ export default {
         //   }
         // },
         legend: {
-          data: ['累计领取次数'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          data: ['领取次数'],
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -173,6 +173,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',
@@ -187,7 +194,7 @@ export default {
         ],
         series: [
           {
-            name: '开关次数',  // 修改为适当的名称
+            name: '领取次数',  // 修改为适当的名称
             type: 'bar',
             barWidth: '25%',
             tooltip: {

+ 9 - 2
src/views/mes/statisticians/LockerDaily.vue

@@ -12,7 +12,7 @@
 <!--      end-placeholder="结束日期"-->
 <!--      :picker-options="pickerOptions" >-->
 <!--    </el-date-picker>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%;height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -170,7 +170,7 @@ export default {
         // },
         legend: {
           data: ['累计领取次数', '累计正常归还次数', '累计超时归还次数'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -182,6 +182,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',

+ 9 - 2
src/views/mes/statisticians/LockerLending.vue

@@ -12,7 +12,7 @@
 <!--      end-placeholder="结束日期"-->
 <!--      :picker-options="pickerOptions" >-->
 <!--    </el-date-picker>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%; height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -165,7 +165,7 @@ export default {
         // },
         legend: {
           data: ['平均借出时长(小时)'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -177,6 +177,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',

+ 9 - 2
src/views/mes/statisticians/LockerMistake.vue

@@ -2,7 +2,7 @@
   <div class="charts-container">
 
     <!-- 单个堆叠柱状图 -->
-    <div id="stackedBarChart" style="width: 100%; height: 400px;"></div>
+    <div id="stackedBarChart" style="width: 100%; height: 350px;"></div>
   </div>
 </template>
 
@@ -139,7 +139,7 @@ export default {
           },
           legend: {
             data: ['物资错放', '超时未关'],
-            top: '5%',
+            top: '6%',
             left: 'center',
             textStyle: {
               fontSize: 14
@@ -154,6 +154,13 @@ export default {
               fontSize: 12
             }
           },
+          dataZoom: {
+            show: true,
+            start: 0,
+            end: 100,
+            maxSpan: 100,
+            // zoomLock: true
+          },
           yAxis: {
             type: 'value',
             name: '次数',

+ 14 - 0
src/views/mes/statisticians/LockerOne.vue

@@ -14,6 +14,14 @@
         :picker-options="pickerOptions"
       >
       </el-date-picker>
+      <el-button v-no-more-click
+                 type="warning"
+                 plain
+                 icon="el-icon-download"
+                 size="mini"
+                 @click="handleExport"
+
+      >导出</el-button>
     </div>
     <div style="display: flex; flex-wrap: wrap; gap: 10px;">
       <div style="flex: 1 1 45%; min-width: 620px;"> <!-- Adjust width and allow flexibility -->
@@ -102,6 +110,12 @@ export default {
     this.getList()
   },
   methods: {
+    handleExport() {
+      // /dev-api/iscs/statistics-api/exportBaseData
+      this.download('iscs/statistics-api/exportBaseData', {
+        ...this.queryParams
+      }, `基础数据统计_${new Date().getTime()}.xlsx`)
+    },
     getDefaultDateRange() {
       const today = new Date()
       const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate())

+ 9 - 2
src/views/mes/statisticians/LockerOpen.vue

@@ -12,7 +12,7 @@
 <!--      end-placeholder="结束日期"-->
 <!--      :picker-options="pickerOptions" >-->
 <!--    </el-date-picker>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%; height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -162,7 +162,7 @@ export default {
         // },
         legend: {
           data: ['开关次数'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -174,6 +174,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',

+ 9 - 2
src/views/mes/statisticians/LockerReturn.vue

@@ -12,7 +12,7 @@
 <!--      end-placeholder="结束日期"-->
 <!--      :picker-options="pickerOptions" >-->
 <!--    </el-date-picker>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%; height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -162,7 +162,7 @@ export default {
         // },
         legend: {
           data: ['正常归还次数','超时归还次数'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -174,6 +174,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',

+ 9 - 2
src/views/mes/statisticians/LockerSpeciality.vue

@@ -14,7 +14,7 @@
 <!--        :picker-options="pickerOptions" >-->
 <!--      </el-date-picker>-->
 <!--    </div>-->
-    <div ref="barChart" style="width: 700px; height: 400px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
+    <div ref="barChart" style="width: 100%; height: 350px;margin-top: 3%"></div>  <!-- 这里指定了柱状图的宽高 -->
   </div>
 </template>
 
@@ -166,7 +166,7 @@ export default {
         // },
         legend: {
           data: ['即将过期','已过期','损坏数'],
-          top: '5%',  // 调整图例距离顶部的距离,确保图例在标题下方
+          top: '6%',  // 调整图例距离顶部的距离,确保图例在标题下方
           left: 'center',  // 图例居中显示
         },
         xAxis: [
@@ -178,6 +178,13 @@ export default {
             }
           }
         ],
+        dataZoom: {
+          show: true,
+          start: 0,
+          end: 100,
+          maxSpan: 100,
+          // zoomLock: true
+        },
         yAxis: [
           {
             type: 'value',

+ 14 - 0
src/views/mes/statisticians/LockerTwo.vue

@@ -13,6 +13,14 @@
         end-placeholder="结束日期"
         :picker-options="pickerOptions" >
       </el-date-picker>
+      <el-button v-no-more-click
+                 type="warning"
+                 plain
+                 icon="el-icon-download"
+                 size="mini"
+                 @click="handleExport"
+
+      >导出</el-button>
     </div>
     <div style="display: flex; flex-wrap: wrap; gap: 10px;">
       <div style="flex: 1 1 45%; min-width: 620px;"> <!-- Adjust width and allow flexibility -->
@@ -104,6 +112,12 @@ export default {
     this.getList()
   },
   methods: {
+    handleExport() {
+      // /dev-api/iscs/statistics-api/exportClaimAndReturn
+      this.download('iscs/statistics-api/exportClaimAndReturn', {
+        ...this.queryParams
+      }, `领取归还统计_${new Date().getTime()}.xlsx`)
+    },
     getDefaultDateRange() {
       const today = new Date();
       const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());