fix(web): 巡检目标模板的占位符显示成名称(FIX-7)

执行时 renderGoal 已正确替换(补单测);界面显示的是模板本身,{{now}} 等改成「当前时间」标签。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-30 00:00:03 +08:00
1 parent 417af9f253
commit 23bd8cfe45
5 files changed
+97 -6

No files matched your search

@@ -129,3 +129,28 @@ export function formatClock(iso: string | null | undefined): string {
second: "2-digit",
});
}
/** 巡检目标模板的占位符(服务端 renderGoal 执行时替换);界面上显示成名称,不露 `{{now}}` */
export const GOAL_PLACEHOLDER_LABEL: Record<string, string> = {
now: "当前时间",
date: "今天日期",
openDecisions: "待处理事项数",
stalledDownloads: "异常下载数",
activeSubscriptions: "追踪中的订阅数",
};
/** 目标模板拆成文字与占位符两段(纯函数,单测覆盖);不认识的占位符原样当文字 */
export function goalTemplateParts(template: string): ({ text: string } | { placeholder: string; label: string })[] {
const out: ({ text: string } | { placeholder: string; label: string })[] = [];
let last = 0;
for (const m of template.matchAll(/\{\{\s*(\w+)\s*\}\}/g)) {
const key = m[1] ?? "";
const label = GOAL_PLACEHOLDER_LABEL[key];
if (!label) continue;
if (m.index > last) out.push({ text: template.slice(last, m.index) });
out.push({ placeholder: key, label });
last = m.index + m[0].length;
}
if (last < template.length) out.push({ text: template.slice(last) });
return out;
}