feat(ios): add device details and reliable ipa build

This commit is contained in:
chick
2026-09-09 00:46:28 +08:00
parent 7778693807
commit 84ec3678c0
10 changed files with 402 additions and 6 deletions
@@ -0,0 +1,131 @@
import SwiftUI
struct InstanceDetailView: View {
@StateObject private var model: DeviceViewModel
@State private var revealsSensitive = false
init(instance: Instance, model: DeviceViewModel? = nil) {
_model = StateObject(wrappedValue: model ?? DefaultContainer.makeDeviceModel(instance: instance))
}
var body: some View {
ZStack {
AITheme.canvas.ignoresSafeArea()
ScrollView {
LazyVStack(spacing: 12) {
header
if let errorMessage = model.errorMessage {
AICard {
Text(errorMessage)
.font(.subheadline)
.foregroundStyle(AITheme.warning)
}
}
if let snapshot = model.snapshot {
ForEach(snapshot.sections) { section in
sectionCard(section)
}
}
}
.padding(16)
}
}
.navigationTitle(model.instance.name)
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {
revealsSensitive.toggle()
} label: {
Label(revealsSensitive ? "隐藏敏感值" : "显示敏感值",
systemImage: revealsSensitive ? "eye.slash" : "eye")
}
.buttonStyle(AIButtonStyle(kind: .secondary, size: .compact))
}
}
.refreshable {
await model.refresh()
}
.task {
await model.refresh()
}
}
private var header: some View {
AICard {
VStack(alignment: .leading, spacing: 8) {
Text("设备详情")
.font(.headline)
Text(model.instance.origin.absoluteString)
.font(.subheadline)
.foregroundStyle(AITheme.muted)
if model.isLoading {
Text("正在读取设备能力…")
.font(.subheadline)
.foregroundStyle(AITheme.muted)
}
}
}
}
private func sectionCard(_ section: DeviceSection) -> some View {
AICard {
VStack(alignment: .leading, spacing: 12) {
Text(section.title)
.font(.headline)
if section.values.isEmpty {
Text("此模块当前不可用或未返回数据。")
.font(.subheadline)
.foregroundStyle(AITheme.muted)
} else {
ForEach(section.values.sorted(by: { $0.key < $1.key }), id: \.key) { item in
HStack(alignment: .top, spacing: 10) {
Text(fieldLabel(item.key))
.font(.subheadline)
.foregroundStyle(AITheme.muted)
.frame(maxWidth: .infinity, alignment: .leading)
Text(display(item.key, item.value))
.font(.subheadline)
.foregroundStyle(AITheme.ink)
.multilineTextAlignment(.trailing)
}
}
}
}
}
}
private let fieldLabels: [String: String] = [
"model": "型号",
"manufacturer": "制造商",
"imei": "IMEI",
"revision": "固件版本",
"online": "在线",
"powered": "基带电源",
"present": "SIM 在位",
"iccid": "ICCID",
"imsi": "IMSI",
"phone_numbers": "号码",
"sms_center": "短信中心",
"operator_name": "运营商",
"registration_status": "注册状态",
"technology_preference": "网络制式",
"signal_strength": "信号强度",
"core_count": "核心数",
"model_name": "CPU 型号",
"state": "连接状态",
"latency_ms": "延迟(ms)"
]
private let sensitiveKeys: Set<String> = ["imei", "iccid", "imsi", "phone_numbers", "sms_center"]
private func fieldLabel(_ key: String) -> String {
fieldLabels[key] ?? key.replacingOccurrences(of: "_", with: " ")
}
private func display(_ key: String, _ value: String) -> String {
guard sensitiveKeys.contains(key), !revealsSensitive else { return value }
guard let first = value.first, value.count > 6 else { return String(repeating: "•", count: min(value.count, 8)) }
let tail = value.suffix(4)
return "\(first) •••• \(tail)"
}
}