Add scenic selection and cooperation order flows aligned with Android.

Upgrade scenic picker with search, location sorting, permission apply/status, and blocking home dialog; add cooperation order module and order source picker improvements with unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-07 10:48:43 +08:00
parent 3c4ca7eefb
commit 2bea05b1d9
50 changed files with 5603 additions and 191 deletions

View File

@ -789,10 +789,19 @@ struct CooperativeSalerEntity: Decodable, Equatable {
let photogRemarkName: String
let phone: String
let salerPhone: String
let commissionRate: Int
let commissionRateLabel: String
let bindTime: String
let boundAt: String
var displayId: Int { saleUserId }
var displayName: String { OrderDisplayName.saleUser(remark: photogRemarkName, primary: name, fallback: salerName) }
var displayPhone: String { salerPhone.isEmpty ? phone : salerPhone }
var displayBindTime: String { bindTime.isEmpty ? boundAt : bindTime }
var displayCommissionRate: String {
if !commissionRateLabel.isEmpty { return commissionRateLabel }
return "\(commissionRate)%"
}
enum CodingKeys: String, CodingKey {
case saleUserId = "sale_user_id"
@ -802,6 +811,67 @@ struct CooperativeSalerEntity: Decodable, Equatable {
case photogRemarkName = "photog_remark_name"
case phone
case salerPhone = "saler_phone"
case commissionRate = "commission_rate"
case commissionRateLabel = "commission_rate_label"
case bindTime = "bind_time"
case boundAt = "bound_at"
}
init(
saleUserId: Int = 0,
bindingId: Int = 0,
name: String = "",
salerName: String = "",
photogRemarkName: String = "",
phone: String = "",
salerPhone: String = "",
commissionRate: Int = 0,
commissionRateLabel: String = "",
bindTime: String = "",
boundAt: String = ""
) {
self.saleUserId = saleUserId
self.bindingId = bindingId
self.name = name
self.salerName = salerName
self.photogRemarkName = photogRemarkName
self.phone = phone
self.salerPhone = salerPhone
self.commissionRate = commissionRate
self.commissionRateLabel = commissionRateLabel
self.bindTime = bindTime
self.boundAt = boundAt
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
saleUserId = try container.decodeIfPresent(Int.self, forKey: .saleUserId) ?? 0
bindingId = try container.decodeIfPresent(Int.self, forKey: .bindingId) ?? 0
name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
salerName = try container.decodeIfPresent(String.self, forKey: .salerName) ?? ""
photogRemarkName = try container.decodeIfPresent(String.self, forKey: .photogRemarkName) ?? ""
phone = try container.decodeIfPresent(String.self, forKey: .phone) ?? ""
salerPhone = try container.decodeIfPresent(String.self, forKey: .salerPhone) ?? ""
commissionRate = try container.decodeIfPresent(Int.self, forKey: .commissionRate) ?? 0
commissionRateLabel = try container.decodeIfPresent(String.self, forKey: .commissionRateLabel) ?? ""
bindTime = try container.decodeIfPresent(String.self, forKey: .bindTime) ?? ""
boundAt = try container.decodeIfPresent(String.self, forKey: .boundAt) ?? ""
}
func withRemarkName(_ remark: String) -> CooperativeSalerEntity {
CooperativeSalerEntity(
saleUserId: saleUserId,
bindingId: bindingId,
name: name,
salerName: salerName,
photogRemarkName: remark,
phone: phone,
salerPhone: salerPhone,
commissionRate: commissionRate,
commissionRateLabel: commissionRateLabel,
bindTime: bindTime,
boundAt: boundAt
)
}
}
@ -819,6 +889,7 @@ struct ReferralOrderEntity: Decodable, Equatable {
let createdAt: String
let status: Int
let statusLabel: String
let images: [String]
var displayReferralOrderNo: String { referralOrderNo.isEmpty ? orderNo : referralOrderNo }
@ -831,6 +902,20 @@ struct ReferralOrderEntity: Decodable, Equatable {
case createdAt = "created_at"
case status
case statusLabel = "status_label"
case images
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(Int.self, forKey: .id) ?? 0
referralOrderNo = try container.decodeIfPresent(String.self, forKey: .referralOrderNo) ?? ""
orderNo = try container.decodeIfPresent(String.self, forKey: .orderNo) ?? ""
userMobile = try container.decodeIfPresent(String.self, forKey: .userMobile) ?? ""
remark = try container.decodeIfPresent(String.self, forKey: .remark) ?? ""
createdAt = try container.decodeIfPresent(String.self, forKey: .createdAt) ?? ""
status = try container.decodeIfPresent(Int.self, forKey: .status) ?? 0
statusLabel = try container.decodeIfPresent(String.self, forKey: .statusLabel) ?? ""
images = (try? container.decode([String].self, forKey: .images)) ?? []
}
}