import Foundation /// 自动修图设置状态,负责加载真实精修模板、单选和配置校验,不直接创建修图任务。 final class TravelAlbumAutoRetouchSettingViewModel { /// 设置页当前层级。 enum Stage: Sendable, Equatable { case mode case templates } let scenicId: Int let startsWithModeSelection: Bool private(set) var stage: Stage private(set) var templates: [TravelAlbumAIRetouchTemplate] = [] private(set) var selectedTemplateId: Int? private(set) var isEnabled: Bool private(set) var isLoading = false private(set) var errorMessage: String? var onStateChange: (() -> Void)? /// 创建自动修图配置状态。 init( scenicId: Int, configuration: TravelAlbumAutoRetouchConfiguration, startsWithModeSelection: Bool ) { self.scenicId = scenicId self.startsWithModeSelection = startsWithModeSelection self.stage = startsWithModeSelection ? .mode : .templates self.isEnabled = configuration.enabled self.selectedTemplateId = configuration.refinedTemplateId } /// 当前可提交配置;启用状态必须已经选择服务端模板。 var pendingConfiguration: TravelAlbumAutoRetouchConfiguration? { if !isEnabled { return .disabled } guard let selectedTemplateId, templates.contains(where: { $0.id == selectedTemplateId }) else { return nil } return TravelAlbumAutoRetouchConfiguration( enabled: true, refinedTemplateId: selectedTemplateId ) } /// 拉取当前景区的真实精修模板。 func loadTemplates(api: any TravelAlbumServing) async { guard scenicId > 0 else { errorMessage = "请先选择景区" notify() return } guard !isLoading else { return } isLoading = true errorMessage = nil notify() defer { isLoading = false notify() } do { let response = try await api.aiRetouchTemplates(scenicId: scenicId) templates = response.refinedTemplates if !templates.contains(where: { $0.id == selectedTemplateId }) { selectedTemplateId = nil } if templates.isEmpty { errorMessage = "暂无可用的原图精修模板" } } catch is CancellationError { return } catch { templates = [] errorMessage = error.localizedDescription.isEmpty ? "模板加载失败" : error.localizedDescription } } /// 选择一级修图方式。 func selectMode(enabled: Bool) { isEnabled = enabled if enabled { stage = .templates } else { selectedTemplateId = nil } notify() } /// 选择一个真实精修模板。 func selectTemplate(id: Int) { guard templates.contains(where: { $0.id == id }) else { return } isEnabled = true selectedTemplateId = id notify() } /// 从模板列表返回修图方式层级。 func returnToModeSelection() { guard startsWithModeSelection else { return } stage = .mode notify() } private func notify() { onStateChange?() } }