Skip to content

Commit e3db7d3

Browse files
committed
Merge branch 'feature/bpm' of https://gitee.com/yudaocode/yudao-ui-admin-vue3 into feature/bpm
2 parents b7329b0 + a61a405 commit e3db7d3

File tree

10 files changed

+230
-89
lines changed

10 files changed

+230
-89
lines changed

src/components/SimpleProcessDesignerV2/src/node.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import {
1616
FieldPermissionType,
1717
ListenerParam
1818
} from './consts'
19-
import { parseFormFields } from '@/components/FormCreate/src/utils/index'
19+
import { parseFormFields } from '@/components/FormCreate/src/utils'
20+
2021
export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
2122
const node = ref<SimpleFlowNode>(props.flowNode)
2223
watch(
@@ -46,7 +47,7 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType)
4647
// 字段权限配置. 需要有 field, title, permissioin 属性
4748
const fieldsPermissionConfig = ref<Array<Record<string, any>>>([])
4849

49-
const formType = inject<Ref<number|undefined>>('formType', ref()) // 表单类型
50+
const formType = inject<Ref<number | undefined>>('formType', ref()) // 表单类型
5051

5152
const formFields = inject<Ref<string[]>>('formFields', ref([])) // 流程表单字段
5253

@@ -108,7 +109,7 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType)
108109
* @description 获取表单的字段
109110
*/
110111
export function useFormFields() {
111-
const formFields = inject<Ref<string[]>>('formFields',ref([])) // 流程表单字段
112+
const formFields = inject<Ref<string[]>>('formFields', ref([])) // 流程表单字段
112113
return parseFormCreateFields(unref(formFields))
113114
}
114115

@@ -178,7 +179,7 @@ export function useNodeForm(nodeType: NodeType) {
178179
const postOptions = inject<Ref<PostApi.PostVO[]>>('postList', ref([])) // 岗位列表
179180
const userOptions = inject<Ref<UserApi.UserVO[]>>('userList', ref([])) // 用户列表
180181
const deptOptions = inject<Ref<DeptApi.DeptVO[]>>('deptList', ref([])) // 部门列表
181-
const userGroupOptions = inject<Ref<UserGroupApi.UserGroupVO[]>>('userGroupList',ref([])) // 用户组列表
182+
const userGroupOptions = inject<Ref<UserGroupApi.UserGroupVO[]>>('userGroupList', ref([])) // 用户组列表
182183
const deptTreeOptions = inject('deptTree', ref()) // 部门树
183184
const formFields = inject<Ref<string[]>>('formFields', ref([])) // 流程表单字段
184185
const configForm = ref<UserTaskFormType | CopyTaskFormType>()

src/components/SimpleProcessDesignerV2/src/nodes/DelayTimerNode.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
]"
1010
>
1111
<div class="node-title-container">
12-
<!-- TODO @芋艿 需要更换图标 -->
1312
<div class="node-title-icon delay-node"><span class="iconfont icon-delay"></span></div>
1413
<input
1514
v-if="!readonly && showInput"

src/components/bpmnProcessDesigner/package/penal/multi-instance/ElementMultiInstance.vue

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<template>
22
<div class="panel-tab__content">
3-
<el-radio-group v-model="approveMethod" @change="onApproveMethodChange">
3+
<el-radio-group
4+
v-if="type === 'UserTask'"
5+
v-model="approveMethod"
6+
@change="onApproveMethodChange"
7+
>
48
<div class="flex-col">
59
<div v-for="(item, index) in APPROVE_METHODS" :key="index">
610
<el-radio :value="item.value" :label="item.value">
@@ -23,6 +27,9 @@
2327
</div>
2428
</div>
2529
</el-radio-group>
30+
<div v-else>
31+
除了UserTask以外节点的多实例待实现
32+
</div>
2633
<!-- 与Simple设计器配置合并,保留以前的代码 -->
2734
<el-form label-width="90px" style="display: none">
2835
<el-form-item label="快捷配置">
@@ -301,19 +308,21 @@ const approveMethod = ref()
301308
const approveRatio = ref(100)
302309
const otherExtensions = ref()
303310
const getElementLoopNew = () => {
304-
const extensionElements =
305-
bpmnElement.value.businessObject?.extensionElements ??
306-
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
307-
approveMethod.value = extensionElements.values.filter(
308-
(ex) => ex.$type === `${prefix}:ApproveMethod`
309-
)?.[0]?.value
311+
if (props.type === 'UserTask') {
312+
const extensionElements =
313+
bpmnElement.value.businessObject?.extensionElements ??
314+
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
315+
approveMethod.value = extensionElements.values.filter(
316+
(ex) => ex.$type === `${prefix}:ApproveMethod`
317+
)?.[0]?.value
310318
311-
otherExtensions.value =
312-
extensionElements.values.filter((ex) => ex.$type !== `${prefix}:ApproveMethod`) ?? []
319+
otherExtensions.value =
320+
extensionElements.values.filter((ex) => ex.$type !== `${prefix}:ApproveMethod`) ?? []
313321
314-
if (!approveMethod.value) {
315-
approveMethod.value = ApproveMethodType.SEQUENTIAL_APPROVE
316-
updateLoopCharacteristics()
322+
if (!approveMethod.value) {
323+
approveMethod.value = ApproveMethodType.SEQUENTIAL_APPROVE
324+
updateLoopCharacteristics()
325+
}
317326
}
318327
}
319328
const onApproveMethodChange = () => {

src/views/bpm/model/CategoryDraggableModel.vue

Lines changed: 95 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex items-center h-50px">
2+
<div class="flex items-center h-50px" v-memo="[categoryInfo.name, isCategorySorting]">
33
<!-- 头部:分类名 -->
44
<div class="flex items-center">
55
<el-tooltip content="拖动排序" v-if="isCategorySorting">
@@ -13,7 +13,7 @@
1313
<div class="color-gray-600 text-16px"> ({{ categoryInfo.modelList?.length || 0 }}) </div>
1414
</div>
1515
<!-- 头部:操作 -->
16-
<div class="flex-1 flex" v-if="!isCategorySorting">
16+
<div class="flex-1 flex" v-show="!isCategorySorting">
1717
<div
1818
v-if="categoryInfo.modelList.length > 0"
1919
class="ml-20px flex items-center"
@@ -69,44 +69,43 @@
6969
<el-collapse-transition>
7070
<div v-show="isExpand">
7171
<el-table
72+
v-if="modelList && modelList.length > 0"
7273
:class="categoryInfo.name"
7374
ref="tableRef"
74-
:header-cell-style="{ backgroundColor: isDark ? '' : '#edeff0', paddingLeft: '10px' }"
75-
:cell-style="{ paddingLeft: '10px' }"
76-
:row-style="{ height: '68px' }"
7775
:data="modelList"
7876
row-key="id"
77+
:header-cell-style="tableHeaderStyle"
78+
:cell-style="tableCellStyle"
79+
:row-style="{ height: '68px' }"
7980
>
8081
<el-table-column label="流程名" prop="name" min-width="150">
81-
<template #default="scope">
82+
<template #default="{ row }">
8283
<div class="flex items-center">
8384
<el-tooltip content="拖动排序" v-if="isModelSorting">
8485
<Icon
8586
icon="ic:round-drag-indicator"
8687
class="drag-icon cursor-move text-#8a909c mr-10px"
8788
/>
8889
</el-tooltip>
89-
<el-image :src="scope.row.icon" class="h-38px w-38px mr-10px rounded" />
90-
{{ scope.row.name }}
90+
<el-image v-if="row.icon" :src="row.icon" class="h-38px w-38px mr-10px rounded" />
91+
{{ row.name }}
9192
</div>
9293
</template>
9394
</el-table-column>
9495
<el-table-column label="可见范围" prop="startUserIds" min-width="150">
95-
<template #default="scope">
96-
<el-text v-if="!scope.row.startUsers || scope.row.startUsers.length === 0">
97-
全部可见
98-
</el-text>
99-
<el-text v-else-if="scope.row.startUsers.length == 1">
100-
{{ scope.row.startUsers[0].nickname }}
96+
<template #default="{ row }">
97+
<el-text v-if="!row.startUsers?.length"> 全部可见 </el-text>
98+
<el-text v-else-if="row.startUsers.length === 1">
99+
{{ row.startUsers[0].nickname }}
101100
</el-text>
102101
<el-text v-else>
103102
<el-tooltip
104103
class="box-item"
105104
effect="dark"
106105
placement="top"
107-
:content="scope.row.startUsers.map((user: any) => user.nickname).join('、')"
106+
:content="row.startUsers.map((user: any) => user.nickname).join('、')"
108107
>
109-
{{ scope.row.startUsers[0].nickname }}等 {{ scope.row.startUsers.length }} 人可见
108+
{{ row.startUsers[0].nickname }}等 {{ row.startUsers.length }} 人可见
110109
</el-tooltip>
111110
</el-text>
112111
</template>
@@ -245,7 +244,6 @@
245244
<script lang="ts" setup>
246245
import { CategoryApi, CategoryVO } from '@/api/bpm/category'
247246
import Sortable from 'sortablejs'
248-
import { propTypes } from '@/utils/propTypes'
249247
import { formatDate } from '@/utils/formatTime'
250248
import * as ModelApi from '@/api/bpm/model'
251249
import * as FormApi from '@/api/bpm/form'
@@ -254,15 +252,49 @@ import { BpmModelFormType } from '@/utils/constants'
254252
import { checkPermi } from '@/utils/permission'
255253
import { useUserStoreWithOut } from '@/store/modules/user'
256254
import { useAppStore } from '@/store/modules/app'
257-
import { cloneDeep } from 'lodash-es'
255+
import { cloneDeep, isEqual } from 'lodash-es'
258256
import { useTagsView } from '@/hooks/web/useTagsView'
257+
import { useDebounceFn } from '@vueuse/core'
259258
260259
defineOptions({ name: 'BpmModel' })
261260
262-
const props = defineProps({
263-
categoryInfo: propTypes.object.def([]), // 分类后的数据
264-
isCategorySorting: propTypes.bool.def(false) // 是否分类在排序
265-
})
261+
// 优化 Props 类型定义
262+
interface UserInfo {
263+
nickname: string
264+
[key: string]: any
265+
}
266+
267+
interface ProcessDefinition {
268+
deploymentTime: string
269+
version: number
270+
suspensionState: number
271+
}
272+
273+
interface ModelInfo {
274+
id: number
275+
name: string
276+
icon?: string
277+
startUsers?: UserInfo[]
278+
processDefinition?: ProcessDefinition
279+
formType?: number
280+
formId?: number
281+
formName?: string
282+
formCustomCreatePath?: string
283+
managerUserIds?: number[]
284+
[key: string]: any
285+
}
286+
287+
interface CategoryInfoProps {
288+
id: number
289+
name: string
290+
modelList: ModelInfo[]
291+
}
292+
293+
const props = defineProps<{
294+
categoryInfo: CategoryInfoProps
295+
isCategorySorting: boolean
296+
}>()
297+
266298
const emit = defineEmits(['success'])
267299
const message = useMessage() // 消息弹窗
268300
const { t } = useI18n() // 国际化
@@ -271,10 +303,20 @@ const userStore = useUserStoreWithOut() // 用户信息缓存
271303
const isDark = computed(() => useAppStore().getIsDark) // 是否黑暗模式
272304
273305
const isModelSorting = ref(false) // 是否正处于排序状态
274-
const originalData: any = ref([]) // 原始数据
275-
const modelList: any = ref([]) // 模型列表
306+
const originalData = ref<ModelInfo[]>([]) // 原始数据
307+
const modelList = ref<ModelInfo[]>([]) // 模型列表
276308
const isExpand = ref(false) // 是否处于展开状态
277309
310+
// 使用 computed 优化表格样式计算
311+
const tableHeaderStyle = computed(() => ({
312+
backgroundColor: isDark.value ? '' : '#edeff0',
313+
paddingLeft: '10px'
314+
}))
315+
316+
const tableCellStyle = computed(() => ({
317+
paddingLeft: '10px'
318+
}))
319+
278320
/** 权限校验:通过 computed 解决列表的卡顿问题 */
279321
const hasPermiUpdate = computed(() => {
280322
return checkPermi(['bpm:model:update'])
@@ -449,14 +491,15 @@ const handleModelSortCancel = () => {
449491
450492
/** 创建拖拽实例 */
451493
const tableRef = ref()
452-
const initSort = () => {
494+
const initSort = useDebounceFn(() => {
453495
const table = document.querySelector(`.${props.categoryInfo.name} .el-table__body-wrapper tbody`)
496+
if (!table) return
497+
454498
Sortable.create(table, {
455499
group: 'shared',
456500
animation: 150,
457501
draggable: '.el-table__row',
458502
handle: '.drag-icon',
459-
// 结束拖动事件
460503
onEnd: ({ newDraggableIndex, oldDraggableIndex }) => {
461504
if (oldDraggableIndex !== newDraggableIndex) {
462505
modelList.value.splice(
@@ -467,15 +510,18 @@ const initSort = () => {
467510
}
468511
}
469512
})
470-
}
513+
}, 200)
471514
472515
/** 更新 modelList 模型列表 */
473-
const updateModeList = () => {
474-
modelList.value = cloneDeep(props.categoryInfo.modelList)
475-
if (props.categoryInfo.modelList.length > 0) {
476-
isExpand.value = true
516+
const updateModeList = useDebounceFn(() => {
517+
const newModelList = props.categoryInfo.modelList
518+
if (!isEqual(modelList.value, newModelList)) {
519+
modelList.value = cloneDeep(newModelList)
520+
if (newModelList?.length > 0) {
521+
isExpand.value = true
522+
}
477523
}
478-
}
524+
}, 100)
479525
480526
/** 重命名弹窗确定 */
481527
const renameCategoryVisible = ref(false)
@@ -526,14 +572,15 @@ const openModelForm = async (type: string, id?: number) => {
526572
}
527573
}
528574
529-
watch(() => props.categoryInfo.modelList, updateModeList, { immediate: true })
530-
watch(
531-
() => props.isCategorySorting,
532-
(val) => {
533-
if (val) isExpand.value = false
534-
},
535-
{ immediate: true }
536-
)
575+
watchEffect(() => {
576+
if (props.categoryInfo?.modelList) {
577+
updateModeList()
578+
}
579+
580+
if (props.isCategorySorting) {
581+
isExpand.value = false
582+
}
583+
})
537584
</script>
538585

539586
<style lang="scss">
@@ -550,10 +597,16 @@ watch(
550597
}
551598
</style>
552599
<style lang="scss" scoped>
553-
:deep() {
554-
.el-table__cell {
600+
.category-draggable-model {
601+
:deep(.el-table__cell) {
555602
overflow: hidden;
556603
border-bottom: none !important;
557604
}
605+
606+
// 优化表格渲染性能
607+
:deep(.el-table__body) {
608+
will-change: transform;
609+
transform: translateZ(0);
610+
}
558611
}
559612
</style>

0 commit comments

Comments
 (0)