Skip to content

Commit 5f2a220

Browse files
YunaiVgitee-org
authored andcommitted
!718 feat: 子流程-多实例
Merge pull request !718 from Lesan/feature/bpm-子流程
2 parents de35fd0 + bad11ff commit 5f2a220

File tree

3 files changed

+219
-27
lines changed

3 files changed

+219
-27
lines changed

src/components/SimpleProcessDesignerV2/src/NodeHandler.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ const addNode = (type: number) => {
306306
},
307307
timeoutSetting: {
308308
enable: false
309+
},
310+
multiInstanceSetting: {
311+
enable: false
309312
}
310313
}
311314
}

src/components/SimpleProcessDesignerV2/src/consts.ts

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -821,20 +821,78 @@ export type ChildProcessSetting = {
821821
skipStartUserNode: boolean,
822822
startUserSetting: StartUserSetting,
823823
timeoutSetting: TimeoutSetting,
824+
multiInstanceSetting: MultiInstanceSetting,
824825
}
825826
export type IOParameter = {
826827
source: string
827-
sourceExpression: string
828828
target: string
829-
targetExpression: string
830829
}
831830
export type StartUserSetting = {
832-
type: number
831+
type: ChildProcessStartUserTypeEnum
833832
formField?: string
834-
emptyType?: number
833+
emptyType?: ChildProcessStartUserEmptyTypeEnum
835834
}
836835
export type TimeoutSetting = {
837836
enable: boolean,
838837
type?: DelayTypeEnum,
839838
timeExpression?: string,
840839
}
840+
export type MultiInstanceSetting = {
841+
enable: boolean,
842+
sequential?: boolean,
843+
completeRatio?: number,
844+
sourceType?: ChildProcessMultiInstanceSourceTypeEnum,
845+
source?: string,
846+
}
847+
export enum ChildProcessStartUserTypeEnum {
848+
/**
849+
* 同主流程发起人
850+
*/
851+
MAIN_PROCESS_START_USER = 1,
852+
/**
853+
* 表单
854+
*/
855+
FROM_FORM = 2,
856+
}
857+
export const CHILD_PROCESS_START_USER_TYPE = [
858+
{ label: '同主流程发起人', value: ChildProcessStartUserTypeEnum.MAIN_PROCESS_START_USER },
859+
{ label: '表单', value: ChildProcessStartUserTypeEnum.FROM_FORM }
860+
]
861+
export enum ChildProcessStartUserEmptyTypeEnum {
862+
/**
863+
* 同主流程发起人
864+
*/
865+
MAIN_PROCESS_START_USER = 1,
866+
/**
867+
* 子流程管理员
868+
*/
869+
CHILD_PROCESS_ADMIN = 2,
870+
/**
871+
* 主流程管理员
872+
*/
873+
MAIN_PROCESS_ADMIN = 3,
874+
}
875+
export const CHILD_PROCESS_START_USER_EMPTY_TYPE = [
876+
{ label: '同主流程发起人', value: ChildProcessStartUserEmptyTypeEnum.MAIN_PROCESS_START_USER },
877+
{ label: '子流程管理员', value: ChildProcessStartUserEmptyTypeEnum.CHILD_PROCESS_ADMIN },
878+
{ label: '主流程管理员', value: ChildProcessStartUserEmptyTypeEnum.MAIN_PROCESS_ADMIN }
879+
]
880+
export enum ChildProcessMultiInstanceSourceTypeEnum {
881+
/**
882+
* 固定数量
883+
*/
884+
FIXED_QUANTITY = 1,
885+
/**
886+
* 数字表单
887+
*/
888+
DIGITAL_FORM = 2,
889+
/**
890+
* 多项表单
891+
*/
892+
MULTI_FORM = 3,
893+
}
894+
export const CHILD_PROCESS_MULTI_INSTANCE_SOURCE_TYPE = [
895+
{ label: '固定数量', value: ChildProcessMultiInstanceSourceTypeEnum.FIXED_QUANTITY },
896+
{ label: '数字表单', value: ChildProcessMultiInstanceSourceTypeEnum.DIGITAL_FORM },
897+
{ label: '多项表单', value: ChildProcessMultiInstanceSourceTypeEnum.MULTI_FORM }
898+
]

src/components/SimpleProcessDesignerV2/src/nodes-config/ChildProcessNodeConfig.vue

Lines changed: 154 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,14 @@
9595
<Icon
9696
icon="ep:delete"
9797
:size="18"
98-
@click="deleteVariable(configForm.inVariables, index)"
98+
@click="deleteVariable(index, configForm.inVariables)"
9999
/>
100100
</div>
101101
</div>
102102
<el-button type="primary" text @click="addVariable(configForm.inVariables)">
103103
<Icon icon="ep:plus" class="mr-5px" />添加一行
104104
</el-button>
105105
</el-form-item>
106-
<!-- TODO @lesan:async、source、target 几个字段,会告警 -->
107106
<el-form-item
108107
v-if="configForm.async === false"
109108
label="子→主变量传递"
@@ -152,19 +151,23 @@
152151
<Icon
153152
icon="ep:delete"
154153
:size="18"
155-
@click="deleteVariable(configForm.outVariables, index)"
154+
@click="deleteVariable(index, configForm.outVariables)"
156155
/>
157156
</div>
158157
</div>
159158
<el-button type="primary" text @click="addVariable(configForm.outVariables)">
160159
<Icon icon="ep:plus" class="mr-5px" />添加一行
161160
</el-button>
162161
</el-form-item>
163-
<!-- TODO @lesan:startUserType、startUserEmptyType 要不走写下枚举类? -->
164162
<el-form-item label="子流程发起人" prop="startUserType">
165163
<el-radio-group v-model="configForm.startUserType">
166-
<el-radio :value="1">同主流程发起人</el-radio>
167-
<el-radio :value="2">表单</el-radio>
164+
<el-radio
165+
v-for="item in CHILD_PROCESS_START_USER_TYPE"
166+
:key="item.value"
167+
:value="item.value"
168+
>
169+
{{ item.label }}</el-radio
170+
>
168171
</el-radio-group>
169172
</el-form-item>
170173
<el-form-item
@@ -173,9 +176,13 @@
173176
prop="startUserType"
174177
>
175178
<el-radio-group v-model="configForm.startUserEmptyType">
176-
<el-radio :value="1">同主流程发起人</el-radio>
177-
<el-radio :value="2">子流程管理员</el-radio>
178-
<el-radio :value="3">主流程管理员</el-radio>
179+
<el-radio
180+
v-for="item in CHILD_PROCESS_START_USER_EMPTY_TYPE"
181+
:key="item.value"
182+
:value="item.value"
183+
>
184+
{{ item.label }}</el-radio
185+
>
179186
</el-radio-group>
180187
</el-form-item>
181188
<el-form-item
@@ -246,6 +253,68 @@
246253
<el-text>后进入下一节点</el-text>
247254
</el-form-item>
248255
</div>
256+
257+
<el-divider content-position="left">多实例设置</el-divider>
258+
<el-form-item label="启用开关" prop="multiInstanceEnable">
259+
<el-switch
260+
v-model="configForm.multiInstanceEnable"
261+
active-text="开启"
262+
inactive-text="关闭"
263+
/>
264+
</el-form-item>
265+
<div v-if="configForm.multiInstanceEnable">
266+
<el-form-item prop="sequential">
267+
<el-switch
268+
v-model="configForm.sequential"
269+
active-text="串行"
270+
inactive-text="并行"
271+
/>
272+
</el-form-item>
273+
<el-form-item prop="completeRatio">
274+
<el-text>完成比例(%)</el-text>
275+
<el-input-number
276+
class="ml-10px"
277+
v-model="configForm.completeRatio"
278+
:min="10"
279+
:max="100"
280+
:step="10"
281+
/>
282+
</el-form-item>
283+
<el-form-item prop="multiInstanceSourceType">
284+
<el-text>多实例来源</el-text>
285+
<el-select class="ml-10px w-200px!" v-model="configForm.multiInstanceSourceType" @change="handleMultiInstanceSourceTypeChange">
286+
<el-option
287+
v-for="item in CHILD_PROCESS_MULTI_INSTANCE_SOURCE_TYPE"
288+
:key="item.value"
289+
:label="item.label"
290+
:value="item.value"
291+
/>
292+
</el-select>
293+
</el-form-item>
294+
<el-form-item v-if="configForm.multiInstanceSourceType === 1">
295+
<el-input-number v-model="configForm.multiInstanceSource" :min="1" />
296+
</el-form-item>
297+
<el-form-item v-if="configForm.multiInstanceSourceType === 2">
298+
<el-select class="w-200px!" v-model="configForm.multiInstanceSource">
299+
<el-option
300+
v-for="(field, fIdx) in digitalFormFieldOptions"
301+
:key="fIdx"
302+
:label="field.title"
303+
:value="field.field"
304+
/>
305+
</el-select>
306+
</el-form-item>
307+
<el-form-item v-if="configForm.multiInstanceSourceType === 3">
308+
<el-select class="w-200px!" v-model="configForm.multiInstanceSource">
309+
<el-option
310+
v-for="(field, fIdx) in multiFormFieldOptions"
311+
:key="fIdx"
312+
:label="field.title"
313+
:value="field.field"
314+
/>
315+
</el-select>
316+
</el-form-item>
317+
</div>
249318
</el-form>
250319
</div>
251320
</el-tab-pane>
@@ -268,7 +337,14 @@ import {
268337
TIME_UNIT_TYPES,
269338
TimeUnitType,
270339
DelayTypeEnum,
271-
DELAY_TYPE
340+
DELAY_TYPE,
341+
IOParameter,
342+
ChildProcessStartUserTypeEnum,
343+
CHILD_PROCESS_START_USER_TYPE,
344+
ChildProcessStartUserEmptyTypeEnum,
345+
CHILD_PROCESS_START_USER_EMPTY_TYPE,
346+
CHILD_PROCESS_MULTI_INSTANCE_SOURCE_TYPE,
347+
ChildProcessMultiInstanceSourceTypeEnum
272348
} from '../consts'
273349
import { useWatchNode, useDrawer, useNodeName, useFormFieldsAndStartUser } from '../node'
274350
import { parseFormFields } from '@/components/FormCreate/src/utils'
@@ -307,25 +383,57 @@ const formRules = reactive({
307383
timeoutEnable: [{ required: true, message: '超时设置是否开启不能为空', trigger: 'change' }],
308384
timeoutType: [{ required: true, message: '超时设置时间不能为空', trigger: 'change' }],
309385
timeDuration: [{ required: true, message: '超时设置时间不能为空', trigger: 'change' }],
310-
dateTime: [{ required: true, message: '超时设置时间不能为空', trigger: 'change' }]
386+
dateTime: [{ required: true, message: '超时设置时间不能为空', trigger: 'change' }],
387+
multiInstanceEnable: [{ required: true, message: '多实例设置不能为空', trigger: 'change' }]
311388
})
312-
const configForm = ref({
389+
type ChildProcessFormType = {
390+
async: boolean
391+
calledProcessDefinitionKey: string
392+
skipStartUserNode: boolean
393+
inVariables?: IOParameter[]
394+
outVariables?: IOParameter[]
395+
startUserType: ChildProcessStartUserTypeEnum
396+
startUserEmptyType: ChildProcessStartUserEmptyTypeEnum
397+
startUserFormField: string
398+
timeoutEnable: boolean
399+
timeoutType: DelayTypeEnum
400+
timeDuration: number
401+
timeUnit: TimeUnitType
402+
dateTime: string
403+
multiInstanceEnable: boolean
404+
sequential: boolean
405+
completeRatio: number
406+
multiInstanceSourceType: ChildProcessMultiInstanceSourceTypeEnum
407+
multiInstanceSource: string
408+
}
409+
const configForm = ref<ChildProcessFormType>({
313410
async: false,
314411
calledProcessDefinitionKey: '',
315412
skipStartUserNode: false,
316413
inVariables: [],
317414
outVariables: [],
318-
startUserType: 1,
319-
startUserEmptyType: 1,
415+
startUserType: ChildProcessStartUserTypeEnum.MAIN_PROCESS_START_USER,
416+
startUserEmptyType: ChildProcessStartUserEmptyTypeEnum.MAIN_PROCESS_START_USER,
320417
startUserFormField: '',
321418
timeoutEnable: false,
322419
timeoutType: DelayTypeEnum.FIXED_TIME_DURATION,
323420
timeDuration: 1,
324421
timeUnit: TimeUnitType.HOUR,
325-
dateTime: ''
422+
dateTime: '',
423+
multiInstanceEnable: false,
424+
sequential: false,
425+
completeRatio: 100,
426+
multiInstanceSourceType: ChildProcessMultiInstanceSourceTypeEnum.FIXED_QUANTITY,
427+
multiInstanceSource: ''
326428
})
327429
const childProcessOptions = ref()
328430
const formFieldOptions = useFormFieldsAndStartUser()
431+
const digitalFormFieldOptions = computed(() => {
432+
return formFieldOptions.filter((item) => item.type === 'inputNumber')
433+
})
434+
const multiFormFieldOptions = computed(() => {
435+
return formFieldOptions.filter((item) => item.type === 'select' || item.type === 'checkbox')
436+
})
329437
const childFormFieldOptions = ref()
330438
331439
// 保存配置
@@ -334,9 +442,8 @@ const saveConfig = async () => {
334442
if (!formRef) return false
335443
const valid = await formRef.value.validate()
336444
if (!valid) return false
337-
// TODO @lesan:这里的 option 黄色告警,也处理下哈
338445
const childInfo = childProcessOptions.value.find(
339-
(option) => option.key === configForm.value.calledProcessDefinitionKey
446+
(option: any) => option.key === configForm.value.calledProcessDefinitionKey
340447
)
341448
currentNode.value.name = nodeName.value!
342449
if (currentNode.value.childProcessSetting) {
@@ -371,14 +478,26 @@ const saveConfig = async () => {
371478
configForm.value.dateTime
372479
}
373480
}
481+
// 8. 多实例设置
482+
currentNode.value.childProcessSetting.multiInstanceSetting = {
483+
enable: configForm.value.multiInstanceEnable
484+
}
485+
if (configForm.value.multiInstanceEnable) {
486+
currentNode.value.childProcessSetting.multiInstanceSetting.sequential = configForm.value.sequential
487+
currentNode.value.childProcessSetting.multiInstanceSetting.completeRatio =
488+
configForm.value.completeRatio
489+
currentNode.value.childProcessSetting.multiInstanceSetting.sourceType =
490+
configForm.value.multiInstanceSourceType
491+
currentNode.value.childProcessSetting.multiInstanceSetting.source =
492+
configForm.value.multiInstanceSource
493+
}
374494
}
375495
376496
currentNode.value.showText = `调用子流程:${childInfo.name}`
377497
settingVisible.value = false
378498
return true
379499
}
380500
// 显示子流程节点配置, 由父组件传过来
381-
// TODO @lesan:inVariables、outVariables 红色告警
382501
const showChildProcessNodeConfig = (node: SimpleFlowNode) => {
383502
nodeName.value = node.name
384503
if (node.childProcessSetting) {
@@ -415,21 +534,30 @@ const showChildProcessNodeConfig = (node: SimpleFlowNode) => {
415534
configForm.value.dateTime = node.childProcessSetting.timeoutSetting.timeExpression ?? ''
416535
}
417536
}
537+
// 8. 多实例设置
538+
configForm.value.multiInstanceEnable =
539+
node.childProcessSetting.multiInstanceSetting.enable ?? false
540+
if (configForm.value.multiInstanceEnable) {
541+
configForm.value.sequential = node.childProcessSetting.multiInstanceSetting.sequential ?? false
542+
configForm.value.completeRatio = node.childProcessSetting.multiInstanceSetting.completeRatio ?? 100
543+
configForm.value.multiInstanceSourceType =
544+
node.childProcessSetting.multiInstanceSetting.sourceType ?? ChildProcessMultiInstanceSourceTypeEnum.FIXED_QUANTITY
545+
configForm.value.multiInstanceSource = node.childProcessSetting.multiInstanceSetting.source ?? ''
546+
}
418547
}
419548
loadFormInfo()
420549
}
421550
422551
defineExpose({ openDrawer, showChildProcessNodeConfig }) // 暴露方法给父组件
423552
424-
// TODO @lesan:这里的 arr 黄色告警,也处理下哈,可以用 cursor quick fix 哈
425-
const addVariable = (arr) => {
426-
arr.push({
553+
const addVariable = (arr?: IOParameter[]) => {
554+
arr?.push({
427555
source: '',
428556
target: ''
429557
})
430558
}
431-
const deleteVariable = (arr, index: number) => {
432-
arr.splice(index, 1)
559+
const deleteVariable = (index: number, arr?: IOParameter[]) => {
560+
arr?.splice(index, 1)
433561
}
434562
const handleCalledElementChange = () => {
435563
configForm.value.inVariables = []
@@ -461,6 +589,9 @@ const getIsoTimeDuration = () => {
461589
}
462590
return strTimeDuration
463591
}
592+
const handleMultiInstanceSourceTypeChange = () => {
593+
configForm.value.multiInstanceSource = ''
594+
}
464595
465596
onMounted(async () => {
466597
childProcessOptions.value = await getModelList(undefined)

0 commit comments

Comments
 (0)