fix: enforce render-safe detail copy without screen meta labels
This commit is contained in:
parent
90d8b5e128
commit
0a693fdb7d
@ -244,6 +244,19 @@ const TITLE_META_TERMS = [
|
||||
"证据背书",
|
||||
];
|
||||
|
||||
const RENDER_META_PATTERNS: RegExp[] = [
|
||||
/第\s*\d+\s*屏/gi,
|
||||
/\bscreen\s*\d+\b/gi,
|
||||
/\bframe\s*\d+\b/gi,
|
||||
/核心机制拆解/gi,
|
||||
/机制拆解/gi,
|
||||
/差异强化/gi,
|
||||
/证据收口/gi,
|
||||
/核心收益可证/gi,
|
||||
/方案拆解/gi,
|
||||
/信任收口/gi,
|
||||
];
|
||||
|
||||
function hasPlanningTitleMeta(value: string): boolean {
|
||||
const text = String(value || "").trim();
|
||||
if (!text) return false;
|
||||
@ -259,6 +272,14 @@ function stripAgentPlanningPhrases(value: string): string {
|
||||
return result.replace(/\s+/g, " ").trim();
|
||||
}
|
||||
|
||||
function stripRenderMetaTerms(value: string): string {
|
||||
let result = String(value || "");
|
||||
for (const pattern of RENDER_META_PATTERNS) {
|
||||
result = result.replace(pattern, " ");
|
||||
}
|
||||
return result.replace(/\s+/g, " ").trim();
|
||||
}
|
||||
|
||||
function desensitizeAudienceCopy(value: string, language: "zh" | "en"): string {
|
||||
let result = String(value || "");
|
||||
if (!result) return result;
|
||||
@ -1245,6 +1266,45 @@ function sanitizePlannedScreens(
|
||||
return fallbackScreens.map((fallback, index) => sanitizeScreen(raw[index], fallback, language));
|
||||
}
|
||||
|
||||
function sanitizeScreensForRender(params: {
|
||||
screens: DetailPlanScreen[];
|
||||
coreFocus: DetailCoreFocusContext;
|
||||
language: "zh" | "en";
|
||||
}): DetailPlanScreen[] {
|
||||
const { screens, coreFocus, language } = params;
|
||||
return screens.map((screen, index) => {
|
||||
const cleanedTitle = stripRenderMetaTerms(screen.title);
|
||||
const title =
|
||||
cleanedTitle && !hasPlanningTitleMeta(cleanedTitle)
|
||||
? cleanedTitle
|
||||
: index === 0
|
||||
? coreFocus.firstScreenTitle
|
||||
: language === "zh"
|
||||
? "舒适升级"
|
||||
: "Comfort Upgrade";
|
||||
const subtitleRaw = stripRenderMetaTerms(screen.subtitle);
|
||||
const subtitle =
|
||||
subtitleRaw || (index === 0 ? coreFocus.firstScreenSubtitle : screen.subtitle);
|
||||
return {
|
||||
...screen,
|
||||
title,
|
||||
subtitle,
|
||||
objective: stripRenderMetaTerms(screen.objective),
|
||||
copy: stripRenderMetaTerms(screen.copy),
|
||||
layoutNote: stripRenderMetaTerms(screen.layoutNote),
|
||||
modelReason: stripRenderMetaTerms(screen.modelReason),
|
||||
bundleReason: stripRenderMetaTerms(screen.bundleReason),
|
||||
visualPrompt: stripRenderMetaTerms(screen.visualPrompt),
|
||||
fabe: {
|
||||
b: stripRenderMetaTerms(screen.fabe.b),
|
||||
f: stripRenderMetaTerms(screen.fabe.f),
|
||||
a: stripRenderMetaTerms(screen.fabe.a),
|
||||
e: stripRenderMetaTerms(screen.fabe.e),
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function sanitizeGlobalStyle(
|
||||
raw: unknown,
|
||||
fallback: DetailPlanResponse["globalStyle"],
|
||||
@ -1875,7 +1935,12 @@ export async function POST(request: Request) {
|
||||
|
||||
const shouldUsePreflightPlan = qualityChecksAfterPreflight.passed && preflightPassed;
|
||||
const shouldFallback = !shouldUsePreflightPlan;
|
||||
const screens = shouldFallback ? fallback.screens : preflightScreens;
|
||||
const screensRaw = shouldFallback ? fallback.screens : preflightScreens;
|
||||
const screens = sanitizeScreensForRender({
|
||||
screens: screensRaw,
|
||||
coreFocus,
|
||||
language,
|
||||
});
|
||||
const globalStyle = shouldFallback ? fallback.globalStyle : preflight.candidateGlobalStyle;
|
||||
const qualityIssuesMerged = [
|
||||
...new Set([
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user