98 lines
3.4 KiB
Swift
98 lines
3.4 KiB
Swift
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?() }
|
|
}
|