riskDetail.vue 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  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 v-for="(item) in content" :key="item.label" :label="item.label" :name="item.label">
  64. <div class="text">
  65. <pre>{{ item.value }}</pre>
  66. </div>
  67. </el-tab-pane>
  68. </el-tabs>
  69. </div>
  70. <el-alert
  71. title=""
  72. type="success"
  73. :closable="false"
  74. description="风险应对选择风险降低后,需要填写对应的措施制定人,以便开启后续部门风险改进记录流程"
  75. />
  76. <div class="choose">
  77. <span>选择风险项:</span>
  78. <!-- 模版弹窗 -->
  79. <ibps-custom-dialog
  80. v-model="form.xuan_ze_feng_xian"
  81. size="mini"
  82. template-key="fxkdhk"
  83. multiple
  84. type="dialog"
  85. class="custom-dialog"
  86. placeholder="请选择风险项"
  87. style="width:80%"
  88. icon="el-icon-search"
  89. :disabled="readonly===0?true:readonly"
  90. />
  91. </div>
  92. <div class="table">
  93. <el-table :data="tableList" border>
  94. <el-table-column
  95. prop=""
  96. label="序号"
  97. type="index"
  98. width="50"
  99. :index="showIndex"
  100. />
  101. <el-table-column
  102. prop="yao_su_tiao_kuan_"
  103. label="要素条款"
  104. width="120"
  105. />
  106. <el-table-column
  107. prop="gong_zuo_huan_jie"
  108. label="工作环节"
  109. width="150"
  110. >
  111. <template slot-scope="{row}">
  112. <el-input v-model="row.gong_zuo_huan_jie" type="textarea" :rows="2" size="mini" :disabled="readonly" />
  113. </template>
  114. </el-table-column>
  115. <!-- <el-table-column
  116. prop="gong_zuo_miao_shu"
  117. label="工作描述"
  118. width="150"
  119. >
  120. <template slot-scope="{row}">
  121. <el-input v-model="row.gong_zuo_miao_shu" type="textarea" :rows="2" size="mini" :readonly="readonly" />
  122. </template>
  123. </el-table-column> -->
  124. <el-table-column
  125. prop="feng_xian_miao_sh"
  126. label="风险描述"
  127. width="150"
  128. >
  129. <template slot-scope="{row}">
  130. <el-input v-model="row.feng_xian_miao_sh" type="textarea" :rows="2" size="mini" :disabled="readonly" />
  131. </template>
  132. </el-table-column>
  133. <el-table-column
  134. prop="xian_xing_kong_zh"
  135. label="现行控制方法"
  136. width="150"
  137. >
  138. <template slot-scope="{row}">
  139. <el-input v-model="row.xian_xing_kong_zh" type="textarea" :rows="2" size="mini" :disabled="readonly" />
  140. </template>
  141. </el-table-column>
  142. <el-table-column
  143. prop="yan_zhong_cheng_d"
  144. label="严重程度"
  145. width="100"
  146. >
  147. <template slot-scope="{row}">
  148. <el-select v-model="row.yan_zhong_cheng_d" placeholder="请选择" :disabled="readonly" size="mini" @change="culRate(row)">
  149. <el-option
  150. v-for="item in yan_zhong_cheng_d_List"
  151. :key="item"
  152. :label="item"
  153. :value="item"
  154. />
  155. </el-select>
  156. </template>
  157. </el-table-column>
  158. <el-table-column
  159. prop="fa_sheng_pin_du_"
  160. label="发生频度"
  161. width="100"
  162. >
  163. <template slot-scope="{row}">
  164. <el-select v-model="row.fa_sheng_pin_du_" placeholder="请选择" :disabled="readonly" size="mini" @change="culRate(row)">
  165. <el-option
  166. v-for="item in fa_sheng_pin_du_List"
  167. :key="item"
  168. :label="item"
  169. :value="item"
  170. />
  171. </el-select>
  172. </template>
  173. </el-table-column>
  174. <el-table-column
  175. v-if="muban==='2'"
  176. prop="ke_jian_ce_du_"
  177. label="可检测度"
  178. width="100"
  179. >
  180. <template slot-scope="{row}">
  181. <el-select v-model="row.ke_jian_ce_du_" placeholder="请选择" :disabled="readonly" size="mini" @change="culRate(row)">
  182. <el-option
  183. v-for="item in ke_jian_ce_du_List"
  184. :key="item"
  185. :label="item"
  186. :value="item"
  187. />
  188. </el-select>
  189. </template>
  190. </el-table-column>
  191. <el-table-column
  192. prop="feng_xian_zhi_shu"
  193. label="风险系数"
  194. width="70"
  195. />
  196. <el-table-column
  197. prop="feng_xian_deng_ji"
  198. label="风险等级"
  199. width="100"
  200. />
  201. <el-table-column
  202. prop="feng_xian_ying_du"
  203. label="风险应对"
  204. width="120"
  205. >
  206. <template slot-scope="{row}">
  207. <el-select v-model="row.feng_xian_ying_du" placeholder="请选择" :disabled="readonly" size="mini">
  208. <el-option
  209. v-for="item in ['风险降低','风险接受','风险回避']"
  210. :key="item"
  211. :label="item"
  212. :value="item"
  213. />
  214. </el-select>
  215. </template>
  216. </el-table-column>
  217. <el-table-column
  218. prop="qian_zai_yuan_yin"
  219. label="潜在原因分析"
  220. width="150"
  221. >
  222. <template slot-scope="{row}">
  223. <el-input v-model="row.qian_zai_yuan_yin" type="textarea" :rows="2" size="mini" :disabled="readonly" />
  224. </template>
  225. </el-table-column>
  226. <el-table-column
  227. prop="ni_cai_qu_cuo_shi"
  228. label="拟采取控制措施"
  229. width="150"
  230. >
  231. <template slot-scope="{row}">
  232. <el-input v-model="row.ni_cai_qu_cuo_shi" type="textarea" :rows="2" size="mini" :disabled="readonly" />
  233. </template>
  234. </el-table-column>
  235. <el-table-column
  236. prop="zhi_ding_ren_"
  237. label="措施制定人"
  238. width="100"
  239. >
  240. <template slot-scope="{row}">
  241. <ibps-user-selector
  242. v-model="row.zhi_ding_ren_"
  243. type="user"
  244. readonly-text="text"
  245. :disabled="readonly"
  246. :multiple="true"
  247. size="mini"
  248. :filter="filter"
  249. filtrate
  250. />
  251. </template>
  252. </el-table-column>
  253. </el-table>
  254. </div>
  255. <!-- <el-pagination
  256. style="margin-top: 5px; padding-bottom: 10px"
  257. :current-page="pagination.currentPage"
  258. :page-sizes="[10, 20,30, 50]"
  259. :page-size="pagination.pageSize"
  260. layout="prev,pager,next,jumper,sizes,->,total"
  261. :total="categoryList.length"
  262. @size-change="handleSizeChange"
  263. @current-change="handleCurrentChange"
  264. /> -->
  265. </div>
  266. <span slot="footer" class="dialog-footer">
  267. <el-button v-if="!readonly" type="primary" size="mini" icon="el-icon-takeaway-box" @click="save">保 存</el-button>
  268. <el-button v-if="!readonly" type="primary" size="mini" icon="el-icon-finished" @click="submit">提 交</el-button>
  269. <el-button size="mini" icon="ibps-icon-close" type="danger" @click="close">退 出</el-button>
  270. </span>
  271. </el-dialog>
  272. </div>
  273. </template>
  274. <script>
  275. import dayjs from 'dayjs'
  276. import ibpsUserSelector from '@/business/platform/org/selector'
  277. export default {
  278. components: {
  279. ibpsUserSelector,
  280. IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog')
  281. },
  282. data () {
  283. const { userId, position, level } = this.$store.getters
  284. return {
  285. filter: [{
  286. descVal: '1',
  287. includeSub: true,
  288. old: 'position',
  289. partyId: this.$store.getters.userInfo.employee.positions,
  290. partyName: '',
  291. scriptContent: '',
  292. type: 'user',
  293. userType: 'position'
  294. }],
  295. form: {
  296. xuan_ze_feng_xian: ''
  297. },
  298. activeName: '严重程度分级描述',
  299. content: [
  300. { label: '严重程度分级描述', value: `1级:轻微,不会对检验科人员、设备、环境、形象造成损害;不会对检验质量造成影响;造成轻微的财产损失;无检验科信息泄露。
  301. 2级:一般,对检验科人员、设备、环境、形象造成轻微损害,对检验质量和TAT造成影响,能通过现场及时处置解决或缓解出现的损害和影响;造成一定的财产损失;未造成投诉;无检验科信息泄露。
  302. 3级:较严重,对检验科人员、设备、环境、形象造成损害,对检验质量和TAT造成影响,无法通过现场及时处置解决或缓解出现的损害和影响;被投诉至检验科管理层;造成较大的财产的损失;有检验科信息泄露。
  303. 4级:严重,对检验科人员造成较大伤害;对仪器设备造成损坏;对周边较少的人员或环境产生损害;对检验质量、TAT、临床诊疗造成严重影响;造成重大的的经济损失;被投诉至上级主管部门;造成不良的社会影响。
  304. 5级:非常严重,对检验科人员造成重大伤害甚至死亡;对仪器设备造成损毁;极度影响检验质量和TAT,对临床造成极大误诊致使病人死亡;对周边人员或环境产生重大损害;造成恶劣的社会影响;导致检验科停工停业。 ` },
  305. { label: '发生概率分级表说明', value: `1级:基本不可能发生,评估范围内未发生过,类似区域/行业也极少发生。
  306. 2级:较不可能发生,评估范围内未发生过,类似区域/行业偶有发生。
  307. 3级:可能发生,评估范围内发生过,类似区域/行业也偶有发生; 评估范围内未发生过,但类似区域/行业发生频率较高。
  308. 4级:很有可能发生,评估范围内发生频率较高。
  309. 5级:必定会发生,评估范围内发生频率很高。` },
  310. { label: '事件可检测度描述', value: `1级:确定,当某项风险发生时,根据现有的控制手段及检测方法,能准确识别出。
  311. 2级:大,当某项风险发生时,根据现有的控制手段及检测方法,识别出的概率较大。
  312. 3级:中等,当某项风险发生时,根据现有的控制手段及检测方法,识别出的概率中等。
  313. 4级:小,当某项风险发生时,根据现有的控制手段及检测方法,识别出的概率较小。
  314. 5级:不可测,当某项风险发生时,根据现有的控制手段及检测方法,不可识别。` },
  315. { label: '风险等级及应对措施说明', value: `低风险:1-4,风险较低,当采取措施消除风险引起的成本比风险本身引起的损失较大时,接受风险。
  316. 中风险:5-11,可采取措施降低风险。
  317. 高风险:12-25,应采取措施规避或降低风险。` }
  318. ],
  319. fengXianDengJi2: { label: '风险等级及应对措施说明', value: `可忽略的:1-8,稍有危险,可以接受。
  320. 可接受的:9-27,一般危险,需要注意。
  321. 中度的:28-63,显著危险,需要整改。
  322. 重大的:64-99,高度危险,需立即整改。
  323. 不可接受的:100-125,极其危险,不能继续作业。` },
  324. yan_zhong_cheng_d_List: ['1', '2', '3', '4', '5'],
  325. fa_sheng_pin_du_List: ['1', '2', '3', '4', '5'],
  326. ke_jian_ce_du_List: ['1', '2', '3', '4', '5'],
  327. userId: userId,
  328. position: position,
  329. level: level.second || level.first,
  330. time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  331. params: {},
  332. rowParams: {},
  333. refresh: true,
  334. loading: false,
  335. title: '',
  336. pagination: {
  337. pageSize: 10,
  338. currentPage: 1
  339. },
  340. dialogVisible: false,
  341. tableList: [],
  342. Ids: [],
  343. fengXianJiSuan: [],
  344. muban: '1'
  345. }
  346. },
  347. computed: {
  348. descriptionContent () {
  349. const msg1 = '1.当前风险系数计算公式为模板一。2.风险系数 RPN = Severity(严重度) × Occurrence(发生度)。'
  350. const msg2 = '1.当前风险系数计算公式为模板二。2.风险系数 RPN = Severity(严重度) × Occurrence(发生度)× Likelihood of Detection(检测度)。'
  351. switch (this.muban) {
  352. case '1':
  353. return msg1
  354. case '2':
  355. return msg2
  356. default:
  357. break
  358. }
  359. return msg1
  360. },
  361. showPaperList () {
  362. const start = (this.pagination.currentPage - 1) * this.pagination.pageSize
  363. const end = start + this.pagination.pageSize
  364. return this.categoryList.slice(start, end)
  365. },
  366. readonly () {
  367. if (this.rowParams.bian_zhi_ren_) {
  368. return true
  369. } else {
  370. if (this.tableList.length) {
  371. return this.tableList.every(item => item.shi_fou_guo_shen_ === '已完成')
  372. } else {
  373. return false
  374. }
  375. }
  376. }
  377. },
  378. watch: {
  379. params: {
  380. handler (val) {
  381. this.getTableData()
  382. }
  383. },
  384. rowParams: {
  385. handler (val) {
  386. this.getTableData()
  387. }
  388. },
  389. 'form.xuan_ze_feng_xian': {
  390. handler (data) {
  391. this.loading = true
  392. data = data.split(',')
  393. data = "'" + data.join("','") + "'"
  394. const sql = `select * from t_fxkzb where id_ in (${data}) ORDER BY FIELD(id_, ${data})`
  395. this.$common.request('sql', sql).then(response => {
  396. let data1 = []
  397. if (response.variables != null && response.variables.data != null && response.variables.data.length > 0) {
  398. data1 = response.variables.data
  399. // console.log(data1)
  400. for (const item of data1) {
  401. const chongfu = this.tableList.find(i => i.shi_bie_xiang_ === item.id_)
  402. if (!chongfu) {
  403. this.tableList.push({
  404. di_dian_: this.level,
  405. bian_zhi_ren_: this.userId,
  406. bian_zhi_bu_men_: this.position,
  407. bian_zhi_shi_jian: this.time,
  408. parent_id_: this.params.id_,
  409. shi_bie_xiang_: item.id_,
  410. yao_su_tiao_kuan_: item.tiao_kuan_,
  411. gong_zuo_huan_jie: item.huan_jie_,
  412. // gong_zuo_miao_shu: item.gong_zuo_miao_shu,
  413. feng_xian_miao_sh: item.feng_xian_miao_sh,
  414. xian_xing_kong_zh: item.gong_zuo_miao_shu,
  415. ni_cai_qu_cuo_shi: '',
  416. zhi_ding_ren_: '',
  417. qian_zai_yuan_yin: ''
  418. })
  419. }
  420. }
  421. }
  422. this.tableList.forEach(item => {
  423. const cunZai = data1.find(i => i.id_ === item.shi_bie_xiang_)
  424. if (!cunZai) {
  425. this.tableList = this.tableList.filter(ii => ii.shi_bie_xiang_ !== item.shi_bie_xiang_)
  426. }
  427. })
  428. this.loading = false
  429. })
  430. }
  431. }
  432. },
  433. methods: {
  434. async getTableData () {
  435. this.loading = true
  436. // console.log(this.params)
  437. if (!this.params.id_) return
  438. let sql = ''
  439. if (this.readonly) {
  440. sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}' and bian_zhi_ren_='${this.rowParams.bian_zhi_ren_}'`
  441. } else {
  442. sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}' and bian_zhi_ren_='${this.userId}'`
  443. }
  444. const { variables: { data }} = await this.$common.request('sql', sql)
  445. if (data.length > 0) {
  446. // console.log('data', data)
  447. this.position = data[0].bian_zhi_bu_men_
  448. this.userId = data[0].bian_zhi_ren_
  449. this.time = data[0].bian_zhi_shi_jian
  450. this.form.xuan_ze_feng_xian = data[0].xuan_ze_feng_xian
  451. this.tableList = data
  452. this.tableList.forEach(i => {
  453. if (!Object.hasOwn(i, 'qian_zai_yuan_yin')) i.qian_zai_yuan_yin = ''
  454. })
  455. // 存储原始数据的 id 数组
  456. this.Ids = this.tableList.map(item => item.shi_bie_xiang_)
  457. } else {
  458. if (this.rowParams.bian_zhi_ren_) {
  459. this.position = this.rowParams.bian_zhi_bu_men_
  460. this.userId = this.rowParams.bian_zhi_ren_
  461. this.time = ''
  462. }
  463. this.tableList = []
  464. this.Ids = []
  465. }
  466. this.muban = this.params.ji_suan_fang_shi_
  467. console.log('模板类型:', this.muban)
  468. // 获取风险等级相关
  469. const degreeSql = `select 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}' ORDER BY fen_ji_ ASC`
  470. const gailvSql = `select 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}' ORDER BY fen_ji_ ASC`
  471. const dengjiSql = `select 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}'`
  472. const jianCeSql = `select 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}' ORDER BY fen_ji_ ASC`
  473. Promise.all([
  474. this.$common.request('sql', degreeSql),
  475. this.$common.request('sql', gailvSql),
  476. this.$common.request('sql', dengjiSql),
  477. this.$common.request('sql', jianCeSql)
  478. ]).then(responses => {
  479. let degreeData = []
  480. let gailvData = []
  481. let dengjiData = []
  482. let jianCeData = []
  483. if (responses[0].variables != null && responses[0].variables.data != null && responses[0].variables.data.length > 0) {
  484. degreeData = responses[0].variables.data
  485. }
  486. if (responses[1].variables != null && responses[1].variables.data != null && responses[1].variables.data.length > 0) {
  487. gailvData = responses[1].variables.data
  488. }
  489. if (responses[2].variables != null && responses[2].variables.data != null && responses[2].variables.data.length > 0) {
  490. dengjiData = responses[2].variables.data
  491. }
  492. if (responses[3].variables != null && responses[3].variables.data != null && responses[3].variables.data.length > 0) {
  493. jianCeData = responses[3].variables.data
  494. }
  495. let degreeWord = ''
  496. let gailvWord = ''
  497. let dengjiWord = ''
  498. let jianCeWord = ''
  499. for (const el of degreeData) {
  500. degreeWord += `${el.fen_ji_}级:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  501. }
  502. for (const el of gailvData) {
  503. gailvWord += `${el.fen_ji_}级:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  504. }
  505. for (const el of dengjiData) {
  506. dengjiWord += `${el.fen_ji_}:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  507. }
  508. for (const el of jianCeData) {
  509. jianCeWord += `${el.fen_ji_}级:${el.yan_zhong_cheng_d},${el.miao_shu_}\n`
  510. }
  511. if (degreeData.length > 0) {
  512. console.log('严重程度使用配置值')
  513. this.content[0].value = degreeWord
  514. this.yan_zhong_cheng_d_List = degreeData.map(item => item.fen_ji_)
  515. }
  516. if (gailvData.length > 0) {
  517. console.log('发生概率使用配置值')
  518. this.content[1].value = gailvWord
  519. this.fa_sheng_pin_du_List = gailvData.map(item => item.fen_ji_)
  520. }
  521. if (jianCeData.length > 0) {
  522. console.log('可检测度使用配置值')
  523. this.content[2].value = jianCeWord
  524. this.ke_jian_ce_du_List = jianCeData.map(item => item.fen_ji_)
  525. }
  526. if (dengjiData.length > 0) {
  527. console.log('风险等级使用配置值')
  528. this.content[3].value = dengjiWord
  529. }
  530. this.fengXianJiSuan = dengjiData
  531. this.loading = false
  532. }).catch(error => {
  533. // 处理错误
  534. console.error('Error fetching data:', error)
  535. this.loading = false
  536. })
  537. },
  538. // 选择器切换
  539. onSelectorChange () {
  540. this.pagination = {
  541. pageSize: 10,
  542. currentPage: 1
  543. }
  544. },
  545. // 当前页码改变
  546. handleCurrentChange (val) {
  547. this.pagination.currentPage = val
  548. },
  549. // 页码选择器改变
  550. handleSizeChange (val) {
  551. this.pagination.pageSize = val
  552. this.pagination.currentPage = 1
  553. },
  554. // 分页连续序号
  555. showIndex (index) {
  556. return index + 1 + (this.pagination.currentPage - 1) * this.pagination.pageSize
  557. },
  558. close () {
  559. this.dialogVisible = false
  560. this.$emit('close')
  561. setTimeout(() => {
  562. this.rowParams = {}
  563. this.params = {}
  564. this.form.xuan_ze_feng_xian = ''
  565. }, 500)
  566. },
  567. open (val, row) {
  568. this.params = val
  569. if (row) {
  570. this.rowParams = row
  571. }
  572. this.dialogVisible = true
  573. },
  574. // 计算风险指数
  575. culRate (row) {
  576. try {
  577. if (this.muban === '1') {
  578. if (row.yan_zhong_cheng_d && row.fa_sheng_pin_du_) {
  579. let degree = ''
  580. let rate = ''
  581. rate = +row.yan_zhong_cheng_d * +row.fa_sheng_pin_du_
  582. if (this.fengXianJiSuan.length === 0) {
  583. if (rate >= 1 && rate <= 4) {
  584. degree = '低风险'
  585. }
  586. if (rate >= 5 && rate <= 11) {
  587. degree = '中风险'
  588. }
  589. if (rate >= 12 && rate <= 25) {
  590. degree = '高风险'
  591. }
  592. } else {
  593. for (let i = 0; i < this.fengXianJiSuan.length; i++) {
  594. const item = this.fengXianJiSuan[i]
  595. if (item.yan_zhong_cheng_d) {
  596. const [a, b] = item.yan_zhong_cheng_d.split('-')
  597. if (a && b) {
  598. if (rate >= +a.trim() && rate <= +b.trim()) {
  599. degree = item.fen_ji_
  600. break
  601. }
  602. }
  603. }
  604. }
  605. }
  606. this.$set(row, 'feng_xian_ying_du', (!row.feng_xian_ying_du && degree === '低风险') ? '风险接受' : '风险降低')
  607. row.feng_xian_zhi_shu = rate + ''
  608. row.feng_xian_deng_ji = degree
  609. }
  610. } else if (this.muban === '2') {
  611. if (row.yan_zhong_cheng_d && row.fa_sheng_pin_du_ && row.ke_jian_ce_du_) {
  612. let degree = ''
  613. let rate = ''
  614. rate = +row.yan_zhong_cheng_d * +row.fa_sheng_pin_du_ * +row.ke_jian_ce_du_
  615. if (this.fengXianJiSuan.length === 0) {
  616. if (rate >= 1 && rate <= 8) {
  617. degree = '可忽略的'
  618. }
  619. if (rate >= 9 && rate <= 27) {
  620. degree = '可接受的'
  621. }
  622. if (rate >= 28 && rate <= 63) {
  623. degree = '中度的'
  624. }
  625. if (rate >= 64 && rate <= 99) {
  626. degree = '重大的'
  627. }
  628. if (rate >= 100 && rate <= 125) {
  629. degree = '不可接受的'
  630. }
  631. } else {
  632. for (let i = 0; i < this.fengXianJiSuan.length; i++) {
  633. const item = this.fengXianJiSuan[i]
  634. if (item.yan_zhong_cheng_d) {
  635. const [a, b] = item.yan_zhong_cheng_d.split('-')
  636. if (a && b) {
  637. if (rate >= +a.trim() && rate <= +b.trim()) {
  638. degree = item.fen_ji_
  639. break
  640. }
  641. }
  642. }
  643. }
  644. }
  645. this.$set(row, 'feng_xian_ying_du', (!row.feng_xian_ying_du && (degree === '可忽略的' || degree === '可接受的')) ? '风险接受' : '风险降低')
  646. row.feng_xian_zhi_shu = rate + ''
  647. row.feng_xian_deng_ji = degree
  648. }
  649. }
  650. } catch (error) {
  651. this.$message.warning('风险系数计算错误,请检查风险模板配置数据是否正确!')
  652. }
  653. },
  654. check () {
  655. if (this.tableList.length === 0) {
  656. throw new Error('请选择风险项!')
  657. }
  658. for (let i = 0; i < this.tableList.length; i++) {
  659. const item = this.tableList[i]
  660. if (!item.feng_xian_zhi_shu) {
  661. throw new Error(`第${i + 1}未计算风险指数,请填写相关数据!`)
  662. }
  663. if (item.feng_xian_ying_du !== '风险接受' && !item.zhi_ding_ren_) {
  664. throw new Error(`第${i + 1}行缺少措施制定人!`)
  665. }
  666. // 格式化成需要的数据
  667. item.xuan_ze_feng_xian = this.form.xuan_ze_feng_xian
  668. delete item.create_by_
  669. delete item.create_time_
  670. }
  671. },
  672. submit () {
  673. // console.log(this.Ids)
  674. this.$confirm('提交后不可再修改,是否确认保存并提交?', '提示', {
  675. confirmButtonText: '继续',
  676. cancelButtonText: '取消',
  677. type: 'warning'
  678. }).then(async () => {
  679. // 提交时自动保存
  680. await this.save()
  681. const params = {
  682. tableName: 't_fxsbpgb2',
  683. updList: this.Ids.map(item => ({
  684. where: {
  685. shi_bie_xiang_: item,
  686. bian_zhi_ren_: this.userId,
  687. parent_id_: this.params.id_
  688. },
  689. param: {
  690. shi_fou_guo_shen_: '已完成'
  691. }
  692. }))
  693. }
  694. console.log(params)
  695. await this.$common.request('update', params)
  696. // 判断是否是最后一个提交的评估人
  697. const pinGuRenNum = this.params.ping_gu_ren_yuan_.split(',').length
  698. const sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}'`
  699. const { variables: { data }} = await this.$common.request('sql', sql)
  700. const submitNum = new Set(data.map(item => item.bian_zhi_ren_)).size
  701. if (submitNum === pinGuRenNum && data.every(item => item.shi_fou_guo_shen_ === '已完成')) {
  702. // 提醒组长
  703. await this.$common.sendMsg({
  704. subject: '风险评估与措施表单待提交',
  705. content: `您有一份评估与措施表单待提交,请前往-风险控制-风险评估与措施页面提交,计划编号:${this.params.ji_hua_bian_hao_}。`,
  706. receiverId: this.params.zu_chang_id_,
  707. canreplay: '0',
  708. skipTypeMsg: JSON.stringify({
  709. skipType: 3,
  710. pathInfo: '/tygl/fxkzV2/fxpgycslb' // 路由
  711. })
  712. })
  713. console.log('通知组长成功')
  714. }
  715. console.log('提交成功')
  716. this.$message({
  717. type: 'success',
  718. message: '提交成功!'
  719. })
  720. this.close()
  721. }).catch(() => {
  722. })
  723. },
  724. // 判断状态是否已完成
  725. async getIsFinish () {
  726. let sql = ''
  727. if (this.readonly) {
  728. sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}' and bian_zhi_ren_='${this.rowParams.bian_zhi_ren_}'`
  729. } else {
  730. sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}' and bian_zhi_ren_='${this.userId}'`
  731. }
  732. const { variables: { data }} = await this.$common.request('sql', sql)
  733. if (data.length > 0 && data.every(item => item.shi_fou_guo_shen_ === '已完成')) {
  734. throw new Error('已提交,不可再次提交!')
  735. }
  736. const sql2 = `select * from t_fxpgjlb2 where id_='${this.params.id_}'`
  737. const { variables: { data: data2 }} = await this.$common.request('sql', sql2)
  738. if (data2.length > 0 && data2[0].shi_fou_guo_shen_ === '已完成') {
  739. throw new Error('已结束,不可再次提交!')
  740. }
  741. },
  742. async save () {
  743. try {
  744. this.check()
  745. await this.getIsFinish()
  746. const curIds = this.tableList.map(item => item.shi_bie_xiang_)
  747. // 计算需要增加项
  748. const addedIds = this.tableList.filter(item => !this.Ids.includes(item.shi_bie_xiang_))
  749. // 计算需要更新项
  750. const updatedIds = this.tableList.filter(item => this.Ids.includes(item.shi_bie_xiang_))
  751. // 计算需要删除项
  752. const deletedIds = this.Ids.filter(id => !curIds.includes(id))
  753. console.log(addedIds, updatedIds, deletedIds)
  754. // 新增
  755. if (addedIds.length > 0) {
  756. const params = {
  757. tableName: 't_fxsbpgb2',
  758. paramWhere: addedIds
  759. }
  760. console.log(params)
  761. await this.$common.request('add', params)
  762. console.log('添加成功')
  763. }
  764. // 更新
  765. if (updatedIds.length > 0) {
  766. const params = {
  767. tableName: 't_fxsbpgb2',
  768. updList: updatedIds.map(item => ({
  769. where: {
  770. id_: item.id_
  771. },
  772. param: {
  773. ...item,
  774. xuan_ze_feng_xian: this.form.xuan_ze_feng_xian
  775. }
  776. }))
  777. }
  778. console.log(params)
  779. await this.$common.request('update', params)
  780. console.log('更新成功')
  781. }
  782. // 删除
  783. if (deletedIds.length > 0) {
  784. const sql3 = `select * from t_fxsbpgb2 where bian_zhi_ren_='${this.userId}' and parent_id_='${this.params.id_}' and shi_bie_xiang_ in (${deletedIds.map(id => `'${id}'`).join(', ')})`
  785. const { variables: { data: data3 }} = await this.$common.request('sql', sql3)
  786. if (data3.length > 0) {
  787. // console.log('data3', data3)
  788. const params = {
  789. tableName: 't_fxsbpgb2',
  790. paramWhere: {
  791. id_: data3.map(item => item.id_).join(',')
  792. }
  793. }
  794. console.log(params)
  795. await this.$common.request('delete', params)
  796. console.log('删除成功')
  797. }
  798. }
  799. await this.getTableData()
  800. this.$message.success('保存成功')
  801. // this.close()
  802. } catch (error) {
  803. this.$message.warning(error.message)
  804. throw new Error(error.message)
  805. }
  806. }
  807. }
  808. }
  809. </script>
  810. <style lang="scss" scoped>
  811. .contain{
  812. padding: 20px;
  813. .info{
  814. padding: 0;
  815. display: flex;
  816. justify-content: space-around;
  817. align-items: center;
  818. width: 80%;
  819. margin: 0 auto;
  820. .item{
  821. display: flex;
  822. align-items: center;
  823. width: 30%;
  824. }
  825. }
  826. .tab{
  827. pre{
  828. overflow: auto;
  829. margin: 0;
  830. padding-bottom: 10px;
  831. }
  832. }
  833. .choose{
  834. display: flex;
  835. align-items: center;
  836. margin: 10px 0;
  837. }
  838. .table{
  839. height:300px;
  840. overflow: auto;
  841. margin-top: 20px;
  842. }
  843. }
  844. </style>