import Foundation import SwiftData @Model final class UserProfile { // —— 核心 4 项 —— var birthYear: Int? // 1990。隐私考虑只存年,不存月日 var biologicalSexRaw: String // "" / "male" / "female" var heightCM: Int? var bloodTypeRaw: String // "" / "A" / "B" / "AB" / "O" // —— 健康背景 —— var allergies: [String] var chronicConditions: [String] var familyHistory: [String] // —— 当前用药 —— var currentMedications: [String] var updatedAt: Date init(birthYear: Int? = nil, biologicalSexRaw: String = "", heightCM: Int? = nil, bloodTypeRaw: String = "", allergies: [String] = [], chronicConditions: [String] = [], familyHistory: [String] = [], currentMedications: [String] = [], updatedAt: Date = .now) { self.birthYear = birthYear self.biologicalSexRaw = biologicalSexRaw self.heightCM = heightCM self.bloodTypeRaw = bloodTypeRaw self.allergies = allergies self.chronicConditions = chronicConditions self.familyHistory = familyHistory self.currentMedications = currentMedications self.updatedAt = updatedAt } } extension UserProfile { enum Sex: String, CaseIterable { case male, female case undisclosed = "" var label: String { switch self { case .male: return "男" case .female: return "女" case .undisclosed: return "不愿透露" } } } var sex: Sex { get { Sex(rawValue: biologicalSexRaw) ?? .undisclosed } set { biologicalSexRaw = newValue.rawValue } } /// 当前年龄。无 birthYear 时返回 nil。基于当前日历年简单相减,不算月日。 var age: Int? { guard let y = birthYear else { return nil } return Calendar.current.component(.year, from: .now) - y } /// 给 ProfileCard 一行预览:"38岁 · 男 · 175cm · A型" var summaryLine: String { var parts: [String] = [] if let age { parts.append("\(age)岁") } if sex != .undisclosed { parts.append(sex.label) } if let h = heightCM { parts.append("\(h)cm") } if !bloodTypeRaw.isEmpty { parts.append("\(bloodTypeRaw)型") } return parts.joined(separator: " · ") } /// 资料是否完整到值得显示 summaryLine(否则提示"完善资料") var hasAnyBasics: Bool { birthYear != nil || sex != .undisclosed || heightCM != nil || !bloodTypeRaw.isEmpty } } /// 单例存取:全 App 只允许一份 UserProfile。第一次取自动创建。 enum UserProfileStore { @MainActor static func loadOrCreate(in ctx: ModelContext) -> UserProfile { let descriptor = FetchDescriptor() if let existing = try? ctx.fetch(descriptor).first { return existing } let new = UserProfile() ctx.insert(new) try? ctx.save() return new } }