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

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

361 lines
15 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.

//
// ScenicPromotionMockStore.swift
// suixinkan
//
// Created by Codex on 2026/7/2.
//
import Foundation
/// Mock
enum ScenicPromotionMockStore {
/// Mock
static let mockBoard = ScenicPromotionBoard(
scenicName: "那拉提景区",
subtitle: "实时查看打卡点排队信息",
qrCodeTitle: "扫码查看排队导览",
spots: [
ScenicPromotionSpot(
id: "bridge",
name: "网红桥",
iconName: "bridge.2",
queue: ScenicPromotionQueueInfo(
waitingPeople: 54,
estimatedMinutes: 18,
averageMinutes: 16,
nextNumber: "B055",
currentNumber: "B054",
shootingDuration: "10分钟30秒"
),
videos: [
ScenicPromotionMedia(
id: "bridge_video_1",
mode: .video,
title: "网红桥",
subtitle: "雪山下的蓝色木桥,旅拍打卡热门点",
duration: "00:32",
palette: [0x1D8BFF, 0x8FD7FF, 0x2F8F45],
assetName: "ScenicPromotionThumbPortrait",
heroAssetName: "ScenicPromotionHero",
previewWidth: 72
),
ScenicPromotionMedia(
id: "bridge_video_2",
mode: .video,
title: "汉地拔冲",
subtitle: "雪山草甸与观景石同框",
duration: "00:28",
palette: [0x2A7BEF, 0xB7E5FF, 0x74B84A],
assetName: "ScenicPromotionThumbMarker",
heroAssetName: nil,
previewWidth: 144
),
ScenicPromotionMedia(
id: "bridge_video_3",
mode: .video,
title: "草甸旅拍",
subtitle: "绿色草坡上的打卡瞬间",
duration: "00:22",
palette: [0x2A7BEF, 0xB7E5FF, 0x74B84A],
assetName: "ScenicPromotionThumbGrass",
heroAssetName: nil,
previewWidth: 72
),
ScenicPromotionMedia(
id: "bridge_video_4",
mode: .video,
title: "骑马路线",
subtitle: "游客骑行与雪山远景",
duration: "00:24",
palette: [0x246BDF, 0x9BD9FF, 0x7EAC3D],
assetName: "ScenicPromotionThumbHorse",
heroAssetName: nil,
previewWidth: 72
)
],
photos: [
ScenicPromotionMedia(
id: "bridge_photo_1",
mode: .photo,
title: "桥边人像",
subtitle: "白裙、花束、雪山背景",
duration: nil,
palette: [0x1B7DFF, 0xA9E8FF, 0xF5D36C],
assetName: "ScenicPromotionThumbPortrait",
heroAssetName: nil,
previewWidth: 72
),
ScenicPromotionMedia(
id: "bridge_photo_2",
mode: .photo,
title: "全景草甸",
subtitle: "高山草甸与云层层次",
duration: nil,
palette: [0x3CA7FF, 0xC8F1FF, 0x4AAE57],
assetName: "ScenicPromotionThumbMarker",
heroAssetName: nil,
previewWidth: 144
),
ScenicPromotionMedia(
id: "bridge_photo_3",
mode: .photo,
title: "骑马路线",
subtitle: "游客骑行与雪山远景",
duration: nil,
palette: [0x246BDF, 0x9BD9FF, 0x7EAC3D],
assetName: "ScenicPromotionThumbHorse",
heroAssetName: nil,
previewWidth: 72
),
ScenicPromotionMedia(
id: "bridge_photo_4",
mode: .photo,
title: "草甸旅拍",
subtitle: "绿色草坡上的打卡瞬间",
duration: nil,
palette: [0x246BDF, 0x9BD9FF, 0x7EAC3D],
assetName: "ScenicPromotionThumbGrass",
heroAssetName: nil,
previewWidth: 72
)
]
),
ScenicPromotionSpot(
id: "hendi",
name: "汉地拔冲",
iconName: "mountain.2.fill",
queue: ScenicPromotionQueueInfo(
waitingPeople: 32,
estimatedMinutes: 12,
averageMinutes: 14,
nextNumber: "H036",
currentNumber: "H035",
shootingDuration: "8分钟20秒"
),
videos: [
ScenicPromotionMedia(
id: "hendi_video_1",
mode: .video,
title: "汉地拔冲",
subtitle: "雪山下的绿色画卷,旅拍打卡圣地",
duration: "00:32",
palette: [0x0B78F6, 0xB4E8FF, 0x4E9D3B],
assetName: "ScenicPromotionThumbMarker",
heroAssetName: "ScenicPromotionHero",
previewWidth: 144
)
],
photos: [
ScenicPromotionMedia(
id: "hendi_photo_1",
mode: .photo,
title: "雪山草原",
subtitle: "开阔草原与雪山远景",
duration: nil,
palette: [0x167CFF, 0xBDEBFF, 0x58B15D],
assetName: "ScenicPromotionThumbGrass",
heroAssetName: nil,
previewWidth: 72
),
ScenicPromotionMedia(
id: "hendi_photo_2",
mode: .photo,
title: "观景石",
subtitle: "点位标识与远山构图",
duration: nil,
palette: [0x1D6BD8, 0xA7DBFF, 0x769A5A],
assetName: "ScenicPromotionThumbMarker",
heroAssetName: nil,
previewWidth: 144
)
]
),
ScenicPromotionSpot(
id: "grassland",
name: "空中草原",
iconName: "leaf.fill",
queue: ScenicPromotionQueueInfo(
waitingPeople: 21,
estimatedMinutes: 9,
averageMinutes: 13,
nextNumber: "G022",
currentNumber: "G021",
shootingDuration: "7分钟40秒"
),
videos: [
ScenicPromotionMedia(
id: "grassland_video_1",
mode: .video,
title: "空中草原",
subtitle: "草甸花海与远山同框",
duration: "00:26",
palette: [0x2A7BEF, 0xB7E5FF, 0x74B84A],
assetName: "ScenicPromotionThumbGrass",
heroAssetName: nil,
previewWidth: 96
)
],
photos: [
ScenicPromotionMedia(
id: "grassland_photo_1",
mode: .photo,
title: "草原花海",
subtitle: "绿色草坡上的花海样片",
duration: nil,
palette: [0x3CA7FF, 0xC8F1FF, 0x4AAE57],
assetName: "ScenicPromotionThumbGrass",
heroAssetName: nil,
previewWidth: 96
)
]
),
ScenicPromotionSpot(
id: "valley",
name: "河谷花海",
iconName: "camera.macro",
queue: ScenicPromotionQueueInfo(
waitingPeople: 18,
estimatedMinutes: 8,
averageMinutes: 12,
nextNumber: "V019",
currentNumber: "V018",
shootingDuration: "6分钟50秒"
),
videos: [
ScenicPromotionMedia(
id: "valley_video_1",
mode: .video,
title: "河谷花海",
subtitle: "花海步道与雪山远景",
duration: "00:24",
palette: [0x1B7DFF, 0xA9E8FF, 0xF5D36C],
assetName: "ScenicPromotionThumbPortrait",
heroAssetName: nil,
previewWidth: 96
)
],
photos: [
ScenicPromotionMedia(
id: "valley_photo_1",
mode: .photo,
title: "花海人像",
subtitle: "花海前景与游客人像",
duration: nil,
palette: [0x1B7DFF, 0xA9E8FF, 0xF5D36C],
assetName: "ScenicPromotionThumbPortrait",
heroAssetName: nil,
previewWidth: 96
)
]
),
ScenicPromotionSpot(
id: "snowtrail",
name: "雪山栈道",
iconName: "snowflake",
queue: ScenicPromotionQueueInfo(
waitingPeople: 27,
estimatedMinutes: 11,
averageMinutes: 15,
nextNumber: "S028",
currentNumber: "S027",
shootingDuration: "9分钟10秒"
),
videos: [
ScenicPromotionMedia(
id: "snowtrail_video_1",
mode: .video,
title: "雪山栈道",
subtitle: "木栈道与雪山背景",
duration: "00:29",
palette: [0x246BDF, 0x9BD9FF, 0x7EAC3D],
assetName: "ScenicPromotionThumbHorse",
heroAssetName: nil,
previewWidth: 96
)
],
photos: [
ScenicPromotionMedia(
id: "snowtrail_photo_1",
mode: .photo,
title: "栈道远眺",
subtitle: "雪山、栈道、游客同框",
duration: nil,
palette: [0x246BDF, 0x9BD9FF, 0x7EAC3D],
assetName: "ScenicPromotionThumbHorse",
heroAssetName: nil,
previewWidth: 96
)
]
)
]
)
/// Mock
static let mockQueuePoints: [ScenicPromotionQueuePoint] = [
ScenicPromotionQueuePoint(id: "queue_bridge", name: "网红桥排队点", areaName: "那拉提景区"),
ScenicPromotionQueuePoint(id: "queue_hendi", name: "汉地拔冲排队点", areaName: "那拉提景区"),
ScenicPromotionQueuePoint(id: "queue_grass", name: "草甸旅拍排队点", areaName: "那拉提景区")
]
/// Mock
static let mockMaterialPoints: [ScenicPromotionMaterialPoint] = [
ScenicPromotionMaterialPoint(id: "material_bridge", name: "网红桥", areaName: "宣传素材点"),
ScenicPromotionMaterialPoint(id: "material_hendi", name: "汉地拔冲", areaName: "宣传素材点"),
ScenicPromotionMaterialPoint(id: "material_grass", name: "空中草原", areaName: "宣传素材点")
]
/// Mock
static let mockMaterialsByPointID: [String: [ScenicPromotionManagedMaterial]] = [
"material_bridge": [
ScenicPromotionManagedMaterial(
id: "material_bridge_video_1",
pointID: "material_bridge",
kind: .video,
title: "网红桥视频1",
subtitle: "雪山草甸旅拍视频",
assetName: "ScenicPromotionHero",
duration: "00:32",
createdAt: "2026-06-25 18:20"
),
ScenicPromotionManagedMaterial(
id: "material_bridge_image_1",
pointID: "material_bridge",
kind: .image,
title: "网红桥图片1",
subtitle: "游客桥边人像样片",
assetName: "ScenicPromotionThumbPortrait",
duration: nil,
createdAt: "2026-06-25 18:24"
)
],
"material_hendi": [
ScenicPromotionManagedMaterial(
id: "material_hendi_image_1",
pointID: "material_hendi",
kind: .image,
title: "汉地拔冲图片1",
subtitle: "观景石与雪山远景",
assetName: "ScenicPromotionThumbMarker",
duration: nil,
createdAt: "2026-06-25 18:30"
)
]
]
/// Mock
static func assetName(for kind: ScenicPromotionUploadKind, index: Int) -> String {
switch kind {
case .video:
return index.isMultiple(of: 2) ? "ScenicPromotionThumbMarker" : "ScenicPromotionHero"
case .image:
let assets = [
"ScenicPromotionThumbPortrait",
"ScenicPromotionThumbGrass",
"ScenicPromotionThumbHorse",
"ScenicPromotionThumbMarker"
]
return assets[(index - 1) % assets.count]
}
}
}