refactor: 优化 BPM 工作流相关组件,更新用户组显示逻辑,调整图标样式

pull/103/head
ziye 2025-05-13 01:04:32 +08:00
parent d5321bc34a
commit acf3d9a6f0
6 changed files with 56 additions and 39 deletions

View File

@ -42,6 +42,21 @@ const [Grid, gridApi] = useVbenVxeGrid({
...formValues, ...formValues,
}); });
}, },
querySuccess: (params) => {
const { list } = params.response;
const userMap = new Map(
userList.value.map((user) => [user.id, user.nickname]),
);
list.forEach(
(item: BpmUserGroupApi.UserGroupVO & { nicknames?: string }) => {
item.nicknames = item.userIds
.map((userId) => userMap.get(userId))
.filter(Boolean)
.join('、');
},
);
},
}, },
}, },
rowConfig: { rowConfig: {
@ -126,16 +141,8 @@ onMounted(async () => {
</Button> </Button>
</template> </template>
<!-- TODO @ziye可以在 data 里翻译哈 -->
<template #userIds-cell="{ row }"> <template #userIds-cell="{ row }">
<span <span>{{ row.nicknames }}</span>
v-for="(userId, index) in row.userIds"
:key="userId"
class="pr-5px"
>
{{ userList.find((user) => user.id === userId)?.nickname }}
<span v-if="index < row.userIds.length - 1"></span>
</span>
</template> </template>
</Grid> </Grid>
</Page> </Page>

View File

@ -265,18 +265,18 @@ onMounted(() => {
width: '100%', width: '100%',
}" }"
> >
<!-- TODO @ziye使用名字作为图标缺少了 -->
<div class="flex items-center"> <div class="flex items-center">
<img <img
v-if="definition.icon" v-if="definition.icon"
:src="definition.icon" :src="definition.icon"
class="h-12 w-12 object-contain" class="flow-icon-img object-contain"
alt="流程图标" alt="流程图标"
/> />
<div v-else class="flow-icon flex-shrink-0"> <div v-else class="flow-icon flex-shrink-0">
<Tooltip :title="definition.name"> <Tooltip :title="definition.name">
<span class="text-xs text-white"> <span class="text-xs text-white">
{{ definition.name }} {{ definition.name?.slice(0, 2) }}
</span> </span>
</Tooltip> </Tooltip>
</div> </div>
@ -325,19 +325,26 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.process-definition-container { .process-definition-container {
.definition-item-card { .definition-item-card {
.flow-icon-img {
width: 48px;
height: 48px;
border-radius: 0.25rem;
}
.flow-icon { .flow-icon {
@apply bg-primary;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 32px; width: 48px;
height: 32px; height: 48px;
background-color: #3f73f7; border-radius: 0.25rem;
border-radius: 50%;
} }
&.search-match { &.search-match {
background-color: rgb(63 115 247 / 10%); background-color: rgb(63 115 247 / 10%);
border: 1px solid #3f73f7; border: 1px solid var(--primary);
animation: bounce 0.5s ease; animation: bounce 0.5s ease;
} }
} }

View File

@ -5,12 +5,6 @@ import type { SystemUserApi } from '#/api/system/user';
import { nextTick, onMounted, ref } from 'vue'; import { nextTick, onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import {
SvgBpmApproveIcon,
SvgBpmCancelIcon,
SvgBpmRejectIcon,
SvgBpmRunningIcon,
} from '@vben/icons';
import { formatDateTime } from '@vben/utils'; import { formatDateTime } from '@vben/utils';
import { import {
@ -38,6 +32,12 @@ import {
registerComponent, registerComponent,
setConfAndFields2, setConfAndFields2,
} from '#/utils'; } from '#/utils';
import {
SvgBpmApproveIcon,
SvgBpmCancelIcon,
SvgBpmRejectIcon,
SvgBpmRunningIcon,
} from '#/views/bpm/processInstance/detail/modules/icons';
import ProcessInstanceTimeline from './modules/time-line.vue'; import ProcessInstanceTimeline from './modules/time-line.vue';

View File

@ -0,0 +1,14 @@
import { createIconifyIcon } from '@vben/icons';
// bpm 图标
const SvgBpmRunningIcon = createIconifyIcon('svg:bpm-running');
const SvgBpmApproveIcon = createIconifyIcon('svg:bpm-approve');
const SvgBpmRejectIcon = createIconifyIcon('svg:bpm-reject');
const SvgBpmCancelIcon = createIconifyIcon('svg:bpm-cancel');
export {
SvgBpmApproveIcon,
SvgBpmCancelIcon,
SvgBpmRejectIcon,
SvgBpmRunningIcon,
};

View File

@ -10,6 +10,7 @@ import { formatDateTime, isEmpty } from '@vben/utils';
import { Avatar, Button, Image, Tooltip } from 'ant-design-vue'; import { Avatar, Button, Image, Tooltip } from 'ant-design-vue';
import { TimeLine } from '#/components/time-line';
import { UserSelectModal } from '#/components/user-select-modal'; import { UserSelectModal } from '#/components/user-select-modal';
import { import {
BpmCandidateStrategyEnum, BpmCandidateStrategyEnum,
@ -215,12 +216,11 @@ const handleUserSelectCancel = () => {
}; };
</script> </script>
<!-- TODO @ziyeantd 组件使用大写哈目前项目风格是这样的 -->
<template> <template>
<div> <div>
<a-timeline class="pt-20px"> <TimeLine class="pt-20px">
<!-- 遍历每个审批节点 --> <!-- 遍历每个审批节点 -->
<a-timeline-item <TimeLine.Item
v-for="(activity, index) in activityNodes" v-for="(activity, index) in activityNodes"
:key="index" :key="index"
:color="getApprovalNodeColor(activity.status)" :color="getApprovalNodeColor(activity.status)"
@ -449,8 +449,8 @@ const handleUserSelectCancel = () => {
</div> </div>
</div> </div>
</div> </div>
</a-timeline-item> </TimeLine.Item>
</a-timeline> </TimeLine>
<!-- 用户选择弹窗 --> <!-- 用户选择弹窗 -->
<UserSelectModal <UserSelectModal

View File

@ -12,13 +12,6 @@ const SvgBellIcon = createIconifyIcon('svg:bell');
const SvgCakeIcon = createIconifyIcon('svg:cake'); const SvgCakeIcon = createIconifyIcon('svg:cake');
const SvgAntdvLogoIcon = createIconifyIcon('svg:antdv-logo'); const SvgAntdvLogoIcon = createIconifyIcon('svg:antdv-logo');
// bpm 图标
// TODO @ziye这个看看是不是拿到 bpm 模块里,不放在这里;因为有些团队,用不到 bpm 哈
const SvgBpmRunningIcon = createIconifyIcon('svg:bpm-running');
const SvgBpmApproveIcon = createIconifyIcon('svg:bpm-approve');
const SvgBpmRejectIcon = createIconifyIcon('svg:bpm-reject');
const SvgBpmCancelIcon = createIconifyIcon('svg:bpm-cancel');
export { export {
SvgAntdvLogoIcon, SvgAntdvLogoIcon,
SvgAvatar1Icon, SvgAvatar1Icon,
@ -26,10 +19,6 @@ export {
SvgAvatar3Icon, SvgAvatar3Icon,
SvgAvatar4Icon, SvgAvatar4Icon,
SvgBellIcon, SvgBellIcon,
SvgBpmApproveIcon,
SvgBpmCancelIcon,
SvgBpmRejectIcon,
SvgBpmRunningIcon,
SvgCakeIcon, SvgCakeIcon,
SvgCardIcon, SvgCardIcon,
SvgDownloadIcon, SvgDownloadIcon,