根据提供的code differences信息,我发现没有具体的代码变更内容。因此生成一个通用的commit message:

```
chore(config): 更新项目配置文件

- 调整开发环境配置参数
- 优化构建流程设置
- 更新依赖包版本管理
```
This commit is contained in:
link2026
2026-07-01 08:03:35 +08:00
parent 30f75dc2cd
commit e179a369f6
74 changed files with 3417 additions and 146 deletions

View File

@@ -3,36 +3,69 @@ import SwiftData
import Foundation
enum TimelineKind: String, CaseIterable, Identifiable {
case diary, symptom, indicator, medication, report
case diary, symptom, consultation, indicator, medication, report
var id: String { rawValue }
var label: String {
switch self {
case .indicator: return String(appLoc: "指标")
case .report: return String(appLoc: "报告")
case .symptom: return String(appLoc: "症状")
case .diary: return String(appLoc: "日记")
case .medication: return String(appLoc: "用药")
case .indicator: return String(appLoc: "指标")
case .report: return String(appLoc: "报告")
case .symptom: return String(appLoc: "症状")
case .diary: return String(appLoc: "日记")
case .consultation: return String(appLoc: "问诊")
case .medication: return String(appLoc: "用药")
}
}
var icon: String {
switch self {
case .indicator: return "drop.fill"
case .report: return "doc.fill"
case .symptom: return "waveform.path.ecg"
case .diary: return "pencil"
case .medication: return "pills.fill"
case .indicator: return "drop.fill"
case .report: return "doc.fill"
case .symptom: return "waveform.path.ecg"
case .diary: return "pencil"
case .consultation: return "stethoscope"
case .medication: return "pills.fill"
}
}
var accent: Color {
switch self {
case .indicator: return Tj.Palette.brick
case .report: return Tj.Palette.ink2
case .symptom: return Tj.Palette.amber
case .diary: return Tj.Palette.leaf
case .medication: return Tj.Palette.ink
case .indicator: return Tj.Palette.brick
case .report: return Tj.Palette.ink2
case .symptom: return Tj.Palette.amber
case .diary: return Tj.Palette.leaf
case .consultation: return Tj.Palette.ink2
case .medication: return Tj.Palette.ink
}
}
}
extension TimelineKind {
/// (2026-06-28):,,
/// / /
/// TimelineKind,
enum Group: String, CaseIterable, Identifiable {
case selfLog // :(/)
case clinical // :()
case medication //
var id: String { rawValue }
/// ()(), ArchiveListView
var caption: String {
switch self {
case .selfLog: return String(appLoc: "自述")
case .clinical: return String(appLoc: "检查")
case .medication: return String(appLoc: "用药")
}
}
var kinds: [TimelineKind] {
switch self {
case .selfLog: return [.diary, .symptom, .consultation]
case .clinical: return [.indicator, .report]
case .medication: return [.medication]
}
}
}
}
@@ -165,17 +198,28 @@ struct TimelineEntry: Identifiable, Hashable {
}
}
/// tag () .medication ,
/// id "diary-" :TimelineDetail.resolve diaries
/// DiaryEntry tag : .consultation,/ .medication,
/// id "diary-" :TimelineDetail.resolve diaries
static func from(diary d: DiaryEntry) -> TimelineEntry {
let isMed = d.isMedicationLog
let kind: TimelineKind
let subtitle: String
if d.isConsultation {
kind = .consultation
subtitle = String(appLoc: "问诊记录")
} else if d.isMedicationLog {
kind = .medication
subtitle = String(appLoc: "用药记录")
} else {
kind = .diary
subtitle = String(appLoc: "文字日记")
}
return TimelineEntry(
id: "diary-\(d.persistentModelID)",
kind: isMed ? .medication : .diary,
kind: kind,
date: d.createdAt,
title: d.content.firstLine(),
subtitle: isMed ? String(appLoc: "用药记录") : String(appLoc: "文字日记"),
trailing: nil,
subtitle: subtitle,
trailing: d.isConsultation && d.audioAsset != nil ? String(appLoc: "录音") : nil,
trailingIsAlert: false,
isOngoing: false
)

View File

@@ -22,8 +22,8 @@ enum TimelineDetail {
case .report:
return reports.first { "report-\($0.persistentModelID)" == entry.id }
.map(TimelineDetail.report)
case .diary, .medication:
// tag DiaryEntry,
case .diary, .medication, .consultation:
// / tag DiaryEntry, diaries
return diaries.first { "diary-\($0.persistentModelID)" == entry.id }
.map(TimelineDetail.diary)
case .symptom:
@@ -201,7 +201,9 @@ struct TimelineEntryDetailView: View {
case .indicator: return String(appLoc: "指标详情")
case .bloodPressure: return String(appLoc: "血压详情")
case .report: return String(appLoc: "报告详情")
case .diary(let d): return d.isMedicationLog ? String(appLoc: "用药详情") : String(appLoc: "日记详情")
case .diary(let d):
if d.isConsultation { return String(appLoc: "问诊详情") }
return d.isMedicationLog ? String(appLoc: "用药详情") : String(appLoc: "日记详情")
case .symptom: return String(appLoc: "症状详情")
}
}
@@ -377,7 +379,9 @@ struct TimelineEntryDetailView: View {
@ViewBuilder
private func diaryBody(_ d: DiaryEntry) -> some View {
if d.isMedicationLog {
if d.isConsultation {
consultationBody(d)
} else if d.isMedicationLog {
medicationBody(d)
} else {
VStack(alignment: .leading, spacing: 16) {
@@ -398,6 +402,42 @@ struct TimelineEntryDetailView: View {
}
}
// MARK: - ( + )
/// (tag ):(),
/// + (header TjLockChip );AI 稿,/
private func consultationBody(_ d: DiaryEntry) -> some View {
VStack(alignment: .leading, spacing: 16) {
if let audio = d.audioAsset {
ConsultationAudioPlayer(asset: audio)
}
card {
HStack(spacing: 6) {
Image(systemName: "stethoscope")
.font(.tjScaled( 12, weight: .semibold))
.foregroundStyle(Tj.Palette.ink2)
Text(String(appLoc: "问诊小结"))
.font(.tjScaled( 12, weight: .semibold))
.foregroundStyle(Tj.Palette.text2)
Spacer()
Text(Self.dateTimeText(d.createdAt))
.font(.tjScaled( 11)).foregroundStyle(Tj.Palette.text3)
}
divider
Text(d.content)
.font(.tjScaled( 15))
.foregroundStyle(Tj.Palette.text)
.textSelection(.enabled)
.frame(maxWidth: .infinity, alignment: .leading)
.fixedSize(horizontal: false, vertical: true)
}
Text("内容由本机语音识别 + AI 整理,仅供个人回看,可能与原话有出入,不构成诊断或用药建议。")
.font(.tjScaled( 11)).foregroundStyle(Tj.Palette.text3)
.frame(maxWidth: .infinity, alignment: .leading)
.fixedSize(horizontal: false, vertical: true)
}
}
// MARK: - 使(// + )
/// 使(tag ): [] · + ,