- 应用图标改用与 Web favicon 同源的扁平标记,金色 SIM 卡体加三格递增信号,29pt 下仍可读 - 标签统一为胶囊形状,提高深色主题下的描边权重,避免标签在暗色下消失 - 消息卡片与详情分区卡片收紧行距,单屏信息密度明显提升 - 详情头部指标精简为 4 行,数据模块改为单条读数 - 批量选择勾选框移出名称区域,工具栏控件统一为等高 34pt - 分组编辑器改为点选即生效,移除说明文字与常驻禁用按钮
40 lines
1.2 KiB
Swift
40 lines
1.2 KiB
Swift
import Foundation
|
|
|
|
@MainActor
|
|
final class DeviceViewModel: ObservableObject {
|
|
@Published var snapshot: DeviceSnapshot?
|
|
@Published var isLoading = false
|
|
@Published var errorMessage: String?
|
|
@Published private(set) var connectionStatus: ConnectionStatus = .unknown
|
|
|
|
let instance: Instance
|
|
private let service: DeviceService
|
|
private let probe: ConnectionProbe?
|
|
|
|
init(instance: Instance, service: DeviceService, probe: ConnectionProbe? = nil) {
|
|
self.instance = instance
|
|
self.service = service
|
|
self.probe = probe
|
|
}
|
|
|
|
func refresh() async {
|
|
isLoading = true
|
|
errorMessage = nil
|
|
do {
|
|
snapshot = try await service.snapshot(instance)
|
|
} catch DeviceServiceError.unauthorized {
|
|
errorMessage = "需要实例密码登录后才能读取设备数据。"
|
|
} catch {
|
|
errorMessage = "节点无响应,请确认地址可访问、设备已开机且端口未被拦截。"
|
|
}
|
|
guard let probe else {
|
|
connectionStatus = .offline
|
|
isLoading = false
|
|
return
|
|
}
|
|
let result = try? await probe.test(instance)
|
|
connectionStatus = result?.status ?? .offline
|
|
isLoading = false
|
|
}
|
|
}
|