Advance UIKit rewrite with AMap integration and core UI modules.
Integrate高德 SDK with simulator-safe build flags, add map views for operating area and punch points, refactor main tabs and key feature screens to UIKit with Diffable lists, and document Swift concurrency defaults in AGENTS.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -6,32 +6,127 @@
|
||||
import SnapKit
|
||||
import UIKit
|
||||
|
||||
// MARK: - Deposit List Diffable 标识
|
||||
|
||||
private typealias DepositListSection = Int
|
||||
private typealias DepositListItem = String
|
||||
|
||||
/// 押金列表空态 / 加载态标识。
|
||||
private enum DepositListItemID {
|
||||
static let placeholder = "depositList:placeholder"
|
||||
}
|
||||
|
||||
// MARK: - Deposit Detail Diffable 标识
|
||||
|
||||
private typealias DepositDetailSection = Int
|
||||
private typealias DepositDetailRow = String
|
||||
|
||||
/// 押金详情行标识。
|
||||
private enum DepositDetailRowID {
|
||||
static let placeholder = "depositDetail:placeholder"
|
||||
static func field(_ index: Int) -> String { "depositDetail:field:\(index)" }
|
||||
}
|
||||
|
||||
// MARK: - Deposit Shooting Diffable 标识
|
||||
|
||||
private typealias DepositShootingSection = Int
|
||||
private typealias DepositShootingRow = String
|
||||
|
||||
/// 押金拍摄信息 section 索引。
|
||||
private enum DepositShootingSectionID {
|
||||
static let summary = 0
|
||||
static let material = 1
|
||||
static let complete = 2
|
||||
}
|
||||
|
||||
/// 押金拍摄信息行标识。
|
||||
private enum DepositShootingRowID {
|
||||
static let placeholder = "depositShooting:placeholder"
|
||||
static let scenicSpot = "depositShooting:scenicSpot"
|
||||
static let rating = "depositShooting:rating"
|
||||
static func material(_ index: Int) -> String { "depositShooting:material:\(index)" }
|
||||
static func complete(_ index: Int) -> String { "depositShooting:complete:\(index)" }
|
||||
}
|
||||
|
||||
/// 押金订单列表页,支持查询、分页、核销和退款。
|
||||
final class DepositOrderListViewController: UIViewController {
|
||||
final class DepositOrderListViewController: UIViewController, UITableViewDelegate {
|
||||
|
||||
private let viewModel = DepositOrderListViewModel()
|
||||
private var orderNumberField = UITextField()
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let table = UITableView(frame: .zero, style: .insetGrouped)
|
||||
table.dataSource = self
|
||||
table.delegate = self
|
||||
table.register(DepositOrderCell.self, forCellReuseIdentifier: DepositOrderCell.reuseID)
|
||||
return table
|
||||
}()
|
||||
|
||||
/// Diffable 数据源,驱动押金订单列表与分页刷新。
|
||||
private var tableDataSource: UITableViewDiffableDataSource<DepositListSection, DepositListItem>!
|
||||
|
||||
/// 视图加载完成后的 UI 初始化与数据绑定。
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
title = "押金订单"
|
||||
view.backgroundColor = AppDesignUIKit.pageBackground
|
||||
configureTableDataSource()
|
||||
view.addSubview(tableView)
|
||||
tableView.snp.makeConstraints { make in make.edges.equalToSuperview() }
|
||||
|
||||
viewModel.onChange = { [weak self] in self?.tableView.reloadData() }
|
||||
viewModel.onChange = { [weak self] in self?.applyTableSnapshot(reconfigure: true) }
|
||||
setupHeader()
|
||||
Task { await reload(showLoading: true) }
|
||||
}
|
||||
|
||||
/// 配置 Diffable 数据源。
|
||||
private func configureTableDataSource() {
|
||||
tableDataSource = UITableViewDiffableDataSource<DepositListSection, DepositListItem>(
|
||||
tableView: tableView
|
||||
) { [weak self] (tableView: UITableView, indexPath: IndexPath, item: DepositListItem) -> UITableViewCell? in
|
||||
guard let self else { return UITableViewCell() }
|
||||
if item == DepositListItemID.placeholder {
|
||||
let cell = UITableViewCell()
|
||||
cell.textLabel?.text = self.viewModel.loading ? "加载中..." : "暂无押金订单"
|
||||
cell.selectionStyle = .none
|
||||
return cell
|
||||
}
|
||||
guard let orderItem = self.viewModel.orders.first(where: { $0.orderNumber == item }) else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: DepositOrderCell.reuseID, for: indexPath) as! DepositOrderCell
|
||||
cell.configure(item: orderItem, isOperating: self.viewModel.operatingOrderNumber == orderItem.orderNumber)
|
||||
cell.onDetail = { [weak self] in
|
||||
self.flatMap { HomeMenuRouting.pushOrders(.depositDetail(orderNumber: orderItem.orderNumber), from: $0) }
|
||||
}
|
||||
cell.onWriteOff = { [weak self] in self?.writeOff(orderItem) }
|
||||
cell.onRefund = { [weak self] in self?.refund(orderItem) }
|
||||
return cell
|
||||
}
|
||||
applyTableSnapshot(animated: false)
|
||||
}
|
||||
|
||||
/// 构建 Diffable snapshot。
|
||||
private func buildTableSnapshot() -> NSDiffableDataSourceSnapshot<DepositListSection, DepositListItem> {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<DepositListSection, DepositListItem>()
|
||||
snapshot.appendSections([0])
|
||||
if viewModel.orders.isEmpty {
|
||||
snapshot.appendItems([DepositListItemID.placeholder], toSection: 0)
|
||||
} else {
|
||||
snapshot.appendItems(viewModel.orders.map(\.orderNumber), toSection: 0)
|
||||
}
|
||||
return snapshot
|
||||
}
|
||||
|
||||
/// 应用 snapshot 刷新列表。
|
||||
private func applyTableSnapshot(animated: Bool = true, reconfigure: Bool = false) {
|
||||
var snapshot = buildTableSnapshot()
|
||||
if reconfigure, !snapshot.itemIdentifiers.isEmpty {
|
||||
snapshot.reconfigureItems(snapshot.itemIdentifiers)
|
||||
}
|
||||
tableDataSource.apply(snapshot, animatingDifferences: animated)
|
||||
}
|
||||
|
||||
/// 初始化Header相关 UI 或状态。
|
||||
private func setupHeader() {
|
||||
let header = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 120))
|
||||
orderNumberField.placeholder = "请输入押金订单号"
|
||||
@ -55,12 +150,14 @@ final class DepositOrderListViewController: UIViewController {
|
||||
tableView.tableHeaderView = header
|
||||
}
|
||||
|
||||
/// open详情相关逻辑。
|
||||
@objc private func openDetail() {
|
||||
let text = orderNumberField.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
guard !text.isEmpty else { return }
|
||||
HomeMenuRouting.pushOrders(.depositDetail(orderNumber: text), from: self)
|
||||
}
|
||||
|
||||
/// 刷新。
|
||||
private func reload(showLoading: Bool) async {
|
||||
if showLoading {
|
||||
await appServices.globalLoading.withLoading {
|
||||
@ -72,6 +169,7 @@ final class DepositOrderListViewController: UIViewController {
|
||||
if let message = viewModel.errorMessage { showToast(message) }
|
||||
}
|
||||
|
||||
/// writeOff相关逻辑。
|
||||
private func writeOff(_ item: DepositOrderListItem) {
|
||||
let alert = UIAlertController(title: "确认核销该押金订单?", message: item.orderNumber, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "取消", style: .cancel))
|
||||
@ -86,6 +184,7 @@ final class DepositOrderListViewController: UIViewController {
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
/// refund 业务逻辑。
|
||||
private func refund(_ item: DepositOrderListItem) {
|
||||
let alert = UIAlertController(title: "申请退款", message: "请填写退款原因", preferredStyle: .alert)
|
||||
alert.addTextField { $0.placeholder = "退款原因" }
|
||||
@ -101,43 +200,25 @@ final class DepositOrderListViewController: UIViewController {
|
||||
})
|
||||
present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension DepositOrderListViewController: UITableViewDataSource, UITableViewDelegate {
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
max(viewModel.orders.count, 1)
|
||||
}
|
||||
|
||||
/// UITableView 代理:section 标题。
|
||||
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
"押金订单列表 \(viewModel.orders.count)/\(viewModel.total)"
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard !viewModel.orders.isEmpty else {
|
||||
let cell = UITableViewCell()
|
||||
cell.textLabel?.text = viewModel.loading ? "加载中..." : "暂无押金订单"
|
||||
cell.selectionStyle = .none
|
||||
return cell
|
||||
}
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: DepositOrderCell.reuseID, for: indexPath) as! DepositOrderCell
|
||||
let item = viewModel.orders[indexPath.row]
|
||||
cell.configure(item: item, isOperating: viewModel.operatingOrderNumber == item.orderNumber)
|
||||
cell.onDetail = { [weak self] in
|
||||
self.flatMap { HomeMenuRouting.pushOrders(.depositDetail(orderNumber: item.orderNumber), from: $0) }
|
||||
}
|
||||
cell.onWriteOff = { [weak self] in self?.writeOff(item) }
|
||||
cell.onRefund = { [weak self] in self?.refund(item) }
|
||||
return cell
|
||||
}
|
||||
|
||||
/// UITableView 代理:分页加载。
|
||||
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
|
||||
guard indexPath.row == viewModel.orders.count - 1, viewModel.hasMore else { return }
|
||||
guard let item = tableDataSource.itemIdentifier(for: indexPath),
|
||||
item != DepositListItemID.placeholder,
|
||||
item == viewModel.orders.last?.orderNumber,
|
||||
viewModel.hasMore else { return }
|
||||
Task {
|
||||
await viewModel.reload(api: appServices.ordersAPI, scenicId: appServices.accountContext.currentScenic?.id, reset: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// DepositOrder列表或网格 Cell,负责单项内容展示。
|
||||
private final class DepositOrderCell: UITableViewCell {
|
||||
static let reuseID = "DepositOrderCell"
|
||||
var onDetail: (() -> Void)?
|
||||
@ -148,6 +229,7 @@ private final class DepositOrderCell: UITableViewCell {
|
||||
private let statusLabel = UILabel()
|
||||
private let amountLabel = UILabel()
|
||||
|
||||
/// 初始化实例。
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
selectionStyle = .none
|
||||
@ -182,14 +264,18 @@ private final class DepositOrderCell: UITableViewCell {
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) { fatalError() }
|
||||
|
||||
/// 配置展示内容。
|
||||
func configure(item: DepositOrderListItem, isOperating: Bool) {
|
||||
titleLabel.text = item.orderNumber
|
||||
statusLabel.text = isOperating ? "处理中" : item.statusName
|
||||
amountLabel.text = "¥\(item.amount.isEmpty ? "0.00" : item.amount)"
|
||||
}
|
||||
|
||||
/// 点击detail的处理逻辑。
|
||||
@objc private func detailTapped() { onDetail?() }
|
||||
/// 点击writeOff的处理逻辑。
|
||||
@objc private func writeOffTapped() { onWriteOff?() }
|
||||
/// 点击refund的处理逻辑。
|
||||
@objc private func refundTapped() { onRefund?() }
|
||||
}
|
||||
|
||||
@ -201,11 +287,14 @@ final class DepositOrderDetailViewController: UIViewController {
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let table = UITableView(frame: .zero, style: .insetGrouped)
|
||||
table.dataSource = self
|
||||
table.backgroundColor = AppDesignUIKit.pageBackground
|
||||
return table
|
||||
}()
|
||||
|
||||
/// Diffable 数据源,驱动详情字段展示。
|
||||
private var tableDataSource: UITableViewDiffableDataSource<DepositDetailSection, DepositDetailRow>!
|
||||
|
||||
/// 初始化实例。
|
||||
init(orderNumber: String) {
|
||||
self.orderNumber = orderNumber
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
@ -214,14 +303,66 @@ final class DepositOrderDetailViewController: UIViewController {
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) { fatalError() }
|
||||
|
||||
/// 视图加载完成后的 UI 初始化与数据绑定。
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
title = "押金订单详情"
|
||||
configureTableDataSource()
|
||||
view.addSubview(tableView)
|
||||
tableView.snp.makeConstraints { make in make.edges.equalToSuperview() }
|
||||
Task { await loadDetail() }
|
||||
}
|
||||
|
||||
/// 配置 Diffable 数据源。
|
||||
private func configureTableDataSource() {
|
||||
tableDataSource = UITableViewDiffableDataSource<DepositDetailSection, DepositDetailRow>(
|
||||
tableView: tableView
|
||||
) { [weak self] (_: UITableView, _: IndexPath, row: DepositDetailRow) -> UITableViewCell? in
|
||||
guard let self else { return UITableViewCell() }
|
||||
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
|
||||
cell.selectionStyle = .none
|
||||
guard let detail = self.viewModel.detail else {
|
||||
cell.textLabel?.text = self.viewModel.errorMessage ?? (self.viewModel.loading ? "加载中..." : "暂无详情")
|
||||
return cell
|
||||
}
|
||||
let rows: [(String, String)] = [
|
||||
("订单号", detail.orderNumber),
|
||||
("状态", detail.orderStatusName),
|
||||
("类型", detail.orderTypeLabel),
|
||||
("付款金额", detail.actualPayAmount),
|
||||
("手机号", detail.phone),
|
||||
("项目", detail.projectName),
|
||||
("创建时间", detail.createdAt),
|
||||
("备注", detail.remark)
|
||||
]
|
||||
let index = Int(row.split(separator: ":").last ?? "") ?? 0
|
||||
if index < rows.count {
|
||||
cell.textLabel?.text = rows[index].0
|
||||
cell.detailTextLabel?.text = rows[index].1
|
||||
}
|
||||
return cell
|
||||
}
|
||||
applyTableSnapshot(animated: false)
|
||||
}
|
||||
|
||||
/// 构建 Diffable snapshot。
|
||||
private func buildTableSnapshot() -> NSDiffableDataSourceSnapshot<DepositDetailSection, DepositDetailRow> {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<DepositDetailSection, DepositDetailRow>()
|
||||
snapshot.appendSections([0])
|
||||
if viewModel.detail == nil {
|
||||
snapshot.appendItems([DepositDetailRowID.placeholder], toSection: 0)
|
||||
} else {
|
||||
snapshot.appendItems((0..<8).map { DepositDetailRowID.field($0) }, toSection: 0)
|
||||
}
|
||||
return snapshot
|
||||
}
|
||||
|
||||
/// 应用 snapshot 刷新列表。
|
||||
private func applyTableSnapshot(animated: Bool = true) {
|
||||
tableDataSource.apply(buildTableSnapshot(), animatingDifferences: animated)
|
||||
}
|
||||
|
||||
/// 加载Detail数据。
|
||||
private func loadDetail() async {
|
||||
await appServices.globalLoading.withLoading {
|
||||
await viewModel.load(
|
||||
@ -230,41 +371,13 @@ final class DepositOrderDetailViewController: UIViewController {
|
||||
orderNumber: orderNumber
|
||||
)
|
||||
}
|
||||
tableView.reloadData()
|
||||
applyTableSnapshot()
|
||||
if let message = viewModel.errorMessage { showToast(message) }
|
||||
}
|
||||
}
|
||||
|
||||
extension DepositOrderDetailViewController: UITableViewDataSource {
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
viewModel.detail == nil ? 1 : 8
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
|
||||
cell.selectionStyle = .none
|
||||
guard let detail = viewModel.detail else {
|
||||
cell.textLabel?.text = viewModel.errorMessage ?? (viewModel.loading ? "加载中..." : "暂无详情")
|
||||
return cell
|
||||
}
|
||||
let rows: [(String, String)] = [
|
||||
("订单号", detail.orderNumber),
|
||||
("状态", detail.orderStatusName),
|
||||
("类型", detail.orderTypeLabel),
|
||||
("付款金额", detail.actualPayAmount),
|
||||
("手机号", detail.phone),
|
||||
("项目", detail.projectName),
|
||||
("创建时间", detail.createdAt),
|
||||
("备注", detail.remark)
|
||||
]
|
||||
cell.textLabel?.text = rows[indexPath.row].0
|
||||
cell.detailTextLabel?.text = rows[indexPath.row].1
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
/// 押金拍摄信息页。
|
||||
final class DepositOrderShootingInfoViewController: UIViewController {
|
||||
final class DepositOrderShootingInfoViewController: UIViewController, UITableViewDelegate {
|
||||
|
||||
private let orderNumber: String
|
||||
private let scenicSpotId: Int
|
||||
@ -273,10 +386,14 @@ final class DepositOrderShootingInfoViewController: UIViewController {
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let table = UITableView(frame: .zero, style: .insetGrouped)
|
||||
table.dataSource = self
|
||||
table.delegate = self
|
||||
return table
|
||||
}()
|
||||
|
||||
/// Diffable 数据源,驱动拍摄摘要与素材列表刷新。
|
||||
private var tableDataSource: UITableViewDiffableDataSource<DepositShootingSection, DepositShootingRow>!
|
||||
|
||||
/// 初始化实例。
|
||||
init(orderNumber: String, scenicSpotId: Int, photogUid: Int) {
|
||||
self.orderNumber = orderNumber
|
||||
self.scenicSpotId = scenicSpotId
|
||||
@ -287,14 +404,75 @@ final class DepositOrderShootingInfoViewController: UIViewController {
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) { fatalError() }
|
||||
|
||||
/// 视图加载完成后的 UI 初始化与数据绑定。
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
title = "押金拍摄信息"
|
||||
configureTableDataSource()
|
||||
view.addSubview(tableView)
|
||||
tableView.snp.makeConstraints { make in make.edges.equalToSuperview() }
|
||||
Task { await loadDetail() }
|
||||
}
|
||||
|
||||
/// 配置 Diffable 数据源。
|
||||
private func configureTableDataSource() {
|
||||
tableDataSource = UITableViewDiffableDataSource<DepositShootingSection, DepositShootingRow>(
|
||||
tableView: tableView
|
||||
) { [weak self] (_: UITableView, indexPath: IndexPath, row: DepositShootingRow) -> UITableViewCell? in
|
||||
guard let self else { return UITableViewCell() }
|
||||
guard let detail = self.viewModel.detail else {
|
||||
let cell = UITableViewCell()
|
||||
cell.textLabel?.text = self.viewModel.errorMessage ?? "加载中..."
|
||||
return cell
|
||||
}
|
||||
if row == DepositShootingRowID.scenicSpot || row == DepositShootingRowID.rating {
|
||||
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
|
||||
if row == DepositShootingRowID.scenicSpot {
|
||||
cell.textLabel?.text = "打卡点"
|
||||
cell.detailTextLabel?.text = detail.scenicSpotName
|
||||
} else {
|
||||
cell.textLabel?.text = "拍摄评分"
|
||||
cell.detailTextLabel?.text = detail.orderComment.map { "\($0.starShooting) 星" } ?? "--"
|
||||
}
|
||||
return cell
|
||||
}
|
||||
let files: [OrderMediaFile]
|
||||
if row.hasPrefix("depositShooting:material:") {
|
||||
files = detail.materialList
|
||||
} else {
|
||||
files = detail.completeList
|
||||
}
|
||||
let index = Int(row.split(separator: ":").last ?? "") ?? 0
|
||||
let media = files[index]
|
||||
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
|
||||
cell.textLabel?.text = media.fileName
|
||||
cell.detailTextLabel?.text = media.fileUrl
|
||||
return cell
|
||||
}
|
||||
applyTableSnapshot(animated: false)
|
||||
}
|
||||
|
||||
/// 构建 Diffable snapshot。
|
||||
private func buildTableSnapshot() -> NSDiffableDataSourceSnapshot<DepositShootingSection, DepositShootingRow> {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<DepositShootingSection, DepositShootingRow>()
|
||||
guard let detail = viewModel.detail else {
|
||||
snapshot.appendSections([0])
|
||||
snapshot.appendItems([DepositShootingRowID.placeholder], toSection: 0)
|
||||
return snapshot
|
||||
}
|
||||
snapshot.appendSections([DepositShootingSectionID.summary, DepositShootingSectionID.material, DepositShootingSectionID.complete])
|
||||
snapshot.appendItems([DepositShootingRowID.scenicSpot, DepositShootingRowID.rating], toSection: DepositShootingSectionID.summary)
|
||||
snapshot.appendItems(detail.materialList.indices.map { DepositShootingRowID.material($0) }, toSection: DepositShootingSectionID.material)
|
||||
snapshot.appendItems(detail.completeList.indices.map { DepositShootingRowID.complete($0) }, toSection: DepositShootingSectionID.complete)
|
||||
return snapshot
|
||||
}
|
||||
|
||||
/// 应用 snapshot 刷新列表。
|
||||
private func applyTableSnapshot(animated: Bool = true) {
|
||||
tableDataSource.apply(buildTableSnapshot(), animatingDifferences: animated)
|
||||
}
|
||||
|
||||
/// 加载Detail数据。
|
||||
private func loadDetail() async {
|
||||
await appServices.globalLoading.withLoading {
|
||||
await viewModel.load(
|
||||
@ -305,56 +483,25 @@ final class DepositOrderShootingInfoViewController: UIViewController {
|
||||
photogUid: photogUid
|
||||
)
|
||||
}
|
||||
tableView.reloadData()
|
||||
applyTableSnapshot()
|
||||
if let message = viewModel.errorMessage { showToast(message) }
|
||||
}
|
||||
}
|
||||
|
||||
extension DepositOrderShootingInfoViewController: UITableViewDataSource {
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
viewModel.detail == nil ? 1 : 3
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
guard let detail = viewModel.detail else { return 1 }
|
||||
switch section {
|
||||
case 0: return 2
|
||||
case 1: return detail.materialList.count
|
||||
default: return detail.completeList.count
|
||||
}
|
||||
}
|
||||
|
||||
/// UITableView 代理:section 标题。
|
||||
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
guard viewModel.detail != nil else { return nil }
|
||||
switch section {
|
||||
case 1: return "素材"
|
||||
case 2: return "成片"
|
||||
guard viewModel.detail != nil,
|
||||
let sectionID = tableDataSource.snapshot().sectionIdentifiers[safe: section] else { return nil }
|
||||
switch sectionID {
|
||||
case DepositShootingSectionID.material: return "素材"
|
||||
case DepositShootingSectionID.complete: return "成片"
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let detail = viewModel.detail else {
|
||||
let cell = UITableViewCell()
|
||||
cell.textLabel?.text = viewModel.errorMessage ?? "加载中..."
|
||||
return cell
|
||||
}
|
||||
if indexPath.section == 0 {
|
||||
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
|
||||
if indexPath.row == 0 {
|
||||
cell.textLabel?.text = "打卡点"
|
||||
cell.detailTextLabel?.text = detail.scenicSpotName
|
||||
} else {
|
||||
cell.textLabel?.text = "拍摄评分"
|
||||
cell.detailTextLabel?.text = detail.orderComment.map { "\($0.starShooting) 星" } ?? "--"
|
||||
}
|
||||
return cell
|
||||
}
|
||||
let files = indexPath.section == 1 ? detail.materialList : detail.completeList
|
||||
let media = files[indexPath.row]
|
||||
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
|
||||
cell.textLabel?.text = media.fileName
|
||||
cell.detailTextLabel?.text = media.fileUrl
|
||||
return cell
|
||||
/// 安全下标,避免 section 越界。
|
||||
private extension Array {
|
||||
subscript(safe index: Int) -> Element? {
|
||||
indices.contains(index) ? self[index] : nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user