riskV2.vue 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. <template>
  2. <el-dialog
  3. v-loading="loading"
  4. :title="title"
  5. :visible.sync="dialogVisible"
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. :show-close="false"
  9. append-to-body
  10. fullscreen
  11. class="dialog paper-detail-dialog"
  12. top="0"
  13. >
  14. <div slot="title" class="dialog-title">
  15. <span class="dialogtitle">{{ title }}</span>
  16. <div>
  17. <ibps-toolbar :actions="toolbars" @action-event="handleActionEvent" />
  18. </div>
  19. </div>
  20. <div class="container">
  21. <div class="left" :style="{width:initWidth}">
  22. <el-descriptions title="" direction="vertical" :column="5" border size="mini">
  23. <el-descriptions-item label="年度" class="aaaa">
  24. <span class="required-star">*</span>
  25. <el-date-picker
  26. v-model="infoFxssbData.nian_du_"
  27. type="year"
  28. placeholder="选择年"
  29. :disabled="readonly"
  30. value-format="yyyy"
  31. size="mini"
  32. />
  33. </el-descriptions-item>
  34. <el-descriptions-item label="编制部门">
  35. <div style="display:flex">
  36. <span class="required-star">*</span>
  37. <ibps-user-selector
  38. type="position"
  39. :value="infoFxssbData.bian_zhi_bu_men_"
  40. readonly-text="text"
  41. :disabled="readonly"
  42. :multiple="false"
  43. size="mini"
  44. style="width:100%"
  45. :filter="filter"
  46. filtrate
  47. />
  48. </div>
  49. </el-descriptions-item>
  50. <el-descriptions-item label="编制人">
  51. <ibps-user-selector
  52. type="user"
  53. :value="infoFxssbData.bian_zhi_ren_"
  54. readonly-text="text"
  55. :disabled="true"
  56. :multiple="true"
  57. size="mini"
  58. />
  59. </el-descriptions-item>
  60. <el-descriptions-item label="编制时间">
  61. <span class="required-star">*</span>
  62. <el-date-picker
  63. v-model="infoFxssbData.bian_zhi_shi_jian"
  64. type="datetime"
  65. placeholder="选择日期时间"
  66. :disabled="readonly"
  67. value-format="yyyy-MM-dd HH:mm:ss"
  68. size="mini"
  69. />
  70. </el-descriptions-item>
  71. <el-descriptions-item label="评估编号">
  72. {{ infoFxssbData.ji_hua_bian_hao_ }}
  73. </el-descriptions-item>
  74. <el-descriptions-item label="组长">
  75. <ibps-user-selector
  76. type="user"
  77. :value="infoFxssbData.zu_chang_id_"
  78. readonly-text="text"
  79. :disabled="true"
  80. :multiple="true"
  81. size="mini"
  82. :filter="filter"
  83. filtrate
  84. />
  85. </el-descriptions-item>
  86. <el-descriptions-item label="评估开始时间">
  87. <span class="required-star">*</span>
  88. <el-date-picker
  89. v-model="infoFxssbData.kai_shi_ri_qi_"
  90. type="date"
  91. placeholder="选择日期"
  92. :disabled="readonly"
  93. value-format="yyyy-MM-dd"
  94. size="mini"
  95. />
  96. </el-descriptions-item>
  97. <el-descriptions-item label="评估结束时间">
  98. <span class="required-star">*</span>
  99. <el-date-picker
  100. v-model="infoFxssbData.jie_shu_ri_qi_"
  101. type="date"
  102. placeholder="选择日期"
  103. :disabled="readonly"
  104. value-format="yyyy-MM-dd"
  105. size="mini"
  106. />
  107. </el-descriptions-item>
  108. <el-descriptions-item label="报告完成时间">
  109. <span class="required-star">*</span>
  110. <el-date-picker
  111. v-model="infoFxssbData.bao_gao_shi_jian_"
  112. type="date"
  113. placeholder="选择日期"
  114. :disabled="readonly"
  115. value-format="yyyy-MM-dd"
  116. size="mini"
  117. />
  118. </el-descriptions-item>
  119. <el-descriptions-item label="风险类型">
  120. <div>
  121. <el-radio v-model="infoFxssbData.feng_xian_lei_xin" label="质量" size="mini" :disabled="isEdit">质量</el-radio>
  122. <el-radio v-model="infoFxssbData.feng_xian_lei_xin" label="安全" size="mini" :disabled="isEdit">安全</el-radio>
  123. </div>
  124. </el-descriptions-item>
  125. <el-descriptions-item label="时机" :span="1">
  126. <el-select v-model="infoFxssbData.shi_ji_" :disabled="readonly" placeholder="请选择" size="mini">
  127. <el-option
  128. v-for="item in ['定期评估','新增活动','不良事件','程序变化','业务变化']"
  129. :key="item"
  130. :label="item"
  131. :value="item"
  132. />
  133. </el-select>
  134. </el-descriptions-item>
  135. <el-descriptions-item label="范围" :span="2">
  136. <el-input v-model="infoFxssbData.fan_wei_" :disabled="readonly" size="mini" />
  137. </el-descriptions-item>
  138. <el-descriptions-item label="方法" :span="1">
  139. <el-input v-model="infoFxssbData.fang_fa_" :disabled="readonly" size="mini" />
  140. </el-descriptions-item>
  141. <el-descriptions-item label="风险系数计算方式" :span="1">
  142. <span class="required-star">*</span>
  143. <el-radio v-model="infoFxssbData.ji_suan_fang_shi_" label="1" size="mini" :disabled="isEdit">风险矩阵法</el-radio>
  144. <el-radio v-model="infoFxssbData.ji_suan_fang_shi_" label="2" size="mini" :disabled="isEdit">FMEA法
  145. </el-radio>
  146. </el-descriptions-item>
  147. <el-descriptions-item label="目的" :span="5">
  148. <el-input v-model="infoFxssbData.mu_di_" :disabled="readonly" size="mini" />
  149. </el-descriptions-item>
  150. <el-descriptions-item label="依据文件" :span="5">
  151. <!-- 模版弹窗 -->
  152. <ibps-custom-dialog
  153. v-if="!readonly"
  154. v-model="infoFxssbData.yi_ju_wen_jian_id"
  155. template-key="nsyjwjxz"
  156. multiple
  157. type="dialog"
  158. class="custom-dialog"
  159. placeholder="请选择依据文件"
  160. size="mini"
  161. icon="el-icon-search"
  162. />
  163. <pre style="margin:0">{{ infoFxssbData.yi_ju_wen_jian_ }}</pre>
  164. </el-descriptions-item>
  165. <el-descriptions-item label="首次会议时间" :span="1">
  166. <el-date-picker
  167. v-model="infoFxssbData.hui_yi_shi_jian_"
  168. type="datetime"
  169. placeholder="选择日期时间"
  170. default-time="12:00:00"
  171. :disabled="readonly"
  172. value-format="yyyy-MM-dd HH:mm"
  173. size="mini"
  174. />
  175. </el-descriptions-item>
  176. <el-descriptions-item label="参会人员" :span="4">
  177. <div style="display:flex">
  178. <ibps-user-selector
  179. v-model="infoFxssbData.can_hui_ren_yuan_"
  180. style="width:100%"
  181. type="user"
  182. readonly-text="text"
  183. :disabled="readonly"
  184. :multiple="true"
  185. size="mini"
  186. :filter="filter"
  187. filtrate
  188. />
  189. </div>
  190. </el-descriptions-item>
  191. <el-descriptions-item label="会议附件" :span="5">
  192. <ibps-attachment
  193. v-model="infoFxssbData.hui_yi_fu_jian_"
  194. :download="true"
  195. multiple
  196. accept="*"
  197. :readonly="readonly"
  198. size="mini"
  199. />
  200. </el-descriptions-item>
  201. <el-descriptions-item label="事务说明 " :span="5">
  202. <el-input v-model="infoFxssbData.shi_wu_shuo_ming_" :disabled="readonly" size="mini" /></el-descriptions-item>
  203. <el-descriptions-item label="评估人员 " :span="5">
  204. <div style="display:flex">
  205. <span class="required-star">*</span>
  206. <ibps-user-selector
  207. v-model="infoFxssbData.ping_gu_ren_yuan_"
  208. type="user"
  209. style="width:100%"
  210. readonly-text="text"
  211. :disabled="readonly"
  212. :multiple="true"
  213. size="mini"
  214. :filter="filter"
  215. filtrate
  216. />
  217. </div>
  218. </el-descriptions-item>
  219. </el-descriptions>
  220. <div v-if="isEdit" style="margin-top:20px">
  221. <el-alert
  222. title="根据评估人员选定的风险识别项给每个措施制定人推送风险改进流程"
  223. type="success"
  224. :closable="false"
  225. />
  226. <RiskPeopleTable ref="RiskPeopleTableRef" :params="params" :people-ids="infoFxssbData.ping_gu_ren_yuan_" @goBack="goRefresh" />
  227. </div>
  228. </div>
  229. </div>
  230. <!-- <data-template-formrender-dialog
  231. :visible="DialogVisible"
  232. form-key="fxbg"
  233. :pk-value="pkValue"
  234. :readonly="readonly"
  235. @close="visible => DialogVisible = visible"
  236. /> -->
  237. <RiskDetail ref="RiskDetailRef" @close="goRefresh" />
  238. <el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="[FlowPic]" />
  239. </el-dialog>
  240. </template>
  241. <script>
  242. import dayjs from 'dayjs'
  243. import RiskPeopleTable from './riskPeopleTable.vue'
  244. import ibpsUserSelector from '@/business/platform/org/selector'
  245. import RiskDetail from './riskDetail.vue'
  246. import IbpsAttachment from '@/business/platform/file/attachment/selector'
  247. import DataFormrender from '@/business/platform/data/templaterender/form'
  248. import DataTemplateFormrenderDialog from '@/business/platform/data/templaterender/form/dialog.vue'
  249. import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
  250. import FlowPic from '@/assets/images/risk/file-read-18951.png'
  251. export default {
  252. components: {
  253. ElImageViewer,
  254. RiskDetail,
  255. RiskPeopleTable,
  256. ibpsUserSelector,
  257. IbpsAttachment,
  258. DataFormrender,
  259. DataTemplateFormrenderDialog,
  260. IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog')
  261. },
  262. props: {
  263. params: {
  264. type: Object,
  265. default: function () {
  266. return {}
  267. }
  268. }
  269. },
  270. data () {
  271. const { userId, position, level } = this.$store.getters
  272. return {
  273. FlowPic: FlowPic,
  274. showViewer: false,
  275. filter: [{
  276. descVal: '1',
  277. includeSub: true,
  278. old: 'position',
  279. partyId: this.$store.getters.userInfo.employee.positions,
  280. partyName: '',
  281. scriptContent: '',
  282. type: 'user',
  283. userType: 'position'
  284. }],
  285. isFirst: true,
  286. userId: userId,
  287. position: position,
  288. level: level.second || level.first,
  289. pkValue: '',
  290. readonly: true,
  291. DialogVisible: false,
  292. loading: false,
  293. dialogVisible: true,
  294. title: '风险评估与措施',
  295. toolbars: [
  296. { key: 'openFlowPic', label: '流程图', icon: 'ibps-icon-image' },
  297. { key: 'refresh', label: '刷新', hidden: () => { return !this.isZuZhang || !this.isEdit || this.isFinished } },
  298. { key: 'save', label: '保存', hidden: () => { return !this.isZuZhang || this.isFinished } },
  299. // { key: 'sendMsg', label: '提醒评估人', icon: 'el-icon-bell', hidden: () => { return !this.isZuZhang || !this.isEdit || this.isFinished } },
  300. // { key: 'peizhifengxian', label: '更新风险库', type: 'info', icon: 'el-icon-setting', hidden: () => { return !this.isZuZhang || !this.isEdit } },
  301. { key: 'submit', label: '提交', icon: 'el-icon-finished', hidden: () => { return !this.isZuZhang || !this.isEdit || this.isFinished } },
  302. { key: 'cancel', label: '退出', type: 'danger', icon: 'ibps-icon-close' }
  303. ],
  304. infoFxssbData: {
  305. nian_du_: '',
  306. bian_zhi_bu_men_: '',
  307. bian_zhi_ren_: '',
  308. bian_zhi_shi_jian: '',
  309. zu_chang_: '',
  310. zu_chang_id_: '',
  311. kai_shi_ri_qi_: '',
  312. jie_shu_ri_qi_: '',
  313. bao_gao_shi_jian_: '',
  314. feng_xian_lei_xin: '',
  315. shi_ji_: '',
  316. fan_wei_: '',
  317. fang_fa_: '',
  318. mu_di_: '',
  319. yi_ju_wen_jian_id: '',
  320. yi_ju_wen_jian_: '',
  321. hui_yi_shi_jian_: '',
  322. can_hui_ren_yuan_: '',
  323. hui_yi_fu_jian_: '',
  324. shi_wu_shuo_ming_: '',
  325. ping_gu_ren_yuan_: '',
  326. ji_hua_bian_hao_: '',
  327. ji_suan_fang_shi_: ''
  328. },
  329. initWidth: '1280px',
  330. isEdit: false,
  331. isPingGuRen: false,
  332. isZuZhang: true,
  333. isFinished: false,
  334. preParams: {},
  335. Ids: []
  336. }
  337. },
  338. watch: {
  339. 'infoFxssbData.yi_ju_wen_jian_id': {
  340. handler (val) {
  341. const sql = `select * from yijuwenjianxuanze where id_ in ('${val.replace(/,/g, "','")}') order by id_`
  342. this.$common.request('sql', sql).then(response => {
  343. const conts = response.variables.data
  344. let fileName = ''
  345. let num = 1
  346. conts.forEach((item, index) => {
  347. fileName += `${num}、${item.name_}\n`
  348. num = num + 1
  349. })
  350. this.infoFxssbData.yi_ju_wen_jian_ = fileName
  351. })
  352. },
  353. immediate: true
  354. },
  355. 'infoFxssbData.zu_chang_id_': {
  356. handler (val) {
  357. if (val) {
  358. const userList = this.$store.getters.userList
  359. const bianzhiUserid = userList.find(i => i.userId === val)
  360. if (bianzhiUserid) {
  361. this.infoFxssbData.zu_chang_ = bianzhiUserid.userName
  362. }
  363. }
  364. }
  365. },
  366. 'infoFxssbData.feng_xian_lei_xin': {
  367. handler (val) {
  368. if (val) {
  369. if (this.isFirst) {
  370. this.isFirst = false
  371. } else {
  372. this.infoFxssbData.fan_wei_ = `本实验室与${val}相关所有活动`
  373. this.infoFxssbData.mu_di_ = `通过对实验室(${val}活动)进行风险评估,识别实验室在(${val}活动)方面存在的潜在风险,评估风险影响程度,制定风险管理策略,减少不利后果发生的概率和影响程度。`
  374. this.infoFxssbData.shi_wu_shuo_ming_ = `年度:${this.infoFxssbData.nian_du_};组长:${this.infoFxssbData.zu_chang_};评估开始日期:${this.infoFxssbData.kai_shi_ri_qi_};风险类型:${val}`
  375. }
  376. }
  377. }
  378. }
  379. },
  380. mounted () {
  381. this.init()
  382. },
  383. beforeDestroy () {
  384. if (this.msg) {
  385. this.msg.close()
  386. }
  387. },
  388. methods: {
  389. // 获取最新数据
  390. async getNewData () {
  391. const sql = `select * from t_fxpgjlb2 where id_='${this.params.id_}'`
  392. const { variables: { data }} = await this.$common.request('sql', sql)
  393. return data
  394. },
  395. // 判断是否已完成
  396. async getIsFinish () {
  397. const data = await this.getNewData()
  398. if (data.length > 0 && data[0].shi_fou_guo_shen_ === '已完成') {
  399. throw new Error('已结束,不可操作!')
  400. }
  401. },
  402. // 快照URL
  403. getReportParams (path, selection, data) {
  404. const { level } = this.$store.getters
  405. const str = `org_=${level.first}&second_=${level.second}&id_=`
  406. const arr = path.split('&')
  407. if (arr.length === 2) {
  408. const fieldArr = arr[1].split('=')
  409. return str + `${data[fieldArr[1]]}`
  410. } else {
  411. // 如果是没有传参,还是原报表路径
  412. return str + `${selection}`
  413. }
  414. },
  415. // 提交
  416. async goSubmit () {
  417. try {
  418. this.$confirm('提交后不可修改,是否确认保存并提交?', '提示', {
  419. confirmButtonText: '继续',
  420. cancelButtonText: '取消',
  421. type: 'warning'
  422. }).then(async () => {
  423. // 提交前自动保存
  424. await this.goSave()
  425. // 判断每个评估人是否已完成识别项
  426. const pinGuRenNum = this.Ids.length
  427. const sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}'`
  428. const { variables: { data }} = await this.$common.request('sql', sql)
  429. const submitNum = new Set(data.map(item => item.bian_zhi_ren_)).size
  430. if (submitNum === pinGuRenNum && data.every(item => item.shi_fou_guo_shen_ === '已完成')) {
  431. // 0.生成快照
  432. const formName = '风险管理/风险识别评估表V2.rpx'
  433. const res = await this.$common.snapshoot({
  434. url: this.$getReportFile(formName, this.getReportParams(formName, this.params.id_, {
  435. ...this.preParams,
  436. shi_fou_guo_shen_: '已完成'
  437. })),
  438. name: this.params.id_,
  439. type: 'pdf'
  440. })
  441. console.log(res)
  442. if (!res.data || !res.data.id) {
  443. console.log('快照生成失败')
  444. } else {
  445. console.log('快照生成成功')
  446. }
  447. // 1.修改状态为已完成 并保存快照
  448. const updateParamsRecord = {
  449. tableName: 't_fxpgjlb2',
  450. updList: [{
  451. where: {
  452. id_: this.params.id_
  453. },
  454. param: {
  455. shi_fou_guo_shen_: '已完成',
  456. kuai_zhao_: res.data.id
  457. }
  458. }]
  459. }
  460. await this.$common.request('update', updateParamsRecord)
  461. // console.log(data)
  462. // 2.推送给措施制定人下一个流程
  463. const addParams = {
  464. tableName: 't_fxkzcsb2',
  465. paramWhere: data.map(item => {
  466. if (item.feng_xian_ying_du !== '风险接受' && item.zhi_ding_ren_) {
  467. return {
  468. di_dian_: this.level,
  469. shi_fou_guo_shen_: '已编制',
  470. bian_zhi_ren_: item.zhi_ding_ren_,
  471. bian_zhi_bu_men_: this.getPersonPosition(item.zhi_ding_ren_.split(',')[0]),
  472. bian_zhi_shi_jian: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  473. gai_jin_bian_hao_: '',
  474. yao_su_tiao_kuan_: item.yao_su_tiao_kuan_,
  475. gong_zuo_huan_jie: item.gong_zuo_huan_jie,
  476. // gong_zuo_miao_shu: item.gong_zuo_miao_shu,
  477. feng_xian_miao_sh: item.feng_xian_miao_sh,
  478. zu_chang_: this.infoFxssbData.zu_chang_,
  479. zu_chang_id_: this.infoFxssbData.zu_chang_id_,
  480. shi_wu_shuo_ming_: this.infoFxssbData.shi_wu_shuo_ming_,
  481. yuan_zhi_shu_: item.feng_xian_zhi_shu,
  482. kong_zhi_fang_fa_: item.xian_xing_kong_zh,
  483. feng_xian_lei_xin: this.infoFxssbData.feng_xian_lei_xin,
  484. qian_fu_jian_: this.infoFxssbData.yi_ju_wen_jian_id,
  485. ji_hua_bian_hao_: this.infoFxssbData.ji_hua_bian_hao_,
  486. ni_cai_qu_kong_zh: item.ni_cai_qu_cuo_shi,
  487. qian_zai_yuan_yin: item.qian_zai_yuan_yin,
  488. ji_suan_fang_shi_: this.infoFxssbData.ji_suan_fang_shi_
  489. }
  490. }
  491. }).filter(i => i !== undefined),
  492. formKey: 'fxcscsbV2',
  493. defKey: 'Process_1li9h0n'
  494. }
  495. for (let i = 0; i < addParams.paramWhere.length; i++) {
  496. const item = addParams.paramWhere[i]
  497. item.gai_jin_bian_hao_ = await this.getNextAlias('gjjllsh')
  498. }
  499. console.log(addParams)
  500. if (addParams.paramWhere.length) {
  501. await this.$common.request('add', addParams)
  502. // 3.推送给组长 评估报告流程
  503. const addParams2 = {
  504. tableName: 't_fxkzbg',
  505. paramWhere: [{
  506. di_dian_: this.level,
  507. shi_fou_guo_shen_: '已编制',
  508. bian_zhi_ren_: this.infoFxssbData.zu_chang_id_,
  509. bian_zhi_bu_men_: this.getPersonPosition(this.infoFxssbData.zu_chang_id_),
  510. bian_zhi_shi_jian: dayjs().format('YYYY-MM-DD HH:mm'),
  511. zu_chang_: this.infoFxssbData.zu_chang_,
  512. zu_chang_id_: this.infoFxssbData.zu_chang_id_,
  513. feng_xian_lei_xin: this.infoFxssbData.feng_xian_lei_xin,
  514. kai_shi_ri_qi_: this.infoFxssbData.kai_shi_ri_qi_,
  515. jie_shu_ri_qi_: this.infoFxssbData.jie_shu_ri_qi_,
  516. wan_cheng_ri_qi_: this.infoFxssbData.bao_gao_shi_jian_,
  517. shi_wu_shuo_ming_: this.infoFxssbData.shi_wu_shuo_ming_,
  518. ji_hua_bian_hao_: this.infoFxssbData.ji_hua_bian_hao_,
  519. hui_yi_wen_jian_: this.infoFxssbData.hui_yi_fu_jian_
  520. }],
  521. formKey: 'fxbg',
  522. defKey: 'Process_0mrlsj7'
  523. }
  524. console.log(addParams2)
  525. await this.$common.request('add', addParams2)
  526. console.log('流程推送成功')
  527. } else {
  528. console.log('无需推送')
  529. }
  530. this.$message.success('提交成功')
  531. // 提醒用户推送信息
  532. if (addParams.paramWhere.length) {
  533. this.$alert(`需要改进项${addParams.paramWhere.length}条,已向其中的每位措施制定人推送风险改进流程,同时向组长 ${this.infoFxssbData.zu_chang_} 推送风险报告流程!`, '提交成功', {
  534. confirmButtonText: '确定',
  535. callback: action => {
  536. this.closeDialog(true)
  537. }
  538. })
  539. } else {
  540. this.closeDialog(true)
  541. }
  542. } else {
  543. this.$message.warning('存在未完成风险识别项的评估人员,无法提交!')
  544. return
  545. }
  546. })
  547. .catch(() => {
  548. })
  549. } catch (error) {
  550. this.$message.warning(error.message)
  551. }
  552. },
  553. // id 转 姓名
  554. switchIdtoUserName (id) {
  555. const { userList } = this.$store.getters
  556. const user = userList.find(item => item.userId === id)
  557. return user ? user.userName : ''
  558. },
  559. goPeizhifengxian () {
  560. const buttons = document.querySelector('button[name="peizhifengxian"]')
  561. if (buttons) {
  562. buttons.click()
  563. }
  564. },
  565. handleActionEvent ({ key }) {
  566. switch (key) {
  567. case 'cancel':
  568. this.closeDialog(true)
  569. break
  570. case 'record':
  571. this.goRecord()
  572. break
  573. case 'save':
  574. this.goSave('close')
  575. break
  576. case 'submit':
  577. this.goSubmit()
  578. break
  579. case 'refresh':
  580. this.goRefresh()
  581. break
  582. case 'sendMsg':
  583. this.goSendMsg()
  584. break
  585. case 'peizhifengxian':
  586. this.goPeizhifengxian()
  587. break
  588. case 'openFlowPic':
  589. this.showViewer = true
  590. break
  591. default:
  592. break
  593. }
  594. },
  595. // 关闭大图预览
  596. closeViewer () {
  597. this.showViewer = false
  598. },
  599. // 推送消息给评估人
  600. async goSendMsg () {
  601. const sql2 = `select * from t_fxpgjlb2 where id_='${this.params.id_}'`
  602. const { variables: { data: data2 }} = await this.$common.request('sql', sql2)
  603. if (data2.length > 0 && data2[0].shi_fou_guo_shen_ === '已完成') {
  604. return this.$message('已结束,不可推送消息!')
  605. }
  606. if (!data2[0].ping_gu_ren_yuan_) {
  607. return this.$message.warning('请先指定评估人!')
  608. }
  609. this.$confirm('此操作将通知所有评估人,是否继续?', '提示', {
  610. confirmButtonText: '确定',
  611. cancelButtonText: '取消',
  612. type: 'warning'
  613. }).then(() => {
  614. // console.log(this.Ids)
  615. const allRequests = []
  616. this.Ids.forEach(item => {
  617. allRequests.push(this.$common.sendMsg({
  618. subject: '风险识别项待填写提醒',
  619. content: `您有一份风险识别项待填写,请前往-风险控制-风险评估与措施页面填写,计划编号:${this.infoFxssbData.ji_hua_bian_hao_},组长:${this.infoFxssbData.zu_chang_}。如已提交请忽略。`,
  620. receiverId: item,
  621. canreplay: '0',
  622. skipTypeMsg: JSON.stringify({
  623. skipType: 3,
  624. pathInfo: '/tygl/fxkzV2/fxpgycslb' // 路由
  625. })
  626. }))
  627. })
  628. Promise.all(allRequests).then(() => {
  629. this.$message({
  630. type: 'success',
  631. message: '推送成功!'
  632. })
  633. })
  634. .catch(() => {
  635. this.$message({
  636. type: 'warning',
  637. message: '推送失败!'
  638. })
  639. })
  640. }).catch(() => {
  641. })
  642. },
  643. // 获取人员部门
  644. getPersonPosition (id) {
  645. const userList = this.$store.getters.userList
  646. const bianzhiUserid = userList.find(i => i.userId === id)
  647. if (bianzhiUserid) {
  648. return bianzhiUserid.positionId.split(',')[0]
  649. }
  650. },
  651. checkRequired () {
  652. if (!this.infoFxssbData.nian_du_) {
  653. throw new Error('请填写年度!')
  654. }
  655. if (!this.infoFxssbData.kai_shi_ri_qi_) {
  656. throw new Error('请填写评估开始日期!')
  657. }
  658. if (!this.infoFxssbData.jie_shu_ri_qi_) {
  659. throw new Error('请填写评估结束日期!')
  660. }
  661. if (!this.infoFxssbData.bao_gao_shi_jian_) {
  662. throw new Error('请填写报告完成时间!')
  663. }
  664. // if (!this.infoFxssbData.hui_yi_shi_jian_) {
  665. // throw new Error('请填写首次会议时间!')
  666. // }
  667. // if (!this.infoFxssbData.can_hui_ren_yuan_) {
  668. // throw new Error('请填写参会人员!')
  669. // }
  670. if (!this.infoFxssbData.ping_gu_ren_yuan_) {
  671. throw new Error('请填写评估人员!')
  672. }
  673. if (!this.infoFxssbData.bian_zhi_shi_jian) {
  674. throw new Error('请选择编制时间!')
  675. }
  676. if (!this.infoFxssbData.bian_zhi_bu_men_) {
  677. throw new Error('请选择编制部门!')
  678. }
  679. if (!this.infoFxssbData.ji_suan_fang_shi_) {
  680. throw new Error('请选择风险系数计算方式!')
  681. }
  682. },
  683. async goAdd () {
  684. try {
  685. const addParamsRecord = {
  686. tableName: 't_fxpgjlb2',
  687. paramWhere: [this.infoFxssbData]
  688. }
  689. const { variables: { cont }} = await this.$common.request('add', addParamsRecord)
  690. if (cont.length) {
  691. this.$message.success('添加成功')
  692. this.closeDialog(true)
  693. }
  694. } catch (error) {
  695. console.log(error)
  696. this.$message.warning('添加失败')
  697. }
  698. },
  699. async goEdit (flag) {
  700. try {
  701. // 先检查状态
  702. await this.getIsFinish()
  703. // 更新主表
  704. const updateParamsRecord = {
  705. tableName: 't_fxpgjlb2',
  706. updList: [{
  707. where: {
  708. id_: this.params.id_
  709. },
  710. param: this.infoFxssbData
  711. }]
  712. }
  713. await this.$common.request('update', updateParamsRecord)
  714. // 当前人员数组
  715. const curIds = this.infoFxssbData.ping_gu_ren_yuan_.split(',')
  716. // 计算需要增加项
  717. const addedIds = curIds.filter(item => !this.Ids.includes(item))
  718. // 计算需要更新项
  719. const updatedIds = curIds.filter(item => this.Ids.includes(item))
  720. // 计算需要删除项
  721. const deletedIds = this.Ids.filter(id => !curIds.includes(id))
  722. console.log(addedIds, updatedIds, deletedIds)
  723. // 删除
  724. if (deletedIds.length > 0) {
  725. const sql3 = `select *from t_fxsbpgb2 where parent_id_='${this.params.id_}' and bian_zhi_ren_ in (${deletedIds.map(id => `'${id}'`).join(', ')})`
  726. const { variables: { data: data3 }} = await this.$common.request('sql', sql3)
  727. // console.log(data3)
  728. if (data3.length > 0) {
  729. const params = {
  730. tableName: 't_fxsbpgb2',
  731. paramWhere: {
  732. id_: data3.map(item => item.id_).join(',')
  733. }
  734. }
  735. console.log(params)
  736. await this.$common.request('delete', params)
  737. console.log('删除成功')
  738. }
  739. }
  740. if (flag === 'close') {
  741. this.closeDialog(true)
  742. this.$message.success('修改成功')
  743. } else {
  744. await this.goRefresh() // 修改之后刷新
  745. }
  746. } catch (error) {
  747. this.$message.warning(error.message)
  748. throw new Error(error.message)
  749. }
  750. },
  751. async goSave (flag) {
  752. try {
  753. this.checkRequired()
  754. if (this.isEdit) {
  755. await this.goEdit(flag)
  756. } else {
  757. this.$confirm('风险类型和风险系数计算公式保存后不可再修改,是否继续?', '提示', {
  758. confirmButtonText: '继续',
  759. cancelButtonText: '取消',
  760. type: 'warning'
  761. }).then(async () => {
  762. await this.goAdd()
  763. }).catch(() => {
  764. })
  765. }
  766. } catch (error) {
  767. this.$message.warning(error.message)
  768. throw new Error(error.message)
  769. }
  770. },
  771. // 刷新
  772. async goRefresh () {
  773. this.loading = true
  774. if (this.msg) {
  775. this.msg.close()
  776. }
  777. await this.init()
  778. if (this.$refs.RiskPeopleTableRef) {
  779. await this.$refs.RiskPeopleTableRef.getPeopleList()
  780. }
  781. this.loading = false
  782. },
  783. // 关闭当前窗口
  784. closeDialog (needRefresh) {
  785. this.dialogVisible = false
  786. if (needRefresh) {
  787. this.$emit('close')
  788. }
  789. if (this.msg) {
  790. this.msg.close()
  791. }
  792. },
  793. // 弹出提醒
  794. async showAlert () {
  795. if (!this.isPingGuRen || this.isFinished) return
  796. // 判断是否已经填写风险识别项
  797. const sql = `select * from t_fxsbpgb2 where parent_id_='${this.params.id_}' and bian_zhi_ren_='${this.userId}'`
  798. const { variables: { data }} = await this.$common.request('sql', sql)
  799. let status = '填写'
  800. let type = 'warning'
  801. if (data.length > 0) {
  802. if (data.every(item => item.shi_fou_guo_shen_ === '已完成')) {
  803. return
  804. } else {
  805. status = '提交'
  806. type = 'success'
  807. }
  808. }
  809. this.msg = this.$notify({
  810. offset: 50,
  811. type: type,
  812. title: `您有一份风险识别评估表待${status}!`,
  813. message: `点击前去${status}`,
  814. showClose: false,
  815. duration: 0,
  816. onClick: () => {
  817. this.$refs.RiskDetailRef.open(this.params)
  818. }
  819. })
  820. },
  821. getNextAlias (alias) {
  822. return new Promise((resolve, reject) => {
  823. this.$common.getNextIdByAlias({
  824. alias
  825. }).then(response => {
  826. resolve(response.data)
  827. }).catch((error) => {
  828. reject(error)
  829. })
  830. })
  831. },
  832. async init () {
  833. this.isEdit = !!(this.params && this.params.id_)
  834. if (this.isEdit) {
  835. this.infoFxssbData = this.params
  836. this.preParams = JSON.parse(JSON.stringify(this.params))
  837. this.isPingGuRen = this.params.ping_gu_ren_yuan_.indexOf(this.userId) >= 0
  838. this.isZuZhang = this.userId === this.infoFxssbData.zu_chang_id_
  839. this.isFinished = this.params && this.params.shi_fou_guo_shen_ === '已完成'
  840. this.readonly = !!((!this.isZuZhang || this.isFinished))
  841. if (this.params.ping_gu_ren_yuan_) {
  842. this.Ids = this.params.ping_gu_ren_yuan_.split(',')
  843. } else {
  844. this.Ids = []
  845. }
  846. await this.showAlert()
  847. } else {
  848. this.readonly = false
  849. this.infoFxssbData.di_dian_ = this.level
  850. this.infoFxssbData.ji_hua_bian_hao_ = await this.getNextAlias('fxjhlsh')
  851. this.infoFxssbData.nian_du_ = dayjs().format('YYYY')
  852. this.infoFxssbData.bian_zhi_bu_men_ = this.position
  853. this.infoFxssbData.bian_zhi_ren_ = this.userId
  854. this.infoFxssbData.bian_zhi_shi_jian = dayjs().format('YYYY-MM-DD HH:mm:ss')
  855. this.infoFxssbData.zu_chang_id_ = this.userId
  856. this.infoFxssbData.kai_shi_ri_qi_ = dayjs().format('YYYY-MM-DD')
  857. this.infoFxssbData.jie_shu_ri_qi_ = dayjs().format('YYYY-MM-DD')
  858. this.infoFxssbData.feng_xian_lei_xin = '质量'
  859. this.infoFxssbData.shi_ji_ = '定期评估'
  860. this.infoFxssbData.fan_wei_ = '本实验室与质量相关所有活动'
  861. this.infoFxssbData.fang_fa_ = '定量风险评估法'
  862. this.infoFxssbData.mu_di_ = '通过对实验室(质量活动)进行风险评估,识别实验室在(质量活动)方面存在的潜在风险,评估风险影响程度,制定风险管理策略,减少不利后果发生的概率和影响程度。'
  863. this.infoFxssbData.hui_yi_shi_jian_ = dayjs().format('YYYY-MM-DD HH:mm')
  864. this.$nextTick(() => {
  865. this.infoFxssbData.shi_wu_shuo_ming_ = `年度:${this.infoFxssbData.nian_du_};组长:${this.infoFxssbData.zu_chang_};评估开始日期:${this.infoFxssbData.kai_shi_ri_qi_};风险类型:${this.infoFxssbData.feng_xian_lei_xin}`
  866. })
  867. }
  868. }
  869. }
  870. }
  871. </script>
  872. <style lang="scss" scoped>
  873. .paper-detail-dialog {
  874. ::v-deep {
  875. .el-dialog__header {
  876. text-align: center;
  877. }
  878. }
  879. .container {
  880. display: flex;
  881. width: 100%;
  882. justify-content: center;
  883. .left{
  884. height: calc(100vh - 100px);
  885. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  886. padding:10px;
  887. overflow-y: auto;
  888. }
  889. .right{
  890. height: calc(100vh - 100px);
  891. flex: 1;
  892. padding:10px;
  893. .text{
  894. line-height: 1.5;
  895. }
  896. overflow-y: auto;
  897. }
  898. }
  899. }
  900. .required-star {
  901. color: red;
  902. margin-right: 4px;
  903. }
  904. .dialog-title{
  905. display: flex;
  906. align-items: center;
  907. justify-content: center;
  908. div{
  909. position: absolute;
  910. right:8vw;
  911. }
  912. .dialogtitle{
  913. font-size: 22px;
  914. font-family: SimHei;
  915. font-weight: bold;
  916. color: #222;
  917. }
  918. }
  919. .el-image-viewer__wrapper{
  920. z-index: 9999 !important;
  921. }
  922. </style>