Skip to content

Commit 6e6754e

Browse files
committed
feat: 流程模型新增/修改页面-优化路由配置、新增修改分为两个并全部使用name进行跳转,每个步骤拆分出一个子组件
1 parent 5e38633 commit 6e6754e

File tree

7 files changed

+771
-11
lines changed

7 files changed

+771
-11
lines changed

src/router/modules/remaining.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,14 +332,26 @@ const remainingRouter: AppRouteRecordRaw[] = [
332332
}
333333
},
334334
{
335-
path: 'manager/model/create-update', // TODO @goldenzqqq:是不是拆分成两个,一个 create 创建流程;一个 update 修改流程?
336-
component: () => import('@/views/bpm/model/CreateUpdate.vue'), // TODO @goldenzqqq:是不是放到 '@/views/bpm/model/form/index.vue'。然后,原本的 editor/index.vue 是不是可以清理了呀?
337-
name: 'BpmModelCreateUpdate',
335+
path: 'manager/model/create',
336+
component: () => import('@/views/bpm/model/form/index.vue'),
337+
name: 'BpmModelCreate',
338338
meta: {
339339
noCache: true,
340340
hidden: true,
341341
canTo: true,
342-
title: '创建/修改流程',
342+
title: '创建流程',
343+
activeMenu: '/bpm/manager/model'
344+
}
345+
},
346+
{
347+
path: 'manager/model/update/:id',
348+
component: () => import('@/views/bpm/model/form/index.vue'),
349+
name: 'BpmModelUpdate',
350+
meta: {
351+
noCache: true,
352+
hidden: true,
353+
canTo: true,
354+
title: '修改流程',
343355
activeMenu: '/bpm/manager/model'
344356
}
345357
}

src/views/bpm/model/CategoryDraggableModel.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,10 @@ const handleChangeState = async (row: any) => {
339339
340340
/** 设计流程 */
341341
const handleDesign = (row: any) => {
342-
// TODO @goldenzqqq:最好使用 name 哈
343-
push(`/bpm/manager/model/create-update?id=${row.id}`)
342+
push({
343+
name: 'BpmModelUpdate',
344+
params: { id: row.id }
345+
})
344346
}
345347
346348
/** 发布流程 */
@@ -483,11 +485,13 @@ const handleDeleteCategory = async () => {
483485
/** 添加流程模型弹窗 */
484486
const modelFormRef = ref()
485487
const openModelForm = (type: string, id?: number) => {
486-
// TODO @goldenzqqq:最好使用 name 哈
487488
if (type === 'create') {
488-
push('/bpm/manager/model/create-update')
489+
push({ name: 'BpmModelCreate' })
489490
} else {
490-
push(`/bpm/manager/model/create-update?id=${id}`)
491+
push({
492+
name: 'BpmModelUpdate',
493+
params: { id }
494+
})
491495
}
492496
}
493497
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
<template>
2+
<el-form
3+
ref="formRef"
4+
:model="modelData"
5+
:rules="rules"
6+
label-width="120px"
7+
class="mt-20px w-600px"
8+
>
9+
<el-form-item label="流程标识" prop="key" class="mb-20px">
10+
<el-input v-model="modelData.key" :disabled="!!modelData.id" placeholder="请输入流标标识" />
11+
<el-tooltip
12+
v-if="!modelData.id"
13+
class="item"
14+
content="新建后,流程标识不可修改!"
15+
effect="light"
16+
placement="top"
17+
>
18+
<Icon icon="ep:question" class="ml-5px" />
19+
</el-tooltip>
20+
<el-tooltip v-else class="item" content="流程标识不可修改!" effect="light" placement="top">
21+
<Icon icon="ep:question" class="ml-5px" />
22+
</el-tooltip>
23+
</el-form-item>
24+
<el-form-item label="流程名称" prop="name" class="mb-20px">
25+
<el-input
26+
v-model="modelData.name"
27+
:disabled="!!modelData.id"
28+
clearable
29+
placeholder="请输入流程名称"
30+
/>
31+
</el-form-item>
32+
<el-form-item label="流程分类" prop="category" class="mb-20px">
33+
<el-select
34+
v-model="modelData.category"
35+
clearable
36+
placeholder="请选择流程分类"
37+
style="width: 100%"
38+
>
39+
<el-option
40+
v-for="category in categoryList"
41+
:key="category.code"
42+
:label="category.name"
43+
:value="category.code"
44+
/>
45+
</el-select>
46+
</el-form-item>
47+
<el-form-item label="流程图标" prop="icon" class="mb-20px">
48+
<UploadImg v-model="modelData.icon" :limit="1" height="64px" width="64px" />
49+
</el-form-item>
50+
<el-form-item label="流程描述" prop="description" class="mb-20px">
51+
<el-input v-model="modelData.description" clearable type="textarea" />
52+
</el-form-item>
53+
<el-form-item label="流程类型" prop="type" class="mb-20px">
54+
<el-radio-group v-model="modelData.type">
55+
<el-radio
56+
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_TYPE)"
57+
:key="dict.value"
58+
:value="dict.value"
59+
>
60+
{{ dict.label }}
61+
</el-radio>
62+
</el-radio-group>
63+
</el-form-item>
64+
<el-form-item label="是否可见" prop="visible" class="mb-20px">
65+
<el-radio-group v-model="modelData.visible">
66+
<el-radio
67+
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
68+
:key="dict.value"
69+
:value="dict.value"
70+
>
71+
{{ dict.label }}
72+
</el-radio>
73+
</el-radio-group>
74+
</el-form-item>
75+
<el-form-item label="谁可以发起" prop="startUserType" class="mb-20px">
76+
<el-select
77+
v-model="modelData.startUserType"
78+
placeholder="请选择谁可以发起"
79+
@change="handleStartUserTypeChange"
80+
>
81+
<el-option label="全员" :value="0" />
82+
<el-option label="指定人员" :value="1" />
83+
<el-option label="均不可提交" :value="2" />
84+
</el-select>
85+
<div v-if="modelData.startUserType === 1" class="mt-2 flex flex-wrap gap-2">
86+
<div
87+
v-for="user in selectedStartUsers"
88+
:key="user.id"
89+
class="bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
90+
>
91+
<el-avatar class="!m-5px" :size="28" v-if="user.avatar" :src="user.avatar" />
92+
<el-avatar class="!m-5px" :size="28" v-else>
93+
{{ user.nickname.substring(0, 1) }}
94+
</el-avatar>
95+
{{ user.nickname }}
96+
<Icon
97+
icon="ep:close"
98+
class="ml-2 cursor-pointer hover:text-red-500"
99+
@click="handleRemoveStartUser(user)"
100+
/>
101+
</div>
102+
<el-button type="primary" link @click="openStartUserSelect">
103+
<Icon icon="ep:plus" />选择人员
104+
</el-button>
105+
</div>
106+
</el-form-item>
107+
<el-form-item label="流程管理员" prop="managerUserType" class="mb-20px">
108+
<el-select
109+
v-model="modelData.managerUserType"
110+
placeholder="请选择流程管理员"
111+
@change="handleManagerUserTypeChange"
112+
>
113+
<el-option label="全员" :value="0" />
114+
<el-option label="指定人员" :value="1" />
115+
<el-option label="均不可提交" :value="2" />
116+
</el-select>
117+
<div v-if="modelData.managerUserType === 1" class="mt-2 flex flex-wrap gap-2">
118+
<div
119+
v-for="user in selectedManagerUsers"
120+
:key="user.id"
121+
class="bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
122+
>
123+
<el-avatar class="!m-5px" :size="28" v-if="user.avatar" :src="user.avatar" />
124+
<el-avatar class="!m-5px" :size="28" v-else>
125+
{{ user.nickname.substring(0, 1) }}
126+
</el-avatar>
127+
{{ user.nickname }}
128+
<Icon
129+
icon="ep:close"
130+
class="ml-2 cursor-pointer hover:text-red-500"
131+
@click="handleRemoveManagerUser(user)"
132+
/>
133+
</div>
134+
<el-button type="primary" link @click="openManagerUserSelect">
135+
<Icon icon="ep:plus" />选择人员
136+
</el-button>
137+
</div>
138+
</el-form-item>
139+
</el-form>
140+
141+
<!-- 用户选择弹窗 -->
142+
<UserSelectForm ref="userSelectFormRef" @confirm="handleUserSelectConfirm" />
143+
</template>
144+
145+
<script lang="ts" setup>
146+
import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
147+
import { BpmModelType } from '@/utils/constants'
148+
import { UserVO } from '@/api/system/user'
149+
150+
const props = defineProps({
151+
modelValue: {
152+
type: Object,
153+
required: true
154+
},
155+
categoryList: {
156+
type: Array,
157+
required: true
158+
},
159+
userList: {
160+
type: Array,
161+
required: true
162+
}
163+
})
164+
165+
const emit = defineEmits(['update:modelValue'])
166+
167+
const formRef = ref()
168+
const selectedStartUsers = ref<UserVO[]>([])
169+
const selectedManagerUsers = ref<UserVO[]>([])
170+
const userSelectFormRef = ref()
171+
const currentSelectType = ref<'start' | 'manager'>('start')
172+
173+
const rules = {
174+
name: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }],
175+
key: [{ required: true, message: '流程标识不能为空', trigger: 'blur' }],
176+
category: [{ required: true, message: '流程分类不能为空', trigger: 'blur' }],
177+
icon: [{ required: true, message: '流程图标不能为空', trigger: 'blur' }],
178+
type: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
179+
visible: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
180+
managerUserIds: [{ required: true, message: '流程管理员不能为空', trigger: 'blur' }]
181+
}
182+
183+
// 创建本地数据副本
184+
const modelData = computed({
185+
get: () => props.modelValue,
186+
set: (val) => emit('update:modelValue', val)
187+
})
188+
189+
// 初始化选中的用户
190+
watch(
191+
() => props.modelValue,
192+
(newVal) => {
193+
if (newVal.startUserIds?.length) {
194+
selectedStartUsers.value = props.userList.filter((user: UserVO) =>
195+
newVal.startUserIds.includes(user.id)
196+
) as UserVO[]
197+
}
198+
if (newVal.managerUserIds?.length) {
199+
selectedManagerUsers.value = props.userList.filter((user: UserVO) =>
200+
newVal.managerUserIds.includes(user.id)
201+
) as UserVO[]
202+
}
203+
},
204+
{ immediate: true }
205+
)
206+
207+
/** 打开发起人选择 */
208+
const openStartUserSelect = () => {
209+
currentSelectType.value = 'start'
210+
userSelectFormRef.value.open(0, selectedStartUsers.value)
211+
}
212+
213+
/** 打开管理员选择 */
214+
const openManagerUserSelect = () => {
215+
currentSelectType.value = 'manager'
216+
userSelectFormRef.value.open(0, selectedManagerUsers.value)
217+
}
218+
219+
/** 处理用户选择确认 */
220+
const handleUserSelectConfirm = (_, users: UserVO[]) => {
221+
if (currentSelectType.value === 'start') {
222+
selectedStartUsers.value = users
223+
emit('update:modelValue', {
224+
...modelData.value,
225+
startUserIds: users.map((u) => u.id)
226+
})
227+
} else {
228+
selectedManagerUsers.value = users
229+
emit('update:modelValue', {
230+
...modelData.value,
231+
managerUserIds: users.map((u) => u.id)
232+
})
233+
}
234+
}
235+
236+
/** 处理发起人类型变化 */
237+
const handleStartUserTypeChange = (value: number) => {
238+
if (value !== 1) {
239+
selectedStartUsers.value = []
240+
emit('update:modelValue', {
241+
...modelData.value,
242+
startUserIds: []
243+
})
244+
}
245+
}
246+
247+
/** 处理管理员类型变化 */
248+
const handleManagerUserTypeChange = (value: number) => {
249+
if (value !== 1) {
250+
selectedManagerUsers.value = []
251+
emit('update:modelValue', {
252+
...modelData.value,
253+
managerUserIds: []
254+
})
255+
}
256+
}
257+
258+
/** 移除发起人 */
259+
const handleRemoveStartUser = (user: UserVO) => {
260+
selectedStartUsers.value = selectedStartUsers.value.filter((u) => u.id !== user.id)
261+
emit('update:modelValue', {
262+
...modelData.value,
263+
startUserIds: modelData.value.startUserIds.filter((id: number) => id !== user.id)
264+
})
265+
}
266+
267+
/** 移除管理员 */
268+
const handleRemoveManagerUser = (user: UserVO) => {
269+
selectedManagerUsers.value = selectedManagerUsers.value.filter((u) => u.id !== user.id)
270+
emit('update:modelValue', {
271+
...modelData.value,
272+
managerUserIds: modelData.value.managerUserIds.filter((id: number) => id !== user.id)
273+
})
274+
}
275+
276+
/** 表单校验 */
277+
const validate = async () => {
278+
await formRef.value?.validate()
279+
}
280+
281+
defineExpose({
282+
validate
283+
})
284+
</script>
285+
286+
<style lang="scss" scoped>
287+
.bg-gray-100 {
288+
background-color: #f5f7fa;
289+
transition: all 0.3s;
290+
291+
&:hover {
292+
background-color: #e6e8eb;
293+
}
294+
295+
.ep-close {
296+
font-size: 14px;
297+
color: #909399;
298+
transition: color 0.3s;
299+
300+
&:hover {
301+
color: #f56c6c;
302+
}
303+
}
304+
}
305+
</style>

0 commit comments

Comments
 (0)