view.vue 16 KB

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