riskDetail.vue 32 KB

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