新增 CooperationOrder 模块(双 Tab 列表、获客员绑定、主 Tab 扫码)、订单来源/带客单绑定及配套 API 测试;同步引入 roleCode 权限匹配与相关单元测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
3.2 KiB
Swift
90 lines
3.2 KiB
Swift
//
|
||
// CooperationAcquirerView.swift
|
||
// suixinkan
|
||
//
|
||
// Created by Codex on 2026/6/29.
|
||
//
|
||
|
||
import SwiftUI
|
||
|
||
/// 合作获客员列表页,支持查看已绑定获客员与扫码绑定。
|
||
struct CooperationAcquirerView: View {
|
||
@EnvironmentObject private var accountContext: AccountContext
|
||
@EnvironmentObject private var toastCenter: ToastCenter
|
||
@Environment(\.cooperationOrderAPI) private var cooperationOrderAPI
|
||
@Environment(\.globalLoading) private var globalLoading
|
||
@Environment(\.openURL) private var openURL
|
||
@StateObject private var viewModel = CooperationAcquirerViewModel()
|
||
@State private var showScanner = false
|
||
let onBind: (Int) -> Void
|
||
|
||
var body: some View {
|
||
ScrollView {
|
||
LazyVStack(spacing: 12) {
|
||
if viewModel.hasLoadedOnce && viewModel.acquirers.isEmpty {
|
||
Text("暂无合作获客员")
|
||
.font(.system(size: 14))
|
||
.foregroundStyle(CooperationOrderColors.text999)
|
||
.frame(maxWidth: .infinity)
|
||
.padding(.vertical, 48)
|
||
} else {
|
||
ForEach(viewModel.acquirers, id: \.displayId) { acquirer in
|
||
CooperativeSalerCard(acquirer: acquirer) { phone in
|
||
dialPhone(phone)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.padding(.horizontal, 14)
|
||
.padding(.vertical, 12)
|
||
}
|
||
.navigationTitle("合作获客员")
|
||
.navigationBarTitleDisplayMode(.inline)
|
||
.toolbar {
|
||
ToolbarItem(placement: .topBarTrailing) {
|
||
Button("扫码绑定") {
|
||
showScanner = true
|
||
}
|
||
.font(.system(size: 14))
|
||
.foregroundStyle(CooperationOrderColors.primary)
|
||
}
|
||
}
|
||
.background(CooperationOrderColors.pageBg.ignoresSafeArea())
|
||
.refreshable {
|
||
await reload(showLoading: false)
|
||
}
|
||
.fullScreenCover(isPresented: $showScanner) {
|
||
OrderScannerPage(
|
||
onClose: { showScanner = false },
|
||
onSuccess: { raw in
|
||
showScanner = false
|
||
if let saleUserId = SaleUserQrParser.parseSaleUserId(raw) {
|
||
onBind(saleUserId)
|
||
} else {
|
||
toastCenter.show("请扫描正确的获客员二维码")
|
||
}
|
||
},
|
||
onFailure: { error in
|
||
showScanner = false
|
||
toastCenter.show(error.localizedDescription)
|
||
}
|
||
)
|
||
}
|
||
.task {
|
||
await reload(showLoading: true)
|
||
}
|
||
}
|
||
|
||
private func reload(showLoading: Bool) async {
|
||
await globalLoading.withOptionalLoading(showLoading) {
|
||
await viewModel.reload(api: cooperationOrderAPI, storeId: accountContext.currentStore?.id)
|
||
}
|
||
}
|
||
|
||
private func dialPhone(_ phone: String) {
|
||
let trimmed = phone.trimmingCharacters(in: .whitespacesAndNewlines)
|
||
guard !trimmed.isEmpty, let url = URL(string: "tel:\(trimmed)") else { return }
|
||
openURL(url)
|
||
}
|
||
}
|