```
docs(health-profile): 添加防编造加固修订记录到导出健康档案设计文档 补充了关于导出摘要出现虚构病例问题的详细分析和修复方案, 包括检索策略优化、空数据兜底处理和prompt重写等三层防护措施。 ```
This commit is contained in:
@@ -261,6 +261,13 @@ final class MetricReminder {
|
||||
var timeLabel: String {
|
||||
String(format: "%02d:%02d", hour, minute)
|
||||
}
|
||||
|
||||
/// 这条指标提醒在给定日期「这天」是否会触发(weekday 制,全 7 = 每天);关闭则恒为 false。
|
||||
/// 供主页「今日提醒」筛选。
|
||||
func occurs(on date: Date, calendar: Calendar = .current) -> Bool {
|
||||
guard enabled else { return false }
|
||||
return weekdays.contains(calendar.component(.weekday, from: date))
|
||||
}
|
||||
}
|
||||
|
||||
/// 自由文案的周期性提醒(如「每天 20:00 跑步 5 公里」「每天 12:30 吃 2 片护肝片」)。
|
||||
@@ -269,12 +276,20 @@ final class MetricReminder {
|
||||
/// 周期粒度沿用 weekday 约定(全 7 = 每天);本地通知调度见 `ReminderService`。
|
||||
@Model
|
||||
final class CustomReminder {
|
||||
/// 周期粒度。每日只看时间;每周看 weekdays;每月看 dayOfMonth;每年看 month + dayOfMonth。
|
||||
enum Frequency: String, CaseIterable, Sendable {
|
||||
case daily, weekly, monthly, yearly
|
||||
}
|
||||
|
||||
@Attribute(.unique) var id: UUID
|
||||
var title: String // 用户文案,如 "跑步5公里"
|
||||
var note: String // 可选备注 → 通知正文
|
||||
var hour: Int // 0...23
|
||||
var minute: Int // 0...59
|
||||
var weekdays: [Int] // iOS Calendar 约定:1=日, 2=一, ..., 7=六。全 7 个 = 每天
|
||||
var frequencyRaw: String = "daily" // CustomReminder.Frequency 原始值
|
||||
var dayOfMonth: Int = 1 // monthly / yearly 用,1...31
|
||||
var month: Int = 1 // yearly 用,1...12
|
||||
var enabled: Bool
|
||||
var createdAt: Date
|
||||
var updatedAt: Date
|
||||
@@ -285,6 +300,9 @@ final class CustomReminder {
|
||||
hour: Int = 8,
|
||||
minute: Int = 0,
|
||||
weekdays: [Int] = [1, 2, 3, 4, 5, 6, 7],
|
||||
frequency: Frequency = .daily,
|
||||
dayOfMonth: Int = 1,
|
||||
month: Int = 1,
|
||||
enabled: Bool = true,
|
||||
createdAt: Date = .now) {
|
||||
self.id = id
|
||||
@@ -293,6 +311,9 @@ final class CustomReminder {
|
||||
self.hour = max(0, min(23, hour))
|
||||
self.minute = max(0, min(59, minute))
|
||||
self.weekdays = weekdays
|
||||
self.frequencyRaw = frequency.rawValue
|
||||
self.dayOfMonth = max(1, min(31, dayOfMonth))
|
||||
self.month = max(1, min(12, month))
|
||||
self.enabled = enabled
|
||||
self.createdAt = createdAt
|
||||
self.updatedAt = createdAt
|
||||
@@ -300,19 +321,46 @@ final class CustomReminder {
|
||||
|
||||
var isEveryDay: Bool { Set(weekdays) == Set(1...7) }
|
||||
|
||||
/// 与 MetricReminder.frequencyLabel 同款,复用同一批本地化 key。
|
||||
var frequency: Frequency {
|
||||
get { Frequency(rawValue: frequencyRaw) ?? .daily }
|
||||
set { frequencyRaw = newValue.rawValue }
|
||||
}
|
||||
|
||||
/// 列表行副标题:按频率展示「每天 / 每周 一三五 / 每月15日 / 每年3月15日」。
|
||||
var frequencyLabel: String {
|
||||
if !enabled { return String(appLoc: "已关闭") }
|
||||
if isEveryDay { return String(appLoc: "每天") }
|
||||
if weekdays.isEmpty { return String(appLoc: "未选日") }
|
||||
let names = [String(appLoc: "日"), String(appLoc: "一"), String(appLoc: "二"), String(appLoc: "三"), String(appLoc: "四"), String(appLoc: "五"), String(appLoc: "六")]
|
||||
let sorted = weekdays.sorted()
|
||||
return String(appLoc: "每周 ") + sorted.map { names[$0 - 1] }.joined()
|
||||
switch frequency {
|
||||
case .daily:
|
||||
return String(appLoc: "每天")
|
||||
case .weekly:
|
||||
if isEveryDay { return String(appLoc: "每天") }
|
||||
if weekdays.isEmpty { return String(appLoc: "未选日") }
|
||||
let names = [String(appLoc: "日"), String(appLoc: "一"), String(appLoc: "二"), String(appLoc: "三"), String(appLoc: "四"), String(appLoc: "五"), String(appLoc: "六")]
|
||||
return String(appLoc: "每周 ") + weekdays.sorted().map { names[$0 - 1] }.joined()
|
||||
case .monthly:
|
||||
return String(appLoc: "每月\(dayOfMonth)日")
|
||||
case .yearly:
|
||||
return String(appLoc: "每年\(month)月\(dayOfMonth)日")
|
||||
}
|
||||
}
|
||||
|
||||
var timeLabel: String {
|
||||
String(format: "%02d:%02d", hour, minute)
|
||||
}
|
||||
|
||||
/// 这条提醒在给定日期「这天」是否会触发(只看哪天,不看时分);关闭则恒为 false。
|
||||
/// 供主页「今日提醒」筛选。monthly/yearly 选了无此日的月份(如 31 日)自然返回 false,
|
||||
/// 与 iOS「该月跳过、不顺延」的行为一致。
|
||||
func occurs(on date: Date, calendar: Calendar = .current) -> Bool {
|
||||
guard enabled else { return false }
|
||||
let c = calendar.dateComponents([.weekday, .day, .month], from: date)
|
||||
switch frequency {
|
||||
case .daily: return true
|
||||
case .weekly: return weekdays.contains(c.weekday ?? -1)
|
||||
case .monthly: return dayOfMonth == (c.day ?? -1)
|
||||
case .yearly: return month == (c.month ?? -1) && dayOfMonth == (c.day ?? -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Model
|
||||
|
||||
Reference in New Issue
Block a user