Files
suixinkan_uikit/suixinkan/Features/Statistics/Models/StatisticsModels.swift
汉秋 6492f80ef0 Implement statistics tab aligned with Android and fix summary decode.
Add role-based analyse APIs, summary/daily UI with date range sheet, and flexible parsing for string refund amounts from the backend.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:32:14 +08:00

135 lines
3.9 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// StatisticsModels.swift
// suixinkan
//
import Foundation
/// Android `StatisticsResponse`
struct StatisticsSummaryResponse: Decodable, Equatable {
let orderAmountSum: String
let orderCount: Int
let orderPriceAvg: String
let receivedAmountSum: String
let refundAmountSum: String
enum CodingKeys: String, CodingKey {
case orderAmountSum = "order_amount_sum"
case orderCount = "order_count"
case orderPriceAvg = "order_price_avg"
case receivedAmountSum = "received_amount_sum"
case refundAmountSum = "refund_amount_sum"
}
init(
orderAmountSum: String = "",
orderCount: Int = 0,
orderPriceAvg: String = "",
receivedAmountSum: String = "",
refundAmountSum: String = ""
) {
self.orderAmountSum = orderAmountSum
self.orderCount = orderCount
self.orderPriceAvg = orderPriceAvg
self.receivedAmountSum = receivedAmountSum
self.refundAmountSum = refundAmountSum
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
orderAmountSum = try container.decodeIfPresent(String.self, forKey: .orderAmountSum) ?? ""
orderCount = try container.decodeIfPresent(Int.self, forKey: .orderCount) ?? 0
orderPriceAvg = try container.decodeIfPresent(String.self, forKey: .orderPriceAvg) ?? ""
receivedAmountSum = try container.decodeIfPresent(String.self, forKey: .receivedAmountSum) ?? ""
refundAmountSum = Self.decodeAmountString(from: container, forKey: .refundAmountSum)
}
private static func decodeAmountString(
from container: KeyedDecodingContainer<CodingKeys>,
forKey key: CodingKeys
) -> String {
if let value = try? container.decode(String.self, forKey: key) {
return value
}
if let value = try? container.decode(Double.self, forKey: key) {
return String(value)
}
if let value = try? container.decode(Int.self, forKey: key) {
return String(value)
}
return ""
}
}
/// Android `StatisticsPageEntity`
struct StatisticsDailyItem: Decodable, Hashable {
let date: String
let orderCount: Int
let orderPrice: String
let refund: String
let received: String
enum CodingKeys: String, CodingKey {
case date
case orderCount = "order_count"
case orderPrice = "order_price"
case refund
case received
}
init(
date: String = "",
orderCount: Int = 0,
orderPrice: String = "",
refund: String = "",
received: String = ""
) {
self.date = date
self.orderCount = orderCount
self.orderPrice = orderPrice
self.refund = refund
self.received = received
}
}
/// Android `ListDataResponse`
struct ListDataResponse<T: Decodable>: Decodable {
let total: Int
let data: [T]
init(total: Int = 0, data: [T] = []) {
self.total = total
self.data = data
}
}
/// Android chip
enum StatisticsSummaryPeriod: String, CaseIterable {
case today = "今日"
case yesterday = "昨日"
case last7Days = "7日"
case thisMonth = "本月"
/// API `range`
var rangeValue: String {
switch self {
case .today: "1"
case .yesterday: "2"
case .last7Days: "3"
case .thisMonth: "4"
}
}
static func fromDisplayName(_ name: String) -> StatisticsSummaryPeriod? {
StatisticsSummaryPeriod(rawValue: name)
}
}
/// Android `DateRangeBottomSheet`
enum StatisticsRangeShortcut: String, CaseIterable {
case today = "今日"
case yesterday = "昨日"
case last7Days = "7日"
case all = "全部"
}