/* * Copyright (c) 2025 SimcuTeam. All rights reserved. * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 * Communications/SimApiLoginItem:登录信息项。 */ package simapi.communications import std.collection.* import soulsoft_serialization.* /** * 登录信息项:Token 认证通过后注入请求上下文。 * 对齐 C# SimApiLoginItem(Id / Type / Meta / Extra,camelCase 输出 id/type/meta/extra)。 * * 说明:因 _extra 为 HashMap(Any 不满足 soulsoft 的 ISerialization 约束, * 无法用 @Serialization 宏),故手动实现 ISerialization(serialize + deserialize); * 调用方统一通过 JsonSerializer.serializeObject() / deserializeObject() 使用 * (对齐 .NET JsonSerializer.Serialize / Deserialize)。 */ public class SimApiLoginItem <: ISerialization { public var _id: String = "" public var _types: Array = [] public var _meta: HashMap = HashMap() public var _extra: HashMap = HashMap() public init() {} public init(id: String) { this._id = id this._types = ["user"] this._meta = HashMap() this._extra = HashMap() } public init(id: String, types: Array) { this._id = id this._types = types this._meta = HashMap() this._extra = HashMap() } /** * 序列化为 DataModel:{"id","type","meta","extra"}。 */ public func serializeObject(options: JsonSerializerOptions): DataModel { let dms = DataModelStruct() dms.add(Field("id", DataModelString(_id))) // type: string[] let typesSeq = DataModelSeq() for (t in _types) { typesSeq.add(DataModelString(t)) } dms.add(Field("type", typesSeq)) // meta: object let metaStruct = DataModelStruct() for ((k, v) in _meta) { metaStruct.add(Field(k, DataModelString(v))) } dms.add(Field("meta", metaStruct)) // extra: object let extraStruct = DataModelStruct() for ((k, v) in _extra) { extraStruct.add(Field(k, anyToDataModel(v))) } dms.add(Field("extra", extraStruct)) dms } /** * 从 DataModel 反序列化:{"id","type","meta","extra"}。 */ public static func deserializeObject(dm: DataModel, options: JsonSerializerOptions): SimApiLoginItem { let item = SimApiLoginItem() if (let dms: DataModelStruct <- dm) { for (field in dms.getFields()) { match (field.getName()) { case "id" => item._id = field.getData() |> dataModelToString case "type" => let list = ArrayList() if (let seq: DataModelSeq <- field.getData()) { for (sub in seq.getItems()) { list.add(dataModelToString(sub)) } } item._types = list.toArray() case "meta" => if (let metaStruct: DataModelStruct <- field.getData()) { for (sub in metaStruct.getFields()) { item._meta[sub.getName()] = dataModelToString(sub.getData()) } } case "extra" => if (let extraStruct: DataModelStruct <- field.getData()) { for (sub in extraStruct.getFields()) { item._extra[sub.getName()] = dataModelToAny(sub.getData()) } } case _ => () } } } item } private static func dataModelToString(dm: DataModel): String { if (let s: DataModelString <- dm) { return s.getValue() } if (let i: DataModelInt <- dm) { return "${i.getValue()}" } if (let b: DataModelBool <- dm) { return "${b.getValue()}" } "" } private static func dataModelToAny(dm: DataModel): Any { if (let s: DataModelString <- dm) { return s.getValue() } if (let i: DataModelInt <- dm) { return i.getValue() } if (let b: DataModelBool <- dm) { return b.getValue() } if (let f: DataModelFloat <- dm) { return f.getValue() } if (let dms: DataModelStruct <- dm) { var map = HashMap() for (field in dms.getFields()) { map[field.getName()] = dataModelToAny(field.getData()) } return map } if (let seq: DataModelSeq <- dm) { let list = ArrayList() for (item in seq.getItems()) { list.add(dataModelToAny(item)) } return list.toArray() } "" } private static func anyToDataModel(v: Any): DataModel { if (let s: String <- v) { return DataModelString(s) } if (let i: Int64 <- v) { return DataModelInt(i) } if (let b: Bool <- v) { return DataModelBool(b) } if (let f: Float64 <- v) { return DataModelFloat(f) } if (let s: ToString <- v) { return DataModelString(s.toString()) } DataModelNull() } }