fix Network
This commit is contained in:
parent
d48c527326
commit
77d7e95eae
@ -13,12 +13,14 @@ class AppContext {
|
|||||||
var noticePort: Int
|
var noticePort: Int
|
||||||
|
|
||||||
// 调用 "/connect" 之后的网络信息
|
// 调用 "/connect" 之后的网络信息
|
||||||
var networkContext: SDLAPIClient.NetworkContext?
|
var networkContext: SDLAPIClient.NetworkContext = .default()
|
||||||
|
|
||||||
var loginCredit: Credit?
|
|
||||||
// 当前app所处的场景
|
// 当前app所处的场景
|
||||||
var appScene: AppScene = .login(username: nil)
|
var appScene: AppScene = .login(username: nil)
|
||||||
|
|
||||||
|
// 登陆凭证
|
||||||
|
var loginCredit: Credit?
|
||||||
|
|
||||||
enum Credit {
|
enum Credit {
|
||||||
case token(token: String, session: SDLAPIClient.NetworkSession)
|
case token(token: String, session: SDLAPIClient.NetworkSession)
|
||||||
case accountAndPasword(account: String, password: String, session: SDLAPIClient.NetworkSession)
|
case accountAndPasword(account: String, password: String, session: SDLAPIClient.NetworkSession)
|
||||||
@ -68,7 +70,27 @@ class AppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 连接到对应的网络
|
||||||
|
func connectNetwork() async throws {
|
||||||
|
guard let session = self.networkSession else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let context = try await SDLAPIClient.connectNetwork(accesToken: session.accessToken)
|
||||||
|
if let options = SystemConfig.getOptions(
|
||||||
|
networkId: UInt32(session.networkId),
|
||||||
|
networkDomain: session.networkDomain,
|
||||||
|
ip: context.ip,
|
||||||
|
maskLen: context.maskLen,
|
||||||
|
accessToken: session.accessToken,
|
||||||
|
identityId: context.identityId,
|
||||||
|
hostname: context.hostname,
|
||||||
|
noticePort: noticePort
|
||||||
|
) {
|
||||||
|
try await VPNManager.shared.enableVpn(options: options)
|
||||||
|
self.networkContext = context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func loadCacheToken() -> String? {
|
func loadCacheToken() -> String? {
|
||||||
if let data = try? KeychainStore.shared.load(account: "token") {
|
if let data = try? KeychainStore.shared.load(account: "token") {
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
//
|
|
||||||
// NetworkModel.swift
|
|
||||||
// punchnet
|
|
||||||
//
|
|
||||||
// Created by 安礼成 on 2026/3/24.
|
|
||||||
//
|
|
||||||
import Foundation
|
|
||||||
import Observation
|
|
||||||
|
|
||||||
@Observable
|
|
||||||
class NetworkModel {
|
|
||||||
var networkContext: SDLAPIClient.NetworkContext = .default()
|
|
||||||
|
|
||||||
func connectNetwork(accessToken: String) async throws {
|
|
||||||
self.networkContext = try await SDLAPIClient.connectNetwork(accesToken: accessToken)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -25,9 +25,6 @@ struct NetworkView: View {
|
|||||||
@State private var showMode: NetworkShowMode = .resource
|
@State private var showMode: NetworkShowMode = .resource
|
||||||
@State private var connectState: ConnectState = .disconnected
|
@State private var connectState: ConnectState = .disconnected
|
||||||
|
|
||||||
// 多个View之间共享变量的最佳方式
|
|
||||||
@State private var networkModel: NetworkModel = NetworkModel()
|
|
||||||
|
|
||||||
private var vpnManager = VPNManager.shared
|
private var vpnManager = VPNManager.shared
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -50,7 +47,7 @@ struct NetworkView: View {
|
|||||||
.font(.system(size: 14, weight: .semibold))
|
.font(.system(size: 14, weight: .semibold))
|
||||||
|
|
||||||
if connectState == .connected {
|
if connectState == .connected {
|
||||||
Text("虚拟局域网 IP: \(networkModel.networkContext.ip)")
|
Text("虚拟局域网 IP: \(self.appContext.networkContext.ip)")
|
||||||
.font(.system(size: 11, design: .monospaced))
|
.font(.system(size: 11, design: .monospaced))
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
} else {
|
} else {
|
||||||
@ -103,7 +100,6 @@ struct NetworkView: View {
|
|||||||
.background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow))
|
.background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow))
|
||||||
}
|
}
|
||||||
.frame(minWidth: 700, minHeight: 500) // 适当调大宽度以适应 SplitView
|
.frame(minWidth: 700, minHeight: 500) // 适当调大宽度以适应 SplitView
|
||||||
.environment(self.networkModel)
|
|
||||||
.onAppear {
|
.onAppear {
|
||||||
syncState(vpnManager.vpnStatus)
|
syncState(vpnManager.vpnStatus)
|
||||||
}
|
}
|
||||||
@ -129,7 +125,7 @@ struct NetworkView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct NetworkConnectedView: View {
|
struct NetworkConnectedView: View {
|
||||||
@Environment(NetworkModel.self) private var networkModel: NetworkModel
|
@Environment(AppContext.self) private var appContext: AppContext
|
||||||
@Binding var showMode: NetworkShowMode
|
@Binding var showMode: NetworkShowMode
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -141,7 +137,7 @@ struct NetworkConnectedView: View {
|
|||||||
GridItem(.flexible(), spacing: 8),
|
GridItem(.flexible(), spacing: 8),
|
||||||
GridItem(.flexible(), spacing: 8)
|
GridItem(.flexible(), spacing: 8)
|
||||||
], spacing: 10) {
|
], spacing: 10) {
|
||||||
ForEach(networkModel.networkContext.resourceList, id: \.uuid) { res in
|
ForEach(appContext.networkContext.resourceList, id: \.uuid) { res in
|
||||||
ResourceItemCard(resource: res)
|
ResourceItemCard(resource: res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +156,6 @@ struct NetworkConnectedView: View {
|
|||||||
|
|
||||||
struct NetworkDisconnectedView: View {
|
struct NetworkDisconnectedView: View {
|
||||||
@Environment(AppContext.self) private var appContext: AppContext
|
@Environment(AppContext.self) private var appContext: AppContext
|
||||||
@Environment(NetworkModel.self) private var networkModel: NetworkModel
|
|
||||||
@State private var isConnecting: Bool = false
|
@State private var isConnecting: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -201,26 +196,9 @@ struct NetworkDisconnectedView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
guard let session = appContext.networkSession else {
|
try await self.appContext.connectNetwork()
|
||||||
return
|
} catch let err {
|
||||||
}
|
print("Connection error: \(err)")
|
||||||
|
|
||||||
let context = try await SDLAPIClient.connectNetwork(accesToken: session.accessToken)
|
|
||||||
if let options = SystemConfig.getOptions(
|
|
||||||
networkId: UInt32(session.networkId),
|
|
||||||
networkDomain: session.networkDomain,
|
|
||||||
ip: context.ip,
|
|
||||||
maskLen: context.maskLen,
|
|
||||||
accessToken: session.accessToken,
|
|
||||||
identityId: context.identityId,
|
|
||||||
hostname: context.hostname,
|
|
||||||
noticePort: appContext.noticePort
|
|
||||||
) {
|
|
||||||
try await VPNManager.shared.enableVpn(options: options)
|
|
||||||
self.networkModel.networkContext = context
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
print("Connection error: \(error)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,19 +206,19 @@ struct NetworkDisconnectedView: View {
|
|||||||
|
|
||||||
// MARK: - 设备组视图 (NavigationSplitView)
|
// MARK: - 设备组视图 (NavigationSplitView)
|
||||||
struct NetworkDeviceGroupView: View {
|
struct NetworkDeviceGroupView: View {
|
||||||
@Environment(NetworkModel.self) private var networkModel: NetworkModel
|
@Environment(AppContext.self) private var appContext: AppContext
|
||||||
@State private var selectedId: Int?
|
@State private var selectedId: Int?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationSplitView {
|
NavigationSplitView {
|
||||||
List(networkModel.networkContext.nodeList, id: \.id, selection: $selectedId) { node in
|
List(appContext.networkContext.nodeList, id: \.id, selection: $selectedId) { node in
|
||||||
NetworkNodeHeadView(node: node)
|
NetworkNodeHeadView(node: node)
|
||||||
.tag(node.id)
|
.tag(node.id)
|
||||||
}
|
}
|
||||||
.listStyle(.sidebar)
|
.listStyle(.sidebar)
|
||||||
.navigationSplitViewColumnWidth(min: 200, ideal: 220)
|
.navigationSplitViewColumnWidth(min: 200, ideal: 220)
|
||||||
} detail: {
|
} detail: {
|
||||||
if let selectedNode = networkModel.networkContext.nodeList.first(where: { $0.id == selectedId }) {
|
if let selectedNode = appContext.networkContext.nodeList.first(where: { $0.id == selectedId }) {
|
||||||
NetworkNodeDetailView(node: selectedNode)
|
NetworkNodeDetailView(node: selectedNode)
|
||||||
} else {
|
} else {
|
||||||
ContentUnavailableView("选择成员设备", systemImage: "macbook.and.iphone", description: Text("查看详细网络信息和服务"))
|
ContentUnavailableView("选择成员设备", systemImage: "macbook.and.iphone", description: Text("查看详细网络信息和服务"))
|
||||||
@ -248,7 +226,7 @@ struct NetworkDeviceGroupView: View {
|
|||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if selectedId == nil {
|
if selectedId == nil {
|
||||||
selectedId = networkModel.networkContext.nodeList.first?.id
|
selectedId = appContext.networkContext.nodeList.first?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,21 +24,21 @@ struct SettingsDeviceView: View {
|
|||||||
.cornerRadius(12)
|
.cornerRadius(12)
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
// Text(self.appContext.networkContext?.hostname ?? "未定义")
|
Text(self.appContext.networkContext.hostname)
|
||||||
// .font(.title3.bold())
|
.font(.title3.bold())
|
||||||
//
|
|
||||||
// Text(SystemConfig.systemInfo)
|
Text(SystemConfig.systemInfo)
|
||||||
// .font(.subheadline)
|
.font(.subheadline)
|
||||||
// .foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 4)
|
.padding(.horizontal, 4)
|
||||||
|
|
||||||
// MARK: - 详细参数卡片
|
// MARK: - 详细参数卡片
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
// 设备名称行
|
// 设备名称行
|
||||||
DevicePropertyRow(title: "设备名称", value: self.appContext.networkContext?.hostname ?? "未定义") {
|
DevicePropertyRow(title: "设备名称", value: self.appContext.networkContext.hostname) {
|
||||||
Button {
|
Button {
|
||||||
// 修改逻辑
|
// 修改逻辑
|
||||||
} label: {
|
} label: {
|
||||||
@ -55,7 +55,7 @@ struct SettingsDeviceView: View {
|
|||||||
Divider().padding(.leading, 16)
|
Divider().padding(.leading, 16)
|
||||||
|
|
||||||
// IPv4 行
|
// IPv4 行
|
||||||
DevicePropertyRow(title: "虚拟 IPv4", value: self.appContext.networkContext?.ip ?? "0.0.0.0") {
|
DevicePropertyRow(title: "虚拟 IPv4", value: self.appContext.networkContext.ip) {
|
||||||
Image(systemName: "info.circle")
|
Image(systemName: "info.circle")
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user