feat(项目管理): 项目与权限成员页面搭建
This commit is contained in:
parent
7b0127a5ea
commit
a49eca779d
|
@ -19,11 +19,13 @@
|
||||||
class="pr-[5px]"
|
class="pr-[5px]"
|
||||||
:style="{
|
:style="{
|
||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
width: props.width ? props.width : `calc(100vw - ${menuWidth}px - 58px)`,
|
width: props.otherWidth
|
||||||
|
? `calc(100vw - ${menuWidth}px - ${props.otherWidth}px)`
|
||||||
|
: `calc(100vw - ${menuWidth}px - 58px)`,
|
||||||
height: props.autoHeight ? 'auto' : `calc(100vh - ${cardOverHeight}px)`,
|
height: props.autoHeight ? 'auto' : `calc(100vh - ${cardOverHeight}px)`,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="min-w-[1000px]">
|
<div :class="[`min-w-[${props.minWidth || 1000}px]`]">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</a-scrollbar>
|
</a-scrollbar>
|
||||||
|
@ -70,7 +72,8 @@
|
||||||
specialHeight: number; // 特殊高度,例如某些页面有面包屑
|
specialHeight: number; // 特殊高度,例如某些页面有面包屑
|
||||||
hideBack: boolean; // 隐藏返回按钮
|
hideBack: boolean; // 隐藏返回按钮
|
||||||
autoHeight: boolean; // 内容区域高度是否自适应
|
autoHeight: boolean; // 内容区域高度是否自适应
|
||||||
width?: string; // 卡片宽度
|
otherWidth?: number; // 该宽度为卡片外部同级容器的宽度
|
||||||
|
minWidth?: number; // 卡片最小宽度
|
||||||
hasBreadcrumb: boolean; // 是否有面包屑,如果有面包屑,高度需要减去面包屑的高度
|
hasBreadcrumb: boolean; // 是否有面包屑,如果有面包屑,高度需要减去面包屑的高度
|
||||||
noContentPadding: boolean; // 内容区域是否有padding
|
noContentPadding: boolean; // 内容区域是否有padding
|
||||||
handleBack: () => void; // 自定义返回按钮触发事件
|
handleBack: () => void; // 自定义返回按钮触发事件
|
||||||
|
|
|
@ -18,6 +18,12 @@ export enum ProjectManagementRouteEnum {
|
||||||
PROJECT_MANAGEMENT = 'projectManagement',
|
PROJECT_MANAGEMENT = 'projectManagement',
|
||||||
PROJECT_MANAGEMENT_INDEX = 'projectManagementIndex',
|
PROJECT_MANAGEMENT_INDEX = 'projectManagementIndex',
|
||||||
PROJECT_MANAGEMENT_LOG = 'projectManagementLog',
|
PROJECT_MANAGEMENT_LOG = 'projectManagementLog',
|
||||||
|
PROJECT_MANAGEMENT_PERMISSION = 'projectManagementPermission',
|
||||||
|
PROJECT_MANAGEMENT_PERMISSION_BASICINFO = 'projectManagementPermissionBasicInfo',
|
||||||
|
PROJECT_MANAGEMENT_PERMISSION_MENUMANAGEMENT = 'projectManagementPermissionMenuManagement',
|
||||||
|
PROJECT_MANAGEMENT_PERMISSION_VERSION = 'projectManagementPermissionVersion',
|
||||||
|
PROJECT_MANAGEMENT_PERMISSION_USERGROUP = 'projectManagementPermissionUserGroup',
|
||||||
|
PROJECT_MANAGEMENT_PERMISSION_MEMBER = 'projectManagementPermissionMember',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TestPlanRouteEnum {
|
export enum TestPlanRouteEnum {
|
||||||
|
|
|
@ -15,6 +15,7 @@ export enum TableKeyEnum {
|
||||||
SYSTEM_ORGANIZATION = 'systemOrganization',
|
SYSTEM_ORGANIZATION = 'systemOrganization',
|
||||||
SYSTEM_PROJECT = 'systemProject',
|
SYSTEM_PROJECT = 'systemProject',
|
||||||
SYSTEM_LOG = 'systemLog',
|
SYSTEM_LOG = 'systemLog',
|
||||||
|
PROJECT_MEMBER = 'projectMember',
|
||||||
ORGANIZATION_MEMBER = 'organizationMember',
|
ORGANIZATION_MEMBER = 'organizationMember',
|
||||||
ORGANIZATION_PROJECT = 'organizationProject',
|
ORGANIZATION_PROJECT = 'organizationProject',
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ export default {
|
||||||
'menu.uiTest': 'UI test',
|
'menu.uiTest': 'UI test',
|
||||||
'menu.performanceTest': 'Performance test',
|
'menu.performanceTest': 'Performance test',
|
||||||
'menu.projectManagement': 'Project management',
|
'menu.projectManagement': 'Project management',
|
||||||
|
'menu.projectManagement.projectPermission': 'Project Permission',
|
||||||
'menu.projectManagement.log': 'Log',
|
'menu.projectManagement.log': 'Log',
|
||||||
'menu.settings': 'Settings',
|
'menu.settings': 'Settings',
|
||||||
'menu.settings.system': 'System',
|
'menu.settings.system': 'System',
|
||||||
|
|
|
@ -27,6 +27,7 @@ export default {
|
||||||
'menu.performanceTest': '性能测试',
|
'menu.performanceTest': '性能测试',
|
||||||
'menu.projectManagement': '项目管理',
|
'menu.projectManagement': '项目管理',
|
||||||
'menu.projectManagement.log': '日志',
|
'menu.projectManagement.log': '日志',
|
||||||
|
'menu.projectManagement.projectPermission': '项目与权限',
|
||||||
'menu.settings': '系统设置',
|
'menu.settings': '系统设置',
|
||||||
'menu.settings.system': '系统',
|
'menu.settings.system': '系统',
|
||||||
'menu.settings.system.user': '用户',
|
'menu.settings.system.user': '用户',
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type { AppRouteRecordRaw } from '../types';
|
||||||
const ProjectManagement: AppRouteRecordRaw = {
|
const ProjectManagement: AppRouteRecordRaw = {
|
||||||
path: '/project-management',
|
path: '/project-management',
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT,
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT,
|
||||||
redirect: '/project-management/index',
|
redirect: '/project-management/permission',
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.projectManagement',
|
locale: 'menu.projectManagement',
|
||||||
|
@ -23,6 +23,71 @@ const ProjectManagement: AppRouteRecordRaw = {
|
||||||
roles: ['*'],
|
roles: ['*'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// 项目与权限
|
||||||
|
{
|
||||||
|
path: 'permission',
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION,
|
||||||
|
component: () => import('@/views/project-management/projectAndPermission/index.vue'),
|
||||||
|
redirect: '/project-management/permission/basicInfo',
|
||||||
|
meta: {
|
||||||
|
locale: 'menu.projectManagement.projectPermission',
|
||||||
|
roles: ['*'],
|
||||||
|
isTopMenu: true,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
// 基本信息
|
||||||
|
{
|
||||||
|
path: 'basicInfo',
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_BASICINFO,
|
||||||
|
component: () => import('@/views/project-management/projectAndPermission/basicInfos/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'project.permission.basicInfo',
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 菜单管理
|
||||||
|
{
|
||||||
|
path: 'menuManagement',
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENUMANAGEMENT,
|
||||||
|
component: () => import('@/views/project-management/projectAndPermission/menuManagement/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'project.permission.menuManagement',
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 项目版本
|
||||||
|
{
|
||||||
|
path: 'projectVersion',
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_VERSION,
|
||||||
|
component: () => import('@/views/project-management/projectAndPermission/projectVersion/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'project.permission.projectVersion',
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 成员
|
||||||
|
{
|
||||||
|
path: 'member',
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MEMBER,
|
||||||
|
component: () => import('@/views/project-management/projectAndPermission/member/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'menu.settings.system.member',
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 用户组
|
||||||
|
{
|
||||||
|
path: 'projectUserGroup',
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_USERGROUP,
|
||||||
|
component: () => import('@/views/project-management/projectAndPermission/userGroup/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'project.permission.userGroup',
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 项目日志
|
||||||
{
|
{
|
||||||
path: 'log',
|
path: 'log',
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_LOG,
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_LOG,
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div> 基本信息 waiting for development</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,134 @@
|
||||||
|
<template>
|
||||||
|
<div class="wrapper flex" :style="{ height: 'calc(100vh - 90px)' }">
|
||||||
|
<div class="left-menu-wrapper mr-[16px] w-[208px] min-w-[208px] bg-white p-[24px]">
|
||||||
|
<div class="left-content">
|
||||||
|
<div class="mb-2 font-medium">{{ t('project.permission.projectAndPermission') }}</div>
|
||||||
|
<div class="menu">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) of menuList"
|
||||||
|
:key="item.key"
|
||||||
|
class="menu-item px-2"
|
||||||
|
:class="{
|
||||||
|
'text-[--color-text-4]': item.level === 1,
|
||||||
|
'is-active': item.name === currentKey && item.level !== 1,
|
||||||
|
'cursor-pointer': item.level !== 1,
|
||||||
|
}"
|
||||||
|
:style="{
|
||||||
|
'border-top': item.level === 1 && index !== 0 ? '1px solid var(--color-border-2)' : 'none',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div @click="toggleMenu(item.name)">{{ t(item.title) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<MsCard simple :other-width="290" :min-width="700">
|
||||||
|
<router-view></router-view>
|
||||||
|
</MsCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onBeforeMount } from 'vue';
|
||||||
|
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const menuList = ref([
|
||||||
|
{
|
||||||
|
key: 'project',
|
||||||
|
title: 'project.permission.project',
|
||||||
|
level: 1,
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projectBasicInfo',
|
||||||
|
title: 'project.permission.basicInfo',
|
||||||
|
level: 2,
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_BASICINFO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projectMenuManage',
|
||||||
|
title: 'project.permission.menuManagement',
|
||||||
|
level: 2,
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENUMANAGEMENT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projectVersion',
|
||||||
|
title: 'project.permission.projectVersion',
|
||||||
|
level: 2,
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_VERSION,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'memberPermission',
|
||||||
|
title: 'project.permission.memberPermission',
|
||||||
|
level: 1,
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projectMember',
|
||||||
|
title: 'project.permission.member',
|
||||||
|
level: 2,
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MEMBER,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projectUserGroup',
|
||||||
|
title: 'project.permission.userGroup',
|
||||||
|
level: 2,
|
||||||
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_USERGROUP,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const currentKey = ref<string>('');
|
||||||
|
|
||||||
|
const toggleMenu = (itemName: string) => {
|
||||||
|
if (itemName) {
|
||||||
|
currentKey.value = itemName;
|
||||||
|
router.push({ name: itemName });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setInitRoute = () => {
|
||||||
|
if (route?.name) currentKey.value = route.name as string;
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
setInitRoute();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.left-menu-wrapper {
|
||||||
|
border-radius: 12px;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
box-shadow: 0 0 10px rgb(120 56 135/ 5%);
|
||||||
|
.left-content {
|
||||||
|
width: 100%;
|
||||||
|
.menu {
|
||||||
|
.menu-item {
|
||||||
|
height: 38px;
|
||||||
|
line-height: 38px;
|
||||||
|
font-family: 'PingFang SC';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-menu-wrapper {
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 0 10px rgb(120 56 135/ 5%);
|
||||||
|
@apply bg-white;
|
||||||
|
}
|
||||||
|
.is-active {
|
||||||
|
border-radius: 4px;
|
||||||
|
color: rgb(var(--primary-5));
|
||||||
|
background-color: rgb(var(--primary-1));
|
||||||
|
}
|
||||||
|
.rightTest {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,10 @@
|
||||||
|
export default {
|
||||||
|
'project.permission.projectAndPermission': 'Project & Permission',
|
||||||
|
'project.permission.project': 'Project',
|
||||||
|
'project.permission.basicInfo': 'Basic Info',
|
||||||
|
'project.permission.menuManagement': 'Menu Management',
|
||||||
|
'project.permission.projectVersion': 'Project Version',
|
||||||
|
'project.permission.memberPermission': 'Member Permission',
|
||||||
|
'project.permission.member': 'Member',
|
||||||
|
'project.permission.userGroup': 'User Group',
|
||||||
|
};
|
|
@ -0,0 +1,10 @@
|
||||||
|
export default {
|
||||||
|
'project.permission.projectAndPermission': '项目与权限',
|
||||||
|
'project.permission.project': '项目',
|
||||||
|
'project.permission.basicInfo': '基本信息',
|
||||||
|
'project.permission.menuManagement': '菜单管理',
|
||||||
|
'project.permission.projectVersion': '项目版本',
|
||||||
|
'project.permission.memberPermission': '成员权限',
|
||||||
|
'project.permission.member': '成员',
|
||||||
|
'project.permission.userGroup': '用户组',
|
||||||
|
};
|
|
@ -0,0 +1,84 @@
|
||||||
|
<template>
|
||||||
|
<MsDialog
|
||||||
|
v-model:visible="visible"
|
||||||
|
dialog-size="medium"
|
||||||
|
title="project.member.addMember"
|
||||||
|
:close="closeHandler"
|
||||||
|
:confirm="confirmFunHandler"
|
||||||
|
ok-text="project.member.add"
|
||||||
|
>
|
||||||
|
<div class="form">
|
||||||
|
<a-form ref="memberFormRef" :model="form" size="large" layout="vertical">
|
||||||
|
<a-form-item
|
||||||
|
field="memberIds"
|
||||||
|
:label="t('project.member.member')"
|
||||||
|
asterisk-position="end"
|
||||||
|
:rules="[{ required: true, message: t('project.member.selectMemberEmptyTip') }]"
|
||||||
|
>
|
||||||
|
<a-select v-model="form.memberIds" multiple :placeholder="t('project.member.selectMemberScope')" allow-clear>
|
||||||
|
<a-option v-for="item of memberList" :key="item.id" :value="item.id">{{ item.name }}</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="userRoleIds"
|
||||||
|
:label="t('project.member.tableColumnUserGroup')"
|
||||||
|
asterisk-position="end"
|
||||||
|
:rules="[{ required: true, message: t('project.member.selectUserEmptyTip') }]"
|
||||||
|
>
|
||||||
|
<a-select v-model="form.userRoleIds" multiple allow-clear :placeholder="t('project.member.selectUserScope')">
|
||||||
|
<a-option v-for="item of userGroupOptions" :key="item.id" :value="item.id">{{ item.name }}</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</MsDialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import MsDialog from '@/components/pure/ms-dialog/index.vue';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { addOrUpdate } from '@/api/modules/setting/serviceIntegration';
|
||||||
|
import { FormInstance, Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const visible = ref<boolean>(false);
|
||||||
|
const initFormValue = {
|
||||||
|
userRoleIds: [],
|
||||||
|
memberIds: [],
|
||||||
|
};
|
||||||
|
const form = ref({ ...initFormValue });
|
||||||
|
|
||||||
|
const memberList = ref([
|
||||||
|
{
|
||||||
|
id: '',
|
||||||
|
name: '全部',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const userGroupOptions = ref([
|
||||||
|
{
|
||||||
|
id: '',
|
||||||
|
name: '全部',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const memberFormRef = ref<FormInstance | null>(null);
|
||||||
|
|
||||||
|
const confirmFunHandler = async () => {
|
||||||
|
await memberFormRef.value?.validate().then(async (error) => {
|
||||||
|
if (!error) {
|
||||||
|
console.log(error);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeHandler = () => {
|
||||||
|
memberFormRef.value?.resetFields();
|
||||||
|
visible.value = false;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,209 @@
|
||||||
|
<template>
|
||||||
|
<div class="mb-4 grid grid-cols-4 gap-2">
|
||||||
|
<div class="col-span-2"
|
||||||
|
><a-button class="mr-3" type="primary" @click="addMember">{{ t('project.member.addMember') }}</a-button></div
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<a-select v-model="searchParams.userId">
|
||||||
|
<a-option v-for="item of userGroupListOptions" :key="item.value" :value="item.value">{{
|
||||||
|
t(item.name)
|
||||||
|
}}</a-option>
|
||||||
|
<template #prefix
|
||||||
|
><span>{{ t('project.member.tableColumnUserGroup') }}</span></template
|
||||||
|
>
|
||||||
|
</a-select></div
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<a-input-search
|
||||||
|
:max-length="250"
|
||||||
|
:placeholder="t('project.member.searchMember')"
|
||||||
|
@search="searchHandler"
|
||||||
|
@press-enter="searchHandler"
|
||||||
|
></a-input-search
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<ms-base-table
|
||||||
|
v-bind="propsRes"
|
||||||
|
:action-config="tableBatchActions"
|
||||||
|
@selected-change="handleTableSelect"
|
||||||
|
v-on="propsEvent"
|
||||||
|
@batch-action="handleTableBatch"
|
||||||
|
>
|
||||||
|
<template #userRole="{ record }">
|
||||||
|
<a-tooltip :content="(record.userRoleIdNameMap||[]).map((e: any) => e.name).join(',')">
|
||||||
|
<div v-if="!record.showUserSelect">
|
||||||
|
<a-tag
|
||||||
|
v-for="org of (record.userRoleIdNameMap || []).slice(0, 3)"
|
||||||
|
:key="org"
|
||||||
|
class="mr-[4px] border-[rgb(var(--primary-5))] bg-transparent !text-[rgb(var(--primary-5))]"
|
||||||
|
bordered
|
||||||
|
>
|
||||||
|
{{ org.name }}
|
||||||
|
</a-tag>
|
||||||
|
<a-tag
|
||||||
|
v-if="record.userRoleIdNameMap.length > 3"
|
||||||
|
class="mr-[4px] border-[rgb(var(--primary-5))] bg-transparent !text-[rgb(var(--primary-5))]"
|
||||||
|
bordered
|
||||||
|
>
|
||||||
|
+{{ record.userRoleIdNameMap.length - 3 }}
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
|
<a-select v-else v-model="record.selectUserList" multiple :max-tag-count="2">
|
||||||
|
<a-option v-for="item of userGroupOptions" :key="item.id" :value="item.id">{{ item.name }}</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<template #enable="{ record }">
|
||||||
|
<div v-if="record.enable" class="flex items-center">
|
||||||
|
<icon-check-circle-fill class="mr-[2px] text-[rgb(var(--success-6))]" />
|
||||||
|
{{ t('organization.member.statusEnable') }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex items-center text-[var(--color-text-4)]">
|
||||||
|
<MsIcon type="icon-icon_disable" class="mr-[2px]" />
|
||||||
|
{{ t('organization.member.statusDisable') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<MsRemoveButton
|
||||||
|
position="br"
|
||||||
|
:title="t('project.member.deleteMemberTip', { name: characterLimit(record.name) })"
|
||||||
|
:sub-title-tip="t('project.member.subTitle')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ms-base-table>
|
||||||
|
<AddMemberModal v-model:visible="addMemberVisible" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onBeforeMount } from 'vue';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
|
import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue';
|
||||||
|
import { getMemberList } from '@/api/modules/setting/member';
|
||||||
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
import { useTableStore, useUserStore } from '@/store';
|
||||||
|
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
|
import { characterLimit } from '@/utils';
|
||||||
|
import AddMemberModal from './components/addMemberModal.vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const tableStore = useTableStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const lastOrganizationId = userStore?.$state.lastOrganizationId;
|
||||||
|
|
||||||
|
const userGroupListOptions = ref([
|
||||||
|
{
|
||||||
|
id: '',
|
||||||
|
name: '全部',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1001',
|
||||||
|
name: '用户组1',
|
||||||
|
value: '1001',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const columns: MsTableColumn = [
|
||||||
|
{
|
||||||
|
title: 'project.member.tableColumnEmail',
|
||||||
|
dataIndex: 'email',
|
||||||
|
showInTable: true,
|
||||||
|
width: 200,
|
||||||
|
showTooltip: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'project.member.tableColumnName',
|
||||||
|
dataIndex: 'name',
|
||||||
|
showInTable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'project.member.tableColumnPhone',
|
||||||
|
dataIndex: 'phone',
|
||||||
|
showInTable: true,
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'project.member.tableColumnUserGroup',
|
||||||
|
slotName: 'userRole',
|
||||||
|
dataIndex: 'userRoleIdNameMap',
|
||||||
|
showInTable: true,
|
||||||
|
width: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'project.member.tableColumnStatus',
|
||||||
|
slotName: 'enable',
|
||||||
|
dataIndex: 'enable',
|
||||||
|
showInTable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'project.member.tableColumnActions',
|
||||||
|
slotName: 'action',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 80,
|
||||||
|
showInTable: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
tableStore.initColumn(TableKeyEnum.PROJECT_MEMBER, columns, 'drawer');
|
||||||
|
|
||||||
|
const tableBatchActions = {
|
||||||
|
baseAction: [
|
||||||
|
{
|
||||||
|
label: 'project.member.batchActionAddProject',
|
||||||
|
eventTag: 'batchAddProject',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'project.member.batchActionAddUserGroup',
|
||||||
|
eventTag: 'batchAddUserGroup',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableSelected = ref<(string | number)[]>([]);
|
||||||
|
|
||||||
|
const handleTableSelect = (selectArr: (string | number)[]) => {
|
||||||
|
tableSelected.value = selectArr;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getMemberList, {
|
||||||
|
tableKey: TableKeyEnum.PROJECT_MEMBER,
|
||||||
|
selectable: true,
|
||||||
|
showSetting: true,
|
||||||
|
scroll: {
|
||||||
|
x: 1000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const initData = async () => {
|
||||||
|
setLoadListParams({ organizationId: lastOrganizationId });
|
||||||
|
await loadList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchParams = ref({
|
||||||
|
userId: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const searchHandler = () => {};
|
||||||
|
|
||||||
|
const handleTableBatch = (actionItem: any) => {};
|
||||||
|
|
||||||
|
const userGroupOptions = ref([
|
||||||
|
{
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const addMemberVisible = ref<boolean>(false);
|
||||||
|
|
||||||
|
const addMember = () => {
|
||||||
|
addMemberVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
initData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,39 @@
|
||||||
|
export default {
|
||||||
|
'project.member.addMember': 'Add Member',
|
||||||
|
'project.member.updateMember': 'Update Member',
|
||||||
|
'project.member.searchMember': 'Search by name or email address',
|
||||||
|
'project.member.remove': 'Remove',
|
||||||
|
'project.member.edit': 'Edit',
|
||||||
|
'project.member.add': 'Add',
|
||||||
|
'project.member.batchActionAddProject': 'Add to project',
|
||||||
|
'project.member.batchActionAddUserGroup': 'Add to usergroup',
|
||||||
|
'project.member.tableEnable': 'Enabled',
|
||||||
|
'project.member.tableDisable': 'Disabled',
|
||||||
|
'project.member.tableColumnEmail': 'Email',
|
||||||
|
'project.member.tableColumnName': 'Name',
|
||||||
|
'project.member.tableColumnPhone': 'Phone',
|
||||||
|
'project.member.tableColumnPro': 'Project',
|
||||||
|
'project.member.tableColumnUserGroup': 'UserGroup',
|
||||||
|
'project.member.tableColumnStatus': 'Status',
|
||||||
|
'project.member.tableColumnActions': 'Actions',
|
||||||
|
'project.member.member': 'Member',
|
||||||
|
'project.member.selectMemberScope': 'Select the member you want to add. Multiple selection is supported',
|
||||||
|
'project.member.selectProjectScope': 'Select the project you want to add. Multiple selection is supported',
|
||||||
|
'project.member.selectMemberEmptyTip': 'The member can not be empty',
|
||||||
|
'project.member.selectProjectEmptyTip': 'The project can not be empty',
|
||||||
|
'project.member.selectUserEmptyTip': 'The user group can not be empty',
|
||||||
|
'project.member.Confirm': 'Confirm',
|
||||||
|
'project.member.Cancel': 'Cancel',
|
||||||
|
'project.member.deleteMemberTip': 'Are you sure to remove the user `{name}` ?',
|
||||||
|
'system.user.deleteUserTip': 'Are you sure to delete the user `{name}` ?',
|
||||||
|
'project.member.deleteMemberConfirm': 'Delete',
|
||||||
|
'project.member.deleteMemberCancel': 'Cancel',
|
||||||
|
'project.member.deleteMemberSuccess': 'Delete successful',
|
||||||
|
'project.member.batchModalSuccess': 'Successfully added',
|
||||||
|
'project.member.batchUpdateSuccess': 'Successfully updated',
|
||||||
|
'project.member.project': 'Project',
|
||||||
|
'project.member.selectUserScope': 'Please select a user group for the above members',
|
||||||
|
'project.member.statusEnable': 'Normal',
|
||||||
|
'project.member.statusDisable': 'Disabled',
|
||||||
|
'project.member.subTitle': 'When removed, you lose your organization privileges',
|
||||||
|
};
|
|
@ -0,0 +1,38 @@
|
||||||
|
export default {
|
||||||
|
'project.member.addMember': '添加成员',
|
||||||
|
'project.member.updateMember': '更新成员',
|
||||||
|
'project.member.searchMember': '通过名称或邮箱搜索搜索',
|
||||||
|
'project.member.remove': '移除',
|
||||||
|
'project.member.edit': '编辑',
|
||||||
|
'project.member.add': '添加',
|
||||||
|
'project.member.batchActionAddProject': '添加至项目',
|
||||||
|
'project.member.batchActionAddUserGroup': '添加至用户组',
|
||||||
|
'project.member.tableEnable': '正常',
|
||||||
|
'project.member.tableDisable': '禁用',
|
||||||
|
'project.member.tableColumnEmail': '邮箱',
|
||||||
|
'project.member.tableColumnName': '姓名',
|
||||||
|
'project.member.tableColumnPhone': '手机',
|
||||||
|
'project.member.tableColumnPro': '项目',
|
||||||
|
'project.member.tableColumnUserGroup': '用户组',
|
||||||
|
'project.member.tableColumnStatus': '状态',
|
||||||
|
'project.member.tableColumnActions': '操作',
|
||||||
|
'project.member.member': '成员',
|
||||||
|
'project.member.selectMemberScope': '请选择需要添加的成员支持多选',
|
||||||
|
'project.member.selectProjectScope': '请选择需要添加的项目支持多选',
|
||||||
|
'project.member.selectMemberEmptyTip': '成员不能为空',
|
||||||
|
'project.member.selectProjectEmptyTip': '项目不能为空',
|
||||||
|
'project.member.selectUserEmptyTip': '用户组不能为空',
|
||||||
|
'project.member.Confirm': '确定',
|
||||||
|
'project.member.Cancel': '取消',
|
||||||
|
'project.member.deleteMemberTip': '确认移除 {name} 这个成员吗?',
|
||||||
|
'project.member.deleteMemberConfirm': '确认删除',
|
||||||
|
'project.member.deleteMemberCancel': '取消',
|
||||||
|
'project.member.deleteMemberSuccess': '删除成功',
|
||||||
|
'project.member.batchModalSuccess': '添加成功',
|
||||||
|
'project.member.batchUpdateSuccess': '更新成功',
|
||||||
|
'project.member.project': '项目',
|
||||||
|
'project.member.selectUserScope': '请为以上成员选择用户组',
|
||||||
|
'project.member.statusEnable': '正常',
|
||||||
|
'project.member.statusDisable': '禁用',
|
||||||
|
'project.member.subTitle': '移除后,将失去组织权限',
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div> 菜单管理 waiting for development</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div>项目版本 waiting for development </div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div> 用户组 waiting for development</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
Loading…
Reference in New Issue