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

Merge remote-tracking branch 'origin/feat/production-safety' into feat/production-safety

sunqijun 3 месяцев назад
Родитель
Сommit
80832793b3
17 измененных файлов с 985 добавлено и 143 удалено
  1. 4 1
      src/api/drawLessons/index.ts
  2. 191 26
      src/api/production-safety-system/index.ts
  3. 70 24
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/areaCheckPlanManagement.vue
  4. 286 20
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/components/areaCheckPlanManagementDetail.vue
  5. 6 6
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/components/areaCheckPlanRecordDetail.vue
  6. 6 5
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/configs/form.ts
  7. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/configs/tables.ts
  8. 2 2
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/configs/types.ts
  9. 313 8
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/components/areaCheckPlanManagementDeptDetail.vue
  10. 77 31
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/components/areaCheckPlanRecordDetailDept.vue
  11. 5 3
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/components/hiddenTroubleAccountManagementDetail.vue
  12. 5 12
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form.ts
  13. 8 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/hiddenTroubleAccountManagement.vue
  14. 1 0
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagement/components/OneByOneAuditDetail.vue
  15. 1 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagement/oneByOneManagement.vue
  16. 3 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagementDept/components/oneByOneManagementDeptDetail.vue
  17. 6 1
      src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagementDept/oneByOneManagementDept.vue

+ 4 - 1
src/api/drawLessons/index.ts

@@ -197,12 +197,14 @@ export function submitDrawLessonsAdminFeedback(data: DrawLessonsFeedbackRequest)
 
 /**
  * 2.8 审核/变更状态
- * PUT /api/drawLessons/admin/approve?id=xxx&statusId=xxx&statusName=xxx
+ * PUT /api/drawLessons/admin/approve?id=xxx&statusId=xxx&statusName=xxx&reviewReason=xxx(不通过时)
  */
 export interface ApproveDrawLessonsRequest {
   id: number;
   statusId: number;
   statusName?: string;
+  /** 不通过原因(审核不通过时必填) */
+  reviewReason?: string;
 }
 
 export function approveDrawLessons(data: ApproveDrawLessonsRequest) {
@@ -213,6 +215,7 @@ export function approveDrawLessons(data: ApproveDrawLessonsRequest) {
       id: data.id,
       statusId: data.statusId,
       statusName: data.statusName,
+      ...(data.reviewReason != null && data.reviewReason !== '' ? { reviewReason: data.reviewReason } : {}),
     },
   });
 }

+ 191 - 26
src/api/production-safety-system/index.ts

@@ -776,8 +776,12 @@ interface AreaCheckPlanManageApiRecord {
   checkPlaceCategory?: string; // 检查场所所属类别
   checkCategory?: string; // 检查类别
   status?: number | string; // 状态:0=未开始 1=进行中 2=已完成 3=已终止
-  responsibleDeptName?: string; // 主责部门名称
-  responsibleDeptCode?: string; // 主责部门code
+  /** save/update 请求体使用:主责部门名称 */
+  primaryResponsibleDeptName?: string;
+  /** save/update 请求体使用:主责部门 code */
+  primaryResponsibleDeptCode?: string;
+  responsibleDeptName?: string; // 主责部门名称(兼容后端返回)
+  responsibleDeptCode?: string; // 主责部门code(兼容后端返回)
   selfCheckFrequency?: number | string; // 自查频次:0=每日 1=每周 2=每月 3=每季度 4=每半年 5=每年
   responsibleDeptExecGroupName?: string; // 主责部门执行人所属分组名称
   responsibleDeptExecGroupCode?: string; // 主责部门执行人所属分组code
@@ -828,8 +832,8 @@ export interface AreaCheckPlanRecord {
   status?: AreaCheckPlanStatus;
   venueCategoryName?: string;
   planName?: string;
-  mainDeptName?: string;
-  mainDeptCode?: string;
+  primaryResponsibleDeptName?: string;
+  primaryResponsibleDeptCode?: string;
   selfCheckFrequency?: string;
   mainDeptExecutorGroupName?: string;
   mainDeptExecGroupCode?: string;
@@ -878,8 +882,8 @@ export function mapAreaCheckPlanApiRecordToUi(api: AreaCheckPlanManageApiRecord
     checkVenue: api.checkPlace,
     venueCategoryName: api.checkPlaceCategory ?? api.checkCategory,
     status: api.status as AreaCheckPlanStatus | undefined,
-    mainDeptName: api.responsibleDeptName ?? api.responsibleDept,
-    mainDeptCode: api.responsibleDeptCode,
+    primaryResponsibleDeptName: api.primaryResponsibleDeptName ?? api.responsibleDeptName ?? api.responsibleDept,
+    primaryResponsibleDeptCode: api.primaryResponsibleDeptCode ?? api.responsibleDeptCode,
     selfCheckFrequency: toFreq(api.selfCheckFrequency),
     mainDeptExecutorGroupName: api.responsibleDeptExecGroupName ?? api.responsibleDeptExecGroup,
     mainDeptExecGroupCode: api.responsibleDeptExecGroupCode,
@@ -917,15 +921,15 @@ function uiRecordToApi(ui: AreaCheckPlanRecord & { id?: number }): AreaCheckPlan
   const toFreqNum = (v: string | undefined) => (v ? LABEL_TO_FREQUENCY[v] ?? undefined : undefined);
   const toNum = (v: boolean | undefined) => (v === true ? 1 : v === false ? 0 : undefined);
   const code = (ui as Record<string, unknown>);
+  const primaryResponsibleDeptCode = (code.primaryResponsibleDeptCode as string | undefined)
+    ?? (code.primaryResponsibleDeptId != null ? String(code.primaryResponsibleDeptId) : undefined);
   return {
     id: ui.id,
     areaCheckPlanName: ui.planName,
     checkPlace: ui.checkVenue,
     checkPlaceCategory: ui.venueCategoryName,
-    responsibleDeptName: ui.mainDeptName,
-    // 若 mainDeptCode 为空,则回退使用 mainDeptId 作为 code
-    responsibleDeptCode: (code.mainDeptCode as string | undefined)
-      ?? (code.mainDeptId != null ? String(code.mainDeptId) : undefined),
+    primaryResponsibleDeptName: ui.primaryResponsibleDeptName,
+    primaryResponsibleDeptCode,
     selfCheckFrequency: toFreqNum(ui.selfCheckFrequency),
     responsibleDeptExecGroupName: ui.mainDeptExecutorGroupName,
     responsibleDeptExecGroupCode: code.mainDeptExecGroupCode as string | undefined,
@@ -1109,18 +1113,126 @@ export function queryAreaCheckPlanManageDeptDetail(id: number) {
   });
 }
 
+/** 下发区域检查计划至部门(sandAreaCheckPlanToDep)请求体:责任部门、责任部门人员分组使用指定字段名 */
+export interface SendAreaCheckPlanToDepReq {
+  id: number;
+  /** 责任部门名称(多选逗号拼接) */
+  responsibleDeptName?: string;
+  /** 责任部门 code(多选逗号拼接) */
+  responsibleDeptCode?: string;
+  /** 责任部门人员分组名称 */
+  responsibleDeptPersonnelGroupName?: string;
+  /** 责任部门人员分组 code */
+  responsibleDeptPersonnelGroupCode?: string;
+  safetyEmergencyDeptName?: string;
+  safetyEmergencyDeptId?: number;
+  safetyEmergencyExecutorGroupName?: string;
+  safetyEmergencyExecGroupCode?: string;
+  hospitalLeaderDeptName?: string;
+  hospitalLeaderDeptId?: number;
+  hospitalLeaderExecutorGroupName?: string;
+  hospitalLeaderExecGroupCode?: string;
+  planStartTime?: string;
+  planEndTime?: string;
+  needOverallDesc?: boolean;
+  needInspectedSign?: boolean;
+  [key: string]: unknown;
+}
+
 /** 下发区域检查计划至部门(管理员) */
-export function sendAreaCheckPlanToDep(data: AreaCheckPlanRecord & { id: number }) {
+export function sendAreaCheckPlanToDep(data: SendAreaCheckPlanToDepReq) {
   return http.request({
-    url: `${ADMIN_BASE}/sendAreaCheckPlanToDep`,
-    method: 'put',
-    data: uiRecordToApi(data),
+    url: `areaCheckPlanManageAdmin/sandAreaCheckPlanToDep`,
+    method: 'post',
+    data,
   });
 }
 
-/** 作废:通过更新状态为3实现 */
-export function cancelAreaCheckPlanManage(id: number, plan: AreaCheckPlanRecord) {
-  return updateAreaCheckPlanManage({ ...plan, id, status: 3 });
+/** 区域检查计划管理(管理员) - 检查记录下入账至隐患台账 */
+export interface SandAreaCheckRecordToHiddenDangerReq {
+  /** 主键ID,自增 */
+  id?: number;
+  /** 区域检查记录ID(与 sourceRefId 一致,用于显式标记来源记录) */
+  areaCheckRecordId: number;
+  /** 数据来源:1员工上报 2台账新增 3台账导入 4区域检查 */
+  sourceType: number;
+  /** 来源记录ID,例如员工上报ID/导入批次ID/检查记录ID */
+  sourceRefId: number;
+  /** 隐患编号 */
+  dangerCode?: string;
+  /** 隐患问题类别ID */
+  typeId?: number;
+  /** 部门ID列表(扣分部门选择),逗号分隔 */
+  departmentIds?: string;
+  /** 隐患问题 */
+  dangerProblem: string;
+  /** 隐患原因ID */
+  reasonId?: number;
+  /** 任务来源 */
+  taskSource?: string;
+  /** 整改要求 */
+  rectificationRequirement?: string;
+  /** 整改期限(yyyy-MM-dd) */
+  rectificationDeadline?: string;
+  /** 整改责任部门ID列表,逗号分隔 */
+  rectificationDepartmentIds?: string;
+  /** 整改负责人 */
+  rectificationResponsiblePerson?: string;
+  /** 整改负责人ID,逗号分隔 */
+  rectificationResponsibleIds?: string;
+  /** 复查人员所属部门ID */
+  reviewDepartmentId?: number;
+  /** 复查人员ID */
+  reviewPersonId?: number;
+  /** 复查人员姓名 */
+  reviewPersonName?: string;
+  /** 举一反三是否推送,1-是,0-否 */
+  isDrawLessonsPush?: number;
+  /** 举一反三内容 */
+  drawLessonsContent?: string;
+  /** 举一反三责任部门ID列表,逗号分隔 */
+  drawLessonsDepartmentIds?: string;
+  /** 举一反三时限(yyyy-MM-dd) */
+  drawLessonsDeadline?: string;
+  /** 举一反三记录ID */
+  associationOtId?: number;
+  /** 隐患状态ID */
+  statusId?: number;
+  /** 当前流程节点 */
+  currentNode?: string;
+  /** 创建人ID */
+  creatorId?: number;
+  /** 创建人名称 */
+  creatorName?: string;
+  /** 创建时间(yyyy-MM-dd HH:mm:ss) */
+  createdAt?: string;
+  /** 更新时间(yyyy-MM-dd HH:mm:ss) */
+  updatedAt?: string;
+  /** 整改完成情况 */
+  rectificationCompletionStatus?: string;
+  /** 整改完成时间(yyyy-MM-dd) */
+  rectificationCompletionTime?: string;
+  /** 附件,通常为URL/ID列表,逗号分隔 */
+  attachments?: string;
+  /** 软删除:0-未删除,大于0(时间戳)-已删除 */
+  isDeleted?: number;
+}
+
+export function sandAreaCheckRecordToProductionHiddenDanger(data: SandAreaCheckRecordToHiddenDangerReq) {
+  return http.request({
+    url: `${ADMIN_BASE}/sandAreaCheckRecordToProductionHiddenDanger`,
+    method: 'post',
+    data,
+  });
+}
+
+/** 作废接口(管理员):/areaCheckPlanManageAdmin/updateStatusAreaCheckPlanManage POST,仅需传 id */
+export function cancelAreaCheckPlanManage(id: number) {
+  return http.request({
+    url: `${ADMIN_BASE}/updateStatusAreaCheckPlanManage?id=${id}`,
+    method: 'post',
+    // data: { id },
+  });
 }
 
 /** 查询区域检查计划关联的检查记录分页(管理员)- 与接口文档 DTO 对齐 */
@@ -1222,18 +1334,72 @@ export interface AreaCheckRecordDetail {
 
 export function queryAreaCheckRecord(id: number) {
   return http.request<AreaCheckRecordDetail>({
-    url: `${ADMIN_BASE}/queryAreaCheckRecord`,
+    url: `${ADMIN_BASE}/queryAreaCheckRecord?id=${id}`,
     method: 'post',
-    params: { id },
+    // params: { id },
   });
 }
 
 /** 查看区域检查计划记录详情(部门) */
 export function queryAreaCheckRecordDept(id: number) {
   return http.request<AreaCheckRecordDetail>({
-    url: `${DEPT_BASE}/queryAreaCheckRecord`,
+    url: `${DEPT_BASE}/queryAreaCheckRecord?id=${id}`,
     method: 'post',
-    params: { id },
+    // params: { id },
+  });
+}
+
+/** 区域检查计划管理(部门) - 新增检查日志时的检查明细模板 item */
+export interface AreaCheckRecordTemplateItem {
+  id?: number; // 主键ID,自增
+  checkPlanId?: number; // 关联检查计划ID(外键,对应 area_check_plan_detail.id)
+  checkContent?: string; // 检查内容
+  checkStandard?: string; // 检查标准
+  checkResult?: string; // 检查结果:合格/不合格
+  checkProblem?: string; // 检查发现问题:目前不存在问题/隐患问题未整改到位
+  isSand?: number; // 0-未入账,1-已入账
+  isDeleted?: number; // 0-未删除,大于0(时间戳)-已删除
+  createdAt?: string; // 创建时间
+  updatedAt?: string; // 更新时间
+}
+
+/** 区域检查计划管理(部门) - 新增检查日志的检查明细模板列表 */
+export function queryAreaCheckRecordTemplateDept(id: number) {
+  return http.request<AreaCheckRecordTemplateItem[]>({
+    url: `${DEPT_BASE}/queryAreaCheckRecordTemplate?id=${id}`,
+    method: 'post',
+  });
+}
+
+/** 区域检查计划管理(部门) - 新增检查日志提交体 */
+export interface SaveAreaCheckPlanDetailDeptReq {
+  areaPlanId: number; // 关联区域计划ID(外键对应 area_check_plan_manage.id)
+  checkTime: string; // 检查时间
+  checkPersonName: string; // 检查人员名称
+  checkPersonCode?: string; // 检查人员code
+  checkAddress: string; // 检查地点
+  overallCheckDesc: string; // 整体检查情况描述(300字)
+  checkedPersonSign?: string; // 被检查人签字(PDF文件地址/KEY)
+  areaCheckRecords: Array<{
+    id?: number;
+    checkPlanId?: number;
+    checkContent?: string;
+    checkStandard?: string;
+    checkResult?: string;
+    checkProblem?: string;
+    isSand?: number;
+    isDeleted?: number;
+    createdAt?: string;
+    updatedAt?: string;
+  }>;
+}
+
+/** 区域检查计划管理(部门) - 新增检查日志提交 */
+export function saveAreaCheckPlanDetailDept(data: SaveAreaCheckPlanDetailDeptReq) {
+  return http.request({
+    url: `${DEPT_BASE}/saveAreaCheckPlanDetailDept`,
+    method: 'post',
+    data,
   });
 }
 
@@ -1251,6 +1417,7 @@ export interface UnqualifiedItemNumRecord {
   checkPlace?: string;
   checkProblem?: string;
   checkTime?: string;
+  isSand?: number; // 0-未入账 1-已入账
 }
 
 /** 分页查询记录不合格数据(管理员) */
@@ -1312,11 +1479,9 @@ export function issueAreaCheckPlan(data: { planId?: number; id?: number } & Part
   return sendAreaCheckPlanToDep({ ...data, id } as AreaCheckPlanRecord & { id: number });
 }
 
-/** 兼容旧命名 */
-export async function cancelAreaCheckPlan(id: number) {
-  const plan = await queryAreaCheckPlanManageDetail(id);
-  const data = (plan as { data?: AreaCheckPlanManageApiRecord })?.data ?? plan;
-  return cancelAreaCheckPlanManage(id, mapAreaCheckPlanApiRecordToUi(data));
+/** 兼容旧命名:内部直接调用新的作废接口 */
+export function cancelAreaCheckPlan(id: number) {
+  return cancelAreaCheckPlanManage(id);
 }
 
 /** 兼容旧命名 */

+ 70 - 24
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/areaCheckPlanManagement.vue

@@ -158,9 +158,9 @@
             style="width: 100%"
           />
         </el-form-item>
-        <el-form-item label="责任部门人员分组:" prop="mainDeptGroupId">
+        <el-form-item label="责任部门人员分组:" prop="responsibleDeptPersonnelGroupCode">
           <el-select
-            v-model="issueForm.mainDeptGroupId"
+            v-model="issueForm.responsibleDeptPersonnelGroupCode"
             placeholder="请选择责任部门执行人所在分组名称,单选"
             filterable
             clearable
@@ -170,7 +170,7 @@
               v-for="item in userGroupOptions"
               :key="item.id"
               :label="item.name"
-              :value="item.id"
+              :value="item.id != null ? String(item.id) : ''"
             />
           </el-select>
         </el-form-item>
@@ -313,7 +313,7 @@
   const issueResponsibleDeptCascaderRef = ref();
   const issueForm = reactive({
     responsibleDeptIds: [] as number[],
-    mainDeptGroupId: undefined as number | undefined,
+    responsibleDeptPersonnelGroupCode: undefined as string | undefined,
     safetyEmergencyDeptId: undefined as number | undefined,
     safetyEmergencyGroupId: undefined as number | undefined,
     hospitalLeaderDeptId: undefined as number | undefined,
@@ -325,7 +325,7 @@
   });
   const issueRules = {
     responsibleDeptIds: [{ required: true, message: '请选择责任部门', trigger: 'change', type: 'array', min: 1 }],
-    mainDeptGroupId: [{ required: true, message: '请选择责任部门人员分组', trigger: 'change' }],
+    responsibleDeptPersonnelGroupCode: [{ required: true, message: '请选择责任部门人员分组', trigger: 'change' }],
     safetyEmergencyDeptId: [{ required: true, message: '请选择安全应急部门', trigger: 'change' }],
     safetyEmergencyGroupId: [{ required: true, message: '请选择安全应急部人员分组', trigger: 'change' }],
     hospitalLeaderDeptId: [{ required: true, message: '请选择院领导部门', trigger: 'change' }],
@@ -382,9 +382,32 @@
     loadUserGroupOptions();
   };
 
+  const findDeptNameById = (nodes: DeptTree[] | undefined, id: number | undefined): string | undefined => {
+    if (!nodes?.length || id == null) return undefined;
+    for (const n of nodes) {
+      if (n.id === id) return n.deptName;
+      const found = findDeptNameById(n.children, id);
+      if (found) return found;
+    }
+    return undefined;
+  };
+
+  const findDeptNamesByIds = (nodes: DeptTree[] | undefined, ids: number[] | undefined): string[] => {
+    const list = (ids ?? []).filter((v) => v != null);
+    if (!list.length) return [];
+    return list
+      .map((id) => findDeptNameById(nodes, id))
+      .filter((name): name is string => !!name && String(name).trim().length > 0);
+  };
+
+  const findGroupNameById = (id: number | undefined): string | undefined => {
+    if (id == null) return undefined;
+    return userGroupOptions.value.find((g) => g.id === id)?.name;
+  };
+
   const resetIssueForm = () => {
     issueForm.responsibleDeptIds = [];
-    issueForm.mainDeptGroupId = undefined;
+    issueForm.responsibleDeptPersonnelGroupCode = undefined;
     issueForm.safetyEmergencyDeptId = undefined;
     issueForm.safetyEmergencyGroupId = undefined;
     issueForm.hospitalLeaderDeptId = undefined;
@@ -510,20 +533,49 @@
       return;
     }
     try {
-      let record = tableData.value.find((item) => item.id === currentIssuePlanId.value);
-      if (!record) {
-        const detailRes = await queryAreaCheckPlanManageDetail(currentIssuePlanId.value);
-        const raw = (detailRes as { data?: unknown })?.data ?? detailRes;
-        record = mapAreaCheckPlanApiRecordToUi(raw);
-      }
-      await sendAreaCheckPlanToDep({
-        ...record,
+      // 仅提交:弹窗页面字段 + id(下拉同时提交 name + value)
+      const responsibleDeptIds = (issueForm.responsibleDeptIds ?? []).filter((v) => v != null);
+      const responsibleDeptNames = findDeptNamesByIds(issueDeptTree.value, responsibleDeptIds);
+      const responsibleDeptName = responsibleDeptNames.length ? responsibleDeptNames.join(',') : undefined;
+      const responsibleDeptCode = responsibleDeptIds.length ? responsibleDeptIds.join(',') : undefined;
+
+      const responsibleDeptPersonnelGroupName = (() => {
+        const code = issueForm.responsibleDeptPersonnelGroupCode;
+        if (code == null || code === '') return undefined;
+        const byId = userGroupOptions.value.find((g) => String(g.id) === code);
+        return byId?.name ?? undefined;
+      })();
+
+      const safetyEmergencyDeptName = findDeptNameById(issueDeptTree.value, issueForm.safetyEmergencyDeptId);
+      const hospitalLeaderDeptName = findDeptNameById(issueDeptTree.value, issueForm.hospitalLeaderDeptId);
+
+      const payload = {
         id: currentIssuePlanId.value,
-        planStartTime: issueForm.planStartTime || record.planStartTime,
-        planEndTime: issueForm.planEndTime || record.planEndTime,
+        responsibleDeptName,
+        responsibleDeptCode,
+        responsibleDeptPersonnelGroupName,
+        responsibleDeptPersonnelGroupCode: issueForm.responsibleDeptPersonnelGroupCode,
+
+        // 安全应急部门
+        safetyEmergencyDeptName,
+        safetyEmergencyDeptId: issueForm.safetyEmergencyDeptId,
+        safetyEmergencyExecutorGroupName: findGroupNameById(issueForm.safetyEmergencyGroupId),
+        safetyEmergencyExecGroupCode: issueForm.safetyEmergencyGroupId != null ? String(issueForm.safetyEmergencyGroupId) : undefined,
+
+        // 院领导部门
+        hospitalLeaderDeptName,
+        hospitalLeaderDeptId: issueForm.hospitalLeaderDeptId,
+        hospitalLeaderExecutorGroupName: findGroupNameById(issueForm.hospitalLeaderGroupId),
+        hospitalLeaderExecGroupCode: issueForm.hospitalLeaderGroupId != null ? String(issueForm.hospitalLeaderGroupId) : undefined,
+
+        // 计划时间与开关项
+        planStartTime: issueForm.planStartTime,
+        planEndTime: issueForm.planEndTime,
         needOverallDesc: issueForm.needOverallDesc,
         needInspectedSign: issueForm.needInspectedSign,
-      } as AreaCheckPlanRecord & { id: number });
+      } as AreaCheckPlanRecord & { id: number } & Record<string, unknown>;
+
+      await sendAreaCheckPlanToDep(payload);
       ElMessage.success('下发成功');
       showIssueDialog.value = false;
       getTableData();
@@ -534,13 +586,7 @@
 
   const handleCancel = async (id: number) => {
     try {
-      let record = tableData.value.find((item) => item.id === id);
-      if (!record) {
-        const detailRes = await queryAreaCheckPlanManageDetail(id);
-        const raw = (detailRes as { data?: unknown })?.data ?? detailRes;
-        record = mapAreaCheckPlanApiRecordToUi(raw);
-      }
-      await cancelAreaCheckPlanManage(id, record);
+      await cancelAreaCheckPlanManage(id);
       ElMessage.success('作废成功');
       getTableData();
     } catch (e) {

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

@@ -29,7 +29,7 @@
         <div class="row">
           <div class="col">
             <div class="label">主责部门:</div>
-            <div class="value">{{ viewDetail.mainDeptName || '-' }}</div>
+            <div class="value">{{ viewDetail.primaryResponsibleDeptName || '-' }}</div>
           </div>
           <div class="col">
             <div class="label">自查频率:</div>
@@ -164,6 +164,18 @@
         @update:pageSize="handleRecordSizeChange"
         @update:pageNumber="handleRecordPageChange"
       >
+        <template #unqualifiedItemNum="scope">
+          <el-button
+            v-if="Number(scope.row.unqualifiedItemNum) > 0"
+            type="primary"
+            link
+            size="small"
+            @click="openUnqualifiedDialog(scope.row)"
+          >
+            {{ scope.row.unqualifiedItemNum }}
+          </el-button>
+          <span v-else>{{ scope.row.unqualifiedItemNum ?? 0 }}</span>
+        </template>
         <template #sign="scope">
           <template v-if="parseSignFiles(scope.row.checkedPersonSign || scope.row.signFile).length">
             <div
@@ -205,10 +217,10 @@
       :formRules="isViewMode ? undefined : formRules"
       :formConfig="computedFormConfig"
     >
-      <template #mainDept>
+      <template #primaryResponsibleDept>
         <el-cascader
-          ref="mainDeptCascaderRef"
-          v-model="ruleFormData.mainDeptId"
+          ref="primaryResponsibleDeptCascaderRef"
+          v-model="ruleFormData.primaryResponsibleDeptId"
           :options="deptTree"
           :props="cascaderDeptProp"
           :show-all-levels="false"
@@ -217,7 +229,7 @@
           clearable
           :disabled="isViewMode"
           style="width: 100%"
-          @change="onMainDeptChange"
+          @change="onPrimaryResponsibleDeptChange"
         />
       </template>
       <template #safetyEmergencyDept>
@@ -292,6 +304,111 @@
     </el-button>
   </footer>
   <PreviewOnline ref="previewOnlineRef" />
+
+  <!-- 检查不合格数据弹窗(管理员) -->
+  <el-dialog
+    v-model="showUnqualifiedDialog"
+    title="检查不合格数据"
+    width="800px"
+    destroy-on-close
+  >
+    <BasicTable
+      :tableData="unqualifiedList"
+      :tableConfig="unqualifiedTableConfig"
+      @update:pageSize="handleUnqualifiedSizeChange"
+      @update:pageNumber="handleUnqualifiedPageChange"
+    >
+      <template #action="scope">
+        <el-button
+          v-if="Number(scope.row.isSand) === 0"
+          type="primary"
+          link
+          size="small"
+          @click="handleSandToHiddenDanger(scope.row)"
+        >
+          下入账
+        </el-button>
+        <span v-else-if="Number(scope.row.isSand) === 1" style="color: #999999">已入账</span>
+        <span v-else>-</span>
+      </template>
+    </BasicTable>
+  </el-dialog>
+
+  <!-- 检查记录入账隐患台账确认弹窗 -->
+  <el-dialog
+    v-model="showSandConfirmDialog"
+    title="检查记录入账隐患台账"
+    width="900px"
+    destroy-on-close
+  >
+    <BasicForm
+      ref="sandHiddenDangerFormRef"
+      :formData="sandHiddenDangerFormData"
+      :formRules="sandHiddenDangerFormRules"
+      :formConfig="sandHiddenDangerFormConfig"
+    >
+      <template #reviewDepartmentId>
+        <el-cascader
+          v-model="sandHiddenDangerFormData.reviewDepartmentId"
+          :options="deptTree"
+          :props="cascaderDeptProp"
+          :show-all-levels="false"
+          placeholder="请选择复查人员所属部门"
+          filterable
+          clearable
+          style="width: 100%"
+        />
+      </template>
+      <template #reviewPerson>
+        <el-select
+          v-model="sandHiddenDangerFormData.reviewPersonId"
+          placeholder="请选择复查人员"
+          clearable
+          filterable
+          style="width: 100%"
+        >
+          <el-option
+            v-for="u in reviewUserList"
+            :key="u.id"
+            :label="u.realname || u.username"
+            :value="u.id"
+          />
+        </el-select>
+      </template>
+      <template #isDrawLessonsPush>
+        <el-radio-group v-model="sandHiddenDangerFormData.isDrawLessonsPush">
+          <el-radio :value="0">否</el-radio>
+          <el-radio :value="1">是</el-radio>
+        </el-radio-group>
+      </template>
+      <template #drawLessonsDepartmentIds>
+        <el-select
+          v-model="drawLessonsDeptIdsArray"
+          placeholder="请选择举一反三责任部门,可多选"
+          clearable
+          filterable
+          multiple
+          collapse-tags
+          collapse-tags-tooltip
+          style="width: 100%"
+          @change="() => { sandHiddenDangerFormData.drawLessonsDepartmentIds = drawLessonsDeptIdsArray.join(','); }"
+        >
+          <el-option
+            v-for="d in deptOptions"
+            :key="d.id"
+            :label="d.deptName"
+            :value="d.id"
+          />
+        </el-select>
+      </template>
+    </BasicForm>
+    <template #footer>
+      <el-button @click="showSandConfirmDialog = false">取消</el-button>
+      <el-button type="primary" :loading="sandConfirmLoading" @click="confirmSandToHiddenDanger">
+        提交
+      </el-button>
+    </template>
+  </el-dialog>
 </template>
 
 <script setup lang="ts">
@@ -328,9 +445,18 @@
     queryAreaCheckRecord,
     mapAreaCheckPlanApiRecordToUi,
     queryCheckListTemplateNameList,
+    queryUnqualifiedItemNumPage,
+    sandAreaCheckRecordToProductionHiddenDanger,
     type ChecklistTemplate,
+    type UnqualifiedItemNumRecord,
+    type SandAreaCheckRecordToHiddenDangerReq,
   } from '@/api/production-safety-system';
   import { queryDictTypeDetail } from '@/api/dict';
+  import {
+    HIDDEN_DANGER_FORM_CONFIG,
+    HIDDEN_DANGER_FORM_DATA,
+    HIDDEN_DANGER_FORM_RULES,
+  } from '@/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form';
 
   const router = useRouter();
   const route = useRoute();
@@ -353,7 +479,7 @@
   );
 
   // 部门树,与新增物品领取记录页的部门下拉一致(getAllDepartments,取第一级 children)
-  const mainDeptCascaderRef = ref();
+  const primaryResponsibleDeptCascaderRef = ref();
   const safetyEmergencyDeptCascaderRef = ref();
   const hospitalLeaderDeptCascaderRef = ref();
   const deptTree = ref<DeptTree[]>([]);
@@ -386,13 +512,18 @@
     return undefined;
   };
 
-  const setDeptNameFromCascader = (refVal: any, nameKey: 'mainDeptName' | 'safetyEmergencyDeptName' | 'hospitalLeaderDeptName') => {
+  const setDeptNameFromCascader = (refVal: any, nameKey: 'primaryResponsibleDeptName' | 'safetyEmergencyDeptName' | 'hospitalLeaderDeptName') => {
     const nodes = refVal?.getCheckedNodes?.();
-    ruleFormData[nameKey] = nodes?.[0]?.label ?? '';
+    const label = nodes?.[0]?.label ?? '';
+    const value = nodes?.[0]?.value;
+    ruleFormData[nameKey] = label;
+    if (nameKey === 'primaryResponsibleDeptName') {
+      ruleFormData.primaryResponsibleDeptCode = value != null ? String(value) : '';
+    }
   };
 
-  const onMainDeptChange = () => {
-    setDeptNameFromCascader(mainDeptCascaderRef.value, 'mainDeptName');
+  const onPrimaryResponsibleDeptChange = () => {
+    setDeptNameFromCascader(primaryResponsibleDeptCascaderRef.value, 'primaryResponsibleDeptName');
   };
   const onSafetyEmergencyDeptChange = () => {
     setDeptNameFromCascader(safetyEmergencyDeptCascaderRef.value, 'safetyEmergencyDeptName');
@@ -504,7 +635,7 @@
       planName: d?.planName ?? ruleFormData.planName ?? '-',
       venueCategoryName: d?.venueCategoryName ?? ruleFormData.venueCategoryName ?? '-',
       checkVenue: d?.checkVenue ?? ruleFormData.checkVenue ?? '-',
-      mainDeptName: d?.mainDeptName ?? ruleFormData.mainDeptName ?? '-',
+      primaryResponsibleDeptName: d?.primaryResponsibleDeptName ?? ruleFormData.primaryResponsibleDeptName ?? '-',
       selfCheckFrequency: d?.selfCheckFrequency ?? ruleFormData.selfCheckFrequency ?? '-',
       mainDeptExecutorGroupName: d?.mainDeptExecutorGroupName ?? '-',
       mainDeptResponsiblePerson: d?.mainDeptResponsiblePerson ?? '-',
@@ -542,7 +673,7 @@
     { label: '检查场所', prop: 'checkPlace', minWidth: '120px' },
     { label: '检查项总数', prop: 'checkItemTotal', align: 'center', width: '100px' },
     { label: '合格项数', prop: 'qualifiedItemNum', align: 'center', width: '90px' },
-    { label: '不合格项数', prop: 'unqualifiedItemNum', align: 'center', width: '100px' },
+    { label: '不合格项数', prop: 'unqualifiedItemNum', slot: 'unqualifiedItemNum', align: 'center', width: '100px' },
     { label: '整体检查情况描述', prop: 'overallCheckDesc', minWidth: '180px', showOverflowTooltip: true },
     { label: '被检查人签字', slot: 'sign', align: 'center', width: '140px' },
     { label: '操作', slot: 'action', align: 'center', width: '160px', fixed: 'right' },
@@ -565,6 +696,44 @@
 
   const paginatedRecordList = computed(() => inspectionRecordList.value);
 
+  // 检查不合格数据弹窗
+  const showUnqualifiedDialog = ref(false);
+  const currentRecordIdForUnqualified = ref<number | null>(null);
+  const currentRowForUnqualified = ref<Record<string, unknown> | null>(null);
+  const unqualifiedList = ref<UnqualifiedItemNumRecord[]>([]);
+  const UNQUALIFIED_TABLE_COLUMNS: TableColumnProps[] = [
+    { label: '编号', type: 'index', align: 'center', width: '60px' },
+    { label: '检查场所', prop: 'checkPlace', minWidth: '200px' },
+    { label: '发现问题', prop: 'checkProblem', minWidth: '220px' },
+    { label: '检查时间', prop: 'checkTime', minWidth: '180px' },
+    { label: '操作', slot: 'action', align: 'center', width: '100px' },
+  ];
+  const UNQUALIFIED_TABLE_OPTIONS = {
+    emptyText: '暂无不合格数据',
+    loading: false,
+    maxHeight: '400px',
+    stripe: true,
+  };
+  const { tableConfig: unqualifiedTableConfig, pagination: unqualifiedPagination } = useTableConfig(
+    UNQUALIFIED_TABLE_COLUMNS,
+    UNQUALIFIED_TABLE_OPTIONS,
+    true,
+  );
+
+  // 入账确认弹窗数据(复用隐患台账新增表单字段与样式)
+  const showSandConfirmDialog = ref(false);
+  const sandConfirmLoading = ref(false);
+  const sandHiddenDangerFormRef = ref<InstanceType<typeof BasicForm>>();
+  const {
+    ruleFormData: sandHiddenDangerFormData,
+    formRules: sandHiddenDangerFormRules,
+    ruleFormConfig: sandHiddenDangerFormConfig,
+  } = useFormConfigHook(
+    HIDDEN_DANGER_FORM_CONFIG,
+    HIDDEN_DANGER_FORM_DATA as Record<string, unknown>,
+    HIDDEN_DANGER_FORM_RULES,
+  );
+
   const handleRecordSizeChange = (value: number) => {
     recordPagination.pageSize = value;
     recordPagination.pageNumber = 1;
@@ -575,6 +744,52 @@
     loadRecordList();
   };
 
+  const loadUnqualifiedList = async () => {
+    if (!currentRecordIdForUnqualified.value) return;
+    unqualifiedTableConfig.loading = true;
+    try {
+      const res = await queryUnqualifiedItemNumPage({
+        pageNumber: unqualifiedPagination.pageNumber,
+        pageSize: unqualifiedPagination.pageSize,
+        queryParam: {
+          id: currentRecordIdForUnqualified.value,
+          checkPlace: String(currentRowForUnqualified.value?.checkPlace ?? ''),
+          checkProblem: String(currentRowForUnqualified.value?.checkProblem ?? ''),
+          checkTime: String(currentRowForUnqualified.value?.checkTime ?? ''),
+        },
+      });
+      const raw = (res as { data?: { records?: UnqualifiedItemNumRecord[]; totalRow?: number } })?.data ?? res;
+      unqualifiedList.value = raw?.records ?? [];
+      unqualifiedPagination.total = raw?.totalRow ?? 0;
+    } catch (e) {
+      console.error('查询不合格数据失败:', e);
+      unqualifiedList.value = [];
+      unqualifiedPagination.total = 0;
+    } finally {
+      unqualifiedTableConfig.loading = false;
+    }
+  };
+
+  const handleUnqualifiedSizeChange = (value: number) => {
+    unqualifiedPagination.pageSize = value;
+    unqualifiedPagination.pageNumber = 1;
+    loadUnqualifiedList();
+  };
+
+  const handleUnqualifiedPageChange = (value: number) => {
+    unqualifiedPagination.pageNumber = value;
+    loadUnqualifiedList();
+  };
+
+  const openUnqualifiedDialog = (row: { id?: number } & Record<string, unknown>) => {
+    if (!row.id) return;
+    currentRecordIdForUnqualified.value = Number(row.id);
+    currentRowForUnqualified.value = row;
+    unqualifiedPagination.pageNumber = 1;
+    showUnqualifiedDialog.value = true;
+    loadUnqualifiedList();
+  };
+
   const loadRecordList = async () => {
     if (!currentId.value) return;
     recordTableConfig.loading = true;
@@ -616,6 +831,62 @@
     ElMessage.success('导出功能开发中');
   };
 
+  const handleSandToHiddenDanger = (row: { id?: number } & Record<string, unknown>) => {
+    if (!row.id) return;
+    currentRecordIdForUnqualified.value = Number(row.id);
+    // 每次打开入账弹窗都使用一份全新的隐患台账初始数据,不带入检查记录旧数据
+    Object.assign(sandHiddenDangerFormData, HIDDEN_DANGER_FORM_DATA);
+    showSandConfirmDialog.value = true;
+  };
+
+  const validateSandHiddenDangerForm = async () => {
+    if (!sandHiddenDangerFormRef.value) return false;
+    return await sandHiddenDangerFormRef.value.validateForm();
+  };
+
+  const confirmSandToHiddenDanger = async () => {
+    if (!currentRecordIdForUnqualified.value) return;
+    const valid = await validateSandHiddenDangerForm();
+    if (!valid) return;
+    sandConfirmLoading.value = true;
+    try {
+      const d = sandHiddenDangerFormData;
+      const payload: SandAreaCheckRecordToHiddenDangerReq = {
+        areaCheckRecordId: currentRecordIdForUnqualified.value,
+        sourceType: 4,
+        sourceRefId: currentRecordIdForUnqualified.value,
+        dangerProblem: d.dangerProblem || '',
+        typeId: d.typeId,
+        reasonId: d.reasonId,
+        taskSource: d.taskSource || '',
+        rectificationRequirement: d.rectificationRequirement || '',
+        rectificationDeadline: d.rectificationDeadline || '',
+        rectificationDepartmentIds: d.rectificationDepartmentIds || '',
+        rectificationResponsiblePerson: d.rectificationResponsiblePerson || '',
+        reviewDepartmentId: d.reviewDepartmentId,
+        reviewPersonId: d.reviewPersonId,
+        reviewPersonName: d.reviewPersonName || '',
+        isDrawLessonsPush: d.isDrawLessonsPush ?? 0,
+        drawLessonsContent: d.drawLessonsContent || '',
+        drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
+        drawLessonsDeadline: d.drawLessonsDeadline || '',
+        attachments: d.attachments || '',
+      };
+      await sandAreaCheckRecordToProductionHiddenDanger(payload);
+      ElMessage.success('下入账成功');
+      // 关闭入账表单弹窗和“不合格数据”弹窗
+      showSandConfirmDialog.value = false;
+      showUnqualifiedDialog.value = false;
+      // 重新加载检查记录列表,刷新 isSand 状态和数量
+      await loadRecordList();
+    } catch (e) {
+      console.error('下入账失败:', e);
+      ElMessage.error('下入账失败,请稍后重试');
+    } finally {
+      sandConfirmLoading.value = false;
+    }
+  };
+
   const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
   const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
     if (url) previewOnlineRef.value?.open(url, type);
@@ -656,12 +927,6 @@
         operate: 'area-check-plan-record-view',
         recordId: row.id,
         planId: currentId.value,
-        inspectedUnit: String(row.checkedCompanyName ?? row.checkedCompany ?? viewDetail.value.mainDeptName ?? viewDetail.value.checkVenue ?? ''),
-        inspector: String(row.checkPersonName ?? row.checkPerson ?? row.inspector ?? ''),
-        checkTime: String(row.checkTime ?? row.inspectionTime ?? ''),
-        checkPlace: String(row.checkAddress ?? row.checkPlace ?? row.venue ?? ''),
-        overallDesc: String(row.overallCheckDesc ?? row.overallDesc ?? ''),
-        signFile: String(row.checkedPersonSign ?? row.signFile ?? ''),
       },
     });
   };
@@ -681,8 +946,9 @@
       ruleFormData.planName = detail.planName ?? '';
       ruleFormData.venueCategoryName = detail.venueCategoryName ?? '';
       ruleFormData.checkVenue = detail.checkVenue ?? '';
-      ruleFormData.mainDeptName = detail.mainDeptName ?? '';
-      ruleFormData.mainDeptId = findDeptIdByName(deptTree.value, ruleFormData.mainDeptName as string) ?? null;
+      ruleFormData.primaryResponsibleDeptName = detail.primaryResponsibleDeptName ?? '';
+      ruleFormData.primaryResponsibleDeptCode = detail.primaryResponsibleDeptCode ?? '';
+      ruleFormData.primaryResponsibleDeptId = findDeptIdByName(deptTree.value, ruleFormData.primaryResponsibleDeptName as string) ?? null;
       ruleFormData.selfCheckFrequency = detail.selfCheckFrequency ?? '';
       ruleFormData.safetyEmergencyDeptName = detail.safetyEmergencyDeptName ?? '';
       ruleFormData.safetyEmergencyDeptId = findDeptIdByName(deptTree.value, ruleFormData.safetyEmergencyDeptName as string) ?? null;

+ 6 - 6
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/components/areaCheckPlanRecordDetail.vue

@@ -119,12 +119,12 @@
       const raw = (res as { data?: Record<string, unknown> })?.data ?? res;
       const r = raw as Record<string, unknown>;
       formData.value = {
-        inspectedUnit: String(r?.checkedCompanyName ?? r?.checkedCompany ?? route.query.inspectedUnit ?? ''),
-        inspector: String(r?.checkPersonName ?? r?.checkPerson ?? route.query.inspector ?? ''),
-        checkTime: String(r?.checkTime ?? route.query.checkTime ?? ''),
-        checkPlace: String(r?.checkAddress ?? r?.checkPlace ?? route.query.checkPlace ?? ''),
-        overallDesc: String(r?.overallCheckDesc ?? route.query.overallDesc ?? ''),
-        signFile: String(r?.checkedPersonSign ?? route.query.signFile ?? ''),
+        inspectedUnit: String(r?.checkedCompanyName ?? r?.checkedCompany ?? ''),
+        inspector: String(r?.checkPersonName ?? r?.checkPerson ?? ''),
+        checkTime: String(r?.checkTime ?? ''),
+        checkPlace: String(r?.checkAddress ?? r?.checkPlace ?? ''),
+        overallDesc: String(r?.overallCheckDesc ?? ''),
+        signFile: String(r?.checkedPersonSign ?? ''),
       };
       const records = (r?.areaCheckRecords ?? []) as Array<Record<string, unknown>>;
       checkItems.value = records.map((r) => ({

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

@@ -44,9 +44,9 @@ export const AREA_CHECK_PLAN_FORM_CONFIG: FormConfig[] = [
     },
   },
   {
-    prop: 'mainDeptName',
+    prop: 'primaryResponsibleDeptName',
     label: '主责部门:',
-    slot: 'mainDept', // 与新增物品领取记录页的部门下拉一致(el-cascader + getAllDepartments)
+    slot: 'primaryResponsibleDept', // 与新增物品领取记录页的部门下拉一致(el-cascader + getAllDepartments)
     componentProps: {
       placeholder: '请选择部门',
     },
@@ -124,8 +124,9 @@ export const AREA_CHECK_PLAN_FORM_DATA: Record<string, unknown> = {
   planName: '',
   venueCategoryName: '',
   checkVenue: '',
-  mainDeptId: null as number | null,
-  mainDeptName: '',
+  primaryResponsibleDeptId: null as number | null,
+  primaryResponsibleDeptName: '',
+  primaryResponsibleDeptCode: '',
   selfCheckFrequency: '',
   safetyEmergencyDeptId: null as number | null,
   safetyEmergencyDeptName: '',
@@ -143,7 +144,7 @@ export const AREA_CHECK_PLAN_FORM_RULES = {
   planName: [{ required: true, message: '请输入区域检查计划名称', trigger: 'blur' }],
   venueCategoryName: [{ required: true, message: '请输入检查类别', trigger: 'blur' }],
   checkVenue: [{ required: true, message: '请输入检查场所', trigger: 'blur' }],
-  mainDeptName: [{ required: true, message: '请选择主责部门', trigger: 'change' }],
+  primaryResponsibleDeptName: [{ required: true, message: '请选择主责部门', trigger: 'change' }],
   selfCheckFrequency: [{ required: true, message: '请选择自查频次', trigger: 'change' }],
   safetyEmergencyDeptName: [{ required: true, message: '请选择安全应急部门', trigger: 'change' }],
   hospitalLeaderDeptName: [{ required: true, message: '请选择院领导部门', trigger: 'change' }],

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

@@ -47,7 +47,7 @@ export const AREA_CHECK_PLAN_TABLE_COLUMNS: TableColumnProps[] = [
   },
   {
     label: '主责部门',
-    prop: 'mainDeptName',
+    prop: 'primaryResponsibleDeptName',
     align: 'left',
     minWidth: '120px',
     showOverflowTooltip: true,

+ 2 - 2
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagement/configs/types.ts

@@ -7,8 +7,8 @@ export interface AreaCheckPlanRecord {
   status?: AreaCheckPlanStatus;
   venueCategoryName?: string;
   planName?: string;
-  mainDeptName?: string;
-  mainDeptCode?: string;
+  primaryResponsibleDeptName?: string;
+  primaryResponsibleDeptCode?: string;
   selfCheckFrequency?: string;
   mainDeptExecutorGroupName?: string;
   mainDeptExecGroupCode?: string;

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

@@ -165,6 +165,18 @@
         @update:pageSize="handleRecordSizeChange"
         @update:pageNumber="handleRecordPageChange"
       >
+        <template #unqualifiedItemNum="scope">
+          <el-button
+
+            type="primary"
+            link
+            size="small"
+            @click="openUnqualifiedDialog(scope.row)"
+          >
+            {{ scope.row.unqualifiedItemNum }}
+          </el-button>
+          <!-- <span v-else>{{ scope.row.unqualifiedItemNum ?? 0 }}</span> -->
+        </template>
         <template #sign="scope">
           <template v-if="parseSignFiles(scope.row.checkedPersonSign || scope.row.signFile).length">
             <div
@@ -198,6 +210,111 @@
     </section>
   </main>
   <PreviewOnline ref="previewOnlineRef" />
+
+  <!-- 检查不合格数据弹窗(部门) -->
+  <el-dialog
+    v-model="showUnqualifiedDialog"
+    title="检查不合格数据"
+    width="800px"
+    destroy-on-close
+  >
+    <BasicTable
+      :tableData="unqualifiedList"
+      :tableConfig="unqualifiedTableConfig"
+      @update:pageSize="handleUnqualifiedSizeChange"
+      @update:pageNumber="handleUnqualifiedPageChange"
+    >
+      <template #action="scope">
+        <el-button
+          v-if="Number(scope.row.IsSand) == 0"
+          type="primary"
+          link
+          size="small"
+          @click="handleSandToHiddenDangerDept(scope.row)"
+        >
+          入账
+        </el-button>
+        <span v-else-if="Number(scope.row.IsSand) === 1" style="color: #999999">已入账</span>
+        <span v-else>-</span>
+      </template>
+    </BasicTable>
+  </el-dialog>
+
+  <!-- 部门端:检查记录入账隐患台账确认弹窗(仅查看提示,不真正入账) -->
+  <el-dialog
+    v-model="showSandConfirmDialogDept"
+    title="检查记录入账隐患台账"
+    width="900px"
+    destroy-on-close
+  >
+    <BasicForm
+      ref="sandHiddenDangerFormRefDept"
+      :formData="sandHiddenDangerFormDataDept"
+      :formRules="sandHiddenDangerFormRulesDept"
+      :formConfig="sandHiddenDangerFormConfigDept"
+    >
+      <template #reviewDepartmentId>
+        <el-cascader
+          v-model="sandHiddenDangerFormDataDept.reviewDepartmentId"
+          :options="deptTree"
+          :props="cascaderDeptProp"
+          :show-all-levels="false"
+          placeholder="请选择复查人员所属部门"
+          filterable
+          clearable
+          style="width: 100%"
+        />
+      </template>
+      <template #reviewPerson>
+        <el-select
+          v-model="sandHiddenDangerFormDataDept.reviewPersonId"
+          placeholder="请选择复查人员"
+          clearable
+          filterable
+          style="width: 100%"
+        >
+          <el-option
+            v-for="u in reviewUserListDept"
+            :key="u.id"
+            :label="u.realname || u.username"
+            :value="u.id"
+          />
+        </el-select>
+      </template>
+      <template #isDrawLessonsPush>
+        <el-radio-group v-model="sandHiddenDangerFormDataDept.isDrawLessonsPush">
+          <el-radio :value="0">否</el-radio>
+          <el-radio :value="1">是</el-radio>
+        </el-radio-group>
+      </template>
+      <template #drawLessonsDepartmentIds>
+        <el-select
+          v-model="drawLessonsDeptIdsArrayDept"
+          placeholder="请选择举一反三责任部门,可多选"
+          clearable
+          filterable
+          multiple
+          collapse-tags
+          collapse-tags-tooltip
+          style="width: 100%"
+          @change="() => { sandHiddenDangerFormDataDept.drawLessonsDepartmentIds = drawLessonsDeptIdsArrayDept.join(','); }"
+        >
+          <el-option
+            v-for="d in deptOptions"
+            :key="d.id"
+            :label="d.deptName"
+            :value="d.id"
+          />
+        </el-select>
+      </template>
+    </BasicForm>
+    <template #footer>
+      <el-button @click="showSandConfirmDialogDept = false">取消</el-button>
+      <el-button type="primary" :loading="sandConfirmLoadingDept" @click="confirmSandToHiddenDangerDept">
+        提交
+      </el-button>
+    </template>
+  </el-dialog>
 </template>
 
 <script setup lang="ts">
@@ -212,13 +329,26 @@
   import { downloadFile } from '@/views/disaster/utils';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import type { TableColumnProps } from '@/types/basic-table';
-  import type { AreaCheckPlanRecord } from '../../areaCheckPlanManagement/configs/types';
   import { AREA_CHECK_PLAN_STATUS_LABEL } from '../../areaCheckPlanManagement/configs/status';
   import {
     queryAreaCheckPlanManageDeptDetail,
     queryAreaCheckPlanDetailDeptPage,
     mapAreaCheckPlanApiRecordToUi,
+    queryUnqualifiedItemNumDeptPage,
+    sandAreaCheckRecordToProductionHiddenDanger,
+    type UnqualifiedItemNumRecord,
+    type SandAreaCheckRecordToHiddenDangerReq,
   } from '@/api/production-safety-system';
+  import BasicForm from '@/components/BasicForm.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import type { DeptTree } from '@/types/dept/type';
+  import {
+    HIDDEN_DANGER_FORM_CONFIG,
+    HIDDEN_DANGER_FORM_DATA,
+    HIDDEN_DANGER_FORM_RULES,
+  } from '@/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form';
+  import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
 
   const router = useRouter();
   const route = useRoute();
@@ -281,7 +411,7 @@
     { label: '检查场所', prop: 'checkPlace', minWidth: '120px' },
     { label: '检查项总数', prop: 'checkItemTotal', align: 'center', width: '100px' },
     { label: '合格项数', prop: 'qualifiedItemNum', align: 'center', width: '90px' },
-    { label: '不合格项数', prop: 'unqualifiedItemNum', align: 'center', width: '100px' },
+    { label: '不合格项数', prop: 'unqualifiedItemNum', slot: 'unqualifiedItemNum', align: 'center', width: '100px' },
     { label: '整体检查情况描述', prop: 'overallCheckDesc', minWidth: '180px', showOverflowTooltip: true },
     { label: '被检查人签字', slot: 'sign', align: 'center', width: '140px' },
     { label: '操作', slot: 'action', align: 'center', width: '160px', fixed: 'right' },
@@ -304,6 +434,85 @@
 
   const paginatedRecordList = computed(() => inspectionRecordList.value);
 
+  // 检查不合格数据弹窗
+  const showUnqualifiedDialog = ref(false);
+  const currentRecordIdForUnqualified = ref<number | null>(null);
+  const currentRowForUnqualified = ref<Record<string, unknown> | null>(null);
+  const unqualifiedList = ref<UnqualifiedItemNumRecord[]>([]);
+  const UNQUALIFIED_TABLE_COLUMNS: TableColumnProps[] = [
+    { label: '编号', type: 'index', align: 'center', width: '60px' },
+    { label: '检查场所', prop: 'checkPlace', minWidth: '200px' },
+    { label: '发现问题', prop: 'checkProblem', minWidth: '220px' },
+    { label: '检查时间', prop: 'checkTime', minWidth: '180px' },
+    { label: '操作', slot: 'action', align: 'center', width: '100px' },
+  ];
+  const UNQUALIFIED_TABLE_OPTIONS = {
+    emptyText: '暂无不合格数据',
+    loading: false,
+    maxHeight: '400px',
+    stripe: true,
+  };
+  const { tableConfig: unqualifiedTableConfig, pagination: unqualifiedPagination } = useTableConfig(
+    UNQUALIFIED_TABLE_COLUMNS,
+    UNQUALIFIED_TABLE_OPTIONS,
+    true,
+  );
+
+  // 部门端入账弹窗数据(复用隐患台账新增表单字段与样式)
+  const showSandConfirmDialogDept = ref(false);
+  const sandConfirmLoadingDept = ref(false);
+  const sandHiddenDangerFormRefDept = ref<InstanceType<typeof BasicForm>>();
+  const {
+    ruleFormData: sandHiddenDangerFormDataDept,
+    formRules: sandHiddenDangerFormRulesDept,
+    ruleFormConfig: sandHiddenDangerFormConfigDept,
+  } = useFormConfigHook(
+    HIDDEN_DANGER_FORM_CONFIG,
+    HIDDEN_DANGER_FORM_DATA as Record<string, unknown>,
+    HIDDEN_DANGER_FORM_RULES,
+  );
+
+  // 复用部门树与用户下拉,用于复查部门/人员 & 举一反三责任部门
+  const deptTree = ref<DeptTree[]>([]);
+  const cascaderDeptProp = {
+    checkStrictly: true,
+    expandTrigger: 'hover' as const,
+    value: 'id',
+    label: 'deptName',
+    emitPath: false,
+  };
+  function flattenDeptTree(nodes: DeptTree[] | undefined): Array<{ id: number; deptName: string }> {
+    if (!nodes?.length) return [];
+    const list: Array<{ id: number; deptName: string }> = [];
+    const walk = (items: DeptTree[]) => {
+      items.forEach((n) => {
+        if (n.id != null) list.push({ id: n.id, deptName: n.deptName });
+        if (n.children?.length) walk(n.children);
+      });
+    };
+    walk(nodes);
+    return list;
+  }
+  const deptOptions = computed(() => flattenDeptTree(deptTree.value));
+  const drawLessonsDeptIdsArrayDept = ref<number[]>([]);
+  const reviewUserListDept = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
+
+  const loadDeptAndUserOptionsDept = async () => {
+    try {
+      const [deptRes, userRes] = await Promise.all([
+        getAllDepartments(),
+        queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
+      ]);
+      const fullTree = (deptRes as DeptTree[]) ?? [];
+      deptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
+      reviewUserListDept.value = (userRes as any)?.records ?? [];
+    } catch (e) {
+      console.error('获取部门/用户列表失败:', e);
+      deptTree.value = [];
+      reviewUserListDept.value = [];
+    }
+  };
+
   const loadRecordList = async () => {
     if (!currentId.value) return;
     recordTableConfig.loading = true;
@@ -355,6 +564,107 @@
     ElMessage.success('导出功能开发中');
   };
 
+  const loadUnqualifiedList = async () => {
+    if (!currentRecordIdForUnqualified.value) return;
+    unqualifiedTableConfig.loading = true;
+    try {
+      const res = await queryUnqualifiedItemNumDeptPage({
+        pageNumber: unqualifiedPagination.pageNumber,
+        pageSize: unqualifiedPagination.pageSize,
+        queryParam: {
+          id: currentRecordIdForUnqualified.value,
+          checkPlace: String(currentRowForUnqualified.value?.checkPlace ?? ''),
+          checkProblem: String(currentRowForUnqualified.value?.checkProblem ?? ''),
+          checkTime: String(currentRowForUnqualified.value?.checkTime ?? ''),
+        },
+      });
+      const raw = (res as { data?: { records?: UnqualifiedItemNumRecord[]; totalRow?: number } })?.data ?? res;
+      unqualifiedList.value = raw?.records ?? [];
+      unqualifiedPagination.total = raw?.totalRow ?? 0;
+    } catch (e) {
+      console.error('查询不合格数据失败:', e);
+      unqualifiedList.value = [];
+      unqualifiedPagination.total = 0;
+    } finally {
+      unqualifiedTableConfig.loading = false;
+    }
+  };
+
+  const handleUnqualifiedSizeChange = (value: number) => {
+    unqualifiedPagination.pageSize = value;
+    unqualifiedPagination.pageNumber = 1;
+    loadUnqualifiedList();
+  };
+
+  const handleUnqualifiedPageChange = (value: number) => {
+    unqualifiedPagination.pageNumber = value;
+    loadUnqualifiedList();
+  };
+
+  const openUnqualifiedDialog = (row: { id?: number } & Record<string, unknown>) => {
+    if (!row.id) return;
+    currentRecordIdForUnqualified.value = Number(row.id);
+    currentRowForUnqualified.value = row;
+    unqualifiedPagination.pageNumber = 1;
+    showUnqualifiedDialog.value = true;
+    loadUnqualifiedList();
+  };
+
+  const handleSandToHiddenDangerDept = (row: { id?: number } & Record<string, unknown>) => {
+    if (!row.id) return;
+    currentRecordIdForUnqualified.value = Number(row.id);
+    // 部门端入账同样不带入检查记录旧数据,每次打开还原为隐患台账初始表单
+    Object.assign(sandHiddenDangerFormDataDept, HIDDEN_DANGER_FORM_DATA);
+    showSandConfirmDialogDept.value = true;
+  };
+
+  const validateSandHiddenDangerFormDept = async () => {
+    if (!sandHiddenDangerFormRefDept.value) return false;
+    return await sandHiddenDangerFormRefDept.value.validateForm();
+  };
+
+  const confirmSandToHiddenDangerDept = async () => {
+    if (!currentRecordIdForUnqualified.value) return;
+    const valid = await validateSandHiddenDangerFormDept();
+    if (!valid) return;
+    sandConfirmLoadingDept.value = true;
+    try {
+      const d = sandHiddenDangerFormDataDept;
+      const payload: SandAreaCheckRecordToHiddenDangerReq = {
+        areaCheckRecordId: currentRecordIdForUnqualified.value,
+        sourceType: 4,
+        sourceRefId: currentRecordIdForUnqualified.value,
+        dangerProblem: d.dangerProblem || '',
+        typeId: d.typeId,
+        reasonId: d.reasonId,
+        taskSource: d.taskSource || '',
+        rectificationRequirement: d.rectificationRequirement || '',
+        rectificationDeadline: d.rectificationDeadline || '',
+        rectificationDepartmentIds: d.rectificationDepartmentIds || '',
+        rectificationResponsiblePerson: d.rectificationResponsiblePerson || '',
+        reviewDepartmentId: d.reviewDepartmentId,
+        reviewPersonId: d.reviewPersonId,
+        reviewPersonName: d.reviewPersonName || '',
+        isDrawLessonsPush: d.isDrawLessonsPush ?? 0,
+        drawLessonsContent: d.drawLessonsContent || '',
+        drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
+        drawLessonsDeadline: d.drawLessonsDeadline || '',
+        attachments: d.attachments || '',
+      };
+      await sandAreaCheckRecordToProductionHiddenDanger(payload);
+      ElMessage.success('入账成功');
+      // 关闭入账表单弹窗和“不合格数据”弹窗
+      showSandConfirmDialogDept.value = false;
+      showUnqualifiedDialog.value = false;
+      await loadRecordList();
+    } catch (e) {
+      console.error('部门端下入账失败:', e);
+      ElMessage.error('下入账失败,请稍后重试');
+    } finally {
+      sandConfirmLoadingDept.value = false;
+    }
+  };
+
   const onAddRecord = () => {
     router.push({
       name: 'areaCheckPlanManagementDeptItem',
@@ -395,12 +705,6 @@
         operate: 'area-check-plan-record-view',
         recordId: row.id,
         planId: currentId.value,
-        inspectedUnit: String(row.checkedCompanyName ?? row.checkedCompany ?? viewDetail.value.mainDeptName ?? viewDetail.value.checkVenue ?? ''),
-        inspector: String(row.checkPersonName ?? row.checkPerson ?? row.inspector ?? ''),
-        checkTime: String(row.checkTime ?? row.inspectionTime ?? ''),
-        checkPlace: String(row.checkAddress ?? row.checkPlace ?? row.venue ?? ''),
-        overallDesc: String(row.overallCheckDesc ?? row.overallDesc ?? ''),
-        signFile: String(row.checkedPersonSign ?? row.signFile ?? ''),
       },
     });
   };
@@ -419,6 +723,7 @@
   };
 
   onMounted(() => {
+    loadDeptAndUserOptionsDept();
     getDetail();
   });
 </script>

+ 77 - 31
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/areaCheckPlanManagementDept/components/areaCheckPlanRecordDetailDept.vue

@@ -11,10 +11,10 @@
         <el-date-picker
           v-if="isAddMode"
           v-model="formData.checkTime"
-          type="datetime"
-          placeholder="选择检查时间"
-          value-format="YYYY-MM-DD HH:mm:ss"
-          format="YYYY-MM-DD HH:mm:ss"
+          type="date"
+          placeholder="选择检查日期"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
           style="width: 100%"
         />
         <el-input v-else v-model="formData.checkTime" disabled />
@@ -59,6 +59,7 @@
             <el-radio-group v-if="isAddMode" v-model="row.checkResult" size="small">
               <el-radio value="合格">合格</el-radio>
               <el-radio value="不合格">不合格</el-radio>
+              <el-radio value="待检">待检</el-radio>
             </el-radio-group>
             <span v-else>{{ row.checkResult || '-' }}</span>
           </template>
@@ -85,7 +86,12 @@
   import { ElMessage } from 'element-plus';
   import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
   import type { FileItem } from '@/components/UploadFiles/types';
-  import { queryAreaCheckRecordDept } from '@/api/production-safety-system';
+  import {
+    queryAreaCheckRecordDept,
+    queryAreaCheckRecordTemplateDept,
+    saveAreaCheckPlanDetailDept,
+    type AreaCheckRecordTemplateItem,
+  } from '@/api/production-safety-system';
 
   const router = useRouter();
   const route = useRoute();
@@ -93,6 +99,7 @@
   const operate = computed(() => (route.query.operate as string) || '');
   const isAddMode = computed(() => operate.value === 'area-check-plan-record-add');
   const recordId = computed(() => Number(route.query.recordId));
+  const planId = computed(() => Number(route.query.planId));
 
   const formRef = ref();
   const formData = ref({
@@ -111,12 +118,6 @@
     checkPlace: [{ required: true, message: '请输入检查地点', trigger: 'blur' }],
   };
 
-  const DEFAULT_VIEW_ITEMS = [
-    { checkContent: '工作场所布局是否合理,通道是否畅通', checkStandard: '通道无阻塞,安全出口标识清晰', checkResult: '合格', checkProblem: '无' },
-    { checkContent: '各种机械、电力、电气等设备的安装和使用是否符合安全技术要求', checkStandard: '设备有完好防护装置,操作规程上墙', checkResult: '不合格', checkProblem: '部分电气设备绝缘老化,未及时更换' },
-    { checkContent: '易燃易爆、有限空间和高处作业等作业场所是否符合安全条件', checkStandard: '作业票证齐全,应急预案到位', checkResult: '合格', checkProblem: '无' },
-  ];
-
   interface CheckItem {
     checkContent: string;
     checkStandard: string;
@@ -163,8 +164,33 @@
     if (!formRef.value) return;
     const valid = await formRef.value.validate().catch(() => false);
     if (!valid) return;
-    ElMessage.success('提交成功');
-    router.back();
+    if (!planId.value) {
+      ElMessage.error('缺少关联的区域检查计划ID,无法提交');
+      return;
+    }
+    try {
+      await saveAreaCheckPlanDetailDept({
+        areaPlanId: planId.value,
+        checkTime: formData.value.checkTime,
+        checkPersonName: formData.value.inspector,
+        // 暂无人员 code 来源,前端先不传或由后端根据名称解析
+        checkAddress: formData.value.checkPlace,
+        overallCheckDesc: formData.value.overallDesc,
+        checkedPersonSign: formData.value.signFile,
+        areaCheckRecords: checkItems.value.map((item) => ({
+          checkContent: item.checkContent || '',
+          checkStandard: item.checkStandard || '',
+          // 新增检查日志时,检查结果和问题直接使用接口返回的数据
+          checkResult: item.checkResult || '',
+          checkProblem: item.checkProblem || '',
+        })),
+      });
+      ElMessage.success('提交成功');
+      router.back();
+    } catch (e) {
+      console.error('新增检查日志提交失败:', e);
+      ElMessage.error('提交失败,请稍后重试');
+    }
   };
 
   const loadRecordDetail = async () => {
@@ -174,12 +200,12 @@
         const raw = (res as { data?: Record<string, unknown> })?.data ?? res;
         const r = raw as Record<string, unknown>;
         formData.value = {
-          inspectedUnit: String(r?.checkedCompanyName ?? r?.checkedCompany ?? route.query.inspectedUnit ?? ''),
-          inspector: String(r?.checkPersonName ?? r?.checkPerson ?? route.query.inspector ?? ''),
-          checkTime: String(r?.checkTime ?? route.query.checkTime ?? ''),
-          checkPlace: String(r?.checkAddress ?? r?.checkPlace ?? route.query.checkPlace ?? ''),
-          overallDesc: String(r?.overallCheckDesc ?? route.query.overallDesc ?? ''),
-          signFile: String(r?.checkedPersonSign ?? route.query.signFile ?? ''),
+          inspectedUnit: String(r?.checkedCompanyName ?? r?.checkedCompany ?? ''),
+          inspector: String(r?.checkPersonName ?? r?.checkPerson ?? ''),
+          checkTime: String(r?.checkTime ?? ''),
+          checkPlace: String(r?.checkAddress ?? r?.checkPlace ?? ''),
+          overallDesc: String(r?.overallCheckDesc ?? ''),
+          signFile: String(r?.checkedPersonSign ?? ''),
         };
         const records = (r?.areaCheckRecords ?? []) as Array<Record<string, unknown>>;
         checkItems.value = records.map((item) => ({
@@ -192,15 +218,39 @@
         console.error('获取检查记录详情失败:', e);
       }
     } else {
+      // 无 recordId 的查看场景,只保留空表单和空检查明细(不依赖路由传递数据)
       formData.value = {
-        inspectedUnit: String(route.query.inspectedUnit || '某被检查单位'),
-        inspector: String(route.query.inspector || '孙菲'),
-        checkTime: String(route.query.checkTime || '2025-03-28 10:00:00'),
-        checkPlace: String(route.query.checkPlace || '18号楼'),
-        overallDesc: String(route.query.overallDesc || '学习宣传贯彻习近平新时代中国特色社会主义思想和党的二十大精神等相关内容。'),
-        signFile: String(route.query.signFile || '领导签字文件.pdf'),
+        inspectedUnit: '',
+        inspector: '',
+        checkTime: '',
+        checkPlace: '',
+        overallDesc: '',
+        signFile: '',
       };
-      checkItems.value = [...DEFAULT_VIEW_ITEMS];
+      checkItems.value = [];
+    }
+  };
+
+  const loadTemplateCheckItems = async () => {
+    // 使用部门模板接口获取“新增检查日志”的检查明细
+    if (!planId.value) {
+      // 没有计划ID时,不展示任何检查明细
+      checkItems.value = [];
+      return;
+    }
+    try {
+      const res = await queryAreaCheckRecordTemplateDept(planId.value);
+      const list = ((res as { data?: AreaCheckRecordTemplateItem[] })?.data ?? res) || [];
+      if (Array.isArray(list) && list.length > 0) {
+        checkItems.value = list
+      } else {
+        // 模板为空时,不展示任何检查明细
+        checkItems.value = [];
+      }
+    } catch (e) {
+      console.error('获取检查明细模板失败:', e);
+      // 接口异常时不影响表单填写,但不展示任何假数据
+      checkItems.value = [];
     }
   };
 
@@ -216,11 +266,7 @@
         signFile: '',
       };
       signFileList.value = [];
-      checkItems.value = DEFAULT_VIEW_ITEMS.map((item) => ({
-        ...item,
-        checkResult: '',
-        checkProblem: '',
-      }));
+      await loadTemplateCheckItems();
     } else {
       await loadRecordDetail();
     }

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

@@ -76,6 +76,8 @@
         <UploadFiles
           label="上传附件"
           :file-list="attachmentsFileList"
+          :readonly="isViewMode && !isRectifyMode"
+          :disabled="isViewMode && !isRectifyMode"
           @uploadSuccess="handleAttachmentsUploadSuccess"
         />
       </template>
@@ -395,9 +397,9 @@
         ruleFormData.rectificationCompletionStatus = d.rectificationCompletionStatus ?? '';
         ruleFormData.rectificationCompletionTime = d.rectificationCompletionTime ?? '';
         ruleFormData.attachments = d.attachments ?? '';
-        // 整改页:保存审查不通过原因供 el-alert 展示
-        if (isRectifyMode.value && d.reviewRejectReason != null && String(d.reviewRejectReason).trim()) {
-          detailReviewRejectReason.value = String(d.reviewRejectReason).trim();
+        // 整改页:保存审查不通过原因供 el-alert 展示(后端字段 reviewReason)
+        if (isRectifyMode.value && d.reviewReason != null && String(d.reviewReason).trim()) {
+          detailReviewRejectReason.value = String(d.reviewReason).trim();
         } else {
           detailReviewRejectReason.value = '';
         }

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

@@ -280,20 +280,13 @@ export const HIDDEN_DANGER_RECTIFY_FORM_CONFIG: FormConfig[] = [
 /**
  * 复查详情完整表单配置:整改字段全部禁用 + 复查意见(可编辑,清空)
  * 从主列表「复查」进入,底部按钮为「审查通过」「审查不通过」
+ * 说明:附件字段继续复用整改/新增时的 Upload 组件(通过插槽渲染),仅在复查详情中禁用交互
  */
 export const HIDDEN_DANGER_REVIEW_FORM_CONFIG: FormConfig[] = [
-  ...HIDDEN_DANGER_RECTIFY_FORM_CONFIG.map((item) => {
-    const disabledProps = { ...item.componentProps, disabled: true };
-    if (item.prop === 'attachments') {
-      return {
-        ...item,
-        slot: undefined,
-        component: 'ElInput',
-        componentProps: { ...disabledProps, placeholder: '暂无' },
-      };
-    }
-    return { ...item, componentProps: disabledProps };
-  }),
+  ...HIDDEN_DANGER_RECTIFY_FORM_CONFIG.map((item) => ({
+    ...item,
+    componentProps: { ...item.componentProps, disabled: true },
+  })),
   {
     prop: 'reviewComments',
     label: '复查意见:',

+ 8 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/hiddenTroubleAccountManagement.vue

@@ -105,9 +105,16 @@
                   <ActionButton text="查看" @click="handleView(scope.row.id)" />
                   <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                 </template>
-                <!-- 待入账 statusId=5:查看、扣分 -->
+                <!-- 待入账 statusId=5:编辑、删除、查看、下发、扣分(与待下发一致) -->
                 <template v-else-if="scope.row.statusId === 5">
+                  <ActionButton text="编辑" @click="handleEdit(scope.row.id)" />
+                  <ActionButton
+                    text="删除"
+                    :popconfirm="{ title: '确定要删除?' }"
+                    @confirm="handleDelete(scope.row.id)"
+                  />
                   <ActionButton text="查看" @click="handleView(scope.row.id)" />
+                  <ActionButton text="下发" @click="handleOpenIssue(scope.row.id)" />
                   <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                 </template>
                 <!-- 其他状态:无操作 -->

+ 1 - 0
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagement/components/OneByOneAuditDetail.vue

@@ -212,6 +212,7 @@
         id: id.value,
         statusId: 6,
         statusName: '已作废',
+        reviewReason: rejectReason.value?.trim() || undefined,
       });
       ElMessage.success('审核不通过操作成功');
       showRejectDialog.value = false;

+ 1 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagement/oneByOneManagement.vue

@@ -90,7 +90,7 @@
                 <!-- 待反馈 statusId=3 -->
                 <template v-else-if="scope.row.statusId === 3">
                   <ActionButton text="通知对象" @click="handleNotifyTarget(scope.row)" />
-                  <ActionButton text="发送" @click="handleSend(scope.row)" />
+                  <!-- <ActionButton text="发送" @click="handleSend(scope.row)" /> -->
                   <ActionButton
                     text="作废"
                     :popconfirm="{ title: '确定要作废该记录?' }"

+ 3 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagementDept/components/oneByOneManagementDeptDetail.vue

@@ -357,7 +357,9 @@
       await submitDrawLessonsDeptFeedback(feedbackForm.value);
       ElMessage.success('反馈提交成功');
       showFeedbackDialog.value = false;
-      getDetail();
+      router.push({
+        path: '/production-safety/hidden-trouble-investigation-and-governance/one-by-one-management-dept',
+      });
     } catch (e) {
       console.error('反馈提交失败:', e);
       ElMessage.error('反馈提交失败,请重试');

+ 6 - 1
src/views/production-safety/hiddenTroubleInvestigationAndGovernance/oneByOneManagementDept/oneByOneManagementDept.vue

@@ -69,7 +69,11 @@
             </template>
             <template #action="scope">
               <div class="action-container--div" style="justify-content: left">
-                <ActionButton text="反馈" @click="handleFeedback(scope.row.id)" />
+                <ActionButton
+                  v-if="scope.row.statusId === 3"
+                  text="反馈"
+                  @click="handleFeedback(scope.row.id)"
+                />
               </div>
             </template>
           </BasicTable>
@@ -160,6 +164,7 @@
         // 这里暂时共用管理员侧分页接口,后端如有部门侧接口再调整
         tableData.value = res.records.map((item: any) => ({
           id: item.id,
+          statusId: item.statusId,
           problem: item.problem,
           statusName: item.statusName,
           associationOtObligationDeptName: item.associationOtObligationDeptName,