ソースを参照

feat: 区域和非区域责任清单相关

sunqijun 3 ヶ月 前
コミット
beea9b998e
22 ファイル変更4454 行追加16 行削除
  1. 244 8
      src/router/routers/production-safety.ts
  2. 262 0
      src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/add.vue
  3. 250 0
      src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/change.vue
  4. 285 0
      src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/edit.vue
  5. 316 0
      src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/list.vue
  6. 288 0
      src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/view.vue
  7. 2 1
      src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/add.vue
  8. 2 2
      src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/change.vue
  9. 2 1
      src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/edit.vue
  10. 0 2
      src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/list.vue
  11. 0 1
      src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/review.vue
  12. 2 1
      src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/view.vue
  13. 262 0
      src/views/production-safety/implement-safety-duty/public-area-responsibilities/add.vue
  14. 250 0
      src/views/production-safety/implement-safety-duty/public-area-responsibilities/change.vue
  15. 286 0
      src/views/production-safety/implement-safety-duty/public-area-responsibilities/edit.vue
  16. 316 0
      src/views/production-safety/implement-safety-duty/public-area-responsibilities/list.vue
  17. 288 0
      src/views/production-safety/implement-safety-duty/public-area-responsibilities/view.vue
  18. 262 0
      src/views/production-safety/implement-safety-duty/public-list-responsibilities/add.vue
  19. 251 0
      src/views/production-safety/implement-safety-duty/public-list-responsibilities/change.vue
  20. 286 0
      src/views/production-safety/implement-safety-duty/public-list-responsibilities/edit.vue
  21. 311 0
      src/views/production-safety/implement-safety-duty/public-list-responsibilities/list.vue
  22. 289 0
      src/views/production-safety/implement-safety-duty/public-list-responsibilities/view.vue

+ 244 - 8
src/router/routers/production-safety.ts

@@ -193,12 +193,13 @@ const productionSafetyRoutes = {
       {
       {
 
 
         id: 90011,
         id: 90011,
-        parentId: 9001,
+        parentId: 90008,
         name: 'changeResponsibilities:nonPublic',
         name: 'changeResponsibilities:nonPublic',
         path: 'non-public-change-responsibilities',
         path: 'non-public-change-responsibilities',
         component: '/production-safety/implement-safety-duty/non-public-list-responsibilities/change',
         component: '/production-safety/implement-safety-duty/non-public-list-responsibilities/change',
         meta: {
         meta: {
           title: '变更非区域责任清单',
           title: '变更非区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/non-public-list-responsibilities',
           icon: 'OverviewIcon',
           icon: 'OverviewIcon',
           isRoot: false,
           isRoot: false,
           hidden: false,
           hidden: false,
@@ -209,12 +210,13 @@ const productionSafetyRoutes = {
       {
       {
 
 
         id: 90012,
         id: 90012,
-        parentId: 9001,
+        parentId: 90008,
         name: 'viewResponsibilities:nonPublic',
         name: 'viewResponsibilities:nonPublic',
         path: 'non-public-view-responsibilities',
         path: 'non-public-view-responsibilities',
         component: '/production-safety/implement-safety-duty/non-public-list-responsibilities/view',
         component: '/production-safety/implement-safety-duty/non-public-list-responsibilities/view',
         meta: {
         meta: {
           title: '查看非区域责任清单',
           title: '查看非区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/non-public-list-responsibilities',
           icon: 'OverviewIcon',
           icon: 'OverviewIcon',
           isRoot: false,
           isRoot: false,
           hidden: false,
           hidden: false,
@@ -222,22 +224,256 @@ const productionSafetyRoutes = {
 
 
         }
         }
       },
       },
+      // 责任区域
       {
       {
-
         id: 90013,
         id: 90013,
         parentId: 9001,
         parentId: 9001,
-        name: 'reviewResponsibilities:nonPublic',
-        path: 'non-public-review-responsibilities',
-        component: '/production-safety/implement-safety-duty/non-public-list-responsibilities/review',
+        name: 'areaResponsibilities:nonPublic',
+        path: 'non-public-area-responsibilities',
+        component: '/production-safety/implement-safety-duty/non-public-area-responsibilities/list',
+        meta: {
+          title: '责任区域',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+
+      {
+        id: 90014,
+        parentId: 90008,
+        name: 'areaAddResponsibilities:nonPublic',
+        path: 'non-public-area-add-responsibilities',
+        component: '/production-safety/implement-safety-duty/non-public-area-responsibilities/add',
+        meta: {
+          title: '新增非区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/non-public-area-responsibilities',
+          // icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+        }
+      },
+      {
+
+        id: 90015,
+        parentId: 90014,
+        name: 'areaEditResponsibilities:nonPublic',
+        path: 'non-public-area-edit-responsibilities',
+        component: '/production-safety/implement-safety-duty/non-public-area-responsibilities/edit',
+        meta: {
+          title: '编辑非区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/non-public-area-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      {
+
+        id: 90016,
+        parentId: 90014,
+        name: 'areaChangeResponsibilities:nonPublic',
+        path: 'non-public-area-change-responsibilities',
+        component: '/production-safety/implement-safety-duty/non-public-area-responsibilities/change',
+        meta: {
+          title: '变更非区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/non-public-area-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      {
+
+        id: 90017,
+        parentId: 90014,
+        name: 'areaViewResponsibilities:nonPublic',
+        path: 'non-public-area-view-responsibilities',
+        component: '/production-safety/implement-safety-duty/non-public-area-responsibilities/view',
+        meta: {
+          title: '查看非区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/non-public-area-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      // 责任清单(公共区域)
+      {
+        id: 90020,
+        parentId: 9001,
+        name: 'listResponsibilities:public',
+        path: 'public-list-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-list-responsibilities/list',
+        meta: {
+          title: '责任清单',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+
+      {
+        id: 90021,
+        parentId: 90008,
+        name: 'addResponsibilities:public',
+        path: 'public-add-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-list-responsibilities/add',
+        meta: {
+          title: '新增区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-list-responsibilities',
+          // icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+        }
+      },
+      {
+
+        id: 90022,
+        parentId: 90008,
+        name: 'editResponsibilities:public',
+        path: 'public-edit-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-list-responsibilities/edit',
+        meta: {
+          title: '编辑区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-list-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      {
+
+        id: 90023,
+        parentId: 90008,
+        name: 'changeResponsibilities:public',
+        path: 'public-change-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-list-responsibilities/change',
+        meta: {
+          title: '变更区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-list-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      {
+
+        id: 90024,
+        parentId: 90008,
+        name: 'viewResponsibilities:public',
+        path: 'public-view-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-list-responsibilities/view',
+        meta: {
+          title: '查看区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-list-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      // 责任区域(公共区域)
+      {
+        id: 90030,
+        parentId: 9001,
+        name: 'areaResponsibilities:public',
+        path: 'public-area-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-area-responsibilities/list',
+        meta: {
+          title: '责任区域',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+
+      {
+        id: 90031,
+        parentId: 90008,
+        name: 'areaAddResponsibilities:public',
+        path: 'public-area-add-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-area-responsibilities/add',
+        meta: {
+          title: '新增区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-area-responsibilities',
+          // icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+        }
+      },
+      {
+
+        id: 90032,
+        parentId: 90014,
+        name: 'areaEditResponsibilities:public',
+        path: 'public-area-edit-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-area-responsibilities/edit',
         meta: {
         meta: {
-          title: '审核非区域责任清单',
+          title: '编辑区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-area-responsibilities',
           icon: 'OverviewIcon',
           icon: 'OverviewIcon',
           isRoot: false,
           isRoot: false,
           hidden: false,
           hidden: false,
           noCache: false,
           noCache: false,
 
 
         }
         }
-      }]
+      },
+      {
+
+        id: 90033,
+        parentId: 90014,
+        name: 'areaChangeResponsibilities:public',
+        path: 'public-area-change-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-area-responsibilities/change',
+        meta: {
+          title: '变更区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-area-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+      {
+
+        id: 90034,
+        parentId: 90014,
+        name: 'areaViewResponsibilities:public',
+        path: 'public-area-view-responsibilities',
+        component: '/production-safety/implement-safety-duty/public-area-responsibilities/view',
+        meta: {
+          title: '查看区域责任清单',
+          activeMenu: '/work-safety/responsibility-implementation/public-area-responsibilities',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: false,
+          noCache: false,
+
+        }
+      },
+    ]
     }
     }
   ],
   ],
 };
 };

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

@@ -0,0 +1,262 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        创建非公共区域责任清单
+      </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 v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="请输入楼宇/区域" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" size="large" placeholder="请输入楼层/房号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input v-model="formValue.nameFunction" size="large" placeholder="请输入名称/功能" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
+          <el-input
+            v-model="formValue.safetyPersonContact"
+            size="large"
+            placeholder="选择责任人后自动填充"
+            style="width: 50%"
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:nonPublic' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { ElMessage } from 'element-plus';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+  import { getUserList } from '@/api/system/user-operate';
+
+  import {
+    queryUserPageByUsername,
+    areaCheckListSavaArea,
+  } from '@/api/production-safety/responsibility-implementation';
+
+  const router = useRouter();
+  const formRef = ref<any>(null);
+  const submiting = ref(false);
+
+  const userOptions = ref<any[]>([]);
+  const firstLevelDepts = ref<any[]>([]);
+
+  const formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        areaCheckListSavaArea({
+          ...formValue,
+          type: 2,
+        })
+          .then(() => {
+            ElMessage.success('创建成功!');
+            router.push({ name: 'areaResponsibilities:nonPublic' });
+          })
+          .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>

+ 250 - 0
src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/change.vue

@@ -0,0 +1,250 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        变更非公共区域责任清单
+      </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 v-model="formValue.buildingNo" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <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>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <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-select>
+        </el-form-item>
+
+        <h5 style="margin: 30px 0">信息变更</h5>
+
+        <el-form-item label="变更后的安全责任部门" prop="safetyResponsibleDepartmentTodo">
+          <el-select
+            v-model="formValue.safetyResponsibleDepartmentTodo"
+            placeholder="请选择新的责任部门"
+            size="large"
+            style="width: 50%"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in firstLevelDepts"
+              :key="item.hrIdtOrgId"
+              :label="item.deptName"
+              :value="item.deptName"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="变更后的安全具体责任人" prop="safetySpecificPersonTodo">
+          <el-select
+            v-model="formValue.safetySpecificPersonTodo"
+            placeholder="请选择新的具体责任人"
+            size="large"
+            style="width: 50%"
+            filterable
+            clearable
+            @change="(val) => syncUserName(val, 'safetySpecificPersonTodo')"
+          >
+            <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="changeReason">
+          <el-input
+            v-model="formValue.changeReason"
+            type="textarea"
+            :rows="7"
+            placeholder="请详细描述变更原因"
+            style="width: 70%"
+            maxlength="200"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:nonPublic' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交变更</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, nextTick, onMounted } 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,
+  } 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 formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyResponsibleDepartment: '',
+    safetyDepartmentManager: null as number | null,
+    safetySpecificPerson: null as number | null,
+    safetyPersonContact: '',
+
+    safetyResponsibleDepartmentTodo: '',
+    safetySpecificPersonTodo: null as number | null,
+    safetySpecificPersonNameTodo: '',
+    changeReason: '',
+  });
+
+  const rules = reactive({
+    safetyResponsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'blur' }],
+    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 syncUserName = (id: number, field: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user && field === 'safetySpecificPersonTodo') {
+      formValue.safetySpecificPersonNameTodo = user.name;
+    }
+  };
+
+  const handlAreaCheckListQueryDetail = async () => {
+    const id = route.query.id;
+    if (!id) return;
+    try {
+      const res: any = await areaCheckListQueryDetail({ id });
+      if (res) {
+        Object.assign(formValue, res);
+
+        if (formValue.safetyCenterManager) formValue.safetyCenterManager = Number(formValue.safetyCenterManager);
+        if (formValue.safetySpecificPerson) formValue.safetySpecificPerson = Number(formValue.safetySpecificPerson);
+      }
+    } catch (err) {
+      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,
+          safetySpecificPersonTodo: formValue.safetySpecificPersonTodo,
+          safetySpecificPersonNameTodo: formValue.safetySpecificPersonNameTodo,
+          changeReason: formValue.changeReason,
+        };
+
+        areaCheckListChange(submitData)
+          .then(() => {
+            ElMessage.success('变更申请提交成功!');
+            router.push({ name: 'areaResponsibilities:nonPublic' });
+          })
+          .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>

+ 285 - 0
src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/edit.vue

@@ -0,0 +1,285 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        编辑非公共区域责任清单
+      </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 v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="请输入楼宇/区域" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" size="large" placeholder="请输入楼层/房号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input v-model="formValue.nameFunction" size="large" placeholder="请输入名称/功能" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
+          <el-input
+            v-model="formValue.safetyPersonContact"
+            size="large"
+            placeholder="选择责任人后自动填充"
+            style="width: 50%"
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:nonPublic' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } 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,
+    areaCheckListSavaArea,
+    areaCheckListQueryDetail,
+    areaCheckListUpdateArea,
+  } 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 formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+    handlAreaCheckListQueryDetail();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        areaCheckListSavaArea({
+          ...formValue,
+          type: 2,
+        })
+          .then(() => {
+            ElMessage.success('编辑成功!');
+            router.push({ name: 'areaResponsibilities:nonPublic' });
+          })
+          .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 *;
+  @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>

+ 316 - 0
src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/list.vue

@@ -0,0 +1,316 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+        <el-tab-pane label="公共区域" :name="1" />
+        <el-tab-pane label="非公共区域" :name="2" />
+      </el-tabs>
+    </header>
+    <main class="safety-platform-container__main">
+      <div class="search-form">
+        <el-form :inline="true">
+          <el-form-item label="功能名称">
+            <el-input
+              v-model="queryParams.queryParam.nameFunction"
+              placeholder="搜索安全责任书名称"
+              style="width: 170px"
+            />
+          </el-form-item>
+          <el-form-item label="状态">
+            <el-select v-model="queryParams.queryParam.status" clearable placeholder="状态" style="width: 170px">
+              <el-option :value="1" label="正常" />
+              <el-option :value="2" label="待确认" />
+              <el-option :value="3" label="已拒绝" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+
+        <div>
+          <el-button @click="batchImportVisible = true">导入</el-button>
+          <el-button type="primary" @click="handleDownload">导出</el-button>
+          <el-button
+            type="primary"
+            @click="
+              $router.push({
+                name: 'areaAddResponsibilities:nonPublic',
+              })
+            "
+            >添加
+          </el-button>
+          <el-button type="primary" @click="queryTableList">查询</el-button>
+          <el-button @click="handleRestParams">重置</el-button>
+        </div>
+      </div>
+
+      <div class="table-content">
+        <el-table :data="tableData.data">
+          <el-table-column type="index" label="序号" width="80" />
+          <el-table-column label="楼号" prop="buildingCode" width="80" />
+          <el-table-column label="楼层" prop="buildingArea" width="100" />
+          <el-table-column label="房间/区域" prop="floorRoomNo" width="180" />
+          <el-table-column label="功能名称" prop="nameFunction" width="120" />
+          <el-table-column label="安全责任所/中心" prop="safetyResponsibleCenter" width="200" />
+          <el-table-column label="安全责任所/中心负责人" prop="safetyCenterManagerName" width="200" />
+          <el-table-column label="安全责任部门" prop="safetyResponsibleDepartment" width="180" />
+          <el-table-column label="安全责任部门负责人" prop="safetyDepartmentManagerName" width="180" />
+          <el-table-column label="安全具体责任人" prop="safetySpecificPersonName" width="180" />
+          <el-table-column label="安全具体责任人联系方式" prop="safetyPersonContact;" width="230" />
+          <el-table-column label="变更原因" prop="changeReason" width="170" />
+          <el-table-column label="状态" prop="statusName" width="100" />
+          <el-table-column fixed="right" min-width="240" label="操作">
+            <template #default="scope">
+              <div v-if="scope.row.status === 1">
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'areaEditResponsibilities:nonPublic',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >编辑
+                </el-button>
+                <el-popconfirm title="确定要删除吗?" @confirm="handleConfirmDeleteRow(scope)">
+                  <template #reference>
+                    <el-button type="primary" link>删除</el-button>
+                  </template>
+                </el-popconfirm>
+
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'areaViewResponsibilities:nonPublic',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >查看</el-button
+                >
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'areaChangeResponsibilities:nonPublic',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >变更</el-button
+                >
+              </div>
+              <div v-if="scope.row.canChange === true">
+                <el-button type="primary" link @click="handleAreaCheckListApprove(scope, 1)">确认</el-button>
+                <el-button type="primary" link @click="handleAreaCheckListApprove(scope, 0)">拒绝</el-button>
+              </div>
+              <div v-if="scope.row.status === 3">
+                <el-button type="primary" link>变更</el-button>
+                <el-button type="primary" link>查看</el-button>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div class="pagination-container" v-if="tableData.total > 0">
+        <el-pagination
+          background
+          :current-page="queryParams.pageNumber"
+          :page-size="queryParams.pageSize"
+          :total="tableData.total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </main>
+  </div>
+  <BatchImport
+    :visible="batchImportVisible"
+    :importApiUrl="importApiUrl"
+    :templateUrl="templateUrl"
+    :templateName="'责任清单-批量导入模版'"
+    @close="() => (batchImportVisible = false)"
+    @update="handleUpdate"
+  />
+</template>
+<script lang="ts" setup>
+  import { onMounted, ref, reactive } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import { useRouter } from 'vue-router';
+  import {
+    areaCheckListQueryPage,
+    areaCheckListApprove,
+    areaCheckListDelete,
+    areaCheckListExportArea,
+  } from '@/api/production-safety/responsibility-implementation';
+  import urlJoin from 'url-join';
+  import { BatchImport } from '@/components/batch-import';
+
+  import { downloadFile } from '@/views/disaster/utils';
+  import { useGlobSetting } from '@/hooks/setting';
+  import { useUserInfoHook } from '@/views/disaster/hooks';
+
+  const router = useRouter();
+  const activeTab = ref(2);
+  const { id } = useUserInfoHook();
+
+  const queryParams = reactive<any>({
+    pageNumber: 1,
+    pageSize: 10,
+    queryParam: {
+      type: 2,
+      nameFunction: '',
+      status: '',
+      responsibilityPersonId: id,
+    },
+  });
+
+  // 批量导入
+  const batchImportVisible = ref(false);
+  const { urlPrefix } = useGlobSetting();
+  const importApiUrl = ref(urlJoin(urlPrefix, '/areaCheckList/importArea?type=2'));
+  const templateUrl = ref('');
+
+  const handleUpdate = () => {
+    batchImportVisible.value = false;
+    queryTableList();
+  };
+
+  const tableData = reactive({
+    data: [],
+    total: 0,
+  });
+  const handleTabChange = (tab) => {
+    console.log(typeof tab);
+    if (tab === 1) {
+      //todo
+      router.push({
+        name: 'areaResponsibilities:public',
+      });
+    } else if (tab === 2) {
+      router.push({
+        name: 'areaResponsibilities:nonPublic',
+      });
+    }
+  };
+
+  async function handleDownload() {
+    // getQuery();
+    try {
+      const res = await areaCheckListExportArea(queryParams.queryParam);
+      if (res.size === 0) return;
+      const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+      const url = window.URL.createObjectURL(blob);
+      downloadFile(url, '责任清单.xlsx');
+    } catch (e) {
+      ElMessage.error('下载失败');
+      console.log(e);
+    }
+  }
+
+  const handleAreaCheckListApprove = (scope, approveType) => {
+    areaCheckListApprove({
+      id: scope.row.id,
+      approveType,
+      refuseReason: null,
+    }).then(() => {
+      ElMessage.success('操作成功!');
+      queryTableList();
+    });
+  };
+
+  const handleSizeChange = (value) => {};
+  const handleCurrentChange = (value) => {
+    queryParams.pageNumber = value;
+    queryTableList();
+  };
+
+  const handleConfirmDeleteRow = (scope) => {
+    areaCheckListDelete(scope.row.id).then(() => {
+      ElMessage.success('删除成功!');
+      queryTableList();
+    });
+  };
+  const queryTableList = () => {
+    areaCheckListQueryPage(queryParams).then((res) => {
+      tableData.data = res.records;
+      tableData.total = res.totalRow;
+    });
+  };
+  const handleRestParams = () => {
+    Object.assign(queryParams, {
+      pageNumber: 1,
+      pageSize: 10,
+      queryParam: {
+        ...queryParams.queryParam,
+        status: '',
+        nameFunction: '',
+      },
+    });
+    queryTableList();
+  };
+
+  onMounted(() => {
+    queryTableList();
+  });
+</script>
+
+<style lang="scss" scoped>
+  @use '@/styles/page-details-layout.scss' as *;
+  @use '@/styles/page-main-layout.scss' as *;
+  @use '@/styles/basic-table-action.scss' as *;
+
+  :deep(.el-tabs__header) {
+    margin: 0;
+  }
+  :deep(.el-tabs__item) {
+    font-size: 14px !important;
+  }
+  :deep(.flexContent) {
+    display: flex;
+  }
+  :deep(.breadcrumb .title) {
+    margin-left: 0;
+  }
+
+  :deep(.el-form) {
+    flex: 1;
+    display: flex;
+    row-gap: 15px;
+    flex-wrap: wrap;
+  }
+  :deep(.el-form-item) {
+    margin-bottom: 0;
+  }
+  :deep(main) {
+    display: flex;
+    flex-direction: column;
+  }
+  .search-form {
+    min-width: 800px;
+    display: flex;
+
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+  }
+
+  .button-content {
+    margin-bottom: 20px;
+  }
+  .table-content {
+    flex: 1;
+    overflow: hidden;
+    overflow-y: auto;
+  }
+  .page-content {
+    display: flex;
+    justify-content: flex-end;
+  }
+</style>

+ 288 - 0
src/views/production-safety/implement-safety-duty/non-public-area-responsibilities/view.vue

@@ -0,0 +1,288 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        查看非公共区域责任清单
+      </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-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input
+            disabled
+            v-model="formValue.buildingArea"
+            size="large"
+            placeholder="请输入楼宇/区域"
+            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>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input
+            disabled
+            v-model="formValue.nameFunction"
+            size="large"
+            placeholder="请输入名称/功能"
+            style="width: 50%"
+          />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            disabled
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            disabled
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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>
+        </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-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-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>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button type="primary" @click="$router.push({ name: 'areaResponsibilities:nonPublic' })">返回</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } 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,
+    areaCheckListSavaArea,
+    areaCheckListQueryDetail,
+  } 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 formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+    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>

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

@@ -121,6 +121,7 @@
     queryUserPageByUsername,
     queryUserPageByUsername,
     areaCheckListSavaArea,
     areaCheckListSavaArea,
   } from '@/api/production-safety/responsibility-implementation';
   } from '@/api/production-safety/responsibility-implementation';
+  import { getUserList } from '@/api/system/user-operate';
 
 
   const router = useRouter();
   const router = useRouter();
   const formRef = ref<any>(null);
   const formRef = ref<any>(null);
@@ -172,7 +173,7 @@
   };
   };
 
 
   const getUserData = () => {
   const getUserData = () => {
-    queryUserPageByUsername({ pageNumber: 1, pageSize: 20, queryParam: '' }).then((res: any) => {
+    getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} }).then((res: any) => {
       userOptions.value = (res.records || []).map((u: any) => ({
       userOptions.value = (res.records || []).map((u: any) => ({
         id: u.userId || u.id,
         id: u.userId || u.id,
         name: u.realName || u.username,
         name: u.realName || u.username,

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

@@ -104,6 +104,7 @@
     areaCheckListQueryDetail,
     areaCheckListQueryDetail,
     areaCheckListChange,
     areaCheckListChange,
   } from '@/api/production-safety/responsibility-implementation';
   } from '@/api/production-safety/responsibility-implementation';
+  import { getUserList } from '@/api/system/user-operate';
 
 
   const router = useRouter();
   const router = useRouter();
   const route = useRoute();
   const route = useRoute();
@@ -142,9 +143,8 @@
     firstLevelDepts.value = formatDeptTree(res);
     firstLevelDepts.value = formatDeptTree(res);
   };
   };
 
 
-  // 获取用户列表
   const getUserData = async () => {
   const getUserData = async () => {
-    const res: any = await queryUserPageByUsername({ pageNumber: 1, pageSize: 30, queryParam: '' });
+    const res: any = await getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} });
     userOptions.value = (res.records || []).map((u: any) => ({
     userOptions.value = (res.records || []).map((u: any) => ({
       id: u.userId || u.id,
       id: u.userId || u.id,
       name: u.realName || u.username,
       name: u.realName || u.username,

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

@@ -123,6 +123,7 @@
     areaCheckListQueryDetail,
     areaCheckListQueryDetail,
     areaCheckListUpdateArea,
     areaCheckListUpdateArea,
   } from '@/api/production-safety/responsibility-implementation';
   } from '@/api/production-safety/responsibility-implementation';
+  import { getUserList } from '@/api/system/user-operate';
 
 
   const router = useRouter();
   const router = useRouter();
   const route = useRoute();
   const route = useRoute();
@@ -175,7 +176,7 @@
   };
   };
 
 
   const getUserData = () => {
   const getUserData = () => {
-    queryUserPageByUsername({ pageNumber: 1, pageSize: 20, queryParam: '' }).then((res: any) => {
+    getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} }).then((res: any) => {
       userOptions.value = (res.records || []).map((u: any) => ({
       userOptions.value = (res.records || []).map((u: any) => ({
         id: u.userId || u.id,
         id: u.userId || u.id,
         name: u.realName || u.username,
         name: u.realName || u.username,

+ 0 - 2
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/list.vue

@@ -184,9 +184,7 @@
     total: 0,
     total: 0,
   });
   });
   const handleTabChange = (tab) => {
   const handleTabChange = (tab) => {
-    console.log(typeof tab);
     if (tab === 1) {
     if (tab === 1) {
-      //todo
       router.push({
       router.push({
         name: 'listResponsibilities:public',
         name: 'listResponsibilities:public',
       });
       });

+ 0 - 1
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/review.vue

@@ -1 +0,0 @@
-<template>review</template>

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

@@ -145,6 +145,7 @@
     areaCheckListSavaArea,
     areaCheckListSavaArea,
     areaCheckListQueryDetail,
     areaCheckListQueryDetail,
   } from '@/api/production-safety/responsibility-implementation';
   } from '@/api/production-safety/responsibility-implementation';
+  import { getUserList } from '@/api/system/user-operate';
 
 
   const router = useRouter();
   const router = useRouter();
   const route = useRoute();
   const route = useRoute();
@@ -197,7 +198,7 @@
   };
   };
 
 
   const getUserData = () => {
   const getUserData = () => {
-    queryUserPageByUsername({ pageNumber: 1, pageSize: 20, queryParam: '' }).then((res: any) => {
+    getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} }).then((res: any) => {
       userOptions.value = (res.records || []).map((u: any) => ({
       userOptions.value = (res.records || []).map((u: any) => ({
         id: u.userId || u.id,
         id: u.userId || u.id,
         name: u.realName || u.username,
         name: u.realName || u.username,

+ 262 - 0
src/views/production-safety/implement-safety-duty/public-area-responsibilities/add.vue

@@ -0,0 +1,262 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        创建非公共区域责任清单
+      </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 v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="请输入楼宇/区域" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" size="large" placeholder="请输入楼层/房号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input v-model="formValue.nameFunction" size="large" placeholder="请输入名称/功能" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
+          <el-input
+            v-model="formValue.safetyPersonContact"
+            size="large"
+            placeholder="选择责任人后自动填充"
+            style="width: 50%"
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:public' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { ElMessage } from 'element-plus';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+  import { getUserList } from '@/api/system/user-operate';
+
+  import {
+    queryUserPageByUsername,
+    areaCheckListSavaArea,
+  } from '@/api/production-safety/responsibility-implementation';
+
+  const router = useRouter();
+  const formRef = ref<any>(null);
+  const submiting = ref(false);
+
+  const userOptions = ref<any[]>([]);
+  const firstLevelDepts = ref<any[]>([]);
+
+  const formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        areaCheckListSavaArea({
+          ...formValue,
+          type: 1,
+        })
+          .then(() => {
+            ElMessage.success('创建成功!');
+            router.push({ name: 'areaResponsibilities:public' });
+          })
+          .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>

+ 250 - 0
src/views/production-safety/implement-safety-duty/public-area-responsibilities/change.vue

@@ -0,0 +1,250 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        变更非公共区域责任清单
+      </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 v-model="formValue.buildingNo" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <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>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <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-select>
+        </el-form-item>
+
+        <h5 style="margin: 30px 0">信息变更</h5>
+
+        <el-form-item label="变更后的安全责任部门" prop="safetyResponsibleDepartmentTodo">
+          <el-select
+            v-model="formValue.safetyResponsibleDepartmentTodo"
+            placeholder="请选择新的责任部门"
+            size="large"
+            style="width: 50%"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in firstLevelDepts"
+              :key="item.hrIdtOrgId"
+              :label="item.deptName"
+              :value="item.deptName"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="变更后的安全具体责任人" prop="safetySpecificPersonTodo">
+          <el-select
+            v-model="formValue.safetySpecificPersonTodo"
+            placeholder="请选择新的具体责任人"
+            size="large"
+            style="width: 50%"
+            filterable
+            clearable
+            @change="(val) => syncUserName(val, 'safetySpecificPersonTodo')"
+          >
+            <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="changeReason">
+          <el-input
+            v-model="formValue.changeReason"
+            type="textarea"
+            :rows="7"
+            placeholder="请详细描述变更原因"
+            style="width: 70%"
+            maxlength="200"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:public' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交变更</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, nextTick, onMounted } 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,
+  } 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 formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyResponsibleDepartment: '',
+    safetyDepartmentManager: null as number | null,
+    safetySpecificPerson: null as number | null,
+    safetyPersonContact: '',
+
+    safetyResponsibleDepartmentTodo: '',
+    safetySpecificPersonTodo: null as number | null,
+    safetySpecificPersonNameTodo: '',
+    changeReason: '',
+  });
+
+  const rules = reactive({
+    safetyResponsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'blur' }],
+    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 syncUserName = (id: number, field: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user && field === 'safetySpecificPersonTodo') {
+      formValue.safetySpecificPersonNameTodo = user.name;
+    }
+  };
+
+  const handlAreaCheckListQueryDetail = async () => {
+    const id = route.query.id;
+    if (!id) return;
+    try {
+      const res: any = await areaCheckListQueryDetail({ id });
+      if (res) {
+        Object.assign(formValue, res);
+
+        if (formValue.safetyCenterManager) formValue.safetyCenterManager = Number(formValue.safetyCenterManager);
+        if (formValue.safetySpecificPerson) formValue.safetySpecificPerson = Number(formValue.safetySpecificPerson);
+      }
+    } catch (err) {
+      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,
+          safetySpecificPersonTodo: formValue.safetySpecificPersonTodo,
+          safetySpecificPersonNameTodo: formValue.safetySpecificPersonNameTodo,
+          changeReason: formValue.changeReason,
+        };
+
+        areaCheckListChange(submitData)
+          .then(() => {
+            ElMessage.success('变更申请提交成功!');
+            router.push({ name: 'areaResponsibilities:public' });
+          })
+          .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>

+ 286 - 0
src/views/production-safety/implement-safety-duty/public-area-responsibilities/edit.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        编辑非公共区域责任清单
+      </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 v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="请输入楼宇/区域" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" size="large" placeholder="请输入楼层/房号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input v-model="formValue.nameFunction" size="large" placeholder="请输入名称/功能" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
+          <el-input
+            v-model="formValue.safetyPersonContact"
+            size="large"
+            placeholder="选择责任人后自动填充"
+            style="width: 50%"
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:public' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } 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,
+    areaCheckListSavaArea,
+    areaCheckListQueryDetail,
+    areaCheckListUpdateArea,
+  } 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 formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+    handlAreaCheckListQueryDetail();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        areaCheckListSavaArea({
+          ...formValue,
+          type: 1,
+        })
+          .then(() => {
+            ElMessage.success('编辑成功!');
+            router.push({ name: 'areaResponsibilities:public' });
+          })
+          .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 *;
+  @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>

+ 316 - 0
src/views/production-safety/implement-safety-duty/public-area-responsibilities/list.vue

@@ -0,0 +1,316 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+        <el-tab-pane label="公共区域" :name="1" />
+        <el-tab-pane label="非公共区域" :name="2" />
+      </el-tabs>
+    </header>
+    <main class="safety-platform-container__main">
+      <div class="search-form">
+        <el-form :inline="true">
+          <el-form-item label="功能名称">
+            <el-input
+              v-model="queryParams.queryParam.nameFunction"
+              placeholder="搜索安全责任书名称"
+              style="width: 170px"
+            />
+          </el-form-item>
+          <el-form-item label="状态">
+            <el-select v-model="queryParams.queryParam.status" clearable placeholder="状态" style="width: 170px">
+              <el-option :value="1" label="正常" />
+              <el-option :value="2" label="待确认" />
+              <el-option :value="3" label="已拒绝" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+
+        <div>
+          <el-button @click="batchImportVisible = true">导入</el-button>
+          <el-button type="primary" @click="handleDownload">导出</el-button>
+          <el-button
+            type="primary"
+            @click="
+              $router.push({
+                name: 'areaAddResponsibilities:public',
+              })
+            "
+            >添加
+          </el-button>
+          <el-button type="primary" @click="queryTableList">查询</el-button>
+          <el-button @click="handleRestParams">重置</el-button>
+        </div>
+      </div>
+
+      <div class="table-content">
+        <el-table :data="tableData.data">
+          <el-table-column type="index" label="序号" width="80" />
+          <el-table-column label="楼号" prop="buildingCode" width="80" />
+          <el-table-column label="楼层" prop="buildingArea" width="100" />
+          <el-table-column label="房间/区域" prop="floorRoomNo" width="180" />
+          <el-table-column label="功能名称" prop="nameFunction" width="120" />
+          <el-table-column label="安全责任所/中心" prop="safetyResponsibleCenter" width="200" />
+          <el-table-column label="安全责任所/中心负责人" prop="safetyCenterManagerName" width="200" />
+          <el-table-column label="安全责任部门" prop="safetyResponsibleDepartment" width="180" />
+          <el-table-column label="安全责任部门负责人" prop="safetyDepartmentManagerName" width="180" />
+          <el-table-column label="安全具体责任人" prop="safetySpecificPersonName" width="180" />
+          <el-table-column label="安全具体责任人联系方式" prop="safetyPersonContact;" width="230" />
+          <el-table-column label="变更原因" prop="changeReason" width="170" />
+          <el-table-column label="状态" prop="statusName" width="100" />
+          <el-table-column fixed="right" min-width="240" label="操作">
+            <template #default="scope">
+              <div v-if="scope.row.status === 1">
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'areaEditResponsibilities:public',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >编辑
+                </el-button>
+                <el-popconfirm title="确定要删除吗?" @confirm="handleConfirmDeleteRow(scope)">
+                  <template #reference>
+                    <el-button type="primary" link>删除</el-button>
+                  </template>
+                </el-popconfirm>
+
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'areaViewResponsibilities:public',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >查看</el-button
+                >
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'areaChangeResponsibilities:public',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >变更</el-button
+                >
+              </div>
+              <div v-if="scope.row.canChange === true">
+                <el-button type="primary" link @click="handleAreaCheckListApprove(scope, 1)">确认</el-button>
+                <el-button type="primary" link @click="handleAreaCheckListApprove(scope, 0)">拒绝</el-button>
+              </div>
+              <div v-if="scope.row.status === 3">
+                <el-button type="primary" link>变更</el-button>
+                <el-button type="primary" link>查看</el-button>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div class="pagination-container" v-if="tableData.total > 0">
+        <el-pagination
+          background
+          :current-page="queryParams.pageNumber"
+          :page-size="queryParams.pageSize"
+          :total="tableData.total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </main>
+  </div>
+  <BatchImport
+    :visible="batchImportVisible"
+    :importApiUrl="importApiUrl"
+    :templateUrl="templateUrl"
+    :templateName="'责任清单-批量导入模版'"
+    @close="() => (batchImportVisible = false)"
+    @update="handleUpdate"
+  />
+</template>
+<script lang="ts" setup>
+  import { onMounted, ref, reactive } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import { useRouter } from 'vue-router';
+  import {
+    areaCheckListQueryPage,
+    areaCheckListApprove,
+    areaCheckListDelete,
+    areaCheckListExportArea,
+  } from '@/api/production-safety/responsibility-implementation';
+  import urlJoin from 'url-join';
+  import { BatchImport } from '@/components/batch-import';
+
+  import { downloadFile } from '@/views/disaster/utils';
+  import { useGlobSetting } from '@/hooks/setting';
+  import { useUserInfoHook } from '@/views/disaster/hooks';
+
+  const router = useRouter();
+  const activeTab = ref(1);
+  const { id } = useUserInfoHook();
+
+  const queryParams = reactive<any>({
+    pageNumber: 1,
+    pageSize: 10,
+    queryParam: {
+      type: 1,
+      nameFunction: '',
+      status: '',
+      responsibilityPersonId: id,
+    },
+  });
+
+  // 批量导入
+  const batchImportVisible = ref(false);
+  const { urlPrefix } = useGlobSetting();
+  const importApiUrl = ref(urlJoin(urlPrefix, '/areaCheckList/importArea?type=2'));
+  const templateUrl = ref('');
+
+  const handleUpdate = () => {
+    batchImportVisible.value = false;
+    queryTableList();
+  };
+
+  const tableData = reactive({
+    data: [],
+    total: 0,
+  });
+  const handleTabChange = (tab) => {
+    console.log(typeof tab);
+    if (tab === 1) {
+      //todo
+      router.push({
+        name: 'areaResponsibilities:public',
+      });
+    } else if (tab === 2) {
+      router.push({
+        name: 'areaResponsibilities:nonPublic',
+      });
+    }
+  };
+
+  async function handleDownload() {
+    // getQuery();
+    try {
+      const res = await areaCheckListExportArea(queryParams.queryParam);
+      if (res.size === 0) return;
+      const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+      const url = window.URL.createObjectURL(blob);
+      downloadFile(url, '责任清单.xlsx');
+    } catch (e) {
+      ElMessage.error('下载失败');
+      console.log(e);
+    }
+  }
+
+  const handleAreaCheckListApprove = (scope, approveType) => {
+    areaCheckListApprove({
+      id: scope.row.id,
+      approveType,
+      refuseReason: null,
+    }).then(() => {
+      ElMessage.success('操作成功!');
+      queryTableList();
+    });
+  };
+
+  const handleSizeChange = (value) => {};
+  const handleCurrentChange = (value) => {
+    queryParams.pageNumber = value;
+    queryTableList();
+  };
+
+  const handleConfirmDeleteRow = (scope) => {
+    areaCheckListDelete(scope.row.id).then(() => {
+      ElMessage.success('删除成功!');
+      queryTableList();
+    });
+  };
+  const queryTableList = () => {
+    areaCheckListQueryPage(queryParams).then((res) => {
+      tableData.data = res.records;
+      tableData.total = res.totalRow;
+    });
+  };
+  const handleRestParams = () => {
+    Object.assign(queryParams, {
+      pageNumber: 1,
+      pageSize: 10,
+      queryParam: {
+        ...queryParams.queryParam,
+        status: '',
+        nameFunction: '',
+      },
+    });
+    queryTableList();
+  };
+
+  onMounted(() => {
+    queryTableList();
+  });
+</script>
+
+<style lang="scss" scoped>
+  @use '@/styles/page-details-layout.scss' as *;
+  @use '@/styles/page-main-layout.scss' as *;
+  @use '@/styles/basic-table-action.scss' as *;
+
+  :deep(.el-tabs__header) {
+    margin: 0;
+  }
+  :deep(.el-tabs__item) {
+    font-size: 14px !important;
+  }
+  :deep(.flexContent) {
+    display: flex;
+  }
+  :deep(.breadcrumb .title) {
+    margin-left: 0;
+  }
+
+  :deep(.el-form) {
+    flex: 1;
+    display: flex;
+    row-gap: 15px;
+    flex-wrap: wrap;
+  }
+  :deep(.el-form-item) {
+    margin-bottom: 0;
+  }
+  :deep(main) {
+    display: flex;
+    flex-direction: column;
+  }
+  .search-form {
+    min-width: 800px;
+    display: flex;
+
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+  }
+
+  .button-content {
+    margin-bottom: 20px;
+  }
+  .table-content {
+    flex: 1;
+    overflow: hidden;
+    overflow-y: auto;
+  }
+  .page-content {
+    display: flex;
+    justify-content: flex-end;
+  }
+</style>

+ 288 - 0
src/views/production-safety/implement-safety-duty/public-area-responsibilities/view.vue

@@ -0,0 +1,288 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        查看非公共区域责任清单
+      </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-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input
+            disabled
+            v-model="formValue.buildingArea"
+            size="large"
+            placeholder="请输入楼宇/区域"
+            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>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input
+            disabled
+            v-model="formValue.nameFunction"
+            size="large"
+            placeholder="请输入名称/功能"
+            style="width: 50%"
+          />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            disabled
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            disabled
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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>
+        </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-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-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>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button type="primary" @click="$router.push({ name: 'areaResponsibilities:public' })">返回</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } 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,
+    areaCheckListSavaArea,
+    areaCheckListQueryDetail,
+  } 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 formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+    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>

+ 262 - 0
src/views/production-safety/implement-safety-duty/public-list-responsibilities/add.vue

@@ -0,0 +1,262 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        创建非公共区域责任清单
+      </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 v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="请输入楼宇/区域" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" size="large" placeholder="请输入楼层/房号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input v-model="formValue.nameFunction" size="large" placeholder="请输入名称/功能" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
+          <el-input
+            v-model="formValue.safetyPersonContact"
+            size="large"
+            placeholder="选择责任人后自动填充"
+            style="width: 50%"
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'listResponsibilities:public' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { ElMessage } from 'element-plus';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+  import { getUserList } from '@/api/system/user-operate';
+
+  import {
+    queryUserPageByUsername,
+    areaCheckListSavaArea,
+  } from '@/api/production-safety/responsibility-implementation';
+
+  const router = useRouter();
+  const formRef = ref<any>(null);
+  const submiting = ref(false);
+
+  const userOptions = ref<any[]>([]);
+  const firstLevelDepts = ref<any[]>([]);
+
+  const formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        areaCheckListSavaArea({
+          ...formValue,
+          type: 1,
+        })
+          .then(() => {
+            ElMessage.success('创建成功!');
+            router.push({ name: 'listResponsibilities:public' });
+          })
+          .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>

+ 251 - 0
src/views/production-safety/implement-safety-duty/public-list-responsibilities/change.vue

@@ -0,0 +1,251 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        变更非公共区域责任清单
+      </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 v-model="formValue.buildingNo" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" disabled size="large" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <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>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <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-select>
+        </el-form-item>
+
+        <h5 style="margin: 30px 0">信息变更</h5>
+
+        <el-form-item label="变更后的安全责任部门" prop="safetyResponsibleDepartmentTodo">
+          <el-select
+            v-model="formValue.safetyResponsibleDepartmentTodo"
+            placeholder="请选择新的责任部门"
+            size="large"
+            style="width: 50%"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in firstLevelDepts"
+              :key="item.hrIdtOrgId"
+              :label="item.deptName"
+              :value="item.deptName"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="变更后的安全具体责任人" prop="safetySpecificPersonTodo">
+          <el-select
+            v-model="formValue.safetySpecificPersonTodo"
+            placeholder="请选择新的具体责任人"
+            size="large"
+            style="width: 50%"
+            filterable
+            clearable
+            @change="(val) => syncUserName(val, 'safetySpecificPersonTodo')"
+          >
+            <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="changeReason">
+          <el-input
+            v-model="formValue.changeReason"
+            type="textarea"
+            :rows="7"
+            placeholder="请详细描述变更原因"
+            style="width: 70%"
+            maxlength="200"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'listResponsibilities:public' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交变更</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, nextTick, onMounted } 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 { getUserList } from '@/api/system/user-operate';
+
+  import {
+    queryUserPageByUsername,
+    areaCheckListQueryDetail,
+    areaCheckListChange,
+  } from '@/api/production-safety/responsibility-implementation';
+
+  const router = useRouter();
+  const route = useRoute();
+  const formRef = ref<any>(null);
+  const submiting = ref(false);
+
+  const userOptions = ref<any[]>([]);
+  const firstLevelDepts = ref<any[]>([]);
+
+  const formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyResponsibleDepartment: '',
+    safetyDepartmentManager: null as number | null,
+    safetySpecificPerson: null as number | null,
+    safetyPersonContact: '',
+
+    safetyResponsibleDepartmentTodo: '',
+    safetySpecificPersonTodo: null as number | null,
+    safetySpecificPersonNameTodo: '',
+    changeReason: '',
+  });
+
+  const rules = reactive({
+    safetyResponsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'blur' }],
+    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 syncUserName = (id: number, field: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user && field === 'safetySpecificPersonTodo') {
+      formValue.safetySpecificPersonNameTodo = user.name;
+    }
+  };
+
+  const handlAreaCheckListQueryDetail = async () => {
+    const id = route.query.id;
+    if (!id) return;
+    try {
+      const res: any = await areaCheckListQueryDetail({ id });
+      if (res) {
+        Object.assign(formValue, res);
+
+        if (formValue.safetyCenterManager) formValue.safetyCenterManager = Number(formValue.safetyCenterManager);
+        if (formValue.safetySpecificPerson) formValue.safetySpecificPerson = Number(formValue.safetySpecificPerson);
+      }
+    } catch (err) {
+      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,
+          safetySpecificPersonTodo: formValue.safetySpecificPersonTodo,
+          safetySpecificPersonNameTodo: formValue.safetySpecificPersonNameTodo,
+          changeReason: formValue.changeReason,
+        };
+
+        areaCheckListChange(submitData)
+          .then(() => {
+            ElMessage.success('变更申请提交成功!');
+            router.push({ name: 'listResponsibilities:public' });
+          })
+          .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>

+ 286 - 0
src/views/production-safety/implement-safety-duty/public-list-responsibilities/edit.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        编辑非公共区域责任清单
+      </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 v-model="formValue.buildingNo" size="large" placeholder="请输入楼号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="请输入楼宇/区域" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="楼层/房号" prop="floorRoomNo">
+          <el-input v-model="formValue.floorRoomNo" size="large" placeholder="请输入楼层/房号" style="width: 50%" />
+        </el-form-item>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input v-model="formValue.nameFunction" size="large" placeholder="请输入名称/功能" style="width: 50%" />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任部门负责人" prop="safetyDepartmentManager">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人" prop="safetySpecificPerson">
+          <el-select
+            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-select>
+        </el-form-item>
+
+        <el-form-item label="安全具体责任人联系方式" prop="safetyPersonContact">
+          <el-input
+            v-model="formValue.safetyPersonContact"
+            size="large"
+            placeholder="选择责任人后自动填充"
+            style="width: 50%"
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'listResponsibilities:public' })">返回</el-button>
+      <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } 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 { getUserList } from '@/api/system/user-operate';
+
+  import {
+    queryUserPageByUsername,
+    areaCheckListSavaArea,
+    areaCheckListQueryDetail,
+    areaCheckListUpdateArea,
+  } from '@/api/production-safety/responsibility-implementation';
+
+  const router = useRouter();
+  const route = useRoute();
+  const formRef = ref<any>(null);
+  const submiting = ref(false);
+
+  const userOptions = ref<any[]>([]);
+  const firstLevelDepts = ref<any[]>([]);
+
+  const formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+    handlAreaCheckListQueryDetail();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        areaCheckListSavaArea({
+          ...formValue,
+          type: 1,
+        })
+          .then(() => {
+            ElMessage.success('编辑成功!');
+            router.push({ name: 'listResponsibilities:public' });
+          })
+          .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 *;
+  @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>

+ 311 - 0
src/views/production-safety/implement-safety-duty/public-list-responsibilities/list.vue

@@ -0,0 +1,311 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+        <el-tab-pane label="公共区域" :name="1" />
+        <el-tab-pane label="非公共区域" :name="2" />
+      </el-tabs>
+    </header>
+    <main class="safety-platform-container__main">
+      <div class="search-form">
+        <el-form :inline="true">
+          <el-form-item label="功能名称">
+            <el-input
+              v-model="queryParams.queryParam.nameFunction"
+              placeholder="搜索安全责任书名称"
+              style="width: 170px"
+            />
+          </el-form-item>
+          <el-form-item label="状态">
+            <el-select v-model="queryParams.queryParam.status" clearable placeholder="状态" style="width: 170px">
+              <el-option :value="1" label="正常" />
+              <el-option :value="2" label="待确认" />
+              <el-option :value="3" label="已拒绝" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+
+        <div>
+          <el-button @click="batchImportVisible = true">导入</el-button>
+          <el-button type="primary" @click="handleDownload">导出</el-button>
+          <el-button
+            type="primary"
+            @click="
+              $router.push({
+                name: 'addResponsibilities:public',
+              })
+            "
+            >添加
+          </el-button>
+          <el-button type="primary" @click="queryTableList">查询</el-button>
+          <el-button @click="handleRestParams">重置</el-button>
+        </div>
+      </div>
+
+      <div class="table-content">
+        <el-table :data="tableData.data">
+          <el-table-column type="index" label="序号" width="80" />
+          <el-table-column label="楼号" prop="buildingCode" width="80" />
+          <el-table-column label="楼层" prop="buildingArea" width="100" />
+          <el-table-column label="房间/区域" prop="floorRoomNo" width="180" />
+          <el-table-column label="功能名称" prop="nameFunction" width="120" />
+          <el-table-column label="安全责任所/中心" prop="safetyResponsibleCenter" width="200" />
+          <el-table-column label="安全责任所/中心负责人" prop="safetyCenterManagerName" width="200" />
+          <el-table-column label="安全责任部门" prop="safetyResponsibleDepartment" width="180" />
+          <el-table-column label="安全责任部门负责人" prop="safetyDepartmentManagerName" width="180" />
+          <el-table-column label="安全具体责任人" prop="safetySpecificPersonName" width="180" />
+          <el-table-column label="安全具体责任人联系方式" prop="safetyPersonContact;" width="230" />
+          <el-table-column label="变更原因" prop="changeReason" width="170" />
+          <el-table-column label="状态" prop="statusName" width="100" />
+          <el-table-column fixed="right" min-width="240" label="操作">
+            <template #default="scope">
+              <div v-if="scope.row.status === 1">
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'editResponsibilities:public',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >编辑
+                </el-button>
+                <el-popconfirm title="确定要删除吗?" @confirm="handleConfirmDeleteRow(scope)">
+                  <template #reference>
+                    <el-button type="primary" link>删除</el-button>
+                  </template>
+                </el-popconfirm>
+
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'viewResponsibilities:public',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >查看</el-button
+                >
+                <el-button
+                  type="primary"
+                  link
+                  @click="
+                    $router.push({
+                      name: 'changeResponsibilities:public',
+                      query: {
+                        id: scope.row.id,
+                      },
+                    })
+                  "
+                  >变更</el-button
+                >
+              </div>
+              <div v-if="scope.row.canChange === true">
+                <el-button type="primary" link @click="handleAreaCheckListApprove(scope, 1)">确认</el-button>
+                <el-button type="primary" link @click="handleAreaCheckListApprove(scope, 0)">拒绝</el-button>
+              </div>
+              <div v-if="scope.row.status === 3">
+                <el-button type="primary" link>变更</el-button>
+                <el-button type="primary" link>查看</el-button>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div class="pagination-container" v-if="tableData.total > 0">
+        <el-pagination
+          background
+          :current-page="queryParams.pageNumber"
+          :page-size="queryParams.pageSize"
+          :total="tableData.total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </main>
+  </div>
+  <BatchImport
+    :visible="batchImportVisible"
+    :importApiUrl="importApiUrl"
+    :templateUrl="templateUrl"
+    :templateName="'责任清单-批量导入模版'"
+    @close="() => (batchImportVisible = false)"
+    @update="handleUpdate"
+  />
+</template>
+<script lang="ts" setup>
+  import { onMounted, ref, reactive } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import { useRouter } from 'vue-router';
+  import {
+    areaCheckListQueryPage,
+    areaCheckListApprove,
+    areaCheckListDelete,
+    areaCheckListExportArea,
+  } from '@/api/production-safety/responsibility-implementation';
+  import urlJoin from 'url-join';
+  import { BatchImport } from '@/components/batch-import';
+
+  import { downloadFile } from '@/views/disaster/utils';
+  import { useGlobSetting } from '@/hooks/setting';
+
+  const router = useRouter();
+  const activeTab = ref(1);
+  const queryParams = reactive<any>({
+    pageNumber: 1,
+    pageSize: 10,
+    queryParam: {
+      type: 1,
+      nameFunction: '',
+      status: '',
+    },
+  });
+
+  // 批量导入
+  const batchImportVisible = ref(false);
+  const { urlPrefix } = useGlobSetting();
+  const importApiUrl = ref(urlJoin(urlPrefix, '/areaCheckList/importArea?type=1'));
+  const templateUrl = ref('');
+
+  const handleUpdate = () => {
+    batchImportVisible.value = false;
+    queryTableList();
+  };
+
+  const tableData = reactive({
+    data: [],
+    total: 0,
+  });
+  const handleTabChange = (tab) => {
+    if (tab === 1) {
+      //todo
+      router.push({
+        name: 'listResponsibilities:public',
+      });
+    } else if (tab === 2) {
+      router.push({
+        name: 'listResponsibilities:nonPublic',
+      });
+    }
+  };
+
+  async function handleDownload() {
+    // getQuery();
+    try {
+      const res = await areaCheckListExportArea(queryParams.queryParam);
+      if (res.size === 0) return;
+      const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+      const url = window.URL.createObjectURL(blob);
+      downloadFile(url, '责任清单.xlsx');
+    } catch (e) {
+      ElMessage.error('下载失败');
+      console.log(e);
+    }
+  }
+
+  const handleAreaCheckListApprove = (scope, approveType) => {
+    areaCheckListApprove({
+      id: scope.row.id,
+      approveType,
+      refuseReason: null,
+    }).then(() => {
+      ElMessage.success('操作成功!');
+      queryTableList();
+    });
+  };
+
+  const handleSizeChange = (value) => {};
+  const handleCurrentChange = (value) => {
+    queryParams.pageNumber = value;
+    queryTableList();
+  };
+
+  const handleConfirmDeleteRow = (scope) => {
+    areaCheckListDelete(scope.row.id).then(() => {
+      ElMessage.success('删除成功!');
+      queryTableList();
+    });
+  };
+  const queryTableList = () => {
+    areaCheckListQueryPage(queryParams).then((res) => {
+      tableData.data = res.records;
+      tableData.total = res.totalRow;
+    });
+  };
+  const handleRestParams = () => {
+    Object.assign(queryParams, {
+      pageNumber: 1,
+      pageSize: 10,
+      queryParam: {
+        ...queryParams.queryParam,
+        status: '',
+        nameFunction: '',
+      },
+    });
+    queryTableList();
+  };
+
+  onMounted(() => {
+    queryTableList();
+  });
+</script>
+
+<style lang="scss" scoped>
+  @use '@/styles/page-details-layout.scss' as *;
+  @use '@/styles/page-main-layout.scss' as *;
+  @use '@/styles/basic-table-action.scss' as *;
+
+  :deep(.el-tabs__header) {
+    margin: 0;
+  }
+  :deep(.el-tabs__item) {
+    font-size: 14px !important;
+  }
+  :deep(.flexContent) {
+    display: flex;
+  }
+  :deep(.breadcrumb .title) {
+    margin-left: 0;
+  }
+
+  :deep(.el-form) {
+    flex: 1;
+    display: flex;
+    row-gap: 15px;
+    flex-wrap: wrap;
+  }
+  :deep(.el-form-item) {
+    margin-bottom: 0;
+  }
+  :deep(main) {
+    display: flex;
+    flex-direction: column;
+  }
+  .search-form {
+    min-width: 800px;
+    display: flex;
+
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+  }
+
+  .button-content {
+    margin-bottom: 20px;
+  }
+  .table-content {
+    flex: 1;
+    overflow: hidden;
+    overflow-y: auto;
+  }
+  .page-content {
+    display: flex;
+    justify-content: flex-end;
+  }
+</style>

+ 289 - 0
src/views/production-safety/implement-safety-duty/public-list-responsibilities/view.vue

@@ -0,0 +1,289 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">
+        <BreadcrumbBack />
+        查看非公共区域责任清单
+      </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-item>
+        <el-form-item label="楼宇/区域" prop="buildingArea">
+          <el-input
+            disabled
+            v-model="formValue.buildingArea"
+            size="large"
+            placeholder="请输入楼宇/区域"
+            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>
+        <el-form-item label="名称/功能" prop="nameFunction">
+          <el-input
+            disabled
+            v-model="formValue.nameFunction"
+            size="large"
+            placeholder="请输入名称/功能"
+            style="width: 50%"
+          />
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心" prop="safetyResponsibleCenter">
+          <el-select
+            disabled
+            v-model="formValue.safetyResponsibleCenter"
+            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>
+        </el-form-item>
+
+        <el-form-item label="安全责任所/中心负责人" prop="safetyCenterManager">
+          <el-select
+            disabled
+            v-model="formValue.safetyCenterManager"
+            placeholder="请选择"
+            size="large"
+            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>
+        </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-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-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>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button type="primary" @click="$router.push({ name: 'listResponsibilities:public' })">返回</el-button>
+    </footer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } 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 { getUserList } from '@/api/system/user-operate';
+
+  import {
+    queryUserPageByUsername,
+    areaCheckListSavaArea,
+    areaCheckListQueryDetail,
+  } from '@/api/production-safety/responsibility-implementation';
+
+  const router = useRouter();
+  const route = useRoute();
+  const formRef = ref<any>(null);
+  const submiting = ref(false);
+
+  const userOptions = ref<any[]>([]);
+  const firstLevelDepts = ref<any[]>([]);
+
+  const formValue = reactive({
+    buildingNo: '',
+    buildingArea: '',
+    floorRoomNo: '',
+    nameFunction: '',
+    safetyResponsibleCenter: '',
+    safetyCenterManager: null as number | null,
+    safetyCenterManagerName: '',
+    safetyResponsibleDepartment: '',
+    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 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 syncUserName = (id: number, nameField: string) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) formValue[nameField] = user.name;
+  };
+
+  const handleSpecificPersonChange = (id: number) => {
+    const user = userOptions.value.find((u) => u.id === id);
+    if (user) {
+      formValue.safetySpecificPersonName = user.name;
+      formValue.safetyPersonContact = user.mobile;
+    }
+  };
+
+  onMounted(() => {
+    getDeptData();
+    getUserData();
+    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>