Explorar el Código

Merge branch 'feat/production-safety' of http://192.168.6.110/product-group-fe/sfy-safety-group/sfy-safety into feat/production-safety

sunqijun hace 1 mes
padre
commit
a2d5c125df

+ 23 - 0
src/api/production-safety-system/index.ts

@@ -1564,3 +1564,26 @@ export function exportInspectionRecordTow (params: AreaCheckPlanQuery) {
     isTransformResponse: false,
   });
 }
+
+/** 检查模板下载 */
+export function checklistTemplateDownload () {
+  return http.request({
+    url: '/areaCheckPlanManageAdmin/exportimportCheckListTemplate',
+    method: 'get',
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}
+
+
+/** 检查模板导出 */
+export function checklistHandleeTemplateDownload (id: number) {
+  return http.request({
+    url: '/areaCheckPlanManageAdmin/exportCheckList?id=' + id,
+    method: 'get',
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}

+ 13 - 1
src/api/production-safety/personal-protective-equipment-purchase-apply.ts

@@ -227,4 +227,16 @@ export function saveThePurchaseRequest(data: SavePpePurchaseApplyReq) {
     method: 'post',
     data,
   });
-}
+}
+
+/** 导出劳防用品采购申请管理 */
+export function exportSafetyEquipmentProcurementRequest (queryParams) {
+  return http.request({
+    url: '/ppePurchaseApply/exportPpePurchaseApplyList',
+    method: 'post',
+    responseType: 'blob',
+    data: queryParams,
+  }, {
+    isTransformResponse: false,
+  });
+}

+ 1 - 1
src/api/safety-organization-management/index.ts

@@ -107,7 +107,7 @@ export const delEmployee = (id) => {
 export const exportSafetyOrganizationSystemManagement = (params)=>{
   return http.request({
     url: `/safetyorguser/exportSafetyOrgUser`,
-    method: 'get',
+    method: 'post',
     params,
     responseType: 'blob',
   }, {

+ 9 - 0
src/main.scss

@@ -54,3 +54,12 @@ body {
   justify-content: flex-end;
   margin-top: 20px;
 }
+
+.w-e-text-container img,
+.w-e-text-container video,
+.w-e-text img,
+.w-e-text video {
+  max-width: 100%;
+  width: 100%;
+  height: auto;
+}

+ 2 - 1
src/main.ts

@@ -5,7 +5,7 @@ import './main.scss';
 import 'element-plus/dist/index.css';
 import App from './App.vue';
 import BreadcrumbBack from '@/components/BreadcrumbBack.vue';
-import { setupElement, setupDirectives } from '@/plugins';
+import { setupElement, setupDirectives, setupWangEditorUpload } from '@/plugins';
 import dayjs from 'dayjs';
 import 'dayjs/locale/zh-cn';
 import '@/utils/g6Extensions';
@@ -15,6 +15,7 @@ import { notivue } from '@/components/custom-notivue/notivue-conf';
 import 'virtual:svg-icons-register';
 
 dayjs.locale('zh-cn');
+setupWangEditorUpload();
 
 async function bootstrap() {
   const app = createApp(App);

+ 1 - 0
src/plugins/index.ts

@@ -1,2 +1,3 @@
 export { setupElement } from '@/plugins/element';
 export { setupDirectives } from '@/plugins/directives';
+export { setupWangEditorUpload } from '@/plugins/wangEditor';

+ 12 - 0
src/plugins/wangEditor.ts

@@ -0,0 +1,12 @@
+import { Boot } from '@wangeditor/editor';
+import { createWangEditorMenuConf } from '@/utils/wangEditorUpload';
+
+export function setupWangEditorUpload() {
+  const menuConf = createWangEditorMenuConf();
+  Boot.setEditorConfig({
+    MENU_CONF: menuConf,
+  });
+  Boot.setSimpleEditorConfig({
+    MENU_CONF: menuConf,
+  });
+}

+ 48 - 0
src/utils/wangEditorUpload.ts

@@ -0,0 +1,48 @@
+import { ElMessage } from 'element-plus';
+import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
+
+type InsertImageFn = (url: string, alt?: string, href?: string) => void;
+type InsertVideoFn = (url: string, poster?: string) => void;
+
+const createUploadFileName = (fileName: string) => {
+  const uuid = Math.random().toString(36).substring(2, 9);
+  const timestamp = Date.now().toString();
+  const random = Math.random().toString(36).substring(2, 4);
+  const extension = fileName.split('.').pop();
+  return extension ? `${uuid}-${timestamp}-${random}.${extension}` : `${uuid}-${timestamp}-${random}`;
+};
+
+const uploadEditorFile = async (file: File) => {
+  const uploadName = createUploadFileName(file.name || 'editor-file');
+  const res = await uploadFileApi({
+    bizType: UPLOAD_BIZ_TYPE.ATTACHMENT,
+    fileName: uploadName,
+    file,
+  });
+  return res.url;
+};
+
+export const createWangEditorMenuConf = () => ({
+  uploadImage: {
+    async customUpload(file: File, insertFn: InsertImageFn) {
+      try {
+        const url = await uploadEditorFile(file);
+        insertFn(url, file.name, url);
+      } catch (error) {
+        console.error('编辑器图片上传失败:', error);
+        ElMessage.error('图片上传失败,请重试');
+      }
+    },
+  },
+  uploadVideo: {
+    async customUpload(file: File, insertFn: InsertVideoFn) {
+      try {
+        const url = await uploadEditorFile(file);
+        insertFn(url);
+      } catch (error) {
+        console.error('编辑器视频上传失败:', error);
+        ElMessage.error('视频上传失败,请重试');
+      }
+    },
+  },
+});

+ 86 - 37
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/areaCheckPlanManagement.vue

@@ -7,12 +7,8 @@
       <div class="search-table-container">
         <header>
           <div style="position: relative">
-            <el-button type="primary" class="search-table-container--button" @click="handleCreate">
-              添加
-            </el-button>
-            <el-button plain class="search-table-container--button" @click="handleImport">
-              导入
-            </el-button>
+            <el-button type="primary" class="search-table-container--button" @click="handleCreate"> 添加 </el-button>
+            <el-button plain class="search-table-container--button" @click="handleImport"> 导入 </el-button>
           </div>
 
           <div class="act-search">
@@ -28,11 +24,7 @@
               </div>
               <div class="select-box--item">
                 <span>状态:</span>
-                <el-select
-                  v-model="tableQuery.queryParam.status"
-                  placeholder="请选择状态"
-                  clearable
-                >
+                <el-select v-model="tableQuery.queryParam.status" placeholder="请选择状态" clearable>
                   <el-option
                     v-for="item in AREA_CHECK_PLAN_STATUS_OPTIONS"
                     :key="String(item.value)"
@@ -73,9 +65,7 @@
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
               <el-button @click="handleReset">重置</el-button>
-              <el-button plain  @click="handleDownload">
-                导出
-              </el-button>
+              <el-button plain @click="handleDownload"> 导出 </el-button>
             </section>
           </div>
         </header>
@@ -92,10 +82,14 @@
               <span>{{ AREA_CHECK_PLAN_STATUS_LABEL[String(scope.row.status)] ?? '-' }}</span>
             </template>
             <template #needOverallDesc="scope">
-              <span>{{ scope.row.needOverallDesc === true ? '是' : scope.row.needOverallDesc === false ? '否' : '-' }}</span>
+              <span>{{
+                scope.row.needOverallDesc === true ? '是' : scope.row.needOverallDesc === false ? '否' : '-'
+              }}</span>
             </template>
             <template #needSigneeSign="scope">
-              <span>{{ scope.row.needSigneeSign === true ? '是' : scope.row.needSigneeSign === false ? '否' : '-' }}</span>
+              <span>{{
+                scope.row.needSigneeSign === true ? '是' : scope.row.needSigneeSign === false ? '否' : '-'
+              }}</span>
             </template>
             <template #action="scope">
               <div class="action-container--div" style="justify-content: left">
@@ -200,12 +194,7 @@
             clearable
             style="width: 100%"
           >
-            <el-option
-              v-for="item in userGroupOptions"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
+            <el-option v-for="item in userGroupOptions" :key="item.id" :label="item.name" :value="item.id" />
           </el-select>
         </el-form-item>
         <el-form-item label="院领导部门:" prop="hospitalLeaderDeptId">
@@ -228,12 +217,7 @@
             clearable
             style="width: 100%"
           >
-            <el-option
-              v-for="item in userGroupOptions"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
+            <el-option v-for="item in userGroupOptions" :key="item.id" :label="item.name" :value="item.id" />
           </el-select>
         </el-form-item>
         <el-form-item label="计划开始日期:" prop="planStartTime">
@@ -295,7 +279,12 @@
   import BasicTable from '@/components/BasicTable.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import ActionButton from '@/components/ActionButton.vue';
-  import { TABLE_OPTIONS, AREA_CHECK_PLAN_TABLE_COLUMNS, AREA_CHECK_PLAN_STATUS_OPTIONS, AREA_CHECK_PLAN_STATUS_LABEL } from './configs/tables';
+  import {
+    TABLE_OPTIONS,
+    AREA_CHECK_PLAN_TABLE_COLUMNS,
+    AREA_CHECK_PLAN_STATUS_OPTIONS,
+    AREA_CHECK_PLAN_STATUS_LABEL,
+  } from './configs/tables';
   import { useRouter } from 'vue-router';
   import type { QueryPageRequest } from '@/types/basic-query';
   import type { AreaCheckPlanQuery, AreaCheckPlanRecord } from './configs/types';
@@ -397,9 +386,36 @@
     }
   };
 
-  const onIssueDialogOpen = () => {
-    loadIssueDeptTree();
-    loadUserGroupOptions();
+  const onIssueDialogOpen = async () => {
+    await Promise.all([loadIssueDeptTree(), loadUserGroupOptions()]);
+
+    if (!currentIssuePlanId.value) return;
+
+    try {
+      const raw = await queryAreaCheckPlanManageDetail(currentIssuePlanId.value);
+      const detail = mapAreaCheckPlanApiRecordToUi(raw);
+
+      const responsibleDeptIdsByCode = parseNumberList(
+        detail.primaryResponsibleDeptCode ?? (detail as Record<string, unknown>).responsibleDeptCode,
+      );
+
+      issueForm.responsibleDeptIds = responsibleDeptIdsByCode.length
+        ? responsibleDeptIdsByCode
+        : (detail.primaryResponsibleDeptName || '')
+            .split(',')
+            .map((name) => findDeptIdByName(issueDeptTree.value, name.trim()))
+            .filter((id): id is number => id != null);
+
+      const safetyEmergencyDeptIdByCode = parseNumber(detail.safetyEmergencyDeptCode);
+      issueForm.safetyEmergencyDeptId =
+        safetyEmergencyDeptIdByCode ?? findDeptIdByName(issueDeptTree.value, detail.safetyEmergencyDeptName);
+
+      const hospitalLeaderDeptIdByCode = parseNumber(detail.hospitalLeaderDeptCode);
+      issueForm.hospitalLeaderDeptId =
+        hospitalLeaderDeptIdByCode ?? findDeptIdByName(issueDeptTree.value, detail.hospitalLeaderDeptName);
+    } catch (e) {
+      console.error('加载下发默认数据失败:', e);
+    }
   };
 
   const findDeptNameById = (nodes: DeptTree[] | undefined, id: number | undefined): string | undefined => {
@@ -412,6 +428,30 @@
     return undefined;
   };
 
+  const findDeptIdByName = (nodes: DeptTree[] | undefined, name: string | undefined): number | undefined => {
+    if (!nodes?.length || !name) return undefined;
+    for (const n of nodes) {
+      if (n.deptName === name) return n.id ?? undefined;
+      const found = findDeptIdByName(n.children, name);
+      if (found != null) return found;
+    }
+    return undefined;
+  };
+
+  const parseNumber = (val: unknown): number | undefined => {
+    if (val == null || val === '') return undefined;
+    const n = Number(val);
+    return Number.isFinite(n) ? n : undefined;
+  };
+
+  const parseNumberList = (val: unknown): number[] => {
+    if (val == null || val === '') return [];
+    return String(val)
+      .split(',')
+      .map((s) => parseNumber(s.trim()))
+      .filter((n): n is number => n != null);
+  };
+
   const findDeptNamesByIds = (nodes: DeptTree[] | undefined, ids: number[] | undefined): string[] => {
     const list = (ids ?? []).filter((v) => v != null);
     if (!list.length) return [];
@@ -548,7 +588,11 @@
     if (!issueFormRef.value || !currentIssuePlanId.value) return;
     const valid = await issueFormRef.value.validate().catch(() => false);
     if (!valid) return;
-    if (issueForm.planStartTime && issueForm.planEndTime && new Date(issueForm.planStartTime) > new Date(issueForm.planEndTime)) {
+    if (
+      issueForm.planStartTime &&
+      issueForm.planEndTime &&
+      new Date(issueForm.planStartTime) > new Date(issueForm.planEndTime)
+    ) {
       ElMessage.error('计划开始日期不能大于计划结束日期');
       return;
     }
@@ -580,13 +624,15 @@
         safetyEmergencyDeptName,
         safetyEmergencyDeptId: issueForm.safetyEmergencyDeptId,
         safetyEmergencyExecutorGroupName: findGroupNameById(issueForm.safetyEmergencyGroupId),
-        safetyEmergencyExecGroupCode: issueForm.safetyEmergencyGroupId != null ? String(issueForm.safetyEmergencyGroupId) : undefined,
+        safetyEmergencyExecGroupCode:
+          issueForm.safetyEmergencyGroupId != null ? String(issueForm.safetyEmergencyGroupId) : undefined,
 
         // 院领导部门
         hospitalLeaderDeptName,
         hospitalLeaderDeptId: issueForm.hospitalLeaderDeptId,
         hospitalLeaderExecutorGroupName: findGroupNameById(issueForm.hospitalLeaderGroupId),
-        hospitalLeaderExecGroupCode: issueForm.hospitalLeaderGroupId != null ? String(issueForm.hospitalLeaderGroupId) : undefined,
+        hospitalLeaderExecGroupCode:
+          issueForm.hospitalLeaderGroupId != null ? String(issueForm.hospitalLeaderGroupId) : undefined,
 
         // 计划时间与开关项
         planStartTime: issueForm.planStartTime,
@@ -651,7 +697,10 @@
       { label: '日常安全', value: '日常安全' },
       { label: '各级危险点', value: '各级危险点' },
       { label: '试验室及试验过程', value: '试验室及试验过程' },
-      { label: '办公区域(含地下车库、图书馆、档案库房、仓库等)', value: '办公区域(含地下车库、图书馆、档案库房、仓库等)' },
+      {
+        label: '办公区域(含地下车库、图书馆、档案库房、仓库等)',
+        value: '办公区域(含地下车库、图书馆、档案库房、仓库等)',
+      },
       { label: '老旧厂房', value: '老旧厂房' },
       { label: '施工现场', value: '施工现场' },
       { label: '职工食堂', value: '职工食堂' },
@@ -673,7 +722,7 @@
       { label: '危险化学品', value: '危险化学品' },
       { label: '设施设备应急操作流程', value: '设施设备应急操作流程' },
       { label: '堆场、物资库房', value: '堆场、物资库房' },
-      { label: '室内外停车场', value: '室内外停车场' }
+      { label: '室内外停车场', value: '室内外停车场' },
     ];
     getTableData();
   });

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/components/areaCheckPlanManagementDetail.vue

@@ -690,7 +690,7 @@ import { id } from 'element-plus/es/locale';
   });
 
   const RECORD_TABLE_COLUMNS: TableColumnProps[] = [
-    { label: '编号', type: 'index', align: 'center', width: '60px' },
+    { label: '编号', type: 'index', align: 'center', width: '80px' },
     { label: '检查时间', prop: 'checkTime', minWidth: '160px' },
     { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
     { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/components/areaCheckPlanManagementDeptDetail.vue

@@ -409,7 +409,7 @@
   });
 
   const RECORD_TABLE_COLUMNS: TableColumnProps[] = [
-    { label: '编号', type: 'index', align: 'center', width: '60px' },
+    { label: '编号', type: 'index', align: 'center', width: '80px' },
     { label: '检查时间', prop: 'checkTime', minWidth: '160px' },
     { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
     { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },

+ 84 - 4
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/checkTemplateManagement/components/checkTemplateManagementDetail.vue

@@ -57,7 +57,19 @@
     </el-form>
 
     <div class="check-items-section">
-      <div class="section-header">
+      <el-button plain @click="TemplateDownload">
+        模板下载
+      </el-button>
+      <el-button plain @click="handleeDownload" v-if="isCreateMode || isEditMode">
+        导入
+      </el-button>
+      <el-button plain @click="handleeTemplateDownload" v-if="isEditMode || isViewMode">
+        导出
+      </el-button>
+    </div>
+
+    <div>
+      <!-- <div class="section-header">
         <el-upload
           v-if="isEditMode && props.id"
           :show-file-list="false"
@@ -66,7 +78,7 @@
         >
           <el-button type="primary" size="small">批量导入明细</el-button>
         </el-upload>
-      </div>
+      </div> -->
       <div class="check-items-table">
         <el-table :data="checkItems" border :span-method="handleSpanMethod">
           <el-table-column label="编号" type="index" width="80" align="center" />
@@ -120,7 +132,18 @@
         </el-table>
       </div>
     </div>
+
   </main>
+  <BatchImport
+    v-if="batchImportVisible"
+    :visible="batchImportVisible"
+    :import-api-url="importApiUrl"
+    :template-url="templateUrl"
+    template-name="下载模板"
+    :show-template="false"
+    @close="batchImportVisible = false"
+    @update="handleUpdate"
+  />
   <footer class="safety-platform-container__footer">
     <el-button @click="router.back()">返回</el-button>
     <el-button v-if="!isViewMode" type="primary" @click="handleSubmit">
@@ -140,10 +163,15 @@
     saveChecklistTemplate,
     updateChecklistTemplate,
     importChecklistTemplateItem,
+    checklistTemplateDownload,
+    checklistHandleeTemplateDownload,
     type ChecklistTemplateItem,
   } from '@/api/production-safety-system';
   import { queryDictTypeDetail } from '@/api/dict';
-
+  import { downloadByData } from '@/utils/file/download';
+  import BatchImport from '@/components/batch-import/BatchImport.vue';
+  import { useGlobSetting } from '@/hooks/setting';
+  import urlJoin from 'url-join';
   const props = defineProps<{
     id?: number;
   }>();
@@ -369,6 +397,58 @@
     return { rowspan: 1, colspan: 1 };
   };
 
+    // 批量导入
+  const batchImportVisible = ref(false);
+  const { urlPrefix } = useGlobSetting();
+  const importApiUrl = ref(urlJoin(urlPrefix, '/areaCheckPlanManageAdmin/importCheckList'));
+  const templateUrl = ref('./skyeye-file-upload/sfysecurity/TEMPLATE/import-hidden-danger-template.xlsx');
+
+  const handleeDownload = () => {
+    batchImportVisible.value = true;
+  };
+
+  const handleUpdate = (value) => {
+    batchImportVisible.value = false;
+    console.log('批量导入成功:', value);
+    if(value.importData && value.importData.length > 0){
+      let newItems = value.importData.map((item) => ({
+        checkContent: item.checkContent || '',
+        checkStandard: item.checkStandard || '',
+        checkResult: item.checkResult || '待检',
+        checkProblem: item.checkProblem || '',
+      }));
+      checkItems.value = [...checkItems.value, ...newItems];
+    }
+  };
+
+  const TemplateDownload = async () => {
+    try {
+      const response = await checklistTemplateDownload();
+      if (response) {
+        const fileName = `检查模板_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('下载成功');
+      }
+    } catch (e) {
+      console.error('下载检查模板失败:', e);
+      ElMessage.error('下载失败,请重试');
+    }
+  };
+
+  const handleeTemplateDownload = async () => {
+    try {
+      const response = await checklistHandleeTemplateDownload(Number(props.id));
+      if (response) {
+        const fileName = `检查模板_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('下载成功');
+      }
+    } catch (e) {
+      console.error('下载检查模板失败:', e);
+      ElMessage.error('下载失败,请重试');
+    }
+  };
+
   onMounted(async () => {
     await loadCategoryOptions();
     if (isEditMode.value || isViewMode.value) {
@@ -398,7 +478,7 @@
   }
 
   .check-items-section {
-    margin-top: 32px;
+    margin: 32px 0 15px 0;
   }
 
   .section-header {

+ 25 - 5
src/views/production-safety/implement-safety-duty/responsibility-agree-manage.vue

@@ -81,11 +81,31 @@
           <el-table-column label="责任书名称" prop="responsibilityName" width="180" />
           <el-table-column label="状态" prop="statusName" width="100" />
           <el-table-column label="类别名称" prop="departmentName" width="180" />
-          <el-table-column label="下发数" prop="issuedQuantity" width="120" />
-          <el-table-column label="签署人数" prop="signedQuantity" width="120" />
-          <el-table-column label="签署比例" prop="signedRatio" width="120" />
-          <el-table-column label="分组名称" prop="userGroupName" width="150" />
-          <el-table-column label="计划完成时间" prop="planEndTime" width="150" />
+          <el-table-column label="下发数" prop="issuedQuantity" width="120" >
+            <template #default="scope">
+              {{ scope.row.status == 1 ? '-' : scope.row.issuedQuantity }}
+            </template>
+          </el-table-column>
+          <el-table-column label="签署人数" prop="signedQuantity" width="120">
+            <template #default="scope">
+              {{ scope.row.status == 1 ? '-' : scope.row.signedQuantity }}
+            </template>
+          </el-table-column>
+          <el-table-column label="签署比例" prop="signedRatio" width="120">
+            <template #default="scope">
+              {{ scope.row.status == 1 ? '-' : scope.row.signedRatio }}
+            </template>
+          </el-table-column>
+          <el-table-column label="分组名称" prop="userGroupName" width="150">
+            <template #default="scope">
+              {{ scope.row.status == 1 ? '-' : scope.row.userGroupName }}
+            </template>
+          </el-table-column>
+          <el-table-column label="计划完成时间" prop="planEndTime" width="150">
+            <template #default="scope">
+              {{ scope.row.status == 1 ? '-' : scope.row.planEndTime }}
+            </template>
+          </el-table-column>
           <el-table-column fixed="right" min-width="300" label="操作">
             <template #default="scope">
               <el-button

+ 3 - 2
src/views/production-safety/productionSafetySystem/doubleSystemManagement/components/doubleSystemManagementDetail.vue

@@ -29,9 +29,9 @@
               <el-button link type="primary" @click="previewOnline(file.fileUrl, file.fileType)"
                 >预览</el-button
               >
-              <!-- <el-button link type="primary" @click.stop="downloadFile(file.fileUrl, file.fileName)"
+              <el-button link type="primary" @click.stop="downloadFile(file.fileUrl, file.fileName)"
                 >下载</el-button
-              > -->
+              >
             </div>
           </div>
         </div>
@@ -89,6 +89,7 @@
   import type { FileItem } from '@/components/UploadFiles/types';
   import { formatAttachmentList } from '@/components/UploadFiles/utils';
   import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
+  import { downloadFile } from '@/views/disaster/utils';
 
   const router = useRouter();
   const route = useRoute();

+ 1 - 1
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/configs/tables.ts

@@ -16,7 +16,7 @@ const PURCHASE_APPLY_TABLE_COLUMNS: TableColumnProps[] = [
   },
   {
     label: '申请单号',
-    prop: 'applyCode',
+    prop: 'applyCodeDesc',
     align: 'left',
     minWidth: '140px',
   },

+ 20 - 1
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/list.vue

@@ -43,12 +43,15 @@
                   placeholder="请输入申请部门名称"
                   class="act-search-input"
                   clearable
-                />
+                /> 
               </div>
             </section>
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
               <el-button @click="handleReset">重置</el-button>
+              <el-button plain  @click="handleDownload">
+                导出
+              </el-button>
             </section>
           </div>
         </header>
@@ -110,10 +113,12 @@
   import {
     queryPurchaseApplyList,
     deletePurchaseApply,
+    exportSafetyEquipmentProcurementRequest,
     type PpePurchaseApply,
     type QueryPurchaseApplyPageReq,
   } from '@/api/production-safety/personal-protective-equipment-purchase-apply';
   import { template } from 'lodash-es';
+  import { downloadByData } from '@/utils/file/download';
 
   const router = useRouter();
   const basicTableRef = ref<InstanceType<typeof BasicTable>>();
@@ -269,6 +274,20 @@
     });
   };
 
+  const handleDownload = async () => {
+    try {
+      const response = await exportSafetyEquipmentProcurementRequest(tableQuery.queryParam);
+      if (response) {
+        const fileName = `劳防用品采购申请管理_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('导出成功');
+      }
+    } catch (e) {
+      console.error('导出劳防用品采购申请管理失败:', e);
+      ElMessage.error('导出失败,请重试');
+    }
+  };
+
   onMounted(() => {
     getTableData();
   });