完善钱包提现状态展示与举报摄影师列表交互。

对齐 Android 提现进度与时间线映射,优化钱包与积分兑换页刷新逻辑,并补充相关单元测试与真机测试说明。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-13 16:51:32 +08:00
parent 5138c1c11a
commit 05804ba7d6
9 changed files with 440 additions and 99 deletions

View File

@ -816,23 +816,11 @@ final class WildPhotographerReportDetailViewController: BaseViewController {
card.stack.addArrangedSubview(WildReportUI.label("补充证据记录", font: .systemFont(ofSize: 18, weight: .bold), color: AppColor.textPrimary))
let items = viewModel.supplementaryEvidences
items.enumerated().forEach { index, item in
let itemStack = UIStackView()
itemStack.axis = .vertical
itemStack.spacing = 8
let header = UIStackView()
header.axis = .horizontal
header.alignment = .center
header.addArrangedSubview(WildReportUI.label(item.submitTime, font: .app(.captionMedium), color: AppColor.textSecondary))
header.addArrangedSubview(UIView())
header.addArrangedSubview(WildReportUI.label(
WildReportSupplementDisplayFormatter.sequenceTitle(forDisplayIndex: index),
font: .app(.captionMedium),
color: AppColor.primary
))
itemStack.addArrangedSubview(header)
itemStack.addArrangedSubview(WildReportUI.label(item.summaryText, font: .app(.bodyMedium), color: AppColor.textPrimary, lines: 0))
card.stack.addArrangedSubview(itemStack)
let row = WildReportSupplementEvidenceRowView(item: item, displayIndex: index)
row.onPreview = { [weak self] in
self?.presentSupplementMediaPreview(item)
}
card.stack.addArrangedSubview(row)
if index < items.count - 1 {
card.stack.addArrangedSubview(makeDivider())
}
@ -1288,6 +1276,23 @@ final class WildPhotographerReportDetailViewController: BaseViewController {
presentMediaPreview(entries: entries, selectedKey: selectedKey, emptyMessage: "当前处理凭证暂无可预览文件")
}
private func presentSupplementMediaPreview(_ record: WildReportSupplementaryEvidence) {
let items = record.evidences.compactMap { evidence -> MediaPreviewItem? in
if evidence.isVideo {
return .remoteVideo(evidence.fileURL)
}
if evidence.isImage {
return .remoteImage(evidence.fileURL)
}
return nil
}
guard !items.isEmpty else {
showToast("当前补充记录暂无可预览文件")
return
}
presentMediaPreview(items: items, startIndex: 0)
}
private func previewEntries(for mediaItems: [WildReportReporterMediaItem]) -> [(key: String, item: MediaPreviewItem)] {
mediaItems.compactMap { mediaItem in
guard let key = mediaItem.previewKey,
@ -1372,6 +1377,79 @@ private final class WildReportDetailIconTextButton: UIControl {
}
}
///
private final class WildReportSupplementEvidenceRowView: UIControl {
var onPreview: (() -> Void)?
private let previewEnabled: Bool
init(item: WildReportSupplementaryEvidence, displayIndex: Int) {
previewEnabled = item.hasMedia
super.init(frame: .zero)
let sequenceTitle = WildReportSupplementDisplayFormatter.sequenceTitle(forDisplayIndex: displayIndex)
let header = UIStackView()
header.axis = .horizontal
header.alignment = .center
header.spacing = 6
header.isUserInteractionEnabled = false
header.addArrangedSubview(WildReportUI.label(item.submitTime, font: .app(.captionMedium), color: AppColor.textSecondary))
header.addArrangedSubview(UIView())
header.addArrangedSubview(WildReportUI.label(sequenceTitle, font: .app(.captionMedium), color: AppColor.primary))
if previewEnabled {
let chevron = UIImageView(image: UIImage(systemName: "chevron.right"))
chevron.tintColor = AppColor.primary
chevron.contentMode = .scaleAspectFit
chevron.snp.makeConstraints { make in
make.size.equalTo(12)
}
header.addArrangedSubview(chevron)
}
let summaryLabel = WildReportUI.label(item.summaryText, font: .app(.bodyMedium), color: AppColor.textPrimary, lines: 0)
summaryLabel.isUserInteractionEnabled = false
let contentStack = UIStackView(arrangedSubviews: [header, summaryLabel])
contentStack.axis = .vertical
contentStack.spacing = 8
contentStack.isUserInteractionEnabled = false
addSubview(contentStack)
contentStack.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
isEnabled = previewEnabled
guard previewEnabled else { return }
addTarget(self, action: #selector(previewTapped), for: .touchUpInside)
isAccessibilityElement = true
accessibilityTraits = .button
accessibilityLabel = [sequenceTitle, item.submitTime, item.summaryText]
.filter { !$0.isEmpty }
.joined(separator: "")
accessibilityHint = "双击全屏预览图片或视频"
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var isHighlighted: Bool {
didSet {
guard previewEnabled else { return }
UIView.animate(withDuration: 0.15) {
self.alpha = self.isHighlighted ? 0.55 : 1
}
}
}
@objc private func previewTapped() {
onPreview?()
}
}
///
private final class WildReportDetailInfoRowView: UIView {
init(title: String, value: String, multiline: Bool = false, trailingIconName: String? = nil) {