接入举报摄影师正式接口
This commit is contained in:
@ -9,12 +9,17 @@ import UIKit
|
||||
/// 我的举报列表页,支持按状态筛选并进入举报详情。
|
||||
final class WildPhotographerReportListViewController: BaseViewController {
|
||||
private let viewModel: WildPhotographerReportListViewModel
|
||||
private let api: any WildPhotographerReportServing
|
||||
private let scrollView = UIScrollView()
|
||||
private let stack = UIStackView()
|
||||
private let filterTabBar = WildReportFilterTabBarView()
|
||||
|
||||
init(homeViewModel: WildPhotographerReportHomeViewModel) {
|
||||
init(
|
||||
homeViewModel: WildPhotographerReportHomeViewModel,
|
||||
api: any WildPhotographerReportServing = NetworkServices.shared.wildPhotographerReportAPI
|
||||
) {
|
||||
self.viewModel = WildPhotographerReportListViewModel(homeViewModel: homeViewModel)
|
||||
self.api = api
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@ -31,11 +36,19 @@ final class WildPhotographerReportListViewController: BaseViewController {
|
||||
view.backgroundColor = AppColor.pageBackgroundSoft
|
||||
scrollView.showsVerticalScrollIndicator = false
|
||||
scrollView.alwaysBounceVertical = true
|
||||
scrollView.delegate = self
|
||||
stack.axis = .vertical
|
||||
stack.spacing = 14
|
||||
|
||||
filterTabBar.onSelect = { [weak self] filter in
|
||||
self?.viewModel.selectFilter(filter)
|
||||
guard let self else { return }
|
||||
Task {
|
||||
await self.viewModel.selectFilter(
|
||||
filter,
|
||||
api: self.api,
|
||||
scenicId: self.currentScenicId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
view.addSubview(scrollView)
|
||||
@ -56,6 +69,13 @@ final class WildPhotographerReportListViewController: BaseViewController {
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
Task {
|
||||
await viewModel.loadInitial(api: api, scenicId: currentScenicId)
|
||||
}
|
||||
}
|
||||
|
||||
override func bindActions() {
|
||||
viewModel.onStateChange = { [weak self] in
|
||||
Task { @MainActor in self?.reloadContent(animated: true) }
|
||||
@ -93,7 +113,7 @@ final class WildPhotographerReportListViewController: BaseViewController {
|
||||
|
||||
let reports = viewModel.filteredReports
|
||||
if reports.isEmpty {
|
||||
stack.addArrangedSubview(WildReportListEmptyView())
|
||||
stack.addArrangedSubview(viewModel.isLoading ? WildReportListLoadingView(text: "正在加载举报记录...") : WildReportListEmptyView())
|
||||
} else {
|
||||
reports.forEach { record in
|
||||
let card = WildReportListCardView(record: record)
|
||||
@ -103,7 +123,7 @@ final class WildPhotographerReportListViewController: BaseViewController {
|
||||
}
|
||||
}
|
||||
|
||||
let footer = WildReportUI.label(viewModel.footerTip, font: .app(.caption), color: UIColor(hex: 0x9CA3AF), lines: 0)
|
||||
let footer = WildReportUI.label(viewModel.footerDisplayText, font: .app(.caption), color: UIColor(hex: 0x9CA3AF), lines: 0)
|
||||
footer.textAlignment = .center
|
||||
let footerWrap = UIView()
|
||||
footerWrap.addSubview(footer)
|
||||
@ -120,6 +140,23 @@ final class WildPhotographerReportListViewController: BaseViewController {
|
||||
animated: true
|
||||
)
|
||||
}
|
||||
|
||||
private var currentScenicId: Int? {
|
||||
let scenicId = AppStore.shared.currentScenicId
|
||||
return scenicId > 0 ? scenicId : nil
|
||||
}
|
||||
}
|
||||
|
||||
extension WildPhotographerReportListViewController: UIScrollViewDelegate {
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
let threshold: CGFloat = 80
|
||||
let visibleBottom = scrollView.contentOffset.y + scrollView.bounds.height
|
||||
let triggerY = scrollView.contentSize.height - threshold
|
||||
guard visibleBottom >= triggerY, scrollView.contentSize.height > scrollView.bounds.height else { return }
|
||||
Task {
|
||||
await viewModel.loadMoreIfNeeded(api: api, scenicId: currentScenicId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 我的举报筛选栏,使用四段等宽胶囊按钮展示状态过滤。
|
||||
@ -180,7 +217,7 @@ private final class WildReportFilterTabBarView: UIView {
|
||||
}
|
||||
|
||||
/// 我的举报列表卡片,展示一条举报记录并提供详情与分享入口。
|
||||
private final class WildReportListCardView: UIControl {
|
||||
private final class WildReportListCardView: UIControl, UIGestureRecognizerDelegate {
|
||||
var onOpen: (() -> Void)?
|
||||
var onShare: (() -> Void)?
|
||||
|
||||
@ -215,7 +252,11 @@ private final class WildReportListCardView: UIControl {
|
||||
layer.cornerRadius = 16
|
||||
layer.borderWidth = 1
|
||||
layer.borderColor = AppColor.cardOutline.cgColor
|
||||
addTarget(self, action: #selector(openTapped), for: .touchUpInside)
|
||||
|
||||
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openTapped))
|
||||
tapRecognizer.delegate = self
|
||||
tapRecognizer.cancelsTouchesInView = false
|
||||
addGestureRecognizer(tapRecognizer)
|
||||
|
||||
let contentStack = UIStackView()
|
||||
contentStack.axis = .vertical
|
||||
@ -365,6 +406,17 @@ private final class WildReportListCardView: UIControl {
|
||||
@objc private func shareTapped() {
|
||||
onShare?()
|
||||
}
|
||||
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
||||
var currentView: UIView? = touch.view
|
||||
while let view = currentView {
|
||||
if view is UIButton {
|
||||
return false
|
||||
}
|
||||
currentView = view.superview
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/// 我的举报列表信息行,展示举报编号、举报时间等左右结构内容。
|
||||
@ -429,6 +481,35 @@ private final class WildReportListEmptyView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
/// 我的举报列表加载态卡片。
|
||||
private final class WildReportListLoadingView: UIView {
|
||||
init(text: String) {
|
||||
super.init(frame: .zero)
|
||||
backgroundColor = .white
|
||||
layer.cornerRadius = 16
|
||||
|
||||
let indicator = UIActivityIndicatorView(style: .medium)
|
||||
indicator.color = AppColor.primary
|
||||
indicator.startAnimating()
|
||||
let label = WildReportUI.label(text, font: .systemFont(ofSize: 15, weight: .semibold), color: AppColor.textSecondary)
|
||||
|
||||
let stack = UIStackView(arrangedSubviews: [indicator, label])
|
||||
stack.axis = .vertical
|
||||
stack.alignment = .center
|
||||
stack.spacing = 12
|
||||
addSubview(stack)
|
||||
stack.snp.makeConstraints { make in
|
||||
make.top.bottom.equalToSuperview().inset(48)
|
||||
make.leading.trailing.equalToSuperview().inset(16)
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
/// 举报详情页。
|
||||
final class WildPhotographerReportDetailViewController: BaseViewController {
|
||||
private let viewModel: WildPhotographerReportDetailViewModel
|
||||
@ -619,7 +700,7 @@ final class WildPhotographerReportDetailViewController: BaseViewController {
|
||||
private func makeReportInfoCard() -> UIView {
|
||||
let card = WildReportCardView(spacing: 0, inset: 0)
|
||||
card.layer.cornerRadius = 18
|
||||
card.stack.addArrangedSubview(WildReportDetailInfoRowView(title: "举报类型", value: viewModel.record.reportType.rawValue))
|
||||
card.stack.addArrangedSubview(WildReportDetailInfoRowView(title: "举报类型", value: viewModel.record.reportType.label))
|
||||
card.stack.addArrangedSubview(makeInsetDivider())
|
||||
card.stack.addArrangedSubview(WildReportDetailInfoRowView(title: "举报说明", value: viewModel.descriptionText, multiline: true))
|
||||
card.stack.addArrangedSubview(makeInsetDivider())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user