支持在 Chat 页面显示,隐藏对话列表

This commit is contained in:
RockYang
2025-01-06 19:17:18 +08:00
parent cffc722622
commit 7da5b7163c
27 changed files with 404 additions and 393 deletions

View File

@@ -131,7 +131,8 @@ type SystemConfig struct {
Title string `json:"title,omitempty"` // 网站标题
Slogan string `json:"slogan,omitempty"` // 网站 slogan
AdminTitle string `json:"admin_title,omitempty"` // 管理后台标题
Logo string `json:"logo,omitempty"` // 形 Logo
Logo string `json:"logo,omitempty"` // 形 Logo
BarLogo string `json:"bar_logo,omitempty"` // 条形 Logo
InitPower int `json:"init_power,omitempty"` // 新用户注册赠送算力值
DailyPower int `json:"daily_power,omitempty"` // 每日签到赠送算力
InvitePower int `json:"invite_power,omitempty"` // 邀请新用户赠送算力值

View File

@@ -92,6 +92,8 @@ func (h *ChatHandler) sendOpenAiMessage(
if strings.HasPrefix(req.Model, "o1-") {
content := fmt.Sprintf("AI 思考结束,耗时:%d 秒。\n\n", time.Now().Unix()-session.Start)
contents = append(contents, "> AI 正在思考中...\n")
contents = append(contents, content)
utils.SendChunkMsg(ws, content)
}

View File

@@ -134,6 +134,7 @@ func (h *WebsocketHandler) Client(c *gin.Context) {
if err != nil {
logger.Error(err, chatModel)
}
session.Model.Id = chatModel.Id
ctx, cancel := context.WithCancel(context.Background())
h.chatHandler.ReqCancelFunc.Put(clientId, cancel)
err = h.chatHandler.sendMessage(ctx, session, chatRole, chatMessage.Content, client)

View File

@@ -8,4 +8,7 @@ VUE_APP_KEY_PREFIX=GeekAI_DEV_
VUE_APP_TITLE="Geek-AI 创作系统"
VUE_APP_VERSION=v4.1.9
VUE_APP_DOCS_URL=https://docs.geekai.me
VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai
VUE_APP_GITHUB_URL=https://github.com/yangjian102621/geekai
VUE_APP_GITEE_URL=https://gitee.com/blackfox/geekai
VUE_APP_GITCODE_URL=https://gitcode.com/yangjian102621/geekai

View File

@@ -3,4 +3,6 @@ VUE_APP_WS_HOST=
VUE_APP_KEY_PREFIX=GeekAI_
VUE_APP_VERSION=v4.1.9
VUE_APP_DOCS_URL=https://docs.geekai.me
VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai
VUE_APP_GITHUB_URL=https://github.com/yangjian102621/geekai
VUE_APP_GITEE_URL=https://gitee.com/blackfox/geekai
VUE_APP_GITCODE_URL=https://gitcode.com/yangjian102621/geekai

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -30,14 +30,6 @@
margin-bottom: 10px
}
//
::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
.content {
width: 100%
overflow-y: scroll
@@ -130,7 +122,7 @@
.chat-container {
min-width: 0;
flex: 1;
background-color: var(--el-bg-color)
background-color: var(--chat-bg)
color var(--text-fb)
.chat-config {
@@ -186,47 +178,25 @@
width: 100%;
position relative
background: var(--chat-bg)
::-webkit-scrollbar {
width: 12px /* */
background #F1F1F1
}
::-webkit-scrollbar-track {
background-color: #e1e1e1;
}
::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
border-radius 12px
}
::-webkit-scrollbar-thumb:hover {
background-color: #A8A8A8;
}
display: flex;
justify-content: center;
padding 0 20px
max-width: 960px;
.chat-box {
overflow-y: auto;
//border-bottom: 1px solid #4f4f4f
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IEEdge */
//
--content-font-size: 16px;
--content-color: #c1c1c1;
font-family: 'Microsoft YaHei', '', Arial, sans-serif;
padding: 0 0 50px 0;
//padding: 0 0 50px 0;
width: 100%;
.chat-line {
font-size: 14px;
display: flex;
align-items: flex-start;
}
::-webkit-scrollbar {
display: none; /* Webkit */
}
}
@@ -234,6 +204,7 @@
position absolute
bottom 0
width 100%
max-width: 800px;
.input-box-inner {
display flex
@@ -363,11 +334,6 @@
}
}
#container::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
}

View File

@@ -2,22 +2,28 @@
display: flex;
position: relative;
height: 100vh;
.big-top-title {
padding-top: 10px;
}
.top-collapse {
padding-top: 10px
img {
width 24px !important
height: 24px !important
}
}
.tab-box {
align-items: center
background-color: var(--card-bg)
border-right: 1px solid var(--line-box);
// height: 100%
// position: fixed;
height: 100vh;
.title {
font-size: 28px
height: 40px
@@ -28,6 +34,7 @@
font-weight: 700
color: var(--text-theme-color)
}
img {
height: 44px
object-fit: cover
@@ -35,6 +42,7 @@
border: 2px solid #754ff6;
background: #fff
}
.marr {
margin-right: 4px;
}
@@ -42,34 +50,29 @@
}
}
.flex-center-col {
display flex
align-items center
flex-direction column
.iconfont {
font-size 22px
}
.icon-expand {
font-size 24px
margin-bottom 10px
cursor pointer
color var(--text-color)
}
.icon-colspan {
font-size 18px
margin-left 3px
cursor pointer
color var(--text-color)
.icon-new-chat {
color #ffffff
}
}
.menu-list-collapse {
.flex-center-col {
flex-direction: row;
}
.menu-list-item {
height: 38px;
@@ -80,51 +83,48 @@
}
}
.menu-list-item:hover,
.active {
background: rgba(79, 89, 102, .122);
border-radius: 8px;
.el-icon {
background: transparent !important;
}
}
.menu-title {
font-size: 15px !important;
margin-bottom: 0 !important;
}
}
.openicon{
font-size: 40px;
color: #754ff6;
}
.menuIcon{
.openicon{
font-size: 28px;
color: #754ff6;
}
}
.menu-list {
margin-top: 20px;
width: 65px;
.svg-icon {
svg {
width: 30px;
height: 30px;
}
}
.menu-list-item {
// margin-bottom: 10px;
margin: 0 8px 8px;
cursor: pointer;
font-weight: 550;
color: var(--text-theme-color);
&:hover {
.el-icon {
background: rgba(79, 89, 102, .122);
}
}
.el-icon {
width: 24px;
height: 24px;
@@ -138,24 +138,22 @@
// }
}
&.active {
color: var(--text-color);
color: var(--text-theme-color);
font-weight: 700;
filter: none !important;
.el-icon{
background: rgba(79, 89, 102, .122);
filter: invert(100%);
}
}
}
.bot {
position: absolute;
bottom: 6px;
width 65px;
}
.bot-line {
width: 100%;
@@ -163,44 +161,48 @@
background: var(--line-box)
margin: 20px 0 10px 0;
}
.menu-title {
font-size: 12px;
margin-bottom: 6px;
}
.icon-house,
.icon-github {
font-size: 20px;
color: #754ff6;
cursor pointer
}
.menu-bot-item {
display: flex;
align-items: center;
justify-content: space-around;
align-items: center;
a{
// margin-right: 46px;
}
}
}
::v-deep(.theme-box) {
position: relative !important;
right: initial;
bottom: initial;
width: 20px;
height: 20px;
line-height: 20px;
line-height: 18px;
.iconfont {
font-size: 15px !important;}
font-size: 15px !important;
}
}
.right-main {
height: 100%;
// background: #f5f7fd;
background: var(--theme-bg-all);
// background-image: linear-gradient(180deg, rgba(247, 232, 255, .54), rgba(191, 223, 255, .35));
width: 100%;
.loginMask {
position: absolute;
top: 0;
@@ -208,6 +210,7 @@
height: 100%;
z-index: 999;
}
.topheader {
display: flex;
position: fixed;
@@ -218,6 +221,7 @@
align-items: center;
justify-content: flex-end;
}
.btn-go {
background: #754ff6;
margin: 10px 10px 0;
@@ -225,7 +229,6 @@
}
.el-popper {
.more-menus {
li {
@@ -251,10 +254,12 @@
background: rgba(79, 89, 102, 0.1);
}
}
.setting-menus {
.title {
color: #222226;
}
.el-icon,
.iconfont {
font-size: 18px
@@ -262,6 +267,7 @@
}
color: #222226;
}
.username {
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -271,20 +277,24 @@
}
.rightHeightMax {
height: 100vh;
max-height: 100vh;
overflow: hidden;
}
.rightHeight {
height: calc(100vh - 42px);
max-height: calc(100vh - 42px);
overflow: hidden;
.content {
padding-top: 42px;
}
}
.content {
height: 100%;
overflow: scroll;

View File

@@ -43,7 +43,7 @@
--el-bg-color-overlay: rgba(17, 28, 68, 1);
--el-border-color-light: rgba(255, 255, 255, 0.2);
--chat-content-bg:rgba(86, 86, 95, .2);
--chat-content-bg-list:rgba(86, 86, 95, .2);
--chat-user-content-bg: #762AA4;
--hover-deep-color:#30323c;
//layout
.more-menus li.moreTitle,
@@ -52,7 +52,7 @@
.setting-menus li .el-icon,
.setting-menus li .iconfont,
.layout .tab-box .menu-list-item{
filter: invert(100%);
//filter: invert(100%);
}
.more-menus span.title{
color:#000;

View File

@@ -31,8 +31,8 @@
--theme-text-primary: #000;
--theme-text-color-secondary: #666;
--chat-content-bg:#f5f7fc;
--chat-user-content-bg: #e0dfff;
--chat-list-bg: #0302020a;
--chat-content-bg-list:#fff;
--chat-wel-bg:rgba(247, 247, 248, 1);
--hover-deep-color:#fff;
--el-bg-color-overlay: #fff;

View File

@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4125778 */
src: url('iconfont.woff2?t=1734934068681') format('woff2'),
url('iconfont.woff?t=1734934068681') format('woff'),
url('iconfont.ttf?t=1734934068681') format('truetype');
src: url('iconfont.woff2?t=1736144380052') format('woff2'),
url('iconfont.woff?t=1736144380052') format('woff'),
url('iconfont.ttf?t=1736144380052') format('truetype');
}
.iconfont {
@@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-gitee:before {
content: "\e6d0";
}
.icon-redeem:before {
content: "\e61a";
}

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "6905420",
"name": "码云",
"font_class": "gitee",
"unicode": "e6d0",
"unicode_decimal": 59088
},
{
"icon_id": "3624396",
"name": "兑换码",

Binary file not shown.

View File

@@ -17,7 +17,10 @@
</div>
<div class="body">
<div class="title">
<el-link :href="file.url" target="_blank" style="--el-font-weight-primary: bold">{{ file.name }}</el-link>
<el-link :href="file.url" target="_blank" style="--el-font-weight-primary: bold">{{
file.name
}}
</el-link>
</div>
<div class="info">
<span>{{ GetFileType(file.ext) }}</span>
@@ -56,7 +59,10 @@
</div>
<div class="body">
<div class="title">
<el-link :href="file.url" target="_blank" style="--el-font-weight-primary: bold">{{ file.name }}</el-link>
<el-link :href="file.url" target="_blank" style="--el-font-weight-primary: bold">{{
file.name
}}
</el-link>
</div>
<div class="info">
<span>{{ GetFileType(file.ext) }}</span>
@@ -162,7 +168,8 @@ const processFiles = () => {
}
}
})
.catch(() => {});
.catch(() => {
});
for (let link of links) {
content.value = content.value.replace(link, "");
@@ -213,6 +220,7 @@ const isExternalImg = (link, files) => {
.file-list-box {
display flex
flex-flow column
.image {
display flex
flex-flow row
@@ -225,6 +233,7 @@ const isExternalImg = (link, files) => {
margin-bottom 10px
}
}
.item {
display flex
flex-flow row
@@ -241,14 +250,17 @@ const isExternalImg = (link, files) => {
height 40px
}
}
.body {
margin-left 8px
font-size 14px
.title {
font-weight bold
line-height 24px
color #0D0D0D
}
.info {
color #B4B4B4
@@ -336,11 +348,12 @@ const isExternalImg = (link, files) => {
.chat-item {
padding: 0;
overflow: hidden;
max-width 60%
max-width calc(100% - 110px);
.file-list-box {
display flex
flex-flow column
.image {
display flex
flex-flow row
@@ -353,6 +366,7 @@ const isExternalImg = (link, files) => {
margin-bottom 10px
}
}
.item {
display flex
flex-flow row
@@ -369,14 +383,17 @@ const isExternalImg = (link, files) => {
height 40px
}
}
.body {
margin-left 8px
font-size 14px
.title {
font-weight bold
line-height 24px
color #0D0D0D
}
.info {
color #B4B4B4
@@ -392,13 +409,14 @@ const isExternalImg = (link, files) => {
.content-wrapper {
display flex
flex-flow row-reverse
.content {
word-break break-word;
padding: 1rem
color var(--theme-text-primary);
font-size: var(--content-font-size);
overflow: auto;
background-color :var(--chat-content-bg);
background-color: var(--chat-user-content-bg);
border-radius: 10px 0 10px 10px;
img {
@@ -421,6 +439,7 @@ const isExternalImg = (link, files) => {
}
}
.bar {
padding 10px 10px 10px 0;

View File

@@ -237,7 +237,6 @@ const reGenerate = (prompt) => {
table {
width 100%
margin-bottom 1rem
color #212529
border-collapse collapse;
border 1px solid #dee2e6;
background-color:var(--chat-content-bg);
@@ -266,7 +265,7 @@ const reGenerate = (prompt) => {
padding: 0.8rem 1.5rem;
color: var(--quote-text-color);
border-left: 0.4rem solid #6b50e1; /* 紫色边框 */
font-size: 1.1rem;
font-size: 16px;
line-height: 1.6;
}
}
@@ -275,7 +274,7 @@ const reGenerate = (prompt) => {
.chat-line-reply-list {
justify-content: center;
background-color: var(--chat-list-bg);
background-color: var(--chat-content-bg);
color:var(--theme-text-color-primary);
width 100%
padding-bottom: 1.5rem;
@@ -376,7 +375,8 @@ const reGenerate = (prompt) => {
position: relative;
padding: 0;
overflow: hidden;
max-width 70%
width 100%
max-width calc(100% - 110px)
.content-wrapper {
display flex
@@ -391,6 +391,7 @@ const reGenerate = (prompt) => {
// background-color #F5F5F5
background-color :var(--chat-content-bg);
border-radius: 0 10px 10px 10px;
width 100%
}
}

View File

@@ -53,6 +53,7 @@ import { isImage, removeArrayItem } from "@/utils/libs";
import {GetFileIcon} from "@/store/system";
import {checkSession} from "@/store/cache";
import {useSharedStore} from "@/store/sharedata";
const props = defineProps({
userId: Number,
});
@@ -151,6 +152,7 @@ const insertURL = (file) => {
.file-upload-img {
.iconfont {
font-size: 19px;
cursor pointer;
}
}

View File

@@ -15,13 +15,12 @@
</template>
<script setup>
import {ref} from "vue";
import { httpGet } from "@/utils/http";
import {showMessageError} from "@/utils/dialog";
import {getLicenseInfo, getSystemInfo} from "@/store/cache";
const title = ref("");
const version = ref(process.env.VUE_APP_VERSION);
const gitURL = ref(process.env.VUE_APP_GIT_URL);
const gitURL = ref(process.env.VUE_APP_GITHUB_URL);
const copyRight = ref("");
const license = ref({});
const props = defineProps({

View File

@@ -1,11 +1,11 @@
<template>
<div class="theme-box" @click="toggleTheme">
<span class="iconfont icon-yueliang">{{ themePage === "light" ? "&#xe679;" : "&#xe60b;" }}</span>
<i class="iconfont" :class="themePage === 'light'?'icon-yueliang':'icon-taiyang'"></i>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {ref} from "vue";
import {useSharedStore} from "@/store/sharedata";
// 定义主题状态,初始值从 localStorage 获取

View File

@@ -132,7 +132,7 @@ const send = (text) => {
line-height: 2.5rem
font-weight 600
margin-bottom: 4rem
color var( --theme-textcolor-normal)
color var(--text-color)
}
.grid-content {

View File

@@ -9,6 +9,7 @@ export const useSharedStore = defineStore("shared", {
socket: { conn: null, handlers: {} },
theme: Storage.get("theme", "light"),
isLogin: false,
chatListExtend: Storage.get("chat_list_extend", true),
}),
getters: {},
actions: {
@@ -29,6 +30,10 @@ export const useSharedStore = defineStore("shared", {
}
this.socket.conn = value;
},
setChatListExtend(value) {
this.chatListExtend = value;
Storage.set("chat_list_extend", value);
},
addMessageHandler(key, callback) {
if (!this.socket.handlers[key]) {
this.socket.handlers[key] = callback;

View File

@@ -1,12 +1,15 @@
<template>
<div class="chat-page">
<el-container>
<el-aside>
<el-aside v-show="store.chatListExtend">
<div class="flex w-full justify-center pt-3 pb-3">
<img :src="logo" style="max-height: 40px" :alt="title" v-if="logo !== ''"/>
<h2 v-else>{{ title }}</h2>
</div>
<div class="media-page">
<el-button @click="_newChat" type="primary" class="newChat">
<el-icon style="margin-right: 5px">
<Plus />
</el-icon>
<i class="iconfont icon-new-chat mr-1"></i>
新建对话
</el-button>
@@ -19,7 +22,7 @@
</template>
</el-input>
</div>
<el-scrollbar :height="chatBoxHeight">
<el-scrollbar :height="chatListHeight">
<div class="content">
<el-row v-for="chat in chatList" :key="chat.chat_id">
<div :class="chat.chat_id === chatId ? 'chat-list-item active' : 'chat-list-item'" @click="loadChat(chat)">
@@ -111,7 +114,7 @@
</div>
</div>
<div>
<div class="flex justify-center">
<div id="container" :style="{ height: mainWinHeight + 'px' }">
<div class="chat-box" id="chat-box" :style="{ height: chatBoxHeight + 'px' }">
<div v-if="showHello">
@@ -232,7 +235,7 @@
import {nextTick, onMounted, onUnmounted, ref, watch} from "vue";
import ChatPrompt from "@/components/ChatPrompt.vue";
import ChatReply from "@/components/ChatReply.vue";
import { Delete, Edit, InfoFilled, More, Plus, Promotion, Search, Share, VideoPause } from "@element-plus/icons-vue";
import {Delete, Edit, InfoFilled, More, Promotion, Search, Share, VideoPause} from "@element-plus/icons-vue";
import "highlight.js/styles/a11y-dark.css";
import {isMobile, randString, removeArrayItem, UUID} from "@/utils/libs";
import {ElMessage, ElMessageBox} from "element-plus";
@@ -247,8 +250,11 @@ import FileList from "@/components/FileList.vue";
import ChatSetting from "@/components/ChatSetting.vue";
import BackTop from "@/components/BackTop.vue";
import {closeLoading, showLoading, showMessageError} from "@/utils/dialog";
import MarkdownIt from "markdown-it";
import emoji from "markdown-it-emoji";
const title = ref("GeekAI-智能助手");
const logo = ref("");
const models = ref([]);
const modelID = ref(0);
const chatData = ref([]);
@@ -256,7 +262,7 @@ const allChats = ref([]); // 会话列表
const chatList = ref(allChats.value);
const mainWinHeight = ref(0); // 主窗口高度
const chatBoxHeight = ref(0); // 聊天内容框高度
const leftBoxHeight = ref(0);
const chatListHeight = ref(0); // 聊天列表高度
const loading = ref(false);
const loginUser = ref(null);
const roles = ref([]);
@@ -311,6 +317,7 @@ if (!chatId.value) {
// 查询对话信息
httpGet("/api/chat/detail", { chat_id: chatId.value })
.then((res) => {
document.title = res.data.title;
roleId.value = res.data.role_id;
modelID.value = res.data.model_id;
})
@@ -324,14 +331,12 @@ getSystemInfo()
.then((res) => {
config.value = res.data;
title.value = config.value.title;
logo.value = res.data.bar_logo;
})
.catch((e) => {
ElMessage.error("获取系统配置失败:" + e.message);
});
import MarkdownIt from "markdown-it";
import emoji from "markdown-it-emoji";
const md = new MarkdownIt({
breaks: true,
html: true,
@@ -540,17 +545,10 @@ const getRoleById = function (rid) {
};
const resizeElement = function () {
chatBoxHeight.value = window.innerHeight - 101 - 82 - 38;
chatListHeight.value = window.innerHeight - 240;
// chatBoxHeight.value = window.innerHeight;
// mainWinHeight.value = window.innerHeight - 101;
mainWinHeight.value = window.innerHeight - 59;
// mainWinHeight.value = window.innerHeight;
// leftBoxHeight.value = window.innerHeight - 90 - 45 - 82;
// leftBoxHeight.value = window.innerHeight - 90 - 82;
leftBoxHeight.value = window.innerHeight - 90 - 100;
mainWinHeight.value = window.innerHeight - 50;
chatBoxHeight.value = window.innerHeight - 101 - 82 - 38;
};
const _newChat = () => {

View File

@@ -1,28 +1,20 @@
<template>
<div class="layout">
<div class="tab-box">
<div class="flex-center-col big-top-title xxx">
<div class="flex-center-col" @click="isCollapse = !isCollapse">
<el-tooltip content="展开菜单" placement="right" v-if="isCollapse">
<i class="iconfont icon-expand"></i>
</el-tooltip>
</div>
<div class="flex" :class="{ 'top-collapse': !isCollapse }">
<div class="top-avatar flex">
<span class="title" v-if="!isCollapse">{{ title }}</span>
<el-tooltip :content="title" placement="right">
<img :src="logo" alt="" :class="{ marr: !isCollapse }" v-if="isCollapse" />
</el-tooltip>
</div>
<div class="menuIcon xxx" @click="isCollapse = !isCollapse">
<el-tooltip content="关闭菜单" placement="right" v-if="!isCollapse">
<div class="flex-center-col pt-2 mb-2">
<div class="flex flex-center-col">
<div class="menuIcon" @click="store.setChatListExtend(!store.chatListExtend)">
<el-tooltip content="隐藏对话列表" placement="right" v-if="store.chatListExtend">
<i class="iconfont icon-colspan"></i>
</el-tooltip>
<el-tooltip content="展开对话列表" placement="right" v-else>
<i class="iconfont icon-expand"></i>
</el-tooltip>
</div>
</div>
</div>
<div class="menu-list" :style="{ width: isCollapse ? '65px' : '170px' }" :class="{ 'menu-list-collapse': !isCollapse }">
<div class="menu-list">
<ul>
<li
class="menu-list-item flex-center-col"
@@ -31,24 +23,23 @@
@click="changeNav(item)"
:class="item.url === curPath ? 'active' : ''"
>
<span v-if="item.icon.startsWith('icon')" :class="{ 'mr-1 ml-2': !isCollapse }">
<span v-if="item.icon.startsWith('icon')">
<i class="iconfont" :class="item.icon"></i>
</span>
<el-image :src="item.icon" class="el-icon ml-1" v-else />
<div class="menu-title" :class="{ 'menu-title-collapse': !isCollapse }">
<div class="menu-title">
{{ item.name }}
</div>
</li>
</ul>
<!-- 更多 -->
<div class="bot" :style="{ width: isCollapse ? '65px' : '170px' }">
<div class="bot p-2">
<div class="bot-line"></div>
<el-popover v-if="moreNavs.length > 0" placement="right-end" trigger="hover">
<template #reference>
<li class="menu-list-item flex-center-col">
<el-icon><CirclePlus /></el-icon>
<div class="menu-title">更多</div>
<i class="iconfont icon-more"/>
</li>
</template>
<template #default>
@@ -76,8 +67,7 @@
<el-popover placement="right-end" trigger="hover" v-if="loginUser.id">
<template #reference>
<li class="menu-list-item flex-center-col">
<el-icon><Setting /></el-icon>
<div v-if="!isCollapse">设置</div>
<i class="iconfont icon-config"/>
</li>
</template>
<template #default>
@@ -99,19 +89,15 @@
</ul>
</template>
</el-popover>
<li class="menu-bot-item">
<a :href="gitURL" class="link-button" target="_blank" v-if="!license.de_copy && !isCollapse">
<i class="iconfont icon-github"></i>
</a>
<div class="menu-bot-item">
<a @click="router.push('/')" class="link-button">
<i class="iconfont icon-house"></i>
</a>
<div class="pl-1">
<ThemeChange/>
</li>
</div>
</ul>
</div>
</div>
</div>
</div>
<el-scrollbar class="right-main">
@@ -141,7 +127,7 @@
</template>
<script setup>
import { CirclePlus, Setting, UserFilled } from "@element-plus/icons-vue";
import {UserFilled} from "@element-plus/icons-vue";
import ThemeChange from "@/components/ThemeChange.vue";
import {useRouter} from "vue-router";
import {onMounted, ref, watch} from "vue";
@@ -153,9 +139,7 @@ import { useSharedStore } from "@/store/sharedata";
import ConfigDialog from "@/components/UserInfoDialog.vue";
import {showMessageError} from "@/utils/dialog";
import LoginDialog from "@/components/LoginDialog.vue";
import { substr } from "@/utils/libs";
const isCollapse = ref(true);
const router = useRouter();
const logo = ref("");
const mainNavs = ref([]);
@@ -163,13 +147,11 @@ const moreNavs = ref([]);
const curPath = ref();
const title = ref("");
const avatarImg = ref("/images/avatar/default.jpg");
const store = useSharedStore();
const loginUser = ref({});
const routerViewKey = ref(0);
const showConfigDialog = ref(false);
const license = ref({ de_copy: true });
const gitURL = ref(process.env.VUE_APP_GIT_URL);
const showLoginDialog = ref(false);
/**

View File

@@ -9,25 +9,24 @@
</div>
<div class="menu-item">
<span v-if="!license.de_copy">
<el-tooltip v-if="!license.de_copy" class="box-item" content="部署文档" placement="bottom">
<el-tooltip class="box-item" content="部署文档" placement="bottom">
<a :href="docsURL" class="link-button mr-2" target="_blank">
<i class="iconfont icon-book"></i>
</a>
</el-tooltip>
<el-tooltip v-if="!license.de_copy" class="box-item" content="项目源码" placement="bottom">
<el-tooltip class="box-item" content="Github 源码" placement="bottom">
<a :href="gitURL" class="link-button" target="_blank">
<i class="iconfont icon-github"></i>
</a>
</el-tooltip>
<el-tooltip class="box-item" content="Gitee 源码" placement="bottom">
<a :href="gitURL" class="link-button" target="_blank">
<i class="iconfont icon-gitee"></i>
</a>
</el-tooltip>
</span>
<span v-if="!isLogin">
<!-- <el-button @click="router.push('/login')" class="shadow" round
>登录</el-button
>
<el-button @click="router.push('/register')" class="shadow" round
>注册</el-button
> -->
<el-button @click="router.push('/login')" class="btn-go animate__animated animate__pulse animate__infinite" round>登录/注册</el-button>
</span>
</div>
@@ -81,7 +80,7 @@ const license = ref({ de_copy: true });
const isLogin = ref(false);
const docsURL = ref(process.env.VUE_APP_DOCS_URL);
const gitURL = ref(process.env.VUE_APP_GIT_URL);
const gitURL = ref(process.env.VUE_APP_GITHUB_URL);
const navs = ref([]);
const iconMap = ref({
@@ -150,7 +149,6 @@ const setContent = () => {
displayedChars.value = [];
if (timer) clearInterval(timer);
timer = setInterval(setContent, interTime.value);
return;
} else {
const nextChar = slogan.value.charAt(initAnimation.value.length);
initAnimation.value += slogan.value.charAt(initAnimation.value.length); // 逐字符追加
@@ -164,7 +162,7 @@ const setContent = () => {
const rainbowColor = (index) => {
const hue = (index * 40) % 360; // 每个字符间隔40度形成彩虹色
return `hsl(${hue}, 90%, 50%)`; // 色调(hue),饱和度(70%),亮度(50%)
};
}
</script>
<style lang="stylus" scoped>

View File

@@ -15,8 +15,8 @@
<el-form-item label="网站Slogan" prop="slogan">
<el-input v-model="system['slogan']" />
</el-form-item>
<el-form-item label="网站 LOGO" prop="logo">
<el-input v-model="system['logo']" placeholder="网站LOGO图片">
<el-form-item label="圆形 LOGO" prop="logo">
<el-input v-model="system['logo']" placeholder="正方形或者圆形 Logo">
<template #append>
<el-upload :auto-upload="true" :show-file-list="false" @click="beforeUpload('logo')" :http-request="uploadImg">
<el-icon class="uploader-icon">
@@ -26,7 +26,18 @@
</template>
</el-input>
</el-form-item>
<el-form-item label="条形 LOGO" prop="logo">
<el-input v-model="system['bar_logo']" placeholder="长方形 Logo">
<template #append>
<el-upload :auto-upload="true" :show-file-list="false" @click="beforeUpload('bar_logo')"
:http-request="uploadImg">
<el-icon class="uploader-icon">
<UploadFilled/>
</el-icon>
</el-upload>
</template>
</el-input>
</el-form-item>
<el-form-item>
<template #label>
<div class="label-title">