修复合作获客扫码绑定崩溃与 Toast 层级,并接入分成比例修改。
将扫码页提升到列表层弹出并补齐 AppDelegate.window,避免扫码时 UIKit 取主窗口崩溃;Toast 改用独立 UIWindow 显示在 sheet 之上;合作获客员支持短信验证修改分成比例,同时优化冷启动根视图创建时机并补充相关测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -36,6 +36,24 @@ struct SaleUserUpdateRemarkRequest: Encodable {
|
||||
}
|
||||
}
|
||||
|
||||
/// 合作获客员分成比例验证码请求体。
|
||||
struct SaleUserCommissionRateSmsRequest: Encodable {
|
||||
let phone: String
|
||||
}
|
||||
|
||||
/// 合作获客员分成比例更新请求体。
|
||||
struct SaleUserCommissionRateUpdateRequest: Encodable {
|
||||
let saleUserId: Int
|
||||
let commissionRate: Int
|
||||
let smsCode: String
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case saleUserId = "sale_user_id"
|
||||
case commissionRate = "commission_rate"
|
||||
case smsCode = "sms_code"
|
||||
}
|
||||
}
|
||||
|
||||
/// 合作获客员列表响应。
|
||||
struct CooperativeSalerListPayload: Decodable {
|
||||
let total: Int
|
||||
@ -73,6 +91,9 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
let salerPhone: String
|
||||
let shareCode: String
|
||||
let storeId: Int
|
||||
let photogCommissionRate: Int
|
||||
let commissionRate: Int
|
||||
let commissionRateLabel: String
|
||||
let bindTime: String
|
||||
let boundAt: String
|
||||
|
||||
@ -88,10 +109,18 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
salerPhone.cooperationNonEmptyOrDefault(phone)
|
||||
}
|
||||
|
||||
var displayMaskedPhone: String {
|
||||
phoneMasked.cooperationNonEmptyOrDefault(displayPhone)
|
||||
}
|
||||
|
||||
var displayBindTime: String {
|
||||
bindTime.cooperationNonEmptyOrDefault(boundAt)
|
||||
}
|
||||
|
||||
var displayCommissionRate: String {
|
||||
commissionRateLabel.cooperationNonEmptyOrDefault("\(commissionRate)%")
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case saleUserId = "sale_user_id"
|
||||
case bindingId = "binding_id"
|
||||
@ -105,6 +134,9 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
case salerPhone = "saler_phone"
|
||||
case shareCode = "share_code"
|
||||
case storeId = "store_id"
|
||||
case photogCommissionRate = "photog_commission_rate"
|
||||
case commissionRate = "commission_rate"
|
||||
case commissionRateLabel = "commission_rate_label"
|
||||
case bindTime = "bind_time"
|
||||
case boundAt = "bound_at"
|
||||
}
|
||||
@ -123,6 +155,9 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
salerPhone = try container.decodeLossyString(forKey: .salerPhone)
|
||||
shareCode = try container.decodeLossyString(forKey: .shareCode)
|
||||
storeId = try container.decodeLossyInt(forKey: .storeId) ?? 0
|
||||
photogCommissionRate = try container.decodeLossyInt(forKey: .photogCommissionRate) ?? 0
|
||||
commissionRate = try container.decodeLossyInt(forKey: .commissionRate) ?? 0
|
||||
commissionRateLabel = try container.decodeLossyString(forKey: .commissionRateLabel)
|
||||
bindTime = try container.decodeLossyString(forKey: .bindTime)
|
||||
boundAt = try container.decodeLossyString(forKey: .boundAt)
|
||||
}
|
||||
@ -142,6 +177,9 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
salerPhone: salerPhone,
|
||||
shareCode: shareCode,
|
||||
storeId: storeId,
|
||||
photogCommissionRate: photogCommissionRate,
|
||||
commissionRate: commissionRate,
|
||||
commissionRateLabel: commissionRateLabel,
|
||||
bindTime: bindTime,
|
||||
boundAt: boundAt
|
||||
)
|
||||
@ -160,6 +198,9 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
salerPhone: String,
|
||||
shareCode: String,
|
||||
storeId: Int,
|
||||
photogCommissionRate: Int = 0,
|
||||
commissionRate: Int = 0,
|
||||
commissionRateLabel: String = "",
|
||||
bindTime: String,
|
||||
boundAt: String
|
||||
) {
|
||||
@ -175,6 +216,9 @@ struct CooperativeSaler: Decodable, Identifiable {
|
||||
self.salerPhone = salerPhone
|
||||
self.shareCode = shareCode
|
||||
self.storeId = storeId
|
||||
self.photogCommissionRate = photogCommissionRate
|
||||
self.commissionRate = commissionRate
|
||||
self.commissionRateLabel = commissionRateLabel
|
||||
self.bindTime = bindTime
|
||||
self.boundAt = boundAt
|
||||
}
|
||||
@ -244,6 +288,10 @@ struct SaleUserInviteInfo: Decodable {
|
||||
struct ReferralLead: Decodable, Identifiable {
|
||||
let id: Int
|
||||
let leadId: Int
|
||||
let displayName: String
|
||||
let photogRemarkName: String
|
||||
let name: String
|
||||
let salerName: String
|
||||
let userPhone: String
|
||||
let userMobileMasked: String
|
||||
let phone: String
|
||||
@ -261,6 +309,10 @@ struct ReferralLead: Decodable, Identifiable {
|
||||
userMobileMasked.cooperationNonEmptyOrDefault(userPhone.cooperationNonEmptyOrDefault(phone))
|
||||
}
|
||||
|
||||
var displaySalerName: String {
|
||||
displayName.cooperationNonEmptyOrDefault(photogRemarkName.saleUserDisplayName(primaryName: name, fallbackName: salerName))
|
||||
}
|
||||
|
||||
var displayImages: [String] {
|
||||
imageUrls.isEmpty ? images : imageUrls
|
||||
}
|
||||
@ -268,6 +320,10 @@ struct ReferralLead: Decodable, Identifiable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case leadId = "lead_id"
|
||||
case displayName = "display_name"
|
||||
case photogRemarkName = "photog_remark_name"
|
||||
case name
|
||||
case salerName = "saler_name"
|
||||
case userPhone = "user_phone"
|
||||
case userMobileMasked = "user_mobile_masked"
|
||||
case phone
|
||||
@ -281,6 +337,10 @@ struct ReferralLead: Decodable, Identifiable {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try container.decodeLossyInt(forKey: .id) ?? 0
|
||||
leadId = try container.decodeLossyInt(forKey: .leadId) ?? 0
|
||||
displayName = try container.decodeLossyString(forKey: .displayName)
|
||||
photogRemarkName = try container.decodeLossyString(forKey: .photogRemarkName)
|
||||
name = try container.decodeLossyString(forKey: .name)
|
||||
salerName = try container.decodeLossyString(forKey: .salerName)
|
||||
userPhone = try container.decodeLossyString(forKey: .userPhone)
|
||||
userMobileMasked = try container.decodeLossyString(forKey: .userMobileMasked)
|
||||
phone = try container.decodeLossyString(forKey: .phone)
|
||||
|
||||
Reference in New Issue
Block a user