edit.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <template>
  2. <el-dialog
  3. :title="title"
  4. :visible.sync="dialogVisible"
  5. :close-on-click-modal="false"
  6. :close-on-press-escape="false"
  7. append-to-body
  8. class="bpmn-agent-dialog"
  9. width="80%"
  10. top="10vh"
  11. @open="getFormData"
  12. @close="closeDialog"
  13. >
  14. <el-form
  15. ref="agentForm"
  16. v-loading="dialogLoading"
  17. :element-loading-text="$t('common.loading')"
  18. :model="bpmAgent"
  19. :rules="rules"
  20. :label-width="formLabelWidth"
  21. @submit.native.prevent
  22. >
  23. <el-form-item label="标题:" prop="title">
  24. <el-input v-if="!readonly" v-model="bpmAgent.title" />
  25. <span v-else>{{ bpmAgent.title }}</span>
  26. </el-form-item>
  27. <el-row>
  28. <el-col :span="12" col>
  29. <el-form-item label="代理类型:" prop="agentType">
  30. <el-radio-group v-if="!readonly" v-model="bpmAgent.agentType">
  31. <el-radio
  32. v-for="option in agentTypeOptions"
  33. :key="option.value"
  34. :label="option.value"
  35. >{{ option.label }}</el-radio>
  36. </el-radio-group>
  37. <el-tag v-else :type="bpmAgent.agentType|optionsFilter(agentTypeOptions,'type')">{{ bpmAgent.agentType|optionsFilter(agentTypeOptions,'label') }}</el-tag>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="12" col>
  41. <el-form-item label="是否启用:" prop="isEnabled">
  42. <el-switch
  43. v-if="!readonly"
  44. v-model="bpmAgent.isEnabled"
  45. active-value="enabled"
  46. inactive-value="disabled"
  47. />
  48. <el-tag v-else :type="bpmAgent.isEnabled|optionsFilter(statusOptions,'type')">{{ bpmAgent.isEnabled|optionsFilter(statusOptions,'label') }}</el-tag>
  49. </el-form-item>
  50. </el-col>
  51. </el-row>
  52. <el-form-item label="委托人:" prop="delegatorId">
  53. <ibps-employee-selector
  54. v-if="!readonly"
  55. v-model="bpmAgent.delegatorId"
  56. @callback="callbackDelegatorrInfo"
  57. />
  58. <span v-else>{{ bpmAgent.delegatorName }}</span>
  59. </el-form-item>
  60. <el-row>
  61. <el-col :span="12" col>
  62. <el-form-item label="生效时间:" prop="effectiveTime">
  63. <el-date-picker v-if="!readonly" v-model="bpmAgent.effectiveTime" type="date" value-format="yyyy-MM-dd" style="width:100%;" />
  64. <span v-else>{{ bpmAgent.effectiveTime }}</span>
  65. </el-form-item>
  66. </el-col>
  67. <el-col :span="12" col>
  68. <el-form-item label="失效时间:" prop="expiryTime">
  69. <el-date-picker v-if="!readonly" v-model="bpmAgent.expiryTime" type="date" value-format="yyyy-MM-dd" style="width:100%;" />
  70. <span v-else>{{ bpmAgent.expiryTime }}</span>
  71. </el-form-item>
  72. </el-col>
  73. </el-row>
  74. <!-- 全部代理 || 部分代理 -->
  75. <el-form-item v-if="bpmAgent.agentType === 'all' || bpmAgent.agentType === 'part'" label="代理人:" prop="agenterId">
  76. <ibps-employee-selector
  77. v-if="!readonly"
  78. v-model="bpmAgent.agenterId"
  79. @callback="callbackAgenterInfo"
  80. />
  81. <span v-else>{{ bpmAgent.agenterName }}</span>
  82. </el-form-item>
  83. <div v-if="bpmAgent.agentType === 'part'">
  84. <el-form-item label="流程定义">
  85. <div v-if="!readonly" class="dialog-right">
  86. <bpm-definition-selector
  87. button
  88. multiple
  89. @callback="updateDefine"
  90. />
  91. <el-button class="ibps-icon-remove ibps-ml-10" type="danger" @click="handleAllDelete(multipleSelection)">删除</el-button>
  92. </div>
  93. </el-form-item>
  94. <el-form-item
  95. v-loading="rowLoading"
  96. label-width="20px"
  97. :element-loading-text="$t('common.loading')"
  98. >
  99. <el-table
  100. ref="multipleTable"
  101. border
  102. :data="bpmAgent.bpmAgentDefPoList"
  103. tooltip-effect="dark"
  104. style="width: 100%"
  105. @selection-change="handleSelectionChange"
  106. >
  107. <el-table-column
  108. v-if="!readonly"
  109. type="selection"
  110. width="45"
  111. />
  112. <el-table-column
  113. label="流程名称"
  114. >
  115. <template slot-scope="scope">{{ scope.row.procDefName?scope.row.procDefName:scope.row.name }}</template>
  116. </el-table-column>
  117. <el-table-column v-if="!readonly" label="操作" width="55">
  118. <template slot-scope="scope">
  119. <el-button type="danger" icon="el-icon-delete" circle @click="handleDelete(scope.$index, scope.row)" />
  120. </template>
  121. </el-table-column>
  122. </el-table>
  123. </el-form-item>
  124. </div>
  125. <!-- 条件代理 -->
  126. <div v-if="bpmAgent.agentType === 'condition'">
  127. <el-form-item label="流程名称:">
  128. <bpm-definition-selector
  129. v-model="bpmAgent.procDefId"
  130. :disabled="readonly"
  131. />
  132. </el-form-item>
  133. <el-form-item label="流程代理条件">
  134. <div v-if="!readonly" class="dialog-right">
  135. <el-button class="ibps-icon-add" type="primary" @click="openConditionDialog">添加</el-button>
  136. <el-button class="ibps-icon-remove ibps-ml-5" type="danger">删除</el-button>
  137. </div>
  138. </el-form-item>
  139. <el-form-item
  140. v-loading="rowLoading"
  141. label-width="20px"
  142. :element-loading-text="$t('common.loading')"
  143. >
  144. <el-table
  145. ref="multipleTable"
  146. :data="bpmAgent.bpmAgentConditionPoList"
  147. tooltip-effect="dark"
  148. style="width: 100%"
  149. @selection-change="handleConditionChange"
  150. >
  151. <el-table-column
  152. type="selection"
  153. width="55"
  154. />
  155. <el-table-column
  156. label="代理人"
  157. >
  158. <template slot-scope="scope">{{ scope.row.agenterName }}</template>
  159. </el-table-column>
  160. <el-table-column
  161. label="条件名称"
  162. >
  163. <template slot-scope="scope">{{ scope.row.name }}</template>
  164. </el-table-column>
  165. <el-table-column
  166. prop="address"
  167. label="管理"
  168. width="100px"
  169. show-overflow-tooltip
  170. >
  171. <el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(scope.$index, scope.row)" />
  172. <el-button type="danger" icon="el-icon-delete" circle @click="handleRemove(scope.$index, scope.row)" />
  173. </el-table-column>
  174. </el-table>
  175. </el-form-item>
  176. </div>
  177. </el-form>
  178. <div slot="footer" class="el-dialog--center">
  179. <ibps-toolbar
  180. :actions="toolbars"
  181. @action-event="handleActionEvent"
  182. />
  183. </div>
  184. <!-- 添加规则弹窗 -->
  185. <condition
  186. :def-id="bpmAgent.procDefId"
  187. :visible="conditionDialogVisible"
  188. @callback="callbackBpmAgentConditionPoList"
  189. @close="visible => conditionDialogVisible = visible"
  190. />
  191. </el-dialog>
  192. </template>
  193. <script>
  194. import { save, get } from '@/api/platform/bpmn/bpmAgent'
  195. import { agentTypeOptions, statusOptions } from './constants'
  196. import ActionUtils from '@/utils/action'
  197. import IbpsEmployeeSelector from '@/business/platform/org/employee/selector'
  198. import BpmDefinitionSelector from '@/business/platform/bpmn/definition/selector'
  199. import Condition from './condition'
  200. import { setTimeout } from 'timers'
  201. export default {
  202. components: {
  203. IbpsEmployeeSelector,
  204. BpmDefinitionSelector,
  205. Condition
  206. },
  207. props: {
  208. visible: {
  209. type: Boolean,
  210. default: false
  211. },
  212. readonly: {
  213. type: Boolean,
  214. default: false
  215. },
  216. id: String,
  217. title: String
  218. },
  219. data() {
  220. return {
  221. formName: 'agentForm',
  222. formLabelWidth: '120px',
  223. dialogVisible: this.visible,
  224. conditionDialogVisible: false, // 条件规则界面
  225. dialogLoading: false,
  226. rowLoading: false,
  227. statusOptions: statusOptions,
  228. agentTypeOptions: agentTypeOptions,
  229. defaultForm: {},
  230. multipleSelection: [],
  231. conditionSelection: [],
  232. bpmAgent: {
  233. title: '',
  234. procDefId: '',
  235. procDefKey: '',
  236. delegatorId: this.$store.getters.userId,
  237. delegatorName: this.$store.getters.name,
  238. effectiveTime: '',
  239. expiryTime: '',
  240. agenterId: '',
  241. agenterName: '',
  242. agentType: 'all',
  243. isEnabled: 'enabled',
  244. bpmAgentDefPoList: [],
  245. bpmAgentConditionPoList: []
  246. },
  247. rules: {
  248. title: [{ required: true, message: this.$t('validate.required') },
  249. { min: 1, max: 64, message: '长度不能超过64个字符', trigger: 'blur' }],
  250. delegatorId: [{ required: true, message: this.$t('validate.required') }],
  251. agenterId: [{ required: true, message: this.$t('validate.required') }],
  252. effectiveTime: [{ required: true, message: this.$t('validate.required') }],
  253. expiryTime: [{ required: true, message: this.$t('validate.required') }]
  254. },
  255. toolbars: [
  256. { key: 'save', hidden: () => { return this.readonly } },
  257. { key: 'cancel' }
  258. ],
  259. orgAddIndex: 'qita',
  260. orgAddId: '990905993732816896,1017183192769101824,990915218848612352,1017182150320979968,1017182194042404864,990914314816716800,990915476898971648,990915611989114880,990915712052625408,1017182721685848064,1017183098200129536'
  261. }
  262. },
  263. computed: {
  264. formId() {
  265. return this.id
  266. }
  267. },
  268. watch: {
  269. visible: {
  270. handler: function(val, oldVal) {
  271. this.dialogVisible = this.visible
  272. },
  273. immediate: true
  274. }
  275. },
  276. created() {
  277. this.defaultForm = JSON.parse(JSON.stringify(this.bpmAgent))
  278. },
  279. mounted() {
  280. this.$nextTick(() => {
  281. if (this.$refs.multipleTable) {
  282. this.$refs.multipleTable.doLayout()
  283. }
  284. })
  285. },
  286. methods: {
  287. handleEdit() {
  288. this.rowLoading = true
  289. setTimeout(() => {
  290. this.rowLoading = false
  291. // TODO:
  292. })
  293. },
  294. handleRemove() {
  295. this.rowLoading = true
  296. setTimeout(() => {
  297. this.rowLoading = false
  298. // TODO:
  299. })
  300. },
  301. callbackBpmAgentConditionPoList(data) {
  302. console.log(data)
  303. },
  304. handleDelete(index, arr) {
  305. this.rowLoading = true
  306. setTimeout(() => {
  307. if (arr !== []) {
  308. this.bpmAgent.bpmAgentDefPoList.splice(index, 1)
  309. } else {
  310. arr.forEach(i => {
  311. this.bpmAgent.bpmAgentDefPoList.forEach(l => {
  312. if (i.procDefKey === l.procDefKey) {
  313. this.bpmAgent.bpmAgentDefPoList.splice(l, 1)
  314. }
  315. })
  316. })
  317. }
  318. this.rowLoading = false
  319. })
  320. },
  321. handleAllDelete(arr) {
  322. this.rowLoading = true
  323. setTimeout(() => {
  324. if (!this.$utils.isEmpty(arr)) {
  325. arr.forEach(i => {
  326. this.bpmAgent.bpmAgentDefPoList.forEach(l => {
  327. if (i.procDefKey === l.procDefKey) {
  328. this.bpmAgent.bpmAgentDefPoList.splice(l, 1)
  329. }
  330. })
  331. })
  332. }
  333. this.rowLoading = false
  334. })
  335. },
  336. handleSelectionChange(val) {
  337. this.multipleSelection = val
  338. },
  339. handleConditionChange(val) {
  340. this.conditionSelection = val
  341. },
  342. handleActionEvent({ key }) {
  343. switch (key) {
  344. case 'save':
  345. this.handleSave()
  346. break
  347. case 'cancel':
  348. this.closeDialog()
  349. break
  350. default:
  351. break
  352. }
  353. },
  354. // 保存数据
  355. handleSave() {
  356. this.$refs[this.formName].validate(valid => {
  357. if (valid) {
  358. this.saveData()
  359. } else {
  360. ActionUtils.saveErrorMessage()
  361. }
  362. })
  363. },
  364. // 提交保存数据
  365. saveData() {
  366. const data = JSON.parse(JSON.stringify(this.bpmAgent))
  367. data.effectiveTime = new Date(this.bpmAgent.effectiveTime).getTime() || ''
  368. data.expiryTime = new Date(this.bpmAgent.expiryTime).getTime() || ''
  369. // 检测生效时间日期是否发布日期在之前。
  370. if (data.effectiveTime > data.expiryTime) {
  371. ActionUtils.error('生效时间与失效时间范围不合法!')
  372. return
  373. }
  374. if (this.$utils.isEmpty(this.bpmAgent.bpmAgentDefPoList) && this.bpmAgent.agentType === 'part') {
  375. ActionUtils.error('流程定义数据不能为空!')
  376. return
  377. }
  378. save(this.bpmAgent).then(response => {
  379. this.$emit('callback', this)
  380. ActionUtils.saveSuccessMessage(response.message, (rtn) => {
  381. if (this.$utils.isEmpty(this.formId)) {
  382. this.$refs[this.formName].resetFields()
  383. }
  384. if (rtn) {
  385. this.closeDialog()
  386. }
  387. })
  388. }).catch((err) => {
  389. console.error(err)
  390. })
  391. },
  392. // 关闭当前窗口
  393. closeDialog() {
  394. this.$emit('close', false)
  395. this.$refs[this.formName].resetFields()
  396. },
  397. /**
  398. * 表单验证
  399. */
  400. formValidate() {
  401. if (this.readonly) return
  402. this.$nextTick(() => {
  403. this.$refs[this.formName].validate(() => {})
  404. })
  405. },
  406. /**
  407. * 获取表单数据
  408. */
  409. getFormData() {
  410. if (this.$utils.isEmpty(this.formId)) {
  411. // 重置表单
  412. this.bpmAgent = JSON.parse(JSON.stringify(this.defaultForm))
  413. this.formValidate()
  414. return
  415. }
  416. this.dialogLoading = true
  417. get({
  418. id: this.formId
  419. }).then(response => {
  420. this.bpmAgent = response.data
  421. console.log(this.bpmAgent)
  422. this.formValidate()
  423. this.dialogLoading = false
  424. }).catch(() => {
  425. this.dialogLoading = false
  426. })
  427. },
  428. addDef() {
  429. alert('打开流程选择器')
  430. },
  431. callbackDelegatorrInfo(data) {
  432. this.bpmAgent.delegatorName = data.name
  433. },
  434. callbackAgenterInfo(data) {
  435. this.bpmAgent.agenterName = data.name
  436. },
  437. updateDefine(data) {
  438. this.rowLoading = true
  439. const arr = data.map(item => {
  440. return {
  441. id: '',
  442. agentId: '',
  443. procDefKey: item.defKey,
  444. nodeId: '',
  445. name: item.name
  446. }
  447. })
  448. setTimeout(() => {
  449. if (this.$utils.isEmpty(this.bpmAgent.bpmAgentDefPoList)) {
  450. this.bpmAgent.bpmAgentDefPoList = arr
  451. } else {
  452. this.bpmAgent.bpmAgentDefPoList = this.bpmAgent.bpmAgentDefPoList.concat(arr)
  453. }
  454. this.rowLoading = false
  455. })
  456. },
  457. openConditionDialog() {
  458. if (this.$utils.isEmpty(this.bpmAgent.procDefId)) {
  459. ActionUtils.warning('请选择流程!!')
  460. return
  461. }
  462. this.conditionDialogVisible = true
  463. }
  464. }
  465. }
  466. </script>
  467. <style lang="scss">
  468. .bpmn-agent-dialog{
  469. .el-dialog__body{
  470. height: calc(70vh - 110px) !important;
  471. }
  472. .dialog-right{
  473. float: right;
  474. div{
  475. display: inline-block;
  476. }
  477. }
  478. }
  479. </style>