智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

294 lines
9.6 KiB

/**
* 消息路由处理器
* 统一处理各种消息类型的跳转和展示逻辑
*/
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();