迁移合作订单完整能力,并统一 AppRoleCode 角色权限与首页菜单展示。

新增 CooperationOrder 模块(双 Tab 列表、获客员绑定、主 Tab 扫码)、订单来源/带客单绑定及配套 API 测试;同步引入 roleCode 权限匹配与相关单元测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-29 13:33:00 +08:00
parent d310d26293
commit 1970572edd
66 changed files with 4247 additions and 201 deletions

View File

@ -157,6 +157,17 @@ struct V9AuthResponse: Decodable, Equatable {
}
}
/// app_role_code
var currentAccountRoleCode: String? {
if let storeUser = storeUsers.first(where: \.isCurrent) ?? storeUsers.first {
return nonEmpty(storeUser.resolvedAppRoleCode)
}
if let scenicUser = scenicUsers.first(where: \.isCurrent) ?? scenicUsers.first {
return nonEmpty(scenicUser.resolvedAppRoleCode)
}
return nil
}
/// v9 JSON
enum CodingKeys: String, CodingKey {
case token
@ -178,6 +189,11 @@ struct V9AuthResponse: Decodable, Equatable {
scenicUsers = (try? container.decodeIfPresent([V9ScenicUser].self, forKey: .scenicUsers)) ?? []
storeUsers = (try? container.decodeIfPresent([V9StoreUser].self, forKey: .storeUsers)) ?? []
}
private func nonEmpty(_ value: String) -> String? {
let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
return text.isEmpty ? nil : text
}
}
/// v9
@ -196,6 +212,13 @@ struct V9ScenicUser: Decodable, Equatable {
let scenicId: Int
let scenicName: String
let isCurrent: Bool
let appRoleCode: String
let appRoleName: String
/// app_role_code
var resolvedAppRoleCode: String {
appRoleCode.trimmingCharacters(in: .whitespacesAndNewlines)
}
/// set-user 使 ID
var businessUserId: Int {
@ -240,6 +263,8 @@ struct V9ScenicUser: Decodable, Equatable {
case scenicId = "scenic_id"
case scenicName = "scenic_name"
case isCurrent = "is_current"
case appRoleCode = "app_role_code"
case appRoleName = "app_role_name"
}
/// ID
@ -257,6 +282,8 @@ struct V9ScenicUser: Decodable, Equatable {
scenicId = try container.decodeLossyInt(forKey: .scenicId) ?? 0
scenicName = try container.decodeLossyString(forKey: .scenicName)
isCurrent = try container.decodeLossyBool(forKey: .isCurrent) ?? false
appRoleCode = try container.decodeLossyString(forKey: .appRoleCode)
appRoleName = try container.decodeLossyString(forKey: .appRoleName)
}
}
@ -278,6 +305,13 @@ struct V9StoreUser: Decodable, Equatable {
let storeId: Int
let storeName: String
let isCurrent: Bool
let appRoleCode: String
let appRoleName: String
/// app_role_code
var resolvedAppRoleCode: String {
appRoleCode.trimmingCharacters(in: .whitespacesAndNewlines)
}
/// set-user 使 ID
var businessUserId: Int {
@ -324,6 +358,8 @@ struct V9StoreUser: Decodable, Equatable {
case storeId = "store_id"
case storeName = "store_name"
case isCurrent = "is_current"
case appRoleCode = "app_role_code"
case appRoleName = "app_role_name"
}
/// ID
@ -343,6 +379,8 @@ struct V9StoreUser: Decodable, Equatable {
storeId = try container.decodeLossyInt(forKey: .storeId) ?? 0
storeName = try container.decodeLossyString(forKey: .storeName)
isCurrent = try container.decodeLossyBool(forKey: .isCurrent) ?? false
appRoleCode = try container.decodeLossyString(forKey: .appRoleCode)
appRoleName = try container.decodeLossyString(forKey: .appRoleName)
}
}