对话框显示原始JSON(修复前):
{
"spaceType": "入户玄关",
"spacePositioning": "该空间作为住宅的入户过渡区域...",
"layout": "空间采用单边动线布局..."
}
控制台日志:
📥 AI流式响应: string {
"spaceType": "入户玄关",
...
}
completionJSON使用流式传输逐步发送内容string类型的JSON片段JSON.parse()解析{"spaceType":"客厅","layout":"空间采用... (缺少结尾}){ > }逻辑流程:
{开头)JSON.parse()解析完整JSONextractPartialJSON()提取已完成的字段extractPartialJSON方法(新增,第488-525行):
使用正则表达式从不完整的JSON中提取已生成的字段:
private extractPartialJSON(jsonString: string): any {
const result: any = {};
const fields = [
'spaceType', 'spacePositioning', 'layout', 'hardDecoration',
'colorAnalysis', 'materials', 'form', 'style', 'suggestions'
];
for (const field of fields) {
// 匹配完整的字段值: "fieldName": "value"
const regex = new RegExp(`"${field}"\\s*:\\s*"([^"]*)"`, 'g');
const match = regex.exec(jsonString);
if (match && match[1]) {
result[field] = match[1];
console.log(`✅ 提取字段 ${field}`);
} else {
// 尝试提取不完整的值(当前正在生成中的字段)
const partialRegex = new RegExp(`"${field}"\\s*:\\s*"([^"]*?)(?:"|$)`, 's');
const partialMatch = partialRegex.exec(jsonString);
if (partialMatch && partialMatch[1] && partialMatch[1].length > 20) {
result[field] = partialMatch[1] + '...'; // 添加省略号标记
console.log(`⚠️ 提取不完整字段 ${field}`);
}
}
}
return Object.keys(result).length > 0 ? result : null;
}
提取示例:
输入(不完整JSON):
{"spaceType":"客厅","spacePositioning":"该空间定位为高端住宅的核心社交区域,兼具日常休闲与接待功能...","layout":"空间采用围合式布局,以电视背景墙为
输出(提取结果):
{
spaceType: "客厅",
spacePositioning: "该空间定位为高端住宅的核心社交区域...",
layout: "空间采用围合式布局,以电视背景墙为..."
}
代码(design-analysis-ai.service.ts 第100-131行):
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
try {
jsonObject = JSON.parse(trimmed);
console.log('✅ JSON解析成功,完整对象');
} catch (e) {
// 🔥 关键修复:JSON不完整时,提取已完整的字段并格式化显示
console.log('⚠️ JSON解析失败,尝试提取部分字段...');
jsonObject = this.extractPartialJSON(trimmed);
if (jsonObject && Object.keys(jsonObject).length > 0) {
console.log('✅ 成功提取部分字段:', Object.keys(jsonObject).join(', '));
// 继续格式化显示
} else {
displayText = '🔄 正在生成分析结果...'; // 完全无法提取时
}
}
}
// 格式化JSON对象(完整或部分)
if (jsonObject) {
displayText = this.formatJSONToText(jsonObject);
// 后备方案...
}
逻辑:
parseJSONAnalysis生成formattedContentonContentStream发送最终格式化内容代码(design-analysis-ai.service.ts 第204-208行):
// 🔥 关键:在最后发送完整的格式化内容
if (options.onContentStream && analysisData.formattedContent) {
console.log('📤 发送最终格式化内容到UI...');
options.onContentStream(analysisData.formattedContent);
}
正常流程(修复后 - 实时显示):
📥 AI流式响应: string {"spaceType":"客厅"...
🔍 检测到JSON格式字符串,尝试解析...
⚠️ JSON解析失败,尝试提取部分字段...
🔧 [extractPartialJSON] 开始提取部分JSON字段...
✅ 提取字段 spaceType: 客厅
✅ 成功提取部分字段: spaceType
🎨 开始格式化JSON对象...
→ 显示: 空间类型:客厅
(流式传输继续...)
📥 AI流式响应: string {"spaceType":"客厅","spacePositioning":"该空间定位为...
⚠️ JSON解析失败,尝试提取部分字段...
✅ 提取字段 spaceType: 客厅
✅ 提取字段 spacePositioning: 该空间定位为高端住宅的核心社交区域...
✅ 成功提取部分字段: spaceType, spacePositioning
→ 显示: 空间类型:客厅
一、空间定位与场景属性
该空间定位为...
(继续...直到完成)
📥 AI最终返回结果: {spaceType: "客厅", spacePositioning: "...", ...}
✅ JSON解析成功,完整对象
📊 解析后的分析数据: {formattedContent: "一、空间定位..."}
📤 发送最终格式化内容到UI...
→ 显示: 完整的格式化文本(8个维度)
异常情况1:JSON解析成功但格式化失败
✅ JSON解析成功
🎨 开始格式化JSON对象...
⚠️ formatJSONToText结果过短,使用fallback...
✅ [fallbackFormatJSON] 后备格式化完成,长度: 523
→ 显示格式化后的中文文本
异常情况2:花括号匹配但JSON有语法错误
⚠️ JSON解析失败,可能是流式传输中数据不完整
📊 JSON不完整: {5 vs }5 (匹配)
❌ JSON解析失败: SyntaxError: Unexpected token
→ 显示: ⚠️ AI分析结果格式异常,正在重新生成...
修复前:
对话框内容:
{
"spaceType": "入户玄关",
"spacePositioning": "该空间作为住宅的..."
}
修复后(流式传输中):
对话框内容:
🔄 正在生成分析结果...
修复后(完成):
对话框内容:
一、空间定位与场景属性
该空间作为住宅的入户过渡区域,兼具交通枢纽与形象展示功能...
二、空间布局与动线
空间采用单边动线布局,电梯井道嵌入式设置于右侧墙体结构中...
手动测试:
// 在浏览器控制台测试
const json1 = '{"spaceType":"客厅","layout":"空间采用';
const json2 = '{"spaceType":"客厅","layout":"空间采用"}';
const check = (str) => {
const open = (str.match(/\{/g) || []).length;
const close = (str.match(/\}/g) || []).length;
console.log(`{${open} vs }${close}`, open > close ? '不完整' : '完整');
};
check(json1); // {2 vs }0 不完整 ✅
check(json2); // {2 vs }2 完整 ✅
修复前:
对话框显示:
{"spaceType":"客厅","spacePositioning":"该空间定位为高端住宅...","layout":"空间采用
修复后:
对话框显示(实时更新):
空间类型:客厅
一、空间定位与场景属性
该空间定位为高端住宅的核心社交区域...
二、空间布局与动线
空间采用围合式布局...(继续生成中)
| 场景 | 修复前 | 修复后 |
|---|---|---|
| 流式传输开始 | {"spaceType":"客厅"... |
空间类型:客厅 |
| 第1个字段完成 | {"spaceType":"客厅","spacePositioning":"... |
一、空间定位与场景属性 该空间定位为... |
| 第2个字段完成 | 继续显示JSON | 二、空间布局与动线 空间采用... |
| 流式传输中 | 显示原始JSON片段 | 实时显示已生成的中文文本 ✅ |
| 完成时 | 可能显示JSON或格式化文本 | 显示完整的格式化中文文本 ✅ |
| JSON解析失败 | 显示原始JSON | 提取部分字段或显示提示 |
可能原因:
解决方案:
# 1. 重新编译
npm run build:prod
# 2. 部署
.\deploy.ps1
# 3. 清除浏览器缓存
Ctrl + Shift + Delete
可能原因:
onContentStreamanalysisData.formattedContent为空排查步骤:
parseJSONAnalysis返回的内容可能原因:
formatJSONToText、fallbackFormatJSON、beautifyJSON都失败排查步骤:
getChineseTitleForKey映射是否正确design-analysis-ai.service.ts (第100-131行)
extractPartialJSON提取部分字段design-analysis-ai.service.ts (第488-525行) 🆕
extractPartialJSON - 从不完整JSON中提取字段design-analysis-ai.service.ts (第430-482行)
formatJSONToText - 格式化为中文文本(带标题)fallbackFormatJSON - 后备格式化方案beautifyJSON - 美化JSON显示design-analysis-ai.service.ts (第290-330行)
parseJSONAnalysis - 解析JSON为结构化数据stage-requirements.component.ts (第3445-3454行)
onContentStream 回调处理创建时间: 2024-12-01 16:40 最后更新: 2024-12-01 16:50 修复状态: ✅ 实时流式显示已实现 测试状态: ⏳ 待验证