feat(Appearance Configuration): Logo and website name optimization

This commit is contained in:
dataeaseShu
2025-10-21 16:07:21 +08:00
committed by dataeaseShu
parent f467cb319f
commit e679785e6b
9 changed files with 187 additions and 61 deletions
+114 -25
View File
@@ -1,19 +1,15 @@
<script lang="ts" setup>
import { ref, computed, onUnmounted } from 'vue'
import Menu from './Menu.vue'
import LOGOCustom from '@/assets/svg/LOGO-custom.svg'
import custom_small from '@/assets/svg/logo-custom_small.svg'
import Workspace from './Workspace.vue'
import Person from './Person.vue'
import LOGO from '@/assets/LOGO.svg'
import LOGO_fold from '@/assets/LOGO-fold.svg'
import icon_moments_categories_outlined from '@/assets/svg/icon_moments-categories_outlined.svg'
import icon_side_fold_outlined from '@/assets/svg/icon_side-fold_outlined.svg'
import icon_side_expand_outlined from '@/assets/svg/icon_side-expand_outlined.svg'
import { useRoute, useRouter } from 'vue-router'
import { useAppearanceStoreWithOut } from '@/stores/appearance'
import logo_blue from '@/assets/blue/LOGO-blue.png'
import logo_fold_blue from '@/assets/blue/LOGO-head_blue.png'
import { useEmitt } from '@/utils/useEmitt'
const router = useRouter()
@@ -24,6 +20,9 @@ let time: any
onUnmounted(() => {
clearTimeout(time)
})
const loginBg = computed(() => {
return appearanceStore.getLogin
})
const handleCollapseChange = (val: any = true) => {
collapseCopy.value = val
clearTimeout(time)
@@ -61,8 +60,18 @@ const showSysmenu = computed(() => {
<div class="left-side" :class="collapse && 'left-side-collapse'">
<template v-if="showSysmenu">
<div @click="toUserIndex" class="sys-management">
<img
:style="{ marginLeft: collapse ? '5px' : 0 }"
@click="toChatIndex"
height="30"
width="30"
v-if="loginBg"
:src="loginBg"
:class="!collapse && 'collapse-icon'"
alt=""
/>
<custom_small
v-if="appearanceStore.themeColor !== 'default'"
v-else-if="appearanceStore.themeColor !== 'default'"
:style="{ marginLeft: collapse ? '5px' : 0 }"
:class="!collapse && 'collapse-icon'"
></custom_small>
@@ -77,41 +86,109 @@ const showSysmenu = computed(() => {
<template v-else>
<template v-if="appearanceStore.isBlue">
<img
v-if="collapse"
width="30"
height="30"
:src="logo_fold_blue"
style="margin: 0 0 6px 5px; cursor: pointer"
@click="toChatIndex"
height="30"
width="30"
v-if="loginBg && collapse"
:src="loginBg"
alt=""
/>
<img
v-else
width="130"
height="31"
:src="logo_blue"
style="margin-bottom: 6px; cursor: pointer"
@click="toChatIndex"
/>
<div v-else-if="loginBg && !collapse" class="default-sqlbot">
<img
@click="toChatIndex"
height="30"
width="30"
:src="loginBg"
alt=""
class="collapse-icon"
/>
<span style="max-width: 150px" :title="appearanceStore.name" class="ellipsis">{{
appearanceStore.name
}}</span>
</div>
<custom_small
v-else-if="collapse"
:style="{ marginLeft: collapse ? '5px' : 0 }"
:class="!collapse && 'collapse-icon'"
></custom_small>
<div v-else class="default-sqlbot">
<custom_small class="collapse-icon"></custom_small>
<span style="max-width: 150px" :title="appearanceStore.name" class="ellipsis">{{
appearanceStore.name
}}</span>
</div>
</template>
<template v-else-if="appearanceStore.themeColor === 'custom'">
<img
style="margin: 0 0 6px 5px; cursor: pointer"
@click="toChatIndex"
height="30"
width="30"
v-if="loginBg && collapse"
:src="loginBg"
alt=""
/>
<div v-else-if="loginBg && !collapse" class="default-sqlbot">
<img
@click="toChatIndex"
height="30"
width="30"
:src="loginBg"
alt=""
class="collapse-icon"
/>
<span style="max-width: 150px" :title="appearanceStore.name" class="ellipsis">{{
appearanceStore.name
}}</span>
</div>
<custom_small
v-if="collapse"
v-else-if="collapse"
style="margin: 0 0 6px 5px; cursor: pointer"
@click="toChatIndex"
></custom_small>
<LOGOCustom
v-else
style="margin-bottom: 6px; cursor: pointer"
@click="toChatIndex"
></LOGOCustom>
<div v-else class="default-sqlbot">
<custom_small class="collapse-icon"></custom_small>
<span style="max-width: 150px" :title="appearanceStore.name" class="ellipsis">{{
appearanceStore.name
}}</span>
</div>
</template>
<template v-else>
<img
style="margin: 0 0 6px 5px; cursor: pointer"
@click="toChatIndex"
height="30"
width="30"
v-if="loginBg && collapse"
:src="loginBg"
alt=""
/>
<div v-else-if="loginBg && !collapse" class="default-sqlbot">
<img
@click="toChatIndex"
height="30"
width="30"
:src="loginBg"
alt=""
class="collapse-icon"
/>
<span style="max-width: 150px" :title="appearanceStore.name" class="ellipsis">{{
appearanceStore.name
}}</span>
</div>
<LOGO_fold
v-if="collapse"
v-else-if="collapse"
style="margin: 0 0 6px 5px; cursor: pointer"
@click="toChatIndex"
></LOGO_fold>
<LOGO v-else style="margin-bottom: 6px; cursor: pointer" @click="toChatIndex"></LOGO>
<div v-else class="default-sqlbot">
<LOGO_fold class="collapse-icon" @click="toChatIndex"></LOGO_fold>
<span style="max-width: 150px" :title="appearanceStore.name" class="ellipsis">{{
appearanceStore.name
}}</span>
</div>
</template>
</template>
<Workspace v-if="!showSysmenu" :collapse="collapse"></Workspace>
@@ -168,6 +245,18 @@ const showSysmenu = computed(() => {
position: relative;
min-width: 240px;
.default-sqlbot {
display: flex;
align-items: center;
font-weight: 500;
font-size: 16px;
cursor: pointer;
margin-bottom: 12px;
.collapse-icon {
margin-right: 8px;
}
}
.sys-management {
display: flex;
align-items: center;
+1 -1
View File
@@ -675,7 +675,7 @@
"tab": "Tab",
"replace_image": "Replace Image",
"larger_than_200kb": "Logo displayed at the top of the website: Recommended size: 48 x 48 pixels, supports JPG, PNG, and SVG, and no larger than 200KB",
"login_logo": "Login Logo",
"login_logo": "System Logo",
"larger_than_200kb_de": "Logo on the right side of the login page: Recommended size: 204 x 52 pixels, supports JPG, PNG, and SVG, and no larger than 200KB",
"login_background_image": "Login Background Image",
"larger_than_5mb": "Background image on the left: Recommended size: 576 x 900 for vector images, 1152 x 1800 for bitmap images, supports JPG, PNG, and SVG, and no larger than 5MB",
+1 -1
View File
@@ -675,7 +675,7 @@
"tab": "페이지 탭",
"replace_image": "이미지 교체",
"larger_than_200kb": "상단 웹사이트에 표시되는 로고, 권장 크기 48 x 48, JPG, PNG, SVG 지원, 크기 200KB 이하",
"login_logo": "로그인 로고",
"login_logo": "시스템 로고",
"larger_than_200kb_de": "로그인 페이지 오른쪽 로고, 권장 크기 204*52, JPG, PNG, SVG 지원, 크기 200KB 이하",
"login_background_image": "로그인 배경 이미지",
"larger_than_5mb": "왼쪽 배경 이미지, 벡터 이미지 권장 크기 576*900, 비트맵 권장 크기 1152*1800; JPG, PNG, SVG 지원, 크기 5MB 이하",
+1 -1
View File
@@ -675,7 +675,7 @@
"tab": "页签",
"replace_image": "替换图片",
"larger_than_200kb": "顶部网站显示的 Logo,建议尺寸 48 x 48,支持 JPG、PNG、SVG,大小不超过 200KB",
"login_logo": "登录 Logo",
"login_logo": "系统 Logo",
"larger_than_200kb_de": "登录页面右侧 Logo,建议尺寸 204*52,支持 JPG、PNG、SVG,大小不超过 200KB",
"login_background_image": "登录背景图",
"larger_than_5mb": "左侧背景图,矢量图建议尺寸 576*900,位图建议尺寸 1152*1800;支持 JPG、PNG、SVG,大小不超过 5M",
+1 -1
View File
@@ -59,7 +59,7 @@ export const useAppearanceStore = defineStore('appearanceStore', {
login: '',
slogan: '',
web: '',
name: '',
name: 'SQLBot',
foot: 'false',
footContent: '',
loaded: false,
+12 -4
View File
@@ -138,9 +138,11 @@
<div class="welcome-content">
<template v-if="isCompletePage">
<div class="greeting">
<el-icon size="32">
<logo_fold />
</el-icon>
<img height="32" width="32" v-if="loginBg" :src="loginBg" alt="" />
<el-icon size="32" v-else
><custom_small v-if="appearanceStore.themeColor !== 'default'"></custom_small>
<LOGO_fold v-else></LOGO_fold
></el-icon>
{{ t('qa.greeting') }}
</div>
<div class="sub">
@@ -422,6 +424,8 @@ import ChatToolBar from './ChatToolBar.vue'
import { dsTypeWithImg } from '@/views/ds/js/ds-type'
import { useI18n } from 'vue-i18n'
import { find, forEach } from 'lodash-es'
import custom_small from '@/assets/svg/logo-custom_small.svg'
import LOGO_fold from '@/assets/LOGO-fold.svg'
import icon_new_chat_outlined from '@/assets/svg/icon_new_chat_outlined.svg'
import icon_sidebar_outlined from '@/assets/svg/icon_sidebar_outlined.svg'
import icon_replace_outlined from '@/assets/svg/icon_replace_outlined.svg'
@@ -432,6 +436,7 @@ import logo from '@/assets/LOGO.svg'
import icon_send_filled from '@/assets/svg/icon_send_filled.svg'
import { useAssistantStore } from '@/stores/assistant'
import { onClickOutside } from '@vueuse/core'
import { useAppearanceStoreWithOut } from '@/stores/appearance'
import { useUserStore } from '@/stores/user'
import { debounce } from 'lodash-es'
@@ -483,11 +488,14 @@ const scrollToBottom = debounce(() => {
const loading = ref<boolean>(false)
const chatList = ref<Array<ChatInfo>>([])
const appearanceStore = useAppearanceStoreWithOut()
const currentChatId = ref<number | undefined>()
const currentChat = ref<ChatInfo>(new ChatInfo())
const isTyping = ref<boolean>(false)
const loginBg = computed(() => {
return appearanceStore.getLogin
})
const computedMessages = computed<Array<ChatMessage>>(() => {
const messages: Array<ChatMessage> = []
if (currentChatId.value === undefined) {
+21 -4
View File
@@ -5,7 +5,16 @@
</div>
<div class="login-content">
<div class="login-right">
<img width="auto" height="52" :src="loginBg" alt="" />
<div class="login-logo-icon">
<img height="52" v-if="loginBg" :src="loginBg" alt="" />
<el-icon size="52" v-else
><custom_small v-if="appearanceStore.themeColor !== 'default'"></custom_small>
<LOGO_fold v-else></LOGO_fold
></el-icon>
<span style="margin-left: 14px; font-size: 34px; font-weight: 900; color: #485559">{{
appearanceStore.name
}}</span>
</div>
<div v-if="appearanceStore.getShowSlogan" class="welcome">
{{ appearanceStore.slogan || $t('common.intelligent_questioning_platform') }}
</div>
@@ -54,10 +63,10 @@ import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { useI18n } from 'vue-i18n'
import aboutBg from '@/assets/embedded/LOGO-about.png'
import custom_small from '@/assets/svg/logo-custom_small.svg'
import LOGO_fold from '@/assets/LOGO-fold.svg'
import login_image from '@/assets/embedded/login_image.png'
import { useAppearanceStoreWithOut } from '@/stores/appearance'
import logo from '@/assets/blue/LOGO-blue.png'
import loginImage from '@/assets/blue/login-image_blue.png'
const router = useRouter()
@@ -75,7 +84,7 @@ const bg = computed(() => {
})
const loginBg = computed(() => {
return appearanceStore.getLogin || (appearanceStore.isBlue ? logo : aboutBg)
return appearanceStore.getLogin
})
const rules = {
@@ -126,6 +135,14 @@ const submitForm = () => {
align-items: center;
flex-direction: column;
position: relative;
.login-logo-icon {
width: auto;
height: 52px;
display: flex;
align-items: center;
justify-content: center;
}
.welcome {
margin: 8px 0 40px 0;
font-weight: 400;
@@ -39,7 +39,17 @@
<div class="login-form-center">
<div class="config-area">
<div class="login-logo">
<img class="login-logo-icon" :src="pageLogin" alt="" />
<div class="login-logo-icon">
<img height="52" v-if="pageLogin" :src="pageLogin" alt="" />
<el-icon size="52" v-else
><custom_small v-if="themeColor !== 'default'"></custom_small>
<LOGO_fold v-else></LOGO_fold
></el-icon>
<span
style="margin-left: 14px; font-size: 34px; font-weight: 900; color: #485559"
>{{ name }}</span
>
</div>
</div>
<div v-if="isBtnShow(showSlogan)" class="login-welcome">
{{ pageSlogan || t('system.available_to_everyone') }}
@@ -92,10 +102,10 @@
<script lang="ts" setup>
import icon_close_outlined from '@/assets/svg/icon_close_outlined.svg'
import LOGO_fold from '@/assets/LOGO-fold.svg'
import login_image from '@/assets/embedded/login_image.png'
import aboutBg from '@/assets/embedded/LOGO-about.png'
import logoHeader from '@/assets/blue/LOGO-head_blue.png'
import logo from '@/assets/blue/LOGO-blue.png'
import custom_small from '@/assets/svg/logo-custom_small.svg'
import loginImage from '@/assets/blue/login-image_blue.png'
import { propTypes } from '@/utils/propTypes'
import { isBtnShow } from '@/utils/utils'
@@ -132,13 +142,7 @@ const pageWeb = computed(() => {
: baseUrl + props.web
})
const pageLogin = computed(() =>
!props.login
? props.isBlue
? logo
: aboutBg
: props.login.startsWith('blob')
? props.login
: baseUrl + props.login
!props.login ? null : props.login.startsWith('blob') ? props.login : baseUrl + props.login
)
const pageBg = computed(() =>
!props.bg
@@ -273,6 +277,9 @@ onMounted(() => {
.login-logo-icon {
width: auto;
height: 52px;
display: flex;
align-items: center;
justify-content: center;
}
}
.login-welcome {
+19 -14
View File
@@ -162,17 +162,10 @@
<div class="navigate-preview" style="height: 425px">
<div class="navigate-head">
<div class="header-sql">
<custom_small v-if="themeColor === 'custom'" class="logo" />
<img
v-else-if="isBlue"
width="131"
height="30"
class="logo"
:src="logoBlue"
alt=""
/>
<img height="30" width="30" v-if="pageLogin" :src="pageLogin" alt="" />
<custom_small v-else-if="themeColor === 'custom'" class="logo" />
<logo v-else></logo>
<span style="margin-left: 8px">{{ loginForm.name }}</span>
</div>
<div class="bottom-sql">
<Person
@@ -232,8 +225,8 @@
</template>
<script lang="ts" setup>
import logo from '@/assets/LOGO.svg'
import custom_small from '@/assets/svg/LOGO-custom.svg'
import logo from '@/assets/LOGO-fold.svg'
import custom_small from '@/assets/svg/logo-custom_small.svg'
import { ref, unref, reactive, onMounted, onUnmounted, nextTick, computed } from 'vue'
import {
type FormInstance,
@@ -241,7 +234,6 @@ import {
type UploadUserFile,
ElMessage,
} from 'element-plus-secondary'
import logoBlue from '@/assets/blue/LOGO-blue.png'
import { useI18n } from 'vue-i18n'
import { request } from '@/utils/request'
import icon_side_fold_outlined from '@/assets/svg/icon_side-fold_outlined.svg'
@@ -249,6 +241,7 @@ import { useAppearanceStoreWithOut } from '@/stores/appearance'
import LoginPreview from './LoginPreview.vue'
import Person from './Person.vue'
import { setCurrentColor } from '@/utils/utils'
// import TinymceEditor from '@/components/rich-text/TinymceEditor.vue'
import { cloneDeep } from 'lodash-es'
const appearanceStore = useAppearanceStoreWithOut()
@@ -278,6 +271,8 @@ const COLOR_PANEL = [
'#000000',
'#FFFFFF',
]
const basePath = import.meta.env.VITE_API_BASE_URL
const baseUrl = basePath + '/system/appearance/picture/'
const fileList = ref<(UploadUserFile & { flag: string })[]>([])
const navigateBg = ref('dark')
const themeColor = ref('default')
@@ -301,7 +296,9 @@ const defaultLoginForm = reactive<LoginForm>({
footContent: '',
})
const loginForm = reactive<LoginForm>(cloneDeep(defaultLoginForm))
const pageLogin = computed(() =>
!login.value ? null : login.value.startsWith('blob') ? login.value : baseUrl + login.value
)
const rules = reactive<FormRules>({
name: [
{
@@ -817,6 +814,14 @@ onUnmounted(() => {
height: 100%;
position: relative;
.header-sql {
width: 131px;
display: flex;
align-items: center;
font-size: 16px;
font-weight: 500;
}
.bottom-sql {
position: absolute;
bottom: 16px;