change.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. <template>
  2. <div class="safety-platform-container">
  3. <header class="safety-platform-container__header">
  4. <div class="breadcrumb-title">
  5. <BreadcrumbBack />
  6. 变更风险清单
  7. </div>
  8. </header>
  9. <main class="safety-platform-container__main">
  10. <el-form ref="formRef" :inline="true" label-width="auto" :model="formValue" :rules="rules">
  11. <el-form-item label="楼号/区域" prop="buildingArea">
  12. <el-input
  13. disabled
  14. v-model="formValue.buildingArea"
  15. size="large"
  16. placeholder="例如:A栋、东区"
  17. style="width: 330px"
  18. />
  19. </el-form-item>
  20. <el-form-item label="楼宇名称" prop="buildingName">
  21. <el-input
  22. v-model="formValue.buildingName"
  23. size="large"
  24. disabled
  25. placeholder="例如:科研楼、实验中心"
  26. style="width: 330px"
  27. />
  28. </el-form-item>
  29. <el-form-item label="安全责任人" prop="safetyResponsibleBuilding">
  30. <el-select
  31. disabled
  32. v-model="formValue.safetyResponsibleBuilding"
  33. placeholder="请选择"
  34. size="large"
  35. style="width: 330px"
  36. filterable
  37. >
  38. <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="楼层/位置" prop="floorLocation">
  42. <el-input
  43. disabled
  44. v-model="formValue.floorLocation"
  45. size="large"
  46. placeholder="例如:3层、地下一层、走廊东侧"
  47. style="width: 330px"
  48. />
  49. </el-form-item>
  50. <el-form-item label="安全责任人" prop="safetyResponsibleFloor">
  51. <el-select
  52. disabled
  53. v-model="formValue.safetyResponsibleFloor"
  54. placeholder="请选择"
  55. size="large"
  56. style="width: 330px"
  57. filterable
  58. >
  59. <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
  60. </el-select>
  61. </el-form-item>
  62. <el-form-item label="房间号(名称)" prop="roomName">
  63. <el-input
  64. disabled
  65. v-model="formValue.roomName"
  66. size="large"
  67. placeholder="例如:301、高压配电室"
  68. style="width: 330px"
  69. />
  70. </el-form-item>
  71. <el-form-item label="责任部门" prop="responsibleDepartment">
  72. <el-cascader
  73. disabled
  74. style="width: 330px"
  75. v-model="formValue.responsibleDepartmentId"
  76. size="large"
  77. ref="cascaderRef"
  78. :options="firstLevelDepts"
  79. :props="cascaderProp"
  80. :show-all-levels="false"
  81. placeholder="请选择责任部门"
  82. filterable
  83. @change="handleChangeDept('responsibleDepartment')"
  84. />
  85. </el-form-item>
  86. <el-form-item label="安全责任人" prop="roomSafetyResponsible">
  87. <el-select
  88. disabled
  89. v-model="formValue.roomSafetyResponsible"
  90. placeholder="请选择"
  91. size="large"
  92. style="width: 330px"
  93. filterable
  94. >
  95. <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
  96. </el-select>
  97. </el-form-item>
  98. <el-form-item label="是否存在风险点" prop="hasRiskPoint">
  99. <el-select
  100. disabled
  101. v-model="formValue.hasRiskPoint"
  102. size="large"
  103. placeholder="请选择是否存有风险点"
  104. style="width: 330px"
  105. >
  106. <el-option label="是" :value="1" />
  107. <el-option label="否" :value="0" />
  108. </el-select>
  109. </el-form-item>
  110. <el-form-item label="风险点类别" prop="riskCategory">
  111. <el-select
  112. disabled
  113. v-model="formValue.riskCategory"
  114. size="large"
  115. placeholder="请选择风险点类别"
  116. style="width: 330px"
  117. >
  118. <el-option :value="1" label="III级危险点" />
  119. <el-option :value="2" label="II级危险点" />
  120. <el-option :value="3" label="I级危险点" />
  121. <el-option :value="4" label="UPS" />
  122. <el-option :value="5" label="电力设施(强电)" />
  123. <el-option :value="6" label="高低温气体液体、高压气体" />
  124. <el-option :value="7" label="试验设施设备" />
  125. <el-option :value="8" label="特种设备" />
  126. <el-option :value="9" label="危化品、易燃易爆固液气体" />
  127. <el-option :value="10" label="有限空间" />
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item label="风险点名称" prop="riskPointName">
  131. <el-input
  132. disabled
  133. v-model="formValue.riskPointName"
  134. size="large"
  135. placeholder="例如:液氮储罐、高压开关柜"
  136. style="width: 330px"
  137. />
  138. </el-form-item>
  139. <el-form-item label="风险点编号" prop="riskPointNumber">
  140. <el-input
  141. disabled
  142. v-model="formValue.riskPointNumber"
  143. size="large"
  144. placeholder="请输入唯一风险点编号"
  145. style="width: 330px"
  146. />
  147. </el-form-item>
  148. <el-form-item label="风险点规格" prop="riskPointSpec">
  149. <el-input
  150. disabled
  151. v-model="formValue.riskPointSpec"
  152. size="large"
  153. placeholder="例如:容量500L、电压10kV"
  154. style="width: 330px"
  155. />
  156. </el-form-item>
  157. <el-form-item label="培训要求" prop="trainingRequirement">
  158. <el-input
  159. disabled
  160. v-model="formValue.trainingRequirement"
  161. size="large"
  162. placeholder="例如:持证上岗、年度复训"
  163. style="width: 330px"
  164. />
  165. </el-form-item>
  166. <el-form-item label="安全风险" prop="safetyRisk">
  167. <el-input
  168. disabled
  169. v-model="formValue.safetyRisk"
  170. size="large"
  171. placeholder="描述该风险点可能引发的安全问题"
  172. style="width: 330px"
  173. />
  174. </el-form-item>
  175. <el-form-item label="可能造成伤害" prop="possibleHarm">
  176. <el-input
  177. disabled
  178. v-model="formValue.possibleHarm"
  179. size="large"
  180. placeholder="例如:爆炸、中毒、触电、窒息等"
  181. style="width: 330px"
  182. />
  183. </el-form-item>
  184. <el-form-item label="主要管控措施" prop="mainControlMeasures">
  185. <el-input
  186. disabled
  187. v-model="formValue.mainControlMeasures"
  188. size="large"
  189. placeholder="例如:定期巡检、设置警示标识、配备防护装备"
  190. style="width: 330px"
  191. />
  192. </el-form-item>
  193. <el-form-item label="目前是否存在安全隐患" prop="currentHazard">
  194. <el-input
  195. disabled
  196. v-model="formValue.currentHazard"
  197. size="large"
  198. placeholder="例如:设备老化、线路裸露、通风不良"
  199. style="width: 330px"
  200. />
  201. </el-form-item>
  202. <el-form-item label="隐患内容" prop="hazardContent">
  203. <el-input
  204. disabled
  205. v-model="formValue.hazardContent"
  206. size="large"
  207. placeholder="详细描述当前存在的隐患情况"
  208. style="width: 330px"
  209. />
  210. </el-form-item>
  211. <el-form-item label="应急预案名称" prop="emergencyPlanName">
  212. <el-input
  213. disabled
  214. v-model="formValue.emergencyPlanName"
  215. size="large"
  216. placeholder="例如:《危化品泄漏应急处置预案》"
  217. style="width: 330px"
  218. />
  219. </el-form-item>
  220. <el-form-item label="应急预案编号" prop="emergencyPlanNumber">
  221. <el-input
  222. disabled
  223. v-model="formValue.emergencyPlanNumber"
  224. size="large"
  225. placeholder="例如:YJYA-2024-001"
  226. style="width: 330px"
  227. />
  228. </el-form-item>
  229. <el-form-item label="演练计划及实施情况" prop="rectificationPlan">
  230. <el-input
  231. disabled
  232. v-model="formValue.rectificationPlan"
  233. size="large"
  234. placeholder="例如:每季度演练一次,最近一次于2025年12月完成"
  235. style="width: 330px"
  236. />
  237. </el-form-item>
  238. <el-form-item label="风险等级" prop="riskLevel">
  239. <el-select
  240. disabled
  241. v-model="formValue.riskLevel"
  242. size="large"
  243. placeholder="请选择风险等级"
  244. style="width: 330px"
  245. >
  246. <el-option :value="1" label="高" />
  247. <el-option :value="2" label="中" />
  248. <el-option :value="3" label="低" />
  249. </el-select>
  250. </el-form-item>
  251. <el-form-item>
  252. <div style="width: 330px"></div>
  253. </el-form-item>
  254. <el-form-item label="备注" prop="remarks" style="width: 87.2%">
  255. <el-input
  256. disabled
  257. type="textarea"
  258. v-model="formValue.remarks"
  259. size="large"
  260. :rows="7"
  261. placeholder="可填写其他补充说明"
  262. />
  263. </el-form-item>
  264. <h4>信息变更</h4>
  265. <el-form-item label="部门名称" prop="responsibleDepartmentTodo">
  266. <el-cascader
  267. style="width: 330px"
  268. ref="cascaderTodoRef"
  269. size="large"
  270. :options="firstLevelDepts"
  271. :props="cascaderProp"
  272. :show-all-levels="false"
  273. placeholder="请选择责任部门"
  274. filterable
  275. @change="() => handleChangeDept('responsibleDepartmentTodo')"
  276. />
  277. </el-form-item>
  278. <el-form-item label="责任人姓名" prop="roomSafetyResponsibleTodo">
  279. <el-select
  280. v-model="formValue.roomSafetyResponsibleTodo"
  281. placeholder="请选择"
  282. size="large"
  283. style="width: 330px"
  284. filterable
  285. >
  286. <el-option
  287. v-for="item in roomSafetyResponsibleTodoOptions"
  288. :key="item.value"
  289. :label="item.label"
  290. :value="item.value"
  291. />
  292. </el-select>
  293. </el-form-item>
  294. <el-form-item>
  295. <div style="width: 330px"></div>
  296. </el-form-item>
  297. <el-form-item label="变更原因" prop="changeReason" style="width: 87.2%">
  298. <el-input
  299. type="textarea"
  300. v-model="formValue.changeReason"
  301. size="large"
  302. :rows="7"
  303. placeholder="请填写驳回审批原因"
  304. />
  305. </el-form-item>
  306. </el-form>
  307. </main>
  308. <footer class="safety-platform-container__footer">
  309. <el-button @click="$router.push({ name: 'areaResponsibilities:public' })">返回</el-button>
  310. <el-button type="primary" :loading="submiting" @click="handleSubmit">提交</el-button>
  311. </footer>
  312. </div>
  313. </template>
  314. <script lang="ts" setup>
  315. import { ref, reactive, onMounted, nextTick } from 'vue';
  316. import { useRouter, useRoute } from 'vue-router';
  317. import { ElMessage } from 'element-plus';
  318. import { getAllDepartments } from '@/api/auth/dept';
  319. import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
  320. import {
  321. queryAvailableUserList,
  322. safetyRiskListChange,
  323. safetyRiskListQueryDetail,
  324. } from '@/api/production-safety/responsibility-implementation';
  325. const router = useRouter();
  326. const route = useRoute();
  327. const formRef = ref<any>(null);
  328. const submiting = ref(false);
  329. const userOptions = ref<any[]>([]);
  330. const firstLevelDepts = ref<any[]>([]);
  331. const cascaderProp = {
  332. expandTrigger: 'click',
  333. checkStrictly: true,
  334. value: 'id',
  335. label: 'deptName',
  336. };
  337. const cascaderRef = ref<any>();
  338. const cascaderTodoRef = ref<any>();
  339. const roomSafetyResponsibleTodoOptions = ref<any[]>([]);
  340. const formValue = reactive({
  341. buildingArea: '',
  342. buildingName: '',
  343. safetyResponsibleBuilding: '',
  344. floorLocation: '',
  345. safetyResponsibleFloor: '',
  346. roomName: '',
  347. responsibleDepartment: '',
  348. roomSafetyResponsible: '',
  349. hasRiskPoint: '',
  350. riskCategory: '',
  351. riskPointName: '',
  352. riskPointNumber: '',
  353. riskPointSpec: '',
  354. trainingRequirement: '',
  355. safetyRisk: '',
  356. possibleHarm: '',
  357. mainControlMeasures: '',
  358. currentHazard: '',
  359. hazardContent: '',
  360. emergencyPlanName: '',
  361. emergencyPlanNumber: '',
  362. rectificationPlan: '',
  363. riskLevel: '',
  364. remarks: '',
  365. changeReason: '',
  366. responsibleDepartmentTodo: '',
  367. roomSafetyResponsibleTodo: '',
  368. responsibleDepartmentId: [],
  369. });
  370. const rules = reactive({
  371. buildingArea: [{ required: true, message: '请输入楼号', trigger: 'blur' }],
  372. buildingName: [{ required: true, message: '请输入楼宇/区域', trigger: 'blur' }],
  373. safetyResponsibleBuilding: [{ required: true, message: '请输入楼层/房号', trigger: 'blur' }],
  374. floorLocation: [{ required: true, message: '请输入名称/功能', trigger: 'blur' }],
  375. safetyResponsibleFloor: [{ required: true, message: '请选择安全责任所/中心', trigger: 'change' }],
  376. roomName: [{ required: true, message: '请选择安全责任所/中心负责人', trigger: 'change' }],
  377. responsibleDepartment: [{ required: true, message: '请选择安全责任部门', trigger: 'change' }],
  378. roomSafetyResponsible: [{ required: true, message: '请输入房间安全责任人', trigger: 'blur' }],
  379. hasRiskPoint: [{ required: true, message: '请选择是否有风险点', trigger: 'change' }],
  380. riskCategory: [{ required: true, message: '请选择风险类别', trigger: 'change' }],
  381. riskPointName: [{ required: true, message: '请输入风险点名称', trigger: 'blur' }],
  382. riskPointNumber: [{ required: true, message: '请输入风险点编号', trigger: 'blur' }],
  383. riskPointSpec: [{ required: true, message: '请输入风险点规格/参数', trigger: 'blur' }],
  384. trainingRequirement: [{ required: true, message: '请输入培训要求', trigger: 'blur' }],
  385. safetyRisk: [{ required: true, message: '请输入安全风险描述', trigger: 'blur' }],
  386. possibleHarm: [{ required: true, message: '请输入可能造成的伤害', trigger: 'blur' }],
  387. mainControlMeasures: [{ required: true, message: '请输入主要控制措施', trigger: 'blur' }],
  388. currentHazard: [{ required: true, message: '请选择当前隐患状态', trigger: 'change' }],
  389. hazardContent: [{ required: true, message: '请输入隐患内容', trigger: 'blur' }],
  390. emergencyPlanName: [{ required: true, message: '请输入应急预案名称', trigger: 'blur' }],
  391. emergencyPlanNumber: [{ required: true, message: '请输入应急预案编号', trigger: 'blur' }],
  392. rectificationPlan: [{ required: true, message: '请输入整改方案', trigger: 'blur' }],
  393. riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
  394. responsibleDepartmentTodo: [{ required: true, message: '请选择变更后的责任部门', trigger: 'change' }],
  395. roomSafetyResponsibleTodo: [{ required: true, message: '请选择变更后的责任人', trigger: 'change' }],
  396. changeReason: [{ required: true, message: '请输入变更原因', trigger: 'blur' }],
  397. remarks: [],
  398. });
  399. const handleChangeDept = (prop) => {
  400. const cascader = cascaderTodoRef.value;
  401. const deptInfo = cascader?.getCheckedNodes();
  402. formValue[prop] = deptInfo[0].label;
  403. formRef.value.validateField(prop);
  404. nextTick(() => {
  405. handleQueryAvailableUserList(deptInfo[0].label, prop);
  406. });
  407. };
  408. const getDeptData = () => {
  409. getAllDepartments().then((res) => {
  410. firstLevelDepts.value = formatDeptTree(res);
  411. });
  412. };
  413. const handleQueryAvailableUserList = (deptName = '', prop = '', realname = '') => {
  414. queryAvailableUserList({
  415. pageNumber: 1,
  416. pageSize: 200,
  417. queryParam: {
  418. deptName,
  419. realname,
  420. },
  421. }).then((res: any) => {
  422. switch (prop) {
  423. case 'responsibleDepartmentTodo':
  424. formValue.roomSafetyResponsibleTodo = '';
  425. roomSafetyResponsibleTodoOptions.value = (res.records || []).map((u: any) => ({
  426. value: u.userId || u.id,
  427. label: u.realname,
  428. }));
  429. break;
  430. default:
  431. break;
  432. }
  433. });
  434. };
  435. const loadDetailData = (id: number) => {
  436. safetyRiskListQueryDetail(id).then((res: any) => {
  437. Object.keys(formValue).forEach((key) => {
  438. if (res[key] !== undefined) {
  439. formValue[key] = res[key];
  440. formValue['responsibleDepartmentId'] = res['responsibleDepartmentId']
  441. ? res['responsibleDepartmentId'].split(',').map((item: string) => Number(item))
  442. : [];
  443. }
  444. });
  445. });
  446. };
  447. // const getUserData = () => {
  448. // getUserList({ pageNumber: 1, pageSize: 200, queryParam: {} }).then((res: any) => {
  449. // userOptions.value = (res.records || []).map((u: any) => ({
  450. // id: u.userId || u.id,
  451. // name: u.realName || u.username,
  452. // }));
  453. // });
  454. // };
  455. onMounted(() => {
  456. getDeptData();
  457. loadDetailData(Number(route.query.id));
  458. handleQueryAvailableUserList('');
  459. });
  460. const handleSubmit = () => {
  461. formRef.value?.validate((valid: boolean) => {
  462. if (valid) {
  463. submiting.value = true;
  464. safetyRiskListChange({
  465. id: route.query.id,
  466. responsibleDepartmentTodo: formValue.responsibleDepartmentTodo,
  467. roomSafetyResponsibleTodo: formValue.roomSafetyResponsibleTodo,
  468. changeReason: formValue.changeReason,
  469. })
  470. .then(() => {
  471. ElMessage.success('变更成功!');
  472. router.push({ name: 'riskManage' });
  473. })
  474. .finally(() => {
  475. submiting.value = false;
  476. });
  477. }
  478. });
  479. };
  480. </script>
  481. <style lang="scss" scoped>
  482. @use '@/styles/page-main-layout.scss' as *;
  483. @use '@/styles/page-details-layout.scss' as *;
  484. @use '@/styles/basic-table-action.scss' as *;
  485. .editor-container {
  486. border: 1px solid #dcdfe6;
  487. border-radius: 4px;
  488. margin-right: 20px;
  489. overflow: hidden;
  490. // :deep(.w-e-text-container) {
  491. // min-height: 400px;
  492. // overflow-y: auto;
  493. // }
  494. }
  495. // :deep(.breadcrumb .title) {
  496. // margin-left: 0;
  497. // }
  498. // .main {
  499. // display: flex;
  500. // flex-direction: column;
  501. // padding: 20px;
  502. // flex: 1;
  503. // overflow: hidden;
  504. // background-color: #fff;
  505. // }
  506. // .button-content {
  507. // margin-bottom: 20px;
  508. // }
  509. // .page-content {
  510. // display: flex;
  511. // justify-content: flex-end;
  512. // }
  513. // // :deep(.el-form) {
  514. // // flex: 1;
  515. // // overflow: hidden;
  516. // // overflow-y: auto;
  517. // // }
  518. </style>