feat: workspace
This commit is contained in:
parent
625b4d6b5d
commit
64b1f3d33a
@ -1,9 +1,9 @@
|
|||||||
import { get, post, del } from '@/request/index'
|
import { get, post, del } from '@/request/index'
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import { Result } from '@/request/Result'
|
import { Result } from '@/request/Result'
|
||||||
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, PageList, RoleMemberItem, CreateMemberParamsItem } from '@/api/type/role'
|
import type { RoleItem, RolePermissionItem, CreateOrUpdateParams, RoleMemberItem, CreateMemberParamsItem } from '@/api/type/role'
|
||||||
import { RoleTypeEnum } from '@/enums/system'
|
import { RoleTypeEnum } from '@/enums/system'
|
||||||
import type { pageRequest } from '@/api/type/common'
|
import type { pageRequest, PageList } from '@/api/type/common'
|
||||||
|
|
||||||
const prefix = '/system/role'
|
const prefix = '/system/role'
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -11,4 +11,11 @@ interface pageRequest {
|
|||||||
page_size: number
|
page_size: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { KeyValue, Dict, pageRequest }
|
interface PageList<T> {
|
||||||
|
current: number,
|
||||||
|
size: number,
|
||||||
|
total: number,
|
||||||
|
records: T
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { KeyValue, Dict, pageRequest, PageList }
|
||||||
|
|||||||
@ -51,14 +51,7 @@ interface RoleMemberItem {
|
|||||||
|
|
||||||
interface CreateMemberParamsItem {
|
interface CreateMemberParamsItem {
|
||||||
user_ids: string[],
|
user_ids: string[],
|
||||||
workspace_ids: string[]
|
workspace_ids?: string[]
|
||||||
}
|
|
||||||
|
|
||||||
interface PageList<T> {
|
|
||||||
current: number,
|
|
||||||
size: number,
|
|
||||||
total: number,
|
|
||||||
records: T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Arrayable<T> = T | T[]
|
type Arrayable<T> = T | T[]
|
||||||
@ -72,4 +65,4 @@ interface FormItemModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { RoleItem, FormItemModel, RolePermissionItem, RoleTableDataItem, CreateOrUpdateParams, PageList, ChildrenPermissionItem, RoleMemberItem, CreateMemberParamsItem }
|
export type { RoleItem, FormItemModel, RolePermissionItem, RoleTableDataItem, CreateOrUpdateParams, ChildrenPermissionItem, RoleMemberItem, CreateMemberParamsItem }
|
||||||
19
ui/src/api/type/workspace.ts
Normal file
19
ui/src/api/type/workspace.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
interface WorkspaceItem {
|
||||||
|
name: string,
|
||||||
|
id?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CreateWorkspaceMemberParamsItem {
|
||||||
|
user_ids: string[],
|
||||||
|
role_ids: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkspaceMemberItem {
|
||||||
|
user_relation_id: string,
|
||||||
|
user_id: string,
|
||||||
|
username: string,
|
||||||
|
nick_name: string,
|
||||||
|
role_id: string,
|
||||||
|
role_name: string,
|
||||||
|
}
|
||||||
|
export type { WorkspaceItem, CreateWorkspaceMemberParamsItem, WorkspaceMemberItem }
|
||||||
97
ui/src/api/workspace.ts
Normal file
97
ui/src/api/workspace.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import { Result } from '@/request/Result'
|
||||||
|
import type { Ref } from 'vue'
|
||||||
|
import { get, post, del } from '@/request/index'
|
||||||
|
import type { WorkspaceItem, CreateWorkspaceMemberParamsItem, WorkspaceMemberItem } from '@/api/type/workspace'
|
||||||
|
import type { pageRequest, PageList } from '@/api/type/common'
|
||||||
|
|
||||||
|
const prefix = '/system/workspace'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取添加成员时的工作空间下拉列表
|
||||||
|
*/
|
||||||
|
const getWorkspaceList: (loading?: Ref<boolean>) => Promise<Result<Record<string, any>[]>> = (loading) => {
|
||||||
|
return get('/workspace/current_user', undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取工作空间列表
|
||||||
|
*/
|
||||||
|
const getSystemWorkspaceList: (loading?: Ref<boolean>) => Promise<Result<WorkspaceItem[]>> = (loading) => {
|
||||||
|
return get(`${prefix}`, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建或更新工作空间
|
||||||
|
*/
|
||||||
|
const CreateOrUpdateWorkspace: (
|
||||||
|
data: WorkspaceItem,
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<any>> = (data, loading) => {
|
||||||
|
return post(`${prefix}`, data, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除工作空间
|
||||||
|
*/
|
||||||
|
const deleteWorkspace: (workspace_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||||
|
workspace_id,
|
||||||
|
loading,
|
||||||
|
) => {
|
||||||
|
return del(`${prefix}/${workspace_id}`, undefined, {}, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取工作空间成员列表
|
||||||
|
*/
|
||||||
|
const getWorkspaceMemberList: (
|
||||||
|
workspace_id: string,
|
||||||
|
page: pageRequest,
|
||||||
|
param: any,
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<PageList<WorkspaceMemberItem[]>>> = (workspace_id, page, param, loading) => {
|
||||||
|
return get(
|
||||||
|
`${prefix}/${workspace_id}/user_list/${page.current_page}/${page.page_size}`,
|
||||||
|
param,
|
||||||
|
loading,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建工作空间成员
|
||||||
|
*/
|
||||||
|
const CreateWorkspaceMember: (
|
||||||
|
workspace_id: string,
|
||||||
|
data: CreateWorkspaceMemberParamsItem[],
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<any>> = (workspace_id, data, loading) => {
|
||||||
|
return post(`${prefix}/${workspace_id}/add_member`, data, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除工作空间成员
|
||||||
|
*/
|
||||||
|
const deleteWorkspaceMember: (workspace_id: string, user_relation_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||||
|
workspace_id,
|
||||||
|
user_relation_id,
|
||||||
|
loading,
|
||||||
|
) => {
|
||||||
|
return post(`${prefix}/${workspace_id}/remove_member/${user_relation_id}`, undefined, {}, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取添加成员时的角色下拉列表
|
||||||
|
*/
|
||||||
|
const getWorkspaceRoleList: (loading?: Ref<boolean>) => Promise<Result<Record<string, any>[]>> = (loading) => {
|
||||||
|
return get('/role_list/current_user', undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getWorkspaceList,
|
||||||
|
getSystemWorkspaceList,
|
||||||
|
CreateOrUpdateWorkspace,
|
||||||
|
deleteWorkspace,
|
||||||
|
getWorkspaceMemberList,
|
||||||
|
CreateWorkspaceMember,
|
||||||
|
deleteWorkspaceMember,
|
||||||
|
getWorkspaceRoleList,
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import notFound from './404'
|
import notFound from './404'
|
||||||
import application from './application'
|
import application from './application'
|
||||||
import role from './role'
|
import role from './role'
|
||||||
|
import workspace from './workspace'
|
||||||
import applicationOverview from './application-overview'
|
import applicationOverview from './application-overview'
|
||||||
import knowledge from './knowledge'
|
import knowledge from './knowledge'
|
||||||
import system from './system'
|
import system from './system'
|
||||||
@ -34,5 +35,6 @@ export default {
|
|||||||
chatLog,
|
chatLog,
|
||||||
login,
|
login,
|
||||||
operateLog,
|
operateLog,
|
||||||
role
|
role,
|
||||||
|
workspace
|
||||||
}
|
}
|
||||||
|
|||||||
11
ui/src/locales/lang/en-US/views/workspace.ts
Normal file
11
ui/src/locales/lang/en-US/views/workspace.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
// TODO
|
||||||
|
title: '工作空间',
|
||||||
|
list: '工作空间列表',
|
||||||
|
name: '工作空间名称',
|
||||||
|
member: {
|
||||||
|
delete: {
|
||||||
|
confirmTitle: '是否移除成员:',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import system from './system'
|
|||||||
import userManage from './user-manage'
|
import userManage from './user-manage'
|
||||||
import resourceAuthorization from './resource-authorization'
|
import resourceAuthorization from './resource-authorization'
|
||||||
import role from './role'
|
import role from './role'
|
||||||
|
import workspace from './workspace'
|
||||||
import application from './application'
|
import application from './application'
|
||||||
import problem from './problem'
|
import problem from './problem'
|
||||||
import applicationOverview from './application-overview'
|
import applicationOverview from './application-overview'
|
||||||
@ -26,6 +27,7 @@ export default {
|
|||||||
userManage,
|
userManage,
|
||||||
resourceAuthorization,
|
resourceAuthorization,
|
||||||
role,
|
role,
|
||||||
|
workspace,
|
||||||
application,
|
application,
|
||||||
problem,
|
problem,
|
||||||
applicationOverview,
|
applicationOverview,
|
||||||
|
|||||||
10
ui/src/locales/lang/zh-CN/views/workspace.ts
Normal file
10
ui/src/locales/lang/zh-CN/views/workspace.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
title: '工作空间',
|
||||||
|
list: '工作空间列表',
|
||||||
|
name: '工作空间名称',
|
||||||
|
member: {
|
||||||
|
delete: {
|
||||||
|
confirmTitle: '是否移除成员:',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import notFound from './404'
|
import notFound from './404'
|
||||||
import application from './application'
|
import application from './application'
|
||||||
import role from './role'
|
import role from './role'
|
||||||
|
import workspace from './workspace'
|
||||||
import applicationOverview from './application-overview'
|
import applicationOverview from './application-overview'
|
||||||
import knowledge from './knowledge'
|
import knowledge from './knowledge'
|
||||||
import system from './system'
|
import system from './system'
|
||||||
@ -34,5 +35,6 @@ export default {
|
|||||||
chatLog,
|
chatLog,
|
||||||
login,
|
login,
|
||||||
operateLog,
|
operateLog,
|
||||||
role
|
role,
|
||||||
|
workspace
|
||||||
}
|
}
|
||||||
|
|||||||
11
ui/src/locales/lang/zh-Hant/views/workspace.ts
Normal file
11
ui/src/locales/lang/zh-Hant/views/workspace.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
// TODO
|
||||||
|
title: '工作空间',
|
||||||
|
list: '工作空间列表',
|
||||||
|
name: '工作空间名称',
|
||||||
|
member: {
|
||||||
|
delete: {
|
||||||
|
confirmTitle: '是否移除成员:',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -45,6 +45,19 @@ const systemRouter = {
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/role/index.vue'),
|
component: () => import('@/views/role/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/system/workspace',
|
||||||
|
name: 'workspace',
|
||||||
|
meta: {
|
||||||
|
icon: 'app-resource-authorization', // TODO
|
||||||
|
iconActive: 'app-resource-authorization-active', // TODO
|
||||||
|
title: 'views.workspace.title',
|
||||||
|
activeMenu: '/system',
|
||||||
|
parentPath: '/system',
|
||||||
|
parentName: 'system',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/workspace/index.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/system/shared',
|
path: '/system/shared',
|
||||||
name: 'shared',
|
name: 'shared',
|
||||||
|
|||||||
@ -109,6 +109,9 @@ h5 {
|
|||||||
.bold {
|
.bold {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
.medium {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
.lighter {
|
.lighter {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
<h4>{{ $t('views.role.member.add') }}</h4>
|
<h4>{{ $t('views.role.member.add') }}</h4>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<MemberFormContent ref="memberFormContentRef" :models="formItemModel" v-model:form="list" />
|
<MemberFormContent ref="memberFormContentRef" :models="formItemModel" v-model:form="list"
|
||||||
|
v-loading="memberFormContentLoading" />
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div style="flex: auto">
|
<div style="flex: auto">
|
||||||
@ -22,12 +23,15 @@ import { onBeforeMount, ref } from 'vue'
|
|||||||
import type { CreateMemberParamsItem, FormItemModel } from '@/api/type/role'
|
import type { CreateMemberParamsItem, FormItemModel } from '@/api/type/role'
|
||||||
import RoleApi from '@/api/system/role'
|
import RoleApi from '@/api/system/role'
|
||||||
import UserApi from '@/api/user/user'
|
import UserApi from '@/api/user/user'
|
||||||
|
import WorkspaceApi from '@/api/workspace'
|
||||||
import MemberFormContent from './MemberFormContent.vue'
|
import MemberFormContent from './MemberFormContent.vue'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
|
import type { RoleItem } from '@/api/type/role'
|
||||||
import { MsgSuccess } from '@/utils/message'
|
import { MsgSuccess } from '@/utils/message'
|
||||||
|
import { RoleTypeEnum } from '@/enums/system'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
roleId: string
|
currentRole?: RoleItem
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -38,55 +42,95 @@ const loading = ref(false)
|
|||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const list = ref<CreateMemberParamsItem[]>([]);
|
const list = ref<CreateMemberParamsItem[]>([]);
|
||||||
|
|
||||||
const formItemModel = ref<FormItemModel[]>([
|
const memberFormContentLoading = ref(false);
|
||||||
{
|
const formItemModel = ref<FormItemModel[]>([]);
|
||||||
path: 'user_ids',
|
const userFormItem = ref<FormItemModel[]>([]);
|
||||||
label: t('views.role.member.title'),
|
const workspaceFormItem = ref<FormItemModel[]>([]);
|
||||||
rules: [
|
|
||||||
{
|
async function getUserFormItem() {
|
||||||
required: true,
|
try {
|
||||||
message: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`,
|
const res = await UserApi.getUserList(memberFormContentLoading);
|
||||||
},
|
userFormItem.value = [{
|
||||||
],
|
path: 'user_ids',
|
||||||
selectProps: {
|
label: t('views.role.member.title'),
|
||||||
options: [],
|
rules: [
|
||||||
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`
|
{
|
||||||
}
|
required: true,
|
||||||
},
|
message: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`,
|
||||||
{
|
},
|
||||||
path: 'workspace_ids',
|
],
|
||||||
label: t('views.role.member.workspace'),
|
selectProps: {
|
||||||
rules: [
|
options: res.data?.map(item => ({
|
||||||
{
|
label: item.nick_name,
|
||||||
required: true,
|
value: item.id
|
||||||
message: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`,
|
})) || [],
|
||||||
},
|
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`
|
||||||
],
|
}
|
||||||
selectProps: {
|
}];
|
||||||
options: [], // TODO
|
} catch (e) {
|
||||||
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`
|
console.error(e);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
]);
|
|
||||||
|
async function getWorkspaceFormItem() {
|
||||||
|
try {
|
||||||
|
const res = await WorkspaceApi.getWorkspaceList(memberFormContentLoading);
|
||||||
|
workspaceFormItem.value = [{
|
||||||
|
path: 'workspace_ids',
|
||||||
|
label: t('views.role.member.workspace'),
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selectProps: {
|
||||||
|
options: res.data?.map(item => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id
|
||||||
|
})) || [],
|
||||||
|
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.workspace')}`
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
if (props.currentRole?.type !== RoleTypeEnum.ADMIN) {
|
||||||
|
formItemModel.value = [...userFormItem.value, ...workspaceFormItem.value]
|
||||||
|
list.value = [{ user_ids: [], workspace_ids: [] }]
|
||||||
|
} else {
|
||||||
|
formItemModel.value = [...userFormItem.value]
|
||||||
|
list.value = [{ user_ids: [] }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
const res = await UserApi.getUserList();
|
await getUserFormItem();
|
||||||
formItemModel.value[0].selectProps.options = res.data?.map(item => ({ label: item.nick_name, value: item.id }))
|
await getWorkspaceFormItem();
|
||||||
|
init()
|
||||||
})
|
})
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
|
init();
|
||||||
visible.value = true
|
visible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
visible.value = false
|
visible.value = false
|
||||||
list.value = []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const memberFormContentRef = ref<InstanceType<typeof MemberFormContent>>()
|
const memberFormContentRef = ref<InstanceType<typeof MemberFormContent>>()
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
memberFormContentRef.value?.validate().then(async (valid) => {
|
memberFormContentRef.value?.validate().then(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
await RoleApi.CreateMember(props.roleId, { members: list.value }, loading)
|
let params;
|
||||||
|
if (props.currentRole?.type === RoleTypeEnum.ADMIN) {
|
||||||
|
params = list.value.map(item => ({ user_ids: item.user_ids, workspace_ids: ['None'] }))
|
||||||
|
}
|
||||||
|
await RoleApi.CreateMember(props.currentRole?.id as string, { members: params ?? list.value }, loading)
|
||||||
MsgSuccess(t('common.addSuccess'))
|
MsgSuccess(t('common.addSuccess'))
|
||||||
handleCancel();
|
handleCancel();
|
||||||
emit('refresh')
|
emit('refresh')
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</app-table>
|
</app-table>
|
||||||
</div>
|
</div>
|
||||||
<AddMemberDrawer ref="addMemberDrawerRef" :role-id="props.currentRole?.id as string" @refresh="getList" />
|
<AddMemberDrawer ref="addMemberDrawerRef" :currentRole="props.currentRole" @refresh="getList" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
:rules="model.rules" :label="index === 0 && model.label ? model.label : ''" class="mr-8" style="flex: 1">
|
:rules="model.rules" :label="index === 0 && model.label ? model.label : ''" class="mr-8" style="flex: 1">
|
||||||
<el-select v-model="element[model.path]"
|
<el-select v-model="element[model.path]"
|
||||||
:placeholder="model.selectProps.placeholder ?? $t('common.selectPlaceholder')" clearable filterable multiple
|
:placeholder="model.selectProps.placeholder ?? $t('common.selectPlaceholder')" clearable filterable multiple
|
||||||
style="width: 100%">
|
style="width: 100%" collapse-tags collapse-tags-tooltip>
|
||||||
<el-option v-for="opt in model.selectProps.options" :key="opt.value" :label="opt.label"
|
<el-option v-for="opt in model.selectProps.options" :key="opt.value" :label="opt.label"
|
||||||
:value="opt.value" />
|
:value="opt.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -53,7 +53,6 @@ watch(() => props.models, () => {
|
|||||||
props.models.forEach((e) => {
|
props.models.forEach((e) => {
|
||||||
formItem[e.path] = [];
|
formItem[e.path] = [];
|
||||||
});
|
});
|
||||||
handleAdd();
|
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
function handleDelete(index: number) {
|
function handleDelete(index: number) {
|
||||||
@ -68,5 +67,4 @@ const validate = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ validate })
|
defineExpose({ validate })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -25,9 +25,11 @@
|
|||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu style="min-width: 80px">
|
<el-dropdown-menu style="min-width: 80px">
|
||||||
<el-dropdown-item @click.stop="createOrUpdateRole(row)" class="p-8">
|
<el-dropdown-item @click.stop="createOrUpdateRole(row)" class="p-8">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
{{ $t('common.rename') }}
|
{{ $t('common.rename') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item @click.stop="deleteRole(row)" class="border-t p-8">
|
<el-dropdown-item @click.stop="deleteRole(row)" class="border-t p-8">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
{{ $t('common.delete') }}
|
{{ $t('common.delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@ -66,10 +68,13 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu style="min-width: 80px">
|
<el-dropdown-menu style="min-width: 80px">
|
||||||
<el-dropdown-item @click.stop="createOrUpdateRole(row)" class="p-8"> {{ $t('common.rename') }}
|
<el-dropdown-item @click.stop="createOrUpdateRole(row)" class="p-8">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
{{ $t('common.rename') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item @click.stop="deleteRole(row)" class="border-t p-8"> {{ $t('common.delete')
|
<el-dropdown-item @click.stop="deleteRole(row)" class="border-t p-8">
|
||||||
}}
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
{{ $t('common.delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
131
ui/src/views/workspace/component/AddMemberDrawer.vue
Normal file
131
ui/src/views/workspace/component/AddMemberDrawer.vue
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="visible" size="600" :destroy-on-close="true" :before-close="handleCancel">
|
||||||
|
<template #header>
|
||||||
|
<h4>{{ $t('views.role.member.add') }}</h4>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<MemberFormContent ref="memberFormContentRef" :models="formItemModel" v-model:form="list"
|
||||||
|
v-loading="memberFormContentLoading" />
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<div style="flex: auto">
|
||||||
|
<el-button @click="handleCancel">{{ $t('common.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="handleAdd()" :loading="loading">
|
||||||
|
{{ $t('common.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onBeforeMount, ref } from 'vue'
|
||||||
|
import UserApi from '@/api/user/user'
|
||||||
|
import WorkspaceApi from '@/api/workspace'
|
||||||
|
import MemberFormContent from '@/views/role/component/MemberFormContent.vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import { MsgSuccess } from '@/utils/message'
|
||||||
|
import type { CreateWorkspaceMemberParamsItem, WorkspaceItem } from '@/api/type/workspace'
|
||||||
|
import type { FormItemModel } from '@/api/type/role'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
currentWorkspace?: WorkspaceItem
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'refresh'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const visible = ref(false)
|
||||||
|
const list = ref<CreateWorkspaceMemberParamsItem[]>([]);
|
||||||
|
|
||||||
|
const memberFormContentLoading = ref(false);
|
||||||
|
const formItemModel = ref<FormItemModel[]>([]);
|
||||||
|
const userFormItem = ref<FormItemModel[]>([]);
|
||||||
|
const roleFormItem = ref<FormItemModel[]>([]);
|
||||||
|
|
||||||
|
async function getUserFormItem() {
|
||||||
|
try {
|
||||||
|
const res = await UserApi.getUserList(memberFormContentLoading);
|
||||||
|
userFormItem.value = [{
|
||||||
|
path: 'user_ids',
|
||||||
|
label: t('views.role.member.title'),
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selectProps: {
|
||||||
|
options: res.data?.map(item => ({
|
||||||
|
label: item.nick_name,
|
||||||
|
value: item.id
|
||||||
|
})) || [],
|
||||||
|
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.title')}`
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRoleFormItem() {
|
||||||
|
try {
|
||||||
|
const res = await WorkspaceApi.getWorkspaceRoleList(memberFormContentLoading);
|
||||||
|
roleFormItem.value = [{
|
||||||
|
path: 'role_ids',
|
||||||
|
label: t('views.role.member.role'),
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: `${t('common.selectPlaceholder')}${t('views.role.member.role')}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selectProps: {
|
||||||
|
options: res.data?.map(item => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id
|
||||||
|
})) || [],
|
||||||
|
placeholder: `${t('common.selectPlaceholder')}${t('views.role.member.role')}`
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
formItemModel.value = [...userFormItem.value, ...roleFormItem.value]
|
||||||
|
list.value = [{ user_ids: [], role_ids: [] }]
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
await getUserFormItem();
|
||||||
|
await getRoleFormItem();
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
init();
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCancel() {
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const memberFormContentRef = ref<InstanceType<typeof MemberFormContent>>()
|
||||||
|
function handleAdd() {
|
||||||
|
memberFormContentRef.value?.validate().then(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
await WorkspaceApi.CreateWorkspaceMember(props.currentWorkspace?.id as string, list.value, loading)
|
||||||
|
MsgSuccess(t('common.addSuccess'))
|
||||||
|
handleCancel();
|
||||||
|
emit('refresh')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="`${!form.id ? $t('common.create') : $t('common.rename')}${$t('views.workspace.title')}`"
|
||||||
|
v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
|
||||||
|
<el-form label-position="top" ref="formRef" :rules="rules" :model="form" require-asterisk-position="right">
|
||||||
|
<el-form-item :label="$t('views.workspace.name')" prop="name">
|
||||||
|
<el-input v-model="form.name" maxlength="64"
|
||||||
|
:placeholder="`${$t('common.inputPlaceholder')}${$t('views.workspace.name')}`" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
|
||||||
|
<el-button type="primary" @click="submit(formRef)" :loading="loading">
|
||||||
|
{{ !form.id ? $t('common.create') : $t('common.save') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import { MsgSuccess } from '@/utils/message'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import type { WorkspaceItem } from '@/api/type/workspace'
|
||||||
|
import WorkspaceApi from '@/api/workspace'
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'refresh', currentWorkspace: WorkspaceItem): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const dialogVisible = ref<boolean>(false)
|
||||||
|
const defaultForm = {
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
const form = ref<WorkspaceItem>({
|
||||||
|
...defaultForm,
|
||||||
|
})
|
||||||
|
function open(item?: WorkspaceItem) {
|
||||||
|
if (item) {
|
||||||
|
form.value = { id: item.id, name: item.name }
|
||||||
|
} else {
|
||||||
|
form.value = { ...defaultForm }
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
name: [{ required: true, message: `${t('common.inputPlaceholder')}${t('views.workspace.name')}`, trigger: 'blur' }],
|
||||||
|
})
|
||||||
|
|
||||||
|
const loading = ref<boolean>(false)
|
||||||
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
WorkspaceApi.CreateOrUpdateWorkspace(form.value, loading).then((res: any) => {
|
||||||
|
MsgSuccess(!form.value.id ? t('common.createSuccess') : t('common.renameSuccess'))
|
||||||
|
emit('refresh', res.data)
|
||||||
|
dialogVisible.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
109
ui/src/views/workspace/component/Member.vue
Normal file
109
ui/src/views/workspace/component/Member.vue
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex-between mb-16">
|
||||||
|
<el-button type="primary" @click="handleAdd">
|
||||||
|
{{ $t('views.role.member.add') }}
|
||||||
|
</el-button>
|
||||||
|
<div class="flex complex-search">
|
||||||
|
<el-select class="complex-search__left" v-model="searchType" style="width: 120px">
|
||||||
|
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
||||||
|
</el-select>
|
||||||
|
<el-input v-if="searchType === 'username'" v-model="searchForm.username" @change="getList"
|
||||||
|
:placeholder="$t('common.inputPlaceholder')" style="width: 220px" clearable />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<app-table :data="tableData" :pagination-config="paginationConfig" @sizeChange="handleSizeChange"
|
||||||
|
@changePage="getList" v-loading="loading">
|
||||||
|
<el-table-column prop="nick_name" :label="$t('views.userManage.form.nick_name.label')" />
|
||||||
|
<el-table-column prop="username" :label="$t('views.userManage.form.username.label')" />
|
||||||
|
<el-table-column prop="role_name" :label="$t('views.role.member.role')" />
|
||||||
|
<el-table-column :label="$t('common.operation')" width="100" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tooltip effect="dark" :content="`${$t('views.role.member.delete.button')}`" placement="top">
|
||||||
|
<el-button type="primary" text @click.stop="handleDelete(row)">
|
||||||
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</app-table>
|
||||||
|
<AddMemberDrawer ref="addMemberDrawerRef" :currentWorkspace="props.currentWorkspace" @refresh="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref, reactive, watch } from 'vue'
|
||||||
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import AddMemberDrawer from './AddMemberDrawer.vue'
|
||||||
|
import WorkspaceApi from '@/api/workspace'
|
||||||
|
import type { WorkspaceMemberItem, WorkspaceItem } from '@/api/type/workspace'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
currentWorkspace?: WorkspaceItem
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const searchType = ref('username')
|
||||||
|
const searchForm = ref<Record<string, any>>({
|
||||||
|
username: '',
|
||||||
|
})
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
current_page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableData = ref<WorkspaceMemberItem[]>([])
|
||||||
|
|
||||||
|
async function getList() {
|
||||||
|
if (!props.currentWorkspace?.id) return
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
[searchType.value]: searchForm.value[searchType.value],
|
||||||
|
}
|
||||||
|
const res = await WorkspaceApi.getWorkspaceMemberList(props.currentWorkspace?.id, paginationConfig, params, loading)
|
||||||
|
tableData.value = res.data.records
|
||||||
|
paginationConfig.total = res.data.total
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSizeChange() {
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => props.currentWorkspace?.id, () => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
|
||||||
|
const addMemberDrawerRef = ref<InstanceType<typeof AddMemberDrawer>>()
|
||||||
|
function handleAdd() {
|
||||||
|
addMemberDrawerRef.value?.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(row: WorkspaceMemberItem) {
|
||||||
|
MsgConfirm(
|
||||||
|
`${t('views.workspace.member.delete.confirmTitle')}${row.nick_name} ?`, '',
|
||||||
|
{
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
confirmButtonClass: 'danger',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true
|
||||||
|
WorkspaceApi.deleteWorkspaceMember(props.currentWorkspace?.id as string, row.user_relation_id, loading).then(() => {
|
||||||
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => { })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
205
ui/src/views/workspace/index.vue
Normal file
205
ui/src/views/workspace/index.vue
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
<template>
|
||||||
|
<div class="workspace">
|
||||||
|
<h2 class="mb-16">{{ $t('views.workspace.title') }}</h2>
|
||||||
|
<el-card style="--el-card-padding: 0" body-class="workspace-card">
|
||||||
|
<div class="flex h-full">
|
||||||
|
<div class="workspace-left border-r p-16">
|
||||||
|
<div class="workspace-left_title">
|
||||||
|
<h4 class="medium">{{ $t('views.workspace.list') }}</h4>
|
||||||
|
<el-tooltip effect="dark" :content="`${$t('common.create')}${$t('views.workspace.title')}`" placement="top">
|
||||||
|
<el-button type="primary" text @click="createOrUpdateWorkspace()">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="p-8">
|
||||||
|
<el-input v-model="filterText" :placeholder="$t('common.search')" prefix-icon="Search" clearable />
|
||||||
|
</div>
|
||||||
|
<div class="list-height-left">
|
||||||
|
<el-scrollbar v-loading="loading">
|
||||||
|
<common-list :data="filterList" @click="clickWorkspace" :default-active="currentWorkspace?.id">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex-between">
|
||||||
|
<span>{{ row.name }}</span>
|
||||||
|
<el-dropdown :teleported="false">
|
||||||
|
<el-button text>
|
||||||
|
<el-icon class="color-secondary">
|
||||||
|
<MoreFilled />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu style="min-width: 80px">
|
||||||
|
<el-dropdown-item @click.stop="createOrUpdateWorkspace(row)" class="p-8">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
{{
|
||||||
|
$t('common.rename') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click.stop="deleteWorkspace(row)" class="border-t p-8">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
{{
|
||||||
|
$t('common.delete')
|
||||||
|
}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #empty>
|
||||||
|
<span></span>
|
||||||
|
</template>
|
||||||
|
</common-list>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右边 -->
|
||||||
|
<div class="workspace-right" v-loading="loading">
|
||||||
|
<div class="flex align-center" style="margin-bottom: 20px;">
|
||||||
|
<h4 class="medium">{{ currentWorkspace?.name }}</h4>
|
||||||
|
<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">
|
||||||
|
数字
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Member :currentWorkspace="currentWorkspace" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<CreateOrUpdateWorkspaceDialog ref="createOrUpdateWorkspaceDialogRef" @refresh="refresh" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref, watch } from 'vue'
|
||||||
|
import WorkspaceApi from '@/api/workspace'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import Member from './component/Member.vue'
|
||||||
|
import CreateOrUpdateWorkspaceDialog from './component/CreateOrUpdateWorkspaceDialog.vue'
|
||||||
|
import type { WorkspaceItem } from '@/api/type/workspace'
|
||||||
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
|
|
||||||
|
const filterText = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
const list = ref<WorkspaceItem[]>([])
|
||||||
|
const filterList = ref<WorkspaceItem[]>([]) // 搜索过滤后列表
|
||||||
|
const currentWorkspace = ref<WorkspaceItem>()
|
||||||
|
|
||||||
|
async function getWorkspace() {
|
||||||
|
try {
|
||||||
|
const res = await WorkspaceApi.getSystemWorkspaceList(loading)
|
||||||
|
list.value = res.data
|
||||||
|
filterList.value = filter(list.value, filterText.value)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getWorkspace()
|
||||||
|
currentWorkspace.value = list.value[0]
|
||||||
|
})
|
||||||
|
|
||||||
|
async function refresh(workspace?: WorkspaceItem) {
|
||||||
|
await getWorkspace();
|
||||||
|
// 创建角色后选中新建的角色
|
||||||
|
currentWorkspace.value = workspace ? workspace : currentWorkspace.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter(list: WorkspaceItem[], filterText: string) {
|
||||||
|
if (!filterText.length) {
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
return list.filter((v: WorkspaceItem) =>
|
||||||
|
v.name.toLowerCase().includes(filterText.toLowerCase()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(filterText, (val: string) => {
|
||||||
|
filterList.value = filter(list.value, val)
|
||||||
|
})
|
||||||
|
|
||||||
|
function clickWorkspace(item: WorkspaceItem) {
|
||||||
|
currentWorkspace.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
const createOrUpdateWorkspaceDialogRef = ref<InstanceType<typeof CreateOrUpdateWorkspaceDialog>>()
|
||||||
|
function createOrUpdateWorkspace(item?: WorkspaceItem) {
|
||||||
|
createOrUpdateWorkspaceDialogRef.value?.open(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 该工作空间下存在 知识库资源、应用资源,无法删除
|
||||||
|
function deleteWorkspace(item: WorkspaceItem) {
|
||||||
|
MsgConfirm(
|
||||||
|
`${t('views.workspace.delete.confirmTitle')}${item.name} ?`,
|
||||||
|
t('views.workspace.delete.confirmMessage'),
|
||||||
|
{
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
confirmButtonClass: 'danger',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
WorkspaceApi.deleteWorkspace(item.id as string, loading).then(async () => {
|
||||||
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
|
await getWorkspace()
|
||||||
|
currentWorkspace.value = item.id === currentWorkspace.value?.id ? list.value[0] : currentWorkspace.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => { })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.workspace {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 16px 24px;
|
||||||
|
|
||||||
|
:deep(.workspace-card) {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-left {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: var(--setting-left-width);
|
||||||
|
min-width: var(--setting-left-width);
|
||||||
|
|
||||||
|
.workspace-left_title {
|
||||||
|
padding: 8px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-height-left {
|
||||||
|
height: calc(100vh - 255px);
|
||||||
|
|
||||||
|
:deep(.common-list li) {
|
||||||
|
padding-right: 4px;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-left_divider {
|
||||||
|
padding: 0 8px;
|
||||||
|
|
||||||
|
:deep(.el-divider) {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-right {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user