// 回答进行中的待发送消息。队列保存在当前浏览器,按用户和 task 隔离; // 后端仍保持单活 run,由前端在上一轮收尾后串行派发。 const STORAGE_PREFIX = "zcbot.chat-queue.v1."; const MAX_PER_TASK = 20; function storageKey(userId) { return userId ? STORAGE_PREFIX + userId : ""; } function readAll(storage, userId) { const key = storageKey(userId); if (!key) return {}; try { const parsed = JSON.parse(storage.getItem(key) || "{}"); return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; } catch (_) { return {}; } } function writeAll(storage, userId, queues) { const key = storageKey(userId); if (!key) return; try { if (Object.keys(queues).length) storage.setItem(key, JSON.stringify(queues)); else storage.removeItem(key); } catch (_) { /* 本地存储不可用时不阻断当前回答 */ } } export function readQueuedMessages(storage, userId, taskId) { const items = readAll(storage, userId)[taskId]; return Array.isArray(items) ? items.filter(item => item && item.id && typeof item.content === "string") : []; } export function enqueueMessage(storage, userId, taskId, entry) { if (!taskId || !entry || !entry.id) return []; const queues = readAll(storage, userId); const items = readQueuedMessages(storage, userId, taskId); items.push(entry); queues[taskId] = items.slice(-MAX_PER_TASK); writeAll(storage, userId, queues); return queues[taskId]; } export function removeQueuedMessage(storage, userId, taskId, messageId) { const queues = readAll(storage, userId); const items = readQueuedMessages(storage, userId, taskId) .filter(item => item.id !== messageId); if (items.length) queues[taskId] = items; else delete queues[taskId]; writeAll(storage, userId, queues); return items; }