task.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. <template>
  2. <div>
  3. <x-form ref="xForm" v-model="formData" :config="formConfig">
  4. <template #executionListener>
  5. <el-badge :value="executionListenerLength">
  6. <el-button size="small" @click="dialogName = 'executionListenerDialog'">编辑</el-button>
  7. </el-badge>
  8. </template>
  9. <template #taskListener>
  10. <el-badge :value="taskListenerLength">
  11. <el-button size="small" @click="dialogName = 'taskListenerDialog'">编辑</el-button>
  12. </el-badge>
  13. </template>
  14. <template #formListener>
  15. <el-button size="small" @click="formUrlOrFormJson">编辑</el-button>
  16. </template>
  17. <template #purviewListener>
  18. <el-button size="small" @click="dialogName = 'purviewListenerDialog'">编辑</el-button>
  19. </template>
  20. <template #multiInstance>
  21. <el-badge :is-dot="hasMultiInstance">
  22. <el-button size="small" @click="dialogName = 'multiInstanceDialog'">编辑</el-button>
  23. </el-badge>
  24. </template>
  25. </x-form>
  26. <executionListenerDialog
  27. v-if="dialogName === 'executionListenerDialog'"
  28. :element="element"
  29. :modeler="modeler"
  30. @close="finishExecutionListener"
  31. />
  32. <taskListenerDialog
  33. v-if="dialogName === 'taskListenerDialog'"
  34. :element="element"
  35. :modeler="modeler"
  36. @close="finishTaskListener"
  37. />
  38. <el-drawer
  39. :visible.sync="formVisible"
  40. direction="rtl"
  41. :withHeader = "false"
  42. close-on-press-escape
  43. destroy-on-close
  44. ref = "drawerGenerator"
  45. :append-to-body = "true"
  46. size="100%">
  47. <formListenerDialog
  48. :tableName = "tableName"
  49. :formJson = "nodeFormJson"
  50. :parentsRefs = "parentsRefs"
  51. :nodeId = "formData.id"
  52. @sendFormJson = "getFormJson"
  53. >
  54. </formListenerDialog>
  55. </el-drawer>
  56. <urlListener
  57. v-if="dialogName === 'urlListenerDialog'"
  58. :nodeId = "formData.id"
  59. :customUrl = "customUrl"
  60. @sendCustomUrl = "gendCustomUrl"
  61. >
  62. </urlListener>
  63. <purviewListenerDialog
  64. v-if="dialogName === 'purviewListenerDialog'"
  65. :purview = "purview"
  66. :nodeId = "formData.id"
  67. @sendPurview = "getPurview"
  68. >
  69. </purviewListenerDialog>
  70. <multiInstanceDialog
  71. v-if="dialogName === 'multiInstanceDialog'"
  72. :element="element"
  73. :modeler="modeler"
  74. @close="finishMultiInstance"
  75. />
  76. </div>
  77. </template>
  78. <script>
  79. import mixinPanel from '../../common/mixinPanel'
  80. import executionListenerDialog from './property/executionListener'
  81. import taskListenerDialog from './property/taskListener'
  82. import multiInstanceDialog from './property/multiInstance'
  83. import purviewListenerDialog from './property/purviewListener'
  84. import urlListener from './property/urlListener'
  85. import formListenerDialog from '../../../src/views/index/Home'
  86. import { commonParse, userTaskParse } from '../../common/parseElement'
  87. export default {
  88. components: {
  89. executionListenerDialog,
  90. taskListenerDialog,
  91. multiInstanceDialog,
  92. formListenerDialog,
  93. purviewListenerDialog,
  94. urlListener
  95. },
  96. mixins: [mixinPanel],
  97. props: {
  98. users: {
  99. type: Array,
  100. required: true
  101. },
  102. groups: {
  103. type: Array,
  104. required: true
  105. },
  106. tableName : {
  107. type: String,
  108. default: ''
  109. },
  110. /** 节点配置信息 */
  111. nodeIdFormJsonArray : {
  112. type : Array,
  113. default: () => []
  114. },
  115. /** 菜单总配置信息 */
  116. menuConfig : {
  117. type : Object,
  118. default: () => {}
  119. },
  120. flowAbleIndex :{
  121. type : Object,
  122. default: () => {}
  123. },
  124. },
  125. data() {
  126. return {
  127. userTypeOption: [
  128. { label: '指定人员', value: 'assignee' },
  129. { label: '候选人员', value: 'candidateUsers' },
  130. { label: '候选组', value: 'candidateGroups' }
  131. ],
  132. dialogName: '',
  133. formVisible : false,
  134. purviewVisible : false,
  135. executionListenerLength: 0,
  136. taskListenerLength: 0,
  137. hasMultiInstance: false,
  138. formData: {},
  139. parentsRefs : this.$refs,
  140. nodeFormJson : '',
  141. purview : '',
  142. customUrl : '',
  143. type : ''
  144. }
  145. },
  146. mounted () {
  147. this.type = this.menuConfig.type;
  148. if (!!this.element.businessObject.extensionElements) {
  149. this.executionListenerLength = this.element.businessObject.extensionElements.values.length;
  150. }
  151. },
  152. computed: {
  153. formConfig() {
  154. const _this = this
  155. return {
  156. inline: false,
  157. item: [
  158. {
  159. xType: 'input',
  160. name: 'id',
  161. label: '节点 id',
  162. rules: [{ required: true, message: 'Id 不能为空' }],
  163. disabled : true
  164. },
  165. {
  166. xType: 'input',
  167. name: 'name',
  168. label: '节点名称'
  169. },
  170. {
  171. xType: 'input',
  172. name: 'documentation',
  173. label: '节点描述'
  174. },
  175. /* {
  176. xType: 'slot',
  177. name: 'executionListener',
  178. label: '执行监听器'
  179. }, */
  180. /* {
  181. xType: 'slot',
  182. name: 'taskListener',
  183. label: '任务监听器',
  184. show: !!_this.showConfig.taskListener
  185. }, */
  186. {
  187. xType: 'slot',
  188. name: 'formListener',
  189. label: '视图设置',
  190. show: !!_this.showConfig.taskListener
  191. },
  192. {
  193. xType: 'slot',
  194. name: 'purviewListener',
  195. label: '操作权限',
  196. show: !!_this.showConfig.taskListener
  197. },
  198. {
  199. xType: 'select',
  200. name: 'userType',
  201. label: '人员类型',
  202. dic: _this.userTypeOption,
  203. show: !!_this.showConfig.userType
  204. },
  205. {
  206. xType: 'select',
  207. name: 'assignee',
  208. label: '指定人员',
  209. //是否允许加入自己随便输入的
  210. allowCreate: false,
  211. filterable: true,
  212. dic: { data: _this.users, label: 'name', value: 'id' },
  213. show: !!_this.showConfig.assignee && _this.formData.userType === 'assignee'
  214. },
  215. {
  216. xType: 'select',
  217. name: 'candidateUsers',
  218. label: '候选人员',
  219. multiple: true,
  220. allowCreate: false,
  221. filterable: true,
  222. dic: { data: _this.users, label: 'name', value: 'id' },
  223. show: !!_this.showConfig.candidateUsers && _this.formData.userType === 'candidateUsers'
  224. },
  225. {
  226. xType: 'select',
  227. name: 'candidateGroups',
  228. label: '候选组',
  229. multiple: true,
  230. allowCreate: false,
  231. filterable: true,
  232. dic: { data: _this.groups, label: 'name', value: 'id' },
  233. show: !!_this.showConfig.candidateGroups && _this.formData.userType === 'candidateGroups'
  234. },
  235. /* {
  236. xType: 'slot',
  237. name: 'multiInstance',
  238. label: '多实例'
  239. }, */
  240. /* {
  241. xType: 'switch',
  242. name: 'async',
  243. label: '异步',
  244. activeText: '是',
  245. inactiveText: '否',
  246. show: !!_this.showConfig.async
  247. }, */
  248. /* {
  249. xType: 'input',
  250. name: 'priority',
  251. label: '优先级',
  252. show: !!_this.showConfig.priority
  253. }, */
  254. /* {
  255. xType: 'input',
  256. name: 'formKey',
  257. label: '表单标识key',
  258. show: !!_this.showConfig.formKey
  259. }, */
  260. /* {
  261. xType: 'input',
  262. name: 'skipExpression',
  263. label: '跳过表达式',
  264. show: !!_this.showConfig.skipExpression
  265. }, */
  266. {
  267. xType: 'switch',
  268. name: 'isForCompensation',
  269. label: '是否为补偿',
  270. activeText: '是',
  271. inactiveText: '否',
  272. show: !!_this.showConfig.isForCompensation
  273. },
  274. {
  275. xType: 'switch',
  276. name: 'triggerable',
  277. label: '服务任务可触发',
  278. activeText: '是',
  279. inactiveText: '否',
  280. show: !!_this.showConfig.triggerable
  281. },
  282. {
  283. xType: 'switch',
  284. name: 'autoStoreVariables',
  285. label: '自动存储变量',
  286. activeText: '是',
  287. inactiveText: '否',
  288. show: !!_this.showConfig.autoStoreVariables
  289. },
  290. {
  291. xType: 'input',
  292. name: 'ruleVariablesInput',
  293. label: '输入变量',
  294. show: !!_this.showConfig.ruleVariablesInput
  295. },
  296. {
  297. xType: 'input',
  298. name: 'rules',
  299. label: '规则',
  300. show: !!_this.showConfig.rules
  301. },
  302. {
  303. xType: 'input',
  304. name: 'resultVariable',
  305. label: '结果变量',
  306. show: !!_this.showConfig.resultVariable
  307. },
  308. {
  309. xType: 'switch',
  310. name: 'exclude',
  311. label: '排除',
  312. activeText: '是',
  313. inactiveText: '否',
  314. show: !!_this.showConfig.exclude
  315. },
  316. {
  317. xType: 'input',
  318. name: 'class',
  319. label: '类',
  320. show: !!_this.showConfig.class
  321. }/* ,
  322. {
  323. xType: 'datePicker',
  324. type: 'datetime',
  325. name: 'dueDate',
  326. label: '到期时间',
  327. show: !!_this.showConfig.dueDate
  328. } */
  329. ]
  330. }
  331. }
  332. },
  333. watch: {
  334. 'formData.userType': function(val, oldVal) {
  335. if (oldVal) {
  336. const types = ['assignee', 'candidateUsers', 'candidateGroups']
  337. types.forEach(type => {
  338. delete this.element.businessObject.$attrs[`flowable:${type}`]
  339. delete this.formData[type]
  340. })
  341. }
  342. },
  343. 'formData.assignee': function(val) {
  344. if (this.formData.userType !== 'assignee') {
  345. delete this.element.businessObject.$attrs[`flowable:assignee`]
  346. return
  347. }
  348. this.updateProperties({ 'flowable:assignee': val })
  349. },
  350. 'formData.candidateUsers': function(val) {
  351. if (this.formData.userType !== 'candidateUsers') {
  352. delete this.element.businessObject.$attrs[`flowable:candidateUsers`]
  353. return
  354. }
  355. this.updateProperties({ 'flowable:candidateUsers': val?.join(',') })
  356. },
  357. 'formData.candidateGroups': function(val) {
  358. if (this.formData.userType !== 'candidateGroups') {
  359. delete this.element.businessObject.$attrs[`flowable:candidateGroups`]
  360. return
  361. }
  362. this.updateProperties({ 'flowable:candidateGroups': val?.join(',') })
  363. },
  364. 'formData.async': function(val) {
  365. if (val === '') val = null
  366. this.updateProperties({ 'flowable:async': true })
  367. },
  368. 'formData.dueDate': function(val) {
  369. if (val === '') val = null
  370. this.updateProperties({ 'flowable:dueDate': val })
  371. },
  372. 'formData.formKey': function(val) {
  373. if (val === '') val = null
  374. this.updateProperties({ 'flowable:formKey': val })
  375. },
  376. 'formData.priority': function(val) {
  377. if (val === '') val = null
  378. this.updateProperties({ 'flowable:priority': val })
  379. },
  380. 'formData.skipExpression': function(val) {
  381. if (val === '') val = null
  382. this.updateProperties({ 'flowable:skipExpression': val })
  383. },
  384. 'formData.isForCompensation': function(val) {
  385. if (val === '') val = null
  386. this.updateProperties({ 'isForCompensation': val })
  387. },
  388. 'formData.triggerable': function(val) {
  389. if (val === '') val = null
  390. this.updateProperties({ 'flowable:triggerable': val })
  391. },
  392. 'formData.class': function(val) {
  393. if (val === '') val = null
  394. this.updateProperties({ 'flowable:class': val })
  395. },
  396. 'formData.autoStoreVariables': function(val) {
  397. if (val === '') val = null
  398. this.updateProperties({ 'flowable:autoStoreVariables': val })
  399. },
  400. 'formData.exclude': function(val) {
  401. if (val === '') val = null
  402. this.updateProperties({ 'flowable:exclude': val })
  403. },
  404. 'formData.ruleVariablesInput': function(val) {
  405. if (val === '') val = null
  406. this.updateProperties({ 'flowable:ruleVariablesInput': val })
  407. },
  408. 'formData.rules': function(val) {
  409. if (val === '') val = null
  410. this.updateProperties({ 'flowable:rules': val })
  411. },
  412. 'formData.resultVariable': function(val) {
  413. if (val === '') val = null
  414. this.updateProperties({ 'flowable:resultVariable': val })
  415. },
  416. nodeIdFormJsonArray : {
  417. handler(val, oldVal){
  418. this.flowAbleIndex.nodeConfigListener(val);
  419. },
  420. deep:true //true 深度监听
  421. }
  422. },
  423. created() {
  424. let cache = commonParse(this.element)
  425. cache = userTaskParse(cache)
  426. this.formData = cache
  427. this.computedExecutionListenerLength()
  428. this.computedTaskListenerLength()
  429. this.computedHasMultiInstance()
  430. },
  431. methods: {
  432. computedExecutionListenerLength() {
  433. this.executionListenerLength = this.element.businessObject.extensionElements?.values
  434. ?.filter(item => item.$type === 'flowable:ExecutionListener').length ?? 0
  435. },
  436. computedTaskListenerLength() {
  437. this.taskListenerLength = this.element.businessObject.extensionElements?.values
  438. ?.filter(item => item.$type === 'flowable:TaskListener').length ?? 0
  439. },
  440. computedHasMultiInstance() {
  441. if (this.element.businessObject.loopCharacteristics) {
  442. this.hasMultiInstance = true
  443. } else {
  444. this.hasMultiInstance = false
  445. }
  446. },
  447. finishExecutionListener() {
  448. if (this.dialogName === 'executionListenerDialog') {
  449. this.computedExecutionListenerLength()
  450. }
  451. this.dialogName = ''
  452. },
  453. finishTaskListener() {
  454. if (this.dialogName === 'taskListenerDialog') {
  455. this.computedTaskListenerLength()
  456. }
  457. this.dialogName = ''
  458. },
  459. finishMultiInstance() {
  460. if (this.dialogName === 'multiInstanceDialog') {
  461. this.computedHasMultiInstance()
  462. }
  463. this.dialogName = ''
  464. },
  465. getFormJson(data) {
  466. var flag = false;
  467. for (let d of this.nodeIdFormJsonArray) {
  468. if (d.nodeId == data.nodeId) {
  469. d.jsonData = data.jsonData;
  470. flag = true;
  471. break;
  472. }
  473. }
  474. if (!flag) {
  475. this.nodeIdFormJsonArray.push(data);
  476. }
  477. },
  478. getPurview(data) {
  479. var flag = false;
  480. for (let d of this.nodeIdFormJsonArray) {
  481. if (d.nodeId == data.nodeId) {
  482. d.purview = data.purview;
  483. flag = true;
  484. break;
  485. }
  486. }
  487. if (!flag) {
  488. this.nodeIdFormJsonArray.push(data);
  489. }
  490. },
  491. gendCustomUrl(data) {
  492. var flag = false;
  493. for (let d of this.nodeIdFormJsonArray) {
  494. if (d.nodeId == data.nodeId) {
  495. d.customUrl = data.customUrl;
  496. flag = true;
  497. break;
  498. }
  499. }
  500. if (!flag) {
  501. this.nodeIdFormJsonArray.push(data);
  502. }
  503. },
  504. formUrlOrFormJson () {
  505. this.nodeFormJson = this.menuConfig.formJson;
  506. this.customUrl = this.menuConfig.customUrl;
  507. for (let n of this.nodeIdFormJsonArray) {
  508. if (n.nodeId == this.formData.id) {
  509. this.nodeFormJson = n.jsonData;
  510. this.purview = n.purview;
  511. this.customUrl = n.customUrl;
  512. break;
  513. }
  514. }
  515. // 自定义视图
  516. if (this.type == '0') {
  517. this.formVisible = true;
  518. } else {
  519. this.dialogName = 'urlListenerDialog'
  520. }
  521. },
  522. closedDialog() {
  523. this.dialogName = '';
  524. }
  525. }
  526. }
  527. </script>
  528. <style></style>