拆分宣传页视图并扩充 Mock 数据,合作订单支持获客员备注名并修复线索图片网格尺寸。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -0,0 +1,113 @@
|
||||
//
|
||||
// ScenicPromotionSettingsView.swift
|
||||
// suixinkan
|
||||
//
|
||||
// Created by Codex on 2026/7/2.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// 宣传页设置视图,管理排队绑定、素材点与 Mock 上传。
|
||||
struct ScenicPromotionSettingsView: View {
|
||||
@StateObject private var viewModel = ScenicPromotionSettingsViewModel()
|
||||
@State private var showSelectMaterialPointAlert = false
|
||||
@State private var showSubmitAlert = false
|
||||
@State private var submitMessage = ""
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
AppDesign.background.ignoresSafeArea()
|
||||
|
||||
Group {
|
||||
switch viewModel.pageState {
|
||||
case .idle, .loading:
|
||||
ScenicPromotionSettingsLoadingView()
|
||||
.transition(.opacity.combined(with: .scale(scale: 0.98)))
|
||||
case .empty:
|
||||
ScenicPromotionSettingsFullStateView(
|
||||
icon: "tray",
|
||||
title: "暂无设置数据",
|
||||
message: "当前没有可配置的排队打卡点和素材打卡点",
|
||||
buttonTitle: "重新加载"
|
||||
) {
|
||||
Task { await viewModel.load() }
|
||||
}
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
case .error(let message):
|
||||
ScenicPromotionSettingsFullStateView(
|
||||
icon: "wifi.exclamationmark",
|
||||
title: "加载失败",
|
||||
message: message,
|
||||
buttonTitle: "重试"
|
||||
) {
|
||||
Task { await viewModel.load() }
|
||||
}
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
case .normal:
|
||||
ScenicPromotionSettingsContentView(
|
||||
viewModel: viewModel,
|
||||
onUploadFailed: { showSelectMaterialPointAlert = true }
|
||||
)
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
}
|
||||
}
|
||||
.animation(.easeInOut(duration: 0.24), value: viewModel.pageState)
|
||||
}
|
||||
.navigationTitle("宣传页设置")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.appNavigationDestination(item: $viewModel.previewMaterial) { material in
|
||||
ScenicPromotionMaterialPreviewView(material: material)
|
||||
}
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
if case .normal = viewModel.pageState {
|
||||
ScenicPromotionSettingsSubmitBarView(onSubmit: handleSubmit)
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Menu {
|
||||
ForEach(ScenicPromotionSettingsDemoScenario.allCases) { scenario in
|
||||
Button(scenario.title) {
|
||||
viewModel.applyScenario(scenario)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
.font(.system(size: 18, weight: .semibold))
|
||||
}
|
||||
.accessibilityLabel("设置页演示状态")
|
||||
}
|
||||
}
|
||||
.alert("请选择素材打卡点", isPresented: $showSelectMaterialPointAlert) {
|
||||
Button("知道了", role: .cancel) {}
|
||||
} message: {
|
||||
Text("视频宣传素材和图片素材上传前,需要先选择素材所属打卡点。")
|
||||
}
|
||||
.alert("提交结果", isPresented: $showSubmitAlert) {
|
||||
Button("知道了", role: .cancel) {}
|
||||
} message: {
|
||||
Text(submitMessage)
|
||||
}
|
||||
.task {
|
||||
await viewModel.loadIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
/// 提交设置并展示 Mock 结果提示。
|
||||
private func handleSubmit() {
|
||||
if viewModel.submit() {
|
||||
submitMessage = "宣传页设置已保存,当前为 Mock 演示数据。"
|
||||
} else {
|
||||
submitMessage = "请至少绑定一个排队打卡点。"
|
||||
}
|
||||
showSubmitAlert = true
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#Preview("宣传页设置") {
|
||||
NavigationStack {
|
||||
ScenicPromotionSettingsView()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user