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
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();
|