优化移动端体验

This commit is contained in:
Wenjie Zhang 2025-02-27 01:37:42 +08:00
parent d5f1e0dd31
commit 2de7b13e87
4 changed files with 49 additions and 18 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="chat" ref="chatContainer"> <div class="chat" ref="chatContainer">
<div class="header"> <div class="chat-header">
<div class="header__left"> <div class="header__left">
<div <div
v-if="!state.isSidebarOpen" v-if="!state.isSidebarOpen"
@ -593,7 +593,7 @@ watch(
flex: 5 5 200px; flex: 5 5 200px;
overflow-y: scroll; overflow-y: scroll;
.header { .chat-header {
user-select: none; user-select: none;
position: sticky; position: sticky;
top: 0; top: 0;
@ -1008,14 +1008,14 @@ watch(
height: calc(100vh - 60px); height: calc(100vh - 60px);
} }
.chat-container .chat .header { .chat-container .chat .chat-header {
background: var(--main-light-4); background: var(--main-light-4);
.header__left, .header__right { .header__left, .header__right {
gap: 20px; gap: 24px;
} }
.nav-btn { .nav-btn {
font-size: 1.5rem; font-size: 1.3rem;
padding: 0; padding: 0;
&:hover { &:hover {

View File

@ -337,8 +337,12 @@ div.header, #app-router-view {
div.header { div.header {
display: none; display: none;
} }
}
.debug-panel {
bottom: 10rem;
}
}
.app-layout div.header-mobile { .app-layout div.header-mobile {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -348,6 +352,7 @@ div.header, #app-router-view {
align-items: center; align-items: center;
flex: 0 0 60px; flex: 0 0 60px;
border-right: none; border-right: none;
height: 40px;
.nav-item { .nav-item {
text-decoration: none; text-decoration: none;

View File

@ -256,10 +256,11 @@ onMounted(() => {
} }
@media (max-width: 520px) { @media (max-width: 520px) {
.conversation { .conversations {
position: absolute; position: absolute;
z-index: 101; z-index: 101;
width: 300px; width: 300px;
height: 100%;
border-radius: 0 16px 16px 0; border-radius: 0 16px 16px 0;
box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.05); box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.05);
} }

View File

@ -14,15 +14,15 @@
</template> </template>
</HeaderComponent> </HeaderComponent>
<div class="setting-container layout-container"> <div class="setting-container layout-container">
<div class="sider"> <div class="sider" v-if="state.windowWidth > 520">
<a-button type="text" :class="{ activesec: state.section === 'base'}" @click="state.section='base'" :icon="h(SettingOutlined)"> 基本设置 </a-button> <a-button type="text" :class="{ activesec: state.section === 'base'}" @click="state.section='base'" :icon="h(SettingOutlined)"> 基本设置 </a-button>
<a-button type="text" :class="{ activesec: state.section === 'model'}" @click="state.section='model'" :icon="h(CodeOutlined)"> 模型配置 </a-button> <a-button type="text" :class="{ activesec: state.section === 'model'}" @click="state.section='model'" :icon="h(CodeOutlined)"> 模型配置 </a-button>
<a-button type="text" :class="{ activesec: state.section === 'path'}" @click="state.section='path'" :icon="h(FolderOutlined)"> 路径配置 </a-button> <a-button type="text" :class="{ activesec: state.section === 'path'}" @click="state.section='path'" :icon="h(FolderOutlined)"> 路径配置 </a-button>
</div> </div>
<div class="setting" v-if="state.section === 'base'"> <div class="setting" v-if="state.windowWidth <= 520 || state.section === 'base'">
<h3>基础模型配置</h3> <h3>基础模型配置</h3>
<div class="section"> <div class="section">
<div class="card"> <div class="card card-select">
<span class="label">{{ items?.embed_model.des }}</span> <span class="label">{{ items?.embed_model.des }}</span>
<a-select style="width: 300px" <a-select style="width: 300px"
:value="configStore.config?.embed_model" :value="configStore.config?.embed_model"
@ -34,7 +34,7 @@
</a-select-option> </a-select-option>
</a-select> </a-select>
</div> </div>
<div class="card"> <div class="card card-select">
<span class="label">{{ items?.reranker.des }}</span> <span class="label">{{ items?.reranker.des }}</span>
<a-select style="width: 300px" <a-select style="width: 300px"
:value="configStore.config?.reranker" :value="configStore.config?.reranker"
@ -81,7 +81,7 @@
</div> </div>
<h3>检索配置</h3> <h3>检索配置</h3>
<div class="section"> <div class="section">
<div class="card"> <div class="card card-select">
<span class="label">{{ items?.use_rewrite_query.des }}</span> <span class="label">{{ items?.use_rewrite_query.des }}</span>
<a-select style="width: 200px" <a-select style="width: 200px"
:value="configStore.config?.use_rewrite_query" :value="configStore.config?.use_rewrite_query"
@ -95,7 +95,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="setting" v-if="state.section === 'model'"> <div class="setting" v-if="state.windowWidth <= 520 || state.section === 'model'">
<h3>模型配置</h3> <h3>模型配置</h3>
<p>请在 <code>src/.env</code> 文件中配置对应的 APIKEY</p> <p>请在 <code>src/.env</code> 文件中配置对应的 APIKEY</p>
<div class="model-provider-card"> <div class="model-provider-card">
@ -184,7 +184,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="setting" v-if="state.section ==='path'"> <div class="setting" v-if="state.windowWidth <= 520 || state.section ==='path'">
<h3>本地模型配置</h3> <h3>本地模型配置</h3>
<p>如果是 Docker 启动务必确保在环境变量中设置了 MODEL_DIR或者设置了 volumes 映射</p> <p>如果是 Docker 启动务必确保在环境变量中设置了 MODEL_DIR或者设置了 volumes 映射</p>
<TableConfigComponent <TableConfigComponent
@ -198,7 +198,7 @@
<script setup> <script setup>
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { computed, reactive, ref, h, watch } from 'vue' import { computed, reactive, ref, h, watch, onMounted, onUnmounted } from 'vue'
import { useConfigStore } from '@/stores/config'; import { useConfigStore } from '@/stores/config';
import { import {
ReloadOutlined, ReloadOutlined,
@ -231,16 +231,17 @@ const customModel = reactive({
}) })
const state = reactive({ const state = reactive({
loading: false, loading: false,
section: 'base' section: 'base',
windowWidth: window?.innerWidth || 0
}) })
// modelStatus key // modelStatus key
const modelKeys = computed(() => { const modelKeys = computed(() => {
return Object.keys(modelStatus.value).filter(key => modelStatus.value[key]) return Object.keys(modelStatus.value || {}).filter(key => modelStatus.value?.[key])
}) })
const notModelKeys = computed(() => { const notModelKeys = computed(() => {
return Object.keys(modelStatus.value).filter(key => !modelStatus.value[key]) return Object.keys(modelStatus.value || {}).filter(key => !modelStatus.value?.[key])
}) })
const generateRandomHash = (length) => { const generateRandomHash = (length) => {
@ -360,6 +361,19 @@ const handleCancelCustomModel = () => {
customModel.visible = false customModel.visible = false
} }
const updateWindowWidth = () => {
state.windowWidth = window?.innerWidth || 0
}
onMounted(() => {
updateWindowWidth()
window.addEventListener('resize', updateWindowWidth)
})
onUnmounted(() => {
window.removeEventListener('resize', updateWindowWidth)
})
const sendRestart = () => { const sendRestart = () => {
console.log('Restarting...') console.log('Restarting...')
message.loading({ content: '重新加载模型中', key: "restart", duration: 0 }); message.loading({ content: '重新加载模型中', key: "restart", duration: 0 });
@ -618,7 +632,18 @@ const sendRestart = () => {
} }
} }
}
@media (max-width: 520px) {
.setting-container {
flex-direction: column;
}
.card.card-select {
gap: 0.75rem;
align-items: flex-start;
flex-direction: column;
}
} }
</style> </style>