import SwiftUI struct SettingsView: View { @StateObject private var model: SettingsViewModel @State private var showsClearDialog = false init(model: SettingsViewModel? = nil) { _model = StateObject(wrappedValue: model ?? DefaultContainer.makeSettingsModel()) } var body: some View { ZStack { AITheme.canvas.ignoresSafeArea() ScrollView { LazyVStack(spacing: 12) { if let errorMessage = model.errorMessage { AIStatusBanner(errorMessage, tint: AITheme.danger, systemImage: "exclamationmark.triangle") } if let notice = model.notice { AIStatusBanner(notice, tint: AITheme.success, systemImage: "checkmark.circle") } runtimeCard storageCard securityCard } .padding(16) } } .navigationTitle("设置") .toolbar { ToolbarItemGroup(placement: .primaryAction) { AIToolbarButton("刷新", systemImage: "arrow.clockwise") { Task { await model.refresh() } } .disabled(model.isLoading) } } .refreshable { await model.refresh() } .confirmationDialog( "确认清除运行日志?此操作不可恢复。", isPresented: $showsClearDialog, titleVisibility: .visible ) { Button("清除运行日志", role: .destructive) { Task { await model.clearRuntimeLogs() } } Button("取消", role: .cancel) {} } .task { await model.refresh() } } private var runtimeCard: some View { AICard { VStack(alignment: .leading, spacing: 12) { AISectionTitle("应用信息", systemImage: "info.circle") if let runtime = model.runtime { AIKeyValueRow("版本", value: "\(runtime.marketingVersion) (\(runtime.buildVersion))") AIKeyValueRow("设备", value: runtime.deviceModel) } else { Text("正在读取应用信息…") .font(.subheadline) .foregroundStyle(AITheme.muted) } } } } private var storageCard: some View { AICard { VStack(alignment: .leading, spacing: 12) { AISectionTitle("本地数据", systemImage: "externaldrive") AIKeyValueRow("存储位置", value: "仅保存在本机应用沙盒") AIKeyValueRow("当前占用", value: model.storageLabel) Button { showsClearDialog = true } label: { Label("清除运行日志", systemImage: "trash") } .buttonStyle(AIButtonStyle(kind: .danger, size: .large, fillsWidth: true)) } } } private var securityCard: some View { AICard { VStack(alignment: .leading, spacing: 12) { AISectionTitle("安全与登录", systemImage: "lock.shield") AIKeyValueRow("实例密码", value: "保存在本机应用沙盒") AIKeyValueRow("登录会话", value: "仅保存在内存") AIStatusBanner( "实例凭据只保存在本机应用沙盒,登录会话只保留在内存中,应用关闭后自动失效。", tint: AITheme.primary, systemImage: "shield.checkered" ) } } } }