/** * 消息路由处理器 * 统一处理各种消息类型的跳转和展示逻辑 */ import apiRoute from '@/api/apiRoute.js' class MessageRouter { constructor() { this.routeHandlers = { 'page_navigation': this.handlePageNavigation, 'popup_with_actions': this.handlePopupWithActions, 'popup_simple': this.handlePopupSimple, 'image_preview': this.handleImagePreview }; } /** * 处理消息点击事件 * @param {Object} message 消息对象 * @param {Object} context 页面上下文 * @return {Promise} 处理结果 */ async processMessage(message, context) { try { // 先标记为已读 if (!message.is_read) { await context.markAsRead(message); } // 获取路由配置并处理 const routeResult = await this.getMessageRoute(message); if (routeResult && routeResult.success) { const { route_type, config } = routeResult; const handler = this.routeHandlers[route_type]; if (handler) { return await handler.call(this, message, config, context); } } // 默认处理:显示弹窗 return this.handlePopupSimple(message, {}, context); } catch (error) { console.error('消息路由处理失败:', error); // 降级到简单弹窗 return this.handlePopupSimple(message, {}, context); } } /** * 获取消息路由配置 * @param {Object} message 消息对象 * @return {Promise} 路由配置 */ async getMessageRoute(message) { try { // 先使用本地路由规则 const localRoute = this.getLocalRoute(message); if (localRoute.success) { return localRoute; } // 如果需要,可以调用后端API获取更复杂的路由配置 // const response = await apiRoute.getMessageRoute({ // message_id: message.id, // message_type: message.message_type // }); // // if (response && response.code === 1) { // return response.data; // } return { success: false }; } catch (error) { console.error('获取消息路由配置失败:', error); return { success: false }; } } /** * 本地路由规则 * @param {Object} message 消息对象 * @return {Object} 路由配置 */ getLocalRoute(message) { const { message_type, business_id, business_type } = message; // 有业务页面的消息类型 const pageRouteMap = { 'order': { page_path: '/pages-common/order/detail', param_key: 'id', fallback: 'popup' }, 'student_courses': { page_path: '/pages-student/courses/detail', param_key: 'id', fallback: 'popup' }, 'person_course_schedule': { page_path: '/pages-student/schedule/detail', param_key: 'id', fallback: 'popup' } }; // 需要特殊操作按钮的消息类型 const actionPopupMap = { 'notification': { actions: [ { text: '确认已读', type: 'primary', action: 'confirmRead' }, { text: '查看详情', type: 'info', action: 'viewDetail' } ] }, 'feedback': { actions: [ { text: '查看反馈', type: 'success', action: 'viewFeedback' }, { text: '回复', type: 'primary', action: 'reply' } ] }, 'reminder': { actions: [ { text: '查看课程', type: 'warning', action: 'viewCourse' }, { text: '设置提醒', type: 'info', action: 'setReminder' } ] } }; // 判断路由类型 if (pageRouteMap[message_type] && business_id) { // 页面跳转 return { success: true, route_type: 'page_navigation', config: { url: pageRouteMap[message_type].page_path + '?' + pageRouteMap[message_type].param_key + '=' + business_id, fallback: pageRouteMap[message_type].fallback } }; } else if (actionPopupMap[message_type]) { // 带操作按钮的弹窗 return { success: true, route_type: 'popup_with_actions', config: actionPopupMap[message_type] }; } else if (message_type === 'img') { // 图片预览 return { success: true, route_type: 'image_preview', config: { allow_save: true } }; } else if (message_type === 'system') { // 系统消息自动标记已读 return { success: true, route_type: 'popup_simple', config: { auto_read: true } }; } else { // 默认简单弹窗 return { success: true, route_type: 'popup_simple', config: { auto_read: false } }; } } /** * 处理页面跳转 * @param {Object} message 消息对象 * @param {Object} config 配置 * @param {Object} context 页面上下文 * @return {Promise} 处理结果 */ handlePageNavigation(message, config, context) { return new Promise((resolve) => { uni.navigateTo({ url: config.url, success: () => { console.log('页面跳转成功:', config.url); resolve({ success: true, action: 'navigate' }); }, fail: (error) => { console.warn('页面跳转失败,降级到弹窗:', error); // 降级到弹窗显示 if (config.fallback === 'popup') { context.showMessagePopup(message); } resolve({ success: true, action: 'popup_fallback' }); } }); }); } /** * 处理带操作按钮的弹窗 * @param {Object} message 消息对象 * @param {Object} config 配置 * @param {Object} context 页面上下文 * @return {Promise} 处理结果 */ handlePopupWithActions(message, config, context) { const enhancedMessage = { ...message, actionButtons: config.actions || [] }; context.showEnhancedMessageDetail(enhancedMessage); return Promise.resolve({ success: true, action: 'popup_with_actions' }); } /** * 处理简单弹窗 * @param {Object} message 消息对象 * @param {Object} config 配置 * @param {Object} context 页面上下文 * @return {Promise} 处理结果 */ handlePopupSimple(message, config, context) { context.showMessagePopup(message); return Promise.resolve({ success: true, action: 'popup_simple' }); } /** * 处理图片预览 * @param {Object} message 消息对象 * @param {Object} config 配置 * @param {Object} context 页面上下文 * @return {Promise} 处理结果 */ handleImagePreview(message, config, context) { const imageUrl = message.content || message.attachment_url; if (imageUrl && this.isImageUrl(imageUrl)) { uni.previewImage({ urls: [imageUrl], current: 0, success: () => { console.log('图片预览成功'); }, fail: (error) => { console.warn('图片预览失败,降级到弹窗:', error); this.handlePopupSimple(message, {}, context); } }); } else { // 不是图片URL,降级到普通弹窗 this.handlePopupSimple(message, {}, context); } return Promise.resolve({ success: true, action: 'image_preview' }); } /** * 判断是否为图片URL * @param {string} url * @return {boolean} */ isImageUrl(url) { if (!url) return false; const imageExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp']; const lowerUrl = url.toLowerCase(); return imageExts.some(ext => lowerUrl.includes(ext)) || lowerUrl.startsWith('data:image/'); } /** * 获取消息类型的中文描述 * @param {string} messageType 消息类型 * @return {string} 中文描述 */ getMessageTypeText(messageType) { const typeMap = { 'text': '文本消息', 'img': '图片消息', 'system': '系统消息', 'notification': '通知公告', 'homework': '作业任务', 'feedback': '反馈评价', 'reminder': '课程提醒', 'order': '订单消息', 'student_courses': '课程变动', 'person_course_schedule': '课程安排' }; return typeMap[messageType] || messageType; } } export default new MessageRouter();