|
@@ -1,14 +1,12 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, nextTick, onMounted } from 'vue'
|
|
|
+import { ref, nextTick, onMounted, reactive } from 'vue'
|
|
|
import { Local } from '/@/utils/storage'
|
|
|
import { User, ChatDotRound, Delete, Edit, Check, Close } from '@element-plus/icons-vue'
|
|
|
import { MarkdownPlugin } from '/@/components/markdown/type/markdown'
|
|
|
import EChartsPlugin from '/@/components/markdown/plugins/markdown-it-echarts'
|
|
|
import Markdown from '/@/components/markdown/Markdown.vue'
|
|
|
|
|
|
-const plugins: Array<MarkdownPlugin<any>> = [
|
|
|
- EChartsPlugin()
|
|
|
-]
|
|
|
+const plugins: Array<MarkdownPlugin<any>> = [EChartsPlugin()]
|
|
|
|
|
|
const getUserInfos = ref<{
|
|
|
avatar: string
|
|
@@ -24,12 +22,10 @@ interface Message {
|
|
|
}
|
|
|
|
|
|
// 会话列表
|
|
|
-const conversations = ref<{id: number,title: string,active: boolean}[]>([])
|
|
|
+const conversations = ref<{ id: number; title: string; active: boolean }[]>([])
|
|
|
|
|
|
for (let i = 0; i < 100; i++) {
|
|
|
- conversations.value.push(
|
|
|
- { id: i, title: `Summary ${i}`, active: false }
|
|
|
- )
|
|
|
+ conversations.value.push({ id: i, title: `Summary ${i}`, active: false })
|
|
|
}
|
|
|
|
|
|
// 编辑状态管理
|
|
@@ -51,17 +47,17 @@ const toolOptions = ref([
|
|
|
children: [
|
|
|
{
|
|
|
value: 'codebase-retrieval',
|
|
|
- label: '代码库检索'
|
|
|
+ label: '代码库检索',
|
|
|
},
|
|
|
{
|
|
|
value: 'str-replace-editor',
|
|
|
- label: '代码编辑器'
|
|
|
+ label: '代码编辑器',
|
|
|
},
|
|
|
{
|
|
|
value: 'save-file',
|
|
|
- label: '文件保存'
|
|
|
- }
|
|
|
- ]
|
|
|
+ label: '文件保存',
|
|
|
+ },
|
|
|
+ ],
|
|
|
},
|
|
|
{
|
|
|
value: 'web',
|
|
@@ -69,13 +65,13 @@ const toolOptions = ref([
|
|
|
children: [
|
|
|
{
|
|
|
value: 'web-search',
|
|
|
- label: '网络搜索'
|
|
|
+ label: '网络搜索',
|
|
|
},
|
|
|
{
|
|
|
value: 'web-fetch',
|
|
|
- label: '网页获取'
|
|
|
- }
|
|
|
- ]
|
|
|
+ label: '网页获取',
|
|
|
+ },
|
|
|
+ ],
|
|
|
},
|
|
|
{
|
|
|
value: 'system',
|
|
@@ -83,14 +79,14 @@ const toolOptions = ref([
|
|
|
children: [
|
|
|
{
|
|
|
value: 'execute-command',
|
|
|
- label: '命令执行'
|
|
|
+ label: '命令执行',
|
|
|
},
|
|
|
{
|
|
|
value: 'launch-process',
|
|
|
- label: '进程启动'
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
+ label: '进程启动',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
])
|
|
|
|
|
|
// 模型选择数据
|
|
@@ -98,7 +94,7 @@ const modelOptions = ref([
|
|
|
{ label: 'Claude Sonnet 4', value: 'claude-sonnet-4' },
|
|
|
{ label: 'GPT-4', value: 'gpt-4' },
|
|
|
{ label: 'GPT-3.5 Turbo', value: 'gpt-3.5-turbo' },
|
|
|
- { label: 'Gemini Pro', value: 'gemini-pro' }
|
|
|
+ { label: 'Gemini Pro', value: 'gemini-pro' },
|
|
|
])
|
|
|
|
|
|
// 选中的工具和模型
|
|
@@ -120,21 +116,30 @@ const sendMessage = () => {
|
|
|
id: Date.now(),
|
|
|
type: 'user',
|
|
|
content: inputMessage.value,
|
|
|
- timestamp: new Date()
|
|
|
+ timestamp: new Date(),
|
|
|
})
|
|
|
|
|
|
+ //清空用户聊天框
|
|
|
const userMessage = inputMessage.value
|
|
|
inputMessage.value = ''
|
|
|
|
|
|
// 滚动到底部
|
|
|
scrollToBottom()
|
|
|
|
|
|
- // 模拟AI回复
|
|
|
- setTimeout(() => {
|
|
|
- messages.value.push({
|
|
|
- id: Date.now() + 1,
|
|
|
- type: 'ai',
|
|
|
- content: `我收到了您的消息:"${userMessage}"。这是一个示例回复,包含markdown格式的内容。
|
|
|
+ const ai = reactive<Message>({
|
|
|
+ id: Date.now()+1,
|
|
|
+ type: 'ai',
|
|
|
+ content: '',
|
|
|
+ timestamp: new Date()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 添加一个回复
|
|
|
+ messages.value.push(ai)
|
|
|
+
|
|
|
+ const delay = async (ms: number) => new Promise<void>(resolve => setTimeout(resolve, ms))
|
|
|
+
|
|
|
+ const action = async () => {
|
|
|
+ const message = `我收到了您的消息:"${userMessage}"。这是一个示例回复,包含markdown格式的内容。
|
|
|
|
|
|
## 回复内容
|
|
|
|
|
@@ -144,12 +149,27 @@ const sendMessage = () => {
|
|
|
|
|
|
\`\`\`javascript
|
|
|
console.log('这是代码示例');
|
|
|
-\`\`\``,
|
|
|
- timestamp: new Date()
|
|
|
- })
|
|
|
+\`\`\``
|
|
|
+ for (let i = 0; i < message.length; i++) {
|
|
|
+ ai.content += message[i]
|
|
|
+ await delay(50)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ action().finally(()=> {
|
|
|
isConversationActive.value = false
|
|
|
scrollToBottom()
|
|
|
- }, 1000)
|
|
|
+ })
|
|
|
+
|
|
|
+ // setTimeout(() => {
|
|
|
+ // messages.value.push({
|
|
|
+ // id: Date.now() + 1,
|
|
|
+ // type: 'ai',
|
|
|
+ // content: ,
|
|
|
+ // timestamp: new Date(),
|
|
|
+ // })
|
|
|
+ // isConversationActive.value = false
|
|
|
+ // scrollToBottom()
|
|
|
+ // }, 1000)
|
|
|
}
|
|
|
|
|
|
// 终止对话
|
|
@@ -168,7 +188,7 @@ const scrollToBottom = () => {
|
|
|
}
|
|
|
// 选择会话
|
|
|
const selectConversation = (id: number) => {
|
|
|
- conversations.value.forEach(conv => {
|
|
|
+ conversations.value.forEach((conv) => {
|
|
|
conv.active = conv.id === id
|
|
|
})
|
|
|
}
|
|
@@ -181,7 +201,7 @@ const deleteConversation = (id: number) => {
|
|
|
|
|
|
// 编辑摘要
|
|
|
const editSummary = (id: number) => {
|
|
|
- const conversation = conversations.value.find(conv => conv.id === id)
|
|
|
+ const conversation = conversations.value.find((conv) => conv.id === id)
|
|
|
if (conversation) {
|
|
|
// 设置当前编辑的会话ID
|
|
|
editingConversationId.value = id
|
|
@@ -199,7 +219,7 @@ const editSummary = (id: number) => {
|
|
|
|
|
|
// 确认编辑
|
|
|
const confirmEdit = (id: number) => {
|
|
|
- const conversation = conversations.value.find(conv => conv.id === id)
|
|
|
+ const conversation = conversations.value.find((conv) => conv.id === id)
|
|
|
if (conversation && editingTitle.value.trim()) {
|
|
|
conversation.title = editingTitle.value.trim()
|
|
|
// 清除编辑状态
|
|
@@ -218,7 +238,6 @@ const cancelEdit = (id: number) => {
|
|
|
onMounted(() => {
|
|
|
scrollToBottom()
|
|
|
})
|
|
|
-
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
@@ -232,7 +251,7 @@ onMounted(() => {
|
|
|
<div
|
|
|
v-for="conv in conversations"
|
|
|
:key="conv.id"
|
|
|
- @click="selectConversation(conv.id)"
|
|
|
+ @click="editingConversationId !== conv.id ? selectConversation(conv.id) : () => {}"
|
|
|
:class="['conversation-item', { active: conv.active, editing: editingConversationId === conv.id }]"
|
|
|
>
|
|
|
<!-- 非编辑状态 -->
|
|
@@ -279,27 +298,15 @@ onMounted(() => {
|
|
|
|
|
|
<!-- 编辑状态的按钮 -->
|
|
|
<template v-else>
|
|
|
- <el-button
|
|
|
- type="success"
|
|
|
- size="small"
|
|
|
- @click.stop="confirmEdit(conv.id)"
|
|
|
- class="action-btn confirm-btn"
|
|
|
- title="确认修改"
|
|
|
- plain
|
|
|
- circle
|
|
|
- >
|
|
|
- <el-icon><Check /></el-icon>
|
|
|
+ <el-button type="success" size="small" @click.stop="confirmEdit(conv.id)" class="action-btn confirm-btn" title="确认修改" plain circle>
|
|
|
+ <el-icon>
|
|
|
+ <Check />
|
|
|
+ </el-icon>
|
|
|
</el-button>
|
|
|
- <el-button
|
|
|
- type="info"
|
|
|
- size="small"
|
|
|
- @click.stop="cancelEdit(conv.id)"
|
|
|
- class="action-btn cancel-btn"
|
|
|
- title="取消编辑"
|
|
|
- plain
|
|
|
- circle
|
|
|
- >
|
|
|
- <el-icon><Close /></el-icon>
|
|
|
+ <el-button type="info" size="small" @click.stop="cancelEdit(conv.id)" class="action-btn cancel-btn" title="取消编辑" plain circle>
|
|
|
+ <el-icon>
|
|
|
+ <Close />
|
|
|
+ </el-icon>
|
|
|
</el-button>
|
|
|
</template>
|
|
|
</div>
|
|
@@ -313,20 +320,12 @@ onMounted(() => {
|
|
|
<!-- 消息展示区域 -->
|
|
|
<div class="messages-container" ref="messagesContainer">
|
|
|
<div v-if="messages.length !== 0">
|
|
|
- <div
|
|
|
- v-for="message in messages"
|
|
|
- :key="message.id"
|
|
|
- :class="['message-wrapper', message.type]"
|
|
|
- >
|
|
|
+ <div v-for="message in messages" :key="message.id" :class="['message-wrapper', message.type]">
|
|
|
<!-- AI消息 -->
|
|
|
<div v-if="message.type === 'ai'" class="ai-message-container">
|
|
|
<el-avatar class="message-avatar" :icon="ChatDotRound" />
|
|
|
<div class="message-bubble ai-bubble">
|
|
|
- <Markdown
|
|
|
- :content="message.content"
|
|
|
- :plugins="plugins"
|
|
|
- class="markdown-content"
|
|
|
- />
|
|
|
+ <Markdown :content="message.content" :plugins="plugins" class="markdown-content" />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
@@ -335,11 +334,7 @@ onMounted(() => {
|
|
|
<div class="message-bubble user-bubble">
|
|
|
{{ message.content }}
|
|
|
</div>
|
|
|
- <el-avatar
|
|
|
- class="message-avatar"
|
|
|
- :src="getUserInfos.avatar"
|
|
|
- :icon="User"
|
|
|
- />
|
|
|
+ <el-avatar class="message-avatar" :src="getUserInfos.avatar" :icon="User" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -357,13 +352,9 @@ onMounted(() => {
|
|
|
<!-- 标题和描述 -->
|
|
|
<div class="empty-text">
|
|
|
<h2 class="empty-title">开始新的对话</h2>
|
|
|
- <p class="empty-description">
|
|
|
- 选择工具和模型,然后在下方输入您的问题开始对话
|
|
|
- </p>
|
|
|
+ <p class="empty-description">选择工具和模型,然后在下方输入您的问题开始对话</p>
|
|
|
</div>
|
|
|
|
|
|
-
|
|
|
-
|
|
|
<!-- 快速开始提示 -->
|
|
|
<div class="quick-start">
|
|
|
<div class="quick-start-item">
|
|
@@ -384,27 +375,13 @@ onMounted(() => {
|
|
|
<div class="example-questions">
|
|
|
<h4>试试这些问题:</h4>
|
|
|
<div class="question-tags">
|
|
|
- <el-tag
|
|
|
- class="question-tag"
|
|
|
- @click="inputMessage = '帮我查看设备运行状态和告警信息'"
|
|
|
- type="info"
|
|
|
- >
|
|
|
+ <el-tag class="question-tag" @click="inputMessage = '帮我查看设备运行状态和告警信息'" type="info">
|
|
|
帮我查看设备运行状态和告警信息
|
|
|
</el-tag>
|
|
|
- <el-tag
|
|
|
- class="question-tag"
|
|
|
- @click="inputMessage = '分析用户权限配置和角色分配情况'"
|
|
|
- type="success"
|
|
|
- >
|
|
|
+ <el-tag class="question-tag" @click="inputMessage = '分析用户权限配置和角色分配情况'" type="success">
|
|
|
分析用户权限配置和角色分配情况
|
|
|
</el-tag>
|
|
|
- <el-tag
|
|
|
- class="question-tag"
|
|
|
- @click="inputMessage = '检查系统性能和在线用户统计'"
|
|
|
- type="warning"
|
|
|
- >
|
|
|
- 检查系统性能和在线用户统计
|
|
|
- </el-tag>
|
|
|
+ <el-tag class="question-tag" @click="inputMessage = '检查系统性能和在线用户统计'" type="warning"> 检查系统性能和在线用户统计 </el-tag>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -432,18 +409,8 @@ onMounted(() => {
|
|
|
|
|
|
<!-- 模型选择 -->
|
|
|
<div class="model-selector">
|
|
|
- <el-select
|
|
|
- v-model="selectedModel"
|
|
|
- placeholder="选择模型"
|
|
|
- size="small"
|
|
|
- style="width: 200px"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in modelOptions"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- />
|
|
|
+ <el-select v-model="selectedModel" placeholder="选择模型" size="small" style="width: 200px">
|
|
|
+ <el-option v-for="item in modelOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -475,14 +442,7 @@ onMounted(() => {
|
|
|
>
|
|
|
发送
|
|
|
</el-button>
|
|
|
- <el-button
|
|
|
- v-else
|
|
|
- type="danger"
|
|
|
- size="small"
|
|
|
- @click="stopConversation"
|
|
|
- >
|
|
|
- 终止
|
|
|
- </el-button>
|
|
|
+ <el-button v-else type="danger" size="small" @click="stopConversation"> 终止 </el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -492,16 +452,18 @@ onMounted(() => {
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
:deep(.el-icon) {
|
|
|
- margin-right: 0!important;
|
|
|
+ margin-right: 0 !important;
|
|
|
}
|
|
|
|
|
|
.chat-container {
|
|
|
height: 100%;
|
|
|
background: var(--el-bg-color-page);
|
|
|
}
|
|
|
+
|
|
|
.create-conversation-btn {
|
|
|
margin: 16px;
|
|
|
}
|
|
|
+
|
|
|
/* 左侧边栏样式 */
|
|
|
.chat-sidebar {
|
|
|
background: var(--el-bg-color);
|
|
@@ -650,10 +612,11 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
.ai-bubble {
|
|
|
- background: #f3f4f6;
|
|
|
+ background: var(--el-fill-color-light);
|
|
|
color: var(--el-text-color-primary);
|
|
|
position: relative;
|
|
|
max-width: 70%;
|
|
|
+ border: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
|
&::before {
|
|
|
content: '';
|
|
@@ -662,7 +625,7 @@ onMounted(() => {
|
|
|
top: 12px;
|
|
|
width: 0;
|
|
|
height: 0;
|
|
|
- border-right: 8px solid #f3f4f6;
|
|
|
+ border-right: 8px solid var(--el-fill-color-light);
|
|
|
border-top: 8px solid transparent;
|
|
|
border-bottom: 8px solid transparent;
|
|
|
}
|
|
@@ -677,7 +640,7 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
.user-bubble {
|
|
|
- background: #4ade80;
|
|
|
+ background: var(--el-color-primary);
|
|
|
color: white;
|
|
|
position: relative;
|
|
|
max-width: 70%;
|
|
@@ -689,7 +652,7 @@ onMounted(() => {
|
|
|
top: 12px;
|
|
|
width: 0;
|
|
|
height: 0;
|
|
|
- border-left: 8px solid #4ade80;
|
|
|
+ border-left: 8px solid var(--el-color-primary);
|
|
|
border-top: 8px solid transparent;
|
|
|
border-bottom: 8px solid transparent;
|
|
|
}
|
|
@@ -729,40 +692,134 @@ onMounted(() => {
|
|
|
gap: 12px;
|
|
|
}
|
|
|
|
|
|
-/* Markdown 内容样式优化 */
|
|
|
+/* Markdown 内容样式优化 - 接入Element Plus颜色系统 */
|
|
|
:deep(.markdown-content) {
|
|
|
- h2 {
|
|
|
- color: var(--el-text-color-primary);
|
|
|
- margin: 16px 0 12px 0;
|
|
|
- font-size: 18px;
|
|
|
+ /* 标题样式 */
|
|
|
+ h1, h2, h3, h4, h5, h6 {
|
|
|
+ margin-top: 24px;
|
|
|
+ margin-bottom: 16px;
|
|
|
font-weight: 600;
|
|
|
+ line-height: 1.25;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
}
|
|
|
|
|
|
- ul, ol {
|
|
|
- margin: 12px 0;
|
|
|
- padding-left: 20px;
|
|
|
+ h1 {
|
|
|
+ font-size: 2em;
|
|
|
+ border-bottom: 1px solid var(--el-border-color-light);
|
|
|
+ padding-bottom: 8px;
|
|
|
}
|
|
|
|
|
|
- li {
|
|
|
- margin: 4px 0;
|
|
|
+ h2 {
|
|
|
+ font-size: 1.5em;
|
|
|
+ border-bottom: 1px solid var(--el-border-color-lighter);
|
|
|
+ padding-bottom: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ font-size: 1.25em;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 段落样式 */
|
|
|
+ p {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ line-height: 1.6;
|
|
|
color: var(--el-text-color-regular);
|
|
|
}
|
|
|
|
|
|
+ /* 代码块样式 */
|
|
|
pre {
|
|
|
- background: rgba(0, 0, 0, 0.05);
|
|
|
+ background-color: var(--el-fill-color-light);
|
|
|
+ border: 1px solid var(--el-border-color-light);
|
|
|
border-radius: 6px;
|
|
|
- margin: 12px 0;
|
|
|
+ padding: 16px;
|
|
|
+ overflow: auto;
|
|
|
+ margin: 16px 0;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
}
|
|
|
|
|
|
+ /* 行内代码样式 */
|
|
|
code {
|
|
|
- background: rgba(0, 0, 0, 0.05);
|
|
|
- padding: 2px 6px;
|
|
|
+ background-color: var(--el-fill-color-light);
|
|
|
+ color: var(--el-color-danger);
|
|
|
+ padding: 2px 4px;
|
|
|
+ border-radius: 3px;
|
|
|
+ font-size: 85%;
|
|
|
+ border: 1px solid var(--el-border-color-lighter);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 引用块样式 */
|
|
|
+ blockquote {
|
|
|
+ border-left: 4px solid var(--el-color-primary);
|
|
|
+ padding-left: 16px;
|
|
|
+ margin: 16px 0;
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
+ background-color: var(--el-fill-color-extra-light);
|
|
|
+ padding: 12px 16px;
|
|
|
border-radius: 4px;
|
|
|
- font-size: 14px;
|
|
|
}
|
|
|
|
|
|
- p {
|
|
|
- margin: 8px 0;
|
|
|
+ /* 列表样式 */
|
|
|
+ ul, ol {
|
|
|
+ margin: 16px 0;
|
|
|
+ padding-left: 32px;
|
|
|
+ color: var(--el-text-color-regular);
|
|
|
+ }
|
|
|
+
|
|
|
+ li {
|
|
|
+ margin: 4px 0;
|
|
|
+ line-height: 1.6;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 表格样式 */
|
|
|
+ table {
|
|
|
+ border-collapse: collapse;
|
|
|
+ margin: 16px 0;
|
|
|
+ width: 100%;
|
|
|
+ border: 1px solid var(--el-border-color-light);
|
|
|
+ }
|
|
|
+
|
|
|
+ th, td {
|
|
|
+ border: 1px solid var(--el-border-color-light);
|
|
|
+ padding: 8px 12px;
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+
|
|
|
+ th {
|
|
|
+ background-color: var(--el-fill-color-light);
|
|
|
+ font-weight: 600;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
+ }
|
|
|
+
|
|
|
+ td {
|
|
|
+ color: var(--el-text-color-regular);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 分割线样式 */
|
|
|
+ hr {
|
|
|
+ border: none;
|
|
|
+ border-top: 1px solid var(--el-border-color-light);
|
|
|
+ margin: 24px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 链接样式 */
|
|
|
+ a {
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ text-decoration: none;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: var(--el-color-primary-light-3);
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 强调文本样式 */
|
|
|
+ strong {
|
|
|
+ font-weight: 600;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
+ }
|
|
|
+
|
|
|
+ em {
|
|
|
+ font-style: italic;
|
|
|
color: var(--el-text-color-regular);
|
|
|
}
|
|
|
}
|
|
@@ -834,7 +891,7 @@ onMounted(() => {
|
|
|
position: absolute;
|
|
|
left: 50%;
|
|
|
top: 50%;
|
|
|
- transform: translate(-50%,-50%);
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
}
|
|
|
|
|
|
.empty-icon {
|
|
@@ -860,8 +917,6 @@ onMounted(() => {
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
.quick-start {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
@@ -924,6 +979,4 @@ onMounted(() => {
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
</style>
|