```
feat(AI): 集成MNN推理引擎替换MLX作为主AI运行时 - 引入MNN(alibaba) + Arm SME2 + CPU作为主AI运行时,支持A19/iPhone17的 SME2和A17的NEON加速 - 添加MLX Swift作为兜底GPU推理方案,实现双后端切换机制 - 使用单一Qwen3.5-2B多模态模型(1.2GB),替代原有的LLM+VL分离架构 - 实现InferenceEngine.current引擎选择逻辑,真机默认MNN,模拟器回退MLX - 更新AIAgent架构,通过MNNLLMBridge(ObjC++) → MNNBackend进行推理 - 修改队列机制防止并发推理导致OOM,使用信号量闸门控制显存占用 - 更新文档中的技术栈说明、模块边界和周次交付计划 ```
This commit is contained in:
@@ -38,7 +38,6 @@ private struct ProfileEditForm: View {
|
||||
@State private var healthImportDraft: HealthProfileImportDraft?
|
||||
@State private var healthImportError: String?
|
||||
@State private var isImportingHealthProfile = false
|
||||
@State private var showMedicationScan = false
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
@@ -88,9 +87,6 @@ private struct ProfileEditForm: View {
|
||||
items: $profile.allergies)
|
||||
StringListSection(title: String(appLoc: "家族史"), placeholder: String(appLoc: "如:母亲 高血压"),
|
||||
items: $profile.familyHistory)
|
||||
StringListSection(title: String(appLoc: "当前用药"), placeholder: String(appLoc: "如:缬沙坦 80mg qd"),
|
||||
items: $profile.currentMedications,
|
||||
onScan: { showMedicationScan = true })
|
||||
}
|
||||
.navigationTitle("个人资料")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -100,16 +96,6 @@ private struct ProfileEditForm: View {
|
||||
profile.updatedAt = .now
|
||||
try? ctx.save()
|
||||
}
|
||||
.fullScreenCover(isPresented: $showMedicationScan) {
|
||||
// 拍药盒 → 本地 OCR + LLM 识别 → 核对 → 统一落库:
|
||||
// 记一条「用药」日记(进记录时间线)+ 同步当前用药(去重)。
|
||||
MedicationScanFlow(
|
||||
onSave: { entries in
|
||||
MedicationArchiver.archive(entries: entries, in: ctx)
|
||||
},
|
||||
onClose: { showMedicationScan = false }
|
||||
)
|
||||
}
|
||||
.sheet(item: $healthImportDraft) { draft in
|
||||
HealthProfileImportPreviewSheet(
|
||||
draft: draft,
|
||||
@@ -468,27 +454,10 @@ private struct StringListSection: View {
|
||||
let title: String
|
||||
let placeholder: String
|
||||
@Binding var items: [String]
|
||||
/// 非 nil 时在节内显示「拍药盒自动识别」入口(目前仅「当前用药」用)。
|
||||
var onScan: (() -> Void)? = nil
|
||||
@State private var newInput = ""
|
||||
|
||||
var body: some View {
|
||||
Section(title) {
|
||||
if let onScan {
|
||||
Button(action: onScan) {
|
||||
HStack(spacing: 10) {
|
||||
Image(systemName: "camera.viewfinder")
|
||||
.foregroundStyle(Tj.Palette.ink)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("拍药盒自动识别")
|
||||
.foregroundStyle(Tj.Palette.text)
|
||||
Text("拍药盒或说明书,本地识别药名与规格")
|
||||
.font(.tjScaled( 12))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ForEach(items, id: \.self) { item in
|
||||
HStack {
|
||||
Text(item)
|
||||
|
||||
Reference in New Issue
Block a user