- 新增 TechInfo 折叠组件(默认收起,标题「技术信息」);设置新增「界面」分区, 「默认展开技术信息」开关存本机浏览器 - 原因码表 @umt/contracts reasons.ts(identity_unknown、blocked:target_exists、below_min_size… → 一句人话 + 下一步),服务端整理记录 message 与冲突事项标题/摘要改用它 - 整理记录列表/详情、下载详情与时间线:原码、ID、hash、用时、变更序号进技术信息; 下载完成但入库失败时单独提示;时间线只列有记录的阶段,标题改「经过」 - 待处理:没识别出作品类事项主按钮「指定作品」(搜媒体库 + TMDB,走已有 resolve; 整理类事项打开重新整理),忽略为次要;去掉正常态徽章与「实时」指示;原始证据改「详细信息」进技术信息 - 整理成功后同时关闭该下载的「没识别出作品」事项 Co-Authored-By: Claude Opus 5.5 <[email protected]>
36 lines
1.6 KiB
TypeScript
36 lines
1.6 KiB
TypeScript
import { looksLikeCode, reasonText } from "@umt/contracts";
|
|
|
|
// 原因串 → 一句人话(DEAI-2)。映射表在 @umt/contracts 的 reasons.ts,服务端与前端共用;
|
|
// 原码交给 <TechInfo> 显示,不直接给人看。
|
|
|
|
/** `{ code, message }`(整理记录 / 文件结果)或裸原因串 → 一句话;不认识的码返回 fallback */
|
|
export function reasonLine(
|
|
r: { code?: string | null; message?: string | null } | string | null | undefined,
|
|
fallback = "处理失败",
|
|
): string | null {
|
|
if (!r) return null;
|
|
const code = typeof r === "string" ? r : (r.code ?? null);
|
|
const message = typeof r === "string" ? null : (r.message ?? null);
|
|
// 服务端给的中文说明(冲突明细等)优先
|
|
if (message && !looksLikeCode(message) && message !== code) return message;
|
|
const t = reasonText(code) ?? reasonText(message);
|
|
if (t) return t.action ? `${t.text}。${t.action}` : t.text;
|
|
if (code && !looksLikeCode(code)) return code;
|
|
return fallback;
|
|
}
|
|
|
|
/** 原码(给技术信息用):只有是内部码时才返回 */
|
|
export function reasonCode(r: { code?: string | null; message?: string | null } | string | null | undefined) {
|
|
if (!r) return null;
|
|
if (typeof r === "string") return looksLikeCode(r) ? r : null;
|
|
const c = r.code ?? null;
|
|
const m = r.message ?? null;
|
|
return [c, m && looksLikeCode(m) && m !== c ? m : null].filter(Boolean).join(" · ") || null;
|
|
}
|
|
|
|
/** 原因串里的内部码替换成人话(如下载计划 statusReason、任务 waitReason) */
|
|
export function humanizeReason(v: string | null | undefined): string | null {
|
|
if (!v) return null;
|
|
return looksLikeCode(v) ? reasonLine(v, v) : v;
|
|
}
|