Files
suixinkan_uikit/suixinkan/UI/Orders/DepositOrderCardCell.swift
汉秋 31d2b6094b Implement orders tab aligned with Android, including scan verify flows.
Add role-based order/deposit lists, AVFoundation QR scanning, verify dialogs, and ViewModel tests so photographers, scenic admins, and store admins match Android behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:59:53 +08:00

145 lines
6.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// DepositOrderCardCell.swift
// suixinkan
//
import SnapKit
import UIKit
struct DepositOrderCardActions {
var onRefund: (() -> Void)?
var onPartialRefund: (() -> Void)?
var onVerify: (() -> Void)?
var onTap: (() -> Void)?
}
/// Android `DepositOrderListScreen`
final class DepositOrderCardCell: UITableViewCell {
static let reuseIdentifier = "DepositOrderCardCell"
private let cardView = UIView()
private let projectLabel = UILabel()
private let statusBadge = OrderStatusBadgeView()
private let amountLabel = UILabel()
private let timeLabel = UILabel()
private let uidLabel = UILabel()
private let phoneLabel = UILabel()
private let refundButton = UIButton(type: .system)
private let partialRefundButton = UIButton(type: .system)
private let verifyButton = UIButton(type: .system)
private var actions = DepositOrderCardActions()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
selectionStyle = .none
backgroundColor = .clear
setupUI()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(item: StoreOrderItem, actions: DepositOrderCardActions) {
self.actions = actions
projectLabel.text = item.projectName.isEmpty ? item.orderTypeLabel : item.projectName
statusBadge.apply(status: item.orderStatus, text: item.orderStatusName)
amountLabel.text = "¥\(item.actualPayAmount)"
timeLabel.text = item.createdAt
uidLabel.text = "UID\(item.userId)"
phoneLabel.text = OrderPhoneMask.mask(item.phone)
let showVerify = item.orderType == StoreOrderType.offlineProduct && item.orderStatus == 20
verifyButton.isHidden = !showVerify
refundButton.isHidden = item.orderStatus != 20 && item.orderStatus != 30
partialRefundButton.isHidden = item.orderStatus != 20 && item.orderStatus != 30
}
private func setupUI() {
cardView.backgroundColor = .white
cardView.layer.cornerRadius = 12
let tap = UITapGestureRecognizer(target: self, action: #selector(cardTapped))
cardView.addGestureRecognizer(tap)
projectLabel.font = .systemFont(ofSize: 16, weight: .medium)
amountLabel.font = .systemFont(ofSize: 16, weight: .semibold)
amountLabel.textColor = AppColor.primary
[timeLabel, uidLabel, phoneLabel].forEach {
$0.font = .systemFont(ofSize: 13)
$0.textColor = UIColor(hex: 0x6B7280)
}
configureActionButton(refundButton, title: "退款", color: UIColor(hex: 0xEF4444), bg: UIColor(hex: 0xFFE7E7))
configureActionButton(partialRefundButton, title: "部分退款", color: AppColor.primary, bg: UIColor(hex: 0xEFF6FF))
configureActionButton(verifyButton, title: "线下核销", color: .white, bg: UIColor(hex: 0x0073FF))
refundButton.addTarget(self, action: #selector(refundTapped), for: .touchUpInside)
partialRefundButton.addTarget(self, action: #selector(partialRefundTapped), for: .touchUpInside)
verifyButton.addTarget(self, action: #selector(verifyTapped), for: .touchUpInside)
contentView.addSubview(cardView)
[projectLabel, statusBadge, amountLabel, timeLabel, uidLabel, phoneLabel, refundButton, partialRefundButton, verifyButton].forEach {
cardView.addSubview($0)
}
cardView.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 12, right: 16))
}
projectLabel.snp.makeConstraints { make in
make.top.leading.equalToSuperview().inset(16)
}
statusBadge.snp.makeConstraints { make in
make.centerY.equalTo(projectLabel)
make.trailing.equalToSuperview().inset(16)
}
amountLabel.snp.makeConstraints { make in
make.top.equalTo(projectLabel.snp.bottom).offset(8)
make.leading.equalToSuperview().inset(16)
}
timeLabel.snp.makeConstraints { make in
make.top.equalTo(amountLabel.snp.bottom).offset(4)
make.leading.equalToSuperview().inset(16)
}
uidLabel.snp.makeConstraints { make in
make.top.equalTo(timeLabel.snp.bottom).offset(4)
make.leading.equalToSuperview().inset(16)
}
phoneLabel.snp.makeConstraints { make in
make.top.equalTo(uidLabel.snp.bottom).offset(4)
make.leading.equalToSuperview().inset(16)
}
refundButton.snp.makeConstraints { make in
make.top.equalTo(phoneLabel.snp.bottom).offset(12)
make.leading.equalToSuperview().inset(16)
make.height.equalTo(40)
make.width.equalTo(88)
make.bottom.equalToSuperview().inset(16)
}
partialRefundButton.snp.makeConstraints { make in
make.centerY.equalTo(refundButton)
make.leading.equalTo(refundButton.snp.trailing).offset(8)
make.height.equalTo(40)
make.width.equalTo(100)
}
verifyButton.snp.makeConstraints { make in
make.centerY.equalTo(refundButton)
make.trailing.equalToSuperview().inset(16)
make.height.equalTo(40)
make.width.equalTo(100)
}
}
private func configureActionButton(_ button: UIButton, title: String, color: UIColor, bg: UIColor) {
button.setTitle(title, for: .normal)
button.setTitleColor(color, for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 14)
button.backgroundColor = bg
button.layer.cornerRadius = 8
}
@objc private func refundTapped() { actions.onRefund?() }
@objc private func partialRefundTapped() { actions.onPartialRefund?() }
@objc private func verifyTapped() { actions.onVerify?() }
@objc private func cardTapped() { actions.onTap?() }
}