workflow-bpmn-modeler-andtv-vue3 10.1.1 → 10.2.0
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.
- package/dist/fonts/bpmn.5d33bee4.eot +0 -0
- package/dist/fonts/bpmn.67058807.woff2 +0 -0
- package/dist/fonts/bpmn.b5c9250d.ttf +0 -0
- package/dist/fonts/bpmn.e9e7d076.woff +0 -0
- package/dist/img/bpmn.74eea12b.svg +224 -0
- package/dist/workflow-bpmn-modeler-andtv-vue3.common.js +199 -5
- package/dist/workflow-bpmn-modeler-andtv-vue3.umd.js +199 -5
- package/dist/workflow-bpmn-modeler-andtv-vue3.umd.min.js +199 -5
- package/package/CHANGELOG.md +6 -0
- package/package/LICENSE +21 -0
- package/package/README.md +208 -0
- package/package/components/nodePanel/process.vue +9 -2
- package/package/components/nodePanel/startEnd.vue +6 -2
- package/package/dist/demo.html +9 -0
- package/package/dist/fonts/bpmn.5d33bee4.eot +0 -0
- package/package/dist/fonts/bpmn.67058807.woff2 +0 -0
- package/package/dist/fonts/bpmn.b5c9250d.ttf +0 -0
- package/package/dist/fonts/bpmn.e9e7d076.woff +0 -0
- package/package/dist/img/bpmn.74eea12b.svg +224 -0
- package/package/dist/workflow-bpmn-modeler-andtv-vue3.common.js +5617 -0
- package/package/dist/workflow-bpmn-modeler-andtv-vue3.umd.js +5617 -0
- package/package/dist/workflow-bpmn-modeler-andtv-vue3.umd.min.js +5617 -0
- package/package/index.vue +91 -427
- package/package/package/BpmData.js +68 -0
- package/package/package/PropertyPanel.vue +342 -0
- package/package/package/common/customTranslate.js +20 -0
- package/package/package/common/mixinExecutionListener.js +24 -0
- package/package/package/common/mixinPanel.js +70 -0
- package/package/package/common/mixinXcrud.js +22 -0
- package/package/package/common/parseElement.js +53 -0
- package/package/package/components/custom/customContextPad.vue +24 -0
- package/package/package/components/nodePanel/gateway.vue +165 -0
- package/package/package/components/nodePanel/process.vue +201 -0
- package/package/package/components/nodePanel/property/executionListener.vue +240 -0
- package/package/package/components/nodePanel/property/listenerParam.vue +137 -0
- package/package/package/components/nodePanel/property/multiInstance.vue +177 -0
- package/package/package/components/nodePanel/property/signal.vue +178 -0
- package/package/package/components/nodePanel/property/taskListener.vue +242 -0
- package/package/package/components/nodePanel/sequenceFlow.vue +180 -0
- package/package/package/components/nodePanel/startEnd.vue +174 -0
- package/package/package/components/nodePanel/task.vue +452 -0
- package/package/package/flowable/flowable.json +1218 -0
- package/package/package/flowable/init.js +24 -0
- package/package/package/flowable/showConfig.js +51 -0
- package/package/package/index.js +9 -0
- package/package/package/index.ts +10 -0
- package/package/package/index.vue +730 -0
- package/package/package/lang/zh.js +227 -0
- package/package/package/types/components.d.ts +35 -0
- package/package/package.json +89 -0
- package/package.json +12 -13
- package/package/bpmn-styles.css +0 -40
@@ -0,0 +1,137 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<a-modal
|
4
|
+
v-model:open="dialogVisible"
|
5
|
+
title="监听器参数"
|
6
|
+
width="700px"
|
7
|
+
:mask-closable="false"
|
8
|
+
:keyboard="false"
|
9
|
+
:closable="false"
|
10
|
+
@cancel="handleClose"
|
11
|
+
>
|
12
|
+
<a-form ref="formRef" :model="formData" layout="vertical">
|
13
|
+
<a-tabs>
|
14
|
+
<a-tab-pane key="paramList" tab="监听器参数">
|
15
|
+
<a-table
|
16
|
+
:columns="columns"
|
17
|
+
:data-source="formData.paramList"
|
18
|
+
:pagination="false"
|
19
|
+
size="small"
|
20
|
+
>
|
21
|
+
<template #bodyCell="{ column, record, index }">
|
22
|
+
<template v-if="column.key === 'type'">
|
23
|
+
<a-select
|
24
|
+
v-model:value="record.type"
|
25
|
+
:options="typeOptions"
|
26
|
+
style="width: 100%"
|
27
|
+
/>
|
28
|
+
</template>
|
29
|
+
<template v-else-if="column.key === 'name'">
|
30
|
+
<a-input v-model:value="record.name" />
|
31
|
+
</template>
|
32
|
+
<template v-else-if="column.key === 'value'">
|
33
|
+
<a-input v-model:value="record.value" />
|
34
|
+
</template>
|
35
|
+
<template v-else-if="column.key === 'action'">
|
36
|
+
<a-button type="link" danger @click="removeParam(index)">删除</a-button>
|
37
|
+
</template>
|
38
|
+
</template>
|
39
|
+
</a-table>
|
40
|
+
<a-button type="dashed" block @click="addParam" style="margin-top: 16px">
|
41
|
+
+ 添加参数
|
42
|
+
</a-button>
|
43
|
+
</a-tab-pane>
|
44
|
+
</a-tabs>
|
45
|
+
</a-form>
|
46
|
+
|
47
|
+
<template #footer>
|
48
|
+
<a-button type="primary" @click="closeDialog">确 定</a-button>
|
49
|
+
</template>
|
50
|
+
</a-modal>
|
51
|
+
</div>
|
52
|
+
</template>
|
53
|
+
|
54
|
+
<script setup lang="ts">
|
55
|
+
import { ref, onMounted } from 'vue'
|
56
|
+
import { FormInstance } from 'ant-design-vue'
|
57
|
+
|
58
|
+
defineOptions({
|
59
|
+
name: 'ListenerParamDialog'
|
60
|
+
})
|
61
|
+
|
62
|
+
interface Props {
|
63
|
+
value: any[]
|
64
|
+
}
|
65
|
+
|
66
|
+
const props = defineProps<Props>()
|
67
|
+
const emit = defineEmits<{
|
68
|
+
close: [value: any[]]
|
69
|
+
}>()
|
70
|
+
|
71
|
+
const formRef = ref<FormInstance>()
|
72
|
+
const dialogVisible = ref(true)
|
73
|
+
const formData = ref({
|
74
|
+
paramList: [] as any[]
|
75
|
+
})
|
76
|
+
|
77
|
+
const typeOptions = [
|
78
|
+
{ label: '字符串', value: 'stringValue' },
|
79
|
+
{ label: '表达式', value: 'expression' }
|
80
|
+
]
|
81
|
+
|
82
|
+
const columns = [
|
83
|
+
{
|
84
|
+
title: '类型',
|
85
|
+
dataIndex: 'type',
|
86
|
+
key: 'type',
|
87
|
+
width: 180
|
88
|
+
},
|
89
|
+
{
|
90
|
+
title: '名称',
|
91
|
+
dataIndex: 'name',
|
92
|
+
key: 'name',
|
93
|
+
width: 180
|
94
|
+
},
|
95
|
+
{
|
96
|
+
title: '值',
|
97
|
+
dataIndex: 'value',
|
98
|
+
key: 'value'
|
99
|
+
},
|
100
|
+
{
|
101
|
+
title: '操作',
|
102
|
+
key: 'action',
|
103
|
+
width: 80
|
104
|
+
}
|
105
|
+
]
|
106
|
+
|
107
|
+
const addParam = () => {
|
108
|
+
formData.value.paramList.push({
|
109
|
+
type: 'stringValue',
|
110
|
+
name: '',
|
111
|
+
value: ''
|
112
|
+
})
|
113
|
+
}
|
114
|
+
|
115
|
+
const removeParam = (index: number) => {
|
116
|
+
formData.value.paramList.splice(index, 1)
|
117
|
+
}
|
118
|
+
|
119
|
+
const closeDialog = () => {
|
120
|
+
dialogVisible.value = false
|
121
|
+
emit('close', formData.value.paramList)
|
122
|
+
}
|
123
|
+
|
124
|
+
const handleClose = () => {
|
125
|
+
emit('close', formData.value.paramList)
|
126
|
+
}
|
127
|
+
|
128
|
+
onMounted(() => {
|
129
|
+
formData.value.paramList = [...props.value]
|
130
|
+
})
|
131
|
+
</script>
|
132
|
+
|
133
|
+
<style scoped>
|
134
|
+
.flow-containers .ant-badge {
|
135
|
+
margin-right: 8px;
|
136
|
+
}
|
137
|
+
</style>
|
@@ -0,0 +1,177 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<a-modal
|
4
|
+
v-model:open="dialogVisible"
|
5
|
+
title="多实例配置"
|
6
|
+
width="500px"
|
7
|
+
:mask-closable="false"
|
8
|
+
:keyboard="false"
|
9
|
+
:closable="false"
|
10
|
+
class="muti-instance"
|
11
|
+
@cancel="$emit('close')"
|
12
|
+
>
|
13
|
+
<a-alert
|
14
|
+
type="info"
|
15
|
+
:closable="false"
|
16
|
+
show-icon
|
17
|
+
style="margin-bottom: 20px"
|
18
|
+
>
|
19
|
+
<template #message>
|
20
|
+
按照BPMN2.0规范的要求,用于为每个实例创建执行的父执行,会提供下列变量:<br>
|
21
|
+
nrOfInstances:实例总数。<br>
|
22
|
+
nrOfActiveInstances:当前活动的(即未完成的),实例数量。对于顺序多实例,这个值总为1。<br>
|
23
|
+
nrOfCompletedInstances:已完成的实例数量。<br>
|
24
|
+
loopCounter:给定实例在for-each循环中的index。<br>
|
25
|
+
</template>
|
26
|
+
</a-alert>
|
27
|
+
|
28
|
+
<a-form ref="formRef" :model="formData" layout="vertical">
|
29
|
+
<a-form-item label="多实例类型" name="multiInstanceType">
|
30
|
+
<a-select v-model:value="formData.multiInstanceType" :options="multiInstanceTypeOptions" />
|
31
|
+
</a-form-item>
|
32
|
+
|
33
|
+
<a-form-item label="基数" name="cardinality">
|
34
|
+
<a-input v-model:value="formData.cardinality" placeholder="请输入基数" />
|
35
|
+
</a-form-item>
|
36
|
+
|
37
|
+
<a-form-item label="集合" name="collection">
|
38
|
+
<a-input v-model:value="formData.collection" placeholder="请输入集合" />
|
39
|
+
</a-form-item>
|
40
|
+
|
41
|
+
<a-form-item label="元素变量" name="elementVariable">
|
42
|
+
<a-input v-model:value="formData.elementVariable" placeholder="请输入元素变量" />
|
43
|
+
</a-form-item>
|
44
|
+
|
45
|
+
<a-form-item label="完成条件" name="completionCondition">
|
46
|
+
<a-input v-model:value="formData.completionCondition" placeholder="请输入完成条件" />
|
47
|
+
</a-form-item>
|
48
|
+
|
49
|
+
<a-form-item label="顺序" name="sequential">
|
50
|
+
<a-switch v-model:checked="formData.sequential" checked-children="是" un-checked-children="否" />
|
51
|
+
</a-form-item>
|
52
|
+
</a-form>
|
53
|
+
|
54
|
+
<template #footer>
|
55
|
+
<a-button @click="cancel">取 消</a-button>
|
56
|
+
<a-button type="primary" @click="save">确 定</a-button>
|
57
|
+
</template>
|
58
|
+
</a-modal>
|
59
|
+
</div>
|
60
|
+
</template>
|
61
|
+
|
62
|
+
<script setup lang="ts">
|
63
|
+
import { ref, onMounted, nextTick, watch } from 'vue'
|
64
|
+
import { FormInstance } from 'ant-design-vue'
|
65
|
+
import { formatJsonKeyValue } from '../../../common/parseElement'
|
66
|
+
import Modeler from 'bpmn-js/lib/Modeler'
|
67
|
+
|
68
|
+
defineOptions({
|
69
|
+
name: 'MultiInstanceDialog'
|
70
|
+
})
|
71
|
+
|
72
|
+
interface Props {
|
73
|
+
element: any
|
74
|
+
modeler: Modeler
|
75
|
+
}
|
76
|
+
|
77
|
+
const props = defineProps<Props>()
|
78
|
+
const emit = defineEmits<{
|
79
|
+
close: []
|
80
|
+
}>()
|
81
|
+
|
82
|
+
const formRef = ref<FormInstance>()
|
83
|
+
const dialogVisible = ref(true)
|
84
|
+
const formData = ref<Record<string, any>>({})
|
85
|
+
|
86
|
+
const multiInstanceTypeOptions = [
|
87
|
+
{ label: '并行', value: 'parallel' },
|
88
|
+
{ label: '顺序', value: 'sequential' }
|
89
|
+
]
|
90
|
+
|
91
|
+
// 监听多实例类型变化
|
92
|
+
watch(() => formData.value.multiInstanceType, (newType) => {
|
93
|
+
formData.value.sequential = newType === 'sequential'
|
94
|
+
})
|
95
|
+
const updateProperties = (properties: Record<string, any>) => {
|
96
|
+
nextTick(() => {
|
97
|
+
try {
|
98
|
+
const modeling = props.modeler.get('modeling')
|
99
|
+
modeling.updateProperties(props.element, properties)
|
100
|
+
} catch (error) {
|
101
|
+
console.warn('Update properties error:', error)
|
102
|
+
}
|
103
|
+
})
|
104
|
+
}
|
105
|
+
|
106
|
+
const updateElement = () => {
|
107
|
+
if (formData.value.sequential !== null && formData.value.sequential !== undefined) {
|
108
|
+
let loopCharacteristics = props.element.businessObject.get('loopCharacteristics')
|
109
|
+
if (!loopCharacteristics) {
|
110
|
+
loopCharacteristics = props.modeler.get('moddle').create('bpmn:MultiInstanceLoopCharacteristics')
|
111
|
+
}
|
112
|
+
loopCharacteristics['isSequential'] = formData.value.sequential
|
113
|
+
|
114
|
+
// 处理基数
|
115
|
+
if (formData.value.cardinality) {
|
116
|
+
const cardinality = props.modeler.get('moddle').create('bpmn:Expression', { body: formData.value.cardinality })
|
117
|
+
loopCharacteristics['cardinality'] = cardinality
|
118
|
+
}
|
119
|
+
|
120
|
+
// 处理集合
|
121
|
+
if (formData.value.collection) {
|
122
|
+
const collection = props.modeler.get('moddle').create('bpmn:Expression', { body: formData.value.collection })
|
123
|
+
loopCharacteristics['collection'] = collection
|
124
|
+
}
|
125
|
+
|
126
|
+
loopCharacteristics['elementVariable'] = formData.value.elementVariable
|
127
|
+
|
128
|
+
if (formData.value.completionCondition) {
|
129
|
+
const completionCondition = props.modeler.get('moddle').create('bpmn:Expression', { body: formData.value.completionCondition })
|
130
|
+
loopCharacteristics['completionCondition'] = completionCondition
|
131
|
+
}
|
132
|
+
updateProperties({ loopCharacteristics: loopCharacteristics })
|
133
|
+
} else {
|
134
|
+
delete props.element.businessObject.loopCharacteristics
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
const save = () => {
|
139
|
+
updateElement()
|
140
|
+
dialogVisible.value = false
|
141
|
+
emit('close')
|
142
|
+
}
|
143
|
+
|
144
|
+
const cancel = () => {
|
145
|
+
dialogVisible.value = false
|
146
|
+
emit('close')
|
147
|
+
}
|
148
|
+
|
149
|
+
onMounted(() => {
|
150
|
+
const loopCharacteristics = props.element.businessObject.loopCharacteristics
|
151
|
+
if (loopCharacteristics) {
|
152
|
+
formData.value = {
|
153
|
+
multiInstanceType: loopCharacteristics.isSequential ? 'sequential' : 'parallel',
|
154
|
+
cardinality: loopCharacteristics.cardinality?.body || '',
|
155
|
+
collection: loopCharacteristics.collection?.body || '',
|
156
|
+
elementVariable: loopCharacteristics.elementVariable || '',
|
157
|
+
completionCondition: loopCharacteristics.completionCondition?.body || '',
|
158
|
+
sequential: loopCharacteristics.isSequential || false
|
159
|
+
}
|
160
|
+
} else {
|
161
|
+
formData.value = {
|
162
|
+
multiInstanceType: 'parallel',
|
163
|
+
cardinality: '',
|
164
|
+
collection: '',
|
165
|
+
elementVariable: '',
|
166
|
+
completionCondition: '',
|
167
|
+
sequential: false
|
168
|
+
}
|
169
|
+
}
|
170
|
+
})
|
171
|
+
</script>
|
172
|
+
|
173
|
+
<style scoped>
|
174
|
+
.muti-instance .ant-form-item {
|
175
|
+
margin-bottom: 22px;
|
176
|
+
}
|
177
|
+
</style>
|
@@ -0,0 +1,178 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<a-modal
|
4
|
+
v-model:open="dialogVisible"
|
5
|
+
title="信号定义"
|
6
|
+
width="700px"
|
7
|
+
:mask-closable="false"
|
8
|
+
:keyboard="false"
|
9
|
+
:closable="false"
|
10
|
+
@cancel="$emit('close')"
|
11
|
+
>
|
12
|
+
<a-form ref="formRef" :model="formData" layout="vertical">
|
13
|
+
<a-tabs>
|
14
|
+
<a-tab-pane key="signal" tab="信号定义">
|
15
|
+
<a-table
|
16
|
+
:columns="columns"
|
17
|
+
:data-source="formData.signal"
|
18
|
+
:pagination="false"
|
19
|
+
size="small"
|
20
|
+
>
|
21
|
+
<template #bodyCell="{ column, record, index }">
|
22
|
+
<template v-if="column.key === 'scope'">
|
23
|
+
<a-select v-model:value="record.scope" size="small" style="width: 100%" placeholder="请选择">
|
24
|
+
<a-select-option value="global">全局</a-select-option>
|
25
|
+
<a-select-option value="processInstance">流程实例</a-select-option>
|
26
|
+
</a-select>
|
27
|
+
</template>
|
28
|
+
<template v-if="column.key === 'id'">
|
29
|
+
<a-input v-model:value="record.id" size="small" placeholder="请输入信号ID" />
|
30
|
+
</template>
|
31
|
+
<template v-if="column.key === 'name'">
|
32
|
+
<a-input v-model:value="record.name" size="small" placeholder="请输入信号名称" />
|
33
|
+
</template>
|
34
|
+
<template v-if="column.key === 'action'">
|
35
|
+
<a-button type="link" danger size="small" @click="removeSignal(index)">删除</a-button>
|
36
|
+
</template>
|
37
|
+
</template>
|
38
|
+
</a-table>
|
39
|
+
<div style="margin-top: 16px;">
|
40
|
+
<a-button type="primary" size="small" @click="addSignal">
|
41
|
+
<template #icon><PlusOutlined /></template>
|
42
|
+
新增
|
43
|
+
</a-button>
|
44
|
+
</div>
|
45
|
+
</a-tab-pane>
|
46
|
+
</a-tabs>
|
47
|
+
</a-form>
|
48
|
+
|
49
|
+
<template #footer>
|
50
|
+
<a-button type="primary" @click="closeDialog">确 定</a-button>
|
51
|
+
</template>
|
52
|
+
</a-modal>
|
53
|
+
</div>
|
54
|
+
</template>
|
55
|
+
|
56
|
+
<script setup lang="ts">
|
57
|
+
import { ref, onMounted, nextTick } from 'vue'
|
58
|
+
import { FormInstance } from 'ant-design-vue'
|
59
|
+
import { PlusOutlined } from '@ant-design/icons-vue'
|
60
|
+
import Modeler from 'bpmn-js/lib/Modeler'
|
61
|
+
|
62
|
+
defineOptions({
|
63
|
+
name: 'SignalDialog'
|
64
|
+
})
|
65
|
+
|
66
|
+
interface Props {
|
67
|
+
element: any
|
68
|
+
modeler: Modeler
|
69
|
+
}
|
70
|
+
|
71
|
+
const props = defineProps<Props>()
|
72
|
+
const emit = defineEmits<{
|
73
|
+
close: []
|
74
|
+
}>()
|
75
|
+
|
76
|
+
const formRef = ref<FormInstance>()
|
77
|
+
const dialogVisible = ref(true)
|
78
|
+
const formData = ref({
|
79
|
+
signal: [] as any[]
|
80
|
+
})
|
81
|
+
|
82
|
+
const columns = [
|
83
|
+
{
|
84
|
+
title: 'scope',
|
85
|
+
dataIndex: 'scope',
|
86
|
+
key: 'scope',
|
87
|
+
width: 120
|
88
|
+
},
|
89
|
+
{
|
90
|
+
title: 'id',
|
91
|
+
dataIndex: 'id',
|
92
|
+
key: 'id',
|
93
|
+
width: 150
|
94
|
+
},
|
95
|
+
{
|
96
|
+
title: '名称',
|
97
|
+
dataIndex: 'name',
|
98
|
+
key: 'name',
|
99
|
+
width: 150
|
100
|
+
},
|
101
|
+
{
|
102
|
+
title: '操作',
|
103
|
+
key: 'action',
|
104
|
+
width: 80
|
105
|
+
}
|
106
|
+
]
|
107
|
+
const updateProperties = (properties: Record<string, any>) => {
|
108
|
+
nextTick(() => {
|
109
|
+
try {
|
110
|
+
const modeling = props.modeler.get('modeling')
|
111
|
+
modeling.updateProperties(props.element, properties)
|
112
|
+
} catch (error) {
|
113
|
+
console.warn('Update properties error:', error)
|
114
|
+
}
|
115
|
+
})
|
116
|
+
}
|
117
|
+
|
118
|
+
const addSignal = () => {
|
119
|
+
formData.value.signal.push({
|
120
|
+
name: '',
|
121
|
+
id: '',
|
122
|
+
scope: 'global'
|
123
|
+
})
|
124
|
+
}
|
125
|
+
|
126
|
+
const removeSignal = (index: number) => {
|
127
|
+
formData.value.signal.splice(index, 1)
|
128
|
+
}
|
129
|
+
|
130
|
+
const updateElement = () => {
|
131
|
+
if (formData.value.signal?.length) {
|
132
|
+
let extensionElements = props.element.businessObject.get('extensionElements')
|
133
|
+
if (!extensionElements) {
|
134
|
+
extensionElements = props.modeler.get('moddle').create('bpmn:ExtensionElements')
|
135
|
+
}
|
136
|
+
// 清除旧值
|
137
|
+
extensionElements.values = extensionElements.values?.filter((item: any) => item.$type !== 'flowable:Signal') ?? []
|
138
|
+
formData.value.signal.forEach((item: any) => {
|
139
|
+
const signal = props.modeler.get('moddle').create('flowable:Signal')
|
140
|
+
signal['id'] = item.id
|
141
|
+
signal['name'] = item.name
|
142
|
+
signal['scope'] = item.scope
|
143
|
+
extensionElements.get('values').push(signal)
|
144
|
+
})
|
145
|
+
updateProperties({ extensionElements: extensionElements })
|
146
|
+
} else {
|
147
|
+
const extensionElements = props.element.businessObject[`extensionElements`]
|
148
|
+
if (extensionElements) {
|
149
|
+
extensionElements.values = extensionElements.values?.filter((item: any) => item.$type !== 'flowable:Signal') ?? []
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
const closeDialog = () => {
|
155
|
+
updateElement()
|
156
|
+
dialogVisible.value = false
|
157
|
+
emit('close')
|
158
|
+
}
|
159
|
+
|
160
|
+
onMounted(() => {
|
161
|
+
// 初始化信号数据
|
162
|
+
if (props.element?.businessObject?.extensionElements?.values) {
|
163
|
+
formData.value.signal = props.element.businessObject.extensionElements.values
|
164
|
+
.filter((item: any) => item.$type === 'flowable:Signal')
|
165
|
+
.map((item: any) => ({
|
166
|
+
id: item.id,
|
167
|
+
name: item.name,
|
168
|
+
scope: item.scope || 'global'
|
169
|
+
}))
|
170
|
+
}
|
171
|
+
})
|
172
|
+
</script>
|
173
|
+
|
174
|
+
<style scoped>
|
175
|
+
.flow-containers .ant-badge {
|
176
|
+
margin-right: 8px;
|
177
|
+
}
|
178
|
+
</style>
|