workflow-bpmn-modeler-andtv-vue3 10.1.2 → 10.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/fonts/bpmn.5d33bee4.eot +0 -0
  2. package/dist/fonts/bpmn.67058807.woff2 +0 -0
  3. package/dist/fonts/bpmn.b5c9250d.ttf +0 -0
  4. package/dist/fonts/bpmn.e9e7d076.woff +0 -0
  5. package/dist/img/bpmn.74eea12b.svg +224 -0
  6. package/dist/workflow-bpmn-modeler-andtv-vue3.common.js +199 -5
  7. package/dist/workflow-bpmn-modeler-andtv-vue3.umd.js +199 -5
  8. package/dist/workflow-bpmn-modeler-andtv-vue3.umd.min.js +199 -5
  9. package/package/CHANGELOG.md +6 -0
  10. package/package/LICENSE +21 -0
  11. package/package/README.md +208 -0
  12. package/package/components/nodePanel/process.vue +9 -2
  13. package/package/components/nodePanel/startEnd.vue +6 -2
  14. package/package/dist/demo.html +9 -0
  15. package/package/dist/fonts/bpmn.5d33bee4.eot +0 -0
  16. package/package/dist/fonts/bpmn.67058807.woff2 +0 -0
  17. package/package/dist/fonts/bpmn.b5c9250d.ttf +0 -0
  18. package/package/dist/fonts/bpmn.e9e7d076.woff +0 -0
  19. package/package/dist/img/bpmn.74eea12b.svg +224 -0
  20. package/package/dist/workflow-bpmn-modeler-andtv-vue3.common.js +5617 -0
  21. package/package/dist/workflow-bpmn-modeler-andtv-vue3.umd.js +5617 -0
  22. package/package/dist/workflow-bpmn-modeler-andtv-vue3.umd.min.js +5617 -0
  23. package/package/index.vue +99 -471
  24. package/package/package/BpmData.js +68 -0
  25. package/package/package/PropertyPanel.vue +342 -0
  26. package/package/package/common/customTranslate.js +20 -0
  27. package/package/package/common/mixinExecutionListener.js +24 -0
  28. package/package/package/common/mixinPanel.js +70 -0
  29. package/package/package/common/mixinXcrud.js +22 -0
  30. package/package/package/common/parseElement.js +53 -0
  31. package/package/package/components/custom/customContextPad.vue +24 -0
  32. package/package/package/components/nodePanel/gateway.vue +165 -0
  33. package/package/package/components/nodePanel/process.vue +201 -0
  34. package/package/package/components/nodePanel/property/executionListener.vue +240 -0
  35. package/package/package/components/nodePanel/property/listenerParam.vue +137 -0
  36. package/package/package/components/nodePanel/property/multiInstance.vue +177 -0
  37. package/package/package/components/nodePanel/property/signal.vue +178 -0
  38. package/package/package/components/nodePanel/property/taskListener.vue +242 -0
  39. package/package/package/components/nodePanel/sequenceFlow.vue +180 -0
  40. package/package/package/components/nodePanel/startEnd.vue +174 -0
  41. package/package/package/components/nodePanel/task.vue +452 -0
  42. package/package/package/flowable/flowable.json +1218 -0
  43. package/package/package/flowable/init.js +24 -0
  44. package/package/package/flowable/showConfig.js +51 -0
  45. package/package/package/index.js +9 -0
  46. package/package/package/index.ts +10 -0
  47. package/package/package/index.vue +730 -0
  48. package/package/package/lang/zh.js +227 -0
  49. package/package/package/types/components.d.ts +35 -0
  50. package/package/package.json +89 -0
  51. package/package.json +12 -13
  52. package/package/bpmn-styles.css +0 -40
@@ -0,0 +1,452 @@
1
+ <template>
2
+ <div>
3
+ <a-form ref="formRef" :model="formData" layout="horizontal">
4
+ <a-form-item label="节点 id" name="id" :rules="[{ required: true, message: 'Id 不能为空' }]">
5
+ <a-input v-model:value="formData.id" />
6
+ </a-form-item>
7
+
8
+ <a-form-item label="节点名称" name="name">
9
+ <a-input v-model:value="formData.name" />
10
+ </a-form-item>
11
+
12
+ <a-form-item label="节点描述" name="documentation">
13
+ <a-textarea v-model:value="formData.documentation" />
14
+ </a-form-item>
15
+
16
+ <a-form-item label="执行监听器">
17
+ <a-badge :count="executionListenerLength">
18
+ <a-button size="small" @click="dialogName = 'executionListenerDialog'">编辑</a-button>
19
+ </a-badge>
20
+ </a-form-item>
21
+
22
+ <a-form-item v-if="showConfig.taskListener" label="任务监听器">
23
+ <a-badge :count="taskListenerLength">
24
+ <a-button size="small" @click="dialogName = 'taskListenerDialog'">编辑</a-button>
25
+ </a-badge>
26
+ </a-form-item>
27
+
28
+ <a-form-item v-if="showConfig.userType" label="人员类型" name="userType">
29
+ <a-select v-model:value="formData.userType" :options="userTypeOptions" />
30
+ </a-form-item>
31
+
32
+ <a-form-item v-if="showConfig.assignee && formData.userType === 'assignee'" label="指定人员" name="assignee">
33
+ <a-select
34
+ v-model:value="formData.assignee"
35
+ :options="userOptions"
36
+ :filter-option="filterOption"
37
+ allow-clear
38
+ show-search
39
+ />
40
+ </a-form-item>
41
+
42
+ <a-form-item v-if="showConfig.candidateUsers && formData.userType === 'candidateUsers'" label="候选人员" name="candidateUsers">
43
+ <a-select
44
+ v-model:value="formData.candidateUsers"
45
+ :options="userOptions"
46
+ :filter-option="filterOption"
47
+ mode="multiple"
48
+ allow-clear
49
+ show-search
50
+ />
51
+ </a-form-item>
52
+
53
+ <a-form-item v-if="showConfig.candidateGroups && formData.userType === 'candidateGroups'" label="候选组" name="candidateGroups">
54
+ <a-select
55
+ v-model:value="formData.candidateGroups"
56
+ :options="groupOptions"
57
+ :filter-option="filterOption"
58
+ mode="multiple"
59
+ allow-clear
60
+ show-search
61
+ />
62
+ </a-form-item>
63
+
64
+ <a-form-item label="多实例">
65
+ <a-badge :dot="hasMultiInstance">
66
+ <a-button size="small" @click="dialogName = 'multiInstanceDialog'">编辑</a-button>
67
+ </a-badge>
68
+ </a-form-item>
69
+
70
+ <a-form-item v-if="showConfig.async" label="异步" name="async">
71
+ <a-switch v-model:checked="formData.async" checked-children="是" un-checked-children="否" />
72
+ </a-form-item>
73
+
74
+ <a-form-item v-if="showConfig.priority" label="优先级" name="priority">
75
+ <a-input v-model:value="formData.priority" />
76
+ </a-form-item>
77
+
78
+ <a-form-item v-if="showConfig.formKey" label="表单标识key" name="formKey">
79
+ <a-input v-model:value="formData.formKey" />
80
+ </a-form-item>
81
+
82
+ <a-form-item v-if="showConfig.skipExpression" label="跳过表达式" name="skipExpression">
83
+ <a-input v-model:value="formData.skipExpression" />
84
+ </a-form-item>
85
+
86
+ <a-form-item v-if="showConfig.isForCompensation" label="是否为补偿" name="isForCompensation">
87
+ <a-switch v-model:checked="formData.isForCompensation" checked-children="是" un-checked-children="否" />
88
+ </a-form-item>
89
+
90
+ <a-form-item v-if="showConfig.triggerable" label="服务任务可触发" name="triggerable">
91
+ <a-switch v-model:checked="formData.triggerable" checked-children="是" un-checked-children="否" />
92
+ </a-form-item>
93
+
94
+ <a-form-item v-if="showConfig.autoStoreVariables" label="自动存储变量" name="autoStoreVariables">
95
+ <a-switch v-model:checked="formData.autoStoreVariables" checked-children="是" un-checked-children="否" />
96
+ </a-form-item>
97
+
98
+ <a-form-item v-if="showConfig.ruleVariablesInput" label="输入变量" name="ruleVariablesInput">
99
+ <a-input v-model:value="formData.ruleVariablesInput" />
100
+ </a-form-item>
101
+
102
+ <a-form-item v-if="showConfig.rules" label="规则" name="rules">
103
+ <a-input v-model:value="formData.rules" />
104
+ </a-form-item>
105
+
106
+ <a-form-item v-if="showConfig.resultVariable" label="结果变量" name="resultVariable">
107
+ <a-input v-model:value="formData.resultVariable" />
108
+ </a-form-item>
109
+
110
+ <a-form-item v-if="showConfig.exclude" label="排除" name="exclude">
111
+ <a-switch v-model:checked="formData.exclude" checked-children="是" un-checked-children="否" />
112
+ </a-form-item>
113
+
114
+ <a-form-item v-if="showConfig.class" label="类" name="class">
115
+ <a-input v-model:value="formData.class" />
116
+ </a-form-item>
117
+
118
+ <a-form-item v-if="showConfig.dueDate" label="到期时间" name="dueDate">
119
+ <a-date-picker v-model:value="formData.dueDate" show-time />
120
+ </a-form-item>
121
+ </a-form>
122
+
123
+ <executionListenerDialog
124
+ v-if="dialogName === 'executionListenerDialog'"
125
+ :element="element"
126
+ :modeler="modeler"
127
+ @close="finishExecutionListener"
128
+ />
129
+ <taskListenerDialog
130
+ v-if="dialogName === 'taskListenerDialog'"
131
+ :element="element"
132
+ :modeler="modeler"
133
+ @close="finishTaskListener"
134
+ />
135
+ <multiInstanceDialog
136
+ v-if="dialogName === 'multiInstanceDialog'"
137
+ :element="element"
138
+ :modeler="modeler"
139
+ @close="finishMultiInstance"
140
+ />
141
+ </div>
142
+ </template>
143
+
144
+ <script setup lang="ts">
145
+ import { ref, computed, watch, onMounted, nextTick } from 'vue'
146
+ import { FormInstance } from 'ant-design-vue'
147
+ import executionListenerDialog from './property/executionListener.vue'
148
+ import taskListenerDialog from './property/taskListener.vue'
149
+ import multiInstanceDialog from './property/multiInstance.vue'
150
+ import { commonParse, userTaskParse } from '../../common/parseElement'
151
+ import showConfigData from '../../flowable/showConfig'
152
+ import Modeler from 'bpmn-js/lib/Modeler'
153
+ // import dayjs from 'dayjs' // 暂时注释,如果需要日期处理再启用
154
+
155
+ defineOptions({
156
+ name: 'TaskPanel'
157
+ })
158
+
159
+ interface User {
160
+ name: string
161
+ id: string
162
+ }
163
+
164
+ interface Group {
165
+ name: string
166
+ id: string
167
+ }
168
+
169
+ interface Props {
170
+ users: User[]
171
+ groups: Group[]
172
+ modeler: Modeler
173
+ element: any
174
+ }
175
+
176
+ const props = defineProps<Props>()
177
+
178
+ const formRef = ref<FormInstance>()
179
+ const dialogName = ref('')
180
+ const executionListenerLength = ref(0)
181
+ const taskListenerLength = ref(0)
182
+ const hasMultiInstance = ref(false)
183
+ const formData = ref<Record<string, any>>({})
184
+
185
+ const userTypeOptions = [
186
+ { label: '指定人员', value: 'assignee' },
187
+ { label: '候选人员', value: 'candidateUsers' },
188
+ { label: '候选组', value: 'candidateGroups' }
189
+ ]
190
+
191
+ const userOptions = computed(() =>
192
+ props.users.map(user => ({ label: user.name, value: user.id }))
193
+ )
194
+
195
+ const groupOptions = computed(() =>
196
+ props.groups.map(group => ({ label: group.name, value: group.id }))
197
+ )
198
+
199
+ const elementType = computed(() => {
200
+ const bizObj = props.element.businessObject
201
+ return bizObj.eventDefinitions
202
+ ? bizObj.eventDefinitions[0].$type
203
+ : bizObj.$type
204
+ })
205
+
206
+ const showConfig = computed(() => (showConfigData as any)[elementType.value] || {})
207
+
208
+ const filterOption = (input: string, option: any) => {
209
+ return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
210
+ }
211
+
212
+ const updateProperties = (properties: Record<string, any>) => {
213
+ nextTick(() => {
214
+ try {
215
+ const modeling = props.modeler.get('modeling')
216
+ modeling.updateProperties(props.element, properties)
217
+ } catch (error) {
218
+ }
219
+ })
220
+ }
221
+
222
+ const computedExecutionListenerLength = () => {
223
+ if (props.element?.businessObject?.extensionElements?.values) {
224
+ executionListenerLength.value = props.element.businessObject.extensionElements.values
225
+ .filter((item: any) => item.$type === 'flowable:ExecutionListener').length
226
+ } else {
227
+ executionListenerLength.value = 0
228
+ }
229
+ }
230
+
231
+ const computedTaskListenerLength = () => {
232
+ if (props.element?.businessObject?.extensionElements?.values) {
233
+ taskListenerLength.value = props.element.businessObject.extensionElements.values
234
+ .filter((item: any) => item.$type === 'flowable:TaskListener').length
235
+ } else {
236
+ taskListenerLength.value = 0
237
+ }
238
+ }
239
+
240
+ const computedHasMultiInstance = () => {
241
+ hasMultiInstance.value = !!props.element?.businessObject?.loopCharacteristics
242
+ }
243
+
244
+ const finishExecutionListener = () => {
245
+ if (dialogName.value === 'executionListenerDialog') {
246
+ computedExecutionListenerLength()
247
+ }
248
+ dialogName.value = ''
249
+ }
250
+
251
+ const finishTaskListener = () => {
252
+ if (dialogName.value === 'taskListenerDialog') {
253
+ computedTaskListenerLength()
254
+ }
255
+ dialogName.value = ''
256
+ }
257
+
258
+ const finishMultiInstance = () => {
259
+ if (dialogName.value === 'multiInstanceDialog') {
260
+ computedHasMultiInstance()
261
+ }
262
+ dialogName.value = ''
263
+ }
264
+
265
+ // Watch for form data changes
266
+ watch(() => formData.value.userType, (val, oldVal) => {
267
+ if (oldVal && props.element?.businessObject?.$attrs) {
268
+ const types = ['assignee', 'candidateUsers', 'candidateGroups']
269
+ types.forEach(type => {
270
+ delete props.element.businessObject.$attrs[`flowable:${type}`]
271
+ delete formData.value[type]
272
+ })
273
+ }
274
+ })
275
+
276
+ watch(() => formData.value.assignee, (val) => {
277
+ if (formData.value.userType !== 'assignee') {
278
+ if (props.element?.businessObject?.$attrs) {
279
+ delete props.element.businessObject.$attrs[`flowable:assignee`]
280
+ }
281
+ return
282
+ }
283
+ updateProperties({ 'flowable:assignee': val })
284
+ })
285
+
286
+ watch(() => formData.value.candidateUsers, (val) => {
287
+ if (formData.value.userType !== 'candidateUsers') {
288
+ if (props.element?.businessObject?.$attrs) {
289
+ delete props.element.businessObject.$attrs[`flowable:candidateUsers`]
290
+ }
291
+ return
292
+ }
293
+ updateProperties({ 'flowable:candidateUsers': val?.join(',') })
294
+ })
295
+
296
+ watch(() => formData.value.candidateGroups, (val) => {
297
+ if (formData.value.userType !== 'candidateGroups') {
298
+ if (props.element?.businessObject?.$attrs) {
299
+ delete props.element.businessObject.$attrs[`flowable:candidateGroups`]
300
+ }
301
+ return
302
+ }
303
+ updateProperties({ 'flowable:candidateGroups': val?.join(',') })
304
+ })
305
+
306
+ watch(() => formData.value.async, (val) => {
307
+ if (val === '') val = null
308
+ updateProperties({ 'flowable:async': val })
309
+ })
310
+
311
+ watch(() => formData.value.dueDate, (val) => {
312
+ if (val === '') val = null
313
+ updateProperties({ 'flowable:dueDate': val })
314
+ })
315
+
316
+ watch(() => formData.value.formKey, (val) => {
317
+ if (val === '') val = null
318
+ updateProperties({ 'flowable:formKey': val })
319
+ })
320
+
321
+ watch(() => formData.value.priority, (val) => {
322
+ if (val === '') val = null
323
+ updateProperties({ 'flowable:priority': val })
324
+ })
325
+
326
+ watch(() => formData.value.skipExpression, (val) => {
327
+ if (val === '') val = null
328
+ updateProperties({ 'flowable:skipExpression': val })
329
+ })
330
+
331
+ watch(() => formData.value.isForCompensation, (val) => {
332
+ if (val === '') val = null
333
+ updateProperties({ 'isForCompensation': val })
334
+ })
335
+
336
+ watch(() => formData.value.triggerable, (val) => {
337
+ if (val === '') val = null
338
+ updateProperties({ 'flowable:triggerable': val })
339
+ })
340
+
341
+ watch(() => formData.value.class, (val) => {
342
+ if (val === '') val = null
343
+ updateProperties({ 'flowable:class': val })
344
+ })
345
+
346
+ watch(() => formData.value.autoStoreVariables, (val) => {
347
+ if (val === '') val = null
348
+ updateProperties({ 'flowable:autoStoreVariables': val })
349
+ })
350
+
351
+ watch(() => formData.value.exclude, (val) => {
352
+ if (val === '') val = null
353
+ updateProperties({ 'flowable:exclude': val })
354
+ })
355
+
356
+ watch(() => formData.value.ruleVariablesInput, (val) => {
357
+ if (val === '') val = null
358
+ updateProperties({ 'flowable:ruleVariablesInput': val })
359
+ })
360
+
361
+ watch(() => formData.value.rules, (val) => {
362
+ if (val === '') val = null
363
+ updateProperties({ 'flowable:rules': val })
364
+ })
365
+
366
+ watch(() => formData.value.resultVariable, (val) => {
367
+ if (val === '') val = null
368
+ updateProperties({ 'flowable:resultVariable': val })
369
+ })
370
+
371
+ watch(() => formData.value.id, (val) => {
372
+ updateProperties({ id: val })
373
+ })
374
+
375
+ watch(() => formData.value.name, (val) => {
376
+ updateProperties({ name: val })
377
+ })
378
+
379
+ watch(() => formData.value.documentation, (val) => {
380
+ if (!val) {
381
+ updateProperties({ documentation: [] })
382
+ return
383
+ }
384
+ if (props.modeler?.get('moddle')) {
385
+ const documentationElement = props.modeler.get('moddle').create('bpmn:Documentation', { text: val })
386
+ updateProperties({ documentation: [documentationElement] })
387
+ }
388
+ })
389
+
390
+ onMounted(() => {
391
+ if (props.element) {
392
+ let cache = commonParse(props.element)
393
+ cache = userTaskParse(cache)
394
+ formData.value = cache
395
+ computedExecutionListenerLength()
396
+ computedTaskListenerLength()
397
+ computedHasMultiInstance()
398
+ }
399
+ })
400
+ </script>
401
+
402
+ <style scoped>
403
+ .flow-containers {
404
+ padding: 0;
405
+ background: transparent;
406
+ min-height: 100%;
407
+ }
408
+
409
+ .flow-containers :deep(.ant-form-item) {
410
+ margin-bottom: 16px;
411
+ }
412
+
413
+ .flow-containers :deep(.ant-form-item-label) {
414
+ font-weight: 500;
415
+ color: #262626;
416
+ }
417
+
418
+ .flow-containers :deep(.ant-input),
419
+ .flow-containers :deep(.ant-select),
420
+ .flow-containers :deep(.ant-textarea) {
421
+ border-radius: 6px;
422
+ transition: all 0.3s;
423
+ }
424
+
425
+ .flow-containers :deep(.ant-button) {
426
+ border-radius: 6px;
427
+ font-weight: 500;
428
+ }
429
+
430
+ .flow-containers :deep(.ant-badge) {
431
+ margin-right: 8px;
432
+ }
433
+
434
+ .flow-containers :deep(.ant-badge .ant-badge-count) {
435
+ background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);
436
+ box-shadow: 0 2px 4px rgba(255, 77, 79, 0.3);
437
+ }
438
+
439
+ .flow-containers :deep(.ant-switch) {
440
+ background-color: #d9d9d9;
441
+ }
442
+
443
+ .flow-containers :deep(.ant-switch-checked) {
444
+ background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
445
+ }
446
+
447
+ .flow-containers :deep(.ant-select-multiple .ant-select-selection-item) {
448
+ background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
449
+ border: 1px solid #91d5ff;
450
+ border-radius: 4px;
451
+ }
452
+ </style>