Files
suixinkan_ios_new/suixinkan/Features/ScenicPromotion/Models/ScenicPromotionModels.swift
汉秋 1b1e93b9ca 新增宣传页 Mock 模块并接入首页路由。
从 xh_test 同步 ScenicPromotion 演示页,补齐 MVVM 结构、本地资源、单元测试与模块文档,注册 promotion_page 首页入口。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 15:29:25 +08:00

216 lines
5.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.

//
// ScenicPromotionModels.swift
// suixinkan
//
// Created by Codex on 2026/7/2.
//
import Foundation
import SwiftUI
// MARK: -
///
enum ScenicPromotionPageState: Equatable {
case idle
case loading
case normal
case empty
case error(String)
}
// MARK: -
/// Loading / Empty / Error
enum ScenicPromotionDemoScenario: String, CaseIterable, Identifiable {
case normal
case noMedia
case noQueue
case loading
case error
case empty
var id: String { rawValue }
var title: String {
switch self {
case .normal: return "正常"
case .noMedia: return "无媒体"
case .noQueue: return "无排队"
case .loading: return "加载"
case .error: return "异常"
case .empty: return "空数据"
}
}
}
// MARK: -
/// /
enum ScenicPromotionMediaMode: String, CaseIterable, Identifiable {
case video
case photo
var id: String { rawValue }
var title: String {
switch self {
case .video: return "视频"
case .photo: return "照片"
}
}
var iconName: String {
switch self {
case .video: return "play.circle.fill"
case .photo: return "photo.fill"
}
}
}
// MARK: -
///
enum ScenicPromotionSettingsPageState: Equatable {
case idle
case loading
case normal
case empty
case error(String)
}
// MARK: -
///
enum ScenicPromotionSettingsDemoScenario: String, CaseIterable, Identifiable {
case normal
case loading
case empty
case error
var id: String { rawValue }
var title: String {
switch self {
case .normal: return "正常"
case .loading: return "加载"
case .empty: return "空数据"
case .error: return "异常"
}
}
}
// MARK: -
///
enum ScenicPromotionUploadKind: String, CaseIterable, Identifiable {
case video
case image
var id: String { rawValue }
var title: String {
switch self {
case .video: return "视频宣传素材"
case .image: return "图片素材"
}
}
var shortTitle: String {
switch self {
case .video: return "视频"
case .image: return "图片"
}
}
var uploadTitle: String {
switch self {
case .video: return "上传视频宣传素材"
case .image: return "上传图片素材"
}
}
var emptyTitle: String {
switch self {
case .video: return "暂无视频宣传素材"
case .image: return "暂无图片素材"
}
}
var iconName: String {
switch self {
case .video: return "video.fill"
case .image: return "photo.on.rectangle.angled"
}
}
}
// MARK: -
/// Mock
struct ScenicPromotionBoard: Equatable {
let scenicName: String
let subtitle: String
let qrCodeTitle: String
let spots: [ScenicPromotionSpot]
}
/// /
struct ScenicPromotionSpot: Identifiable, Equatable {
let id: String
let name: String
let iconName: String
let queue: ScenicPromotionQueueInfo?
let videos: [ScenicPromotionMedia]
let photos: [ScenicPromotionMedia]
}
///
struct ScenicPromotionQueueInfo: Equatable {
let waitingPeople: Int
let estimatedMinutes: Int
let averageMinutes: Int
let nextNumber: String
let currentNumber: String
let shootingDuration: String
}
///
struct ScenicPromotionMedia: Identifiable, Hashable {
let id: String
let mode: ScenicPromotionMediaMode
let title: String
let subtitle: String
let duration: String?
let palette: [UInt]
let assetName: String?
let heroAssetName: String?
let previewWidth: CGFloat
}
/// 使
struct ScenicPromotionQueuePoint: Identifiable, Hashable {
let id: String
let name: String
let areaName: String
}
/// /
struct ScenicPromotionMaterialPoint: Identifiable, Hashable {
let id: String
let name: String
let areaName: String
}
/// Mock
struct ScenicPromotionManagedMaterial: Identifiable, Hashable {
let id: String
let pointID: String
let kind: ScenicPromotionUploadKind
let title: String
let subtitle: String
let assetName: String
let duration: String?
let createdAt: String
}