Skip to content

Commit

Permalink
Merge pull request #111 from GoldenZqqq/feature/bpm
Browse files Browse the repository at this point in the history
工作流模块改造优化
  • Loading branch information
YunaiV authored Dec 15, 2024
2 parents 24e1374 + 746aeaf commit 9685fbf
Show file tree
Hide file tree
Showing 10 changed files with 1,179 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,21 @@ import * as UserGroupApi from '@/api/bpm/userGroup'
defineOptions({
name: 'SimpleProcessDesigner'
})
const emits = defineEmits(['success']) // 保存成功事件
const props = defineProps({
modelId: {
type: String,
required: true
required: false
},
modelKey: {
type: String,
required: false
},
modelName: {
type: String,
required: false
}
})
Expand All @@ -69,28 +78,62 @@ const message = useMessage() // 国际化
const processNodeTree = ref<SimpleFlowNode | undefined>()
const errorDialogVisible = ref(false)
let errorNodes: SimpleFlowNode[] = []
// 添加更新模型的方法
const updateModel = (key?: string, name?: string) => {
if (!processNodeTree.value) {
processNodeTree.value = {
name: name || '发起人',
type: NodeType.START_USER_NODE,
id: NodeId.START_USER_NODE_ID,
childNode: {
id: NodeId.END_EVENT_NODE_ID,
name: '结束',
type: NodeType.END_EVENT_NODE
}
}
} else if (name) {
// 更新现有模型的名称
processNodeTree.value.name = name
}
}
// 监听属性变化
watch([() => props.modelKey, () => props.modelName], ([newKey, newName]) => {
if (!props.modelId && newKey && newName) {
updateModel(newKey, newName)
}
}, { immediate: true, deep: true })
const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
if (!simpleModelNode) {
message.error('模型数据为空')
return
}
try {
loading.value = true
const data = {
id: props.modelId,
simpleModel: simpleModelNode
}
const result = await updateBpmSimpleModel(data)
if (result) {
message.success('修改成功')
emits('success')
if (props.modelId) {
// 编辑模式
const data = {
id: props.modelId,
simpleModel: simpleModelNode
}
const result = await updateBpmSimpleModel(data)
if (result) {
message.success('修改成功')
emits('success')
} else {
message.alert('修改失败')
}
} else {
message.alert('修改失败')
// 新建模式,直接返回数据
emits('success', simpleModelNode)
}
} finally {
loading.value = false
}
}
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
if (node) {
Expand Down Expand Up @@ -134,12 +177,14 @@ onMounted(async () => {
try {
loading.value = true
// 获取表单字段
const bpmnModel = await getModel(props.modelId)
if (bpmnModel) {
formType.value = bpmnModel.formType
if (formType.value === 10) {
const bpmnForm = (await getForm(bpmnModel.formId)) as unknown as FormVO
formFields.value = bpmnForm?.fields
if (props.modelId) {
const bpmnModel = await getModel(props.modelId)
if (bpmnModel) {
formType.value = bpmnModel.formType
if (formType.value === 10) {
const bpmnForm = (await getForm(bpmnModel.formId)) as unknown as FormVO
formFields.value = bpmnForm?.fields
}
}
}
// 获得角色列表
Expand All @@ -155,14 +200,18 @@ onMounted(async () => {
// 获取用户组列表
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
//获取 SIMPLE 设计器模型
const result = await getBpmSimpleModel(props.modelId)
if (result) {
processNodeTree.value = result
} else {
// 初始值
if (props.modelId) {
//获取 SIMPLE 设计器模型
const result = await getBpmSimpleModel(props.modelId)
if (result) {
processNodeTree.value = result
}
}
// 如果没有现有模型,创建初始模型
if (!processNodeTree.value) {
processNodeTree.value = {
name: '发起人',
name: props.modelName || '发起人',
type: NodeType.START_USER_NODE,
id: NodeId.START_USER_NODE_ID,
childNode: {
Expand Down
39 changes: 29 additions & 10 deletions src/components/UserSelectForm/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</Dialog>
</template>
<script lang="ts" setup>
import { defaultProps, findTreeNode, handleTree } from '@/utils/tree'
import { defaultProps, handleTree } from '@/utils/tree'
import * as DeptApi from '@/api/system/dept'
import * as UserApi from '@/api/system/user'
Expand All @@ -50,6 +50,7 @@ const emit = defineEmits<{
const { t } = useI18n() // 国际
const message = useMessage() // 消息弹窗
const deptTree = ref<Tree[]>([]) // 部门树形结构化
const deptList = ref<any[]>([]) // 保存扁平化的部门列表数据
const userList = ref<UserApi.UserVO[]>([]) // 所有用户列表
const filteredUserList = ref<UserApi.UserVO[]>([]) // 当前部门过滤后的用户列表
const selectedUserIdList: any = ref([]) // 选中的用户列表
Expand Down Expand Up @@ -79,7 +80,9 @@ const open = async (id: number, selectedList?: any[]) => {
resetForm()
// 加载部门、用户列表
deptTree.value = handleTree(await DeptApi.getSimpleDeptList())
const deptData = await DeptApi.getSimpleDeptList()
deptList.value = deptData // 保存扁平结构的部门数据
deptTree.value = handleTree(deptData) // 转换成树形结构
userList.value = await UserApi.getSimpleUserList()
// 初始状态下,过滤列表等于所有用户列表
Expand All @@ -88,16 +91,31 @@ const open = async (id: number, selectedList?: any[]) => {
dialogVisible.value = true
}
/** 获取指定部门及其所有子部门的ID列表 */
const getChildDeptIds = (deptId: number, deptList: any[]): number[] => {
const ids = [deptId]
const children = deptList.filter((dept) => dept.parentId === deptId)
children.forEach((child) => {
ids.push(...getChildDeptIds(child.id, deptList))
})
return ids
}
/** 获取部门过滤后的用户列表 */
const getUserList = async (deptId?: number) => {
const filterUserList = async (deptId?: number) => {
formLoading.value = true
try {
// @ts-ignore
// TODO @芋艿:替换到 simple List 暂不支持 deptId 过滤
// TODO @Zqqq:这个,可以使用前端过滤么?通过 deptList 获取到 deptId 子节点,然后去 userList
const data = await UserApi.getUserPage({ pageSize: 100, pageNo: 1, deptId })
// 更新过滤后的用户列表
filteredUserList.value = data.list
if (!deptId) {
// 如果没有选择部门,显示所有用户
filteredUserList.value = [...userList.value]
return
}
// 直接使用已保存的部门列表数据进行过滤
const deptIds = getChildDeptIds(deptId, deptList.value)
// 过滤出这些部门下的用户
filteredUserList.value = userList.value.filter((user) => deptIds.includes(user.deptId))
} finally {
formLoading.value = false
}
Expand All @@ -121,14 +139,15 @@ const submitForm = async () => {
/** 重置表单 */
const resetForm = () => {
deptTree.value = []
deptList.value = []
userList.value = []
filteredUserList.value = []
selectedUserIdList.value = []
}
/** 处理部门被点击 */
const handleNodeClick = (row: { [key: string]: any }) => {
getUserList(row.id)
filterUserList(row.id)
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
Expand Down
115 changes: 76 additions & 39 deletions src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="process-panel__container" :style="{ width: `${width}px` }">
<el-collapse v-model="activeTab">
<el-collapse v-model="activeTab" v-if="isReady">
<el-collapse-item name="base">
<!-- class="panel-tab__title" -->
<template #title>
Expand Down Expand Up @@ -108,24 +108,16 @@ const elementBusinessObject = ref<any>({}) // 元素 businessObject 镜像,提
const conditionFormVisible = ref(false) // 流转条件设置
const formVisible = ref(false) // 表单配置
const bpmnElement = ref()
const isReady = ref(false)
provide('prefix', props.prefix)
provide('width', props.width)
const bpmnInstances = () => (window as any)?.bpmnInstances
// 监听 props.bpmnModeler 然后 initModels
const unwatchBpmn = watch(
() => props.bpmnModeler,
() => {
// 避免加载时 流程图 并未加载完成
if (!props.bpmnModeler) {
console.log('缺少props.bpmnModeler')
return
}
console.log('props.bpmnModeler 有值了!!!')
const w = window as any
w.bpmnInstances = {
// 初始化 bpmnInstances
const initBpmnInstances = () => {
if (!props.bpmnModeler) return false
try {
const instances = {
modeler: props.bpmnModeler,
modeling: props.bpmnModeler.get('modeling'),
moddle: props.bpmnModeler.get('moddle'),
Expand All @@ -136,17 +128,55 @@ const unwatchBpmn = watch(
replace: props.bpmnModeler.get('replace'),
selection: props.bpmnModeler.get('selection')
}
// 检查所有实例是否都存在
const allInstancesExist = Object.values(instances).every(instance => instance)
if (allInstancesExist) {
const w = window as any
w.bpmnInstances = instances
return true
}
return false
} catch (error) {
console.error('初始化 bpmnInstances 失败:', error)
return false
}
}
const bpmnInstances = () => (window as any)?.bpmnInstances
console.log(bpmnInstances(), 'window.bpmnInstances')
getActiveElement()
unwatchBpmn()
// 监听 props.bpmnModeler 然后 initModels
const unwatchBpmn = watch(
() => props.bpmnModeler,
async () => {
// 避免加载时 流程图 并未加载完成
if (!props.bpmnModeler) {
console.log('缺少props.bpmnModeler')
return
}
try {
// 等待 modeler 初始化完成
await nextTick()
if (initBpmnInstances()) {
isReady.value = true
await nextTick()
getActiveElement()
} else {
console.error('modeler 实例未完全初始化')
}
} catch (error) {
console.error('初始化失败:', error)
}
},
{
immediate: true
}
)
const getActiveElement = () => {
if (!isReady.value || !props.bpmnModeler) return
// 初始第一个选中元素 bpmn:Process
initFormOnChanged(null)
props.bpmnModeler.on('import.done', (e) => {
Expand All @@ -164,41 +194,48 @@ const getActiveElement = () => {
}
})
}
// 初始化数据
const initFormOnChanged = (element) => {
if (!isReady.value || !bpmnInstances()) return
let activatedElement = element
if (!activatedElement) {
activatedElement =
bpmnInstances().elementRegistry.find((el) => el.type === 'bpmn:Process') ??
bpmnInstances().elementRegistry.find((el) => el.type === 'bpmn:Collaboration')
}
if (!activatedElement) return
console.log(`
----------
select element changed:
id: ${activatedElement.id}
type: ${activatedElement.businessObject.$type}
----------
`)
console.log('businessObject: ', activatedElement.businessObject)
bpmnInstances().bpmnElement = activatedElement
bpmnElement.value = activatedElement
elementId.value = activatedElement.id
elementType.value = activatedElement.type.split(':')[1] || ''
elementBusinessObject.value = JSON.parse(JSON.stringify(activatedElement.businessObject))
conditionFormVisible.value = !!(
elementType.value === 'SequenceFlow' &&
activatedElement.source &&
activatedElement.source.type.indexOf('StartEvent') === -1
)
formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
try {
console.log(`
----------
select element changed:
id: ${activatedElement.id}
type: ${activatedElement.businessObject.$type}
----------
`)
console.log('businessObject: ', activatedElement.businessObject)
bpmnInstances().bpmnElement = activatedElement
bpmnElement.value = activatedElement
elementId.value = activatedElement.id
elementType.value = activatedElement.type.split(':')[1] || ''
elementBusinessObject.value = JSON.parse(JSON.stringify(activatedElement.businessObject))
conditionFormVisible.value = !!(
elementType.value === 'SequenceFlow' &&
activatedElement.source &&
activatedElement.source.type.indexOf('StartEvent') === -1
)
formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
} catch (error) {
console.error('初始化表单数据失败:', error)
}
}
onBeforeUnmount(() => {
const w = window as any
w.bpmnInstances = null
console.log(props, 'props1')
console.log(props.bpmnModeler, 'props.bpmnModeler1')
isReady.value = false
})
watch(
Expand Down
Loading

0 comments on commit 9685fbf

Please sign in to comment.