feat: add AI retouch before-after comparison

This commit is contained in:
2026-08-13 17:46:06 +08:00
parent e190b5958b
commit 0f3b26991e
12 changed files with 953 additions and 145 deletions
@@ -403,23 +403,45 @@ enum TravelAlbumAIRetouchWorkflow: Sendable, Equatable {
}
}
/// AI 修图模板,包含业务 ID、展示名称和预览图地址。
/// AI 修图模板,包含业务 ID、展示名称、卡片预览图及前后对比图片地址。
struct TravelAlbumAIRetouchTemplate: Decodable, Sendable, Equatable, Hashable, Identifiable {
let id: Int
let name: String
let previewURL: String
let beforeURL: String
let afterURL: String
enum CodingKeys: String, CodingKey {
case id
case name
case previewURL = "preview_url"
case beforeURL = "before_url"
case afterURL = "after_url"
}
/// 创建 AI 修图模板。
init(id: Int, name: String, previewURL: String) {
init(
id: Int,
name: String,
previewURL: String,
beforeURL: String = "",
afterURL: String = ""
) {
self.id = id
self.name = name
self.previewURL = previewURL
self.beforeURL = beforeURL
self.afterURL = afterURL
}
/// 解码模板;前后对比字段缺失或为 null 时按空字符串兼容旧接口响应。
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
previewURL = try container.decode(String.self, forKey: .previewURL)
beforeURL = (try? container.decodeIfPresent(String.self, forKey: .beforeURL)) ?? ""
afterURL = (try? container.decodeIfPresent(String.self, forKey: .afterURL)) ?? ""
}
}