feat: 品牌化那拉提景区收款页

This commit is contained in:
2026-07-23 15:39:34 +08:00
parent 74f7370aab
commit 787a166263
13 changed files with 840 additions and 31 deletions

View File

@ -17,6 +17,9 @@ final class PaymentCollectionDetailsViewModel {
private(set) var showAmountDialog = false
private(set) var amount = ""
private(set) var remark = ""
private(set) var scenicId = 0
private(set) var payPageConfig = PayPageConfig.nalatiDefault
private(set) var brandingRefreshVersion = 0
let merchantInfo = PaymentMerchantInfo.defaultInfo
@ -26,9 +29,21 @@ final class PaymentCollectionDetailsViewModel {
private var staticPayURL = ""
private var dynamicPayURL = ""
private let appStore: AppStore
private let payPageConfigCache: PayPageConfigCaching
init(appStore: AppStore = .shared) {
init(
appStore: AppStore = .shared,
payPageConfigCache: PayPageConfigCaching = PayPageConfigCache()
) {
self.appStore = appStore
self.payPageConfigCache = payPageConfigCache
scenicId = appStore.session.currentScenicId
scenicName = appStore.session.currentScenicName
staffId = appStore.session.userId
isVoiceBroadcastOpen = appStore.payment.isOpenReceiveVoice
if PayPageBrandingPolicy.isNalati(scenicId: scenicId) {
payPageConfig = payPageConfigCache.config(scenicId: scenicId) ?? .nalatiDefault
}
}
var hasPayCode: Bool {
@ -39,10 +54,32 @@ final class PaymentCollectionDetailsViewModel {
scenicName.isEmpty ? "暂无景区" : scenicName
}
var usesNalatiBranding: Bool {
PayPageBrandingPolicy.isNalati(scenicId: scenicId)
}
var displayPhotographerName: String {
PaymentAccountDisplayFormatter.photographerName(
userName: appStore.session.userName,
realName: appStore.session.realName
)
}
var displayStoreNames: String {
let names = appStore.permissions.rolePermissionList().flatMap(\.store).map(\.name)
return PaymentAccountDisplayFormatter.storeNames(names)
}
func refreshLocalState() {
scenicId = appStore.session.currentScenicId
scenicName = appStore.session.currentScenicName
staffId = appStore.session.userId
isVoiceBroadcastOpen = appStore.payment.isOpenReceiveVoice
if usesNalatiBranding {
payPageConfig = payPageConfigCache.config(scenicId: scenicId) ?? .nalatiDefault
} else {
payPageConfig = .nalatiDefault
}
notifyStateChange()
}
@ -56,7 +93,7 @@ final class PaymentCollectionDetailsViewModel {
notifyStateChange()
}
let scenicId = appStore.session.currentScenicId
let scenicId = self.scenicId
guard scenicId > 0 else {
clearPayCode()
return
@ -72,8 +109,27 @@ final class PaymentCollectionDetailsViewModel {
}
}
func loadPayPageConfig(api: PaymentAPI) async {
let requestedScenicId = appStore.session.currentScenicId
guard PayPageBrandingPolicy.isNalati(scenicId: requestedScenicId) else { return }
do {
let response = try await api.payPageConfig(scenicId: requestedScenicId)
guard appStore.session.currentScenicId == requestedScenicId else { return }
let resolved = payPageConfig.merging(response)
payPageConfigCache.save(resolved, scenicId: requestedScenicId)
payPageConfig = resolved
brandingRefreshVersion += 1
notifyStateChange()
} catch {
//
}
}
func refresh(api: PaymentAPI) async {
await loadPayCode(api: api)
async let payCode: Void = loadPayCode(api: api)
async let pageConfig: Void = loadPayPageConfig(api: api)
_ = await (payCode, pageConfig)
}
func showSetAmountDialog() {