实现权限驱动的首页 Tab 并对齐 Android
This commit is contained in:
28
suixinkan/Features/Home/Models/HomeMenuItem.swift
Normal file
28
suixinkan/Features/Home/Models/HomeMenuItem.swift
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// HomeMenuItem.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 首页菜单展示项,由服务端权限 URI 与本地 catalog 合并而成。
|
||||
struct HomeMenuItem: Equatable, Hashable, Sendable {
|
||||
let uri: String
|
||||
let title: String
|
||||
let iconName: String
|
||||
let serverName: String
|
||||
|
||||
init(uri: String, title: String, iconName: String, serverName: String = "") {
|
||||
self.uri = uri
|
||||
self.title = title
|
||||
self.iconName = iconName
|
||||
self.serverName = serverName
|
||||
}
|
||||
|
||||
/// 固定的「更多功能」入口。
|
||||
static let moreFunctions = HomeMenuItem(
|
||||
uri: "more_functions",
|
||||
title: "更多功能",
|
||||
iconName: "square.grid.2x2"
|
||||
)
|
||||
}
|
||||
38
suixinkan/Features/Home/Models/LocationModels.swift
Normal file
38
suixinkan/Features/Home/Models/LocationModels.swift
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// LocationModels.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 位置上报详情,对齐 Android `LocationDetailResponse`。
|
||||
struct LocationDetailResponse: Decodable, Sendable {
|
||||
let status: Int
|
||||
let needReport: Bool
|
||||
let expireTime: Int64
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case status
|
||||
case needReport = "need_report"
|
||||
case expireTime = "expire_time"
|
||||
}
|
||||
|
||||
init(status: Int = 0, needReport: Bool = true, expireTime: Int64 = 0) {
|
||||
self.status = status
|
||||
self.needReport = needReport
|
||||
self.expireTime = expireTime
|
||||
}
|
||||
}
|
||||
|
||||
/// 位置上报结果,对齐 Android `LocationReportResponse`。
|
||||
struct LocationReportResponse: Decodable, Sendable {
|
||||
let staffId: String
|
||||
let expired: Int64
|
||||
let status: Int
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case staffId = "staff_id"
|
||||
case expired
|
||||
case status
|
||||
}
|
||||
}
|
||||
143
suixinkan/Features/Home/Models/RolePermissionModels.swift
Normal file
143
suixinkan/Features/Home/Models/RolePermissionModels.swift
Normal file
@ -0,0 +1,143 @@
|
||||
//
|
||||
// RolePermissionModels.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 角色权限接口根节点,对齐 Android `RolePermissionResponse`。
|
||||
struct RolePermissionResponse: Codable, Equatable, Sendable {
|
||||
let role: RoleInfo
|
||||
let scenic: [ScenicInfo]
|
||||
|
||||
init(role: RoleInfo, scenic: [ScenicInfo] = []) {
|
||||
self.role = role
|
||||
self.scenic = scenic
|
||||
}
|
||||
}
|
||||
|
||||
/// 角色信息与顶层权限列表。
|
||||
struct RoleInfo: Codable, Equatable, Sendable {
|
||||
let id: Int
|
||||
let name: String
|
||||
let roleCode: String
|
||||
let notes: String?
|
||||
let permission: [PermissionItem]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case name
|
||||
case roleCode = "role_code"
|
||||
case notes
|
||||
case permission
|
||||
}
|
||||
|
||||
init(
|
||||
id: Int = 0,
|
||||
name: String = "",
|
||||
roleCode: String = "",
|
||||
notes: String? = nil,
|
||||
permission: [PermissionItem] = []
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.roleCode = roleCode
|
||||
self.notes = notes
|
||||
self.permission = permission
|
||||
}
|
||||
}
|
||||
|
||||
/// 权限树节点。
|
||||
struct PermissionItem: Codable, Equatable, Sendable {
|
||||
let id: Int
|
||||
let pid: Int
|
||||
let name: String
|
||||
let uri: String
|
||||
let iconSrc: String?
|
||||
let children: [PermissionItem]?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case pid
|
||||
case name
|
||||
case uri
|
||||
case iconSrc = "icon_src"
|
||||
case children
|
||||
}
|
||||
|
||||
init(
|
||||
id: Int = 0,
|
||||
pid: Int = 0,
|
||||
name: String = "",
|
||||
uri: String = "",
|
||||
iconSrc: String? = nil,
|
||||
children: [PermissionItem]? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.pid = pid
|
||||
self.name = name
|
||||
self.uri = uri
|
||||
self.iconSrc = iconSrc
|
||||
self.children = children
|
||||
}
|
||||
}
|
||||
|
||||
/// 角色绑定的景区信息。
|
||||
struct ScenicInfo: Codable, Equatable, Sendable, Hashable {
|
||||
let id: Int
|
||||
let name: String
|
||||
let status: Int
|
||||
let location: ScenicLocationInfo?
|
||||
let coverImg: String?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case name
|
||||
case status
|
||||
case location
|
||||
case coverImg = "cover_img"
|
||||
}
|
||||
|
||||
init(
|
||||
id: Int = 0,
|
||||
name: String = "",
|
||||
status: Int = 0,
|
||||
location: ScenicLocationInfo? = nil,
|
||||
coverImg: String? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.status = status
|
||||
self.location = location
|
||||
self.coverImg = coverImg
|
||||
}
|
||||
}
|
||||
|
||||
/// 景区位置信息。
|
||||
struct ScenicLocationInfo: Codable, Equatable, Sendable, Hashable {
|
||||
let lng: Double
|
||||
let lat: Double
|
||||
let address: String
|
||||
}
|
||||
|
||||
/// 扁平化后的权限项,供首页菜单与本地缓存使用。
|
||||
struct HomePermissionItem: Codable, Equatable, Sendable, Hashable {
|
||||
let id: String
|
||||
let name: String
|
||||
let uri: String
|
||||
let pid: Int
|
||||
|
||||
init(id: String, name: String, uri: String, pid: Int = 0) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.uri = uri
|
||||
self.pid = pid
|
||||
}
|
||||
|
||||
init(from item: PermissionItem) {
|
||||
self.id = String(item.id)
|
||||
self.name = item.name
|
||||
self.uri = item.uri
|
||||
self.pid = item.pid
|
||||
}
|
||||
}
|
||||
52
suixinkan/Features/Home/Models/StoreModels.swift
Normal file
52
suixinkan/Features/Home/Models/StoreModels.swift
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// StoreModels.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 门店列表项,对齐 Android `StoreItem`。
|
||||
struct StoreItem: Codable, Equatable, Sendable {
|
||||
let id: Int
|
||||
let scenicId: Int
|
||||
let name: String
|
||||
let address: String
|
||||
let status: Int
|
||||
let statusText: String
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case scenicId = "scenic_id"
|
||||
case name
|
||||
case address
|
||||
case status
|
||||
case statusText = "status_text"
|
||||
}
|
||||
|
||||
init(
|
||||
id: Int = 0,
|
||||
scenicId: Int = 0,
|
||||
name: String = "",
|
||||
address: String = "",
|
||||
status: Int = 0,
|
||||
statusText: String = ""
|
||||
) {
|
||||
self.id = id
|
||||
self.scenicId = scenicId
|
||||
self.name = name
|
||||
self.address = address
|
||||
self.status = status
|
||||
self.statusText = statusText
|
||||
}
|
||||
}
|
||||
|
||||
/// 门店列表响应,对齐 Android `ListResponse<StoreItem>`。
|
||||
struct StoreListResponse: Codable, Sendable {
|
||||
let total: Int
|
||||
let list: [StoreItem]
|
||||
|
||||
init(total: Int = 0, list: [StoreItem] = []) {
|
||||
self.total = total
|
||||
self.list = list
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user