fix views
This commit is contained in:
parent
a18d07924f
commit
fd22574db1
@ -30,6 +30,9 @@ struct SDLAPIClient {
|
|||||||
request.httpBody = postData
|
request.httpBody = postData
|
||||||
|
|
||||||
let (data, _) = try await URLSession.shared.data(for: request)
|
let (data, _) = try await URLSession.shared.data(for: request)
|
||||||
|
|
||||||
|
NSLog("response is: \(String(bytes: data, encoding: .utf8))")
|
||||||
|
|
||||||
let apiResponse = try JSONDecoder().decode(SDLAPIResponse<T>.self, from: data)
|
let apiResponse = try JSONDecoder().decode(SDLAPIResponse<T>.self, from: data)
|
||||||
|
|
||||||
if apiResponse.code == 0, let data = apiResponse.data {
|
if apiResponse.code == 0, let data = apiResponse.data {
|
||||||
|
|||||||
@ -18,43 +18,61 @@ class NetworkModel {
|
|||||||
case disconnected
|
case disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
// 展示状态
|
|
||||||
enum ShowMode {
|
|
||||||
case resource
|
|
||||||
case device
|
|
||||||
}
|
|
||||||
|
|
||||||
// 资源列表
|
// 资源列表
|
||||||
struct Resource {
|
struct Resource: Codable {
|
||||||
var id: Int
|
var id: Int
|
||||||
var status: Int
|
|
||||||
var name: String
|
var name: String
|
||||||
var schema: String
|
var url: String
|
||||||
|
var connectionStatus: String
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
case name
|
||||||
|
case url
|
||||||
|
case connectionStatus = "connection_status"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备列表
|
// 设备列表
|
||||||
struct Device {
|
struct Node: Codable {
|
||||||
var id: Int
|
var id: Int
|
||||||
var status: Int
|
|
||||||
var name: String
|
var name: String
|
||||||
var ipv4: String
|
var ip: String
|
||||||
var ipv6: String
|
|
||||||
var system: String
|
var system: String
|
||||||
|
var connectStatus: Int
|
||||||
var resources: [Resource]
|
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
hasher.combine(id)
|
hasher.combine(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
case name
|
||||||
|
case ip
|
||||||
|
case system
|
||||||
|
case connectStatus = "connect_status"
|
||||||
|
}
|
||||||
|
|
||||||
static func == (lhs: Self, rhs: Self) -> Bool {
|
static func == (lhs: Self, rhs: Self) -> Bool {
|
||||||
return lhs.id == rhs.id
|
return lhs.id == rhs.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NetworkContext: Codable {
|
||||||
|
let ip: String
|
||||||
|
let resourceList: [Resource]
|
||||||
|
let nodeList: [Node]
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case ip
|
||||||
|
case resourceList = "resource_list"
|
||||||
|
case nodeList = "node_list"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 状态管理
|
// 状态管理
|
||||||
var connectState: ConnectState = .disconnected
|
var connectState: ConnectState = .disconnected
|
||||||
var showModel: ShowMode = .device
|
|
||||||
|
|
||||||
// 网络连接开关
|
// 网络连接开关
|
||||||
var isOn: Bool = false {
|
var isOn: Bool = false {
|
||||||
@ -68,51 +86,37 @@ class NetworkModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 当前选中的设备
|
// 当前选中的设备
|
||||||
var selectedDevice: Device?
|
var selectedNode: Node?
|
||||||
|
|
||||||
var resources: [Resource] = [
|
var ip: String = ""
|
||||||
.init(id: 1, status: 1, name: "OA", schema: "http://100.92.108.1:8080"),
|
var resourceList: [Resource] = []
|
||||||
.init(id: 2, status: 0, name: "数据资源", schema: "http://100.92.108.1:8080"),
|
var nodeList: [Node] = []
|
||||||
.init(id: 3, status: 1, name: "OA", schema: "http://100.92.108.1:8080"),
|
|
||||||
.init(id: 4, status: 0, name: "TEST", schema: "http://100.92.108.1:8080"),
|
|
||||||
.init(id: 10, status: 1, name: "YES", schema: "http://100.92.108.1:8080"),
|
|
||||||
.init(id: 11, status: 0, name: "DEBUG", schema: "http://100.92.108.1:8080"),
|
|
||||||
]
|
|
||||||
|
|
||||||
var devices: [Device] = [
|
|
||||||
]
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
self.devices = [
|
|
||||||
.init(id: 1, status: 1, name: "test1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 2, status: 1, name: "test2", ipv4: "192.168.1.2", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 3, status: 1, name: "test3", ipv4: "192.168.1.3", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 4, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 5, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 15, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 25, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 35, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 45, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
.init(id: 55, status: 1, name: "阿里云1", ipv4: "192.168.1.1", ipv6: "fa9d.fa9d.fa9d.fa9d", system: "MacOS 12", resources: self.resources),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func changeSelectedDevice(deviceId: Int?) {
|
func changeSelectedNode(nodeId: Int?) {
|
||||||
if let deviceId {
|
if let nodeId {
|
||||||
if let device = self.devices.first(where: { $0.id == deviceId}) {
|
if let node = self.nodeList.first(where: { $0.id == nodeId}) {
|
||||||
self.selectedDevice = device
|
self.selectedNode = node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func connect() async throws {
|
@MainActor
|
||||||
// let params: [String: Any] = [
|
func connect(networkSession: UserContext.NetworkSession) async throws {
|
||||||
// "client_id": SystemConfig.getClientId(),
|
let params: [String: Any] = [
|
||||||
// "access_token": networkSession.accessToken
|
"client_id": SystemConfig.getClientId(),
|
||||||
// ]
|
"access_token": networkSession.accessToken
|
||||||
//
|
]
|
||||||
// try await SDLAPIClient.doPost(path: "/connect", params: params, as: <#T##Decodable.Type#>)
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
let networkContext = try await SDLAPIClient.doPost(path: "/connect", params: params, as: NetworkContext.self)
|
||||||
|
self.ip = networkContext.ip
|
||||||
|
self.resourceList = networkContext.resourceList
|
||||||
|
self.nodeList = networkContext.nodeList
|
||||||
|
self.connectState = .connected
|
||||||
|
self.isOn = true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,13 @@ import SwiftUI
|
|||||||
struct NetworkView: View {
|
struct NetworkView: View {
|
||||||
@Environment(UserContext.self) var userContext: UserContext
|
@Environment(UserContext.self) var userContext: UserContext
|
||||||
@State private var networkModel = NetworkModel()
|
@State private var networkModel = NetworkModel()
|
||||||
|
@State private var showMode: ShowMode = .resource
|
||||||
|
|
||||||
|
// 展示状态
|
||||||
|
enum ShowMode {
|
||||||
|
case resource
|
||||||
|
case device
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
@ -25,6 +32,7 @@ struct NetworkView: View {
|
|||||||
HStack {
|
HStack {
|
||||||
Toggle("", isOn: $networkModel.isOn)
|
Toggle("", isOn: $networkModel.isOn)
|
||||||
.toggleStyle(SwitchToggleStyle(tint: .green))
|
.toggleStyle(SwitchToggleStyle(tint: .green))
|
||||||
|
.disabled(true)
|
||||||
|
|
||||||
Text("已连接")
|
Text("已连接")
|
||||||
|
|
||||||
@ -36,13 +44,13 @@ struct NetworkView: View {
|
|||||||
// 显示设备和资源选项
|
// 显示设备和资源选项
|
||||||
HStack {
|
HStack {
|
||||||
Button {
|
Button {
|
||||||
self.networkModel.showModel = .resource
|
self.showMode = .resource
|
||||||
} label: {
|
} label: {
|
||||||
Text("资源")
|
Text("资源")
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
self.networkModel.showModel = .device
|
self.showMode = .device
|
||||||
} label: {
|
} label: {
|
||||||
Text("设备")
|
Text("设备")
|
||||||
}
|
}
|
||||||
@ -55,7 +63,14 @@ struct NetworkView: View {
|
|||||||
case .waitAuth:
|
case .waitAuth:
|
||||||
NetworkWaitAuthView(networkModel: self.networkModel)
|
NetworkWaitAuthView(networkModel: self.networkModel)
|
||||||
case .connected:
|
case .connected:
|
||||||
NetworkConnctedView(networkModel: self.networkModel)
|
Group {
|
||||||
|
switch self.showMode {
|
||||||
|
case .resource:
|
||||||
|
NetworkResourceGroupView(networkModel: self.networkModel)
|
||||||
|
case .device:
|
||||||
|
NetworkDeviceGroupView(networkModel: self.networkModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
case .disconnected:
|
case .disconnected:
|
||||||
NetworkDisconnctedView(networkModel: self.networkModel)
|
NetworkDisconnctedView(networkModel: self.networkModel)
|
||||||
}
|
}
|
||||||
@ -80,16 +95,25 @@ struct NetworkView: View {
|
|||||||
// 网络处于未连接状态
|
// 网络处于未连接状态
|
||||||
struct NetworkDisconnctedView: View {
|
struct NetworkDisconnctedView: View {
|
||||||
@Bindable var networkModel: NetworkModel
|
@Bindable var networkModel: NetworkModel
|
||||||
|
@Environment(UserContext.self) var userContext: UserContext
|
||||||
|
|
||||||
|
@State private var showAlert = false
|
||||||
|
@State private var errorMessage = ""
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
Color.clear
|
Color.clear
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
Task {
|
Task { @MainActor in
|
||||||
try await startVpn()
|
do {
|
||||||
|
try await self.connect()
|
||||||
|
try await self.startVpn()
|
||||||
|
} catch let err {
|
||||||
|
self.showAlert = true
|
||||||
|
self.errorMessage = err.localizedDescription
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Text("连接")
|
Text("连接")
|
||||||
@ -120,9 +144,19 @@ struct NetworkDisconnctedView: View {
|
|||||||
.frame(width: 120, height: 35)
|
.frame(width: 120, height: 35)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.alert(isPresented: $showAlert) {
|
||||||
|
Alert(title: Text("提示"), message: Text(self.errorMessage))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func connect() async throws {
|
||||||
|
guard let networkSession = userContext.networkSession else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try await networkModel.connect(networkSession: networkSession)
|
||||||
|
}
|
||||||
|
|
||||||
// 执行登陆操作
|
// 执行登陆操作
|
||||||
private func startVpn() async throws {
|
private func startVpn() async throws {
|
||||||
let clientId = SystemConfig.getClientId()
|
let clientId = SystemConfig.getClientId()
|
||||||
@ -143,151 +177,125 @@ struct NetworkDisconnctedView: View {
|
|||||||
|
|
||||||
// 网络处于连接状态
|
// 网络处于连接状态
|
||||||
|
|
||||||
struct NetworkConnctedView: View {
|
// 显示资源信息
|
||||||
|
struct NetworkResourceGroupView: View {
|
||||||
@Bindable var networkModel: NetworkModel
|
@Bindable var networkModel: NetworkModel
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3), spacing: 8) {
|
||||||
switch networkModel.showModel {
|
ForEach(self.networkModel.resourceList, id: \.id) { resource in
|
||||||
case .resource:
|
NetworkResourceView(resource: resource)
|
||||||
NetworkResourceGroupView(networkModel: self.networkModel)
|
|
||||||
case .device:
|
|
||||||
NetworkDeviceGroupView(networkModel: self.networkModel)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NetworkConnctedView {
|
struct NetworkResourceView: View {
|
||||||
|
var resource: NetworkModel.Resource
|
||||||
|
|
||||||
// 显示资源信息
|
var body: some View {
|
||||||
struct NetworkResourceGroupView: View {
|
VStack {
|
||||||
@Bindable var networkModel: NetworkModel
|
HStack {
|
||||||
|
Text(resource.connectionStatus)
|
||||||
|
|
||||||
var body: some View {
|
Text(resource.name)
|
||||||
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3), spacing: 8) {
|
|
||||||
ForEach(self.networkModel.resources, id: \.id) { resource in
|
|
||||||
NetworkResourceView(resource: resource)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NetworkResourceView: View {
|
|
||||||
var resource: NetworkModel.Resource
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack {
|
|
||||||
HStack {
|
|
||||||
Text(resource.status == 1 ? "yes" : "no")
|
|
||||||
|
|
||||||
Text(resource.name)
|
|
||||||
.font(.system(size: 14, weight: .regular))
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(resource.schema)
|
|
||||||
.font(.system(size: 14, weight: .regular))
|
.font(.system(size: 14, weight: .regular))
|
||||||
.padding(.leading, 30)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text(resource.url)
|
||||||
|
.font(.system(size: 14, weight: .regular))
|
||||||
|
.padding(.leading, 30)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示设备信息
|
||||||
|
struct NetworkDeviceGroupView: View {
|
||||||
|
@Bindable var networkModel: NetworkModel
|
||||||
|
@State private var selectedId: Int?
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationSplitView {
|
||||||
|
List(self.networkModel.nodeList, id: \.id, selection: $selectedId) { node in
|
||||||
|
NetworkNodeHeadView(node: node)
|
||||||
|
}
|
||||||
|
.listStyle(.sidebar)
|
||||||
|
.onChange(of: selectedId) {
|
||||||
|
self.networkModel.changeSelectedNode(nodeId: selectedId)
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
if selectedId == nil {
|
||||||
|
selectedId = self.networkModel.nodeList.first?.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} detail: {
|
||||||
|
NetworkNodeDetailView(node: $networkModel.selectedNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示设备信息
|
}
|
||||||
struct NetworkDeviceGroupView: View {
|
|
||||||
@Bindable var networkModel: NetworkModel
|
|
||||||
@State private var selectedId: Int?
|
|
||||||
|
|
||||||
var body: some View {
|
struct NetworkNodeHeadView: View {
|
||||||
NavigationSplitView {
|
var node: NetworkModel.Node
|
||||||
List(self.networkModel.devices, id: \.id, selection: $selectedId) { device in
|
|
||||||
NetworkDeviceHeadView(device: device)
|
|
||||||
}
|
|
||||||
.listStyle(.sidebar)
|
|
||||||
.onChange(of: selectedId) {
|
|
||||||
self.networkModel.changeSelectedDevice(deviceId: selectedId)
|
|
||||||
}
|
|
||||||
.onAppear {
|
|
||||||
if selectedId == nil {
|
|
||||||
selectedId = self.networkModel.devices.first?.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} detail: {
|
|
||||||
NetworkDeviceDetailView(device: $networkModel.selectedDevice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
Text(node.connectStatus == 1 ? "yes" : "no")
|
||||||
|
|
||||||
struct NetworkDeviceHeadView: View {
|
Text(node.name)
|
||||||
var device: NetworkModel.Device
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack {
|
|
||||||
HStack {
|
|
||||||
Text(device.status == 1 ? "yes" : "no")
|
|
||||||
|
|
||||||
Text(device.name)
|
|
||||||
.font(.system(size: 14, weight: .regular))
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(device.ipv4)
|
|
||||||
.font(.system(size: 14, weight: .regular))
|
.font(.system(size: 14, weight: .regular))
|
||||||
.padding(.leading, 30)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text(node.ip)
|
||||||
|
.font(.system(size: 14, weight: .regular))
|
||||||
|
.padding(.leading, 30)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct NetworkDeviceDetailView: View {
|
struct NetworkNodeDetailView: View {
|
||||||
@Binding var device: NetworkModel.Device?
|
@Binding var node: NetworkModel.Node?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
Group {
|
||||||
if let device {
|
if let node {
|
||||||
List {
|
List {
|
||||||
Section {
|
Section {
|
||||||
HStack {
|
HStack {
|
||||||
Text("连接状态")
|
Text("连接状态")
|
||||||
|
|
||||||
Text("\(device.status)")
|
Text("\(node.connectStatus)")
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
|
||||||
|
|
||||||
HStack {
|
|
||||||
Text("虚拟IPv4")
|
|
||||||
|
|
||||||
Text("\(device.ipv4)")
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
|
|
||||||
HStack {
|
|
||||||
Text("虚拟IPv6")
|
|
||||||
|
|
||||||
Text("\(device.ipv6)")
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
|
|
||||||
HStack {
|
|
||||||
Text("操作系统")
|
|
||||||
|
|
||||||
Text("\(device.system)")
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Section("服务列表") {
|
HStack {
|
||||||
ForEach(device.resources, id: \.id) { resource in
|
Text("虚拟IPv4")
|
||||||
HStack {
|
|
||||||
Text("\(resource.name)")
|
Text("\(node.ip)")
|
||||||
Text("\(resource.schema)")
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
HStack {
|
||||||
|
Text("操作系统")
|
||||||
|
Text("\(node.system)")
|
||||||
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
EmptyView()
|
// Section("服务列表") {
|
||||||
|
// ForEach(device.resources, id: \.id) { resource in
|
||||||
|
// HStack {
|
||||||
|
// Text("\(resource.name)")
|
||||||
|
// Text("\(resource.schema)")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user