|
@@ -1,48 +1,84 @@
|
|
|
<template>
|
|
<template>
|
|
|
<!-- 数字人智能问答 -->
|
|
<!-- 数字人智能问答 -->
|
|
|
<div class="home-container">
|
|
<div class="home-container">
|
|
|
|
|
+ <!-- 展开收起侧边栏 -->
|
|
|
|
|
+ <div class="icon-expand">
|
|
|
|
|
+ <el-icon
|
|
|
|
|
+ @click="toggleDrawer"
|
|
|
|
|
+ :style="{ color: drawerVisible ? 'white' : '#B6B0D8' }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <component :is="drawerVisible ? Fold : Expand" />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- 左侧折叠面板 -->
|
|
<!-- 左侧折叠面板 -->
|
|
|
- <div class="left-group">
|
|
|
|
|
- <div class="title-box">
|
|
|
|
|
- <div class="box-icon" @click="goBack">
|
|
|
|
|
- <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
|
|
|
|
|
- {{ personName }}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <transition name="drawer-slide">
|
|
|
|
|
+ <div class="left-group" v-if="drawerVisible">
|
|
|
|
|
+ <el-row class="tac">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-menu
|
|
|
|
|
+ default-active="2"
|
|
|
|
|
+ class="el-menu-vertical-demo"
|
|
|
|
|
+ @open="handleOpen"
|
|
|
|
|
+ @close="handleClose"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-menu-item
|
|
|
|
|
+ v-for="(item, index) in groupList"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ @click="navigateToAI(item)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-icon><component :is="item.icon" /></el-icon>
|
|
|
|
|
+ {{ item.title }}
|
|
|
|
|
+ </el-menu-item>
|
|
|
|
|
+ </el-menu>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="selected-image">
|
|
|
|
|
- <img :src="selectedImage" alt="" />
|
|
|
|
|
|
|
+ </transition>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 原左侧折叠面板和右侧AI问答 -->
|
|
|
|
|
+ <div class="content-wrapper">
|
|
|
|
|
+ <div class="left-group2">
|
|
|
|
|
+ <div class="title-box">
|
|
|
|
|
+ <div class="box-icon" @click="goBack">
|
|
|
|
|
+ <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
|
|
|
|
|
+ {{ personName }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="selected-image">
|
|
|
|
|
+ <img :src="selectedImage" alt="" />
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- <!-- 右侧AI问答 -->
|
|
|
|
|
- <div class="number-people">
|
|
|
|
|
- <div class="content-box">
|
|
|
|
|
- <!-- AI对话框 -->
|
|
|
|
|
- <div class="chat-dialog">
|
|
|
|
|
- <!-- 对话消息列表 -->
|
|
|
|
|
- <div class="message-list">
|
|
|
|
|
- <div v-for="(item, index) in messageList" :key="index">
|
|
|
|
|
- <!-- AI消息 -->
|
|
|
|
|
- <div class="ai-message" v-if="item.type !== 'user'">
|
|
|
|
|
- <MarkdownView class="left-text" :content="item.content" />
|
|
|
|
|
- <!-- {{item.content}} -->
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 用户消息 -->
|
|
|
|
|
- <div class="user-message" v-if="item.type === 'user'">
|
|
|
|
|
- {{ item.content }}
|
|
|
|
|
|
|
+ <!-- 右侧AI问答 -->
|
|
|
|
|
+ <div class="number-people">
|
|
|
|
|
+ <div class="content-box">
|
|
|
|
|
+ <!-- AI对话框 -->
|
|
|
|
|
+ <div class="chat-dialog">
|
|
|
|
|
+ <!-- 对话消息列表 -->
|
|
|
|
|
+ <div class="message-list">
|
|
|
|
|
+ <div v-for="(item, index) in messageList" :key="index">
|
|
|
|
|
+ <!-- AI消息 -->
|
|
|
|
|
+ <div class="ai-message" v-if="item.type !== 'user'">
|
|
|
|
|
+ <MarkdownView class="left-text" :content="item.content" />
|
|
|
|
|
+ <!-- {{item.content}} -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 用户消息 -->
|
|
|
|
|
+ <div class="user-message" v-if="item.type === 'user'">
|
|
|
|
|
+ {{ item.content }}
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- <!-- 输入框和发送按钮 -->
|
|
|
|
|
- <div class="input-section">
|
|
|
|
|
- <input
|
|
|
|
|
- type="text"
|
|
|
|
|
- v-model="prompt"
|
|
|
|
|
- placeholder="问我任何问题..."
|
|
|
|
|
- @keyup.enter="handleSendByKeydown"
|
|
|
|
|
- />
|
|
|
|
|
- <button @click="handleSendByButton">发送</button>
|
|
|
|
|
|
|
+ <!-- 输入框和发送按钮 -->
|
|
|
|
|
+ <div class="input-section">
|
|
|
|
|
+ <input
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ v-model="prompt"
|
|
|
|
|
+ placeholder="问我任何问题..."
|
|
|
|
|
+ @keyup.enter="handleSendByKeydown"
|
|
|
|
|
+ />
|
|
|
|
|
+ <button @click="handleSendByButton">发送</button>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -63,7 +99,54 @@ import {
|
|
|
ArrowLeftBold,
|
|
ArrowLeftBold,
|
|
|
MagicStick,
|
|
MagicStick,
|
|
|
ChatLineRound,
|
|
ChatLineRound,
|
|
|
|
|
+ Fold,
|
|
|
|
|
+ Expand,
|
|
|
|
|
+ Picture,
|
|
|
|
|
+ Tickets,
|
|
|
|
|
+ Avatar
|
|
|
} from '@element-plus/icons-vue'
|
|
} from '@element-plus/icons-vue'
|
|
|
|
|
+
|
|
|
|
|
+// 添加抽屉显示状态
|
|
|
|
|
+const drawerVisible = ref(true)
|
|
|
|
|
+// 添加切换抽屉显示状态的函数
|
|
|
|
|
+const toggleDrawer = () => {
|
|
|
|
|
+ drawerVisible.value = !drawerVisible.value
|
|
|
|
|
+}
|
|
|
|
|
+// 渲染侧边栏
|
|
|
|
|
+const groupList = ref([
|
|
|
|
|
+ { icon: ChatLineRound, title: '智能问答' },
|
|
|
|
|
+ { icon: MagicStick, title: '智能绘画' },
|
|
|
|
|
+ { icon: Avatar, title: '数字人老师' }
|
|
|
|
|
+])
|
|
|
|
|
+// 跳转智能问答
|
|
|
|
|
+const navigateToAI = group => {
|
|
|
|
|
+ if (group.title === '智能问答') {
|
|
|
|
|
+ let person = {
|
|
|
|
|
+ id: 10,
|
|
|
|
|
+ name: '小智',
|
|
|
|
|
+ image: '@/assets/images/xiaozhi.png',
|
|
|
|
|
+ message:
|
|
|
|
|
+ '您好,我是您的AI智能助手小智,我会尽力回答您的问题或提供有用的建议!!!!'
|
|
|
|
|
+ }
|
|
|
|
|
+ router.push({
|
|
|
|
|
+ // 跳转问答页面
|
|
|
|
|
+ path: '/ai-questions',
|
|
|
|
|
+ query: {
|
|
|
|
|
+ id: person.id,
|
|
|
|
|
+ name: person.name,
|
|
|
|
|
+ image: person.image,
|
|
|
|
|
+ message: person.message
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ if (group.title === '智能绘画') {
|
|
|
|
|
+ router.push('/ai-painting')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+// 处理菜单展开和关闭
|
|
|
|
|
+const handleOpen = () => {}
|
|
|
|
|
+const handleClose = () => {}
|
|
|
|
|
+
|
|
|
// 返回上一页
|
|
// 返回上一页
|
|
|
const goBack = () => {
|
|
const goBack = () => {
|
|
|
router.go(-1)
|
|
router.go(-1)
|
|
@@ -86,7 +169,7 @@ onMounted(() => {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 聊天对话
|
|
// 聊天对话
|
|
|
-const activeConversationModelPath= ref(null) // 选中的对话编号
|
|
|
|
|
|
|
+const activeConversationModelPath = ref(null) // 选中的对话编号
|
|
|
const activeConversationId = ref(null) // 选中的对话编号
|
|
const activeConversationId = ref(null) // 选中的对话编号
|
|
|
const activeConversation = ref(null) // 选中的 Conversation
|
|
const activeConversation = ref(null) // 选中的 Conversation
|
|
|
const conversationInProgress = ref(false) // 对话是否正在进行中。目前只有【发送】消息时,会更新为 true,避免切换对话、删除对话等操作,导致 stream 中断
|
|
const conversationInProgress = ref(false) // 对话是否正在进行中。目前只有【发送】消息时,会更新为 true,避免切换对话、删除对话等操作,导致 stream 中断
|
|
@@ -110,11 +193,10 @@ const enableContext = ref(true) // 是否开启上下文
|
|
|
const receiveMessageFullText = ref('')
|
|
const receiveMessageFullText = ref('')
|
|
|
const receiveMessageDisplayedText = ref('')
|
|
const receiveMessageDisplayedText = ref('')
|
|
|
|
|
|
|
|
-
|
|
|
|
|
// =========== 【聊天对话】相关 ===========
|
|
// =========== 【聊天对话】相关 ===========
|
|
|
|
|
|
|
|
/** 获取对话信息 */
|
|
/** 获取对话信息 */
|
|
|
-const getConversation = async (id) => {
|
|
|
|
|
|
|
+const getConversation = async id => {
|
|
|
if (!id) {
|
|
if (!id) {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -128,11 +210,10 @@ const getConversation = async (id) => {
|
|
|
activeConversationModelPath.value = personImage.value
|
|
activeConversationModelPath.value = personImage.value
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
// =========== 【发送消息】相关 ===========
|
|
// =========== 【发送消息】相关 ===========
|
|
|
|
|
|
|
|
/** 处理来自 keydown 的发送消息 */
|
|
/** 处理来自 keydown 的发送消息 */
|
|
|
-const handleSendByKeydown = async (event) => {
|
|
|
|
|
|
|
+const handleSendByKeydown = async event => {
|
|
|
// 判断用户是否在输入
|
|
// 判断用户是否在输入
|
|
|
if (isComposing.value) {
|
|
if (isComposing.value) {
|
|
|
return
|
|
return
|
|
@@ -161,7 +242,7 @@ const handleSendByButton = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 处理 prompt 输入变化 */
|
|
/** 处理 prompt 输入变化 */
|
|
|
-const handlePromptInput = (event) => {
|
|
|
|
|
|
|
+const handlePromptInput = event => {
|
|
|
// 非输入法 输入设置为 true
|
|
// 非输入法 输入设置为 true
|
|
|
if (!isComposing.value) {
|
|
if (!isComposing.value) {
|
|
|
// 回车 event data 是 null
|
|
// 回车 event data 是 null
|
|
@@ -190,7 +271,7 @@ const onCompositionend = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 真正执行【发送】消息操作 */
|
|
/** 真正执行【发送】消息操作 */
|
|
|
-const doSendMessage = async (content) => {
|
|
|
|
|
|
|
+const doSendMessage = async content => {
|
|
|
// 校验
|
|
// 校验
|
|
|
if (content.length < 1) {
|
|
if (content.length < 1) {
|
|
|
console.error('发送失败,原因:内容为空!')
|
|
console.error('发送失败,原因:内容为空!')
|
|
@@ -211,8 +292,7 @@ const doSendMessage = async (content) => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 真正执行【发送】消息操作 */
|
|
/** 真正执行【发送】消息操作 */
|
|
|
-const doSendMessageStream = async (userMessage) => {
|
|
|
|
|
-
|
|
|
|
|
|
|
+const doSendMessageStream = async userMessage => {
|
|
|
// 创建 AbortController 实例,以便中止请求
|
|
// 创建 AbortController 实例,以便中止请求
|
|
|
conversationInAbortController.value = new AbortController()
|
|
conversationInAbortController.value = new AbortController()
|
|
|
// 标记对话进行中
|
|
// 标记对话进行中
|
|
@@ -244,41 +324,42 @@ const doSendMessageStream = async (userMessage) => {
|
|
|
let isFirstChunk = true // 是否是第一个 chunk 消息段
|
|
let isFirstChunk = true // 是否是第一个 chunk 消息段
|
|
|
|
|
|
|
|
await sendChatMessageStream(
|
|
await sendChatMessageStream(
|
|
|
- userMessage.conversationId,
|
|
|
|
|
- userMessage.content,
|
|
|
|
|
- conversationInAbortController.value,
|
|
|
|
|
- enableContext.value,
|
|
|
|
|
- async (res) => {
|
|
|
|
|
- const { code, data, msg } = JSON.parse(res.data)
|
|
|
|
|
- if (code !== 0) {
|
|
|
|
|
- console.log(`对话异常! ${msg}`)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- // 如果内容为空,就不处理。
|
|
|
|
|
- // if (data.receive.content === '') {
|
|
|
|
|
- // return
|
|
|
|
|
- // }
|
|
|
|
|
- receiveMessageFullText.value = receiveMessageFullText.value + data.receive.content
|
|
|
|
|
- // 首次返回需要添加一个 message 到页面,后面的都是更新
|
|
|
|
|
- if (isFirstChunk) {
|
|
|
|
|
- isFirstChunk = false
|
|
|
|
|
- // 弹出两个假数据
|
|
|
|
|
- activeMessageList.value.pop()
|
|
|
|
|
- activeMessageList.value.pop()
|
|
|
|
|
- // 更新返回的数据
|
|
|
|
|
- activeMessageList.value.push(data.send)
|
|
|
|
|
- activeMessageList.value.push(data.receive)
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- (error) => {
|
|
|
|
|
- console.log(`对话异常! ${error}`)
|
|
|
|
|
- stopStream()
|
|
|
|
|
- // 需要抛出异常,禁止重试
|
|
|
|
|
- throw error
|
|
|
|
|
- },
|
|
|
|
|
- () => {
|
|
|
|
|
- stopStream()
|
|
|
|
|
|
|
+ userMessage.conversationId,
|
|
|
|
|
+ userMessage.content,
|
|
|
|
|
+ conversationInAbortController.value,
|
|
|
|
|
+ enableContext.value,
|
|
|
|
|
+ async res => {
|
|
|
|
|
+ const { code, data, msg } = JSON.parse(res.data)
|
|
|
|
|
+ if (code !== 0) {
|
|
|
|
|
+ console.log(`对话异常! ${msg}`)
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
|
|
+ // 如果内容为空,就不处理。
|
|
|
|
|
+ // if (data.receive.content === '') {
|
|
|
|
|
+ // return
|
|
|
|
|
+ // }
|
|
|
|
|
+ receiveMessageFullText.value =
|
|
|
|
|
+ receiveMessageFullText.value + data.receive.content
|
|
|
|
|
+ // 首次返回需要添加一个 message 到页面,后面的都是更新
|
|
|
|
|
+ if (isFirstChunk) {
|
|
|
|
|
+ isFirstChunk = false
|
|
|
|
|
+ // 弹出两个假数据
|
|
|
|
|
+ activeMessageList.value.pop()
|
|
|
|
|
+ activeMessageList.value.pop()
|
|
|
|
|
+ // 更新返回的数据
|
|
|
|
|
+ activeMessageList.value.push(data.send)
|
|
|
|
|
+ activeMessageList.value.push(data.receive)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ error => {
|
|
|
|
|
+ console.log(`对话异常! ${error}`)
|
|
|
|
|
+ stopStream()
|
|
|
|
|
+ // 需要抛出异常,禁止重试
|
|
|
|
|
+ throw error
|
|
|
|
|
+ },
|
|
|
|
|
+ () => {
|
|
|
|
|
+ stopStream()
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
} catch {}
|
|
} catch {}
|
|
|
}
|
|
}
|
|
@@ -319,9 +400,9 @@ const messageList = computed(() => {
|
|
|
// ============== 【消息滚动】相关 =============
|
|
// ============== 【消息滚动】相关 =============
|
|
|
|
|
|
|
|
/** 滚动到 message 底部 */
|
|
/** 滚动到 message 底部 */
|
|
|
-const scrollToBottom = async (isIgnore) => {
|
|
|
|
|
|
|
+const scrollToBottom = async isIgnore => {
|
|
|
// if (messageRef.value) {
|
|
// if (messageRef.value) {
|
|
|
- // messageRef.value.scrollToBottom(isIgnore)
|
|
|
|
|
|
|
+ // messageRef.value.scrollToBottom(isIgnore)
|
|
|
// }
|
|
// }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -339,7 +420,9 @@ const textRoll = async () => {
|
|
|
const task = async () => {
|
|
const task = async () => {
|
|
|
// 调整速度
|
|
// 调整速度
|
|
|
const diff =
|
|
const diff =
|
|
|
- (receiveMessageFullText.value.length - receiveMessageDisplayedText.value.length) / 10
|
|
|
|
|
|
|
+ (receiveMessageFullText.value.length -
|
|
|
|
|
+ receiveMessageDisplayedText.value.length) /
|
|
|
|
|
+ 10
|
|
|
if (diff > 5) {
|
|
if (diff > 5) {
|
|
|
textSpeed.value = 10
|
|
textSpeed.value = 10
|
|
|
} else if (diff > 2) {
|
|
} else if (diff > 2) {
|
|
@@ -359,7 +442,8 @@ const textRoll = async () => {
|
|
|
index++
|
|
index++
|
|
|
|
|
|
|
|
// 更新 message
|
|
// 更新 message
|
|
|
- const lastMessage = activeMessageList.value[activeMessageList.value.length - 1]
|
|
|
|
|
|
|
+ const lastMessage =
|
|
|
|
|
+ activeMessageList.value[activeMessageList.value.length - 1]
|
|
|
lastMessage.content = receiveMessageDisplayedText.value
|
|
lastMessage.content = receiveMessageDisplayedText.value
|
|
|
// 滚动到住下面
|
|
// 滚动到住下面
|
|
|
await scrollToBottom()
|
|
await scrollToBottom()
|
|
@@ -380,24 +464,24 @@ const textRoll = async () => {
|
|
|
} catch {}
|
|
} catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/** 初始化 **/
|
|
/** 初始化 **/
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
- if(personId.value) {
|
|
|
|
|
|
|
+ if (personId.value) {
|
|
|
// 智能问答
|
|
// 智能问答
|
|
|
- CreateDialogue({roleId: personId.value}).then(res => {
|
|
|
|
|
- console.log("创建会话:",res);
|
|
|
|
|
- activeConversationId.value = res.data;
|
|
|
|
|
- }).catch(error => {
|
|
|
|
|
- console.error('请求出错:', error);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ CreateDialogue({ roleId: personId.value })
|
|
|
|
|
+ .then(res => {
|
|
|
|
|
+ console.log('创建会话:', res)
|
|
|
|
|
+ activeConversationId.value = res.data
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(error => {
|
|
|
|
|
+ console.error('请求出错:', error)
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
await getConversation(personId.value)
|
|
await getConversation(personId.value)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 获取列表数据
|
|
// 获取列表数据
|
|
|
// activeMessageListLoading.value = true
|
|
// activeMessageListLoading.value = true
|
|
|
-
|
|
|
|
|
})
|
|
})
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
@@ -407,6 +491,17 @@ onMounted(async () => {
|
|
|
@function rpx($px) {
|
|
@function rpx($px) {
|
|
|
@return math.div($px, 750) * 100vw;
|
|
@return math.div($px, 750) * 100vw;
|
|
|
}
|
|
}
|
|
|
|
|
+/* 添加过渡样式 */
|
|
|
|
|
+.drawer-slide-enter-active,
|
|
|
|
|
+.drawer-slide-leave-active {
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.drawer-slide-enter-from,
|
|
|
|
|
+.drawer-slide-leave-to {
|
|
|
|
|
+ transform: translateX(-100%);
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+}
|
|
|
.home-container {
|
|
.home-container {
|
|
|
position: fixed;
|
|
position: fixed;
|
|
|
top: 0;
|
|
top: 0;
|
|
@@ -416,16 +511,81 @@ onMounted(async () => {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
flex-direction: row;
|
|
|
gap: rpx(0);
|
|
gap: rpx(0);
|
|
|
|
|
+ background: linear-gradient(to bottom, #e2ddfc, #f1effd);
|
|
|
|
|
+}
|
|
|
|
|
+.icon-expand {
|
|
|
|
|
+ width: rpx(30);
|
|
|
|
|
+ height: rpx(30);
|
|
|
|
|
+ z-index: 9999;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ cursor: pointer;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 侧边栏
|
|
|
|
|
|
|
+.icon-expand .el-icon {
|
|
|
|
|
+ font-size: rpx(15);
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ left: rpx(9);
|
|
|
|
|
+ margin-top: rpx(17);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.icon-expand .el-icon:active {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-wrapper {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+}
|
|
|
.left-group {
|
|
.left-group {
|
|
|
|
|
+ width: rpx(135);
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ background: linear-gradient(to bottom, #001169, #b4a8e1);
|
|
|
|
|
+}
|
|
|
|
|
+.mb-2 {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ margin-top: rpx(1);
|
|
|
|
|
+}
|
|
|
|
|
+.tac ::v-deep(.el-menu) {
|
|
|
|
|
+ background-color: transparent;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin-top: rpx(55);
|
|
|
|
|
+ margin-left: rpx(10);
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu-item {
|
|
|
|
|
+ width: rpx(115);
|
|
|
|
|
+ height: rpx(25);
|
|
|
|
|
+ margin-bottom: rpx(5);
|
|
|
|
|
+ border-radius: rpx(6);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: rpx(8);
|
|
|
|
|
+}
|
|
|
|
|
+.el-menu-item .el-icon svg {
|
|
|
|
|
+ font-size: rpx(15);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.el-menu ::v-deep(.el-menu-item:hover),
|
|
|
|
|
+.el-menu ::v-deep(.el-menu-item:focus),
|
|
|
|
|
+.el-menu ::v-deep(.el-menu-item:active) {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ #ffefb0,
|
|
|
|
|
+ #ffcc00
|
|
|
|
|
+ ); /* 设置悬停、聚焦、点击状态下的背景色 */
|
|
|
|
|
+ box-shadow: 0 8px 8px rgb(0, 0, 0, 0.3);
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ font-size: rpx(8);
|
|
|
|
|
+}
|
|
|
|
|
+// 侧边栏
|
|
|
|
|
+.left-group2 {
|
|
|
width: rpx(150);
|
|
width: rpx(150);
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
background-color: #ece9fd;
|
|
background-color: #ece9fd;
|
|
|
}
|
|
}
|
|
|
-.left-group img {
|
|
|
|
|
|
|
+.left-group2 img {
|
|
|
width: rpx(120);
|
|
width: rpx(120);
|
|
|
// height: auto;
|
|
// height: auto;
|
|
|
}
|
|
}
|