feat(projects): 微调
This commit is contained in:
@@ -2,6 +2,8 @@ import { computed, defineComponent, h, ref } from 'vue';
|
||||
import type { Component, PropType } from 'vue';
|
||||
import { ElButton, ElPopover, ElTooltip } from 'element-plus';
|
||||
import { $t } from '@/locales';
|
||||
import IconMdiDotsHorizontal from '~icons/mdi/dots-horizontal';
|
||||
import IconMdiChevronDown from '~icons/mdi/chevron-down';
|
||||
|
||||
export type BusinessTableAction = {
|
||||
key: string;
|
||||
@@ -162,11 +164,11 @@ export default defineComponent({
|
||||
onClick={event => event.stopPropagation()}
|
||||
>
|
||||
{props.variant === 'icon' ? (
|
||||
<icon-mdi-dots-horizontal class="business-table-action-icon" />
|
||||
<IconMdiDotsHorizontal class="business-table-action-icon" />
|
||||
) : (
|
||||
<span class="inline-flex items-center gap-4px">
|
||||
{$t('common.more')}
|
||||
<icon-mdi-chevron-down class="text-14px" />
|
||||
<IconMdiChevronDown class="text-14px" />
|
||||
</span>
|
||||
)}
|
||||
</ElButton>
|
||||
|
||||
84
src/components/custom/current-user-role-tags.vue
Normal file
84
src/components/custom/current-user-role-tags.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { ElTag } from 'element-plus';
|
||||
|
||||
defineOptions({ name: 'CurrentUserRoleTags' });
|
||||
|
||||
interface Props {
|
||||
/** 当前登录用户在该对象(产品/项目)的角色;无角色为 []。后端只读计算字段,随登录身份变化 */
|
||||
roles?: Api.Common.CurrentUserRole[] | null;
|
||||
/** 无业务角色时的占位文案 */
|
||||
emptyText?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), { roles: () => [], emptyText: '--' });
|
||||
|
||||
/**
|
||||
* 角色族按 roleKey 后缀匹配。
|
||||
*
|
||||
* 后端 roleKey 为域前缀风格:product_manager / project_manager / product_creator /
|
||||
* project_creator / *_observer 等(见 src/constants/business.ts 的经理 code);
|
||||
* 文档示例里的裸 creator / implicit_observer 不是真实 key,故不能按字面量精确匹配。
|
||||
*/
|
||||
function isManagerRole(roleKey: string) {
|
||||
return /manager$/i.test(roleKey);
|
||||
}
|
||||
|
||||
function isCreatorRole(roleKey: string) {
|
||||
return /creator$/i.test(roleKey);
|
||||
}
|
||||
|
||||
/** 系统隐式角色:创建者 / 隐式观察者,弱化为淡灰标签 */
|
||||
function isMuted(roleKey: string) {
|
||||
return isCreatorRole(roleKey) || /observer$/i.test(roleKey) || roleKey.includes('implicit');
|
||||
}
|
||||
|
||||
const items = computed(() => {
|
||||
const roles = props.roles ?? [];
|
||||
// 当前用户是产品经理 / 项目经理时,隐藏创建者标签(隐式观察者不受影响)
|
||||
const hasManager = roles.some(role => isManagerRole(role.roleKey));
|
||||
const visibleRoles = hasManager ? roles.filter(role => !isCreatorRole(role.roleKey)) : roles;
|
||||
|
||||
return visibleRoles.map((role, index) => ({
|
||||
key: `${role.roleKey}-${index}`,
|
||||
roleName: role.roleName,
|
||||
muted: isMuted(role.roleKey)
|
||||
}));
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="items.length" class="current-user-role-tags">
|
||||
<ElTag
|
||||
v-for="item in items"
|
||||
:key="item.key"
|
||||
size="small"
|
||||
effect="plain"
|
||||
round
|
||||
:type="item.muted ? 'info' : 'primary'"
|
||||
:class="{ 'current-user-role-tags__muted': item.muted }"
|
||||
>
|
||||
{{ item.roleName }}
|
||||
</ElTag>
|
||||
</div>
|
||||
<span v-else class="current-user-role-tags__empty">{{ emptyText }}</span>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.current-user-role-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// 列设置 align="center" 只影响文本流;flex 容器需显式居中标签
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
// 隐式角色(创建者 / 隐式观察者)弱化:在灰色 info 标签基础上再降透明度
|
||||
.current-user-role-tags__muted {
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.current-user-role-tags__empty {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user