// // SaleUserQrParser.swift // suixinkan // // Created by Codex on 2026/6/29. // import Foundation /// 获客员绑定二维码解析器,从扫码内容提取 sale_user_id。 enum SaleUserQrParser { /// 标准获客员绑定二维码 method,与后端约定一致。 static let methodSaleUserBind = "sale_user_bind" /// 从获客员二维码内容解析 sale_user_id。 /// 标准格式:`{"method":"sale_user_bind","sale_user_id":2}` /// 兼容:纯数字、URL query、无 method 的历史 JSON。 static func parseSaleUserId(_ content: String) -> Int? { let trimmed = content.trimmingCharacters(in: .whitespacesAndNewlines) if trimmed.isEmpty { return nil } if trimmed.hasPrefix("{") { if let value = parseFromJSON(trimmed) { return value } } if let value = Int(trimmed), value > 0 { return value } if trimmed.contains("://") || trimmed.contains("?") { return parseFromURL(trimmed) } return nil } /// 判断扫码内容是否为获客员绑定专用二维码。 static func isSaleUserBindQR(_ content: String) -> Bool { guard let object = jsonObject(from: content) else { return false } let method = (object["method"] as? String)? .trimmingCharacters(in: .whitespacesAndNewlines) ?? "" return method == methodSaleUserBind } private static func parseFromJSON(_ json: String) -> Int? { guard let object = jsonObject(from: json) else { return nil } return parseFromJSONObject(object) } private static func jsonObject(from json: String) -> [String: Any]? { guard let data = json.data(using: .utf8), let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { return nil } return object } private static func parseFromJSONObject(_ object: [String: Any]) -> Int? { let method = (object["method"] as? String)? .trimmingCharacters(in: .whitespacesAndNewlines) ?? "" if method == methodSaleUserBind { return readIntValue(object["sale_user_id"]) } return readSaleUserId(object) } private static func readSaleUserId(_ object: [String: Any]) -> Int? { let keys = ["sale_user_id", "saleUserId", "user_id", "id"] for key in keys { if let value = readIntValue(object[key]) { return value } } return nil } private static func readIntValue(_ value: Any?) -> Int? { switch value { case let intValue as Int where intValue > 0: return intValue case let number as NSNumber where number.intValue > 0: return number.intValue case let stringValue as String: let trimmed = stringValue.trimmingCharacters(in: .whitespacesAndNewlines) if let intValue = Int(trimmed), intValue > 0 { return intValue } return nil default: return nil } } private static func parseFromURL(_ urlString: String) -> Int? { guard let components = URLComponents(string: urlString) else { return nil } let keys = ["sale_user_id", "saleUserId", "user_id", "id"] for key in keys { if let value = components.queryItems?.first(where: { $0.name == key })?.value, let intValue = Int(value.trimmingCharacters(in: .whitespacesAndNewlines)), intValue > 0 { return intValue } } return nil } }