wyn 4 mēneši atpakaļ
vecāks
revīzija
1c93a9a722

+ 3 - 1
src/api/basic/mapconfig/index.ts

@@ -21,7 +21,9 @@ export interface PageParam {
 export const getIsMapPage = async (params: PageParam) => {
   return await request.get({ url: '/iscs/map/getMapPage', params })
 }
-
+export const getNotUsedMap = async () => {
+  return await request.get({ url: '/iscs/map/getNotUsedMap' })
+}
 // 查询地图参数详细
 export const selectIsMapById = async (id: number) => {
   return await request.get({ url: '/iscs/map/selectMapById', params: { id } })

+ 2 - 3
src/api/material/plan/index.ts

@@ -34,13 +34,13 @@ export interface AutoConfigVO {
 
 // 查询物资检查计划列表
 export const listPlan = async (params: PlanQuery) => {
-  return await request.get({ url: '/iscs/materials-check-plan/updateMaterialsCheckPlan', params })
+  return await request.get({ url: '/iscs/materials-check-plan/getMaterialsCheckPlanPage', params })
 }
 
 // 查询物资检查计划详情
 export const getPlanInfo = async (id: number) => {
   return await request.get({
-    url: '/iscs/materials-check-plan/insertMaterialsCheckPlan',
+    url: '/iscs/materials-check-plan/selectMaterialsCheckPlanById',
     params: { id: id }
   })
 }
@@ -59,7 +59,6 @@ export const updatePlan = async (data: PlanVO) => {
 export const deletePlan = async (ids: number) => {
   return await request.post({
     url: '/iscs/materials-check-plan/deleteMaterialsCheckPlanList?ids='+ids,
-
   })
 }
 

+ 12 - 0
src/api/material/statistics/index.ts

@@ -141,3 +141,15 @@ export const getInventorySum = async () => {
     url: '/iscs/statistics-api/getInventorySum'
   })
 }
+// 导出基础数据统计
+export const exportBaseData = async (params) => {
+  return await request.post({ url: `/iscs/statistics-api/exportBaseData`, params })
+}
+// 导出领取归还统计
+export const exportClaimAndReturn = async (params) => {
+  return await request.post({ url: `/iscs/statistics-api/exportClaimAndReturn`, params })
+}
+//导出物资盘点
+export const exportMaterialInventory = async (params) => {
+  return await request.post({ url: `/iscs/statistics-api/exportMaterialInventory`, params })
+}

+ 4 - 0
src/api/system/user/index.ts

@@ -26,6 +26,10 @@ export const getUserPage = (params: PageParam) => {
 export const getUser = (id: number) => {
   return request.get({ url: '/system/user/get?id=' + id })
 }
+// code查询 /system/user/getUserByRoleCode
+export const getRoleUser = (code: number) => {
+  return request.get({ url: '/system/user/getUserByRoleCode?roleCode=' + code})
+}
 
 // 新增用户
 export const createUser = (data: UserVO) => {

+ 4 - 3
src/views/dv/lotoStation/LotoStationForm.vue

@@ -73,6 +73,7 @@ import * as MapconfigApi from '@/api/basic/mapconfig/index'
 import * as  HardwareApi from '@/api/hw/hardware/information/index'
 import * as  MarsDeptApi from '@/api/system/marsdept'
 import {  handleTree } from '@/utils/tree'
+import {getNotUsedMap} from "@/api/basic/mapconfig/index";
 defineOptions({ name: 'LotoStationForm' })
 
 const { t } = useI18n() // 国际化
@@ -123,9 +124,9 @@ const open = async (type: string, id?: number) => {
   const deptRes = await MarsDeptApi.listMarsDept({ pageNo: 1, pageSize: -1 })
   marsOptions.value = handleTree(deptRes.list)
 
-  // 获取地图数据
-  const mapRes = await MapconfigApi.getIsMapPage({ pageNo: 1, pageSize: -1 })
-  mapOptions.value = mapRes.list
+  // 获取地图数据 (getNotUsedMap这个接口可以筛选已经被使用的就不再出现 未被使用的才出现)
+  const mapRes = await MapconfigApi.getNotUsedMap()
+  mapOptions.value = mapRes
 
   // 获取硬件数据
   const hwRes = await HardwareApi.listHardware({ pageNo: 1, pageSize: -1 })

+ 32 - 9
src/views/dv/lotoStation/MapData.vue

@@ -1,4 +1,4 @@
-<template>
+<template v-if="renderKey">
   <div class="mapdata-container">
     <v-stage
       ref="stageRef"
@@ -436,12 +436,37 @@ const getIsIsolationPointPage = async () => {
 }
 
 // 重置功能
-const handleReset = () => {
-  mapData.originData = mapData.originData
-  mapData.rightPoints = JSON.parse(JSON.stringify(mapData.orgRightPoints))
-  mapData.leftPoints = JSON.parse(JSON.stringify(mapData.orgLeftPoints))
+const renderKey = ref(0)
+const handleReset = async () => {
+  try {
+    // 暂时隐藏点位,等数据重建后再显示
+    renderKey.value = 0
+
+    // 清空数据
+    mapData.leftPoints = []
+    mapData.rightPoints = []
+    mapData.pointList = []
+    mapData.bindingPointIds = []
+    mapData.unbindPointIds = []
+    mapData.originData = null
+
+    // 重新加载所有地图信息
+    await getInfo()
+    await getIsIsolationPointPage()
+
+    // 延迟一点恢复渲染(确保 dom 更新完)
+    await nextTick()
+    renderKey.value = 1
+
+    message.success('已重置为初始状态')
+  } catch (error) {
+    console.error('重置失败:', error)
+    message.error('重置失败,请稍后重试')
+  }
 }
 
+
+
 // 保存功能
 const handleSave = async () => {
   try {
@@ -727,10 +752,7 @@ const handleCabinetEnter = (point: any, col: number, row: number) => {
   mapData.leftPoints.push(point)
 }
 
-// 处理舞台拖拽结束
-const handleStageDragEnd = (e: any) => {
-  // 舞台拖拽结束处理
-}
+
 
 // 组件挂载
 onMounted(async () => {
@@ -745,6 +767,7 @@ onMounted(async () => {
   width: 100%;
   height: 100%;
   display: flex;
+
 }
 
 /* 按钮样式 */

+ 2 - 2
src/views/dv/lotoStation/index.vue

@@ -68,7 +68,7 @@
       <el-table-column label="岗位" align="center" prop="workstationName" />
       <el-table-column label="地图名称" align="center" prop="mapName" />
       <el-table-column label="所属硬件序列号" align="center" prop="lotoSerialNumber" />
-      <el-table-column label="锁定站详情" align="center" width="120">
+      <el-table-column label="锁定站详情" align="center" >
         <template #default="scope">
           <el-button
             link
@@ -80,7 +80,7 @@
           </el-button>
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" width="120">
+      <el-table-column label="操作" align="center" >
         <template #default="scope">
           <el-button
             link

+ 0 - 11
src/views/dv/spm/SegregationPointForm.vue

@@ -308,18 +308,7 @@ const resetForm = () => {
 //     formData.value.pointCode = ''
 //   }
 // }
-const machineryOptionsChange = (val) => {
-  console.log(val, '选中的ID')
 
-  // 通过ID找到对应的machineryName
-  const selectedMachinery = machineryOptions.value.find(item => item.value === val)
-
-  if (selectedMachinery) {
-    const machineryName = selectedMachinery.label
-
-    formData.value.machineryName = machineryName
-  }
-}
 
 /** 选择隔离点图标 */
 const selectIcon = (imageUrl: string, index: number) => {

+ 2 - 2
src/views/dv/spm/index.vue

@@ -94,7 +94,7 @@
       <el-table-column label="隔离点编号" align="center" prop="id" width="100"/>
 
       <el-table-column label="隔离点名称" align="center" prop="pointName" />
-      <el-table-column label="隔离点图标" align="center" prop="pointIcon" width="90">
+      <el-table-column label="隔离点图标" align="center" prop="pointIcon" width="100">
         <template #default="scope">
           <el-image
             v-if="scope.row.pointIcon"
@@ -127,7 +127,7 @@
       <el-table-column label="锁定站" align="center" prop="lotoName" />
       <el-table-column label="隔离点序列号" align="center" prop="pointSerialNumber" />
       <el-table-column label="作用" align="center" prop="remark" />
-      <el-table-column label="隔离点图片" align="center" prop="pointPicture" width="90">
+      <el-table-column label="隔离点图片" align="center" prop="pointPicture" width="100">
         <template #default="scope">
           <el-image
             v-if="scope.row.pointPicture"

+ 34 - 39
src/views/dv/technology/technologyDetail/CraftDetail.vue

@@ -46,7 +46,7 @@
           @selection-change="handleSelectionChange"
         >
           <el-table-column type="selection" width="55" align="center" />
-          <!--        <el-table-column prop="machineryCode" label="设备编码" />-->
+          <el-table-column prop="id" label="设备编号" />
           <el-table-column prop="machineryName" label="设备名称" />
           <el-table-column prop="machineryImg" label="设备图">
             <template #default="{ row }">
@@ -61,7 +61,7 @@
           <el-table-column label="操作" align="center" width="200">
             <template #default="{ row }">
               <el-button
-                v-hasPermi="['iscs:machinery:edit']"
+                v-hasPermi="['iscs:machinery:update']"
                 type="primary"
                 link
                 @click="handleUpdate(row)"
@@ -70,7 +70,7 @@
                 编辑
               </el-button>
               <el-button
-                v-hasPermi="['iscs:machinery:remove']"
+                v-hasPermi="['iscs:machinery:delete']"
                 type="danger"
                 link
                 @click="handleDelete(row)"
@@ -196,7 +196,7 @@
           <el-tree-select
             v-model="formData.workstationId"
             :data="workstationOptions"
-            :props="defaultProps"
+            :props="{ label: 'workstationName', value: 'id', children: 'children' }"
             placeholder="请选择岗位"
             disabled
           />
@@ -219,13 +219,7 @@
         </el-form-item>
 
         <el-form-item label="设备图" prop="machineryImg">
-          <ImageUpload
-            v-model="formData.machineryImg"
-            :limit="1"
-            :file-size="5"
-            @onUploaded="handleImgUploaded"
-            @onRemoved="handleImgRemoved"
-          />
+          <UploadImg v-model="formData.machineryImg" :limit="1" height="75px" width="75px" />
         </el-form-item>
       </el-form>
       <template #footer>
@@ -289,8 +283,9 @@ import { useI18n } from 'vue-i18n'
 import { useMessage } from '@/hooks/web/useMessage'
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import * as TechnologyApi from '@/api/dv/technology'
+import * as MardDeptApi from "@/api/system/marsdept/index"
 import * as LotoApi from '@/api/dv/lotoStation'
-// import * as SopApi from '@/api/sop/sopindex'
+import * as SopApi from '@/api/dv/lotoStation'
 
 import MapData from './MapData.vue'
 import TinyMCE from '@/components/TinyMCE/index.vue'
@@ -387,8 +382,8 @@ const getList = async () => {
       machineryType: '设备'
     }
     const res = await TechnologyApi.listTechnology(data)
-    deviceList.value = res.data.records
-    total.value = res.data.total
+    deviceList.value = res.list
+    total.value = res.total
   } finally {
     loading.value = false
   }
@@ -402,9 +397,9 @@ const getSopList = async () => {
       ...queryParams,
       machineryId: route.query.machineryId
     }
-    const res = await SopApi.getIsMarsSopPage(data)
-    sopList.value = res.data.records
-    sopTotal.value = res.data.total
+    // const res = await SopApi.getIsMarsSopPage(data)
+    // sopList.value = res.list
+    // sopTotal.value = res.total
   } finally {
     loading.value = false
   }
@@ -412,18 +407,19 @@ const getSopList = async () => {
 
 /** 获取选项数据 */
 const getOptions = async () => {
-  // 获取岗位树
-  const marsRes = await TechnologyApi.listMarsDept({ pageSize: -1 })
-  workstationOptions.value = marsRes.data.records
+
 
   // 获取设备工艺树
-  const techRes = await TechnologyApi.listTechnology({ pageSize: -1 })
-  machineryOptions.value = techRes.data.records
+  const techRes = await TechnologyApi.listTechnology({ pageNo:1,pageSize: -1 })
+  machineryOptions.value = techRes.list
+  // 获取岗位树
+  const marsRes = await MardDeptApi.listMarsDept({ pageNo:1,pageSize: -1 })
+  workstationOptions.value = marsRes.list
 
   // 获取电柜列表
-  const lotoRes = await LotoApi.listLoto({ pageSize: -1 })
-  lotoOptions.value = lotoRes.data.records.map((item) => ({
-    value: item.lotoId,
+  const lotoRes = await LotoApi.listLoto({ pageNo:1,pageSize: -1 })
+  lotoOptions.value = lotoRes.list.map((item) => ({
+    value: item.id,
     label: item.lotoName
   }))
 }
@@ -432,7 +428,10 @@ const getOptions = async () => {
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
   dialogTitle.value = t('action.' + type)
+
   resetForm()
+
+  console.log(formData.value,'formData')
   if (id) {
     formLoading.value = true
     try {
@@ -440,6 +439,11 @@ const open = async (type: string, id?: number) => {
     } finally {
       formLoading.value = false
     }
+  }else{
+    const detail= await TechnologyApi.getTechnologyInfo(route.query.machineryId)
+    formData.value.lotoId=detail.lotoId
+    formData.value.workstationId=detail.workstationId
+    formData.value.parentId=route.query.machineryId
   }
 }
 
@@ -451,7 +455,7 @@ const openSop = async (type: string, id?: number) => {
   if (id) {
     formLoading.value = true
     try {
-      sopFormData.value = await SopApi.selectIsMarsSopById(id)
+      // sopFormData.value = await SopApi.selectIsMarsSopById(id)
     } finally {
       formLoading.value = false
     }
@@ -459,8 +463,7 @@ const openSop = async (type: string, id?: number) => {
 }
 
 /** 新增设备 */
-const handleAdd = () => {
-  formData.value.parentId = route.query.machineryId
+const handleAdd = async () => {
   open('create')
 }
 
@@ -481,7 +484,7 @@ const handleSopUpdate = (row: any) => {
 
 /** 删除设备 */
 const handleDelete = async (row?: any) => {
-  const ids = row?.machineryId || selectedIds.value
+  const ids = row?.id || selectedIds.value
   await message.confirm('确认删除数据项?')
   try {
     await TechnologyApi.delTechnology(ids)
@@ -555,15 +558,7 @@ const submitSopForm = async () => {
 //   }
 // }
 
-/** 图片上传成功 */
-const handleImgUploaded = (urls: string[]) => {
-  formData.value.machineryImg = urls[0]
-}
 
-/** 图片移除 */
-const handleImgRemoved = () => {
-  formData.value.machineryImg = undefined
-}
 
 /** 重置设备表单 */
 const resetForm = () => {
@@ -578,7 +573,7 @@ const resetForm = () => {
     machineryType: '设备'
   }
   formRef.value?.resetFields()
-  autoGenFlag.value = false
+  // autoGenFlag.value = false
 }
 
 /** 重置SOP表单 */
@@ -595,7 +590,7 @@ const resetSopForm = () => {
 /** 表格选择 */
 const selectedIds = ref<number[]>([])
 const handleSelectionChange = (selection: any[]) => {
-  selectedIds.value = selection.map((item) => item.machineryId)
+  selectedIds.value = selection.map((item) => item.id)
   multiple.value = !selection.length
 }
 

+ 193 - 277
src/views/dv/technology/technologyDetail/MapData.vue

@@ -1,336 +1,252 @@
 <template>
   <div class="mapdata">
-    <div id="container" ref="container" class="w-full h-full" ></div>
-    <div class="left">
-      <div class="bottombtn w-full h-35px">
-        <el-button
-          type="primary"
-          @click="handleSave"
-        >
-          <Icon icon="ep:edit" />
-          保存
-        </el-button>
-      </div>
+    <v-stage
+      ref="stageRef"
+      :config="{ width: stageWidth, height: stageHeight }"
+      class="konva-container"
+    >
+      <!-- 网格层 -->
+      <v-layer>
+        <v-line
+          v-for="(line, index) in gridLines"
+          :key="index"
+          :config="line"
+        />
+      </v-layer>
+
+      <!-- 背景图层 -->
+      <v-layer>
+        <v-image :config="bgImageConfig" />
+      </v-layer>
+
+      <!-- 点位图层 -->
+      <v-layer>
+        <template v-for="point in pointList" :key="point.entityId">
+          <v-rect :config="getBgRectConfig(point)" />
+          <v-image :config="getImageConfig(point)" @click="() => toggleSelect(point)" />
+          <v-text :config="getTextConfig(point)" />
+          <v-rect v-if="isSelected(point.entityId)" :config="getOverlayConfig(point)" />
+          <v-text v-if="isSelected(point.entityId)" :config="getCheckTextConfig(point)" />
+        </template>
+      </v-layer>
+    </v-stage>
+
+    <div class="action-bar">
+      <el-button
+        v-no-more-click
+        @click="handleSave"
+        type="primary"
+        :icon="Check"
+        class="action-btn save-btn"
+      >
+        保存配置
+      </el-button>
+
     </div>
   </div>
 </template>
 
-<script lang="ts" setup>
-import { ref, onMounted } from 'vue'
+<script setup lang="ts">
+import { ref, onMounted, computed } from 'vue'
 import { useRoute } from 'vue-router'
-import { useI18n } from 'vue-i18n'
 import { useMessage } from '@/hooks/web/useMessage'
-import Konva from 'konva'
+import { useI18n } from 'vue-i18n'
+import {
+  Check,
+} from '@element-plus/icons-vue'
 import * as TechnologyApi from '@/api/dv/technology'
 import * as LotoApi from '@/api/dv/lotoStation'
 import * as MapApi from '@/api/basic/mapconfig'
 
-defineOptions({ name: 'MapData' })
-
-const props = defineProps({
-  machineryId: {
-    type: String,
-    default: ''
-  }
-})
-
-const { t } = useI18n() // 国际化
-const message = useMessage() // 消息弹窗
 const route = useRoute()
+const message = useMessage()
+const { t } = useI18n()
 
-// Konva 相关
-const container = ref<HTMLElement>()
-const stage = ref<Konva.Stage>()
-const layer = ref<Konva.Layer>()
-const backgroundLayer = ref<Konva.Layer>()
-const gridLayer = ref<Konva.Layer>()
+const stageRef = ref()
+const stageWidth = 1600
+const stageHeight = 860
 
-// 数据相关
-const selectedStates = ref<boolean[]>([])
-const selectedText = ref<string[]>([])
-const rects = ref<Record<string, Konva.Rect>>({})
-const texts = ref<Record<string, Konva.Text>>({})
-const redrects = ref<Record<string, Konva.Rect>>({})
-const redtexts = ref<Record<string, Konva.Text>>({})
-const pointIdList = ref<number[]>([])
-const selectPoints = ref<number[]>([])
-
-// 表单数据
 const formData = ref({
-  map: null,
-  mapId: undefined,
   imageUrl: '',
-  width: 0,
-  height: 0,
+  width: 1200,
+  height: 860,
   x: 0,
   y: 0,
-  pointList: []
+  pointList: [] as any[],
 })
 
-/** 初始化数据 */
-const initData = async () => {
-  try {
-    // 获取设备工艺信息
-
-    const techRes = await TechnologyApi.getTechnologyInfo(props.machineryId)
-    const lotoId = techRes.data.lotoId
-    selectPoints.value = techRes.data.pointIdList
+const pointIdList = ref<number[]>([])
+const selectPoints = ref<number[]>([])
 
-    // 获取电柜地图信息
-    const mapRes = await LotoApi.selectLotoMapById(lotoId, '', '')
-    formData.value.map = mapRes.data
+const pointList = computed(() => formData.value.pointList)
 
-    // 获取电柜信息
-    const lotoRes = await LotoApi.selectIsLotoStationById(lotoId)
-    formData.value = { ...formData.value, ...lotoRes.data }
+onMounted(async () => {
 
-    // 获取地图配置
-    const configRes = await MapApi.selectIsMapById(lotoRes.data.mapId)
-    formData.value = {
-      ...formData.value,
-      imageUrl: configRes.data.imageUrl,
-      width: configRes.data.width,
-      height: configRes.data.height,
-      x: configRes.data.x,
-      y: configRes.data.y,
-      pointList: configRes.data.pointList
-    }
 
-    initKonva()
-  } catch (error) {
-    console.error('初始化数据失败:', error)
+  const techRes = await TechnologyApi.getTechnologyInfo(route.query.machineryId as string)
+  const lotoId = techRes.lotoId
+  const lotoRes = await LotoApi.selectIsLotoStationById(lotoId)
+  const mapRes = await MapApi.selectIsMapById(lotoRes.mapId)
+  console.log(mapRes,'mapRes')
+  // 关键:设置选中点
+  if(techRes.pointIdList!==null){
+    pointIdList.value = [...techRes.pointIdList]  // 替换这里!
   }
-}
-
-/** 初始化 Konva */
-const initKonva = () => {
-  if (!container.value) return
-
-  // 创建舞台
-  stage.value = new Konva.Stage({
-    container: container.value,
-    width: 1600,
-    height: 860
-  })
-
-  // 创建网格图层
-  gridLayer.value = new Konva.Layer()
-  stage.value.add(gridLayer.value)
-  drawGrid(50, 50, '#e0e0e0', gridLayer.value)
-
-  // 创建底图图层
-  backgroundLayer.value = new Konva.Layer()
-  stage.value.add(backgroundLayer.value)
-
-  // 加载底图
-  const bgImage = new Image()
-  bgImage.src = formData.value.imageUrl
-  bgImage.onload = () => {
-    const konvaImage = new Konva.Image({
-      x: formData.value.x || 0,
-      y: formData.value.y || 0,
-      image: bgImage,
-      width: formData.value.width || 1200,
-      height: formData.value.height || 860,
-      draggable: false
-    })
-    backgroundLayer.value?.add(konvaImage)
-    backgroundLayer.value?.draw()
+  formData.value = {
+    ...formData.value,
+    ...lotoRes.data,
+    imageUrl: mapRes.imageUrl,
+    width: mapRes.width,
+    height: mapRes.height,
+    x: mapRes.x,
+    y: mapRes.y,
+    pointList: mapRes.pointList
   }
+})
 
-  // 创建主图层
-  layer.value = new Konva.Layer()
-  stage.value.add(layer.value)
-
-  // 渲染隔离点
-  renderGrid()
+const gridLines = computed(() => {
+  const lines = []
+  const cellSize = 50
+  for (let i = 0; i <= stageWidth; i += cellSize) {
+    lines.push({ points: [i, 0, i, stageHeight], stroke: '#e0e0e0', strokeWidth: 1 })
+  }
+  for (let j = 0; j <= stageHeight; j += cellSize) {
+    lines.push({ points: [0, j, stageWidth, j], stroke: '#e0e0e0', strokeWidth: 1 })
+  }
+  return lines
+})
 
-  // 禁止舞台拖拽
-  stage.value.draggable(false)
-}
+const bgImageConfig = computed(() => {
+  const image = new window.Image()
+  image.src = formData.value.imageUrl
+  return {
+    image,
+    x: formData.value.x,
+    y: formData.value.y,
+    width: formData.value.width,
+    height: formData.value.height,
+    draggable: false
+  }
+})
 
-/** 绘制网格 */
-const drawGrid = (cellWidth: number, cellHeight: number, gridColor: string, layer: Konva.Layer) => {
-  const width = 1600
-  const height = 860
+const imageCache = new Map<string, HTMLImageElement>()
 
-  // 绘制竖线
-  for (let i = 0; i <= width; i += cellWidth) {
-    const verticalLine = new Konva.Line({
-      points: [i, 0, i, height],
-      stroke: gridColor,
-      strokeWidth: 1
-    })
-    layer.add(verticalLine)
+const getImageConfig = (point: any) => {
+  let img = imageCache.get(point.pointIcon)
+  if (!img) {
+    img = new window.Image()
+    img.src = point.pointIcon
+    imageCache.set(point.pointIcon, img)
   }
-
-  // 绘制横线
-  for (let j = 0; j <= height; j += cellHeight) {
-    const horizontalLine = new Konva.Line({
-      points: [0, j, width, j],
-      stroke: gridColor,
-      strokeWidth: 1
-    })
-    layer.add(horizontalLine)
+  return {
+    image: img,
+    x: point.x * 50,
+    y: point.y * 50,
+    width: 45,
+    height: 45,
+    draggable: false
   }
-
-  layer.draw()
 }
 
-/** 渲染隔离点 */
-const renderGrid = () => {
-  if (!layer.value) return
-
-  // 重置数据
-  selectedStates.value = []
-  rects.value = {}
-  texts.value = {}
-  redrects.value = {}
-  redtexts.value = {}
-  selectedText.value = []
-  pointIdList.value = []
-
-  // 渲染点位
-  formData.value.pointList.forEach((pos) => {
-    const x = pos.x * 50
-    const y = pos.y * 50
-    const labelText = pos.entityName
-
-    const point = new Image()
-    point.src = pos.pointIcon
-    point.onload = () => {
-      // 创建点位图片
-      const konvaImage = new Konva.Image({
-        x: x + 2,
-        y: y,
-        image: point,
-        width: 45,
-        height: 45,
-        draggable: false
-      })
-
-      // 添加点击事件
-      konvaImage.on('click', () => {
-        const isCurrentlySelected = redrects.value[labelText]?.visible()
 
-        if (isCurrentlySelected) {
-          redrects.value[labelText]?.visible(false)
-          redtexts.value[labelText]?.visible(false)
-          pointIdList.value = pointIdList.value.filter(id => id !== pos.entityId)
-        } else {
-          redrects.value[labelText]?.visible(true)
-          redtexts.value[labelText]?.visible(true)
-          pointIdList.value.push(pos.entityId)
-        }
-
-        layer.value?.batchDraw()
-      })
-
-      // 创建背景矩形
-      const bgrect = new Konva.Rect({
-        x: x - 2,
-        y: y - 5,
-        width: 50,
-        height: 78,
-        cornerRadius: 5,
-        stroke: 'white',
-        strokeWidth: 2,
-        fill: 'white'
-      })
-      layer.value?.add(bgrect)
-      rects.value[labelText] = bgrect
-
-      // 添加图片
-      layer.value?.add(konvaImage)
+const getBgRectConfig = (point: any) => ({
+  x: point.x * 50 - 2,
+  y: point.y * 50 - 5,
+  width: 50,
+  height: 78,
+  cornerRadius: 5,
+  stroke: 'red',
+  strokeWidth: 2,
+  fill: 'white'
+})
 
-      // 创建文本
-      const text = new Konva.Text({
-        x: x + 8,
-        y: y + 50,
-        fontSize: 17,
-        text: labelText,
-        fontFamily: 'Calibri',
-        fill: 'red'
-      })
-      layer.value?.add(text)
-      texts.value[labelText] = text
+const getTextConfig = (point: any) => ({
+  x: point.x * 50 + 8,
+  y: point.y * 50 + 50,
+  fontSize: 17,
+  text: point.entityName,
+  fontFamily: 'Calibri',
+  fill: 'red'
+})
 
-      // 创建选中状态覆盖层
-      const redrect = new Konva.Rect({
-        x: x - 3,
-        y: y - 6,
-        width: 52,
-        height: 80,
-        cornerRadius: 5,
-        fill: 'rgba(97, 97, 97, 0.5)',
-        visible: false,
-        listening: false
-      })
-      layer.value?.add(redrect)
-      redrects.value[labelText] = redrect
+const getOverlayConfig = (point: any) => ({
+  x: point.x * 50 - 3,
+  y: point.y * 50 - 6,
+  width: 52,
+  height: 80,
+  cornerRadius: 5,
+  fill: 'rgba(97, 97, 97, 0.5)',
+  listening: false
+})
 
-      // 创建选中状态对号
-      const redtext = new Konva.Text({
-        x: x - 8 + 42 / 2,
-        y: y + 50 / 2,
-        fontSize: 24,
-        text: '✔',
-        fontFamily: 'Arial',
-        fill: 'white',
-        align: 'center',
-        verticalAlign: 'middle',
-        visible: false,
-        listening: false
-      })
-      layer.value?.add(redtext)
-      redtexts.value[labelText] = redtext
+const getCheckTextConfig = (point: any) => ({
+  x: point.x * 50 + 13,
+  y: point.y * 50 + 25,
+  fontSize: 24,
+  text: '✔',
+  fontFamily: 'Arial',
+  fill: 'white',
+  align: 'center',
+  verticalAlign: 'middle',
+  listening: false
+})
 
-      // 设置初始选中状态
-      if (selectPoints.value?.includes(pos.entityId)) {
-        redrects.value[labelText]?.visible(true)
-        redtexts.value[labelText]?.visible(true)
-        pointIdList.value.push(pos.entityId)
-      }
+const isSelected = (id: number) => pointIdList.value.includes(id)
 
-      layer.value?.draw()
-    }
-  })
+const toggleSelect = (point: any) => {
+  const idx = pointIdList.value.indexOf(point.entityId)
+  if (idx >= 0) {
+    pointIdList.value.splice(idx, 1)
+  } else {
+    pointIdList.value.push(point.entityId)
+  }
 }
 
-/** 保存 */
 const handleSave = async () => {
   await message.confirm('请确认是否保存修改内容')
-  try {
-    const data = {
-      machineryId: route.query.machineryId,
-      pointIdList: pointIdList.value
-    }
-    await TechnologyApi.saveMachineryPoints(data)
-    message.success(t('common.saveSuccess'))
-  } catch (error) {
-    console.error('保存失败:', error)
+  const data = {
+    machineryId: route.query.machineryId,
+    pointIdList: pointIdList.value
   }
+  await TechnologyApi.saveMachineryPoints(data)
+  message.success(t('common.saveSuccess'))
 }
-
-onMounted(() => {
-  initData()
-})
 </script>
 
 <style scoped lang="scss">
 .mapdata {
+  display: flex;
   width: 100%;
   height: 100%;
-  display: flex;
+}
+.konva-container {
+  width: 1600px;
+  height: 860px;
+}
+/* 按钮样式 */
+.action-btn {
+  height: 44px;
+  min-width: 120px;
+  font-size: 16px;
+  font-weight: bold;
+  border-radius: 8px !important;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+  transition: all 0.2s;
 }
 
-.left {
-  flex: 1;
-  display: flex;
-  flex-direction: column;
+.save-btn {
+  background: linear-gradient(135deg, #409EFF, #3375e0);
+  border: none;
+  margin: 10px 0px 10px 10px;
+
+}
+
+.action-btn:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
 }
 
-.h-35px {
-  height: 35px;
+.action-btn:active {
+  transform: translateY(0);
 }
 </style>

+ 23 - 21
src/views/material/coll/index.vue

@@ -37,7 +37,7 @@
         <el-tree-select
           v-model="queryParams.materialsTypeId"
           :data="machinerytypeOptions"
-          :props="{ label: 'materialsTypeName', value: 'materialsTypeId' }"
+          :props="{ label: 'materialsTypeName', value: 'id' }"
           placeholder="请选择物资类型"
           class="!w-240px"
         />
@@ -137,8 +137,8 @@
 
     <Pagination
       v-model:total="total"
-      v-model:page="queryParams.current"
-      v-model:limit="queryParams.size"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
       @pagination="getList"
     />
   </ContentWrap>
@@ -148,18 +148,20 @@
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { handleTree } from '@/utils/tree'
 import * as LoanApi from '@/api/material/loan/index'
-import * as CabinetApi from '@/api/material/information/index'
+import * as CabinetApi from '@/api/material/lockers/index'
 import * as TypeApi from '@/api/material/type/index'
-import {getMaterialsCabinets} from "@/api/material/information/index";
 
-defineOptions({ name: 'CollectionManagement' })
 
+// 定义组件 props
 const props = defineProps({
   cabinetId: {
-    type: String,
+    type: String || null,
     required: false
   }
 })
+defineOptions({ name: 'CollectionManagement' })
+
+
 
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
@@ -173,8 +175,8 @@ const visibleSelect = ref(false) // 是否显示物资柜选择
 
 // 查询参数
 const queryParams = reactive({
-  current: 1,
-  size: 10,
+  pageNo: 1,
+  pageSize: 10,
   materialsName: undefined,
   materialsCode: undefined,
   loanUserName: undefined,
@@ -209,7 +211,7 @@ const getList = async () => {
       queryParams.restitutionTimeEnd = formatDate(restitutionTime.value[1])
     }
     const data = await LoanApi.listLoan(queryParams)
-    list.value = data.records
+    list.value = data.list
     total.value = data.total
   } finally {
     loading.value = false
@@ -218,13 +220,13 @@ const getList = async () => {
 
 /** 获取物资柜列表 */
 const getCabinets = async () => {
-  const data = await CabinetApi.getMaterialsCabinets({
-    current: 1,
-    size: -1
+  const data = await CabinetApi.listMaterialsCabinet({
+    pageNo: 1,
+    pageSize: -1
   })
-  if (data?.records) {
-    cabinets.value = data.records.map((item) => ({
-      value: item.cabinetId,
+  if (data?.list) {
+    cabinets.value = data.list.map((item) => ({
+      value: item.id,
       label: item.cabinetName
     }))
   }
@@ -233,15 +235,15 @@ const getCabinets = async () => {
 /** 获取物资类型树形数据 */
 const getTreeselect = async () => {
   const data = await TypeApi.listType({
-    current: 1,
-    size: -1
+    pageNo: 1,
+    pageSize: -1
   })
-  machinerytypeOptions.value = handleTree(data.records, 'materialsTypeId', 'parentId', 'children')
+  machinerytypeOptions.value = handleTree(data.list, 'id', 'parentId', 'children')
 }
 
 /** 搜索按钮操作 */
 const handleQuery = () => {
-  queryParams.current = 1
+  queryParams.pageNo = 1
   getList()
 }
 
@@ -256,7 +258,7 @@ const resetQuery = () => {
 /** 查询超时未还 */
 const handleQueryStatus = () => {
   queryParams.status = '2'
-  queryParams.current = 1
+  queryParams.pageNo = 1
   getList()
 }
 

+ 1 - 0
src/views/material/information/index.vue

@@ -451,6 +451,7 @@ const getTreeselect = async () => {
 /** 查询物资柜列表 */
 const materialsCabinets = async () => {
   const data = await CabinetApi.listMaterialsCabinet(queryParamsCabinets)
+
   if (data?.list) {
     cabinets.value = data.list.map((item) => ({
       value: item.id,

+ 21 - 24
src/views/material/inspectionplan/index.vue

@@ -215,8 +215,8 @@
 
     <Pagination
       v-model:total="total"
-      v-model:page="queryParams.current"
-      v-model:limit="queryParams.size"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
       @pagination="getList"
     />
   </ContentWrap>
@@ -235,13 +235,14 @@
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 
 import * as PlanApi from '@/api/material/plan'
-import * as CabinetApi from '@/api/material/information/index'
+import * as CabinetApi from '@/api/material/lockers/index'
 import * as UserApi from '@/api/system/user'
-// import * as DeptApi from '@/api/system/marsdept'
+import * as MarsDeptApi from '@/api/system/marsdept'
 import PlanForm from './PlanForm.vue'
 import PlanDetailDialog from './PlanDetailDialog.vue'
 import CheckRecordDialog from './CheckRecordDialog.vue'
-import {getMaterialsCabinets} from "@/api/material/information/index";
+import {listMaterialsCabinet} from "@/api/material/lockers/index";
+import {getRoleUser, getUserPage} from "@/api/system/user";
 
 
 defineOptions({ name: 'InspectionPlan' })
@@ -265,8 +266,8 @@ const visibleSelect = ref(false) // 是否显示物资柜选择
 
 // 查询参数
 const queryParams = reactive({
-  current: 1,
-  size: 10,
+  pageNo: 1,
+  pageSize: 10,
   checkUserName: undefined,
   planName: undefined,
   cabinetId: undefined,
@@ -299,7 +300,7 @@ const getList = async () => {
       queryParams.endTime = formatDate(createTime.value[1])
     }
     const data = await PlanApi.listPlan(queryParams)
-    list.value = data.records
+    list.value = data.list
     total.value = data.total
   } finally {
     loading.value = false
@@ -308,28 +309,24 @@ const getList = async () => {
 
 /** 获取物资柜列表 */
 const getCabinets = async () => {
-  const data = await CabinetApi.getMaterialsCabinets({
-    current: 1,
-    size: -1
+  const data = await CabinetApi.listMaterialsCabinet({
+    pageNo: 1,
+    pageSize: -1
   })
-  if (data?.records) {
-    cabinets.value = data.records.map((item) => ({
-      value: item.cabinetId,
+  if (data?.list) {
+    cabinets.value = data.list.map((item) => ({
+      value: item.id,
       label: item.cabinetName
     }))
   }
 }
 
-/** 获取检察员列表 */
+/** 获取检察员列表  */
 const getCheckUsers = async () => {
-  const data = await UserApi.getUserPage({
-    pageSize: 999999999,
-    pageNum: 1,
-    roleId: 12
-  })
-  planPersonOption.value = data.rows.map((item) => ({
-    label: item.nickName,
-    value: item.userId
+  const data = await UserApi.getRoleUser('check')
+  planPersonOption.value = data.map((item) => ({
+    label: item.nickname,
+    value: item.id
   }))
 }
 
@@ -394,7 +391,7 @@ const handleClickStatus = async (value: boolean) => {
 
 /** 搜索按钮操作 */
 const handleQuery = () => {
-  queryParams.current = 1
+  queryParams.pageNo = 1
   getList()
 }
 

+ 3 - 4
src/views/material/lockers/DetailsIndex.vue

@@ -9,9 +9,8 @@
       <el-radio-button label="fifth">更换记录</el-radio-button>
     </el-radio-group>
   </ContentWrap>
-  <ContentWrap>
-    <!-- 物资清单 -->
 
+    <!-- 物资清单 -->
     <div v-if="tabPosition === 'first'" class="materials-list">
       <MaterialInfromation :cabinetId="cabinetId" />
     </div>
@@ -42,7 +41,7 @@
         :recordId="recordId"
       />
     </div>
-  </ContentWrap>
+
 </template>
 
 <script lang="ts" setup>
@@ -64,7 +63,7 @@ const planData = ref(null)
 const route=useRoute()
 // 获取路由参数
 onMounted(() => {
-  cabinetId.value = route.query.cabinetId as string || ''
+  cabinetId.value = route.query.cabinetId
 })
 
 // 方法定义

+ 1 - 1
src/views/material/lockers/index.vue

@@ -61,7 +61,7 @@
 
         <!-- 异常信息图标 -->
         <img
-          style="width: 40px; height: 40px; position: absolute; top: 2%; right: -4%"
+          style="width: 40px; height: 40px; position: absolute; top: 2%; right: -4%;cursor: pointer;"
           :src="ExceptionTableImage"
           alt="异常"
           @click="showExTable"

+ 8 - 0
src/views/statisticians/LockerOne/LockerChange.vue

@@ -5,7 +5,11 @@
 </template>
 
 <script lang="ts" setup>
+<<<<<<< HEAD
 import { getMaterialsChangeStatistics } from '@/api/material/statistics/index'
+=======
+import * as StatisticsApi from '@/api/material/statistics/index'
+>>>>>>> f00047ed1956f2985366fa9347c83b2a9520744f
 import * as echarts from 'echarts'
 
 defineOptions({ name: 'LockerChange' })
@@ -45,8 +49,12 @@ watch(
 /** 获取数据 */
 const getList = async () => {
   try {
+<<<<<<< HEAD
     const response = await getMaterialsChangeStatistics(queryParams)
     console.log(response,'数据格式')
+=======
+    const response = await StatisticsApi.getMaterialsChangeStatistics(queryParams)
+>>>>>>> f00047ed1956f2985366fa9347c83b2a9520744f
     cabinetData.value = response
     renderChart()
   } catch (error) {

+ 3 - 1
src/views/statisticians/LockerOne/LockerMistake.vue

@@ -41,7 +41,9 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {

+ 3 - 1
src/views/statisticians/LockerOne/LockerOpen.vue

@@ -41,7 +41,9 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {

+ 3 - 1
src/views/statisticians/LockerOne/LockerSpeciality.vue

@@ -41,7 +41,9 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {

+ 35 - 8
src/views/statisticians/LockerOne/index.vue

@@ -43,12 +43,13 @@
 </template>
 
 <script lang="ts" setup>
-import { dateFormatter } from '@/utils/formatTime'
 import LockerOpen from './LockerOpen.vue'
 import LockerMistake from './LockerMistake.vue'
 import LockerSpeciality from './LockerSpeciality.vue'
 import LockerChange from './LockerChange.vue'
 import download from '@/utils/download'
+import * as StatisticsApi from "@/api/material/statistics";
+
 defineOptions({ name: 'LockerOne' })
 
 const message = useMessage() // 消息弹窗
@@ -101,20 +102,46 @@ function getDefaultDateRange(): [Date, Date] {
 
 /** 处理日期变化 */
 const handleDateChange = (val: [Date, Date] | null) => {
-  if (val?.length === 2) {
-    queryParams.startTime = dateFormatter(val[0])
-    queryParams.endTime = dateFormatter(val[1])
+  if (val && val.length === 2) {
+    // 格式化开始时间(设置为当天开始)
+    const startDate = new Date(val[0])
+    startDate.setHours(0, 0, 0, 0)
+    queryParams.startTime = formatDateTime(startDate)
+
+    // 格式化结束时间(设置为当天结束)
+    const endDate = new Date(val[1])
+    endDate.setHours(23, 59, 59, 999)
+    queryParams.endTime = formatDateTime(endDate)
+
+    console.log('开始时间:', queryParams.startTime)
+    console.log('结束时间:', queryParams.endTime)
   } else {
     queryParams.startTime = undefined
     queryParams.endTime = undefined
   }
 }
 
+/** 格式化日期时间为字符串 */
+const formatDateTime = (date: Date): string => {
+  const year = date.getFullYear()
+  const month = String(date.getMonth() + 1).padStart(2, '0')
+  const day = String(date.getDate()).padStart(2, '0')
+  const hours = String(date.getHours()).padStart(2, '0')
+  const minutes = String(date.getMinutes()).padStart(2, '0')
+  const seconds = String(date.getSeconds()).padStart(2, '0')
+
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+}
+
 /** 导出数据 */
-const handleExport = () => {
-  download('iscs/statistics-api/exportBaseData', {
-    ...queryParams
-  }, `基础数据统计_${new Date().getTime()}.xlsx`)
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    const data = await StatisticsApi.exportBaseData(queryParams)
+    download.excel(data, '基础数据.xls')
+  } catch {
+  }
 }
 
 /** 初始化 */

+ 5 - 3
src/views/statisticians/LockerTwo/LockerCollection.vue

@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { getMaterialsLoanStatistics } from '@/api/mes/statisticians'
+import { getMaterialsLoanStatistics } from '@/api/material/statistics/index'
 import * as echarts from 'echarts'
 
 defineOptions({ name: 'LockerCollection' })
@@ -41,12 +41,14 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {
     const response = await getMaterialsLoanStatistics(queryParams)
-    cabinetData.value = response.data
+    cabinetData.value = response
     renderChart()
   } catch (error) {
     console.error('获取物资领取统计数据失败:', error)

+ 8 - 3
src/views/statisticians/LockerTwo/LockerDaily.vue

@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { getDayLoanStatistics } from '@/api/mes/statisticians'
+import { getDayLoanStatistics } from '@/api/material/statistics/index'
 import * as echarts from 'echarts'
 
 defineOptions({ name: 'LockerDaily' })
@@ -34,6 +34,7 @@ const queryParams = reactive({
 watch(
   () => [props.startTime, props.endTime],
   ([newStartTime, newEndTime]) => {
+
     if (newStartTime && newEndTime) {
       queryParams.startTime = newStartTime
       queryParams.endTime = newEndTime
@@ -41,13 +42,17 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  queryParams.startTime = props.startTime
+  queryParams.endTime = props.endTime
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {
     const response = await getDayLoanStatistics(queryParams)
     // 按日期排序
-    const sortData = response.data.sort((a, b) => {
+    const sortData = response.sort((a, b) => {
       const dateA = new Date(a.day)
       const dateB = new Date(b.day)
       return dateA.getTime() - dateB.getTime()

+ 5 - 3
src/views/statisticians/LockerTwo/LockerLending.vue

@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { getMaterialsLoanStatistics } from '@/api/mes/statisticians'
+import { getMaterialsLoanStatistics } from '@/api/material/statistics/index'
 import * as echarts from 'echarts'
 
 defineOptions({ name: 'LockerLending' })
@@ -41,12 +41,14 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {
     const response = await getMaterialsLoanStatistics(queryParams)
-    cabinetData.value = response.data
+    cabinetData.value = response
     renderChart()
   } catch (error) {
     console.error('获取物资借出平均时长统计数据失败:', error)

+ 5 - 3
src/views/statisticians/LockerTwo/LockerReturn.vue

@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { getMaterialsLoanStatistics } from '@/api/mes/statisticians'
+import { getMaterialsLoanStatistics } from '@/api/material/statistics/index'
 import * as echarts from 'echarts'
 
 defineOptions({ name: 'LockerReturn' })
@@ -41,12 +41,14 @@ watch(
     }
   }
 )
-
+onMounted(()=>{
+  getList()
+})
 /** 获取数据 */
 const getList = async () => {
   try {
     const response = await getMaterialsLoanStatistics(queryParams)
-    cabinetData.value = response.data
+    cabinetData.value = response
     renderChart()
   } catch (error) {
     console.error('获取物资归还统计数据失败:', error)

+ 37 - 8
src/views/statisticians/LockerTwo/index.vue

@@ -43,12 +43,13 @@
 </template>
 
 <script lang="ts" setup>
-import { dateFormatter } from '@/utils/formatTime'
 import LockerDaily from './LockerDaily.vue'
 import LockerLending from './LockerLending.vue'
 import LockerCollection from './LockerCollection.vue'
 import LockerReturn from './LockerReturn.vue'
 import download from '@/utils/download'
+import * as StatisticsApi from "@/api/material/statistics";
+import {exportClaimAndReturn} from "@/api/material/statistics";
 defineOptions({ name: 'LockerTwo' })
 
 const message = useMessage() // 消息弹窗
@@ -101,24 +102,52 @@ function getDefaultDateRange(): [Date, Date] {
 
 /** 处理日期变化 */
 const handleDateChange = (val: [Date, Date] | null) => {
-  if (val?.length === 2) {
-    queryParams.startTime = dateFormatter(val[0])
-    queryParams.endTime = dateFormatter(val[1])
+  if (val && val.length === 2) {
+    // 格式化开始时间(设置为当天开始)
+    const startDate = new Date(val[0])
+    startDate.setHours(0, 0, 0, 0)
+    queryParams.startTime = formatDateTime(startDate)
+
+    // 格式化结束时间(设置为当天结束)
+    const endDate = new Date(val[1])
+    endDate.setHours(23, 59, 59, 999)
+    queryParams.endTime = formatDateTime(endDate)
+
+    console.log('开始时间:', queryParams.startTime)
+    console.log('结束时间:', queryParams.endTime)
   } else {
     queryParams.startTime = undefined
     queryParams.endTime = undefined
   }
 }
 
+/** 格式化日期时间为字符串 */
+const formatDateTime = (date: Date): string => {
+  const year = date.getFullYear()
+  const month = String(date.getMonth() + 1).padStart(2, '0')
+  const day = String(date.getDate()).padStart(2, '0')
+  const hours = String(date.getHours()).padStart(2, '0')
+  const minutes = String(date.getMinutes()).padStart(2, '0')
+  const seconds = String(date.getSeconds()).padStart(2, '0')
+
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+}
+
+
 /** 导出数据 */
-const handleExport = () => {
-  download('iscs/statistics-api/exportClaimAndReturn', {
-    ...queryParams
-  }, `领取归还统计_${new Date().getTime()}.xlsx`)
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    const data = await StatisticsApi.exportClaimAndReturn(queryParams)
+    download.excel(data, '领取归还统计.xls')
+  } catch {
+  }
 }
 
 /** 初始化 */
 onMounted(() => {
+
   handleDateChange(dateRange.value)
 })
 </script>