import Foundation /// 自动修图设置状态,负责加载真实精修模板、单选和配置校验,不直接创建修图任务。 final class TravelAlbumAutoRetouchSettingViewModel { let scenicId: Int /// 是否在模板上方展示修图方式;创建页已选择 AI 时只展示模板。 let allowsModeSelection: Bool 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, allowsModeSelection: Bool ) { self.scenicId = scenicId self.allowsModeSelection = allowsModeSelection self.isEnabled = configuration.enabled || !allowsModeSelection self.selectedTemplateId = configuration.refinedTemplateId } /// 关闭自动修图不依赖模板加载;开启时必须选择有效模板。 var canConfirm: Bool { !isEnabled || (!isLoading && pendingConfiguration != nil) } /// 当前草稿模板名称,用于固定底部的选择摘要。 var selectedTemplateName: String? { templates.first { $0.id == selectedTemplateId }?.name } /// 当前可提交配置;启用状态必须已经选择服务端模板。 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) { guard allowsModeSelection else { return } isEnabled = enabled notify() } /// 选择一个真实精修模板。 func selectTemplate(id: Int) { guard templates.contains(where: { $0.id == id }) else { return } isEnabled = true selectedTemplateId = id notify() } private func notify() { onStateChange?() } }