diff --git a/ui/src/components/folder-breadcrumb/index.vue b/ui/src/components/folder-breadcrumb/index.vue new file mode 100644 index 000000000..3fa2cb7f9 --- /dev/null +++ b/ui/src/components/folder-breadcrumb/index.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/ui/src/components/folder-tree/CreateFolderDialog.vue b/ui/src/components/folder-tree/CreateFolderDialog.vue index 9d6b0fd31..2888ab45c 100644 --- a/ui/src/components/folder-tree/CreateFolderDialog.vue +++ b/ui/src/components/folder-tree/CreateFolderDialog.vue @@ -52,6 +52,8 @@ import { ref, watch, reactive } from 'vue' import folderApi from '@/api/folder' import { MsgSuccess, MsgAlert } from '@/utils/message' import { t } from '@/locales' +import useStore from '@/stores' +const { tool } = useStore() const emit = defineEmits(['refresh']) const props = defineProps({ @@ -122,12 +124,14 @@ const submitHandle = async () => { .then((res) => { MsgSuccess(t('common.editSuccess')) emit('refresh') + tool.setToolList([]) dialogVisible.value = false }) } else { folderApi.postFolder(sourceType.value, folderForm.value, loading).then((res) => { MsgSuccess(t('common.createSuccess')) emit('refresh') + tool.setToolList([]) dialogVisible.value = false }) } diff --git a/ui/src/components/folder-tree/index.vue b/ui/src/components/folder-tree/index.vue index c50e1c5af..f6cb59563 100644 --- a/ui/src/components/folder-tree/index.vue +++ b/ui/src/components/folder-tree/index.vue @@ -14,7 +14,7 @@ :class="currentNodeKey === 'share' && 'active'" > - {{ $t(shareTitle) }} + {{ shareTitle }}
{{ $t('common.delete') }} @@ -109,7 +109,7 @@ const props = defineProps({ }, shareTitle: { type: String, - default: 'views.system.share_knowledge', + default: 'views.system.shared.shared_knowledge', }, canOperation: { type: Boolean, @@ -162,7 +162,7 @@ const handleNodeClick = (data: Tree) => { const handleSharedNodeClick = () => { treeRef.value?.setCurrentKey(undefined) - emit('handleNodeClick', { id: 'share', name: t(props.shareTitle) }) + emit('handleNodeClick', { id: 'share', name: props.shareTitle }) } function deleteFolder(row: Tree) { diff --git a/ui/src/components/index.ts b/ui/src/components/index.ts index 931fef593..21e341bea 100644 --- a/ui/src/components/index.ts +++ b/ui/src/components/index.ts @@ -25,6 +25,7 @@ import AiChat from './ai-chat/index.vue' import KnowledgeIcon from './app-icon/KnowledgeIcon.vue' import TagGroup from './tag-group/index.vue' import WorkspaceDropdown from './workspace-dropdown/index.vue' +import FolderBreadcrumb from './folder-breadcrumb/index.vue' export default { install(app: App) { app.component('LogoFull', LogoFull) @@ -53,5 +54,6 @@ export default { app.component('KnowledgeIcon', KnowledgeIcon) app.component('TagGroup', TagGroup) app.component('WorkspaceDropdown', WorkspaceDropdown) + app.component('FolderBreadcrumb', FolderBreadcrumb) }, } diff --git a/ui/src/locales/lang/en-US/views/system.ts b/ui/src/locales/lang/en-US/views/system.ts index 6f19fef5b..52ff18e87 100644 --- a/ui/src/locales/lang/en-US/views/system.ts +++ b/ui/src/locales/lang/en-US/views/system.ts @@ -1,10 +1,6 @@ export default { title: 'System', subTitle: 'Syetem Settings', - shared: 'Shared', - shared_resources: 'Shared Resources', - share_knowledge: 'Shared Knowledge', - authorized_workspace: 'Authorize Workspace', test: 'Test Connection', testSuccess: 'Successful', testFailed: 'Test connection failed', @@ -23,7 +19,7 @@ export default { ldap_filterPlaceholder: 'Please enter user filter', ldap_mapping: 'LDAP Attribute Mapping', ldap_mappingPlaceholder: 'Please enter LDAP attribute mapping', - enableAuthentication: 'Enable LDAP Authentication' + enableAuthentication: 'Enable LDAP Authentication', }, cas: { title: 'CAS', @@ -33,7 +29,7 @@ export default { validateUrlPlaceholder: 'Please enter validation address', redirectUrl: 'Callback Address', redirectUrlPlaceholder: 'Please enter callback address', - enableAuthentication: 'Enable CAS Authentication' + enableAuthentication: 'Enable CAS Authentication', }, oidc: { title: 'OIDC', @@ -52,7 +48,7 @@ export default { logoutEndpointPlaceholder: 'Please enter logout endpoint', redirectUrl: 'Redirect URL', redirectUrlPlaceholder: 'Please enter redirect URL', - enableAuthentication: 'Enable OIDC Authentication' + enableAuthentication: 'Enable OIDC Authentication', }, oauth2: { @@ -73,7 +69,7 @@ export default { redirectUrlPlaceholder: 'Please enter redirect URL', filedMapping: 'Field Mapping', filedMappingPlaceholder: 'Please enter field mapping', - enableAuthentication: 'Enable OAuth2 Authentication' + enableAuthentication: 'Enable OAuth2 Authentication', }, scanTheQRCode: { title: 'Scan the QR code', @@ -95,10 +91,10 @@ export default { larkQrCode: 'Lark Scan Code Login', dingtalkQrCode: 'DingTalk Scan Code Login', setting: ' Setting', - access: 'Access' - } + access: 'Access', + }, }, - theme: { + theme: { title: 'Appearance Settings', platformDisplayTheme: 'Platform Display Theme', customTheme: 'Custom Theme', @@ -115,8 +111,10 @@ export default { loginLogo: 'Login Logo', websiteLogo: 'Website Logo', replacePicture: 'Replace Picture', - websiteLogoTip: "The logo displayed on the top of the website. The recommended size is 48*48. It supports JPG, PNG, and GIF formats, with a size not exceeding 10MB.", - loginLogoTip: "Login page right-side logo. Recommended size is 204*52. Supports JPG, PNG, GIF formats, with a maximum file size of 10 MB.", + websiteLogoTip: + 'The logo displayed on the top of the website. The recommended size is 48*48. It supports JPG, PNG, and GIF formats, with a size not exceeding 10MB.', + loginLogoTip: + 'Login page right-side logo. Recommended size is 204*52. Supports JPG, PNG, GIF formats, with a maximum file size of 10 MB.', loginBackgroundTip: 'Left background image, vector image recommended size 576 * 900, bitmap recommended size 1152 * 1800; Supports JPG, PNG, GIF, with a size not exceeding 10 MB.', websiteName: 'Website Name', @@ -146,14 +144,14 @@ export default { smtpPortPlaceholder: 'Please enter SMTP port', smtpUser: 'SMTP User', smtpUserPlaceholder: 'Please enter SMTP user', - sendEmail: 'Sender\'s Email', - sendEmailPlaceholder: 'Please enter the sender\'s email', + sendEmail: "Sender's Email", + sendEmailPlaceholder: "Please enter the sender's email", smtpPassword: 'SMTP Password', smtpPasswordPlaceholder: 'Please enter SMTP password', enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)', - enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)' + enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)', }, - group: { + group: { title: 'Team Member', member: 'Member', manage: 'Owner', @@ -166,7 +164,8 @@ export default { delete: { button: 'Remove', confirmTitle: 'Wheather to remove the member:', - confirmMessage: "After removal, the member's knowledge base and application permissions will be revoked.", + confirmMessage: + "After removal, the member's knowledge base and application permissions will be revoked.", }, setting: { management: 'manegement', @@ -180,5 +179,16 @@ export default { requiredMessage: 'Please enter Username/Email', }, }, - }, + }, + shared: { + label: 'Shared', + shared_resources: 'Shared Resources', + shared_tool: 'Shared Tool', + shared_model: 'Shared Model', + shared_knowledge: 'Shared Knowledge', + authorized_workspace: 'Authorize Workspace', + }, + resource_management: { + label: 'Resource Management', + }, } diff --git a/ui/src/locales/lang/zh-CN/views/system.ts b/ui/src/locales/lang/zh-CN/views/system.ts index 128c7eff7..9e5f4d8b7 100644 --- a/ui/src/locales/lang/zh-CN/views/system.ts +++ b/ui/src/locales/lang/zh-CN/views/system.ts @@ -1,13 +1,6 @@ export default { title: '系统管理', subTitle: '系统设置', - shared: '共享', - shared_resources: '共享资源', - resource_management: '资源管理', - share_tool: '共享工具', - share_model: '共享模型', - share_knowledge: '共享知识库', - authorized_workspace: '授权工作空间', test: '测试连接', testSuccess: '测试连接成功', testFailed: '测试连接失败', @@ -184,4 +177,15 @@ export default { }, }, }, + shared: { + label: '共享', + shared_resources: '共享资源', + shared_tool: '共享工具', + shared_model: '共享模型', + shared_knowledge: '共享知识库', + authorized_workspace: '授权工作空间', + }, + resource_management: { + label: '资源管理', + }, } diff --git a/ui/src/locales/lang/zh-Hant/views/system.ts b/ui/src/locales/lang/zh-Hant/views/system.ts index c5215e9f9..4944c1ddf 100644 --- a/ui/src/locales/lang/zh-Hant/views/system.ts +++ b/ui/src/locales/lang/zh-Hant/views/system.ts @@ -110,4 +110,15 @@ export default { enableSSL: '啟用 SSL(如果 SMTP 端口是 465,通常需要啟用 SSL)', enableTLS: '啟用 TLS(如果 SMTP 端口是 587,通常需要啟用 TLS)', }, + shared: { + label: '共享', + shared_resources: '共享资源', + shared_tool: '共享工具', + shared_model: '共享模型', + shared_knowledge: '共享知识', + authorized_workspace: '授权工作区', + }, + resource_management: { + label: '资源管理', + }, } diff --git a/ui/src/router/modules/system.ts b/ui/src/router/modules/system.ts index 5dcc9a40a..54c0a238e 100644 --- a/ui/src/router/modules/system.ts +++ b/ui/src/router/modules/system.ts @@ -70,7 +70,7 @@ const systemRouter = { meta: { icon: 'app-folder-share', iconActive: 'app-folder-share-active', - title: 'views.system.resource_management', + title: 'views.system.resource_management.label', activeMenu: '/system', parentPath: '/system', parentName: 'system', @@ -119,7 +119,7 @@ const systemRouter = { meta: { icon: 'app-folder-share', iconActive: 'app-folder-share-active', - title: 'views.system.shared_resources', + title: 'views.system.shared.shared_resources', activeMenu: '/system', parentPath: '/system', parentName: 'system', @@ -146,7 +146,7 @@ const systemRouter = { parentPath: '/system', parentName: 'system', }, - component: () => import('@/views/shared/tool-shared/index.vue'), + component: () => import('@/views/system-shared/ToolSharedIndex.vue'), }, { path: '/system/shared/model', diff --git a/ui/src/stores/index.ts b/ui/src/stores/index.ts index 39f7a36ef..838a991a8 100644 --- a/ui/src/stores/index.ts +++ b/ui/src/stores/index.ts @@ -12,6 +12,7 @@ import useDocumentStore from './modules/document' import useApplicationStore from './modules/application' import useChatLogStore from './modules/chat-log' import useChatUserStore from './modules/chat-user' +import useToolStore from './modules/tool' const useStore = () => ({ common: useCommonStore(), login: useLoginStore(), @@ -27,6 +28,7 @@ const useStore = () => ({ application: useApplicationStore(), chatLog: useChatLogStore(), chatUser: useChatUserStore(), + tool: useToolStore(), }) export default useStore diff --git a/ui/src/stores/modules/folder.ts b/ui/src/stores/modules/folder.ts index 47e583a7a..2b3d7a87e 100644 --- a/ui/src/stores/modules/folder.ts +++ b/ui/src/stores/modules/folder.ts @@ -1,10 +1,15 @@ -import {defineStore} from 'pinia' -import {type Ref} from 'vue' +import { defineStore } from 'pinia' +import { type Ref } from 'vue' import folderApi from '@/api/folder' const useFolderStore = defineStore('folder', { - state: () => ({}), + state: () => ({ + currentFolder: {} as any, + }), actions: { + setCurrentFolder(folder: any) { + this.currentFolder = folder + }, async asyncGetFolder(source: string, data: any, loading?: Ref) { return new Promise((resolve, reject) => { folderApi diff --git a/ui/src/stores/modules/tool.ts b/ui/src/stores/modules/tool.ts new file mode 100644 index 000000000..b5acdcabe --- /dev/null +++ b/ui/src/stores/modules/tool.ts @@ -0,0 +1,42 @@ +import { defineStore } from 'pinia' +import { type Ref } from 'vue' +import { loadSharedApi } from '@/utils/dynamics-api/shared-api' +import type { pageRequest } from '@/api/type/common' +import useUserStore from './user' +import useFolderStore from './folder' + +const useToolStore = defineStore('tool', { + state: () => ({ + toolList: [] as any[], + }), + actions: { + setToolList(list: any[]) { + this.toolList = list + }, + async asyncGetToolListPage( + page: pageRequest, + isShared?: boolean | undefined, + systemType: 'systemShare' | 'workspace' | 'systemManage' = 'workspace', + loading?: Ref, + ) { + return new Promise((resolve, reject) => { + const folder = useFolderStore() + const user = useUserStore() + const params = { + folder_id: folder.currentFolder?.id || user.getWorkspaceId(), + scope: systemType === 'systemShare' ? 'SHARED' : 'WORKSPACE', + } + loadSharedApi({ type: 'tool', isShared, systemType }) + .getToolListPage(page, params, loading) + .then((res: any) => { + resolve(res) + }) + .catch((error: any) => { + reject(error) + }) + }) + }, + }, +}) + +export default useToolStore diff --git a/ui/src/utils/array.ts b/ui/src/utils/array.ts new file mode 100644 index 000000000..15a8a2044 --- /dev/null +++ b/ui/src/utils/array.ts @@ -0,0 +1,7 @@ +// 树形结构转平 +export function TreeToFlatten(treeData: any[]) { + return treeData.reduce((acc, node) => { + const { children, ...rest } = node + return [...acc, rest, ...(children ? TreeToFlatten(children) : [])] + }, []) +} diff --git a/ui/src/utils/dynamics-api/shared-api.ts b/ui/src/utils/dynamics-api/shared-api.ts index f1ed6e3d3..71e7eb42a 100644 --- a/ui/src/utils/dynamics-api/shared-api.ts +++ b/ui/src/utils/dynamics-api/shared-api.ts @@ -2,6 +2,9 @@ import knowledgeWorkspaceApi from '@/api/knowledge/knowledge' import modelWorkspaceApi from '@/api/model/model' import toolWorkspaceApi from '@/api/tool/tool' import sharedWorkspaceApi from '@/api/shared-workspace' +import toolSystemShareApi from '@/api/system-shared/tool' +import modelSystemShareApi from '@/api/system-shared/model' +import knowledgeSystemShareApi from '@/api/system-shared/knowledge' // 普通 API const workspaceApiMap = { @@ -10,15 +13,41 @@ const workspaceApiMap = { tool: toolWorkspaceApi, } as any -/** 动态导入 API 模块的函数 - * loadSharedApi('knowledge', true) - */ +// 系统分享 API +const systemShareApiMap = { + knowledge: knowledgeSystemShareApi, + model: modelSystemShareApi, + tool: toolSystemShareApi, +} as any -export function loadSharedApi(type: string, isShared?: boolean) { +// 资源管理 API +const systemManageApiMap = { + // knowledge: knowledgeWorkspaceApi, + // model: modelWorkspaceApi, + // tool: toolSystemShareApi, +} as any + +const data = { + systemShare: systemShareApiMap, + workspace: workspaceApiMap, + systemManage: systemManageApiMap, +} +/** 动态导入 API 模块的函数 + * loadSharedApi('knowledge', true,'systemShare') + */ +export function loadSharedApi({ + type, + isShared, + systemType, +}: { + type: string + isShared?: boolean | undefined + systemType?: 'systemShare' | 'workspace' | 'systemManage' +}) { if (isShared) { // 共享 API return sharedWorkspaceApi } else { - return workspaceApiMap[type] + return data[systemType || 'workspace'][type] } } diff --git a/ui/src/views/application/index.vue b/ui/src/views/application/index.vue index 9215c19b9..e71730959 100644 --- a/ui/src/views/application/index.vue +++ b/ui/src/views/application/index.vue @@ -3,7 +3,7 @@ - -