Selaa lähdekoodia

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

sunqijun 2 kuukautta sitten
vanhempi
commit
8037b32281

+ 79 - 0
src/api/evaluationSystem/index.ts

@@ -51,6 +51,15 @@ export interface EvaluationSystemQueryParam {
   planEndTime?: string; // 计划结束时间
 }
 
+/**
+ * 导出月度扣分请求参数
+ */
+export interface ExportMonthlyDeductionRequest {
+  deductionTitle?: string; // 扣分标题
+  status?: boolean; // 状态
+  id?: number; // 考核表ID
+}
+
 /**
  * 查询安全考核管理列表
  */
@@ -686,3 +695,73 @@ export function deleteSecurityExamineDeptAdvUser(id: number) {
     method: 'delete',
   });
 }
+
+/**
+ * 考核对象
+ */
+export function exportEvaluationTarget(query: ExportMonthlyDeductionRequest) {
+  return http.request({
+    url: '/securityExamine/admin/exportSecurityExamineIssue',
+    method: 'post',
+    data: query,
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}
+
+/**
+ * 导出先进个人
+ */
+export function exportEvaluationAdvUser(query: ExportMonthlyDeductionRequest) {
+  return http.request({
+    url: '/securityExamine/admin/exportSecurityExamineIssueAdvancedUser',
+    method: 'post',
+    data: query,
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}
+
+/**
+ * 导出部门排序
+ */
+export function exportEvaluationDeptSort(query: ExportMonthlyDeductionRequest) {
+  return http.request({
+    url: '/securityExamine/admin/exportSecurityExamineIssueAdvanced',
+    method: 'post',
+    data: query,
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}
+
+/**
+ * 下载模板
+ */
+export function addDownloadTheTemplate(query: ExportMonthlyDeductionRequest) {
+  return http.request({
+    url: '/securityExamine/admin/exportImportSecurityExamineDetTemplate',
+    method: 'get',
+    data: query,
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}
+
+/**
+ * 导出安全检查详情
+ */
+export function exportSecurityExamineDet(query: ExportMonthlyDeductionRequest) {
+  return http.request({
+    url: '/securityExamine/admin/exportSecurityExamineDet?id=' + query.id,
+    method: 'get',
+    data: query,
+    responseType: 'blob',
+  }, {
+    isTransformResponse: false,
+  });
+}

+ 136 - 15
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/components/detail.vue

@@ -83,14 +83,42 @@
           </el-table-column>
           <el-table-column label="样式照片" min-width="420" align="center">
             <template #default="{ row }">
-              <span v-if="isViewMode || isAuditMode">{{ getStylePhotoDisplay(row) }}</span>
-              <UploadFiles
+              <!-- <span v-if="isViewMode || isAuditMode">{{ getStylePhotoDisplay(row) }}</span> -->
+              <!-- <UploadFiles
                 v-else
-                label="选择附件"
+                label="选择附件" 
                 :file-list="getRowFileList(row)"
                 :max-count="1"
                 @uploadSuccess="(list: FileItem[]) => onStylePhotoSuccess(row, list)"
-              />
+              /> -->
+              <el-upload
+                :key="row.id || row.$$uid || $index"
+                :ref="el => setUploadRef(row, el)"
+                v-model:file-list="row.pictureUrl"
+                :auto-upload="false"
+                list-type="picture-card"
+                :limit="1"
+                :disabled="isViewMode"
+                :on-change="(file) => handleApprovalImageChange(row, file)"
+                :on-exceed="handleApprovalImageExceed"
+                :on-remove="() => handleApprovalImageRemove(row)"
+                :class="{'hide': isViewMode}"
+              >
+                <el-icon><Plus /></el-icon>
+                <template #file="{ file }"> 
+                  <div>
+                    <img class="el-upload-list__item-thumbnail" :src="file.fileUrl" alt="" />
+                    <span class="el-upload-list__item-actions">
+                      <span class="el-upload-list__item-preview" v-if="isViewMode" @click="previewOnline(file.fileUrl)">
+                        <el-icon><ZoomIn /></el-icon>
+                      </span>
+                      <span class="el-upload-list__item-delete" v-if="!isViewMode" @click.stop="handleApprovalDeleteClick()">
+                        <el-icon><Delete /></el-icon>
+                      </span>
+                    </span>
+                  </div>
+                </template>
+              </el-upload>
             </template>
           </el-table-column>
           <el-table-column label="物品尺寸/鞋码" min-width="150">
@@ -143,13 +171,14 @@
           <el-table-column label="商品编号" min-width="150">
             <template #default="{ row }">
               <!-- v-if="isViewMode || isAuditMode || isCreateMode" -->
-              <span>{{ row.productNo || row.equipmentId || '-' }}</span>
-              <!-- <el-input
+              <!-- <span>{{ row.productNo || row.equipmentId || '-' }}</span> -->
+              <span v-if="isViewMode || isAuditMode">{{ row.equipmentId ?? '-' }}</span>
+              <el-input
                 v-else
-                v-model="row.productNo"
+                v-model="row.equipmentId"
                 placeholder="请输入..."
                 clearable
-              /> -->
+              />
             </template>
           </el-table-column>
           <el-table-column label="备注" min-width="150">
@@ -308,7 +337,7 @@
         <el-button @click="basicDialogRef.closeDialog">取消</el-button>
       </template>
     </BasicDialog>
-
+    <PreviewOnline ref="previewOnlineRef" />
   </main>
   <footer class="safety-platform-container__footer">
     <el-button @click="router.back()">返回</el-button>
@@ -331,10 +360,12 @@
 <script setup lang="ts">
   import { computed, onMounted, ref, reactive } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
-  import { ElMessage } from 'element-plus';
-  import type { FormInstance, FormRules } from 'element-plus';
-  import { Plus, Minus } from '@element-plus/icons-vue';
+  // import { ElMessage } from 'element-plus';
+  // import type { FormInstance, FormRules } from 'element-plus';
+  import { ElMessage , ElIcon, genFileId, FormInstance, FormRules, type UploadProps, type UploadUserFile, type UploadRawFile, type UploadInstance } from 'element-plus';
+  // import { Plus, Minus } from '@element-plus/icons-vue';
   import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
+  import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
   import type { FileItem } from '@/components/UploadFiles/types';
   import { queryPersonalProtectiveEquipmentList } from '@/api/production-safety/personal-protective-equipment';
   import type { PersonalProtectiveEquipment } from '@/api/production-safety/personal-protective-equipment';
@@ -364,6 +395,18 @@
   import { getApprovalNodeInstanceList } from '@/api/approval/approval';
   import { i } from 'vite/dist/node/types.d-jgA8ss1A';
   import { te } from 'element-plus/es/locale';
+  import { Plus, Delete, ZoomIn } from '@element-plus/icons-vue';
+  import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
+  const approvalImageFileList = ref<UploadUserFile[]>([]);
+  const uploadRefs = ref<Record<string, UploadInstance>>({});
+  // 为每行设置独立的upload ref
+  const setUploadRef = (row: PurchaseApplyItem, el: any) => {
+    if (el) {
+      const key = row.id || row.$$uid || 'default';
+      uploadRefs.value[key] = el;
+    }
+  };
+  const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
 
   const { approvalList, getApprovalList } =
   useEmergencyHook()
@@ -520,7 +563,7 @@
     const found = ppeOptions.value.find((p) => p.ppeName === ppeName);
     if (found?.id) {
       row.ppeId = found.id;
-      row.equipmentId = found.id;
+      // row.equipmentId = found.id;
       row.productNo = String(found.id);
     }
   }
@@ -560,6 +603,9 @@
       form.applyNo = mainFromQuery.value.applyCode ?? '';
       const res = await queryPurchaseApplyDetail(currentId.value);
       if (res && Array.isArray(res) && res.length) {
+        res.forEach((d) => {
+          d.pictureUrl =JSON.parse(d.pictureUrl || '[]');
+        });
         form.itemList = res.map((d) => detailToItem(d));
       } else if (res && Array.isArray(res)) {
         form.itemList = [defaultItem()];
@@ -738,7 +784,7 @@
     auditSubmitting.value = true;
     try {
       await auditPurchaseApply({ id: currentId.value, status: 3, rejectReason: rejectReason.value.trim(), approvalOrder: Number(approvalOrder.value),templateId: form.approvalTemplateId });
-      ElMessage.success('已提交审核不通过');
+      ElMessage.success('提交成功');
       showRejectDialog.value = false;
       router.back();
     } catch (e) {
@@ -793,6 +839,78 @@
     });
   };
 
+  const handleApprovalImageChange = (row: PurchaseApplyItem, uploadFile: UploadUserFile) => {
+    if (!uploadFile.raw) return;
+
+    uploadFileApi({
+      file: uploadFile.raw,
+      bizType: UPLOAD_BIZ_TYPE['DICTIONARY'],
+      fileName: uploadFile.raw.name,
+    })
+      .then((res) => {
+        // 更新当前行的图片URL
+        row.pictureUrl = [{
+          fileName: uploadFile.name || res.url.split('/').pop() || 'image',
+          fileUrl: res.url,
+          fileId: res.uid
+        }];
+        
+        // 同时更新stylePhoto字段
+        row.stylePhoto = JSON.stringify([{
+          fileUrl: res.url,
+          fileName: uploadFile.name || res.url.split('/').pop() || 'image',
+          fileId: res.uid,
+          fileType: 'image',
+          fileSize: uploadFile.size ? (uploadFile.size / 1024).toFixed(2) + 'KB' : ''
+        }]);
+      })
+      .catch(() => {
+        ElMessage.error('图片上传失败,请重试');
+      });
+  };
+
+  const handleApprovalImageExceed: UploadProps['onExceed'] = (files) => {
+    const uploadInstance = approvalUploadRef.value;
+    if (!uploadInstance) return;
+
+    uploadInstance.clearFiles();
+    const file = files[0] as UploadRawFile;
+    file.uid = genFileId();
+    uploadInstance.handleStart(file);
+  };
+
+  const handleApprovalPictureCardPreview: UploadProps['onPreview'] = (fileUrl) => {
+    
+    // dialogImageUrl.value = uploadFile.url || '';
+    // dialogVisible.value = true;
+  };
+
+  const resetApprovalImageUpload = () => {
+    // 清除所有行的图片数据
+    form.itemList.forEach(row => {
+      row.pictureUrl = [];
+      row.stylePhoto = '';
+    });
+    approvalImageFileList.value = [];
+    form.itemList[approvalUploadKey.value].imageUrl = [];
+  };
+
+  const handleApprovalDeleteClick = () => {
+    resetApprovalImageUpload();
+  };
+
+  const handleApprovalImageRemove = (row: PurchaseApplyItem) => {
+    // 清除当前行的图片数据
+    row.pictureUrl = [];
+    row.stylePhoto = '';
+  };
+
+  const previewOnline = (url: string | undefined) => {
+    if (url) {
+      previewOnlineRef.value?.open(url,'image');
+    }
+  };
+
   onMounted(() => {
     loadPpeOptions();
     getApprovalList();
@@ -845,4 +963,7 @@
   .detail-reject-alert{
     margin-bottom: 20px;
   }
-</style>
+  ::v-deep.hide .el-upload--picture-card {
+    display: none;
+  }
+</style>

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

@@ -15,10 +15,10 @@
           <div class="act-search">
             <section class="select-box">
               <div class="select-box--item">
-                <span>用品名称/申请人:</span>
+                <span>申请人:</span>
                 <el-input
                   v-model="tableQuery.queryParam.name"
-                  placeholder="请输入用品名称或申请人"
+                  placeholder="请输入申请人"
                   class="act-search-input"
                   clearable
                 />

+ 5 - 5
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/listAdmin.vue

@@ -15,15 +15,15 @@
           <div class="act-search">
             <section class="select-box">
               <div class="select-box--item">
-                <span>用品名称/申请人:</span>
+                <span>申请人:</span>
                 <el-input
                   v-model="tableQuery.queryParam.name"
-                  placeholder="请输入用品名称或申请人"
+                  placeholder="请输入申请人"
                   class="act-search-input"
                   clearable
                 />
               </div>
-              <div class="select-box--item">
+              <!-- <div class="select-box--item">
                 <span>状态:</span>
                 <el-select
                   v-model="tableQuery.queryParam.approvalStatus"
@@ -35,7 +35,7 @@
                   <el-option label="审核通过" :value="2" />
                   <el-option label="审核不通过" :value="3" />
                 </el-select>
-              </div>
+              </div> -->
               <div class="select-box--item">
                 <span>申请部门:</span>
                 <el-input
@@ -131,7 +131,7 @@
     pageSize: pagination.pageSize,
     queryParam: {
       name: '',
-      approvalStatus: undefined,
+      status: 1,
       applyDeptCode: '',
       applyDeptName: '',
     },

+ 17 - 2
src/views/production-safety/risk-identification-and-control/work-injury-apply-manage/components/detail.vue

@@ -7,7 +7,15 @@
       show-icon
       class="detail-reject-alert"
     />
-
+    <div class="detail-reject-alert">
+      <div class="detail-reject-alert-name">
+        填表说明:
+      </div>
+      <div class="detail-reject-alert-content">
+        4张(事故报告、委托书、地址确认书、申请表)工伤认定表格需下载模版,手填,上传相关材料给吴剑希审批(驳回或通过)+判定工伤类别(责任事故/非责任事故);通过后状态变为申请加盖公章及材料申请;用印申请后编写一段告知通知(内容先把告知单信息先编辑进去),给申请人。
+        
+      </div>
+    </div>
     <BasicForm
       ref="basicFormRef"
       :formData="ruleFormData"
@@ -824,7 +832,7 @@
     auditSubmitting.value = true;
     try {
       await auditPurchaseApply({ id: currentId.value, status: auditType.value === true ? 2 : 3, rejectReason: rejectReason.value.trim(), approvalOrder: Number(approvalOrder.value),templateId: approvalTemplateId.value,code: rejectReason.value });
-      ElMessage.success('已提交审核通过');
+      ElMessage.success('审核通过');
       showRejectDialog.value = false;
       router.back();
     } catch (e) {
@@ -857,4 +865,11 @@
   .detail-reject-alert{
     margin-bottom: 20px;
   }
+  .detail-reject-alert-name{
+    color: #aaa;
+    margin-bottom: 10px;
+  }
+  .detail-reject-alert-content{
+    color: #aaa;
+  }
 </style>

+ 7 - 6
src/views/production-safety/risk-identification-and-control/work-injury-apply-manage/list.vue

@@ -31,7 +31,7 @@
               <div class="select-box--item">
                 <span>状态:</span>
                 <el-select
-                  v-model="tableQuery.queryParam.workStatus"
+                  v-model="tableQuery.queryParam.status"
                   placeholder="请选择状态"
                   clearable
                 >
@@ -92,7 +92,7 @@
                 <!-- 申请加盖公章及材料申请 -->
                 <template v-else-if="scope.row.workStatus === 2 || scope.row.workStatus === '2'">
                   <ActionButton text="查看" @click="handleView(scope.row.id)" />
-                  <!-- <ActionButton text="确认" @click="confirmDialog = true;confirmId = scope.row.id;" /> -->
+                  <ActionButton text="确认" @click="confirmDialog = true;confirmId = scope.row.id;" />
                 </template>
                 <!-- 审核不通过:编辑、删除、查看 -->
                 <template v-else-if="scope.row.workStatus === 3 || scope.row.workStatus === '3'">
@@ -213,7 +213,7 @@
     pageSize: pagination.pageSize,
     queryParam: {
       queryKey: '', // 名称
-      workStatus: '', // 状态,默认启用
+      status: '', // 状态,默认启用
       ids: [], // 选择数据的ID
       deptCode: '', // 所属部门ID
     },
@@ -253,7 +253,7 @@
           approvalOrder: item.approvalOrder, // 审批订单
           templateId: item.templateId, // 模板ID
           injuryCategoryCode: item.injuryCategoryCode, // 工伤类别编码
-          rejectReason: item.workDescription, // 拒绝原因
+          rejectReason: item.rejectReason, // 拒绝原因
         }));
         pagination.total = res.totalRow;
       }
@@ -274,8 +274,9 @@
 
   const handleReset = () => {
     tableQuery.queryParam.queryKey = '';
-    tableQuery.queryParam.workStatus = ''; // 重置为默认启用状态
+    tableQuery.queryParam.status = ''; // 重置为默认启用状态
     tableQuery.queryParam.ids = [];
+    tableQuery.queryParam.deptCode = ''; // 重置为默认启用状态
     handleSearch();
   };
 
@@ -327,7 +328,7 @@
       name: 'workInjuryApplyManageItem',
       query: {
         id,
-        rejectReason:row.workDescription ?? '',
+        rejectReason:row.rejectReason ?? '',
         approvalTemplateId:row.templateId ?? '',
         approvalOrder:row.approvalOrder ?? '',
         approvalStatus:row.workStatus ?? '',

+ 7 - 6
src/views/production-safety/risk-identification-and-control/work-injury-apply-manage/listAdmin.vue

@@ -28,10 +28,10 @@
                   class="act-search-input"
                 />
               </div>
-              <div class="select-box--item">
+              <!-- <div class="select-box--item">
                 <span>状态:</span>
                 <el-select
-                  v-model="tableQuery.queryParam.approvalStatus"
+                  v-model="tableQuery.queryParam.status"
                   placeholder="请选择状态"
                   clearable
                 >
@@ -40,7 +40,7 @@
                   <el-option label="审核不通过" :value="3" />
                   <el-option label="已完成" :value="4" />
                 </el-select>
-              </div>
+              </div> -->
               <div class="select-box--item">
                 <span>所属部门:</span>
                  <el-cascader
@@ -92,7 +92,7 @@
                 <!-- 申请加盖公章及材料申请 -->
                 <template v-else-if="scope.row.approvalStatus === 2 || scope.row.approvalStatus === '2'">
                   <ActionButton text="查看" @click="handleView(scope.row.id)" />
-                  <ActionButton text="确认" @click="confirmDialog = true;confirmId = scope.row.id;" />
+                  <!-- <ActionButton text="确认" @click="confirmDialog = true;confirmId = scope.row.id;" /> -->
                 </template>
                 <!-- 审核不通过:编辑、删除、查看 -->
                 <template v-else-if="scope.row.approvalStatus === 3 || scope.row.approvalStatus === '3'">
@@ -214,7 +214,7 @@
     pageSize: pagination.pageSize,
     queryParam: {
       queryKey: '', // 物品名称
-      approvalStatus: '', // 状态,默认启用
+      status: '', // 状态,默认启用
       ids: [], // 选择数据的ID
       deptCode: '', // 所属部门ID
     },
@@ -275,8 +275,9 @@
 
   const handleReset = () => {
     tableQuery.queryParam.queryKey = '';
-    tableQuery.queryParam.approvalStatus = ''; // 重置为默认启用状态
+    tableQuery.queryParam.status = ''; // 重置为默认启用状态
     tableQuery.queryParam.ids = [];
+    tableQuery.queryParam.deptCode = ''; // 重置为默认启用状态
     handleSearch();
   };
 

+ 0 - 1
src/views/production-safety/safety-culture/safetyCultureActivityManagementExecutor/components/safetyCultureActivityManagementDetail.vue

@@ -315,7 +315,6 @@
   };
 
   const previewOnline = (url: string | undefined, type) => {
-    debugger
     if (url) {
       previewOnlineRef.value?.open(url, type);
     }

+ 21 - 3
src/views/production-safety/safetyAssessment/evaluationSystem/components/EvaluationSystemAdvancedPerson.vue

@@ -240,6 +240,7 @@
     updateSecurityExamineAdvUserAdmin,
     deleteSecurityExamineDeptAdvUser,
     querySecurityExamineAdvUser,
+    exportEvaluationAdvUser,
   } from '@/api/evaluationSystem';
   import type {
     QuerySecurityExamineIssueAdvancedUserParams,
@@ -250,6 +251,7 @@
   } from '@/api/evaluationSystem';
   import { getAllDepartments } from '@/api/auth/dept';
   import type { DeptTree } from '@/types/dept/type';
+  import { downloadByData } from '@/utils/file/download';
 
   const route = useRoute();
 
@@ -674,9 +676,25 @@
     }
   };
 
-  const handleExport = () => {
-    // TODO: 导出当前筛选结果
-    console.log('export advanced person list', tableQuery);
+  const handleExport = async () => {
+    try {
+      const exportParams = {
+        psemId: evaluationId.value,
+        deptName: tableQuery.queryParam.deptName || undefined,
+        userName: tableQuery.queryParam.userName || undefined,
+        planStartTime: tableQuery.queryParam.startTime || undefined,
+        planEndTime: tableQuery.queryParam.endTime || undefined,
+      };
+      const response = await exportEvaluationAdvUser(exportParams);
+      if (response) {
+        const fileName = `先进个人_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('导出成功');
+      }
+    } catch (e) {
+      console.error('导出月度扣分失败:', e);
+      ElMessage.error(e?.message || e?.data || '导出失败,请重试');
+    }
   };
 
   // 格式化日期时间

+ 37 - 5
src/views/production-safety/safetyAssessment/evaluationSystem/components/EvaluationSystemDetail.vue

@@ -24,8 +24,9 @@
 
     <div class="evaluation-items-section">
       <div class="section-header">
-        <!-- <el-button plain @click="handleDownloadTemplate">模板下载</el-button> -->
-        <!-- <el-button plain @click="handleImport">导入</el-button> -->
+        <el-button plain @click="handleDownloadTemplate">模板下载</el-button>
+        <el-button plain @click="importDialogVisible = true">导入</el-button>
+        <el-button plain v-if="isEditMode" @click="handleExport">导出</el-button>
       </div>
       <div class="evaluation-items-table">
         <el-table :data="evaluationItems" border :span-method="handleSpanMethod">
@@ -144,12 +145,15 @@
     saveSecurityExamine,
     querySecurityExamineDetail,
     updateSecurityExamine,
+    addDownloadTheTemplate,
+    exportSecurityExamineDet,
   } from '@/api/evaluationSystem';
   import type { EvaluationContent } from '@/api/evaluationSystem';
   import type { FileItem } from '@/components/UploadFiles/types';
   import { useUserInfoHook } from '@/hooks/useUserInfoHook';
   import { formatAttachmentList } from '@/components/UploadFiles/utils';
   import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
+  import { downloadByData } from '@/utils/file/download';
 
   const props = defineProps<{
     id?: number;
@@ -228,9 +232,19 @@
     ruleFormData.value.attachmentDocument = files;
   };
 
-  const handleDownloadTemplate = () => {
-    // TODO: 下载模板
-    console.log('download template');
+  const handleDownloadTemplate = async () => {
+    try {
+      const exportParams = {};
+      const response = await addDownloadTheTemplate(exportParams);
+      if (response) {
+        const fileName = `安全考核内容模板_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('导出成功');
+      }
+    } catch (e) {
+      console.error('导出月度扣分失败:', e);
+      ElMessage.error(e?.message || e?.data || '导出失败,请重试');
+    }
   };
 
   // 导入弹窗相关
@@ -759,6 +773,24 @@
     }
   };
 
+  const handleExport = async () => {
+      try {
+        const exportParams = {
+          id: props.id || 0,
+        };
+        const response = await exportSecurityExamineDet(exportParams);
+        if (response) {
+          const fileName = `${route.query.operate == 'evaluationSystem-advanced-group' ? '部门考核' : '考核对象'}_${new Date().toISOString().split('T')[0]}.xlsx`;
+          downloadByData(response, fileName);
+          ElMessage.success('导出成功');
+        }
+      } catch (e) {
+        console.error('导出月度扣分失败:', e);
+        ElMessage.error(e?.message || e?.data || '导出失败,请重试');
+      }
+    };
+
+
   onMounted(() => {
     // 获取复评人列表
     getReviewUserList();

+ 20 - 3
src/views/production-safety/safetyAssessment/evaluationSystem/components/EvaluationTarget.vue

@@ -298,6 +298,8 @@
     updateSecurityExamineIssueRepeal,
     deleteSecurityExamineIssue,
     querySecurityExamineIssueAdvanced,
+    exportEvaluationDeptSort,
+    exportEvaluationTarget,
   } from '@/api/evaluationSystem';
   import type { QuerySecurityExamineIssueParams, EvaluationSystemItem } from '@/api/evaluationSystem';
   import { ElMessage } from 'element-plus';
@@ -305,6 +307,7 @@
   import { downloadFile } from '@/views/disaster/utils';
   import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
   import { FILE_TYPE_ICON } from '@/components/UploadFiles/constants';
+  import { downloadByData } from '@/utils/file/download';
 
   const route = useRoute();
   const router = useRouter();
@@ -550,9 +553,23 @@
     handleSearch();
   };
 
-  const handleExport = () => {
-    // TODO: 导出当前筛选结果
-    console.log('export evaluation target list', tableQuery);
+  const handleExport = async () => {
+    try {
+      const exportParams = {
+        psemId: evaluationId.value,
+        deductionTitle: tableQuery.queryParam.deductionTitle || undefined,
+        status: tableQuery.queryParam.status === '' ? '' : Number(tableQuery.queryParam.status),
+      };
+      const response = route.query.operate == 'evaluationSystem-advanced-group' ? await exportEvaluationDeptSort(exportParams) : await exportEvaluationTarget(exportParams);
+      if (response) {
+        const fileName = `${route.query.operate == 'evaluationSystem-advanced-group' ? '部门考核' : '考核对象'}_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('导出成功');
+      }
+    } catch (e) {
+      console.error('导出月度扣分失败:', e);
+      ElMessage.error(e?.message || e?.data || '导出失败,请重试');
+    }
   };
 
   const handleBatchDelete = () => {

+ 1 - 1
src/views/production-safety/safetyAssessment/evaluationSystem/evaluationSystem.vue

@@ -115,7 +115,7 @@
 
                 <!-- 待反馈:作废 / 考核对象 -->
                 <template v-else-if="Number(scope.row.status) === 2">
-                  <ActionButton text="下发" @click="handleIssue(scope.row.id)" />
+                  <!-- <ActionButton text="下发" @click="handleIssue(scope.row.id)" /> -->
                   <ActionButton
                     text="作废"
                     :popconfirm="{

+ 2 - 2
src/views/production-safety/safetyAssessment/pointDeduction/pointDeduction.vue

@@ -8,12 +8,12 @@
         <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 plain class="search-table-container--button" @click="handleImport">
               导入
             </el-button>
             <el-button plain class="search-table-container--button" @click="handleDownload">
               导出
-            </el-button> -->
+            </el-button>
           </div>
 
           <div class="act-search">