fix(core): 代码审查修复 AI 并发/隐私/解析等多处缺陷

- AIRuntime 加 actor 内串行推理闸门,封死 LLM/VL in-flight 并发解码窄口(jetsam OOM 根因)
- prepare 的 .loading 改轮询等待消除假就绪竞态;就绪判据 isReady→isComplete 防半下载崩溃
- applyReanalyzed 重新解读时 unlink 旧 Asset,消除 Vault 孤儿图片(§6 隐私承诺)
- parseReportJSON 改 extractBalancedJSON + 裸数组兜底,防 VL 多项输出被静默截断丢指标
- 临时文件改 completeUnlessOpen 修锁屏写失败;parseDate 支持多格式防归档年份错位
- TimelineEntry/DayDetailSheet 修「偏高」文案与血压箭头方向(偏低指标不再显示相反结论)
- FileVault.wipe 容错;HealthExportSheet 异常关键词排除否定句;modelTag 取实际枚举值
- 删除 B1-B5 + ArchiveFlow 死代码(含违反 §6 的 AES 加密文案)
- 补 3 个回归测试,编译 + 测试全部通过
This commit is contained in:
link2026
2026-06-01 07:43:49 +08:00
parent 32e7c25ed7
commit bff7cfd4b6
16 changed files with 185 additions and 1204 deletions

View File

@@ -162,22 +162,22 @@ struct CaptureReviewForm: View {
.padding(.vertical, 8)
} else {
VStack(spacing: 10) {
ForEach(parsed.indicators.indices, id: \.self) { idx in
indicatorRow(idx)
ForEach($parsed.indicators) { $indicator in
indicatorRow($indicator)
}
}
}
}
}
private func indicatorRow(_ idx: Int) -> some View {
let binding = $parsed.indicators[idx]
private func indicatorRow(_ binding: Binding<ParsedReport.ParsedIndicator>) -> some View {
let id = binding.wrappedValue.id
return VStack(spacing: 8) {
HStack(spacing: 8) {
TextField("指标名", text: binding.name)
.font(.system(size: 14, weight: .medium))
Button(role: .destructive) {
parsed.indicators.remove(at: idx)
parsed.indicators.removeAll { $0.id == id }
} label: {
Image(systemName: "minus.circle.fill")
.foregroundStyle(Tj.Palette.text3)