Files
suixinkan_ios_new/suixinkan/Core/Models/SharedBusinessModels.swift
汉秋 fb8430889b Add Projects, Schedule, and Invite modules with home routing.
Migrate project management, schedule management, and photographer invitation flows from placeholders, including project image OSS upload and shared business models.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 15:57:15 +08:00

167 lines
6.0 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.

//
// SharedBusinessModels.swift
// suixinkan
//
// Created by Codex on 2026/6/24.
//
import Foundation
///
struct AvailableOrderResponse: Decodable, Identifiable, Hashable {
var id: String { orderNumber }
let projectName: String
let orderNumber: String
let orderStatus: Int
let orderStatusLabel: String
let payTime: String
let userPhone: String
/// 线
enum CodingKeys: String, CodingKey {
case projectName = "project_name"
case orderNumber = "order_number"
case orderStatus = "order_status"
case orderStatusLabel = "order_status_label"
case payTime = "pay_time"
case userPhone = "user_phone"
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
projectName = try container.decodeSharedLossyString(forKey: .projectName)
orderNumber = try container.decodeSharedLossyString(forKey: .orderNumber)
orderStatus = try container.decodeSharedLossyInt(forKey: .orderStatus) ?? 0
orderStatusLabel = try container.decodeSharedLossyString(forKey: .orderStatusLabel)
payTime = try container.decodeSharedLossyString(forKey: .payTime)
userPhone = try container.decodeSharedLossyString(forKey: .userPhone)
}
}
///
struct PhotographerProjectItem: Decodable, Identifiable, Hashable {
let id: Int
let type: Int
let typeName: String
let status: Int
let statusName: String
let name: String
let coverProject: String
let coverVideo: String
let price: String
let otPrice: String
let priceDeposit: String
let attrLabel: [String]
let label: String
///
init(
id: Int,
type: Int = 0,
typeName: String = "",
status: Int = 0,
statusName: String = "",
name: String,
coverProject: String = "",
coverVideo: String = "",
price: String = "",
otPrice: String = "",
priceDeposit: String = "",
attrLabel: [String] = [],
label: String = ""
) {
self.id = id
self.type = type
self.typeName = typeName
self.status = status
self.statusName = statusName
self.name = name
self.coverProject = coverProject
self.coverVideo = coverVideo
self.price = price
self.otPrice = otPrice
self.priceDeposit = priceDeposit
self.attrLabel = attrLabel
self.label = label
}
/// 线
enum CodingKeys: String, CodingKey {
case id
case type
case typeName = "type_name"
case status
case statusName = "status_name"
case name
case coverProject = "cover_project"
case coverVideo = "cover_video"
case price
case otPrice = "ot_price"
case priceDeposit = "price_deposit"
case attrLabel = "attr_label"
case label
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeSharedLossyInt(forKey: .id) ?? 0
type = try container.decodeSharedLossyInt(forKey: .type) ?? 0
typeName = try container.decodeSharedLossyString(forKey: .typeName)
status = try container.decodeSharedLossyInt(forKey: .status) ?? 0
statusName = try container.decodeSharedLossyString(forKey: .statusName)
name = try container.decodeSharedLossyString(forKey: .name)
coverProject = try container.decodeSharedLossyString(forKey: .coverProject)
coverVideo = try container.decodeSharedLossyString(forKey: .coverVideo)
price = try container.decodeSharedLossyString(forKey: .price)
otPrice = try container.decodeSharedLossyString(forKey: .otPrice)
priceDeposit = try container.decodeSharedLossyString(forKey: .priceDeposit)
label = try container.decodeSharedLossyString(forKey: .label)
if let labels = try? container.decodeIfPresent([String].self, forKey: .attrLabel) {
attrLabel = labels
} else if let text = try? container.decodeIfPresent(String.self, forKey: .attrLabel) {
attrLabel = text
.components(separatedBy: CharacterSet(charactersIn: ","))
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty }
} else {
attrLabel = []
}
}
}
private extension KeyedDecodingContainer {
/// String Bool
func decodeSharedLossyString(forKey key: Key) throws -> String {
if let value = try? decodeIfPresent(String.self, forKey: key) {
return value
}
if let value = try? decodeIfPresent(Int.self, forKey: key) {
return String(value)
}
if let value = try? decodeIfPresent(Double.self, forKey: key) {
return String(value)
}
if let value = try? decodeIfPresent(Bool.self, forKey: key) {
return value ? "1" : "0"
}
return ""
}
/// StringDouble Int Int
func decodeSharedLossyInt(forKey key: Key) throws -> Int? {
if let value = try? decodeIfPresent(Int.self, forKey: key) {
return value
}
if let value = try? decodeIfPresent(Double.self, forKey: key) {
return Int(value)
}
if let value = try? decodeIfPresent(String.self, forKey: key) {
let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
return Int(text) ?? Double(text).map(Int.init)
}
return nil
}
}