feat: 添加获客员分成记录并重构列表
This commit is contained in:
@ -445,22 +445,25 @@ final class CooperationAcquirerCell: UITableViewCell {
|
||||
|
||||
var onEditRemark: (() -> Void)?
|
||||
var onEditCommission: (() -> Void)?
|
||||
var onViewCommissionLogs: (() -> Void)?
|
||||
var onCall: (() -> Void)?
|
||||
|
||||
private let cardView = UIView()
|
||||
private let avatarContainer = UIView()
|
||||
private let avatarIconView = UIImageView(image: UIImage(systemName: "person.fill"))
|
||||
private let nameTitleLabel = UILabel()
|
||||
private let nameValueLabel = UILabel()
|
||||
private let editRemarkButton = UIButton(type: .system)
|
||||
private let phoneTitleLabel = UILabel()
|
||||
private let phoneValueLabel = UILabel()
|
||||
private let callButton = UIButton(type: .system)
|
||||
private let bindTimeTitleLabel = UILabel()
|
||||
private let bindTimeValueLabel = UILabel()
|
||||
private let commissionContainer = UIView()
|
||||
private let commissionTitleLabel = UILabel()
|
||||
private let commissionValueLabel = UILabel()
|
||||
private let bindTimeIconView = UIImageView(image: UIImage(systemName: "calendar"))
|
||||
private let bindTimeValueLabel = UILabel()
|
||||
private let dividerView = UIView()
|
||||
private let editRemarkButton = UIButton(type: .system)
|
||||
private let editCommissionButton = UIButton(type: .system)
|
||||
private let commissionLogButton = UIButton(type: .system)
|
||||
private let actionStack = UIStackView()
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
@ -469,135 +472,180 @@ final class CooperationAcquirerCell: UITableViewCell {
|
||||
contentView.backgroundColor = .clear
|
||||
|
||||
cardView.backgroundColor = .white
|
||||
cardView.layer.cornerRadius = AppRadius.md
|
||||
cardView.layer.cornerRadius = AppRadius.xl
|
||||
cardView.layer.borderWidth = 0.5
|
||||
cardView.layer.borderColor = AppColor.cardOutline.cgColor
|
||||
cardView.layer.shadowColor = UIColor.black.cgColor
|
||||
cardView.layer.shadowOpacity = 0.04
|
||||
cardView.layer.shadowOffset = CGSize(width: 0, height: 1)
|
||||
cardView.layer.shadowRadius = 2
|
||||
cardView.layer.shadowOffset = CGSize(width: 0, height: 3)
|
||||
cardView.layer.shadowRadius = 8
|
||||
cardView.accessibilityIdentifier = "cooperation_acquirer_card"
|
||||
|
||||
avatarContainer.backgroundColor = AppColor.primary.withAlphaComponent(0.08)
|
||||
avatarContainer.layer.cornerRadius = AppRadius.sm
|
||||
avatarContainer.layer.cornerRadius = 24
|
||||
avatarContainer.clipsToBounds = true
|
||||
|
||||
avatarIconView.tintColor = AppColor.primary
|
||||
avatarIconView.contentMode = .scaleAspectFit
|
||||
|
||||
configureTitleLabel(nameTitleLabel, text: "获客员名称")
|
||||
configureTitleLabel(phoneTitleLabel, text: "手机号")
|
||||
configureTitleLabel(bindTimeTitleLabel, text: "绑定时间")
|
||||
configureTitleLabel(commissionTitleLabel, text: "分成比例")
|
||||
|
||||
nameValueLabel.font = .systemFont(ofSize: 15, weight: .bold)
|
||||
nameValueLabel.font = .systemFont(ofSize: 17, weight: .semibold)
|
||||
nameValueLabel.textColor = AppColor.textPrimary
|
||||
nameValueLabel.numberOfLines = 1
|
||||
nameValueLabel.lineBreakMode = .byTruncatingTail
|
||||
nameValueLabel.accessibilityIdentifier = "cooperation_acquirer_name"
|
||||
|
||||
[phoneValueLabel, bindTimeValueLabel, commissionValueLabel].forEach { label in
|
||||
label.font = .systemFont(ofSize: 13)
|
||||
label.textColor = AppColor.textSecondary
|
||||
label.numberOfLines = 1
|
||||
label.lineBreakMode = .byTruncatingTail
|
||||
}
|
||||
commissionValueLabel.font = .systemFont(ofSize: 13, weight: .medium)
|
||||
|
||||
editRemarkButton.setTitle("修改备注", for: .normal)
|
||||
editRemarkButton.titleLabel?.font = .systemFont(ofSize: 13)
|
||||
editRemarkButton.setTitleColor(AppColor.primary, for: .normal)
|
||||
editRemarkButton.setConfigurationContentInsets(
|
||||
NSDirectionalEdgeInsets(top: 16, leading: 14, bottom: 16, trailing: 14)
|
||||
)
|
||||
editRemarkButton.addTarget(self, action: #selector(editRemarkTapped), for: .touchUpInside)
|
||||
phoneValueLabel.font = .systemFont(ofSize: 14)
|
||||
phoneValueLabel.textColor = AppColor.textTertiary
|
||||
phoneValueLabel.numberOfLines = 1
|
||||
phoneValueLabel.lineBreakMode = .byTruncatingTail
|
||||
phoneValueLabel.accessibilityIdentifier = "cooperation_acquirer_phone"
|
||||
|
||||
callButton.setImage(UIImage(systemName: "phone.fill"), for: .normal)
|
||||
callButton.tintColor = AppColor.primary
|
||||
callButton.backgroundColor = AppColor.primaryLight
|
||||
callButton.layer.cornerRadius = 15
|
||||
callButton.layer.cornerRadius = AppSpacing.minTouchTarget / 2
|
||||
callButton.layer.borderWidth = 0.5
|
||||
callButton.layer.borderColor = AppColor.primary.withAlphaComponent(0.12).cgColor
|
||||
callButton.imageView?.contentMode = .scaleAspectFit
|
||||
callButton.accessibilityLabel = "拨打获客员电话"
|
||||
callButton.accessibilityIdentifier = "cooperation_acquirer_call"
|
||||
callButton.addTarget(self, action: #selector(callTapped), for: .touchUpInside)
|
||||
|
||||
editCommissionButton.setTitle("修改比例", for: .normal)
|
||||
editCommissionButton.titleLabel?.font = .systemFont(ofSize: 13)
|
||||
editCommissionButton.setTitleColor(AppColor.primary, for: .normal)
|
||||
editCommissionButton.setConfigurationContentInsets(
|
||||
NSDirectionalEdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)
|
||||
commissionContainer.backgroundColor = AppColor.primary.withAlphaComponent(0.06)
|
||||
commissionContainer.layer.cornerRadius = AppRadius.lg
|
||||
|
||||
commissionTitleLabel.text = "分成比例"
|
||||
commissionTitleLabel.font = .systemFont(ofSize: 12)
|
||||
commissionTitleLabel.textColor = AppColor.textTertiary
|
||||
|
||||
commissionValueLabel.font = .systemFont(ofSize: 24, weight: .bold)
|
||||
commissionValueLabel.textColor = AppColor.primary
|
||||
commissionValueLabel.numberOfLines = 1
|
||||
commissionValueLabel.adjustsFontSizeToFitWidth = true
|
||||
commissionValueLabel.minimumScaleFactor = 0.75
|
||||
commissionValueLabel.accessibilityIdentifier = "cooperation_acquirer_commission_rate"
|
||||
|
||||
bindTimeIconView.tintColor = AppColor.textTertiary
|
||||
bindTimeIconView.contentMode = .scaleAspectFit
|
||||
|
||||
bindTimeValueLabel.font = .systemFont(ofSize: 13)
|
||||
bindTimeValueLabel.textColor = AppColor.textTertiary
|
||||
bindTimeValueLabel.numberOfLines = 2
|
||||
bindTimeValueLabel.lineBreakMode = .byTruncatingTail
|
||||
bindTimeValueLabel.accessibilityIdentifier = "cooperation_acquirer_bind_time"
|
||||
|
||||
dividerView.backgroundColor = AppColor.cardOutline
|
||||
|
||||
configureActionButton(
|
||||
editRemarkButton,
|
||||
title: "修改备注",
|
||||
isPrimary: false,
|
||||
accessibilityIdentifier: "cooperation_acquirer_edit_remark"
|
||||
)
|
||||
editRemarkButton.addTarget(self, action: #selector(editRemarkTapped), for: .touchUpInside)
|
||||
|
||||
configureActionButton(
|
||||
commissionLogButton,
|
||||
title: "修改记录",
|
||||
isPrimary: false,
|
||||
accessibilityIdentifier: "cooperation_acquirer_commission_logs"
|
||||
)
|
||||
commissionLogButton.accessibilityLabel = "查看分成比例修改记录"
|
||||
commissionLogButton.addTarget(self, action: #selector(commissionLogTapped), for: .touchUpInside)
|
||||
|
||||
configureActionButton(
|
||||
editCommissionButton,
|
||||
title: "修改比例",
|
||||
isPrimary: true,
|
||||
accessibilityIdentifier: "cooperation_acquirer_edit_commission"
|
||||
)
|
||||
editCommissionButton.addTarget(self, action: #selector(editCommissionTapped), for: .touchUpInside)
|
||||
|
||||
actionStack.axis = .horizontal
|
||||
actionStack.alignment = .fill
|
||||
actionStack.distribution = .fillEqually
|
||||
actionStack.spacing = AppSpacing.xs
|
||||
actionStack.addArrangedSubview(editRemarkButton)
|
||||
actionStack.addArrangedSubview(commissionLogButton)
|
||||
actionStack.addArrangedSubview(editCommissionButton)
|
||||
|
||||
contentView.addSubview(cardView)
|
||||
cardView.addSubview(avatarContainer)
|
||||
avatarContainer.addSubview(avatarIconView)
|
||||
cardView.addSubview(nameTitleLabel)
|
||||
cardView.addSubview(nameValueLabel)
|
||||
cardView.addSubview(editRemarkButton)
|
||||
cardView.addSubview(phoneTitleLabel)
|
||||
cardView.addSubview(phoneValueLabel)
|
||||
cardView.addSubview(callButton)
|
||||
cardView.addSubview(bindTimeTitleLabel)
|
||||
cardView.addSubview(commissionContainer)
|
||||
commissionContainer.addSubview(commissionTitleLabel)
|
||||
commissionContainer.addSubview(commissionValueLabel)
|
||||
cardView.addSubview(bindTimeIconView)
|
||||
cardView.addSubview(bindTimeValueLabel)
|
||||
cardView.addSubview(commissionTitleLabel)
|
||||
cardView.addSubview(commissionValueLabel)
|
||||
cardView.addSubview(editCommissionButton)
|
||||
cardView.addSubview(dividerView)
|
||||
cardView.addSubview(actionStack)
|
||||
|
||||
cardView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 14, bottom: AppSpacing.sm, right: 14))
|
||||
make.edges.equalToSuperview().inset(
|
||||
UIEdgeInsets(top: 0, left: AppSpacing.md, bottom: AppSpacing.sm, right: AppSpacing.md)
|
||||
)
|
||||
}
|
||||
avatarContainer.snp.makeConstraints { make in
|
||||
make.leading.equalToSuperview().offset(14)
|
||||
make.centerY.equalToSuperview()
|
||||
make.size.equalTo(44)
|
||||
make.top.leading.equalToSuperview().inset(AppSpacing.md)
|
||||
make.size.equalTo(48)
|
||||
}
|
||||
avatarIconView.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
make.size.equalTo(22)
|
||||
}
|
||||
nameTitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview().offset(AppSpacing.md)
|
||||
make.leading.equalTo(avatarContainer.snp.trailing).offset(AppSpacing.sm)
|
||||
make.size.equalTo(24)
|
||||
}
|
||||
nameValueLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(nameTitleLabel)
|
||||
make.leading.equalTo(nameTitleLabel.snp.trailing).offset(AppSpacing.sm)
|
||||
make.trailing.lessThanOrEqualTo(editRemarkButton.snp.leading).offset(-AppSpacing.xs)
|
||||
}
|
||||
editRemarkButton.snp.makeConstraints { make in
|
||||
make.top.trailing.equalToSuperview()
|
||||
}
|
||||
phoneTitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(nameTitleLabel.snp.bottom).offset(AppSpacing.xs)
|
||||
make.leading.equalTo(nameTitleLabel)
|
||||
make.top.equalTo(avatarContainer).offset(2)
|
||||
make.leading.equalTo(avatarContainer.snp.trailing).offset(AppSpacing.sm)
|
||||
make.trailing.lessThanOrEqualTo(callButton.snp.leading).offset(-AppSpacing.sm)
|
||||
}
|
||||
phoneValueLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(phoneTitleLabel)
|
||||
make.leading.equalTo(phoneTitleLabel.snp.trailing).offset(AppSpacing.sm)
|
||||
make.trailing.lessThanOrEqualTo(callButton.snp.leading).offset(-AppSpacing.xs)
|
||||
make.top.equalTo(nameValueLabel.snp.bottom).offset(AppSpacing.xxs)
|
||||
make.leading.equalTo(nameValueLabel)
|
||||
make.trailing.lessThanOrEqualTo(callButton.snp.leading).offset(-AppSpacing.sm)
|
||||
}
|
||||
callButton.snp.makeConstraints { make in
|
||||
make.trailing.equalToSuperview().inset(14)
|
||||
make.centerY.equalTo(phoneTitleLabel)
|
||||
make.size.equalTo(30)
|
||||
make.top.trailing.equalToSuperview().inset(AppSpacing.md)
|
||||
make.size.equalTo(AppSpacing.minTouchTarget)
|
||||
}
|
||||
bindTimeTitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(phoneTitleLabel.snp.bottom).offset(AppSpacing.xs)
|
||||
make.leading.equalTo(nameTitleLabel)
|
||||
}
|
||||
bindTimeValueLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(bindTimeTitleLabel)
|
||||
make.leading.equalTo(bindTimeTitleLabel.snp.trailing).offset(AppSpacing.sm)
|
||||
make.trailing.lessThanOrEqualToSuperview().inset(14)
|
||||
commissionContainer.snp.makeConstraints { make in
|
||||
make.top.equalTo(avatarContainer.snp.bottom).offset(14)
|
||||
make.leading.equalToSuperview().inset(AppSpacing.md)
|
||||
make.width.equalTo(120)
|
||||
make.height.equalTo(64)
|
||||
}
|
||||
commissionTitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(bindTimeTitleLabel.snp.bottom).offset(AppSpacing.xs)
|
||||
make.leading.equalTo(nameTitleLabel)
|
||||
make.bottom.equalToSuperview().inset(AppSpacing.md)
|
||||
make.top.equalToSuperview().offset(AppSpacing.xs)
|
||||
make.centerX.equalToSuperview()
|
||||
}
|
||||
commissionValueLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(commissionTitleLabel)
|
||||
make.leading.equalTo(commissionTitleLabel.snp.trailing).offset(AppSpacing.sm)
|
||||
make.trailing.lessThanOrEqualTo(editCommissionButton.snp.leading).offset(-AppSpacing.xs)
|
||||
make.top.equalTo(commissionTitleLabel.snp.bottom).offset(2)
|
||||
make.centerX.equalToSuperview()
|
||||
make.leading.greaterThanOrEqualToSuperview().offset(AppSpacing.xs)
|
||||
make.trailing.lessThanOrEqualToSuperview().inset(AppSpacing.xs)
|
||||
}
|
||||
editCommissionButton.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(commissionTitleLabel)
|
||||
make.trailing.equalToSuperview().inset(AppSpacing.xs)
|
||||
bindTimeIconView.snp.makeConstraints { make in
|
||||
make.leading.equalTo(commissionContainer.snp.trailing).offset(AppSpacing.md)
|
||||
make.centerY.equalTo(commissionContainer)
|
||||
make.size.equalTo(18)
|
||||
}
|
||||
bindTimeValueLabel.snp.makeConstraints { make in
|
||||
make.leading.equalTo(bindTimeIconView.snp.trailing).offset(AppSpacing.xs)
|
||||
make.trailing.equalToSuperview().inset(AppSpacing.md)
|
||||
make.centerY.equalTo(bindTimeIconView)
|
||||
}
|
||||
dividerView.snp.makeConstraints { make in
|
||||
make.top.equalTo(commissionContainer.snp.bottom).offset(14)
|
||||
make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
|
||||
make.height.equalTo(0.5)
|
||||
}
|
||||
actionStack.snp.makeConstraints { make in
|
||||
make.top.equalTo(dividerView.snp.bottom).offset(AppSpacing.sm)
|
||||
make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
|
||||
make.height.equalTo(AppSpacing.minTouchTarget)
|
||||
make.bottom.equalToSuperview().inset(14)
|
||||
}
|
||||
}
|
||||
|
||||
@ -610,26 +658,52 @@ final class CooperationAcquirerCell: UITableViewCell {
|
||||
super.prepareForReuse()
|
||||
onEditRemark = nil
|
||||
onEditCommission = nil
|
||||
onViewCommissionLogs = nil
|
||||
onCall = nil
|
||||
}
|
||||
|
||||
func configure(with acquirer: CooperativeSalerEntity) {
|
||||
nameValueLabel.text = acquirer.displayName.isEmpty ? "—" : acquirer.displayName
|
||||
phoneValueLabel.text = acquirer.displayPhone.isEmpty ? "—" : CooperationOrderPhoneMask.mask(acquirer.displayPhone)
|
||||
bindTimeValueLabel.text = acquirer.displayBindTime.isEmpty ? "—" : acquirer.displayBindTime
|
||||
let bindTime = acquirer.displayBindTime.isEmpty ? "—" : Self.minutePrecisionTime(acquirer.displayBindTime)
|
||||
bindTimeValueLabel.text = "绑定于 \(bindTime)"
|
||||
commissionValueLabel.text = acquirer.displayCommissionRate.isEmpty ? "—" : acquirer.displayCommissionRate
|
||||
}
|
||||
|
||||
private func configureTitleLabel(_ label: UILabel, text: String) {
|
||||
label.text = text
|
||||
label.font = .systemFont(ofSize: 13)
|
||||
label.textColor = AppColor.textTertiary
|
||||
label.setContentHuggingPriority(.required, for: .horizontal)
|
||||
label.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
private func configureActionButton(
|
||||
_ button: UIButton,
|
||||
title: String,
|
||||
isPrimary: Bool,
|
||||
accessibilityIdentifier: String
|
||||
) {
|
||||
var configuration = UIButton.Configuration.plain()
|
||||
configuration.title = title
|
||||
configuration.baseForegroundColor = isPrimary ? AppColor.primary : UIColor(hex: 0x5F6673)
|
||||
configuration.background.backgroundColor = isPrimary ? AppColor.primaryLight : .white
|
||||
configuration.background.strokeColor = isPrimary
|
||||
? AppColor.primary.withAlphaComponent(0.35)
|
||||
: UIColor(hex: 0xD9DEE7)
|
||||
configuration.background.strokeWidth = 1
|
||||
configuration.background.cornerRadius = AppRadius.md
|
||||
configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 6, bottom: 0, trailing: 6)
|
||||
configuration.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attributes in
|
||||
var updated = attributes
|
||||
updated.font = .systemFont(ofSize: 12, weight: .medium)
|
||||
return updated
|
||||
}
|
||||
button.configuration = configuration
|
||||
button.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
|
||||
private static func minutePrecisionTime(_ value: String) -> String {
|
||||
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard trimmed.count == 19, trimmed.dropFirst(16).first == ":" else { return trimmed }
|
||||
return String(trimmed.prefix(16))
|
||||
}
|
||||
|
||||
@objc private func editRemarkTapped() { onEditRemark?() }
|
||||
@objc private func editCommissionTapped() { onEditCommission?() }
|
||||
@objc private func commissionLogTapped() { onViewCommissionLogs?() }
|
||||
@objc private func callTapped() { onCall?() }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user