Skip to content

Commit 472da92

Browse files
committed
2 parents ecfe1b6 + 6f724d9 commit 472da92

File tree

18 files changed

+1683
-258
lines changed

18 files changed

+1683
-258
lines changed

src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<div v-loading="loading" class="overflow-auto">
33
<SimpleProcessModel
4+
ref="simpleProcessModelRef"
45
v-if="processNodeTree"
56
:flow-node="processNodeTree"
67
:readonly="false"
@@ -38,12 +39,21 @@ import * as UserGroupApi from '@/api/bpm/userGroup'
3839
defineOptions({
3940
name: 'SimpleProcessDesigner'
4041
})
42+
4143
const emits = defineEmits(['success']) // 保存成功事件
4244
4345
const props = defineProps({
4446
modelId: {
4547
type: String,
46-
required: true
48+
required: false
49+
},
50+
modelKey: {
51+
type: String,
52+
required: false
53+
},
54+
modelName: {
55+
type: String,
56+
required: false
4757
}
4858
})
4959
@@ -69,28 +79,62 @@ const message = useMessage() // 国际化
6979
const processNodeTree = ref<SimpleFlowNode | undefined>()
7080
const errorDialogVisible = ref(false)
7181
let errorNodes: SimpleFlowNode[] = []
82+
83+
// 添加更新模型的方法
84+
const updateModel = (key?: string, name?: string) => {
85+
if (!processNodeTree.value) {
86+
processNodeTree.value = {
87+
name: name || '发起人',
88+
type: NodeType.START_USER_NODE,
89+
id: NodeId.START_USER_NODE_ID,
90+
childNode: {
91+
id: NodeId.END_EVENT_NODE_ID,
92+
name: '结束',
93+
type: NodeType.END_EVENT_NODE
94+
}
95+
}
96+
} else if (name) {
97+
// 更新现有模型的名称
98+
processNodeTree.value.name = name
99+
}
100+
}
101+
102+
// 监听属性变化
103+
watch([() => props.modelKey, () => props.modelName], ([newKey, newName]) => {
104+
if (!props.modelId && newKey && newName) {
105+
updateModel(newKey, newName)
106+
}
107+
}, { immediate: true, deep: true })
108+
72109
const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
73110
if (!simpleModelNode) {
74111
message.error('模型数据为空')
75112
return
76113
}
77114
try {
78115
loading.value = true
79-
const data = {
80-
id: props.modelId,
81-
simpleModel: simpleModelNode
82-
}
83-
const result = await updateBpmSimpleModel(data)
84-
if (result) {
85-
message.success('修改成功')
86-
emits('success')
116+
if (props.modelId) {
117+
// 编辑模式
118+
const data = {
119+
id: props.modelId,
120+
simpleModel: simpleModelNode
121+
}
122+
const result = await updateBpmSimpleModel(data)
123+
if (result) {
124+
message.success('修改成功')
125+
emits('success')
126+
} else {
127+
message.alert('修改失败')
128+
}
87129
} else {
88-
message.alert('修改失败')
130+
// 新建模式,直接返回数据
131+
emits('success', simpleModelNode)
89132
}
90133
} finally {
91134
loading.value = false
92135
}
93136
}
137+
94138
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
95139
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
96140
if (node) {
@@ -134,12 +178,14 @@ onMounted(async () => {
134178
try {
135179
loading.value = true
136180
// 获取表单字段
137-
const bpmnModel = await getModel(props.modelId)
138-
if (bpmnModel) {
139-
formType.value = bpmnModel.formType
140-
if (formType.value === 10) {
141-
const bpmnForm = (await getForm(bpmnModel.formId)) as unknown as FormVO
142-
formFields.value = bpmnForm?.fields
181+
if (props.modelId) {
182+
const bpmnModel = await getModel(props.modelId)
183+
if (bpmnModel) {
184+
formType.value = bpmnModel.formType
185+
if (formType.value === 10) {
186+
const bpmnForm = (await getForm(bpmnModel.formId)) as unknown as FormVO
187+
formFields.value = bpmnForm?.fields
188+
}
143189
}
144190
}
145191
// 获得角色列表
@@ -155,14 +201,18 @@ onMounted(async () => {
155201
// 获取用户组列表
156202
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
157203
158-
//获取 SIMPLE 设计器模型
159-
const result = await getBpmSimpleModel(props.modelId)
160-
if (result) {
161-
processNodeTree.value = result
162-
} else {
163-
// 初始值
204+
if (props.modelId) {
205+
//获取 SIMPLE 设计器模型
206+
const result = await getBpmSimpleModel(props.modelId)
207+
if (result) {
208+
processNodeTree.value = result
209+
}
210+
}
211+
212+
// 如果没有现有模型,创建初始模型
213+
if (!processNodeTree.value) {
164214
processNodeTree.value = {
165-
name: '发起人',
215+
name: props.modelName || '发起人',
166216
type: NodeType.START_USER_NODE,
167217
id: NodeId.START_USER_NODE_ID,
168218
childNode: {
@@ -176,4 +226,19 @@ onMounted(async () => {
176226
loading.value = false
177227
}
178228
})
229+
230+
const simpleProcessModelRef = ref()
231+
232+
/** 获取当前流程数据 */
233+
const getCurrentFlowData = async () => {
234+
if (simpleProcessModelRef.value) {
235+
return await simpleProcessModelRef.value.getCurrentFlowData()
236+
}
237+
return undefined
238+
}
239+
240+
defineExpose({
241+
getCurrentFlowData,
242+
updateModel
243+
})
179244
</script>

src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@
88
<el-button size="default" class="w-80px"> {{ scaleValue }}% </el-button>
99
<el-button size="default" :plain="true" :icon="ZoomIn" @click="zoomIn()" />
1010
</el-button-group>
11-
<el-button
12-
v-if="!readonly"
13-
size="default"
14-
class="ml-4px"
15-
type="primary"
16-
:icon="Select"
17-
@click="saveSimpleFlowModel"
18-
>保存模型</el-button
19-
>
2011
</el-row>
2112
</div>
2213
<div class="simple-process-model" :style="`transform: scale(${scaleValue / 100});`">
@@ -42,7 +33,8 @@
4233
import ProcessNodeTree from './ProcessNodeTree.vue'
4334
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts'
4435
import { useWatchNode } from './node'
45-
import { Select, ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
36+
import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue'
37+
4638
defineOptions({
4739
name: 'SimpleProcessModel'
4840
})
@@ -58,6 +50,7 @@ const props = defineProps({
5850
default: true
5951
}
6052
})
53+
6154
const emits = defineEmits<{
6255
'save': [node: SimpleFlowNode | undefined]
6356
}>()
@@ -68,35 +61,30 @@ provide('readonly', props.readonly)
6861
let scaleValue = ref(100)
6962
const MAX_SCALE_VALUE = 200
7063
const MIN_SCALE_VALUE = 50
64+
7165
// 放大
7266
const zoomIn = () => {
7367
if (scaleValue.value == MAX_SCALE_VALUE) {
7468
return
7569
}
7670
scaleValue.value += 10
7771
}
72+
7873
// 缩小
7974
const zoomOut = () => {
8075
if (scaleValue.value == MIN_SCALE_VALUE) {
8176
return
8277
}
8378
scaleValue.value -= 10
8479
}
80+
8581
const processReZoom = () => {
8682
scaleValue.value = 100
8783
}
8884
8985
const errorDialogVisible = ref(false)
9086
let errorNodes: SimpleFlowNode[] = []
91-
const saveSimpleFlowModel = async () => {
92-
errorNodes = []
93-
validateNode(processNodeTree.value, errorNodes)
94-
if (errorNodes.length > 0) {
95-
errorDialogVisible.value = true
96-
return
97-
}
98-
emits('save', processNodeTree.value)
99-
}
87+
10088
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
10189
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
10290
if (node) {
@@ -135,6 +123,26 @@ const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNo
135123
}
136124
}
137125
}
126+
127+
/** 获取当前流程数据 */
128+
const getCurrentFlowData = async () => {
129+
try {
130+
errorNodes = []
131+
validateNode(processNodeTree.value, errorNodes)
132+
if (errorNodes.length > 0) {
133+
errorDialogVisible.value = true
134+
return undefined
135+
}
136+
return processNodeTree.value
137+
} catch (error) {
138+
console.error('获取流程数据失败:', error)
139+
return undefined
140+
}
141+
}
142+
143+
defineExpose({
144+
getCurrentFlowData
145+
})
138146
</script>
139147

140148
<style lang="scss" scoped></style>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ const fieldOptions = computed(() => {
381381
382382
/** 获取字段名称 */
383383
const getFieldTitle = (field: string) => {
384-
const item = fieldsInfo.find((item) => item.field === field)
384+
const item = fieldOptions.value.find((item) => item.field === field)
385385
return item?.title
386386
}
387387

src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,16 @@
173173
height: 100%;
174174
padding-top: 32px;
175175
background-color: #fafafa;
176+
overflow-x: auto;
177+
width: 100%;
178+
176179
.simple-process-model {
177180
display: flex;
178181
flex-direction: column;
179182
justify-content: center;
180183
align-items: center;
181184
transform-origin: 50% 0 0;
182-
overflow: auto;
185+
min-width: fit-content;
183186
transform: scale(1);
184187
transition: transform 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
185188
background: url(@/assets/svgs/bpm/simple-process-bg.svg) 0 0 repeat;
@@ -473,6 +476,7 @@
473476
.branch-node-container {
474477
position: relative;
475478
display: flex;
479+
min-width: fit-content;
476480

477481
&::before {
478482
position: absolute;
@@ -548,6 +552,7 @@
548552
background: transparent;
549553
border-top: 2px solid #dedede;
550554
border-bottom: 2px solid #dedede;
555+
flex-shrink: 0;
551556

552557
&::before {
553558
position: absolute;

src/components/UserSelectForm/index.vue

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
</Dialog>
4040
</template>
4141
<script lang="ts" setup>
42-
import { defaultProps, findTreeNode, handleTree } from '@/utils/tree'
42+
import { defaultProps, handleTree } from '@/utils/tree'
4343
import * as DeptApi from '@/api/system/dept'
4444
import * as UserApi from '@/api/system/user'
4545
@@ -50,6 +50,7 @@ const emit = defineEmits<{
5050
const { t } = useI18n() // 国际
5151
const message = useMessage() // 消息弹窗
5252
const deptTree = ref<Tree[]>([]) // 部门树形结构化
53+
const deptList = ref<any[]>([]) // 保存扁平化的部门列表数据
5354
const userList = ref<UserApi.UserVO[]>([]) // 所有用户列表
5455
const filteredUserList = ref<UserApi.UserVO[]>([]) // 当前部门过滤后的用户列表
5556
const selectedUserIdList: any = ref([]) // 选中的用户列表
@@ -79,7 +80,9 @@ const open = async (id: number, selectedList?: any[]) => {
7980
resetForm()
8081
8182
// 加载部门、用户列表
82-
deptTree.value = handleTree(await DeptApi.getSimpleDeptList())
83+
const deptData = await DeptApi.getSimpleDeptList()
84+
deptList.value = deptData // 保存扁平结构的部门数据
85+
deptTree.value = handleTree(deptData) // 转换成树形结构
8386
userList.value = await UserApi.getSimpleUserList()
8487
8588
// 初始状态下,过滤列表等于所有用户列表
@@ -88,16 +91,31 @@ const open = async (id: number, selectedList?: any[]) => {
8891
dialogVisible.value = true
8992
}
9093
94+
/** 获取指定部门及其所有子部门的ID列表 */
95+
const getChildDeptIds = (deptId: number, deptList: any[]): number[] => {
96+
const ids = [deptId]
97+
const children = deptList.filter((dept) => dept.parentId === deptId)
98+
children.forEach((child) => {
99+
ids.push(...getChildDeptIds(child.id, deptList))
100+
})
101+
return ids
102+
}
103+
91104
/** 获取部门过滤后的用户列表 */
92-
const getUserList = async (deptId?: number) => {
105+
const filterUserList = async (deptId?: number) => {
93106
formLoading.value = true
94107
try {
95-
// @ts-ignore
96-
// TODO @芋艿:替换到 simple List 暂不支持 deptId 过滤
97-
// TODO @Zqqq:这个,可以使用前端过滤么?通过 deptList 获取到 deptId 子节点,然后去 userList
98-
const data = await UserApi.getUserPage({ pageSize: 100, pageNo: 1, deptId })
99-
// 更新过滤后的用户列表
100-
filteredUserList.value = data.list
108+
if (!deptId) {
109+
// 如果没有选择部门,显示所有用户
110+
filteredUserList.value = [...userList.value]
111+
return
112+
}
113+
114+
// 直接使用已保存的部门列表数据进行过滤
115+
const deptIds = getChildDeptIds(deptId, deptList.value)
116+
117+
// 过滤出这些部门下的用户
118+
filteredUserList.value = userList.value.filter((user) => deptIds.includes(user.deptId))
101119
} finally {
102120
formLoading.value = false
103121
}
@@ -121,14 +139,15 @@ const submitForm = async () => {
121139
/** 重置表单 */
122140
const resetForm = () => {
123141
deptTree.value = []
142+
deptList.value = []
124143
userList.value = []
125144
filteredUserList.value = []
126145
selectedUserIdList.value = []
127146
}
128147
129148
/** 处理部门被点击 */
130149
const handleNodeClick = (row: { [key: string]: any }) => {
131-
getUserList(row.id)
150+
filterUserList(row.id)
132151
}
133152
134153
defineExpose({ open }) // 提供 open 方法,用于打开弹窗

0 commit comments

Comments
 (0)