将定金订单、历史拍摄与多行程上传接入 Orders,并以真实页面替换首页排队管理、消息中心、景区结算与提现审核占位入口。 Co-authored-by: Cursor <cursoragent@cursor.com>
74 lines
2.7 KiB
Swift
74 lines
2.7 KiB
Swift
//
|
||
// ScenicQueueAnnouncementState.swift
|
||
// suixinkan
|
||
//
|
||
// Created by Codex on 2026/6/25.
|
||
//
|
||
|
||
import Foundation
|
||
|
||
/// 排队语音播报内容。
|
||
struct ScenicQueueAnnouncement: Equatable {
|
||
enum Kind: Equatable {
|
||
case newTickets(count: Int)
|
||
case calledTicket(id: Int64)
|
||
}
|
||
|
||
let kind: Kind
|
||
let text: String
|
||
}
|
||
|
||
/// 排队播报去重状态,避免同一批队列反复播报。
|
||
struct ScenicQueueAnnouncementState {
|
||
private var knownTicketIds = Set<Int64>()
|
||
private var calledTicketIds = Set<Int64>()
|
||
|
||
/// 根据最新统计和列表计算下一条需要播报的内容。
|
||
mutating func nextAnnouncement(
|
||
stats: ScenicQueueStatsData,
|
||
tickets: [ScenicQueueTicket],
|
||
customCallText: String?
|
||
) -> ScenicQueueAnnouncement? {
|
||
let currentIds = Set(tickets.map(\.id))
|
||
let newTickets = tickets.filter { !knownTicketIds.contains($0.id) }
|
||
knownTicketIds = currentIds
|
||
|
||
if let ticket = tickets.first(where: { ($0.isCalled == 1 || $0.statusText.contains("已叫号")) && !calledTicketIds.contains($0.id) }) {
|
||
calledTicketIds.insert(ticket.id)
|
||
return ScenicQueueAnnouncement(kind: .calledTicket(id: ticket.id), text: Self.callText(for: ticket, customText: customCallText))
|
||
}
|
||
|
||
guard !newTickets.isEmpty else { return nil }
|
||
let text = "排队提醒,当前新增\(newTickets.count)位游客,在排人数\(stats.queueCount)人。"
|
||
return ScenicQueueAnnouncement(kind: .newTickets(count: newTickets.count), text: text)
|
||
}
|
||
|
||
/// 重置播报去重状态。
|
||
mutating func reset() {
|
||
knownTicketIds.removeAll()
|
||
calledTicketIds.removeAll()
|
||
}
|
||
|
||
/// 生成叫号播报文案。
|
||
static func callText(for ticket: ScenicQueueTicket, customText: String?) -> String {
|
||
callText(forQueueCode: ticket.queueCode, customText: customText)
|
||
}
|
||
|
||
/// 生成叫号播报文案。
|
||
static func callText(forQueueCode queueCode: String, customText: String?) -> String {
|
||
let custom = customText?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||
if !custom.isEmpty, custom != "A0001" {
|
||
return custom.replacingOccurrences(of: "{number}", with: queueCode)
|
||
}
|
||
let code = queueCode.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? "当前游客" : ttsLabel(for: queueCode)
|
||
return "请\(code)到拍摄点拍摄。"
|
||
}
|
||
|
||
/// 将排队号拆成更适合语音播报的文本。
|
||
static func ttsLabel(for queueCode: String) -> String {
|
||
let trimmed = queueCode.trimmingCharacters(in: .whitespacesAndNewlines)
|
||
guard !trimmed.isEmpty else { return "当前游客" }
|
||
return trimmed.map(String.init).joined(separator: " ")
|
||
}
|
||
}
|