Skip to content

Commit 97b1ac6

Browse files
committed
feat: bpm设计器适配simple设计器,超时审批
1 parent be33226 commit 97b1ac6

File tree

2 files changed

+271
-4
lines changed

2 files changed

+271
-4
lines changed

src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,34 @@
13291329
"isAttr": true
13301330
}
13311331
]
1332+
},
1333+
{
1334+
"name": "BoundaryEventType",
1335+
"superClass": ["Element"],
1336+
"meta": {
1337+
"allowedIn": ["bpmn:BoundaryEvent"]
1338+
},
1339+
"properties": [
1340+
{
1341+
"name": "value",
1342+
"type": "Integer",
1343+
"isBody": true
1344+
}
1345+
]
1346+
},
1347+
{
1348+
"name": "TimeoutHandlerType",
1349+
"superClass": ["Element"],
1350+
"meta": {
1351+
"allowedIn": ["bpmn:BoundaryEvent"]
1352+
},
1353+
"properties": [
1354+
{
1355+
"name": "value",
1356+
"type": "Integer",
1357+
"isBody": true
1358+
}
1359+
]
13321360
}
13331361
],
13341362
"emumerations": []
Lines changed: 243 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,252 @@
11
<template>
22
<div>
3-
定时边界事件(非中断)
3+
<el-divider content-position="left">审批人超时未处理时</el-divider>
4+
<el-form-item label="启用开关" prop="timeoutHandlerEnable">
5+
<el-switch
6+
v-model="timeoutHandlerEnable"
7+
active-text="开启"
8+
inactive-text="关闭"
9+
@change="timeoutHandlerChange"
10+
/>
11+
</el-form-item>
12+
<el-form-item label="执行动作" prop="timeoutHandlerType" v-if="timeoutHandlerEnable">
13+
<el-radio-group v-model="timeoutHandlerType.value" @change="onTimeoutHandlerTypeChanged">
14+
<el-radio-button
15+
v-for="item in TIMEOUT_HANDLER_TYPES"
16+
:key="item.value"
17+
:value="item.value"
18+
:label="item.label"
19+
/>
20+
</el-radio-group>
21+
</el-form-item>
22+
<el-form-item label="超时时间设置" v-if="timeoutHandlerEnable">
23+
<span class="mr-2">当超过</span>
24+
<el-form-item prop="timeDuration">
25+
<el-input-number
26+
class="mr-2"
27+
:style="{ width: '100px' }"
28+
v-model="timeDuration"
29+
:min="1"
30+
controls-position="right"
31+
@change="() => updateTimeModdle()"
32+
/>
33+
</el-form-item>
34+
<el-select
35+
v-model="timeUnit"
36+
class="mr-2"
37+
:style="{ width: '100px' }"
38+
@change="onTimeUnitChange"
39+
>
40+
<el-option
41+
v-for="item in TIME_UNIT_TYPES"
42+
:key="item.value"
43+
:label="item.label"
44+
:value="item.value"
45+
/>
46+
</el-select>
47+
未处理
48+
</el-form-item>
49+
<el-form-item
50+
label="最大提醒次数"
51+
prop="maxRemindCount"
52+
v-if="timeoutHandlerEnable && timeoutHandlerType.value === 1"
53+
>
54+
<el-input-number
55+
v-model="maxRemindCount"
56+
:min="1"
57+
:max="10"
58+
@change="() => updateTimeModdle()"
59+
/>
60+
</el-form-item>
461
</div>
562
</template>
663

764
<script lang="ts" setup>
8-
// TODO 未来继续完善
65+
import {
66+
TimeUnitType,
67+
TIME_UNIT_TYPES,
68+
TIMEOUT_HANDLER_TYPES,
69+
} from '@/components/SimpleProcessDesignerV2/src/consts'
70+
import { convertTimeUnit } from '@/components/SimpleProcessDesignerV2/src/utils'
71+
972
defineOptions({ name: 'ElementCustomConfig4BoundaryEventTimer' })
73+
const props = defineProps({
74+
id: String,
75+
type: String
76+
})
77+
const prefix = inject('prefix')
78+
79+
const bpmnElement = ref()
80+
const bpmnInstances = () => (window as any)?.bpmnInstances
81+
82+
const timeoutHandlerEnable = ref(false)
83+
const boundaryEventType = ref()
84+
const timeoutHandlerType = ref({
85+
value: undefined
86+
})
87+
const timeModdle = ref()
88+
const timeDuration = ref(6)
89+
const timeUnit = ref(TimeUnitType.HOUR)
90+
const maxRemindCount = ref(1)
91+
92+
const elExtensionElements = ref()
93+
const otherExtensions = ref()
94+
const configExtensions = ref([])
95+
const eventDefinition = ref()
96+
97+
const resetElement = () => {
98+
bpmnElement.value = bpmnInstances().bpmnElement
99+
eventDefinition.value = bpmnElement.value.businessObject.eventDefinitions[0]
100+
101+
// 获取元素扩展属性 或者 创建扩展属性
102+
elExtensionElements.value =
103+
bpmnElement.value.businessObject?.extensionElements ??
104+
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
105+
106+
// 是否开启自定义用户任务超时处理
107+
boundaryEventType.value = elExtensionElements.value.values?.filter(
108+
(ex) => ex.$type === `${prefix}:BoundaryEventType`
109+
)?.[0]
110+
if (boundaryEventType.value && boundaryEventType.value.value === 1) {
111+
timeoutHandlerEnable.value = true
112+
configExtensions.value.push(boundaryEventType.value)
113+
}
114+
115+
// 执行动作
116+
timeoutHandlerType.value = elExtensionElements.value.values?.filter(
117+
(ex) => ex.$type === `${prefix}:TimeoutHandlerType`
118+
)?.[0]
119+
if (timeoutHandlerType.value) {
120+
configExtensions.value.push(timeoutHandlerType.value)
121+
if (eventDefinition.value.timeCycle) {
122+
const timeStr = eventDefinition.value.timeCycle.body
123+
const maxRemindCountStr = timeStr.split('/')[0]
124+
const timeDurationStr = timeStr.split('/')[1]
125+
console.log(maxRemindCountStr)
126+
maxRemindCount.value = parseInt(maxRemindCountStr.slice(1))
127+
timeDuration.value = parseInt(timeDurationStr.slice(2, timeDurationStr.length - 1))
128+
timeUnit.value = convertTimeUnit(timeDurationStr.slice(timeDurationStr.length - 1))
129+
timeModdle.value = eventDefinition.value.timeCycle
130+
}
131+
if (eventDefinition.value.timeDuration) {
132+
const timeDurationStr = eventDefinition.value.timeDuration.body
133+
timeDuration.value = parseInt(timeDurationStr.slice(2, timeDurationStr.length - 1))
134+
timeUnit.value = convertTimeUnit(timeDurationStr.slice(timeDurationStr.length - 1))
135+
timeModdle.value = eventDefinition.value.timeDuration
136+
}
137+
}
138+
139+
// 保留剩余扩展元素,便于后面更新该元素对应属性
140+
otherExtensions.value =
141+
elExtensionElements.value.values?.filter(
142+
(ex) =>
143+
ex.$type !== `${prefix}:BoundaryEventType` && ex.$type !== `${prefix}:TimeoutHandlerType`
144+
) ?? []
145+
}
146+
147+
const timeoutHandlerChange = (val) => {
148+
timeoutHandlerEnable.value = val
149+
if (val) {
150+
// 启用自定义用户任务超时处理
151+
// 边界事件类型 --- 超时
152+
boundaryEventType.value = bpmnInstances().moddle.create(`${prefix}:BoundaryEventType`, {
153+
value: 1
154+
})
155+
configExtensions.value.push(boundaryEventType.value)
156+
// 超时处理类型
157+
timeoutHandlerType.value = bpmnInstances().moddle.create(`${prefix}:TimeoutHandlerType`, {
158+
value: 1
159+
})
160+
configExtensions.value.push(timeoutHandlerType.value)
161+
// 超时时间表达式
162+
timeDuration.value = 6
163+
timeUnit.value = 2
164+
maxRemindCount.value = 1
165+
timeModdle.value = bpmnInstances().moddle.create(`bpmn:Expression`, {
166+
body: 'PT6H'
167+
})
168+
eventDefinition.value.timeDuration = timeModdle.value
169+
} else {
170+
// 关闭自定义用户任务超时处理
171+
configExtensions.value = []
172+
delete eventDefinition.value.timeDuration
173+
delete eventDefinition.value.timeCycle
174+
}
175+
updateElementExtensions()
176+
}
177+
178+
const onTimeoutHandlerTypeChanged = () => {
179+
maxRemindCount.value = 1
180+
updateElementExtensions()
181+
updateTimeModdle()
182+
}
183+
184+
const onTimeUnitChange = () => {
185+
// 分钟,默认是 60 分钟
186+
if (timeUnit.value === TimeUnitType.MINUTE) {
187+
timeDuration.value = 60
188+
}
189+
// 小时,默认是 6 个小时
190+
if (timeUnit.value === TimeUnitType.HOUR) {
191+
timeDuration.value = 6
192+
}
193+
// 天, 默认 1天
194+
if (timeUnit.value === TimeUnitType.DAY) {
195+
timeDuration.value = 1
196+
}
197+
updateTimeModdle()
198+
}
199+
200+
const updateTimeModdle = () => {
201+
if (maxRemindCount.value > 1) {
202+
timeModdle.value.body = 'R' + maxRemindCount.value + '/' + isoTimeDuration()
203+
if (!eventDefinition.value.timeCycle) {
204+
delete eventDefinition.value.timeDuration
205+
eventDefinition.value.timeCycle = timeModdle.value
206+
}
207+
} else {
208+
timeModdle.value.body = isoTimeDuration()
209+
if (!eventDefinition.value.timeDuration) {
210+
delete eventDefinition.value.timeCycle
211+
eventDefinition.value.timeDuration = timeModdle.value
212+
}
213+
}
214+
}
215+
216+
const isoTimeDuration = () => {
217+
let strTimeDuration = 'PT'
218+
if (timeUnit.value === TimeUnitType.MINUTE) {
219+
strTimeDuration += timeDuration.value + 'M'
220+
}
221+
if (timeUnit.value === TimeUnitType.HOUR) {
222+
strTimeDuration += timeDuration.value + 'H'
223+
}
224+
if (timeUnit.value === TimeUnitType.DAY) {
225+
strTimeDuration += timeDuration.value + 'D'
226+
}
227+
return strTimeDuration
228+
}
229+
230+
const updateElementExtensions = () => {
231+
const extensions = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
232+
values: [...otherExtensions.value, ...configExtensions.value]
233+
})
234+
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
235+
extensionElements: extensions
236+
})
237+
}
238+
239+
watch(
240+
() => props.id,
241+
(val) => {
242+
val &&
243+
val.length &&
244+
nextTick(() => {
245+
resetElement()
246+
})
247+
},
248+
{ immediate: true }
249+
)
10250
</script>
11251

12-
<style lang="scss" scoped>
13-
</style>
252+
<style lang="scss" scoped></style>

0 commit comments

Comments
 (0)