- 删除旧 ViewModel/Repository/Storage 层,简化架构 - 新增网络层:APIClient、APIConfig、APIError - 新增数据模型层:APIModels(含 20+ DTO) - 新增服务层:APIService(含 8 个业务服务类) - 各页面内联组件定义,消除跨文件依赖 - 修复 ZXQuickAction、ZXAIInteractionRow、ZXWeakRow 缺失 - 修复 ZXTabBtn 参数标签缺失 - 配置 ATS 例外允许 HTTP 请求 - API 地址指向线上服务器 81.70.187.179:3001
82 lines
9.7 KiB
Swift
82 lines
9.7 KiB
Swift
import SwiftUI
|
||
|
||
struct CreateLibraryPage: View {
|
||
@State private var name = ""; @State private var desc = ""
|
||
var body: some View {
|
||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
||
ScrollView { VStack(spacing: 20) {
|
||
VStack(alignment: .leading, spacing: 8) { Text("知识库名称").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextField("例如:机器学习", text: $name).font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
|
||
VStack(alignment: .leading, spacing: 8) { Text("描述(可选)").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextField("简单描述这个知识库的内容", text: $desc).font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
|
||
Button {} label: { Text("创建").font(.system(size: 14, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 52).background(ZXGradient.ctaPurple).clipShape(RoundedRectangle(cornerRadius: 16)) }
|
||
}.padding(.horizontal, 20).padding(.top, 20) }.scrollIndicators(.hidden) }
|
||
}.navigationBarHidden(true)}
|
||
}
|
||
|
||
struct LibraryDetailPage: View {
|
||
var body: some View {
|
||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
||
ScrollView { VStack(spacing: 12) {
|
||
NavigationLink(destination: KnowledgeDetailPage()) { ZXCardRow(emoji: "📝", title: "偏差-方差权衡", desc: "模型复杂度 · 泛化误差", status: "已掌握", c: Color.zxGreen) }
|
||
NavigationLink(destination: KnowledgeDetailPage()) { ZXCardRow(emoji: "📝", title: "梯度下降优化", desc: "SGD · Adam · 学习率", status: "学习中", c: Color.zxOrange) }
|
||
NavigationLink(destination: KnowledgeDetailPage()) { ZXCardRow(emoji: "📝", title: "正则化方法", desc: "L1 · L2 · Dropout", status: "待复习", c: Color.zxYellow) }
|
||
NavigationLink(destination: KnowledgeDetailPage()) { ZXCardRow(emoji: "📝", title: "过拟合与欠拟合", desc: "偏差方差 · 模型选择", status: "已掌握", c: Color.zxGreen) }
|
||
}.padding(.horizontal, 20).padding(.bottom, 80) }.scrollIndicators(.hidden) }
|
||
}.navigationBarHidden(true)}
|
||
}
|
||
struct ZXCardRow: View { let emoji: String; let title: String; let desc: String; let status: String; let c: Color
|
||
var body: some View { HStack(spacing: 12) { Text(emoji).font(.system(size: 20)).frame(width: 40, height: 40).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 10)); VStack(alignment: .leading, spacing: 2) { Text(title).font(.system(size: 14, weight: .semibold)).foregroundColor(Color.zxF0); Text(desc).font(.system(size: 11)).foregroundColor(Color.zxF03) }; Spacer(); Text(status).font(.system(size: 10, weight: .semibold)).foregroundColor(c).padding(.horizontal, 8).padding(.vertical, 2).background(c.opacity(0.12)).clipShape(Capsule()) }
|
||
.padding(14).background(Color.zxFill003).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder006, lineWidth: 1)) }
|
||
}
|
||
|
||
struct AddKnowledgePage: View {
|
||
@State private var title = ""; @State private var content = ""
|
||
var body: some View {
|
||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
||
ScrollView { VStack(spacing: 16) {
|
||
VStack(alignment: .leading, spacing: 8) { Text("标题").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextField("输入知识点标题", text: $title).font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
|
||
VStack(alignment: .leading, spacing: 8) { Text("内容").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextEditor(text: $content).frame(minHeight: 200).scrollContentBackground(.hidden).padding(12).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
|
||
Button {} label: { Text("保存").font(.system(size: 14, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 52).background(ZXGradient.ctaPurple).clipShape(RoundedRectangle(cornerRadius: 16)) }
|
||
}.padding(.horizontal, 20).padding(.bottom, 80) }.scrollIndicators(.hidden) }
|
||
}.navigationBarHidden(true)}
|
||
}
|
||
|
||
struct KnowledgeDetailPage: View {
|
||
var body: some View {
|
||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
||
ScrollView { VStack(spacing: 16) {
|
||
VStack(alignment: .leading, spacing: 8) { HStack { ZXChip(text: "算法", color: Color.zxPurple); ZXChip(text: "机器学习", color: Color.zxAccent); ZXChip(text: "需要复习", color: Color.zxYellow) }; Text("偏差-方差权衡").font(.system(size: 22, weight: .heavy)).foregroundColor(Color.zxF0); Text("偏差-方差权衡是机器学习模型选择的核心理念。").font(.system(size: 14)).foregroundColor(Color.zxF007).lineSpacing(6) }.padding(20).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 20)).overlay(RoundedRectangle(cornerRadius: 20).stroke(Color.zxBorder006, lineWidth: 1))
|
||
HStack(spacing: 12) { Button {} label: { Label("开始复习", systemImage: "arrow.triangle.2.circlepath").font(.system(size: 14, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 44).background(ZXGradient.brandPurple).clipShape(RoundedRectangle(cornerRadius: 14)) }; Button {} label: { Label("费曼解释", systemImage: "mic.fill").font(.system(size: 14, weight: .semibold)).foregroundColor(Color.zxF05).frame(maxWidth: .infinity).frame(height: 44).background(Color.zxFill005).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) } }
|
||
}.padding(.horizontal, 20).padding(.bottom, 80) }.scrollIndicators(.hidden) }
|
||
}.navigationBarHidden(true)}
|
||
}
|
||
struct ZXChip: View { let text: String; let color: Color
|
||
var body: some View { Text(text).font(.system(size: 10, weight: .semibold)).foregroundColor(color).padding(.horizontal, 8).padding(.vertical, 2).background(color.opacity(0.12)).clipShape(Capsule()) }
|
||
}
|
||
|
||
struct ImportPage: View {
|
||
var body: some View {
|
||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
||
ScrollView { VStack(spacing: 12) {
|
||
ZXImportOption(icon: "camera.fill", title: "拍照导入", desc: "拍下书本或笔记,AI 自动识别")
|
||
ZXImportOption(icon: "doc.text.fill", title: "文件导入", desc: "支持 PDF、Word、Markdown")
|
||
ZXImportOption(icon: "link", title: "链接导入", desc: "粘贴网页链接,自动提取内容")
|
||
ZXImportOption(icon: "photo.on.rectangle", title: "相册导入", desc: "从相册选择截图或图片")
|
||
}.padding(.horizontal, 20).padding(.top, 16) }.scrollIndicators(.hidden) }
|
||
}.navigationBarHidden(true)}
|
||
}
|
||
struct ZXImportOption: View { let icon: String; let title: String; let desc: String
|
||
var body: some View { Button {} label: { HStack(spacing: 14) { Image(systemName: icon).font(.system(size: 22)).foregroundColor(Color.zxPurple).frame(width: 48, height: 48).background(Color.zxPurpleBG(0.1)).clipShape(RoundedRectangle(cornerRadius: 14)); VStack(alignment: .leading, spacing: 2) { Text(title).font(.system(size: 15, weight: .semibold)).foregroundColor(Color.zxF0); Text(desc).font(.system(size: 12)).foregroundColor(Color.zxF04) }; Spacer(); Image(systemName: "chevron.right").font(.system(size: 12)).foregroundColor(Color.zxF03) }.padding(16).background(Color.zxFill003).clipShape(RoundedRectangle(cornerRadius: 16)).overlay(RoundedRectangle(cornerRadius: 16).stroke(Color.zxBorder006, lineWidth: 1)) }.foregroundColor(.primary) }
|
||
}
|
||
|
||
struct EditKnowledgePage: View {
|
||
@State private var title = "偏差-方差权衡"; @State private var content = "偏差衡量模型的预测与真实值之间的差异..."
|
||
var body: some View {
|
||
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
|
||
ScrollView { VStack(spacing: 16) {
|
||
VStack(alignment: .leading, spacing: 8) { Text("标题").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextField("", text: $title).font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
|
||
VStack(alignment: .leading, spacing: 8) { Text("内容").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextEditor(text: $content).frame(minHeight: 200).scrollContentBackground(.hidden).padding(12).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
|
||
Button {} label: { Text("保存修改").font(.system(size: 14, weight: .bold)).foregroundColor(.white).frame(maxWidth: .infinity).frame(height: 52).background(ZXGradient.ctaPurple).clipShape(RoundedRectangle(cornerRadius: 16)) }
|
||
}.padding(.horizontal, 20).padding(.bottom, 80) }.scrollIndicators(.hidden) }
|
||
}.navigationBarHidden(true)}
|
||
}
|