feat: folder
This commit is contained in:
parent
8f1b0e0da5
commit
43c7350415
@ -40,7 +40,7 @@ const postFolder: (
|
||||
data?: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<Array<any>>> = (source, data, loading) => {
|
||||
return post(`${prefix.value}/${source}/folder`, data, loading)
|
||||
return post(`${prefix.value}/${source}/folder`, data, null, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -3,12 +3,9 @@ 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'
|
||||
|
||||
@ -56,10 +56,10 @@ const getWorkspaceMemberList: (
|
||||
/**
|
||||
* 获取工作空间全部成员列表
|
||||
*/
|
||||
const getAllMemberList: (workspace_id: string, loading?: Ref<boolean>) => Promise<Result<any[]>> = (
|
||||
workspace_id,
|
||||
loading,
|
||||
) => {
|
||||
const getAllMemberList: (
|
||||
workspace_id: string | null,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any[]>> = (workspace_id, loading) => {
|
||||
return get(`${prefix}/${workspace_id}/user_list`, undefined, loading)
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ import folderApi from '@/api/folder'
|
||||
import { MsgSuccess, MsgAlert } from '@/utils/message'
|
||||
import { t } from '@/locales'
|
||||
import useStore from '@/stores'
|
||||
const { tool, knowledge } = useStore()
|
||||
const { tool, knowledge, folder } = useStore()
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const props = defineProps({
|
||||
@ -124,15 +124,17 @@ const submitHandle = async () => {
|
||||
.putFolder(editId.value, sourceType.value, folderForm.value, loading)
|
||||
.then((res) => {
|
||||
MsgSuccess(t('common.editSuccess'))
|
||||
emit('refresh')
|
||||
clearData()
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
} else {
|
||||
folderApi.postFolder(sourceType.value, folderForm.value, loading).then((res) => {
|
||||
MsgSuccess(t('common.createSuccess'))
|
||||
emit('refresh')
|
||||
folder.setCurrentFolder(res.data)
|
||||
folder.asyncGetFolder(sourceType.value, {}, loading)
|
||||
clearData()
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
>
|
||||
<el-dropdown trigger="click" :teleported="false">
|
||||
<el-button text class="w-full">
|
||||
<el-icon class="rotate-90"><MoreFilled /></el-icon>
|
||||
<el-icon><MoreFilled /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
@ -97,6 +97,8 @@ import folderApi from '@/api/folder'
|
||||
import { EditionConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
import useStore from '@/stores'
|
||||
import { TreeToFlatten } from '@/utils/array'
|
||||
import { MsgConfirm } from '@/utils/message'
|
||||
|
||||
defineOptions({ name: 'FolderTree' })
|
||||
const props = defineProps({
|
||||
@ -106,7 +108,7 @@ const props = defineProps({
|
||||
},
|
||||
currentNodeKey: {
|
||||
type: String,
|
||||
default: 'root',
|
||||
default: 'default',
|
||||
},
|
||||
source: {
|
||||
type: String,
|
||||
@ -140,6 +142,7 @@ interface Tree {
|
||||
children?: Tree[]
|
||||
id?: string
|
||||
show?: boolean
|
||||
parent_id?: string
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
@ -185,9 +188,23 @@ const handleSharedNodeClick = () => {
|
||||
}
|
||||
|
||||
function deleteFolder(row: Tree) {
|
||||
MsgConfirm(
|
||||
`${t('common.deleteConfirm')}:${row.name}`,
|
||||
t('components.folder.deleteConfirmMessage'),
|
||||
{
|
||||
confirmButtonText: t('common.delete'),
|
||||
confirmButtonClass: 'danger',
|
||||
},
|
||||
)
|
||||
.then(() => {
|
||||
folderApi.delFolder(row.id as string, props.source, loading).then(() => {
|
||||
treeRef.value?.setCurrentKey(row.parent_id || 'default')
|
||||
const prevFolder = TreeToFlatten(props.data).find((item: any) => item.id === row.parent_id)
|
||||
folder.setCurrentFolder(prevFolder)
|
||||
emit('refreshTree')
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
const CreateFolderDialogRef = ref()
|
||||
|
||||
@ -97,4 +97,5 @@ export default {
|
||||
},
|
||||
custom: 'Custom',
|
||||
moveTo: 'Move To',
|
||||
deleteConfirm: 'Confirm delete',
|
||||
}
|
||||
|
||||
@ -16,5 +16,7 @@ export default {
|
||||
folderNamePlaceholder: 'Please enter a name',
|
||||
description: 'Description',
|
||||
descriptionPlaceholder: 'Please enter a description',
|
||||
requiredMessage: 'Please select a folder',
|
||||
deleteConfirmMessage: 'Folders with resources will be deleted, please be cautious.',
|
||||
},
|
||||
}
|
||||
|
||||
@ -101,4 +101,5 @@ export default {
|
||||
},
|
||||
custom: '自定义',
|
||||
moveTo: '转移到',
|
||||
deleteConfirm: '是否删除',
|
||||
}
|
||||
|
||||
@ -17,5 +17,6 @@ export default {
|
||||
description: '描述',
|
||||
descriptionPlaceholder: '请输入描述',
|
||||
requiredMessage: '请选择文件夹',
|
||||
deleteConfirmMessage: '文件夹下的资源会被删除,请谨慎操作。'
|
||||
},
|
||||
}
|
||||
|
||||
@ -97,4 +97,5 @@ export default {
|
||||
},
|
||||
custom: '自定義',
|
||||
moveTo: '移動到',
|
||||
deleteConfirm: '是否刪除',
|
||||
}
|
||||
|
||||
@ -16,5 +16,7 @@ export default {
|
||||
folderNamePlaceholder: '請輸入名稱',
|
||||
description: '描述',
|
||||
descriptionPlaceholder: '請輸入描述',
|
||||
requiredMessage: '請選擇文件夾',
|
||||
deleteConfirmMessage: '文件夹下的資源會被刪除,請謹慎操作。',
|
||||
},
|
||||
}
|
||||
|
||||
@ -316,10 +316,7 @@ const { folder, application, user, common } = useStore()
|
||||
const loading = ref(false)
|
||||
|
||||
const search_type = ref('name')
|
||||
const search_form = ref<{
|
||||
name: string
|
||||
create_user: string
|
||||
}>({
|
||||
const search_form = ref<any>({
|
||||
name: '',
|
||||
create_user: '',
|
||||
})
|
||||
@ -544,7 +541,6 @@ function getList() {
|
||||
|
||||
onMounted(() => {
|
||||
getFolder(true)
|
||||
|
||||
WorkspaceApi.getAllMemberList(user.getWorkspaceId(), loading).then((res) => {
|
||||
user_options.value = res.data
|
||||
})
|
||||
|
||||
@ -308,7 +308,7 @@
|
||||
</ContentContainer>
|
||||
|
||||
<component :is="currentCreateDialog" ref="CreateKnowledgeDialogRef" v-if="!isShared" />
|
||||
<CreateFolderDialog ref="CreateFolderDialogRef" v-if="!isShared" />
|
||||
<CreateFolderDialog ref="CreateFolderDialogRef" v-if="!isShared" @refresh="refreshFolder" />
|
||||
<GenerateRelatedDialog ref="GenerateRelatedDialogRef" :apiType="apiType" />
|
||||
<SyncWebDialog ref="SyncWebDialogRef" v-if="!isShared" />
|
||||
<AuthorizedWorkspace
|
||||
@ -350,6 +350,8 @@ onBeforeRouteLeave((to, from) => {
|
||||
knowledge.setKnowledgeList([])
|
||||
})
|
||||
|
||||
const emit = defineEmits(['refreshFolder'])
|
||||
|
||||
const apiType = computed(() => {
|
||||
if (route.path.includes('shared')) {
|
||||
return 'systemShare'
|
||||
@ -523,6 +525,10 @@ function searchHandle() {
|
||||
getList()
|
||||
}
|
||||
|
||||
function refreshFolder() {
|
||||
emit('refreshFolder')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (apiType.value !== 'workspace') {
|
||||
folder.setCurrentFolder({
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
@refreshTree="refreshFolder"
|
||||
/>
|
||||
</template>
|
||||
<KnowledgeListContainer>
|
||||
<KnowledgeListContainer @refreshFolder="refreshFolder">
|
||||
<template #header>
|
||||
<FolderBreadcrumb :folderList="folderList" @click="folderClickHandle" />
|
||||
</template>
|
||||
|
||||
@ -3,14 +3,11 @@
|
||||
<h2 class="mb-16">{{ $t('views.userManage.title') }}</h2>
|
||||
<el-card>
|
||||
<div class="flex-between mb-16">
|
||||
<el-button type="primary" @click="createUser"
|
||||
v-hasPermission="[
|
||||
RoleConst.ADMIN,
|
||||
PermissionConst.USER_CREATE
|
||||
]"
|
||||
>{{
|
||||
$t('views.userManage.createUser')
|
||||
}}
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="createUser"
|
||||
v-hasPermission="[RoleConst.ADMIN, PermissionConst.USER_CREATE]"
|
||||
>{{ $t('views.userManage.createUser') }}
|
||||
</el-button>
|
||||
<div class="flex-between complex-search">
|
||||
<el-select
|
||||
@ -19,9 +16,9 @@
|
||||
style="width: 120px"
|
||||
@change="search_type_change"
|
||||
>
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="username"/>
|
||||
<el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name"/>
|
||||
<el-option :label="$t('views.login.loginForm.email.label')" value="email"/>
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
||||
<el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name" />
|
||||
<el-option :label="$t('views.login.loginForm.email.label')" value="email" />
|
||||
</el-select>
|
||||
<el-input
|
||||
v-if="search_type === 'username'"
|
||||
@ -54,15 +51,16 @@
|
||||
@changePage="getList"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')"/>
|
||||
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')"/>
|
||||
<el-table-column
|
||||
prop="nick_name"
|
||||
:label="$t('views.userManage.userForm.nick_name.label')"
|
||||
/>
|
||||
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" />
|
||||
<el-table-column prop="is_active" :label="$t('common.status.label')">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.is_active" class="flex align-center">
|
||||
<el-icon class="color-success mr-8" style="font-size: 16px"
|
||||
>
|
||||
<SuccessFilled
|
||||
/>
|
||||
<el-icon class="color-success mr-8" style="font-size: 16px">
|
||||
<SuccessFilled />
|
||||
</el-icon>
|
||||
<span class="color-secondary">
|
||||
{{ $t('common.status.enabled') }}
|
||||
@ -91,12 +89,21 @@
|
||||
{{ row.phone || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="role_name" :label="$t('views.role.member.role')" min-width="100"
|
||||
v-if="user.isEE() || user.isPE()">
|
||||
<el-table-column
|
||||
prop="role_name"
|
||||
:label="$t('views.role.member.role')"
|
||||
min-width="100"
|
||||
v-if="user.isEE() || user.isPE()"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-popover :width="400">
|
||||
<template #reference>
|
||||
<TagGroup class="cursor" style="width: fit-content;" :tags="row.role_name" tooltipDisabled/>
|
||||
<TagGroup
|
||||
class="cursor"
|
||||
style="width: fit-content"
|
||||
:tags="row.role_name"
|
||||
tooltipDisabled
|
||||
/>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-table :data="row.role_workspace">
|
||||
@ -141,72 +148,84 @@
|
||||
size="small"
|
||||
v-model="row.is_active"
|
||||
:before-change="() => changeState(row)"
|
||||
v-if="hasPermission([RoleConst.ADMIN,PermissionConst.USER_EDIT],'OR')"
|
||||
v-if="hasPermission([RoleConst.ADMIN, PermissionConst.USER_EDIT], 'OR')"
|
||||
/>
|
||||
</span>
|
||||
<el-divider direction="vertical"/>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip effect="dark" :content="$t('common.edit')" placement="top">
|
||||
<span class="mr-8">
|
||||
<el-button type="primary" text @click.stop="editUser(row)" :title="$t('common.edit')"
|
||||
v-if="hasPermission([RoleConst.ADMIN,PermissionConst.USER_EDIT],'OR')">
|
||||
<el-icon><EditPen/></el-icon>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
@click.stop="editUser(row)"
|
||||
:title="$t('common.edit')"
|
||||
v-if="hasPermission([RoleConst.ADMIN, PermissionConst.USER_EDIT], 'OR')"
|
||||
>
|
||||
<el-icon><EditPen /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('views.userManage.setting.updatePwd')"
|
||||
placement="top"
|
||||
>
|
||||
<span class="mr-8">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
@click.stop="editPwdUser(row)"
|
||||
:title="$t('views.userManage.setting.updatePwd')"
|
||||
v-if="hasPermission([RoleConst.ADMIN,PermissionConst.USER_EDIT],'OR')"
|
||||
v-if="hasPermission([RoleConst.ADMIN, PermissionConst.USER_EDIT], 'OR')"
|
||||
>
|
||||
<el-icon><Lock/></el-icon>
|
||||
<el-icon><Lock /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
<span>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('common.delete')" placement="top">
|
||||
<el-button
|
||||
:disabled="row.role === 'ADMIN' || row.id === user.userInfo?.id"
|
||||
type="primary"
|
||||
text
|
||||
@click.stop="deleteUserManage(row)"
|
||||
:title="$t('common.delete')"
|
||||
v-if="hasPermission([RoleConst.ADMIN,PermissionConst.USER_DELETE],'OR')"
|
||||
v-if="hasPermission([RoleConst.ADMIN, PermissionConst.USER_DELETE], 'OR')"
|
||||
>
|
||||
<el-icon><Delete/></el-icon>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</app-table>
|
||||
</el-card>
|
||||
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh"/>
|
||||
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh"/>
|
||||
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh" />
|
||||
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {onMounted, ref, reactive, watch} from 'vue'
|
||||
import { onMounted, ref, reactive, watch } from 'vue'
|
||||
import UserDrawer from './component/UserDrawer.vue'
|
||||
import UserPwdDialog from './component/UserPwdDialog.vue'
|
||||
import userManageApi from '@/api/system/user-manage'
|
||||
import {datetimeFormat} from '@/utils/time'
|
||||
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
||||
import {t} from '@/locales'
|
||||
import {ValidCount, ValidType} from "@/enums/common.ts";
|
||||
import useStore from "@/stores";
|
||||
import {PermissionConst, RoleConst} from '@/utils/permission/data'
|
||||
import {hasPermission} from '@/utils/permission/index'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { t } from '@/locales'
|
||||
import { ValidCount, ValidType } from '@/enums/common.ts'
|
||||
import useStore from '@/stores'
|
||||
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
|
||||
const {user, common} = useStore()
|
||||
const { user, common } = useStore()
|
||||
const search_type = ref('username')
|
||||
const search_form = ref<{
|
||||
username: string,
|
||||
nick_name?: string,
|
||||
username: string
|
||||
nick_name?: string
|
||||
email?: string
|
||||
}>({
|
||||
username: '',
|
||||
nick_name: '',
|
||||
email: ''
|
||||
email: '',
|
||||
})
|
||||
|
||||
const UserDrawerRef = ref()
|
||||
@ -222,7 +241,7 @@ const paginationConfig = reactive({
|
||||
const userTableData = ref<any[]>([])
|
||||
|
||||
const search_type_change = () => {
|
||||
search_form.value = {username: '', nick_name: '', email: ''}
|
||||
search_form.value = { username: '', nick_name: '', email: '' }
|
||||
}
|
||||
|
||||
function handleSizeChange() {
|
||||
@ -234,15 +253,14 @@ function getList() {
|
||||
const params = {
|
||||
[search_type.value]: search_form.value[search_type.value as keyof typeof search_form.value],
|
||||
}
|
||||
return userManageApi
|
||||
.getUserManage(paginationConfig, params, loading)
|
||||
.then((res) => {
|
||||
return userManageApi.getUserManage(paginationConfig, params, loading).then((res) => {
|
||||
userTableData.value = res.data.records.map((item: any) => ({
|
||||
...item,
|
||||
role_workspace: Object.entries(item.role_workspace ?? {}).map(([role, workspaces]) => ({
|
||||
role,
|
||||
workspace: (workspaces as string[])?.[0] === 'None' ? '-' : (workspaces as string[])?.join(", ")
|
||||
}))
|
||||
workspace:
|
||||
(workspaces as string[])?.[0] === 'None' ? '-' : (workspaces as string[])?.join(', '),
|
||||
})),
|
||||
}))
|
||||
paginationConfig.total = res.data.total
|
||||
})
|
||||
@ -293,8 +311,7 @@ function deleteUserManage(row: any) {
|
||||
getList()
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
function editPwdUser(row: any) {
|
||||
|
||||
@ -286,7 +286,7 @@
|
||||
</ContentContainer>
|
||||
<InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh" />
|
||||
<ToolFormDrawer ref="ToolFormDrawerRef" @refresh="refresh" :title="ToolDrawertitle" />
|
||||
<CreateFolderDialog ref="CreateFolderDialogRef" v-if="!isShared" />
|
||||
<CreateFolderDialog ref="CreateFolderDialogRef" v-if="!isShared" @refresh="refreshFolder" />
|
||||
<ToolStoreDialog ref="toolStoreDialogRef" :api-type="apiType" @refresh="refresh" />
|
||||
<AddInternalToolDialog ref="AddInternalToolDialogRef" @refresh="confirmAddInternalTool" />
|
||||
<AuthorizedWorkspace
|
||||
@ -324,6 +324,7 @@ const { folder, user, tool } = useStore()
|
||||
onBeforeRouteLeave((to, from) => {
|
||||
tool.setToolList([])
|
||||
})
|
||||
const emit = defineEmits(['refreshFolder'])
|
||||
|
||||
const apiType = computed(() => {
|
||||
if (route.path.includes('shared')) {
|
||||
@ -621,6 +622,10 @@ function clickFolder(item: any) {
|
||||
folder.setCurrentFolder(item)
|
||||
}
|
||||
|
||||
function refreshFolder() {
|
||||
emit('refreshFolder')
|
||||
}
|
||||
|
||||
function searchHandle() {
|
||||
paginationConfig.current_page = 1
|
||||
tool.setToolList([])
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
class="p-8"
|
||||
/>
|
||||
</template>
|
||||
<ToolListContainer>
|
||||
<ToolListContainer @refreshFolder="refreshFolder">
|
||||
<template #header>
|
||||
<FolderBreadcrumb :folderList="folderList" @click="folderClickHandle" />
|
||||
</template>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user