diff --git a/app/[locale]/docs/[...slug]/page.tsx b/app/[locale]/docs/[...slug]/page.tsx
index 49fbc004..f8c79764 100644
--- a/app/[locale]/docs/[...slug]/page.tsx
+++ b/app/[locale]/docs/[...slug]/page.tsx
@@ -63,7 +63,9 @@ async function resolveDocPath(
}
return null;
}
- // 非 3xx:记录真实状态,便于从 Vercel 日志定位(CF 403 / 后端异常等)
+ // 404 = 后端无历史映射,是正常的"真 404"结论,不算故障
+ if (res.status === 404) return null;
+ // 其余非 3xx:记录真实状态,便于从 Vercel 日志定位(CF 403 / 后端异常等)
console.error("[docs/resolve] non-redirect status", {
path: strippedPath,
status: res.status,
diff --git a/app/api/suggestions/route.ts b/app/api/suggestions/route.ts
index a07f1c2f..2fa23003 100644
--- a/app/api/suggestions/route.ts
+++ b/app/api/suggestions/route.ts
@@ -159,6 +159,11 @@ export async function POST(req: Request) {
// 修复大模型可能生成的中文引号
cleanedText = cleanedText.replace(/“/g, '"').replace(/”/g, '"');
+ // 修复 key 后的全角冒号 / 冒号被包进引号,如 "action:"xx" 或 "action:"xx"
+ cleanedText = cleanedText.replace(
+ /"(title|label|action)"?\s*[::]\s*"/g,
+ '"$1":"',
+ );
// 尝试仅提取数组部分,防止 AI 返回了前缀描述文本
const arrayMatch = cleanedText.match(/\[[\s\S]*\]/);
@@ -166,7 +171,22 @@ export async function POST(req: Request) {
cleanedText = arrayMatch[0];
}
- questions = JSON.parse(cleanedText);
+ try {
+ questions = JSON.parse(cleanedText);
+ } catch (parseError) {
+ // 编号列表 / 多个数组拼接等非法外壳:逐个提取对象
+ const objects = (cleanedText.match(/\{[^{}]*\}/g) ?? []).flatMap(
+ (chunk) => {
+ try {
+ return [JSON.parse(chunk)];
+ } catch {
+ return [];
+ }
+ },
+ );
+ if (objects.length === 0) throw parseError;
+ questions = objects;
+ }
} catch (e) {
console.error("解析建议 JSON 失败:", e, "原始文本:", text);
diff --git a/mdx-components.tsx b/mdx-components.tsx
index e5655539..4f6f781a 100644
--- a/mdx-components.tsx
+++ b/mdx-components.tsx
@@ -30,7 +30,15 @@ export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
// 覆盖默认的 img 映射,使用原生
标签而不是 Next.js Image 组件
- img: (props) =>
,
+ // 本地相对路径图片会被 remark-image 编译成静态 import,src 是
+ // StaticImageData 对象而不是字符串,直接透传会渲染成 "[object Object]"
+ img: ({ src, ...props }) => {
+ const resolved =
+ src && typeof src === "object" && "src" in src
+ ? (src as { src: string }).src
+ : src;
+ return
;
+ },
...components,
};
}