// // LoginState.swift // punchnet // // Created by 安礼成 on 2026/1/16. // import Foundation import Observation @Observable class UserContext { var isLogined: Bool = false var loginCredit: LoginCredit? var networkSession: NetworkSession? enum LoginCredit { case token(token: String) case accountAndPasword(account: String, password: String) } // 登陆后的网络会话信息 struct NetworkSession: Codable { struct ExitNode: Codable { let nnid: Int let nodeName: String enum CodingKeys: String, CodingKey { case nnid case nodeName = "node_name" } } let accessToken: String let username: String let userType: String let audit: Int let networkId: Int let networkName: String let networkDomain: String let exitNodes: [ExitNode] enum CodingKeys: String, CodingKey { case accessToken = "access_token" case username case userType = "user_type" case audit case networkId = "network_id" case networkName = "network_name" case networkDomain = "network_domain" case exitNodes = "exit_node" } } private let baseParams: [String: Any] = [ "client_id": SystemConfig.getClientId(), "mac": SystemConfig.macAddressString(mac: SystemConfig.getMacAddress()) ] @MainActor func loginWithAccountAndPassword(username: String, password: String) async throws { var params: [String: Any] = [ "username": username, "password": password, ] params.merge(baseParams) {$1} self.networkSession = try await SDLAPIClient.doPost(path: "/auth/login", params: params, as: NetworkSession.self) self.loginCredit = .accountAndPasword(account: username, password: password) self.isLogined = true } @MainActor func loginWithToken(token: String) async throws { var params: [String: Any] = [ "token": token, ] params.merge(baseParams) {$1} self.networkSession = try await SDLAPIClient.doPost(path: "/auth/token", params: params, as: NetworkSession.self) self.loginCredit = .token(token: token) self.isLogined = true } }