From 2f6e3503ae12251c8b04e0c91a36ffb5f5ce8b08 Mon Sep 17 00:00:00 2001 From: MDSMO Date: Mon, 4 Aug 2025 15:26:00 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=AD=A6=E5=B7=A5=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=89=8D=E7=AB=AF=E9=A1=B5=E9=9D=A2=E5=92=8C?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E5=B7=A5=E4=BD=9C=E5=8F=B0=E6=88=91=E7=9A=84?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=A8=A1=E5=9D=97=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/routine/NotificationManagement.js | 64 +++ src/views/Home/index-new-blue.vue | 385 +++++++++++++++++- .../routine/NotificationManagement/index.vue | 344 ++++++++++++++++ 3 files changed, 773 insertions(+), 20 deletions(-) create mode 100644 src/api/routine/NotificationManagement.js create mode 100644 src/views/routine/NotificationManagement/index.vue diff --git a/src/api/routine/NotificationManagement.js b/src/api/routine/NotificationManagement.js new file mode 100644 index 0000000..cfa3e7f --- /dev/null +++ b/src/api/routine/NotificationManagement.js @@ -0,0 +1,64 @@ +import request from '@/utils/request' + +// 查询通知管理列表 +export function listNotificationManagement(query) { + return request({ + url: '/routine/NotificationManagement/my-sent', + method: 'get', + params: query + }) +} + +// 查询通知管理详细 +export function getNotificationManagement(id) { + return request({ + url: '/routine/NotificationManagement/' + id, + method: 'get' + }) +} + +// 新增通知管理 +export function addNotificationManagement(data) { + return request({ + url: '/routine/NotificationManagement/add', + method: 'post', + data: data + }) +} + +// 修改通知管理 +export function updateNotificationManagement(data) { + return request({ + url: '/routine/NotificationManagement/update', + method: 'post', + data: data + }) +} + +// 删除通知管理 +export function delNotificationManagement(id) { + return request({ + url: '/routine/NotificationManagement/' + id, + method: 'post' + }) +} + +// 获取年级列表 +export function getGradeList() { + return request({ + url: '/routine/NotificationManagement/gradeList', + method: 'get' + }) +} + +// 按年级发送通知 +export function sendNotificationByGrades(data) { + return request({ + url: '/routine/NotificationManagement/sendByGrades', + method: 'post', + data: data + }) +} + + + diff --git a/src/views/Home/index-new-blue.vue b/src/views/Home/index-new-blue.vue index 6274453..fd63cce 100644 --- a/src/views/Home/index-new-blue.vue +++ b/src/views/Home/index-new-blue.vue @@ -8,57 +8,57 @@
-
姓名:
+
姓名:
{{ user.nickName }}
-
用户名称:
+
用户名称:
{{ user.userName }}
-
手机号码:
+
手机号码:
{{ user.phonenumber }}
-
用户邮箱:
+
用户邮箱:
{{ user.email }}
-
所属角色:
+
所属角色:
{{ displayRole(roleGroup) }}
-
+
我的消息
-
更多 >
+
更多 >
-
+
{{ v.content }}
-
- +
-
+
公示栏
-
更多 >
+
更多 >
-
+
{{ v.submitterName }}--{{ v.projectName }} -- 审核通过
{{ formatTime(v.createTime) }}
@@ -236,8 +236,107 @@
+ + + +
+ + + + + + + + +
+ +

暂无消息数据

+
+
+
+ + + +
+ + + + + + + + + + + + +
+ +

暂无公示数据

+
+
+
+ + +
+
+
+

消息详情

+
+ {{ formatTime(currentMessageDetail.createTime) }} +
+ +
+
+
+
{{ currentMessageDetail.content || '暂无内容' }}
+
+
+
+
+ + +
+
+
+

公示详情

+
+ {{ formatTime(currentAnnouncementDetail.createTime) }} +
+ +
+
+
+
{{ currentAnnouncementDetail.projectName || '暂无项目名称' }} - {{ currentAnnouncementDetail.submitterName || '暂无提交人' }} - 审核通过
+
+
+
+
+ + \ No newline at end of file diff --git a/src/views/routine/NotificationManagement/index.vue b/src/views/routine/NotificationManagement/index.vue new file mode 100644 index 0000000..70fc32d --- /dev/null +++ b/src/views/routine/NotificationManagement/index.vue @@ -0,0 +1,344 @@ + + + From dddb8961eb7ad45d4194598f8b936c34fdc600dc Mon Sep 17 00:00:00 2001 From: firefly <1633489380@qq.com> Date: Mon, 11 Aug 2025 18:03:30 +0800 Subject: [PATCH 2/5] =?UTF-8?q?ai=E8=BE=85=E5=AF=BC=E5=91=98=E7=9A=84?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=81=8A=E5=A4=A9=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/aitutor/chat.js | 85 +++ src/views/aitutor/chathistory/index.vue | 273 +++++++ src/views/aitutor/chattest/index.vue | 671 ++++++++++++++++++ .../psychological-earlywarning/index.vue | 0 vue.config.js | 2 +- 5 files changed, 1030 insertions(+), 1 deletion(-) create mode 100644 src/api/aitutor/chat.js create mode 100644 src/views/aitutor/chathistory/index.vue create mode 100644 src/views/aitutor/chattest/index.vue create mode 100644 src/views/aitutor/psychological-earlywarning/index.vue diff --git a/src/api/aitutor/chat.js b/src/api/aitutor/chat.js new file mode 100644 index 0000000..15eff17 --- /dev/null +++ b/src/api/aitutor/chat.js @@ -0,0 +1,85 @@ +import request from '@/utils/request'; + +/** + * 获取会话列表 + * @param {Object} params - 请求参数 + * @param {number} params.user - 用户ID + * @returns {Promise} + */ +export function getConversationList(params) { + return request({ + url: '/aitutor/aichat/conversations', + method: 'get', + params + }); +} + +/** + * 发送消息 + * @param {Object} data - 请求体 + * @param {string} data.query - 查询内容 + * @param {string} [data.conversation_id] - 会话ID + * @param {number} data.user - 用户ID + * @param {number} data.user_id - 用户ID + * @param {string} data.user_name - 用户名 + * @param {string} data.user_role - 用户角色 + * @param {string} data.user_token - 用户token + * @returns {Promise} + */ +export function sendMessage(data) { + return request({ + url: '/aitutor/aichat/stream', + method: 'post', + data, + headers: { + 'Accept': 'text/event-stream' + } + }); +} + +/** + * 提交反馈 + * @param {Object} data - 请求体 + * @param {string} data.message_id - 消息ID + * @param {number} data.user_id - 用户ID + * @param {string} data.rating - 评分('like'或'dislike') + * @param {string} [data.content] - 反馈内容 + * @returns {Promise} + */ +export function submitFeedback(data) { + return request({ + url: '/aitutor/aichat/feedback', + method: 'post', + data + }); +} + +/** + * 获取反馈列表 + * @param {Object} params - 请求参数 + * @param {string} params.conversation_id - 会话ID + * @param {number} params.user_id - 用户ID + * @returns {Promise} + */ +export function getFeedbacks(params) { + return request({ + url: '/aitutor/aichat/app/feedbacks', + method: 'get', + params + }); +} + +/** + * 获取历史消息 + * @param {Object} params - 请求参数 + * @param {string} params.conversation_id - 会话ID + * @param {number} params.user - 用户ID + * @returns {Promise} + */ +export function getHistoryMessages(params) { + return request({ + url: '/aitutor/aichat/history', + method: 'get', + params + }); +} \ No newline at end of file diff --git a/src/views/aitutor/chathistory/index.vue b/src/views/aitutor/chathistory/index.vue new file mode 100644 index 0000000..1cf4cf4 --- /dev/null +++ b/src/views/aitutor/chathistory/index.vue @@ -0,0 +1,273 @@ + + + + + \ No newline at end of file diff --git a/src/views/aitutor/chattest/index.vue b/src/views/aitutor/chattest/index.vue new file mode 100644 index 0000000..e9f8884 --- /dev/null +++ b/src/views/aitutor/chattest/index.vue @@ -0,0 +1,671 @@ + + + + + + + \ No newline at end of file diff --git a/src/views/aitutor/psychological-earlywarning/index.vue b/src/views/aitutor/psychological-earlywarning/index.vue new file mode 100644 index 0000000..e69de29 diff --git a/vue.config.js b/vue.config.js index 94899a3..7f746b0 100644 --- a/vue.config.js +++ b/vue.config.js @@ -36,7 +36,7 @@ module.exports = { // detail: https://cli.vuejs.org/config/#devserver-proxy `http://124.70.202.11:8085` https://wap.wzzyhp.com [process.env.VUE_APP_BASE_API]: { // target: 'http://172.16.96.111:8585', //`http://zhxg.gxsdxy.cn`,`https://wap.wzzyhp.com`, http://localhost:8085 http://zhxgjava.gxsdxy.cn - target: 'http://localhost:8085',// `http://zhxg.gxsdxy.cn`,`https://wap.wzzyhp.com`, http://localhost:8085 http://zhxgjava.gxsdxy.cn + target: 'http://localhost:8088',// `http://zhxg.gxsdxy.cn`,`https://wap.wzzyhp.com`, http://localhost:8085 http://zhxgjava.gxsdxy.cn //target:`http://zhxg.gxsdxy.cn`, changeOrigin: true, pathRewrite: { From ad477813f3806390562b9eed65a9ca31eaa0356a Mon Sep 17 00:00:00 2001 From: MDSMO Date: Tue, 12 Aug 2025 17:36:08 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=AD=A6=E5=B7=A5=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=89=8D=E7=AB=AF=E9=A1=B5=E9=9D=A2=E7=9A=84?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E7=94=A8=E4=BA=8E=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=EF=BC=8C=E5=AF=B9=E6=95=B4=E4=B8=AA=E5=B9=B4?= =?UTF-8?q?=E7=BA=A7=E5=8F=91=E9=80=81=E7=9A=84=E9=80=9A=E7=9F=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=92=8C=E5=88=A0=E9=99=A4;=E7=BB=99=E5=AD=A6?= =?UTF-8?q?=E7=94=9F=E8=AF=81=E6=8F=90=E4=BA=A4=E6=B5=81=E7=A8=8B=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=AE=8C=E6=88=90=E5=88=B6=E4=BD=9C=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E7=9A=84=E5=89=8D=E7=AB=AF=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/routine/NotificationManagement.js | 21 +- src/api/routine/stuIdReissue.js | 18 +- src/api/routine/stuMultiLevelReview.js | 10 + src/api/stuCQS/process-center/msg.js | 8 + src/utils/request.js | 23 ++ .../routine/NotificationManagement/index.vue | 154 ++++------ src/views/routine/stuIdReissue/index.vue | 262 +++++++++++++++--- .../routine/stuIdReissue/reissuerLIst.vue | 15 +- .../routine/stuMultiLevelReview/index.vue | 111 +++++++- 9 files changed, 485 insertions(+), 137 deletions(-) diff --git a/src/api/routine/NotificationManagement.js b/src/api/routine/NotificationManagement.js index cfa3e7f..3a522be 100644 --- a/src/api/routine/NotificationManagement.js +++ b/src/api/routine/NotificationManagement.js @@ -3,7 +3,7 @@ import request from '@/utils/request' // 查询通知管理列表 export function listNotificationManagement(query) { return request({ - url: '/routine/NotificationManagement/my-sent', + url: '/routine/NotificationManagement/list', method: 'get', params: query }) @@ -43,6 +43,15 @@ export function delNotificationManagement(id) { }) } +// 批量修改通知管理 +export function batchUpdateNotificationManagement(data) { + return request({ + url: '/routine/NotificationManagement/batchUpdate', + method: 'post', + data: data + }) +} + // 获取年级列表 export function getGradeList() { return request({ @@ -60,5 +69,15 @@ export function sendNotificationByGrades(data) { }) } +// 查询当前用户发送的通知列表 +export function listMySentNotifications(query) { + return request({ + url: '/routine/NotificationManagement/my-sent', + method: 'get', + params: query + }) +} + + diff --git a/src/api/routine/stuIdReissue.js b/src/api/routine/stuIdReissue.js index a29c454..a958f8a 100644 --- a/src/api/routine/stuIdReissue.js +++ b/src/api/routine/stuIdReissue.js @@ -90,7 +90,23 @@ export function updateStuIdReissue(data) { // 删除学生证补办 export function delStuIdReissue(id) { return request({ - url: '/routine/stuIdReissue/' + id, + url: '/routine/stuIdReissue/cancel/' + id, + method: 'post' + }) +} + +// 获取学生证补办审核状态 +export function getStuIdReissueStatus(stuNo) { + return request({ + url: '/routine/stuIdReissue/getStatus/' + stuNo, + method: 'get' + }) +} + +// 完成制作 +export function completedStuIdReissue(id) { + return request({ + url: '/routine/stuIdReissue/completed/' + id, method: 'post' }) } diff --git a/src/api/routine/stuMultiLevelReview.js b/src/api/routine/stuMultiLevelReview.js index dbbd79f..9f6c3aa 100644 --- a/src/api/routine/stuMultiLevelReview.js +++ b/src/api/routine/stuMultiLevelReview.js @@ -54,3 +54,13 @@ export function delStuMultiLevelReview(id) { method: 'post' }) } + + +// 更新审核信息并同时更新学生证补办状态 +export function updateStuMultiLevelReviewWithStuIdReissue(data) { + return request({ + url: '/routine/stuMultiLevelReview/updateWithStuIdReissue', + method: 'post', + data: data + }) +} diff --git a/src/api/stuCQS/process-center/msg.js b/src/api/stuCQS/process-center/msg.js index c81ac02..680ee8e 100644 --- a/src/api/stuCQS/process-center/msg.js +++ b/src/api/stuCQS/process-center/msg.js @@ -45,3 +45,11 @@ export function delMsg(id) { method: 'post' }) } + +// 根据学号查询用户ID +export function getUserIdByStuNo(stuNo) { + return request({ + url: '/system/msg/getUserIdByStuNo/' + stuNo, + method: 'get' + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 2608e5f..a108cdd 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -112,8 +112,31 @@ service.interceptors.response.use(res => { }, error => { console.log('err' + error) + + // 判断是否是请求取消错误 + const isCanceled = error && ( + error.code === 'ERR_CANCELED' || + error.code === 'ECONNABORTED' || + error.message === 'canceled' || + error.message === 'Cancel' || + error.__CANCEL__ === true || + (typeof error.message === 'string' && /cancel/i.test(error.message)) + ); + + // 如果是请求取消,直接返回,不显示错误消息 + if (isCanceled) { + console.log('请求被取消,忽略该错误'); + return Promise.reject(error); + } + let { message } = error; if (message == "Network Error") { + // 进一步判断是否真的是网络错误,还是页面卸载导致的 + if (window.performance && window.performance.navigation.type === 1) { + // 页面刷新导致的,忽略 + console.log('页面刷新导致的网络错误,已忽略'); + return Promise.reject(error); + } message = "后端接口连接异常"; Message({ message: message, type: 'error', duration: 5 * 1000 }) } else if (message.includes("timeout")) { diff --git a/src/views/routine/NotificationManagement/index.vue b/src/views/routine/NotificationManagement/index.vue index 70fc32d..29de064 100644 --- a/src/views/routine/NotificationManagement/index.vue +++ b/src/views/routine/NotificationManagement/index.vue @@ -2,12 +2,7 @@
- + 搜索 @@ -17,46 +12,20 @@ - 新增 + 新增 - 修改 + 修改 - 删除 + 删除 - 导出 + 导出 @@ -64,35 +33,21 @@ - + + - - + + @@ -103,31 +58,22 @@ 按年级发送 - + - - - + + + - - - + + + + + + + +
+ + +
+ + 加载更多历史消息 + + +
+ + 已经到底了 + +
+
@@ -149,6 +169,7 @@ import { listStudent, getClassName } from "@/api/stuCQS/basedata/student"; import { getMessagesToAdmin } from "@/api/aitutor/chat"; import { listGrade } from "@/api/stuCQS/basedata/grade"; import { getDeptName } from "@/api/system/dept"; +import { marked } from 'marked'; export default { name: "ChatHistory", @@ -186,7 +207,11 @@ export default { dialogVisible: false, chatMessages: [], chatLoading: false, - currentStudent: null + currentStudent: null, + // 分页加载相关 + loadMoreLoading: false, + hasMoreMessages: true, + isLoadingMore: false }; }, created() { @@ -264,13 +289,24 @@ export default { this.chatLoading = true; this.chatMessages = []; + // 重置分页状态 + this.hasMoreMessages = true; + this.isLoadingMore = false; + this.loadMoreLoading = false; + getMessagesToAdmin({ - user: row.stuNo + user: row.stuNo, + limit: 20 }).then(response => { console.log('对话记录API响应:', response); if (response.code === 200 && response.data && response.data.data) { - this.chatMessages = response.data.data; + // 按照created_at时间戳进行降序排序,最新的消息在最上面 + this.chatMessages = response.data.data.sort((a, b) => b.created_at - a.created_at); + // 如果返回的消息数量少于20条,说明没有更多消息了 + if (response.data.data.length < 20) { + this.hasMoreMessages = false; + } } else { this.$modal.msgWarning(response.msg || '该学生暂无对话记录'); } @@ -287,6 +323,95 @@ export default { this.dialogVisible = false; this.currentStudent = null; this.chatMessages = []; + // 重置分页状态 + this.hasMoreMessages = true; + this.isLoadingMore = false; + this.loadMoreLoading = false; + }, + /** 加载更多历史消息 */ + loadMoreMessages() { + if (this.loadMoreLoading || !this.hasMoreMessages || this.chatMessages.length === 0) { + return; + } + + this.loadMoreLoading = true; + this.isLoadingMore = true; + + // 获取当前消息列表中最早的消息ID(created_at最小的) + const earliestMessage = this.chatMessages.reduce((earliest, current) => { + return current.created_at < earliest.created_at ? current : earliest; + }); + + getMessagesToAdmin({ + user: this.currentStudent.stuNo, + limit: 50, + firstId: earliestMessage.id + }).then(response => { + console.log('加载更多消息API响应:', response); + + if (response.code === 200 && response.data && response.data.data) { + const newMessages = response.data.data; + + if (newMessages.length === 0) { + // 没有更多消息了 + this.hasMoreMessages = false; + this.$message.info('已经到底了'); + } else { + // 将新消息按时间排序后添加到现有消息列表的底部 + const sortedNewMessages = newMessages.sort((a, b) => b.created_at - a.created_at); + this.chatMessages = [...this.chatMessages, ...sortedNewMessages]; + + // 如果返回的消息数量少于50条,说明没有更多消息了 + if (newMessages.length < 50) { + this.hasMoreMessages = false; + } + } + } else { + this.$message.error('加载更多消息失败'); + } + + this.loadMoreLoading = false; + this.isLoadingMore = false; + }).catch(error => { + console.error('加载更多消息失败:', error); + this.$message.error('加载更多消息失败'); + this.loadMoreLoading = false; + this.isLoadingMore = false; + }); + }, + /** 渲染Markdown内容 */ + renderMarkdown(content) { + if (!content) return ''; + + // 配置marked选项 + marked.setOptions({ + breaks: true, // 支持换行 + gfm: true, // 支持GitHub风格的markdown + sanitize: false // 允许HTML标签 + }); + + // 自定义渲染器,为链接添加新标签页打开属性和内联样式 + const renderer = new marked.Renderer(); + renderer.link = function(href, title, text) { + const titleAttr = title ? ` title="${title}"` : ''; + // 直接使用内联样式来确保样式生效,绕过CSS优先级问题 + const inlineStyle = ` + color: #1890ff !important; + background: linear-gradient(135deg, rgba(24, 144, 255, 0.1) 0%, rgba(64, 158, 255, 0.1) 100%) !important; + border: 1px solid rgba(24, 144, 255, 0.3) !important; + border-radius: 4px !important; + padding: 2px 6px !important; + text-decoration: none !important; + display: inline-block !important; + margin: 0 2px !important; + transition: all 0.3s ease !important; + position: relative !important; + font-weight: 500 !important; + `; + return `${text}`; + }; + + return marked(content, { renderer }); } } }; @@ -582,4 +707,171 @@ export default { .chat-content::-webkit-scrollbar-thumb:hover { background: #a8a8a8; } + +/* Markdown样式 */ +.ai-text h1, .ai-text h2, .ai-text h3, .ai-text h4, .ai-text h5, .ai-text h6 { + margin: 16px 0 8px 0; + font-weight: 600; + line-height: 1.4; +} + +.ai-text h1 { + font-size: 1.5em; + color: #303133; + border-bottom: 2px solid #e4e7ed; + padding-bottom: 8px; +} + +.ai-text h2 { + font-size: 1.3em; + color: #409eff; +} + +.ai-text h3 { + font-size: 1.2em; + color: #606266; +} + +.ai-text h4, .ai-text h5, .ai-text h6 { + font-size: 1.1em; + color: #909399; +} + +.ai-text p { + margin: 8px 0; + line-height: 1.6; +} + +.ai-text code { + background: #f5f5f5; + border: 1px solid #e4e7ed; + border-radius: 3px; + padding: 2px 6px; + font-family: 'Courier New', Consolas, monospace; + font-size: 0.9em; + color: #e74c3c; +} + +.ai-text pre { + background: #2d3748; + color: #e2e8f0; + border-radius: 6px; + padding: 16px; + margin: 12px 0; + overflow-x: auto; + font-family: 'Courier New', Consolas, monospace; + font-size: 0.9em; + line-height: 1.4; +} + +.ai-text pre code { + background: transparent; + border: none; + padding: 0; + color: inherit; + font-size: inherit; +} + +.ai-text ul, .ai-text ol { + margin: 8px 0; + padding-left: 24px; +} + +.ai-text li { + margin: 4px 0; + line-height: 1.6; +} + +.ai-text ul li { + list-style-type: disc; +} + +.ai-text ol li { + list-style-type: decimal; +} + +.ai-text blockquote { + border-left: 4px solid #409eff; + background: #f8f9fa; + margin: 12px 0; + padding: 12px 16px; + color: #606266; + font-style: italic; +} + + + +.ai-text table { + border-collapse: collapse; + width: 100%; + margin: 12px 0; +} + +.ai-text th, .ai-text td { + border: 1px solid #e4e7ed; + padding: 8px 12px; + text-align: left; +} + +.ai-text th { + background: #f5f7fa; + font-weight: 600; +} + +.ai-text hr { + border: none; + border-top: 2px solid #e4e7ed; + margin: 16px 0; +} + +.ai-text strong { + font-weight: 600; + color: #303133; +} + +.ai-text em { + font-style: italic; + color: #606266; +} + +/* 加载更多按钮样式 */ +.load-more-container { + text-align: center; + padding: 20px; + border-top: 1px solid #e4e7ed; + margin-top: 16px; +} + +.load-more-btn { + background: linear-gradient(135deg, #409eff 0%, #1890ff 100%); + border: none; + border-radius: 6px; + padding: 8px 24px; + font-size: 14px; + font-weight: 500; + box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3); + transition: all 0.3s ease; +} + +.load-more-btn:hover { + background: linear-gradient(135deg, #66b1ff 0%, #40a9ff 100%); + box-shadow: 0 4px 8px rgba(64, 158, 255, 0.4); + transform: translateY(-1px); +} + +.no-more-messages { + margin: 16px 0; +} + +.no-more-text { + color: #909399; + font-size: 14px; + font-style: italic; + padding: 0 16px; + background: #f8f9fa; +} + +.el-divider--horizontal { + margin: 16px 0; +} \ No newline at end of file