// // WalletCells.swift // suixinkan // import SnapKit import UIKit /// 钱包提现记录 Cell。 final class WalletWithdrawRecordCell: UITableViewCell { static let reuseIdentifier = "WalletWithdrawRecordCell" private let cardView = UIView() private let amountLabel = UILabel() private let statusLabel = UILabel() private let timeLabel = UILabel() private let progressView = UIProgressView(progressViewStyle: .bar) private let stepsStack = UIStackView() private let infoLabel = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupUI() } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// 配置提现记录。 func apply(_ record: WalletWithdrawItem) { amountLabel.text = WalletViewModel.formatAmount(record.amount) statusLabel.text = record.statusLabel.isEmpty ? "--" : record.statusLabel timeLabel.text = record.createdAt.isEmpty ? "--" : record.createdAt let style = statusStyle(for: record.settlementStatus) statusLabel.textColor = style.text statusLabel.backgroundColor = style.background progressView.progressTintColor = style.progress progressView.progress = progress(for: record.settlementStatus) 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 } private func setupUI() { selectionStyle = .none backgroundColor = .white contentView.backgroundColor = .white cardView.backgroundColor = .white cardView.layer.cornerRadius = 16 cardView.layer.borderWidth = 1 cardView.layer.borderColor = UIColor(hex: 0xF3F4F6).cgColor cardView.clipsToBounds = true amountLabel.font = .systemFont(ofSize: 18, weight: .bold) amountLabel.textColor = .black statusLabel.font = .systemFont(ofSize: 12, weight: .medium) statusLabel.textAlignment = .center statusLabel.layer.cornerRadius = 4 statusLabel.clipsToBounds = true timeLabel.font = .systemFont(ofSize: 14) timeLabel.textColor = UIColor(hex: 0x7B8EAA) progressView.trackTintColor = UIColor(hex: 0xF2F4F8) progressView.layer.cornerRadius = 3 progressView.clipsToBounds = true stepsStack.axis = .horizontal stepsStack.distribution = .equalSpacing stepsStack.alignment = .center infoLabel.font = .systemFont(ofSize: 14) infoLabel.textColor = UIColor(hex: 0x4B5563) infoLabel.numberOfLines = 0 contentView.addSubview(cardView) [amountLabel, statusLabel, timeLabel, progressView, stepsStack, infoLabel].forEach(cardView.addSubview) cardView.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 6, left: 16, bottom: 6, right: 16)) } amountLabel.snp.makeConstraints { make in make.top.leading.equalToSuperview().offset(16) make.trailing.lessThanOrEqualTo(statusLabel.snp.leading).offset(-12) } statusLabel.snp.makeConstraints { make in make.centerY.equalTo(amountLabel) make.trailing.equalToSuperview().inset(16) make.height.equalTo(24) make.width.greaterThanOrEqualTo(62) } timeLabel.snp.makeConstraints { make in make.top.equalTo(amountLabel.snp.bottom).offset(6) make.leading.trailing.equalToSuperview().inset(16) } progressView.snp.makeConstraints { make in make.top.equalTo(timeLabel.snp.bottom).offset(16) make.leading.trailing.equalToSuperview().inset(16) make.height.equalTo(6) } stepsStack.snp.makeConstraints { make in make.top.equalTo(progressView.snp.bottom).offset(10) make.leading.trailing.equalToSuperview().inset(16) } infoLabel.snp.makeConstraints { make in make.top.equalTo(stepsStack.snp.bottom).offset(10) make.leading.trailing.equalToSuperview().inset(16) make.bottom.equalToSuperview().inset(14) } } private func configureSteps(progress: Float, tint: UIColor) { stepsStack.arrangedSubviews.forEach { $0.removeFromSuperview() } ["提交申请", "审核中", "打款中", "已完成"].enumerated().forEach { index, title in let label = UILabel() label.text = title label.font = .systemFont(ofSize: 11) let threshold = Float(index) / 3.0 label.textColor = progress >= threshold ? tint : UIColor(hex: 0xB3B8C2) stepsStack.addArrangedSubview(label) } let percent = UILabel() percent.text = "\(Int(progress * 100))%" percent.font = .systemFont(ofSize: 12, weight: .medium) percent.textColor = tint stepsStack.addArrangedSubview(percent) } 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)) case 60, 30: (UIColor(hex: 0xFFF1F0), UIColor(hex: 0xFF4D4F), UIColor(hex: 0xFF4D4F)) case 40: (UIColor(hex: 0xFFF3E8), UIColor(hex: 0xFF8A00), UIColor(hex: 0x1677FF)) default: (UIColor(hex: 0xE6F1FF), UIColor(hex: 0x1677FF), UIColor(hex: 0x1677FF)) } } private func progress(for status: Int) -> Float { switch status { case 10: 0.1 case 40: 0.4 case 20: 0.8 case 30: 1.0 case 60: 0.0 default: 1.0 } } private func infoText(for record: WalletWithdrawItem) -> String { if (record.settlementStatus == 10 || record.settlementStatus == 40), !record.expectedAt.isEmpty { return "预计到账时间:\(record.expectedAt)" } if (record.settlementStatus == 60 || record.settlementStatus == 30), !record.auditTime.isEmpty { let remark = record.auditRemark.isEmpty ? "" : "\n备注信息:\(record.auditRemark)" return "审核时间:\(record.auditTime)\(remark)" } if record.settlementStatus == 50, !record.expectedAt.isEmpty { return "到账时间:\(record.expectedAt)" } return "" } } /// 钱包收益明细日期分组头 Cell。 final class WalletTransactionHeaderCell: UITableViewCell { static let reuseIdentifier = "WalletTransactionHeaderCell" private let dateLabel = UILabel() private let incomeLabel = UILabel() private let pointsLabel = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupUI() } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// 配置收益明细分组。 func apply(_ group: EarningDetailGroup) { dateLabel.text = group.date incomeLabel.text = "当日收益:\(WalletViewModel.formatAmount(group.dayAmount))" pointsLabel.text = group.dayPoints > 0 ? "积分+\(group.dayPoints)" : "" } 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) incomeLabel.textAlignment = .right pointsLabel.font = .systemFont(ofSize: 14) pointsLabel.textColor = UIColor(hex: 0xFF7B00) pointsLabel.textAlignment = .right contentView.addSubview(dateLabel) contentView.addSubview(incomeLabel) contentView.addSubview(pointsLabel) dateLabel.snp.makeConstraints { make in make.top.bottom.equalToSuperview().inset(8) make.leading.equalToSuperview().offset(16) } pointsLabel.snp.makeConstraints { make in make.centerY.equalTo(dateLabel) make.trailing.equalToSuperview().inset(16) } incomeLabel.snp.makeConstraints { make in make.centerY.equalTo(dateLabel) make.leading.greaterThanOrEqualTo(dateLabel.snp.trailing).offset(8) make.trailing.equalTo(pointsLabel.snp.leading).offset(-12) } } } /// 钱包收益明细记录 Cell。 final class WalletTransactionRecordCell: UITableViewCell { static let reuseIdentifier = "WalletTransactionRecordCell" private let cardView = UIView() private let amountLabel = UILabel() private let pointsLabel = UILabel() private let typeLabel = UILabel() private let orderLabel = UILabel() private let timeLabel = UILabel() private let withdrawLabel = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupUI() } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// 配置收益明细记录。 func apply(_ item: EarningDetailItem) { amountLabel.text = item.amount.isEmpty ? "" : WalletViewModel.formatAmount(item.amount) pointsLabel.text = item.points > 0 ? "积分+\(item.points)" : "" amountLabel.isHidden = item.amount.isEmpty pointsLabel.isHidden = item.points <= 0 if item.amount.isEmpty, item.points <= 0 { amountLabel.text = "--" amountLabel.isHidden = false } typeLabel.text = item.typeLabel orderLabel.text = item.orderNumberSuffix orderLabel.isHidden = item.orderNumberSuffix.isEmpty timeLabel.text = item.createdAt withdrawLabel.text = item.withdrawLabel withdrawLabel.isHidden = item.withdrawLabel.isEmpty let style = labelStyle(for: item.withdrawLabel) withdrawLabel.textColor = style.text withdrawLabel.backgroundColor = style.background orderLabel.textColor = style.orderText orderLabel.backgroundColor = style.orderBackground } private func setupUI() { selectionStyle = .none backgroundColor = .white cardView.backgroundColor = .white cardView.layer.cornerRadius = 12 cardView.layer.borderWidth = 1 cardView.layer.borderColor = UIColor(hex: 0xF3F4F6).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) pointsLabel.textAlignment = .right typeLabel.font = .systemFont(ofSize: 14) typeLabel.textColor = UIColor(hex: 0x9CA3AF) orderLabel.font = .systemFont(ofSize: 12) orderLabel.textAlignment = .center orderLabel.layer.cornerRadius = 4 orderLabel.clipsToBounds = true timeLabel.font = .systemFont(ofSize: 14) timeLabel.textColor = UIColor(hex: 0x4B5563) withdrawLabel.font = .systemFont(ofSize: 12) withdrawLabel.textAlignment = .center withdrawLabel.layer.cornerRadius = 4 withdrawLabel.clipsToBounds = true contentView.addSubview(cardView) [amountLabel, pointsLabel, typeLabel, orderLabel, timeLabel, withdrawLabel].forEach(cardView.addSubview) cardView.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 6, left: 16, bottom: 6, right: 16)) } amountLabel.snp.makeConstraints { make in make.top.leading.equalToSuperview().offset(16) } pointsLabel.snp.makeConstraints { make in make.centerY.equalTo(amountLabel) make.leading.greaterThanOrEqualTo(amountLabel.snp.trailing).offset(12) make.trailing.equalToSuperview().inset(16) } typeLabel.snp.makeConstraints { make in make.top.equalTo(amountLabel.snp.bottom).offset(10) make.leading.equalToSuperview().offset(16) } orderLabel.snp.makeConstraints { make in make.centerY.equalTo(typeLabel) make.leading.equalTo(typeLabel.snp.trailing).offset(8) make.height.equalTo(20) make.width.greaterThanOrEqualTo(36) } timeLabel.snp.makeConstraints { make in make.top.equalTo(typeLabel.snp.bottom).offset(12) make.leading.equalToSuperview().offset(16) make.bottom.equalToSuperview().inset(16) } withdrawLabel.snp.makeConstraints { make in make.centerY.equalTo(timeLabel) make.trailing.equalToSuperview().inset(16) make.height.equalTo(20) make.width.greaterThanOrEqualTo(48) } } 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)) default: return (UIColor(hex: 0xF4F4F4), UIColor(hex: 0x7B8EAA), UIColor(hex: 0xF4F4F4), UIColor(hex: 0x7B8EAA)) } } }