Sync app branding and fix order list decode for referral_order payloads.

Align display name, icon, and launch screen with suixinkan_ios_new, and tolerate nested sale_user and empty travel objects in listv2 responses.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 17:07:50 +08:00
parent 31d2b6094b
commit 75d0cb1f9a
8 changed files with 247 additions and 7 deletions

View File

@ -116,9 +116,9 @@ struct OrderEntity: Decodable, Equatable {
orderTypeLabel = try container.decodeIfPresent(String.self, forKey: .orderTypeLabel) ?? ""
depositPayTime = try container.decodeIfPresent(String.self, forKey: .depositPayTime) ?? ""
createdAt = try container.decodeIfPresent(String.self, forKey: .createdAt) ?? ""
photoTravel = try container.decodeIfPresent(PhotoTravelEntity.self, forKey: .photoTravel)
photoTravel = try Self.decodePhotoTravel(from: container)
refundAmount = try Self.decodeFlexibleString(container: container, key: .refundAmount, defaultValue: "0")
multiTravel = try container.decodeIfPresent(MultiTravelEntity.self, forKey: .multiTravel)
multiTravel = try Self.decodeMultiTravel(from: container)
isNeedEdit = try container.decodeIfPresent(Bool.self, forKey: .isNeedEdit) ?? true
isRefined = try container.decodeIfPresent(Int.self, forKey: .isRefined) ?? 0
canBindReferral = try container.decodeIfPresent(Int.self, forKey: .canBindReferral) ?? 0
@ -145,6 +145,26 @@ struct OrderEntity: Decodable, Equatable {
}
return defaultValue
}
private static func decodePhotoTravel(
from container: KeyedDecodingContainer<CodingKeys>
) throws -> PhotoTravelEntity? {
guard container.contains(.photoTravel), try !container.decodeNil(forKey: .photoTravel) else {
return nil
}
let travel = try container.decode(PhotoTravelEntity.self, forKey: .photoTravel)
return travel.isEmpty ? nil : travel
}
private static func decodeMultiTravel(
from container: KeyedDecodingContainer<CodingKeys>
) throws -> MultiTravelEntity? {
guard container.contains(.multiTravel), try !container.decodeNil(forKey: .multiTravel) else {
return nil
}
let travel = try container.decode(MultiTravelEntity.self, forKey: .multiTravel)
return travel.isEmpty ? nil : travel
}
}
struct BoundReferralOrderEntity: Decodable, Equatable {
@ -184,6 +204,53 @@ struct BoundReferralOrderEntity: Decodable, Equatable {
case status
case statusLabel = "status_label"
case createdAt = "created_at"
case saleUser = "sale_user"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(Int.self, forKey: .id) ?? 0
orderNo = try container.decodeIfPresent(String.self, forKey: .orderNo) ?? ""
saleUserId = try container.decodeIfPresent(Int.self, forKey: .saleUserId) ?? 0
salerName = try container.decodeIfPresent(String.self, forKey: .salerName) ?? ""
salerPhone = try container.decodeIfPresent(String.self, forKey: .salerPhone) ?? ""
displayText = try container.decodeIfPresent(String.self, forKey: .displayText) ?? ""
userMobile = try container.decodeIfPresent(String.self, forKey: .userMobile) ?? ""
remark = try container.decodeIfPresent(String.self, forKey: .remark) ?? ""
bindOrderNumber = try container.decodeIfPresent(String.self, forKey: .bindOrderNumber) ?? ""
sourceType = try container.decodeIfPresent(Int.self, forKey: .sourceType) ?? 0
sourceTypeLabel = try container.decodeIfPresent(String.self, forKey: .sourceTypeLabel) ?? ""
status = try container.decodeIfPresent(Int.self, forKey: .status) ?? 0
statusLabel = try container.decodeIfPresent(String.self, forKey: .statusLabel) ?? ""
createdAt = try container.decodeIfPresent(String.self, forKey: .createdAt) ?? ""
let saleUser = try container.decodeIfPresent(ReferralSaleUserEntity.self, forKey: .saleUser)
photogRemarkName = try container.decodeIfPresent(String.self, forKey: .photogRemarkName)
?? saleUser?.photogRemarkName
?? saleUser?.displayName
?? ""
}
}
/// `referral_order.sale_user`
struct ReferralSaleUserEntity: Decodable, Equatable {
let photogRemarkName: String
let displayName: String
let salerName: String
enum CodingKeys: String, CodingKey {
case photogRemarkName = "photog_remark_name"
case displayName = "display_name"
case salerName = "saler_name"
case name
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
photogRemarkName = try container.decodeIfPresent(String.self, forKey: .photogRemarkName) ?? ""
let name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
salerName = try container.decodeIfPresent(String.self, forKey: .salerName) ?? name
displayName = try container.decodeIfPresent(String.self, forKey: .displayName) ?? salerName
}
}
@ -222,6 +289,18 @@ struct PhotoTravelEntity: Decodable, Equatable {
retouchGiftPhotoNum = try container.decodeIfPresent(Int.self, forKey: .retouchGiftPhotoNum) ?? 0
retouchGiftVideoNum = try container.decodeIfPresent(Int.self, forKey: .retouchGiftVideoNum) ?? 0
}
var isEmpty: Bool {
orderPhotoNum == 0
&& orderVideoNum == 0
&& !canCancelOrder
&& !needCheckIn
&& checkInTime.isEmpty
&& !canGiftRetouch
&& retouchGiftTime.isEmpty
&& retouchGiftPhotoNum == 0
&& retouchGiftVideoNum == 0
}
}
struct MultiTravelEntity: Decodable, Equatable {
@ -235,6 +314,10 @@ struct MultiTravelEntity: Decodable, Equatable {
self.materialList = materialList
}
var isEmpty: Bool {
materialList.isEmpty
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
materialList = try container.decodeIfPresent([MultiTravelMaterialEntity].self, forKey: .materialList) ?? []