Skip to content

Commit cd69659

Browse files
committed
feat: 发起流程页面-增加搜索框、前端搜索功能完成;右侧展示所有流程,通过滚动或者点击,可以切换分类;鼠标hover时,展示描述
1 parent 5121d56 commit cd69659

File tree

1 file changed

+227
-56
lines changed
  • src/views/bpm/processInstance/create

1 file changed

+227
-56
lines changed

src/views/bpm/processInstance/create/index.vue

Lines changed: 227 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,74 @@
11
<template>
22
<!-- 第一步,通过流程定义的列表,选择对应的流程 -->
3-
<ContentWrap
4-
class="process-definition-container position-relative pb-20px"
5-
v-if="!selectProcessDefinition"
6-
v-loading="loading"
7-
>
8-
<el-row :gutter="20" class="!flex-nowrap">
9-
<el-col :span="5">
10-
<div class="flex flex-col">
11-
<div
12-
v-for="category in categoryList"
13-
:key="category.code"
14-
class="flex items-center p-10px cursor-pointer text-14px rounded-md"
15-
:class="categoryActive.code === category.code ? 'text-#3e7bff bg-#e8eeff' : ''"
16-
@click="handleCategoryClick(category)"
17-
>
18-
{{ category.name }}
3+
<template v-if="!selectProcessDefinition">
4+
<el-input
5+
v-model="currentSearchKey"
6+
class="!w-50% mb-15px"
7+
placeholder="请输入流程名称"
8+
clearable
9+
@keyup.enter="handleQuery"
10+
@clear="handleClear"
11+
>
12+
<template #prefix>
13+
<Icon icon="ep:search" />
14+
</template>
15+
</el-input>
16+
<ContentWrap
17+
:class="{ 'process-definition-container': filteredProcessDefinitionList?.length }"
18+
class="position-relative pb-20px h-700px"
19+
v-loading="loading"
20+
>
21+
<el-row v-if="filteredProcessDefinitionList?.length" :gutter="20" class="!flex-nowrap">
22+
<el-col :span="5">
23+
<div class="flex flex-col">
24+
<div
25+
v-for="category in categoryList"
26+
:key="category.code"
27+
class="flex items-center p-10px cursor-pointer text-14px rounded-md"
28+
:class="categoryActive.code === category.code ? 'text-#3e7bff bg-#e8eeff' : ''"
29+
@click="handleCategoryClick(category)"
30+
>
31+
{{ category.name }}
32+
</div>
1933
</div>
20-
</div>
21-
</el-col>
22-
<el-col :span="19">
23-
<h3 class="text-16px font-bold mb-10px mt-5px">{{ categoryActive.name }}</h3>
24-
<div class="grid grid-cols-3 gap3" v-if="categoryProcessDefinitionList.length">
25-
<el-card
26-
v-for="definition in categoryProcessDefinitionList"
27-
:key="definition.id"
28-
shadow="hover"
29-
class="cursor-pointer definition-item-card"
30-
@click="handleSelect(definition)"
31-
>
32-
<template #default>
33-
<div class="flex">
34-
<el-image :src="definition.icon" class="w-32px h-32px" />
35-
<el-text class="!ml-10px" size="large">{{ definition.name }}</el-text>
34+
</el-col>
35+
<el-col :span="19">
36+
<el-scrollbar ref="scrollWrapper" height="700">
37+
<div
38+
class="mb-20px pl-10px"
39+
v-for="(definitions, title) in processDefinitionGroup"
40+
:key="title"
41+
:ref="`category-${title}`"
42+
>
43+
<h3 class="text-18px font-bold mb-10px mt-5px">{{ title }}</h3>
44+
<div class="grid grid-cols-3 gap3">
45+
<el-tooltip
46+
v-for="definition in definitions"
47+
:key="definition.id"
48+
:content="definition.description"
49+
placement="top"
50+
>
51+
<el-card
52+
shadow="hover"
53+
class="cursor-pointer definition-item-card"
54+
@click="handleSelect(definition)"
55+
>
56+
<template #default>
57+
<div class="flex">
58+
<el-image :src="definition.icon" class="w-32px h-32px" />
59+
<el-text class="!ml-10px" size="large">{{ definition.name }}</el-text>
60+
</div>
61+
</template>
62+
</el-card>
63+
</el-tooltip>
3664
</div>
37-
</template>
38-
</el-card>
39-
</div>
40-
<el-empty v-else />
41-
</el-col>
42-
</el-row>
43-
</ContentWrap>
65+
</div>
66+
</el-scrollbar>
67+
</el-col>
68+
</el-row>
69+
<el-empty class="!py-200px" :image-size="200" description="没有找到搜索结果" v-else />
70+
</ContentWrap>
71+
</template>
4472

4573
<!-- 第二步,填写表单,进行流程的提交 -->
4674
<ProcessDefinitionDetail
@@ -56,12 +84,14 @@ import * as DefinitionApi from '@/api/bpm/definition'
5684
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
5785
import { CategoryApi } from '@/api/bpm/category'
5886
import ProcessDefinitionDetail from './ProcessDefinitionDetail.vue'
87+
import { groupBy } from 'lodash-es'
5988
6089
defineOptions({ name: 'BpmProcessInstanceCreate' })
6190
91+
const { proxy } = getCurrentInstance() as any
6292
const route = useRoute() // 路由
6393
const message = useMessage() // 消息
64-
94+
const currentSearchKey = ref('') // 当前搜索关键字
6595
const processInstanceId: any = route.query.processInstanceId
6696
const loading = ref(true) // 加载中
6797
const categoryList: any = ref([]) // 分类的列表
@@ -71,15 +101,10 @@ const processDefinitionList = ref([]) // 流程定义的列表
71101
const getList = async () => {
72102
loading.value = true
73103
try {
74-
// 流程分类
75-
categoryList.value = await CategoryApi.getCategorySimpleList()
76-
if (categoryList.value.length > 0) {
77-
categoryActive.value = categoryList.value[0]
78-
}
79-
// 流程定义
80-
processDefinitionList.value = await DefinitionApi.getProcessDefinitionList({
81-
suspensionState: 1
82-
})
104+
// 所有流程分类数据
105+
await getCategoryList()
106+
// 所有流程定义数据
107+
await getDefinitionList()
83108
84109
// 如果 processInstanceId 非空,说明是重新发起
85110
if (processInstanceId?.length > 0) {
@@ -102,11 +127,149 @@ const getList = async () => {
102127
}
103128
}
104129
105-
/** 选中分类对应的流程定义列表 */
106-
const categoryProcessDefinitionList: any = computed(() => {
107-
return processDefinitionList.value.filter(
108-
(item: any) => item.category == categoryActive.value.code
109-
)
130+
// 获取所有流程分类数据
131+
const getCategoryList = async () => {
132+
try {
133+
// 流程分类
134+
categoryList.value = await CategoryApi.getCategorySimpleList()
135+
if (categoryList.value.length > 0) {
136+
categoryActive.value = categoryList.value[0]
137+
}
138+
} finally {
139+
}
140+
}
141+
142+
// 获取所有流程定义数据
143+
const getDefinitionList = async () => {
144+
try {
145+
// 流程定义
146+
processDefinitionList.value = await DefinitionApi.getProcessDefinitionList({
147+
suspensionState: 1
148+
})
149+
/* 测试数据 */
150+
// processDefinitionList.value = [
151+
// {
152+
// id: 'business:3:fab1dceb-95be-11ef-8c7d-00a6181404fd',
153+
// version: 3,
154+
// name: '商务管理',
155+
// key: 'business',
156+
// icon: 'https://picsum.photos/200?r=2',
157+
// description: '商务管理',
158+
// category: 'test0',
159+
// categoryName: '分类0',
160+
// formType: 10,
161+
// formId: 27,
162+
// formName: null,
163+
// formConf:
164+
// '{"form":{"inline":false,"hideRequiredAsterisk":false,"labelPosition":"right","size":"default","labelWidth":"100px"},"resetBtn":{"show":false,"innerText":"重置"},"submitBtn":{"show":false,"innerText":"提交"}}',
165+
// formFields: [
166+
// '{"type":"input","field":"F1yrm2sosxgeabc","title":"请假原因","info":"","$required":false,"props":{"type":"text","placeholder":"请输入123"},"_fc_id":"id_Fhrbm2sosxgeacc","name":"ref_Festm2sosxgeadc","display":true,"hidden":false,"_fc_drag_tag":"input"}',
167+
// '{"type":"radio","field":"F9r3m2sp1b34aec","title":"请假类型","info":"","$required":false,"props":{"_optionType":2},"_fc_id":"id_F4nwm2sp1b34afc","name":"ref_Fkodm2sp1b34agc","display":true,"hidden":false,"_fc_drag_tag":"radio","options":[{"label":"事假","value":"1"},{"label":"婚假","value":"2"},{"label":"丧假","value":"3"}]}',
168+
// '{"type":"datePicker","field":"Finom2tsbwbpadc","title":"请假时间段","info":"","$required":false,"props":{"type":"datetimerange"},"_fc_id":"id_F028m2tsbwbpaec","name":"ref_F0okm2tsbwbpafc","display":true,"hidden":false,"_fc_drag_tag":"dateRange"}'
169+
// ],
170+
// formCustomCreatePath: '',
171+
// formCustomViewPath: '',
172+
// suspensionState: 1,
173+
// deploymentTime: null,
174+
// bpmnXml: null,
175+
// startUserSelectTasks: null
176+
// },
177+
// {
178+
// id: 'oa_leave:1:6e5ac269-5f87-11ef-bdb6-00a6181404fd',
179+
// version: 1,
180+
// name: 'oa_leave',
181+
// key: 'oa_leave',
182+
// icon: null,
183+
// description: 'oa_leave',
184+
// category: 'etst',
185+
// categoryName: '分类1',
186+
// formType: 20,
187+
// formId: null,
188+
// formName: null,
189+
// formConf: null,
190+
// formFields: null,
191+
// formCustomCreatePath: '/bpm/oa/leave/create',
192+
// formCustomViewPath: '/bpm/oa/leave/detail',
193+
// suspensionState: 1,
194+
// deploymentTime: null,
195+
// bpmnXml: null,
196+
// startUserSelectTasks: null
197+
// },
198+
// {
199+
// id: 'oa_leave:3:c9d06889-94fd-11ef-bf08-00a6181404fd',
200+
// version: 3,
201+
// name: '请假流程',
202+
// key: 'oa_leave',
203+
// icon: 'https://picsum.photos/200?r=1',
204+
// description: '请假流程',
205+
// category: 'test3',
206+
// categoryName: '分类3',
207+
// formType: 10,
208+
// formId: 27,
209+
// formName: null,
210+
// formConf:
211+
// '{"form":{"inline":false,"hideRequiredAsterisk":false,"labelPosition":"right","size":"default","labelWidth":"100px"},"resetBtn":{"show":false,"innerText":"重置"},"submitBtn":{"show":true,"innerText":"提交"}}',
212+
// formFields: [
213+
// '{"type":"input","field":"F1yrm2sosxgeabc","title":"请假原因","info":"","$required":false,"props":{"type":"text","placeholder":"请输入123"},"_fc_id":"id_Fhrbm2sosxgeacc","name":"ref_Festm2sosxgeadc","display":true,"hidden":false,"_fc_drag_tag":"input"}',
214+
// '{"type":"radio","field":"F9r3m2sp1b34aec","title":"请假类型","info":"","$required":false,"props":{"_optionType":2},"_fc_id":"id_F4nwm2sp1b34afc","name":"ref_Fkodm2sp1b34agc","display":true,"hidden":false,"_fc_drag_tag":"radio","options":[{"label":"事假","value":"1"},{"label":"婚假","value":"2"},{"label":"丧假","value":"3"}]}'
215+
// ],
216+
// formCustomCreatePath: 'bpm/oa/leave/create',
217+
// formCustomViewPath: 'bpm/oa/leave/create',
218+
// suspensionState: 1,
219+
// deploymentTime: null,
220+
// bpmnXml: null,
221+
// startUserSelectTasks: null
222+
// }
223+
// ]
224+
/* 测试数据 */
225+
// processDefinitionList.value = [
226+
// ...processDefinitionList.value,
227+
// ...processDefinitionList.value,
228+
// ...processDefinitionList.value,
229+
// ...processDefinitionList.value,
230+
// ...processDefinitionList.value,
231+
// ...processDefinitionList.value,
232+
// ...processDefinitionList.value,
233+
// ...processDefinitionList.value,
234+
// ...processDefinitionList.value,
235+
// ...processDefinitionList.value,
236+
// ...processDefinitionList.value,
237+
// ...processDefinitionList.value,
238+
// ...processDefinitionList.value,
239+
// ...processDefinitionList.value,
240+
// ...processDefinitionList.value,
241+
// ...processDefinitionList.value
242+
// ]
243+
// 初始化过滤列表为全部流程定义
244+
filteredProcessDefinitionList.value = processDefinitionList.value
245+
} finally {
246+
}
247+
}
248+
249+
const filteredProcessDefinitionList = ref([]) // 用于存储搜索过滤后的流程定义
250+
// 直接进行前端搜索
251+
const handleQuery = () => {
252+
if (currentSearchKey.value.trim()) {
253+
// 如果有搜索关键字,进行过滤
254+
filteredProcessDefinitionList.value = processDefinitionList.value.filter(
255+
(definition: any) =>
256+
definition.name.toLowerCase().includes(currentSearchKey.value.toLowerCase()) // 假设搜索依据是流程定义的名称
257+
)
258+
} else {
259+
// 如果没有搜索关键字,恢复所有数据
260+
filteredProcessDefinitionList.value = processDefinitionList.value
261+
}
262+
}
263+
264+
// 监听input `clearable` 事件
265+
const handleClear = () => {
266+
filteredProcessDefinitionList.value = processDefinitionList.value
267+
}
268+
269+
// 流程定义的分组
270+
const processDefinitionGroup: any = computed(() => {
271+
if (!processDefinitionList.value?.length) return {}
272+
return groupBy(filteredProcessDefinitionList.value, 'categoryName')
110273
})
111274
112275
// ========== 表单相关 ==========
@@ -122,8 +285,16 @@ const handleSelect = async (row, formVariables?) => {
122285
processDefinitionDetailRef.value?.initProcessInfo(row, formVariables)
123286
}
124287
// 左侧分类切换
125-
const handleCategoryClick = (val: number) => {
126-
categoryActive.value = val
288+
const handleCategoryClick = (category) => {
289+
categoryActive.value = category
290+
const categoryRef = proxy.$refs[`category-${category.name}`] // 获取点击分类对应的 DOM 元素
291+
if (categoryRef?.length) {
292+
const scrollWrapper = proxy.$refs.scrollWrapper // 获取右侧滚动容器
293+
const categoryOffsetTop = categoryRef[0].offsetTop
294+
295+
// 滚动到对应位置
296+
scrollWrapper.scrollTo({ top: categoryOffsetTop, behavior: 'smooth' })
297+
}
127298
}
128299
129300
/** 初始化 */

0 commit comments

Comments
 (0)