update: 更新样式和主题配置,新增设置管理,优化聊天界面,支持历史会话和背景信息展示
This commit is contained in:
parent
ce52a06ee7
commit
0601a3a166
|
@ -25,6 +25,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
"sass": "^1.86.3",
|
||||||
"sass-embedded": "^1.86.3",
|
"sass-embedded": "^1.86.3",
|
||||||
"vite": "^6.2.0"
|
"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
|
// 引入 Element Plus
|
||||||
import ElementPlus from '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'
|
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||||
|
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
|
|
@ -15,6 +15,7 @@ const routes = [
|
||||||
component: () => import("@/layouts/blank.vue"),
|
component: () => import("@/layouts/blank.vue"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
redirect: "/chat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/chat",
|
path: "/chat",
|
||||||
|
|
|
@ -4,18 +4,43 @@ import { sendMessage } from '@/api/chat'
|
||||||
const chatModes = {
|
const chatModes = {
|
||||||
training: {
|
training: {
|
||||||
name: '寿险代理人AI陪练',
|
name: '寿险代理人AI陪练',
|
||||||
icon: 'fas fa-user-tie',
|
icon: '👨💼',
|
||||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX'
|
token: 'app-88ae2GN49aUyNO6qGg7tbTfX',
|
||||||
|
background: `# 客户信息
|
||||||
|
### **基础背景与性格设定**
|
||||||
|
|
||||||
|
**姓名**:张伟
|
||||||
|
|
||||||
|
**年龄**:34 岁
|
||||||
|
|
||||||
|
**职业**:腾讯员工
|
||||||
|
|
||||||
|
**家庭**:妻子为全职太太,女儿 9 岁,双方父母健在
|
||||||
|
|
||||||
|
**性格**:冷静、理性、务实,偏好客观数据和逻辑分析,对保险持观望态度,防备心较强
|
||||||
|
|
||||||
|
**近期状态**:
|
||||||
|
|
||||||
|
- 体检显示中度脂肪肝,担心投保问题
|
||||||
|
|
||||||
|
- 已为全家配置百万医疗险,妻子有重疾险,但认为保障不足 (保费 50W)
|
||||||
|
|
||||||
|
- 对理财型保险收益不认可,但对补充重疾险有潜在需求 `,
|
||||||
|
chatBackground: '你通过你的老同学顾先生介绍,和一位中国人寿的保险代理人约在你家中首次面谈。你的家中布置简洁,茶几上摆放着一套茶具。',
|
||||||
},
|
},
|
||||||
quote_objection: {
|
quote_objection: {
|
||||||
name: '报价中异议',
|
name: '报价中异议',
|
||||||
icon: 'fas fa-comments',
|
icon: '💬',
|
||||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX'
|
token: 'app-88ae2GN49aUyNO6qGg7tbTfX',
|
||||||
|
background: '',
|
||||||
|
chatBackground: '',
|
||||||
},
|
},
|
||||||
post_quote_objection: {
|
post_quote_objection: {
|
||||||
name: '报价后异议',
|
name: '报价后异议',
|
||||||
icon: 'fas fa-comment-dollar',
|
icon: '💰',
|
||||||
token: 'app-88ae2GN49aUyNO6qGg7tbTfX'
|
token: 'app-88ae2GN49aUyNO6qGg7tbTfX',
|
||||||
|
background: '',
|
||||||
|
chatBackground: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 返回示例
|
// 返回示例
|
||||||
|
@ -180,9 +205,10 @@ export const useChatStore = defineStore('chat', {
|
||||||
conversationId: message.conversation_id,
|
conversationId: message.conversation_id,
|
||||||
messageId: message.message_id,
|
messageId: message.message_id,
|
||||||
createdAt: message.created_at,
|
createdAt: message.created_at,
|
||||||
|
createdAtTimestamp: '',
|
||||||
question: question,
|
question: question,
|
||||||
answerBuffer: '',
|
answerBuffer: '',
|
||||||
showEvaluation: true,
|
showEvaluation: false,
|
||||||
respondingType: '',
|
respondingType: '',
|
||||||
kehu: '',
|
kehu: '',
|
||||||
pingfen: '',
|
pingfen: '',
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const useRouteStore = defineStore('route', {
|
export const useRouteStore = defineStore('route', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
currentRoute: '/'
|
currentRoute: '/chat'
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
updateCurrentRoute(path) {
|
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;
|
line-height: 1.5;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
color-scheme: light dark;
|
color-scheme: light only;
|
||||||
color: rgba(255, 255, 255, 0.87);
|
color: rgba(255, 255, 255, 0.87);
|
||||||
background-color: #242424;
|
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>
|
<template>
|
||||||
<div class="chat-container">
|
<div class="chat-container">
|
||||||
|
<ChatHeader />
|
||||||
<div class="chat-messages" ref="chatContainer">
|
<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">
|
<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="avatar"><span class="emoji">👤</span></div>
|
||||||
<div class="message-content">
|
<div class="message-content">
|
||||||
<div class="message-text-wrapper">
|
<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 class="message-text">{{ message.question }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 改进建议部分 -->
|
<!-- 改进建议部分 -->
|
||||||
<div class="evaluation-toggle" @click="chatStore.toggleEvaluation(message.messageId)">
|
<div class="evaluation-toggle" @click="chatStore.toggleEvaluation(message.messageId)">
|
||||||
<span class="evaluation-btn">改进建议</span>
|
<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><span></span><span></span>
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="evaluation-icon">{{ message.showEvaluation ? '▼' : '▶' }}</span>
|
<span v-else class="evaluation-icon">{{ message.showEvaluation ? '▼' : '▶' }}</span>
|
||||||
|
@ -24,7 +39,7 @@
|
||||||
<div class="evaluation-content">
|
<div class="evaluation-content">
|
||||||
<div class="evaluation-text pingfen" v-html="formatMarkdown(message.pingfen, 'pingfen')"></div>
|
<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 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>
|
<span></span><span></span><span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,15 +53,22 @@
|
||||||
<div class="avatar"><span class="emoji">🤖</span></div>
|
<div class="avatar"><span class="emoji">🤖</span></div>
|
||||||
<div class="message-content">
|
<div class="message-content">
|
||||||
<div class="message-text-wrapper">
|
<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 class="message-text" v-html="message.kehu"></div>
|
||||||
<div v-if="message.respondingType === 'kehu'" class="typing-indicator">
|
<div v-if="message.respondingType === 'kehu'" class="typing-indicator">
|
||||||
<span></span><span></span><span></span>
|
<span></span><span></span><span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="input-area">
|
<div class="input-area">
|
||||||
<button class="new-chat-btn" @click="chatStore.startNewChat" :disabled="newChatButtonsDisabled">
|
<button class="new-chat-btn" @click="chatStore.startNewChat" :disabled="newChatButtonsDisabled">
|
||||||
|
@ -61,13 +83,17 @@
|
||||||
rows="1"
|
rows="1"
|
||||||
ref="messageInputRef"
|
ref="messageInputRef"
|
||||||
@input="adjustTextareaHeight"
|
@input="adjustTextareaHeight"
|
||||||
|
:disabled="isInputDisabled"
|
||||||
></textarea>
|
></textarea>
|
||||||
<button class="send-btn" @click="sendMessage" :disabled="sendButtonsDisabled">发送</button>
|
<button class="send-btn" @click="sendMessage" :disabled="isInputDisabled || !messageInput.trim()">发送</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 添加总结弹窗 -->
|
<!-- 总结弹窗 -->
|
||||||
<div v-if="lastMessageWithDafen" class="summary-panel" :class="{ 'summary-panel-collapsed': isSummaryCollapsed }">
|
<div v-if="lastMessageWithDafen" class="summary-panel" :class="{ 'summary-panel-collapsed': isSummaryCollapsed }">
|
||||||
<div class="summary-header" @click="toggleSummary">
|
<div class="summary-header" @click="toggleSummary">
|
||||||
<span class="summary-title">会话总结</span>
|
<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>
|
<span class="summary-toggle-icon">{{ isSummaryCollapsed ? '▼' : '▲' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="summary-content" v-html="formatMarkdown(lastMessageWithDafen.dafen)"></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 { marked } from 'marked'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { useChatStore } from '@/store/chat'
|
import { useChatStore } from '@/store/chat'
|
||||||
|
import ChatHeader from '@/views/chat/ChatHeader.vue'
|
||||||
|
import { ElTag } from 'element-plus'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'ChatInterface'
|
name: 'ChatInterface'
|
||||||
|
@ -96,6 +124,8 @@ const shouldAutoScroll = ref(true)
|
||||||
const lastScrollTop = ref(0)
|
const lastScrollTop = ref(0)
|
||||||
const lastScrollHeight = ref(0)
|
const lastScrollHeight = ref(0)
|
||||||
const isSummaryCollapsed = ref(false)
|
const isSummaryCollapsed = ref(false)
|
||||||
|
const showBackgroundDialog = ref(false)
|
||||||
|
const showBackground = ref(false)
|
||||||
|
|
||||||
// 使用计算属性获取当前会话的消息
|
// 使用计算属性获取当前会话的消息
|
||||||
const currentMessages = computed(() => {
|
const currentMessages = computed(() => {
|
||||||
|
@ -217,62 +247,6 @@ const sendMessage = () => {
|
||||||
scrollToBottom(true)
|
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) => {
|
const formatMarkdown = (text, tagType) => {
|
||||||
if (!text) return ''
|
if (!text) return ''
|
||||||
|
@ -290,6 +264,29 @@ const toggleSummary = () => {
|
||||||
isSummaryCollapsed.value = !isSummaryCollapsed.value
|
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(() => {
|
onMounted(() => {
|
||||||
if (chatContainer.value) {
|
if (chatContainer.value) {
|
||||||
chatContainer.value.addEventListener('scroll', handleScroll)
|
chatContainer.value.addEventListener('scroll', handleScroll)
|
||||||
|
@ -298,9 +295,6 @@ onMounted(() => {
|
||||||
shouldAutoScroll.value = true
|
shouldAutoScroll.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chatStore.score && scoreChart.value) {
|
|
||||||
initChart()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
@ -322,6 +316,120 @@ onUnmounted(() => {
|
||||||
overflow: hidden;
|
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 {
|
.chat-messages {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
@ -332,7 +440,7 @@ onUnmounted(() => {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
-webkit-overflow-scrolling: touch; // 添加iOS滚动优化
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
|
@ -385,6 +493,7 @@ onUnmounted(() => {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
.message-text {
|
.message-text {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
color: #333333;
|
||||||
}
|
}
|
||||||
.message-content {
|
.message-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -427,6 +536,7 @@ onUnmounted(() => {
|
||||||
|
|
||||||
.message-text {
|
.message-text {
|
||||||
min-height: 36px;
|
min-height: 36px;
|
||||||
|
min-width: 60px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
|
@ -606,6 +716,13 @@ onUnmounted(() => {
|
||||||
border-color: #07c160;
|
border-color: #07c160;
|
||||||
box-shadow: 0 0 0 2px rgba(7, 193, 96, 0.1);
|
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 {
|
button {
|
||||||
|
@ -621,7 +738,9 @@ onUnmounted(() => {
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
&:disabled {
|
&:disabled {
|
||||||
background: #ccc;
|
background: #f5f5f5 !important;
|
||||||
|
border-color: #e0e0e0;
|
||||||
|
color: #999;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,14 +810,22 @@ onUnmounted(() => {
|
||||||
|
|
||||||
/* 添加媒体查询以适应不同屏幕 */
|
/* 添加媒体查询以适应不同屏幕 */
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.message-wrapper {
|
.message-content {
|
||||||
max-width: 90%;
|
max-width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message .message-wrapper.user {
|
||||||
|
padding-left: 10%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 480px) {
|
@media screen and (max-width: 480px) {
|
||||||
.message-wrapper {
|
.message-content {
|
||||||
max-width: 95%;
|
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>
|
</style>
|
|
@ -1,35 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mode-selector">
|
<div class="mode-selector" :class="{ 'collapsed': settingsStore.sidebarCollapsed }">
|
||||||
<div class="mode-header">
|
<div class="mode-header">
|
||||||
<h3 class="mode-title">对话场景</h3>
|
<h3 class="mode-title">对话场景</h3>
|
||||||
<el-dropdown trigger="hover" @command="handleHistorySelect">
|
<div class="header-actions">
|
||||||
<el-button class="history-btn" :icon="Document" text bg>
|
<HistoryButton v-if="!settingsStore.sidebarCollapsed" :icon-only="true" />
|
||||||
历史会话
|
<el-button
|
||||||
</el-button>
|
class="collapse-btn"
|
||||||
<template #dropdown>
|
:icon="settingsStore.sidebarCollapsed ? Expand : Fold"
|
||||||
<el-dropdown-menu>
|
text
|
||||||
<template v-if="currentModeHistory.length">
|
bg
|
||||||
<el-dropdown-item
|
@click="settingsStore.toggleSidebar"
|
||||||
v-for="chat in currentModeHistory"
|
/>
|
||||||
:key="chat.conversationId"
|
</div>
|
||||||
: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>
|
</div>
|
||||||
<div class="mode-list">
|
<div class="mode-list">
|
||||||
<div
|
<div
|
||||||
|
@ -38,8 +20,22 @@
|
||||||
:class="['mode-item', { active: chatStore.currentMode === mode.id }]"
|
:class="['mode-item', { active: chatStore.currentMode === mode.id }]"
|
||||||
@click="selectMode(mode.id)"
|
@click="selectMode(mode.id)"
|
||||||
>
|
>
|
||||||
<i :class="mode.icon"></i>
|
<span class="emoji-icon">{{ mode.icon }}</span>
|
||||||
<span>{{ mode.name }}</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,11 +43,15 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useChatStore } from '@/store/chat'
|
import { useChatStore } from '@/store/chat'
|
||||||
import { computed, ref } from 'vue'
|
import { useSettingsStore } from '@/store/settings'
|
||||||
import { Document, Delete } from '@element-plus/icons-vue'
|
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 { 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 chatStore = useChatStore()
|
||||||
|
const settingsStore = useSettingsStore()
|
||||||
|
|
||||||
const chatModes = computed(() => {
|
const chatModes = computed(() => {
|
||||||
return Object.keys(chatStore.chatModes).map(key => ({
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -119,22 +136,56 @@ $hover-color-dark: #2d2d2d;
|
||||||
background: $background-color;
|
background: $background-color;
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 20px 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;
|
||||||
|
|
||||||
|
&.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 {
|
.mode-header {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
height: 60px;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.mode-title {
|
.mode-title {
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: 500;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-btn {
|
.history-btn {
|
||||||
|
@ -143,15 +194,33 @@ $hover-color-dark: #2d2d2d;
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
transition: all 0.3s ease;
|
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 {
|
&:hover {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
background: rgba($primary-color, 0.1);
|
background: transparent !important;
|
||||||
}
|
|
||||||
|
|
||||||
&:focus-visible {
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
|
@ -161,12 +230,12 @@ $hover-color-dark: #2d2d2d;
|
||||||
|
|
||||||
:deep(.el-icon) {
|
:deep(.el-icon) {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-right: 4px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-list {
|
.mode-list {
|
||||||
|
padding: 0 0 20px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
@ -180,9 +249,15 @@ $hover-color-dark: #2d2d2d;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $hover-color;
|
background: $hover-color;
|
||||||
|
|
||||||
|
:deep(.setting-btn) {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
|
@ -190,14 +265,27 @@ $hover-color-dark: #2d2d2d;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
.emoji-icon {
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
line-height: 1;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
.mode-name {
|
||||||
font-size: 14px;
|
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) {
|
// @media (prefers-color-scheme: dark) {
|
||||||
.mode-selector {
|
// .mode-selector {
|
||||||
background: $background-color-dark;
|
// background: $background-color-dark;
|
||||||
border-right-color: $border-color-dark;
|
// border-right-color: $border-color-dark;
|
||||||
|
|
||||||
.mode-title {
|
// .mode-title {
|
||||||
color: $text-color-dark;
|
// color: $text-color-dark;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.mode-item {
|
// .mode-item {
|
||||||
color: $text-color-dark;
|
// color: $text-color-dark;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
background: $hover-color-dark;
|
// background: $hover-color-dark;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
.history-btn {
|
// .history-btn {
|
||||||
color: $text-color-dark;
|
// color: $text-color-dark;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
color: $primary-color;
|
// color: $primary-color;
|
||||||
background: rgba($primary-color, 0.15);
|
// background: rgba($primary-color, 0.15);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
.delete-btn {
|
// .delete-btn {
|
||||||
&:hover {
|
// &:hover {
|
||||||
background-color: rgba(245, 108, 108, 0.15);
|
// background-color: rgba(245, 108, 108, 0.15);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
</style>
|
</style>
|
|
@ -24,6 +24,13 @@ export default defineConfig(({ command, mode }) => {
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
additionalData: ``
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
|
|
199
yarn.lock
199
yarn.lock
|
@ -246,6 +246,95 @@
|
||||||
unimport "^4.1.3"
|
unimport "^4.1.3"
|
||||||
untyped "^2.0.0"
|
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":
|
"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
|
||||||
version "2.11.7"
|
version "2.11.7"
|
||||||
resolved "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671"
|
resolved "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671"
|
||||||
|
@ -431,29 +520,29 @@
|
||||||
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
|
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
|
||||||
|
|
||||||
"@vue/devtools-api@^7.7.2":
|
"@vue/devtools-api@^7.7.2":
|
||||||
version "7.7.2"
|
version "7.7.5"
|
||||||
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.2.tgz#49837eae6f61fc43a09f5d6c2d3210f9f73a0d09"
|
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.5.tgz#1e6c3d72c1a77419c1940bc94ee12d2949334aaf"
|
||||||
integrity sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==
|
integrity sha512-HYV3tJGARROq5nlVMJh5KKHk7GU8Au3IrrmNNqr978m0edxgpHgYPDoNUGrvEgIbObz09SQezFR3A1EVmB5WZg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/devtools-kit" "^7.7.2"
|
"@vue/devtools-kit" "^7.7.5"
|
||||||
|
|
||||||
"@vue/devtools-kit@^7.7.2":
|
"@vue/devtools-kit@^7.7.5":
|
||||||
version "7.7.2"
|
version "7.7.5"
|
||||||
resolved "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.2.tgz#3315bd5b144f98c7b84c2f44270b445644ec8f10"
|
resolved "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.5.tgz#2992fbf793064b302a324d423b35e9a85c0903f5"
|
||||||
integrity sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==
|
integrity sha512-S9VAVJYVAe4RPx2JZb9ZTEi0lqTySz2CBeF0wHT5D3dkTLnT9yMMGegKNl4b2EIELwLSkcI9bl2qp0/jW+upqA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/devtools-shared" "^7.7.2"
|
"@vue/devtools-shared" "^7.7.5"
|
||||||
birpc "^0.2.19"
|
birpc "^2.3.0"
|
||||||
hookable "^5.5.3"
|
hookable "^5.5.3"
|
||||||
mitt "^3.0.1"
|
mitt "^3.0.1"
|
||||||
perfect-debounce "^1.0.0"
|
perfect-debounce "^1.0.0"
|
||||||
speakingurl "^14.0.1"
|
speakingurl "^14.0.1"
|
||||||
superjson "^2.2.1"
|
superjson "^2.2.2"
|
||||||
|
|
||||||
"@vue/devtools-shared@^7.7.2":
|
"@vue/devtools-shared@^7.7.5":
|
||||||
version "7.7.2"
|
version "7.7.5"
|
||||||
resolved "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.2.tgz#b11b143820130a32d8ce5737e264d06ab6d62f40"
|
resolved "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.5.tgz#0be847df75d72ff7e6be05a1581abeade7edc31e"
|
||||||
integrity sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==
|
integrity sha512-QBjG72RfpM0DKtpns2RZOxBltO226kOAls9e4Lri6YxS2gWTgL0H+wj1R2K76lxxIeOrqo4+2Ty6RQnzv+WSTQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
rfdc "^1.4.1"
|
rfdc "^1.4.1"
|
||||||
|
|
||||||
|
@ -541,10 +630,10 @@ axios@^1.8.4:
|
||||||
form-data "^4.0.0"
|
form-data "^4.0.0"
|
||||||
proxy-from-env "^1.1.0"
|
proxy-from-env "^1.1.0"
|
||||||
|
|
||||||
birpc@^0.2.19:
|
birpc@^2.3.0:
|
||||||
version "0.2.19"
|
version "2.3.0"
|
||||||
resolved "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz#cdd183a4a70ba103127d49765b4a71349da5a0ca"
|
resolved "https://registry.npmmirror.com/birpc/-/birpc-2.3.0.tgz#e5a402dc785ef952a2383ef3cfc075e0842f3e8c"
|
||||||
integrity sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==
|
integrity sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==
|
||||||
|
|
||||||
braces@^3.0.3:
|
braces@^3.0.3:
|
||||||
version "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"
|
es-errors "^1.3.0"
|
||||||
function-bind "^1.1.2"
|
function-bind "^1.1.2"
|
||||||
|
|
||||||
chokidar@^4.0.3:
|
chokidar@^4.0.0, chokidar@^4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
|
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
|
||||||
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
|
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
|
||||||
|
@ -662,6 +751,11 @@ destr@^2.0.3:
|
||||||
resolved "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb"
|
resolved "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb"
|
||||||
integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==
|
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:
|
dotenv@^16.4.7:
|
||||||
version "16.5.0"
|
version "16.5.0"
|
||||||
resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692"
|
resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692"
|
||||||
|
@ -685,9 +779,9 @@ echarts@^5.6.0:
|
||||||
zrender "5.6.1"
|
zrender "5.6.1"
|
||||||
|
|
||||||
element-plus@^2.9.7:
|
element-plus@^2.9.7:
|
||||||
version "2.9.7"
|
version "2.9.8"
|
||||||
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.7.tgz#05bcc35de1d98192d25ebfd06fff7d6d2de9f911"
|
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.8.tgz#72aea48dfcd5ef70a1859d2c8a16d189451f4afb"
|
||||||
integrity sha512-6vjZh5SXBncLhUwJGTVKS5oDljfgGMh6J4zVTeAZK3YdMUN76FgpvHkwwFXocpJpMbii6rDYU3sgie64FyPerQ==
|
integrity sha512-srViUaUdfblBKGMeuEPiXxxKlH5aUmKqEwmhb/At9Sj91DbU6od/jYN1955cTnzt3wTSA7GfnZF7UiRX9sdRHg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ctrl/tinycolor" "^3.4.1"
|
"@ctrl/tinycolor" "^3.4.1"
|
||||||
"@element-plus/icons-vue" "^2.3.1"
|
"@element-plus/icons-vue" "^2.3.1"
|
||||||
|
@ -796,9 +890,9 @@ estree-walker@^3.0.3:
|
||||||
"@types/estree" "^1.0.0"
|
"@types/estree" "^1.0.0"
|
||||||
|
|
||||||
exsolve@^1.0.1, exsolve@^1.0.4:
|
exsolve@^1.0.1, exsolve@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.5"
|
||||||
resolved "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.4.tgz#7de5c75af82ecd15998328fbf5f2295883be3a39"
|
resolved "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.5.tgz#1f5b6b4fe82ad6b28a173ccb955a635d77859dcf"
|
||||||
integrity sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==
|
integrity sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==
|
||||||
|
|
||||||
fast-glob@^3.3.3:
|
fast-glob@^3.3.3:
|
||||||
version "3.3.3"
|
version "3.3.3"
|
||||||
|
@ -818,10 +912,10 @@ fastq@^1.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
reusify "^1.0.4"
|
reusify "^1.0.4"
|
||||||
|
|
||||||
fdir@^6.4.3:
|
fdir@^6.4.3, fdir@^6.4.4:
|
||||||
version "6.4.3"
|
version "6.4.4"
|
||||||
resolved "https://registry.npmmirror.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72"
|
resolved "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz#1cfcf86f875a883e19a8fab53622cfe992e8d2f9"
|
||||||
integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==
|
integrity sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==
|
||||||
|
|
||||||
fill-range@^7.1.1:
|
fill-range@^7.1.1:
|
||||||
version "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"
|
resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||||
|
|
||||||
is-glob@^4.0.1:
|
is-glob@^4.0.1, is-glob@^4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||||
|
@ -1047,7 +1141,7 @@ merge2@^1.3.0:
|
||||||
resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||||
|
|
||||||
micromatch@^4.0.8:
|
micromatch@^4.0.5, micromatch@^4.0.8:
|
||||||
version "4.0.8"
|
version "4.0.8"
|
||||||
resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
|
resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
|
||||||
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
|
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"
|
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
||||||
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
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:
|
node-fetch-native@^1.6.6:
|
||||||
version "1.6.6"
|
version "1.6.6"
|
||||||
resolved "https://registry.npmmirror.com/node-fetch-native/-/node-fetch-native-1.6.6.tgz#ae1d0e537af35c2c0b0de81cbff37eedd410aa37"
|
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"
|
resolved "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca"
|
||||||
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
|
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
|
||||||
|
|
||||||
rollup@^4.30.1:
|
rollup@^4.34.9:
|
||||||
version "4.40.0"
|
version "4.40.0"
|
||||||
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.40.0.tgz#13742a615f423ccba457554f006873d5a4de1920"
|
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.40.0.tgz#13742a615f423ccba457554f006873d5a4de1920"
|
||||||
integrity sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==
|
integrity sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==
|
||||||
|
@ -1403,6 +1502,17 @@ sass-embedded@^1.86.3:
|
||||||
sass-embedded-win32-ia32 "1.86.3"
|
sass-embedded-win32-ia32 "1.86.3"
|
||||||
sass-embedded-win32-x64 "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:
|
scule@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz#6efbd22fd0bb801bdcc585c89266a7d2daa8fbd3"
|
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"
|
resolved "https://registry.npmmirror.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce"
|
||||||
integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
|
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"
|
version "1.2.1"
|
||||||
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||||
|
@ -1440,7 +1550,7 @@ strip-literal@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
js-tokens "^9.0.1"
|
js-tokens "^9.0.1"
|
||||||
|
|
||||||
superjson@^2.2.1:
|
superjson@^2.2.2:
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz#9d52bf0bf6b5751a3c3472f1292e714782ba3173"
|
resolved "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz#9d52bf0bf6b5751a3c3472f1292e714782ba3173"
|
||||||
integrity sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==
|
integrity sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==
|
||||||
|
@ -1472,11 +1582,11 @@ tinyexec@^0.3.2:
|
||||||
integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==
|
integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==
|
||||||
|
|
||||||
tinyglobby@^0.2.12:
|
tinyglobby@^0.2.12:
|
||||||
version "0.2.12"
|
version "0.2.13"
|
||||||
resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.12.tgz#ac941a42e0c5773bd0b5d08f32de82e74a1a61b5"
|
resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz#a0e46515ce6cbcd65331537e57484af5a7b2ff7e"
|
||||||
integrity sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==
|
integrity sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==
|
||||||
dependencies:
|
dependencies:
|
||||||
fdir "^6.4.3"
|
fdir "^6.4.4"
|
||||||
picomatch "^4.0.2"
|
picomatch "^4.0.2"
|
||||||
|
|
||||||
to-regex-range@^5.0.1:
|
to-regex-range@^5.0.1:
|
||||||
|
@ -1570,13 +1680,16 @@ varint@^6.0.0:
|
||||||
integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
|
integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
|
||||||
|
|
||||||
vite@^6.2.0:
|
vite@^6.2.0:
|
||||||
version "6.2.6"
|
version "6.3.2"
|
||||||
resolved "https://registry.npmmirror.com/vite/-/vite-6.2.6.tgz#7f0ccf2fdc0c1eda079ce258508728e2473d3f61"
|
resolved "https://registry.npmmirror.com/vite/-/vite-6.3.2.tgz#4c1bb01b1cea853686a191657bbc14272a038f0a"
|
||||||
integrity sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==
|
integrity sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild "^0.25.0"
|
esbuild "^0.25.0"
|
||||||
|
fdir "^6.4.3"
|
||||||
|
picomatch "^4.0.2"
|
||||||
postcss "^8.5.3"
|
postcss "^8.5.3"
|
||||||
rollup "^4.30.1"
|
rollup "^4.34.9"
|
||||||
|
tinyglobby "^0.2.12"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.3"
|
fsevents "~2.3.3"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue