缺少代码差异信息,无法生成具体的commit message。

请提供 "code differences" 的具体内容,以便我能够根据代码变更情况生成符合 Angular 规范的中文 commit message。
This commit is contained in:
link2026
2026-06-07 09:40:59 +08:00
parent 675c33bea1
commit 60b6ad6d65
18 changed files with 1552 additions and 299 deletions

View File

@@ -0,0 +1,176 @@
import SwiftUI
import SwiftData
/// : +
/// CalendarOverviewView / @Query( TodayRemindersCard)
struct HomeCalendarCard: View {
@Query(sort: \Indicator.capturedAt, order: .reverse)
private var indicators: [Indicator]
@Query(sort: \Report.reportDate, order: .reverse)
private var reports: [Report]
@Query(sort: \DiaryEntry.createdAt, order: .reverse)
private var diaries: [DiaryEntry]
@Query(sort: \Symptom.startedAt, order: .reverse)
private var symptoms: [Symptom]
/// (nil = )
@State private var openDay: SelectedDay?
private let calendar: Calendar = {
var c = Calendar(identifier: .gregorian)
c.firstWeekday = 2
c.locale = Locale.current
return c
}()
@MainActor
private var data: CalendarData {
CalendarData.build(
indicators: indicators,
reports: reports,
diaries: diaries,
symptoms: symptoms
)
}
///
private var weekDays: [Date] {
let today = calendar.startOfDay(for: .now)
let weekdayIndex = (calendar.component(.weekday, from: today) - calendar.firstWeekday + 7) % 7
guard let monday = calendar.date(byAdding: .day, value: -weekdayIndex, to: today) else {
return []
}
return (0..<7).compactMap { calendar.date(byAdding: .day, value: $0, to: monday) }
}
/// (///)
private var daysWithRecordsThisMonth: Int {
guard let interval = calendar.dateInterval(of: .month, for: .now) else { return 0 }
let count = calendar.range(of: .day, in: .month, for: .now)?.count ?? 30
var n = 0
for i in 0..<count {
guard let d = calendar.date(byAdding: .day, value: i, to: interval.start) else { continue }
if data.marks(for: d, calendar: calendar).hasAnyEvent ||
!data.ranges(touching: d, calendar: calendar).isEmpty {
n += 1
}
}
return n
}
var body: some View {
VStack(alignment: .leading, spacing: 12) {
header
weekStrip
}
.padding(14)
.frame(maxWidth: .infinity, alignment: .leading)
.tjCard(bordered: true)
.padding(.bottom, 18)
.contentShape(Rectangle())
.onTapGesture { openDay = SelectedDay(date: .now) }
.fullScreenCover(item: $openDay) { day in
CalendarOverviewView(initialDate: day.date, onClose: { openDay = nil })
}
}
private var header: some View {
HStack(alignment: .firstTextBaseline) {
Text("健康日历")
.font(.tjH2())
.foregroundStyle(Tj.Palette.text)
Spacer()
HStack(spacing: 3) {
Text(summaryLine)
.font(.system(size: 12))
.foregroundStyle(Tj.Palette.text3)
Image(systemName: "chevron.right")
.font(.system(size: 11, weight: .semibold))
.foregroundStyle(Tj.Palette.text3)
}
}
}
private var summaryLine: String {
let n = daysWithRecordsThisMonth
return n > 0 ? String(appLoc: "本月 \(n) 天有记录") : String(appLoc: "本月暂无记录")
}
private var weekStrip: some View {
HStack(spacing: 6) {
ForEach(weekDays, id: \.self) { day in
dayCell(day)
}
}
}
private func dayCell(_ day: Date) -> some View {
let marks = data.marks(for: day, calendar: calendar)
let ranges = data.ranges(touching: day, calendar: calendar)
let isToday = calendar.isDateInToday(day)
let hasSymptom = !ranges.isEmpty
return Button {
openDay = SelectedDay(date: day)
} label: {
VStack(spacing: 5) {
Text(weekdayLabel(day))
.font(.system(size: 10, weight: .medium))
.foregroundStyle(Tj.Palette.text3)
ZStack {
RoundedRectangle(cornerRadius: 9, style: .continuous)
.fill(cellFill(isToday: isToday, hasSymptom: hasSymptom))
if isToday {
RoundedRectangle(cornerRadius: 9, style: .continuous)
.strokeBorder(Tj.Palette.ink, lineWidth: 1.2)
}
Text("\(calendar.component(.day, from: day))")
.font(.system(size: 14, weight: isToday ? .bold : .regular))
.foregroundStyle(isToday ? Tj.Palette.ink : Tj.Palette.text)
}
.frame(height: 38)
marksDots(marks)
.frame(height: 5)
}
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
.buttonStyle(.plain)
}
@ViewBuilder
private func marksDots(_ marks: DayMarks) -> some View {
HStack(spacing: 2) {
if marks.abnormalCount > 0 {
dot(Tj.Palette.brick)
} else if marks.normalCount > 0 {
dot(Tj.Palette.leaf)
}
if marks.reportCount > 0 { dot(Tj.Palette.ink2) }
if marks.diaryCount > 0 { dot(Tj.Palette.text3.opacity(0.7)) }
}
}
private func dot(_ color: Color) -> some View {
Circle().fill(color).frame(width: 4, height: 4)
}
private func cellFill(isToday: Bool, hasSymptom: Bool) -> Color {
if hasSymptom { return Tj.Palette.amber.opacity(0.18) }
if isToday { return Tj.Palette.sand2 }
return Tj.Palette.sand2.opacity(0.5)
}
private func weekdayLabel(_ day: Date) -> String {
let labels = [
String(appLoc: ""), String(appLoc: ""), String(appLoc: ""),
String(appLoc: ""), String(appLoc: ""), String(appLoc: ""),
String(appLoc: "")
]
let idx = (calendar.component(.weekday, from: day) - calendar.firstWeekday + 7) % 7
return labels[idx]
}
}