update: 更新样式和主题配置,新增设置管理,优化聊天界面,支持历史会话和背景信息展示
This commit is contained in:
parent
ce52a06ee7
commit
0601a3a166
|
@ -25,6 +25,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"sass": "^1.86.3",
|
||||
"sass-embedded": "^1.86.3",
|
||||
"vite": "^6.2.0"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
width="500px"
|
||||
:close-on-click-modal="true"
|
||||
destroy-on-close
|
||||
>
|
||||
<div class="background-info-content" v-if="currentMode">
|
||||
<div v-html="formattedBackground"></div>
|
||||
</div>
|
||||
<div v-else class="no-mode">
|
||||
暂无背景信息
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useChatStore } from '@/store/chat'
|
||||
import { marked } from 'marked'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const chatStore = useChatStore()
|
||||
|
||||
const dialogVisible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
const currentMode = computed(() => {
|
||||
return chatStore.chatModes[chatStore.currentMode]
|
||||
})
|
||||
|
||||
const hasBackground = computed(() => {
|
||||
return currentMode.value?.background?.trim() !== ''
|
||||
})
|
||||
|
||||
const formattedBackground = computed(() => {
|
||||
if (!currentMode.value?.background) return ''
|
||||
marked.setOptions({
|
||||
headerIds: false,
|
||||
mangle: false
|
||||
})
|
||||
return marked.parse(currentMode.value.background)
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
hasBackground
|
||||
})
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.background-info-content {
|
||||
padding: 0 20px;
|
||||
|
||||
:deep(h1) {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
:deep(h2) {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin: 24px 0 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
:deep(h3) {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 20px 0 12px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
:deep(p) {
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
:deep(ul), :deep(ol) {
|
||||
margin-bottom: 12px;
|
||||
padding-left: 20px;
|
||||
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(strong) {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.no-mode {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,177 @@
|
|||
<template>
|
||||
<el-dropdown trigger="hover" @command="handleHistorySelect">
|
||||
<el-button
|
||||
:class="['history-btn', { 'icon-only': iconOnly }]"
|
||||
:icon="Document"
|
||||
text
|
||||
bg
|
||||
>
|
||||
<span v-if="!iconOnly">历史会话</span>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template v-if="currentModeHistory.length">
|
||||
<el-dropdown-item
|
||||
v-for="chat in currentModeHistory"
|
||||
:key="chat.conversationId"
|
||||
:command="chat.conversationId"
|
||||
class="history-item"
|
||||
>
|
||||
<div class="history-content">
|
||||
<span class="history-title">{{ formatChatTitle(chat) }}</span>
|
||||
<el-button
|
||||
class="delete-btn"
|
||||
:icon="Delete"
|
||||
link
|
||||
@click.stop="handleDelete(chat.conversationId)"
|
||||
/>
|
||||
</div>
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
<el-dropdown-item v-else disabled>暂无历史会话</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useChatStore } from '@/store/chat'
|
||||
import { Document, Delete } from '@element-plus/icons-vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
|
||||
const props = defineProps({
|
||||
iconOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const chatStore = useChatStore()
|
||||
|
||||
const currentModeHistory = computed(() => {
|
||||
return chatStore.conversations.filter(chat => chat.mode === chatStore.currentMode)
|
||||
})
|
||||
|
||||
const formatChatTitle = (chat) => {
|
||||
if (chat.messages && chat.messages.length > 0) {
|
||||
const firstMessage = chat.messages[0].question
|
||||
return firstMessage.length > 20 ? firstMessage.substring(0, 20) + '...' : firstMessage
|
||||
}
|
||||
return `会话 ${chat.conversationId.substring(0, 8)}`
|
||||
}
|
||||
|
||||
const handleHistorySelect = (conversationId) => {
|
||||
chatStore.switchConversation(conversationId)
|
||||
}
|
||||
|
||||
const handleDelete = async (conversationId) => {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'确定要删除这个会话吗?删除后无法恢复。',
|
||||
'删除确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
confirmButtonClass: 'el-button--danger'
|
||||
}
|
||||
)
|
||||
chatStore.deleteConversation(conversationId)
|
||||
} catch {
|
||||
// 用户取消删除
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.history-btn {
|
||||
height: 32px;
|
||||
padding: 4px 12px;
|
||||
color: inherit;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border: none;
|
||||
background: transparent !important;
|
||||
|
||||
&.icon-only {
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #07c160 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu__item) {
|
||||
font-size: 13px;
|
||||
padding: 8px 16px;
|
||||
line-height: 1.4;
|
||||
max-width: 300px;
|
||||
overflow-x: hidden;
|
||||
|
||||
&:hover .delete-btn {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu) {
|
||||
min-width: 200px;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.history-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.history-title {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 24px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
opacity: 0;
|
||||
transform: translateX(10px);
|
||||
transition: all 0.3s ease;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
padding: 0;
|
||||
color: #f56c6c;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
color: #f56c6c;
|
||||
background-color: rgba(245, 108, 108, 0.1);
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,90 @@
|
|||
<template>
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
@command="handleCommand"
|
||||
class="mode-setting"
|
||||
>
|
||||
<el-button
|
||||
class="setting-btn"
|
||||
:icon="Setting"
|
||||
text
|
||||
bg
|
||||
@click.stop
|
||||
/>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<slot>
|
||||
<!-- 默认选项 -->
|
||||
<el-dropdown-item command="edit">
|
||||
<el-icon><Edit /></el-icon>
|
||||
编辑设置
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="reset">
|
||||
<el-icon><RefreshRight /></el-icon>
|
||||
重置设置
|
||||
</el-dropdown-item>
|
||||
</slot>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Setting, Edit, RefreshRight } from '@element-plus/icons-vue'
|
||||
|
||||
const emit = defineEmits(['command'])
|
||||
|
||||
const handleCommand = (command) => {
|
||||
emit('command', command)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mode-setting {
|
||||
.setting-btn {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
opacity: 0;
|
||||
transform: translateX(10px);
|
||||
transition: all 0.3s ease;
|
||||
border: none;
|
||||
background: transparent !important;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu__item) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
padding: 8px 16px;
|
||||
|
||||
.el-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 在深色模式下的样式
|
||||
.mode-item.active {
|
||||
.setting-btn {
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -7,7 +7,8 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
|||
|
||||
// 引入 Element Plus
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
// 使用自定义主题
|
||||
import './styles/element-variables.scss'
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
|
||||
const pinia = createPinia();
|
||||
|
|
|
@ -15,6 +15,7 @@ const routes = [
|
|||
component: () => import("@/layouts/blank.vue"),
|
||||
},
|
||||
],
|
||||
redirect: "/chat"
|
||||
},
|
||||
{
|
||||
path: "/chat",
|
||||
|
|
|
@ -4,18 +4,43 @@ import { sendMessage } from '@/api/chat'
|
|||
const chatModes = {
|
||||
training: {
|
||||
name: '寿险代理人AI陪练',
|
||||
icon: 'fas fa-user-tie',
|
||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX'
|
||||
icon: '👨💼',
|
||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX',
|
||||
background: `# 客户信息
|
||||
### **基础背景与性格设定**
|
||||
|
||||
**姓名**:张伟
|
||||
|
||||
**年龄**:34 岁
|
||||
|
||||
**职业**:腾讯员工
|
||||
|
||||
**家庭**:妻子为全职太太,女儿 9 岁,双方父母健在
|
||||
|
||||
**性格**:冷静、理性、务实,偏好客观数据和逻辑分析,对保险持观望态度,防备心较强
|
||||
|
||||
**近期状态**:
|
||||
|
||||
- 体检显示中度脂肪肝,担心投保问题
|
||||
|
||||
- 已为全家配置百万医疗险,妻子有重疾险,但认为保障不足 (保费 50W)
|
||||
|
||||
- 对理财型保险收益不认可,但对补充重疾险有潜在需求 `,
|
||||
chatBackground: '你通过你的老同学顾先生介绍,和一位中国人寿的保险代理人约在你家中首次面谈。你的家中布置简洁,茶几上摆放着一套茶具。',
|
||||
},
|
||||
quote_objection: {
|
||||
name: '报价中异议',
|
||||
icon: 'fas fa-comments',
|
||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX'
|
||||
icon: '💬',
|
||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX',
|
||||
background: '',
|
||||
chatBackground: '',
|
||||
},
|
||||
post_quote_objection: {
|
||||
name: '报价后异议',
|
||||
icon: 'fas fa-comment-dollar',
|
||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX'
|
||||
icon: '💰',
|
||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX',
|
||||
background: '',
|
||||
chatBackground: '',
|
||||
}
|
||||
}
|
||||
// 返回示例
|
||||
|
@ -180,9 +205,10 @@ export const useChatStore = defineStore('chat', {
|
|||
conversationId: message.conversation_id,
|
||||
messageId: message.message_id,
|
||||
createdAt: message.created_at,
|
||||
createdAtTimestamp: '',
|
||||
question: question,
|
||||
answerBuffer: '',
|
||||
showEvaluation: true,
|
||||
showEvaluation: false,
|
||||
respondingType: '',
|
||||
kehu: '',
|
||||
pingfen: '',
|
||||
|
|
|
@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
|
|||
|
||||
export const useRouteStore = defineStore('route', {
|
||||
state: () => ({
|
||||
currentRoute: '/'
|
||||
currentRoute: '/chat'
|
||||
}),
|
||||
actions: {
|
||||
updateCurrentRoute(path) {
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useSettingsStore = defineStore('settings', {
|
||||
state: () => ({
|
||||
// 侧边栏状态
|
||||
sidebarCollapsed: false,
|
||||
|
||||
// 界面配置
|
||||
interface: {
|
||||
// 是否显示时间戳
|
||||
showTimestamp: true,
|
||||
// 消息气泡最大宽度(px)
|
||||
messageMaxWidth: 800,
|
||||
// 字体大小(px)
|
||||
fontSize: 14
|
||||
},
|
||||
|
||||
// 主题配置
|
||||
theme: {
|
||||
// 主色调
|
||||
primary: '#07c160',
|
||||
// 背景色
|
||||
background: '#f5f5f5',
|
||||
// 文字颜色
|
||||
textColor: '#333333'
|
||||
}
|
||||
}),
|
||||
|
||||
actions: {
|
||||
// 切换侧边栏状态
|
||||
toggleSidebar() {
|
||||
this.sidebarCollapsed = !this.sidebarCollapsed
|
||||
},
|
||||
|
||||
// 更新界面配置
|
||||
updateInterface(config) {
|
||||
this.interface = {
|
||||
...this.interface,
|
||||
...config
|
||||
}
|
||||
},
|
||||
|
||||
// 更新主题配置
|
||||
updateTheme(config) {
|
||||
this.theme = {
|
||||
...this.theme,
|
||||
...config
|
||||
}
|
||||
},
|
||||
|
||||
// 重置所有设置
|
||||
resetSettings() {
|
||||
this.$reset()
|
||||
}
|
||||
}
|
||||
})
|
|
@ -3,7 +3,7 @@
|
|||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color-scheme: light only;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/* 自定义主题变量 */
|
||||
$--color-primary: #07c160;
|
||||
|
||||
/* 导入 Element Plus 样式 */
|
||||
@use "element-plus/theme-chalk/src/index.scss" as *;
|
|
@ -0,0 +1,249 @@
|
|||
<template>
|
||||
<div class="chat-header">
|
||||
<div class="header-content">
|
||||
<div class="title">
|
||||
<span class="title-text">{{ title }}</span>
|
||||
<el-tag v-if="chatStore.currentConversation?.conversationStatus === 'typing'"
|
||||
size="small"
|
||||
class="status-tag"
|
||||
type="warning"
|
||||
>
|
||||
对话中
|
||||
</el-tag>
|
||||
<HistoryButton v-if="settingsStore.sidebarCollapsed" :icon-only="false" class="title-history-btn" />
|
||||
</div>
|
||||
<div class="actions">
|
||||
<el-tooltip content="删除会话" placement="bottom">
|
||||
<el-button
|
||||
class="action-btn delete-btn"
|
||||
:icon="Delete"
|
||||
@click="handleDelete"
|
||||
text
|
||||
>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="设置" placement="bottom">
|
||||
<el-button
|
||||
class="action-btn"
|
||||
:icon="Setting"
|
||||
@click="handleSettings"
|
||||
text
|
||||
>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="hasBackground ? '客户背景' : '暂无客户背景信息'" placement="bottom">
|
||||
<el-button
|
||||
class="action-btn"
|
||||
:icon="User"
|
||||
@click="showUserInfo = true"
|
||||
text
|
||||
:disabled="!hasBackground"
|
||||
>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CustomerBackground v-model="showUserInfo" ref="customerBackgroundRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { useChatStore } from '@/store/chat'
|
||||
import { useSettingsStore } from '@/store/settings'
|
||||
import { Delete, Setting, User } from '@element-plus/icons-vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import HistoryButton from '@/components/chat/HistoryButton.vue'
|
||||
import CustomerBackground from '@/components/chat/CustomerBackground.vue'
|
||||
|
||||
const chatStore = useChatStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const showUserInfo = ref(false)
|
||||
const customerBackgroundRef = ref(null)
|
||||
|
||||
const title = computed(() => {
|
||||
const conversation = chatStore.currentConversation
|
||||
if (!conversation) return '新会话'
|
||||
// 使用第一条消息作为标题
|
||||
if (conversation.chatMessages && conversation.chatMessages.length > 0) {
|
||||
return conversation.chatMessages[0].question
|
||||
}
|
||||
return '新会话'
|
||||
})
|
||||
|
||||
const hasBackground = computed(() => {
|
||||
return customerBackgroundRef.value?.hasBackground ?? false
|
||||
})
|
||||
|
||||
const handleDelete = async () => {
|
||||
console.log(chatStore.conversationId)
|
||||
if (!chatStore.conversationId) return
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'确定要删除当前会话吗?删除后无法恢复。',
|
||||
'删除确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
confirmButtonClass: 'el-button--danger'
|
||||
}
|
||||
)
|
||||
chatStore.deleteConversation(chatStore.conversationId)
|
||||
} catch {
|
||||
// 用户取消操作
|
||||
}
|
||||
}
|
||||
|
||||
const handleSettings = () => {
|
||||
// TODO: 实现设置功能
|
||||
console.log('打开设置')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chat-header {
|
||||
height: 60px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background: #fff;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.header-content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.title-text {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
max-width: 500px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
font-weight: normal;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.title-history-btn {
|
||||
:deep(.history-btn) {
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
color: #666;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
color: #07c160 !important;
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
.action-btn {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
transition: all 0.3s ease;
|
||||
border: none;
|
||||
background: transparent !important;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
color: #07c160;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
&.delete-btn {
|
||||
&:hover {
|
||||
color: var(--el-color-danger) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-info-content {
|
||||
padding: 20px;
|
||||
|
||||
.info-section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin: 0 0 12px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.description {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
min-width: 80px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
padding-top: 20px;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,18 @@
|
|||
<template>
|
||||
<div class="chat-container">
|
||||
<ChatHeader />
|
||||
<div class="chat-messages" ref="chatContainer">
|
||||
<!-- 聊天背景按钮 -->
|
||||
<div v-if="chatStore.chatModes[chatStore.currentMode]?.chatBackground" class="chat-background">
|
||||
<div class="background-toggle" @click="toggleBackground">
|
||||
<span class="background-btn">聊天背景</span>
|
||||
</div>
|
||||
<div v-if="showBackground" class="background-section">
|
||||
<div class="background-content">
|
||||
<div class="background-text" v-html="formatMarkdown(chatStore.chatModes[chatStore.currentMode].chatBackground)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 历史缓存 -->
|
||||
<div v-for="(message, index) in currentMessages" :key="message.messageId" class="message-group">
|
||||
<!-- 用户消息 -->
|
||||
|
@ -9,12 +21,15 @@
|
|||
<div class="avatar"><span class="emoji">👤</span></div>
|
||||
<div class="message-content">
|
||||
<div class="message-text-wrapper">
|
||||
<!-- <div v-if="message.createdAt" class="message-timestamp">
|
||||
{{ formatTimestamp(message.createdAtTimestamp) }}
|
||||
</div> -->
|
||||
<div class="message-text">{{ message.question }}</div>
|
||||
</div>
|
||||
<!-- 改进建议部分 -->
|
||||
<div class="evaluation-toggle" @click="chatStore.toggleEvaluation(message.messageId)">
|
||||
<span class="evaluation-btn">改进建议</span>
|
||||
<span v-if="['pingfen', 'zongjie'].includes(message.respondingType)" class="typing-indicator evaluation-icon">
|
||||
<span v-if="['pingfen', 'zongjie'].includes(message?.respondingType)" class="typing-indicator evaluation-icon">
|
||||
<span></span><span></span><span></span>
|
||||
</span>
|
||||
<span v-else class="evaluation-icon">{{ message.showEvaluation ? '▼' : '▶' }}</span>
|
||||
|
@ -24,7 +39,7 @@
|
|||
<div class="evaluation-content">
|
||||
<div class="evaluation-text pingfen" v-html="formatMarkdown(message.pingfen, 'pingfen')"></div>
|
||||
<div class="evaluation-text zongjie" v-html="formatMarkdown(message.zongjie, 'zongjie')"></div>
|
||||
<div v-if="['pingfen', 'zongjie'].includes(message.respondingType)" class="typing-indicator">
|
||||
<div v-if="['pingfen', 'zongjie'].includes(message?.respondingType)" class="typing-indicator">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -38,15 +53,22 @@
|
|||
<div class="avatar"><span class="emoji">🤖</span></div>
|
||||
<div class="message-content">
|
||||
<div class="message-text-wrapper">
|
||||
<!-- <div v-if="message.createdAt" class="message-timestamp">
|
||||
{{ formatTimestamp(message.createdAtTimestamp) }}
|
||||
</div> -->
|
||||
<div class="message-text" v-html="message.kehu"></div>
|
||||
<div v-if="message.respondingType === 'kehu'" class="typing-indicator">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
<div v-if="message.respondingType === 'kehu'" class="typing-indicator">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 会话结束标签 -->
|
||||
<div v-if="chatStore.currentConversation?.conversationStatus === 'finished'" class="conversation-end">
|
||||
<el-tag size="large" type="info" class="end-tag">会话已结束</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-area">
|
||||
<button class="new-chat-btn" @click="chatStore.startNewChat" :disabled="newChatButtonsDisabled">
|
||||
|
@ -61,13 +83,17 @@
|
|||
rows="1"
|
||||
ref="messageInputRef"
|
||||
@input="adjustTextareaHeight"
|
||||
:disabled="isInputDisabled"
|
||||
></textarea>
|
||||
<button class="send-btn" @click="sendMessage" :disabled="sendButtonsDisabled">发送</button>
|
||||
<button class="send-btn" @click="sendMessage" :disabled="isInputDisabled || !messageInput.trim()">发送</button>
|
||||
</div>
|
||||
<!-- 添加总结弹窗 -->
|
||||
<!-- 总结弹窗 -->
|
||||
<div v-if="lastMessageWithDafen" class="summary-panel" :class="{ 'summary-panel-collapsed': isSummaryCollapsed }">
|
||||
<div class="summary-header" @click="toggleSummary">
|
||||
<span class="summary-title">会话总结</span>
|
||||
<span v-if="['dafen'].includes(message?.respondingType)" class="typing-indicator evaluation-icon">
|
||||
<span></span><span></span><span></span>
|
||||
</span>
|
||||
<span class="summary-toggle-icon">{{ isSummaryCollapsed ? '▼' : '▲' }}</span>
|
||||
</div>
|
||||
<div class="summary-content" v-html="formatMarkdown(lastMessageWithDafen.dafen)"></div>
|
||||
|
@ -80,6 +106,8 @@ import { ref, onMounted, onUnmounted, nextTick, watch, computed, defineOptions }
|
|||
import { marked } from 'marked'
|
||||
import * as echarts from 'echarts'
|
||||
import { useChatStore } from '@/store/chat'
|
||||
import ChatHeader from '@/views/chat/ChatHeader.vue'
|
||||
import { ElTag } from 'element-plus'
|
||||
|
||||
defineOptions({
|
||||
name: 'ChatInterface'
|
||||
|
@ -96,6 +124,8 @@ const shouldAutoScroll = ref(true)
|
|||
const lastScrollTop = ref(0)
|
||||
const lastScrollHeight = ref(0)
|
||||
const isSummaryCollapsed = ref(false)
|
||||
const showBackgroundDialog = ref(false)
|
||||
const showBackground = ref(false)
|
||||
|
||||
// 使用计算属性获取当前会话的消息
|
||||
const currentMessages = computed(() => {
|
||||
|
@ -217,62 +247,6 @@ const sendMessage = () => {
|
|||
scrollToBottom(true)
|
||||
}
|
||||
|
||||
const initChart = () => {
|
||||
if (scoreChart.value) {
|
||||
const chart = echarts.init(scoreChart.value)
|
||||
|
||||
const scoreData = chatStore.score.split(',').map(item => {
|
||||
const [name, value] = item.split(':')
|
||||
return { name, value: parseFloat(value) }
|
||||
})
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: '成绩维度分析',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
radar: {
|
||||
indicator: scoreData.map(item => ({
|
||||
name: item.name,
|
||||
max: 100
|
||||
}))
|
||||
},
|
||||
series: [{
|
||||
type: 'radar',
|
||||
data: [{
|
||||
value: scoreData.map(item => item.value),
|
||||
name: '成绩',
|
||||
areaStyle: {
|
||||
color: 'rgba(76, 175, 80, 0.3)'
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#4CAF50'
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#4CAF50'
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
|
||||
const handleResize = () => {
|
||||
chart.resize()
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
chart.dispose()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化聊天内容
|
||||
const formatMarkdown = (text, tagType) => {
|
||||
if (!text) return ''
|
||||
|
@ -290,6 +264,29 @@ const toggleSummary = () => {
|
|||
isSummaryCollapsed.value = !isSummaryCollapsed.value
|
||||
}
|
||||
|
||||
const formatTimestamp = (timestamp) => {
|
||||
console.log('%c timestamp:', 'color: #2196F3; font-weight: bold', timestamp)
|
||||
if (!timestamp) return ''
|
||||
const date = new Date(timestamp)
|
||||
return date.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
|
||||
const isInputDisabled = computed(() => {
|
||||
return chatStore.currentConversation?.conversationStatus === 'finished'
|
||||
})
|
||||
|
||||
const toggleBackground = () => {
|
||||
showBackground.value = !showBackground.value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (chatContainer.value) {
|
||||
chatContainer.value.addEventListener('scroll', handleScroll)
|
||||
|
@ -298,9 +295,6 @@ onMounted(() => {
|
|||
shouldAutoScroll.value = true
|
||||
}
|
||||
|
||||
if (chatStore.score && scoreChart.value) {
|
||||
initChart()
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
@ -322,6 +316,120 @@ onUnmounted(() => {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-background {
|
||||
margin: 0 0 20px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.background-toggle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.background-btn {
|
||||
font-size: 12px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
background-color: #f4f4f5;
|
||||
border: 1px solid #e9e9eb;
|
||||
color: #909399;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: #e9e9eb;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.background-section {
|
||||
margin-top: 12px;
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
|
||||
.background-content {
|
||||
padding: 16px 24px 16px 16px;
|
||||
background: var(--el-color-primary-light-9);
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
border: 2px solid transparent;
|
||||
background-clip: padding-box;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.background-text {
|
||||
opacity: 0.9;
|
||||
color: #495057;
|
||||
line-height: 1.6;
|
||||
|
||||
:deep(p) {
|
||||
margin: 0 0 12px 0;
|
||||
line-height: 1.6;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(ul), :deep(ol) {
|
||||
margin: 8px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
:deep(strong) {
|
||||
color: #2c3e50;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:deep(h1) {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 16px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
:deep(h2) {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin: 20px 0 12px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
:deep(h3) {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 16px 0 8px 0;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
|
@ -332,7 +440,7 @@ onUnmounted(() => {
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch; // 添加iOS滚动优化
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
|
@ -385,6 +493,7 @@ onUnmounted(() => {
|
|||
justify-content: flex-start;
|
||||
.message-text {
|
||||
background-color: #ffffff;
|
||||
color: #333333;
|
||||
}
|
||||
.message-content {
|
||||
display: flex;
|
||||
|
@ -427,6 +536,7 @@ onUnmounted(() => {
|
|||
|
||||
.message-text {
|
||||
min-height: 36px;
|
||||
min-width: 60px;
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
padding: 8px 12px;
|
||||
|
@ -606,6 +716,13 @@ onUnmounted(() => {
|
|||
border-color: #07c160;
|
||||
box-shadow: 0 0 0 2px rgba(7, 193, 96, 0.1);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
color: #999;
|
||||
border-color: #e0e0e0;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
|
@ -621,7 +738,9 @@ onUnmounted(() => {
|
|||
border: 1px solid #ddd;
|
||||
white-space: nowrap;
|
||||
&:disabled {
|
||||
background: #ccc;
|
||||
background: #f5f5f5 !important;
|
||||
border-color: #e0e0e0;
|
||||
color: #999;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
@ -691,14 +810,22 @@ onUnmounted(() => {
|
|||
|
||||
/* 添加媒体查询以适应不同屏幕 */
|
||||
@media screen and (max-width: 768px) {
|
||||
.message-wrapper {
|
||||
max-width: 90%;
|
||||
.message-content {
|
||||
max-width: 85%;
|
||||
}
|
||||
|
||||
.message .message-wrapper.user {
|
||||
padding-left: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.message-wrapper {
|
||||
max-width: 95%;
|
||||
.message-content {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.message .message-wrapper.user {
|
||||
padding-left: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -873,4 +1000,63 @@ onUnmounted(() => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-timestamp {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.message-text-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
|
||||
&:hover {
|
||||
.message-timestamp {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.message-text {
|
||||
min-height: 36px;
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
white-space: pre-wrap;
|
||||
position: relative;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conversation-end {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 20px 0;
|
||||
|
||||
.end-tag {
|
||||
font-size: 12px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
background-color: #f4f4f5;
|
||||
border-color: #e9e9eb;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,35 +1,17 @@
|
|||
<template>
|
||||
<div class="mode-selector">
|
||||
<div class="mode-selector" :class="{ 'collapsed': settingsStore.sidebarCollapsed }">
|
||||
<div class="mode-header">
|
||||
<h3 class="mode-title">对话场景</h3>
|
||||
<el-dropdown trigger="hover" @command="handleHistorySelect">
|
||||
<el-button class="history-btn" :icon="Document" text bg>
|
||||
历史会话
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template v-if="currentModeHistory.length">
|
||||
<el-dropdown-item
|
||||
v-for="chat in currentModeHistory"
|
||||
:key="chat.conversationId"
|
||||
:command="chat.conversationId"
|
||||
class="history-item"
|
||||
>
|
||||
<div class="history-content">
|
||||
<span class="history-title">{{ formatChatTitle(chat) }}</span>
|
||||
<el-button
|
||||
class="delete-btn"
|
||||
:icon="Delete"
|
||||
link
|
||||
@click.stop="handleDelete(chat.conversationId)"
|
||||
/>
|
||||
</div>
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
<el-dropdown-item v-else disabled>暂无历史会话</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<div class="header-actions">
|
||||
<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 class="mode-list">
|
||||
<div
|
||||
|
@ -38,8 +20,22 @@
|
|||
:class="['mode-item', { active: chatStore.currentMode === mode.id }]"
|
||||
@click="selectMode(mode.id)"
|
||||
>
|
||||
<i :class="mode.icon"></i>
|
||||
<span>{{ mode.name }}</span>
|
||||
<span class="emoji-icon">{{ mode.icon }}</span>
|
||||
<span v-if="!settingsStore.sidebarCollapsed" class="mode-name">{{ mode.name }}</span>
|
||||
<ModeSetting v-if="!settingsStore.sidebarCollapsed" @command="(cmd) => handleModeSettings(cmd, mode.id)">
|
||||
<el-dropdown-item command="edit">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
编辑设置
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="reset">
|
||||
<el-icon><RefreshRight /></el-icon>
|
||||
重置设置
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="delete" divided>
|
||||
<el-icon><Delete /></el-icon>
|
||||
删除场景
|
||||
</el-dropdown-item>
|
||||
</ModeSetting>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -47,11 +43,15 @@
|
|||
|
||||
<script setup>
|
||||
import { useChatStore } from '@/store/chat'
|
||||
import { computed, ref } from 'vue'
|
||||
import { Document, Delete } from '@element-plus/icons-vue'
|
||||
import { useSettingsStore } from '@/store/settings'
|
||||
import { computed } from 'vue'
|
||||
import { Delete, EditPen, RefreshRight, Expand, Fold } from '@element-plus/icons-vue'
|
||||
import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElButton, ElMessageBox } from 'element-plus'
|
||||
import ModeSetting from '@/components/chat/ModeSetting.vue'
|
||||
import HistoryButton from '@/components/chat/HistoryButton.vue'
|
||||
|
||||
const chatStore = useChatStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const chatModes = computed(() => {
|
||||
return Object.keys(chatStore.chatModes).map(key => ({
|
||||
|
@ -100,6 +100,23 @@ const handleDelete = async (conversationId) => {
|
|||
// 用户取消删除
|
||||
}
|
||||
}
|
||||
|
||||
const handleModeSettings = (command, modeId) => {
|
||||
switch (command) {
|
||||
case 'edit':
|
||||
// TODO: 实现编辑设置的逻辑
|
||||
console.log('编辑设置:', modeId)
|
||||
break
|
||||
case 'reset':
|
||||
// TODO: 实现重置设置的逻辑
|
||||
console.log('重置设置:', modeId)
|
||||
break
|
||||
case 'delete':
|
||||
// TODO: 实现删除场景的逻辑
|
||||
console.log('删除场景:', modeId)
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -119,22 +136,56 @@ $hover-color-dark: #2d2d2d;
|
|||
background: $background-color;
|
||||
border-right: 1px solid $border-color;
|
||||
height: 100%;
|
||||
padding: 20px 0;
|
||||
padding: 0;
|
||||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.collapsed {
|
||||
width: 64px;
|
||||
min-width: 64px;
|
||||
|
||||
.mode-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mode-item {
|
||||
padding: 15px;
|
||||
justify-content: center;
|
||||
|
||||
.mode-name {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.mode-header {
|
||||
padding: 0 20px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
height: 60px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.mode-title {
|
||||
color: $text-color;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.history-btn {
|
||||
|
@ -143,15 +194,33 @@ $hover-color-dark: #2d2d2d;
|
|||
padding: 4px 12px;
|
||||
color: $text-color;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
&:hover {
|
||||
color: #07c160;
|
||||
background: rgba(7, 193, 96, 0.1);
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-btn {
|
||||
font-size: 14px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
color: $text-color;
|
||||
transition: all 0.3s ease;
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
background: rgba($primary-color, 0.1);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
|
@ -161,12 +230,12 @@ $hover-color-dark: #2d2d2d;
|
|||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mode-list {
|
||||
padding: 0 0 20px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
@ -180,9 +249,15 @@ $hover-color-dark: #2d2d2d;
|
|||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
color: $text-color;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background: $hover-color;
|
||||
|
||||
:deep(.setting-btn) {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
|
@ -190,14 +265,27 @@ $hover-color-dark: #2d2d2d;
|
|||
color: white;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
.emoji-icon {
|
||||
font-size: 20px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
.mode-name {
|
||||
font-size: 14px;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
:deep(.mode-setting) {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,37 +349,37 @@ $hover-color-dark: #2d2d2d;
|
|||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.mode-selector {
|
||||
background: $background-color-dark;
|
||||
border-right-color: $border-color-dark;
|
||||
// @media (prefers-color-scheme: dark) {
|
||||
// .mode-selector {
|
||||
// background: $background-color-dark;
|
||||
// border-right-color: $border-color-dark;
|
||||
|
||||
.mode-title {
|
||||
color: $text-color-dark;
|
||||
}
|
||||
// .mode-title {
|
||||
// color: $text-color-dark;
|
||||
// }
|
||||
|
||||
.mode-item {
|
||||
color: $text-color-dark;
|
||||
// .mode-item {
|
||||
// color: $text-color-dark;
|
||||
|
||||
&:hover {
|
||||
background: $hover-color-dark;
|
||||
}
|
||||
}
|
||||
// &:hover {
|
||||
// background: $hover-color-dark;
|
||||
// }
|
||||
// }
|
||||
|
||||
.history-btn {
|
||||
color: $text-color-dark;
|
||||
// .history-btn {
|
||||
// color: $text-color-dark;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
background: rgba($primary-color, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
// &:hover {
|
||||
// color: $primary-color;
|
||||
// background: rgba($primary-color, 0.15);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.delete-btn {
|
||||
&:hover {
|
||||
background-color: rgba(245, 108, 108, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
// .delete-btn {
|
||||
// &:hover {
|
||||
// background-color: rgba(245, 108, 108, 0.15);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
</style>
|
|
@ -24,6 +24,13 @@ export default defineConfig(({ command, mode }) => {
|
|||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: ``
|
||||
}
|
||||
}
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
|
|
199
yarn.lock
199
yarn.lock
|
@ -246,6 +246,95 @@
|
|||
unimport "^4.1.3"
|
||||
untyped "^2.0.0"
|
||||
|
||||
"@parcel/watcher-android-arm64@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz#507f836d7e2042f798c7d07ad19c3546f9848ac1"
|
||||
integrity sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==
|
||||
|
||||
"@parcel/watcher-darwin-arm64@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz#3d26dce38de6590ef79c47ec2c55793c06ad4f67"
|
||||
integrity sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==
|
||||
|
||||
"@parcel/watcher-darwin-x64@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz#99f3af3869069ccf774e4ddfccf7e64fd2311ef8"
|
||||
integrity sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==
|
||||
|
||||
"@parcel/watcher-freebsd-x64@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz#14d6857741a9f51dfe51d5b08b7c8afdbc73ad9b"
|
||||
integrity sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==
|
||||
|
||||
"@parcel/watcher-linux-arm-glibc@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz#43c3246d6892381db473bb4f663229ad20b609a1"
|
||||
integrity sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==
|
||||
|
||||
"@parcel/watcher-linux-arm-musl@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz#663750f7090bb6278d2210de643eb8a3f780d08e"
|
||||
integrity sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==
|
||||
|
||||
"@parcel/watcher-linux-arm64-glibc@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz#ba60e1f56977f7e47cd7e31ad65d15fdcbd07e30"
|
||||
integrity sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==
|
||||
|
||||
"@parcel/watcher-linux-arm64-musl@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz#f7fbcdff2f04c526f96eac01f97419a6a99855d2"
|
||||
integrity sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==
|
||||
|
||||
"@parcel/watcher-linux-x64-glibc@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz#4d2ea0f633eb1917d83d483392ce6181b6a92e4e"
|
||||
integrity sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==
|
||||
|
||||
"@parcel/watcher-linux-x64-musl@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz#277b346b05db54f55657301dd77bdf99d63606ee"
|
||||
integrity sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==
|
||||
|
||||
"@parcel/watcher-win32-arm64@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz#7e9e02a26784d47503de1d10e8eab6cceb524243"
|
||||
integrity sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==
|
||||
|
||||
"@parcel/watcher-win32-ia32@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz#2d0f94fa59a873cdc584bf7f6b1dc628ddf976e6"
|
||||
integrity sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==
|
||||
|
||||
"@parcel/watcher-win32-x64@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz#ae52693259664ba6f2228fa61d7ee44b64ea0947"
|
||||
integrity sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==
|
||||
|
||||
"@parcel/watcher@^2.4.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.1.tgz#342507a9cfaaf172479a882309def1e991fb1200"
|
||||
integrity sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==
|
||||
dependencies:
|
||||
detect-libc "^1.0.3"
|
||||
is-glob "^4.0.3"
|
||||
micromatch "^4.0.5"
|
||||
node-addon-api "^7.0.0"
|
||||
optionalDependencies:
|
||||
"@parcel/watcher-android-arm64" "2.5.1"
|
||||
"@parcel/watcher-darwin-arm64" "2.5.1"
|
||||
"@parcel/watcher-darwin-x64" "2.5.1"
|
||||
"@parcel/watcher-freebsd-x64" "2.5.1"
|
||||
"@parcel/watcher-linux-arm-glibc" "2.5.1"
|
||||
"@parcel/watcher-linux-arm-musl" "2.5.1"
|
||||
"@parcel/watcher-linux-arm64-glibc" "2.5.1"
|
||||
"@parcel/watcher-linux-arm64-musl" "2.5.1"
|
||||
"@parcel/watcher-linux-x64-glibc" "2.5.1"
|
||||
"@parcel/watcher-linux-x64-musl" "2.5.1"
|
||||
"@parcel/watcher-win32-arm64" "2.5.1"
|
||||
"@parcel/watcher-win32-ia32" "2.5.1"
|
||||
"@parcel/watcher-win32-x64" "2.5.1"
|
||||
|
||||
"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
|
||||
version "2.11.7"
|
||||
resolved "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671"
|
||||
|
@ -431,29 +520,29 @@
|
|||
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
|
||||
|
||||
"@vue/devtools-api@^7.7.2":
|
||||
version "7.7.2"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.2.tgz#49837eae6f61fc43a09f5d6c2d3210f9f73a0d09"
|
||||
integrity sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==
|
||||
version "7.7.5"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.5.tgz#1e6c3d72c1a77419c1940bc94ee12d2949334aaf"
|
||||
integrity sha512-HYV3tJGARROq5nlVMJh5KKHk7GU8Au3IrrmNNqr978m0edxgpHgYPDoNUGrvEgIbObz09SQezFR3A1EVmB5WZg==
|
||||
dependencies:
|
||||
"@vue/devtools-kit" "^7.7.2"
|
||||
"@vue/devtools-kit" "^7.7.5"
|
||||
|
||||
"@vue/devtools-kit@^7.7.2":
|
||||
version "7.7.2"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.2.tgz#3315bd5b144f98c7b84c2f44270b445644ec8f10"
|
||||
integrity sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==
|
||||
"@vue/devtools-kit@^7.7.5":
|
||||
version "7.7.5"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.5.tgz#2992fbf793064b302a324d423b35e9a85c0903f5"
|
||||
integrity sha512-S9VAVJYVAe4RPx2JZb9ZTEi0lqTySz2CBeF0wHT5D3dkTLnT9yMMGegKNl4b2EIELwLSkcI9bl2qp0/jW+upqA==
|
||||
dependencies:
|
||||
"@vue/devtools-shared" "^7.7.2"
|
||||
birpc "^0.2.19"
|
||||
"@vue/devtools-shared" "^7.7.5"
|
||||
birpc "^2.3.0"
|
||||
hookable "^5.5.3"
|
||||
mitt "^3.0.1"
|
||||
perfect-debounce "^1.0.0"
|
||||
speakingurl "^14.0.1"
|
||||
superjson "^2.2.1"
|
||||
superjson "^2.2.2"
|
||||
|
||||
"@vue/devtools-shared@^7.7.2":
|
||||
version "7.7.2"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.2.tgz#b11b143820130a32d8ce5737e264d06ab6d62f40"
|
||||
integrity sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==
|
||||
"@vue/devtools-shared@^7.7.5":
|
||||
version "7.7.5"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.5.tgz#0be847df75d72ff7e6be05a1581abeade7edc31e"
|
||||
integrity sha512-QBjG72RfpM0DKtpns2RZOxBltO226kOAls9e4Lri6YxS2gWTgL0H+wj1R2K76lxxIeOrqo4+2Ty6RQnzv+WSTQ==
|
||||
dependencies:
|
||||
rfdc "^1.4.1"
|
||||
|
||||
|
@ -541,10 +630,10 @@ axios@^1.8.4:
|
|||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
birpc@^0.2.19:
|
||||
version "0.2.19"
|
||||
resolved "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz#cdd183a4a70ba103127d49765b4a71349da5a0ca"
|
||||
integrity sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==
|
||||
birpc@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmmirror.com/birpc/-/birpc-2.3.0.tgz#e5a402dc785ef952a2383ef3cfc075e0842f3e8c"
|
||||
integrity sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==
|
||||
|
||||
braces@^3.0.3:
|
||||
version "3.0.3"
|
||||
|
@ -584,7 +673,7 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
|||
es-errors "^1.3.0"
|
||||
function-bind "^1.1.2"
|
||||
|
||||
chokidar@^4.0.3:
|
||||
chokidar@^4.0.0, chokidar@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
|
||||
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
|
||||
|
@ -662,6 +751,11 @@ destr@^2.0.3:
|
|||
resolved "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb"
|
||||
integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==
|
||||
|
||||
detect-libc@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
|
||||
|
||||
dotenv@^16.4.7:
|
||||
version "16.5.0"
|
||||
resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692"
|
||||
|
@ -685,9 +779,9 @@ echarts@^5.6.0:
|
|||
zrender "5.6.1"
|
||||
|
||||
element-plus@^2.9.7:
|
||||
version "2.9.7"
|
||||
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.7.tgz#05bcc35de1d98192d25ebfd06fff7d6d2de9f911"
|
||||
integrity sha512-6vjZh5SXBncLhUwJGTVKS5oDljfgGMh6J4zVTeAZK3YdMUN76FgpvHkwwFXocpJpMbii6rDYU3sgie64FyPerQ==
|
||||
version "2.9.8"
|
||||
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.8.tgz#72aea48dfcd5ef70a1859d2c8a16d189451f4afb"
|
||||
integrity sha512-srViUaUdfblBKGMeuEPiXxxKlH5aUmKqEwmhb/At9Sj91DbU6od/jYN1955cTnzt3wTSA7GfnZF7UiRX9sdRHg==
|
||||
dependencies:
|
||||
"@ctrl/tinycolor" "^3.4.1"
|
||||
"@element-plus/icons-vue" "^2.3.1"
|
||||
|
@ -796,9 +890,9 @@ estree-walker@^3.0.3:
|
|||
"@types/estree" "^1.0.0"
|
||||
|
||||
exsolve@^1.0.1, exsolve@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.4.tgz#7de5c75af82ecd15998328fbf5f2295883be3a39"
|
||||
integrity sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.5.tgz#1f5b6b4fe82ad6b28a173ccb955a635d77859dcf"
|
||||
integrity sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==
|
||||
|
||||
fast-glob@^3.3.3:
|
||||
version "3.3.3"
|
||||
|
@ -818,10 +912,10 @@ fastq@^1.6.0:
|
|||
dependencies:
|
||||
reusify "^1.0.4"
|
||||
|
||||
fdir@^6.4.3:
|
||||
version "6.4.3"
|
||||
resolved "https://registry.npmmirror.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72"
|
||||
integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==
|
||||
fdir@^6.4.3, fdir@^6.4.4:
|
||||
version "6.4.4"
|
||||
resolved "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz#1cfcf86f875a883e19a8fab53622cfe992e8d2f9"
|
||||
integrity sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==
|
||||
|
||||
fill-range@^7.1.1:
|
||||
version "7.1.1"
|
||||
|
@ -959,7 +1053,7 @@ is-extglob@^2.1.1:
|
|||
resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-glob@^4.0.1:
|
||||
is-glob@^4.0.1, is-glob@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
|
@ -1047,7 +1141,7 @@ merge2@^1.3.0:
|
|||
resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
micromatch@^4.0.8:
|
||||
micromatch@^4.0.5, micromatch@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
|
||||
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
|
||||
|
@ -1087,6 +1181,11 @@ nanoid@^3.3.8:
|
|||
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
||||
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
||||
|
||||
node-addon-api@^7.0.0:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558"
|
||||
integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==
|
||||
|
||||
node-fetch-native@^1.6.6:
|
||||
version "1.6.6"
|
||||
resolved "https://registry.npmmirror.com/node-fetch-native/-/node-fetch-native-1.6.6.tgz#ae1d0e537af35c2c0b0de81cbff37eedd410aa37"
|
||||
|
@ -1225,7 +1324,7 @@ rfdc@^1.4.1:
|
|||
resolved "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca"
|
||||
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
|
||||
|
||||
rollup@^4.30.1:
|
||||
rollup@^4.34.9:
|
||||
version "4.40.0"
|
||||
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.40.0.tgz#13742a615f423ccba457554f006873d5a4de1920"
|
||||
integrity sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==
|
||||
|
@ -1403,6 +1502,17 @@ sass-embedded@^1.86.3:
|
|||
sass-embedded-win32-ia32 "1.86.3"
|
||||
sass-embedded-win32-x64 "1.86.3"
|
||||
|
||||
sass@^1.86.3:
|
||||
version "1.86.3"
|
||||
resolved "https://registry.npmmirror.com/sass/-/sass-1.86.3.tgz#0a0d9ea97cb6665e73f409639f8533ce057464c9"
|
||||
integrity sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==
|
||||
dependencies:
|
||||
chokidar "^4.0.0"
|
||||
immutable "^5.0.2"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
optionalDependencies:
|
||||
"@parcel/watcher" "^2.4.1"
|
||||
|
||||
scule@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz#6efbd22fd0bb801bdcc585c89266a7d2daa8fbd3"
|
||||
|
@ -1418,7 +1528,7 @@ slash@^5.1.0:
|
|||
resolved "https://registry.npmmirror.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce"
|
||||
integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
|
||||
|
||||
source-map-js@^1.2.0, source-map-js@^1.2.1:
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.0, source-map-js@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
@ -1440,7 +1550,7 @@ strip-literal@^3.0.0:
|
|||
dependencies:
|
||||
js-tokens "^9.0.1"
|
||||
|
||||
superjson@^2.2.1:
|
||||
superjson@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz#9d52bf0bf6b5751a3c3472f1292e714782ba3173"
|
||||
integrity sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==
|
||||
|
@ -1472,11 +1582,11 @@ tinyexec@^0.3.2:
|
|||
integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==
|
||||
|
||||
tinyglobby@^0.2.12:
|
||||
version "0.2.12"
|
||||
resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.12.tgz#ac941a42e0c5773bd0b5d08f32de82e74a1a61b5"
|
||||
integrity sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==
|
||||
version "0.2.13"
|
||||
resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz#a0e46515ce6cbcd65331537e57484af5a7b2ff7e"
|
||||
integrity sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==
|
||||
dependencies:
|
||||
fdir "^6.4.3"
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
|
@ -1570,13 +1680,16 @@ varint@^6.0.0:
|
|||
integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
|
||||
|
||||
vite@^6.2.0:
|
||||
version "6.2.6"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-6.2.6.tgz#7f0ccf2fdc0c1eda079ce258508728e2473d3f61"
|
||||
integrity sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==
|
||||
version "6.3.2"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-6.3.2.tgz#4c1bb01b1cea853686a191657bbc14272a038f0a"
|
||||
integrity sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==
|
||||
dependencies:
|
||||
esbuild "^0.25.0"
|
||||
fdir "^6.4.3"
|
||||
picomatch "^4.0.2"
|
||||
postcss "^8.5.3"
|
||||
rollup "^4.30.1"
|
||||
rollup "^4.34.9"
|
||||
tinyglobby "^0.2.12"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
|
|
Loading…
Reference in New Issue