riskDetail.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  1. <template>
  2. <div>
  3. <el-dialog
  4. :title="title"
  5. center
  6. :visible.sync="dialogVisible"
  7. width="90%"
  8. append-to-body
  9. top
  10. style="margin-top: 5vh"
  11. :close-on-click-modal="false"
  12. :show-close="false"
  13. :close-on-press-escape="false"
  14. >
  15. <div v-loading="loading" class="contain">
  16. <div class="info">
  17. <div class="item">
  18. <span>部门:</span>
  19. <ibps-user-selector
  20. v-model="position"
  21. style="width: 60%"
  22. type="position"
  23. readonly-text="text"
  24. :disabled="readonly"
  25. :multiple="false"
  26. size="mini"
  27. :filter="filter"
  28. filtrate
  29. />
  30. </div>
  31. <div class="item">
  32. <span>评估人:</span>
  33. <ibps-user-selector
  34. style="width: 60%"
  35. type="user"
  36. :value="userId"
  37. readonly-text="text"
  38. :disabled="true"
  39. :multiple="false"
  40. size="mini"
  41. />
  42. </div>
  43. <div class="item">
  44. <span>编制时间:</span>
  45. <el-date-picker
  46. v-model="time"
  47. type="datetime"
  48. placeholder="未编制"
  49. :disabled="readonly"
  50. value-format="yyyy-MM-dd HH:mm:ss"
  51. size="mini"
  52. />
  53. </div>
  54. </div>
  55. <el-alert
  56. title="说明"
  57. type="success"
  58. :closable="false"
  59. :description="descriptionContent"
  60. />
  61. <div class="tab">
  62. <el-tabs v-model="activeName">
  63. <el-tab-pane
  64. v-for="item in content.filter((i) => !!!i.hide)"
  65. :key="item.label"
  66. :label="item.label"
  67. :name="item.label"
  68. >
  69. <div class="content">
  70. <div class="left">
  71. <pre>{{ item.value }}</pre>
  72. </div>
  73. <div
  74. v-if="
  75. activeName === '风险等级及应对措施说明' && muban === '1'
  76. "
  77. class="right"
  78. >
  79. <el-image
  80. style="width: 100%; height: 100%"
  81. :src="photo"
  82. fit="contain"
  83. :preview-src-list="[photo]"
  84. alt="风险矩阵参照图"
  85. />
  86. </div>
  87. </div>
  88. </el-tab-pane>
  89. </el-tabs>
  90. </div>
  91. <el-alert
  92. title=""
  93. type="success"
  94. :closable="false"
  95. description="风险应对选择风险降低后,需要填写对应的措施制定人,以便开启后续部门风险改进记录流程"
  96. />
  97. <div class="choose">
  98. <span>选择风险项:</span>
  99. <!-- 模版弹窗 -->
  100. <ibps-custom-dialog
  101. v-model="form.xuan_ze_feng_xian"
  102. size="mini"
  103. template-key="fxkdhk"
  104. multiple
  105. type="dialog"
  106. class="custom-dialog"
  107. placeholder="请选择风险项"
  108. style="width: 80%"
  109. icon="el-icon-search"
  110. :disabled="readonly === 0 ? true : readonly"
  111. />
  112. </div>
  113. <div class="table">
  114. <el-alert
  115. style="margin-bottom: 12px"
  116. title=""
  117. type="success"
  118. :closable="false"
  119. description="提示:可以拖动表格数据进行排序"
  120. />
  121. <el-table ref="eltable1" :data="tableList" border>
  122. <el-table-column
  123. prop=""
  124. label="序号"
  125. type="index"
  126. width="50"
  127. :index="showIndex"
  128. />
  129. <el-table-column
  130. prop="yao_su_tiao_kuan_"
  131. label="要素条款"
  132. width="120"
  133. />
  134. <el-table-column
  135. prop="gong_zuo_huan_jie"
  136. label="工作环节"
  137. width="150"
  138. >
  139. <template slot-scope="{ row }">
  140. <el-input
  141. v-model="row.gong_zuo_huan_jie"
  142. type="textarea"
  143. :rows="2"
  144. size="mini"
  145. :disabled="readonly"
  146. />
  147. </template>
  148. </el-table-column>
  149. <!-- <el-table-column
  150. prop="gong_zuo_miao_shu"
  151. label="工作描述"
  152. width="150"
  153. >
  154. <template slot-scope="{row}">
  155. <el-input v-model="row.gong_zuo_miao_shu" type="textarea" :rows="2" size="mini" :readonly="readonly" />
  156. </template>
  157. </el-table-column> -->
  158. <el-table-column
  159. prop="feng_xian_miao_sh"
  160. label="风险描述"
  161. width="150"
  162. >
  163. <template slot-scope="{ row }">
  164. <el-input
  165. v-model="row.feng_xian_miao_sh"
  166. type="textarea"
  167. :rows="2"
  168. size="mini"
  169. :disabled="readonly"
  170. />
  171. </template>
  172. </el-table-column>
  173. <el-table-column
  174. prop="xian_xing_kong_zh"
  175. label="现行控制方法"
  176. width="150"
  177. >
  178. <template slot-scope="{ row }">
  179. <el-input
  180. v-model="row.xian_xing_kong_zh"
  181. type="textarea"
  182. :rows="2"
  183. size="mini"
  184. :disabled="readonly"
  185. />
  186. </template>
  187. </el-table-column>
  188. <el-table-column
  189. prop="yan_zhong_cheng_d"
  190. label="严重程度"
  191. width="100"
  192. >
  193. <template slot-scope="{ row }">
  194. <el-select
  195. v-model="row.yan_zhong_cheng_d"
  196. placeholder="请选择"
  197. :disabled="readonly"
  198. size="mini"
  199. @change="culRate(row)"
  200. >
  201. <el-option
  202. v-for="item in yan_zhong_cheng_d_List"
  203. :key="item"
  204. :label="item"
  205. :value="item"
  206. />
  207. </el-select>
  208. </template>
  209. </el-table-column>
  210. <el-table-column
  211. prop="fa_sheng_pin_du_"
  212. label="发生频度"
  213. width="100"
  214. >
  215. <template slot-scope="{ row }">
  216. <el-select
  217. v-model="row.fa_sheng_pin_du_"
  218. placeholder="请选择"
  219. :disabled="readonly"
  220. size="mini"
  221. @change="culRate(row)"
  222. >
  223. <el-option
  224. v-for="item in fa_sheng_pin_du_List"
  225. :key="item"
  226. :label="item"
  227. :value="item"
  228. />
  229. </el-select>
  230. </template>
  231. </el-table-column>
  232. <el-table-column
  233. v-if="muban === '2'"
  234. prop="ke_jian_ce_du_"
  235. label="可检测度"
  236. width="100"
  237. >
  238. <template slot-scope="{ row }">
  239. <el-select
  240. v-model="row.ke_jian_ce_du_"
  241. placeholder="请选择"
  242. :disabled="readonly"
  243. size="mini"
  244. @change="culRate(row)"
  245. >
  246. <el-option
  247. v-for="item in ke_jian_ce_du_List"
  248. :key="item"
  249. :label="item"
  250. :value="item"
  251. />
  252. </el-select>
  253. </template>
  254. </el-table-column>
  255. <el-table-column
  256. prop="feng_xian_zhi_shu"
  257. label="风险系数"
  258. width="70"
  259. />
  260. <el-table-column
  261. prop="feng_xian_deng_ji"
  262. label="风险等级"
  263. width="100"
  264. />
  265. <el-table-column
  266. prop="feng_xian_ying_du"
  267. label="风险应对"
  268. width="120"
  269. >
  270. <template slot-scope="{ row }">
  271. <el-select
  272. v-model="row.feng_xian_ying_du"
  273. placeholder="请选择"
  274. :disabled="readonly"
  275. size="mini"
  276. >
  277. <el-option
  278. v-for="item in riskResponse"
  279. :key="item"
  280. :label="item"
  281. :value="item"
  282. />
  283. </el-select>
  284. </template>
  285. </el-table-column>
  286. <el-table-column
  287. prop="qian_zai_yuan_yin"
  288. label="潜在原因分析"
  289. width="150"
  290. >
  291. <template slot-scope="{ row }">
  292. <el-input
  293. v-model="row.qian_zai_yuan_yin"
  294. type="textarea"
  295. :rows="2"
  296. size="mini"
  297. :disabled="readonly"
  298. />
  299. </template>
  300. </el-table-column>
  301. <el-table-column
  302. prop="ni_cai_qu_cuo_shi"
  303. label="拟采取控制措施"
  304. width="150"
  305. >
  306. <template slot-scope="{ row }">
  307. <el-input
  308. v-model="row.ni_cai_qu_cuo_shi"
  309. type="textarea"
  310. :rows="2"
  311. size="mini"
  312. :disabled="readonly"
  313. />
  314. </template>
  315. </el-table-column>
  316. <el-table-column
  317. prop="zhi_ding_ren_"
  318. label="措施制定人"
  319. width="100"
  320. >
  321. <template slot-scope="{ row }">
  322. <ibps-user-selector
  323. v-model="row.zhi_ding_ren_"
  324. type="user"
  325. readonly-text="text"
  326. :disabled="readonly"
  327. :multiple="true"
  328. size="mini"
  329. :filter="filter"
  330. filtrate
  331. />
  332. </template>
  333. </el-table-column>
  334. </el-table>
  335. </div>
  336. <!-- <el-pagination
  337. style="margin-top: 5px; padding-bottom: 10px"
  338. :current-page="pagination.currentPage"
  339. :page-sizes="[10, 20,30, 50]"
  340. :page-size="pagination.pageSize"
  341. layout="prev,pager,next,jumper,sizes,->,total"
  342. :total="categoryList.length"
  343. @size-change="handleSizeChange"
  344. @current-change="handleCurrentChange"
  345. /> -->
  346. </div>
  347. <span slot="footer" class="dialog-footer">
  348. <el-button
  349. v-if="!readonly"
  350. type="primary"
  351. size="mini"
  352. icon="el-icon-takeaway-box"
  353. @click="save"
  354. >保 存</el-button
  355. >
  356. <el-button
  357. v-if="!readonly"
  358. type="primary"
  359. size="mini"
  360. icon="el-icon-finished"
  361. @click="submit"
  362. >提 交</el-button
  363. >
  364. <el-button
  365. size="mini"
  366. icon="ibps-icon-close"
  367. type="danger"
  368. @click="close"
  369. >退 出</el-button
  370. >
  371. </span>
  372. </el-dialog>
  373. </div>
  374. </template>
  375. <script>
  376. import { getSetting } from '@/utils/query'
  377. import dayjs from 'dayjs'
  378. import ibpsUserSelector from '@/business/platform/org/selector'
  379. import { getImage } from '@/api/platform/file/attachment'
  380. import sortableJs from '@/mixins/sortable'
  381. import Sortable from 'sortablejs'
  382. export default {
  383. mixins: [sortableJs],
  384. components: {
  385. ibpsUserSelector,
  386. IbpsCustomDialog: () =>
  387. import('@/business/platform/data/templaterender/custom-dialog')
  388. },
  389. props: {
  390. culWays: {
  391. type: Object,
  392. default: () => ({})
  393. }
  394. },
  395. data() {
  396. const { userId, position, level } = this.$store.getters
  397. return {
  398. filter: [
  399. {
  400. descVal: '1',
  401. includeSub: true,
  402. old: 'position',
  403. partyId: this.$store.getters.userInfo.employee.positions,
  404. partyName: '',
  405. scriptContent: '',
  406. type: 'user',
  407. userType: 'position'
  408. }
  409. ],
  410. tkey: 1,
  411. form: {
  412. xuan_ze_feng_xian: ''
  413. },
  414. activeName: '风险等级及应对措施说明',
  415. content: [
  416. { label: '严重程度分级描述', value: '/' },
  417. { label: '发生概率分级表说明', value: '/' },
  418. { label: '事件可检测度描述', value: '/' },
  419. {
  420. label: '风险等级及应对措施说明',
  421. value: `未找到配置数据,使用默认配置:
  422. 低:可保持已有的安全措施。
  423. 中:需采取有效措施对风险进行控制。
  424. 高:需采取有效措施对风险进行控制。
  425. 极高:需采取有效措施对风险进行控制。`
  426. }
  427. ],
  428. fengXianDengJi2: {
  429. label: '风险等级及应对措施说明',
  430. value: `未找到配置数据,使用默认配置:
  431. 可忽略的:1-8,稍有危险,可以接受。
  432. 可接受的:9-27,一般危险,需要注意。
  433. 中度的:28-63,显著危险,需要整改。
  434. 重大的:64-99,高度危险,需立即整改。
  435. 不可接受的:100-125,极其危险,不能继续作业。`
  436. },
  437. fengXianDengJi3: {
  438. label: '风险等级及应对措施说明',
  439. value: `未找到配置数据,使用默认配置:
  440. 低风险:1-4,风险较低,当采取措施消除风险引起的成本比风险本身引起的损失较大时,接受风险。
  441. 中风险:5-11,可采取措施降低风险或风险规避。
  442. 高风险:12-25,应采取措施规避或降低风险。`
  443. },
  444. yan_zhong_cheng_d_List: ['1', '2', '3', '4', '5'],
  445. fa_sheng_pin_du_List: ['1', '2', '3', '4', '5'],
  446. ke_jian_ce_du_List: ['1', '2', '3', '4', '5'],
  447. userId: userId,
  448. position: position,
  449. level: level.second || level.first,
  450. time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  451. params: {},
  452. rowParams: {},
  453. refresh: true,
  454. loading: false,
  455. title: '',
  456. pagination: {
  457. pageSize: 10,
  458. currentPage: 1
  459. },
  460. dialogVisible: false,
  461. tableList: [],
  462. Ids: [],
  463. fengXianJiSuan: [],
  464. muban: '2',
  465. leixing: '安全',
  466. riskResponse: ['风险降低', '风险接受', '风险回避']
  467. }
  468. },
  469. computed: {
  470. photo() {
  471. return getImage('risk_fxjz') // 风险矩阵参照图
  472. },
  473. descriptionContent() {
  474. const msg1 = `1.当前风险系数计算公式为模板一:'${
  475. this.culWays[this.muban]
  476. }'。2.风险等级由严重程度和发生频度组成的坐标值映射成为矩阵坐标。`
  477. const msg2 = `1.当前风险系数计算公式为模板二:'${
  478. this.culWays[this.muban]
  479. }'。2.风险系数 RPN = Severity(严重度) × Occurrence(发生度)× Likelihood of Detection(检测度)。`
  480. const msg3 = `1.当前风险系数计算公式为模板三:'${
  481. this.culWays[this.muban]
  482. }'。2.风险系数 RPN = Severity(严重程度) × Possibility(发生的可能性)。`
  483. switch (this.muban) {
  484. case '1':
  485. return msg1
  486. case '2':
  487. return msg2
  488. case '3':
  489. return msg3
  490. default:
  491. break
  492. }
  493. return msg1
  494. },
  495. showPaperList() {
  496. const start = (this.pagination.currentPage - 1) * this.pagination.pageSize
  497. const end = start + this.pagination.pageSize
  498. return this.categoryList.slice(start, end)
  499. },
  500. readonly() {
  501. if (this.rowParams.bian_zhi_ren_) {
  502. return true
  503. } else {
  504. if (this.tableList.length) {
  505. return this.tableList.every(
  506. (item) => item.shi_fou_guo_shen_ === '已完成'
  507. )
  508. } else {
  509. return false
  510. }
  511. }
  512. }
  513. },
  514. watch: {
  515. params: {
  516. handler(val) {
  517. console.log('params')
  518. this.getTableData()
  519. }
  520. },
  521. rowParams: {
  522. handler(val) {
  523. console.log('rowParams')
  524. this.getTableData()
  525. }
  526. },
  527. 'form.xuan_ze_feng_xian': {
  528. handler(data) {
  529. this.loading = true
  530. const order = data.replace(/,/g, "','")
  531. // const sql = `select * from t_fxkzb where find_in_set(id_ , '${data}') ORDER BY FIELD(id_, '${order}')`
  532. this.$common
  533. .request('query', {
  534. key: 'getRiskLibraryData',
  535. params: [data, order]
  536. })
  537. .then((response) => {
  538. let data1 = []
  539. if (
  540. response.variables != null &&
  541. response.variables.data != null &&
  542. response.variables.data.length > 0
  543. ) {
  544. data1 = response.variables.data
  545. // console.log(data1)
  546. for (const item of data1) {
  547. const chongfu = this.tableList.find(
  548. (i) => i.shi_bie_xiang_ === item.id_
  549. )
  550. if (!chongfu) {
  551. this.tableList.push({
  552. di_dian_: this.level,
  553. bian_zhi_ren_: this.userId,
  554. bian_zhi_bu_men_: this.position,
  555. bian_zhi_shi_jian: this.time,
  556. parent_id_: this.params.id_,
  557. shi_bie_xiang_: item.id_,
  558. yao_su_tiao_kuan_: item.tiao_kuan_,
  559. gong_zuo_huan_jie: item.huan_jie_,
  560. // gong_zuo_miao_shu: item.gong_zuo_miao_shu,
  561. feng_xian_miao_sh: item.feng_xian_miao_sh,
  562. xian_xing_kong_zh: item.gong_zuo_miao_shu,
  563. ni_cai_qu_cuo_shi: '',
  564. zhi_ding_ren_: '',
  565. qian_zai_yuan_yin: ''
  566. })
  567. }
  568. }
  569. }
  570. this.tableList.forEach((item) => {
  571. const cunZai = data1.find((i) => i.id_ === item.shi_bie_xiang_)
  572. if (!cunZai) {
  573. this.tableList = this.tableList.filter(
  574. (ii) => ii.shi_bie_xiang_ !== item.shi_bie_xiang_
  575. )
  576. }
  577. })
  578. this.loading = false
  579. })
  580. }
  581. }
  582. },
  583. async mounted() {
  584. const riskResponse = await getSetting('risk', 'riskResponse')
  585. if (this.$utils.isNotEmpty(riskResponse)) {
  586. this.riskResponse = riskResponse
  587. }
  588. },
  589. methods: {
  590. // 初始化拖拽排序
  591. initSortable() {
  592. // 获取表格的tbody元素
  593. console.log(this.$refs)
  594. const el = this.$refs.eltable1.$el.querySelectorAll(
  595. '.el-table__body-wrapper > table > tbody'
  596. )[0]
  597. this.sortable = new Sortable(el, {
  598. // 拖拽时的类名
  599. ghostClass: 'sortable-ghost',
  600. // 拖拽动画时间
  601. animation: 150,
  602. // 结束拖拽时的回调
  603. onEnd: this.sortableEnd
  604. })
  605. },
  606. sortableEnd(evt) {
  607. const { oldIndex, newIndex } = evt
  608. // 复制原数组
  609. const newData = [...this.tableList]
  610. // 操作副本
  611. const movedItem = newData.splice(oldIndex, 1)[0]
  612. newData.splice(newIndex, 0, movedItem)
  613. // 重新赋值(引用变化,触发更新)
  614. this.tableList = []
  615. this.$nextTick(() => {
  616. // 确保数据已更新到DOM
  617. this.tableList = newData // 可结合表格自身的强制更新
  618. })
  619. // this.$forceUpdate()
  620. // const { oldIndex, newIndex } = evt
  621. // const temData = JSON.parse(JSON.stringify(this.tableList))
  622. // // 处理数据交换
  623. // const currRow = temData.splice(oldIndex, 1)[0]
  624. // temData.splice(newIndex, 0, currRow)
  625. // console.log(
  626. // 'temData==>',
  627. // temData.map((t) => t.yao_su_tiao_kuan_)
  628. // )
  629. // this.tableList = temData
  630. // this.$nextTick(() => {
  631. // this.$refs.eltable1.doLayout()
  632. // })
  633. },
  634. async getTableData() {
  635. this.loading = true
  636. // console.log(this.params)
  637. if (!this.params.id_) return
  638. // const sql = `select * from t_fxsbpgb2 where parent_id_ = '${this.params.id_}' and find_in_set(bian_zhi_ren_, '${this.readonly ? this.rowParams.bian_zhi_ren_ : this.userId}')`
  639. const params = [
  640. this.params.id_,
  641. this.readonly ? this.rowParams.bian_zhi_ren_ : this.userId
  642. ]
  643. const {
  644. variables: { data }
  645. } = await this.$common.request('query', {
  646. key: 'getFxsbpgb2ByUid',
  647. params
  648. })
  649. if (data.length > 0) {
  650. // console.log('data', data)
  651. this.position = data[0].bian_zhi_bu_men_
  652. this.userId = data[0].bian_zhi_ren_
  653. this.time = data[0].bian_zhi_shi_jian
  654. this.form.xuan_ze_feng_xian = data[0].xuan_ze_feng_xian
  655. this.tableList = data
  656. this.tableList.forEach((i) => {
  657. if (!Object.hasOwn(i, 'qian_zai_yuan_yin')) i.qian_zai_yuan_yin = ''
  658. })
  659. // 存储原始数据的 id 数组
  660. this.Ids = this.tableList.map((item) => item.shi_bie_xiang_)
  661. } else {
  662. if (this.rowParams.bian_zhi_ren_) {
  663. this.position = this.rowParams.bian_zhi_bu_men_
  664. this.userId = this.rowParams.bian_zhi_ren_
  665. this.time = ''
  666. }
  667. this.tableList = []
  668. this.Ids = []
  669. }
  670. this.muban = this.params.ji_suan_fang_shi_
  671. this.leixing = this.params.feng_xian_lei_xin
  672. if (this.muban === '2') {
  673. this.content[3] = this.fengXianDengJi2
  674. } else if (this.muban === '3') {
  675. this.content[3] = this.fengXianDengJi3
  676. }
  677. // 获取风险等级相关
  678. // const degreeSql = `select feng_xian_lei_xin,yan_zhong_cheng_d, fen_ji_, miao_shu_ FROM t_yzcdfjbzb WHERE zi_fen_lei_ ='严重程度' and di_dian_ = '${this.level}' and mo_ban_fen_lei_='${this.muban}' and feng_xian_lei_xin='${this.leixing}' ORDER BY fen_ji_ ASC`
  679. // const gailvSql = `select feng_xian_lei_xin,yan_zhong_cheng_d, fen_ji_, miao_shu_ FROM t_yzcdfjbzb WHERE zi_fen_lei_ ='发生概率' and di_dian_ = '${this.level}' and mo_ban_fen_lei_='${this.muban}' and feng_xian_lei_xin='${this.leixing}' ORDER BY fen_ji_ ASC`
  680. // const dengjiSql = `select feng_xian_lei_xin,yan_zhong_cheng_d, fen_ji_, miao_shu_ FROM t_yzcdfjbzb WHERE zi_fen_lei_ ='风险等级' and di_dian_ = '${this.level}' and mo_ban_fen_lei_='${this.muban}' and feng_xian_lei_xin='${this.leixing}'`
  681. // const jianCeSql = `select feng_xian_lei_xin,yan_zhong_cheng_d, fen_ji_, miao_shu_ FROM t_yzcdfjbzb WHERE zi_fen_lei_ ='可检测度' and di_dian_ = '${this.level}' and mo_ban_fen_lei_='${this.muban}' and feng_xian_lei_xin='${this.leixing}' ORDER BY fen_ji_ ASC`
  682. Promise.all([
  683. this.$common.request('query', {
  684. key: 'getRiskConfigWithOrder',
  685. params: ['严重程度', this.level, this.muban, this.leixing]
  686. }),
  687. this.$common.request('query', {
  688. key: 'getRiskConfigWithOrder',
  689. params: ['发生概率', this.level, this.muban, this.leixing]
  690. }),
  691. this.$common.request('query', {
  692. key: 'getRiskConfig',
  693. params: ['风险等级', this.level, this.muban, this.leixing]
  694. }),
  695. this.$common.request('query', {
  696. key: 'getRiskConfigWithOrder',
  697. params: ['可检测度', this.level, this.muban, this.leixing]
  698. })
  699. ])
  700. .then((responses) => {
  701. let degreeData = []
  702. let gailvData = []
  703. let dengjiData = []
  704. let jianCeData = []
  705. if (
  706. responses[0].variables != null &&
  707. responses[0].variables.data != null &&
  708. responses[0].variables.data.length > 0
  709. ) {
  710. degreeData = responses[0].variables.data
  711. }
  712. if (
  713. responses[1].variables != null &&
  714. responses[1].variables.data != null &&
  715. responses[1].variables.data.length > 0
  716. ) {
  717. gailvData = responses[1].variables.data
  718. }
  719. if (
  720. responses[2].variables != null &&
  721. responses[2].variables.data != null &&
  722. responses[2].variables.data.length > 0
  723. ) {
  724. dengjiData = responses[2].variables.data
  725. }
  726. if (
  727. responses[3].variables != null &&
  728. responses[3].variables.data != null &&
  729. responses[3].variables.data.length > 0
  730. ) {
  731. jianCeData = responses[3].variables.data
  732. }
  733. ;(this.muban === '1' || this.muban === '3') &&
  734. (this.content[2].hide = true)
  735. if (
  736. degreeData.length === 0 ||
  737. gailvData.length === 0 ||
  738. dengjiData.length === 0 ||
  739. (this.muban === '2' && jianCeData.length === 0)
  740. ) {
  741. throw new Error(
  742. `检测到风险类型为${this.leixing}且计算方式为'${
  743. this.culWays[this.muban] || this.muban
  744. }'的配置数据不完整,建议配置完成后再使用!`
  745. )
  746. }
  747. let degreeWord = ''
  748. let gailvWord = ''
  749. let dengjiWord = ''
  750. let jianCeWord = ''
  751. for (const el of degreeData) {
  752. degreeWord += `${el.fen_ji_}级:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  753. }
  754. for (const el of gailvData) {
  755. gailvWord += `${el.fen_ji_}级:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  756. }
  757. for (const el of dengjiData) {
  758. if (this.muban === '1') {
  759. dengjiWord += `${el.fen_ji_}:${el.miao_shu_}\n`
  760. } else {
  761. dengjiWord += `${el.fen_ji_}:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  762. }
  763. }
  764. for (const el of jianCeData) {
  765. jianCeWord += `${el.fen_ji_}级:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  766. }
  767. if (degreeData.length > 0) {
  768. this.content[0].value = degreeWord
  769. this.yan_zhong_cheng_d_List = degreeData.map((item) => item.fen_ji_)
  770. }
  771. if (gailvData.length > 0) {
  772. this.content[1].value = gailvWord
  773. this.fa_sheng_pin_du_List = gailvData.map((item) => item.fen_ji_)
  774. }
  775. if (jianCeData.length > 0) {
  776. this.content[2].value = jianCeWord
  777. this.ke_jian_ce_du_List = jianCeData.map((item) => item.fen_ji_)
  778. }
  779. if (dengjiData.length > 0) {
  780. this.content[3].value = dengjiWord
  781. }
  782. this.fengXianJiSuan = dengjiData
  783. this.loading = false
  784. })
  785. .catch((error) => {
  786. // 处理错误
  787. this.$message.warning(error.message)
  788. this.loading = false
  789. })
  790. },
  791. // 选择器切换
  792. onSelectorChange() {
  793. this.pagination = {
  794. pageSize: 10,
  795. currentPage: 1
  796. }
  797. },
  798. // 当前页码改变
  799. handleCurrentChange(val) {
  800. this.pagination.currentPage = val
  801. },
  802. // 页码选择器改变
  803. handleSizeChange(val) {
  804. this.pagination.pageSize = val
  805. this.pagination.currentPage = 1
  806. },
  807. // 分页连续序号
  808. showIndex(index) {
  809. return (
  810. index + 1 + (this.pagination.currentPage - 1) * this.pagination.pageSize
  811. )
  812. },
  813. close() {
  814. this.dialogVisible = false
  815. this.$emit('close')
  816. setTimeout(() => {
  817. this.rowParams = {}
  818. this.params = {}
  819. this.form.xuan_ze_feng_xian = ''
  820. }, 500)
  821. },
  822. open(val, row) {
  823. this.params = val
  824. if (row) {
  825. this.rowParams = row
  826. }
  827. this.dialogVisible = true
  828. !this.readonly && this.refreshSortable()
  829. },
  830. // 计算风险指数
  831. culRate(row) {
  832. try {
  833. if (this.muban === '1') {
  834. if (row.yan_zhong_cheng_d && row.fa_sheng_pin_du_) {
  835. let degree = ''
  836. let rate = ''
  837. rate = +row.yan_zhong_cheng_d * +row.fa_sheng_pin_du_
  838. if (this.fengXianJiSuan.length === 0) {
  839. if (rate >= 1 && rate < 4) {
  840. degree = '低'
  841. }
  842. if (rate > 4 && rate <= 9) {
  843. degree = '中'
  844. }
  845. if (rate >= 10 && rate <= 16) {
  846. degree = '高'
  847. }
  848. if (rate >= 20 && rate <= 25) {
  849. degree = '极高'
  850. }
  851. if (rate === 4) {
  852. if (
  853. +row.yan_zhong_cheng_d === 2 &&
  854. +row.fa_sheng_pin_du_ === 2
  855. ) {
  856. degree = '低'
  857. } else {
  858. degree = '中'
  859. }
  860. }
  861. } else {
  862. for (let i = 0; i < this.fengXianJiSuan.length; i++) {
  863. const item = this.fengXianJiSuan[i]
  864. if (item.yan_zhong_cheng_d) {
  865. const arr = JSON.parse(item.yan_zhong_cheng_d) || []
  866. for (let j = 0; j < arr.length; j++) {
  867. const [a, b] = arr[j]
  868. if (
  869. +a === +row.yan_zhong_cheng_d &&
  870. +b === +row.fa_sheng_pin_du_
  871. ) {
  872. degree = item.fen_ji_
  873. break
  874. }
  875. }
  876. }
  877. }
  878. }
  879. this.$set(
  880. row,
  881. 'feng_xian_ying_du',
  882. !row.feng_xian_ying_du && degree === '低'
  883. ? '风险接受'
  884. : '风险降低'
  885. )
  886. row.feng_xian_zhi_shu = rate + ''
  887. row.feng_xian_deng_ji = degree
  888. }
  889. } else if (this.muban === '2') {
  890. if (
  891. row.yan_zhong_cheng_d &&
  892. row.fa_sheng_pin_du_ &&
  893. row.ke_jian_ce_du_
  894. ) {
  895. let degree = ''
  896. let rate = ''
  897. rate =
  898. +row.yan_zhong_cheng_d *
  899. +row.fa_sheng_pin_du_ *
  900. +row.ke_jian_ce_du_
  901. if (this.fengXianJiSuan.length === 0) {
  902. if (rate >= 1 && rate <= 8) {
  903. degree = '可忽略的'
  904. }
  905. if (rate >= 9 && rate <= 27) {
  906. degree = '可接受的'
  907. }
  908. if (rate >= 28 && rate <= 63) {
  909. degree = '中度的'
  910. }
  911. if (rate >= 64 && rate <= 99) {
  912. degree = '重大的'
  913. }
  914. if (rate >= 100 && rate <= 125) {
  915. degree = '不可接受的'
  916. }
  917. } else {
  918. for (let i = 0; i < this.fengXianJiSuan.length; i++) {
  919. const item = this.fengXianJiSuan[i]
  920. if (item.yan_zhong_cheng_d) {
  921. const [a, b] = item.yan_zhong_cheng_d.split('-')
  922. if (a && b) {
  923. if (rate >= +a.trim() && rate <= +b.trim()) {
  924. degree = item.fen_ji_
  925. break
  926. }
  927. }
  928. }
  929. }
  930. }
  931. this.$set(
  932. row,
  933. 'feng_xian_ying_du',
  934. !row.feng_xian_ying_du &&
  935. (degree === '可忽略的' || degree === '可接受的')
  936. ? '风险接受'
  937. : '风险降低'
  938. )
  939. row.feng_xian_zhi_shu = rate + ''
  940. row.feng_xian_deng_ji = degree
  941. }
  942. } else if (this.muban === '3') {
  943. if (row.yan_zhong_cheng_d && row.fa_sheng_pin_du_) {
  944. let degree = ''
  945. let rate = ''
  946. rate = +row.yan_zhong_cheng_d * +row.fa_sheng_pin_du_
  947. if (this.fengXianJiSuan.length === 0) {
  948. if (rate >= 1 && rate <= 4) {
  949. degree = '低风险'
  950. }
  951. if (rate >= 5 && rate <= 11) {
  952. degree = '中风险'
  953. }
  954. if (rate >= 12 && rate <= 25) {
  955. degree = '高风险'
  956. }
  957. } else {
  958. for (let i = 0; i < this.fengXianJiSuan.length; i++) {
  959. const item = this.fengXianJiSuan[i]
  960. if (item.yan_zhong_cheng_d) {
  961. const [a, b] = item.yan_zhong_cheng_d.split('-')
  962. if (a && b) {
  963. if (rate >= +a.trim() && rate <= +b.trim()) {
  964. degree = item.fen_ji_
  965. break
  966. }
  967. }
  968. }
  969. }
  970. }
  971. this.$set(
  972. row,
  973. 'feng_xian_ying_du',
  974. !row.feng_xian_ying_du && degree === '低风险'
  975. ? '风险接受'
  976. : '风险降低'
  977. )
  978. row.feng_xian_zhi_shu = rate + ''
  979. row.feng_xian_deng_ji = degree
  980. }
  981. }
  982. } catch (error) {
  983. this.$message.warning(
  984. '风险系数计算错误,请检查风险模板配置数据是否正确!'
  985. )
  986. }
  987. },
  988. check() {
  989. if (this.tableList.length === 0) {
  990. throw new Error('请选择风险项!')
  991. }
  992. for (let i = 0; i < this.tableList.length; i++) {
  993. const item = this.tableList[i]
  994. if (!item.feng_xian_zhi_shu) {
  995. throw new Error(`第${i + 1}未计算风险指数,请填写相关数据!`)
  996. }
  997. if (item.feng_xian_ying_du !== '风险接受' && !item.zhi_ding_ren_) {
  998. throw new Error(`第${i + 1}行缺少措施制定人!`)
  999. }
  1000. // 格式化成需要的数据
  1001. item.xuan_ze_feng_xian = this.form.xuan_ze_feng_xian
  1002. delete item.create_by_
  1003. delete item.create_time_
  1004. }
  1005. },
  1006. submit() {
  1007. // console.log(this.Ids)
  1008. this.$confirm('提交后不可再修改,是否确认保存并提交?', '提示', {
  1009. confirmButtonText: '继续',
  1010. cancelButtonText: '取消',
  1011. type: 'warning'
  1012. })
  1013. .then(async () => {
  1014. // 提交时自动保存
  1015. await this.save()
  1016. const params = {
  1017. tableName: 't_fxsbpgb2',
  1018. updList: this.Ids.map((item) => ({
  1019. where: {
  1020. shi_bie_xiang_: item,
  1021. bian_zhi_ren_: this.userId,
  1022. parent_id_: this.params.id_
  1023. },
  1024. param: {
  1025. shi_fou_guo_shen_: '已完成'
  1026. }
  1027. }))
  1028. }
  1029. console.log(params)
  1030. await this.$common.request('update', params)
  1031. // 判断是否是最后一个提交的评估人
  1032. const pinGuRenNum = this.params.ping_gu_ren_yuan_.split(',').length
  1033. // const sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}'`
  1034. const {
  1035. variables: { data }
  1036. } = await this.$common.request('query', {
  1037. key: 'getFxsbpgb2ByPid',
  1038. params: [this.params.id_]
  1039. })
  1040. const submitNum = new Set(data.map((item) => item.bian_zhi_ren_)).size
  1041. if (
  1042. submitNum === pinGuRenNum &&
  1043. data.every((item) => item.shi_fou_guo_shen_ === '已完成')
  1044. ) {
  1045. // 提醒组长
  1046. await this.$common.sendMsg({
  1047. subject: '风险评估与措施表单待提交',
  1048. content: `您有一份评估与措施表单待提交,请前往-风险控制-风险评估与措施页面提交,计划编号:${this.params.ji_hua_bian_hao_}。`,
  1049. receiverId: this.params.zu_chang_id_,
  1050. canreplay: '0',
  1051. skipTypeMsg: JSON.stringify({
  1052. skipType: 3,
  1053. pathInfo: '/tygl/fxkzV2/fxpgycslb' // 路由
  1054. })
  1055. })
  1056. console.log('通知组长成功')
  1057. }
  1058. console.log('提交成功')
  1059. this.$message({
  1060. type: 'success',
  1061. message: '提交成功!'
  1062. })
  1063. this.close()
  1064. })
  1065. .catch(() => {})
  1066. },
  1067. // 判断状态是否已完成
  1068. async getIsFinish() {
  1069. // const sql = `select * from t_fxsbpgb2 where parent_id_ = '${this.params.id_}' and find_in_set(bian_zhi_ren_, '${this.readonly ? this.rowParams.bian_zhi_ren_ : this.userId}')`
  1070. const params = [
  1071. this.params.id_,
  1072. this.readonly ? this.rowParams.bian_zhi_ren_ : this.userId
  1073. ]
  1074. const {
  1075. variables: { data }
  1076. } = await this.$common.request('query', {
  1077. key: 'getFxsbpgb2ByUid',
  1078. params
  1079. })
  1080. if (
  1081. data.length > 0 &&
  1082. data.every((item) => item.shi_fou_guo_shen_ === '已完成')
  1083. ) {
  1084. throw new Error('已提交,不可再次提交!')
  1085. }
  1086. // const sql2 = `select * from t_fxpgjlb2 where id_='${this.params.id_}'`
  1087. const {
  1088. variables: { data: data2 }
  1089. } = await this.$common.request('query', {
  1090. key: 'getFxpgjlb2ById',
  1091. params: [this.params.id_]
  1092. })
  1093. if (data2.length > 0 && data2[0].shi_fou_guo_shen_ === '已完成') {
  1094. throw new Error('已结束,不可再次提交!')
  1095. }
  1096. },
  1097. async save() {
  1098. try {
  1099. this.check()
  1100. await this.getIsFinish()
  1101. const curIds = this.tableList.map((item) => item.shi_bie_xiang_)
  1102. // 计算需要增加项
  1103. const addedIds = this.tableList.filter(
  1104. (item) => !this.Ids.includes(item.shi_bie_xiang_)
  1105. )
  1106. // 计算需要更新项
  1107. const updatedIds = this.tableList.filter(
  1108. (item) => this.Ids.includes(item.shi_bie_xiang_) && item.id_
  1109. )
  1110. // 计算需要删除项
  1111. const deletedIds = this.Ids.filter((id) => !curIds.includes(id))
  1112. console.log(addedIds, updatedIds, deletedIds)
  1113. // 新增
  1114. if (addedIds.length > 0) {
  1115. const params = {
  1116. tableName: 't_fxsbpgb2',
  1117. paramWhere: addedIds
  1118. }
  1119. console.log(params)
  1120. await this.$common.request('add', params)
  1121. console.log('添加成功')
  1122. }
  1123. // 更新
  1124. if (updatedIds.length > 0) {
  1125. const params = {
  1126. tableName: 't_fxsbpgb2',
  1127. updList: updatedIds.map((item) => ({
  1128. where: {
  1129. id_: item.id_
  1130. },
  1131. param: {
  1132. ...item,
  1133. xuan_ze_feng_xian: this.form.xuan_ze_feng_xian,
  1134. bian_zhi_bu_men_: this.position,
  1135. bian_zhi_shi_jian: this.time
  1136. }
  1137. }))
  1138. }
  1139. console.log(params)
  1140. await this.$common.request('update', params)
  1141. console.log('更新成功')
  1142. }
  1143. // 删除
  1144. if (deletedIds.length > 0) {
  1145. const ids = deletedIds.map((id) => id).join(',')
  1146. // const sql3 = `select * from t_fxsbpgb2 where parent_id_ = '${this.params.id_}' and bian_zhi_ren_='${this.userId}' and find_in_set(shi_bie_xiang_, '${ids}')`
  1147. const {
  1148. variables: { data: data3 }
  1149. } = await this.$common.request('query', {
  1150. key: 'getFxsbpgb2BySbx',
  1151. params: [this.params.id_, this.userId, ids]
  1152. })
  1153. if (data3.length > 0) {
  1154. // console.log('data3', data3)
  1155. const params = {
  1156. tableName: 't_fxsbpgb2',
  1157. paramWhere: {
  1158. id_: data3.map((item) => item.id_).join(',')
  1159. }
  1160. }
  1161. console.log(params)
  1162. await this.$common.request('delete', params)
  1163. console.log('删除成功')
  1164. }
  1165. }
  1166. await this.getTableData()
  1167. this.$message.success('保存成功')
  1168. // this.close()
  1169. } catch (error) {
  1170. this.$message.warning(error.message)
  1171. throw new Error(error.message)
  1172. }
  1173. }
  1174. }
  1175. }
  1176. </script>
  1177. <style lang="scss" scoped>
  1178. .contain {
  1179. padding: 20px;
  1180. .info {
  1181. padding: 0;
  1182. display: flex;
  1183. justify-content: space-around;
  1184. align-items: center;
  1185. width: 80%;
  1186. margin: 0 auto;
  1187. .item {
  1188. display: flex;
  1189. align-items: center;
  1190. width: 30%;
  1191. }
  1192. }
  1193. .tab {
  1194. pre {
  1195. overflow: auto;
  1196. margin: 0;
  1197. }
  1198. .content {
  1199. display: flex;
  1200. justify-content: space-between;
  1201. align-items: center;
  1202. .right {
  1203. width: 300px;
  1204. }
  1205. }
  1206. }
  1207. .choose {
  1208. display: flex;
  1209. align-items: center;
  1210. margin: 10px 0;
  1211. }
  1212. .table {
  1213. height: 300px;
  1214. overflow: auto;
  1215. margin-top: 20px;
  1216. ::v-deep .el-table__row {
  1217. cursor: move;
  1218. }
  1219. }
  1220. .tip {
  1221. padding-bottom: 12px;
  1222. }
  1223. }
  1224. </style>