Compare commits
No commits in common. "0d3d30952db163a91fabaaced4f667bff281ed9f" and "f6555e5726f193f3b8ac0e1adc128abf8502a0fb" have entirely different histories.
0d3d30952d
...
f6555e5726
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="main-layout">
|
<div class="main-layout">
|
||||||
<Sidebar class="sidebar" />
|
<Sidebar />
|
||||||
<main class="content-area">
|
<main class="content-area">
|
||||||
<!-- 路由视图将渲染在这里 -->
|
<!-- 路由视图将渲染在这里 -->
|
||||||
<router-view />
|
<router-view />
|
||||||
|
|
@ -16,7 +16,7 @@ import Sidebar from '../components/Sidebar.vue'
|
||||||
.main-layout {
|
.main-layout {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
/* min-width: 640px; */
|
min-width: 640px;
|
||||||
overflow: hidden; /* 防止内部滚动影响布局 */
|
overflow: hidden; /* 防止内部滚动影响布局 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,21 +28,6 @@ import Sidebar from '../components/Sidebar.vue'
|
||||||
background-color: #ffffff; /* 示例背景色 */
|
background-color: #ffffff; /* 示例背景色 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 移动端样式 */
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
.sidebar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-area {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 简单的侧边栏列表样式 */
|
/* 简单的侧边栏列表样式 */
|
||||||
.sidebar ul {
|
.sidebar ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,6 @@ export const useSettingsStore = defineStore('settings', {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
persist: {
|
|
||||||
key: 'settings',
|
|
||||||
paths: ['sidebarCollapsed']
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
// 切换侧边栏状态
|
// 切换侧边栏状态
|
||||||
toggleSidebar() {
|
toggleSidebar() {
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,6 @@
|
||||||
<div class="chat-header">
|
<div class="chat-header">
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<el-button
|
|
||||||
class="mobile-sidebar-toggle"
|
|
||||||
:icon="Expand"
|
|
||||||
@click="settingsStore.toggleSidebar"
|
|
||||||
text
|
|
||||||
v-if="isMobile"
|
|
||||||
/>
|
|
||||||
<span class="title-text">{{ title }}</span>
|
<span class="title-text">{{ title }}</span>
|
||||||
<el-tag v-if="chatStore.currentConversation?.conversationStatus === 'typing'"
|
<el-tag v-if="chatStore.currentConversation?.conversationStatus === 'typing'"
|
||||||
size="small"
|
size="small"
|
||||||
|
|
@ -56,10 +49,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useChatStore } from '@/store/chat'
|
import { useChatStore } from '@/store/chat'
|
||||||
import { useSettingsStore } from '@/store/settings'
|
import { useSettingsStore } from '@/store/settings'
|
||||||
import { Delete, Setting, User, Expand } from '@element-plus/icons-vue'
|
import { Delete, Setting, User } from '@element-plus/icons-vue'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
import HistoryButton from '@/components/chat/HistoryButton.vue'
|
import HistoryButton from '@/components/chat/HistoryButton.vue'
|
||||||
import CustomerBackground from '@/components/chat/CustomerBackground.vue'
|
import CustomerBackground from '@/components/chat/CustomerBackground.vue'
|
||||||
|
|
@ -68,7 +61,6 @@ const chatStore = useChatStore()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
const showUserInfo = ref(false)
|
const showUserInfo = ref(false)
|
||||||
const customerBackgroundRef = ref(null)
|
const customerBackgroundRef = ref(null)
|
||||||
const isMobile = ref(false)
|
|
||||||
|
|
||||||
const title = computed(() => {
|
const title = computed(() => {
|
||||||
const conversation = chatStore.currentConversation
|
const conversation = chatStore.currentConversation
|
||||||
|
|
@ -109,19 +101,6 @@ const handleSettings = () => {
|
||||||
// TODO: 实现设置功能
|
// TODO: 实现设置功能
|
||||||
console.log('打开设置')
|
console.log('打开设置')
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkMobile = () => {
|
|
||||||
isMobile.value = window.innerWidth <= 768
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
checkMobile()
|
|
||||||
window.addEventListener('resize', checkMobile)
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener('resize', checkMobile)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -142,38 +121,7 @@ onUnmounted(() => {
|
||||||
.title {
|
.title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 12px;
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.mobile-sidebar-toggle {
|
|
||||||
height: 24px;
|
|
||||||
width: 24px;
|
|
||||||
padding: 0;
|
|
||||||
color: #666;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border: none;
|
|
||||||
background: transparent !important;
|
|
||||||
font-size: 14px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-left: -4px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #07c160;
|
|
||||||
background: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-icon) {
|
|
||||||
font-size: 18px;
|
|
||||||
margin-top: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-text {
|
.title-text {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
@ -183,8 +131,6 @@ onUnmounted(() => {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 24px;
|
|
||||||
padding-top: 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-tag {
|
.status-tag {
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,41 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="mode-selector" :class="{ 'collapsed': settingsStore.sidebarCollapsed }">
|
||||||
<div
|
<div class="mode-header">
|
||||||
class="mode-selector-backdrop"
|
<h3 class="mode-title">对话场景</h3>
|
||||||
:class="{ visible: !settingsStore.sidebarCollapsed }"
|
<div class="header-actions">
|
||||||
@click="settingsStore.toggleSidebar"
|
<HistoryButton v-if="!settingsStore.sidebarCollapsed" :icon-only="true" />
|
||||||
v-if="isMobile"
|
<el-button
|
||||||
></div>
|
class="collapse-btn"
|
||||||
<div class="mode-selector" :class="{ 'collapsed': settingsStore.sidebarCollapsed }">
|
:icon="settingsStore.sidebarCollapsed ? Expand : Fold"
|
||||||
<div class="mode-header">
|
text
|
||||||
<h3 class="mode-title">对话场景</h3>
|
bg
|
||||||
<div class="header-actions">
|
@click="settingsStore.toggleSidebar"
|
||||||
<HistoryButton v-if="!settingsStore.sidebarCollapsed" :icon-only="true" />
|
/>
|
||||||
<el-button
|
|
||||||
class="collapse-btn"
|
|
||||||
:icon="settingsStore.sidebarCollapsed ? Expand : Fold"
|
|
||||||
text
|
|
||||||
bg
|
|
||||||
@click="settingsStore.toggleSidebar"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mode-list">
|
</div>
|
||||||
<div
|
<div class="mode-list">
|
||||||
v-for="mode in chatModes"
|
<div
|
||||||
:key="mode.id"
|
v-for="mode in chatModes"
|
||||||
:class="['mode-item', { active: chatStore.currentMode === mode.id }]"
|
:key="mode.id"
|
||||||
@click="selectMode(mode.id)"
|
:class="['mode-item', { active: chatStore.currentMode === mode.id }]"
|
||||||
>
|
@click="selectMode(mode.id)"
|
||||||
<span class="emoji-icon">{{ mode.icon }}</span>
|
>
|
||||||
<span v-if="!settingsStore.sidebarCollapsed" class="mode-name">{{ mode.name }}</span>
|
<span class="emoji-icon">{{ mode.icon }}</span>
|
||||||
<ModeSetting v-if="!settingsStore.sidebarCollapsed" @command="(cmd) => handleModeSettings(cmd, mode.id)">
|
<span v-if="!settingsStore.sidebarCollapsed" class="mode-name">{{ mode.name }}</span>
|
||||||
<el-dropdown-item command="edit">
|
<ModeSetting v-if="!settingsStore.sidebarCollapsed" @command="(cmd) => handleModeSettings(cmd, mode.id)">
|
||||||
<el-icon><EditPen /></el-icon>
|
<el-dropdown-item command="edit">
|
||||||
编辑设置
|
<el-icon><EditPen /></el-icon>
|
||||||
</el-dropdown-item>
|
编辑设置
|
||||||
<el-dropdown-item command="reset">
|
</el-dropdown-item>
|
||||||
<el-icon><RefreshRight /></el-icon>
|
<el-dropdown-item command="reset">
|
||||||
重置设置
|
<el-icon><RefreshRight /></el-icon>
|
||||||
</el-dropdown-item>
|
重置设置
|
||||||
<el-dropdown-item command="delete" divided>
|
</el-dropdown-item>
|
||||||
<el-icon><Delete /></el-icon>
|
<el-dropdown-item command="delete" divided>
|
||||||
删除场景
|
<el-icon><Delete /></el-icon>
|
||||||
</el-dropdown-item>
|
删除场景
|
||||||
</ModeSetting>
|
</el-dropdown-item>
|
||||||
</div>
|
</ModeSetting>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -52,7 +44,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useChatStore } from '@/store/chat'
|
import { useChatStore } from '@/store/chat'
|
||||||
import { useSettingsStore } from '@/store/settings'
|
import { useSettingsStore } from '@/store/settings'
|
||||||
import { computed, ref, onMounted, onUnmounted } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { Delete, EditPen, RefreshRight, Expand, Fold } from '@element-plus/icons-vue'
|
import { Delete, EditPen, RefreshRight, Expand, Fold } from '@element-plus/icons-vue'
|
||||||
import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElButton, ElMessageBox } from 'element-plus'
|
import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElButton, ElMessageBox } from 'element-plus'
|
||||||
import ModeSetting from '@/components/chat/ModeSetting.vue'
|
import ModeSetting from '@/components/chat/ModeSetting.vue'
|
||||||
|
|
@ -125,21 +117,6 @@ const handleModeSettings = (command, modeId) => {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMobile = ref(false)
|
|
||||||
|
|
||||||
const checkMobile = () => {
|
|
||||||
isMobile.value = window.innerWidth <= 768
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
checkMobile()
|
|
||||||
window.addEventListener('resize', checkMobile)
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener('resize', checkMobile)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -162,8 +139,6 @@ $hover-color-dark: #2d2d2d;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
position: relative;
|
|
||||||
z-index: 1000;
|
|
||||||
|
|
||||||
&.collapsed {
|
&.collapsed {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
|
|
@ -374,44 +349,6 @@ $hover-color-dark: #2d2d2d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 移动端样式 */
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
.mode-selector {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
z-index: 1000;
|
|
||||||
|
|
||||||
&.collapsed {
|
|
||||||
transform: translateX(-240px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.collapsed) {
|
|
||||||
transform: translateX(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode-selector-backdrop {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 999;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&.visible {
|
|
||||||
opacity: 1;
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @media (prefers-color-scheme: dark) {
|
// @media (prefers-color-scheme: dark) {
|
||||||
// .mode-selector {
|
// .mode-selector {
|
||||||
// background: $background-color-dark;
|
// background: $background-color-dark;
|
||||||
|
|
|
||||||
|
|
@ -55,20 +55,4 @@ const handleModeChange = (mode) => {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 移动端样式 */
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
.chat-container {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue