Files
suixinkan_uikit/suixinkan/Features/CooperationOrder/ViewModels/CooperationAcquirerViewModel.swift

213 lines
7.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// CooperationAcquirerViewModel.swift
// suixinkan
//
import Foundation
/// ViewModel Android `CooperationAcquirerViewModel`
final class CooperationAcquirerViewModel {
private(set) var acquirers: [CooperativeSalerEntity] = []
private(set) var isRefreshing = false
private(set) var remarkEditingAcquirer: CooperativeSalerEntity?
private(set) var remarkDraft = ""
private(set) var commissionEditingAcquirer: CooperativeSalerEntity?
private(set) var commissionRateDraft = ""
private(set) var commissionSmsCodeDraft = ""
private(set) var commissionSmsCountdown = 0
var onStateChange: (() -> Void)?
var onShowMessage: ((String) -> Void)?
var onNavigateBindAcquirer: ((Int) -> Void)?
private let appStore: AppStore
private var commissionSmsTimerTask: Task<Void, Never>?
init(appStore: AppStore = .shared) {
self.appStore = appStore
}
deinit {
commissionSmsTimerTask?.cancel()
}
func loadAcquirers(api: OrderAPI, initial: Bool = false) async {
let storeId = appStore.currentStoreId
let storeIdParam = storeId > 0 ? String(storeId) : nil
do {
let response = try await api.cooperativeSalers(storeId: storeIdParam, pageSize: "20")
acquirers = response.list
} catch {
onShowMessage?(error.localizedDescription)
}
isRefreshing = false
notifyStateChange()
}
func refresh(api: OrderAPI) async {
isRefreshing = true
notifyStateChange()
await loadAcquirers(api: api, initial: false)
}
func startEditRemark(_ acquirer: CooperativeSalerEntity) {
remarkEditingAcquirer = acquirer
remarkDraft = acquirer.photogRemarkName
notifyStateChange()
}
func updateRemarkDraft(_ text: String) {
remarkDraft = String(text.prefix(CooperationOrderFeature.remarkNameMaxLength))
notifyStateChange()
}
func dismissRemarkDialog() {
remarkEditingAcquirer = nil
remarkDraft = ""
notifyStateChange()
}
func saveRemark(api: OrderAPI) async {
guard let acquirer = remarkEditingAcquirer else { return }
let saleUserId = acquirer.saleUserId
guard saleUserId > 0 else { return }
let trimmedRemark = remarkDraft.trimmingCharacters(in: .whitespacesAndNewlines)
if let message = CooperationOrderFeature.remarkNameValidationMessage(remarkDraft) {
onShowMessage?(message)
return
}
dismissRemarkDialog()
do {
try await api.saleUserUpdateRemark(saleUserId: saleUserId, photogRemarkName: trimmedRemark)
acquirers = acquirers.map { item in
item.saleUserId == saleUserId ? item.withRemarkName(trimmedRemark) : item
}
onShowMessage?("备注已保存")
notifyStateChange()
} catch {
onShowMessage?(error.localizedDescription)
}
}
func startEditCommissionRate(_ acquirer: CooperativeSalerEntity) {
stopCommissionSmsTimer()
commissionEditingAcquirer = acquirer
commissionRateDraft = String(acquirer.commissionRate)
commissionSmsCodeDraft = ""
notifyStateChange()
}
func updateCommissionRateDraft(_ text: String) {
commissionRateDraft = String(text.filter(\.isNumber).prefix(3))
notifyStateChange()
}
func updateCommissionSmsCodeDraft(_ text: String) {
commissionSmsCodeDraft = String(text.filter(\.isNumber).prefix(6))
notifyStateChange()
}
func dismissCommissionRateDialog() {
commissionEditingAcquirer = nil
commissionRateDraft = ""
commissionSmsCodeDraft = ""
stopCommissionSmsTimer()
notifyStateChange()
}
func requestCommissionSmsCode(api: OrderAPI) async {
guard let acquirer = commissionEditingAcquirer else { return }
if commissionSmsCountdown > 0 {
onShowMessage?("请在倒计时结束后重新获取")
return
}
let phone = acquirer.salerPhone.isEmpty ? acquirer.displayPhone : acquirer.salerPhone
let trimmedPhone = phone.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmedPhone.isEmpty else {
onShowMessage?("获客员手机号为空")
return
}
do {
try await api.saleUserCommissionRateSendSmsCode(phone: trimmedPhone)
startCommissionSmsTimer()
onShowMessage?("验证码已发送")
} catch {
onShowMessage?(error.localizedDescription)
}
}
func saveCommissionRate(api: OrderAPI) async {
guard let acquirer = commissionEditingAcquirer else { return }
let saleUserId = acquirer.saleUserId
guard saleUserId > 0 else { return }
guard let commissionRate = Int(commissionRateDraft.trimmingCharacters(in: .whitespacesAndNewlines)) else {
onShowMessage?("请输入分成比例")
return
}
guard (0...100).contains(commissionRate) else {
onShowMessage?("分成比例需在0到100之间")
return
}
let smsCode = commissionSmsCodeDraft.trimmingCharacters(in: .whitespacesAndNewlines)
guard !smsCode.isEmpty else {
onShowMessage?("请输入验证码")
return
}
do {
let updated = try await api.saleUserUpdateCommissionRate(
saleUserId: saleUserId,
commissionRate: commissionRate,
smsCode: smsCode
)
dismissCommissionRateDialog()
if updated.saleUserId > 0 {
acquirers = acquirers.map { item in
item.saleUserId == updated.saleUserId ? updated : item
}
} else {
await loadAcquirers(api: api, initial: false)
}
onShowMessage?("分成比例已修改")
notifyStateChange()
} catch {
onShowMessage?(error.localizedDescription)
}
}
func processScanResult(_ scanResult: String) {
guard let saleUserId = SaleUserQrParser.parseSaleUserId(scanResult), saleUserId > 0 else {
onShowMessage?("请扫描正确的获客员二维码")
return
}
onNavigateBindAcquirer?(saleUserId)
}
private func startCommissionSmsTimer() {
commissionSmsTimerTask?.cancel()
commissionSmsTimerTask = Task { [weak self] in
guard let self else { return }
for second in stride(from: 60, through: 1, by: -1) {
if Task.isCancelled { return }
commissionSmsCountdown = second
notifyStateChange()
try? await Task.sleep(nanoseconds: 1_000_000_000)
}
if !Task.isCancelled {
commissionSmsCountdown = 0
notifyStateChange()
}
}
}
private func stopCommissionSmsTimer() {
commissionSmsTimerTask?.cancel()
commissionSmsTimerTask = nil
commissionSmsCountdown = 0
}
private func notifyStateChange() {
onStateChange?()
}
}