246 lines
10 KiB
Swift
246 lines
10 KiB
Swift
//
|
|
// OfflineCollectionHomeView.swift
|
|
// suixinkan
|
|
//
|
|
|
|
import SnapKit
|
|
import UIKit
|
|
|
|
/// 收款首页中的线下收款入口、今日汇总和历史逾期提醒区域。
|
|
final class OfflineCollectionHomeView: UIView {
|
|
var onRegister: (() -> Void)?
|
|
var onOpenToday: (() -> Void)?
|
|
var onOpenOverdue: (() -> Void)?
|
|
|
|
private let contentStack = UIStackView()
|
|
private let sectionTitleLabel = UILabel()
|
|
|
|
private let overdueControl = UIControl()
|
|
private let overdueTitleLabel = UILabel()
|
|
private let overdueDetailLabel = UILabel()
|
|
private let overdueActionLabel = UILabel()
|
|
|
|
private let registerControl = UIControl()
|
|
private let registerIconView = UIImageView()
|
|
private let registerTitleLabel = UILabel()
|
|
private let registerSubtitleLabel = UILabel()
|
|
private let registerActionLabel = UILabel()
|
|
|
|
private let summaryControl = UIControl()
|
|
private let summaryTitleLabel = UILabel()
|
|
private let summaryAmountLabel = UILabel()
|
|
private let summaryCountLabel = UILabel()
|
|
private let summaryRegisteredLabel = UILabel()
|
|
private let summaryStatusLabel = UILabel()
|
|
private let summaryActionLabel = UILabel()
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
setupUI()
|
|
setupConstraints()
|
|
bindActions()
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
/// 根据今日与历史逾期汇总刷新页面内容。
|
|
func apply(
|
|
today: OfflineDailySummary,
|
|
overdueDayCount: Int,
|
|
overdueRecordCount: Int,
|
|
overdueAmountFen: Int
|
|
) {
|
|
let hasOverdue = overdueDayCount > 0 && overdueAmountFen > 0
|
|
overdueControl.isHidden = !hasOverdue
|
|
overdueDetailLabel.text = "\(overdueDayCount) 个营业日,共 \(overdueRecordCount) 笔,待补缴 \(OfflineCollectionMoney.display(overdueAmountFen))"
|
|
|
|
summaryAmountLabel.text = OfflineCollectionMoney.display(today.pendingAmountFen)
|
|
summaryCountLabel.text = "\(today.pendingCount) 笔线下收款"
|
|
summaryRegisteredLabel.text = "今日已登记 \(OfflineCollectionMoney.display(today.totalAmountFen))"
|
|
let isSettled = today.totalCount > 0 && today.pendingAmountFen == 0
|
|
summaryStatusLabel.text = isSettled ? "今日已结清" : ""
|
|
summaryStatusLabel.isHidden = !isSettled
|
|
summaryActionLabel.text = today.pendingAmountFen > 0 ? "去补缴" : "查看明细"
|
|
summaryActionLabel.backgroundColor = today.pendingAmountFen > 0
|
|
? AppColor.primary
|
|
: UIColor(hex: 0xEEF2F7)
|
|
summaryActionLabel.textColor = today.pendingAmountFen > 0
|
|
? .white
|
|
: AppColor.textSecondary
|
|
}
|
|
|
|
private func setupUI() {
|
|
backgroundColor = .clear
|
|
|
|
contentStack.axis = .vertical
|
|
contentStack.spacing = AppSpacing.md
|
|
|
|
sectionTitleLabel.text = "线下收款"
|
|
sectionTitleLabel.font = .systemFont(ofSize: 16, weight: .semibold)
|
|
sectionTitleLabel.textColor = AppColor.textPrimary
|
|
|
|
configureCard(overdueControl, backgroundColor: UIColor(hex: 0xFFF1F0))
|
|
overdueControl.layer.borderColor = UIColor(hex: 0xFFCCC7).cgColor
|
|
overdueControl.layer.borderWidth = 1
|
|
overdueTitleLabel.text = "存在逾期未补缴"
|
|
overdueTitleLabel.font = .systemFont(ofSize: 15, weight: .semibold)
|
|
overdueTitleLabel.textColor = AppColor.danger
|
|
overdueDetailLabel.font = .systemFont(ofSize: 13)
|
|
overdueDetailLabel.textColor = UIColor(hex: 0x8C2F27)
|
|
overdueDetailLabel.numberOfLines = 0
|
|
configureActionLabel(overdueActionLabel, title: "立即处理", background: AppColor.danger, foreground: .white)
|
|
|
|
configureCard(registerControl, backgroundColor: .white)
|
|
registerIconView.image = UIImage(systemName: "plus.circle.fill")
|
|
registerIconView.tintColor = AppColor.primary
|
|
registerIconView.contentMode = .scaleAspectFit
|
|
registerTitleLabel.text = "线下收款登记"
|
|
registerTitleLabel.font = .systemFont(ofSize: 16, weight: .semibold)
|
|
registerTitleLabel.textColor = AppColor.textPrimary
|
|
registerSubtitleLabel.text = "线下收款后,请及时登记并在当日完成补缴"
|
|
registerSubtitleLabel.font = .systemFont(ofSize: 13)
|
|
registerSubtitleLabel.textColor = AppColor.textSecondary
|
|
registerSubtitleLabel.numberOfLines = 0
|
|
configureActionLabel(registerActionLabel, title: "去登记", background: UIColor(hex: 0xEEF5FF), foreground: AppColor.primary)
|
|
|
|
configureCard(summaryControl, backgroundColor: .white)
|
|
summaryTitleLabel.text = "今日待补缴"
|
|
summaryTitleLabel.font = .systemFont(ofSize: 15, weight: .semibold)
|
|
summaryTitleLabel.textColor = AppColor.textPrimary
|
|
summaryAmountLabel.font = .systemFont(ofSize: 30, weight: .bold)
|
|
summaryAmountLabel.textColor = AppColor.textPrimary
|
|
summaryCountLabel.font = .systemFont(ofSize: 13)
|
|
summaryCountLabel.textColor = UIColor(hex: 0xD97706)
|
|
summaryRegisteredLabel.font = .systemFont(ofSize: 13)
|
|
summaryRegisteredLabel.textColor = AppColor.textSecondary
|
|
summaryStatusLabel.font = .systemFont(ofSize: 13, weight: .semibold)
|
|
summaryStatusLabel.textColor = AppColor.success
|
|
configureActionLabel(summaryActionLabel, title: "查看明细", background: UIColor(hex: 0xEEF2F7), foreground: AppColor.textSecondary)
|
|
|
|
addSubview(contentStack)
|
|
[sectionTitleLabel, overdueControl, registerControl, summaryControl].forEach(contentStack.addArrangedSubview)
|
|
|
|
let overdueTextStack = UIStackView(arrangedSubviews: [overdueTitleLabel, overdueDetailLabel])
|
|
overdueTextStack.axis = .vertical
|
|
overdueTextStack.spacing = 5
|
|
overdueControl.addSubview(overdueTextStack)
|
|
overdueControl.addSubview(overdueActionLabel)
|
|
|
|
let registerTextStack = UIStackView(arrangedSubviews: [registerTitleLabel, registerSubtitleLabel])
|
|
registerTextStack.axis = .vertical
|
|
registerTextStack.spacing = 5
|
|
registerControl.addSubview(registerIconView)
|
|
registerControl.addSubview(registerTextStack)
|
|
registerControl.addSubview(registerActionLabel)
|
|
|
|
let summaryTextStack = UIStackView(arrangedSubviews: [
|
|
summaryTitleLabel,
|
|
summaryAmountLabel,
|
|
summaryCountLabel,
|
|
summaryRegisteredLabel,
|
|
summaryStatusLabel,
|
|
])
|
|
summaryTextStack.axis = .vertical
|
|
summaryTextStack.spacing = 6
|
|
summaryControl.addSubview(summaryTextStack)
|
|
summaryControl.addSubview(summaryActionLabel)
|
|
}
|
|
|
|
private func setupConstraints() {
|
|
contentStack.snp.makeConstraints { make in
|
|
make.edges.equalToSuperview()
|
|
}
|
|
sectionTitleLabel.snp.makeConstraints { make in
|
|
make.height.equalTo(24)
|
|
}
|
|
|
|
overdueControl.snp.makeConstraints { make in
|
|
make.height.greaterThanOrEqualTo(84)
|
|
}
|
|
overdueControl.subviews.first?.snp.makeConstraints { make in
|
|
make.leading.top.bottom.equalToSuperview().inset(AppSpacing.md)
|
|
make.trailing.lessThanOrEqualTo(overdueActionLabel.snp.leading).offset(-AppSpacing.sm)
|
|
}
|
|
overdueActionLabel.snp.makeConstraints { make in
|
|
make.trailing.equalToSuperview().inset(AppSpacing.md)
|
|
make.centerY.equalToSuperview()
|
|
make.height.equalTo(32)
|
|
}
|
|
|
|
registerControl.snp.makeConstraints { make in
|
|
make.height.greaterThanOrEqualTo(96)
|
|
}
|
|
registerIconView.snp.makeConstraints { make in
|
|
make.leading.equalToSuperview().inset(AppSpacing.md)
|
|
make.centerY.equalToSuperview()
|
|
make.width.height.equalTo(34)
|
|
}
|
|
registerTitleLabel.superview?.snp.makeConstraints { make in
|
|
make.leading.equalTo(registerIconView.snp.trailing).offset(AppSpacing.sm)
|
|
make.centerY.equalToSuperview()
|
|
make.trailing.lessThanOrEqualTo(registerActionLabel.snp.leading).offset(-AppSpacing.sm)
|
|
}
|
|
registerActionLabel.snp.makeConstraints { make in
|
|
make.trailing.equalToSuperview().inset(AppSpacing.md)
|
|
make.centerY.equalToSuperview()
|
|
make.height.equalTo(32)
|
|
}
|
|
|
|
summaryControl.snp.makeConstraints { make in
|
|
make.height.greaterThanOrEqualTo(180)
|
|
}
|
|
summaryTitleLabel.superview?.snp.makeConstraints { make in
|
|
make.leading.top.bottom.equalToSuperview().inset(AppSpacing.md)
|
|
make.trailing.lessThanOrEqualTo(summaryActionLabel.snp.leading).offset(-AppSpacing.sm)
|
|
}
|
|
summaryActionLabel.snp.makeConstraints { make in
|
|
make.trailing.equalToSuperview().inset(AppSpacing.md)
|
|
make.bottom.equalToSuperview().inset(AppSpacing.md)
|
|
make.height.equalTo(34)
|
|
}
|
|
}
|
|
|
|
private func bindActions() {
|
|
overdueControl.addTarget(self, action: #selector(overdueTapped), for: .touchUpInside)
|
|
registerControl.addTarget(self, action: #selector(registerTapped), for: .touchUpInside)
|
|
summaryControl.addTarget(self, action: #selector(summaryTapped), for: .touchUpInside)
|
|
}
|
|
|
|
private func configureCard(_ control: UIControl, backgroundColor: UIColor) {
|
|
control.backgroundColor = backgroundColor
|
|
control.layer.cornerRadius = AppRadius.lg
|
|
control.clipsToBounds = true
|
|
}
|
|
|
|
private func configureActionLabel(
|
|
_ label: UILabel,
|
|
title: String,
|
|
background: UIColor,
|
|
foreground: UIColor
|
|
) {
|
|
label.text = " \(title) "
|
|
label.font = .systemFont(ofSize: 13, weight: .semibold)
|
|
label.textAlignment = .center
|
|
label.textColor = foreground
|
|
label.backgroundColor = background
|
|
label.layer.cornerRadius = 16
|
|
label.clipsToBounds = true
|
|
label.setContentCompressionResistancePriority(.required, for: .horizontal)
|
|
}
|
|
|
|
@objc private func overdueTapped() {
|
|
onOpenOverdue?()
|
|
}
|
|
|
|
@objc private func registerTapped() {
|
|
onRegister?()
|
|
}
|
|
|
|
@objc private func summaryTapped() {
|
|
onOpenToday?()
|
|
}
|
|
}
|