refactor: 重命名项目名称从"体己"到"康康" 将整个项目的目录结构从"体己"重命名为"康康",包括所有源代码文件、 资源文件、测试文件以及Xcode项目配置文件。此更改涉及项目中所有的 文件路径和应用入口点(App/TijiApp.swift → App/KangkangApp.swift)。 ```
181 lines
6.8 KiB
Swift
181 lines
6.8 KiB
Swift
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: "偏高", style: .brick)
|
||
}
|
||
|
||
HStack(spacing: 12) {
|
||
FieldBox(label: "数值") {
|
||
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: "参考范围") {
|
||
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<Content: View>: 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)
|
||
)
|
||
}
|
||
}
|