risk-tasks-form.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. <template>
  2. <div>
  3. <sd-webflow
  4. ref="flow"
  5. :removed-tabs="['sdRelatedDoc']"
  6. :validate-form="validForm"
  7. :class="$style.ristTasksForm"
  8. @actionBtnClick="actionBtnClick"
  9. @saveproject="saveproject"
  10. >
  11. <template v-slot:form="{ model, fields }">
  12. <table>
  13. <tr>
  14. <td style="border: none">
  15. <audit-advanced-group
  16. :expand="planExpand"
  17. :expand-str="'planExpand'"
  18. :group-label="'基本信息'"
  19. tablestyle="''"
  20. @changedClick="changedClick"
  21. ></audit-advanced-group>
  22. </td>
  23. </tr>
  24. </table>
  25. <table v-show="planExpand">
  26. <tr v-show="initData(model)">
  27. <!-- ID -->
  28. <!-- <sd-form-item-td name="id" /> -->
  29. <!-- 随机ID -->
  30. <!-- <sd-form-item-td name="sourceId" /> -->
  31. </tr>
  32. <tr>
  33. <!-- 计划年度 -->
  34. <sd-form-item-td name="year">
  35. <template v-slot:read-and-edit="{ editable }">
  36. <a-select v-if="!isTaskWork && editable" v-model="model.year">
  37. <a-select-option v-for="year in yearArry" :key="year + ''">
  38. {{ year }}
  39. </a-select-option>
  40. </a-select>
  41. <span v-if="isTaskWork || !editable">{{ model.year }}</span>
  42. </template>
  43. </sd-form-item-td>
  44. <!-- 发起机构 -->
  45. <sd-form-item-td name="inspectUnitOpt" :hidden="true"> </sd-form-item-td>
  46. <sd-form-item-td name="inspectUnitId" :hidden="true"> </sd-form-item-td>
  47. <sd-form-item-td name="inspectUnitName" label="发起机构">
  48. <template v-slot:read-and-edit="{ editable }">
  49. {{ model.inspectUnitName }}
  50. </template>
  51. </sd-form-item-td>
  52. </tr>
  53. <tr>
  54. <!-- 任务名称 -->
  55. <sd-form-item-td name="dutieName" />
  56. <!-- 任务编号 -->
  57. <sd-form-item-td name="dutieCode">
  58. <template v-slot:read-and-edit="{ editable }">
  59. {{ model.dutieCode }}
  60. </template>
  61. </sd-form-item-td>
  62. </tr>
  63. <tr>
  64. <!-- 任务开始时间 -->
  65. <sd-form-item-td name="dutieStartDate"> </sd-form-item-td>
  66. <!-- 任务结束时间 -->
  67. <sd-form-item-td name="dutieEndDate" range-after="dutieStartDate" />
  68. </tr>
  69. <tr>
  70. <!-- 附件 -->
  71. <sd-form-item-td name="attachment" :colspan="3">
  72. <template v-slot:read-and-edit="{ editable }">
  73. <sd-attachment
  74. v-model="model.attachment"
  75. :group-id="JSON.parse(fields.attachment.value).value"
  76. :read-only="!editable"
  77. />
  78. </template>
  79. </sd-form-item-td>
  80. </tr>
  81. <tr>
  82. <!-- 任务描述 -->
  83. <sd-form-item-td name="dutieDesc" :colspan="3">
  84. <a-textarea v-model="model.dutieDesc" :auto-size="{ maxRows: 3, minRows: 3 }" />
  85. </sd-form-item-td>
  86. </tr>
  87. <tr>
  88. <!-- 任务类型 -->
  89. <sd-form-item-td
  90. name="dutieType"
  91. component="a-checkbox-group"
  92. :colspan="model.dutieType && model.dutieType.includes('RISK_ASSESSMENT') ? 1 : 3"
  93. :input-td-attrs="{
  94. class:
  95. model.dutieType && model.dutieType.includes('RISK_ASSESSMENT')
  96. ? ''
  97. : $style.typeTd,
  98. }"
  99. @change="dutieTypeChange"
  100. />
  101. <!-- 风险准则 -->
  102. <sd-form-item-td
  103. name="riskCriteria"
  104. :hidden="
  105. model.dutieType && model.dutieType.includes('RISK_ASSESSMENT') ? false : true
  106. "
  107. >
  108. <template v-slot:read-and-edit="{ editable }">
  109. <a-select
  110. v-if="editable"
  111. v-model="riskCriteriaObj"
  112. :options="riskCriteriaDict"
  113. not-found-content="当前发起机构未配置可用风险准则"
  114. @change="riskCriteriaChange"
  115. ></a-select>
  116. <span v-else>{{ model.riskCriteria }}</span>
  117. </template>
  118. </sd-form-item-td>
  119. <!-- 风险准则 -->
  120. <sd-form-item-td name="riskCriteriaId" :hidden="true" />
  121. </tr>
  122. <tr v-if="isTaskWork">
  123. <!-- 创建人 -->
  124. <sd-form-item-td name="creatorOpt" />
  125. <!-- 创建日期 -->
  126. <sd-form-item-td name="creationTime" />
  127. </tr>
  128. <tr v-if="!isTaskWork">
  129. <!-- 创建人 -->
  130. <sd-form-item-td name="creatorName">
  131. <template v-slot:read-and-edit>
  132. {{ model.creatorName }}
  133. </template>
  134. </sd-form-item-td>
  135. <!-- 创建日期 -->
  136. <sd-form-item-td name="creationTime">
  137. <template v-slot:read-and-edit>
  138. {{ model.creationTime | sdDateFormat('YYYY-MM-DD') }}
  139. </template>
  140. </sd-form-item-td>
  141. </tr>
  142. </table>
  143. <table>
  144. <tr
  145. ><td :colspan="4">
  146. <sd-form-item name="riskDutieUnitList" :label="null">
  147. <template v-slot:read-and-edit="{ editable }">
  148. <audit-advanced-group
  149. :expand="FpdwExpand"
  150. :expand-str="'FpdwExpand'"
  151. :group-label="'分派单位'"
  152. @changedClick="changedClick"
  153. >
  154. <template>
  155. <template>
  156. <div :class="$style.wrapper">
  157. <div v-show="FpdwExpand && editable" :class="$style.btnselect">
  158. <a-button type="link" :class="$style.batchselect" @click="depSelect">
  159. <a-icon type="check-circle" :theme="'filled'" />选择
  160. </a-button>
  161. </div>
  162. </div>
  163. </template>
  164. <xm-child-table
  165. ref="tabaData"
  166. v-model="model.riskDutieUnitList"
  167. :class="$style.deptPlanChild"
  168. :label="null"
  169. :read-only="!editable"
  170. :addbuttonvisiable="false"
  171. :fields="
  172. [
  173. {
  174. caption: '序号',
  175. name: 'sortNum',
  176. dataType: 'number',
  177. },
  178. ].concat(Array.from(fields.riskDutieUnitList.attr.dync))
  179. "
  180. :columns="columns"
  181. :flagpage="true"
  182. >
  183. <!-- 联系单位 -->
  184. <template v-slot:unitDeptMember="{ field, text, index, value }">
  185. <audit-group-picker
  186. v-model="value[index].unitDeptMemberObj"
  187. :root-node="{ code: 0, name: '内控机构', id: 0 }"
  188. :selectall="false"
  189. :top-node-text="'内控机构'"
  190. :treeparams="{
  191. moduleId: 'iamOrg2',
  192. }"
  193. :single="true"
  194. :read-only="!editable"
  195. />
  196. </template>
  197. <!-- 联系人 -->
  198. <template v-slot:contactsUserMember="{ field, text, index, value }">
  199. <sd-user-picker
  200. v-model="value[index].contactsUserMemberObj"
  201. :single="true"
  202. :read-only="!editable"
  203. />
  204. </template>
  205. </xm-child-table>
  206. </template>
  207. </audit-advanced-group>
  208. </template>
  209. </sd-form-item>
  210. </td>
  211. </tr>
  212. </table>
  213. <!-- 选择人员组件 -->
  214. <div v-show="false">
  215. <audit-group-picker
  216. ref="depSelect"
  217. v-model="unitOpt"
  218. :single="false"
  219. :read-only="false"
  220. :root-node="{ code: 0, name: '风控机构', id: 0 }"
  221. :selectall="false"
  222. :top-node-text="'风控机构'"
  223. :treeparams="{
  224. moduleId: 'iamOrg2',
  225. }"
  226. @change="depChange"
  227. />
  228. </div>
  229. </template>
  230. </sd-webflow>
  231. </div>
  232. </template>
  233. <script>
  234. import moment from 'moment'
  235. import riskService from '@product/iam/risk/risklib/risk-service'
  236. import { Modal, message } from '@/common/one-ui'
  237. import { getUserInfo } from '@/common/store-mixin'
  238. import auditGroupPicker from '@product/iam/components/picker/audit-group-picker.vue'
  239. import auditAdvancedGroup from '@product/iam/components/audit-advanced-group.vue'
  240. import auditAdvancedGroupMixins from '@product/iam/components/audit-advanced-group-mixins'
  241. import riskIdentificationService from './riskIdentification/risk-identification-service'
  242. import riskTasksService from './risk-tasks-service'
  243. import components from './_import-components/risk-tasks-form-import'
  244. // 修改主子表的首行title名
  245. export default {
  246. name: 'RiskTasksForm',
  247. metaInfo: {
  248. title: '风险任务',
  249. },
  250. components: {
  251. ...components,
  252. auditAdvancedGroup,
  253. auditGroupPicker,
  254. },
  255. mixins: [auditAdvancedGroupMixins],
  256. data() {
  257. return {
  258. errorText: null, // 是否有错误提示
  259. childTableKey: 0, // 刷新子表组件
  260. inited: true,
  261. planExpand: true,
  262. FpdwExpand: true,
  263. expand: true,
  264. columns: [
  265. {
  266. title: '序号',
  267. dataIndex: 'sortNum',
  268. width: '50px',
  269. customRender: (text, record, index) => `${index + 1}`,
  270. },
  271. {
  272. dataIndex: 'unitName',
  273. title: '单位名称',
  274. width: '120px',
  275. sdHidden: true,
  276. },
  277. { dataIndex: 'unitDeptMember', title: '单位名称' },
  278. {
  279. title: '联系人',
  280. dataIndex: 'contactsName',
  281. sdHidden: true,
  282. },
  283. { dataIndex: 'contactsUserMember', title: '联系人' },
  284. {
  285. dataIndex: 'dutieId',
  286. sdHidden: true,
  287. },
  288. {
  289. dataIndex: 'unitId',
  290. sdHidden: true,
  291. },
  292. {
  293. dataIndex: 'unitCode',
  294. sdHidden: true,
  295. },
  296. {
  297. dataIndex: 'contactsId',
  298. sdHidden: true,
  299. },
  300. {
  301. dataIndex: 'contactsAccount',
  302. sdHidden: true,
  303. },
  304. {
  305. dataIndex: 'contactsName',
  306. sdHidden: true,
  307. },
  308. ],
  309. yearArry: [],
  310. expressions: [],
  311. riskCriteriaDict: [],
  312. isSave: true, // 是否有保存操作
  313. riskDutieUnitList: [],
  314. isTaskWork: false,
  315. unitOpt: [],
  316. riskCriteriaObj: null, // 风险准则
  317. auditOrgid: null,
  318. }
  319. },
  320. mounted() {
  321. // 日期下拉框初始化
  322. this.initDateSelect()
  323. },
  324. methods: {
  325. // 风险准则变化时
  326. riskCriteriaChange(val, option) {
  327. this.$refs.flow.setFieldValue('riskCriteriaId', val + '')
  328. this.$refs.flow.setFieldValue(
  329. 'riskCriteria',
  330. this.riskCriteriaDict.find((item) => item.value === val).label
  331. )
  332. },
  333. // 任务类型变化时触发
  334. dutieTypeChange(val, option) {
  335. if (!val) val = []
  336. if (val.includes('RISK_ASSESSMENT')) {
  337. this.$refs.flow.FlowData.processFormData.processFormPropertyValues.find((item) => {
  338. return item.name === 'riskCriteria'
  339. }).required = true
  340. } else {
  341. this.$refs.flow.FlowData.processFormData.processFormPropertyValues.find((item) => {
  342. return item.name === 'riskCriteria'
  343. }).required = false
  344. // 不为必填时,清空风险准则及ID
  345. this.riskCriteriaObj = null
  346. this.$refs.flow.setFieldValue('riskCriteria', null)
  347. this.$refs.flow.setFieldValue('riskCriteriaId', null)
  348. }
  349. },
  350. // 初始化表单字典
  351. initFormDict(depId) {
  352. riskTasksService.getRiskCriteria(depId).then((res) => {
  353. if (!res.data) return
  354. this.riskCriteriaDict = res.data.map((item) => {
  355. return {
  356. label: item.criteriaCode,
  357. value: item.id + '',
  358. }
  359. })
  360. })
  361. },
  362. // 子表变化时
  363. childchange() {
  364. return new Promise((resolve, reject) => {
  365. var List = this.$refs.flow.getFieldValue('riskDutieUnitList')
  366. if (List !== undefined) {
  367. List.forEach((l) => {
  368. if (l.unitDeptMemberObj !== undefined && l.unitDeptMemberObj.length > 0) {
  369. l.unitDeptMemberObj[0].type = 'Group'
  370. l.unitId = l.unitDeptMemberObj[0].code
  371. l.unitName = l.unitDeptMemberObj[0].name
  372. }
  373. l.unitDeptMember = JSON.stringify(l.unitDeptMemberObj)
  374. l.contactsUserMember = JSON.stringify(l.contactsUserMemberObj)
  375. if (l.contactsUserMemberObj !== undefined && l.contactsUserMemberObj.length > 0) {
  376. l.contactsAccount = l.contactsUserMemberObj[0].code
  377. l.contactsName = l.contactsUserMemberObj[0].name
  378. }
  379. })
  380. this.$refs.flow.setFieldValue('riskDutieUnitList', List)
  381. }
  382. var opt = this.$refs.flow.getFieldValue('evaluationUnitOpt')
  383. if (opt !== undefined && opt.length > 0) {
  384. opt[0].type = 'Group'
  385. if (opt[0].props?.ORG_ID) {
  386. opt[0].code = opt[0].props.ORG_ID
  387. }
  388. this.$refs.flow.setFieldValue('evaluationUnitOpt', opt)
  389. }
  390. resolve(true)
  391. return true
  392. })
  393. },
  394. openchild() {
  395. var List = this.$refs.flow.getFieldValue('riskDutieUnitList')
  396. if (List !== undefined) {
  397. List.forEach((l) => {
  398. l.unitDeptMemberObj = JSON.parse(l.unitDeptMember)
  399. l.contactsUserMemberObj = JSON.parse(l.contactsUserMember)
  400. })
  401. }
  402. this.$refs.flow.setFieldValue('riskDutieUnitList', List)
  403. },
  404. depChange(val) {
  405. let List = this.$refs.flow.getFieldValue('riskDutieUnitList')
  406. const nList = []
  407. val.forEach((l, index) => {
  408. let flag = true
  409. if (List !== undefined) {
  410. if (List.findIndex((i) => i.unitId === l.props.ORG_ID.toString()) > -1) {
  411. flag = false
  412. }
  413. }
  414. if (flag) {
  415. l.type = 'Group'
  416. if (l.props.ORG_ID) {
  417. l.code = l.props.ORG_ID.toString()
  418. }
  419. nList.push({
  420. id: null,
  421. unitName: l.name,
  422. unitId: l.code,
  423. unitDeptMember: JSON.stringify([l]),
  424. unitDeptMemberObj: [l],
  425. contactsUserMemberObj: [],
  426. })
  427. }
  428. if (index === val.length - 1) {
  429. if (List === undefined) {
  430. List = []
  431. }
  432. List = List.concat(nList)
  433. this.$refs.flow.setFieldValue('riskDutieUnitList', List)
  434. }
  435. })
  436. // })
  437. },
  438. depSelect() {
  439. this.$refs.depSelect.openPicker()
  440. },
  441. // 保存操作,记录标识位
  442. saveproject(formdata) {
  443. this.isSave = true
  444. },
  445. initData(model) {
  446. if (this.isSave) {
  447. if (this.$refs.flow) {
  448. const userInfo = getUserInfo()
  449. // 获取可用风险准则
  450. // 如果是分派任务,则直接取发起机构ID
  451. // 如果是起草,则取当前登录人ID
  452. let depId = this.$refs.flow?.getFieldValue('inspectUnitId')
  453. if (!depId) {
  454. depId = userInfo.deptId
  455. }
  456. this.initFormDict(parseFloat(depId))
  457. // 获取风险准则结束
  458. this.riskCriteriaObj = this.$refs.flow?.getFieldValue('riskCriteriaId')
  459. // 判断增加准则的必填
  460. this.dutieTypeChange(this.$refs.flow?.getFieldValue('dutieType'))
  461. this.openchild()
  462. this.isTaskWork = !!this.$refs.flow?.getFieldValue('isTaskWork')
  463. // 创建人和创建时间赋值 creationTime creatorName
  464. if (!this.$refs.flow?.getFieldValue('creatorName')) {
  465. this.$refs.flow?.setFieldValue('creatorName', userInfo.name)
  466. this.$refs.flow?.setFieldValue('creatorId', userInfo.id)
  467. this.$refs.flow?.setFieldValue('creatorOpt', [
  468. {
  469. code: userInfo.account,
  470. name: userInfo.name,
  471. type: 'User',
  472. },
  473. ])
  474. this.$refs.flow?.setFieldValue('creatorAccount', userInfo.account)
  475. this.$refs.flow?.setFieldValue('creationTime', moment(new Date()))
  476. }
  477. // 分派任务不重新赋值年份和组织结构
  478. if (!this.isTaskWork) {
  479. // 主任务的创建人和创建时间不可编辑,不显示必填星号
  480. this.$refs.flow.flowData.processFormData.processFormPropertyValues.find((item) => {
  481. return item.name === 'creatorName'
  482. }).required = false
  483. this.$refs.flow.flowData.processFormData.processFormPropertyValues.find((item) => {
  484. return item.name === 'creationTime'
  485. }).required = false
  486. // 获取当前人所属机构公司
  487. riskIdentificationService.getCompany().then((res) => {
  488. if (res.data) {
  489. this.$refs.flow?.setFieldValue('inspectUnitId', res.data.id)
  490. this.$refs.flow?.setFieldValue('inspectUnitName', res.data.name)
  491. // 检查是否能获取风险机构
  492. this.checkOrg(res.data.id)
  493. this.initFormDict(parseFloat(res.data.id))
  494. }
  495. })
  496. const unit = [
  497. {
  498. code: userInfo.deptId.toString(),
  499. id: userInfo.deptId,
  500. name: userInfo.deptName.indexOf('/')
  501. ? userInfo.deptName.split('/').pop()
  502. : userInfo.deptName,
  503. props: { code: userInfo.deptId.toString() },
  504. type: 'GROUP',
  505. },
  506. ]
  507. this.$refs.flow?.setFieldValue('inspectUnitOpt', unit)
  508. const nowYear = new Date().getFullYear()
  509. this.$refs.flow?.setFieldValue('year', nowYear + '')
  510. }
  511. this.isSave = false
  512. }
  513. }
  514. return false
  515. },
  516. // 检查风险机构
  517. checkOrg(deptId) {
  518. riskIdentificationService
  519. .findIamOrgId(deptId)
  520. .then((res) => {
  521. // 获取风控库版本
  522. this.errorText = null
  523. if (res.data) {
  524. return riskService.getversion(parseFloat(res.data))
  525. }
  526. })
  527. .then((res) => {
  528. if (!res.data.id) {
  529. message.info('当前所属机构未设置风险库版本,请联系管理员', 3)
  530. this.errorText = '当前所属机构未设置风险库版本,请联系管理员'
  531. } else {
  532. this.errorText = null
  533. }
  534. })
  535. .catch(() => {
  536. message.info('未获取到当前组织所属风险机构,请联系管理员', 3)
  537. this.errorText = '未获取到当前组织所属风险机构,请联系管理员'
  538. })
  539. },
  540. // 日期下拉框初始化
  541. initDateSelect() {
  542. const nowYear = new Date().getFullYear()
  543. this.yearArry.push(nowYear)
  544. for (let i = 1; i < 6; i++) {
  545. this.yearArry.push(nowYear - i)
  546. }
  547. for (let i = 1; i < 11; i++) {
  548. this.yearArry.push(nowYear + i)
  549. }
  550. this.yearArry.sort()
  551. if (this.$refs.flow.getFieldValue('planYear') === undefined) {
  552. this.$refs.flow.setFieldValue('planYear', nowYear + '')
  553. }
  554. },
  555. validForm() {
  556. if (this.errorText) {
  557. return Promise.resolve(false)
  558. }
  559. // 防止创建人员变化,重新赋值 start
  560. const cUser = this.$refs.flow?.getFieldValue('creatorOpt')
  561. this.$refs.flow?.setFieldValue('creatorName', cUser[0].name)
  562. this.$refs.flow?.setFieldValue('creatorAccount', cUser[0].code)
  563. // 防止创建人员变化,重新赋值 end
  564. const child = this.$refs.flow.getFieldValue('riskDutieUnitList')
  565. if (child !== undefined && child.length !== 0) {
  566. let flag = true
  567. child.forEach((c) => {
  568. if (
  569. c.contactsUserMember === '' ||
  570. c.contactsUserMember === '[]' ||
  571. c.contactsUserMember === null ||
  572. c.contactsUserMember === undefined
  573. ) {
  574. flag = false
  575. }
  576. if (
  577. c.unitDeptMember === '' ||
  578. c.unitDeptMember === '[]' ||
  579. c.unitDeptMember === null ||
  580. c.unitDeptMember === undefined
  581. ) {
  582. flag = false
  583. }
  584. })
  585. if (flag) {
  586. return Promise.resolve(true)
  587. } else {
  588. Modal.warning({
  589. title: '提示',
  590. content: '请完善分派单位中的单位和人员信息!',
  591. })
  592. this.flag = false
  593. return Promise.resolve(false)
  594. }
  595. } else {
  596. return Promise.resolve(true)
  597. }
  598. },
  599. actionBtnClick(evt, btn) {
  600. this.childchange()
  601. if (btn.button.buttonId.indexOf('save') > -1) {
  602. evt.waitUntil(
  603. new Promise((resolve, reject) => {
  604. if (this.$refs.flow.getFieldValue('year') === undefined) {
  605. this.$refs.flow.validateField('year')
  606. evt.preventDefault()
  607. resolve()
  608. } else {
  609. resolve()
  610. }
  611. })
  612. )
  613. }
  614. },
  615. },
  616. }
  617. </script>
  618. <style module lang="scss">
  619. @use '@/common/design' as *;
  620. .btnselect {
  621. position: relative;
  622. top: 4px;
  623. float: right;
  624. .batchselect {
  625. z-index: 100;
  626. margin-right: 80px;
  627. }
  628. }
  629. .rist_tasks_form {
  630. :global(.ant-calendar-picker) {
  631. width: 100%;
  632. }
  633. .type_td {
  634. border-right: none !important;
  635. }
  636. }
  637. </style>