缺少代码差异信息,无法生成具体的commit message。请提供code differences内容以便分析并生成符合Angular规范的提交信息。
当您提供代码差异后,我将按照以下格式生成: ``` <type>(<scope>): <subject> <body> ``` 其中type会根据更改类型选择(feat、fix、docs、style、refactor等),scope表示影响范围,subject简要描述变更内容,body详细说明修改内容。
This commit is contained in:
@@ -125,7 +125,7 @@ struct CustomMetricEditor: View {
|
||||
Spacer()
|
||||
if existing == nil {
|
||||
Text("保存后会出现在录入选项里")
|
||||
.font(.system(size: 11))
|
||||
.font(.tjScaled( 11))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
}
|
||||
@@ -147,10 +147,10 @@ struct CustomMetricEditor: View {
|
||||
if nameConflict != .none {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: "exclamationmark.triangle.fill")
|
||||
.font(.system(size: 11))
|
||||
.font(.tjScaled( 11))
|
||||
.foregroundStyle(Tj.Palette.amber)
|
||||
Text(nameConflict.warningText)
|
||||
.font(.system(size: 11))
|
||||
.font(.tjScaled( 11))
|
||||
.foregroundStyle(Tj.Palette.amber)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
Spacer(minLength: 0)
|
||||
@@ -175,7 +175,7 @@ struct CustomMetricEditor: View {
|
||||
sectionLabel(String(appLoc: "参考范围(可选)"))
|
||||
Spacer()
|
||||
Text("用于自动判定 正常/偏高/偏低")
|
||||
.font(.system(size: 10))
|
||||
.font(.tjScaled( 10))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
HStack(spacing: 12) {
|
||||
@@ -188,10 +188,10 @@ struct CustomMetricEditor: View {
|
||||
|
||||
private func rangeField(label: String, value: Binding<String>, placeholder: String) -> some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(label).font(.system(size: 11)).foregroundStyle(Tj.Palette.text3)
|
||||
Text(label).font(.tjScaled( 11)).foregroundStyle(Tj.Palette.text3)
|
||||
TextField(placeholder, text: value)
|
||||
.keyboardType(.decimalPad)
|
||||
.font(.system(size: 16, weight: .medium, design: .monospaced))
|
||||
.font(.tjScaled( 16, weight: .medium, design: .monospaced))
|
||||
.padding(.horizontal, 12).padding(.vertical, 10)
|
||||
.background(fieldBg).overlay(fieldBorder)
|
||||
}
|
||||
@@ -207,7 +207,7 @@ struct CustomMetricEditor: View {
|
||||
icon = sf
|
||||
} label: {
|
||||
Image(systemName: sf)
|
||||
.font(.system(size: 20, weight: .medium))
|
||||
.font(.tjScaled( 20, weight: .medium))
|
||||
.foregroundStyle(icon == sf ? Tj.Palette.paper : Tj.Palette.ink)
|
||||
.frame(maxWidth: .infinity, minHeight: 44)
|
||||
.background(
|
||||
@@ -239,7 +239,7 @@ struct CustomMetricEditor: View {
|
||||
Image(systemName: "trash")
|
||||
Text("删除这项自定义指标")
|
||||
}
|
||||
.font(.system(size: 13, weight: .semibold))
|
||||
.font(.tjScaled( 13, weight: .semibold))
|
||||
.foregroundStyle(Tj.Palette.brick)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 12)
|
||||
@@ -282,7 +282,7 @@ struct CustomMetricEditor: View {
|
||||
.strokeBorder(Tj.Palette.line, lineWidth: 1)
|
||||
}
|
||||
private func sectionLabel(_ t: String) -> some View {
|
||||
Text(t).font(.system(size: 12, weight: .semibold)).tracking(0.3)
|
||||
Text(t).font(.tjScaled( 12, weight: .semibold)).tracking(0.3)
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ private let labPresets: [IndicatorPreset] = [
|
||||
/// 无 seriesKey,不进 Trends。
|
||||
/// 3. **自由输入** — name/value/unit/range 全自己填,status 手动选。
|
||||
struct IndicatorQuickSheet: View {
|
||||
/// 「拍照识别」入口回调。由 RootView 注入:关闭本表单 → 打开 QuickRegionCaptureFlow(相机→VL→存)。
|
||||
/// nil 时(如 Preview)不显示拍照按钮。
|
||||
var onRequestCamera: (() -> Void)? = nil
|
||||
|
||||
@Environment(\.modelContext) private var ctx
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Query private var profiles: [UserProfile]
|
||||
@@ -103,6 +107,7 @@ struct IndicatorQuickSheet: View {
|
||||
|
||||
ScrollView(showsIndicators: false) {
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
cameraEntrySection
|
||||
monitorGridSection
|
||||
labPresetSection
|
||||
Divider().padding(.vertical, 4)
|
||||
@@ -161,13 +166,69 @@ struct IndicatorQuickSheet: View {
|
||||
.foregroundStyle(Tj.Palette.text)
|
||||
Spacer()
|
||||
Text("本地处理 · 永不上传")
|
||||
.font(.system(size: 12))
|
||||
.font(.tjScaled( 12))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.bottom, 16)
|
||||
}
|
||||
|
||||
/// 顶部「拍照识别」入口:并入原「异常项快拍」。点后由 RootView 切到相机 VL 流程。
|
||||
@ViewBuilder
|
||||
private var cameraEntrySection: some View {
|
||||
if let onRequestCamera {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Button {
|
||||
onRequestCamera()
|
||||
} label: {
|
||||
HStack(spacing: 12) {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: Tj.Radius.sm, style: .continuous)
|
||||
.fill(Tj.Palette.brick)
|
||||
Image(systemName: "camera.fill")
|
||||
.font(.tjScaled(18, weight: .medium))
|
||||
.foregroundStyle(Tj.Palette.paper)
|
||||
}
|
||||
.frame(width: 44, height: 44)
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("拍照识别")
|
||||
.font(.tjScaled(15, weight: .semibold))
|
||||
.foregroundStyle(Tj.Palette.text)
|
||||
Text("拍化验单,VL 自动读出数值")
|
||||
.font(.tjScaled(12))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
Spacer()
|
||||
Image(systemName: "chevron.right")
|
||||
.font(.tjScaled(14, weight: .medium))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
.padding(14)
|
||||
.frame(maxWidth: .infinity)
|
||||
.tjCard(bordered: true)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
line
|
||||
Text("或手动填写")
|
||||
.font(.tjScaled(11))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
.fixedSize()
|
||||
line
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var line: some View {
|
||||
Rectangle()
|
||||
.fill(Tj.Palette.lineSoft)
|
||||
.frame(height: 1)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
private var monitorGridSection: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
HStack {
|
||||
@@ -217,18 +278,18 @@ struct IndicatorQuickSheet: View {
|
||||
} label: {
|
||||
HStack(spacing: 10) {
|
||||
Image(systemName: cm.icon)
|
||||
.font(.system(size: 18, weight: .medium))
|
||||
.font(.tjScaled( 18, weight: .medium))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper : Tj.Palette.ink)
|
||||
.frame(width: 32, height: 32)
|
||||
.background(Circle().fill(selected ? Tj.Palette.ink : Tj.Palette.leafSoft))
|
||||
|
||||
VStack(alignment: .leading, spacing: 1) {
|
||||
Text(cm.name)
|
||||
.font(.system(size: 14, weight: selected ? .semibold : .medium))
|
||||
.font(.tjScaled( 14, weight: selected ? .semibold : .medium))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper : Tj.Palette.text)
|
||||
.lineLimit(1)
|
||||
Text("自定义")
|
||||
.font(.system(size: 9, design: .monospaced))
|
||||
.font(.tjScaled( 9, design: .monospaced))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper.opacity(0.7) : Tj.Palette.text3)
|
||||
}
|
||||
Spacer()
|
||||
@@ -260,14 +321,14 @@ struct IndicatorQuickSheet: View {
|
||||
} label: {
|
||||
HStack(spacing: 10) {
|
||||
Image(systemName: "plus")
|
||||
.font(.system(size: 18, weight: .semibold))
|
||||
.font(.tjScaled( 18, weight: .semibold))
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
.frame(width: 32, height: 32)
|
||||
.background(
|
||||
Circle().strokeBorder(Tj.Palette.line, lineWidth: 1, antialiased: true)
|
||||
)
|
||||
Text("自定义")
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.font(.tjScaled( 14, weight: .medium))
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
Spacer()
|
||||
}
|
||||
@@ -293,13 +354,13 @@ struct IndicatorQuickSheet: View {
|
||||
} label: {
|
||||
HStack(spacing: 10) {
|
||||
Image(systemName: m.icon)
|
||||
.font(.system(size: 18, weight: .medium))
|
||||
.font(.tjScaled( 18, weight: .medium))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper : Tj.Palette.ink)
|
||||
.frame(width: 32, height: 32)
|
||||
.background(Circle().fill(selected ? Tj.Palette.ink : Tj.Palette.amber.opacity(0.25)))
|
||||
|
||||
Text(m.displayName)
|
||||
.font(.system(size: 14, weight: selected ? .semibold : .medium))
|
||||
.font(.tjScaled( 14, weight: selected ? .semibold : .medium))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper : Tj.Palette.text)
|
||||
Spacer()
|
||||
}
|
||||
@@ -348,7 +409,7 @@ struct IndicatorQuickSheet: View {
|
||||
}
|
||||
HStack(spacing: 12) {
|
||||
bpField(label: String(appLoc: "收缩压"), value: $systolic, placeholder: "120")
|
||||
Text("/").font(.system(size: 22, weight: .light)).foregroundStyle(Tj.Palette.text3)
|
||||
Text("/").font(.tjScaled( 22, weight: .light)).foregroundStyle(Tj.Palette.text3)
|
||||
bpField(label: String(appLoc: "舒张压"), value: $diastolic, placeholder: "80")
|
||||
Text("mmHg").foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
@@ -358,10 +419,10 @@ struct IndicatorQuickSheet: View {
|
||||
|
||||
private func bpField(label: String, value: Binding<String>, placeholder: String) -> some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(label).font(.system(size: 11)).foregroundStyle(Tj.Palette.text3)
|
||||
Text(label).font(.tjScaled( 11)).foregroundStyle(Tj.Palette.text3)
|
||||
TextField(placeholder, text: value)
|
||||
.keyboardType(.decimalPad)
|
||||
.font(.system(size: 20, weight: .semibold, design: .monospaced))
|
||||
.font(.tjScaled( 20, weight: .semibold, design: .monospaced))
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.vertical, 10)
|
||||
.frame(width: 90)
|
||||
@@ -380,11 +441,11 @@ struct IndicatorQuickSheet: View {
|
||||
let rangeText = "\(formatRange(sysRange)) / \(formatRange(diasRange))"
|
||||
return HStack(spacing: 4) {
|
||||
Text(rangeText)
|
||||
.font(.system(size: 11, design: .monospaced))
|
||||
.font(.tjScaled( 11, design: .monospaced))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
if personalized, let age = profile?.age {
|
||||
Text("· 按\(age)岁调整")
|
||||
.font(.system(size: 10))
|
||||
.font(.tjScaled( 10))
|
||||
.foregroundStyle(Tj.Palette.amber)
|
||||
}
|
||||
}
|
||||
@@ -427,7 +488,7 @@ struct IndicatorQuickSheet: View {
|
||||
sectionLabel(String(appLoc: "数值"))
|
||||
TextField(monitorFieldPlaceholder, text: $value)
|
||||
.keyboardType(.decimalPad)
|
||||
.font(.system(size: 18, weight: .semibold, design: .monospaced))
|
||||
.font(.tjScaled( 18, weight: .semibold, design: .monospaced))
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 12)
|
||||
.background(fieldBg)
|
||||
@@ -475,7 +536,7 @@ struct IndicatorQuickSheet: View {
|
||||
return HStack(spacing: 4) {
|
||||
if personalized, let age = profile?.age {
|
||||
Text("按\(age)岁调整")
|
||||
.font(.system(size: 10))
|
||||
.font(.tjScaled( 10))
|
||||
.foregroundStyle(Tj.Palette.amber)
|
||||
}
|
||||
}
|
||||
@@ -500,7 +561,7 @@ struct IndicatorQuickSheet: View {
|
||||
statusBadge(s.label, color: s.color)
|
||||
} else {
|
||||
Text("待输入")
|
||||
.font(.system(size: 12))
|
||||
.font(.tjScaled( 12))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
}
|
||||
@@ -546,7 +607,7 @@ struct IndicatorQuickSheet: View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Text("时间")
|
||||
.font(.system(size: 13))
|
||||
.font(.tjScaled( 13))
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
Spacer()
|
||||
DatePicker("", selection: $reminderTime,
|
||||
@@ -558,11 +619,11 @@ struct IndicatorQuickSheet: View {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
HStack {
|
||||
Text("频率")
|
||||
.font(.system(size: 13))
|
||||
.font(.tjScaled( 13))
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
Spacer()
|
||||
Text(reminderFrequencyLabel)
|
||||
.font(.system(size: 12))
|
||||
.font(.tjScaled( 12))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
weekdayPickerRow
|
||||
@@ -581,11 +642,11 @@ struct IndicatorQuickSheet: View {
|
||||
|
||||
if notifAuthBlocked {
|
||||
Text("⚠️ 通知权限已关闭,去「设置 → 康康 → 通知」打开")
|
||||
.font(.system(size: 11))
|
||||
.font(.tjScaled( 11))
|
||||
.foregroundStyle(Tj.Palette.brick)
|
||||
} else {
|
||||
Text("本机提醒 · 不发任何数据")
|
||||
.font(.system(size: 11))
|
||||
.font(.tjScaled( 11))
|
||||
.foregroundStyle(Tj.Palette.text3)
|
||||
}
|
||||
}
|
||||
@@ -625,7 +686,7 @@ struct IndicatorQuickSheet: View {
|
||||
}
|
||||
} label: {
|
||||
Text(names[idx])
|
||||
.font(.system(size: 13,
|
||||
.font(.tjScaled( 13,
|
||||
weight: reminderWeekdays.contains(w) ? .semibold : .regular))
|
||||
.foregroundStyle(reminderWeekdays.contains(w) ? Tj.Palette.paper : Tj.Palette.text)
|
||||
.frame(maxWidth: .infinity, minHeight: 32)
|
||||
@@ -647,7 +708,7 @@ struct IndicatorQuickSheet: View {
|
||||
private func quickFreqChip(_ label: String, action: @escaping () -> Void) -> some View {
|
||||
Button(action: action) {
|
||||
Text(label)
|
||||
.font(.system(size: 11))
|
||||
.font(.tjScaled( 11))
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 4)
|
||||
@@ -755,7 +816,7 @@ struct IndicatorQuickSheet: View {
|
||||
|
||||
private func sectionLabel(_ text: String) -> some View {
|
||||
Text(text)
|
||||
.font(.system(size: 12, weight: .semibold))
|
||||
.font(.tjScaled( 12, weight: .semibold))
|
||||
.tracking(0.3)
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
}
|
||||
@@ -763,7 +824,7 @@ struct IndicatorQuickSheet: View {
|
||||
private func chip(_ label: String, selected: Bool, action: @escaping () -> Void) -> some View {
|
||||
Button(action: action) {
|
||||
Text(label)
|
||||
.font(.system(size: 13, weight: selected ? .semibold : .regular))
|
||||
.font(.tjScaled( 13, weight: selected ? .semibold : .regular))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper : Tj.Palette.text)
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 8)
|
||||
@@ -779,7 +840,7 @@ struct IndicatorQuickSheet: View {
|
||||
manualStatus = value
|
||||
} label: {
|
||||
Text(label)
|
||||
.font(.system(size: 13, weight: selected ? .semibold : .regular))
|
||||
.font(.tjScaled( 13, weight: selected ? .semibold : .regular))
|
||||
.foregroundStyle(selected ? Tj.Palette.paper : color)
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 8)
|
||||
@@ -792,7 +853,7 @@ struct IndicatorQuickSheet: View {
|
||||
|
||||
private func statusBadge(_ label: String, color: Color) -> some View {
|
||||
Text(label)
|
||||
.font(.system(size: 11, weight: .semibold))
|
||||
.font(.tjScaled( 11, weight: .semibold))
|
||||
.foregroundStyle(color)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 4)
|
||||
@@ -832,9 +893,9 @@ struct IndicatorQuickSheet: View {
|
||||
} label: {
|
||||
HStack(spacing: 3) {
|
||||
Text("已隐藏 \(hiddenSet.count)")
|
||||
.font(.system(size: 11, weight: .medium))
|
||||
.font(.tjScaled( 11, weight: .medium))
|
||||
Image(systemName: "chevron.right")
|
||||
.font(.system(size: 9, weight: .semibold))
|
||||
.font(.tjScaled( 9, weight: .semibold))
|
||||
}
|
||||
.foregroundStyle(Tj.Palette.text2)
|
||||
.padding(.horizontal, 10)
|
||||
@@ -1121,7 +1182,7 @@ private struct HiddenMonitorRestoreSheet: View {
|
||||
.foregroundStyle(Tj.Palette.text)
|
||||
Spacer()
|
||||
Button("完成") { dismiss() }
|
||||
.font(.system(size: 14))
|
||||
.font(.tjScaled( 14))
|
||||
.foregroundStyle(Tj.Palette.ink)
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
@@ -1146,13 +1207,13 @@ private struct HiddenMonitorRestoreSheet: View {
|
||||
private func row(_ m: MonitorMetric) -> some View {
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: m.icon)
|
||||
.font(.system(size: 16, weight: .medium))
|
||||
.font(.tjScaled( 16, weight: .medium))
|
||||
.foregroundStyle(Tj.Palette.ink)
|
||||
.frame(width: 32, height: 32)
|
||||
.background(Circle().fill(Tj.Palette.amber.opacity(0.25)))
|
||||
|
||||
Text(m.displayName)
|
||||
.font(.system(size: 15, weight: .medium))
|
||||
.font(.tjScaled( 15, weight: .medium))
|
||||
.foregroundStyle(Tj.Palette.text)
|
||||
|
||||
Spacer()
|
||||
@@ -1160,7 +1221,7 @@ private struct HiddenMonitorRestoreSheet: View {
|
||||
Button("显示") {
|
||||
onRestore(m)
|
||||
}
|
||||
.font(.system(size: 13, weight: .semibold))
|
||||
.font(.tjScaled( 13, weight: .semibold))
|
||||
.foregroundStyle(Tj.Palette.paper)
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 6)
|
||||
|
||||
Reference in New Issue
Block a user