TSGeneratePosterOperation.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. //
  2. // TSGeneratePTPOperation.swift
  3. // AIRingtone
  4. //
  5. // Created by 100Years on 2025/3/24.
  6. //
  7. import Combine
  8. import Alamofire
  9. import ObjectMapper
  10. import Kingfisher
  11. class TSGeneratePTPOperationQueue: TSGenerateBaseOperationQueue {
  12. static let shared:TSGeneratePTPOperationQueue = TSGeneratePTPOperationQueue()
  13. func creatOperation(uuid: String) -> TSGeneratePTPOperation {
  14. let operation = super.creatOperation(uuid: uuid, type: TSGeneratePTPOperation.self)
  15. handleStateDatauPblished(uuid: uuid, generateOperation: operation as! TSGenerateBaseOperation, notificationName: .kGeneratePTPOperationChanged)
  16. return operation as! TSGeneratePTPOperation
  17. }
  18. override func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
  19. if let PosterOperation = TSGeneratePTPOperationQueue.shared.findOperation(uuid: uuid) as? TSGeneratePTPOperation {
  20. dePrint("TSBaseOperation stateDatauPblished 发送 = \(PosterOperation.stateDatauPblished)")
  21. return (PosterOperation.stateDatauPblished.0,PosterOperation.currentActionInfoModel)
  22. }
  23. return (.none,TSActionInfoModel())
  24. }
  25. }
  26. class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
  27. //是否展示成功后的 View 提醒
  28. public var isShowSuccessView:Bool = false
  29. override var actionInfoDict:[String:Any]{
  30. return [
  31. "actionType":"image_create",
  32. "comments": "Success",
  33. "costTime":9,
  34. "createdTimestamp":1742183242,
  35. "id":2449,
  36. "percent":1,
  37. "request":"{\"prompt\": \"Traditional Chinese ink painting style phoenix soaring through misty mountain peaks, dynamic black brushstrokes with crimson accents on rice paper texture, Googie architecture space station, 1950s atomic age aesthetic, curved aluminum panels, starburst patterns, glass dome observatory --edge_threshold 0.5 --atomic_age_style 0.8 --chrome_reflection 1.2\", \"width\": 800, \"height\": 1440, \"countryCode\": \"FR\"}",
  38. "response": "{\"resultUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/4c946f78-b1e7-4ffe-ba18-fff26b10178c.png\"}",
  39. "status":"success"
  40. ]
  41. }
  42. override func replaceSaveInfoModel(model:TSActionInfoModel){
  43. model.uuid = uuid
  44. model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
  45. if isSaveDB {
  46. TSRMShared.ptpDBHistory.updateData(model,id: currentActionInfoModel.id)
  47. }
  48. currentActionInfoModel = model
  49. dePrint("model actionStatus 发出=\(model.actionStatus)")
  50. currentActionInfoModelChanged?(currentActionInfoModel)
  51. }
  52. // override func handleGenerateSuccess() {
  53. // kPurchaseDefault.useOnceForFree(type: .picToPic)
  54. //
  55. // if isShowSuccessView == false {
  56. // return
  57. // }
  58. //
  59. // guard let window = WindowHelper.getKeyWindow() else {
  60. // debugPrint("getKeyWindow nil")
  61. // return
  62. // }
  63. //
  64. // guard let rootVC = WindowHelper.topViewController() else {
  65. // debugPrint("handleGenerateSuccess topViewController nil")
  66. // return
  67. // }
  68. //
  69. // let copyModel = self.currentActionInfoModel.copy()
  70. // if let rootVC = WindowHelper.getCurrentViewController() ,let cyModel = copyModel as? TSActionInfoModel {
  71. // kSaveSuccesswShared.show(atView: rootVC.view,text: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: k_Nav_Height+10)) {
  72. // let gennerateVC = TSPTPGeneratorVC(generateStyleModel: TSGenerateOnlineStyleModel(),infoModel: cyModel) { model in }
  73. // gennerateVC.modalPresentationStyle = .overFullScreen
  74. // gennerateVC.modalTransitionStyle = .crossDissolve
  75. // rootVC.present(gennerateVC, animated: true)
  76. // }
  77. // }else{
  78. // debugPrint("copyModel as? TSActionInfoModel error")
  79. // }
  80. // }
  81. override func handleGenerateSuccess() {
  82. kPurchaseDefault.useOnceForFree(type: .picToPic)
  83. Self.saveCurrentActionInfoModel = self.currentActionInfoModel
  84. debugPrint("handleGenerateSuccess currentActionInfoModel=\(self.currentActionInfoModel)")
  85. if isShowSuccessView == false {
  86. return
  87. }
  88. guard let _ = WindowHelper.getKeyWindow() else {
  89. debugPrint("getKeyWindow nil")
  90. return
  91. }
  92. guard let _ = WindowHelper.topViewController() else {
  93. debugPrint("handleGenerateSuccess topViewController nil")
  94. return
  95. }
  96. if let rootVC = WindowHelper.getCurrentViewController() ,let cyModel = Self.saveCurrentActionInfoModel {
  97. kSaveSuccesswShared.show(atView: rootVC.view,text: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: k_Nav_Height+10)) {
  98. debugPrint("handleGenerateSuccess saveCurrentActionInfoModel=\(cyModel)")
  99. let gennerateVC = TSPTPGeneratorVC(generateStyleModel: TSGenerateOnlineStyleModel(),infoModel: cyModel) { model in }
  100. gennerateVC.modalPresentationStyle = .overFullScreen
  101. gennerateVC.modalTransitionStyle = .crossDissolve
  102. rootVC.present(gennerateVC, animated: true)
  103. }
  104. }else{
  105. debugPrint("copyModel as? TSActionInfoModel error")
  106. }
  107. }
  108. /**
  109. 1.用户上传图片
  110. 2.调用生成接口
  111. 3.后台返回查询 id,根据 id 不断查询进度和结果.(此时才允许进度后台)
  112. 利用3后台返回的TSActionRequestModel中存着关键的请求接口数据,请求数据
  113. */
  114. private var uploadRequest:Request?
  115. private var creatRequest:Request?
  116. private func createActionInfoModel(generateStyleModel:TSGenerateOnlineStyleModel) -> TSActionInfoModel? {
  117. guard let upLoadImageUrl = generateStyleModel.upLoadImageUrl else { return nil }
  118. let infoModel = TSActionInfoModel()
  119. infoModel.id = Date.timestampInt
  120. infoModel.request = TSActionRequestModel()
  121. infoModel.request.imageUrl = upLoadImageUrl
  122. infoModel.request.imageUrlTimestamp = Date.timestampInt
  123. infoModel.request.prompt = ""
  124. infoModel.request.promptSort = generateStyleModel.inputText
  125. infoModel.request.style = generateStyleModel.styleId
  126. infoModel.request.advance = false
  127. return infoModel
  128. }
  129. func uploadImage(generateStyleModel:TSGenerateOnlineStyleModel,complete:@escaping (TSActionInfoModel?)->Void) {
  130. guard let upLoadImage = generateStyleModel.upLoadImage else { return }
  131. if let imageUrl = generateStyleModel.upLoadImageUrl,imageUrl.contains("http") {
  132. complete(createActionInfoModel(generateStyleModel: generateStyleModel))
  133. return
  134. }
  135. stopNetwork = false
  136. stateDatauPblished = (.start,currentActionInfoModel)
  137. stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),currentActionInfoModel)
  138. uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb) { [weak self] progress in
  139. guard let self = self else { return }
  140. if generatingProgress == 0 {
  141. stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)),currentActionInfoModel)
  142. }
  143. } completion: { [weak self] data, error in
  144. guard let self = self else { return }
  145. if let error = error {
  146. generateStyleModel.upLoadImageUrl = nil
  147. self.stateDatauPblished = (.failed(error.localizedDescription),currentActionInfoModel)
  148. complete(nil)
  149. }else{
  150. if let string = data as? String {
  151. generateStyleModel.upLoadImageUrl = string
  152. if let url = URL(string: string){//上传成功后,就将图片缓存到本地
  153. ImageCache.default.store(upLoadImage, forKey: url.cacheKey)
  154. }
  155. complete(createActionInfoModel(generateStyleModel: generateStyleModel))
  156. }else{
  157. complete(nil)
  158. }
  159. }
  160. }
  161. }
  162. func creatImage(oldModel:TSActionInfoModel) {
  163. initializeActionInfoModel(oldModel: oldModel)
  164. if oldModel.upImageURLExpired { return }
  165. generatingProgress = 0
  166. stopNetwork = false
  167. stateDatauPblished = (.start,currentActionInfoModel)
  168. currentActionInfoModel.status = "running"
  169. currentActionInfoModel.actionStatus = .running
  170. currentActionInfoModel.percent = 0
  171. replaceSaveInfoModel(model: currentActionInfoModel)
  172. stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
  173. let request = currentActionInfoModel.request
  174. var prompt = request.prompt
  175. let promptSort = request.promptSort
  176. if promptSort.count>0{
  177. if prompt.count > 0 {
  178. prompt = prompt + ", " + promptSort
  179. }else {
  180. prompt = promptSort
  181. }
  182. }
  183. creatRequest = TSNetworkShared.post(urlType: .imageRewriteV2,parameters:
  184. ["prompt":prompt,
  185. "imageUrl":request.imageUrl,
  186. "styleId":request.style,
  187. "device":getUserInfoJsonString(),
  188. ]) { [weak self] data,error in
  189. guard let self = self else { return }
  190. if let dataDict = kNetWorkCodeSuccess(data: data),
  191. let actionId = dataDict["actionId"] as? Int{
  192. if stopNetwork == false {
  193. self.stateDatauPblished = (.pending,currentActionInfoModel) //通知首页进行更新
  194. self.stateDatauPblished = (.backstage(true),currentActionInfoModel) //通知允许进入后台生成
  195. self.getActionInfo(action_id:actionId)
  196. }
  197. }else{
  198. handleFailInfoModel(errorString: error?.localizedDescription ?? "")
  199. }
  200. }
  201. }
  202. override func generating(progress: Float) -> String {
  203. let progress = Float(progress)*(0.9) // 预留 10% 进度给图片下载
  204. //Generating 0%-100%
  205. var progressInt = Int(progress*100)
  206. if progressInt > 99 {
  207. progressInt = 99
  208. }
  209. generatingProgress = progressInt
  210. return "Generating".localized + " \(progressInt)%"
  211. }
  212. var imageMaxKb:Int{
  213. return 10*1024
  214. }
  215. func uploadingPhoto(progress:Float) -> String {
  216. //Uploading Photo 0%-100%
  217. var progressInt = Int(progress*100)
  218. if progressInt > 99 {
  219. progressInt = 99
  220. }
  221. return "Uploading Photo".localized + " \(progressInt)%"
  222. }
  223. override func cancelCleanContent() {
  224. super.cancelCleanContent()
  225. debugPrint("cancelCleanContent")
  226. uploadRequest?.cancel()
  227. creatRequest?.cancel()
  228. }
  229. }