Implement permission-driven home tab aligned with Android.

Load role-permission on first visit to drive menus, role-based layout, store card, and location reporting with account-scoped persistence and unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 17:27:54 +08:00
parent 75d0cb1f9a
commit 3b17b7f7f0
27 changed files with 2573 additions and 10 deletions

View File

@ -0,0 +1,85 @@
//
// ScenicSelectionViewController.swift
// suixinkan
//
import SnapKit
import UIKit
/// 使 role-permission
final class ScenicSelectionViewController: BaseViewController {
var onSelected: (() -> Void)?
private let scenicList: [ScenicInfo]
private let tableView = UITableView(frame: .zero, style: .insetGrouped)
init(scenicList: [ScenicInfo]) {
self.scenicList = scenicList
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setupNavigationBar() {
title = "选择景区"
navigationItem.leftBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .close,
target: self,
action: #selector(closeTapped)
)
}
override func setupUI() {
view.backgroundColor = UIColor(hex: 0xF7FAFF)
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
view.addSubview(tableView)
}
override func setupConstraints() {
tableView.snp.makeConstraints { make in
make.edges.equalTo(view.safeAreaLayoutGuide)
}
}
@objc private func closeTapped() {
dismiss(animated: true)
}
}
extension ScenicSelectionViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
scenicList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
var config = cell.defaultContentConfiguration()
config.text = scenicList[indexPath.row].name
cell.contentConfiguration = config
cell.accessoryType = scenicList[indexPath.row].id == AppStore.shared.currentScenicId ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let scenic = scenicList[indexPath.row]
AppStore.shared.currentScenicId = scenic.id
AppStore.shared.currentScenicName = scenic.name
NotificationCenter.default.post(
name: NotificationName.scenicDidChange,
object: nil,
userInfo: [
NotificationUserInfoKey.scenicId: scenic.id,
NotificationUserInfoKey.scenicName: scenic.name,
]
)
onSelected?()
dismiss(animated: true)
}
}