浏览代码

feat:风险管理相关

sunqijun 3 月之前
父节点
当前提交
f6a0110985

+ 52 - 0
src/api/production-safety/responsibility-implementation/index.ts

@@ -524,4 +524,56 @@ export function safetyRiskListApprove(params) {
     method: 'put',
     params
   });
+}
+
+/**
+ * 保存安全风险清单
+ * @param params - 安全风险清单数据
+ * @returns Promise<void>
+ */
+export function safetyRiskListSaveRiskList(params) {
+  return http.request({
+    url: `/safetyRisk/list/saveRiskList`,
+    method: 'post',
+    params
+  });
+}
+
+/**
+ * 更新安全风险清单
+ * @param params - 更新后的安全风险清单数据(需包含 ID)
+ * @returns Promise<void>
+ */
+export function safetyRiskListUpdateRiskList(params) {
+  return http.request({
+    url: `/safetyRisk/list/updateRiskList`,
+    method: 'put',
+    params
+  });
+}
+
+/**   
+ *  切换安全风险清单状态(启用/停用)
+ * @param params - 包含 id 和目标状态
+ * @returns Promise<void>
+ */
+export function safetyRiskListChange(params) {
+  return http.request({
+    url: `/safetyRisk/list/change`,
+    method: 'put',
+    params
+  });
+}
+
+
+/** 
+ * 查询安全风险清单详情           
+ *  @param id - 安全风险清单 ID
+ * @returns Promise<any> 安全风险清单详细信息
+ */       
+export function safetyRiskListQueryDetail(id) {
+  return http.request({
+    url: `/safetyRisk/list/queryDetail?id=${id}`,
+    method: 'get',
+  });
 }

+ 432 - 0
src/views/production-safety/implement-safety-duty/risk-manage/add.vue

@@ -0,0 +1,432 @@
+<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" :inline="true" label-width="auto" :model="formValue" :rules="rules">
+        <el-form-item label="楼号/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="例如:A栋、东区" style="width: 330px" />
+        </el-form-item>
+        <el-form-item label="楼宇名称" prop="buildingName">
+          <el-input
+            v-model="formValue.buildingName"
+            size="large"
+            placeholder="例如:科研楼、实验中心"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleBuilding">
+          <el-select
+            v-model="formValue.safetyResponsibleBuilding"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="楼层/位置" prop="floorLocation">
+          <el-input
+            v-model="formValue.floorLocation"
+            size="large"
+            placeholder="例如:3层、地下一层、走廊东侧"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleFloor">
+          <!-- <el-input
+            v-model="formValue.safetyResponsibleFloor"
+            size="large"
+            placeholder="请输入楼层/位置安全责任人姓名"
+            style="width: 330px"
+          /> -->
+          <el-select
+            v-model="formValue.safetyResponsibleFloor"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="房间号(名称)" prop="roomName">
+          <el-input
+            v-model="formValue.roomName"
+            size="large"
+            placeholder="例如:301、高压配电室"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="责任部门" prop="responsibleDepartment">
+          <el-cascader
+            style="width: 330px"
+            v-model="formValue.responsibleDepartmentId"
+            size="large"
+            ref="cascaderRef"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择责任部门"
+            filterable
+            @change="handleChangeDept('responsibleDepartment')"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="roomSafetyResponsible">
+          <!-- <el-input
+            v-model="formValue.roomSafetyResponsible"
+            size="large"
+            placeholder="请输入房间安全责任人姓名"
+            style="width: 330px"
+          /> -->
+          <el-select
+            v-model="formValue.roomSafetyResponsible"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="是否存在风险点" prop="hasRiskPoint">
+          <el-select
+            v-model="formValue.hasRiskPoint"
+            size="large"
+            placeholder="请选择是否存有风险点"
+            style="width: 330px"
+          >
+            <el-option label="是" :value="1" />
+            <el-option label="否" :value="0" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点类别" prop="riskCategory">
+          <el-select v-model="formValue.riskCategory" size="large" placeholder="请选择风险点类别" style="width: 330px">
+            <el-option :value="1" label="III级危险点" />
+            <el-option :value="2" label="II级危险点" />
+            <el-option :value="3" label="I级危险点" />
+            <el-option :value="4" label="UPS" />
+            <el-option :value="5" label="电力设施(强电)" />
+            <el-option :value="6" label="高低温气体液体、高压气体" />
+            <el-option :value="7" label="试验设施设备" />
+            <el-option :value="8" label="特种设备" />
+            <el-option :value="9" label="危化品、易燃易爆固液气体" />
+            <el-option :value="10" label="有限空间" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点名称" prop="riskPointName">
+          <el-input
+            v-model="formValue.riskPointName"
+            size="large"
+            placeholder="例如:液氮储罐、高压开关柜"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险点编号" prop="riskPointNumber">
+          <el-input
+            v-model="formValue.riskPointNumber"
+            size="large"
+            placeholder="请输入唯一风险点编号"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险点规格" prop="riskPointSpec">
+          <el-input
+            v-model="formValue.riskPointSpec"
+            size="large"
+            placeholder="例如:容量500L、电压10kV"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="培训要求" prop="trainingRequirement">
+          <el-input
+            v-model="formValue.trainingRequirement"
+            size="large"
+            placeholder="例如:持证上岗、年度复训"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全风险" prop="safetyRisk">
+          <el-input
+            v-model="formValue.safetyRisk"
+            size="large"
+            placeholder="描述该风险点可能引发的安全问题"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="可能造成伤害" prop="possibleHarm">
+          <el-input
+            v-model="formValue.possibleHarm"
+            size="large"
+            placeholder="例如:爆炸、中毒、触电、窒息等"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="主要管控措施" prop="mainControlMeasures">
+          <el-input
+            v-model="formValue.mainControlMeasures"
+            size="large"
+            placeholder="例如:定期巡检、设置警示标识、配备防护装备"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="目前是否存在安全隐患" prop="currentHazard">
+          <el-input
+            v-model="formValue.currentHazard"
+            size="large"
+            placeholder="例如:设备老化、线路裸露、通风不良"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="隐患内容" prop="hazardContent">
+          <el-input
+            v-model="formValue.hazardContent"
+            size="large"
+            placeholder="详细描述当前存在的隐患情况"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="应急预案名称" prop="emergencyPlanName">
+          <el-input
+            v-model="formValue.emergencyPlanName"
+            size="large"
+            placeholder="例如:《危化品泄漏应急处置预案》"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="应急预案编号" prop="emergencyPlanNumber">
+          <el-input
+            v-model="formValue.emergencyPlanNumber"
+            size="large"
+            placeholder="例如:YJYA-2024-001"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="演练计划及实施情况" prop="rectificationPlan">
+          <el-input
+            v-model="formValue.rectificationPlan"
+            size="large"
+            placeholder="例如:每季度演练一次,最近一次于2025年12月完成"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险等级" prop="riskLevel">
+          <el-select v-model="formValue.riskLevel" size="large" placeholder="请选择风险等级" style="width: 330px">
+            <el-option :value="1" label="高" />
+            <el-option :value="2" label="中" />
+            <el-option :value="3" label="低" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <div style="width: 330px"></div>
+        </el-form-item>
+        <el-form-item label="备注" prop="remarks" style="width: 87.2%">
+          <el-input
+            type="textarea"
+            v-model="formValue.remarks"
+            size="large"
+            :rows="7"
+            placeholder="可填写其他补充说明"
+          />
+        </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, nextTick } 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 {
+    queryAvailableUserList,
+    safetyRiskListSaveRiskList,
+  } 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 cascaderProp = {
+    expandTrigger: 'click',
+    checkStrictly: true,
+    value: 'id',
+    label: 'deptName',
+  };
+  const cascaderRef = ref<any>();
+
+  const formValue = reactive({
+    buildingArea: '',
+    buildingName: '',
+    safetyResponsibleBuilding: '',
+    floorLocation: '',
+    safetyResponsibleFloor: '',
+    roomName: '',
+    responsibleDepartment: '',
+    roomSafetyResponsible: '',
+    hasRiskPoint: '',
+    riskCategory: '',
+    riskPointName: '',
+    riskPointNumber: '',
+    riskPointSpec: '',
+    trainingRequirement: '',
+    safetyRisk: '',
+    possibleHarm: '',
+    mainControlMeasures: '',
+    currentHazard: '',
+    hazardContent: '',
+    emergencyPlanName: '',
+    emergencyPlanNumber: '',
+    rectificationPlan: '',
+    riskLevel: '',
+    remarks: '',
+    responsibleDepartmentId: [],
+  });
+
+  const rules = reactive({
+    buildingArea: [{ required: true, message: '请输入楼号', trigger: 'blur' }],
+    buildingName: [{ required: true, message: '请输入楼宇/区域', trigger: 'blur' }],
+    safetyResponsibleBuilding: [{ required: true, message: '请输入楼层/房号', trigger: 'blur' }],
+    floorLocation: [{ required: true, message: '请输入名称/功能', trigger: 'blur' }],
+    safetyResponsibleFloor: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
+    roomName: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
+    responsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
+    roomSafetyResponsible: [{ required: true, message: '请输入房间安全责任人', trigger: 'blur' }],
+    hasRiskPoint: [{ required: true, message: '请选择是否有风险点', trigger: 'change' }],
+    riskCategory: [{ required: true, message: '请选择风险类别', trigger: 'change' }],
+    riskPointName: [{ required: true, message: '请输入风险点名称', trigger: 'blur' }],
+    riskPointNumber: [{ required: true, message: '请输入风险点编号', trigger: 'blur' }],
+    riskPointSpec: [{ required: true, message: '请输入风险点规格/参数', trigger: 'blur' }],
+    trainingRequirement: [{ required: true, message: '请输入培训要求', trigger: 'blur' }],
+    safetyRisk: [{ required: true, message: '请输入安全风险描述', trigger: 'blur' }],
+    possibleHarm: [{ required: true, message: '请输入可能造成的伤害', trigger: 'blur' }],
+    mainControlMeasures: [{ required: true, message: '请输入主要控制措施', trigger: 'blur' }],
+    currentHazard: [{ required: true, message: '请选择当前隐患状态', trigger: 'change' }],
+    hazardContent: [{ required: true, message: '请输入隐患内容', trigger: 'blur' }],
+    emergencyPlanName: [{ required: true, message: '请输入应急预案名称', trigger: 'blur' }],
+    emergencyPlanNumber: [{ required: true, message: '请输入应急预案编号', trigger: 'blur' }],
+    rectificationPlan: [{ required: true, message: '请输入整改方案', trigger: 'blur' }],
+    riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
+    remarks: [],
+  });
+
+  const handleChangeDept = (prop) => {
+    const cascader = cascaderRef.value;
+    const deptInfo = cascader?.getCheckedNodes();
+    formValue[prop] = deptInfo[0].label;
+    formRef.value.validateField(prop);
+    nextTick(() => {
+      handleQueryAvailableUserList(deptInfo[0].label, prop);
+    });
+  };
+
+  const getDeptData = () => {
+    getAllDepartments().then((res) => {
+      firstLevelDepts.value = formatDeptTree(res);
+    });
+  };
+
+  const handleQueryAvailableUserList = (deptName, realname = '') => {
+    queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: {
+        deptName,
+        realname,
+      },
+    }).then((res: any) => {
+      userOptions.value = (res.records || []).map((u: any) => ({
+        value: u.userId || u.id,
+        label: u.realname,
+      }));
+    });
+  };
+
+  // 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,
+  //     }));
+  //   });
+  // };
+
+  onMounted(() => {
+    getDeptData();
+    handleQueryAvailableUserList('');
+    // getUserData();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        safetyRiskListSaveRiskList({
+          ...formValue,
+          responsibleDepartmentId: formValue.responsibleDepartmentId.join(','),
+        })
+          .then(() => {
+            ElMessage.success('创建成功!');
+            router.push({ name: 'riskManage' });
+          })
+          .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>

+ 533 - 0
src/views/production-safety/implement-safety-duty/risk-manage/change.vue

@@ -0,0 +1,533 @@
+<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" :inline="true" label-width="auto" :model="formValue" :rules="rules">
+        <el-form-item label="楼号/区域" prop="buildingArea">
+          <el-input
+            disabled
+            v-model="formValue.buildingArea"
+            size="large"
+            placeholder="例如:A栋、东区"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="楼宇名称" prop="buildingName">
+          <el-input
+            v-model="formValue.buildingName"
+            size="large"
+            disabled
+            placeholder="例如:科研楼、实验中心"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleBuilding">
+          <el-select
+            disabled
+            v-model="formValue.safetyResponsibleBuilding"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="楼层/位置" prop="floorLocation">
+          <el-input
+            disabled
+            v-model="formValue.floorLocation"
+            size="large"
+            placeholder="例如:3层、地下一层、走廊东侧"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleFloor">
+          <el-select
+            disabled
+            v-model="formValue.safetyResponsibleFloor"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="房间号(名称)" prop="roomName">
+          <el-input
+            disabled
+            v-model="formValue.roomName"
+            size="large"
+            placeholder="例如:301、高压配电室"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="责任部门" prop="responsibleDepartment">
+          <el-cascader
+            disabled
+            style="width: 330px"
+            v-model="formValue.responsibleDepartmentId"
+            size="large"
+            ref="cascaderRef"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择责任部门"
+            filterable
+            @change="handleChangeDept('responsibleDepartment')"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="roomSafetyResponsible">
+          <el-select
+            disabled
+            v-model="formValue.roomSafetyResponsible"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="是否存在风险点" prop="hasRiskPoint">
+          <el-select
+            disabled
+            v-model="formValue.hasRiskPoint"
+            size="large"
+            placeholder="请选择是否存有风险点"
+            style="width: 330px"
+          >
+            <el-option label="是" :value="1" />
+            <el-option label="否" :value="0" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点类别" prop="riskCategory">
+          <el-select
+            disabled
+            v-model="formValue.riskCategory"
+            size="large"
+            placeholder="请选择风险点类别"
+            style="width: 330px"
+          >
+            <el-option :value="1" label="III级危险点" />
+            <el-option :value="2" label="II级危险点" />
+            <el-option :value="3" label="I级危险点" />
+            <el-option :value="4" label="UPS" />
+            <el-option :value="5" label="电力设施(强电)" />
+            <el-option :value="6" label="高低温气体液体、高压气体" />
+            <el-option :value="7" label="试验设施设备" />
+            <el-option :value="8" label="特种设备" />
+            <el-option :value="9" label="危化品、易燃易爆固液气体" />
+            <el-option :value="10" label="有限空间" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点名称" prop="riskPointName">
+          <el-input
+            disabled
+            v-model="formValue.riskPointName"
+            size="large"
+            placeholder="例如:液氮储罐、高压开关柜"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险点编号" prop="riskPointNumber">
+          <el-input
+            disabled
+            v-model="formValue.riskPointNumber"
+            size="large"
+            placeholder="请输入唯一风险点编号"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险点规格" prop="riskPointSpec">
+          <el-input
+            disabled
+            v-model="formValue.riskPointSpec"
+            size="large"
+            placeholder="例如:容量500L、电压10kV"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="培训要求" prop="trainingRequirement">
+          <el-input
+            disabled
+            v-model="formValue.trainingRequirement"
+            size="large"
+            placeholder="例如:持证上岗、年度复训"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全风险" prop="safetyRisk">
+          <el-input
+            disabled
+            v-model="formValue.safetyRisk"
+            size="large"
+            placeholder="描述该风险点可能引发的安全问题"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="可能造成伤害" prop="possibleHarm">
+          <el-input
+            disabled
+            v-model="formValue.possibleHarm"
+            size="large"
+            placeholder="例如:爆炸、中毒、触电、窒息等"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="主要管控措施" prop="mainControlMeasures">
+          <el-input
+            disabled
+            v-model="formValue.mainControlMeasures"
+            size="large"
+            placeholder="例如:定期巡检、设置警示标识、配备防护装备"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="目前是否存在安全隐患" prop="currentHazard">
+          <el-input
+            disabled
+            v-model="formValue.currentHazard"
+            size="large"
+            placeholder="例如:设备老化、线路裸露、通风不良"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="隐患内容" prop="hazardContent">
+          <el-input
+            disabled
+            v-model="formValue.hazardContent"
+            size="large"
+            placeholder="详细描述当前存在的隐患情况"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="应急预案名称" prop="emergencyPlanName">
+          <el-input
+            disabled
+            v-model="formValue.emergencyPlanName"
+            size="large"
+            placeholder="例如:《危化品泄漏应急处置预案》"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="应急预案编号" prop="emergencyPlanNumber">
+          <el-input
+            disabled
+            v-model="formValue.emergencyPlanNumber"
+            size="large"
+            placeholder="例如:YJYA-2024-001"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="演练计划及实施情况" prop="rectificationPlan">
+          <el-input
+            disabled
+            v-model="formValue.rectificationPlan"
+            size="large"
+            placeholder="例如:每季度演练一次,最近一次于2025年12月完成"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险等级" prop="riskLevel">
+          <el-select
+            disabled
+            v-model="formValue.riskLevel"
+            size="large"
+            placeholder="请选择风险等级"
+            style="width: 330px"
+          >
+            <el-option :value="1" label="高" />
+            <el-option :value="2" label="中" />
+            <el-option :value="3" label="低" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <div style="width: 330px"></div>
+        </el-form-item>
+        <el-form-item label="备注" prop="remarks" style="width: 87.2%">
+          <el-input
+            disabled
+            type="textarea"
+            v-model="formValue.remarks"
+            size="large"
+            :rows="7"
+            placeholder="可填写其他补充说明"
+          />
+        </el-form-item>
+        <h4>信息变更</h4>
+        <el-form-item label="部门名称" prop="responsibleDepartmentTodo">
+          <el-cascader
+            style="width: 330px"
+            ref="cascaderTodoRef"
+            size="large"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择责任部门"
+            filterable
+            @change="() => handleChangeDept('responsibleDepartmentTodo')"
+          />
+        </el-form-item>
+        <el-form-item label="责任人姓名" prop="roomSafetyResponsibleTodo">
+          <el-select
+            v-model="formValue.roomSafetyResponsibleTodo"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option
+              v-for="item in roomSafetyResponsibleTodoOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <div style="width: 330px"></div>
+        </el-form-item>
+        <el-form-item label="变更原因" prop="changeReason" style="width: 87.2%">
+          <el-input
+            type="textarea"
+            v-model="formValue.changeReason"
+            size="large"
+            :rows="7"
+            placeholder="请填写驳回审批原因"
+          />
+        </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, nextTick } from 'vue';
+  import { useRouter, useRoute } from 'vue-router';
+  import { ElMessage } from 'element-plus';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+
+  import {
+    queryAvailableUserList,
+    safetyRiskListChange,
+    safetyRiskListQueryDetail,
+  } 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 cascaderProp = {
+    expandTrigger: 'click',
+    checkStrictly: true,
+    value: 'id',
+    label: 'deptName',
+  };
+  const cascaderRef = ref<any>();
+  const cascaderTodoRef = ref<any>();
+  const roomSafetyResponsibleTodoOptions = ref<any[]>([]);
+  const formValue = reactive({
+    buildingArea: '',
+    buildingName: '',
+    safetyResponsibleBuilding: '',
+    floorLocation: '',
+    safetyResponsibleFloor: '',
+    roomName: '',
+    responsibleDepartment: '',
+    roomSafetyResponsible: '',
+    hasRiskPoint: '',
+    riskCategory: '',
+    riskPointName: '',
+    riskPointNumber: '',
+    riskPointSpec: '',
+    trainingRequirement: '',
+    safetyRisk: '',
+    possibleHarm: '',
+    mainControlMeasures: '',
+    currentHazard: '',
+    hazardContent: '',
+    emergencyPlanName: '',
+    emergencyPlanNumber: '',
+    rectificationPlan: '',
+    riskLevel: '',
+    remarks: '',
+    changeReason: '',
+    responsibleDepartmentTodo: '',
+    roomSafetyResponsibleTodo: '',
+    responsibleDepartmentId: [],
+  });
+
+  const rules = reactive({
+    buildingArea: [{ required: true, message: '请输入楼号', trigger: 'blur' }],
+    buildingName: [{ required: true, message: '请输入楼宇/区域', trigger: 'blur' }],
+    safetyResponsibleBuilding: [{ required: true, message: '请输入楼层/房号', trigger: 'blur' }],
+    floorLocation: [{ required: true, message: '请输入名称/功能', trigger: 'blur' }],
+    safetyResponsibleFloor: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
+    roomName: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
+    responsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
+    roomSafetyResponsible: [{ required: true, message: '请输入房间安全责任人', trigger: 'blur' }],
+    hasRiskPoint: [{ required: true, message: '请选择是否有风险点', trigger: 'change' }],
+    riskCategory: [{ required: true, message: '请选择风险类别', trigger: 'change' }],
+    riskPointName: [{ required: true, message: '请输入风险点名称', trigger: 'blur' }],
+    riskPointNumber: [{ required: true, message: '请输入风险点编号', trigger: 'blur' }],
+    riskPointSpec: [{ required: true, message: '请输入风险点规格/参数', trigger: 'blur' }],
+    trainingRequirement: [{ required: true, message: '请输入培训要求', trigger: 'blur' }],
+    safetyRisk: [{ required: true, message: '请输入安全风险描述', trigger: 'blur' }],
+    possibleHarm: [{ required: true, message: '请输入可能造成的伤害', trigger: 'blur' }],
+    mainControlMeasures: [{ required: true, message: '请输入主要控制措施', trigger: 'blur' }],
+    currentHazard: [{ required: true, message: '请选择当前隐患状态', trigger: 'change' }],
+    hazardContent: [{ required: true, message: '请输入隐患内容', trigger: 'blur' }],
+    emergencyPlanName: [{ required: true, message: '请输入应急预案名称', trigger: 'blur' }],
+    emergencyPlanNumber: [{ required: true, message: '请输入应急预案编号', trigger: 'blur' }],
+    rectificationPlan: [{ required: true, message: '请输入整改方案', trigger: 'blur' }],
+    riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
+    responsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'change' }],
+    roomSafetyResponsibleTodo: [{ required: true, message: '请选择变更后的责任人', trigger: 'change' }],
+    changeReason: [{ required: true, message: '请输入变更原因', trigger: 'blur' }],
+    remarks: [],
+  });
+
+  const handleChangeDept = (prop) => {
+    const cascader = cascaderTodoRef.value;
+    const deptInfo = cascader?.getCheckedNodes();
+    formValue[prop] = deptInfo[0].label;
+    formRef.value.validateField(prop);
+    nextTick(() => {
+      handleQueryAvailableUserList(deptInfo[0].label, prop);
+    });
+  };
+
+  const getDeptData = () => {
+    getAllDepartments().then((res) => {
+      firstLevelDepts.value = formatDeptTree(res);
+    });
+  };
+
+  const handleQueryAvailableUserList = (deptName = '', prop = '', realname = '') => {
+    queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: {
+        deptName,
+        realname,
+      },
+    }).then((res: any) => {
+      switch (prop) {
+        case 'responsibleDepartmentTodo':
+          formValue.roomSafetyResponsibleTodo = '';
+          roomSafetyResponsibleTodoOptions.value = (res.records || []).map((u: any) => ({
+            value: u.userId || u.id,
+            label: u.realname,
+          }));
+          break;
+
+        default:
+          break;
+      }
+    });
+  };
+
+  const loadDetailData = (id: number) => {
+    safetyRiskListQueryDetail(id).then((res: any) => {
+      Object.keys(formValue).forEach((key) => {
+        if (res[key] !== undefined) {
+          formValue[key] = res[key];
+          formValue['responsibleDepartmentId'] = res['responsibleDepartmentId']
+            ? res['responsibleDepartmentId'].split(',').map((item: string) => Number(item))
+            : [];
+        }
+      });
+    });
+  };
+
+  // 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,
+  //     }));
+  //   });
+  // };
+
+  onMounted(() => {
+    getDeptData();
+    loadDetailData(Number(route.query.id));
+    handleQueryAvailableUserList('');
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        safetyRiskListChange({
+          id: route.query.id,
+          responsibleDepartmentTodo: formValue.responsibleDepartmentTodo,
+          roomSafetyResponsibleTodo: formValue.roomSafetyResponsibleTodo,
+          changeReason: formValue.changeReason,
+        })
+          .then(() => {
+            ElMessage.success('变更成功!');
+            router.push({ name: 'riskManage' });
+          })
+          .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>

+ 436 - 0
src/views/production-safety/implement-safety-duty/risk-manage/edit.vue

@@ -0,0 +1,436 @@
+<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" :inline="true" label-width="auto" :model="formValue" :rules="rules">
+        <el-form-item label="楼号/区域" prop="buildingArea">
+          <el-input v-model="formValue.buildingArea" size="large" placeholder="例如:A栋、东区" style="width: 330px" />
+        </el-form-item>
+        <el-form-item label="楼宇名称" prop="buildingName">
+          <el-input
+            v-model="formValue.buildingName"
+            size="large"
+            placeholder="例如:科研楼、实验中心"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleBuilding">
+          <el-select
+            v-model="formValue.safetyResponsibleBuilding"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="楼层/位置" prop="floorLocation">
+          <el-input
+            v-model="formValue.floorLocation"
+            size="large"
+            placeholder="例如:3层、地下一层、走廊东侧"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleFloor">
+          <el-select
+            v-model="formValue.safetyResponsibleFloor"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="房间号(名称)" prop="roomName">
+          <el-input
+            v-model="formValue.roomName"
+            size="large"
+            placeholder="例如:301、高压配电室"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="责任部门" prop="responsibleDepartment">
+          <el-cascader
+            style="width: 330px"
+            v-model="formValue.responsibleDepartmentId"
+            size="large"
+            ref="cascaderRef"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择责任部门"
+            filterable
+            @change="handleChangeDept('responsibleDepartment')"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="roomSafetyResponsible">
+          <el-select
+            v-model="formValue.roomSafetyResponsible"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="是否存在风险点" prop="hasRiskPoint">
+          <el-select
+            v-model="formValue.hasRiskPoint"
+            size="large"
+            placeholder="请选择是否存有风险点"
+            style="width: 330px"
+          >
+            <el-option label="是" :value="1" />
+            <el-option label="否" :value="0" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点类别" prop="riskCategory">
+          <el-select v-model="formValue.riskCategory" size="large" placeholder="请选择风险点类别" style="width: 330px">
+            <el-option :value="1" label="III级危险点" />
+            <el-option :value="2" label="II级危险点" />
+            <el-option :value="3" label="I级危险点" />
+            <el-option :value="4" label="UPS" />
+            <el-option :value="5" label="电力设施(强电)" />
+            <el-option :value="6" label="高低温气体液体、高压气体" />
+            <el-option :value="7" label="试验设施设备" />
+            <el-option :value="8" label="特种设备" />
+            <el-option :value="9" label="危化品、易燃易爆固液气体" />
+            <el-option :value="10" label="有限空间" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点名称" prop="riskPointName">
+          <el-input
+            v-model="formValue.riskPointName"
+            size="large"
+            placeholder="例如:液氮储罐、高压开关柜"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险点编号" prop="riskPointNumber">
+          <el-input
+            v-model="formValue.riskPointNumber"
+            size="large"
+            placeholder="请输入唯一风险点编号"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险点规格" prop="riskPointSpec">
+          <el-input
+            v-model="formValue.riskPointSpec"
+            size="large"
+            placeholder="例如:容量500L、电压10kV"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="培训要求" prop="trainingRequirement">
+          <el-input
+            v-model="formValue.trainingRequirement"
+            size="large"
+            placeholder="例如:持证上岗、年度复训"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="安全风险" prop="safetyRisk">
+          <el-input
+            v-model="formValue.safetyRisk"
+            size="large"
+            placeholder="描述该风险点可能引发的安全问题"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="可能造成伤害" prop="possibleHarm">
+          <el-input
+            v-model="formValue.possibleHarm"
+            size="large"
+            placeholder="例如:爆炸、中毒、触电、窒息等"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="主要管控措施" prop="mainControlMeasures">
+          <el-input
+            v-model="formValue.mainControlMeasures"
+            size="large"
+            placeholder="例如:定期巡检、设置警示标识、配备防护装备"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="目前是否存在安全隐患" prop="currentHazard">
+          <el-input
+            v-model="formValue.currentHazard"
+            size="large"
+            placeholder="例如:设备老化、线路裸露、通风不良"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="隐患内容" prop="hazardContent">
+          <el-input
+            v-model="formValue.hazardContent"
+            size="large"
+            placeholder="详细描述当前存在的隐患情况"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="应急预案名称" prop="emergencyPlanName">
+          <el-input
+            v-model="formValue.emergencyPlanName"
+            size="large"
+            placeholder="例如:《危化品泄漏应急处置预案》"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="应急预案编号" prop="emergencyPlanNumber">
+          <el-input
+            v-model="formValue.emergencyPlanNumber"
+            size="large"
+            placeholder="例如:YJYA-2024-001"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="演练计划及实施情况" prop="rectificationPlan">
+          <el-input
+            v-model="formValue.rectificationPlan"
+            size="large"
+            placeholder="例如:每季度演练一次,最近一次于2025年12月完成"
+            style="width: 330px"
+          />
+        </el-form-item>
+        <el-form-item label="风险等级" prop="riskLevel">
+          <el-select v-model="formValue.riskLevel" size="large" placeholder="请选择风险等级" style="width: 330px">
+            <el-option :value="1" label="高" />
+            <el-option :value="2" label="中" />
+            <el-option :value="3" label="低" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <div style="width: 330px"></div>
+        </el-form-item>
+        <el-form-item label="备注" prop="remarks" style="width: 87.2%">
+          <el-input
+            type="textarea"
+            v-model="formValue.remarks"
+            size="large"
+            :rows="7"
+            placeholder="可填写其他补充说明"
+          />
+        </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, nextTick } from 'vue';
+  import { useRouter, useRoute } from 'vue-router';
+  import { ElMessage } from 'element-plus';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+
+  import {
+    queryAvailableUserList,
+    safetyRiskListUpdateRiskList,
+    safetyRiskListQueryDetail,
+  } 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 cascaderProp = {
+    expandTrigger: 'click',
+    checkStrictly: true,
+    value: 'id',
+    label: 'deptName',
+  };
+  const cascaderRef = ref<any>();
+
+  const formValue = reactive({
+    buildingArea: '',
+    buildingName: '',
+    safetyResponsibleBuilding: '',
+    floorLocation: '',
+    safetyResponsibleFloor: '',
+    roomName: '',
+    responsibleDepartment: '',
+    roomSafetyResponsible: '',
+    hasRiskPoint: '',
+    riskCategory: '',
+    riskPointName: '',
+    riskPointNumber: '',
+    riskPointSpec: '',
+    trainingRequirement: '',
+    safetyRisk: '',
+    possibleHarm: '',
+    mainControlMeasures: '',
+    currentHazard: '',
+    hazardContent: '',
+    emergencyPlanName: '',
+    emergencyPlanNumber: '',
+    rectificationPlan: '',
+    riskLevel: '',
+    remarks: '',
+    responsibleDepartmentId: [],
+  });
+
+  const rules = reactive({
+    buildingArea: [{ required: true, message: '请输入楼号', trigger: 'blur' }],
+    buildingName: [{ required: true, message: '请输入楼宇/区域', trigger: 'blur' }],
+    safetyResponsibleBuilding: [{ required: true, message: '请输入楼层/房号', trigger: 'blur' }],
+    floorLocation: [{ required: true, message: '请输入名称/功能', trigger: 'blur' }],
+    safetyResponsibleFloor: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
+    roomName: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
+    responsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
+    roomSafetyResponsible: [{ required: true, message: '请输入房间安全责任人', trigger: 'blur' }],
+    hasRiskPoint: [{ required: true, message: '请选择是否有风险点', trigger: 'change' }],
+    riskCategory: [{ required: true, message: '请选择风险类别', trigger: 'change' }],
+    riskPointName: [{ required: true, message: '请输入风险点名称', trigger: 'blur' }],
+    riskPointNumber: [{ required: true, message: '请输入风险点编号', trigger: 'blur' }],
+    riskPointSpec: [{ required: true, message: '请输入风险点规格/参数', trigger: 'blur' }],
+    trainingRequirement: [{ required: true, message: '请输入培训要求', trigger: 'blur' }],
+    safetyRisk: [{ required: true, message: '请输入安全风险描述', trigger: 'blur' }],
+    possibleHarm: [{ required: true, message: '请输入可能造成的伤害', trigger: 'blur' }],
+    mainControlMeasures: [{ required: true, message: '请输入主要控制措施', trigger: 'blur' }],
+    currentHazard: [{ required: true, message: '请选择当前隐患状态', trigger: 'change' }],
+    hazardContent: [{ required: true, message: '请输入隐患内容', trigger: 'blur' }],
+    emergencyPlanName: [{ required: true, message: '请输入应急预案名称', trigger: 'blur' }],
+    emergencyPlanNumber: [{ required: true, message: '请输入应急预案编号', trigger: 'blur' }],
+    rectificationPlan: [{ required: true, message: '请输入整改方案', trigger: 'blur' }],
+    riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
+    remarks: [],
+  });
+
+  const handleChangeDept = (prop) => {
+    const cascader = cascaderRef.value;
+    const deptInfo = cascader?.getCheckedNodes();
+    formValue[prop] = deptInfo[0].label;
+    formRef.value.validateField(prop);
+    nextTick(() => {
+      handleQueryAvailableUserList(deptInfo[0].label, prop);
+    });
+  };
+
+  const getDeptData = () => {
+    getAllDepartments().then((res) => {
+      firstLevelDepts.value = formatDeptTree(res);
+    });
+  };
+
+  const handleQueryAvailableUserList = (deptName, realname = '') => {
+    queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: {
+        deptName,
+        realname,
+      },
+    }).then((res: any) => {
+      userOptions.value = (res.records || []).map((u: any) => ({
+        value: u.userId || u.id,
+        label: u.realname,
+      }));
+    });
+  };
+
+  const loadDetailData = (id: number) => {
+    safetyRiskListQueryDetail(id).then((res: any) => {
+      Object.keys(formValue).forEach((key) => {
+        if (res[key] !== undefined) {
+          formValue[key] = res[key];
+          formValue['responsibleDepartmentId'] = res['responsibleDepartmentId']
+            ? res['responsibleDepartmentId'].split(',').map((item: string) => Number(item))
+            : [];
+        }
+      });
+    });
+  };
+
+  // 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,
+  //     }));
+  //   });
+  // };
+
+  onMounted(() => {
+    getDeptData();
+    loadDetailData(Number(route.query.id));
+    handleQueryAvailableUserList('');
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        safetyRiskListUpdateRiskList({
+          ...formValue,
+          id: route.query.id,
+          responsibleDepartmentId: formValue.responsibleDepartmentId.join(','),
+        })
+          .then(() => {
+            ElMessage.success('编辑成功!');
+            router.push({ name: 'riskManage' });
+          })
+          .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>

+ 14 - 2
src/views/production-safety/implement-safety-duty/risk-manage/list.vue

@@ -60,7 +60,7 @@
         </el-form>
 
         <div>
-          <el-button type="primary">添加 </el-button>
+          <el-button type="primary" @click="$router.push({ name: 'riskManageAdd' })">添加 </el-button>
           <el-button type="primary" @click="queryTableList">查询</el-button>
           <el-button @click="handleRestParams">重置</el-button>
         </div>
@@ -80,8 +80,20 @@
           <el-table-column label="状态" prop="statusName" width="100" />
           <el-table-column fixed="right" min-width="240" label="操作">
             <template #default="scope">
-              <el-button type="primary" link>编辑</el-button>
+              <el-button
+                type="primary"
+                link
+                @click="$router.push({ name: 'riskManageEdit', query: { id: scope.row.id } })"
+                >编辑</el-button
+              >
               <el-button type="primary" link @click="handleConfirmDeleteRow(scope)">删除</el-button>
+              <el-button type="primary" link>查看</el-button>
+              <el-button
+                type="primary"
+                link
+                @click="$router.push({ name: 'riskManageChange', query: { id: scope.row.id } })"
+                >变更</el-button
+              >
               <el-button type="primary" link @click="handleApprove(scope, 1)">确认</el-button>
               <el-button type="primary" link @click="handleApprove(scope, 0)">拒绝</el-button>
               <el-button type="primary" link @click="handleApprove(scope, 0)">撤回</el-button>

+ 473 - 0
src/views/production-safety/implement-safety-duty/risk-manage/view.vue

@@ -0,0 +1,473 @@
+<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" :inline="true" label-width="auto" :model="formValue" :rules="rules">
+        <el-form-item label="楼号/区域" prop="buildingArea">
+          <el-input
+            v-model="formValue.buildingArea"
+            size="large"
+            placeholder="例如:A栋、东区"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="楼宇名称" prop="buildingName">
+          <el-input
+            v-model="formValue.buildingName"
+            size="large"
+            placeholder="例如:科研楼、实验中心"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleBuilding">
+          <el-select
+            v-model="formValue.safetyResponsibleBuilding"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+            disabled
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="楼层/位置" prop="floorLocation">
+          <el-input
+            v-model="formValue.floorLocation"
+            size="large"
+            placeholder="例如:3层、地下一层、走廊东侧"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="safetyResponsibleFloor">
+          <el-select
+            v-model="formValue.safetyResponsibleFloor"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+            disabled
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="房间号(名称)" prop="roomName">
+          <el-input
+            v-model="formValue.roomName"
+            size="large"
+            placeholder="例如:301、高压配电室"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="责任部门" prop="responsibleDepartment">
+          <el-cascader
+            style="width: 330px"
+            v-model="formValue.responsibleDepartmentId"
+            size="large"
+            ref="cascaderRef"
+            :options="firstLevelDepts"
+            :props="cascaderProp"
+            :show-all-levels="false"
+            placeholder="请选择责任部门"
+            filterable
+            disabled
+            @change="handleChangeDept('responsibleDepartment')"
+          />
+        </el-form-item>
+        <el-form-item label="安全责任人" prop="roomSafetyResponsible">
+          <el-select
+            v-model="formValue.roomSafetyResponsible"
+            placeholder="请选择"
+            size="large"
+            style="width: 330px"
+            filterable
+            disabled
+          >
+            <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="是否存在风险点" prop="hasRiskPoint">
+          <el-select
+            v-model="formValue.hasRiskPoint"
+            size="large"
+            placeholder="请选择是否存有风险点"
+            style="width: 330px"
+            disabled
+          >
+            <el-option label="是" :value="1" />
+            <el-option label="否" :value="0" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点类别" prop="riskCategory">
+          <el-select
+            v-model="formValue.riskCategory"
+            size="large"
+            placeholder="请选择风险点类别"
+            style="width: 330px"
+            disabled
+          >
+            <el-option :value="1" label="III级危险点" />
+            <el-option :value="2" label="II级危险点" />
+            <el-option :value="3" label="I级危险点" />
+            <el-option :value="4" label="UPS" />
+            <el-option :value="5" label="电力设施(强电)" />
+            <el-option :value="6" label="高低温气体液体、高压气体" />
+            <el-option :value="7" label="试验设施设备" />
+            <el-option :value="8" label="特种设备" />
+            <el-option :value="9" label="危化品、易燃易爆固液气体" />
+            <el-option :value="10" label="有限空间" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风险点名称" prop="riskPointName">
+          <el-input
+            v-model="formValue.riskPointName"
+            size="large"
+            placeholder="例如:液氮储罐、高压开关柜"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="风险点编号" prop="riskPointNumber">
+          <el-input
+            v-model="formValue.riskPointNumber"
+            size="large"
+            placeholder="请输入唯一风险点编号"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="风险点规格" prop="riskPointSpec">
+          <el-input
+            v-model="formValue.riskPointSpec"
+            size="large"
+            placeholder="例如:容量500L、电压10kV"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="培训要求" prop="trainingRequirement">
+          <el-input
+            v-model="formValue.trainingRequirement"
+            size="large"
+            placeholder="例如:持证上岗、年度复训"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="安全风险" prop="safetyRisk">
+          <el-input
+            v-model="formValue.safetyRisk"
+            size="large"
+            placeholder="描述该风险点可能引发的安全问题"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="可能造成伤害" prop="possibleHarm">
+          <el-input
+            v-model="formValue.possibleHarm"
+            size="large"
+            placeholder="例如:爆炸、中毒、触电、窒息等"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="主要管控措施" prop="mainControlMeasures">
+          <el-input
+            v-model="formValue.mainControlMeasures"
+            size="large"
+            placeholder="例如:定期巡检、设置警示标识、配备防护装备"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="目前是否存在安全隐患" prop="currentHazard">
+          <el-input
+            v-model="formValue.currentHazard"
+            size="large"
+            placeholder="例如:设备老化、线路裸露、通风不良"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="隐患内容" prop="hazardContent">
+          <el-input
+            v-model="formValue.hazardContent"
+            size="large"
+            placeholder="详细描述当前存在的隐患情况"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="应急预案名称" prop="emergencyPlanName">
+          <el-input
+            v-model="formValue.emergencyPlanName"
+            size="large"
+            placeholder="例如:《危化品泄漏应急处置预案》"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="应急预案编号" prop="emergencyPlanNumber">
+          <el-input
+            v-model="formValue.emergencyPlanNumber"
+            size="large"
+            placeholder="例如:YJYA-2024-001"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="演练计划及实施情况" prop="rectificationPlan">
+          <el-input
+            v-model="formValue.rectificationPlan"
+            size="large"
+            placeholder="例如:每季度演练一次,最近一次于2025年12月完成"
+            style="width: 330px"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item label="风险等级" prop="riskLevel">
+          <el-select
+            v-model="formValue.riskLevel"
+            size="large"
+            placeholder="请选择风险等级"
+            style="width: 330px"
+            disabled
+          >
+            <el-option :value="1" label="高" />
+            <el-option :value="2" label="中" />
+            <el-option :value="3" label="低" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <div style="width: 330px"></div>
+        </el-form-item>
+        <el-form-item label="备注" prop="remarks" style="width: 87.2%">
+          <el-input
+            type="textarea"
+            v-model="formValue.remarks"
+            size="large"
+            :rows="7"
+            placeholder="可填写其他补充说明"
+            disabled
+          />
+        </el-form-item>
+      </el-form>
+    </main>
+    <footer class="safety-platform-container__footer">
+      <el-button @click="$router.push({ name: 'areaResponsibilities:public' })">返回</el-button>
+    </footer>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { ref, reactive, onMounted, nextTick } from 'vue';
+  import { useRouter, useRoute } from 'vue-router';
+  import { ElMessage } from 'element-plus';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+
+  import {
+    queryAvailableUserList,
+    safetyRiskListSaveRiskList,
+    safetyRiskListQueryDetail,
+  } 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 cascaderProp = {
+    expandTrigger: 'click',
+    checkStrictly: true,
+    value: 'id',
+    label: 'deptName',
+  };
+  const cascaderRef = ref<any>();
+
+  const formValue = reactive({
+    buildingArea: '',
+    buildingName: '',
+    safetyResponsibleBuilding: '',
+    floorLocation: '',
+    safetyResponsibleFloor: '',
+    roomName: '',
+    responsibleDepartment: '',
+    roomSafetyResponsible: '',
+    hasRiskPoint: '',
+    riskCategory: '',
+    riskPointName: '',
+    riskPointNumber: '',
+    riskPointSpec: '',
+    trainingRequirement: '',
+    safetyRisk: '',
+    possibleHarm: '',
+    mainControlMeasures: '',
+    currentHazard: '',
+    hazardContent: '',
+    emergencyPlanName: '',
+    emergencyPlanNumber: '',
+    rectificationPlan: '',
+    riskLevel: '',
+    remarks: '',
+    responsibleDepartmentId: [],
+  });
+
+  const rules = reactive({
+    buildingArea: [{ required: true, message: '请输入楼号', trigger: 'blur' }],
+    buildingName: [{ required: true, message: '请输入楼宇/区域', trigger: 'blur' }],
+    safetyResponsibleBuilding: [{ required: true, message: '请输入楼层/房号', trigger: 'blur' }],
+    floorLocation: [{ required: true, message: '请输入名称/功能', trigger: 'blur' }],
+    safetyResponsibleFloor: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
+    roomName: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
+    responsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
+    roomSafetyResponsible: [{ required: true, message: '请输入房间安全责任人', trigger: 'blur' }],
+    hasRiskPoint: [{ required: true, message: '请选择是否有风险点', trigger: 'change' }],
+    riskCategory: [{ required: true, message: '请选择风险类别', trigger: 'change' }],
+    riskPointName: [{ required: true, message: '请输入风险点名称', trigger: 'blur' }],
+    riskPointNumber: [{ required: true, message: '请输入风险点编号', trigger: 'blur' }],
+    riskPointSpec: [{ required: true, message: '请输入风险点规格/参数', trigger: 'blur' }],
+    trainingRequirement: [{ required: true, message: '请输入培训要求', trigger: 'blur' }],
+    safetyRisk: [{ required: true, message: '请输入安全风险描述', trigger: 'blur' }],
+    possibleHarm: [{ required: true, message: '请输入可能造成的伤害', trigger: 'blur' }],
+    mainControlMeasures: [{ required: true, message: '请输入主要控制措施', trigger: 'blur' }],
+    currentHazard: [{ required: true, message: '请选择当前隐患状态', trigger: 'change' }],
+    hazardContent: [{ required: true, message: '请输入隐患内容', trigger: 'blur' }],
+    emergencyPlanName: [{ required: true, message: '请输入应急预案名称', trigger: 'blur' }],
+    emergencyPlanNumber: [{ required: true, message: '请输入应急预案编号', trigger: 'blur' }],
+    rectificationPlan: [{ required: true, message: '请输入整改方案', trigger: 'blur' }],
+    riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
+    remarks: [],
+  });
+
+  const handleChangeDept = (prop) => {
+    const cascader = cascaderRef.value;
+    const deptInfo = cascader?.getCheckedNodes();
+    formValue[prop] = deptInfo[0].label;
+    formRef.value.validateField(prop);
+    nextTick(() => {
+      handleQueryAvailableUserList(deptInfo[0].label, prop);
+    });
+  };
+
+  const getDeptData = () => {
+    getAllDepartments().then((res) => {
+      firstLevelDepts.value = formatDeptTree(res);
+    });
+  };
+
+  const handleQueryAvailableUserList = (deptName, realname = '') => {
+    queryAvailableUserList({
+      pageNumber: 1,
+      pageSize: 200,
+      queryParam: {
+        deptName,
+        realname,
+      },
+    }).then((res: any) => {
+      userOptions.value = (res.records || []).map((u: any) => ({
+        value: u.userId || u.id,
+        label: u.realname,
+      }));
+    });
+  };
+
+  const loadDetailData = (id: number) => {
+    safetyRiskListQueryDetail(id).then((res: any) => {
+      Object.keys(formValue).forEach((key) => {
+        if (res[key] !== undefined) {
+          formValue[key] = res[key];
+          formValue['responsibleDepartmentId'] = res['responsibleDepartmentId']
+            ? res['responsibleDepartmentId'].split(',').map((item: string) => Number(item))
+            : [];
+        }
+      });
+    });
+  };
+
+  // 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,
+  //     }));
+  //   });
+  // };
+
+  onMounted(() => {
+    getDeptData();
+    loadDetailData(Number(route.query.id));
+    handleQueryAvailableUserList('');
+    // getUserData();
+  });
+
+  const handleSubmit = () => {
+    formRef.value?.validate((valid: boolean) => {
+      if (valid) {
+        submiting.value = true;
+        safetyRiskListSaveRiskList({
+          ...formValue,
+        })
+          .then(() => {
+            ElMessage.success('创建成功!');
+            router.push({ name: 'riskManage' });
+          })
+          .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>

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

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