feat: tool
This commit is contained in:
parent
2ab57802f4
commit
11fa3c4814
51
ui/src/components/folder-breadcrumb/index.vue
Normal file
51
ui/src/components/folder-breadcrumb/index.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<el-breadcrumb separator-icon="ArrowRight" style="line-height: 22px">
|
||||||
|
<h4 v-if="breadcrumbData?.length === 1">{{ breadcrumbData[0]?.name }}</h4>
|
||||||
|
<el-breadcrumb-item v-for="(item, index) in breadcrumbData" :key="index" v-else>
|
||||||
|
<h5 class="ml-4" v-if="index === breadcrumbData.length - 1">{{ item.name }}</h5>
|
||||||
|
<el-button v-else link @click="handleClick(item)">{{ item.name }}</el-button>
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { TreeToFlatten } from '@/utils/array'
|
||||||
|
defineOptions({ name: 'FolderBreadcrumb' })
|
||||||
|
import useStore from '@/stores'
|
||||||
|
const { folder, user } = useStore()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
folderList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const breadcrumbData = computed(() => {
|
||||||
|
return folder.currentFolder?.id && getBreadcrumbData()
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['click'])
|
||||||
|
|
||||||
|
function getBreadcrumbData() {
|
||||||
|
const targetId = folder.currentFolder?.id
|
||||||
|
const list = TreeToFlatten(props.folderList)
|
||||||
|
if (!folder.currentFolder) return [] // 如果没有 id,返回空数组
|
||||||
|
const breadcrumbList: any[] = []
|
||||||
|
let currentId: string | null = targetId
|
||||||
|
while (currentId) {
|
||||||
|
const currentNode = list.find((item: any) => item.id === currentId)
|
||||||
|
if (!currentNode) break // 如果找不到节点,终止循环
|
||||||
|
breadcrumbList.unshift(currentNode) // 添加到面包屑
|
||||||
|
currentId = currentNode.parent_id // 继续查找父级
|
||||||
|
}
|
||||||
|
return breadcrumbList
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClick(item: any) {
|
||||||
|
emit('click', item)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -52,6 +52,8 @@ import { ref, watch, reactive } from 'vue'
|
|||||||
import folderApi from '@/api/folder'
|
import folderApi from '@/api/folder'
|
||||||
import { MsgSuccess, MsgAlert } from '@/utils/message'
|
import { MsgSuccess, MsgAlert } from '@/utils/message'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
|
import useStore from '@/stores'
|
||||||
|
const { tool } = useStore()
|
||||||
const emit = defineEmits(['refresh'])
|
const emit = defineEmits(['refresh'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -122,12 +124,14 @@ const submitHandle = async () => {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
MsgSuccess(t('common.editSuccess'))
|
MsgSuccess(t('common.editSuccess'))
|
||||||
emit('refresh')
|
emit('refresh')
|
||||||
|
tool.setToolList([])
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
folderApi.postFolder(sourceType.value, folderForm.value, loading).then((res) => {
|
folderApi.postFolder(sourceType.value, folderForm.value, loading).then((res) => {
|
||||||
MsgSuccess(t('common.createSuccess'))
|
MsgSuccess(t('common.createSuccess'))
|
||||||
emit('refresh')
|
emit('refresh')
|
||||||
|
tool.setToolList([])
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
:class="currentNodeKey === 'share' && 'active'"
|
:class="currentNodeKey === 'share' && 'active'"
|
||||||
>
|
>
|
||||||
<AppIcon :iconName="iconName" style="font-size: 18px"></AppIcon>
|
<AppIcon :iconName="iconName" style="font-size: 18px"></AppIcon>
|
||||||
<span class="ml-8 lighter">{{ $t(shareTitle) }}</span>
|
<span class="ml-8 lighter">{{ shareTitle }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-tree
|
<el-tree
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="canOperation"
|
v-if="canOperation && node.level !== 3"
|
||||||
@click.stop
|
@click.stop
|
||||||
v-show="hoverNodeId === data.id"
|
v-show="hoverNodeId === data.id"
|
||||||
@mouseenter.stop="handleMouseEnter(data)"
|
@mouseenter.stop="handleMouseEnter(data)"
|
||||||
@ -61,7 +61,7 @@
|
|||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
divided
|
divided
|
||||||
@click.stop="deleteFolder(data)"
|
@click.stop="deleteFolder(data)"
|
||||||
:disabled="data.id === 'default'"
|
:disabled="!data.parent_id"
|
||||||
>
|
>
|
||||||
<el-icon><Delete /></el-icon>
|
<el-icon><Delete /></el-icon>
|
||||||
{{ $t('common.delete') }}
|
{{ $t('common.delete') }}
|
||||||
@ -109,7 +109,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
shareTitle: {
|
shareTitle: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'views.system.share_knowledge',
|
default: 'views.system.shared.shared_knowledge',
|
||||||
},
|
},
|
||||||
canOperation: {
|
canOperation: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -162,7 +162,7 @@ const handleNodeClick = (data: Tree) => {
|
|||||||
|
|
||||||
const handleSharedNodeClick = () => {
|
const handleSharedNodeClick = () => {
|
||||||
treeRef.value?.setCurrentKey(undefined)
|
treeRef.value?.setCurrentKey(undefined)
|
||||||
emit('handleNodeClick', { id: 'share', name: t(props.shareTitle) })
|
emit('handleNodeClick', { id: 'share', name: props.shareTitle })
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteFolder(row: Tree) {
|
function deleteFolder(row: Tree) {
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import AiChat from './ai-chat/index.vue'
|
|||||||
import KnowledgeIcon from './app-icon/KnowledgeIcon.vue'
|
import KnowledgeIcon from './app-icon/KnowledgeIcon.vue'
|
||||||
import TagGroup from './tag-group/index.vue'
|
import TagGroup from './tag-group/index.vue'
|
||||||
import WorkspaceDropdown from './workspace-dropdown/index.vue'
|
import WorkspaceDropdown from './workspace-dropdown/index.vue'
|
||||||
|
import FolderBreadcrumb from './folder-breadcrumb/index.vue'
|
||||||
export default {
|
export default {
|
||||||
install(app: App) {
|
install(app: App) {
|
||||||
app.component('LogoFull', LogoFull)
|
app.component('LogoFull', LogoFull)
|
||||||
@ -53,5 +54,6 @@ export default {
|
|||||||
app.component('KnowledgeIcon', KnowledgeIcon)
|
app.component('KnowledgeIcon', KnowledgeIcon)
|
||||||
app.component('TagGroup', TagGroup)
|
app.component('TagGroup', TagGroup)
|
||||||
app.component('WorkspaceDropdown', WorkspaceDropdown)
|
app.component('WorkspaceDropdown', WorkspaceDropdown)
|
||||||
|
app.component('FolderBreadcrumb', FolderBreadcrumb)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
title: 'System',
|
title: 'System',
|
||||||
subTitle: 'Syetem Settings',
|
subTitle: 'Syetem Settings',
|
||||||
shared: 'Shared',
|
|
||||||
shared_resources: 'Shared Resources',
|
|
||||||
share_knowledge: 'Shared Knowledge',
|
|
||||||
authorized_workspace: 'Authorize Workspace',
|
|
||||||
test: 'Test Connection',
|
test: 'Test Connection',
|
||||||
testSuccess: 'Successful',
|
testSuccess: 'Successful',
|
||||||
testFailed: 'Test connection failed',
|
testFailed: 'Test connection failed',
|
||||||
@ -23,7 +19,7 @@ export default {
|
|||||||
ldap_filterPlaceholder: 'Please enter user filter',
|
ldap_filterPlaceholder: 'Please enter user filter',
|
||||||
ldap_mapping: 'LDAP Attribute Mapping',
|
ldap_mapping: 'LDAP Attribute Mapping',
|
||||||
ldap_mappingPlaceholder: 'Please enter LDAP attribute mapping',
|
ldap_mappingPlaceholder: 'Please enter LDAP attribute mapping',
|
||||||
enableAuthentication: 'Enable LDAP Authentication'
|
enableAuthentication: 'Enable LDAP Authentication',
|
||||||
},
|
},
|
||||||
cas: {
|
cas: {
|
||||||
title: 'CAS',
|
title: 'CAS',
|
||||||
@ -33,7 +29,7 @@ export default {
|
|||||||
validateUrlPlaceholder: 'Please enter validation address',
|
validateUrlPlaceholder: 'Please enter validation address',
|
||||||
redirectUrl: 'Callback Address',
|
redirectUrl: 'Callback Address',
|
||||||
redirectUrlPlaceholder: 'Please enter callback address',
|
redirectUrlPlaceholder: 'Please enter callback address',
|
||||||
enableAuthentication: 'Enable CAS Authentication'
|
enableAuthentication: 'Enable CAS Authentication',
|
||||||
},
|
},
|
||||||
oidc: {
|
oidc: {
|
||||||
title: 'OIDC',
|
title: 'OIDC',
|
||||||
@ -52,7 +48,7 @@ export default {
|
|||||||
logoutEndpointPlaceholder: 'Please enter logout endpoint',
|
logoutEndpointPlaceholder: 'Please enter logout endpoint',
|
||||||
redirectUrl: 'Redirect URL',
|
redirectUrl: 'Redirect URL',
|
||||||
redirectUrlPlaceholder: 'Please enter redirect URL',
|
redirectUrlPlaceholder: 'Please enter redirect URL',
|
||||||
enableAuthentication: 'Enable OIDC Authentication'
|
enableAuthentication: 'Enable OIDC Authentication',
|
||||||
},
|
},
|
||||||
|
|
||||||
oauth2: {
|
oauth2: {
|
||||||
@ -73,7 +69,7 @@ export default {
|
|||||||
redirectUrlPlaceholder: 'Please enter redirect URL',
|
redirectUrlPlaceholder: 'Please enter redirect URL',
|
||||||
filedMapping: 'Field Mapping',
|
filedMapping: 'Field Mapping',
|
||||||
filedMappingPlaceholder: 'Please enter field mapping',
|
filedMappingPlaceholder: 'Please enter field mapping',
|
||||||
enableAuthentication: 'Enable OAuth2 Authentication'
|
enableAuthentication: 'Enable OAuth2 Authentication',
|
||||||
},
|
},
|
||||||
scanTheQRCode: {
|
scanTheQRCode: {
|
||||||
title: 'Scan the QR code',
|
title: 'Scan the QR code',
|
||||||
@ -95,10 +91,10 @@ export default {
|
|||||||
larkQrCode: 'Lark Scan Code Login',
|
larkQrCode: 'Lark Scan Code Login',
|
||||||
dingtalkQrCode: 'DingTalk Scan Code Login',
|
dingtalkQrCode: 'DingTalk Scan Code Login',
|
||||||
setting: ' Setting',
|
setting: ' Setting',
|
||||||
access: 'Access'
|
access: 'Access',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
title: 'Appearance Settings',
|
title: 'Appearance Settings',
|
||||||
platformDisplayTheme: 'Platform Display Theme',
|
platformDisplayTheme: 'Platform Display Theme',
|
||||||
customTheme: 'Custom Theme',
|
customTheme: 'Custom Theme',
|
||||||
@ -115,8 +111,10 @@ export default {
|
|||||||
loginLogo: 'Login Logo',
|
loginLogo: 'Login Logo',
|
||||||
websiteLogo: 'Website Logo',
|
websiteLogo: 'Website Logo',
|
||||||
replacePicture: 'Replace Picture',
|
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.",
|
websiteLogoTip:
|
||||||
loginLogoTip: "Login page right-side logo. Recommended size is 204*52. Supports JPG, PNG, GIF formats, with a maximum file size of 10 MB.",
|
'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:
|
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.',
|
'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',
|
websiteName: 'Website Name',
|
||||||
@ -146,14 +144,14 @@ export default {
|
|||||||
smtpPortPlaceholder: 'Please enter SMTP port',
|
smtpPortPlaceholder: 'Please enter SMTP port',
|
||||||
smtpUser: 'SMTP User',
|
smtpUser: 'SMTP User',
|
||||||
smtpUserPlaceholder: 'Please enter SMTP user',
|
smtpUserPlaceholder: 'Please enter SMTP user',
|
||||||
sendEmail: 'Sender\'s Email',
|
sendEmail: "Sender's Email",
|
||||||
sendEmailPlaceholder: 'Please enter the sender\'s email',
|
sendEmailPlaceholder: "Please enter the sender's email",
|
||||||
smtpPassword: 'SMTP Password',
|
smtpPassword: 'SMTP Password',
|
||||||
smtpPasswordPlaceholder: 'Please enter SMTP password',
|
smtpPasswordPlaceholder: 'Please enter SMTP password',
|
||||||
enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)',
|
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',
|
title: 'Team Member',
|
||||||
member: 'Member',
|
member: 'Member',
|
||||||
manage: 'Owner',
|
manage: 'Owner',
|
||||||
@ -166,7 +164,8 @@ export default {
|
|||||||
delete: {
|
delete: {
|
||||||
button: 'Remove',
|
button: 'Remove',
|
||||||
confirmTitle: 'Wheather to remove the member:',
|
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: {
|
setting: {
|
||||||
management: 'manegement',
|
management: 'manegement',
|
||||||
@ -180,5 +179,16 @@ export default {
|
|||||||
requiredMessage: 'Please enter Username/Email',
|
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',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
subTitle: '系统设置',
|
subTitle: '系统设置',
|
||||||
shared: '共享',
|
|
||||||
shared_resources: '共享资源',
|
|
||||||
resource_management: '资源管理',
|
|
||||||
share_tool: '共享工具',
|
|
||||||
share_model: '共享模型',
|
|
||||||
share_knowledge: '共享知识库',
|
|
||||||
authorized_workspace: '授权工作空间',
|
|
||||||
test: '测试连接',
|
test: '测试连接',
|
||||||
testSuccess: '测试连接成功',
|
testSuccess: '测试连接成功',
|
||||||
testFailed: '测试连接失败',
|
testFailed: '测试连接失败',
|
||||||
@ -184,4 +177,15 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
shared: {
|
||||||
|
label: '共享',
|
||||||
|
shared_resources: '共享资源',
|
||||||
|
shared_tool: '共享工具',
|
||||||
|
shared_model: '共享模型',
|
||||||
|
shared_knowledge: '共享知识库',
|
||||||
|
authorized_workspace: '授权工作空间',
|
||||||
|
},
|
||||||
|
resource_management: {
|
||||||
|
label: '资源管理',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,4 +110,15 @@ export default {
|
|||||||
enableSSL: '啟用 SSL(如果 SMTP 端口是 465,通常需要啟用 SSL)',
|
enableSSL: '啟用 SSL(如果 SMTP 端口是 465,通常需要啟用 SSL)',
|
||||||
enableTLS: '啟用 TLS(如果 SMTP 端口是 587,通常需要啟用 TLS)',
|
enableTLS: '啟用 TLS(如果 SMTP 端口是 587,通常需要啟用 TLS)',
|
||||||
},
|
},
|
||||||
|
shared: {
|
||||||
|
label: '共享',
|
||||||
|
shared_resources: '共享资源',
|
||||||
|
shared_tool: '共享工具',
|
||||||
|
shared_model: '共享模型',
|
||||||
|
shared_knowledge: '共享知识',
|
||||||
|
authorized_workspace: '授权工作区',
|
||||||
|
},
|
||||||
|
resource_management: {
|
||||||
|
label: '资源管理',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,7 +70,7 @@ const systemRouter = {
|
|||||||
meta: {
|
meta: {
|
||||||
icon: 'app-folder-share',
|
icon: 'app-folder-share',
|
||||||
iconActive: 'app-folder-share-active',
|
iconActive: 'app-folder-share-active',
|
||||||
title: 'views.system.resource_management',
|
title: 'views.system.resource_management.label',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
@ -119,7 +119,7 @@ const systemRouter = {
|
|||||||
meta: {
|
meta: {
|
||||||
icon: 'app-folder-share',
|
icon: 'app-folder-share',
|
||||||
iconActive: 'app-folder-share-active',
|
iconActive: 'app-folder-share-active',
|
||||||
title: 'views.system.shared_resources',
|
title: 'views.system.shared.shared_resources',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
@ -146,7 +146,7 @@ const systemRouter = {
|
|||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
},
|
},
|
||||||
component: () => import('@/views/shared/tool-shared/index.vue'),
|
component: () => import('@/views/system-shared/ToolSharedIndex.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system/shared/model',
|
path: '/system/shared/model',
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import useDocumentStore from './modules/document'
|
|||||||
import useApplicationStore from './modules/application'
|
import useApplicationStore from './modules/application'
|
||||||
import useChatLogStore from './modules/chat-log'
|
import useChatLogStore from './modules/chat-log'
|
||||||
import useChatUserStore from './modules/chat-user'
|
import useChatUserStore from './modules/chat-user'
|
||||||
|
import useToolStore from './modules/tool'
|
||||||
const useStore = () => ({
|
const useStore = () => ({
|
||||||
common: useCommonStore(),
|
common: useCommonStore(),
|
||||||
login: useLoginStore(),
|
login: useLoginStore(),
|
||||||
@ -27,6 +28,7 @@ const useStore = () => ({
|
|||||||
application: useApplicationStore(),
|
application: useApplicationStore(),
|
||||||
chatLog: useChatLogStore(),
|
chatLog: useChatLogStore(),
|
||||||
chatUser: useChatUserStore(),
|
chatUser: useChatUserStore(),
|
||||||
|
tool: useToolStore(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default useStore
|
export default useStore
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
import {defineStore} from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import {type Ref} from 'vue'
|
import { type Ref } from 'vue'
|
||||||
import folderApi from '@/api/folder'
|
import folderApi from '@/api/folder'
|
||||||
|
|
||||||
const useFolderStore = defineStore('folder', {
|
const useFolderStore = defineStore('folder', {
|
||||||
state: () => ({}),
|
state: () => ({
|
||||||
|
currentFolder: {} as any,
|
||||||
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
|
setCurrentFolder(folder: any) {
|
||||||
|
this.currentFolder = folder
|
||||||
|
},
|
||||||
async asyncGetFolder(source: string, data: any, loading?: Ref<boolean>) {
|
async asyncGetFolder(source: string, data: any, loading?: Ref<boolean>) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
folderApi
|
folderApi
|
||||||
|
|||||||
42
ui/src/stores/modules/tool.ts
Normal file
42
ui/src/stores/modules/tool.ts
Normal file
@ -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<boolean>,
|
||||||
|
) {
|
||||||
|
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
|
||||||
7
ui/src/utils/array.ts
Normal file
7
ui/src/utils/array.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// 树形结构转平
|
||||||
|
export function TreeToFlatten(treeData: any[]) {
|
||||||
|
return treeData.reduce((acc, node) => {
|
||||||
|
const { children, ...rest } = node
|
||||||
|
return [...acc, rest, ...(children ? TreeToFlatten(children) : [])]
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
@ -2,6 +2,9 @@ import knowledgeWorkspaceApi from '@/api/knowledge/knowledge'
|
|||||||
import modelWorkspaceApi from '@/api/model/model'
|
import modelWorkspaceApi from '@/api/model/model'
|
||||||
import toolWorkspaceApi from '@/api/tool/tool'
|
import toolWorkspaceApi from '@/api/tool/tool'
|
||||||
import sharedWorkspaceApi from '@/api/shared-workspace'
|
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
|
// 普通 API
|
||||||
const workspaceApiMap = {
|
const workspaceApiMap = {
|
||||||
@ -10,15 +13,41 @@ const workspaceApiMap = {
|
|||||||
tool: toolWorkspaceApi,
|
tool: toolWorkspaceApi,
|
||||||
} as any
|
} as any
|
||||||
|
|
||||||
/** 动态导入 API 模块的函数
|
// 系统分享 API
|
||||||
* loadSharedApi('knowledge', true)
|
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) {
|
if (isShared) {
|
||||||
// 共享 API
|
// 共享 API
|
||||||
return sharedWorkspaceApi
|
return sharedWorkspaceApi
|
||||||
} else {
|
} else {
|
||||||
return workspaceApiMap[type]
|
return data[systemType || 'workspace'][type]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<template #left>
|
<template #left>
|
||||||
<h4 class="p-16 pb-0">{{ $t('views.application.title') }}</h4>
|
<h4 class="p-16 pb-0">{{ $t('views.application.title') }}</h4>
|
||||||
<folder-tree
|
<folder-tree
|
||||||
:source="FolderSource.TOOL"
|
:source="FolderSource.APPLICATION"
|
||||||
:data="folderList"
|
:data="folderList"
|
||||||
:currentNodeKey="currentFolder?.id"
|
:currentNodeKey="currentFolder?.id"
|
||||||
@handleNodeClick="folderClickHandel"
|
@handleNodeClick="folderClickHandel"
|
||||||
|
|||||||
@ -199,10 +199,14 @@
|
|||||||
router.push({ path: `/knowledge/${item.id}/${currentFolder.id}/document` })
|
router.push({ path: `/knowledge/${item.id}/${currentFolder.id}/document` })
|
||||||
"
|
"
|
||||||
v-hasPermission="[
|
v-hasPermission="[
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
PermissionConst.KNOWLEDGE_DOCUMENT_READ.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_DOCUMENT_READ
|
||||||
PermissionConst.KNOWLEDGE_DOCUMENT_READ.getKnowledgeWorkspaceResourcePermission(item.id),]"
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_DOCUMENT_READ.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<KnowledgeIcon :type="item.type" />
|
<KnowledgeIcon :type="item.type" />
|
||||||
@ -214,7 +218,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #tag>
|
<template #tag>
|
||||||
<el-tag v-if="isShared" type="info" class="info-tag">
|
<el-tag v-if="isShared" type="info" class="info-tag">
|
||||||
{{ t('views.system.shared') }}
|
{{ t('views.system.shared.label') }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -248,12 +252,21 @@
|
|||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
icon="Refresh"
|
icon="Refresh"
|
||||||
@click.stop="syncKnowledge(item)"
|
@click.stop="syncKnowledge(item)"
|
||||||
v-if="item.type === 1 &&
|
v-if="
|
||||||
hasPermission([
|
item.type === 1 &&
|
||||||
RoleConst.ADMIN,
|
hasPermission(
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
[
|
||||||
PermissionConst.KNOWLEDGE_SYNC.getWorkspacePermissionWorkspaceManageRole,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_SYNC.getKnowledgeWorkspaceResourcePermission(item.id)],'OR')"
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
PermissionConst.KNOWLEDGE_SYNC
|
||||||
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_SYNC.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
>{{ $t('views.knowledge.setting.sync') }}
|
>{{ $t('views.knowledge.setting.sync') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@ -263,8 +276,11 @@
|
|||||||
[
|
[
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_VECTOR.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_VECTOR
|
||||||
PermissionConst.KNOWLEDGE_VECTOR.getKnowledgeWorkspaceResourcePermission(item.id),
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_VECTOR.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
)
|
)
|
||||||
@ -282,8 +298,11 @@
|
|||||||
[
|
[
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_PROBLEM_CREATE.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_PROBLEM_CREATE
|
||||||
PermissionConst.KNOWLEDGE_PROBLEM_CREATE.getKnowledgeWorkspaceResourcePermission(item.id),
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_PROBLEM_CREATE.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
)
|
)
|
||||||
@ -302,8 +321,11 @@
|
|||||||
[
|
[
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_EDIT
|
||||||
PermissionConst.KNOWLEDGE_EDIT.getKnowledgeWorkspaceResourcePermission(item.id),
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_EDIT.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
)
|
)
|
||||||
@ -318,8 +340,11 @@
|
|||||||
[
|
[
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_EXPORT.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_EXPORT
|
||||||
PermissionConst.KNOWLEDGE_EXPORT.getKnowledgeWorkspaceResourcePermission(item.id),
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_EXPORT.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
)
|
)
|
||||||
@ -335,8 +360,11 @@
|
|||||||
[
|
[
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_EXPORT.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_EXPORT
|
||||||
PermissionConst.KNOWLEDGE_EXPORT.getKnowledgeWorkspaceResourcePermission(item.id),
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_EXPORT.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
)
|
)
|
||||||
@ -354,8 +382,11 @@
|
|||||||
[
|
[
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
RoleConst.ADMIN,
|
RoleConst.ADMIN,
|
||||||
PermissionConst.KNOWLEDGE_DELETE.getWorkspacePermissionWorkspaceManageRole,
|
PermissionConst.KNOWLEDGE_DELETE
|
||||||
PermissionConst.KNOWLEDGE_DELETE.getKnowledgeWorkspaceResourcePermission(item.id),
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.KNOWLEDGE_DELETE.getKnowledgeWorkspaceResourcePermission(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
)
|
)
|
||||||
@ -476,7 +507,7 @@ function getList() {
|
|||||||
[search_type.value]: search_form.value[search_type.value],
|
[search_type.value]: search_form.value[search_type.value],
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSharedApi('knowledge', isShared.value)
|
loadSharedApi({ type: 'knowledge', isShared: isShared.value })
|
||||||
.getKnowledgeListPage(paginationConfig, params, loading)
|
.getKnowledgeListPage(paginationConfig, params, loading)
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
paginationConfig.total = res.data.total
|
paginationConfig.total = res.data.total
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #tag>
|
<template #tag>
|
||||||
<el-tag v-if="isShared" type="info" class="info-tag">
|
<el-tag v-if="isShared" type="info" class="info-tag">
|
||||||
{{ t('views.system.shared') }}
|
{{ t('views.system.shared.label') }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
:class="active?.provider === 'share' && 'active'"
|
:class="active?.provider === 'share' && 'active'"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-folder-share-active" style="font-size: 18px"></AppIcon>
|
<AppIcon iconName="app-folder-share-active" style="font-size: 18px"></AppIcon>
|
||||||
<span class="ml-8 lighter">{{ $t('views.system.share_model') }}</span>
|
<span class="ml-8 lighter">{{ $t('views.system.shared.shared_model') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="all-mode flex cursor"
|
class="all-mode flex cursor"
|
||||||
@ -145,7 +145,7 @@ const clickListHandle = (item: Provider) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSharedNodeClick = () => {
|
const handleSharedNodeClick = () => {
|
||||||
emit('click', { provider: 'share', name: t('views.system.share_model') })
|
emit('click', { provider: 'share', name: t('views.system.shared.shared_model') })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
:data="provider_list"
|
:data="provider_list"
|
||||||
@click="clickListHandle"
|
@click="clickListHandle"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
shareTitle="views.system.share_tool"
|
shareTitle="views.system.shared.shared_tool"
|
||||||
:showShared="permissionPrecise['is_share']()"
|
:showShared="permissionPrecise['is_share']()"
|
||||||
:active="active_provider"
|
:active="active_provider"
|
||||||
/>
|
/>
|
||||||
@ -55,8 +55,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="!isShared &&
|
v-if="!isShared &&
|
||||||
permissionPrecise.addModel()
|
permissionPrecise.addModel()
|
||||||
"
|
"
|
||||||
class="ml-16"
|
class="ml-16"
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -202,7 +202,7 @@ const openCreateModel = (provider?: Provider, model_type?: string) => {
|
|||||||
|
|
||||||
const list_model = () => {
|
const list_model = () => {
|
||||||
const params = active_provider.value?.provider ? { provider: active_provider.value.provider } : {}
|
const params = active_provider.value?.provider ? { provider: active_provider.value.provider } : {}
|
||||||
loadSharedApi('model', isShared.value)
|
loadSharedApi({ type: 'model', isShared: isShared.value })
|
||||||
.getModel({ ...model_search_form.value, ...params }, list_model_loading)
|
.getModel({ ...model_search_form.value, ...params }, list_model_loading)
|
||||||
.then((ok: any) => {
|
.then((ok: any) => {
|
||||||
model_list.value = ok.data
|
model_list.value = ok.data
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="resource-manage_knowledge">
|
<div class="resource-manage_knowledge">
|
||||||
<div class="shared-header">
|
<div class="shared-header">
|
||||||
<span class="title">{{ t('views.system.resource_management') }}</span>
|
<span class="title">{{ t('views.system.resource_management.label') }}</span>
|
||||||
<el-icon size="12">
|
<el-icon size="12">
|
||||||
<rightOutlined></rightOutlined>
|
<rightOutlined></rightOutlined>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="resource-manage_tool">
|
<div class="resource-manage_tool">
|
||||||
<div class="shared-header">
|
<div class="shared-header">
|
||||||
<span class="title">{{ t('views.system.resource_management') }}</span>
|
<span class="title">{{ t('views.system.resource_management.label') }}</span>
|
||||||
<el-icon size="12">
|
<el-icon size="12">
|
||||||
<rightOutlined></rightOutlined>
|
<rightOutlined></rightOutlined>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="knowledge-shared">
|
<div class="knowledge-shared">
|
||||||
<ContentContainer :header="$t('views.system.share_knowledge')">
|
<ContentContainer :header="$t('views.system.shared.shared_knowledge')">
|
||||||
<template #search>
|
<template #search>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex-between complex-search">
|
<div class="flex-between complex-search">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="shared-header">
|
<div class="shared-header">
|
||||||
<span class="title">{{ t('views.system.shared_resources') }}</span>
|
<span class="title">{{ t('views.system.shared.shared_resources') }}</span>
|
||||||
<el-icon size="12">
|
<el-icon size="12">
|
||||||
<rightOutlined></rightOutlined>
|
<rightOutlined></rightOutlined>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -230,7 +230,7 @@
|
|||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
icon="Lock"
|
icon="Lock"
|
||||||
@click.stop="openAuthorizedWorkspaceDialog(item)"
|
@click.stop="openAuthorizedWorkspaceDialog(item)"
|
||||||
>{{ $t('views.system.authorized_workspace') }}</el-dropdown-item
|
>{{ $t('views.system.shared.authorized_workspace') }}</el-dropdown-item
|
||||||
>
|
>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
icon="Setting"
|
icon="Setting"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="model-shared">
|
<div class="model-shared">
|
||||||
<ContentContainer
|
<ContentContainer
|
||||||
:header="t('views.system.share_model')"
|
:header="t('views.system.shared.shared_model')"
|
||||||
v-loading="list_model_loading"
|
v-loading="list_model_loading"
|
||||||
>
|
>
|
||||||
<template #search>
|
<template #search>
|
||||||
|
|||||||
@ -85,7 +85,7 @@
|
|||||||
{{ $t('common.modify') }}
|
{{ $t('common.modify') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item icon="Lock" @click.stop="openAuthorizedWorkspaceDialog(model)">{{
|
<el-dropdown-item icon="Lock" @click.stop="openAuthorizedWorkspaceDialog(model)">{{
|
||||||
$t('views.system.authorized_workspace')
|
$t('views.system.shared.authorized_workspace')
|
||||||
}}</el-dropdown-item>
|
}}</el-dropdown-item>
|
||||||
|
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="model-shared">
|
<div class="model-shared">
|
||||||
<div class="shared-header">
|
<div class="shared-header">
|
||||||
<span class="title">{{ t('views.system.shared_resources') }}</span>
|
<span class="title">{{ t('views.system.shared.shared_resources') }}</span>
|
||||||
<el-icon size="12">
|
<el-icon size="12">
|
||||||
<rightOutlined></rightOutlined>
|
<rightOutlined></rightOutlined>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tool-shared">
|
<div class="tool-shared">
|
||||||
<ContentContainer :header="$t('views.system.share_tool')">
|
<ContentContainer :header="$t('views.system.shared.shared_tool')">
|
||||||
<template #search>
|
<template #search>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex-between complex-search">
|
<div class="flex-between complex-search">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="shared-header">
|
<div class="shared-header">
|
||||||
<span class="title">{{ t('views.system.shared_resources') }}</span>
|
<span class="title">{{ t('views.system.shared.shared_resources') }}</span>
|
||||||
<el-icon size="12">
|
<el-icon size="12">
|
||||||
<rightOutlined></rightOutlined>
|
<rightOutlined></rightOutlined>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -132,7 +132,7 @@
|
|||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
icon="Lock"
|
icon="Lock"
|
||||||
@click.stop="openAuthorizedWorkspaceDialog(item)"
|
@click.stop="openAuthorizedWorkspaceDialog(item)"
|
||||||
>{{ $t('views.system.authorized_workspace') }}</el-dropdown-item
|
>{{ $t('views.system.shared.authorized_workspace') }}</el-dropdown-item
|
||||||
>
|
>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
v-if="!item.template_id"
|
v-if="!item.template_id"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="shared-header">
|
<div class="shared-header">
|
||||||
<span class="title">{{ t('views.system.shared_resources') }}</span>
|
<span class="title">{{ t('views.system.shared.shared_resources') }}</span>
|
||||||
<el-icon size="12">
|
<el-icon size="12">
|
||||||
<rightOutlined></rightOutlined>
|
<rightOutlined></rightOutlined>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
:data="provider_list"
|
:data="provider_list"
|
||||||
@click="clickListHandle"
|
@click="clickListHandle"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
shareTitle="views.system.share_tool"
|
:shareTitle="$t('views.system.shared.shared_tool')"
|
||||||
isShared
|
isShared
|
||||||
:active="active_provider"
|
:active="active_provider"
|
||||||
/>
|
/>
|
||||||
|
|||||||
46
ui/src/views/system-shared/ToolSharedIndex.vue
Normal file
46
ui/src/views/system-shared/ToolSharedIndex.vue
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tool-shared">
|
||||||
|
<ToolListContainer>
|
||||||
|
<template #header>
|
||||||
|
<el-breadcrumb separator-icon="ArrowRight">
|
||||||
|
<el-breadcrumb-item>{{ t('views.system.shared.shared_resources') }}</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item>
|
||||||
|
{{ t('views.tool.title') }}
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
</ToolListContainer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref, reactive, computed } from 'vue'
|
||||||
|
|
||||||
|
import ToolListContainer from '@/views/tool/component/ToolListContainer.vue'
|
||||||
|
|
||||||
|
import { t } from '@/locales'
|
||||||
|
|
||||||
|
onMounted(() => {})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tool-shared {
|
||||||
|
padding-left: 8px;
|
||||||
|
.shared-header {
|
||||||
|
color: #646a73;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
:deep(.el-icon i) {
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-title {
|
||||||
|
color: #1f2329;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
583
ui/src/views/tool/component/ToolListContainer.vue
Normal file
583
ui/src/views/tool/component/ToolListContainer.vue
Normal file
@ -0,0 +1,583 @@
|
|||||||
|
<template>
|
||||||
|
<ContentContainer>
|
||||||
|
<template #header>
|
||||||
|
<slot name="header"> </slot>
|
||||||
|
</template>
|
||||||
|
<template #search>
|
||||||
|
<div class="flex">
|
||||||
|
<div class="flex-between complex-search">
|
||||||
|
<el-select
|
||||||
|
class="complex-search__left"
|
||||||
|
v-model="search_type"
|
||||||
|
style="width: 120px"
|
||||||
|
@change="search_type_change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('common.creator')" value="create_user" />
|
||||||
|
|
||||||
|
<el-option :label="$t('views.model.modelForm.modeName.label')" value="name" />
|
||||||
|
</el-select>
|
||||||
|
<el-input
|
||||||
|
v-if="search_type === 'name'"
|
||||||
|
v-model="search_form.name"
|
||||||
|
@change="getList"
|
||||||
|
:placeholder="$t('common.searchBar.placeholder')"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<el-select
|
||||||
|
v-else-if="search_type === 'create_user'"
|
||||||
|
v-model="search_form.create_user"
|
||||||
|
@change="getList"
|
||||||
|
clearable
|
||||||
|
style="width: 220px"
|
||||||
|
>
|
||||||
|
<el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.username" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<el-dropdown trigger="click" v-if="!isShared">
|
||||||
|
<el-button type="primary" class="ml-8" v-if="permissionPrecise.create()">
|
||||||
|
{{ $t('common.create') }}
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu class="create-dropdown">
|
||||||
|
<el-dropdown-item @click="openCreateDialog()">
|
||||||
|
<div class="flex align-center">
|
||||||
|
<el-avatar class="avatar-green" shape="square" :size="32">
|
||||||
|
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<div class="pre-wrap ml-8">
|
||||||
|
<div class="lighter">空白创建</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-upload
|
||||||
|
ref="elUploadRef"
|
||||||
|
:file-list="[]"
|
||||||
|
action="#"
|
||||||
|
multiple
|
||||||
|
:auto-upload="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:limit="1"
|
||||||
|
:on-change="(file: any, fileList: any) => importTool(file)"
|
||||||
|
class="import-button"
|
||||||
|
>
|
||||||
|
<el-dropdown-item class="w-full">
|
||||||
|
<div class="flex align-center w-full">
|
||||||
|
<el-avatar shape="square" class="mt-4" :size="36" style="background: none">
|
||||||
|
<img src="@/assets/icon_import.svg" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<div class="pre-wrap ml-8">
|
||||||
|
<div class="lighter">{{ $t('common.importCreate') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-upload>
|
||||||
|
<el-dropdown-item @click="openToolStoreDialog()">
|
||||||
|
<div class="flex align-center">
|
||||||
|
<el-avatar class="avatar-green" shape="square" :size="32">
|
||||||
|
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<div class="pre-wrap ml-8">
|
||||||
|
<div class="lighter">
|
||||||
|
{{ $t('views.tool.toolStore.createFromToolStore') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click="openCreateFolder" divided>
|
||||||
|
<div class="flex align-center">
|
||||||
|
<AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
|
||||||
|
<div class="pre-wrap ml-4">
|
||||||
|
<div class="lighter">
|
||||||
|
{{ $t('components.folder.addFolder') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
|
||||||
|
style="max-height: calc(100vh - 140px)"
|
||||||
|
>
|
||||||
|
<InfiniteScroll
|
||||||
|
:size="tool.toolList.length"
|
||||||
|
:total="paginationConfig.total"
|
||||||
|
:page_size="paginationConfig.page_size"
|
||||||
|
v-model:current_page="paginationConfig.current_page"
|
||||||
|
@load="getList"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
<el-row v-if="tool.toolList.length > 0" :gutter="15">
|
||||||
|
<template v-for="(item, index) in tool.toolList" :key="index">
|
||||||
|
<el-col
|
||||||
|
v-if="item.resource_type === 'folder'"
|
||||||
|
:xs="24"
|
||||||
|
:sm="12"
|
||||||
|
:md="12"
|
||||||
|
:lg="8"
|
||||||
|
:xl="6"
|
||||||
|
class="mb-16"
|
||||||
|
>
|
||||||
|
<CardBox
|
||||||
|
:title="item.name"
|
||||||
|
:description="item.desc || $t('common.noData')"
|
||||||
|
class="cursor"
|
||||||
|
@click="clickFolder(item)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<el-avatar shape="square" :size="32" style="background: none">
|
||||||
|
<AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
|
||||||
|
</el-avatar>
|
||||||
|
</template>
|
||||||
|
<template #subTitle>
|
||||||
|
<el-text class="color-secondary lighter" size="small">
|
||||||
|
{{ $t('common.creator') }}: {{ item.nick_name }}
|
||||||
|
</el-text>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
|
</el-col>
|
||||||
|
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||||
|
<CardBox
|
||||||
|
:title="item.name"
|
||||||
|
:description="item.desc"
|
||||||
|
class="cursor"
|
||||||
|
@click.stop="openCreateDialog(item)"
|
||||||
|
:disabled="
|
||||||
|
hasPermission(
|
||||||
|
[
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
PermissionConst.TOOL_EDIT.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.TOOL_EDIT.getWorkspacePermission,
|
||||||
|
],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<el-avatar
|
||||||
|
v-if="isAppIcon(item?.icon)"
|
||||||
|
shape="square"
|
||||||
|
:size="32"
|
||||||
|
style="background: none"
|
||||||
|
class="mr-8"
|
||||||
|
>
|
||||||
|
<img :src="item?.icon" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<el-avatar v-else class="avatar-green" shape="square" :size="32">
|
||||||
|
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
</template>
|
||||||
|
<template #subTitle>
|
||||||
|
<el-text class="color-secondary lighter" size="small">
|
||||||
|
{{ $t('common.creator') }}: {{ item.nick_name }}
|
||||||
|
</el-text>
|
||||||
|
</template>
|
||||||
|
<template #tag>
|
||||||
|
<el-tag v-if="isShared" type="info" class="info-tag">
|
||||||
|
{{ t('views.system.shared.label') }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div v-if="item.is_active" class="flex align-center">
|
||||||
|
<el-icon class="color-success mr-8" style="font-size: 16px">
|
||||||
|
<SuccessFilled />
|
||||||
|
</el-icon>
|
||||||
|
<span class="color-secondary">
|
||||||
|
{{ $t('common.status.enabled') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex align-center">
|
||||||
|
<AppIcon iconName="app-disabled" class="color-secondary mr-8"></AppIcon>
|
||||||
|
<span class="color-secondary">
|
||||||
|
{{ $t('common.status.disabled') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #mouseEnter>
|
||||||
|
<div @click.stop v-if="!isShared">
|
||||||
|
<el-switch
|
||||||
|
v-model="item.is_active"
|
||||||
|
:before-change="() => changeState(item)"
|
||||||
|
size="small"
|
||||||
|
class="mr-4"
|
||||||
|
v-if="permissionPrecise.switch()"
|
||||||
|
/>
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
<el-dropdown trigger="click">
|
||||||
|
<el-button text @click.stop>
|
||||||
|
<el-icon>
|
||||||
|
<MoreFilled />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="item.template_id"
|
||||||
|
@click.stop="addInternalFunction(item, true)"
|
||||||
|
>
|
||||||
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
|
{{ $t('common.edit') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="!item.template_id && permissionPrecise.edit()"
|
||||||
|
@click.stop="openCreateDialog(item)"
|
||||||
|
>
|
||||||
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
|
{{ $t('common.edit') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="!item.template_id && permissionPrecise.copy()"
|
||||||
|
@click.stop="copyTool(item)"
|
||||||
|
>
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
{{ $t('common.copy') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="item.init_field_list?.length > 0"
|
||||||
|
@click.stop="configInitParams(item)"
|
||||||
|
>
|
||||||
|
<AppIcon iconName="app-operation" class="mr-4"></AppIcon>
|
||||||
|
{{ $t('common.param.initParam') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="!item.template_id && permissionPrecise.export()"
|
||||||
|
@click.stop="exportTool(item)"
|
||||||
|
>
|
||||||
|
<AppIcon iconName="app-export"></AppIcon>
|
||||||
|
{{ $t('common.export') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="permissionPrecise.delete()"
|
||||||
|
divided
|
||||||
|
@click.stop="deleteTool(item)"
|
||||||
|
>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
{{ $t('common.delete') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
|
</el-row>
|
||||||
|
<el-empty :description="$t('common.noData')" v-else />
|
||||||
|
</InfiniteScroll>
|
||||||
|
</div>
|
||||||
|
</ContentContainer>
|
||||||
|
<InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh" />
|
||||||
|
<ToolFormDrawer ref="ToolFormDrawerRef" @refresh="refresh" :title="ToolDrawertitle" />
|
||||||
|
<CreateFolderDialog ref="CreateFolderDialogRef" v-if="!isShared" />
|
||||||
|
<ToolStoreDialog ref="toolStoreDialogRef" @refresh="refresh" />
|
||||||
|
<AddInternalFunctionDialog
|
||||||
|
ref="addInternalFunctionDialogRef"
|
||||||
|
@refresh="confirmAddInternalFunction"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref, reactive, computed, watch } from 'vue'
|
||||||
|
import { cloneDeep, get } from 'lodash'
|
||||||
|
import ToolApi from '@/api/tool/tool'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
|
||||||
|
import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue'
|
||||||
|
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
||||||
|
import { isAppIcon } from '@/utils/common'
|
||||||
|
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
||||||
|
import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||||
|
import { hasPermission } from '@/utils/permission/index'
|
||||||
|
import { FolderSource } from '@/enums/common'
|
||||||
|
import ToolStoreDialog from '@/views/tool/component/ToolStoreDialog.vue'
|
||||||
|
import AddInternalFunctionDialog from '@/views/tool/component/AddInternalFunctionDialog.vue'
|
||||||
|
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
||||||
|
import permissionMap from '@/permission'
|
||||||
|
import useStore from '@/stores'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
const route = useRoute()
|
||||||
|
const { folder, user, tool } = useStore()
|
||||||
|
|
||||||
|
const type = computed(() => {
|
||||||
|
if (route.path.includes('shared')) {
|
||||||
|
return 'systemShare'
|
||||||
|
} else if (route.path.includes('resource-management')) {
|
||||||
|
return 'systemManage'
|
||||||
|
} else {
|
||||||
|
return 'workspace'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const permissionPrecise = computed(() => {
|
||||||
|
return permissionMap['tool'][type.value]
|
||||||
|
})
|
||||||
|
|
||||||
|
const InitParamDrawerRef = ref()
|
||||||
|
const search_type = ref('name')
|
||||||
|
const search_form = ref<{
|
||||||
|
name: string
|
||||||
|
create_user: string
|
||||||
|
}>({
|
||||||
|
name: '',
|
||||||
|
create_user: '',
|
||||||
|
})
|
||||||
|
const user_options = ref<any[]>([])
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const changeStateloading = ref(false)
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
current_page: 1,
|
||||||
|
page_size: 30,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentFolder = ref<any>({})
|
||||||
|
|
||||||
|
const isShared = computed(() => {
|
||||||
|
return folder.currentFolder.id === 'share'
|
||||||
|
})
|
||||||
|
|
||||||
|
const search_type_change = () => {
|
||||||
|
search_form.value = { name: '', create_user: '' }
|
||||||
|
}
|
||||||
|
const ToolFormDrawerRef = ref()
|
||||||
|
const ToolDrawertitle = ref('')
|
||||||
|
|
||||||
|
function openCreateDialog(data?: any) {
|
||||||
|
// 有template_id的不允许编辑,是模板转换来的
|
||||||
|
if (data?.template_id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ToolDrawertitle.value = data ? t('views.tool.editTool') : t('views.tool.createTool')
|
||||||
|
if (data) {
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.getToolById(data?.id, loading)
|
||||||
|
.then((res) => {
|
||||||
|
ToolFormDrawerRef.value.open(res.data)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ToolFormDrawerRef.value.open(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function changeState(row: any) {
|
||||||
|
if (row.is_active) {
|
||||||
|
MsgConfirm(
|
||||||
|
`${t('views.tool.disabled.confirmTitle')}${row.name} ?`,
|
||||||
|
t('views.tool.disabled.confirmMessage'),
|
||||||
|
{
|
||||||
|
confirmButtonText: t('common.status.disable'),
|
||||||
|
confirmButtonClass: 'danger',
|
||||||
|
},
|
||||||
|
).then(() => {
|
||||||
|
const obj = {
|
||||||
|
is_active: !row.is_active,
|
||||||
|
}
|
||||||
|
ToolApi.putTool(row.id, obj, changeStateloading)
|
||||||
|
.then(() => {
|
||||||
|
const list = cloneDeep(tool.toolList)
|
||||||
|
const index = list.findIndex((v) => v.id === row.id)
|
||||||
|
list[index].is_active = !row.is_active
|
||||||
|
tool.setToolList(list)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const res = await loadSharedApi({ type: 'tool', systemType: type.value }).getToolById(
|
||||||
|
row.id,
|
||||||
|
changeStateloading,
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
!res.data.init_params &&
|
||||||
|
res.data.init_field_list &&
|
||||||
|
res.data.init_field_list.length > 0 &&
|
||||||
|
res.data.init_field_list.filter((item: any) => item.default_value && item.show_default_value)
|
||||||
|
.length !== res.data.init_field_list.length
|
||||||
|
) {
|
||||||
|
InitParamDrawerRef.value.open(res.data, !row.is_active)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const obj = {
|
||||||
|
is_active: !row.is_active,
|
||||||
|
}
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.putTool(row.id, obj, changeStateloading)
|
||||||
|
.then(() => {
|
||||||
|
const list = cloneDeep(tool.toolList)
|
||||||
|
const index = list.findIndex((v) => v.id === row.id)
|
||||||
|
list[index].is_active = !row.is_active
|
||||||
|
tool.setToolList(list)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh(data?: any) {
|
||||||
|
if (data) {
|
||||||
|
const list = cloneDeep(tool.toolList)
|
||||||
|
const index = list.findIndex((v) => v.id === data.id)
|
||||||
|
list.splice(index, 1, data)
|
||||||
|
tool.setToolList(list)
|
||||||
|
} else {
|
||||||
|
paginationConfig.total = 0
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
tool.setToolList([])
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyTool(row: any) {
|
||||||
|
ToolDrawertitle.value = t('views.tool.copyTool')
|
||||||
|
const obj = cloneDeep(row)
|
||||||
|
delete obj['id']
|
||||||
|
obj['name'] = obj['name'] + ` ${t('views.tool.form.title.copy')}`
|
||||||
|
ToolFormDrawerRef.value.open(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportTool(row: any) {
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.exportTool(row.id, row.name, loading)
|
||||||
|
.catch((e: any) => {
|
||||||
|
if (e.response.status !== 403) {
|
||||||
|
e.response.data.text().then((res: string) => {
|
||||||
|
MsgError(`${t('views.application.tip.ExportError')}:${JSON.parse(res).message}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTool(row: any) {
|
||||||
|
MsgConfirm(
|
||||||
|
`${t('views.tool.delete.confirmTitle')}${row.name} ?`,
|
||||||
|
t('views.tool.delete.confirmMessage'),
|
||||||
|
{
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
cancelButtonText: t('common.cancel'),
|
||||||
|
confirmButtonClass: 'danger',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.delTool(row.id, loading)
|
||||||
|
.then(() => {
|
||||||
|
const list = cloneDeep(tool.toolList)
|
||||||
|
const index = list.findIndex((v) => v.id === row.id)
|
||||||
|
list.splice(index, 1)
|
||||||
|
tool.setToolList(list)
|
||||||
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
function configInitParams(item: any) {
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.getToolById(item?.id, changeStateloading)
|
||||||
|
.then((res) => {
|
||||||
|
InitParamDrawerRef.value.open(res.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolStoreDialogRef = ref<InstanceType<typeof ToolStoreDialog>>()
|
||||||
|
function openToolStoreDialog() {
|
||||||
|
toolStoreDialogRef.value?.open(currentFolder.value.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addInternalFunctionDialogRef = ref<InstanceType<typeof AddInternalFunctionDialog>>()
|
||||||
|
function addInternalFunction(data?: any, isEdit?: boolean) {
|
||||||
|
addInternalFunctionDialogRef.value?.open(data, isEdit)
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmAddInternalFunction(data?: any, isEdit?: boolean) {
|
||||||
|
if (isEdit) {
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.putTool(data?.id as string, { name: data.name }, loading)
|
||||||
|
.then((res) => {
|
||||||
|
MsgSuccess(t('common.saveSuccess'))
|
||||||
|
refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const elUploadRef = ref()
|
||||||
|
function importTool(file: any) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file.raw, file.name)
|
||||||
|
elUploadRef.value.clearFiles()
|
||||||
|
loadSharedApi({ type: 'tool', systemType: type.value })
|
||||||
|
.postImportTool(formData, loading)
|
||||||
|
.then(async (res: any) => {
|
||||||
|
if (res?.data) {
|
||||||
|
tool.setToolList([])
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e: any) => {
|
||||||
|
if (e.code === 400) {
|
||||||
|
MsgConfirm(t('common.tip'), t('views.application.tip.professionalMessage'), {
|
||||||
|
cancelButtonText: t('common.confirm'),
|
||||||
|
confirmButtonText: t('common.professional'),
|
||||||
|
}).then(() => {
|
||||||
|
window.open('https://maxkb.cn/pricing.html', '_blank')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件夹相关
|
||||||
|
const CreateFolderDialogRef = ref()
|
||||||
|
function openCreateFolder() {
|
||||||
|
CreateFolderDialogRef.value.open(FolderSource.TOOL, folder.currentFolder.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => folder.currentFolder,
|
||||||
|
(newValue) => {
|
||||||
|
if (newValue && newValue.id) {
|
||||||
|
tool.setToolList([])
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
)
|
||||||
|
function getList() {
|
||||||
|
tool
|
||||||
|
.asyncGetToolListPage(paginationConfig, isShared.value, type.value, loading)
|
||||||
|
.then((res: any) => {
|
||||||
|
paginationConfig.total = res.data?.total
|
||||||
|
tool.setToolList([...tool.toolList, ...res.data?.records])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickFolder(item: any) {
|
||||||
|
folder.setCurrentFolder(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (type.value !== 'workspace') {
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -8,321 +8,23 @@
|
|||||||
:currentNodeKey="currentFolder?.id"
|
:currentNodeKey="currentFolder?.id"
|
||||||
@handleNodeClick="folderClickHandel"
|
@handleNodeClick="folderClickHandel"
|
||||||
@refreshTree="refreshFolder"
|
@refreshTree="refreshFolder"
|
||||||
:shareTitle="$t('views.system.share_tool')"
|
:shareTitle="$t('views.system.shared.shared_tool')"
|
||||||
:showShared="permissionPrecise['is_share']()"
|
:showShared="permissionPrecise['is_share']()"
|
||||||
class="p-8"
|
class="p-8"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<ContentContainer :header="currentFolder?.name">
|
<ToolListContainer>
|
||||||
<template #search>
|
<template #header>
|
||||||
<div class="flex">
|
<FolderBreadcrumb :folderList="folderList" @click="folderClickHandel" />
|
||||||
<div class="flex-between complex-search">
|
|
||||||
<el-select
|
|
||||||
class="complex-search__left"
|
|
||||||
v-model="search_type"
|
|
||||||
style="width: 120px"
|
|
||||||
@change="search_type_change"
|
|
||||||
>
|
|
||||||
<el-option :label="$t('common.creator')" value="create_user" />
|
|
||||||
|
|
||||||
<el-option :label="$t('views.model.modelForm.modeName.label')" value="name" />
|
|
||||||
</el-select>
|
|
||||||
<el-input
|
|
||||||
v-if="search_type === 'name'"
|
|
||||||
v-model="search_form.name"
|
|
||||||
@change="getList"
|
|
||||||
:placeholder="$t('common.searchBar.placeholder')"
|
|
||||||
style="width: 220px"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
<el-select
|
|
||||||
v-else-if="search_type === 'create_user'"
|
|
||||||
v-model="search_form.create_user"
|
|
||||||
@change="getList"
|
|
||||||
clearable
|
|
||||||
style="width: 220px"
|
|
||||||
>
|
|
||||||
<el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.username" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<el-dropdown trigger="click" v-if="!isShared">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
class="ml-8"
|
|
||||||
v-if="permissionPrecise.create()"
|
|
||||||
>
|
|
||||||
{{ $t('common.create') }}
|
|
||||||
<el-icon class="el-icon--right">
|
|
||||||
<arrow-down />
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu class="create-dropdown">
|
|
||||||
<el-dropdown-item @click="openCreateDialog()">
|
|
||||||
<div class="flex align-center">
|
|
||||||
<el-avatar class="avatar-green" shape="square" :size="32">
|
|
||||||
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<div class="pre-wrap ml-8">
|
|
||||||
<div class="lighter">空白创建</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-upload
|
|
||||||
ref="elUploadRef"
|
|
||||||
:file-list="[]"
|
|
||||||
action="#"
|
|
||||||
multiple
|
|
||||||
:auto-upload="false"
|
|
||||||
:show-file-list="false"
|
|
||||||
:limit="1"
|
|
||||||
:on-change="(file: any, fileList: any) => importTool(file)"
|
|
||||||
class="import-button"
|
|
||||||
>
|
|
||||||
<el-dropdown-item class="w-full">
|
|
||||||
<div class="flex align-center w-full">
|
|
||||||
<el-avatar shape="square" class="mt-4" :size="36" style="background: none">
|
|
||||||
<img src="@/assets/icon_import.svg" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<div class="pre-wrap ml-8">
|
|
||||||
<div class="lighter">{{ $t('common.importCreate') }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-upload>
|
|
||||||
<el-dropdown-item @click="openToolStoreDialog()">
|
|
||||||
<div class="flex align-center">
|
|
||||||
<el-avatar class="avatar-green" shape="square" :size="32">
|
|
||||||
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<div class="pre-wrap ml-8">
|
|
||||||
<div class="lighter">
|
|
||||||
{{ $t('views.tool.toolStore.createFromToolStore') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item @click="openCreateFolder" divided>
|
|
||||||
<div class="flex align-center">
|
|
||||||
<AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
|
|
||||||
<div class="pre-wrap ml-4">
|
|
||||||
<div class="lighter">
|
|
||||||
{{ $t('components.folder.addFolder') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
</ToolListContainer>
|
||||||
<div
|
|
||||||
v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
|
|
||||||
style="max-height: calc(100vh - 140px)"
|
|
||||||
>
|
|
||||||
<InfiniteScroll
|
|
||||||
:size="toolList.length"
|
|
||||||
:total="paginationConfig.total"
|
|
||||||
:page_size="paginationConfig.page_size"
|
|
||||||
v-model:current_page="paginationConfig.current_page"
|
|
||||||
@load="getList"
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
<el-row v-if="toolList.length > 0" :gutter="15">
|
|
||||||
<template v-for="(item, index) in toolList" :key="index">
|
|
||||||
<el-col
|
|
||||||
v-if="item.resource_type === 'folder'"
|
|
||||||
:xs="24"
|
|
||||||
:sm="12"
|
|
||||||
:md="12"
|
|
||||||
:lg="8"
|
|
||||||
:xl="6"
|
|
||||||
class="mb-16"
|
|
||||||
>
|
|
||||||
<CardBox
|
|
||||||
:title="item.name"
|
|
||||||
:description="item.desc || $t('common.noData')"
|
|
||||||
class="cursor"
|
|
||||||
@click="clickFolder(item)"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<el-avatar shape="square" :size="32" style="background: none">
|
|
||||||
<AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
|
|
||||||
</el-avatar>
|
|
||||||
</template>
|
|
||||||
<template #subTitle>
|
|
||||||
<el-text class="color-secondary lighter" size="small">
|
|
||||||
{{ $t('common.creator') }}: {{ item.nick_name }}
|
|
||||||
</el-text>
|
|
||||||
</template>
|
|
||||||
</CardBox>
|
|
||||||
</el-col>
|
|
||||||
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
|
||||||
<CardBox
|
|
||||||
:title="item.name"
|
|
||||||
:description="item.desc"
|
|
||||||
class="cursor"
|
|
||||||
@click.stop="openCreateDialog(item)"
|
|
||||||
:disabled="
|
|
||||||
hasPermission(
|
|
||||||
[
|
|
||||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
|
||||||
RoleConst.USER.getWorkspaceRole,
|
|
||||||
PermissionConst.TOOL_EDIT.getWorkspacePermissionWorkspaceManageRole,
|
|
||||||
PermissionConst.TOOL_EDIT.getWorkspacePermission,
|
|
||||||
],
|
|
||||||
'OR',
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<el-avatar
|
|
||||||
v-if="isAppIcon(item?.icon)"
|
|
||||||
shape="square"
|
|
||||||
:size="32"
|
|
||||||
style="background: none"
|
|
||||||
class="mr-8"
|
|
||||||
>
|
|
||||||
<img :src="item?.icon" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<el-avatar v-else class="avatar-green" shape="square" :size="32">
|
|
||||||
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
</template>
|
|
||||||
<template #subTitle>
|
|
||||||
<el-text class="color-secondary lighter" size="small">
|
|
||||||
{{ $t('common.creator') }}: {{ item.nick_name }}
|
|
||||||
</el-text>
|
|
||||||
</template>
|
|
||||||
<template #tag>
|
|
||||||
<el-tag v-if="isShared" type="info" class="info-tag">
|
|
||||||
{{ t('views.system.shared') }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<div v-if="item.is_active" class="flex align-center">
|
|
||||||
<el-icon class="color-success mr-8" style="font-size: 16px">
|
|
||||||
<SuccessFilled />
|
|
||||||
</el-icon>
|
|
||||||
<span class="color-secondary">
|
|
||||||
{{ $t('common.status.enabled') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div v-else class="flex align-center">
|
|
||||||
<AppIcon iconName="app-disabled" class="color-secondary mr-8"></AppIcon>
|
|
||||||
<span class="color-secondary">
|
|
||||||
{{ $t('common.status.disabled') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #mouseEnter>
|
|
||||||
<div @click.stop v-if="!isShared">
|
|
||||||
<el-switch
|
|
||||||
v-model="item.is_active"
|
|
||||||
:before-change="() => changeState(item)"
|
|
||||||
size="small"
|
|
||||||
class="mr-4"
|
|
||||||
v-if="permissionPrecise.switch()"
|
|
||||||
/>
|
|
||||||
<el-divider direction="vertical" />
|
|
||||||
<el-dropdown trigger="click">
|
|
||||||
<el-button text @click.stop>
|
|
||||||
<el-icon>
|
|
||||||
<MoreFilled />
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item v-if="item.template_id" @click.stop="addInternalFunction(item, true)">
|
|
||||||
<el-icon>
|
|
||||||
<EditPen />
|
|
||||||
</el-icon>
|
|
||||||
{{ $t('common.edit') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="
|
|
||||||
!item.template_id &&
|
|
||||||
permissionPrecise.edit()
|
|
||||||
"
|
|
||||||
@click.stop="openCreateDialog(item)"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<EditPen />
|
|
||||||
</el-icon>
|
|
||||||
{{ $t('common.edit') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="
|
|
||||||
!item.template_id &&
|
|
||||||
permissionPrecise.copy()
|
|
||||||
"
|
|
||||||
@click.stop="copyTool(item)"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-copy"></AppIcon>
|
|
||||||
{{ $t('common.copy') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="item.init_field_list?.length > 0"
|
|
||||||
@click.stop="configInitParams(item)"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-operation" class="mr-4"></AppIcon>
|
|
||||||
{{ $t('common.param.initParam') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="
|
|
||||||
!item.template_id &&
|
|
||||||
permissionPrecise.export()
|
|
||||||
"
|
|
||||||
@click.stop="exportTool(item)"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-export"></AppIcon>
|
|
||||||
{{ $t('common.export') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="permissionPrecise.delete()"
|
|
||||||
divided
|
|
||||||
@click.stop="deleteTool(item)"
|
|
||||||
>
|
|
||||||
<el-icon><Delete /></el-icon>
|
|
||||||
{{ $t('common.delete') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</CardBox>
|
|
||||||
</el-col>
|
|
||||||
</template>
|
|
||||||
</el-row>
|
|
||||||
<el-empty :description="$t('common.noData')" v-else />
|
|
||||||
</InfiniteScroll>
|
|
||||||
</div>
|
|
||||||
</ContentContainer>
|
|
||||||
<InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh" />
|
|
||||||
<ToolFormDrawer ref="ToolFormDrawerRef" @refresh="refresh" :title="ToolDrawertitle" />
|
|
||||||
<CreateFolderDialog ref="CreateFolderDialogRef" @refresh="refreshFolder" v-if="!isShared" />
|
|
||||||
<ToolStoreDialog ref="toolStoreDialogRef" @refresh="refresh" />
|
|
||||||
<AddInternalFunctionDialog ref="addInternalFunctionDialogRef" @refresh="confirmAddInternalFunction" />
|
|
||||||
</LayoutContainer>
|
</LayoutContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, reactive, computed } from 'vue'
|
import { onMounted, ref, reactive, computed } from 'vue'
|
||||||
import { cloneDeep, get } from 'lodash'
|
import ToolListContainer from '@/views/tool/component/ToolListContainer.vue'
|
||||||
import ToolApi from '@/api/tool/tool'
|
|
||||||
import useStore from '@/stores'
|
|
||||||
import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
|
|
||||||
import ToolFormDrawer from './ToolFormDrawer.vue'
|
|
||||||
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
||||||
import { t } from '@/locales'
|
|
||||||
import { isAppIcon } from '@/utils/common'
|
|
||||||
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
|
||||||
import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data'
|
|
||||||
import { hasPermission } from '@/utils/permission/index'
|
|
||||||
import { FolderSource } from '@/enums/common'
|
import { FolderSource } from '@/enums/common'
|
||||||
import { ComplexPermission } from '@/utils/permission/type'
|
import { ComplexPermission } from '@/utils/permission/type'
|
||||||
import ToolStoreDialog from './toolStore/ToolStoreDialog.vue'
|
import ToolStoreDialog from './toolStore/ToolStoreDialog.vue'
|
||||||
@ -330,8 +32,9 @@ import AddInternalFunctionDialog from './toolStore/AddInternalFunctionDialog.vue
|
|||||||
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
||||||
import permissionMap from '@/permission'
|
import permissionMap from '@/permission'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
import useStore from '@/stores'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { folder, user } = useStore()
|
const { folder, tool } = useStore()
|
||||||
|
|
||||||
const type = computed(() => {
|
const type = computed(() => {
|
||||||
if (route.path.includes('shared')) {
|
if (route.path.includes('shared')) {
|
||||||
@ -346,231 +49,11 @@ const permissionPrecise = computed(() => {
|
|||||||
return permissionMap['tool'][type.value]
|
return permissionMap['tool'][type.value]
|
||||||
})
|
})
|
||||||
|
|
||||||
const InitParamDrawerRef = ref()
|
|
||||||
const search_type = ref('name')
|
|
||||||
const search_form = ref<{
|
|
||||||
name: string
|
|
||||||
create_user: string
|
|
||||||
}>({
|
|
||||||
name: '',
|
|
||||||
create_user: '',
|
|
||||||
})
|
|
||||||
const user_options = ref<any[]>([])
|
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const changeStateloading = ref(false)
|
|
||||||
const paginationConfig = reactive({
|
|
||||||
current_page: 1,
|
|
||||||
page_size: 30,
|
|
||||||
total: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
const folderList = ref<any[]>([])
|
const folderList = ref<any[]>([])
|
||||||
const toolList = ref<any[]>([])
|
|
||||||
const currentFolder = ref<any>({})
|
const currentFolder = ref<any>({})
|
||||||
|
|
||||||
const isShared = computed(() => {
|
|
||||||
return currentFolder.value.id === 'share'
|
|
||||||
})
|
|
||||||
|
|
||||||
const search_type_change = () => {
|
|
||||||
search_form.value = { name: '', create_user: '' }
|
|
||||||
}
|
|
||||||
const ToolFormDrawerRef = ref()
|
|
||||||
const ToolDrawertitle = ref('')
|
|
||||||
|
|
||||||
function openCreateDialog(data?: any) {
|
|
||||||
// 有template_id的不允许编辑,是模板转换来的
|
|
||||||
if (data?.template_id) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ToolDrawertitle.value = data ? t('views.tool.editTool') : t('views.tool.createTool')
|
|
||||||
if (data) {
|
|
||||||
ToolApi.getToolById(data?.id, loading).then((res) => {
|
|
||||||
ToolFormDrawerRef.value.open(res.data)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
ToolFormDrawerRef.value.open(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getList() {
|
|
||||||
const params = {
|
|
||||||
folder_id: currentFolder.value?.id || user.getWorkspaceId(),
|
|
||||||
scope: 'WORKSPACE',
|
|
||||||
}
|
|
||||||
loadSharedApi('tool', isShared.value)
|
|
||||||
.getToolListPage(paginationConfig, params, loading)
|
|
||||||
.then((res: any) => {
|
|
||||||
paginationConfig.total = res.data?.total
|
|
||||||
toolList.value = [...toolList.value, ...res.data?.records]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function clickFolder(item: any) {
|
|
||||||
currentFolder.value.id = item.id
|
|
||||||
toolList.value = []
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
async function changeState(row: any) {
|
|
||||||
if (row.is_active) {
|
|
||||||
MsgConfirm(
|
|
||||||
`${t('views.tool.disabled.confirmTitle')}${row.name} ?`,
|
|
||||||
t('views.tool.disabled.confirmMessage'),
|
|
||||||
{
|
|
||||||
confirmButtonText: t('common.status.disable'),
|
|
||||||
confirmButtonClass: 'danger',
|
|
||||||
},
|
|
||||||
).then(() => {
|
|
||||||
const obj = {
|
|
||||||
is_active: !row.is_active,
|
|
||||||
}
|
|
||||||
ToolApi.putTool(row.id, obj, changeStateloading)
|
|
||||||
.then(() => {
|
|
||||||
const index = toolList.value.findIndex((v) => v.id === row.id)
|
|
||||||
toolList.value[index].is_active = !row.is_active
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const res = await ToolApi.getToolById(row.id, changeStateloading)
|
|
||||||
if (
|
|
||||||
(!res.data.init_params || Object.keys(res.data.init_params).length === 0) &&
|
|
||||||
res.data.init_field_list &&
|
|
||||||
res.data.init_field_list.length > 0 &&
|
|
||||||
res.data.init_field_list.filter((item: any) => item.default_value && item.show_default_value)
|
|
||||||
.length !== res.data.init_field_list.length
|
|
||||||
) {
|
|
||||||
InitParamDrawerRef.value.open(res.data, !row.is_active)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const obj = {
|
|
||||||
is_active: !row.is_active,
|
|
||||||
}
|
|
||||||
ToolApi.putTool(row.id, obj, changeStateloading)
|
|
||||||
.then(() => {
|
|
||||||
const index = toolList.value.findIndex((v) => v.id === row.id)
|
|
||||||
toolList.value[index].is_active = !row.is_active
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refresh(data?: any) {
|
|
||||||
if (data) {
|
|
||||||
const index = toolList.value.findIndex((v) => v.id === data.id)
|
|
||||||
// if (user.userInfo && data.user_id === user.userInfo.id) {
|
|
||||||
// data.username = user.userInfo.username
|
|
||||||
// } else {
|
|
||||||
// data.username = userOptions.value.find((v) => v.value === data.user_id)?.label
|
|
||||||
// }
|
|
||||||
toolList.value.splice(index, 1, data)
|
|
||||||
}
|
|
||||||
paginationConfig.total = 0
|
|
||||||
paginationConfig.current_page = 1
|
|
||||||
toolList.value = []
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function copyTool(row: any) {
|
|
||||||
ToolDrawertitle.value = t('views.tool.copyTool')
|
|
||||||
const res = await ToolApi.getToolById(row.id, changeStateloading)
|
|
||||||
const obj = cloneDeep(res.data)
|
|
||||||
delete obj['id']
|
|
||||||
obj['name'] = obj['name'] + ` ${t('views.tool.form.title.copy')}`
|
|
||||||
ToolFormDrawerRef.value.open(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportTool(row: any) {
|
|
||||||
ToolApi.exportTool(row.id, row.name, loading).catch((e: any) => {
|
|
||||||
if (e.response.status !== 403) {
|
|
||||||
e.response.data.text().then((res: string) => {
|
|
||||||
MsgError(`${t('views.application.tip.ExportError')}:${JSON.parse(res).message}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteTool(row: any) {
|
|
||||||
MsgConfirm(
|
|
||||||
`${t('views.tool.delete.confirmTitle')}${row.name} ?`,
|
|
||||||
t('views.tool.delete.confirmMessage'),
|
|
||||||
{
|
|
||||||
confirmButtonText: t('common.confirm'),
|
|
||||||
cancelButtonText: t('common.cancel'),
|
|
||||||
confirmButtonClass: 'danger',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
ToolApi.delTool(row.id, loading).then(() => {
|
|
||||||
const index = toolList.value.findIndex((v) => v.id === row.id)
|
|
||||||
toolList.value.splice(index, 1)
|
|
||||||
MsgSuccess(t('common.deleteSuccess'))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
}
|
|
||||||
|
|
||||||
function configInitParams(item: any) {
|
|
||||||
ToolApi.getToolById(item?.id, changeStateloading).then((res) => {
|
|
||||||
InitParamDrawerRef.value.open(res.data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const toolStoreDialogRef = ref<InstanceType<typeof ToolStoreDialog>>()
|
|
||||||
function openToolStoreDialog() {
|
|
||||||
toolStoreDialogRef.value?.open(currentFolder.value.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
const addInternalFunctionDialogRef = ref<InstanceType<typeof AddInternalFunctionDialog>>()
|
|
||||||
function addInternalFunction(data?: any, isEdit?: boolean) {
|
|
||||||
addInternalFunctionDialogRef.value?.open(data, isEdit)
|
|
||||||
}
|
|
||||||
|
|
||||||
function confirmAddInternalFunction(data?: any, isEdit?: boolean) {
|
|
||||||
if (isEdit) {
|
|
||||||
ToolApi.putTool(data?.id as string, { name: data.name }, loading).then((res) => {
|
|
||||||
MsgSuccess(t('common.saveSuccess'))
|
|
||||||
refresh()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const elUploadRef = ref()
|
|
||||||
function importTool(file: any) {
|
|
||||||
const formData = new FormData()
|
|
||||||
formData.append('file', file.raw, file.name)
|
|
||||||
elUploadRef.value.clearFiles()
|
|
||||||
ToolApi.postImportTool(formData, loading)
|
|
||||||
.then(async (res: any) => {
|
|
||||||
if (res?.data) {
|
|
||||||
toolList.value = []
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e: any) => {
|
|
||||||
if (e.code === 400) {
|
|
||||||
MsgConfirm(t('common.tip'), t('views.application.tip.professionalMessage'), {
|
|
||||||
cancelButtonText: t('common.confirm'),
|
|
||||||
confirmButtonText: t('common.professional'),
|
|
||||||
}).then(() => {
|
|
||||||
window.open('https://maxkb.cn/pricing.html', '_blank')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 文件夹相关
|
|
||||||
const CreateFolderDialogRef = ref()
|
|
||||||
function openCreateFolder() {
|
|
||||||
CreateFolderDialogRef.value.open(FolderSource.TOOL, currentFolder.value.id)
|
|
||||||
}
|
|
||||||
function getFolder(bool?: boolean) {
|
function getFolder(bool?: boolean) {
|
||||||
const params = {}
|
const params = {}
|
||||||
folder.asyncGetFolder(FolderSource.TOOL, params, loading).then((res: any) => {
|
folder.asyncGetFolder(FolderSource.TOOL, params, loading).then((res: any) => {
|
||||||
@ -578,19 +61,19 @@ function getFolder(bool?: boolean) {
|
|||||||
if (bool) {
|
if (bool) {
|
||||||
// 初始化刷新
|
// 初始化刷新
|
||||||
currentFolder.value = res.data?.[0] || {}
|
currentFolder.value = res.data?.[0] || {}
|
||||||
|
folder.setCurrentFolder(currentFolder.value)
|
||||||
}
|
}
|
||||||
getList()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function refreshFolder() {
|
|
||||||
toolList.value = []
|
|
||||||
getFolder()
|
|
||||||
}
|
|
||||||
|
|
||||||
function folderClickHandel(row: any) {
|
function folderClickHandel(row: any) {
|
||||||
currentFolder.value = row
|
currentFolder.value = row
|
||||||
toolList.value = []
|
folder.setCurrentFolder(currentFolder.value)
|
||||||
getList()
|
tool.setToolList([])
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshFolder() {
|
||||||
|
getFolder()
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default defineConfig(({ mode }) => {
|
|||||||
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
|
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
|
||||||
const proxyConf: Record<string, string | ProxyOptions> = {}
|
const proxyConf: Record<string, string | ProxyOptions> = {}
|
||||||
proxyConf['/api'] = {
|
proxyConf['/api'] = {
|
||||||
// target: 'http://43.166.1.146:8080',
|
// target: 'http://47.92.195.88:8080',
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user