Просмотр исходного кода

Merge branch 'feat/production-safety' into 'dev'

Feat/production safety

See merge request product-group-fe/sfy-safety-group/sfy-safety!347
ai0197(吴云丰) 1 месяц назад
Родитель
Сommit
aedcd86e08
30 измененных файлов с 721 добавлено и 218 удалено
  1. 55 0
      src/api/equipment-high-alert-List/index.ts
  2. 25 0
      src/api/production-education-training-plan-dept/index.ts
  3. 24 0
      src/api/production-safety-system/index.ts
  4. 13 1
      src/api/production-safety/personal-protective-equipment-purchase-apply.ts
  5. 1 1
      src/api/safety-organization-management/index.ts
  6. 9 0
      src/main.scss
  7. 2 1
      src/main.ts
  8. 1 0
      src/plugins/index.ts
  9. 12 0
      src/plugins/wangEditor.ts
  10. 48 0
      src/utils/wangEditorUpload.ts
  11. 86 37
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/areaCheckPlanManagement.vue
  12. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/components/areaCheckPlanManagementDetail.vue
  13. 102 3
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/components/areaCheckPlanManagementDeptDetail.vue
  14. 84 4
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/checkTemplateManagement/components/checkTemplateManagementDetail.vue
  15. 46 3
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/components/hiddenTroubleAccountManagementDetail.vue
  16. 37 29
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form.ts
  17. 33 5
      src/views/production-safety/implement-safety-duty/responsibility-agree-manage.vue
  18. 5 4
      src/views/production-safety/implement-safety-duty/sign-agree-dept.vue
  19. 3 2
      src/views/production-safety/productionSafetySystem/doubleSystemManagement/components/doubleSystemManagementDetail.vue
  20. 2 0
      src/views/production-safety/productionSafetySystem/doubleSystemManagement/configs/form.ts
  21. 18 65
      src/views/production-safety/risk-identification-and-control/equipment-high-alert/list.vue
  22. 8 8
      src/views/production-safety/risk-identification-and-control/hazard-manage/add.vue
  23. 7 7
      src/views/production-safety/risk-identification-and-control/hazard-manage/edit.vue
  24. 15 4
      src/views/production-safety/risk-identification-and-control/hazard-manage/list.vue
  25. 6 6
      src/views/production-safety/risk-identification-and-control/hazard-manage/view.vue
  26. 1 1
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/configs/tables.ts
  27. 20 1
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/list.vue
  28. 4 4
      src/views/production-safety/risk-identification-and-control/special-equipment-manage/add.vue
  29. 37 27
      src/views/production-safety/safetyTrainingAndEducation/educationTrainingPlanManagementDept/components/addTrainingInformation.vue
  30. 16 4
      src/views/production-safety/safetyTrainingAndEducation/educationTrainingPlanManagementDept/components/educationTrainingPlanManagementDeptDetail.vue

+ 55 - 0
src/api/equipment-high-alert-List/index.ts

@@ -0,0 +1,55 @@
+/*
+ * @Author: liuJie
+ * @Date: 2026-03-12 16:06:18
+ * @LastEditors: liuJie
+ * @LastEditTime: 2026-03-12 16:11:25
+ * @Describe: 告警列表
+ */
+import { http } from '@/utils/http/axios';
+
+export interface QueryParamType {
+    pageNumber: number;
+    pageSize: number;
+    queryParam: {
+      //设备编码
+      deviceNo?: string | undefined;
+      //设备名称
+      deviceName?: string | undefined;
+      // 设备类型
+      deviceType?: string | undefined;
+      // 告警类型
+      alarmType?: string | undefined;
+      // 所属部门
+      deptName?: string | undefined;
+      // 开始时间
+      startTime: string | undefined,
+      // 结束
+      endTime: string | undefined,
+    };
+  }
+  // 列表数据
+export const equipmentHighAlertList = (query: QueryParamType)=>{
+  return http.request({
+    url: '/prodAlarm/queryProdAlarm',
+    method: 'post',
+    data: query,
+  });
+}
+  // 所属部门
+export const deptList = ()=>{
+  return http.request({
+    url: '/prodAlarm/queryDept',
+    method: 'post',
+  });
+}
+// 导出接口
+export const exportTableData = (params)=>{
+    return http.request({
+        url: '/prodAlarm/export',
+        method: 'post',
+        data: params,
+        responseType: 'blob',
+    }, {
+        isTransformResponse: false,
+    });
+}

+ 25 - 0
src/api/production-education-training-plan-dept/index.ts

@@ -12,6 +12,13 @@ export interface ProductionSafetyFileQuery {
   endDate?: string; // 上传日期范围-结束日期
   endDate?: string; // 上传日期范围-结束日期
 }
 }
 
 
+// 课程参数
+export interface QueryType {
+  petpiId?:string | number;
+  courseName?: string | number;
+  dateStart?: string;
+  dateEnd?:string;
+}
 // 新增、编辑表单数据类型
 // 新增、编辑表单数据类型
 export interface FormDataType {
 export interface FormDataType {
   id?: string; // 编辑时使用
   id?: string; // 编辑时使用
@@ -125,6 +132,24 @@ export function queryEducationTrainingPlanCourseDetail(id: string | number) {
 }
 }
 
 
 
 
+/**
+ * @description: 导出课程
+ * @param {QueryType} params
+ * @return {*}
+ */
+export function exportEducationTrainingPlanCourseData(params: QueryType){
+  return http.request(
+    {
+        url: '/educationTrainingPlanIssuance/exportEducationTrainingPlanCourse',
+        method: 'post',
+        responseType: 'blob',
+        params,
+        },
+        { isTransformResponse: false },
+    );
+}
+
+
 /**
 /**
  * 教育培训计划管理(部门)-详情
  * 教育培训计划管理(部门)-详情
  */
  */

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

@@ -1027,6 +1027,7 @@ function buildPageQuery(uiQuery: { pageNumber: number; pageSize: number; queryPa
       checkPlaceCategory: q.venueCategory ?? undefined,
       checkPlaceCategory: q.venueCategory ?? undefined,
       startDate: q.startDate ?? q.planStartTime ?? undefined,
       startDate: q.startDate ?? q.planStartTime ?? undefined,
       endDate: q.endDate ?? q.planEndTime ?? undefined,
       endDate: q.endDate ?? q.planEndTime ?? undefined,
+      id: q.id ?? undefined,
     },
     },
   };
   };
 }
 }
@@ -1564,3 +1565,26 @@ export function exportInspectionRecordTow (params: AreaCheckPlanQuery) {
     isTransformResponse: false,
     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',
     method: 'post',
     data,
     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)=>{
 export const exportSafetyOrganizationSystemManagement = (params)=>{
   return http.request({
   return http.request({
     url: `/safetyorguser/exportSafetyOrgUser`,
     url: `/safetyorguser/exportSafetyOrgUser`,
-    method: 'get',
+    method: 'post',
     params,
     params,
     responseType: 'blob',
     responseType: 'blob',
   }, {
   }, {

+ 9 - 0
src/main.scss

@@ -54,3 +54,12 @@ body {
   justify-content: flex-end;
   justify-content: flex-end;
   margin-top: 20px;
   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 'element-plus/dist/index.css';
 import App from './App.vue';
 import App from './App.vue';
 import BreadcrumbBack from '@/components/BreadcrumbBack.vue';
 import BreadcrumbBack from '@/components/BreadcrumbBack.vue';
-import { setupElement, setupDirectives } from '@/plugins';
+import { setupElement, setupDirectives, setupWangEditorUpload } from '@/plugins';
 import dayjs from 'dayjs';
 import dayjs from 'dayjs';
 import 'dayjs/locale/zh-cn';
 import 'dayjs/locale/zh-cn';
 import '@/utils/g6Extensions';
 import '@/utils/g6Extensions';
@@ -15,6 +15,7 @@ import { notivue } from '@/components/custom-notivue/notivue-conf';
 import 'virtual:svg-icons-register';
 import 'virtual:svg-icons-register';
 
 
 dayjs.locale('zh-cn');
 dayjs.locale('zh-cn');
+setupWangEditorUpload();
 
 
 async function bootstrap() {
 async function bootstrap() {
   const app = createApp(App);
   const app = createApp(App);

+ 1 - 0
src/plugins/index.ts

@@ -1,2 +1,3 @@
 export { setupElement } from '@/plugins/element';
 export { setupElement } from '@/plugins/element';
 export { setupDirectives } from '@/plugins/directives';
 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">
       <div class="search-table-container">
         <header>
         <header>
           <div style="position: relative">
           <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>
 
 
           <div class="act-search">
           <div class="act-search">
@@ -28,11 +24,7 @@
               </div>
               </div>
               <div class="select-box--item">
               <div class="select-box--item">
                 <span>状态:</span>
                 <span>状态:</span>
-                <el-select
-                  v-model="tableQuery.queryParam.status"
-                  placeholder="请选择状态"
-                  clearable
-                >
+                <el-select v-model="tableQuery.queryParam.status" placeholder="请选择状态" clearable>
                   <el-option
                   <el-option
                     v-for="item in AREA_CHECK_PLAN_STATUS_OPTIONS"
                     v-for="item in AREA_CHECK_PLAN_STATUS_OPTIONS"
                     :key="String(item.value)"
                     :key="String(item.value)"
@@ -73,9 +65,7 @@
             <section class="search-btn">
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
               <el-button type="primary" @click="handleSearch">查询</el-button>
               <el-button @click="handleReset">重置</el-button>
               <el-button @click="handleReset">重置</el-button>
-              <el-button plain  @click="handleDownload">
-                导出
-              </el-button>
+              <el-button plain @click="handleDownload"> 导出 </el-button>
             </section>
             </section>
           </div>
           </div>
         </header>
         </header>
@@ -92,10 +82,14 @@
               <span>{{ AREA_CHECK_PLAN_STATUS_LABEL[String(scope.row.status)] ?? '-' }}</span>
               <span>{{ AREA_CHECK_PLAN_STATUS_LABEL[String(scope.row.status)] ?? '-' }}</span>
             </template>
             </template>
             <template #needOverallDesc="scope">
             <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>
             <template #needSigneeSign="scope">
             <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>
             <template #action="scope">
             <template #action="scope">
               <div class="action-container--div" style="justify-content: left">
               <div class="action-container--div" style="justify-content: left">
@@ -200,12 +194,7 @@
             clearable
             clearable
             style="width: 100%"
             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-select>
         </el-form-item>
         </el-form-item>
         <el-form-item label="院领导部门:" prop="hospitalLeaderDeptId">
         <el-form-item label="院领导部门:" prop="hospitalLeaderDeptId">
@@ -228,12 +217,7 @@
             clearable
             clearable
             style="width: 100%"
             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-select>
         </el-form-item>
         </el-form-item>
         <el-form-item label="计划开始日期:" prop="planStartTime">
         <el-form-item label="计划开始日期:" prop="planStartTime">
@@ -295,7 +279,12 @@
   import BasicTable from '@/components/BasicTable.vue';
   import BasicTable from '@/components/BasicTable.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import ActionButton from '@/components/ActionButton.vue';
   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 { useRouter } from 'vue-router';
   import type { QueryPageRequest } from '@/types/basic-query';
   import type { QueryPageRequest } from '@/types/basic-query';
   import type { AreaCheckPlanQuery, AreaCheckPlanRecord } from './configs/types';
   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 => {
   const findDeptNameById = (nodes: DeptTree[] | undefined, id: number | undefined): string | undefined => {
@@ -412,6 +428,30 @@
     return undefined;
     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 findDeptNamesByIds = (nodes: DeptTree[] | undefined, ids: number[] | undefined): string[] => {
     const list = (ids ?? []).filter((v) => v != null);
     const list = (ids ?? []).filter((v) => v != null);
     if (!list.length) return [];
     if (!list.length) return [];
@@ -548,7 +588,11 @@
     if (!issueFormRef.value || !currentIssuePlanId.value) return;
     if (!issueFormRef.value || !currentIssuePlanId.value) return;
     const valid = await issueFormRef.value.validate().catch(() => false);
     const valid = await issueFormRef.value.validate().catch(() => false);
     if (!valid) return;
     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('计划开始日期不能大于计划结束日期');
       ElMessage.error('计划开始日期不能大于计划结束日期');
       return;
       return;
     }
     }
@@ -580,13 +624,15 @@
         safetyEmergencyDeptName,
         safetyEmergencyDeptName,
         safetyEmergencyDeptId: issueForm.safetyEmergencyDeptId,
         safetyEmergencyDeptId: issueForm.safetyEmergencyDeptId,
         safetyEmergencyExecutorGroupName: findGroupNameById(issueForm.safetyEmergencyGroupId),
         safetyEmergencyExecutorGroupName: findGroupNameById(issueForm.safetyEmergencyGroupId),
-        safetyEmergencyExecGroupCode: issueForm.safetyEmergencyGroupId != null ? String(issueForm.safetyEmergencyGroupId) : undefined,
+        safetyEmergencyExecGroupCode:
+          issueForm.safetyEmergencyGroupId != null ? String(issueForm.safetyEmergencyGroupId) : undefined,
 
 
         // 院领导部门
         // 院领导部门
         hospitalLeaderDeptName,
         hospitalLeaderDeptName,
         hospitalLeaderDeptId: issueForm.hospitalLeaderDeptId,
         hospitalLeaderDeptId: issueForm.hospitalLeaderDeptId,
         hospitalLeaderExecutorGroupName: findGroupNameById(issueForm.hospitalLeaderGroupId),
         hospitalLeaderExecutorGroupName: findGroupNameById(issueForm.hospitalLeaderGroupId),
-        hospitalLeaderExecGroupCode: issueForm.hospitalLeaderGroupId != null ? String(issueForm.hospitalLeaderGroupId) : undefined,
+        hospitalLeaderExecGroupCode:
+          issueForm.hospitalLeaderGroupId != null ? String(issueForm.hospitalLeaderGroupId) : undefined,
 
 
         // 计划时间与开关项
         // 计划时间与开关项
         planStartTime: issueForm.planStartTime,
         planStartTime: issueForm.planStartTime,
@@ -651,7 +697,10 @@
       { label: '日常安全', value: '日常安全' },
       { label: '日常安全', value: '日常安全' },
       { label: '各级危险点', value: '各级危险点' },
       { label: '各级危险点', value: '各级危险点' },
       { label: '试验室及试验过程', value: '试验室及试验过程' },
       { label: '试验室及试验过程', value: '试验室及试验过程' },
-      { 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: '堆场、物资库房' },
       { label: '堆场、物资库房', value: '堆场、物资库房' },
-      { label: '室内外停车场', value: '室内外停车场' }
+      { label: '室内外停车场', value: '室内外停车场' },
     ];
     ];
     getTableData();
     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[] = [
   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: 'checkTime', minWidth: '160px' },
     { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
     { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
     { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },
     { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },

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

@@ -251,6 +251,38 @@
       :formRules="sandHiddenDangerFormRulesDept"
       :formRules="sandHiddenDangerFormRulesDept"
       :formConfig="sandHiddenDangerFormConfigDept"
       :formConfig="sandHiddenDangerFormConfigDept"
     >
     >
+      <template #rectificationDepartmentIds>
+        <el-form-item prop="rectificationDepartmentIds" style="width: 100%;">
+          <el-cascader
+            v-model="sandHiddenDangerFormDataDept.rectificationDepartmentIds"
+            :options="issueDeptTree"
+            :props="cascaderDeptProp"
+            :show-all-levels="false"
+            placeholder="请选择整改责任部门"
+            filterable
+            clearable
+            @change="onIssueDeptChange"
+          />
+        </el-form-item>
+      </template>
+      <template #rectificationResponsibleIds>
+        <el-form-item prop="rectificationResponsibleIds" style="width: 100%;">
+          <el-select
+            v-model="sandHiddenDangerFormDataDept.rectificationResponsibleIds"
+            placeholder="选择整改负责人"
+            filterable
+            clearable
+            style="width: 100%"
+          >
+            <el-option
+              v-for="user in issueUserList"
+              :key="user.id"
+              :label="user.realname ?? user.username"
+              :value="user.id"
+            />
+          </el-select>
+        </el-form-item>
+      </template>
       <template #reviewDepartmentId>
       <template #reviewDepartmentId>
         <el-cascader
         <el-cascader
           v-model="sandHiddenDangerFormDataDept.reviewDepartmentId"
           v-model="sandHiddenDangerFormDataDept.reviewDepartmentId"
@@ -280,12 +312,12 @@
         </el-select>
         </el-select>
       </template>
       </template>
       <template #isDrawLessonsPush>
       <template #isDrawLessonsPush>
-        <el-radio-group v-model="sandHiddenDangerFormDataDept.isDrawLessonsPush">
+        <el-radio-group v-model="sandHiddenDangerFormDataDept.isDrawLessonsPush" @change="isDrawLessonsPushChange">
           <el-radio :value="0">否</el-radio>
           <el-radio :value="0">否</el-radio>
           <el-radio :value="1">是</el-radio>
           <el-radio :value="1">是</el-radio>
         </el-radio-group>
         </el-radio-group>
       </template>
       </template>
-      <template #drawLessonsDepartmentIds>
+      <template #drawLessonsDepartmentIds> 
         <el-select
         <el-select
           v-model="drawLessonsDeptIdsArrayDept"
           v-model="drawLessonsDeptIdsArrayDept"
           placeholder="请选择举一反三责任部门,可多选"
           placeholder="请选择举一反三责任部门,可多选"
@@ -305,6 +337,16 @@
           />
           />
         </el-select>
         </el-select>
       </template>
       </template>
+      <template #drawLessonsDeadline>
+        <el-form-item prop="drawLessonsDeadline" style="width: 100%;">
+          <el-date-picker
+            v-model="sandHiddenDangerFormDataDept.drawLessonsDeadline"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择举一反三截止日期(选填)"
+          />
+        </el-form-item>
+      </template>
     </BasicForm>
     </BasicForm>
     <template #footer>
     <template #footer>
       <el-button @click="showSandConfirmDialogDept = false">取消</el-button>
       <el-button @click="showSandConfirmDialogDept = false">取消</el-button>
@@ -394,6 +436,26 @@
     };
     };
   });
   });
 
 
+  const issueDeptTree = ref<DeptTree[]>([]);
+  const issueUserList = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
+
+  const onIssueDialogOpen = async () => {
+    try {
+      const [deptRes, userRes] = await Promise.all([
+        getAllDepartments(),
+        queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
+      ]);
+      const fullTree = (deptRes as DeptTree[]) ?? [];
+      issueDeptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
+      issueUserList.value = (userRes as any)?.records ?? [];
+    } catch (e) {
+      console.error('获取部门/用户列表失败:', e);
+      ElMessage.error(e?.message || e?.data || '加载部门或负责人列表失败');
+      issueDeptTree.value = [];
+      issueUserList.value = [];
+    }
+  };
+
   const inspectionContentList = computed(() => {
   const inspectionContentList = computed(() => {
     const content = (viewDetailData.value?.checkKeyContent ?? '') as string;
     const content = (viewDetailData.value?.checkKeyContent ?? '') as string;
     if (!content || typeof content !== 'string') {
     if (!content || typeof content !== 'string') {
@@ -409,7 +471,7 @@
   });
   });
 
 
   const RECORD_TABLE_COLUMNS: TableColumnProps[] = [
   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: 'checkTime', minWidth: '160px' },
     { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
     { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
     { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },
     { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },
@@ -532,6 +594,7 @@
           searchKey: recordSearchKeyword.value || undefined,
           searchKey: recordSearchKeyword.value || undefined,
           startDate: start || undefined,
           startDate: start || undefined,
           endDate: end || undefined,
           endDate: end || undefined,
+          id: currentId.value,
         },
         },
       });
       });
       const raw = (res as { data?: { records?: Array<Record<string, unknown>>; totalRow?: number } })?.data ?? res;
       const raw = (res as { data?: { records?: Array<Record<string, unknown>>; totalRow?: number } })?.data ?? res;
@@ -673,6 +736,11 @@
         drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
         drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
         drawLessonsDeadline: d.drawLessonsDeadline || '',
         drawLessonsDeadline: d.drawLessonsDeadline || '',
         attachments: d.attachments || '',
         attachments: d.attachments || '',
+        confirmSandToHiddenDangerDept: d.confirmSandToHiddenDangerDept ?? 0,
+        rectificationResponsibleIds: d.rectificationResponsibleIds || '',
+        drawLessonsContent: d.drawLessonsContent || '',
+        drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
+        drawLessonsDeadline: d.drawLessonsDeadline || '',
       };
       };
       await sandAreaCheckRecordToProductionHiddenDanger(payload);
       await sandAreaCheckRecordToProductionHiddenDanger(payload);
       ElMessage.success('入账成功');
       ElMessage.success('入账成功');
@@ -753,10 +821,41 @@
     }
     }
   };
   };
 
 
+  const isDrawLessonsPushChange = () => {
+    console.log(sandHiddenDangerFormDataDept.isDrawLessonsPush)
+    console.log('HIDDEN_DANGER_FORM_CONFIG', HIDDEN_DANGER_FORM_CONFIG)
+    let data = [
+        {
+          prop: 'drawLessonsContent',
+          label: '举一反三内容:',
+          component: 'ElInput',
+          componentProps: {
+            placeholder: '如:上级检查、院内自查',
+          },
+        },
+        {
+          prop: 'drawLessonsDepartmentIds',
+          label: '举一反三责任部门:',
+          slot: 'drawLessonsDepartmentIds',
+        },
+        {
+          prop: 'drawLessonsDeadline',
+          label: '举一反三时限:',
+          slot: 'drawLessonsDeadline',
+        },
+    ]
+  };
+
+  const onIssueDeptChange = () => {
+    sandHiddenDangerFormDataDept.rectificationResponsibleIds = undefined;
+  };
+
   onMounted(() => {
   onMounted(() => {
     loadDeptAndUserOptionsDept();
     loadDeptAndUserOptionsDept();
     getDetail();
     getDetail();
+    onIssueDialogOpen();
   });
   });
+  
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">

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

@@ -57,7 +57,19 @@
     </el-form>
     </el-form>
 
 
     <div class="check-items-section">
     <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
         <el-upload
           v-if="isEditMode && props.id"
           v-if="isEditMode && props.id"
           :show-file-list="false"
           :show-file-list="false"
@@ -66,7 +78,7 @@
         >
         >
           <el-button type="primary" size="small">批量导入明细</el-button>
           <el-button type="primary" size="small">批量导入明细</el-button>
         </el-upload>
         </el-upload>
-      </div>
+      </div> -->
       <div class="check-items-table">
       <div class="check-items-table">
         <el-table :data="checkItems" border :span-method="handleSpanMethod">
         <el-table :data="checkItems" border :span-method="handleSpanMethod">
           <el-table-column label="编号" type="index" width="80" align="center" />
           <el-table-column label="编号" type="index" width="80" align="center" />
@@ -120,7 +132,18 @@
         </el-table>
         </el-table>
       </div>
       </div>
     </div>
     </div>
+
   </main>
   </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">
   <footer class="safety-platform-container__footer">
     <el-button @click="router.back()">返回</el-button>
     <el-button @click="router.back()">返回</el-button>
     <el-button v-if="!isViewMode" type="primary" @click="handleSubmit">
     <el-button v-if="!isViewMode" type="primary" @click="handleSubmit">
@@ -140,10 +163,15 @@
     saveChecklistTemplate,
     saveChecklistTemplate,
     updateChecklistTemplate,
     updateChecklistTemplate,
     importChecklistTemplateItem,
     importChecklistTemplateItem,
+    checklistTemplateDownload,
+    checklistHandleeTemplateDownload,
     type ChecklistTemplateItem,
     type ChecklistTemplateItem,
   } from '@/api/production-safety-system';
   } from '@/api/production-safety-system';
   import { queryDictTypeDetail } from '@/api/dict';
   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<{
   const props = defineProps<{
     id?: number;
     id?: number;
   }>();
   }>();
@@ -369,6 +397,58 @@
     return { rowspan: 1, colspan: 1 };
     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 () => {
   onMounted(async () => {
     await loadCategoryOptions();
     await loadCategoryOptions();
     if (isEditMode.value || isViewMode.value) {
     if (isEditMode.value || isViewMode.value) {
@@ -398,7 +478,7 @@
   }
   }
 
 
   .check-items-section {
   .check-items-section {
-    margin-top: 32px;
+    margin: 32px 0 15px 0;
   }
   }
 
 
   .section-header {
   .section-header {

+ 46 - 3
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/components/hiddenTroubleAccountManagementDetail.vue

@@ -72,6 +72,24 @@
         />
         />
       </el-form-item>
       </el-form-item>
 
 
+      <el-form-item label="整改责任部门:" prop="rectificationDepartmentId" v-if="ruleFormData.statusId !== 1 && !isCreateMode">
+        <el-input
+          v-model="ruleFormData.rectificationDepartmentNames"
+          placeholder="整改责任部门"
+          disabled
+          style="width: 450px"
+        />
+      </el-form-item>
+
+      <el-form-item label="整改负责人:" prop="rectificationResponsibleUserId" v-if="ruleFormData.statusId !== 1 && !isCreateMode">
+        <el-input
+          v-model="ruleFormData.rectificationResponsiblePerson"
+          placeholder="整改负责人"
+          disabled
+          style="width: 450px"
+        />
+      </el-form-item>
+
       <el-form-item label="整改日期:" prop="rectificationDeadline">
       <el-form-item label="整改日期:" prop="rectificationDeadline">
         <el-date-picker
         <el-date-picker
           v-model="ruleFormData.rectificationDeadline"
           v-model="ruleFormData.rectificationDeadline"
@@ -162,7 +180,7 @@
             v-model="ruleFormData.rectificationCompletionStatus"
             v-model="ruleFormData.rectificationCompletionStatus"
             placeholder="请输入整改完成情况"
             placeholder="请输入整改完成情况"
             show-word-limit
             show-word-limit
-            :disabled="detailStatusOrder>=3"
+            :disabled="!isRectifyMode"
             style="width: 450px"
             style="width: 450px"
           />
           />
         </el-form-item>
         </el-form-item>
@@ -170,7 +188,7 @@
             <el-date-picker
             <el-date-picker
             v-model="ruleFormData.rectificationCompletionTime"
             v-model="ruleFormData.rectificationCompletionTime"
             type="date"
             type="date"
-            :disabled="detailStatusOrder>=3"
+            :disabled="!isRectifyMode"
             value-format="YYYY-MM-DD"
             value-format="YYYY-MM-DD"
             placeholder="请选择整改完成时间"
             placeholder="请选择整改完成时间"
             style="width: 450px"
             style="width: 450px"
@@ -181,7 +199,7 @@
                 label="选择附件"
                 label="选择附件"
                 :maxCount="1"
                 :maxCount="1"
                 v-if="detailStatusOrder==2"
                 v-if="detailStatusOrder==2"
-                :disabled="detailStatusOrder>=3"
+                :disabled="!isRectifyMode"
                 :file-list="attachmentsFileList"
                 :file-list="attachmentsFileList"
                 :allow-all-file-types="true"
                 :allow-all-file-types="true"
                 @uploadSuccess="(list: FileItem[]) => handleAttachmentsUploadSuccess(list)"
                 @uploadSuccess="(list: FileItem[]) => handleAttachmentsUploadSuccess(list)"
@@ -357,6 +375,7 @@
   import type { DeptTree } from '@/types/dept/type';
   import type { DeptTree } from '@/types/dept/type';
   import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
   import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
   import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
   import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
+import { ru } from 'element-plus/es/locale';
 
 
   const router = useRouter();
   const router = useRouter();
   const route = useRoute();
   const route = useRoute();
@@ -562,6 +581,8 @@ const attachmentsFileList = ref([]) as any
         ruleFormData.attachments = d.attachments ?? '';
         ruleFormData.attachments = d.attachments ?? '';
         attachmentsFileList.value = JSON.parse(d.attachments|| '[]');
         attachmentsFileList.value = JSON.parse(d.attachments|| '[]');
         ruleFormData.reviewComments = d.reviewComments?? '';
         ruleFormData.reviewComments = d.reviewComments?? '';
+        ruleFormData.rectificationResponsibleUserId = d.rectificationResponsibleUserId;
+        ruleFormData.rectificationDepartmentNames = d.rectificationDepartmentNames ?? '';
         // 整改页:保存审查不通过原因供 el-alert 展示(后端字段 reviewReason)
         // 整改页:保存审查不通过原因供 el-alert 展示(后端字段 reviewReason)
         if (isRectifyMode.value && d.reviewReason != null && String(d.reviewReason).trim()) {
         if (isRectifyMode.value && d.reviewReason != null && String(d.reviewReason).trim()) {
           detailReviewRejectReason.value = String(d.reviewReason).trim();
           detailReviewRejectReason.value = String(d.reviewReason).trim();
@@ -609,6 +630,7 @@ const attachmentsFileList = ref([]) as any
         taskSource: ruleFormData.taskSource,
         taskSource: ruleFormData.taskSource,
         rectificationRequirement: ruleFormData.rectificationRequirement,
         rectificationRequirement: ruleFormData.rectificationRequirement,
         rectificationDeadline: rectificationDeadline,
         rectificationDeadline: rectificationDeadline,
+        rectificationDepartmentId: ruleFormData.rectificationDepartmentId,
         rectificationDepartmentIds: ruleFormData.rectificationDepartmentIds,
         rectificationDepartmentIds: ruleFormData.rectificationDepartmentIds,
         rectificationResponsiblePerson: ruleFormData.rectificationResponsiblePerson,
         rectificationResponsiblePerson: ruleFormData.rectificationResponsiblePerson,
         reviewDepartmentId: ruleFormData.reviewDepartmentId!,
         reviewDepartmentId: ruleFormData.reviewDepartmentId!,
@@ -807,8 +829,29 @@ const attachmentsFileList = ref([]) as any
     }
     }
   }
   }
 
 
+  const issueDeptTree = ref<DeptTree[]>([]);
+  const issueUserList = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
+
+  const onIssueDialogOpen = async () => {
+    try {
+      const [deptRes, userRes] = await Promise.all([
+        getAllDepartments(),
+        queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
+      ]);
+      const fullTree = (deptRes as DeptTree[]) ?? [];
+      issueDeptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
+      issueUserList.value = (userRes as any)?.records ?? [];
+    } catch (e) {
+      console.error('获取部门/用户列表失败:', e);
+      ElMessage.error(e?.message || e?.data || '加载部门或负责人列表失败');
+      issueDeptTree.value = [];
+      issueUserList.value = [];
+    }
+  };
+
   onMounted(async () => {
   onMounted(async () => {
     cloneRuleFormData();
     cloneRuleFormData();
+    onIssueDialogOpen();
     await loadDeptAndUserOptions();
     await loadDeptAndUserOptions();
     if (isEditMode.value || isViewMode.value) {
     if (isEditMode.value || isViewMode.value) {
       await getDetail();
       await getDetail();

+ 37 - 29
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form.ts

@@ -60,6 +60,16 @@ export const HIDDEN_DANGER_FORM_CONFIG: FormConfig[] = [
       placeholder: '请输入整改要求',
       placeholder: '请输入整改要求',
     },
     },
   },
   },
+  {
+    prop: 'rectificationDepartmentIds',
+    label: '整改责任部门:',
+    slot: 'rectificationDepartmentIds',
+  }, 
+  {
+    prop: 'rectificationResponsibleIds',
+    label: '整改负责人:',
+    slot: 'rectificationResponsibleIds',
+  },
   {
   {
     prop: 'rectificationDeadline',
     prop: 'rectificationDeadline',
     label: '整改日期:',
     label: '整改日期:',
@@ -94,34 +104,25 @@ export const HIDDEN_DANGER_FORM_CONFIG: FormConfig[] = [
     label: '举一反三是否推送:',
     label: '举一反三是否推送:',
     slot: 'isDrawLessonsPush',
     slot: 'isDrawLessonsPush',
   },
   },
-  //   {
-  //     prop: 'drawLessonsContent',
-  //     label: '举一反三内容:',
-  //     component: 'ElInput',
-  //     componentProps: {
-  //       placeholder: '选填,推送举一反三时建议填写',
-  //     },
-  //   },
-  //   {
-  //     prop: 'drawLessonsDepartmentIds',
-  //     label: '举一反三责任部门:',
-  //     slot: 'drawLessonsDepartmentIds',
-  //     componentProps: {
-  //       placeholder: '请选择举一反三责任部门,可多选',
-  //       style: { width: '100%' },
-  //     },
-  //   },
-  //   {
-  //     prop: 'drawLessonsDeadline',
-  //     label: '举一反三时限:',
-  //     component: 'ElDatePicker',
-  //     componentProps: {
-  //       type: 'date',
-  //       placeholder: '请选择举一反三时限',
-  //       valueFormat: 'YYYY-MM-DD',
-  //       style: { width: '100%' },
-  //     },
-  //   },
+  {
+    prop: 'drawLessonsContent',
+    label: '',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '如:上级检查、院内自查',
+      style: { paddingLeft: '136.5px' },
+    },
+  },
+  {
+    prop: 'drawLessonsDepartmentIds',
+    label: '举一反三责任部门:',
+    slot: 'drawLessonsDepartmentIds',
+  },
+  {
+    prop: 'drawLessonsDeadline',
+    label: '举一反三时限:',
+    slot: 'drawLessonsDeadline',
+  },
 ];
 ];
 
 
 /**
 /**
@@ -320,6 +321,7 @@ export const HIDDEN_DANGER_FORM_DATA = {
   rectificationCompletionTime: '',
   rectificationCompletionTime: '',
   attachments: '',
   attachments: '',
   reviewComments: '',
   reviewComments: '',
+  rectificationResponsibleUserId: '',
 };
 };
 
 
 export const HIDDEN_DANGER_FORM_RULES = {
 export const HIDDEN_DANGER_FORM_RULES = {
@@ -358,5 +360,11 @@ export const HIDDEN_DANGER_FORM_RULES = {
   ],
   ],
   rectificationCompletionTime: [
   rectificationCompletionTime: [
     { required: true, message: '请选择整改完成时间', trigger: 'change' }
     { required: true, message: '请选择整改完成时间', trigger: 'change' }
-  ]
+  ],
+  rectificationDepartmentIds: [
+    { required: true, message: '请选择整改责任部门', trigger: 'change' }
+  ],
+  rectificationResponsibleIds: [
+    { required: true, message: '请选择整改负责人', trigger: 'change' }
+  ],
 };
 };

+ 33 - 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="responsibilityName" width="180" />
           <el-table-column label="状态" prop="statusName" width="100" />
           <el-table-column label="状态" prop="statusName" width="100" />
           <el-table-column label="类别名称" prop="departmentName" width="180" />
           <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="操作">
           <el-table-column fixed="right" min-width="300" label="操作">
             <template #default="scope">
             <template #default="scope">
               <el-button
               <el-button
@@ -317,6 +337,14 @@
           : undefined,
           : undefined,
       },
       },
     }).then((res) => {
     }).then((res) => {
+      res.records.forEach(item=>{
+        // 未下发
+        if(item.status === 1){
+            item.issuedQuantity = '-'
+            item.signedQuantity = '-'
+            item.signedRatio = '-'
+        }
+      })
       tableData.data = res.records;
       tableData.data = res.records;
       tableData.total = res.totalRow;
       tableData.total = res.totalRow;
     });
     });

+ 5 - 4
src/views/production-safety/implement-safety-duty/sign-agree-dept.vue

@@ -34,10 +34,10 @@
               <div class="label">签署人数:</div>
               <div class="label">签署人数:</div>
               <div class="value">{{ formData.signedQuantity }}</div>
               <div class="value">{{ formData.signedQuantity }}</div>
             </div>
             </div>
-            <!-- <div class="col">
-              <div class="label">下发对象:</div>
-              <div class="value">{{ formData.userGroupName }}</div>
-            </div> -->
+            <div class="col">
+              <div class="label">下发:</div>
+              <div class="value">{{ formData.issueQuantity }}</div>
+            </div>
           </div>
           </div>
           <div class="row">
           <div class="row">
             <div class="col">
             <div class="col">
@@ -252,6 +252,7 @@
     signsUpload: [],
     signsUpload: [],
     responsibilityName: '',
     responsibilityName: '',
     statusName: '',
     statusName: '',
+    issueQuantity: '',
     signedQuantity: '',
     signedQuantity: '',
     userGroupName: '',
     userGroupName: '',
     planStartTime: null,
     planStartTime: null,

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

+ 2 - 0
src/views/production-safety/productionSafetySystem/doubleSystemManagement/configs/form.ts

@@ -90,4 +90,6 @@ export const DUAL_SYSTEM_FORM_RULES = {
   fileFormat: [{ required: true, message: '请选择文件格式', trigger: 'change' }],
   fileFormat: [{ required: true, message: '请选择文件格式', trigger: 'change' }],
   releaseDate: [{ required: true, message: '请选择发布日期', trigger: 'change' }],
   releaseDate: [{ required: true, message: '请选择发布日期', trigger: 'change' }],
   fileUrl: [{ required: true, message: '请上传文件', trigger: 'change' }],
   fileUrl: [{ required: true, message: '请上传文件', trigger: 'change' }],
+  content: [{ required: true, message: '请输入内容', trigger: 'blur' }],
+  status: [{ required: true, message: '请选择状态', trigger: 'blur' }],
 };
 };

+ 18 - 65
src/views/production-safety/risk-identification-and-control/equipment-high-alert/list.vue

@@ -62,7 +62,7 @@
                 <span>所属部门:</span>
                 <span>所属部门:</span>
                 <el-cascader
                 <el-cascader
                   v-model="useDeptPath"
                   v-model="useDeptPath"
-                  :options="deptOptions"
+                  :options="deptTreeList"
                   :props="deptCascaderProps"
                   :props="deptCascaderProps"
                   :show-all-levels="false"
                   :show-all-levels="false"
                   placeholder="请选择责任部门"
                   placeholder="请选择责任部门"
@@ -127,13 +127,6 @@
 <script lang="ts" setup>
 <script lang="ts" setup>
   import { onMounted, reactive, ref } from 'vue';
   import { onMounted, reactive, ref } from 'vue';
   import { ElMessage } from 'element-plus';
   import { ElMessage } from 'element-plus';
-  import {
-    querySpecialEquipmentPage,
-    deleteSpecialEquipment,
-    exportSpecialEquipment,
-    type SpecialEquipment,
-    type SpecialEquipmentQueryParam,
-  } from '@/api/production-safety/special-equipment';
   import { getAllDepartments } from '@/api/auth/dept';
   import { getAllDepartments } from '@/api/auth/dept';
   import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
   import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
   import BasicTable from '@/components/BasicTable.vue';
   import BasicTable from '@/components/BasicTable.vue';
@@ -141,50 +134,13 @@
   import ActionButton from '@/components/ActionButton.vue';
   import ActionButton from '@/components/ActionButton.vue';
   import { TABLE_OPTIONS, SPECIAL_EQUIPMENT_TABLE_COLUMNS } from './configs/tables';
   import { TABLE_OPTIONS, SPECIAL_EQUIPMENT_TABLE_COLUMNS } from './configs/tables';
   import { DEVICE_CATEGORY_OPTIONS, Alarm_TYPE_OPTIONS, DEVICE_TYPE, ALARM_TYPE} from './configs/form';
   import { DEVICE_CATEGORY_OPTIONS, Alarm_TYPE_OPTIONS, DEVICE_TYPE, ALARM_TYPE} from './configs/form';
+  import {type QueryParamType, equipmentHighAlertList, deptList, exportTableData} from '@/api/equipment-high-alert-List'
   import { downloadByData } from '@/utils/file/download';
   import { downloadByData } from '@/utils/file/download';
-import { http } from '@/utils/http/axios';
+
   import dayjs from 'dayjs';
   import dayjs from 'dayjs';
   const loading = ref(false);
   const loading = ref(false);
   const dateRange = ref<[string, string] | null>(null);
   const dateRange = ref<[string, string] | null>(null);
-  interface  QueryParamType {
-    pageNumber: number;
-    pageSize: number;
-    queryParam: {
-      //设备编码
-      deviceNo?: string | undefined;
-      //设备名称
-      deviceName?: string | undefined;
-      // 设备类型
-      deviceType?: string | undefined;
-      // 告警类型
-      alarmType?: string | undefined;
-      // 所属部门
-      deptName?: string | undefined;
-      // 开始时间
-      startTime: string | undefined,
-      // 结束
-      endTime: string | undefined,
-    };
-  }
-  // 列表数据
-const equipmentHighAlertList = (query: QueryParamType)=>{
-  return http.request({
-    url: '/prodAlarm/queryProdAlarm',
-    method: 'post',
-    data: query,
-  });
-}
-// 导出接口
-const exportTableData = (params)=>{
-    return http.request({
-        url: '/prodAlarm/export',
-        method: 'post',
-        data: params,
-        responseType: 'blob',
-    }, {
-        isTransformResponse: false,
-    });
-}
+  
 
 
   // BasicTable
   // BasicTable
   const basicTableRef = ref<InstanceType<typeof BasicTable>>();
   const basicTableRef = ref<InstanceType<typeof BasicTable>>();
@@ -222,7 +178,7 @@ const exportTableData = (params)=>{
   };
   };
 
 
   const tableData = ref([]);
   const tableData = ref([]);
-
+  const deptTreeList = ref([])
   const handleSizeChange = (value: number) => {
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     pagination.pageSize = value;
     queryParams.pageSize = value;
     queryParams.pageSize = value;
@@ -236,12 +192,15 @@ const exportTableData = (params)=>{
     queryTableList();
     queryTableList();
   };
   };
 
 
-  const getStatusText = (status?: number, statusName?: string) => {
-    if (statusName) return statusName;
-    if (status === 1) return '在用';
-    if (status === 2) return '停用';
-    if (status === 3) return '报废';
-    return '-';
+  const getDeptList = async () => {
+    try {
+      let res = await deptList()
+      deptTreeList.value = res || []
+    } catch (e) {
+      console.error('获取部门树失败:', e);
+      deptOptions.value = [];
+    }
+    
   };
   };
 
 
   const loadDeptTree = async () => {
   const loadDeptTree = async () => {
@@ -275,18 +234,11 @@ const exportTableData = (params)=>{
         pageSize: queryParams.pageSize,
         pageSize: queryParams.pageSize,
         queryParam:{
         queryParam:{
             ...queryParams.queryParam,
             ...queryParams.queryParam,
-            startTime: dateRange?.[0]
-                ? dayjs(dateRange?.[0]).format('YYYY-MM-DD')
-                : undefined,
-            endTime: dateRange?.[1]
-                ? dayjs(dateRange?.[1]).format('YYYY-MM-DD')
-                : undefined,
+            startTime: dateRange.value?.[0] ?? undefined,
+            endTime: dateRange.value?.[1] ?? undefined,
         }
         }
     }
     }
-    equipmentHighAlertList({
-        ...queryParams
-
-    })
+    equipmentHighAlertList(data)
       .then((res: any) => {
       .then((res: any) => {
         tableData.value = res?.records;
         tableData.value = res?.records;
         pagination.total = res?.totalRow ?? res?.total ?? 0;
         pagination.total = res?.totalRow ?? res?.total ?? 0;
@@ -336,6 +288,7 @@ const exportTableData = (params)=>{
   };
   };
 
 
   onMounted(() => {
   onMounted(() => {
+    getDeptList()
     loadDeptTree();
     loadDeptTree();
     queryTableList();
     queryTableList();
   });
   });

+ 8 - 8
src/views/production-safety/risk-identification-and-control/hazard-manage/add.vue

@@ -126,7 +126,7 @@
               <!-- <el-select v-model="formValue.inherentRiskM" size="large" placeholder="1-5" style="width: 330px">
               <!-- <el-select v-model="formValue.inherentRiskM" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-              <el-input-number
+              <el-input
                 placeholder="请输入固有风险评估(M)"
                 placeholder="请输入固有风险评估(M)"
                 :step="1"
                 :step="1"
                 :precision="0"
                 :precision="0"
@@ -141,7 +141,7 @@
               <!-- <el-select v-model="formValue.inherentRiskE" size="large" placeholder="1-6" style="width: 330px">
               <!-- <el-select v-model="formValue.inherentRiskE" size="large" placeholder="1-6" style="width: 330px">
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-              <el-input-number
+              <el-input
                 placeholder="请输入固有风险评估(E)"
                 placeholder="请输入固有风险评估(E)"
                 :step="1"
                 :step="1"
                 :precision="0"
                 :precision="0"
@@ -156,7 +156,7 @@
               <!-- <el-select v-model="formValue.inherentRiskS" size="large" placeholder="1-5" style="width: 330px">
               <!-- <el-select v-model="formValue.inherentRiskS" size="large" placeholder="1-5" style="width: 330px">
                   <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
                   <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
                 </el-select> -->
                 </el-select> -->
-              <el-input-number
+              <el-input
                 placeholder="请输入固有风险评估(S)"
                 placeholder="请输入固有风险评估(S)"
                 :step="1"
                 :step="1"
                 :precision="0"
                 :precision="0"
@@ -305,7 +305,7 @@
               <!-- <el-select v-model="formValue.controlRiskM" size="large" placeholder="1-5" style="width: 330px">
               <!-- <el-select v-model="formValue.controlRiskM" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-              <el-input-number
+              <el-input
                 placeholder="控制风险评估(M)"
                 placeholder="控制风险评估(M)"
                 :step="1"
                 :step="1"
                 :precision="0"
                 :precision="0"
@@ -320,7 +320,7 @@
               <!-- <el-select v-model="formValue.controlRiskE" size="large" placeholder="1-6" style="width: 330px">
               <!-- <el-select v-model="formValue.controlRiskE" size="large" placeholder="1-6" style="width: 330px">
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-              <el-input-number
+              <el-input
                 placeholder="控制风险评估(E)"
                 placeholder="控制风险评估(E)"
                 :step="1"
                 :step="1"
                 :precision="0"
                 :precision="0"
@@ -335,7 +335,7 @@
               <!-- <el-select v-model="formValue.controlRiskS" size="large" placeholder="1-5" style="width: 330px">
               <!-- <el-select v-model="formValue.controlRiskS" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-              <el-input-number
+              <el-input
                 placeholder="控制风险评估(S)"
                 placeholder="控制风险评估(S)"
                 :step="1"
                 :step="1"
                 :precision="0"
                 :precision="0"
@@ -356,8 +356,8 @@
             </el-form-item>
             </el-form-item>
           </el-col>
           </el-col>
           <el-col :span="12">
           <el-col :span="12">
-            <el-form-item label="风险等级" prop="controlRiskLevel">
-              <el-select v-model="formValue.controlRiskLevel" size="large" placeholder="请选择" style="width: 280px">
+            <el-form-item label="控制风险等级" prop="controlRiskLevel">
+              <el-select v-model="formValue.controlRiskLevel" size="large" placeholder="请选择控制风险等级" style="width: 280px">
                 <!-- <el-option label="A" value="A" />
                 <!-- <el-option label="A" value="A" />
             <el-option label="B" value="B" />
             <el-option label="B" value="B" />
             <el-option label="C" value="C" /> -->
             <el-option label="C" value="C" /> -->

+ 7 - 7
src/views/production-safety/risk-identification-and-control/hazard-manage/edit.vue

@@ -114,7 +114,7 @@
           <!-- <el-select v-model="formValue.inherentRiskM" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.inherentRiskM" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             placeholder="输入固有风险评估M"
             placeholder="输入固有风险评估M"
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -127,7 +127,7 @@
           <!-- <el-select v-model="formValue.inherentRiskE" size="large" placeholder="1-6" style="width: 330px">
           <!-- <el-select v-model="formValue.inherentRiskE" size="large" placeholder="1-6" style="width: 330px">
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             placeholder="输入固有风险评估E"
             placeholder="输入固有风险评估E"
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -140,7 +140,7 @@
           <!-- <el-select v-model="formValue.inherentRiskS" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.inherentRiskS" size="large" placeholder="1-5" style="width: 330px">
                   <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
                   <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
                 </el-select> -->
                 </el-select> -->
-          <el-input-number
+          <el-input
             placeholder="输入固有风险评估S"
             placeholder="输入固有风险评估S"
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -265,7 +265,7 @@
           <!-- <el-select v-model="formValue.controlRiskM" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.controlRiskM" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             placeholder="输入控制风险评估M"
             placeholder="输入控制风险评估M"
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -278,7 +278,7 @@
           <!-- <el-select v-model="formValue.controlRiskE" size="large" placeholder="1-6" style="width: 330px">
           <!-- <el-select v-model="formValue.controlRiskE" size="large" placeholder="1-6" style="width: 330px">
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             placeholder="输入控制风险评估E"
             placeholder="输入控制风险评估E"
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -291,7 +291,7 @@
           <!-- <el-select v-model="formValue.controlRiskS" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.controlRiskS" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             placeholder="输入控制风险评估S"
             placeholder="输入控制风险评估S"
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -309,7 +309,7 @@
           />
           />
         </el-form-item>
         </el-form-item>
         <el-form-item label="控制风险等级" prop="controlRiskLevel">
         <el-form-item label="控制风险等级" prop="controlRiskLevel">
-          <el-select v-model="formValue.controlRiskLevel" size="large" placeholder="请选择" style="width: 330px">
+          <el-select v-model="formValue.controlRiskLevel" size="large" placeholder="请选择控制风险等级" style="width: 330px">
             <!-- <el-option label="A" value="A" />
             <!-- <el-option label="A" value="A" />
             <el-option label="B" value="B" />
             <el-option label="B" value="B" />
             <el-option label="C" value="C" /> -->
             <el-option label="C" value="C" /> -->

+ 15 - 4
src/views/production-safety/risk-identification-and-control/hazard-manage/list.vue

@@ -41,7 +41,13 @@
           </el-form-item> -->
           </el-form-item> -->
 
 
           <el-form-item label="固有风险等级">
           <el-form-item label="固有风险等级">
-            <el-select
+            <el-input
+              v-model="queryParams.queryParam.inherentRiskLevel"
+              placeholder="搜索固有风险等级"
+              style="width: 170px"
+            />
+            <!-- 需求变更为input -->
+            <!-- <el-select
               v-model="queryParams.queryParam.inherentRiskLevel"
               v-model="queryParams.queryParam.inherentRiskLevel"
               clearable
               clearable
               placeholder="固有风险等级"
               placeholder="固有风险等级"
@@ -49,17 +55,22 @@
             >
             >
               <el-option :value="1" label="B" />
               <el-option :value="1" label="B" />
               <el-option :value="2" label="C" />
               <el-option :value="2" label="C" />
-            </el-select>
+            </el-select> -->
           </el-form-item>
           </el-form-item>
           <el-form-item label="控制风险等级">
           <el-form-item label="控制风险等级">
-            <el-select
+            <el-input
+              v-model="queryParams.queryParam.controlRiskLevel"
+              placeholder="搜索控制风险等级"
+              style="width: 170px"
+            />
+            <!-- <el-select
               v-model="queryParams.queryParam.controlRiskLevel"
               v-model="queryParams.queryParam.controlRiskLevel"
               clearable
               clearable
               placeholder="控制风险等级"
               placeholder="控制风险等级"
               style="width: 170px"
               style="width: 170px"
             >
             >
               <el-option value="D" label="D" />
               <el-option value="D" label="D" />
-            </el-select>
+            </el-select> -->
           </el-form-item>
           </el-form-item>
         </el-form>
         </el-form>
 
 

+ 6 - 6
src/views/production-safety/risk-identification-and-control/hazard-manage/view.vue

@@ -124,7 +124,7 @@
           <!-- <el-select v-model="formValue.inherentRiskM" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.inherentRiskM" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             disabled
             disabled
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -137,7 +137,7 @@
           <!-- <el-select v-model="formValue.inherentRiskE" size="large" placeholder="1-6" style="width: 330px">
           <!-- <el-select v-model="formValue.inherentRiskE" size="large" placeholder="1-6" style="width: 330px">
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             disabled
             disabled
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -150,7 +150,7 @@
           <!-- <el-select v-model="formValue.inherentRiskS" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.inherentRiskS" size="large" placeholder="1-5" style="width: 330px">
                   <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
                   <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
                 </el-select> -->
                 </el-select> -->
-          <el-input-number
+          <el-input
             disabled
             disabled
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -284,7 +284,7 @@
           <!-- <el-select v-model="formValue.controlRiskM" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.controlRiskM" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             disabled
             disabled
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -297,7 +297,7 @@
           <!-- <el-select v-model="formValue.controlRiskE" size="large" placeholder="1-6" style="width: 330px">
           <!-- <el-select v-model="formValue.controlRiskE" size="large" placeholder="1-6" style="width: 330px">
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 6" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             disabled
             disabled
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"
@@ -310,7 +310,7 @@
           <!-- <el-select v-model="formValue.controlRiskS" size="large" placeholder="1-5" style="width: 330px">
           <!-- <el-select v-model="formValue.controlRiskS" size="large" placeholder="1-5" style="width: 330px">
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
             <el-option v-for="n in 5" :key="n" :label="n" :value="n" />
           </el-select> -->
           </el-select> -->
-          <el-input-number
+          <el-input
             disabled
             disabled
             :step="1"
             :step="1"
             :precision="0"
             :precision="0"

+ 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: '申请单号',
     label: '申请单号',
-    prop: 'applyCode',
+    prop: 'applyCodeDesc',
     align: 'left',
     align: 'left',
     minWidth: '140px',
     minWidth: '140px',
   },
   },

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

@@ -43,12 +43,15 @@
                   placeholder="请输入申请部门名称"
                   placeholder="请输入申请部门名称"
                   class="act-search-input"
                   class="act-search-input"
                   clearable
                   clearable
-                />
+                /> 
               </div>
               </div>
             </section>
             </section>
             <section class="search-btn">
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
               <el-button type="primary" @click="handleSearch">查询</el-button>
               <el-button @click="handleReset">重置</el-button>
               <el-button @click="handleReset">重置</el-button>
+              <el-button plain  @click="handleDownload">
+                导出
+              </el-button>
             </section>
             </section>
           </div>
           </div>
         </header>
         </header>
@@ -110,10 +113,12 @@
   import {
   import {
     queryPurchaseApplyList,
     queryPurchaseApplyList,
     deletePurchaseApply,
     deletePurchaseApply,
+    exportSafetyEquipmentProcurementRequest,
     type PpePurchaseApply,
     type PpePurchaseApply,
     type QueryPurchaseApplyPageReq,
     type QueryPurchaseApplyPageReq,
   } from '@/api/production-safety/personal-protective-equipment-purchase-apply';
   } from '@/api/production-safety/personal-protective-equipment-purchase-apply';
   import { template } from 'lodash-es';
   import { template } from 'lodash-es';
+  import { downloadByData } from '@/utils/file/download';
 
 
   const router = useRouter();
   const router = useRouter();
   const basicTableRef = ref<InstanceType<typeof BasicTable>>();
   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(() => {
   onMounted(() => {
     getTableData();
     getTableData();
   });
   });

+ 4 - 4
src/views/production-safety/risk-identification-and-control/special-equipment-manage/add.vue

@@ -14,9 +14,9 @@
       >
       >
         <template #deviceStatus>
         <template #deviceStatus>
           <el-radio-group v-model="formData.deviceStatus">
           <el-radio-group v-model="formData.deviceStatus">
-            <el-radio :label="1">在用</el-radio>
-            <el-radio :label="2">停用</el-radio>
-            <el-radio :label="3">报废</el-radio>
+            <el-radio :value="1">在用</el-radio>
+            <el-radio :value="2">停用</el-radio>
+            <el-radio :value="3">报废</el-radio>
           </el-radio-group>
           </el-radio-group>
         </template>
         </template>
         <template #useDepartment>
         <template #useDepartment>
@@ -117,7 +117,7 @@
     if (Array.isArray(val) && val.length) {
     if (Array.isArray(val) && val.length) {
       (formData as any).responsibilityDeptId = val[val.length - 1];
       (formData as any).responsibilityDeptId = val[val.length - 1];
       (formData as any).useDepartment = getDeptNameByPath(deptOptions.value, val);
       (formData as any).useDepartment = getDeptNameByPath(deptOptions.value, val);
-      useDepartmentPath.value = [...val];
+      responsibilityDeptPath.value = [...val];
     } else {
     } else {
       (formData as any).responsibilityDeptId = undefined;
       (formData as any).responsibilityDeptId = undefined;
     }
     }

+ 37 - 27
src/views/production-safety/safetyTrainingAndEducation/educationTrainingPlanManagementDept/components/addTrainingInformation.vue

@@ -12,6 +12,7 @@
   import { ElMessage, UploadRawFile } from 'element-plus';
   import { ElMessage, UploadRawFile } from 'element-plus';
   import { unformatAttachment, formatAttachmentList } from '@/components/UploadFiles/utils';
   import { unformatAttachment, formatAttachmentList } from '@/components/UploadFiles/utils';
   import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
   import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
+  import { downloadFile } from '@/views/disaster/utils';
 
 
   import { debounce } from 'lodash-es';
   import { debounce } from 'lodash-es';
   const props = defineProps({
   const props = defineProps({
@@ -49,9 +50,10 @@
     courseIntroduction: '',
     courseIntroduction: '',
     courseContent: '', //[] as FileItem[],
     courseContent: '', //[] as FileItem[],
     isSign: 0,
     isSign: 0,
-    courseImg: [] as FileItem[],
+    courseImg: '', //[] as FileItem[],
   });
   });
   const fileList = ref<FileItem[]>([]);
   const fileList = ref<FileItem[]>([]);
+  const courseImgList = ref<FileItem[]>([]);
   const fileInfo = ref<any>(null);
   const fileInfo = ref<any>(null);
 
 
   const categoryOptions = ref([
   const categoryOptions = ref([
@@ -83,7 +85,7 @@ const openState = ref(false)
       // 编辑/查看模式,加载现有详情数据
       // 编辑/查看模式,加载现有详情数据
       // 这里可以调用接口获取当前培训课程的信息,并填充到 form 中
       // 这里可以调用接口获取当前培训课程的信息,并填充到 form 中
       await queryEducationTrainingPlanCourseDetail(props.currentId).then((res) => {
       await queryEducationTrainingPlanCourseDetail(props.currentId).then((res) => {
-        console.log(res, '课程详情',);
+        // console.log(res, '课程详情',);
         Object.assign(form, {
         Object.assign(form, {
             courseType: res.courseType,
             courseType: res.courseType,
             courseName: res.courseName,
             courseName: res.courseName,
@@ -98,12 +100,12 @@ const openState = ref(false)
         form.groupOfParticipants = res.groupOfParticipants ? res.groupOfParticipants.split(',').map(Number) : [];
         form.groupOfParticipants = res.groupOfParticipants ? res.groupOfParticipants.split(',').map(Number) : [];
         // 编辑和查看时 没有回显
         // 编辑和查看时 没有回显
         if(res.courseImg){
         if(res.courseImg){
-            form.courseImg = [JSON.parse(res.courseImg)]
+            form.courseImg = JSON.parse(res.courseImg)
+            courseImgList.value = JSON.parse(res.courseImg) || []
         }
         }
         if(res.courseContent){
         if(res.courseContent){
-            // handleFileExceed(JSON.parse(res.courseContent))
-            // fileList.value =  JSON.parse(res.courseContent) || [];
-            // form.courseContent = res.courseContent
+            fileList.value =  JSON.parse(res.courseContent) || [];
+            form.courseContent = JSON.parse(res.courseContent)
         }
         }
       });
       });
     } else if (props.state === 'add') {
     } else if (props.state === 'add') {
@@ -145,13 +147,24 @@ const openState = ref(false)
   };
   };
 
 
   //  上传图片
   //  上传图片
-  const handleImageUploadChange = async (uploadFile: any, uploadFiles: any) => {
-    form.courseImg = uploadFiles;
-    if(uploadFile.raw){
-        let res = await formatAttachment(uploadFile.raw)
-        console.log(res, '图片上传')
-        if(res){
-            ElMessage.success('上传成功')
+  const handleImageUploadChange = async (file: any, fileLists: any) => {
+    
+    if(file.raw){
+        try {
+            const res = await formatAttachment(file.raw);
+            
+            const targetFile = fileLists.find(f => f.uid === file.uid);
+            if (targetFile) {
+                targetFile.url = res.url; 
+                targetFile.contentType = res.contentType
+            }
+            courseImgList.value = fileLists; 
+            form.courseImg = JSON.stringify(fileLists);
+            ElMessage.success('上传成功');
+        } catch (error) {
+            ElMessage.error('上传失败,请重试');
+            // 上传失败时,可以从 fileLists 中移除该文件
+            courseImgList.value = fileLists.filter(f => f.uid !== file.uid);
         }
         }
     }
     }
   };
   };
@@ -275,16 +288,7 @@ const openState = ref(false)
             fileList.value = fileLists.filter(f => f.uid !== file.uid);
             fileList.value = fileLists.filter(f => f.uid !== file.uid);
         }
         }
     }
     }
-    if(file.raw){
-        let res = await formatAttachment(file.raw)
-        console.log(res, '文件上传')
-        if(res){
-            ElMessage.success('上传成功')
-        }
-    }
-    // // 直接替换为新文件
-    // fileList.value = [file.raw]; 
-    // form.courseContent = file; // 更新表单数据
+
   };
   };
 
 
   // 提交保存/编辑
   // 提交保存/编辑
@@ -304,9 +308,8 @@ const openState = ref(false)
       const basePayload = {
       const basePayload = {
         ...form,
         ...form,
         petpiId: props.currentId,
         petpiId: props.currentId,
-        courseImg: form.courseImg[0],
       };
       };
-      console.log('提交的表单数据:', basePayload);
+    //   console.log('提交的表单数据:', basePayload);
       
       
       if (isCreateMode.value) {
       if (isCreateMode.value) {
         // 新增,创建接口
         // 新增,创建接口
@@ -417,7 +420,6 @@ const openState = ref(false)
             <Editor
             <Editor
               style="height: 400px; overflow-y: auto"
               style="height: 400px; overflow-y: auto"
               v-model="form.courseIntroduction"
               v-model="form.courseIntroduction"
-              mode="disabled"
               :disabled="isViewMode"
               :disabled="isViewMode"
               :defaultConfig="editorConfig"
               :defaultConfig="editorConfig"
               @on-created="handleEditorCreated"
               @on-created="handleEditorCreated"
@@ -446,6 +448,14 @@ const openState = ref(false)
               <div class="el-upload__tip"> 支持格式:.rar .zip .doc .docx .pdf .mp4,单个文件不能超过20MB </div>
               <div class="el-upload__tip"> 支持格式:.rar .zip .doc .docx .pdf .mp4,单个文件不能超过20MB </div>
             </template>
             </template>
           </el-upload>
           </el-upload>
+          <div class="file-list" >
+          <div class="file-item" v-for="file in fileList" :key="file.fileId">
+            <span class="file-item--name">{{ file.fileName }}</span>
+            <div class="file-item--footer">
+              <el-button link type="primary" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</el-button>
+            </div>
+          </div>
+        </div>
         </el-form-item>
         </el-form-item>
 
 
         <el-form-item label="是否需要签名:" prop="isSign">
         <el-form-item label="是否需要签名:" prop="isSign">
@@ -460,7 +470,7 @@ const openState = ref(false)
             class="image-uploader"
             class="image-uploader"
             ref="courseImgRef"
             ref="courseImgRef"
             action="#"
             action="#"
-            :file-list="form.courseImg"
+            :file-list="courseImgList"
             :disabled="isViewMode"
             :disabled="isViewMode"
             :auto-upload="false"
             :auto-upload="false"
             :limit="1"
             :limit="1"

+ 16 - 4
src/views/production-safety/safetyTrainingAndEducation/educationTrainingPlanManagementDept/components/educationTrainingPlanManagementDeptDetail.vue

@@ -84,7 +84,7 @@
 
 
         <!-- 表格 -->
         <!-- 表格 -->
         <el-table :data="tableData" border stripe>
         <el-table :data="tableData" border stripe>
-          <el-table-column prop="id" label="编号" width="80" fixed="left" />
+          <el-table-column type="index" label="编号" width="80" fixed="left" />
           <el-table-column prop="courseName" label="培训课程名称" width="240" fixed="left" />
           <el-table-column prop="courseName" label="培训课程名称" width="240" fixed="left" />
           <el-table-column prop="trainingDate" width="230" label="培训时间" />
           <el-table-column prop="trainingDate" width="230" label="培训时间" />
           <el-table-column prop="courseTypeName" label="课程所属分类" width="180" />
           <el-table-column prop="courseTypeName" label="课程所属分类" width="180" />
@@ -128,11 +128,12 @@
     queryTrainingTableData,
     queryTrainingTableData,
     queryEducationAndTrainingProgramDetail,
     queryEducationAndTrainingProgramDetail,
     deleteTrainingInformation,
     deleteTrainingInformation,
+    exportEducationTrainingPlanCourseData,
     type TableParamsType,
     type TableParamsType,
   } from '@/api/production-education-training-plan-dept';
   } from '@/api/production-education-training-plan-dept';
   import AddTrainingInformation from './addTrainingInformation.vue';
   import AddTrainingInformation from './addTrainingInformation.vue';
   import type { QueryPageRequest } from '@/types/basic-query';
   import type { QueryPageRequest } from '@/types/basic-query';
-  import { id, pa } from 'element-plus/es/locale';
+  import { downloadByData } from '@/utils/file/download';
   const router = useRouter();
   const router = useRouter();
   const route = useRoute();
   const route = useRoute();
 
 
@@ -202,8 +203,19 @@
     getTableList();
     getTableList();
   };
   };
 
 
-  const handleExport = () => {
-    ElMessage.success('点击了导出');
+  const handleExport = async () => {
+    
+    try {
+      const response = await exportEducationTrainingPlanCourseData(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('导出失败,请重试');
+    }
   };
   };
 
 
   const handleAdd = () => {
   const handleAdd = () => {