TSGeneratePosterOperation.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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. if isShowSuccessView == false {
  85. return
  86. }
  87. guard let _ = WindowHelper.getKeyWindow() else {
  88. debugPrint("getKeyWindow nil")
  89. return
  90. }
  91. guard let _ = WindowHelper.topViewController() else {
  92. debugPrint("handleGenerateSuccess topViewController nil")
  93. return
  94. }
  95. if let rootVC = WindowHelper.getCurrentViewController() ,let cyModel = Self.saveCurrentActionInfoModel {
  96. kSaveSuccesswShared.show(atView: rootVC.view,text: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: k_Nav_Height+10)) {
  97. let gennerateVC = TSPTPGeneratorVC(generateStyleModel: TSGenerateOnlineStyleModel(),infoModel: cyModel) { model in }
  98. gennerateVC.modalPresentationStyle = .overFullScreen
  99. gennerateVC.modalTransitionStyle = .crossDissolve
  100. rootVC.present(gennerateVC, animated: true)
  101. }
  102. }else{
  103. debugPrint("copyModel as? TSActionInfoModel error")
  104. }
  105. }
  106. /**
  107. 1.用户上传图片
  108. 2.调用生成接口
  109. 3.后台返回查询 id,根据 id 不断查询进度和结果.(此时才允许进度后台)
  110. 利用3后台返回的TSActionRequestModel中存着关键的请求接口数据,请求数据
  111. */
  112. private var uploadRequest:Request?
  113. private var creatRequest:Request?
  114. private func createActionInfoModel(generateStyleModel:TSGenerateOnlineStyleModel) -> TSActionInfoModel? {
  115. guard let upLoadImageUrl = generateStyleModel.upLoadImageUrl else { return nil }
  116. let infoModel = TSActionInfoModel()
  117. infoModel.id = Date.timestampInt
  118. infoModel.request = TSActionRequestModel()
  119. infoModel.request.imageUrl = upLoadImageUrl
  120. infoModel.request.imageUrlTimestamp = Date.timestampInt
  121. infoModel.request.prompt = ""
  122. infoModel.request.promptSort = generateStyleModel.inputText
  123. infoModel.request.style = generateStyleModel.styleId
  124. infoModel.request.advance = false
  125. return infoModel
  126. }
  127. func uploadImage(generateStyleModel:TSGenerateOnlineStyleModel,complete:@escaping (TSActionInfoModel?)->Void) {
  128. guard let upLoadImage = generateStyleModel.upLoadImage else { return }
  129. if let imageUrl = generateStyleModel.upLoadImageUrl,imageUrl.contains("http") {
  130. complete(createActionInfoModel(generateStyleModel: generateStyleModel))
  131. return
  132. }
  133. stopNetwork = false
  134. stateDatauPblished = (.start,currentActionInfoModel)
  135. stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),currentActionInfoModel)
  136. uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb) { [weak self] progress in
  137. guard let self = self else { return }
  138. if generatingProgress == 0 {
  139. stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)),currentActionInfoModel)
  140. }
  141. } completion: { [weak self] data, error in
  142. guard let self = self else { return }
  143. if let error = error {
  144. generateStyleModel.upLoadImageUrl = nil
  145. self.stateDatauPblished = (.failed(error.localizedDescription),currentActionInfoModel)
  146. complete(nil)
  147. }else{
  148. if let string = data as? String {
  149. generateStyleModel.upLoadImageUrl = string
  150. if let url = URL(string: string){//上传成功后,就将图片缓存到本地
  151. ImageCache.default.store(upLoadImage, forKey: url.cacheKey)
  152. }
  153. complete(createActionInfoModel(generateStyleModel: generateStyleModel))
  154. }else{
  155. complete(nil)
  156. }
  157. }
  158. }
  159. }
  160. func creatImage(oldModel:TSActionInfoModel) {
  161. initializeActionInfoModel(oldModel: oldModel)
  162. if oldModel.upImageURLExpired { return }
  163. generatingProgress = 0
  164. stopNetwork = false
  165. stateDatauPblished = (.start,currentActionInfoModel)
  166. currentActionInfoModel.status = "running"
  167. currentActionInfoModel.actionStatus = .running
  168. currentActionInfoModel.percent = 0
  169. replaceSaveInfoModel(model: currentActionInfoModel)
  170. stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
  171. let request = currentActionInfoModel.request
  172. var prompt = request.prompt
  173. let promptSort = request.promptSort
  174. if promptSort.count>0{
  175. if prompt.count > 0 {
  176. prompt = prompt + ", " + promptSort
  177. }else {
  178. prompt = promptSort
  179. }
  180. }
  181. creatRequest = TSNetworkShared.post(urlType: .imageRewriteV2,parameters:
  182. ["prompt":prompt,
  183. "imageUrl":request.imageUrl,
  184. "styleId":request.style,
  185. "device":getUserInfoJsonString(),
  186. ]) { [weak self] data,error in
  187. guard let self = self else { return }
  188. if let dataDict = kNetWorkCodeSuccess(data: data),
  189. let actionId = dataDict["actionId"] as? Int{
  190. if stopNetwork == false {
  191. self.stateDatauPblished = (.pending,currentActionInfoModel) //通知首页进行更新
  192. self.stateDatauPblished = (.backstage(true),currentActionInfoModel) //通知允许进入后台生成
  193. self.getActionInfo(action_id:actionId)
  194. }
  195. }else{
  196. handleFailInfoModel(errorString: error?.localizedDescription ?? "")
  197. }
  198. }
  199. }
  200. override func generating(progress: Float) -> String {
  201. let progress = Float(progress)*(0.9) // 预留 10% 进度给图片下载
  202. //Generating 0%-100%
  203. var progressInt = Int(progress*100)
  204. if progressInt > 99 {
  205. progressInt = 99
  206. }
  207. generatingProgress = progressInt
  208. return "Generating".localized + " \(progressInt)%"
  209. }
  210. var imageMaxKb:Int{
  211. return 10*1024
  212. }
  213. func uploadingPhoto(progress:Float) -> String {
  214. //Uploading Photo 0%-100%
  215. var progressInt = Int(progress*100)
  216. if progressInt > 99 {
  217. progressInt = 99
  218. }
  219. return "Uploading Photo".localized + " \(progressInt)%"
  220. }
  221. override func cancelCleanContent() {
  222. super.cancelCleanContent()
  223. debugPrint("cancelCleanContent")
  224. uploadRequest?.cancel()
  225. creatRequest?.cancel()
  226. }
  227. }