import SwiftUI struct A2ConfirmView: View { var onSave: () -> Void var onNext: () -> Void var onBack: () -> Void @State private var expanded = false var body: some View { VStack(spacing: 0) { header ScrollView(showsIndicators: false) { VStack(alignment: .leading, spacing: 0) { croppedPhoto.padding(.bottom, 14) resultCard.padding(.bottom, 16) actions } .padding(.horizontal, 18) .padding(.bottom, 18) } } .background(Tj.Palette.sand.ignoresSafeArea()) } private var header: some View { HStack(spacing: 6) { Button(action: onBack) { Image(systemName: "chevron.left") .font(.system(size: 18, weight: .semibold)) .foregroundStyle(Tj.Palette.text) .frame(width: 36, height: 36) } Text("核对识别结果") .font(.system(size: 15, weight: .semibold)) .foregroundStyle(Tj.Palette.text) Spacer() Text("识别用时 0.4s · 本地") .font(.system(size: 10, design: .monospaced)) .foregroundStyle(Tj.Palette.text3) .padding(.horizontal, 8) .padding(.vertical, 4) .background(Capsule().fill(Tj.Palette.sand2)) } .padding(.horizontal, 12) .padding(.top, 4) .padding(.bottom, 8) } private var croppedPhoto: some View { ZStack(alignment: .topTrailing) { Text("低密度脂蛋白 3.84 mmol/L ↑") .font(.system(size: 13, design: .monospaced)) .fontWeight(.semibold) .tracking(0.3) .foregroundStyle(Tj.Palette.text) .padding(.vertical, 14) .padding(.horizontal, 16) .frame(maxWidth: .infinity, alignment: .leading) .background(Color(red: 0.96, green: 0.93, blue: 0.87).opacity(0.92)) .clipShape(RoundedRectangle(cornerRadius: Tj.Radius.md, style: .continuous)) .shadow(color: Color(red: 0.196, green: 0.157, blue: 0.098).opacity(0.06), radius: 2, x: 0, y: 1) Text("已裁剪") .font(.system(size: 9)) .tracking(0.5) .foregroundStyle(Tj.Palette.text3) .padding(.top, 8) .padding(.trailing, 10) } } private var resultCard: some View { VStack(alignment: .leading, spacing: 14) { HStack(alignment: .top) { VStack(alignment: .leading, spacing: 4) { Text("指标名 · 可编辑") .font(.system(size: 11)) .foregroundStyle(Tj.Palette.text3) Text("低密度脂蛋白胆固醇") .font(.system(size: 19, weight: .semibold)) .foregroundStyle(Tj.Palette.text) Text("LDL-C") .font(.system(size: 12)) .foregroundStyle(Tj.Palette.text3) } Spacer() TjBadge(text: String(appLoc: "偏高"), style: .brick) } HStack(spacing: 12) { FieldBox(label: String(appLoc: "数值")) { HStack(alignment: .firstTextBaseline, spacing: 4) { Text("3.84") .font(.system(size: 30, weight: .semibold)) .foregroundStyle(Tj.Palette.brick) Text("mmol/L") .font(.system(size: 11, design: .monospaced)) .foregroundStyle(Tj.Palette.text3) } } FieldBox(label: String(appLoc: "参考范围")) { HStack(alignment: .firstTextBaseline, spacing: 4) { Text("< 3.40") .font(.system(size: 14, design: .monospaced)) .foregroundStyle(Tj.Palette.text2) Text("mmol/L") .font(.system(size: 11, design: .monospaced)) .foregroundStyle(Tj.Palette.text3) } } } Button { withAnimation { expanded.toggle() } } label: { HStack(alignment: .top, spacing: 10) { RoundedRectangle(cornerRadius: 2, style: .continuous) .fill(Tj.Palette.brick) .frame(width: 4) Text(expanded ? "超过参考上限 0.44,属轻度偏高。建议关注饮食结构(减少动物脂肪摄入),3 个月内复查。若家族有心血管病史,可与医生沟通是否需要药物干预。" : "超过参考上限 0.44,属轻度偏高。点击展开详细解读 ›") .font(.system(size: 12)) .foregroundStyle(Tj.Palette.text2) .lineSpacing(5) .multilineTextAlignment(.leading) .frame(maxWidth: .infinity, alignment: .leading) } .padding(12) .background( RoundedRectangle(cornerRadius: Tj.Radius.sm, style: .continuous) .fill(Tj.Palette.sand) ) } .buttonStyle(.plain) } .padding(18) .tjCard() } private var actions: some View { VStack(spacing: 10) { Button(action: onSave) { Text("保存到记录") .frame(maxWidth: .infinity) } .buttonStyle(TjPrimaryButton()) Button(action: onNext) { HStack(spacing: 8) { Image(systemName: "camera.fill").font(.system(size: 14)) Text("继续拍下一项") } .frame(maxWidth: .infinity) } .buttonStyle(TjGhostButton()) } } } private struct FieldBox: View { let label: String @ViewBuilder var content: Content var body: some View { VStack(alignment: .leading, spacing: 4) { Text(label) .font(.system(size: 10)) .tracking(0.5) .foregroundStyle(Tj.Palette.text3) content } .frame(maxWidth: .infinity, alignment: .leading) .padding(.vertical, 10) .padding(.horizontal, 12) .overlay( RoundedRectangle(cornerRadius: Tj.Radius.sm, style: .continuous) .strokeBorder(Tj.Palette.lineSoft, lineWidth: 1) ) } }