Ver código fonte

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

Feat/production safety

See merge request product-group-fe/sfy-safety-group/sfy-safety!303
xiaweibo 3 meses atrás
pai
commit
a32ba862f7
45 arquivos alterados com 1247 adições e 886 exclusões
  1. 289 0
      src/api/production-safety/index.ts
  2. 9 2
      src/components/UploadFiles/UploadFiles.vue
  3. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/configs/form.ts
  4. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/configs/form.ts
  5. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/checkTemplateManagement/configs/form.ts
  6. 41 147
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/components/employeeReportHiddenTroubleManagementDetail.vue
  7. 84 46
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/configs/form.ts
  8. 31 17
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/configs/tables.ts
  9. 81 51
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/employeeReportHiddenTroubleManagement.vue
  10. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form.ts
  11. 17 146
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/components/hiddenTroubleCategoryManagementDetail.vue
  12. 18 61
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/configs/form.ts
  13. 20 24
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/configs/tables.ts
  14. 29 56
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/hiddenTroubleCategoryManagement.vue
  15. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleReviewManagement/configs/form.ts
  16. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagement/configs/form.ts
  17. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagementDept/configs/form.ts
  18. 31 12
      src/views/production-safety/productionSafetySystem/collegeFileManagement/collegeFileManagement.vue
  19. 7 10
      src/views/production-safety/productionSafetySystem/collegeFileManagement/components/collegeFileManagementDetail.vue
  20. 1 1
      src/views/production-safety/productionSafetySystem/collegeFileManagement/configs/form.ts
  21. 2 2
      src/views/production-safety/productionSafetySystem/collegeFileManagement/configs/tables.ts
  22. 7 10
      src/views/production-safety/productionSafetySystem/doubleSystemManagement/components/doubleSystemManagementDetail.vue
  23. 1 1
      src/views/production-safety/productionSafetySystem/doubleSystemManagement/configs/form.ts
  24. 2 2
      src/views/production-safety/productionSafetySystem/doubleSystemManagement/configs/tables.ts
  25. 30 12
      src/views/production-safety/productionSafetySystem/doubleSystemManagement/doubleSystemManagement.vue
  26. 7 10
      src/views/production-safety/productionSafetySystem/lawManagement/components/lawManagementDetail.vue
  27. 1 1
      src/views/production-safety/productionSafetySystem/lawManagement/configs/form.ts
  28. 2 2
      src/views/production-safety/productionSafetySystem/lawManagement/configs/tables.ts
  29. 30 12
      src/views/production-safety/productionSafetySystem/lawManagement/lawManagement.vue
  30. 7 10
      src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/components/safetyStandardizationSystemManagementDetail.vue
  31. 1 1
      src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/configs/form.ts
  32. 2 2
      src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/configs/tables.ts
  33. 30 12
      src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/safetyStandardizationSystemManagement.vue
  34. 45 21
      src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagement/configs/tables.ts
  35. 154 98
      src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagement/safetySystemConstructionWorkPlanManagement.vue
  36. 45 21
      src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagementDept/configs/tables.ts
  37. 168 56
      src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagementDept/safetySystemConstructionWorkPlanManagementDept.vue
  38. 7 10
      src/views/production-safety/productionSafetySystem/safetyTraining/components/safetyTrainingDetail.vue
  39. 1 1
      src/views/production-safety/productionSafetySystem/safetyTraining/configs/form.ts
  40. 2 2
      src/views/production-safety/productionSafetySystem/safetyTraining/configs/tables.ts
  41. 30 12
      src/views/production-safety/productionSafetySystem/safetyTraining/safetyTraining.vue
  42. 2 2
      src/views/production-safety/safetyAssessment/evaluationSystem/components/EvaluationSystemDetail.vue
  43. 2 2
      src/views/production-safety/safetyAssessment/evaluationSystem/evaluationSystem.vue
  44. 2 2
      src/views/production-safety/safetyAssessment/receiptRecord/components/ReceiptRecordDetail.vue
  45. 2 2
      src/views/production-safety/safetyAssessment/receiptRecord/configs/form.ts

+ 289 - 0
src/api/production-safety/index.ts

@@ -0,0 +1,289 @@
+import { http } from '@/utils/http/axios';
+import type { QueryPageRequest, QueryPageResponse } from '@/types/basic-query';
+
+/**
+ * ==================== 员工上报隐患管理 hiddenDanger ====================
+ */
+
+// 隐患上报数据对象(详情 / 列表返回)
+export interface HiddenDanger {
+  id: number;
+  dangerName: string;
+  dangerType: number;
+  dangerTypeName?: string;
+  dangerLevel: number;
+  dangerLevelName?: string;
+  location: string;
+  description: string;
+  reporterName: string;
+  reporterPhone: string;
+  reporterDept: string;
+  reportTime: string;
+  images?: string[];
+  status: number;
+  statusName?: string;
+  handlerName?: string;
+  handleTime?: string;
+  handleResult?: string;
+  createdAt?: string;
+  updatedAt?: string;
+}
+
+// 新增隐患上报
+export interface SaveHiddenDangerReq {
+  dangerName: string;
+  dangerType: number;
+  dangerLevel: number;
+  location: string;
+  description: string;
+  reporterName: string;
+  reporterPhone: string;
+  reporterDept: string;
+  reportTime: string;
+  images?: string[];
+  status?: number;
+}
+
+// 编辑隐患上报
+export interface UpdateHiddenDangerReq extends SaveHiddenDangerReq {
+  id: number;
+}
+
+// 查询条件
+export interface QueryHiddenDangerReq {
+  keyword?: string;
+  dangerType?: number;
+  dangerLevel?: number;
+  status?: number;
+  startDate?: string;
+  endDate?: string;
+}
+
+// 处理隐患
+export interface HandleHiddenDangerReq {
+  id: number;
+  status: number;
+  handlerName: string;
+  handleTime: string;
+  handleResult?: string;
+}
+
+// 新增隐患上报
+export function saveHiddenDanger(data: SaveHiddenDangerReq) {
+  return http.request<number>({
+    url: '/admin/prod/hiddenDanger/saveHiddenDanger',
+    method: 'post',
+    data,
+  });
+}
+
+// 编辑隐患上报
+export function updateHiddenDanger(data: UpdateHiddenDangerReq) {
+  return http.request({
+    url: '/admin/prod/hiddenDanger/updateHiddenDanger',
+    method: 'put',
+    data,
+  });
+}
+
+// 删除隐患上报
+export function deleteHiddenDanger(id: number) {
+  return http.request({
+    url: `/admin/prod/hiddenDanger/deleteHiddenDanger?id=${id}`,
+    method: 'delete',
+  });
+}
+
+// 根据 ID 查询隐患详情
+export function queryHiddenDangerById(id: number) {
+  return http.request<HiddenDanger>({
+    url: `/admin/prod/hiddenDanger/queryHiddenDangerById?id=${id}`,
+    method: 'get',
+  });
+}
+
+// 查询隐患上报列表(不分页)
+export function queryHiddenDangerList(params?: QueryHiddenDangerReq) {
+  return http.request<HiddenDanger[]>({
+    url: '/admin/prod/hiddenDanger/queryHiddenDangerList',
+    method: 'post',
+    data: params,
+  });
+}
+
+// 分页查询隐患上报
+export function queryHiddenDangerPage(query: QueryPageRequest<QueryHiddenDangerReq>) {
+  return http.request<QueryPageResponse<HiddenDanger>>({
+    url: '/admin/prod/hiddenDanger/queryHiddenDangerPage',
+    method: 'post',
+    data: query,
+  });
+}
+
+// 导出隐患上报
+export function exportHiddenDanger(params?: QueryHiddenDangerReq) {
+  return http.request(
+    {
+      url: '/admin/prod/hiddenDanger/exportHiddenDanger',
+      method: 'post',
+      data: params,
+      responseType: 'blob',
+    },
+    {
+      isTransformResponse: false,
+    },
+  );
+}
+
+// 导入隐患上报
+export interface ImportRes {
+  successCount: number;
+  failCount: number;
+  failMessages: string[];
+}
+
+export function importHiddenDanger(file: File) {
+  const formData = new FormData();
+  formData.append('file', file);
+  return http.request<ImportRes>({
+    url: '/admin/prod/hiddenDanger/importHiddenDanger',
+    method: 'post',
+    data: formData,
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    },
+  });
+}
+
+// 处理隐患
+export function handleHiddenDanger(data: HandleHiddenDangerReq) {
+  return http.request({
+    url: '/admin/prod/hiddenDanger/handleHiddenDanger',
+    method: 'put',
+    data,
+  });
+}
+
+/**
+ * ==================== 隐患类别管理 dangerType ====================
+ */
+
+export interface DangerType {
+  id: number;
+  typeName: string;
+  parentId: number | null;
+  parentName?: string | null;
+  sort?: number;
+  status: number;
+  statusName?: string;
+  createdAt?: string;
+  updatedAt?: string;
+  children?: DangerType[];
+}
+
+export interface SaveDangerTypeReq {
+  typeName: string;
+  parentId?: number | null;
+  sort?: number;
+  status?: number;
+}
+
+export interface UpdateDangerTypeReq extends SaveDangerTypeReq {
+  id: number;
+}
+
+export interface QueryDangerTypeReq {
+  keyword?: string;
+  parentId?: number | null;
+  status?: number;
+}
+
+// 新增隐患类别
+export function saveDangerType(data: SaveDangerTypeReq) {
+  return http.request<number>({
+    url: '/admin/prod/dangerType/saveDangerType',
+    method: 'post',
+    data,
+  });
+}
+
+// 编辑隐患类别
+export function updateDangerType(data: UpdateDangerTypeReq) {
+  return http.request({
+    url: '/admin/prod/dangerType/updateDangerType',
+    method: 'put',
+    data,
+  });
+}
+
+// 删除隐患类别
+export function deleteDangerType(id: number) {
+  return http.request({
+    url: `/admin/prod/dangerType/deleteDangerType?id=${id}`,
+    method: 'delete',
+  });
+}
+
+// 根据 ID 查询隐患类别详情
+export function queryDangerTypeById(id: number) {
+  return http.request<DangerType>({
+    url: `/admin/prod/dangerType/queryDangerTypeById?id=${id}`,
+    method: 'get',
+  });
+}
+
+// 查询隐患类别列表(不分页)
+export function queryDangerTypeList(params?: QueryDangerTypeReq) {
+  return http.request<DangerType[]>({
+    url: '/admin/prod/dangerType/queryDangerTypeList',
+    method: 'post',
+    data: params,
+  });
+}
+
+// 分页查询隐患类别
+export function queryDangerTypePage(query: QueryPageRequest<QueryDangerTypeReq>) {
+  return http.request<QueryPageResponse<DangerType>>({
+    url: '/admin/prod/dangerType/queryDangerTypePage',
+    method: 'post',
+    data: query,
+  });
+}
+
+// 获取隐患类别树形结构
+export function getDangerTypeTree(status?: number) {
+  return http.request<DangerType[]>({
+    url: '/admin/prod/dangerType/getDangerTypeTree',
+    method: 'get',
+    params: typeof status === 'number' ? { status } : undefined,
+  });
+}
+
+// 导出隐患类别
+export function exportDangerType(params?: QueryDangerTypeReq) {
+  return http.request(
+    {
+      url: '/admin/prod/dangerType/exportDangerType',
+      method: 'post',
+      data: params,
+      responseType: 'blob',
+    },
+    {
+      isTransformResponse: false,
+    },
+  );
+}
+
+// 导入隐患类别
+export function importDangerType(file: File) {
+  const formData = new FormData();
+  formData.append('file', file);
+  return http.request<ImportRes>({
+    url: '/admin/prod/dangerType/importDangerType',
+    method: 'post',
+    data: formData,
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    },
+  });
+}

+ 9 - 2
src/components/UploadFiles/UploadFiles.vue

@@ -40,7 +40,13 @@
           <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
           <span class="file-name">{{ file.fileName }}</span>
         </div>
-        <el-icon class="delete-button" @click="removeFile(file.fileId)"><Delete /></el-icon>
+        <el-icon 
+          v-if="!isUploadDisabled"
+          class="delete-button" 
+          @click="removeFile(file.fileId)"
+        >
+          <Delete />
+        </el-icon>
       </div>
     </div>
   </div>
@@ -58,6 +64,7 @@
     fileList?: FileItem[];
     maxSize?: number;
     maxCount?: number;
+    disabled?: boolean;
   }>();
 
   const inputId = `upload-file-${Math.random().toString(36).slice(2, 10)}`;
@@ -79,7 +86,7 @@
   });
 
   const isUploadDisabled = computed(() => {
-    return fileList.value.length >= MAX_COUNT.value;
+    return props.disabled || fileList.value.length >= MAX_COUNT.value;
   });
 
   // 检查文件是否已存在

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/checkTemplateManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 41 - 147
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/components/employeeReportHiddenTroubleManagementDetail.vue

@@ -6,43 +6,12 @@
       :formRules="isViewMode ? undefined : formRules"
       :formConfig="computedFormConfig"
     >
-      <template #fileFormat>
-        <el-radio-group v-model="ruleFormData.fileFormat" :disabled="isViewMode">
-          <el-radio value="PDF">PDF</el-radio>
-          <el-radio value="WORD">WORD</el-radio>
-        </el-radio-group>
-      </template>
-      <template #fileUrl>
-        <UploadFiles
-          v-if="!isViewMode"
-          label="上传文件"
-          :maxCount="1"
-          :fileList="uploadFileList"
-          @uploadSuccess="handleUploadSuccess"
-        />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
-      </template>
-      <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
-          <Editor
-            style="height: 400px; overflow-y: auto"
-            v-model="ruleFormData.content"
-            mode="default"
-            :defaultConfig="editorConfig"
-            @on-created="handleEditorCreated"
-            @on-change="handleEditorChange"
-          />
-        </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
-      </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
-          <el-radio :value="1">启用</el-radio>
-          <el-radio :value="0">禁用</el-radio>
+          <el-radio :value="1">待处理</el-radio>
+          <el-radio :value="2">处理中</el-radio>
+          <el-radio :value="3">已处理</el-radio>
+          <el-radio :value="4">已驳回</el-radio>
         </el-radio-group>
       </template>
     </BasicForm>
@@ -56,22 +25,18 @@
 </template>
 
 <script setup lang="ts">
-  import { computed, onMounted, ref, shallowRef, onBeforeUnmount } from 'vue';
+  import { computed, onMounted, ref } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import BasicForm from '@/components/BasicForm.vue';
-  import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
-  import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
-  import '@wangeditor/editor/dist/css/style.css';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { ACADEMY_FILE_FORM_CONFIG, ACADEMY_FILE_FORM_DATA, ACADEMY_FILE_FORM_RULES } from '../configs/form';
   import {
-    queryAcademyFileById,
-    saveAcademyFile,
-    updateAcademyFile,
-    type ProductionSafetyFile,
-  } from '@/api/production-safety-system';
-  import type { FileItem } from '@/components/UploadFiles/types';
+    queryHiddenDangerById,
+    saveHiddenDanger,
+    updateHiddenDanger,
+    type HiddenDanger,
+  } from '@/api/production-safety';
 
   const router = useRouter();
   const route = useRoute();
@@ -105,39 +70,6 @@
   });
 
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
-  
-  // 富文本编辑器
-  const editorRef = shallowRef();
-  const editorConfig = {
-    placeholder: '请输入文档内容',
-    MENU_CONF: {},
-  };
-
-  const handleEditorCreated = (editor: any) => {
-    editorRef.value = editor;
-  };
-
-  const handleEditorChange = () => {
-    // 编辑器内容变化时的处理
-  };
-
-  // 文件上传
-  const uploadFileList = ref<FileItem[]>([]);
-
-  const handleUploadSuccess = (files: FileItem[]) => {
-    uploadFileList.value = files;
-    if (files.length > 0 && files[0].file) {
-      // 这里需要实际上传文件到服务器,获取 fileUrl
-      // 暂时使用文件对象,实际应该调用上传接口
-      ruleFormData.fileUrl = files[0].file.name; // 临时处理,需要替换为实际上传后的URL
-    }
-  };
-
-  const getFileName = (url: string) => {
-    if (!url) return '';
-    const parts = url.split('/');
-    return parts[parts.length - 1];
-  };
 
   const handleValidate = async () => {
     if (!basicFormRef.value) return;
@@ -148,34 +80,24 @@
   const getDetail = async () => {
     if (!currentId.value) return;
     try {
-      const res = await queryAcademyFileById(currentId.value);
+      const res = await queryHiddenDangerById(currentId.value);
       if (res) {
         // 映射接口字段到表单字段
-        ruleFormData.fileName = res.fileName || '';
-        ruleFormData.classifyName = res.classifyName || '';
-        ruleFormData.fileCode = res.fileCode || '';
-        ruleFormData.fileVersion = res.fileVersion || '';
-        ruleFormData.fileFormat = res.fileFormat || '';
-        ruleFormData.releaseDate = res.releaseDate || '';
-        ruleFormData.fileUrl = res.fileUrl || '';
-        ruleFormData.content = res.content || '';
+        ruleFormData.dangerName = res.dangerName || '';
+        ruleFormData.dangerType = res.dangerType ?? undefined;
+        ruleFormData.dangerLevel = res.dangerLevel ?? undefined;
+        ruleFormData.location = res.location || '';
+        ruleFormData.description = res.description || '';
+        ruleFormData.reporterName = res.reporterName || '';
+        ruleFormData.reporterPhone = res.reporterPhone || '';
+        ruleFormData.reporterDept = res.reporterDept || '';
+        ruleFormData.reportTime = res.reportTime || '';
+        ruleFormData.imagesText = res.images && res.images.length ? res.images.join(',') : '';
         ruleFormData.status = res.status ?? 1;
-        
-        // 如果有文件URL,转换为FileItem格式
-        if (res.fileUrl) {
-          uploadFileList.value = [
-            {
-              fileId: Date.now(),
-              fileName: getFileName(res.fileUrl),
-              fileType: res.fileFormat?.toLowerCase() === 'pdf' ? 'pdf' : 'word',
-              fileSize: '0KB',
-            },
-          ];
-        }
       }
       cloneRuleFormData();
     } catch (e) {
-      console.error('获取院级文件详情失败:', e);
+      console.error('获取隐患上报详情失败:', e);
       ElMessage.error('获取详情失败');
     }
   };
@@ -184,23 +106,30 @@
     const res = await handleValidate();
     if (!res) return;
     try {
-      const basePayload: ProductionSafetyFile = {
-        fileName: ruleFormData.fileName,
-        classifyName: ruleFormData.classifyName,
-        fileCode: ruleFormData.fileCode,
-        fileVersion: ruleFormData.fileVersion,
-        fileFormat: ruleFormData.fileFormat,
-        releaseDate: ruleFormData.releaseDate,
-        fileUrl: ruleFormData.fileUrl || undefined,
-        content: ruleFormData.content || undefined,
+      const images =
+        ruleFormData.imagesText && ruleFormData.imagesText.trim().length > 0
+          ? ruleFormData.imagesText.split(',').map((item: string) => item.trim()).filter(Boolean)
+          : [];
+
+      const basePayload = {
+        dangerName: ruleFormData.dangerName,
+        dangerType: Number(ruleFormData.dangerType),
+        dangerLevel: Number(ruleFormData.dangerLevel),
+        location: ruleFormData.location,
+        description: ruleFormData.description,
+        reporterName: ruleFormData.reporterName,
+        reporterPhone: ruleFormData.reporterPhone,
+        reporterDept: ruleFormData.reporterDept,
+        reportTime: ruleFormData.reportTime,
+        images,
         status: ruleFormData.status ?? 1,
       };
 
       if (isCreateMode.value) {
-        await saveAcademyFile(basePayload);
+        await saveHiddenDanger(basePayload);
         ElMessage.success('创建成功');
       } else if (isEditMode.value && currentId.value) {
-        await updateAcademyFile({
+        await updateHiddenDanger({
           id: currentId.value,
           ...basePayload,
         });
@@ -209,7 +138,7 @@
 
       router.back();
     } catch (e) {
-      console.error('保存院级文件失败:', e);
+      console.error('保存隐患上报失败:', e);
       ElMessage.error('保存失败,请重试');
     }
   };
@@ -221,44 +150,9 @@
       getDetail();
     }
   });
-
-  onBeforeUnmount(() => {
-    const editor = editorRef.value;
-    if (editor == null) return;
-    editor.destroy();
-  });
 </script>
 
 <style scoped lang="scss">
   @use '@/styles/page-details-layout.scss' as *;
-
-  .editor-container {
-    width: 100%;
-    border: 1px solid #dcdfe6;
-    border-radius: 4px;
-    overflow: hidden;
-  }
-
-  .content-display {
-    min-height: 200px;
-    padding: 12px;
-    border: 1px solid #dcdfe6;
-    border-radius: 4px;
-    background-color: #f5f7fa;
-  }
-
-  .file-display {
-    .file-link {
-      color: #409eff;
-      text-decoration: none;
-      &:hover {
-        text-decoration: underline;
-      }
-    }
-  }
-
-  .no-file {
-    color: rgba(0, 0, 0, 0.65);
-  }
 </style>
 

+ 84 - 46
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/configs/form.ts

@@ -1,91 +1,129 @@
 import { FormConfig } from '@/types/basic-form';
 
+// 员工上报隐患管理表单配置
 export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
   {
-    prop: 'fileName',
-    label: '文件名称:',
+    prop: 'dangerName',
+    label: '隐患名称:',
     component: 'ElInput',
     componentProps: {
-      placeholder: '请输入文件名称',
+      placeholder: '请输入隐患名称',
     },
   },
   {
-    prop: 'classifyName',
-    label: '分类名称:',
+    prop: 'dangerType',
+    label: '隐患类别ID:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入隐患类别ID',
+      type: 'number',
+    },
+  },
+  {
+    prop: 'dangerLevel',
+    label: '隐患等级:',
     component: 'ElSelect',
     componentProps: {
-      placeholder: '请选择分类名称',
+      placeholder: '请选择隐患等级',
     },
-    options: [
-      { label: '外部院级文件', value: '外部院级文件' },
-      { label: '内部院级文件', value: '内部院级文件' },
+    selectOptions: [
+      { label: '一般', value: 1 },
+      { label: '较大', value: 2 },
+      { label: '重大', value: 3 },
     ],
   },
   {
-    prop: 'fileCode',
-    label: '文件编号:',
+    prop: 'location',
+    label: '隐患位置:',
     component: 'ElInput',
     componentProps: {
-      placeholder: '请输入文件编号',
+      placeholder: '请输入隐患位置',
     },
   },
   {
-    prop: 'fileVersion',
-    label: '文件版本号:',
+    prop: 'description',
+    label: '隐患描述:',
     component: 'ElInput',
     componentProps: {
-      placeholder: '请输入文件版本号,如:V1.0',
+      type: 'textarea',
+      rows: 3,
+      placeholder: '请输入隐患描述',
     },
   },
   {
-    prop: 'fileFormat',
-    label: '文件格式:',
-    slot: 'fileFormat',
+    prop: 'reporterName',
+    label: '上报人姓名:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入上报人姓名',
+    },
   },
   {
-    prop: 'releaseDate',
-    label: '发布日期:',
-    component: 'ElDatePicker',
+    prop: 'reporterPhone',
+    label: '上报人电话:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入上报人电话',
+    },
+  },
+  {
+    prop: 'reporterDept',
+    label: '上报人部门:',
+    component: 'ElInput',
     componentProps: {
-      type: 'date',
-      placeholder: '请选择发布日期',
-      valueFormat: 'YYYY-MM-DD',
+      placeholder: '请输入上报人部门',
     },
   },
   {
-    prop: 'fileUrl',
-    label: '文件上传:',
-    slot: 'fileUrl',
+    prop: 'reportTime',
+    label: '上报时间:',
+    component: 'ElDatePicker',
+    componentProps: {
+      type: 'datetime',
+      placeholder: '请选择上报时间',
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+    },
   },
   {
-    prop: 'content',
-    label: '文档内容:',
-    slot: 'content',
+    prop: 'imagesText',
+    label: '隐患图片:',
+    component: 'ElInput',
+    componentProps: {
+      type: 'textarea',
+      rows: 2,
+      placeholder: '请输入图片URL,多个用英文逗号分隔',
+    },
   },
   {
     prop: 'status',
-    label: '状态:',
+    label: '处理状态:',
     slot: 'status',
   },
 ];
 
 export const ACADEMY_FILE_FORM_DATA = {
-  fileName: '',
-  classifyName: '',
-  fileCode: '',
-  fileVersion: '',
-  fileFormat: '',
-  releaseDate: '',
-  fileUrl: '',
-  content: '',
-  status: 1, // 默认启用
+  dangerName: '',
+  dangerType: undefined as number | undefined,
+  dangerLevel: undefined as number | undefined,
+  location: '',
+  description: '',
+  reporterName: '',
+  reporterPhone: '',
+  reporterDept: '',
+  reportTime: '',
+  imagesText: '',
+  status: 1, // 默认待处理
 };
 
 export const ACADEMY_FILE_FORM_RULES = {
-  fileName: [{ required: true, message: '请输入文件名称', trigger: 'blur' }],
-  classifyName: [{ required: true, message: '请选择分类名称', trigger: 'change' }],
-  fileCode: [{ required: true, message: '请输入文件编号', trigger: 'blur' }],
-  fileVersion: [{ required: true, message: '请输入文件版本号', trigger: 'blur' }],
-  fileFormat: [{ required: true, message: '请选择文件格式', trigger: 'change' }],
-  releaseDate: [{ required: true, message: '请选择发布日期', trigger: 'change' }],
+  dangerName: [{ required: true, message: '请输入隐患名称', trigger: 'blur' }],
+  dangerType: [{ required: true, message: '请输入隐患类别ID', trigger: 'blur' }],
+  dangerLevel: [{ required: true, message: '请选择隐患等级', trigger: 'change' }],
+  location: [{ required: true, message: '请输入隐患位置', trigger: 'blur' }],
+  description: [{ required: true, message: '请输入隐患描述', trigger: 'blur' }],
+  reporterName: [{ required: true, message: '请输入上报人姓名', trigger: 'blur' }],
+  reporterPhone: [{ required: true, message: '请输入上报人电话', trigger: 'blur' }],
+  reporterDept: [{ required: true, message: '请输入上报人部门', trigger: 'blur' }],
+  reportTime: [{ required: true, message: '请选择上报时间', trigger: 'change' }],
 };
+

+ 31 - 17
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/configs/tables.ts

@@ -7,56 +7,70 @@ export const TABLE_OPTIONS = {
   maxHeight: 'calc(70vh - 150px)',
 };
 
+// 员工上报隐患管理表格列
 export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
   {
-    label: '号',
+    label: '号',
     type: 'index',
     align: 'center',
     width: '80px',
   },
   {
-    label: '物品名称',
-    prop: 'itemName',
+    label: '隐患名称',
+    prop: 'dangerName',
     align: 'left',
-    minWidth: '120px',
+    minWidth: '160px',
   },
   {
-    label: '入库日期',
-    prop: 'warehouseDate',
+    label: '隐患类别',
+    prop: 'dangerTypeName',
     align: 'left',
-    minWidth: '120px',
+    minWidth: '140px',
   },
   {
-    label: '物品数量',
-    prop: 'itemQuantity',
+    label: '隐患等级',
+    prop: 'dangerLevelName',
     align: 'center',
     minWidth: '120px',
   },
   {
-    label: '经办人',
-    prop: 'handler',
+    label: '隐患位置',
+    prop: 'location',
+    align: 'left',
+    minWidth: '180px',
+  },
+  {
+    label: '上报人',
+    prop: 'reporterName',
     align: 'left',
     minWidth: '120px',
   },
   {
-    label: '备注',
-    prop: 'remarks',
+    label: '上报部门',
+    prop: 'reporterDept',
     align: 'left',
-    minWidth: '150px',
+    minWidth: '140px',
   },
   {
-    label: '状态',
+    label: '上报时间',
+    prop: 'reportTime',
+    align: 'left',
+    minWidth: '180px',
+  },
+  {
+    label: '处理状态',
     prop: 'status',
     slot: 'status',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '120px',
   },
   {
     label: '操作',
     prop: 'action',
     slot: 'action',
     fixed: 'right',
-    width: '180px',
+    width: '200px',
     align: 'left',
   },
 ];
+

+ 81 - 51
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/employeeReportHiddenTroubleManagement/employeeReportHiddenTroubleManagement.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="safety-platform-container">
     <header class="safety-platform-container__header">
-      <div class="breadcrumb-title"> 院级文件管理 </div>
+      <div class="breadcrumb-title"> 员工上报隐患管理 </div>
     </header>
     <main class="safety-platform-container__main">
       <div class="search-table-container">
         <header>
           <div style="position: relative">
             <el-button type="primary" class="search-table-container--button" @click="handleCreate">
-              添加
+              新增
             </el-button>
             <el-button plain class="search-table-container--button" @click="handleImport">
               导入
@@ -21,35 +21,49 @@
           <div class="act-search">
             <section class="select-box">
               <div class="select-box--item">
-                <span>文件名称/编号:</span>
+                <span>关键字:</span>
                 <el-input
                   v-model="tableQuery.queryParam.keyword"
-                  placeholder="搜索文件名称或编号"
+                  placeholder="隐患名称/位置/上报人"
                   class="act-search-input"
                 />
               </div>
               <div class="select-box--item">
-                <span>分类:</span>
+                <span>隐患等级:</span>
                 <el-select
-                  v-model="tableQuery.queryParam.classifyName"
-                  placeholder="请选择分类"
+                  v-model="tableQuery.queryParam.dangerLevel"
+                  placeholder="请选择隐患等级"
                   clearable
                 >
-                  <el-option label="外部院级文件" value="外部院级文件" />
-                  <el-option label="内部院级文件" value="内部院级文件" />
+                  <el-option label="一般" :value="1" />
+                  <el-option label="较大" :value="2" />
+                  <el-option label="重大" :value="3" />
                 </el-select>
               </div>
               <div class="select-box--item">
-                <span>状态:</span>
+                <span>处理状态:</span>
                 <el-select
                   v-model="tableQuery.queryParam.status"
-                  placeholder="请选择状态"
+                  placeholder="请选择处理状态"
                   clearable
                 >
-                  <el-option label="启用" :value="1" />
-                  <el-option label="禁用" :value="0" />
+                  <el-option label="待处理" :value="1" />
+                  <el-option label="处理中" :value="2" />
+                  <el-option label="已处理" :value="3" />
+                  <el-option label="已驳回" :value="4" />
                 </el-select>
               </div>
+              <div class="select-box--item">
+                <span>上报日期:</span>
+                <el-date-picker
+                  v-model="reportDateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                  value-format="YYYY-MM-DD"
+                />
+              </div>
             </section>
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
@@ -68,7 +82,17 @@
           >
             <template #status="scope">
               <span>
-                {{ scope.row.status === 1 ? '启用' : scope.row.status === 0 ? '禁用' : '-' }}
+                {{
+                  scope.row.status === 1
+                    ? '待处理'
+                    : scope.row.status === 2
+                      ? '处理中'
+                      : scope.row.status === 3
+                        ? '已处理'
+                        : scope.row.status === 4
+                          ? '已驳回'
+                          : '-'
+                }}
               </span>
             </template>
             <template #action="scope">
@@ -111,11 +135,12 @@
   import { useRouter } from 'vue-router';
   import type { QueryPageRequest } from '@/types/basic-query';
   import {
-    queryAcademyFilePage,
-    deleteAcademyFile,
-    exportAcademyFile,
-    type ProductionSafetyFileQuery,
-  } from '@/api/production-safety-system';
+    queryHiddenDangerPage,
+    deleteHiddenDanger,
+    exportHiddenDanger,
+    type QueryHiddenDangerReq,
+    type HiddenDanger,
+  } from '@/api/production-safety';
   import { downloadByData } from '@/utils/file/download';
   import BatchImport from '@/components/batch-import/BatchImport.vue';
   import { useGlobSetting } from '@/hooks/setting';
@@ -128,20 +153,24 @@
 
   const { tableConfig, pagination } = useTableConfig(INVENTORY_TABLE_COLUMNS, TABLE_OPTIONS);
 
-  const tableData = ref<any[]>([]);
+  const tableData = ref<HiddenDanger[]>([]);
 
-  const tableQuery = reactive<QueryPageRequest<ProductionSafetyFileQuery>>({
+  const tableQuery = reactive<QueryPageRequest<QueryHiddenDangerReq>>({
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
     queryParam: {
-      keyword: '', // 文件名称/编号(模糊查询)
-      status: 1, // 状态:1-启用,0-禁用
-      classifyName: '', // 分类名称:外部院级文件/内部院级文件
-      startDate: '', // 上传日期范围-开始日期
-      endDate: '', // 上传日期范围-结束日期
+      keyword: '',
+      dangerType: undefined,
+      dangerLevel: undefined,
+      status: undefined,
+      startDate: '',
+      endDate: '',
     },
   });
 
+  // 上报日期范围(用于双向绑定日期组件)
+  const reportDateRange = ref<[string, string] | []>([]);
+
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     tableQuery.pageSize = value;
@@ -158,24 +187,22 @@
   async function getTableData() {
     tableConfig.loading = true;
     try {
-      const res = await queryAcademyFilePage(tableQuery);
+      // 将日期范围同步到查询参数
+      if (reportDateRange.value && reportDateRange.value.length === 2) {
+        tableQuery.queryParam.startDate = reportDateRange.value[0];
+        tableQuery.queryParam.endDate = reportDateRange.value[1];
+      } else {
+        tableQuery.queryParam.startDate = '';
+        tableQuery.queryParam.endDate = '';
+      }
+
+      const res = await queryHiddenDangerPage(tableQuery);
       if (res) {
-        // 映射返回数据字段到表格字段
-        tableData.value = res.records.map((item) => ({
-          id: item.id,
-          fileName: item.fileName, // 文件名称
-          fileCode: item.fileCode, // 文件编号
-          classifyName: item.classifyName, // 分类名称
-          fileVersion: item.fileVersion, // 文件版本号
-          fileFormat: item.fileFormat, // 文件格式
-          releaseDate: item.releaseDate, // 发布日期
-          status: item.status, // 状态:1-启用,0-禁用
-          uploadTime: item.uploadTime || item.createdAt, // 上传时间
-        }));
-        pagination.total = res.total || 0;
+        tableData.value = res.records || [];
+        pagination.total = res.totalRow || 0;
       }
     } catch (e) {
-      console.error('获取院级文件列表失败:', e);
+      console.error('获取隐患上报列表失败:', e);
       tableData.value = [];
       pagination.total = 0;
     } finally {
@@ -191,18 +218,20 @@
 
   const handleReset = () => {
     tableQuery.queryParam.keyword = '';
+    tableQuery.queryParam.dangerType = undefined;
+    tableQuery.queryParam.dangerLevel = undefined;
     tableQuery.queryParam.status = undefined;
-    tableQuery.queryParam.classifyName = '';
     tableQuery.queryParam.startDate = '';
     tableQuery.queryParam.endDate = '';
+    reportDateRange.value = [];
     handleSearch();
   };
 
   // 批量导入
   const batchImportVisible = ref(false);
   const { urlPrefix } = useGlobSetting();
-  const importApiUrl = ref(urlJoin(urlPrefix, '/productionSafety/academyFile/import'));
-  const templateUrl = ref('./skyeye-file-upload/sfysecurity/TEMPLATE/import-academy-file-template.xlsx');
+  const importApiUrl = ref(urlJoin(urlPrefix, '/admin/prod/hiddenDanger/importHiddenDanger'));
+  const templateUrl = ref('');
 
   const handleImport = () => {
     batchImportVisible.value = true;
@@ -215,21 +244,22 @@
 
   const handleDownload = async () => {
     try {
-      const exportParams: ProductionSafetyFileQuery = {
+      const exportParams: QueryHiddenDangerReq = {
         keyword: tableQuery.queryParam.keyword || undefined,
+        dangerType: tableQuery.queryParam.dangerType,
+        dangerLevel: tableQuery.queryParam.dangerLevel,
         status: tableQuery.queryParam.status,
-        classifyName: tableQuery.queryParam.classifyName || undefined,
         startDate: tableQuery.queryParam.startDate || undefined,
         endDate: tableQuery.queryParam.endDate || undefined,
       };
-      const response = await exportAcademyFile(exportParams);
+      const response = await exportHiddenDanger(exportParams);
       if (response) {
-        const fileName = `院级文件管理_${new Date().toISOString().split('T')[0]}.xlsx`;
+        const fileName = `员工上报隐患管理_${new Date().toISOString().split('T')[0]}.xlsx`;
         downloadByData(response, fileName);
         ElMessage.success('导出成功');
       }
     } catch (e) {
-      console.error('导出院级文件失败:', e);
+      console.error('导出隐患上报失败:', e);
       ElMessage.error('导出失败,请重试');
     }
   };
@@ -255,11 +285,11 @@
 
   const handleDelete = async (id: number) => {
     try {
-      await deleteAcademyFile(id);
+      await deleteHiddenDanger(id);
       ElMessage.success('删除成功');
       getTableData();
     } catch (e) {
-      console.error('删除院级文件失败:', e);
+      console.error('删除隐患上报失败:', e);
       ElMessage.error('删除失败,请重试');
     }
   };

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

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 17 - 146
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/components/hiddenTroubleCategoryManagementDetail.vue

@@ -6,39 +6,6 @@
       :formRules="isViewMode ? undefined : formRules"
       :formConfig="computedFormConfig"
     >
-      <template #fileFormat>
-        <el-radio-group v-model="ruleFormData.fileFormat" :disabled="isViewMode">
-          <el-radio value="PDF">PDF</el-radio>
-          <el-radio value="WORD">WORD</el-radio>
-        </el-radio-group>
-      </template>
-      <template #fileUrl>
-        <UploadFiles
-          v-if="!isViewMode"
-          label="上传文件"
-          :maxCount="1"
-          :fileList="uploadFileList"
-          @uploadSuccess="handleUploadSuccess"
-        />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
-      </template>
-      <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
-          <Editor
-            style="height: 400px; overflow-y: auto"
-            v-model="ruleFormData.content"
-            mode="default"
-            :defaultConfig="editorConfig"
-            @on-created="handleEditorCreated"
-            @on-change="handleEditorChange"
-          />
-        </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
-      </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
           <el-radio :value="1">启用</el-radio>
@@ -56,22 +23,17 @@
 </template>
 
 <script setup lang="ts">
-  import { computed, onMounted, ref, shallowRef, onBeforeUnmount } from 'vue';
+  import { computed, onMounted, ref } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import BasicForm from '@/components/BasicForm.vue';
-  import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
-  import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
-  import '@wangeditor/editor/dist/css/style.css';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { ACADEMY_FILE_FORM_CONFIG, ACADEMY_FILE_FORM_DATA, ACADEMY_FILE_FORM_RULES } from '../configs/form';
   import {
-    queryAcademyFileById,
-    saveAcademyFile,
-    updateAcademyFile,
-    type ProductionSafetyFile,
-  } from '@/api/production-safety-system';
-  import type { FileItem } from '@/components/UploadFiles/types';
+    queryDangerTypeById,
+    saveDangerType,
+    updateDangerType,
+  } from '@/api/production-safety';
 
   const router = useRouter();
   const route = useRoute();
@@ -105,39 +67,6 @@
   });
 
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
-  
-  // 富文本编辑器
-  const editorRef = shallowRef();
-  const editorConfig = {
-    placeholder: '请输入文档内容',
-    MENU_CONF: {},
-  };
-
-  const handleEditorCreated = (editor: any) => {
-    editorRef.value = editor;
-  };
-
-  const handleEditorChange = () => {
-    // 编辑器内容变化时的处理
-  };
-
-  // 文件上传
-  const uploadFileList = ref<FileItem[]>([]);
-
-  const handleUploadSuccess = (files: FileItem[]) => {
-    uploadFileList.value = files;
-    if (files.length > 0 && files[0].file) {
-      // 这里需要实际上传文件到服务器,获取 fileUrl
-      // 暂时使用文件对象,实际应该调用上传接口
-      ruleFormData.fileUrl = files[0].file.name; // 临时处理,需要替换为实际上传后的URL
-    }
-  };
-
-  const getFileName = (url: string) => {
-    if (!url) return '';
-    const parts = url.split('/');
-    return parts[parts.length - 1];
-  };
 
   const handleValidate = async () => {
     if (!basicFormRef.value) return;
@@ -148,34 +77,16 @@
   const getDetail = async () => {
     if (!currentId.value) return;
     try {
-      const res = await queryAcademyFileById(currentId.value);
+      const res = await queryDangerTypeById(currentId.value);
       if (res) {
-        // 映射接口字段到表单字段
-        ruleFormData.fileName = res.fileName || '';
-        ruleFormData.classifyName = res.classifyName || '';
-        ruleFormData.fileCode = res.fileCode || '';
-        ruleFormData.fileVersion = res.fileVersion || '';
-        ruleFormData.fileFormat = res.fileFormat || '';
-        ruleFormData.releaseDate = res.releaseDate || '';
-        ruleFormData.fileUrl = res.fileUrl || '';
-        ruleFormData.content = res.content || '';
+        ruleFormData.typeName = res.typeName || '';
+        ruleFormData.parentId = (res.parentId ?? undefined) as number | undefined;
+        ruleFormData.sort = res.sort ?? 0;
         ruleFormData.status = res.status ?? 1;
-        
-        // 如果有文件URL,转换为FileItem格式
-        if (res.fileUrl) {
-          uploadFileList.value = [
-            {
-              fileId: Date.now(),
-              fileName: getFileName(res.fileUrl),
-              fileType: res.fileFormat?.toLowerCase() === 'pdf' ? 'pdf' : 'word',
-              fileSize: '0KB',
-            },
-          ];
-        }
       }
       cloneRuleFormData();
     } catch (e) {
-      console.error('获取院级文件详情失败:', e);
+      console.error('获取隐患类别详情失败:', e);
       ElMessage.error('获取详情失败');
     }
   };
@@ -184,23 +95,18 @@
     const res = await handleValidate();
     if (!res) return;
     try {
-      const basePayload: ProductionSafetyFile = {
-        fileName: ruleFormData.fileName,
-        classifyName: ruleFormData.classifyName,
-        fileCode: ruleFormData.fileCode,
-        fileVersion: ruleFormData.fileVersion,
-        fileFormat: ruleFormData.fileFormat,
-        releaseDate: ruleFormData.releaseDate,
-        fileUrl: ruleFormData.fileUrl || undefined,
-        content: ruleFormData.content || undefined,
+      const basePayload = {
+        typeName: ruleFormData.typeName,
+        parentId: ruleFormData.parentId ?? null,
+        sort: Number(ruleFormData.sort ?? 0),
         status: ruleFormData.status ?? 1,
       };
 
       if (isCreateMode.value) {
-        await saveAcademyFile(basePayload);
+        await saveDangerType(basePayload);
         ElMessage.success('创建成功');
       } else if (isEditMode.value && currentId.value) {
-        await updateAcademyFile({
+        await updateDangerType({
           id: currentId.value,
           ...basePayload,
         });
@@ -209,7 +115,7 @@
 
       router.back();
     } catch (e) {
-      console.error('保存院级文件失败:', e);
+      console.error('保存隐患类别失败:', e);
       ElMessage.error('保存失败,请重试');
     }
   };
@@ -221,44 +127,9 @@
       getDetail();
     }
   });
-
-  onBeforeUnmount(() => {
-    const editor = editorRef.value;
-    if (editor == null) return;
-    editor.destroy();
-  });
 </script>
 
 <style scoped lang="scss">
   @use '@/styles/page-details-layout.scss' as *;
-
-  .editor-container {
-    width: 100%;
-    border: 1px solid #dcdfe6;
-    border-radius: 4px;
-    overflow: hidden;
-  }
-
-  .content-display {
-    min-height: 200px;
-    padding: 12px;
-    border: 1px solid #dcdfe6;
-    border-radius: 4px;
-    background-color: #f5f7fa;
-  }
-
-  .file-display {
-    .file-link {
-      color: #409eff;
-      text-decoration: none;
-      &:hover {
-        text-decoration: underline;
-      }
-    }
-  }
-
-  .no-file {
-    color: rgba(0, 0, 0, 0.65);
-  }
 </style>
 

+ 18 - 61
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/configs/form.ts

@@ -1,91 +1,48 @@
 import { FormConfig } from '@/types/basic-form';
 
+// 隐患类别管理表单配置
 export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
   {
-    prop: 'fileName',
-    label: '文件名称:',
+    prop: 'typeName',
+    label: '类别名称:',
     component: 'ElInput',
     componentProps: {
-      placeholder: '请输入文件名称',
+      placeholder: '请输入类别名称',
     },
   },
   {
-    prop: 'classifyName',
-    label: '分类名称:',
-    component: 'ElSelect',
-    componentProps: {
-      placeholder: '请选择分类名称',
-    },
-    options: [
-      { label: '外部院级文件', value: '外部院级文件' },
-      { label: '内部院级文件', value: '内部院级文件' },
-    ],
-  },
-  {
-    prop: 'fileCode',
-    label: '文件编号:',
+    prop: 'parentId',
+    label: '父级ID:',
     component: 'ElInput',
     componentProps: {
-      placeholder: '请输入文件编号',
+      placeholder: '请输入父级ID,顶级留空',
+      type: 'number',
     },
   },
   {
-    prop: 'fileVersion',
-    label: '文件版本号:',
+    prop: 'sort',
+    label: '排序:',
     component: 'ElInput',
     componentProps: {
-      placeholder: '请输入文件版本号,如:V1.0',
+      placeholder: '请输入排序数字',
+      type: 'number',
     },
   },
-  {
-    prop: 'fileFormat',
-    label: '文件格式:',
-    slot: 'fileFormat',
-  },
-  {
-    prop: 'releaseDate',
-    label: '发布日期:',
-    component: 'ElDatePicker',
-    componentProps: {
-      type: 'date',
-      placeholder: '请选择发布日期',
-      valueFormat: 'YYYY-MM-DD',
-    },
-  },
-  {
-    prop: 'fileUrl',
-    label: '文件上传:',
-    slot: 'fileUrl',
-  },
-  {
-    prop: 'content',
-    label: '文档内容:',
-    slot: 'content',
-  },
   {
     prop: 'status',
-    label: '状态:',
+    label: '启用状态:',
     slot: 'status',
   },
 ];
 
 export const ACADEMY_FILE_FORM_DATA = {
-  fileName: '',
-  classifyName: '',
-  fileCode: '',
-  fileVersion: '',
-  fileFormat: '',
-  releaseDate: '',
-  fileUrl: '',
-  content: '',
+  typeName: '',
+  parentId: undefined as number | undefined,
+  sort: 0,
   status: 1, // 默认启用
 };
 
 export const ACADEMY_FILE_FORM_RULES = {
-  fileName: [{ required: true, message: '请输入文件名称', trigger: 'blur' }],
-  classifyName: [{ required: true, message: '请选择分类名称', trigger: 'change' }],
-  fileCode: [{ required: true, message: '请输入文件编号', trigger: 'blur' }],
-  fileVersion: [{ required: true, message: '请输入文件版本号', trigger: 'blur' }],
-  fileFormat: [{ required: true, message: '请选择文件格式', trigger: 'change' }],
-  releaseDate: [{ required: true, message: '请选择发布日期', trigger: 'change' }],
+  typeName: [{ required: true, message: '请输入类别名称', trigger: 'blur' }],
 };
+

+ 20 - 24
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/configs/tables.ts

@@ -7,56 +7,52 @@ export const TABLE_OPTIONS = {
   maxHeight: 'calc(70vh - 150px)',
 };
 
+// 隐患类别管理表格列
 export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
   {
-    label: '号',
+    label: '号',
     type: 'index',
     align: 'center',
     width: '80px',
   },
   {
-    label: '物品名称',
-    prop: 'itemName',
+    label: '类别名称',
+    prop: 'typeName',
     align: 'left',
-    minWidth: '120px',
+    minWidth: '160px',
   },
   {
-    label: '入库日期',
-    prop: 'warehouseDate',
+    label: '父级类别',
+    prop: 'parentName',
     align: 'left',
-    minWidth: '120px',
+    minWidth: '160px',
   },
   {
-    label: '物品数量',
-    prop: 'itemQuantity',
+    label: '排序',
+    prop: 'sort',
     align: 'center',
-    minWidth: '120px',
-  },
-  {
-    label: '经办人',
-    prop: 'handler',
-    align: 'left',
-    minWidth: '120px',
-  },
-  {
-    label: '备注',
-    prop: 'remarks',
-    align: 'left',
-    minWidth: '150px',
+    minWidth: '100px',
   },
   {
     label: '状态',
     prop: 'status',
     slot: 'status',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '120px',
+  },
+  {
+    label: '创建时间',
+    prop: 'createdAt',
+    align: 'left',
+    minWidth: '180px',
   },
   {
     label: '操作',
     prop: 'action',
     slot: 'action',
     fixed: 'right',
-    width: '180px',
+    width: '200px',
     align: 'left',
   },
 ];
+

+ 29 - 56
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleCategoryManagement/hiddenTroubleCategoryManagement.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="safety-platform-container">
     <header class="safety-platform-container__header">
-      <div class="breadcrumb-title"> 院级文件管理 </div>
+      <div class="breadcrumb-title"> 隐患类别管理 </div>
     </header>
     <main class="safety-platform-container__main">
       <div class="search-table-container">
         <header>
           <div style="position: relative">
             <el-button type="primary" class="search-table-container--button" @click="handleCreate">
-              添加
+              新增
             </el-button>
             <el-button plain class="search-table-container--button" @click="handleImport">
               导入
@@ -21,24 +21,13 @@
           <div class="act-search">
             <section class="select-box">
               <div class="select-box--item">
-                <span>文件名称/编号:</span>
+                <span>关键字:</span>
                 <el-input
                   v-model="tableQuery.queryParam.keyword"
-                  placeholder="搜索文件名称或编号"
+                  placeholder="类别名称"
                   class="act-search-input"
                 />
               </div>
-              <div class="select-box--item">
-                <span>分类:</span>
-                <el-select
-                  v-model="tableQuery.queryParam.classifyName"
-                  placeholder="请选择分类"
-                  clearable
-                >
-                  <el-option label="外部院级文件" value="外部院级文件" />
-                  <el-option label="内部院级文件" value="内部院级文件" />
-                </el-select>
-              </div>
               <div class="select-box--item">
                 <span>状态:</span>
                 <el-select
@@ -111,11 +100,12 @@
   import { useRouter } from 'vue-router';
   import type { QueryPageRequest } from '@/types/basic-query';
   import {
-    queryAcademyFilePage,
-    deleteAcademyFile,
-    exportAcademyFile,
-    type ProductionSafetyFileQuery,
-  } from '@/api/production-safety-system';
+    queryDangerTypePage,
+    deleteDangerType,
+    exportDangerType,
+    type QueryDangerTypeReq,
+    type DangerType,
+  } from '@/api/production-safety';
   import { downloadByData } from '@/utils/file/download';
   import BatchImport from '@/components/batch-import/BatchImport.vue';
   import { useGlobSetting } from '@/hooks/setting';
@@ -128,17 +118,15 @@
 
   const { tableConfig, pagination } = useTableConfig(INVENTORY_TABLE_COLUMNS, TABLE_OPTIONS);
 
-  const tableData = ref<any[]>([]);
+  const tableData = ref<DangerType[]>([]);
 
-  const tableQuery = reactive<QueryPageRequest<ProductionSafetyFileQuery>>({
+  const tableQuery = reactive<QueryPageRequest<QueryDangerTypeReq>>({
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
     queryParam: {
-      keyword: '', // 文件名称/编号(模糊查询)
-      status: 1, // 状态:1-启用,0-禁用
-      classifyName: '', // 分类名称:外部院级文件/内部院级文件
-      startDate: '', // 上传日期范围-开始日期
-      endDate: '', // 上传日期范围-结束日期
+      keyword: '',
+      parentId: undefined,
+      status: undefined,
     },
   });
 
@@ -158,24 +146,13 @@
   async function getTableData() {
     tableConfig.loading = true;
     try {
-      const res = await queryAcademyFilePage(tableQuery);
+      const res = await queryDangerTypePage(tableQuery);
       if (res) {
-        // 映射返回数据字段到表格字段
-        tableData.value = res.records.map((item) => ({
-          id: item.id,
-          fileName: item.fileName, // 文件名称
-          fileCode: item.fileCode, // 文件编号
-          classifyName: item.classifyName, // 分类名称
-          fileVersion: item.fileVersion, // 文件版本号
-          fileFormat: item.fileFormat, // 文件格式
-          releaseDate: item.releaseDate, // 发布日期
-          status: item.status, // 状态:1-启用,0-禁用
-          uploadTime: item.uploadTime || item.createdAt, // 上传时间
-        }));
-        pagination.total = res.total || 0;
+        tableData.value = res.records || [];
+        pagination.total = res.totalRow || 0;
       }
     } catch (e) {
-      console.error('获取院级文件列表失败:', e);
+      console.error('获取隐患类别列表失败:', e);
       tableData.value = [];
       pagination.total = 0;
     } finally {
@@ -192,17 +169,15 @@
   const handleReset = () => {
     tableQuery.queryParam.keyword = '';
     tableQuery.queryParam.status = undefined;
-    tableQuery.queryParam.classifyName = '';
-    tableQuery.queryParam.startDate = '';
-    tableQuery.queryParam.endDate = '';
+    tableQuery.queryParam.parentId = undefined;
     handleSearch();
   };
 
   // 批量导入
   const batchImportVisible = ref(false);
   const { urlPrefix } = useGlobSetting();
-  const importApiUrl = ref(urlJoin(urlPrefix, '/productionSafety/academyFile/import'));
-  const templateUrl = ref('./skyeye-file-upload/sfysecurity/TEMPLATE/import-academy-file-template.xlsx');
+  const importApiUrl = ref(urlJoin(urlPrefix, '/admin/prod/dangerType/importDangerType'));
+  const templateUrl = ref('');
 
   const handleImport = () => {
     batchImportVisible.value = true;
@@ -215,21 +190,19 @@
 
   const handleDownload = async () => {
     try {
-      const exportParams: ProductionSafetyFileQuery = {
+      const exportParams: QueryDangerTypeReq = {
         keyword: tableQuery.queryParam.keyword || undefined,
         status: tableQuery.queryParam.status,
-        classifyName: tableQuery.queryParam.classifyName || undefined,
-        startDate: tableQuery.queryParam.startDate || undefined,
-        endDate: tableQuery.queryParam.endDate || undefined,
+        parentId: tableQuery.queryParam.parentId,
       };
-      const response = await exportAcademyFile(exportParams);
+      const response = await exportDangerType(exportParams);
       if (response) {
-        const fileName = `院级文件管理_${new Date().toISOString().split('T')[0]}.xlsx`;
+        const fileName = `隐患类别管理_${new Date().toISOString().split('T')[0]}.xlsx`;
         downloadByData(response, fileName);
         ElMessage.success('导出成功');
       }
     } catch (e) {
-      console.error('导出院级文件失败:', e);
+      console.error('导出隐患类别失败:', e);
       ElMessage.error('导出失败,请重试');
     }
   };
@@ -255,11 +228,11 @@
 
   const handleDelete = async (id: number) => {
     try {
-      await deleteAcademyFile(id);
+      await deleteDangerType(id);
       ElMessage.success('删除成功');
       getTableData();
     } catch (e) {
-      console.error('删除院级文件失败:', e);
+      console.error('删除隐患类别失败:', e);
       ElMessage.error('删除失败,请重试');
     }
   };

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleReviewManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagementDept/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 31 - 12
src/views/production-safety/productionSafetySystem/collegeFileManagement/collegeFileManagement.vue

@@ -53,19 +53,13 @@
               <div class="select-box--item">
                 <span>上传日期范围:</span>
                 <el-date-picker
-                  v-model="queryParams.startDate"
-                  type="date"
+                  v-model="uploadDateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
                   value-format="YYYY-MM-DD"
-                  placeholder="开始日期"
-                  style="width: 130px"
-                />
-                <span style="margin: 0 4px">至</span>
-                <el-date-picker
-                  v-model="queryParams.endDate"
-                  type="date"
-                  value-format="YYYY-MM-DD"
-                  placeholder="结束日期"
-                  style="width: 130px"
+                  format="YYYY-MM-DD"
                 />
               </div>
             </section>
@@ -100,6 +94,7 @@
                   @confirm="handleDelete(scope.row.id)"
                 />
                 <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <ActionButton text="下载" @click="handleDownloadFile(scope.row)" />
               </div>
             </template>
           </BasicTable>
@@ -156,6 +151,9 @@
     endDate: '', // 上传日期范围-结束日期
   });
 
+  // 上传日期范围(用于日期选择器)
+  const uploadDateRange = ref<[string, string] | null>(null);
+
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     getTableData();
@@ -193,6 +191,7 @@
           fileFormat: item.fileFormat, // 文件格式
           releaseDate: item.releaseDate, // 发布日期
           status: item.status, // 状态:1-启用,0-禁用
+          fileUrl: item.fileUrl, // 文件地址
           uploadTime: item.uploadTime || item.createdAt, // 上传时间
         }));
         pagination.total = res.totalRow || 0;
@@ -207,6 +206,15 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (uploadDateRange.value && uploadDateRange.value.length === 2) {
+      queryParams.startDate = uploadDateRange.value[0];
+      queryParams.endDate = uploadDateRange.value[1];
+    } else {
+      queryParams.startDate = '';
+      queryParams.endDate = '';
+    }
+
     pagination.pageNumber = 1;
     getTableData();
   };
@@ -217,6 +225,7 @@
     queryParams.classifyName = '';
     queryParams.startDate = '';
     queryParams.endDate = '';
+    uploadDateRange.value = null;
     handleSearch();
   };
 
@@ -256,6 +265,16 @@
     }
   };
 
+  // 文件下载
+  const handleDownloadFile = (row: any) => {
+    const url = row?.fileUrl;
+    if (!url) {
+      ElMessage.warning('暂无文件可下载');
+      return;
+    }
+    window.open(url, '_blank');
+  };
+
   const handleCreate = () => {
     router.push({
       name: 'CollegeFileManagementItem',

+ 7 - 10
src/views/production-safety/productionSafetySystem/collegeFileManagement/components/collegeFileManagementDetail.vue

@@ -14,20 +14,18 @@
       </template>
       <template #fileUrl>
         <UploadFiles
-          v-if="!isViewMode"
           label="上传文件"
           :maxCount="1"
           :fileList="uploadFileList"
           @uploadSuccess="handleUploadSuccess"
         />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
       </template>
       <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
+        <div class="editor-container">
+          <Toolbar 
+            style="border-bottom: 1px solid #dcdfe6" 
+            :editor="editorRef" 
+          />
           <Editor
             style="height: 400px; overflow-y: auto"
             v-model="ruleFormData.content"
@@ -37,7 +35,6 @@
             @on-change="handleEditorChange"
           />
         </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
       </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
@@ -108,10 +105,10 @@
   
   // 富文本编辑器
   const editorRef = shallowRef();
-  const editorConfig = {
+  const editorConfig = computed(() => ({
     placeholder: '请输入文档内容',
     MENU_CONF: {},
-  };
+  }));
 
   const handleEditorCreated = (editor: any) => {
     editorRef.value = editor;

+ 1 - 1
src/views/production-safety/productionSafetySystem/collegeFileManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const ACADEMY_FILE_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部院级文件', value: '外部院级文件' },
       { label: '内部院级文件', value: '内部院级文件' },
     ],

+ 2 - 2
src/views/production-safety/productionSafetySystem/collegeFileManagement/configs/tables.ts

@@ -45,7 +45,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件版本号',
     prop: 'fileVersion',
     align: 'left',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '发布日期',
@@ -57,7 +57,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件格式',
     prop: 'fileFormat',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '上传时间',

+ 7 - 10
src/views/production-safety/productionSafetySystem/doubleSystemManagement/components/doubleSystemManagementDetail.vue

@@ -14,20 +14,18 @@
       </template>
       <template #fileUrl>
         <UploadFiles
-          v-if="!isViewMode"
           label="上传文件"
           :maxCount="1"
           :fileList="uploadFileList"
           @uploadSuccess="handleUploadSuccess"
         />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
       </template>
       <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
+        <div class="editor-container">
+          <Toolbar 
+            style="border-bottom: 1px solid #dcdfe6" 
+            :editor="editorRef" 
+          />
           <Editor
             style="height: 400px; overflow-y: auto"
             v-model="ruleFormData.content"
@@ -37,7 +35,6 @@
             @on-change="handleEditorChange"
           />
         </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
       </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
@@ -108,10 +105,10 @@
   
   // 富文本编辑器
   const editorRef = shallowRef();
-  const editorConfig = {
+  const editorConfig = computed(() => ({
     placeholder: '请输入文档内容',
     MENU_CONF: {},
-  };
+  }));
 
   const handleEditorCreated = (editor: any) => {
     editorRef.value = editor;

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

@@ -16,7 +16,7 @@ export const DUAL_SYSTEM_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部文件', value: '外部文件' },
       { label: '内部文件', value: '内部文件' },
     ],

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

@@ -45,7 +45,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件版本号',
     prop: 'fileVersion',
     align: 'left',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '发布日期',
@@ -57,7 +57,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件格式',
     prop: 'fileFormat',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '上传时间',

+ 30 - 12
src/views/production-safety/productionSafetySystem/doubleSystemManagement/doubleSystemManagement.vue

@@ -53,19 +53,13 @@
               <div class="select-box--item">
                 <span>上传日期范围:</span>
                 <el-date-picker
-                  v-model="queryParams.startDate"
-                  type="date"
+                  v-model="uploadDateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
                   value-format="YYYY-MM-DD"
-                  placeholder="开始日期"
-                  style="width: 130px"
-                />
-                <span style="margin: 0 4px">至</span>
-                <el-date-picker
-                  v-model="queryParams.endDate"
-                  type="date"
-                  value-format="YYYY-MM-DD"
-                  placeholder="结束日期"
-                  style="width: 130px"
+                  format="YYYY-MM-DD"
                 />
               </div>
             </section>
@@ -100,6 +94,7 @@
                   @confirm="handleDelete(scope.row.id)"
                 />
                 <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <ActionButton text="下载" @click="handleDownloadFile(scope.row)" />
               </div>
             </template>
           </BasicTable>
@@ -156,6 +151,9 @@
     endDate: '', // 上传日期范围-结束日期
   });
 
+  // 上传日期范围(用于日期选择器)
+  const uploadDateRange = ref<[string, string] | null>(null);
+
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     getTableData();
@@ -193,6 +191,7 @@
           fileFormat: item.fileFormat, // 文件格式
           releaseDate: item.releaseDate, // 发布日期
           status: item.status, // 状态:1-启用,0-禁用
+          fileUrl: item.fileUrl, // 文件地址
           uploadTime: item.uploadTime || item.createdAt, // 上传时间
         }));
         pagination.total = res.totalRow || 0;
@@ -207,6 +206,14 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (uploadDateRange.value && uploadDateRange.value.length === 2) {
+      queryParams.startDate = uploadDateRange.value[0];
+      queryParams.endDate = uploadDateRange.value[1];
+    } else {
+      queryParams.startDate = '';
+      queryParams.endDate = '';
+    }
     pagination.pageNumber = 1;
     getTableData();
   };
@@ -217,6 +224,7 @@
     queryParams.classifyName = '';
     queryParams.startDate = '';
     queryParams.endDate = '';
+    uploadDateRange.value = null;
     handleSearch();
   };
 
@@ -256,6 +264,16 @@
     }
   };
 
+  // 文件下载
+  const handleDownloadFile = (row: any) => {
+    const url = row?.fileUrl;
+    if (!url) {
+      ElMessage.warning('暂无文件可下载');
+      return;
+    }
+    window.open(url, '_blank');
+  };
+
   const handleCreate = () => {
     router.push({
       name: 'DoubleSystemManagementItem',

+ 7 - 10
src/views/production-safety/productionSafetySystem/lawManagement/components/lawManagementDetail.vue

@@ -14,20 +14,18 @@
       </template>
       <template #fileUrl>
         <UploadFiles
-          v-if="!isViewMode"
           label="上传文件"
           :maxCount="1"
           :fileList="uploadFileList"
           @uploadSuccess="handleUploadSuccess"
         />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
       </template>
       <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
+        <div class="editor-container">
+          <Toolbar 
+            style="border-bottom: 1px solid #dcdfe6" 
+            :editor="editorRef" 
+          />
           <Editor
             style="height: 400px; overflow-y: auto"
             v-model="ruleFormData.content"
@@ -37,7 +35,6 @@
             @on-change="handleEditorChange"
           />
         </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
       </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
@@ -108,10 +105,10 @@
   
   // 富文本编辑器
   const editorRef = shallowRef();
-  const editorConfig = {
+  const editorConfig = computed(() => ({
     placeholder: '请输入文档内容',
     MENU_CONF: {},
-  };
+  }));
 
   const handleEditorCreated = (editor: any) => {
     editorRef.value = editor;

+ 1 - 1
src/views/production-safety/productionSafetySystem/lawManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const LAW_REGULATION_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部法律法规', value: '外部法律法规' },
       { label: '内部法律法规', value: '内部法律法规' },
     ],

+ 2 - 2
src/views/production-safety/productionSafetySystem/lawManagement/configs/tables.ts

@@ -45,7 +45,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件版本号',
     prop: 'fileVersion',
     align: 'left',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '发布日期',
@@ -57,7 +57,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件格式',
     prop: 'fileFormat',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '上传时间',

+ 30 - 12
src/views/production-safety/productionSafetySystem/lawManagement/lawManagement.vue

@@ -53,19 +53,13 @@
               <div class="select-box--item">
                 <span>上传日期范围:</span>
                 <el-date-picker
-                  v-model="queryParams.startDate"
-                  type="date"
+                  v-model="uploadDateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
                   value-format="YYYY-MM-DD"
-                  placeholder="开始日期"
-                  style="width: 130px"
-                />
-                <span style="margin: 0 4px">至</span>
-                <el-date-picker
-                  v-model="queryParams.endDate"
-                  type="date"
-                  value-format="YYYY-MM-DD"
-                  placeholder="结束日期"
-                  style="width: 130px"
+                  format="YYYY-MM-DD"
                 />
               </div>
             </section>
@@ -100,6 +94,7 @@
                   @confirm="handleDelete(scope.row.id)"
                 />
                 <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <ActionButton text="下载" @click="handleDownloadFile(scope.row)" />
               </div>
             </template>
           </BasicTable>
@@ -156,6 +151,9 @@
     endDate: '', // 上传日期范围-结束日期
   });
 
+  // 上传日期范围(用于日期选择器)
+  const uploadDateRange = ref<[string, string] | null>(null);
+
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     getTableData();
@@ -193,6 +191,7 @@
           fileFormat: item.fileFormat, // 文件格式
           releaseDate: item.releaseDate, // 发布日期
           status: item.status, // 状态:1-启用,0-禁用
+          fileUrl: item.fileUrl, // 文件地址
           uploadTime: item.uploadTime || item.createdAt, // 上传时间
         }));
         pagination.total = res.totalRow || 0;
@@ -207,6 +206,14 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (uploadDateRange.value && uploadDateRange.value.length === 2) {
+      queryParams.startDate = uploadDateRange.value[0];
+      queryParams.endDate = uploadDateRange.value[1];
+    } else {
+      queryParams.startDate = '';
+      queryParams.endDate = '';
+    }
     pagination.pageNumber = 1;
     getTableData();
   };
@@ -217,6 +224,7 @@
     queryParams.classifyName = '';
     queryParams.startDate = '';
     queryParams.endDate = '';
+    uploadDateRange.value = null;
     handleSearch();
   };
 
@@ -256,6 +264,16 @@
     }
   };
 
+  // 文件下载
+  const handleDownloadFile = (row: any) => {
+    const url = row?.fileUrl;
+    if (!url) {
+      ElMessage.warning('暂无文件可下载');
+      return;
+    }
+    window.open(url, '_blank');
+  };
+
   const handleCreate = () => {
     router.push({
       name: 'LawManagementItem',

+ 7 - 10
src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/components/safetyStandardizationSystemManagementDetail.vue

@@ -14,20 +14,18 @@
       </template>
       <template #fileUrl>
         <UploadFiles
-          v-if="!isViewMode"
           label="上传文件"
           :maxCount="1"
           :fileList="uploadFileList"
           @uploadSuccess="handleUploadSuccess"
         />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
       </template>
       <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
+        <div class="editor-container">
+          <Toolbar 
+            style="border-bottom: 1px solid #dcdfe6" 
+            :editor="editorRef" 
+          />
           <Editor
             style="height: 400px; overflow-y: auto"
             v-model="ruleFormData.content"
@@ -37,7 +35,6 @@
             @on-change="handleEditorChange"
           />
         </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
       </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
@@ -116,10 +113,10 @@
   
   // 富文本编辑器
   const editorRef = shallowRef();
-  const editorConfig = {
+  const editorConfig = computed(() => ({
     placeholder: '请输入文档内容',
     MENU_CONF: {},
-  };
+  }));
 
   const handleEditorCreated = (editor: any) => {
     editorRef.value = editor;

+ 1 - 1
src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/configs/form.ts

@@ -16,7 +16,7 @@ export const SAFETY_STANDARDIZATION_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部文件', value: '外部文件' },
       { label: '内部文件', value: '内部文件' },
     ],

+ 2 - 2
src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/configs/tables.ts

@@ -45,7 +45,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件版本号',
     prop: 'fileVersion',
     align: 'left',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '发布日期',
@@ -57,7 +57,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件格式',
     prop: 'fileFormat',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '上传时间',

+ 30 - 12
src/views/production-safety/productionSafetySystem/safetyStandardizationSystemManagement/safetyStandardizationSystemManagement.vue

@@ -53,19 +53,13 @@
               <div class="select-box--item">
                 <span>上传日期范围:</span>
                 <el-date-picker
-                  v-model="queryParams.startDate"
-                  type="date"
+                  v-model="uploadDateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
                   value-format="YYYY-MM-DD"
-                  placeholder="开始日期"
-                  style="width: 130px"
-                />
-                <span style="margin: 0 4px">至</span>
-                <el-date-picker
-                  v-model="queryParams.endDate"
-                  type="date"
-                  value-format="YYYY-MM-DD"
-                  placeholder="结束日期"
-                  style="width: 130px"
+                  format="YYYY-MM-DD"
                 />
               </div>
             </section>
@@ -100,6 +94,7 @@
                   @confirm="handleDelete(scope.row.id)"
                 />
                 <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <ActionButton text="下载" @click="handleDownloadFile(scope.row)" />
               </div>
             </template>
           </BasicTable>
@@ -156,6 +151,9 @@
     endDate: '', // 上传日期范围-结束日期
   });
 
+  // 上传日期范围(用于日期选择器)
+  const uploadDateRange = ref<[string, string] | null>(null);
+
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     getTableData();
@@ -193,6 +191,7 @@
           fileFormat: item.fileFormat, // 文件格式
           releaseDate: item.releaseDate, // 发布日期
           status: item.status, // 状态:1-启用,0-禁用
+          fileUrl: item.fileUrl, // 文件地址
           uploadTime: item.uploadTime || item.createdAt, // 上传时间
         }));
         pagination.total = res.totalRow || 0;
@@ -207,6 +206,14 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (uploadDateRange.value && uploadDateRange.value.length === 2) {
+      queryParams.startDate = uploadDateRange.value[0];
+      queryParams.endDate = uploadDateRange.value[1];
+    } else {
+      queryParams.startDate = '';
+      queryParams.endDate = '';
+    }
     pagination.pageNumber = 1;
     getTableData();
   };
@@ -217,6 +224,7 @@
     queryParams.classifyName = '';
     queryParams.startDate = '';
     queryParams.endDate = '';
+    uploadDateRange.value = null;
     handleSearch();
   };
 
@@ -256,6 +264,16 @@
     }
   };
 
+  // 文件下载
+  const handleDownloadFile = (row: any) => {
+    const url = row?.fileUrl;
+    if (!url) {
+      ElMessage.warning('暂无文件可下载');
+      return;
+    }
+    window.open(url, '_blank');
+  };
+
   const handleCreate = () => {
     router.push({
       name: 'SafetyStandardizationSystemManagementItem',

+ 45 - 21
src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagement/configs/tables.ts

@@ -7,7 +7,23 @@ export const TABLE_OPTIONS = {
   maxHeight: 'calc(70vh - 150px)',
 };
 
-export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
+// 状态选项
+export const WORK_PLAN_STATUS_OPTIONS = [
+  { label: '未下发', value: 0 },
+  { label: '进行中', value: 1 },
+  { label: '已完成', value: 2 },
+  { label: '已作废', value: 3 },
+];
+
+// 状态标签映射
+export const WORK_PLAN_STATUS_LABEL: Record<string, string> = {
+  '0': '未下发',
+  '1': '进行中',
+  '2': '已完成',
+  '3': '已作废',
+};
+
+export const WORK_PLAN_TABLE_COLUMNS: TableColumnProps[] = [
   {
     label: '编号',
     type: 'index',
@@ -15,48 +31,56 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     width: '80px',
   },
   {
-    label: '物品名称',
-    prop: 'itemName',
+    label: '工作内容',
+    prop: 'workContent',
     align: 'left',
-    minWidth: '120px',
+    minWidth: '150px',
+    showOverflowTooltip: true,
+  },
+  {
+    label: '状态',
+    prop: 'status',
+    slot: 'status',
+    align: 'center',
+    minWidth: '100px',
   },
   {
-    label: '入库日期',
-    prop: 'warehouseDate',
+    label: '分类名称',
+    prop: 'classifyName',
     align: 'left',
     minWidth: '120px',
   },
   {
-    label: '物品数量',
-    prop: 'itemQuantity',
-    align: 'center',
-    minWidth: '120px',
+    label: '培训计划名称',
+    prop: 'trainingPlanName',
+    align: 'left',
+    minWidth: '150px',
+    showOverflowTooltip: true,
   },
   {
-    label: '经办人',
-    prop: 'handler',
+    label: '责任部门',
+    prop: 'responsibleDept',
     align: 'left',
     minWidth: '120px',
   },
   {
-    label: '备注',
-    prop: 'remarks',
+    label: '配合部门',
+    prop: 'cooperateDept',
     align: 'left',
-    minWidth: '150px',
+    minWidth: '120px',
   },
   {
-    label: '状态',
-    prop: 'status',
-    slot: 'status',
-    align: 'center',
-    minWidth: '100px',
+    label: '计划完成时间',
+    prop: 'planCompleteTime',
+    align: 'left',
+    minWidth: '160px',
   },
   {
     label: '操作',
     prop: 'action',
     slot: 'action',
     fixed: 'right',
-    width: '180px',
+    width: '280px',
     align: 'left',
   },
 ];

+ 154 - 98
src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagement/safetySystemConstructionWorkPlanManagement.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="safety-platform-container">
     <header class="safety-platform-container__header">
-      <div class="breadcrumb-title"> 物品库存管理 </div>
+      <div class="breadcrumb-title"> 安全体系建设工作计划管理(管理员) </div>
     </header>
     <main class="safety-platform-container__main">
       <div class="search-table-container">
@@ -10,21 +10,15 @@
             <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 plain class="search-table-container--button" @click="handleDownload">
-              导出
-            </el-button>
           </div>
 
           <div class="act-search">
             <section class="select-box">
               <div class="select-box--item">
-                <span>物品名称:</span>
+                <span>工作内容/计划名称:</span>
                 <el-input
-                  v-model="tableQuery.queryParam.stuffName"
-                  placeholder="搜索物品名称"
+                  v-model="tableQuery.queryParam.keyword"
+                  placeholder="搜索工作内容或计划名称"
                   class="act-search-input"
                 />
               </div>
@@ -35,10 +29,42 @@
                   placeholder="请选择状态"
                   clearable
                 >
-                  <el-option label="启用" :value="true" />
-                  <el-option label="禁用" :value="false" />
+                  <el-option
+                    v-for="item in WORK_PLAN_STATUS_OPTIONS"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </div>
+              <div class="select-box--item">
+                <span>分类名称:</span>
+                <el-select
+                  v-model="tableQuery.queryParam.classifyName"
+                  placeholder="请选择分类名称"
+                  filterable
+                  clearable
+                >
+                  <el-option
+                    v-for="item in classifyNameOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
                 </el-select>
               </div>
+              <div>
+                <span>计划日期范围:</span>
+                <el-date-picker
+                  v-model="dateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                />
+              </div>
             </section>
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
@@ -57,36 +83,59 @@
           >
             <template #status="scope">
               <span>
-                {{ scope.row.statusName || (scope.row.status === true || scope.row.status === 'true' ? '启用' : scope.row.status === false || scope.row.status === 'false' ? '禁用' : '-') }}
+                {{ WORK_PLAN_STATUS_LABEL[String(scope.row.status)] || '-' }}
               </span>
             </template>
             <template #action="scope">
               <div class="action-container--div" style="justify-content: left">
-                <ActionButton text="编辑" @click="handleEdit(scope.row.id)" />
-                <ActionButton
-                  text="删除"
-                  :popconfirm="{
-                    title: '确定要删除?',
-                  }"
-                  @confirm="handleDelete(scope.row.id)"
-                />
-                <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <!-- 未下发(0):编辑、删除、查看发送对象、下发 -->
+                <template v-if="Number(scope.row.status) === 0">
+                  <ActionButton text="编辑" @click="handleEdit(scope.row.id)" />
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{
+                      title: '确定要删除?',
+                    }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
+                  <ActionButton text="查看发送对象" @click="handleViewRecipients(scope.row.id)" />
+                  <ActionButton text="下发" @click="handleIssue(scope.row.id)" />
+                </template>
+
+                <!-- 进行中(1)/待反馈:查看 -->
+                <template v-else-if="Number(scope.row.status) === 1">
+                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                </template>
+
+                <!-- 已完成(2):删除、查看 -->
+                <template v-else-if="Number(scope.row.status) === 2">
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{
+                      title: '确定要删除?',
+                    }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
+                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                </template>
+
+                <!-- 已作废(3):删除、查看 -->
+                <template v-else-if="Number(scope.row.status) === 3">
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{
+                      title: '确定要删除?',
+                    }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
+                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                </template>
               </div>
             </template>
           </BasicTable>
         </div>
       </div>
     </main>
-    <BatchImport
-      v-if="batchImportVisible"
-      :visible="batchImportVisible"
-      :import-api-url="importApiUrl"
-      :template-url="templateUrl"
-      template-name="下载模板"
-      :show-template="false"
-      @close="batchImportVisible = false"
-      @update="handleUpdate"
-    />
   </div>
 </template>
 
@@ -96,31 +145,39 @@
   import BasicTable from '@/components/BasicTable.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import ActionButton from '@/components/ActionButton.vue';
-  import { TABLE_OPTIONS, INVENTORY_TABLE_COLUMNS } from './configs/tables';
+  import { TABLE_OPTIONS, WORK_PLAN_TABLE_COLUMNS, WORK_PLAN_STATUS_OPTIONS, WORK_PLAN_STATUS_LABEL } from './configs/tables';
   import { useRouter } from 'vue-router';
   import type { QueryPageRequest } from '@/types/basic-query';
-  import { queryInventoryManage, deleteInventory, exportInventory } from '@/api/inventory';
-  import { downloadByData } from '@/utils/file/download';
-  import BatchImport from '@/components/batch-import/BatchImport.vue';
-  import { useGlobSetting } from '@/hooks/setting';
-  import urlJoin from 'url-join';
+  // TODO: 替换为实际的工作计划管理API
+  // import { queryWorkPlanPage, deleteWorkPlan, issueWorkPlan } from '@/api/workPlan';
 
   const router = useRouter();
 
   // 表格
   const basicTableRef = ref<InstanceType<typeof BasicTable>>();
 
-  const { tableConfig, pagination } = useTableConfig(INVENTORY_TABLE_COLUMNS, TABLE_OPTIONS);
+  const { tableConfig, pagination } = useTableConfig(WORK_PLAN_TABLE_COLUMNS, TABLE_OPTIONS);
 
   const tableData = ref<any[]>([]);
 
+  // 日期范围
+  const dateRange = ref<[string, string] | null>(null);
+
+  // 分类名称选项(TODO: 从接口获取或使用字典)
+  const classifyNameOptions = ref<Array<{ label: string; value: string }>>([
+    // { label: '分类1', value: '分类1' },
+    // { label: '分类2', value: '分类2' },
+  ]);
+
   const tableQuery = reactive<QueryPageRequest<any>>({
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
     queryParam: {
-      stuffName: '', // 物品名称
-      status: true, // 状态,默认启用
-      ids: [], // 选择数据的ID
+      keyword: '', // 工作内容/计划名称
+      status: undefined, // 状态
+      classifyName: '', // 分类名称
+      planStartTime: '', // 计划开始时间
+      planEndTime: '', // 计划结束时间
     },
   });
 
@@ -136,27 +193,31 @@
     getTableData();
   };
 
-
   async function getTableData() {
     tableConfig.loading = true;
     try {
-      const res = await queryInventoryManage(tableQuery);
-      if (res) {
-        // 映射返回数据字段到表格字段
-        tableData.value = res.records.map((item) => ({
-          id: item.id,
-          itemName: item.stuffName, // 物品名称
-          warehouseDate: item.inStoreTime, // 入库日期
-          itemQuantity: item.stuffQty, // 物品数量
-          handler: item.createdUserName, // 经办人
-          remarks: item.remark, // 备注
-          status: item.status, // 状态:true-启用,false-禁用
-          statusName: item.statusName, // 状态名称
-        }));
-        pagination.total = res.totalRow;
-      }
+      // TODO: 替换为实际的工作计划管理API调用
+      // const res = await queryWorkPlanPage(tableQuery);
+      // if (res) {
+      //   tableData.value = res.records.map((item) => ({
+      //     id: item.id,
+      //     workContent: item.workContent || item.planName, // 工作内容
+      //     status: item.status, // 状态
+      //     classifyName: item.classifyName, // 分类名称
+      //     trainingPlanName: item.trainingPlanName, // 培训计划名称
+      //     responsibleDept: item.responsibleDept, // 责任部门
+      //     cooperateDept: item.cooperateDept, // 配合部门
+      //     planCompleteTime: item.planCompleteTime, // 计划完成时间
+      //   }));
+      //   pagination.total = res.totalRow;
+      // }
+      
+      // 临时数据,用于测试
+      tableData.value = [];
+      pagination.total = 0;
     } catch (e) {
-      console.error('获取物品库存列表失败:', e);
+      console.error('获取工作计划列表失败:', e);
+      ElMessage.error('获取工作计划列表失败');
       tableData.value = [];
       pagination.total = 0;
     } finally {
@@ -165,52 +226,29 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (dateRange.value && dateRange.value.length === 2) {
+      tableQuery.queryParam.planStartTime = dateRange.value[0];
+      tableQuery.queryParam.planEndTime = dateRange.value[1];
+    } else {
+      tableQuery.queryParam.planStartTime = '';
+      tableQuery.queryParam.planEndTime = '';
+    }
     pagination.pageNumber = 1;
     tableQuery.pageNumber = 1;
     getTableData();
   };
 
   const handleReset = () => {
-    tableQuery.queryParam.stuffName = '';
-    tableQuery.queryParam.status = true; // 重置为默认启用状态
-    tableQuery.queryParam.ids = [];
+    tableQuery.queryParam.keyword = '';
+    tableQuery.queryParam.status = undefined;
+    tableQuery.queryParam.classifyName = '';
+    tableQuery.queryParam.planStartTime = '';
+    tableQuery.queryParam.planEndTime = '';
+    dateRange.value = null;
     handleSearch();
   };
 
-  // 批量导入
-  const batchImportVisible = ref(false);
-  const { urlPrefix } = useGlobSetting();
-  const importApiUrl = ref(urlJoin(urlPrefix, '/inventory/importInventory'));
-  const templateUrl = ref('./skyeye-file-upload/sfysecurity/TEMPLATE/import-inventory-template.xlsx');
-
-  const handleImport = () => {
-    batchImportVisible.value = true;
-  };
-
-  const handleUpdate = () => {
-    batchImportVisible.value = false;
-    getTableData();
-  };
-
-  const handleDownload = async () => {
-    try {
-      const exportParams = {
-        stuffName: tableQuery.queryParam.stuffName || undefined,
-        status: tableQuery.queryParam.status,
-        ids: tableQuery.queryParam.ids.length > 0 ? tableQuery.queryParam.ids : undefined,
-      };
-      const response = await exportInventory(exportParams);
-      if (response) {
-        const fileName = `物品库存管理_${new Date().toISOString().split('T')[0]}.xlsx`;
-        downloadByData(response, fileName);
-        ElMessage.success('导出成功');
-      }
-    } catch (e) {
-      console.error('导出物品库存失败:', e);
-      ElMessage.error('导出失败,请重试');
-    }
-  };
-
   const handleCreate = () => {
     router.push({
       name: 'SafetySystemConstructionWorkPlanManagementItem',
@@ -232,7 +270,8 @@
 
   const handleDelete = async (id: number) => {
     try {
-      await deleteInventory(id);
+      // TODO: 替换为实际的工作计划删除API
+      // await deleteWorkPlan(id);
       ElMessage.success('删除成功');
       getTableData();
     } catch (e) {
@@ -251,6 +290,23 @@
     });
   };
 
+  const handleViewRecipients = (id: number) => {
+    // TODO: 实现查看发送对象功能
+    ElMessage.info('查看发送对象功能待实现');
+  };
+
+  const handleIssue = async (id: number) => {
+    try {
+      // TODO: 替换为实际的工作计划下发API
+      // await issueWorkPlan(id);
+      ElMessage.success('下发成功');
+      getTableData();
+    } catch (e) {
+      console.error('下发工作计划失败:', e);
+      ElMessage.error('下发失败,请重试');
+    }
+  };
+
   onMounted(() => {
     getTableData();
   });
@@ -261,4 +317,4 @@
   @use '@/styles/page-main-layout.scss' as *;
   @use '@/styles/basic-table-action.scss' as *;
   @use '@/views/traffic/violation/style/act-search-table.scss' as *;
-</style>
+</style>

+ 45 - 21
src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagementDept/configs/tables.ts

@@ -7,7 +7,23 @@ export const TABLE_OPTIONS = {
   maxHeight: 'calc(70vh - 150px)',
 };
 
-export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
+// 状态选项
+export const WORK_PLAN_STATUS_OPTIONS = [
+  { label: '未下发', value: 0 },
+  { label: '进行中', value: 1 },
+  { label: '已完成', value: 2 },
+  { label: '已作废', value: 3 },
+];
+
+// 状态标签映射
+export const WORK_PLAN_STATUS_LABEL: Record<string, string> = {
+  '0': '未下发',
+  '1': '进行中',
+  '2': '已完成',
+  '3': '已作废',
+};
+
+export const WORK_PLAN_TABLE_COLUMNS: TableColumnProps[] = [
   {
     label: '编号',
     type: 'index',
@@ -15,48 +31,56 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     width: '80px',
   },
   {
-    label: '物品名称',
-    prop: 'itemName',
+    label: '工作内容',
+    prop: 'workContent',
     align: 'left',
-    minWidth: '120px',
+    minWidth: '150px',
+    showOverflowTooltip: true,
+  },
+  {
+    label: '状态',
+    prop: 'status',
+    slot: 'status',
+    align: 'center',
+    minWidth: '100px',
   },
   {
-    label: '入库日期',
-    prop: 'warehouseDate',
+    label: '分类名称',
+    prop: 'classifyName',
     align: 'left',
     minWidth: '120px',
   },
   {
-    label: '物品数量',
-    prop: 'itemQuantity',
-    align: 'center',
-    minWidth: '120px',
+    label: '培训计划名称',
+    prop: 'trainingPlanName',
+    align: 'left',
+    minWidth: '150px',
+    showOverflowTooltip: true,
   },
   {
-    label: '经办人',
-    prop: 'handler',
+    label: '责任部门',
+    prop: 'responsibleDept',
     align: 'left',
     minWidth: '120px',
   },
   {
-    label: '备注',
-    prop: 'remarks',
+    label: '配合部门',
+    prop: 'cooperateDept',
     align: 'left',
-    minWidth: '150px',
+    minWidth: '120px',
   },
   {
-    label: '状态',
-    prop: 'status',
-    slot: 'status',
-    align: 'center',
-    minWidth: '100px',
+    label: '计划完成时间',
+    prop: 'planCompleteTime',
+    align: 'left',
+    minWidth: '160px',
   },
   {
     label: '操作',
     prop: 'action',
     slot: 'action',
     fixed: 'right',
-    width: '180px',
+    width: '280px',
     align: 'left',
   },
 ];

+ 168 - 56
src/views/production-safety/productionSafetySystem/safetySystemConstructionWorkPlanManagementDept/safetySystemConstructionWorkPlanManagementDept.vue

@@ -1,24 +1,18 @@
 <template>
   <div class="safety-platform-container">
     <header class="safety-platform-container__header">
-      <div class="breadcrumb-title"> 物品库存管理 </div>
+      <div class="breadcrumb-title"> 安全体系建设工作计划管理(部门) </div>
     </header>
     <main class="safety-platform-container__main">
       <div class="search-table-container">
         <header>
-          <div style="position: relative">
-            <el-button plain class="search-table-container--button" @click="handleDownload">
-              导出
-            </el-button>
-          </div>
-
           <div class="act-search">
             <section class="select-box">
               <div class="select-box--item">
-                <span>物品名称:</span>
+                <span>工作内容/计划名称:</span>
                 <el-input
-                  v-model="tableQuery.queryParam.stuffName"
-                  placeholder="搜索物品名称"
+                  v-model="tableQuery.queryParam.keyword"
+                  placeholder="搜索工作内容或计划名称"
                   class="act-search-input"
                 />
               </div>
@@ -29,10 +23,42 @@
                   placeholder="请选择状态"
                   clearable
                 >
-                  <el-option label="启用" :value="true" />
-                  <el-option label="禁用" :value="false" />
+                  <el-option
+                    v-for="item in WORK_PLAN_STATUS_OPTIONS"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
                 </el-select>
               </div>
+              <div class="select-box--item">
+                <span>分类名称:</span>
+                <el-select
+                  v-model="tableQuery.queryParam.classifyName"
+                  placeholder="请选择分类名称"
+                  filterable
+                  clearable
+                >
+                  <el-option
+                    v-for="item in classifyNameOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </div>
+              <div>
+                <span>计划日期范围:</span>
+                <el-date-picker
+                  v-model="dateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                />
+              </div>
             </section>
             <section class="search-btn">
               <el-button type="primary" @click="handleSearch">查询</el-button>
@@ -51,12 +77,53 @@
           >
             <template #status="scope">
               <span>
-                {{ scope.row.statusName || (scope.row.status === true || scope.row.status === 'true' ? '启用' : scope.row.status === false || scope.row.status === 'false' ? '禁用' : '-') }}
+                {{ WORK_PLAN_STATUS_LABEL[String(scope.row.status)] || '-' }}
               </span>
             </template>
             <template #action="scope">
               <div class="action-container--div" style="justify-content: left">
-                <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <!-- 未下发(0):编辑、删除、查看发送对象、下发 -->
+                <template v-if="Number(scope.row.status) === 0">
+                  <ActionButton text="编辑" @click="handleEdit(scope.row.id)" />
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{
+                      title: '确定要删除?',
+                    }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
+                  <ActionButton text="查看发送对象" @click="handleViewRecipients(scope.row.id)" />
+                  <ActionButton text="下发" @click="handleIssue(scope.row.id)" />
+                </template>
+
+                <!-- 进行中(1)/待反馈:查看 -->
+                <template v-else-if="Number(scope.row.status) === 1">
+                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                </template>
+
+                <!-- 已完成(2):删除、查看 -->
+                <template v-else-if="Number(scope.row.status) === 2">
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{
+                      title: '确定要删除?',
+                    }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
+                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                </template>
+
+                <!-- 已作废(3):删除、查看 -->
+                <template v-else-if="Number(scope.row.status) === 3">
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{
+                      title: '确定要删除?',
+                    }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
+                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                </template>
               </div>
             </template>
           </BasicTable>
@@ -72,28 +139,39 @@
   import BasicTable from '@/components/BasicTable.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import ActionButton from '@/components/ActionButton.vue';
-  import { TABLE_OPTIONS, INVENTORY_TABLE_COLUMNS } from './configs/tables';
+  import { TABLE_OPTIONS, WORK_PLAN_TABLE_COLUMNS, WORK_PLAN_STATUS_OPTIONS, WORK_PLAN_STATUS_LABEL } from './configs/tables';
   import { useRouter } from 'vue-router';
   import type { QueryPageRequest } from '@/types/basic-query';
-  import { queryInventoryManage, exportInventory } from '@/api/inventory';
-  import { downloadByData } from '@/utils/file/download';
+  // TODO: 替换为实际的工作计划管理API
+  // import { queryWorkPlanDeptPage, deleteWorkPlan, issueWorkPlan } from '@/api/workPlan';
 
   const router = useRouter();
 
   // 表格
   const basicTableRef = ref<InstanceType<typeof BasicTable>>();
 
-  const { tableConfig, pagination } = useTableConfig(INVENTORY_TABLE_COLUMNS, TABLE_OPTIONS);
+  const { tableConfig, pagination } = useTableConfig(WORK_PLAN_TABLE_COLUMNS, TABLE_OPTIONS);
 
   const tableData = ref<any[]>([]);
 
+  // 日期范围
+  const dateRange = ref<[string, string] | null>(null);
+
+  // 分类名称选项(TODO: 从接口获取或使用字典)
+  const classifyNameOptions = ref<Array<{ label: string; value: string }>>([
+    // { label: '分类1', value: '分类1' },
+    // { label: '分类2', value: '分类2' },
+  ]);
+
   const tableQuery = reactive<QueryPageRequest<any>>({
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
     queryParam: {
-      stuffName: '', // 物品名称
-      status: true, // 状态,默认启用
-      ids: [], // 选择数据的ID
+      keyword: '', // 工作内容/计划名称
+      status: undefined, // 状态
+      classifyName: '', // 分类名称
+      planStartTime: '', // 计划开始时间
+      planEndTime: '', // 计划结束时间
     },
   });
 
@@ -109,27 +187,31 @@
     getTableData();
   };
 
-
   async function getTableData() {
     tableConfig.loading = true;
     try {
-      const res = await queryInventoryManage(tableQuery);
-      if (res) {
-        // 映射返回数据字段到表格字段
-        tableData.value = res.records.map((item) => ({
-          id: item.id,
-          itemName: item.stuffName, // 物品名称
-          warehouseDate: item.inStoreTime, // 入库日期
-          itemQuantity: item.stuffQty, // 物品数量
-          handler: item.createdUserName, // 经办人
-          remarks: item.remark, // 备注
-          status: item.status, // 状态:true-启用,false-禁用
-          statusName: item.statusName, // 状态名称
-        }));
-        pagination.total = res.totalRow;
-      }
+      // TODO: 替换为实际的工作计划管理API调用
+      // const res = await queryWorkPlanDeptPage(tableQuery);
+      // if (res) {
+      //   tableData.value = res.records.map((item) => ({
+      //     id: item.id,
+      //     workContent: item.workContent || item.planName, // 工作内容
+      //     status: item.status, // 状态
+      //     classifyName: item.classifyName, // 分类名称
+      //     trainingPlanName: item.trainingPlanName, // 培训计划名称
+      //     responsibleDept: item.responsibleDept, // 责任部门
+      //     cooperateDept: item.cooperateDept, // 配合部门
+      //     planCompleteTime: item.planCompleteTime, // 计划完成时间
+      //   }));
+      //   pagination.total = res.totalRow;
+      // }
+      
+      // 临时数据,用于测试
+      tableData.value = [];
+      pagination.total = 0;
     } catch (e) {
-      console.error('获取物品库存列表失败:', e);
+      console.error('获取工作计划列表失败:', e);
+      ElMessage.error('获取工作计划列表失败');
       tableData.value = [];
       pagination.total = 0;
     } finally {
@@ -138,35 +220,48 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (dateRange.value && dateRange.value.length === 2) {
+      tableQuery.queryParam.planStartTime = dateRange.value[0];
+      tableQuery.queryParam.planEndTime = dateRange.value[1];
+    } else {
+      tableQuery.queryParam.planStartTime = '';
+      tableQuery.queryParam.planEndTime = '';
+    }
     pagination.pageNumber = 1;
     tableQuery.pageNumber = 1;
     getTableData();
   };
 
   const handleReset = () => {
-    tableQuery.queryParam.stuffName = '';
-    tableQuery.queryParam.status = true; // 重置为默认启用状态
-    tableQuery.queryParam.ids = [];
+    tableQuery.queryParam.keyword = '';
+    tableQuery.queryParam.status = undefined;
+    tableQuery.queryParam.classifyName = '';
+    tableQuery.queryParam.planStartTime = '';
+    tableQuery.queryParam.planEndTime = '';
+    dateRange.value = null;
     handleSearch();
   };
 
+  const handleEdit = (id: number) => {
+    router.push({
+      name: 'SafetySystemConstructionWorkPlanManagementDeptItem',
+      query: {
+        id,
+        operate: 'work-plan-dept-edit',
+      },
+    });
+  };
 
-  const handleDownload = async () => {
+  const handleDelete = async (id: number) => {
     try {
-      const exportParams = {
-        stuffName: tableQuery.queryParam.stuffName || undefined,
-        status: tableQuery.queryParam.status,
-        ids: tableQuery.queryParam.ids.length > 0 ? tableQuery.queryParam.ids : undefined,
-      };
-      const response = await exportInventory(exportParams);
-      if (response) {
-        const fileName = `物品库存管理_${new Date().toISOString().split('T')[0]}.xlsx`;
-        downloadByData(response, fileName);
-        ElMessage.success('导出成功');
-      }
+      // TODO: 替换为实际的工作计划删除API
+      // await deleteWorkPlan(id);
+      ElMessage.success('删除成功');
+      getTableData();
     } catch (e) {
-      console.error('导出物品库存失败:', e);
-      ElMessage.error('导出失败,请重试');
+      console.error('删除工作计划失败:', e);
+      ElMessage.error('删除失败,请重试');
     }
   };
 
@@ -180,6 +275,23 @@
     });
   };
 
+  const handleViewRecipients = (id: number) => {
+    // TODO: 实现查看发送对象功能
+    ElMessage.info('查看发送对象功能待实现');
+  };
+
+  const handleIssue = async (id: number) => {
+    try {
+      // TODO: 替换为实际的工作计划下发API
+      // await issueWorkPlan(id);
+      ElMessage.success('下发成功');
+      getTableData();
+    } catch (e) {
+      console.error('下发工作计划失败:', e);
+      ElMessage.error('下发失败,请重试');
+    }
+  };
+
   onMounted(() => {
     getTableData();
   });
@@ -190,4 +302,4 @@
   @use '@/styles/page-main-layout.scss' as *;
   @use '@/styles/basic-table-action.scss' as *;
   @use '@/views/traffic/violation/style/act-search-table.scss' as *;
-</style>
+</style>

+ 7 - 10
src/views/production-safety/productionSafetySystem/safetyTraining/components/safetyTrainingDetail.vue

@@ -14,20 +14,18 @@
       </template>
       <template #fileUrl>
         <UploadFiles
-          v-if="!isViewMode"
           label="上传文件"
           :maxCount="1"
           :fileList="uploadFileList"
           @uploadSuccess="handleUploadSuccess"
         />
-        <div v-else-if="ruleFormData.fileUrl" class="file-display">
-          <a :href="ruleFormData.fileUrl" target="_blank" class="file-link">{{ getFileName(ruleFormData.fileUrl) }}</a>
-        </div>
-        <span v-else class="no-file">暂无文件</span>
       </template>
       <template #content>
-        <div v-if="!isViewMode" class="editor-container">
-          <Toolbar style="border-bottom: 1px solid #dcdfe6" :editor="editorRef" />
+        <div class="editor-container">
+          <Toolbar 
+            style="border-bottom: 1px solid #dcdfe6" 
+            :editor="editorRef" 
+          />
           <Editor
             style="height: 400px; overflow-y: auto"
             v-model="ruleFormData.content"
@@ -37,7 +35,6 @@
             @on-change="handleEditorChange"
           />
         </div>
-        <div v-else class="content-display" v-html="ruleFormData.content || '暂无内容'"></div>
       </template>
       <template #status>
         <el-radio-group v-model="ruleFormData.status" :disabled="isViewMode">
@@ -115,10 +112,10 @@
 
   // 富文本编辑器
   const editorRef = shallowRef();
-  const editorConfig = {
+  const editorConfig = computed(() => ({
     placeholder: '请输入文档内容',
     MENU_CONF: {},
-  };
+  }));
 
   const handleEditorCreated = (editor: any) => {
     editorRef.value = editor;

+ 1 - 1
src/views/production-safety/productionSafetySystem/safetyTraining/configs/form.ts

@@ -16,7 +16,7 @@ export const INDUSTRY_STANDARD_FORM_CONFIG: FormConfig[] = [
     componentProps: {
       placeholder: '请选择分类名称',
     },
-    options: [
+    selectOptions: [
       { label: '外部行业标准', value: '外部行业标准' },
       { label: '内部行业标准', value: '内部行业标准' },
     ],

+ 2 - 2
src/views/production-safety/productionSafetySystem/safetyTraining/configs/tables.ts

@@ -45,7 +45,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件版本号',
     prop: 'fileVersion',
     align: 'left',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '发布日期',
@@ -57,7 +57,7 @@ export const INVENTORY_TABLE_COLUMNS: TableColumnProps[] = [
     label: '文件格式',
     prop: 'fileFormat',
     align: 'center',
-    minWidth: '100px',
+    minWidth: '150px',
   },
   {
     label: '上传时间',

+ 30 - 12
src/views/production-safety/productionSafetySystem/safetyTraining/safetyTraining.vue

@@ -53,19 +53,13 @@
               <div class="select-box--item">
                 <span>上传日期范围:</span>
                 <el-date-picker
-                  v-model="queryParams.startDate"
-                  type="date"
+                  v-model="uploadDateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
                   value-format="YYYY-MM-DD"
-                  placeholder="开始日期"
-                  style="width: 130px"
-                />
-                <span style="margin: 0 4px">至</span>
-                <el-date-picker
-                  v-model="queryParams.endDate"
-                  type="date"
-                  value-format="YYYY-MM-DD"
-                  placeholder="结束日期"
-                  style="width: 130px"
+                  format="YYYY-MM-DD"
                 />
               </div>
             </section>
@@ -100,6 +94,7 @@
                   @confirm="handleDelete(scope.row.id)"
                 />
                 <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                <ActionButton text="下载" @click="handleDownloadFile(scope.row)" />
               </div>
             </template>
           </BasicTable>
@@ -156,6 +151,9 @@
     endDate: '', // 上传日期范围-结束日期
   });
 
+  // 上传日期范围(用于日期选择器)
+  const uploadDateRange = ref<[string, string] | null>(null);
+
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
     getTableData();
@@ -193,6 +191,7 @@
           fileFormat: item.fileFormat, // 文件格式
           releaseDate: item.releaseDate, // 发布日期
           status: item.status, // 状态:1-启用,0-禁用
+          fileUrl: item.fileUrl, // 文件地址
           uploadTime: item.uploadTime || item.createdAt, // 上传时间
         }));
         pagination.total = res.totalRow || 0;
@@ -207,6 +206,14 @@
   }
 
   const handleSearch = () => {
+    // 处理日期范围
+    if (uploadDateRange.value && uploadDateRange.value.length === 2) {
+      queryParams.startDate = uploadDateRange.value[0];
+      queryParams.endDate = uploadDateRange.value[1];
+    } else {
+      queryParams.startDate = '';
+      queryParams.endDate = '';
+    }
     pagination.pageNumber = 1;
     getTableData();
   };
@@ -217,6 +224,7 @@
     queryParams.classifyName = '';
     queryParams.startDate = '';
     queryParams.endDate = '';
+    uploadDateRange.value = null;
     handleSearch();
   };
 
@@ -256,6 +264,16 @@
     }
   };
 
+  // 文件下载
+  const handleDownloadFile = (row: any) => {
+    const url = row?.fileUrl;
+    if (!url) {
+      ElMessage.warning('暂无文件可下载');
+      return;
+    }
+    window.open(url, '_blank');
+  };
+
   const handleCreate = () => {
     router.push({
       name: 'SafetyTrainingItem',

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

@@ -171,7 +171,7 @@
   import type { FileItem } from '@/components/UploadFiles/types';
   import { useUserInfoHook } from '@/hooks/useUserInfoHook';
   import { formatAttachmentList } from '@/components/UploadFiles/utils';
-  import { getUserList } from '@/api/system/user-operate';
+  import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
 
   const props = defineProps<{
     id?: number;
@@ -210,7 +210,7 @@
   const reviewUserList = ref<UserLisItem[]>([]);
   const getReviewUserList = async () => {
     try {
-      const res = await getUserList({
+      const res = await queryAvailableUserList({
         pageNumber: 1,
         pageSize: 9999,
         queryParam: {}, // 不传递 deptId 参数

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

@@ -306,7 +306,7 @@
   import type { DeptTree } from '@/types/dept/type';
   import { queryUserGroupPage } from '@/api/system/person-group';
   import type { PersonGroupListItem } from '@/types/person-group/type';
-  import { getUserList } from '@/api/system/user-operate';
+  import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
   import type { UserLisItem } from '@/api/system/user-operate';
 
   const router = useRouter();
@@ -377,7 +377,7 @@
   // 获取部门自评审核人用户列表
   const getDeptSelfApproveUserList = async () => {
     try {
-      const res = await getUserList({
+      const res = await queryAvailableUserList({
         pageNumber: 1,
         pageSize: 9999,
         queryParam: {}, // 不传递 deptId 参数

+ 2 - 2
src/views/production-safety/safetyAssessment/receiptRecord/components/ReceiptRecordDetail.vue

@@ -88,7 +88,7 @@
   import type { InventoryItem } from '@/api/inventory';
   import { getAllDepartments } from '@/api/auth/dept';
   import type { DeptTree } from '@/types/dept/type';
-  import { getUserList } from '@/api/system/user-operate';
+  import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
   import type { UserLisItem } from '@/api/system/user-operate';
 
   const router = useRouter();
@@ -145,7 +145,7 @@
   const recipientUserList = ref<UserLisItem[]>([]);
   const getRecipientUserList = async (deptId: number) => {
     try {
-      const res = await getUserList({
+      const res = await queryAvailableUserList({
         pageNumber: 1,
         pageSize: 9999,
         queryParam: {

+ 2 - 2
src/views/production-safety/safetyAssessment/receiptRecord/configs/form.ts

@@ -50,7 +50,7 @@ export const RECEIPT_RECORD_FORM_CONFIG: FormConfig[] = [
   {
     prop: 'recipient',
     label: '领取人:',
-    slot: 'recipient', // 使用用户列表接口(getUserList + el-select)
+    slot: 'recipient', // 使用用户列表接口(queryAvailableUserList + el-select)
     componentProps: {
       placeholder: '请选择领取人',
     },
@@ -64,7 +64,7 @@ export const RECEIPT_RECORD_FORM_DATA = {
   receiptNumber: '',
   deptId: null as number | null, // 部门ID(部门级联,与应急预案制定部门同源)
   department: '', // 部门名称,提交给接口的 deptName
-  recipientUserId: null as number | null, // 领取人用户ID(通过getUserList接口获取)
+  recipientUserId: null as number | null, // 领取人用户ID(通过queryAvailableUserList接口获取)
   recipient: '', // 领取人姓名,提交给接口的 userName
   pimId: 0, // 物品库存ID(用于提交时使用,兼容旧数据)
 };