iOS 門店營收表格功能實現方案
核心功能需求
- 數據展示:表格形式展示門店/日期維度的營收數據
- 排序功能:支持按營收金額、增長率等排序
- 篩選功能:按日期范圍/門店/區域篩選
- 交互操作:點擊查看詳情、數據刷新
- 數據可視化:關鍵指標圖表展示
技術實現方案(UIKit)
1. 數據模型設計
struct StoreRevenue {let storeId: Stringlet storeName: Stringlet region: Stringvar dailyRevenue: [Date: Double] // 日期-營收鍵值對var totalRevenue: Double { dailyRevenue.values.reduce(0, +) }
}// 日期范圍結構體
struct DateRange {let startDate: Datelet endDate: Date
}
2. 表格視圖實現(UITableView)
class RevenueViewController: UIViewController {private let tableView = UITableView()private var revenues: [StoreRevenue] = []private var filteredRevenues: [StoreRevenue] = []override func viewDidLoad() {super.viewDidLoad()setupTableView()loadData()}private func setupTableView() {tableView.delegate = selftableView.dataSource = selftableView.register(RevenueCell.self, forCellReuseIdentifier: "RevenueCell")// 添加下拉刷新tableView.refreshControl = UIRefreshControl()tableView.refreshControl?.addTarget(self, action: #selector(refreshData), for: .valueChanged)}@objc private func refreshData() {// 實現數據刷新邏輯}
}
3. 自定義表格單元格
class RevenueCell: UITableViewCell {static let identifier = "RevenueCell"private let nameLabel = UILabel()private let revenueLabel = UILabel()private let trendIndicator = UIImageView()override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {super.init(style: style, reuseIdentifier: reuseIdentifier)setupViews()}private func setupViews() {// 布局代碼contentView.addSubview(nameLabel)contentView.addSubview(revenueLabel)contentView.addSubview(trendIndicator)// 自動布局約束...}func configure(with revenue: StoreRevenue) {nameLabel.text = revenue.storeNamerevenueLabel.text = formatCurrency(revenue.totalRevenue)trendIndicator.image = revenue.growthRate >= 0 ? UIImage(systemName: "arrow.up") : UIImage(systemName: "arrow.down")}private func formatCurrency(_ amount: Double) -> String {let formatter = NumberFormatter()formatter.numberStyle = .currencyreturn formatter.string(from: NSNumber(value: amount)) ?? ""}
}
4. 篩選控制器實現
class FilterViewController: UIViewController {var onFilterApplied: ((DateRange, String?) -> Void)?private let datePicker = UIDatePicker()private let regionPicker = UIPickerView()private let regions = ["All", "North", "South", "East", "West"]override func viewDidLoad() {super.viewDidLoad()setupFilterUI()}private func setupFilterUI() {// 日期范圍選擇器datePicker.datePickerMode = .datedatePicker.preferredDatePickerStyle = .compact// 區域選擇器regionPicker.delegate = selfregionPicker.dataSource = self// 應用按鈕let applyButton = UIButton(type: .system)applyButton.setTitle("Apply Filters", for: .normal)applyButton.addTarget(self, action: #selector(applyFilters), for: .touchUpInside)// 添加視圖和約束...}@objc private func applyFilters() {let selectedRegion = regions[regionPicker.selectedRow(inComponent: 0)]let dateRange = DateRange(startDate: ..., endDate: ...)onFilterApplied?(dateRange, selectedRegion == "All" ? nil : selectedRegion)dismiss(animated: true)}
}
5. 排序功能實現
extension RevenueViewController {enum SortOption {case nameAscending, nameDescendingcase revenueAscending, revenueDescendingcase growthRateAscending, growthRateDescending}func sortData(by option: SortOption) {filteredRevenues.sort {switch option {case .nameAscending: return $0.storeName < $1.storeNamecase .nameDescending: return $0.storeName > $1.storeNamecase .revenueAscending: return $0.totalRevenue < $1.totalRevenuecase .revenueDescending: return $0.totalRevenue > $1.totalRevenuecase .growthRateAscending: return $0.growthRate < $1.growthRatecase .growthRateDescending: return $0.growthRate > $1.growthRate}}tableView.reloadData()}
}
6. 數據可視化(使用Charts框架)
import Chartsclass RevenueChartView: UIView {private let barChart = BarChartView()func configure(with revenues: [StoreRevenue]) {var entries = [BarChartDataEntry]()for (index, revenue) in revenues.enumerated() {let entry = BarChartDataEntry(x: Double(index),y: revenue.totalRevenue)entries.append(entry)}let dataSet = BarChartDataSet(entries: entries, label: "門店營收")dataSet.colors = [.systemBlue]let data = BarChartData(dataSet: dataSet)barChart.data = data// 配置圖表樣式barChart.xAxis.valueFormatter = IndexAxisValueFormatter(values: revenues.map { $0.storeName })barChart.xAxis.granularity = 1barChart.leftAxis.axisMinimum = 0barChart.animate(yAxisDuration: 1.0)}
}
7. 性能優化策略
- 數據分頁加載:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {if indexPath.row == filteredRevenues.count - 2 {loadMoreData()}
}
- 圖片/圖標緩存:
let imageCache = NSCache<NSString, UIImage>()func loadStoreImage(for storeId: String) {if let cachedImage = imageCache.object(forKey: storeId as NSString) {// 使用緩存圖片return}// 異步加載網絡圖片DispatchQueue.global().async {if let image = // 下載圖片 {imageCache.setObject(image, forKey: storeId as NSString)DispatchQueue.main.async {// 更新UI}}}
}
- 后臺數據處理:
DispatchQueue.global(qos: .userInitiated).async {let processedData = self.processRawData(rawData)DispatchQueue.main.async {self.revenues = processedDataself.tableView.reloadData()}
}
關鍵注意事項
-
數據安全:
- 使用HTTPS傳輸敏感營收數據
- 本地緩存加密(使用Keychain存儲認證token)
-
空狀態處理:
func showEmptyState() {let emptyView = EmptyStateView()emptyView.configure(title: "無營收數據",message: "當前篩選條件下沒有找到門店營收記錄",image: UIImage(named: "empty-revenue"))tableView.backgroundView = emptyView }
-
國際化支持:
- 使用NSLocalizedString處理多語言
- 動態適配貨幣符號和數字格式
-
無障礙訪問:
revenueLabel.accessibilityLabel = "總營收: \(formatCurrency(revenue.totalRevenue))" revenueLabel.accessibilityTraits = .staticText
-
深色模式適配:
- 使用系統顏色(.label, .systemBackground)
- 提供深色模式下的圖表配色方案
擴展功能建議
-
數據導出:
- 支持導出CSV/PDF格式報表
- 使用UIActivityViewController實現分享功能
-
實時更新:
// 使用WebSocket接收實時數據更新 socket.on("revenue_update") { [weak self] data inself?.handleRevenueUpdate(data) }
-
多維度分析:
- 添加切換視圖:日/周/月視圖
- 同比/環比分析功能
-
異常檢測:
func detectAnomalies() {// 使用機器學習框架檢測異常波動CoreMLHelper.detectAnomalies(in: revenues) }
-
離線模式:
- 使用CoreData緩存數據
- 實現本地數據修改同步隊列
此實現方案提供了高性能的表格展示、靈活的數據操作和良好的用戶體驗,可根據實際業務需求調整具體實現細節。建議結合AutoLayout實現響應式布局,確保在各種設備尺寸上正常顯示。