Explorar el Código

fix: update code

sunqijun hace 3 meses
padre
commit
109d230adb

+ 1 - 1
src/router/routers/production-safety-router/responsibility-implementation.ts

@@ -1,6 +1,6 @@
  import { RouteComponent } from "vue-router";
  
- const responsibilityImplementationRoutes: RouteComponent[] = [{
+const responsibilityImplementationRoutes: RouteComponent[] = [{
       id: 9001,
       parentId: 9000,
       name: 'responsibilityImplementation',

+ 16 - 0
src/router/routers/production-safety-router/risk-identification-and-control.ts

@@ -258,6 +258,22 @@
             noCache: false,
           }
         },
+        // 施工作业安全审核
+        {
+          id: 93013,
+          parentId: 90014,
+          name: 'constructionSafetyManageAudit',
+          path: 'construction-safety-manage-audit',
+          component: '/production-safety/risk-identification-and-control/construction-safety-manage/audit',
+          meta: {
+            title: '施工作业安全审核',
+            activeMenu: '/work-safety/risk-identification-and-control/construction-safety-manage',
+            icon: 'OverviewIcon',
+            isRoot: false,
+            hidden: false,
+            noCache: false,
+          }
+        },
       ],
     }];
      

+ 1 - 0
src/router/routers/production-safety.ts

@@ -24,6 +24,7 @@ const productionSafetyRoutes = {
     ...productionSafetySystemRoutes,
     ...hiddenTroubleInvestigationAndGovernanceRoutes,
   ],
+  
 };
 
 export default productionSafetyRoutes;

+ 1 - 1
src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/add.vue

@@ -3,7 +3,7 @@
     <header class="safety-platform-container__header">
       <div class="breadcrumb-title">
         <BreadcrumbBack />
-        创建非公共区域责任清单
+        创建非公共区域责任区域
       </div>
     </header>
     <main class="safety-platform-container__main">

+ 5 - 3
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/add.vue

@@ -116,7 +116,7 @@
           <el-input
             v-model="formValue.safetyPersonContact"
             size="large"
-            placeholder="选择责任人后自动填充"
+            placeholder="请输入联系方式"
             style="width: 50%"
           />
         </el-form-item>
@@ -243,10 +243,9 @@
   };
 
   const syncUserName = (optionList, id: number, nameField: string) => {
-    console.log('opt:', optionList, id);
     const user = optionList?.find((u) => u.value === id);
     if (user) {
-      formValue[nameField] = user.value;
+      formValue[nameField] = user.label;
       console.log(formValue[nameField]);
     }
   };
@@ -265,12 +264,15 @@
   });
 
   const handleSubmit = () => {
+    console.log(formValue);
     formRef.value?.validate((valid: boolean) => {
       if (valid) {
         submiting.value = true;
         areaCheckListSavaArea({
           ...formValue,
           type: 2,
+          safetyResponsibleDepartmentId: JSON.stringify(formValue.safetyResponsibleDepartmentId),
+          safetyResponsibleCenterId: JSON.stringify(formValue.safetyResponsibleCenterId),
         })
           .then(() => {
             ElMessage.success('创建成功!');

+ 93 - 96
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/change.vue

@@ -8,67 +8,72 @@
     </header>
     <main class="safety-platform-container__main">
       <el-form ref="formRef" label-width="auto" :model="formValue" :rules="rules">
-        <el-form-item label="楼号" prop="buildingNo">
+        <el-form-item label="楼号">
           <el-input v-model="formValue.buildingNo" disabled size="large" style="width: 50%" />
         </el-form-item>
-        <el-form-item label="楼宇/区域" prop="buildingArea">
+        <el-form-item label="楼宇/区域">
           <el-input v-model="formValue.buildingArea" disabled size="large" style="width: 50%" />
         </el-form-item>
-        <el-form-item label="楼层/房号" prop="floorRoomNo">
+        <el-form-item label="楼层/房号">
           <el-input v-model="formValue.floorRoomNo" disabled size="large" style="width: 50%" />
         </el-form-item>
-        <el-form-item label="名称/功能" prop="nameFunction">
+        <el-form-item label="名称/功能">
           <el-input v-model="formValue.nameFunction" disabled size="large" style="width: 50%" />
         </el-form-item>
 
-        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
-          <el-select v-model="formValue.safetyResponsibleCenter" disabled size="large" style="width: 50%">
-            <el-option
-              v-for="item in firstLevelDepts"
-              :key="item.hrIdtOrgId"
-              :label="item.deptName"
-              :value="item.deptName"
-            />
-          </el-select>
+        <el-form-item label="安全责任所/中心">
+          <el-cascader
+            v-model="formValue.safetyResponsibleCenterId"
+            disabled
+            style="width: 50%"
+            size="large"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+          />
         </el-form-item>
 
-        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+        <el-form-item label="安全责任所/中心负责人">
           <el-select v-model="formValue.safetyCenterManager" disabled size="large" style="width: 50%">
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+            <el-option
+              v-for="item in oldCenterManagerOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
           </el-select>
         </el-form-item>
 
-        <h5 style="margin: 30px 0">信息变更</h5>
+        <h5 style="margin: 30px 0; font-weight: bold; color: #409eff">信息变更</h5>
 
         <el-form-item label="变更后的安全责任部门" prop="safetyResponsibleDepartmentTodo">
-          <el-select
-            v-model="formValue.safetyResponsibleDepartmentTodo"
-            placeholder="请选择新的责任部门"
-            size="large"
+          <el-cascader
+            v-model="formValue.safetyResponsibleDepartmentIdTodo"
             style="width: 50%"
+            size="large"
+            :ref="(el) => (cascaderRef['safetyResponsibleDepartmentTodo'] = el)"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择新的责任部门"
             filterable
             clearable
-          >
-            <el-option
-              v-for="item in firstLevelDepts"
-              :key="item.hrIdtOrgId"
-              :label="item.deptName"
-              :value="item.deptName"
-            />
-          </el-select>
+            @change="(val) => handleChangeDept(val, 'safetyResponsibleDepartmentTodo')"
+          />
         </el-form-item>
 
         <el-form-item label="变更后的安全具体责任人" prop="safetySpecificPersonTodo">
           <el-select
+            :disabled="!todoUserOptions.length"
             v-model="formValue.safetySpecificPersonTodo"
             placeholder="请选择新的具体责任人"
             size="large"
             style="width: 50%"
             filterable
             clearable
-            @change="(val) => syncUserName(val, 'safetySpecificPersonTodo')"
+            @change="(val) => syncUserName(todoUserOptions, val, 'safetySpecificPersonNameTodo')"
           >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+            <el-option v-for="item in todoUserOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
 
@@ -76,7 +81,7 @@
           <el-input
             v-model="formValue.changeReason"
             type="textarea"
-            :rows="7"
+            :rows="5"
             placeholder="请详细描述变更原因"
             style="width: 70%"
             maxlength="200"
@@ -94,102 +99,131 @@
 </template>
 
 <script lang="ts" setup>
-  import { ref, reactive, nextTick, onMounted } from 'vue';
+  import { ref, reactive, onMounted, nextTick } from 'vue';
   import { useRouter, useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import { getAllDepartments } from '@/api/auth/dept';
   import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
   import {
-    queryUserPageByUsername,
     areaCheckListQueryDetail,
     areaCheckListChange,
+    queryAvailableUserList,
   } from '@/api/production-safety/responsibility-implementation';
-  import { getUserList } from '@/api/system/user-operate';
 
   const router = useRouter();
   const route = useRoute();
   const formRef = ref<any>(null);
   const submiting = ref(false);
 
-  const userOptions = ref<any[]>([]);
+  // 数据源
   const firstLevelDepts = ref<any[]>([]);
+  const oldCenterManagerOptions = ref<any[]>([]); // 旧负责人数据源
+  const todoUserOptions = ref<any[]>([]); // 新负责人下拉数据源
+  const cascaderRef = ref({});
+  const cascaderProp = { expandTrigger: 'click', checkStrictly: true, value: 'id', label: 'deptName' };
 
   const formValue = reactive({
+    id: undefined,
     buildingNo: '',
     buildingArea: '',
     floorRoomNo: '',
     nameFunction: '',
+    // 旧数据
     safetyResponsibleCenter: '',
+    safetyResponsibleCenterId: [],
     safetyCenterManager: null as number | null,
-    safetyResponsibleDepartment: '',
-    safetyDepartmentManager: null as number | null,
-    safetySpecificPerson: null as number | null,
-    safetyPersonContact: '',
-
+    // 变更数据
     safetyResponsibleDepartmentTodo: '',
+    safetyResponsibleDepartmentIdTodo: [],
     safetySpecificPersonTodo: null as number | null,
     safetySpecificPersonNameTodo: '',
     changeReason: '',
   });
 
   const rules = reactive({
-    safetyResponsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'blur' }],
+    safetyResponsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'change' }],
     safetySpecificPersonTodo: [{ required: true, message: '请选择变更后的具体责任人', trigger: 'change' }],
     changeReason: [{ required: true, message: '请输入变更原因', trigger: 'blur' }],
   });
 
+  // 获取部门树
   const getDeptData = async () => {
     const res = await getAllDepartments();
     firstLevelDepts.value = formatDeptTree(res);
   };
 
-  const getUserData = async () => {
-    const res: any = await getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} });
-    userOptions.value = (res.records || []).map((u: any) => ({
-      id: u.userId || u.id,
-      name: u.realName || u.username,
-    }));
+  // 获取用户列表封装
+  const getUserData = (optionList, deptName) => {
+    return queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: { deptName },
+    }).then((res: any) => {
+      optionList.value = (res.records || []).map((u: any) => ({
+        value: u.id,
+        label: u.realname,
+      }));
+    });
   };
 
-  const syncUserName = (id: number, field: string) => {
-    const user = userOptions.value.find((u) => u.id === id);
-    if (user && field === 'safetySpecificPersonTodo') {
-      formValue.safetySpecificPersonNameTodo = user.name;
+  // 级联选择处理
+  const handleChangeDept = (val, prop) => {
+    const cascader = cascaderRef.value?.[prop];
+    const deptInfo = cascader?.getCheckedNodes();
+    if (deptInfo?.length) {
+      formValue[prop] = deptInfo[0].label;
+      // 级联变更后清空已选人员并重新加载
+      formValue.safetySpecificPersonTodo = null;
+      getUserData(todoUserOptions, deptInfo[0].label);
     }
   };
 
+  const syncUserName = (optionList, id: number, nameField: string) => {
+    const user = optionList.find((u) => u.value === id);
+    if (user) formValue[nameField] = user.label;
+  };
+
+  // 详情回显
   const handlAreaCheckListQueryDetail = async () => {
     const id = route.query.id;
     if (!id) return;
+
     try {
       const res: any = await areaCheckListQueryDetail({ id });
       if (res) {
         Object.assign(formValue, res);
 
+        // 1. 解析旧部门级联路径
+        if (typeof res.safetyResponsibleCenterId === 'string') {
+          formValue.safetyResponsibleCenterId = JSON.parse(res.safetyResponsibleCenterId);
+        }
+
+        // 2. 加载旧负责人列表以显示名称
+        if (formValue.safetyResponsibleCenter) {
+          getUserData(oldCenterManagerOptions, formValue.safetyResponsibleCenter);
+        }
+
+        // 3. 纠正 ID 类型
         if (formValue.safetyCenterManager) formValue.safetyCenterManager = Number(formValue.safetyCenterManager);
-        if (formValue.safetySpecificPerson) formValue.safetySpecificPerson = Number(formValue.safetySpecificPerson);
       }
     } catch (err) {
-      ElMessage.error('详情加载失败');
+      ElMessage.error('加载详情失败');
     }
   };
 
   onMounted(async () => {
-    submiting.value = true;
     await getDeptData();
-    await getUserData();
     await handlAreaCheckListQueryDetail();
-    submiting.value = false;
   });
 
   const handleSubmit = () => {
     formRef.value?.validate((valid: boolean) => {
       if (valid) {
         submiting.value = true;
-
         const submitData = {
           id: Number(route.query.id),
           safetyResponsibleDepartmentTodo: formValue.safetyResponsibleDepartmentTodo,
+          safetyResponsibleDepartmentIdTodo: JSON.stringify(formValue.safetyResponsibleDepartmentIdTodo), // 根据接口需求决定是否 stringify
           safetySpecificPersonTodo: formValue.safetySpecificPersonTodo,
           safetySpecificPersonNameTodo: formValue.safetySpecificPersonNameTodo,
           changeReason: formValue.changeReason,
@@ -200,51 +234,14 @@
             ElMessage.success('变更申请提交成功!');
             router.push({ name: 'listResponsibilities:nonPublic' });
           })
-          .finally(() => {
-            submiting.value = false;
-          });
+          .finally(() => (submiting.value = false));
       }
     });
   };
 </script>
+
 <style lang="scss" scoped>
   @use '@/styles/page-main-layout.scss' as *;
   @use '@/styles/page-details-layout.scss' as *;
   @use '@/styles/basic-table-action.scss' as *;
-  .editor-container {
-    border: 1px solid #dcdfe6;
-    border-radius: 4px;
-    margin-right: 20px;
-    overflow: hidden;
-
-    // :deep(.w-e-text-container) {
-    //   min-height: 400px;
-    //   overflow-y: auto;
-    // }
-  }
-  // :deep(.breadcrumb .title) {
-  //   margin-left: 0;
-  // }
-
-  // .main {
-  //   display: flex;
-  //   flex-direction: column;
-  //   padding: 20px;
-  //   flex: 1;
-  //   overflow: hidden;
-  //   background-color: #fff;
-  // }
-  // .button-content {
-  //   margin-bottom: 20px;
-  // }
-
-  // .page-content {
-  //   display: flex;
-  //   justify-content: flex-end;
-  // }
-  // // :deep(.el-form) {
-  // //   flex: 1;
-  // //   overflow: hidden;
-  // //   overflow-y: auto;
-  // // }
 </style>

+ 119 - 82
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/edit.vue

@@ -22,20 +22,18 @@
         </el-form-item>
 
         <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
-          <el-select
-            v-model="formValue.safetyResponsibleCenter"
-            placeholder="请选择"
-            size="large"
+          <el-cascader
+            v-model="formValue.safetyResponsibleCenterId"
             style="width: 50%"
+            size="large"
+            :ref="(el) => (cascaderRef['safetyResponsibleCenter'] = el)"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择安全责任部门"
             filterable
-          >
-            <el-option
-              v-for="item in firstLevelDepts"
-              :key="item.hrIdtOrgId"
-              :label="item.deptName"
-              :value="item.deptName"
-            />
-          </el-select>
+            @change="(val) => handleChangeDept(val, 'safetyResponsibleCenter')"
+          />
         </el-form-item>
 
         <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
@@ -45,27 +43,30 @@
             size="large"
             style="width: 50%"
             filterable
-            @change="(val) => syncUserName(val, 'safetyCenterManagerName')"
+            @change="(val) => syncUserName(safetyCenterManagerOptions, val, 'safetyCenterManagerName')"
           >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+            <el-option
+              v-for="item in safetyCenterManagerOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
           </el-select>
         </el-form-item>
 
         <el-form-item label="安全责任部门" prop="safetyResponsibleDepartment">
-          <el-select
-            v-model="formValue.safetyResponsibleDepartment"
-            placeholder="请选择"
-            size="large"
+          <el-cascader
+            v-model="formValue.safetyResponsibleDepartmentId"
             style="width: 50%"
+            size="large"
+            :ref="(el) => (cascaderRef['safetyResponsibleDepartment'] = el)"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择安全责任部门"
             filterable
-          >
-            <el-option
-              v-for="item in firstLevelDepts"
-              :key="item.hrIdtOrgId"
-              :label="item.deptName"
-              :value="item.deptName"
-            />
-          </el-select>
+            @change="(val) => handleChangeDept(val, 'safetyResponsibleDepartment')"
+          />
         </el-form-item>
 
         <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
@@ -75,9 +76,9 @@
             size="large"
             style="width: 50%"
             filterable
-            @change="(val) => syncUserName(val, 'safetyDepartmentManagerName')"
+            @change="(val) => syncUserName(userOptions, val, 'safetyDepartmentManagerName')"
           >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
 
@@ -88,9 +89,9 @@
             size="large"
             style="width: 50%"
             filterable
-            @change="handleSpecificPersonChange"
+            @change="(val) => syncUserName(userOptions, val, 'safetySpecificPersonName')"
           >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
 
@@ -112,17 +113,16 @@
 </template>
 
 <script lang="ts" setup>
-  import { ref, reactive, onMounted } from 'vue';
+  import { ref, reactive, onMounted, nextTick } from 'vue';
   import { useRouter, useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import { getAllDepartments } from '@/api/auth/dept';
   import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
   import {
-    queryUserPageByUsername,
     areaCheckListQueryDetail,
     areaCheckListUpdateArea,
+    queryAvailableUserList,
   } from '@/api/production-safety/responsibility-implementation';
-  import { getUserList } from '@/api/system/user-operate';
 
   const router = useRouter();
   const route = useRoute();
@@ -130,17 +130,23 @@
   const submiting = ref(false);
 
   const userOptions = ref<any[]>([]);
+  const safetyCenterManagerOptions = ref<any[]>([]);
   const firstLevelDepts = ref<any[]>([]);
+  const cascaderRef = ref({});
+  const cascaderProp = { expandTrigger: 'click', checkStrictly: true, value: 'id', label: 'deptName' };
 
   const formValue = reactive({
+    id: undefined,
     buildingNo: '',
     buildingArea: '',
     floorRoomNo: '',
     nameFunction: '',
     safetyResponsibleCenter: '',
+    safetyResponsibleCenterId: [],
     safetyCenterManager: null as number | null,
     safetyCenterManagerName: '',
     safetyResponsibleDepartment: '',
+    safetyResponsibleDepartmentId: [],
     safetyDepartmentManager: null as number | null,
     safetyDepartmentManagerName: '',
     safetySpecificPerson: null as number | null,
@@ -153,93 +159,124 @@
     buildingArea: [{ required: true, message: '请输入楼宇/区域' }],
     floorRoomNo: [{ required: true, message: '请输入楼层/房号' }],
     nameFunction: [{ required: true, message: '请输入名称/功能' }],
-
     safetyResponsibleCenter: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
-    safetyCenterManager: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
-
+    safetyCenterManager: [{ required: true, message: '请选择负责人', trigger: 'change' }],
     safetyResponsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
-    safetyDepartmentManager: [{ required: true, message: '请选择安全责任部门负责人', trigger: 'change' }],
-
+    safetyDepartmentManager: [{ required: true, message: '请选择负责人', trigger: 'change' }],
     safetySpecificPerson: [{ required: true, message: '请选择安全具体责任人', trigger: 'change' }],
     safetyPersonContact: [
-      { required: true, message: '请输入安全具体责任人联系方式' },
-      { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码格式' },
+      { required: true, message: '请输入联系方式' },
+      { pattern: /^1[3-9]\d{9}$/, message: '格式不正确' },
     ],
   });
 
-  // 获取部门数据
   const getDeptData = () => {
     getAllDepartments().then((res) => {
       firstLevelDepts.value = formatDeptTree(res);
     });
   };
 
-  const getUserData = () => {
-    getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} }).then((res: any) => {
-      userOptions.value = (res.records || []).map((u: any) => ({
-        id: u.userId || u.id,
-        name: u.realName || u.username,
+  const getUserData = (optionList, deptName) => {
+    return queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: { deptName },
+    }).then((res: any) => {
+      optionList.value = (res.records || []).map((u: any) => ({
+        value: u.id,
+        label: u.realname,
+        mobile: u.mobile,
       }));
     });
   };
 
-  const syncUserName = (id: number, nameField: string) => {
-    const user = userOptions.value.find((u) => u.id === id);
-    if (user) formValue[nameField] = user.name;
+  const handleChangeDept = (val, prop) => {
+    const cascader = cascaderRef.value?.[prop];
+    const deptInfo = cascader?.getCheckedNodes();
+    if (deptInfo?.length) {
+      formValue[prop] = deptInfo[0].label;
+      handleQueryAvailableUserList(deptInfo[0].label, prop);
+    }
+  };
+
+  const handleQueryAvailableUserList = (value, prop) => {
+    if (prop === 'safetyResponsibleCenter') {
+      formValue.safetyCenterManager = null;
+      getUserData(safetyCenterManagerOptions, value);
+    } else {
+      formValue.safetySpecificPerson = null;
+      formValue.safetyDepartmentManager = null;
+      getUserData(userOptions, value);
+    }
   };
 
-  const handleSpecificPersonChange = (id: number) => {
-    const user = userOptions.value.find((u) => u.id === id);
+  const syncUserName = (optionList, id, nameField) => {
+    const user = optionList.find((u) => u.value === id);
     if (user) {
-      formValue.safetySpecificPersonName = user.name;
-      formValue.safetyPersonContact = user.mobile;
+      formValue[nameField] = user.label;
+      if (nameField === 'safetySpecificPersonName') formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  const handlAreaCheckListQueryDetail = async () => {
+    const id = route.query.id;
+    if (!id) return;
+
+    try {
+      const res: any = await areaCheckListQueryDetail({ id });
+      if (res) {
+        // 1. 基础赋值
+        Object.assign(formValue, res);
+
+        // 2. 解析 JSON 字符串格式的 ID 数组
+        try {
+          if (typeof res.safetyResponsibleCenterId === 'string') {
+            formValue.safetyResponsibleCenterId = JSON.parse(res.safetyResponsibleCenterId);
+          }
+          if (typeof res.safetyResponsibleDepartmentId === 'string') {
+            formValue.safetyResponsibleDepartmentId = JSON.parse(res.safetyResponsibleDepartmentId);
+          }
+        } catch (e) {
+          console.error('ID数组解析失败', e);
+        }
+
+        // 3. ID 类型纠正 (String to Number)
+        formValue.safetyCenterManager = res.safetyCenterManager ? Number(res.safetyCenterManager) : null;
+        formValue.safetyDepartmentManager = res.safetyDepartmentManager ? Number(res.safetyDepartmentManager) : null;
+        formValue.safetySpecificPerson = res.safetySpecificPerson ? Number(res.safetySpecificPerson) : null;
+
+        // 4. 立即同步加载人员列表,防止页面初次显示 ID 数字
+        if (formValue.safetyResponsibleCenter) {
+          getUserData(safetyCenterManagerOptions, formValue.safetyResponsibleCenter);
+        }
+        if (formValue.safetyResponsibleDepartment) {
+          getUserData(userOptions, formValue.safetyResponsibleDepartment);
+        }
+      }
+    } catch (err) {
+      ElMessage.error('详情获取失败');
     }
   };
 
   onMounted(() => {
     getDeptData();
-    getUserData();
     handlAreaCheckListQueryDetail();
   });
 
   const handleSubmit = () => {
-    formRef.value?.validate((valid: boolean) => {
+    formRef.value?.validate((valid) => {
       if (valid) {
         submiting.value = true;
-        areaCheckListUpdateArea({
-          ...formValue,
-          type: 2,
-        })
+        // 提交时后端通常接受字符串形式,如果后端要数组,则直接传 formValue
+        areaCheckListUpdateArea({ ...formValue, type: 2 })
           .then(() => {
             ElMessage.success('编辑成功!');
             router.push({ name: 'listResponsibilities:nonPublic' });
           })
-          .finally(() => {
-            submiting.value = false;
-          });
+          .finally(() => (submiting.value = false));
       }
     });
   };
-
-  const handlAreaCheckListQueryDetail = () => {
-    const id = route.query.id;
-    if (!id) return;
-
-    areaCheckListQueryDetail({ id })
-      .then((res: any) => {
-        if (res) {
-          Object.assign(formValue, res);
-          if (formValue.safetyCenterManager) formValue.safetyCenterManager = Number(formValue.safetyCenterManager);
-          if (formValue.safetyDepartmentManager)
-            formValue.safetyDepartmentManager = Number(formValue.safetyDepartmentManager);
-          if (formValue.safetySpecificPerson) formValue.safetySpecificPerson = Number(formValue.safetySpecificPerson);
-        }
-      })
-      .catch((err) => {
-        ElMessage.error('获取详情失败');
-        console.error(err);
-      });
-  };
 </script>
 <style lang="scss" scoped>
   @use '@/styles/page-main-layout.scss' as *;

+ 95 - 201
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/view.vue

@@ -7,124 +7,69 @@
       </div>
     </header>
     <main class="safety-platform-container__main">
-      <el-form ref="formRef" label-width="auto" :model="formValue" :rules="rules">
-        <el-form-item label="楼号" prop="buildingNo">
-          <el-input disabled v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+      <el-form ref="formRef" label-width="auto" :model="formValue">
+        <el-form-item label="楼号">
+          <el-input disabled v-model="formValue.buildingNo" size="large" style="width: 50%" />
         </el-form-item>
-        <el-form-item label="楼宇/区域" prop="buildingArea">
-          <el-input
-            disabled
-            v-model="formValue.buildingArea"
-            size="large"
-            placeholder="请输入楼宇/区域"
-            style="width: 50%"
-          />
+        <el-form-item label="楼宇/区域">
+          <el-input disabled v-model="formValue.buildingArea" size="large" style="width: 50%" />
         </el-form-item>
-        <el-form-item label="楼层/房号" prop="floorRoomNo">
-          <el-input
-            disabled
-            v-model="formValue.floorRoomNo"
-            size="large"
-            placeholder="请输入楼层/房号"
-            style="width: 50%"
-          />
+        <el-form-item label="楼层/房号">
+          <el-input disabled v-model="formValue.floorRoomNo" size="large" style="width: 50%" />
         </el-form-item>
-        <el-form-item label="名称/功能" prop="nameFunction">
-          <el-input
+        <el-form-item label="名称/功能">
+          <el-input disabled v-model="formValue.nameFunction" size="large" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心">
+          <el-cascader
             disabled
-            v-model="formValue.nameFunction"
-            size="large"
-            placeholder="请输入名称/功能"
+            v-model="formValue.safetyResponsibleCenterId"
             style="width: 50%"
+            size="large"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
           />
         </el-form-item>
 
-        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
-          <el-select
-            disabled
-            v-model="formValue.safetyResponsibleCenter"
-            placeholder="请选择"
-            size="large"
-            style="width: 50%"
-            filterable
-          >
+        <el-form-item label="安全责任所/中心负责人">
+          <el-select disabled v-model="formValue.safetyCenterManager" size="large" style="width: 50%">
             <el-option
-              v-for="item in firstLevelDepts"
-              :key="item.hrIdtOrgId"
-              :label="item.deptName"
-              :value="item.deptName"
+              v-for="item in safetyCenterManagerOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
             />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
-          <el-select
+        <el-form-item label="安全责任部门">
+          <el-cascader
             disabled
-            v-model="formValue.safetyCenterManager"
-            placeholder="请选择"
-            size="large"
+            v-model="formValue.safetyResponsibleDepartmentId"
             style="width: 50%"
-            filterable
-            @change="(val) => syncUserName(val, 'safetyCenterManagerName')"
-          >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
-          </el-select>
-        </el-form-item>
-
-        <el-form-item label="安全责任部门" prop="safetyResponsibleDepartment">
-          <el-select
-            disabled
-            v-model="formValue.safetyResponsibleDepartment"
-            placeholder="请选择"
             size="large"
-            style="width: 50%"
-            filterable
-          >
-            <el-option
-              v-for="item in firstLevelDepts"
-              :key="item.hrIdtOrgId"
-              :label="item.deptName"
-              :value="item.deptName"
-            />
-          </el-select>
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+          />
         </el-form-item>
 
-        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
-          <el-select
-            disabled
-            v-model="formValue.safetyDepartmentManager"
-            placeholder="请选择"
-            size="large"
-            style="width: 50%"
-            filterable
-            @change="(val) => syncUserName(val, 'safetyDepartmentManagerName')"
-          >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+        <el-form-item label="安全责任部门负责人">
+          <el-select disabled v-model="formValue.safetyDepartmentManager" size="large" style="width: 50%">
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
-          <el-select
-            disabled
-            v-model="formValue.safetySpecificPerson"
-            placeholder="请选择"
-            size="large"
-            style="width: 50%"
-            filterable
-            @change="handleSpecificPersonChange"
-          >
-            <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
+        <el-form-item label="安全具体责任人">
+          <el-select disabled v-model="formValue.safetySpecificPerson" size="large" style="width: 50%">
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
-          <el-input
-            disabled
-            v-model="formValue.safetyPersonContact"
-            size="large"
-            placeholder="选择责任人后自动填充"
-            style="width: 50%"
-          />
+        <el-form-item label="安全具体责任人联系方式">
+          <el-input disabled v-model="formValue.safetyPersonContact" size="large" style="width: 50%" />
         </el-form-item>
       </el-form>
     </main>
@@ -136,24 +81,21 @@
 
 <script lang="ts" setup>
   import { ref, reactive, onMounted } from 'vue';
-  import { useRouter, useRoute } from 'vue-router';
+  import { useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import { getAllDepartments } from '@/api/auth/dept';
   import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
   import {
-    queryUserPageByUsername,
-    areaCheckListSavaArea,
     areaCheckListQueryDetail,
+    queryAvailableUserList,
   } from '@/api/production-safety/responsibility-implementation';
-  import { getUserList } from '@/api/system/user-operate';
 
-  const router = useRouter();
   const route = useRoute();
-  const formRef = ref<any>(null);
-  const submiting = ref(false);
 
   const userOptions = ref<any[]>([]);
+  const safetyCenterManagerOptions = ref<any[]>([]);
   const firstLevelDepts = ref<any[]>([]);
+  const cascaderProp = { value: 'id', label: 'deptName', checkStrictly: true };
 
   const formValue = reactive({
     buildingNo: '',
@@ -161,128 +103,80 @@
     floorRoomNo: '',
     nameFunction: '',
     safetyResponsibleCenter: '',
+    safetyResponsibleCenterId: [],
     safetyCenterManager: null as number | null,
-    safetyCenterManagerName: '',
     safetyResponsibleDepartment: '',
+    safetyResponsibleDepartmentId: [],
     safetyDepartmentManager: null as number | null,
-    safetyDepartmentManagerName: '',
     safetySpecificPerson: null as number | null,
-    safetySpecificPersonName: '',
     safetyPersonContact: '',
   });
 
-  const rules = reactive({
-    buildingNo: [{ required: true, message: '请输入楼号' }],
-    buildingArea: [{ required: true, message: '请输入楼宇/区域' }],
-    floorRoomNo: [{ required: true, message: '请输入楼层/房号' }],
-    nameFunction: [{ required: true, message: '请输入名称/功能' }],
-
-    safetyResponsibleCenter: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
-    safetyCenterManager: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
-
-    safetyResponsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
-    safetyDepartmentManager: [{ required: true, message: '请选择安全责任部门负责人', trigger: 'change' }],
-
-    safetySpecificPerson: [{ required: true, message: '请选择安全具体责任人', trigger: 'change' }],
-    safetyPersonContact: [
-      { required: true, message: '请输入安全具体责任人联系方式' },
-      { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码格式' },
-    ],
-  });
-
-  // 获取部门数据
-  const getDeptData = () => {
-    getAllDepartments().then((res) => {
-      firstLevelDepts.value = formatDeptTree(res);
-    });
+  const getDeptData = async () => {
+    const res = await getAllDepartments();
+    firstLevelDepts.value = formatDeptTree(res);
   };
 
-  const getUserData = () => {
-    getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} }).then((res: any) => {
-      userOptions.value = (res.records || []).map((u: any) => ({
-        id: u.userId || u.id,
-        name: u.realName || u.username,
+  const getUserData = (optionList: any, deptName: string) => {
+    return queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: { deptName },
+    }).then((res: any) => {
+      optionList.value = (res.records || []).map((u: any) => ({
+        value: u.id,
+        label: u.realname,
       }));
     });
   };
 
-  const syncUserName = (id: number, nameField: string) => {
-    const user = userOptions.value.find((u) => u.id === id);
-    if (user) formValue[nameField] = user.name;
-  };
+  const handlAreaCheckListQueryDetail = async () => {
+    const id = route.query.id;
+    if (!id) return;
 
-  const handleSpecificPersonChange = (id: number) => {
-    const user = userOptions.value.find((u) => u.id === id);
-    if (user) {
-      formValue.safetySpecificPersonName = user.name;
-      formValue.safetyPersonContact = user.mobile;
+    try {
+      const res: any = await areaCheckListQueryDetail({ id });
+      if (res) {
+        Object.assign(formValue, res);
+
+        // 1. 解析级联 ID 数组
+        try {
+          if (typeof res.safetyResponsibleCenterId === 'string') {
+            formValue.safetyResponsibleCenterId = JSON.parse(res.safetyResponsibleCenterId);
+          }
+          if (typeof res.safetyResponsibleDepartmentId === 'string') {
+            formValue.safetyResponsibleDepartmentId = JSON.parse(res.safetyResponsibleDepartmentId);
+          }
+        } catch (e) {
+          console.error('解析部门ID路径失败', e);
+        }
+
+        // 2. 类型转换
+        formValue.safetyCenterManager = res.safetyCenterManager ? Number(res.safetyCenterManager) : null;
+        formValue.safetyDepartmentManager = res.safetyDepartmentManager ? Number(res.safetyDepartmentManager) : null;
+        formValue.safetySpecificPerson = res.safetySpecificPerson ? Number(res.safetySpecificPerson) : null;
+
+        // 3. 补全人员名单以显示姓名
+        if (formValue.safetyResponsibleCenter) {
+          getUserData(safetyCenterManagerOptions, formValue.safetyResponsibleCenter);
+        }
+        if (formValue.safetyResponsibleDepartment) {
+          getUserData(userOptions, formValue.safetyResponsibleDepartment);
+        }
+      }
+    } catch (err) {
+      ElMessage.error('获取详情失败');
     }
   };
 
-  onMounted(() => {
-    getDeptData();
-    getUserData();
+  onMounted(async () => {
+    await getDeptData();
     handlAreaCheckListQueryDetail();
   });
-
-  const handlAreaCheckListQueryDetail = () => {
-    const id = route.query.id;
-    if (!id) return;
-
-    areaCheckListQueryDetail({ id })
-      .then((res: any) => {
-        if (res) {
-          Object.assign(formValue, res);
-          if (formValue.safetyCenterManager) formValue.safetyCenterManager = Number(formValue.safetyCenterManager);
-          if (formValue.safetyDepartmentManager)
-            formValue.safetyDepartmentManager = Number(formValue.safetyDepartmentManager);
-          if (formValue.safetySpecificPerson) formValue.safetySpecificPerson = Number(formValue.safetySpecificPerson);
-        }
-      })
-      .catch((err) => {
-        ElMessage.error('获取详情失败');
-        console.error(err);
-      });
-  };
 </script>
+
 <style lang="scss" scoped>
   @use '@/styles/page-main-layout.scss' as *;
   @use '@/styles/page-details-layout.scss' as *;
   @use '@/styles/basic-table-action.scss' as *;
-  .editor-container {
-    border: 1px solid #dcdfe6;
-    border-radius: 4px;
-    margin-right: 20px;
-    overflow: hidden;
-
-    // :deep(.w-e-text-container) {
-    //   min-height: 400px;
-    //   overflow-y: auto;
-    // }
-  }
-  // :deep(.breadcrumb .title) {
-  //   margin-left: 0;
-  // }
-
-  // .main {
-  //   display: flex;
-  //   flex-direction: column;
-  //   padding: 20px;
-  //   flex: 1;
-  //   overflow: hidden;
-  //   background-color: #fff;
-  // }
-  // .button-content {
-  //   margin-bottom: 20px;
-  // }
-
-  // .page-content {
-  //   display: flex;
-  //   justify-content: flex-end;
-  // }
-  // // :deep(.el-form) {
-  // //   flex: 1;
-  // //   overflow: hidden;
-  // //   overflow-y: auto;
-  // // }
 </style>

+ 5 - 0
src/views/production-safety/risk-identification-and-control/construction-safety-manage/audit.vue

@@ -0,0 +1,5 @@
+<template>
+  <div>
+    <h1>Audit</h1>
+  </div>
+</template>

+ 1 - 1
utils/devProxy/staff/proxy.ts

@@ -3,7 +3,7 @@ import path from 'path';
 
 // staff环境
 const proxyStaff: PROXY_TYPE = {
-  serverHost: 'http://192.168.6.42:8802/',
+  serverHost: 'http://192.168.21.154:8802/',
   // serverHost: 'http://192.168.20.4:8802/',
   skyeyeLoginHost: 'http://192.168.6.42:7000/skyeye-login/#/',
   skyeyePlatformHost: 'http://192.168.6.42:7000/skyeye-pc/#/',