feat:mvp
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
// API服务文件
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
import { API_CONFIG, getApiUrl } from '@/utils/config.js';
|
||||
|
||||
// 图片URL处理函数 - 处理小程序中图片路径问题
|
||||
export const getResourceUrl = (url) => {
|
||||
@@ -14,12 +15,12 @@ export const getResourceUrl = (url) => {
|
||||
|
||||
// 如果是相对路径,拼接完整的服务器地址
|
||||
if (url.startsWith('/file/')) {
|
||||
return BASE_URL + url;
|
||||
return API_CONFIG.BASE_URL + url;
|
||||
}
|
||||
|
||||
// 如果是其他相对路径,也拼接服务器地址
|
||||
if (url.startsWith('/')) {
|
||||
return BASE_URL + url;
|
||||
return API_CONFIG.BASE_URL + url;
|
||||
}
|
||||
|
||||
// 默认返回原路径
|
||||
@@ -73,9 +74,6 @@ export const cleanText = (text) => {
|
||||
return cleaned;
|
||||
};
|
||||
|
||||
// 基础配置
|
||||
const BASE_URL = 'http://192.168.1.2:8091'; // 根据后端地址调整
|
||||
|
||||
// 检查用户登录状态
|
||||
const checkLoginStatus = () => {
|
||||
const userStore = useUserStore();
|
||||
@@ -111,7 +109,7 @@ const request = (options) => {
|
||||
|
||||
// 默认配置
|
||||
const defaultOptions = {
|
||||
url: BASE_URL + options.url,
|
||||
url: getApiUrl(options.url),
|
||||
method: options.method || 'GET',
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -119,7 +117,7 @@ const request = (options) => {
|
||||
...options.header
|
||||
},
|
||||
data: options.data || {},
|
||||
timeout: options.timeout || 30000
|
||||
timeout: options.timeout || API_CONFIG.TIMEOUT
|
||||
};
|
||||
|
||||
// 发送请求
|
||||
@@ -181,7 +179,7 @@ export const chatAPI = {
|
||||
console.log('发送AI聊天请求,参数:', requestData);
|
||||
|
||||
const response = await request({
|
||||
url: '/api/chat/sync',
|
||||
url: API_CONFIG.ENDPOINTS.CHAT_SYNC,
|
||||
method: 'POST',
|
||||
data: requestData
|
||||
});
|
||||
@@ -288,7 +286,7 @@ export const chatAPI = {
|
||||
asyncChat: async (params) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/api/chat/async',
|
||||
url: API_CONFIG.ENDPOINTS.CHAT_ASYNC,
|
||||
method: 'POST',
|
||||
data: {
|
||||
message: params.message,
|
||||
@@ -315,7 +313,7 @@ export const chatAPI = {
|
||||
getChatHistory: async (conversationId) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: `/api/chat/history/${conversationId}`,
|
||||
url: `${API_CONFIG.ENDPOINTS.CHAT_HISTORY}/${conversationId}`,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -336,7 +334,7 @@ export const chatAPI = {
|
||||
createConversation: async (characterId) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/api/chat/conversation',
|
||||
url: API_CONFIG.ENDPOINTS.CHAT_CONVERSATION,
|
||||
method: 'POST',
|
||||
data: {
|
||||
characterId: characterId
|
||||
@@ -360,7 +358,7 @@ export const chatAPI = {
|
||||
clearSession: async (sessionId) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: `/api/chat/session/${sessionId}`,
|
||||
url: `${API_CONFIG.ENDPOINTS.CHAT_SESSION}/${sessionId}`,
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
@@ -393,7 +391,7 @@ export const chatAPI = {
|
||||
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/message/history',
|
||||
url: API_CONFIG.ENDPOINTS.MESSAGE_HISTORY,
|
||||
method: 'GET',
|
||||
data: {
|
||||
sessionId: sessionId
|
||||
@@ -451,7 +449,7 @@ export const voiceAPI = {
|
||||
console.log('开始文本转语音:', text);
|
||||
|
||||
const response = await request({
|
||||
url: '/api/chat/tts',
|
||||
url: API_CONFIG.ENDPOINTS.TTS,
|
||||
method: 'POST',
|
||||
data: {
|
||||
text: text,
|
||||
@@ -506,7 +504,7 @@ export const voiceAPI = {
|
||||
console.log('开始对话+语音合成:', message);
|
||||
|
||||
const response = await request({
|
||||
url: '/api/chat/answer-tts',
|
||||
url: API_CONFIG.ENDPOINTS.ANSWER_TTS,
|
||||
method: 'POST',
|
||||
data: {
|
||||
message: message,
|
||||
@@ -569,7 +567,7 @@ export const voiceAPI = {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
uni.uploadFile({
|
||||
url: BASE_URL + '/api/chat/voice-chat',
|
||||
url: getApiUrl(API_CONFIG.ENDPOINTS.VOICE_CHAT),
|
||||
filePath: filePath,
|
||||
name: 'audio',
|
||||
header: authHeader ? {
|
||||
@@ -695,7 +693,7 @@ export const voiceAPI = {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
uni.uploadFile({
|
||||
url: BASE_URL + '/api/chat/upload-voice-chat',
|
||||
url: getApiUrl(API_CONFIG.ENDPOINTS.UPLOAD_VOICE_CHAT),
|
||||
filePath: filePath,
|
||||
name: 'audio',
|
||||
header: authHeader ? {
|
||||
@@ -817,7 +815,7 @@ export const rechargeAPI = {
|
||||
getUserBalance: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/api/recharge/balance',
|
||||
url: API_CONFIG.ENDPOINTS.RECHARGE_BALANCE,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -838,7 +836,7 @@ export const rechargeAPI = {
|
||||
createRechargeOrder: async (orderData) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/api/recharge/create-order',
|
||||
url: API_CONFIG.ENDPOINTS.RECHARGE_CREATE_ORDER,
|
||||
method: 'POST',
|
||||
data: {
|
||||
amount: orderData.amount,
|
||||
@@ -864,7 +862,7 @@ export const rechargeAPI = {
|
||||
getOrderStatus: async (orderId) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: `/api/recharge/order-status/${orderId}`,
|
||||
url: `${API_CONFIG.ENDPOINTS.RECHARGE_ORDER_STATUS}/${orderId}`,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -885,7 +883,7 @@ export const rechargeAPI = {
|
||||
getRechargeHistory: async (params = {}) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/api/recharge/history',
|
||||
url: API_CONFIG.ENDPOINTS.RECHARGE_HISTORY,
|
||||
method: 'GET',
|
||||
data: {
|
||||
page: params.page || 1,
|
||||
@@ -915,7 +913,7 @@ export const roleAPI = {
|
||||
getRoles: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/role/query',
|
||||
url: API_CONFIG.ENDPOINTS.ROLE_QUERY,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -936,7 +934,7 @@ export const roleAPI = {
|
||||
getRoleById: async (roleId) => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: `/api/role/query?roleId=${roleId}`,
|
||||
url: `${API_CONFIG.ENDPOINTS.ROLE_DETAIL}?roleId=${roleId}`,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -960,7 +958,7 @@ export const configAPI = {
|
||||
getAllConfigs: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/config/query',
|
||||
url: API_CONFIG.ENDPOINTS.CONFIG_QUERY,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -981,7 +979,7 @@ export const configAPI = {
|
||||
getModels: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/config/models',
|
||||
url: API_CONFIG.ENDPOINTS.CONFIG_MODELS,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -1002,7 +1000,7 @@ export const configAPI = {
|
||||
getSTTConfigs: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/config/stt',
|
||||
url: API_CONFIG.ENDPOINTS.CONFIG_STT,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -1023,7 +1021,7 @@ export const configAPI = {
|
||||
getTemplates: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/config/templates',
|
||||
url: API_CONFIG.ENDPOINTS.CONFIG_TEMPLATES,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
@@ -1044,7 +1042,7 @@ export const configAPI = {
|
||||
getTTSConfigs: async () => {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/app/config/tts',
|
||||
url: API_CONFIG.ENDPOINTS.CONFIG_TTS,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
|
||||
63
src/utils/config.js
Normal file
63
src/utils/config.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// API配置统一管理
|
||||
export const API_CONFIG = {
|
||||
// 基础API地址
|
||||
BASE_URL: 'https://api.aixsy.com.cn',
|
||||
|
||||
// 其他服务地址(如果需要)
|
||||
WEB_URL: 'https://www.aixsy.com.cn',
|
||||
|
||||
// API端点
|
||||
ENDPOINTS: {
|
||||
// 登录相关
|
||||
LOGIN: '/app/login',
|
||||
LOGOUT: '/app/logout',
|
||||
|
||||
// 聊天相关
|
||||
CHAT_SYNC: '/api/chat/sync',
|
||||
CHAT_ASYNC: '/api/chat/async',
|
||||
CHAT_HISTORY: '/api/chat/history',
|
||||
CHAT_CONVERSATION: '/api/chat/conversation',
|
||||
CHAT_SESSION: '/api/chat/session',
|
||||
MESSAGE_HISTORY: '/app/message/history',
|
||||
|
||||
// 语音相关
|
||||
TTS: '/api/chat/tts',
|
||||
ANSWER_TTS: '/api/chat/answer-tts',
|
||||
VOICE_CHAT: '/api/chat/voice-chat',
|
||||
UPLOAD_VOICE_CHAT: '/api/chat/upload-voice-chat',
|
||||
|
||||
// 充值相关
|
||||
RECHARGE_BALANCE: '/api/recharge/balance',
|
||||
RECHARGE_CREATE_ORDER: '/api/recharge/create-order',
|
||||
RECHARGE_ORDER_STATUS: '/api/recharge/order-status',
|
||||
RECHARGE_HISTORY: '/api/recharge/history',
|
||||
|
||||
// 角色相关
|
||||
ROLE_QUERY: '/app/role/query',
|
||||
ROLE_DETAIL: '/api/role/query',
|
||||
|
||||
// 配置相关
|
||||
CONFIG_QUERY: '/app/config/query',
|
||||
CONFIG_MODELS: '/app/config/models',
|
||||
CONFIG_STT: '/app/config/stt',
|
||||
CONFIG_TEMPLATES: '/app/config/templates',
|
||||
CONFIG_TTS: '/app/config/tts'
|
||||
},
|
||||
|
||||
// 请求超时时间(毫秒)
|
||||
TIMEOUT: 30000,
|
||||
|
||||
// 登录超时时间(毫秒)
|
||||
LOGIN_TIMEOUT: 10000
|
||||
};
|
||||
|
||||
// 导出完整的API URL构建函数
|
||||
export const getApiUrl = (endpoint) => {
|
||||
return API_CONFIG.BASE_URL + endpoint;
|
||||
};
|
||||
|
||||
// 导出Web URL构建函数(用于登出等特殊接口)
|
||||
export const getWebUrl = (endpoint) => {
|
||||
return API_CONFIG.WEB_URL + endpoint;
|
||||
};
|
||||
|
||||
388
src/utils/unreadMessages.js
Normal file
388
src/utils/unreadMessages.js
Normal file
@@ -0,0 +1,388 @@
|
||||
/**
|
||||
* 未读消息管理模块
|
||||
*/
|
||||
|
||||
// 存储键名
|
||||
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<String>} 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 };
|
||||
Reference in New Issue
Block a user