From 82c02739b890acc5a9b68ee6d75a16ab287b8dd9 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Thu, 19 Mar 2026 23:43:45 +0800 Subject: [PATCH] fix settings network --- .../Views/Settings/SettingsAccountView.swift | 71 ------- .../Views/Settings/SettingsNetworkView.swift | 188 +++++++++--------- punchnet/punchnetApp.swift | 8 + 3 files changed, 98 insertions(+), 169 deletions(-) diff --git a/punchnet/Views/Settings/SettingsAccountView.swift b/punchnet/Views/Settings/SettingsAccountView.swift index 3d371b2..ea19366 100644 --- a/punchnet/Views/Settings/SettingsAccountView.swift +++ b/punchnet/Views/Settings/SettingsAccountView.swift @@ -39,82 +39,11 @@ struct SettingsAccountView: View { .background(Color.primary.opacity(0.03)) .cornerRadius(12) .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.primary.opacity(0.05), lineWidth: 1)) - - // MARK: - 网络部分 - sectionHeader(title: "网络配置", icon: "network") - - if let networkSession = userContext.networkSession { - VStack(spacing: 16) { - HStack { - VStack(alignment: .leading, spacing: 4) { - Text("网络") - .font(.subheadline) - .foregroundColor(.secondary) - - Text(networkSession.networkName) - .font(.headline) - } - - Spacer() -// -// Menu { -// ForEach(state.networks, id: \.id) { network in -// Button(network.name) { -// self.state.selectedNetwork = network -// } -// } -// } label: { -// Text("切换网络") -// .font(.subheadline) -// .padding(.horizontal, 12) -// .padding(.vertical, 6) -// .background(Capsule().fill(Color.blue.opacity(0.1))) -// } -// .buttonStyle(.plain) - } - - 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) - } - } .frame(maxWidth: 600) // 限制宽度防止在大屏幕上显得太散 } } - private func openNetworkUrl(url: String) { - if let url = URL(string: url) { - openURL(url) { accepted in - if accepted { - print("浏览器已成功打开") - } else { - print("打开失败(可能是 URL 格式错误)") - } - } - } - } - // 打开窗口 private func openMainWindow(id: String) { let window = NSApp.windows.first { win in diff --git a/punchnet/Views/Settings/SettingsNetworkView.swift b/punchnet/Views/Settings/SettingsNetworkView.swift index 8967e8f..1dbf3f5 100644 --- a/punchnet/Views/Settings/SettingsNetworkView.swift +++ b/punchnet/Views/Settings/SettingsNetworkView.swift @@ -8,57 +8,95 @@ import SwiftUI struct SettingsNetworkView: View { @Environment(UserContext.self) var userContext: UserContext + @Environment(\.openURL) var openURL + @State private var selectedExitNode: UserContext.NetworkSession.ExitNode? var body: some View { ScrollView(.vertical, showsIndicators: false) { VStack(alignment: .leading, spacing: 24) { - // MARK: - 网络连接配置 - networkSectionHeader(title: "连接设置", icon: "wifi.router.fill") + // MARK: - 网络部分 + sectionHeader(title: "网络配置", icon: "network") if let networkSession = userContext.networkSession { - VStack(spacing: 0) { -// // 默认网络项 -// NetworkRow(title: "默认网络", value: state.selectedNetwork.name) { -// Menu { -// ForEach(state.networks, id: \.id) { network in -// Button(network.name) { -// self.state.selectedNetwork = network -// } -// } -// } label: { -// actionLabel(text: "切换") -// } -// .buttonStyle(.plain) -// } -// -// Divider().padding(.leading, 16) - - // 出口节点项 - NetworkRow(title: "出口节点", value: selectedExitNode?.nodeName ?? "") { - Menu { - ForEach(networkSession.exitNodes, id: \.uuid) { node in - Button { - self.selectedExitNode = node - } label: { - Text(node.nodeName) - } - } - } label: { - actionLabel(text: "更改") + VStack(spacing: 16) { + HStack { + VStack(alignment: .leading, spacing: 4) { + Text("网络") + .font(.subheadline) + .foregroundColor(.secondary) + + Text(networkSession.networkName) + .font(.headline) } - .buttonStyle(.plain) + + 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 { + VStack(alignment: .leading, spacing: 4) { + Text("出口节点") + .font(.caption) + .foregroundColor(.secondary) + + if let selectedExitNode = self.selectedExitNode { + Text(selectedExitNode.nodeName) + .font(.system(size: 15, weight: .medium)) + } + } + Spacer() + + Menu { + ForEach(networkSession.exitNodes, id: \.uuid) { node in + Button { + self.selectedExitNode = node + } label: { + Text(node.nodeName) + } + } + } label: { + Text("更改") + .font(.subheadline) + .padding(.horizontal, 10) + .padding(.vertical, 4) + .background(Capsule().fill(Color.blue.opacity(0.1))) + .foregroundColor(.blue) + } + .buttonStyle(.plain) + } + .padding(16) .background(Color.primary.opacity(0.03)) .cornerRadius(12) - .overlay(RoundedRectangle(cornerRadius: 12).stroke(Color.primary.opacity(0.05), lineWidth: 1)) } // MARK: - 授权与安全 - networkSectionHeader(title: "授权状态", icon: "checkmark.shield.fill") + sectionHeader(title: "授权状态", icon: "checkmark.shield.fill") VStack(spacing: 0) { StatusRow(title: "当前状态", value: "有效", valueColor: .green) @@ -70,81 +108,41 @@ struct SettingsNetworkView: View { } .background(Color.primary.opacity(0.03)) .cornerRadius(12) - - // MARK: - 外部操作 - HStack(spacing: 16) { - Button { - - } label: { - Label("进入管理平台", systemImage: "arrow.up.right.app") - .font(.subheadline.bold()) - } - .buttonStyle(.borderedProminent) - .controlSize(.large) - - Button { - - } label: { - Text("查看诊断详情") - } - .buttonStyle(.bordered) - .controlSize(.large) - } - .padding(.top, 8) } .padding(32) .frame(maxWidth: 600, alignment: .leading) } + .onAppear { + self.selectedExitNode = self.userContext.networkSession?.exitNodes.first + } } // MARK: - 辅助组件 - private func networkSectionHeader(title: String, icon: String) -> some View { + 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) - .font(.system(size: 14, weight: .semibold)) Text(title) - .font(.system(size: 15, weight: .bold)) - .foregroundColor(.secondary) + .font(.system(size: 16, weight: .bold)) } .padding(.leading, 4) } - private func actionLabel(text: String) -> some View { - Text(text) - .font(.subheadline) - .padding(.horizontal, 10) - .padding(.vertical, 4) - .background(Capsule().fill(Color.blue.opacity(0.1))) - .foregroundColor(.blue) - } -} - -// MARK: - 通用行组件 -struct NetworkRow: View { - let title: String - let value: String - let action: () -> Content - - init(title: String, value: String, @ViewBuilder action: @escaping () -> Content) { - self.title = title - self.value = value - self.action = action - } - - var body: some View { - HStack { - VStack(alignment: .leading, spacing: 4) { - Text(title).font(.caption).foregroundColor(.secondary) - Text(value).font(.system(size: 15, weight: .medium)) - } - Spacer() - action() - } - .padding(16) - } } struct StatusRow: View { @@ -166,9 +164,3 @@ struct StatusRow: View { .padding(16) } } - -// MARK: - 预览辅助 -#Preview { - SettingsNetworkView() - .environment(UserContext()) // 确保环境中存在 UserContext -} diff --git a/punchnet/punchnetApp.swift b/punchnet/punchnetApp.swift index fcd50e9..e615bec 100644 --- a/punchnet/punchnetApp.swift +++ b/punchnet/punchnetApp.swift @@ -38,6 +38,14 @@ struct punchnetApp: App { self.noticeServer = UDPNoticeCenterServer() self.noticeServer.start() self.appContext = AppContext(noticePort: self.noticeServer.port) + + // TODO test + self.userContext.networkSession = .init(accessToken: "", username: "", userType: "", audit: 0, networkId: 1, networkName: "测试网络1", networkDomain: "punchnet.com", exitNodes: [ + .init(nnid: 1, nodeName: "出口1"), + .init(nnid: 2, nodeName: "出口2"), + .init(nnid: 3, nodeName: "出口2"), + ]) + } var body: some Scene {