feat: 接通图片预览 AI 修图流程
This commit is contained in:
@@ -129,6 +129,7 @@ struct TravelAlbumMaterial: Decodable, Sendable, Equatable, Hashable, Identifiab
|
||||
let isPurchased: Bool
|
||||
let aiRetouchStatus: Int
|
||||
let aiRetouchStatusName: String
|
||||
let aiRetouchBatchId: Int
|
||||
let aiRefinedURL: String
|
||||
let aiAtmosphereURL: String
|
||||
let createdAt: String
|
||||
@@ -148,6 +149,7 @@ struct TravelAlbumMaterial: Decodable, Sendable, Equatable, Hashable, Identifiab
|
||||
case isPurchased = "is_purchased"
|
||||
case aiRetouchStatus = "ai_retouch_status"
|
||||
case aiRetouchStatusName = "ai_retouch_status_name"
|
||||
case aiRetouchBatchId = "ai_retouch_batch_id"
|
||||
case aiRefinedURL = "ai_refined_url"
|
||||
case aiAtmosphereURL = "ai_atmosphere_url"
|
||||
case createdAt = "created_at"
|
||||
@@ -172,6 +174,7 @@ struct TravelAlbumMaterial: Decodable, Sendable, Equatable, Hashable, Identifiab
|
||||
aiRetouchStatusName = (
|
||||
try? container.decodeIfPresent(String.self, forKey: .aiRetouchStatusName)
|
||||
) ?? ""
|
||||
aiRetouchBatchId = (try? container.decodeIfPresent(Int.self, forKey: .aiRetouchBatchId)) ?? 0
|
||||
aiRefinedURL = (try? container.decodeIfPresent(String.self, forKey: .aiRefinedURL)) ?? ""
|
||||
aiAtmosphereURL = (
|
||||
try? container.decodeIfPresent(String.self, forKey: .aiAtmosphereURL)
|
||||
@@ -194,6 +197,7 @@ struct TravelAlbumMaterial: Decodable, Sendable, Equatable, Hashable, Identifiab
|
||||
isPurchased: Bool = false,
|
||||
aiRetouchStatus: Int = 0,
|
||||
aiRetouchStatusName: String = "",
|
||||
aiRetouchBatchId: Int = 0,
|
||||
aiRefinedURL: String = "",
|
||||
aiAtmosphereURL: String = "",
|
||||
createdAt: String = "",
|
||||
@@ -212,6 +216,7 @@ struct TravelAlbumMaterial: Decodable, Sendable, Equatable, Hashable, Identifiab
|
||||
self.isPurchased = isPurchased
|
||||
self.aiRetouchStatus = aiRetouchStatus
|
||||
self.aiRetouchStatusName = aiRetouchStatusName
|
||||
self.aiRetouchBatchId = aiRetouchBatchId
|
||||
self.aiRefinedURL = aiRefinedURL
|
||||
self.aiAtmosphereURL = aiAtmosphereURL
|
||||
self.createdAt = createdAt
|
||||
@@ -342,6 +347,62 @@ struct TravelAlbumMpCodeResponse: Decodable, Sendable, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
/// AI 修图模板类别,决定页面分组、选择规则和提交字段。
|
||||
enum TravelAlbumAIRetouchTemplateCategory: Int, Sendable, Hashable {
|
||||
case refined
|
||||
case atmosphere
|
||||
case cover
|
||||
|
||||
/// 模板分组展示标题。
|
||||
var title: String {
|
||||
switch self {
|
||||
case .refined: "原图精修"
|
||||
case .atmosphere: "氛围感修图"
|
||||
case .cover: "封面风格模板"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AI 修图模板页工作流,明确区分首次批量修图与单张结果覆盖重修。
|
||||
enum TravelAlbumAIRetouchWorkflow: Sendable, Equatable {
|
||||
/// 对一个相册内的原始素材发起首次 AI 修图。
|
||||
case initial(albumId: Int, materialIds: [Int])
|
||||
/// 对单张素材的既有 AI 结果发起覆盖重修。
|
||||
case reretouch(materialId: Int, batchId: Int, type: TravelAlbumAIReretouchType)
|
||||
|
||||
/// 当前页面需要展示的模板分组。
|
||||
var visibleCategories: [TravelAlbumAIRetouchTemplateCategory] {
|
||||
switch self {
|
||||
case .initial(_, let materialIds):
|
||||
var categories: [TravelAlbumAIRetouchTemplateCategory] = [.refined, .atmosphere]
|
||||
if materialIds.count >= 4 { categories.append(.cover) }
|
||||
return categories
|
||||
case .reretouch(_, _, .refined):
|
||||
return [.refined]
|
||||
case .reretouch(_, _, .atmosphere):
|
||||
return [.atmosphere]
|
||||
case .reretouch(_, _, .all):
|
||||
return [.refined, .atmosphere]
|
||||
}
|
||||
}
|
||||
|
||||
/// 当前分组是否允许不选择;仅首次修图的氛围感模板选填。
|
||||
func isOptional(_ category: TravelAlbumAIRetouchTemplateCategory) -> Bool {
|
||||
if case .initial = self, category == .atmosphere { return true }
|
||||
return false
|
||||
}
|
||||
|
||||
/// 工作流目标是否满足接口的最小参数要求。
|
||||
var isValid: Bool {
|
||||
switch self {
|
||||
case .initial(let albumId, let materialIds):
|
||||
return albumId > 0 && !materialIds.isEmpty
|
||||
case .reretouch(let materialId, let batchId, _):
|
||||
return materialId > 0 && batchId > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AI 修图模板,包含业务 ID、展示名称和预览图地址。
|
||||
struct TravelAlbumAIRetouchTemplate: Decodable, Sendable, Equatable, Hashable, Identifiable {
|
||||
let id: Int
|
||||
@@ -392,14 +453,38 @@ struct TravelAlbumAIRetouchRequest: Encodable, Sendable, Equatable {
|
||||
let materialIds: [Int]
|
||||
let refinedTemplateId: Int
|
||||
let atmosphereTemplateId: Int?
|
||||
let aiPreviewTabs: Int?
|
||||
let coverTemplateId: Int?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case userEquityTravelId = "user_equity_travel_id"
|
||||
case materialIds = "material_ids"
|
||||
case refinedTemplateId = "refined_template_id"
|
||||
case atmosphereTemplateId = "atmosphere_template_id"
|
||||
case aiPreviewTabs = "ai_preview_tabs"
|
||||
case coverTemplateId = "cover_template_id"
|
||||
}
|
||||
}
|
||||
|
||||
/// 重新修图类型,决定后端覆盖的 AI 结果及必需模板字段。
|
||||
enum TravelAlbumAIReretouchType: Int, Encodable, Sendable, Equatable {
|
||||
case refined = 1
|
||||
case atmosphere = 2
|
||||
case all = 3
|
||||
}
|
||||
|
||||
/// 提交单张素材重新修图的最小请求参数。
|
||||
struct TravelAlbumAIReretouchRequest: Encodable, Sendable, Equatable {
|
||||
let id: Int
|
||||
let aiRetouchBatchId: Int
|
||||
let type: TravelAlbumAIReretouchType
|
||||
let refinedTemplateId: Int?
|
||||
let atmosphereTemplateId: Int?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case aiRetouchBatchId = "ai_retouch_batch_id"
|
||||
case type
|
||||
case refinedTemplateId = "refined_template_id"
|
||||
case atmosphereTemplateId = "atmosphere_template_id"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user