// // SettingsNetworkView 2.swift // punchnet // // Created by 安礼成 on 2026/3/19. // import SwiftUI struct SettingsNetworkView: View { @Environment(AppContext.self) var appContext: AppContext @Environment(\.openURL) var openURL var body: some View { ScrollView(.vertical, showsIndicators: false) { VStack(alignment: .leading, spacing: 24) { // MARK: - 网络部分 sectionHeader(title: "网络配置", icon: "network") if let networkSession = appContext.networkSession { VStack(spacing: 16) { HStack { VStack(alignment: .leading, spacing: 4) { Text("网络") .font(.subheadline) .foregroundColor(.secondary) Text(networkSession.networkName) .font(.headline) } Spacer() } Divider() HStack { Button { self.openNetworkUrl(url: networkSession.networkUrl) } label: { Label("进入管理平台", systemImage: "arrow.up.right.square") } .buttonStyle(.plain) .foregroundColor(.blue) Spacer() Button("查看详情") { self.openNetworkUrl(url: networkSession.networkUrl) } .buttonStyle(.bordered) .controlSize(.small) } } .padding(16) .background(Color.primary.opacity(0.03)) .cornerRadius(12) // 出口节点项 HStack(alignment: .top, spacing: 12) { ZStack { RoundedRectangle(cornerRadius: 8, style: .continuous) .fill(Color.blue.opacity(0.1)) .frame(width: 32, height: 32) Image(systemName: "arrow.triangle.branch") .font(.system(size: 14, weight: .medium)) .foregroundColor(.blue) } VStack(alignment: .leading, spacing: 4) { Text("出口节点") .font(.system(size: 14, weight: .medium)) Text("已迁移到主界面顶部状态栏,可结合当前连接状态以下拉方式切换,也支持保持未设置。") .font(.system(size: 12)) .foregroundColor(.secondary) .fixedSize(horizontal: false, vertical: true) } Spacer() } .padding(16) .background(Color.primary.opacity(0.03)) .cornerRadius(12) .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.primary.opacity(0.05), lineWidth: 1)) } // MARK: - 授权与安全 sectionHeader(title: "授权状态", icon: "checkmark.shield.fill") VStack(spacing: 0) { StatusRow(title: "当前状态", value: "有效", valueColor: .green) Divider() .padding(.leading, 16) StatusRow(title: "有效期", value: "临时 (至断开连接)", valueColor: .secondary) } .background(Color.primary.opacity(0.03)) .cornerRadius(12) } .padding(32) .frame(maxWidth: 600, alignment: .leading) } } // MARK: - 辅助组件 private func openNetworkUrl(url: String) { if let url = URL(string: url) { openURL(url) { accepted in if accepted { print("浏览器已成功打开") } else { print("打开失败(可能是 URL 格式错误)") } } } } // 辅助头部组件 private func sectionHeader(title: String, icon: String) -> some View { HStack { Image(systemName: icon) .foregroundColor(.blue) Text(title) .font(.system(size: 16, weight: .bold)) } .padding(.leading, 4) } } private struct StatusRow: View { let title: String let value: String let valueColor: Color var body: some View { HStack { Text(title) .font(.system(size: 14)) .foregroundColor(.primary.opacity(0.8)) Spacer() Text(value) .font(.system(size: 14, weight: .medium)) .foregroundColor(valueColor) } .padding(16) } }