Agent/utils/pidmap-store.ts
2026-08-06 22:17:39 +08:00

108 lines
3.3 KiB
TypeScript

// @ts-nocheck
import { setMaskingPidMap, clearMaskingPidMap } from '../reports/markdown.js';
const META_KEY = 'ccsparkle_pidmap_meta';
const DEFAULT_TTL_MS = 4 * 60 * 60 * 1000;
const EXPIRING_THRESHOLD_MS = 5 * 60 * 1000;
function readMeta() {
try {
const s = localStorage.getItem(META_KEY);
return s ? JSON.parse(s) : {};
} catch (e) {
return {};
}
}
function writeMeta(meta) {
try {
localStorage.setItem(META_KEY, JSON.stringify(meta));
} catch (e) {}
}
export function persist(newPidMap, opts = {}) {
if (!newPidMap || typeof newPidMap !== 'object') return;
setMaskingPidMap(newPidMap);
const now = Date.now();
const expiresAt = (typeof opts.expiresAt === 'number' && opts.expiresAt > now)
? opts.expiresAt
: (now + DEFAULT_TTL_MS);
writeMeta({ lastReturnAt: now, expiresAt });
}
export function restore() {
}
export function clear() {
try {
localStorage.removeItem(META_KEY);
} catch (e) {}
clearMaskingPidMap();
}
export function getStatus() {
const meta = readMeta();
if (!meta.expiresAt) {
return { state: 'none', remainingSec: null, expiresAt: null, lastReturnAt: meta.lastReturnAt || null };
}
const now = Date.now();
const remaining = meta.expiresAt - now;
if (remaining <= 0) {
return { state: 'expired', remainingSec: 0, expiresAt: meta.expiresAt, lastReturnAt: meta.lastReturnAt };
}
if (remaining <= EXPIRING_THRESHOLD_MS) {
return { state: 'expiring', remainingSec: Math.floor(remaining / 1000), expiresAt: meta.expiresAt, lastReturnAt: meta.lastReturnAt };
}
return { state: 'active', remainingSec: Math.floor(remaining / 1000), expiresAt: meta.expiresAt, lastReturnAt: meta.lastReturnAt };
}
export function formatStatus() {
const s = getStatus();
switch (s.state) {
case 'none':
return {
text: '映射加密:未启用',
dot: '⚪',
cls: 'none',
title: '还没查询过任何员工(profile 假名映射未建立)',
};
case 'expired':
return {
text: '映射加密:已过期',
dot: '🔴',
cls: 'expired',
title: '假名映射已过期,多轮对话反查会失败。请重新发起查询(如「查曹云飞报告」)',
};
case 'expiring': {
const min = Math.max(1, Math.ceil(s.remainingSec / 60));
return {
text: `映射加密:剩余 ${min}`,
dot: '🟡',
cls: 'expiring',
title: '即将过期,多轮对话可能失败。建议重新发起查询续期',
};
}
case 'active': {
const hours = Math.floor(s.remainingSec / 3600);
const min = Math.ceil((s.remainingSec % 3600) / 60);
const text = hours > 0
? `映射加密:剩余 ${hours} 小时 ${min}`
: `映射加密:剩余 ${min}`;
return {
text,
dot: '🟢',
cls: 'active',
title: '假名映射有效,多轮对话可正常反查',
};
}
default:
return { text: '映射加密:未知', dot: '⚪', cls: 'none', title: '' };
}
}