import SwiftUI struct InstanceFormView: View { @Environment(\.dismiss) private var dismiss @ObservedObject var model: FleetViewModel @State private var name = "" @State private var originText = "" @State private var tagsText = "" @State private var password = "" @State private var validationMessage: String? private var canSave: Bool { !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !originText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } var body: some View { NavigationStack { ZStack { AITheme.canvas.ignoresSafeArea() ScrollView { VStack(spacing: 12) { AICard { VStack(alignment: .leading, spacing: 14) { field("名称", text: $name, placeholder: "Home Node") field("地址", text: $originText, placeholder: "http://192.168.1.10:3000") field("标签", text: $tagsText, placeholder: "home, primary") field("实例密码", text: $password, placeholder: "可选,保存在本机沙盒", secure: true) } } if let validationMessage { AIStatusBanner(validationMessage, tint: AITheme.danger, systemImage: "exclamationmark.triangle") } } .padding(16) } } .navigationTitle("添加实例") .aiBottomActionBar { HStack(spacing: 10) { Button("取消") { dismiss() } .buttonStyle( AIButtonStyle( kind: .secondary, size: .regular, fixedWidth: AITheme.footerSecondaryButtonWidth ) ) Button("保存实例") { save() } .buttonStyle(AIButtonStyle(kind: .primary, size: .regular, fillsWidth: true)) .disabled(!canSave) } } } } private func field( _ title: String, text: Binding, placeholder: String, secure: Bool = false ) -> some View { VStack(alignment: .leading, spacing: 6) { Text(title) .font(.subheadline.weight(.semibold)) .foregroundStyle(AITheme.ink) if secure { SecureField(placeholder, text: text) .textFieldStyle(AIFieldStyle()) .textContentType(.password) } else { TextField(placeholder, text: text) .textFieldStyle(AIFieldStyle()) #if os(iOS) .keyboardType(title == "地址" ? .URL : .default) .textInputAutocapitalization(title == "地址" || title == "标签" ? .never : nil) #endif .autocorrectionDisabled(title == "地址" || title == "标签") } } } private func save() { let normalizedName = name.trimmingCharacters(in: .whitespacesAndNewlines) guard let origin = URL(string: originText.trimmingCharacters(in: .whitespacesAndNewlines)), origin.scheme == "http" || origin.scheme == "https", origin.host != nil else { validationMessage = "请输入有效的 HTTP 或 HTTPS 根地址。" return } let tags = tagsText .split(separator: ",") .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .filter { !$0.isEmpty } let input = InstanceInput( name: normalizedName, origin: origin, tags: tags, password: password.isEmpty ? nil : password ) Task { do { try await model.add(input) dismiss() } catch { validationMessage = "保存失败,请检查地址是否重复。" } } } }