feat: system

This commit is contained in:
wangdan-fit2cloud 2025-06-17 16:11:07 +08:00
parent 3aa804f666
commit bdedf49a71
9 changed files with 134 additions and 60 deletions

View File

@ -12,13 +12,12 @@ Object.defineProperty(prefix, 'value', {
},
})
/**
*
* @query
*/
const getUserList: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) => {
return get(`${prefix}/user_list`, undefined, loading)
return get(`${prefix.value}/user_list`, undefined, loading)
}
/**
@ -29,7 +28,7 @@ const getResourceAuthorization: (
user_id: string,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (user_id, loading) => {
return get(`${prefix}/user_resource_permission/user/${user_id}`, undefined, loading)
return get(`${prefix.value}/user_resource_permission/user/${user_id}`, undefined, loading)
}
/**
@ -55,10 +54,10 @@ const putResourceAuthorization: (
body: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (user_id, body, loading) => {
return put(`${prefix}/user_resource_permission/user/${user_id}`, body, loading)
return put(`${prefix.value}/user_resource_permission/user/${user_id}`, body, loading)
}
const getUserMember: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) => {
return get(`${prefix}/user_member`, undefined, loading)
return get(`${prefix.value}/user_member`, undefined, loading)
}
export default {
getResourceAuthorization,

View File

@ -0,0 +1,30 @@
import { get, post, del } from '@/request/index'
import type { Ref } from 'vue'
import { Result } from '@/request/Result'
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, RoleMemberItem, CreateMemberParamsItem } from '@/api/type/role'
import { RoleTypeEnum } from '@/enums/system'
import type { pageRequest, PageList } from '@/api/type/common'
const prefix = '/workspace/role'
/**
*
*/
const getRoleList: (loading?: Ref<boolean>) => Promise<Result<{ internal_role: RoleItem[], custom_role: RoleItem[] }>> = (loading) => {
return get(`${prefix}`, undefined, loading)
}
/**
*
*/
const CreateMember: (
role_id: string,
data: { members: CreateMemberParamsItem[] },
loading?: Ref<boolean>,
) => Promise<Result<any>> = (role_id, data, loading) => {
return post(`${prefix}/${role_id}/add_member`, data, undefined, loading)
}
export default {
getRoleList,
CreateMember,
}

View File

@ -166,4 +166,3 @@ export const iconMap: any = {
// 动态加载的图标
...dynamicIcons,
}
console.log(iconMap);

View File

@ -1,4 +1,4 @@
import { Role, ComplexPermission } from '@/utils/permission/type'
import { PermissionConst, EditionConst, RoleConst } from '@/utils/permission/data'
const systemRouter = {
path: '/system',
name: 'system',
@ -42,6 +42,7 @@ const systemRouter = {
activeMenu: '/system',
parentPath: '/system',
parentName: 'system',
permission: [EditionConst.IS_EE],
},
component: () => import('@/views/role/index.vue'),
},
@ -55,6 +56,7 @@ const systemRouter = {
activeMenu: '/system',
parentPath: '/system',
parentName: 'system',
permission: [EditionConst.IS_EE],
},
component: () => import('@/views/workspace/index.vue'),
},
@ -68,6 +70,7 @@ const systemRouter = {
activeMenu: '/system',
parentPath: '/system',
parentName: 'system',
permission: [EditionConst.IS_EE],
},
children: [
{
@ -115,6 +118,7 @@ const systemRouter = {
activeMenu: '/system',
parentPath: '/system',
parentName: 'system',
permission: [EditionConst.IS_PE, EditionConst.IS_EE],
},
children: [
{
@ -172,7 +176,7 @@ const systemRouter = {
activeMenu: '/system',
parentPath: '/system',
parentName: 'system',
//permission: new ComplexPermission(['ADMIN'], ['x-pack'], 'AND')
permission: [EditionConst.IS_PE, EditionConst.IS_EE],
},
component: () => import('@/views/theme/index.vue'),
},
@ -184,7 +188,7 @@ const systemRouter = {
activeMenu: '/system',
parentPath: '/system',
parentName: 'system',
//permission: new ComplexPermission(['ADMIN'], ['x-pack'], 'AND')
permission: [EditionConst.IS_PE, EditionConst.IS_EE],
},
component: () => import('@/views/authentication/index.vue'),
},

View File

@ -0,0 +1,28 @@
import { PermissionConst, EditionConst, RoleConst } from '@/utils/permission/data'
import { hasPermission } from '@/utils/permission/index'
import roleSystemApi from '@/api/system/role'
import roleWorkspaceApi from '@/api/workspace/role'
// 系统管理员 API
const systemApiMap = {
role: roleSystemApi,
} as any
// 企业版工作空间管理员 API
const workspaceApiMap = {
role: roleWorkspaceApi,
} as any
/** API
* loadPermissionApi('role')
*/
export function loadPermissionApi(type: string) {
if (hasPermission([EditionConst.IS_EE, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole], 'AND')) {
// 加载企业版工作空间管理员 API
return workspaceApiMap[type]
} else {
// 加载系统管理员 API
return systemApiMap[type]
}
}

View File

@ -22,13 +22,13 @@
</el-avatar>
<LogoIcon
v-else-if="isApplication"
v-if="isApplication"
height="28px"
style="width: 28px; height: 28px; display: block"
class="mr-12"
/>
<el-avatar
v-if="row.isFolder"
v-else-if="row.isFolder"
class="mr-12"
shape="square"
:size="20"

View File

@ -33,6 +33,7 @@ import { t } from '@/locales'
import type { RoleItem } from '@/api/type/role'
import { MsgSuccess } from '@/utils/message'
import { RoleTypeEnum } from '@/enums/system'
import { loadPermissionApi } from '@/utils/permission-api'
const props = defineProps<{
currentRole?: RoleItem
@ -140,7 +141,7 @@ function handleAdd() {
if (props.currentRole?.type === RoleTypeEnum.ADMIN) {
params = list.value.map((item) => ({ user_ids: item.user_ids, workspace_ids: ['None'] }))
}
await RoleApi.CreateMember(
await loadPermissionApi('role').CreateMember(
props.currentRole?.id as string,
{ members: params ?? list.value },
loading,

View File

@ -5,23 +5,30 @@
<div class="flex h-full">
<div class="role-left border-r p-16">
<div class="p-8 pb-0">
<el-input v-model="filterText" :placeholder="$t('common.search')" prefix-icon="Search"
clearable/>
<el-input
v-model="filterText"
:placeholder="$t('common.search')"
prefix-icon="Search"
clearable
/>
</div>
<div class="list-height-left mt-8">
<el-scrollbar v-loading="loading">
<div class="role-left_title color-secondary lighter">
<span>{{ $t('views.role.internalRole') }}</span>
</div>
<common-list :data="filterInternalRole" @click="clickRole"
:default-active="currentRole?.id">
<common-list
:data="filterInternalRole"
@click="clickRole"
:default-active="currentRole?.id"
>
<template #default="{ row }">
<div class="flex-between">
<span class="mr-8">{{ row.role_name }}</span>
<el-dropdown :teleported="false">
<el-button text>
<el-icon class="color-secondary">
<MoreFilled/>
<MoreFilled />
</el-icon>
</el-button>
<template #dropdown>
@ -44,32 +51,37 @@
</template>
</common-list>
<div class="role-left_divider">
<el-divider/>
<el-divider />
</div>
<div class="role-left_title">
<span class="color-secondary lighter">{{ $t('views.role.customRole') }}</span>
<el-tooltip effect="dark"
<el-tooltip
effect="dark"
:content="`${$t('common.create')}${$t('views.role.customRole')}`"
placement="top">
placement="top"
>
<el-button type="primary" text @click="createOrUpdateRole()">
<AppIcon iconName="app-copy"></AppIcon>
</el-button>
</el-tooltip>
</div>
<common-list :data="filterCustomRole" @click="clickRole"
:default-active="currentRole?.id">
<common-list
:data="filterCustomRole"
@click="clickRole"
:default-active="currentRole?.id"
>
<template #default="{ row }">
<div class="flex-between">
<span>
{{ row.role_name }}
<span class="color-input-placeholder ml-4">({{
roleTypeMap[row.type as RoleTypeEnum]
}})</span>
<span class="color-input-placeholder ml-4"
>({{ roleTypeMap[row.type as RoleTypeEnum] }})</span
>
</span>
<el-dropdown :teleported="false">
<el-button text>
<el-icon class="color-secondary">
<MoreFilled/>
<MoreFilled />
</el-icon>
</el-button>
<template #dropdown>
@ -101,46 +113,53 @@
<div class="flex align-center">
<span>
{{ currentRole?.role_name }}
<span v-if="currentRole?.type && !currentRole.internal"
class="color-input-placeholder ml-4">({{
roleTypeMap[currentRole?.type as
RoleTypeEnum]
}})
<span
v-if="currentRole?.type && !currentRole.internal"
class="color-input-placeholder ml-4"
>({{ roleTypeMap[currentRole?.type as RoleTypeEnum] }})
</span>
</span>
<el-divider direction="vertical" class="mr-8 ml-8"/>
<AppIcon iconName="app-wordspace" style="font-size: 16px"
class="color-input-placeholder"></AppIcon>
<el-divider direction="vertical" class="mr-8 ml-8" />
<AppIcon
iconName="app-wordspace"
style="font-size: 16px"
class="color-input-placeholder"
></AppIcon>
<span class="color-input-placeholder ml-4">
{{ currentRole?.user_count }}
</span>
</div>
<el-radio-group v-model="currentTab">
<el-radio-button v-for="item in tabList" :key="item.value" :label="item.label"
:value="item.value"/>
<el-radio-button
v-for="item in tabList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-radio-group>
</div>
<PermissionConfiguration v-if="currentTab === 'permission'" :currentRole="currentRole"/>
<Member v-else :currentRole="currentRole"/>
<PermissionConfiguration v-if="currentTab === 'permission'" :currentRole="currentRole" />
<Member v-else :currentRole="currentRole" />
</div>
</div>
</el-card>
<CreateOrUpdateRoleDialog ref="createOrUpdateRoleDialogRef" @refresh="refresh"/>
<CreateOrUpdateRoleDialog ref="createOrUpdateRoleDialogRef" @refresh="refresh" />
</div>
</template>
<script lang="ts" setup>
import {onMounted, ref, watch} from 'vue'
import { onMounted, ref, watch } from 'vue'
import RoleApi from '@/api/system/role'
import {t} from '@/locales'
import { t } from '@/locales'
import PermissionConfiguration from './component/PermissionConfiguration.vue'
import Member from './component/Member.vue'
import CreateOrUpdateRoleDialog from './component/CreateOrUpdateRoleDialog.vue'
import type {RoleItem} from '@/api/type/role'
import {RoleTypeEnum} from '@/enums/system'
import {roleTypeMap} from './index'
import {MsgSuccess, MsgConfirm} from '@/utils/message'
import type { RoleItem } from '@/api/type/role'
import { RoleTypeEnum } from '@/enums/system'
import { roleTypeMap } from './index'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { loadPermissionApi } from '@/utils/permission-api'
const filterText = ref('')
const loading = ref(false)
@ -152,7 +171,7 @@ const currentRole = ref<RoleItem>()
async function getRole() {
try {
const res = await RoleApi.getRoleList(loading)
const res = await loadPermissionApi('role').getRoleList(loading)
internalRoleList.value = res.data.internal_role
customRoleList.value = res.data.custom_role
filterInternalRole.value = filter(internalRoleList.value, filterText.value)
@ -168,7 +187,7 @@ onMounted(async () => {
})
async function refresh(role?: RoleItem) {
await getRole();
await getRole()
//
currentRole.value = role ? role : currentRole.value
}
@ -177,9 +196,7 @@ function filter(list: RoleItem[], filterText: string) {
if (!filterText.length) {
return list
}
return list.filter((v: RoleItem) =>
v.role_name.toLowerCase().includes(filterText.toLowerCase()),
)
return list.filter((v: RoleItem) => v.role_name.toLowerCase().includes(filterText.toLowerCase()))
}
watch(filterText, (val: string) => {
@ -194,7 +211,7 @@ function clickRole(item: RoleItem) {
const createOrUpdateRoleDialogRef = ref<InstanceType<typeof CreateOrUpdateRoleDialog>>()
function createOrUpdateRole(item?: RoleItem) {
createOrUpdateRoleDialogRef.value?.open(item);
createOrUpdateRoleDialogRef.value?.open(item)
}
function deleteRole(item: RoleItem) {
@ -210,14 +227,13 @@ function deleteRole(item: RoleItem) {
RoleApi.deleteRole(item.id, loading).then(async () => {
MsgSuccess(t('common.deleteSuccess'))
await getRole()
currentRole.value = item.id === currentRole.value?.id ? internalRoleList.value[0] : currentRole.value
currentRole.value =
item.id === currentRole.value?.id ? internalRoleList.value[0] : currentRole.value
})
})
.catch(() => {
})
.catch(() => {})
}
const currentTab = ref('permission')
const tabList = [
{
@ -229,7 +245,6 @@ const tabList = [
label: t('views.role.member.title'),
},
]
</script>
<style lang="scss" scoped>
@ -273,8 +288,6 @@ const tabList = [
margin: 4px 0;
}
}
}
.role-right {

View File

@ -17,7 +17,7 @@ export default defineConfig(({ mode }) => {
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
const proxyConf: Record<string, string | ProxyOptions> = {}
proxyConf['/api'] = {
target: 'http://127.0.0.1:8080',
target: 'http://43.166.1.146:8080',
changeOrigin: true,
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
}