对齐 Android 立即收款页面 UI,并补齐推送状态与语音开关。

统一收款详情布局、设置金额弹窗和收款记录样式,接入 type 6/1 推送驱动与轮询 fallback,使 iOS 收款反馈与 Android 一致。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-29 15:17:09 +08:00
parent 5bdf4a7dbf
commit 3dcfb99254
11 changed files with 924 additions and 228 deletions

View File

@ -124,6 +124,13 @@ final class PushNotificationManager: NSObject, UNUserNotificationCenterDelegate
}
private func route(from payload: PushPayload) {
if let type = payload.paymentEventType, type == 1 || type == 6 {
PaymentPushEventCenter.shared.post(type: type, dataJSON: payload.paymentEventData)
if type == 1 {
handlePaymentVoiceIfNeeded(payload: payload)
}
}
guard let router else { return }
switch payload.route {
@ -147,4 +154,15 @@ final class PushNotificationManager: NSObject, UNUserNotificationCenterDelegate
router.select(.home)
router.router(for: .home).navigate(to: .home(route))
}
///
private func handlePaymentVoiceIfNeeded(payload: PushPayload) {
let preferences = AppPreferencesStore()
guard preferences.loadPaymentReceiveVoiceEnabled(),
let amount = payload.paymentSuccessAmount,
!amount.isEmpty else {
return
}
PaymentVoiceSpeaker.shared.speak("收款到账\(amount)")
}
}

View File

@ -46,7 +46,7 @@ struct PushPayload: Sendable {
let actionText = values["action"] ?? ""
let merged = [typeText, routeText, uriText, actionText].joined(separator: " ").lowercased()
if typeText == "1" || merged.contains("payment") || merged.contains("pay") || merged.contains("收款") {
if typeText == "1" || typeText == "6" || merged.contains("payment") || merged.contains("pay") || merged.contains("收款") {
return .payment
}
if merged.contains("queue") || merged.contains("排队") || merged.contains("叫号") || uriText == "/scenic-queue" {
@ -64,6 +64,34 @@ struct PushPayload: Sendable {
return .messageCenter
}
/// extras type /
nonisolated var paymentEventType: Int? {
guard let typeText = values["type"], !typeText.isEmpty else { return nil }
return Int(typeText)
}
/// extras data JSON
nonisolated var paymentEventData: String? {
let data = values["data"]?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
return data.isEmpty ? nil : data
}
/// data JSON 使
nonisolated var paymentSuccessAmount: String? {
guard let dataJSON = paymentEventData,
let data = dataJSON.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
return nil
}
if let amount = json["order_amount"] as? String, !amount.isEmpty {
return amount
}
if let amount = json["order_amount"] as? NSNumber {
return amount.stringValue
}
return nil
}
nonisolated private static func mergeJSON(_ value: Any, into result: inout [String: String]) {
if let dict = value as? [String: Any] {
for (key, value) in dict {