mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: tool
This commit is contained in:
parent
f21d301140
commit
796eff7759
|
|
@ -19,6 +19,7 @@
|
|||
"element-plus": "^2.9.7",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^3.0.1",
|
||||
"use-element-plus-theme": "^0.0.5",
|
||||
"vue": "^3.5.13",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"vue-i18n": "^11.1.3",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.50959 19.3955C6.84272 20.0622 5.93829 20.4368 4.99527 20.4367C4.05226 20.4366 3.1479 20.0619 2.48114 19.395C1.81439 18.7282 1.43986 17.8238 1.43994 16.8807C1.44002 15.9377 1.81472 15.0334 2.48159 14.3666L4.6407 12.207C3.70381 9.41949 4.34648 6.21772 6.56692 3.99594C8.78914 1.77372 11.9927 1.13238 14.7816 2.07105C14.9607 2.13105 15.1758 2.21994 15.426 2.33683C15.5488 2.39405 15.656 2.48004 15.7385 2.5875C15.821 2.69496 15.8764 2.82073 15.8999 2.95414C15.9235 3.08754 15.9145 3.22467 15.8738 3.35388C15.8331 3.48309 15.7618 3.60057 15.666 3.69638L11.9096 7.45283L14.4238 9.96705L18.1318 6.25905C18.2333 6.15762 18.3578 6.08226 18.4947 6.0394C18.6316 5.99653 18.7768 5.98744 18.918 6.0129C19.0592 6.03836 19.1921 6.09761 19.3054 6.1856C19.4187 6.27358 19.5091 6.38769 19.5687 6.51816C19.6825 6.76616 19.7683 6.97949 19.8265 7.15861C20.7345 9.93283 20.0856 13.1048 17.8807 15.3097C15.6594 17.5306 12.4571 18.1728 9.66914 17.2359L7.50959 19.395V19.3955Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -117,6 +117,31 @@ export const iconMap: any = {
|
|||
])
|
||||
},
|
||||
},
|
||||
'app-folder': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
style: { height: '100%', width: '100%' },
|
||||
viewBox: '0 0 1024 1024',
|
||||
version: '1.1',
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M42.666667 170.666667a42.666667 42.666667 0 0 1 42.666666-42.666667h357.632a42.666667 42.666667 0 0 1 38.144 23.594667L512 213.333333h426.666667a42.666667 42.666667 0 0 1 42.666666 42.666667v597.333333a42.666667 42.666667 0 0 1-42.666666 42.666667H85.333333a42.666667 42.666667 0 0 1-42.666666-42.666667V170.666667z',
|
||||
fill: '#FFA53D',
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M42.666667 256a42.666667 42.666667 0 0 1 42.666666-42.666667h853.333334a42.666667 42.666667 0 0 1 42.666666 42.666667v597.333333a42.666667 42.666667 0 0 1-42.666666 42.666667H85.333333a42.666667 42.666667 0 0 1-42.666666-42.666667V256z',
|
||||
fill: '#FFC60A',
|
||||
}),
|
||||
],
|
||||
),
|
||||
])
|
||||
},
|
||||
},
|
||||
// 动态加载的图标
|
||||
...dynamicIcons,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,72 @@
|
|||
<template>
|
||||
<el-tree
|
||||
style="max-width: 600px"
|
||||
:data="data"
|
||||
:props="defaultProps"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
<div>
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
:placeholder="$t('common.search')"
|
||||
prefix-icon="Search"
|
||||
clearable
|
||||
class="p-8"
|
||||
/>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="data"
|
||||
:props="defaultProps"
|
||||
@node-click="handleNodeClick"
|
||||
:filter-node-method="filterNode"
|
||||
:default-expanded-keys="[currentNodeKey]"
|
||||
:current-node-key="currentNodeKey"
|
||||
highlight-current
|
||||
node-key="id"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node flex align-center">
|
||||
<AppIcon iconName="app-folder" style="font-size: 16px"></AppIcon>
|
||||
<span class="ml-8" >{{ node.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import type { TreeInstance } from 'element-plus'
|
||||
defineOptions({ name: 'FolderTree' })
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
currentNodeKey: {
|
||||
type: String,
|
||||
default: 'root',
|
||||
},
|
||||
})
|
||||
interface Tree {
|
||||
name: string
|
||||
children?: Tree[]
|
||||
}
|
||||
|
||||
const handleNodeClick = (data: Tree) => {
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
}
|
||||
|
||||
const emit = defineEmits(['handleNodeClick'])
|
||||
|
||||
const treeRef = ref<TreeInstance>()
|
||||
const filterText = ref('')
|
||||
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value!.filter(val)
|
||||
})
|
||||
|
||||
const filterNode = (value: string, data: Tree) => {
|
||||
if (!value) return true
|
||||
return data.name.includes(value)
|
||||
}
|
||||
|
||||
const handleNodeClick = (data: Tree) => {
|
||||
emit('handleNodeClick', data)
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<img v-if="user.themeInfo?.loginLogo" :src="fileURL" alt="" height="45px" class="mr-8" />
|
||||
<img v-if="theme.themeInfo?.loginLogo" :src="fileURL" alt="" height="45px" class="mr-8" />
|
||||
<template v-else>
|
||||
<svg
|
||||
v-if="!isDefaultTheme"
|
||||
|
|
@ -66,20 +66,20 @@ defineOptions({ name: 'LogoFull' })
|
|||
defineProps({
|
||||
height: {
|
||||
type: String,
|
||||
default: '36px'
|
||||
}
|
||||
default: '36px',
|
||||
},
|
||||
})
|
||||
const { user } = useStore()
|
||||
const { theme } = useStore()
|
||||
const isDefaultTheme = computed(() => {
|
||||
return user.isDefaultTheme()
|
||||
return theme.isDefaultTheme()
|
||||
})
|
||||
|
||||
const fileURL = computed(() => {
|
||||
if (user.themeInfo) {
|
||||
if (typeof user.themeInfo?.loginLogo === 'string') {
|
||||
return user.themeInfo?.loginLogo
|
||||
if (theme.themeInfo) {
|
||||
if (typeof theme.themeInfo?.loginLogo === 'string') {
|
||||
return theme.themeInfo?.loginLogo
|
||||
} else {
|
||||
return URL.createObjectURL(user.themeInfo?.loginLogo)
|
||||
return URL.createObjectURL(theme.themeInfo?.loginLogo)
|
||||
}
|
||||
} else {
|
||||
return ''
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ defineProps({
|
|||
default: '36px'
|
||||
}
|
||||
})
|
||||
const { user } = useStore()
|
||||
const { theme } = useStore()
|
||||
const isDefaultTheme = computed(() => {
|
||||
return user.isDefaultTheme()
|
||||
return theme.isDefaultTheme()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ defineProps({
|
|||
default: '36px'
|
||||
}
|
||||
})
|
||||
const { user } = useStore()
|
||||
const { theme } = useStore()
|
||||
const isDefaultTheme = computed(() => {
|
||||
return user.isDefaultTheme()
|
||||
return theme.isDefaultTheme()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
</template>
|
||||
<div class="about-ui" v-loading="loading">
|
||||
<div class="flex">
|
||||
<span class="label">{{ $t('layout.about.authorize') }}</span><span>{{ licenseInfo?.corporation || '-' }}</span>
|
||||
<span class="label">{{ $t('layout.about.authorize') }}</span
|
||||
><span>{{ licenseInfo?.corporation || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="label">{{ $t('layout.about.expiredTime') }}</span>
|
||||
|
|
@ -24,16 +25,23 @@
|
|||
</div>
|
||||
<div class="flex">
|
||||
<span class="label">{{ $t('layout.about.edition.label') }}</span>
|
||||
<span>{{ user.showXpack() ? $t('layout.about.edition.professional') : $t('layout.about.edition.community') }}</span>
|
||||
<span>{{
|
||||
user.showXpack()
|
||||
? $t('layout.about.edition.professional')
|
||||
: $t('layout.about.edition.community')
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="label">{{ $t('layout.about.version') }}</span><span>{{ user.version }}</span>
|
||||
<span class="label">{{ $t('layout.about.version') }}</span
|
||||
><span>{{ user.version }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="label">{{ $t('layout.about.serialNo') }}</span><span>{{ licenseInfo?.serialNo || '-' }}</span>
|
||||
<span class="label">{{ $t('layout.about.serialNo') }}</span
|
||||
><span>{{ licenseInfo?.serialNo || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="label">{{ $t('layout.about.remark') }}</span><span>{{ licenseInfo?.remark || '-' }}</span>
|
||||
<span class="label">{{ $t('layout.about.remark') }}</span
|
||||
><span>{{ licenseInfo?.remark || '-' }}</span>
|
||||
</div>
|
||||
<div class="mt-16 flex align-center" v-if="user.showXpack()">
|
||||
<el-upload
|
||||
|
|
@ -44,7 +52,9 @@
|
|||
:on-change="onChange"
|
||||
v-hasPermission="new Role('ADMIN')"
|
||||
>
|
||||
<el-button class="border-primary mr-16">{{ $t('layout.about.update') }} License</el-button>
|
||||
<el-button class="border-primary mr-16"
|
||||
>{{ $t('layout.about.update') }} License</el-button
|
||||
>
|
||||
</el-upload>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -59,9 +69,9 @@ import licenseApi from '@/api/license'
|
|||
import { fromNowDate } from '@/utils/time'
|
||||
import { Role } from '@/utils/permission/type'
|
||||
import useStore from '@/stores'
|
||||
const { user } = useStore()
|
||||
const { user, theme } = useStore()
|
||||
const isDefaultTheme = computed(() => {
|
||||
return user.isDefaultTheme()
|
||||
return theme.isDefaultTheme()
|
||||
})
|
||||
|
||||
const aboutDialogVisible = ref(false)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<el-avatar :size="30">
|
||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
||||
</el-avatar>
|
||||
<span class="ml-8">{{ user.userInfo?.username }}</span>
|
||||
<span class="ml-8 color-text-primary">{{ user.userInfo?.username }}</span>
|
||||
<el-icon class="el-icon--right">
|
||||
<CaretBottom />
|
||||
</el-icon>
|
||||
|
|
|
|||
|
|
@ -4,46 +4,46 @@
|
|||
effect="dark"
|
||||
:content="$t('layout.github')"
|
||||
placement="top"
|
||||
v-if="user.themeInfo?.showProject"
|
||||
v-if="theme.themeInfo?.showProject"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-github"
|
||||
class="cursor color-secondary mr-8 ml-8"
|
||||
style="font-size: 20px"
|
||||
@click="toUrl(user.themeInfo?.projectUrl)"
|
||||
@click="toUrl(theme.themeInfo?.projectUrl)"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('layout.wiki')"
|
||||
placement="top"
|
||||
v-if="user.themeInfo?.showUserManual"
|
||||
v-if="theme.themeInfo?.showUserManual"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-user-manual"
|
||||
class="cursor color-secondary mr-8 ml-8"
|
||||
style="font-size: 20px"
|
||||
@click="toUrl(user.themeInfo?.userManualUrl)"
|
||||
@click="toUrl(theme.themeInfo?.userManualUrl)"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('layout.forum')"
|
||||
placement="top"
|
||||
v-if="user.themeInfo?.showForum"
|
||||
v-if="theme.themeInfo?.showForum"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-help"
|
||||
class="cursor color-secondary mr-16 ml-8"
|
||||
style="font-size: 20px"
|
||||
@click="toUrl(user.themeInfo?.forumUrl)"
|
||||
@click="toUrl(theme.themeInfo?.forumUrl)"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import useStore from '@/stores'
|
||||
const { user } = useStore()
|
||||
const { theme } = useStore()
|
||||
function toUrl(url: string) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import useLoginStore from './modules/login'
|
||||
import useUserStore from './modules/user'
|
||||
import useFolderStore from './modules/folder'
|
||||
import useThemeStore from './modules/theme'
|
||||
|
||||
const useStore = () => ({
|
||||
login: useLoginStore(),
|
||||
user: useUserStore(),
|
||||
folder: useFolderStore(),
|
||||
theme: useThemeStore(),
|
||||
})
|
||||
|
||||
export default useStore
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { useElementPlusTheme } from 'use-element-plus-theme'
|
||||
export interface themeStateTypes {
|
||||
themeInfo: any
|
||||
}
|
||||
const defalueColor = '#3370FF'
|
||||
|
||||
const useThemeStore = defineStore('theme', {
|
||||
state: (): themeStateTypes => ({
|
||||
themeInfo: null,
|
||||
}),
|
||||
actions: {
|
||||
isDefaultTheme() {
|
||||
return !this.themeInfo?.theme || this.themeInfo?.theme === defalueColor
|
||||
},
|
||||
|
||||
setTheme(data?: any) {
|
||||
const { changeTheme } = useElementPlusTheme(this.themeInfo?.theme || defalueColor)
|
||||
changeTheme(defalueColor)
|
||||
// changeTheme(data?.['theme'])
|
||||
// this.themeInfo = cloneDeep(data)
|
||||
},
|
||||
|
||||
// async theme(loading?: Ref<boolean>) {
|
||||
// return await ThemeApi.getThemeInfo(loading).then((ok) => {
|
||||
// this.setTheme(ok.data)
|
||||
// // window.document.title = this.themeInfo['title'] || 'MaxKB'
|
||||
// // const link = document.querySelector('link[rel="icon"]') as any
|
||||
// // if (link) {
|
||||
// // link['href'] = this.themeInfo['icon'] || '/favicon.ico'
|
||||
// // }
|
||||
// })
|
||||
// },
|
||||
},
|
||||
})
|
||||
|
||||
export default useThemeStore
|
||||
|
|
@ -8,13 +8,13 @@ import UserApi from '@/api/user/user'
|
|||
// import { defaultPlatformSetting } from '@/utils/theme'
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { localeConfigKey, getBrowserLang } from '@/locales/index'
|
||||
import useThemeStore from './theme'
|
||||
export interface userStateTypes {
|
||||
userType: number // 1 系统操作者 2 对话用户
|
||||
userInfo: User | null
|
||||
version?: string
|
||||
XPACK_LICENSE_IS_VALID: false
|
||||
isXPack: false
|
||||
themeInfo: any
|
||||
}
|
||||
|
||||
const useLoginStore = defineStore('user', {
|
||||
|
|
@ -24,7 +24,6 @@ const useLoginStore = defineStore('user', {
|
|||
version: '',
|
||||
XPACK_LICENSE_IS_VALID: false,
|
||||
isXPack: false,
|
||||
themeInfo: null,
|
||||
}),
|
||||
actions: {
|
||||
getLanguage() {
|
||||
|
|
@ -32,14 +31,13 @@ const useLoginStore = defineStore('user', {
|
|||
? localStorage.getItem('MaxKB-locale') || getBrowserLang()
|
||||
: sessionStorage.getItem('language') || getBrowserLang()
|
||||
},
|
||||
isDefaultTheme() {
|
||||
return !this.themeInfo?.theme || this.themeInfo?.theme === '#3370FF'
|
||||
},
|
||||
async profile(loading?: Ref<boolean>) {
|
||||
return UserApi.getUserProfile(loading).then((ok) => {
|
||||
this.userInfo = ok.data
|
||||
useLocalStorage<string>(localeConfigKey, 'en-US').value =
|
||||
ok?.data?.language || this.getLanguage()
|
||||
const theme = useThemeStore()
|
||||
theme.setTheme()
|
||||
// return this.asyncGetProfile()
|
||||
})
|
||||
},
|
||||
|
|
@ -86,11 +84,6 @@ const useLoginStore = defineStore('user', {
|
|||
// return this.isXPack
|
||||
// },
|
||||
|
||||
// setTheme(data: any) {
|
||||
// const { changeTheme } = useElementPlusTheme(this.themeInfo?.theme)
|
||||
// changeTheme(data?.['theme'])
|
||||
// this.themeInfo = cloneDeep(data)
|
||||
// },
|
||||
// isExpire() {
|
||||
// return this.isXPack && !this.XPACK_LICENSE_IS_VALID
|
||||
// },
|
||||
|
|
@ -103,16 +96,7 @@ const useLoginStore = defineStore('user', {
|
|||
// this.userAccessToken = token
|
||||
// },
|
||||
|
||||
// async theme(loading?: Ref<boolean>) {
|
||||
// return await ThemeApi.getThemeInfo(loading).then((ok) => {
|
||||
// this.setTheme(ok.data)
|
||||
// // window.document.title = this.themeInfo['title'] || 'MaxKB'
|
||||
// // const link = document.querySelector('link[rel="icon"]') as any
|
||||
// // if (link) {
|
||||
// // link['href'] = this.themeInfo['icon'] || '/favicon.ico'
|
||||
// // }
|
||||
// })
|
||||
// },
|
||||
|
||||
|
||||
// async dingCallback(code: string) {
|
||||
// return UserApi.getDingCallback(code).then((ok) => {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ body {
|
|||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--app-text-color);
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
#app {
|
||||
|
|
@ -373,6 +373,15 @@ h5 {
|
|||
}
|
||||
|
||||
// 颜色
|
||||
.color-text-primary {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.color-secondary {
|
||||
color: var(--app-text-color-secondary);
|
||||
}
|
||||
.avatar-purple {
|
||||
background: #7f3bf5;
|
||||
}
|
||||
.avatar-green {
|
||||
background: var(--el-color-success);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
$primary-color: #3370ff;
|
||||
:root {
|
||||
--el-color-primary: #3370ff;
|
||||
--el-color-success: #34c724;
|
||||
--el-text-color-primary: #1f2329;
|
||||
// --el-menu-item-height: 45px;
|
||||
// --el-box-shadow-light: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
|
||||
// --el-border-color: #dee0e3;
|
||||
// --el-text-color-regular: #1f2329;
|
||||
// --el-color-info: #8f959e !important;
|
||||
// --el-disabled-bg-color: #eff0f1 !important;
|
||||
// --el-text-color-primary: #1f2329;
|
||||
|
||||
// --el-font-line-height-primary: 22px;
|
||||
}
|
||||
|
||||
|
|
@ -21,6 +24,22 @@
|
|||
--el-card-padding: calc(var(--app-base-px) * 2);
|
||||
}
|
||||
|
||||
// tree
|
||||
.el-tree {
|
||||
background: none;
|
||||
}
|
||||
.el-tree-node__content {
|
||||
border-radius: 4px;
|
||||
padding: 7px 0;
|
||||
&:hover {
|
||||
background: var(--app-text-color-light-1);
|
||||
}
|
||||
}
|
||||
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
|
||||
background: rgba($primary-color, 0.1);
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-tree-node__expand-icon {
|
||||
color: var(--app-text-color-secondary);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
:root {
|
||||
--app-base-px: 8px;
|
||||
--app-layout-bg-color: #f5f6f7;
|
||||
--app-text-color: #1f2329;
|
||||
--app-text-color-light-1: rgba(31, 35, 41, 0.1);
|
||||
--app-text-color-secondary: #646a73;
|
||||
--app-text-color-disable: #bbbfc4;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ defineProps({
|
|||
default: true,
|
||||
},
|
||||
})
|
||||
const { user } = useStore()
|
||||
const { user, theme } = useStore()
|
||||
|
||||
const changeLang = (lang: string) => {
|
||||
useLocalStorage(localeConfigKey, getBrowserLang()).value = lang
|
||||
|
|
@ -63,11 +63,11 @@ const currentLanguage = computed(() => {
|
|||
})
|
||||
|
||||
const fileURL = computed(() => {
|
||||
if (user.themeInfo?.loginImage) {
|
||||
if (typeof user.themeInfo?.loginImage === 'string') {
|
||||
return user.themeInfo?.loginImage
|
||||
if (theme.themeInfo?.loginImage) {
|
||||
if (typeof theme.themeInfo?.loginImage === 'string') {
|
||||
return theme.themeInfo?.loginImage
|
||||
} else {
|
||||
return URL.createObjectURL(user.themeInfo?.loginImage)
|
||||
return URL.createObjectURL(theme.themeInfo?.loginImage)
|
||||
}
|
||||
} else {
|
||||
return ''
|
||||
|
|
@ -75,10 +75,10 @@ const fileURL = computed(() => {
|
|||
})
|
||||
|
||||
const loginImage = computed(() => {
|
||||
if (user.themeInfo?.loginImage) {
|
||||
if (theme.themeInfo?.loginImage) {
|
||||
return `${fileURL.value}`
|
||||
} else {
|
||||
const imgName = getThemeImg(user.themeInfo?.theme)
|
||||
const imgName = getThemeImg(theme.themeInfo?.theme)
|
||||
const imgPath = `../../../assets/theme/${imgName}.jpg`
|
||||
const imageUrl = new URL(imgPath, import.meta.url).href
|
||||
return imageUrl
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<login-layout v-if="!loading" v-loading="loading">
|
||||
<LoginContainer :subTitle="user.themeInfo?.slogan || $t('theme.defaultSlogan')">
|
||||
<LoginContainer :subTitle="theme.themeInfo?.slogan || $t('theme.defaultSlogan')">
|
||||
<h2 class="mb-24">{{ $t('views.login.title') }}</h2>
|
||||
<div>
|
||||
<el-form
|
||||
|
|
@ -88,7 +88,7 @@ import useStore from '@/stores'
|
|||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const router = useRouter()
|
||||
const { login, user } = useStore()
|
||||
const { login, user, theme } = useStore()
|
||||
const { locale } = useI18n({ useScope: 'global' })
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
<template>
|
||||
<LayoutContainer class="tool-manage">
|
||||
<template #left>
|
||||
<h4>{{ $t('views.tool.title') }}</h4>
|
||||
<folder-tree :data="folderList" />
|
||||
<h4 class="p-8">{{ $t('views.tool.title') }}</h4>
|
||||
|
||||
<folder-tree
|
||||
:data="folderList"
|
||||
:currentNodeKey="currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandel"
|
||||
/>
|
||||
</template>
|
||||
<ContentContainer>
|
||||
<div class="flex-between mb-16">
|
||||
<h4>{{ $t('views.tool.title') }}</h4>
|
||||
<h4>{{ currentFolder?.name }}</h4>
|
||||
<div class="flex-between"></div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -15,25 +20,8 @@
|
|||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<CardBox :title="item.name" :description="item.desc" class="cursor">
|
||||
<template #icon>
|
||||
<el-avatar
|
||||
v-if="item.type === '1'"
|
||||
class="mr-8 avatar-purple"
|
||||
shape="square"
|
||||
:size="32"
|
||||
>
|
||||
<img src="@/assets/knowledge/icon_web.svg" style="width: 58%" alt="" />
|
||||
</el-avatar>
|
||||
<el-avatar
|
||||
v-else-if="item.type === '2'"
|
||||
class="mr-8 avatar-purple"
|
||||
shape="square"
|
||||
:size="32"
|
||||
style="background: none"
|
||||
>
|
||||
<img src="@/assets/knowledge/logo_lark.svg" style="width: 100%" alt="" />
|
||||
</el-avatar>
|
||||
<el-avatar v-else class="mr-8 avatar-blue" shape="square" :size="32">
|
||||
<img src="@/assets/knowledge/icon_document.svg" style="width: 58%" alt="" />
|
||||
<el-avatar class="mr-8 avatar-green" shape="square" :size="32">
|
||||
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
|
||||
</el-avatar>
|
||||
</template>
|
||||
<template #subTitle>
|
||||
|
|
@ -67,14 +55,14 @@ const paginationConfig = reactive({
|
|||
page_size: 30,
|
||||
total: 0,
|
||||
})
|
||||
|
||||
const searchValue = ref('')
|
||||
const folderList = ref<any[]>([])
|
||||
const toolList = ref<any[]>([])
|
||||
const folderId = ref<string>('root')
|
||||
const currentFolder = ref<any>({})
|
||||
|
||||
function getList() {
|
||||
const params = {
|
||||
folder_id: folderId.value,
|
||||
folder_id: currentFolder.value?.id || 'root',
|
||||
tool_type: 'CUSTOM',
|
||||
}
|
||||
ToolApi.getToolList('default', paginationConfig, params, loading).then((res) => {
|
||||
|
|
@ -87,12 +75,13 @@ function getFolder() {
|
|||
const params = {}
|
||||
folder.asynGetFolder('default', 'TOOL', params, loading).then((res: any) => {
|
||||
folderList.value = res.data
|
||||
currentFolder.value = res.data?.[0] || {}
|
||||
getList()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getFolder()
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue