- 移除 3 处强制深色模式,用 @AppStorage 全局切换 - 设置页「外观」按钮实时切换深色/浅色/跟随系统 - 底部导航栏 inactive 颜色改为自适应 Color.zxF03 - 12 个子页面修复:保留返回按钮 + 消除顶部空白 - 新增 LearningSessionView/ReviewCardView/ActiveRecallView - 新增 NotificationListView/SettingsView 等子页面 - 补全所有按钮 NavigationLink 跳转(0 个空白 action) - KnowledgeBase 模型对齐服务器数据 - Info.plist 补充 CFBundleIdentifier + ATS - 新增缺口分析文档 gap-analysis-1/2.md
66 lines
4.8 KiB
Swift
66 lines
4.8 KiB
Swift
import SwiftUI
|
|
|
|
struct AnalysisHomeView: View {
|
|
var body: some View {
|
|
ZStack {
|
|
Color.zxBg0.ignoresSafeArea()
|
|
VStack(spacing: 0) {
|
|
HStack {
|
|
Text("学习分析").font(.system(size: 22, weight: .heavy)).foregroundColor(Color.zxF0).tracking(-0.5)
|
|
Spacer()
|
|
HStack(spacing: 4) { Text("近 7 天").font(.system(size: 12)).foregroundColor(Color.zxF05); Image(systemName: "chevron.down").font(.system(size: 10)).foregroundColor(Color.zxF04) }
|
|
.padding(.horizontal, 12).padding(.vertical, 6).background(Color.zxFill005).clipShape(Capsule()).overlay(Capsule().stroke(Color.zxBorder008, lineWidth: 1))
|
|
}
|
|
.padding(.horizontal, 20).padding(.top, ZXSpacing.statusBarH + 16).padding(.bottom, 12)
|
|
ScrollView {
|
|
VStack(spacing: 16) {
|
|
HStack(spacing: 12) {
|
|
ZXStatBadge(icon: "trophy.fill", label: "综合掌握", value: "65%", trend: "+8%", color: Color.zxPurple)
|
|
ZXStatBadge(icon: "bolt.fill", label: "本周积分", value: "1,240", trend: "+320", color: Color.zxOrange)
|
|
ZXStatBadge(icon: "exclamationmark.triangle.fill", label: "待巩固", value: "23", trend: "-5", color: Color.zxYellow)
|
|
ZXStatBadge(icon: "chart.line.uptrend.xyaxis", label: "连续天", value: "14", trend: "🔥", color: Color.zxGreen)
|
|
}
|
|
VStack(alignment: .leading, spacing: 16) {
|
|
HStack { Text("掌握度趋势").font(.system(size: 14, weight: .bold)).foregroundColor(Color.zxF0); Spacer(); Text("↑ +8% 本周").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxGreen) }
|
|
ZXChartView()
|
|
}.padding(16).background(Color.zxFill004).overlay(RoundedRectangle(cornerRadius: 20).stroke(Color.zxBorder006, lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 20))
|
|
VStack(alignment: .leading, spacing: 12) {
|
|
HStack { HStack(spacing: 8) { Image(systemName: "exclamationmark.triangle.fill").font(.system(size: 14)).foregroundColor(Color.zxYellow); Text("薄弱知识点").font(.system(size: 15, weight: .bold)).foregroundColor(Color.zxF0) }; Spacer(); NavigationLink(destination: WeakPointsPage()) { Text("全部 23 个").font(.system(size: 12)).foregroundColor(Color.zxPurple) } }
|
|
NavigationLink(destination: KnowledgeDetailPage()) { ZXWeakRow(score: 32, topic: "贝叶斯定理应用", lib: "机器学习", priority: "高") }.foregroundColor(.primary)
|
|
NavigationLink(destination: KnowledgeDetailPage()) { ZXWeakRow(score: 41, topic: "正态分布性质", lib: "高等数学", priority: "高") }.foregroundColor(.primary)
|
|
ZXWeakRow(score: 55, topic: "词根 spect- 相关词汇", lib: "英语词汇", priority: "中")
|
|
}
|
|
}.padding(.horizontal, 20).padding(.bottom, 120)
|
|
}.scrollIndicators(.hidden)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ZXStatBadge: View { let icon: String; let label: String; let value: String; let trend: String; let color: Color
|
|
var body: some View {
|
|
VStack(spacing: 3) {
|
|
Image(systemName: icon).font(.system(size: 14)).foregroundColor(color)
|
|
Text(value).font(.system(size: 16, weight: .heavy)).foregroundColor(Color.zxF0)
|
|
Text(label).font(.system(size: 9)).foregroundColor(Color.zxF04).multilineTextAlignment(.center)
|
|
}.frame(maxWidth: .infinity).frame(height: 72).padding(.vertical, 4).background(color.opacity(0.06)).overlay(RoundedRectangle(cornerRadius: 14).stroke(color.opacity(0.15), lineWidth: 1)).clipShape(RoundedRectangle(cornerRadius: 14))
|
|
}
|
|
}
|
|
|
|
struct ZXChartView: View {
|
|
let data: [(String, CGFloat)] = [("一", 0.62), ("二", 0.65), ("三", 0.71), ("四", 0.68), ("五", 0.75), ("六", 0.79), ("今", 0.78)]
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
GeometryReader { g in
|
|
ZStack(alignment: .topLeading) {
|
|
Path { path in let w = g.size.width / 7
|
|
for (i, d) in data.enumerated() { let x = w * CGFloat(i) + w / 2; let y = (1 - d.1) * g.size.height
|
|
if i == 0 { path.move(to: CGPoint(x: x, y: y)) } else { path.addLine(to: CGPoint(x: x, y: y)) } }
|
|
}.stroke(Color.zxPurple, style: StrokeStyle(lineWidth: 2, lineCap: .round, lineJoin: .round))
|
|
}
|
|
}.frame(height: 100)
|
|
HStack(spacing: 0) { ForEach(data, id: \.0) { d in Text(d.0).font(.system(size: 9)).foregroundColor(Color(hex: "#F0F0FF", opacity: 0.35)).frame(maxWidth: .infinity) } }
|
|
}
|
|
}
|
|
}
|