Pre Merge pull request !119 from ZETA/pr-workflow

This commit is contained in:
ZETA 2024-06-02 11:52:44 +00:00 committed by Gitee
commit 8c163800ec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 394 additions and 315 deletions

View File

@ -1020,6 +1020,11 @@ export default {
'isAttr': true, 'isAttr': true,
'type': 'String' 'type': 'String'
}, },
{
'name': 'alias',
'isAttr': true,
'type': 'String'
},
{ {
'name': 'event', 'name': 'event',
'isAttr': true, 'isAttr': true,
@ -1058,6 +1063,11 @@ export default {
'isAttr': true, 'isAttr': true,
'type': 'String' 'type': 'String'
}, },
{
'name': 'alias',
'isAttr': true,
'type': 'String'
},
{ {
'name': 'event', 'name': 'event',
'isAttr': true, 'isAttr': true,
@ -1247,4 +1257,4 @@ export default {
} }
], ],
'emumerations': [] 'emumerations': []
}; }

View File

@ -1,29 +1,29 @@
import showConfig from '../assets/showConfig'; import showConfig from '../assets/showConfig'
import type { ModdleElement } from 'bpmn'; import type { ModdleElement } from 'bpmn'
import useModelerStore from '@/store/modules/modeler'; import useModelerStore from '@/store/modules/modeler'
import { MultiInstanceTypeEnum } from '@/enums/bpmn/IndexEnums'; import { MultiInstanceTypeEnum } from '@/enums/bpmn/IndexEnums'
interface Options { interface Options {
element: ModdleElement; element: ModdleElement
} }
export default (ops: Options) => { export default (ops: Options) => {
const { element } = ops; const { element } = ops
const { getModeling, getModdle } = useModelerStore(); const { getModeling, getModdle } = useModelerStore()
const modeling = getModeling(); const modeling = getModeling()
const moddle = getModdle(); const moddle = getModdle()
/** /**
* *
*/ */
const elementType = computed(() => { const elementType = computed(() => {
const bizObj = element.businessObject; const bizObj = element.businessObject
return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type; return bizObj.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj.$type
}); })
/** /**
* *
*/ */
const config = computed(() => showConfig[elementType.value] || {}); const config = computed(() => showConfig[elementType.value] || {})
/** /**
* *
@ -32,22 +32,22 @@ export default (ops: Options) => {
* @param parent * @param parent
*/ */
const createModdleElement = (elementType: string, properties: any, parent: ModdleElement) => { const createModdleElement = (elementType: string, properties: any, parent: ModdleElement) => {
const element = moddle.create(elementType, properties); const element = moddle.create(elementType, properties)
parent && (element.$parent = parent); parent && (element.$parent = parent)
return element; return element
}; }
/** /**
* *
*/ */
const getExtensionElements = (create = true) => { const getExtensionElements = (create = true) => {
let extensionElements = element.businessObject.get<ModdleElement>('extensionElements'); let extensionElements = element.businessObject.get<ModdleElement>('extensionElements')
if (!extensionElements && create) { if (!extensionElements && create) {
extensionElements = createModdleElement('bpmn:ExtensionElements', { values: [] }, element.businessObject); extensionElements = createModdleElement('bpmn:ExtensionElements', { values: [] }, element.businessObject)
modeling.updateModdleProperties(element, element.businessObject, { extensionElements }); modeling.updateModdleProperties(element, element.businessObject, { extensionElements })
} }
return extensionElements; return extensionElements
}; }
/** /**
* extensionElements下的properties * extensionElements下的properties
@ -55,25 +55,26 @@ export default (ops: Options) => {
*/ */
const getPropertiesElements = (extensionElements?: ModdleElement) => { const getPropertiesElements = (extensionElements?: ModdleElement) => {
if (!extensionElements) { if (!extensionElements) {
extensionElements = getExtensionElements(); extensionElements = getExtensionElements()
} }
let propertiesElements = extensionElements.values.find((item) => item.$type === 'flowable:properties'); let propertiesElements = extensionElements.values.find((item) => item.$type === 'flowable:properties')
if (!propertiesElements) { if (!propertiesElements) {
propertiesElements = createModdleElement('flowable:properties', { values: [] }, extensionElements); propertiesElements = createModdleElement('flowable:properties', { values: [] }, extensionElements)
modeling.updateModdleProperties(element, extensionElements, { modeling.updateModdleProperties(element, extensionElements, {
values: [...extensionElements.get<[]>('values'), propertiesElements] values: [...extensionElements.get<[]>('values'), propertiesElements]
}); })
} }
return propertiesElements; return propertiesElements
}; }
/** /**
* *
* @param properties * @param properties
*/ */
const updateProperties = (properties: any) => { const updateProperties = (properties: any) => {
modeling.updateProperties(element, properties); console.log(properties)
}; modeling.updateProperties(element, properties)
}
/** /**
* *
@ -81,8 +82,8 @@ export default (ops: Options) => {
* @param properties * @param properties
*/ */
const updateModdleProperties = (updateElement, properties: any) => { const updateModdleProperties = (updateElement, properties: any) => {
modeling.updateModdleProperties(element, updateElement, properties); modeling.updateModdleProperties(element, updateElement, properties)
}; }
/** /**
* Property属性 * Property属性
@ -90,41 +91,41 @@ export default (ops: Options) => {
* @param value * @param value
*/ */
const updateProperty = (name: string, value: string) => { const updateProperty = (name: string, value: string) => {
const propertiesElements = getPropertiesElements(); const propertiesElements = getPropertiesElements()
let propertyElements = propertiesElements.values.find((item) => item.name === name); let propertyElements = propertiesElements.values.find((item) => item.name === name)
if (!propertyElements) { if (!propertyElements) {
propertyElements = createModdleElement('flowable:property', { name: name, value: value }, propertiesElements); propertyElements = createModdleElement('flowable:property', { name: name, value: value }, propertiesElements)
modeling.updateModdleProperties(element, propertiesElements, { modeling.updateModdleProperties(element, propertiesElements, {
values: [...propertiesElements.get('values'), propertyElements] values: [...propertiesElements.get('values'), propertyElements]
}); })
} else { } else {
propertyElements.name = name; propertyElements.name = name
propertyElements.value = value; propertyElements.value = value
} }
return propertyElements; return propertyElements
}; }
const idChange = (newVal: string) => { const idChange = (newVal: string) => {
if (newVal) { if (newVal) {
updateProperties({ id: newVal }); updateProperties({ id: newVal })
} }
}; }
const nameChange = (newVal: string) => { const nameChange = (newVal: string) => {
if (newVal) { if (newVal) {
updateProperties({ name: newVal }); updateProperties({ name: newVal })
} }
}; }
const formKeyChange = (newVal: string) => { const formKeyChange = (newVal: string) => {
updateProperties({ formKey: newVal }); updateProperties({ formKey: newVal })
}; }
const constant = { const constant = {
MultiInstanceType: [ MultiInstanceType: [
{ id: '373d4b81-a0d1-4eb8-8685-0d2fb1b468e2', label: '无', value: MultiInstanceTypeEnum.NONE }, { id: '373d4b81-a0d1-4eb8-8685-0d2fb1b468e2', label: '无', value: MultiInstanceTypeEnum.NONE },
{ id: 'b5acea7c-b7e5-46b0-8778-390db091bdab', label: '串行', value: MultiInstanceTypeEnum.SERIAL }, { id: 'b5acea7c-b7e5-46b0-8778-390db091bdab', label: '串行', value: MultiInstanceTypeEnum.SERIAL },
{ id: 'b4f0c683-1ccc-43c4-8380-e1b998986caf', label: '并行', value: MultiInstanceTypeEnum.PARALLEL } { id: 'b4f0c683-1ccc-43c4-8380-e1b998986caf', label: '并行', value: MultiInstanceTypeEnum.PARALLEL }
] ]
}; }
return { return {
elementType, elementType,
@ -141,5 +142,5 @@ export default (ops: Options) => {
formKeyChange, formKeyChange,
getExtensionElements, getExtensionElements,
getPropertiesElements getPropertiesElements
}; }
}; }

View File

@ -42,7 +42,7 @@
:show-close="false" :show-close="false"
append-to-body append-to-body
> >
<el-form ref="formRef" :model="formData" :rules="tableRules" label-width="100px"> <el-form ref="formRef" :model="formData" :rules="tableRules" label-width="120px">
<el-form-item label="事件" prop="event"> <el-form-item label="事件" prop="event">
<el-select v-model="formData.event"> <el-select v-model="formData.event">
<el-option v-for="item in eventSelect" :key="item.id" :value="item.value" :label="item.label"></el-option> <el-option v-for="item in eventSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
@ -62,7 +62,7 @@
</el-tooltip> </el-tooltip>
</span> </span>
</template> </template>
<el-select v-model="formData.type"> <el-select v-model="formData.type" @change="handleChangeType">
<el-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></el-option> <el-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -70,7 +70,7 @@
:label="typeSelect.filter((e) => e.value === formData.type)[0] ? typeSelect.filter((e) => e.value === formData.type)[0]?.label : '表达式'" :label="typeSelect.filter((e) => e.value === formData.type)[0] ? typeSelect.filter((e) => e.value === formData.type)[0]?.label : '表达式'"
prop="className" prop="className"
> >
<el-input v-model="formData.className" type="text"></el-input> <el-input v-model="formData.className" type="text" :disabled="formData.alias? true : false"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-tabs type="border-card"> <el-tabs type="border-card">
@ -88,139 +88,164 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ListenerParam from './ListenerParam.vue'; import ListenerParam from './ListenerParam.vue'
import { VxeTableEvents, VxeTableInstance, VxeTablePropTypes } from 'vxe-table'; import { VxeTableEvents, VxeTableInstance, VxeTablePropTypes } from 'vxe-table'
import type { ExecutionListenerVO } from 'bpmnDesign'; import type { ExecutionListenerVO } from 'bpmnDesign'
import type { Moddle, Modeler, ModdleElement } from 'bpmn'; import type { Moddle, Modeler, ModdleElement } from 'bpmn'
import usePanel from '../../hooks/usePanel'; import usePanel from '../../hooks/usePanel'
import useDialog from '@/hooks/useDialog'; import useDialog from '@/hooks/useDialog'
import useModelerStore from '@/store/modules/modeler'; import useModelerStore from '@/store/modules/modeler'
const emit = defineEmits(['close']); const emit = defineEmits(['close'])
interface PropType { interface PropType {
element: ModdleElement; element: ModdleElement
} }
const props = withDefaults(defineProps<PropType>(), {}); const props = withDefaults(defineProps<PropType>(), {})
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance
const selectRow = ref<ExecutionListenerVO | null>(); const selectRow = ref<ExecutionListenerVO | null>()
const formDialog = useDialog({ const formDialog = useDialog({
title: selectRow.value ? '编辑&保存' : '新增&保存' title: selectRow.value ? '编辑&保存' : '新增&保存'
}); })
const { showConfig, elementType, updateProperties } = usePanel({ const { showConfig, elementType, updateProperties } = usePanel({
element: toRaw(props.element) element: toRaw(props.element)
}); })
const { getModdle } = useModelerStore(); const { getModdle } = useModelerStore()
const moddle = getModdle(); const moddle = getModdle()
const listenerParamRef = ref<InstanceType<typeof ListenerParam>>(); const listenerParamRef = ref<InstanceType<typeof ListenerParam>>()
const tableRef = ref<VxeTableInstance<ExecutionListenerVO>>(); const tableRef = ref<VxeTableInstance<ExecutionListenerVO>>()
const formRef = ref<ElFormInstance>(); const formRef = ref<ElFormInstance>()
const initData: ExecutionListenerVO = { const initData: ExecutionListenerVO = {
event: '', event: '',
type: '', type: '',
className: '', className: '',
params: [] params: []
}; }
const formData = ref<ExecutionListenerVO>({ ...initData }); const formData = ref<ExecutionListenerVO>({ ...initData })
const tableData = ref<ExecutionListenerVO[]>([]); const tableData = ref<ExecutionListenerVO[]>([])
const tableRules = ref<ElFormRules>({ const tableRules = ref<ElFormRules>({
event: [{ required: true, message: '请选择', trigger: 'blur' }], event: [{ required: true, message: '请选择', trigger: 'blur' }],
type: [{ required: true, message: '请选择', trigger: 'blur' }], type: [{ required: true, message: '请选择', trigger: 'blur' }],
className: [{ required: true, message: '请输入', trigger: 'blur' }] className: [{ required: true, message: '请输入', trigger: 'blur' }]
}); })
const submitEvent = async () => { const submitEvent = async () => {
const error = await listenerParamRef.value.validate(); const error = await listenerParamRef.value.validate()
await formRef.value.validate((validate) => { await formRef.value.validate((validate) => {
if (validate && !error) { if (validate && !error) {
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
formData.value.params = listenerParamRef.value.getTableData(); formData.value.params = listenerParamRef.value.getTableData()
if (selectRow.value) { if (selectRow.value) {
Object.assign(selectRow.value, formData.value); Object.assign(selectRow.value, formData.value)
} else { } else {
$table.insertAt({ ...formData.value }, -1); $table.insertAt({ ...formData.value }, -1)
} }
updateElement(); updateElement()
formDialog.closeDialog(); formDialog.closeDialog()
} }
} }
}); })
}; }
const handleChangeType = (v) => {
if (v === 'serviceClass') {
formData.value.className = '${delegatedExecutionListener}'
formData.value.alias = v
formData.value.params = listenerParamRef.value.getTableData()
const index = formData.value.params.findIndex((item) => item.name === 'clazz')
console.log(index, formData.value.params)
if (index === -1) {
formData.value.params.unshift({
name: 'interfaceName',
type: 'stringValue',
value: ''
})
}
} else {
formData.value.alias = ''
}
}
const removeSelectRowEvent = async () => { const removeSelectRowEvent = async () => {
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
const selectCount = $table.getCheckboxRecords().length; const selectCount = $table.getCheckboxRecords().length
if (selectCount === 0) { if (selectCount === 0) {
proxy?.$modal.msgWarning('请选择行'); proxy?.$modal.msgWarning('请选择行')
} else { } else {
await $table.removeCheckboxRow(); await $table.removeCheckboxRow()
updateElement(); updateElement()
} }
} }
}; }
const insertEvent = async () => { const insertEvent = async () => {
Object.assign(formData.value, initData); formData.value.alias = ''
selectRow.value = null; Object.assign(formData.value, initData)
formDialog.openDialog(); selectRow.value = null
}; formDialog.openDialog()
}
const editEvent = (row: ExecutionListenerVO) => { const editEvent = (row: ExecutionListenerVO) => {
Object.assign(formData.value, row); Object.assign(formData.value, row)
selectRow.value = row; selectRow.value = row
formDialog.openDialog(); formDialog.openDialog()
}; }
const removeEvent = async (row: ExecutionListenerVO) => { const removeEvent = async (row: ExecutionListenerVO) => {
await proxy?.$modal.confirm('您确定要删除该数据?'); await proxy?.$modal.confirm('您确定要删除该数据?')
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
await $table.remove(row); await $table.remove(row)
updateElement(); updateElement()
} }
}; }
const updateElement = () => { const updateElement = () => {
const $table = tableRef.value; const $table = tableRef.value
const data = $table.getTableData().fullData; const data = $table.getTableData().fullData
if (data.length) { if (data.length) {
let extensionElements = props.element.businessObject.get('extensionElements'); let extensionElements = props.element.businessObject.get('extensionElements')
if (!extensionElements) { if (!extensionElements) {
extensionElements = moddle.create('bpmn:ExtensionElements'); extensionElements = moddle.create('bpmn:ExtensionElements')
} }
// //
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? []; extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? []
data.forEach((item) => { data.forEach((item) => {
const executionListener = moddle.create('flowable:ExecutionListener'); const executionListener = moddle.create('flowable:ExecutionListener')
executionListener['event'] = item.event; executionListener['event'] = item.event
executionListener[item.type] = item.className; if (item.alias) {
executionListener.delegateExpression = item.className
executionListener.alias = item.alias
} else {
executionListener[item.type] = item.className
}
if (item.params && item.params.length) { if (item.params && item.params.length) {
item.params.forEach((field) => { item.params.forEach((field) => {
const fieldElement = moddle.create('flowable:Field'); const fieldElement = moddle.create('flowable:Field')
fieldElement['name'] = field.name; fieldElement['name'] = field.name
fieldElement[field.type] = field.value; fieldElement[field.type] = field.value
executionListener.get('fields').push(fieldElement); executionListener.get('fields').push(fieldElement)
}); })
} }
extensionElements.get('values').push(executionListener); extensionElements.get('values').push(executionListener)
}); })
updateProperties({ extensionElements: extensionElements }); updateProperties({ extensionElements: extensionElements })
} else { } else {
const extensionElements = props.element.businessObject[`extensionElements`]; const extensionElements = props.element.businessObject[`extensionElements`]
if (extensionElements) { if (extensionElements) {
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? []; extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:ExecutionListener') ?? []
} }
} }
}; }
const cellDBLClickEvent: VxeTableEvents.CellDblclick<ExecutionListenerVO> = ({ row }) => { const cellDBLClickEvent: VxeTableEvents.CellDblclick<ExecutionListenerVO> = ({ row }) => {
editEvent(row); editEvent(row)
}; }
const menuConfig = reactive<VxeTablePropTypes.MenuConfig<ExecutionListenerVO>>({ const menuConfig = reactive<VxeTablePropTypes.MenuConfig<ExecutionListenerVO>>({
body: { body: {
@ -232,71 +257,73 @@ const menuConfig = reactive<VxeTablePropTypes.MenuConfig<ExecutionListenerVO>>({
] ]
}, },
visibleMethod({ options, column }) { visibleMethod({ options, column }) {
const isDisabled = !column; const isDisabled = !column
options.forEach((list) => { options.forEach((list) => {
list.forEach((item) => { list.forEach((item) => {
item.disabled = isDisabled; item.disabled = isDisabled
}); })
}); })
return true; return true
} }
}); })
const contextMenuClickEvent: VxeTableEvents.MenuClick<ExecutionListenerVO> = ({ menu, row, column }) => { const contextMenuClickEvent: VxeTableEvents.MenuClick<ExecutionListenerVO> = ({ menu, row, column }) => {
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
switch (menu.code) { switch (menu.code) {
case 'edit': case 'edit':
editEvent(row); editEvent(row)
break; break
case 'remove': case 'remove':
removeEvent(row); removeEvent(row)
break; break
} }
} }
}; }
const initTableData = () => { const initTableData = () => {
tableData.value = tableData.value =
props.element.businessObject.extensionElements?.values props.element.businessObject.extensionElements?.values
.filter((item) => item.$type === 'flowable:ExecutionListener') .filter((item) => item.$type === 'flowable:ExecutionListener')
.map((item) => { .map((item) => {
let type; let type
if ('class' in item) type = 'class'; if ('class' in item) type = 'class'
if ('expression' in item) type = 'expression'; if ('expression' in item) type = 'expression'
if ('delegateExpression' in item) type = 'delegateExpression'; if ('delegateExpression' in item) type = 'delegateExpression'
return { return {
event: item.event, event: item.event,
type: type, type: type,
className: item[type], className: item[type],
alias: item.alias || undefined,
params: params:
item.fields?.map((field) => { item.fields?.map((field) => {
let fieldType; let fieldType
if ('stringValue' in field) fieldType = 'stringValue'; if ('stringValue' in field) fieldType = 'stringValue'
if ('expression' in field) fieldType = 'expression'; if ('expression' in field) fieldType = 'expression'
return { return {
name: field.name, name: field.name,
type: fieldType, type: fieldType,
value: field[fieldType] value: field[fieldType]
}; }
}) ?? [] }) ?? []
}; }
}) ?? []; }) ?? []
}; }
onMounted(() => { onMounted(() => {
initTableData(); initTableData()
}); })
const typeSelect = [ const typeSelect = [
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '类', value: 'class' }, { id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '类', value: 'class' },
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' }, { id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' },
{ id: '4b8135ab-6bc3-4a0f-80be-22f58bc6c5fd', label: '委托表达式', value: 'delegateExpression' } { id: '4b8135ab-6bc3-4a0f-80be-22f58bc6c5fd', label: '委托表达式', value: 'delegateExpression' },
]; { id: 'ssjksjksjkslkw', label: '远程服务代理', value: 'serviceClass' }
]
const eventSelect = [ const eventSelect = [
{ id: 'e6e0a51a-2d5d-4dc4-b847-b5c14f43a6ab', label: '开始', value: 'start' }, { id: 'e6e0a51a-2d5d-4dc4-b847-b5c14f43a6ab', label: '开始', value: 'start' },
{ id: '6da97c1e-15fc-4445-8943-75d09f49778e', label: '结束', value: 'end' }, { id: '6da97c1e-15fc-4445-8943-75d09f49778e', label: '结束', value: 'end' },
{ id: '6a2cbcec-e026-4f11-bef7-fff0b5c871e2', label: '启用', value: 'take' } { id: '6a2cbcec-e026-4f11-bef7-fff0b5c871e2', label: '启用', value: 'take' }
]; ]
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -1,3 +1,11 @@
<!--
* @Description:
* @Author: Panda
* @Date: 2024-05-28 15:05:21
* @LastEditors: Panda
* @LastEditTime: 2024-05-30 18:13:12
* @FilePath: \platform-frontend\src\bpmn\panel\property\TaskListener.vue
-->
<template> <template>
<div> <div>
<vxe-toolbar> <vxe-toolbar>
@ -42,7 +50,7 @@
:show-close="false" :show-close="false"
append-to-body append-to-body
> >
<el-form ref="formRef" :model="formData" :rules="tableRules" label-width="100px"> <el-form ref="formRef" :model="formData" :rules="tableRules" label-width="120px">
<el-form-item label="事件" prop="event"> <el-form-item label="事件" prop="event">
<template #label> <template #label>
<span> <span>
@ -63,7 +71,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="类型" prop="type"> <el-form-item label="类型" prop="type">
<el-select v-model="formData.type"> <el-select v-model="formData.type" @change="handleChangeType">
<el-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></el-option> <el-option v-for="item in typeSelect" :key="item.id" :value="item.value" :label="item.label"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -71,7 +79,7 @@
:label="typeSelect.filter((e) => e.value === formData.type)[0] ? typeSelect.filter((e) => e.value === formData.type)[0]?.label : '表达式'" :label="typeSelect.filter((e) => e.value === formData.type)[0] ? typeSelect.filter((e) => e.value === formData.type)[0]?.label : '表达式'"
prop="className" prop="className"
> >
<el-input v-model="formData.className" type="text"></el-input> <el-input v-model="formData.className" :disabled="formData.alias ? true : false" type="text"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-tabs type="border-card"> <el-tabs type="border-card">
@ -89,35 +97,35 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ListenerParam from './ListenerParam.vue'; import ListenerParam from './ListenerParam.vue'
import { VxeTableEvents, VxeTableInstance, VxeTablePropTypes } from 'vxe-table'; import { VxeTableEvents, VxeTableInstance, VxeTablePropTypes } from 'vxe-table'
import type { TaskListenerVO } from 'bpmnDesign'; import type { TaskListenerVO } from 'bpmnDesign'
import type { ModdleElement } from 'bpmn'; import type { ModdleElement } from 'bpmn'
import usePanel from '../../hooks/usePanel'; import usePanel from '../../hooks/usePanel'
import useDialog from '@/hooks/useDialog'; import useDialog from '@/hooks/useDialog'
import useModelerStore from '@/store/modules/modeler'; import useModelerStore from '@/store/modules/modeler'
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance
interface PropType { interface PropType {
element: ModdleElement; element: ModdleElement
} }
const props = withDefaults(defineProps<PropType>(), {}); const props = withDefaults(defineProps<PropType>(), {})
const selectRow = ref<TaskListenerVO | null>(); const selectRow = ref<TaskListenerVO | null>()
const formDialog = useDialog({ const formDialog = useDialog({
title: selectRow.value ? '编辑&保存' : '新增&保存' title: selectRow.value ? '编辑&保存' : '新增&保存'
}); })
const { showConfig, elementType, updateProperties } = usePanel({ const { showConfig, elementType, updateProperties } = usePanel({
element: toRaw(props.element) element: toRaw(props.element)
}); })
const { getModdle } = useModelerStore(); const { getModdle } = useModelerStore()
const moddle = getModdle(); const moddle = getModdle()
const listenerParamRef = ref<InstanceType<typeof ListenerParam>>(); const listenerParamRef = ref<InstanceType<typeof ListenerParam>>()
const tableRef = ref<VxeTableInstance<TaskListenerVO>>(); const tableRef = ref<VxeTableInstance<TaskListenerVO>>()
const formRef = ref<ElFormInstance>(); const formRef = ref<ElFormInstance>()
const initData: TaskListenerVO = { const initData: TaskListenerVO = {
event: '', event: '',
@ -125,104 +133,133 @@ const initData: TaskListenerVO = {
className: '', className: '',
name: '', name: '',
params: [] params: []
}; }
const formData = ref<TaskListenerVO>({ ...initData }); const formData = ref<TaskListenerVO>({ ...initData })
const currentIndex = ref(0); const currentIndex = ref(0)
const tableData = ref<TaskListenerVO[]>([]); const tableData = ref<TaskListenerVO[]>([])
const tableRules = ref<VxeTablePropTypes.EditRules>({ const tableRules = ref<VxeTablePropTypes.EditRules>({
event: [{ required: true, message: '请选择', trigger: 'blur' }], event: [{ required: true, message: '请选择', trigger: 'blur' }],
type: [{ required: true, message: '请选择', trigger: 'blur' }], type: [{ required: true, message: '请选择', trigger: 'blur' }],
name: [{ required: true, message: '请输入', trigger: 'blur' }], name: [{ required: true, message: '请输入', trigger: 'blur' }],
className: [{ required: true, message: '请输入', trigger: 'blur' }] className: [{ required: true, message: '请输入', trigger: 'blur' }]
}); })
const submitEvent = async () => { const submitEvent = async () => {
const error = await listenerParamRef.value.validate(); const error = await listenerParamRef.value.validate()
await formRef.value.validate((validate) => { await formRef.value.validate((validate) => {
if (validate && !error) { if (validate && !error) {
const $table = tableRef.value; const $table = tableRef.value
console.log($table)
if ($table) { if ($table) {
formData.value.params = listenerParamRef.value.getTableData(); formData.value.params = listenerParamRef.value.getTableData()
if (selectRow.value) { if (selectRow.value) {
Object.assign(selectRow.value, formData.value); Object.assign(selectRow.value, formData.value)
} else { } else {
$table.insertAt({ ...formData.value }, -1); $table.insertAt({ ...formData.value }, -1)
} }
updateElement(); updateElement()
formDialog.closeDialog(); formDialog.closeDialog()
} }
} }
}); })
}; }
const handleChangeType = (v) => {
if (v === 'serviceClass') {
formData.value.className = '${delegatedTaskListener}'
formData.value.alias = v
formData.value.params = listenerParamRef.value.getTableData()
const index = formData.value.params.findIndex((item) => item.name === 'clazz')
console.log(index, formData.value.params)
if (index === -1) {
formData.value.params.unshift({
name: 'interfaceName',
type: 'stringValue',
value: ''
})
}
} else {
formData.value.alias = ''
}
}
const insertEvent = async () => { const insertEvent = async () => {
Object.assign(formData.value, initData); formData.value.alias = ''
selectRow.value = null; Object.assign(formData.value, initData)
formDialog.openDialog(); selectRow.value = null
}; formDialog.openDialog()
}
const editEvent = (row: TaskListenerVO) => { const editEvent = (row: TaskListenerVO) => {
Object.assign(formData.value, row); Object.assign(formData.value, row)
selectRow.value = row; selectRow.value = row
formDialog.openDialog(); formDialog.openDialog()
}; }
const removeEvent = async (row: TaskListenerVO) => { const removeEvent = async (row: TaskListenerVO) => {
await proxy?.$modal.confirm('您确定要删除该数据?'); await proxy?.$modal.confirm('您确定要删除该数据?')
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
await $table.remove(row); await $table.remove(row)
updateElement(); updateElement()
} }
}; }
const removeSelectRowEvent = async () => { const removeSelectRowEvent = async () => {
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
const selectCount = $table.getCheckboxRecords().length; const selectCount = $table.getCheckboxRecords().length
if (selectCount === 0) { if (selectCount === 0) {
proxy?.$modal.msgWarning('请选择行'); proxy?.$modal.msgWarning('请选择行')
} else { } else {
await $table.removeCheckboxRow(); await $table.removeCheckboxRow()
updateElement(); updateElement()
} }
} }
}; }
const updateElement = () => { const updateElement = () => {
const $table = tableRef.value; const $table = tableRef.value
const data = $table.getTableData().fullData; const data = $table.getTableData().fullData
if (data.length) { if (data.length) {
let extensionElements = props.element.businessObject.get('extensionElements'); let extensionElements = props.element.businessObject.get('extensionElements')
if (!extensionElements) { if (!extensionElements) {
extensionElements = moddle.create('bpmn:ExtensionElements'); extensionElements = moddle.create('bpmn:ExtensionElements')
} }
// //
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:TaskListener') ?? []; extensionElements.values = extensionElements?.values.filter((item) => item.$type !== 'flowable:TaskListener') ?? []
data.forEach((item) => { data.forEach((item) => {
const taskListener = moddle.create('flowable:TaskListener'); const taskListener = moddle.create('flowable:TaskListener')
taskListener['event'] = item.event; taskListener['event'] = item.event
taskListener[item.type] = item.className; if (item.alias) {
taskListener.delegateExpression = item.className
taskListener.alias = item.alias
} else {
taskListener[item.type] = item.className
}
if (item.params && item.params.length) { if (item.params && item.params.length) {
item.params.forEach((field) => { item.params.forEach((field) => {
const fieldElement = moddle.create('flowable:Field'); const fieldElement = moddle.create('flowable:Field')
fieldElement['name'] = field.name; fieldElement['name'] = field.name
fieldElement[field.type] = field.value; fieldElement[field.type] = field.value
taskListener.get('fields').push(fieldElement); taskListener.get('fields').push(fieldElement)
}); })
} }
extensionElements.get('values').push(taskListener); extensionElements.get('values').push(taskListener)
}); })
updateProperties({ extensionElements: extensionElements }); updateProperties({ extensionElements: extensionElements })
data.forEach((item) => {
if (item.alias) item.type = item.alias
})
} else { } else {
const extensionElements = props.element.businessObject[`extensionElements`]; const extensionElements = props.element.businessObject[`extensionElements`]
if (extensionElements) { if (extensionElements) {
extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:TaskListener') ?? []; extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:TaskListener') ?? []
} }
} }
}; }
const cellDBLClickEvent: VxeTableEvents.CellDblclick<TaskListenerVO> = ({ row }) => { const cellDBLClickEvent: VxeTableEvents.CellDblclick<TaskListenerVO> = ({ row }) => {
editEvent(row); editEvent(row)
}; }
const menuConfig = reactive<VxeTablePropTypes.MenuConfig<TaskListenerVO>>({ const menuConfig = reactive<VxeTablePropTypes.MenuConfig<TaskListenerVO>>({
body: { body: {
@ -234,71 +271,73 @@ const menuConfig = reactive<VxeTablePropTypes.MenuConfig<TaskListenerVO>>({
] ]
}, },
visibleMethod({ options, column }) { visibleMethod({ options, column }) {
const isDisabled = !column; const isDisabled = !column
options.forEach((list) => { options.forEach((list) => {
list.forEach((item) => { list.forEach((item) => {
item.disabled = isDisabled; item.disabled = isDisabled
}); })
}); })
return true; return true
} }
}); })
const contextMenuClickEvent: VxeTableEvents.MenuClick<TaskListenerVO> = ({ menu, row, column }) => { const contextMenuClickEvent: VxeTableEvents.MenuClick<TaskListenerVO> = ({ menu, row, column }) => {
const $table = tableRef.value; const $table = tableRef.value
if ($table) { if ($table) {
switch (menu.code) { switch (menu.code) {
case 'edit': case 'edit':
editEvent(row); editEvent(row)
break; break
case 'remove': case 'remove':
removeEvent(row); removeEvent(row)
break; break
} }
} }
}; }
const initTableData = () => { const initTableData = () => {
tableData.value = tableData.value =
props.element.businessObject.extensionElements?.values props.element.businessObject.extensionElements?.values
.filter((item) => item.$type === 'flowable:TaskListener') .filter((item) => item.$type === 'flowable:TaskListener')
.map((item) => { .map((item) => {
let type; let type
if ('class' in item) type = 'class'; if ('class' in item) type = 'class'
if ('expression' in item) type = 'expression'; if ('expression' in item) type = 'expression'
if ('delegateExpression' in item) type = 'delegateExpression'; if ('delegateExpression' in item) type = 'delegateExpression'
return { return {
event: item.event, event: item.event,
type: type, type: item.alias || type,
className: item[type], className: item[type],
alias: item.alias || undefined,
params: params:
item.fields?.map((field) => { item.fields?.map((field) => {
let fieldType; let fieldType
if ('stringValue' in field) fieldType = 'stringValue'; if ('stringValue' in field) fieldType = 'stringValue'
if ('expression' in field) fieldType = 'expression'; if ('expression' in field) fieldType = 'expression'
return { return {
name: field.name, name: field.name,
type: fieldType, type: fieldType,
value: field[fieldType] value: field[fieldType]
}; }
}) ?? [] }) ?? []
}; }
}) ?? []; }) ?? []
}; }
onMounted(() => { onMounted(() => {
initTableData(); initTableData()
}); })
const typeSelect = [ const typeSelect = [
{ id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '类', value: 'class' }, { id: '742fdeb7-23b4-416b-ac66-cd4ec8b901b7', label: '类', value: 'class' },
{ id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' }, { id: '660c9c46-8fae-4bae-91a0-0335420019dc', label: '表达式', value: 'expression' },
{ id: '4b8135ab-6bc3-4a0f-80be-22f58bc6c5fd', label: '委托表达式', value: 'delegateExpression' } { id: '4b8135ab-6bc3-4a0f-80be-22f58bc6c5fd', label: '委托表达式', value: 'delegateExpression' },
]; { id: 'ssjksjksjkslkw', label: '远程服务代理', value: 'serviceClass' }
]
const eventSelect = [ const eventSelect = [
{ id: 'e6e0a51a-2d5d-4dc4-b847-b5c14f43a6ab', label: '创建', value: 'create' }, { id: 'e6e0a51a-2d5d-4dc4-b847-b5c14f43a6ab', label: '创建', value: 'create' },
{ id: '6da97c1e-15fc-4445-8943-75d09f49778e', label: '指派', value: 'assignment' }, { id: '6da97c1e-15fc-4445-8943-75d09f49778e', label: '指派', value: 'assignment' },
{ id: '6a2cbcec-e026-4f11-bef7-fff0b5c871e2', label: '完成', value: 'complete' }, { id: '6a2cbcec-e026-4f11-bef7-fff0b5c871e2', label: '完成', value: 'complete' },
{ id: '68801972-85f1-482f-bd86-1fad015c26ed', label: '删除', value: 'delete' } { id: '68801972-85f1-482f-bd86-1fad015c26ed', label: '删除', value: 'delete' }
]; ]
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -1,92 +1,94 @@
declare module 'bpmnDesign' { declare module 'bpmnDesign' {
import { AllocationTypeEnum, SpecifyDescEnum, MultiInstanceTypeEnum } from '@/enums/bpmn/IndexEnums'; import { AllocationTypeEnum, SpecifyDescEnum, MultiInstanceTypeEnum } from '@/enums/bpmn/IndexEnums'
export interface ParamVO { export interface ParamVO {
type: string; type: string
name: string; name: string
value: string; value: string
alias?: string
} }
export interface TaskListenerVO { export interface TaskListenerVO {
event: string; event: string
type: string; type: string
name: string; name: string
className: string; className: string
params: ParamVO[]; alias?: string
params: ParamVO[]
} }
export interface ExecutionListenerVO { export interface ExecutionListenerVO {
event: string; event: string
type: string; type: string
className: string; className: string
params: ParamVO[]; params: ParamVO[]
} }
interface BasePanel { interface BasePanel {
id: string; id: string
name: string; name: string
} }
export interface ProcessPanel extends BasePanel {} export interface ProcessPanel extends BasePanel {}
export interface TaskPanel extends BasePanel { export interface TaskPanel extends BasePanel {
allocationType: AllocationTypeEnum; allocationType: AllocationTypeEnum
specifyDesc: SpecifyDescEnum; specifyDesc: SpecifyDescEnum
multiInstanceType: MultiInstanceTypeEnum; multiInstanceType: MultiInstanceTypeEnum
async?: boolean; async?: boolean
priority?: number; priority?: number
formKey?: string; formKey?: string
skipExpression?: string; skipExpression?: string
isForCompensation?: boolean; isForCompensation?: boolean
triggerServiceTask?: boolean; triggerServiceTask?: boolean
autoStoreVariables?: boolean; autoStoreVariables?: boolean
ruleVariablesInput?: string; ruleVariablesInput?: string
excludeTaskListener?: boolean; excludeTaskListener?: boolean
exclude?: boolean; exclude?: boolean
class?: string; class?: string
dueDate?: string; dueDate?: string
fixedAssignee?: string; fixedAssignee?: string
candidateUsers?: string; candidateUsers?: string
assignee?: string; assignee?: string
candidateGroups?: string; candidateGroups?: string
collection?: string; collection?: string
elementVariable?: string; elementVariable?: string
completionCondition?: string; completionCondition?: string
isSequential?: boolean; isSequential?: boolean
loopCharacteristics?: { loopCharacteristics?: {
collection: string; collection: string
elementVariable: string; elementVariable: string
isSequential: boolean; isSequential: boolean
completionCondition: { completionCondition: {
body: string; body: string
}; }
}; }
} }
export interface StartEndPanel extends BasePanel {} export interface StartEndPanel extends BasePanel {}
export interface GatewayPanel extends BasePanel {} export interface GatewayPanel extends BasePanel {}
export interface SequenceFlowPanel extends BasePanel { export interface SequenceFlowPanel extends BasePanel {
conditionExpression: { conditionExpression: {
body: string; body: string
}; }
conditionExpressionValue: string; conditionExpressionValue: string
skipExpression: string; skipExpression: string
} }
export interface ParticipantPanel extends BasePanel {} export interface ParticipantPanel extends BasePanel {}
export interface SubProcessPanel extends BasePanel { export interface SubProcessPanel extends BasePanel {
multiInstanceType: MultiInstanceTypeEnum; multiInstanceType: MultiInstanceTypeEnum
collection?: string; collection?: string
elementVariable?: string; elementVariable?: string
completionCondition?: string; completionCondition?: string
loopCharacteristics?: { loopCharacteristics?: {
collection: string; collection: string
elementVariable: string; elementVariable: string
isSequential: boolean; isSequential: boolean
completionCondition: { completionCondition: {
body: string; body: string
}; }
}; }
} }
} }