完善实名认证、钱包与打卡点模块 UI 与业务逻辑。
对齐 Android 实名认证流程与审核页、钱包提现/积分兑换界面,优化打卡点列表与详情交互,并补充相关资源、主题 token 与单元测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -41,8 +41,17 @@ final class WalletWithdrawRecordCell: UITableViewCell {
|
||||
configureSteps(progress: progress(for: record.settlementStatus), tint: style.progress)
|
||||
progressView.isHidden = record.settlementStatus == 50
|
||||
stepsStack.isHidden = record.settlementStatus == 50
|
||||
infoLabel.text = infoText(for: record)
|
||||
infoLabel.isHidden = infoLabel.text?.isEmpty ?? true
|
||||
infoLabel.attributedText = infoText(for: record)
|
||||
infoLabel.isHidden = infoLabel.attributedText?.length == 0
|
||||
infoLabel.snp.remakeConstraints { make in
|
||||
if record.settlementStatus == 50 {
|
||||
make.top.equalTo(timeLabel.snp.bottom).offset(WalletTokens.compactGap)
|
||||
} else {
|
||||
make.top.equalTo(stepsStack.snp.bottom).offset(10)
|
||||
}
|
||||
make.leading.trailing.equalToSuperview().inset(WalletTokens.cardPadding)
|
||||
make.bottom.equalToSuperview().inset(14)
|
||||
}
|
||||
}
|
||||
|
||||
private func setupUI() {
|
||||
@ -51,23 +60,23 @@ final class WalletWithdrawRecordCell: UITableViewCell {
|
||||
contentView.backgroundColor = .white
|
||||
|
||||
cardView.backgroundColor = .white
|
||||
cardView.layer.cornerRadius = 16
|
||||
cardView.layer.cornerRadius = WalletTokens.contentRadius
|
||||
cardView.layer.borderWidth = 1
|
||||
cardView.layer.borderColor = UIColor(hex: 0xF3F4F6).cgColor
|
||||
cardView.layer.borderColor = WalletTokens.cardBorder.cgColor
|
||||
cardView.clipsToBounds = true
|
||||
|
||||
amountLabel.font = .systemFont(ofSize: 18, weight: .bold)
|
||||
amountLabel.textColor = .black
|
||||
amountLabel.font = WalletTokens.metricBoldFont
|
||||
amountLabel.textColor = WalletTokens.textPrimary
|
||||
|
||||
statusLabel.font = .systemFont(ofSize: 12, weight: .medium)
|
||||
statusLabel.font = WalletTokens.captionMediumFont
|
||||
statusLabel.textAlignment = .center
|
||||
statusLabel.layer.cornerRadius = 4
|
||||
statusLabel.layer.cornerRadius = WalletTokens.chipRadius
|
||||
statusLabel.clipsToBounds = true
|
||||
|
||||
timeLabel.font = .systemFont(ofSize: 14)
|
||||
timeLabel.textColor = UIColor(hex: 0x7B8EAA)
|
||||
timeLabel.font = WalletTokens.bodyFont
|
||||
timeLabel.textColor = WalletTokens.textMuted
|
||||
|
||||
progressView.trackTintColor = UIColor(hex: 0xF2F4F8)
|
||||
progressView.trackTintColor = WalletTokens.progressTrack
|
||||
progressView.layer.cornerRadius = 3
|
||||
progressView.clipsToBounds = true
|
||||
|
||||
@ -75,8 +84,8 @@ final class WalletWithdrawRecordCell: UITableViewCell {
|
||||
stepsStack.distribution = .equalSpacing
|
||||
stepsStack.alignment = .center
|
||||
|
||||
infoLabel.font = .systemFont(ofSize: 14)
|
||||
infoLabel.textColor = UIColor(hex: 0x4B5563)
|
||||
infoLabel.font = WalletTokens.bodyFont
|
||||
infoLabel.textColor = WalletTokens.textSecondary
|
||||
infoLabel.numberOfLines = 0
|
||||
|
||||
contentView.addSubview(cardView)
|
||||
@ -120,14 +129,14 @@ final class WalletWithdrawRecordCell: UITableViewCell {
|
||||
["提交申请", "审核中", "打款中", "已完成"].enumerated().forEach { index, title in
|
||||
let label = UILabel()
|
||||
label.text = title
|
||||
label.font = .systemFont(ofSize: 11)
|
||||
label.font = WalletTokens.stepFont
|
||||
let threshold = Float(index) / 3.0
|
||||
label.textColor = progress >= threshold ? tint : UIColor(hex: 0xB3B8C2)
|
||||
label.textColor = progress >= threshold ? tint : WalletTokens.textDisabled
|
||||
stepsStack.addArrangedSubview(label)
|
||||
}
|
||||
let percent = UILabel()
|
||||
percent.text = "\(Int(progress * 100))%"
|
||||
percent.font = .systemFont(ofSize: 12, weight: .medium)
|
||||
percent.font = WalletTokens.captionMediumFont
|
||||
percent.textColor = tint
|
||||
stepsStack.addArrangedSubview(percent)
|
||||
}
|
||||
@ -135,13 +144,13 @@ final class WalletWithdrawRecordCell: UITableViewCell {
|
||||
private func statusStyle(for status: Int) -> (background: UIColor, text: UIColor, progress: UIColor) {
|
||||
switch status {
|
||||
case 50, 20:
|
||||
(UIColor(hex: 0xEBFFF5), UIColor(hex: 0x16C26D), UIColor(hex: 0x1677FF))
|
||||
(WalletTokens.settlementSuccessBackground, WalletTokens.settlementSuccess, WalletTokens.summaryBackground)
|
||||
case 60, 30:
|
||||
(UIColor(hex: 0xFFF1F0), UIColor(hex: 0xFF4D4F), UIColor(hex: 0xFF4D4F))
|
||||
(WalletTokens.settlementDangerBackground, WalletTokens.progressDanger, WalletTokens.progressDanger)
|
||||
case 40:
|
||||
(UIColor(hex: 0xFFF3E8), UIColor(hex: 0xFF8A00), UIColor(hex: 0x1677FF))
|
||||
(WalletTokens.warningBackground, WalletTokens.warning, WalletTokens.summaryBackground)
|
||||
default:
|
||||
(UIColor(hex: 0xE6F1FF), UIColor(hex: 0x1677FF), UIColor(hex: 0x1677FF))
|
||||
(WalletTokens.infoBackground, WalletTokens.summaryBackground, WalletTokens.summaryBackground)
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,18 +165,34 @@ final class WalletWithdrawRecordCell: UITableViewCell {
|
||||
}
|
||||
}
|
||||
|
||||
private func infoText(for record: WalletWithdrawItem) -> String {
|
||||
private func infoText(for record: WalletWithdrawItem) -> NSAttributedString {
|
||||
let result = NSMutableAttributedString()
|
||||
let normal: [NSAttributedString.Key: Any] = [
|
||||
.font: WalletTokens.bodyFont,
|
||||
.foregroundColor: WalletTokens.textSecondary,
|
||||
]
|
||||
let success: [NSAttributedString.Key: Any] = [
|
||||
.font: WalletTokens.bodyFont,
|
||||
.foregroundColor: WalletTokens.settlementSuccess,
|
||||
]
|
||||
let danger: [NSAttributedString.Key: Any] = [
|
||||
.font: WalletTokens.bodyFont,
|
||||
.foregroundColor: WalletTokens.progressDanger,
|
||||
]
|
||||
if (record.settlementStatus == 10 || record.settlementStatus == 40), !record.expectedAt.isEmpty {
|
||||
return "预计到账时间:\(record.expectedAt)"
|
||||
result.append(NSAttributedString(string: "预计到账时间:\(record.expectedAt)", attributes: normal))
|
||||
}
|
||||
if (record.settlementStatus == 60 || record.settlementStatus == 30), !record.auditTime.isEmpty {
|
||||
let remark = record.auditRemark.isEmpty ? "" : "\n备注信息:\(record.auditRemark)"
|
||||
return "审核时间:\(record.auditTime)\(remark)"
|
||||
result.append(NSAttributedString(string: "审核时间:\(record.auditTime)", attributes: normal))
|
||||
}
|
||||
if (record.settlementStatus == 60 || record.settlementStatus == 30), !record.auditRemark.isEmpty {
|
||||
if result.length > 0 { result.append(NSAttributedString(string: "\n")) }
|
||||
result.append(NSAttributedString(string: "备注信息:\(record.auditRemark)", attributes: danger))
|
||||
}
|
||||
if record.settlementStatus == 50, !record.expectedAt.isEmpty {
|
||||
return "到账时间:\(record.expectedAt)"
|
||||
result.append(NSAttributedString(string: "到账时间:\(record.expectedAt)", attributes: success))
|
||||
}
|
||||
return ""
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,13 +224,13 @@ final class WalletTransactionHeaderCell: UITableViewCell {
|
||||
private func setupUI() {
|
||||
selectionStyle = .none
|
||||
backgroundColor = .white
|
||||
dateLabel.font = .systemFont(ofSize: 14)
|
||||
dateLabel.textColor = UIColor(hex: 0x9CA3AF)
|
||||
incomeLabel.font = .systemFont(ofSize: 14)
|
||||
incomeLabel.textColor = UIColor(hex: 0x4B5563)
|
||||
dateLabel.font = WalletTokens.bodyFont
|
||||
dateLabel.textColor = WalletTokens.textTertiary
|
||||
incomeLabel.font = WalletTokens.bodyFont
|
||||
incomeLabel.textColor = WalletTokens.textSecondary
|
||||
incomeLabel.textAlignment = .right
|
||||
pointsLabel.font = .systemFont(ofSize: 14)
|
||||
pointsLabel.textColor = UIColor(hex: 0xFF7B00)
|
||||
pointsLabel.font = WalletTokens.bodyFont
|
||||
pointsLabel.textColor = WalletTokens.points
|
||||
pointsLabel.textAlignment = .right
|
||||
|
||||
contentView.addSubview(dateLabel)
|
||||
@ -277,27 +302,27 @@ final class WalletTransactionRecordCell: UITableViewCell {
|
||||
selectionStyle = .none
|
||||
backgroundColor = .white
|
||||
cardView.backgroundColor = .white
|
||||
cardView.layer.cornerRadius = 12
|
||||
cardView.layer.cornerRadius = WalletTokens.cardRadius
|
||||
cardView.layer.borderWidth = 1
|
||||
cardView.layer.borderColor = UIColor(hex: 0xF3F4F6).cgColor
|
||||
cardView.layer.borderColor = WalletTokens.cardBorder.cgColor
|
||||
cardView.clipsToBounds = true
|
||||
|
||||
amountLabel.font = .systemFont(ofSize: 18, weight: .medium)
|
||||
amountLabel.textColor = .black
|
||||
pointsLabel.font = .systemFont(ofSize: 18, weight: .medium)
|
||||
pointsLabel.textColor = UIColor(hex: 0xFF7B00)
|
||||
amountLabel.font = WalletTokens.metricMediumFont
|
||||
amountLabel.textColor = WalletTokens.textPrimary
|
||||
pointsLabel.font = WalletTokens.metricMediumFont
|
||||
pointsLabel.textColor = WalletTokens.points
|
||||
pointsLabel.textAlignment = .right
|
||||
typeLabel.font = .systemFont(ofSize: 14)
|
||||
typeLabel.textColor = UIColor(hex: 0x9CA3AF)
|
||||
orderLabel.font = .systemFont(ofSize: 12)
|
||||
typeLabel.font = WalletTokens.bodyFont
|
||||
typeLabel.textColor = WalletTokens.textTertiary
|
||||
orderLabel.font = WalletTokens.captionFont
|
||||
orderLabel.textAlignment = .center
|
||||
orderLabel.layer.cornerRadius = 4
|
||||
orderLabel.layer.cornerRadius = WalletTokens.chipRadius
|
||||
orderLabel.clipsToBounds = true
|
||||
timeLabel.font = .systemFont(ofSize: 14)
|
||||
timeLabel.textColor = UIColor(hex: 0x4B5563)
|
||||
withdrawLabel.font = .systemFont(ofSize: 12)
|
||||
timeLabel.font = WalletTokens.bodyFont
|
||||
timeLabel.textColor = WalletTokens.textSecondary
|
||||
withdrawLabel.font = WalletTokens.captionFont
|
||||
withdrawLabel.textAlignment = .center
|
||||
withdrawLabel.layer.cornerRadius = 4
|
||||
withdrawLabel.layer.cornerRadius = WalletTokens.chipRadius
|
||||
withdrawLabel.clipsToBounds = true
|
||||
|
||||
contentView.addSubview(cardView)
|
||||
@ -340,9 +365,34 @@ final class WalletTransactionRecordCell: UITableViewCell {
|
||||
private func labelStyle(for label: String) -> (background: UIColor, text: UIColor, orderBackground: UIColor, orderText: UIColor) {
|
||||
switch label {
|
||||
case "可提现":
|
||||
return (UIColor(hex: 0xF0FDF4), UIColor(hex: 0x22C55E), UIColor(hex: 0xEFF6FF), UIColor(hex: 0x0073FF))
|
||||
return (WalletTokens.successBackground, WalletTokens.success, WalletTokens.orderBackground, WalletTokens.primary)
|
||||
default:
|
||||
return (UIColor(hex: 0xF4F4F4), UIColor(hex: 0x7B8EAA), UIColor(hex: 0xF4F4F4), UIColor(hex: 0x7B8EAA))
|
||||
return (WalletTokens.neutralChipBackground, WalletTokens.textMuted, WalletTokens.neutralChipBackground, WalletTokens.textMuted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 钱包列表分页加载 Cell,展示 Android 同款蓝色加载指示器。
|
||||
final class WalletLoadingCell: UITableViewCell {
|
||||
static let reuseIdentifier = "WalletLoadingCell"
|
||||
|
||||
private let indicator = UIActivityIndicatorView(style: .medium)
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
selectionStyle = .none
|
||||
backgroundColor = .white
|
||||
indicator.color = WalletTokens.summaryBackground
|
||||
indicator.startAnimating()
|
||||
contentView.addSubview(indicator)
|
||||
indicator.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
make.top.bottom.equalToSuperview().inset(WalletTokens.cardPadding)
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user