/** * 未读消息管理模块 */ // 存储键名 const STORAGE_KEY = 'unread_messages'; // 🎭 角色专属消息模板库 const roleMessageTemplates = { // 默认消息(当找不到角色时使用) default: [ '嗨!好久不见啦~', '最近怎么样?想你了~', '在忙吗?有空聊聊天吗?', '刚才想起你了,过来打个招呼~', '今天天气不错,心情怎么样?', '有什么新鲜事要分享吗?', '突然想和你说说话~', '你最近在忙什么呀?', ], // 小智AI助手 - 专业、贴心 1: [ '你好!我注意到你有一段时间没来了,最近工作还顺利吗?', '嗨!我刚学会了一些新技能,要不要试试看?', '想你啦!今天有什么问题需要我帮忙的吗?', '好久不见!我一直在这里等你哦~', '最近有遇到什么有趣的事情吗?跟我分享一下吧!', ], // 元气少女小樱 - 活泼、可爱 2: [ '哇!好久不见!!!想死你啦 (。♥‿♥。)', '嘿嘿,我又来找你玩啦~ 最近过得开心吗?', '今天天气超级好!要不要一起出去玩呀?', '我刚才在想你呢,你的耳朵有没有发烫呀 (≧▽≦)', '快来快来!我有好多话想跟你说~', '你猜我今天遇到什么有趣的事了?想听吗想听吗?', ], // 温柔大姐姐琳娜 - 温柔、体贴 3: [ '好久不见了呢,最近还好吗?如果累了记得休息哦~', '看到你上线真开心,要不要聊聊最近的事情?', '今天过得怎么样?如果有什么烦恼可以跟我说说~', '想你了呢,有空的话陪我聊聊天好吗?', '最近工作辛苦了吧?记得好好照顾自己~', '晚上好呀,今天发生了什么有趣的事吗?', ], // 知识博士艾伦 - 博学、严谨 4: [ '你好!我最近研究了一些有趣的课题,要不要听听看?', '好久不见!我整理了一些新的知识,或许对你有帮助。', '嗨!最近有什么想深入了解的话题吗?', '你上次提到的问题,我又做了一些研究,要听听吗?', '根据我的观察,你已经很久没来了,一切还好吗?', ], // 搞笑达人阿杰 - 幽默、风趣 5: [ '哎呦喂!终于等到你了!我的笑话都快憋坏了 hhh', '嘿兄弟!想听个新段子吗?保证笑到你肚子疼!', '你可算来了!我这里存了一堆搞笑视频等着你呢~', '好久不见!最近有啥搞笑的事儿分享一下呗?', '哟!看谁来了?我最喜欢的观众!今天表演啥好呢?', '嘿嘿,我又来了!准备好笑容,别笑掉大牙哦~', ], // 运动教练米克 - 阳光、励志 6: [ '嘿!伙计!好久不见,最近有坚持运动吗?', '来来来!今天一起训练吧,我给你设计了新的计划!', '想你了兄弟!说,是不是又偷懒了?hhh', '早上好!一日之计在于晨,要不要来个晨练?', '你可算来了!准备好出汗了吗?今天我们加大强度!', '嗨!我刚跑完10公里,感觉超棒!你呢?', ], // 心理咨询师莉莉 - 沉稳、专业 7: [ '你好,好久不见了。最近的心情还好吗?', '看到你上线真好,最近有什么想聊的吗?我在听~', '好久没见你了,如果有什么困扰可以说出来哦。', '最近过得怎么样?有什么想倾诉的吗?', '你好呀,工作和生活都还顺利吗?', '嗨,最近睡眠质量怎么样?记得好好休息~', ], // 美食家小美 - 热情、亲切 8: [ '哇!好久不见!你最近吃了什么好吃的吗?', '嘿嘿,我又发现了一家超棒的餐厅!要不要一起去?', '今天我做了好吃的,好想让你尝尝呀~', '快来快来!告诉我你最喜欢吃什么,我教你做!', '想你啦!最近有没有发现什么美食?分享一下呗~', '肚子饿了吗?我正好知道一道超简单又好吃的菜!', ], // 旅行达人安迪 - 自由、洒脱 9: [ '嘿!我刚从一个超美的地方回来,要看照片吗?', '好久不见!最近有没有想去的地方?我可以给你攻略哦~', '你上次说想去的那个地方,我去过了!超赞!', '嗨!周末有空吗?我发现了一个小众景点~', '想你了!要不要听听我最近的旅行趣事?', '好久没见!说,是不是又宅在家里了?出去走走吧~', ], // 程序员小码 - 理性、技术范 10: [ 'Hello!好久不见,最近在写什么项目?', '嘿,我刚解决了一个超有意思的算法问题,要听吗?', '你好!最近有遇到什么技术难题吗?我们可以讨论一下。', 'Hi!我发现了一个很酷的开源项目,要不要一起研究?', '好久没见了!最近在学什么新技术?', '嗨!刚看到一个有趣的bug,想分享给你~', ], }; /** * 获取所有未读消息 */ export function getAllUnreadMessages() { try { const data = uni.getStorageSync(STORAGE_KEY); return data ? JSON.parse(data) : {}; } catch (e) { console.error('获取未读消息失败:', e); return {}; } } /** * 获取指定角色的未读消息 * @param {String|Number} roleId - 角色ID */ export function getUnreadMessages(roleId) { const allMessages = getAllUnreadMessages(); return allMessages[roleId] || []; } /** * 添加单条未读消息 * @param {String|Number} roleId - 角色ID * @param {String} content - 消息内容 */ export function addUnreadMessage(roleId, content) { const allMessages = getAllUnreadMessages(); if (!allMessages[roleId]) { allMessages[roleId] = []; } const message = { id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, content: content, timestamp: Date.now(), read: false }; allMessages[roleId].push(message); try { uni.setStorageSync(STORAGE_KEY, JSON.stringify(allMessages)); console.log(`✅ 已为角色 ${roleId} 添加未读消息:`, content); return true; } catch (e) { console.error('保存未读消息失败:', e); return false; } } /** * 批量添加未读消息 * @param {String|Number} roleId - 角色ID * @param {Array} messages - 消息内容数组 */ export function addMultipleUnreadMessages(roleId, messages) { const allMessages = getAllUnreadMessages(); if (!allMessages[roleId]) { allMessages[roleId] = []; } messages.forEach(content => { const message = { id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, content: content, timestamp: Date.now(), read: false }; allMessages[roleId].push(message); }); try { uni.setStorageSync(STORAGE_KEY, JSON.stringify(allMessages)); console.log(`✅ 已为角色 ${roleId} 批量添加 ${messages.length} 条未读消息`); return true; } catch (e) { console.error('批量保存未读消息失败:', e); return false; } } /** * 清空指定角色的未读消息 * @param {String|Number} roleId - 角色ID */ export function clearUnreadMessages(roleId) { const allMessages = getAllUnreadMessages(); const count = allMessages[roleId]?.length || 0; delete allMessages[roleId]; try { uni.setStorageSync(STORAGE_KEY, JSON.stringify(allMessages)); console.log(`✅ 已清空角色 ${roleId} 的 ${count} 条未读消息`); return true; } catch (e) { console.error('清空未读消息失败:', e); return false; } } /** * 获取指定角色的未读消息数量 * @param {String|Number} roleId - 角色ID */ export function getUnreadCount(roleId) { const messages = getUnreadMessages(roleId); return messages.filter(msg => !msg.read).length; } /** * 获取所有角色的未读消息数量统计 */ export function getAllUnreadCounts() { const allMessages = getAllUnreadMessages(); const counts = {}; Object.keys(allMessages).forEach(roleId => { counts[roleId] = allMessages[roleId].filter(msg => !msg.read).length; }); return counts; } /** * 根据角色ID生成随机消息 * @param {String|Number} roleId - 角色ID * @param {String} roleName - 角色名称(可选,用于日志) */ export function generateRandomMessage(roleId, roleName = '') { // 获取该角色的消息模板 const templates = roleMessageTemplates[roleId] || roleMessageTemplates.default; // 随机选择一条消息 const randomIndex = Math.floor(Math.random() * templates.length); const message = templates[randomIndex]; console.log(`🎲 为角色 ${roleName || roleId} 随机生成消息:`, message); return message; } /** * 批量生成测试消息(用于开发调试) * @param {String|Number} roleId - 角色ID * @param {String} roleName - 角色名称 * @param {Number} count - 生成消息数量(默认1条) */ export function generateTestMessages(roleId, roleName, count = 1) { const messages = []; const templates = roleMessageTemplates[roleId] || roleMessageTemplates.default; // 随机选择不重复的消息 const usedIndexes = new Set(); for (let i = 0; i < count && i < templates.length; i++) { let randomIndex; do { randomIndex = Math.floor(Math.random() * templates.length); } while (usedIndexes.has(randomIndex) && usedIndexes.size < templates.length); usedIndexes.add(randomIndex); messages.push(templates[randomIndex]); } console.log(`🧪 为角色 ${roleName} (ID: ${roleId}) 生成 ${messages.length} 条测试消息`); return addMultipleUnreadMessages(roleId, messages); } /** * 清空所有角色的未读消息(调试用) */ export function clearAllUnreadMessages() { try { uni.removeStorageSync(STORAGE_KEY); console.log('🗑️ 已清空所有未读消息'); return true; } catch (e) { console.error('清空所有未读消息失败:', e); return false; } } /** * 为所有角色生成测试消息(调试用) * @param {Array} roleList - 角色列表 * @param {Number} messagesPerRole - 每个角色生成的消息数量 */ export function generateMessagesForAllRoles(roleList, messagesPerRole = 1) { let successCount = 0; roleList.forEach(role => { const success = generateTestMessages(role.roleId, role.roleName, messagesPerRole); if (success) successCount++; }); console.log(`🎉 已为 ${successCount}/${roleList.length} 个角色生成测试消息`); return successCount; } /** * 为随机N个角色生成消息(智能版) * @param {Array} roleList - 角色列表 * @param {Number} count - 随机选择的角色数量(默认2个) * @param {Number} messagesPerRole - 每个角色生成的消息数量(默认1条) * @param {Boolean} avoidDuplicate - 是否避免给已有未读消息的角色再次生成(默认true) */ export function autoGenerateMessagesForRandomRoles(roleList, count = 2, messagesPerRole = 1, avoidDuplicate = true) { if (!roleList || roleList.length === 0) { console.log('⚠️ 角色列表为空'); return 0; } // 获取当前所有未读消息 const allUnreadMessages = getAllUnreadMessages(); // 筛选候选角色 let candidateRoles = roleList; if (avoidDuplicate) { // 过滤掉已经有未读消息的角色 candidateRoles = roleList.filter(role => { const hasUnread = allUnreadMessages[role.roleId] && allUnreadMessages[role.roleId].length > 0; return !hasUnread; }); // 如果所有角色都有未读消息,就从全部角色中随机选择 if (candidateRoles.length === 0) { console.log('💡 所有角色都有未读消息,从全部角色中随机选择'); candidateRoles = roleList; } } // 随机选择指定数量的角色 const selectedRoles = []; const actualCount = Math.min(count, candidateRoles.length); // 使用随机抽样算法(Fisher-Yates shuffle变体) const availableIndexes = [...Array(candidateRoles.length).keys()]; for (let i = 0; i < actualCount; i++) { const randomIndex = Math.floor(Math.random() * availableIndexes.length); const roleIndex = availableIndexes.splice(randomIndex, 1)[0]; selectedRoles.push(candidateRoles[roleIndex]); } // 为选中的角色生成消息 let successCount = 0; selectedRoles.forEach(role => { const success = generateTestMessages(role.roleId, role.roleName, messagesPerRole); if (success) { console.log(` ✓ 已为 ${role.roleName} (ID: ${role.roleId}) 生成 ${messagesPerRole} 条消息`); successCount++; } }); if (successCount > 0) { console.log(`🎲 随机为 ${successCount} 个角色生成了主动消息`); } return successCount; } // 导出消息模板(用于外部查看或修改) export { roleMessageTemplates };