108 lines
3.3 KiB
TypeScript
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: '' };
|
|
}
|
|
}
|