修复主题切换组件Bug,优化前端公告 markdown 样式

This commit is contained in:
RockYang
2025-01-13 12:03:24 +08:00
parent 4e6f14cb9e
commit 4e440b7910
11 changed files with 284 additions and 268 deletions

View File

@@ -1,5 +1,10 @@
# 更新日志 # 更新日志
## v4.2.0
- 功能优化:优化聊天页面 Notice 组件样式,采用 Vuepress 文档样式
- Bug 修复:修复主题切换的组件显示异常问题
## v4.1.9 ## v4.1.9
- 功能优化:优化系统配置,移除已废弃的配置项 - 功能优化:优化系统配置,移除已废弃的配置项

View File

@@ -6,7 +6,7 @@ VUE_APP_ADMIN_USER=admin
VUE_APP_ADMIN_PASS=admin123 VUE_APP_ADMIN_PASS=admin123
VUE_APP_KEY_PREFIX=GeekAI_DEV_ VUE_APP_KEY_PREFIX=GeekAI_DEV_
VUE_APP_TITLE="Geek-AI 创作系统" VUE_APP_TITLE="Geek-AI 创作系统"
VUE_APP_VERSION=v4.1.9 VUE_APP_VERSION=v4.2.0
VUE_APP_DOCS_URL=https://docs.geekai.me VUE_APP_DOCS_URL=https://docs.geekai.me
VUE_APP_GITHUB_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_GITEE_URL=https://gitee.com/blackfox/geekai

View File

@@ -1,7 +1,7 @@
VUE_APP_API_HOST= VUE_APP_API_HOST=
VUE_APP_WS_HOST= VUE_APP_WS_HOST=
VUE_APP_KEY_PREFIX=GeekAI_ VUE_APP_KEY_PREFIX=GeekAI_
VUE_APP_VERSION=v4.1.9 VUE_APP_VERSION=v4.2.0
VUE_APP_DOCS_URL=https://docs.geekai.me VUE_APP_DOCS_URL=https://docs.geekai.me
VUE_APP_GITHUB_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_GITEE_URL=https://gitee.com/blackfox/geekai

View File

@@ -132,11 +132,6 @@
overflow: hidden; overflow: hidden;
border-radius: 50%; border-radius: 50%;
font-size: 20px; font-size: 20px;
// img{
// width: 24px;
// height: 24px;
// }
} }
&.active { &.active {
@@ -183,19 +178,6 @@
} }
} }
::v-deep(.theme-box) {
position: relative !important;
right: initial;
bottom: initial;
width: 20px;
height: 20px;
line-height: 18px;
.iconfont {
font-size: 15px !important;
}
}
.right-main { .right-main {
height: 100%; height: 100%;
// background: #f5f7fd; // background: #f5f7fd;
@@ -246,18 +228,18 @@
} }
&:hover { &:hover {
background: rgba(79, 89, 102, 0.1); background: rgba(183, 176, 255, 0.5);
} }
} }
li.active { li.active {
background: rgba(79, 89, 102, 0.1); background: rgba(183, 176, 255, 0.5);
} }
} }
.setting-menus { .setting-menus {
.title { .title {
color: #222226; color: var(--text-theme-color);
} }
.el-icon, .el-icon,
@@ -265,7 +247,7 @@
font-size: 18px font-size: 18px
margin-right: 6px margin-right: 6px
} }
color: #222226; color: var(--text-theme-color);
} }
.username { .username {

View File

@@ -1,238 +1,239 @@
.chat-line { .chat-line,
ol, ul { .notice-dialog {
margin: 0.8em 0; ol,
list-style: normal; ul {
} margin: 0.8em 0;
a { list-style: normal;
}
color :var(--a-link-color); a {
text-decoration: underline; color: var(--a-link-color);
text-decoration: underline;
padding: 0 2px;
}
h1, padding: 0 2px;
h2, }
h3,
h4,
h5,
h6 {
position: relative;
margin-top: 1rem;
margin-bottom: 1rem;
font-weight: bold;
line-height: 1.4;
cursor: text;
}
h1:hover a.anchor, h1,
h2:hover a.anchor, h2,
h3:hover a.anchor, h3,
h4:hover a.anchor, h4,
h5:hover a.anchor, h5,
h6:hover a.anchor { h6 {
text-decoration: none; position: relative;
} margin-top: 1rem;
margin-bottom: 1rem;
font-weight: bold;
line-height: 1.4;
cursor: text;
}
h1 tt, h1:hover a.anchor,
h1 code { h2:hover a.anchor,
font-size: inherit !important; h3:hover a.anchor,
} h4:hover a.anchor,
h5:hover a.anchor,
h6:hover a.anchor {
text-decoration: none;
}
h2 tt, h1 tt,
h2 code { h1 code {
font-size: inherit !important; font-size: inherit !important;
} }
h3 tt, h2 tt,
h3 code { h2 code {
font-size: inherit !important; font-size: inherit !important;
} }
h4 tt, h3 tt,
h4 code { h3 code {
font-size: inherit !important; font-size: inherit !important;
} }
h5 tt, h4 tt,
h5 code { h4 code {
font-size: inherit !important; font-size: inherit !important;
} }
h6 tt, h5 tt,
h6 code { h5 code {
font-size: inherit !important; font-size: inherit !important;
} }
h2 a, h6 tt,
h3 a { h6 code {
color: #34495e; font-size: inherit !important;
} }
h1 { h2 a,
padding-bottom: .4rem; h3 a {
font-size: 2.2rem; color: #34495e;
line-height: 1.3; }
}
h2 { h1 {
font-size: 1.75rem; padding-bottom: 0.4rem;
line-height: 1.225; font-size: 2.2rem;
margin: 35px 0 15px; line-height: 1.3;
padding-bottom: 0.5em; }
border-bottom: 1px solid #ddd;
}
h3 { h2 {
font-size: 1.4rem; font-size: 1.75rem;
line-height: 1.43; line-height: 1.225;
margin: 20px 0 7px; margin: 35px 0 15px;
} padding-bottom: 0.5em;
border-bottom: 1px solid #ddd;
}
h4 { h3 {
font-size: 1.2rem; font-size: 1.4rem;
} line-height: 1.43;
margin: 20px 0 7px;
}
h5 { h4 {
font-size: 1rem; font-size: 1.2rem;
} }
h6 { h5 {
font-size: 1rem; font-size: 1rem;
color: #777; }
}
p, h6 {
blockquote, font-size: 1rem;
ul, color: #777;
ol, }
dl,
table {
margin: 0.8em 0;
}
li > ol, p,
li > ul { blockquote,
margin: 0 0; ul,
} ol,
dl,
table {
margin: 0.8em 0;
}
hr { li > ol,
height: 2px; li > ul {
padding: 0; margin: 0 0;
margin: 16px 0; }
background-color: #e7e7e7;
border: 0 none;
overflow: hidden;
box-sizing: content-box;
}
body > h2:first-child { hr {
margin-top: 0; height: 2px;
padding-top: 0; padding: 0;
} margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
overflow: hidden;
box-sizing: content-box;
}
body > h1:first-child { body > h2:first-child {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
body > h1:first-child + h2 { body > h1:first-child {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
body > h3:first-child, body > h1:first-child + h2 {
body > h4:first-child, margin-top: 0;
body > h5:first-child, padding-top: 0;
body > h6:first-child { }
margin-top: 0;
padding-top: 0;
}
a:first-child h1, body > h3:first-child,
a:first-child h2, body > h4:first-child,
a:first-child h3, body > h5:first-child,
a:first-child h4, body > h6:first-child {
a:first-child h5, margin-top: 0;
a:first-child h6 { padding-top: 0;
margin-top: 0; }
padding-top: 0;
}
h1 p, a:first-child h1,
h2 p, a:first-child h2,
h3 p, a:first-child h3,
h4 p, a:first-child h4,
h5 p, a:first-child h5,
h6 p { a:first-child h6 {
margin-top: 0; margin-top: 0;
} padding-top: 0;
}
li p.first { h1 p,
display: inline-block; h2 p,
} h3 p,
h4 p,
h5 p,
h6 p {
margin-top: 0;
}
ul, li p.first {
ol { display: inline-block;
padding-left: 30px; }
}
ul:first-child, ul,
ol:first-child { ol {
margin-top: 0; padding-left: 30px;
} }
ul:last-child, ul:first-child,
ol:last-child { ol:first-child {
margin-bottom: 0; margin-top: 0;
} }
blockquote { ul:last-child,
border-left: 4px solid #42b983; ol:last-child {
padding: 10px 15px; margin-bottom: 0;
color: #777; }
background-color: rgba(66, 185, 131, .1);
}
table { blockquote {
padding: 0; border-left: 4px solid #42b983;
word-break: initial; padding: 10px 15px;
} color: #777;
background-color: rgba(66, 185, 131, 0.1);
}
table tr { table {
border-top: 1px solid #dfe2e5; padding: 0;
margin: 0; word-break: initial;
padding: 0; }
}
table tr:nth-child(2n), table tr {
thead { border-top: 1px solid #dfe2e5;
background-color: #fafafa; margin: 0;
} padding: 0;
}
table tr th { table tr:nth-child(2n),
font-weight: bold; thead {
border: 1px solid #dfe2e5; background-color: #fafafa;
border-bottom: 0; }
text-align: left;
margin: 0;
padding: 6px 13px;
}
table tr td { table tr th {
border: 1px solid #dfe2e5; font-weight: bold;
text-align: left; border: 1px solid #dfe2e5;
margin: 0; border-bottom: 0;
padding: 6px 13px; text-align: left;
} margin: 0;
padding: 6px 13px;
}
table tr th:first-child, table tr td {
table tr td:first-child { border: 1px solid #dfe2e5;
margin-top: 0; text-align: left;
} margin: 0;
padding: 6px 13px;
}
table tr th:last-child, table tr th:first-child,
table tr td:last-child { table tr td:first-child {
margin-bottom: 0; margin-top: 0;
} }
table tr th:last-child,
table tr td:last-child {
margin-bottom: 0;
}
} }

View File

@@ -55,7 +55,7 @@
//filter: invert(100%); //filter: invert(100%);
} }
.more-menus span.title{ .more-menus span.title{
color:#000; color: var(--text-theme-color);
} }
// //
@@ -89,4 +89,7 @@
// //
--quote-bg-color: #1F243F; --quote-bg-color: #1F243F;
--quote-text-color: #fff; --quote-text-color: #fff;
// el-dialog
--el-box-shadow: 0 0 15px rgba(107, 80, 225, 0.8);
} }

View File

@@ -1,12 +1,19 @@
<template> <template>
<div class="theme-box" @click="toggleTheme"> <div class="theme-box" @click="toggleTheme" :class="size">
<i class="iconfont" :class="themePage === 'light'?'icon-yueliang':'icon-taiyang'"></i> <i class="iconfont" :class="themePage === 'light' ? 'icon-yueliang' : 'icon-taiyang'"></i>
</div> </div>
</template> </template>
<script setup> <script setup>
import {ref} from "vue"; import { ref } from "vue";
import {useSharedStore} from "@/store/sharedata"; import { useSharedStore } from "@/store/sharedata";
const props = defineProps({
size: {
type: String,
default: "",
},
});
// 定义主题状态,初始值从 localStorage 获取 // 定义主题状态,初始值从 localStorage 获取
const store = useSharedStore(); const store = useSharedStore();
@@ -20,7 +27,6 @@ const toggleTheme = () => {
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
@import '@/assets/iconfont/iconfont.css'
.theme-box{ .theme-box{
z-index :111 z-index :111
position: fixed; position: fixed;
@@ -49,4 +55,17 @@ const toggleTheme = () => {
transition: transform 0.3s ease; transition: transform 0.3s ease;
} }
} }
.theme-box.small {
position: relative !important;
right: initial;
bottom: initial;
width: 20px;
height: 20px;
line-height: 18px;
.iconfont {
font-size: 15px !important;
}
}
</style> </style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-dialog class="config-dialog" v-model="showDialog" :close-on-click-modal="true" :before-close="close" style="max-width: 400px" title="账户信息"> <el-dialog class="config-dialog" v-model="showDialog" :close-on-click-modal="true" :before-close="close" style="max-width: 400px" title="账户信息">
<div class="flex-center-col p-4 pt-0" id="user-info"> <div class="flex-center-col pl-4 pr-4" id="user-info">
<user-profile @hide="close" /> <user-profile @hide="close" />
</div> </div>
</el-dialog> </el-dialog>

View File

@@ -3,7 +3,7 @@
<el-container> <el-container>
<el-aside v-show="store.chatListExtend"> <el-aside v-show="store.chatListExtend">
<div class="flex w-full justify-center pt-3 pb-3"> <div class="flex w-full justify-center pt-3 pb-3">
<img :src="logo" style="max-height: 40px" :alt="title" v-if="logo !== ''"/> <img :src="logo" style="max-height: 40px" :alt="title" v-if="logo !== ''" />
<h2 v-else>{{ title }}</h2> <h2 v-else>{{ title }}</h2>
</div> </div>
@@ -194,7 +194,7 @@
</el-container> </el-container>
<el-dialog v-model="showNotice" :show-close="true" class="notice-dialog" title="网站公告"> <el-dialog v-model="showNotice" :show-close="true" class="notice-dialog" title="网站公告">
<div class="notice p-4"> <div class="notice">
<div v-html="notice"></div> <div v-html="notice"></div>
</div> </div>
@@ -232,24 +232,24 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import {nextTick, onMounted, onUnmounted, ref, watch} from "vue"; import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
import ChatPrompt from "@/components/ChatPrompt.vue"; import ChatPrompt from "@/components/ChatPrompt.vue";
import ChatReply from "@/components/ChatReply.vue"; import ChatReply from "@/components/ChatReply.vue";
import {Delete, Edit, InfoFilled, More, 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 "highlight.js/styles/a11y-dark.css";
import {isMobile, randString, removeArrayItem, UUID} from "@/utils/libs"; import { isMobile, randString, removeArrayItem, UUID } from "@/utils/libs";
import {ElMessage, ElMessageBox} from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import {httpGet, httpPost} from "@/utils/http"; import { httpGet, httpPost } from "@/utils/http";
import {useRouter} from "vue-router"; import { useRouter } from "vue-router";
import Clipboard from "clipboard"; import Clipboard from "clipboard";
import {checkSession, getClientId, getSystemInfo} from "@/store/cache"; import { checkSession, getClientId, getSystemInfo } from "@/store/cache";
import Welcome from "@/components/Welcome.vue"; import Welcome from "@/components/Welcome.vue";
import {useSharedStore} from "@/store/sharedata"; import { useSharedStore } from "@/store/sharedata";
import FileSelect from "@/components/FileSelect.vue"; import FileSelect from "@/components/FileSelect.vue";
import FileList from "@/components/FileList.vue"; import FileList from "@/components/FileList.vue";
import ChatSetting from "@/components/ChatSetting.vue"; import ChatSetting from "@/components/ChatSetting.vue";
import BackTop from "@/components/BackTop.vue"; import BackTop from "@/components/BackTop.vue";
import {closeLoading, showLoading, showMessageError} from "@/utils/dialog"; import { closeLoading, showLoading, showMessageError } from "@/utils/dialog";
import MarkdownIt from "markdown-it"; import MarkdownIt from "markdown-it";
import emoji from "markdown-it-emoji"; import emoji from "markdown-it-emoji";
@@ -977,6 +977,7 @@ const realtimeChat = () => {
</style> </style>
<style lang="stylus"> <style lang="stylus">
@import '@/assets/css/markdown/vue.css';
.notice-dialog { .notice-dialog {
.el-dialog__header { .el-dialog__header {
padding-bottom 0 padding-bottom 0
@@ -985,6 +986,10 @@ const realtimeChat = () => {
.el-dialog__body { .el-dialog__body {
padding 0 20px padding 0 20px
h2 {
margin: 20px 0 15px 0;
}
ol, ul { ol, ul {
padding-left 10px padding-left 10px
} }

View File

@@ -320,6 +320,7 @@ onMounted(() => {
models.value = res.data; models.value = res.data;
selectedModel.value = models.value[0]; selectedModel.value = models.value[0];
params.value.model_id = selectedModel.value.id; params.value.model_id = selectedModel.value.id;
changeModel(selectedModel.value);
}) })
.catch((e) => { .catch((e) => {
showMessageError("获取模型列表失败:" + e.message); showMessageError("获取模型列表失败:" + e.message);

View File

@@ -39,25 +39,25 @@
<el-popover v-if="moreNavs.length > 0" placement="right-end" trigger="hover"> <el-popover v-if="moreNavs.length > 0" placement="right-end" trigger="hover">
<template #reference> <template #reference>
<li class="menu-list-item flex-center-col"> <li class="menu-list-item flex-center-col">
<i class="iconfont icon-more"/> <i class="iconfont icon-more" />
</li> </li>
</template> </template>
<template #default> <template #default>
<ul class="more-menus"> <ul class="more-menus">
<li <li
v-for="(item, index) in moreNavs" v-for="(item, index) in moreNavs"
:key="item.url" :key="item.url"
:class="{ :class="{
active: item.url === curPath, active: item.url === curPath,
moreTitle: index !== 3 && index !== 4, moreTitle: index !== 3 && index !== 4,
twoTittle: index === 3 || index === 4, twoTittle: index === 3 || index === 4,
}" }"
> >
<a @click="changeNav(item)"> <a @click="changeNav(item)">
<span v-if="item.icon.startsWith('icon')" class="mr-2"> <span v-if="item.icon.startsWith('icon')" class="mr-2">
<i class="iconfont" :class="item.icon"></i> <i class="iconfont" :class="item.icon"></i>
</span> </span>
<el-image :src="item.icon" style="width: 20px; height: 20px" v-else/> <el-image :src="item.icon" style="width: 20px; height: 20px" v-else />
<span :class="item.url === curPath ? 'title active' : 'title'">{{ item.name }}</span> <span :class="item.url === curPath ? 'title active' : 'title'">{{ item.name }}</span>
</a> </a>
</li> </li>
@@ -67,7 +67,7 @@
<el-popover placement="right-end" trigger="hover" v-if="loginUser.id"> <el-popover placement="right-end" trigger="hover" v-if="loginUser.id">
<template #reference> <template #reference>
<li class="menu-list-item flex-center-col"> <li class="menu-list-item flex-center-col">
<i class="iconfont icon-config"/> <i class="iconfont icon-config" />
</li> </li>
</template> </template>
<template #default> <template #default>
@@ -75,7 +75,7 @@
<li> <li>
<div @click="showConfigDialog = true" class="flex"> <div @click="showConfigDialog = true" class="flex">
<el-icon> <el-icon>
<UserFilled/> <UserFilled />
</el-icon> </el-icon>
<span class="username title">{{ loginUser.nickname }}</span> <span class="username title">{{ loginUser.nickname }}</span>
</div> </div>
@@ -100,7 +100,7 @@
<i class="iconfont icon-house"></i> <i class="iconfont icon-house"></i>
</a> </a>
<div class="pl-1"> <div class="pl-1">
<ThemeChange/> <ThemeChange size="small" />
</div> </div>
</div> </div>
</div> </div>
@@ -133,17 +133,17 @@
</template> </template>
<script setup> <script setup>
import {UserFilled} from "@element-plus/icons-vue"; import { UserFilled } from "@element-plus/icons-vue";
import ThemeChange from "@/components/ThemeChange.vue"; import ThemeChange from "@/components/ThemeChange.vue";
import {useRouter} from "vue-router"; import { useRouter } from "vue-router";
import {computed, onMounted, ref, watch} from "vue"; import { computed, onMounted, ref, watch } from "vue";
import {httpGet} from "@/utils/http"; import { httpGet } from "@/utils/http";
import {ElMessage} from "element-plus"; import { ElMessage } from "element-plus";
import {checkSession, getLicenseInfo, getSystemInfo} from "@/store/cache"; import { checkSession, getLicenseInfo, getSystemInfo } from "@/store/cache";
import {removeUserToken} from "@/store/session"; import { removeUserToken } from "@/store/session";
import {useSharedStore} from "@/store/sharedata"; import { useSharedStore } from "@/store/sharedata";
import ConfigDialog from "@/components/UserInfoDialog.vue"; import ConfigDialog from "@/components/UserInfoDialog.vue";
import {showMessageError} from "@/utils/dialog"; import { showMessageError } from "@/utils/dialog";
import LoginDialog from "@/components/LoginDialog.vue"; import LoginDialog from "@/components/LoginDialog.vue";
const router = useRouter(); const router = useRouter();
@@ -188,7 +188,7 @@ const getFirstPathSegment = (url) => {
const stars = computed(() => { const stars = computed(() => {
return 1000; return 1000;
}) });
watch( watch(
() => store.showLoginDialog, () => store.showLoginDialog,