// // SettingsViewControllers.swift // suixinkan // import SnapKit import UIKit import WebKit // MARK: - Diffable 标识 /// 设置页行标识。 private enum SettingsRowID { static let about = "settings:about" static let version = "settings:version" static let download = "settings:download" static let userAgreement = "settings:userAgreement" static let privacyPolicy = "settings:privacyPolicy" } /// 设置页行操作类型。 private enum SettingsRowAction { case agreement(AgreementPage) case version case download } /// 设置中心页面。 final class SettingsViewController: SimpleTableDiffableViewController { private var copiedDownloadLink = false private let rowActions: [String: SettingsRowAction] = [ SettingsRowID.about: .agreement(.about), SettingsRowID.version: .version, SettingsRowID.download: .download, SettingsRowID.userAgreement: .agreement(.userAgreement), SettingsRowID.privacyPolicy: .agreement(.privacyPolicy) ] private let rowTitles: [String: String] = [ SettingsRowID.about: "关于我们", SettingsRowID.version: "系统版本", SettingsRowID.download: "App下载", SettingsRowID.userAgreement: "用户协议", SettingsRowID.privacyPolicy: "隐私政策" ] /// 视图加载完成后的 UI 初始化与数据绑定。 override func viewDidLoad() { super.viewDidLoad() title = "设置" } /// 构建 Diffable snapshot。 override func buildSnapshot() -> NSDiffableDataSourceSnapshot { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([0]) snapshot.appendItems([ SettingsRowID.about, SettingsRowID.version, SettingsRowID.download, SettingsRowID.userAgreement, SettingsRowID.privacyPolicy ], toSection: 0) return snapshot } /// section 页脚文案。 override func sectionFooter(for section: SimpleTableSection) -> String? { "Copyright © 2025 All Rights Reserved\n苏ICP备2025157647号" } /// 配置 Cell 展示内容。 override func configureCell(_ cell: UITableViewCell, row: SimpleTableRow, at indexPath: IndexPath) { cell.textLabel?.text = rowTitles[row] cell.textLabel?.textColor = UIColor(hex: 0x4B5563) cell.detailTextLabel?.text = nil cell.detailTextLabel?.textColor = nil cell.accessoryType = .none cell.selectionStyle = .default guard let action = rowActions[row] else { return } switch action { case .version: cell.detailTextLabel?.text = SettingsDisplayPolicy.versionText() cell.selectionStyle = .none case .download: cell.detailTextLabel?.text = copiedDownloadLink ? "已复制" : "复制链接" cell.detailTextLabel?.textColor = AppDesignUIKit.primary case .agreement: cell.accessoryType = .disclosureIndicator } } /// 处理行选中。 override func didSelectRow(_ row: SimpleTableRow, at indexPath: IndexPath) { guard let action = rowActions[row] else { return } switch action { case .agreement(let page): HomeMenuRouting.pushProfile(.agreement(page), from: self) case .download: copyDownloadLink() case .version: break } } private var downloadLink: String { APIEnvironment.current.baseURL.appending(path: "/h5/app/download").absoluteString } /// 复制下载链接并刷新对应行展示。 private func copyDownloadLink() { UIPasteboard.general.string = downloadLink copiedDownloadLink = true showToast("下载链接已复制") var snapshot = tableDataSource.snapshot() snapshot.reconfigureItems([SettingsRowID.download]) tableDataSource.apply(snapshot, animatingDifferences: false) DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { [weak self] in guard let self else { return } self.copiedDownloadLink = false var snapshot = self.tableDataSource.snapshot() snapshot.reconfigureItems([SettingsRowID.download]) self.tableDataSource.apply(snapshot, animatingDifferences: false) } } } /// 协议 H5 页面。 final class AgreementViewController: UIViewController { private let page: AgreementPage private let webView = WKWebView(frame: .zero) private let loadingIndicator = UIActivityIndicatorView(style: .large) /// 初始化实例。 init(page: AgreementPage) { self.page = page super.init(nibName: nil, bundle: nil) } @available(*, unavailable) required init?(coder: NSCoder) { fatalError() } /// 视图加载完成后的 UI 初始化与数据绑定。 override func viewDidLoad() { super.viewDidLoad() title = page.title view.backgroundColor = AppDesignUIKit.pageBackground webView.navigationDelegate = self view.addSubview(webView) view.addSubview(loadingIndicator) webView.snp.makeConstraints { make in make.edges.equalToSuperview() } loadingIndicator.snp.makeConstraints { make in make.center.equalToSuperview() } loadingIndicator.startAnimating() webView.load(URLRequest(url: page.url)) } } extension AgreementViewController: WKNavigationDelegate { /// web视图相关逻辑。 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { loadingIndicator.stopAnimating() } /// web视图相关逻辑。 func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { loadingIndicator.stopAnimating() showToast(error.localizedDescription) } }