197 lines
5.5 KiB
Swift
197 lines
5.5 KiB
Swift
//
|
|
// LocationModels.swift
|
|
// suixinkan
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// 位置上报详情,对齐 Android `LocationDetailResponse`。
|
|
struct LocationDetailResponse: Decodable, Sendable {
|
|
let status: Int
|
|
let needReport: Bool
|
|
let expireTime: Int64
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case status
|
|
case needReport = "need_report"
|
|
case expireTime = "expire_time"
|
|
}
|
|
|
|
init(status: Int = 0, needReport: Bool = true, expireTime: Int64 = 0) {
|
|
self.status = status
|
|
self.needReport = needReport
|
|
self.expireTime = expireTime
|
|
}
|
|
}
|
|
|
|
/// 位置上报结果,对齐 Android `LocationReportResponse`。
|
|
struct LocationReportResponse: Decodable, Sendable {
|
|
let staffId: String
|
|
let expired: Int64
|
|
let status: Int
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case staffId = "staff_id"
|
|
case expired
|
|
case status
|
|
case storeUserId = "store_user_id"
|
|
}
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
staffId = Self.decodeFlexibleString(from: container, forKey: .staffId)
|
|
expired = try container.decodeIfPresent(Int64.self, forKey: .expired) ?? 0
|
|
status = try container.decodeIfPresent(Int.self, forKey: .status) ?? 0
|
|
}
|
|
|
|
init(staffId: String = "", expired: Int64 = 0, status: Int = 0) {
|
|
self.staffId = staffId
|
|
self.expired = expired
|
|
self.status = status
|
|
}
|
|
|
|
private static func decodeFlexibleString(
|
|
from container: KeyedDecodingContainer<CodingKeys>,
|
|
forKey key: CodingKeys,
|
|
defaultValue: String = ""
|
|
) -> String {
|
|
if let string = try? container.decode(String.self, forKey: key) {
|
|
return string
|
|
}
|
|
if let intValue = try? container.decode(Int.self, forKey: key) {
|
|
return String(intValue)
|
|
}
|
|
if let int64Value = try? container.decode(Int64.self, forKey: key) {
|
|
return String(int64Value)
|
|
}
|
|
return defaultValue
|
|
}
|
|
}
|
|
|
|
/// 历史上报类型筛选,对齐 Android `LocationReportFilterType`。
|
|
enum LocationReportFilterType: CaseIterable, Equatable {
|
|
case all
|
|
case immediate
|
|
case marked
|
|
case offline
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .all: "全部"
|
|
case .immediate: "立即上报"
|
|
case .marked: "标记上报"
|
|
case .offline: "离线上报"
|
|
}
|
|
}
|
|
|
|
var typeCode: Int {
|
|
switch self {
|
|
case .all: 0
|
|
case .immediate: 1
|
|
case .marked: 2
|
|
case .offline: 3
|
|
}
|
|
}
|
|
|
|
var tagColorHex: UInt {
|
|
switch self {
|
|
case .all, .immediate: 0x0073FF
|
|
case .marked: 0x22C55E
|
|
case .offline: 0x999999
|
|
}
|
|
}
|
|
|
|
static func from(typeCode: Int) -> LocationReportFilterType {
|
|
switch typeCode {
|
|
case 1: .immediate
|
|
case 2: .marked
|
|
case 3: .offline
|
|
default: .all
|
|
}
|
|
}
|
|
|
|
static func fromReportType(_ type: Int) -> LocationReportFilterType {
|
|
switch type {
|
|
case 1: .immediate
|
|
case 2: .marked
|
|
case 3: .offline
|
|
default: .all
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 历史上报单条记录,对齐 Android `LocationReportHistoryItem`。
|
|
struct LocationReportHistoryItem: Decodable, Equatable, Identifiable {
|
|
let id: Int64
|
|
let staffId: Int64
|
|
let type: Int
|
|
let latitude: String
|
|
let longitude: String
|
|
let address: String
|
|
let ip: String?
|
|
let remark: String
|
|
let createdAt: String
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case id
|
|
case staffId = "staff_id"
|
|
case type
|
|
case latitude
|
|
case longitude
|
|
case address
|
|
case ip
|
|
case remark
|
|
case createdAt = "created_at"
|
|
}
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
id = try container.decodeIfPresent(Int64.self, forKey: .id) ?? 0
|
|
staffId = try container.decodeIfPresent(Int64.self, forKey: .staffId) ?? 0
|
|
type = try container.decodeIfPresent(Int.self, forKey: .type) ?? 0
|
|
latitude = try container.decodeIfPresent(String.self, forKey: .latitude) ?? ""
|
|
longitude = try container.decodeIfPresent(String.self, forKey: .longitude) ?? ""
|
|
address = try container.decodeIfPresent(String.self, forKey: .address) ?? ""
|
|
ip = try container.decodeIfPresent(String.self, forKey: .ip)
|
|
remark = try container.decodeIfPresent(String.self, forKey: .remark) ?? ""
|
|
createdAt = try container.decodeIfPresent(String.self, forKey: .createdAt) ?? ""
|
|
}
|
|
|
|
init(
|
|
id: Int64 = 0,
|
|
staffId: Int64 = 0,
|
|
type: Int = 0,
|
|
latitude: String = "",
|
|
longitude: String = "",
|
|
address: String = "",
|
|
ip: String? = nil,
|
|
remark: String = "",
|
|
createdAt: String = ""
|
|
) {
|
|
self.id = id
|
|
self.staffId = staffId
|
|
self.type = type
|
|
self.latitude = latitude
|
|
self.longitude = longitude
|
|
self.address = address
|
|
self.ip = ip
|
|
self.remark = remark
|
|
self.createdAt = createdAt
|
|
}
|
|
|
|
var filterType: LocationReportFilterType {
|
|
LocationReportFilterType.fromReportType(type)
|
|
}
|
|
}
|
|
|
|
/// 历史上报列表响应。
|
|
struct LocationReportHistoryListResponse: Decodable, Equatable {
|
|
let list: [LocationReportHistoryItem]
|
|
let total: Int
|
|
|
|
init(list: [LocationReportHistoryItem] = [], total: Int = 0) {
|
|
self.list = list
|
|
self.total = total
|
|
}
|
|
}
|