KMAIRequestServerManager.swift 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. //
  2. // KMAIRequestServerManager.swift
  3. // PDF Reader Pro Edition
  4. //
  5. // Created by wanjun on 2024/1/17.
  6. //
  7. import Cocoa
  8. import AFNetworking
  9. @objcMembers
  10. class ResultWrapper: NSObject {
  11. var success: Bool = false
  12. var result: NSDictionary = [:]
  13. var content: String = ""
  14. init(success: Bool, content: String) {
  15. self.success = success
  16. self.content = content
  17. self.result = NSDictionary.init()
  18. }
  19. init(success: Bool, resultData: NSDictionary) {
  20. self.success = success
  21. self.content = ""
  22. self.result = resultData
  23. }
  24. }
  25. @objc enum KMAIRewritingState : Int {
  26. case rewrite = 0 // 重写
  27. case correctTypos // 纠错
  28. case uploadTranslate // 翻译上传文件
  29. case fileTranslate // 翻译文件
  30. case textTranslate // 翻译文本
  31. case extractSummaryFile //摘要
  32. case aiPonder // AI思考
  33. }
  34. @objc enum KMAIFileUploadState : Int {
  35. case Translation = 0
  36. case ExtractAbstract
  37. }
  38. //typealias KMRequestServerComplete = (_ success: Bool, _ result: Result?) -> Void
  39. @objcMembers class KMAIRequestServerManager: NSObject {
  40. static let defaultManager = KMAIRequestServerManager()
  41. typealias KMRequestServerComplete = (_ wrapper: ResultWrapper) -> Void
  42. private var downFileUrl: String = "" // 文件翻译
  43. var downFileName: String = "" // 文件翻译
  44. var fromLanguages: [String] = ["Automatic", "English", "Simplified Chinese", "Traditional Chinese", "Japanese", "Korean", "French", "Spanish", "Italian", "German", "Portuguese", "Russian", "Vietnamese", "Thai", "Arabic", "Greek", "Bulgarian", "Finnish", "Slovene", "Dutch", "Czech", "Swedish", "Polish", "Danish", "Romanian", "Hungarian"]
  45. var toLanguages: [String] = ["English", "Simplified Chinese", "Traditional Chinese", "Japanese", "Korean", "French", "Spanish", "Italian", "German", "Portuguese", "Russian", "Vietnamese", "Thai", "Arabic", "Greek", "Bulgarian", "Finnish", "Slovene", "Dutch", "Czech", "Swedish", "Polish", "Danish", "Romanian", "Hungarian"]
  46. // MARK: AI Action (public)
  47. func aiAction(content: String, state: KMAIRewritingState, from: String = "auto", to: String = "en", complete: @escaping KMRequestServerComplete) {
  48. if state == .rewrite || state == .correctTypos { //重写 && 纠错
  49. aiRewriting(content: content, state: state, complete: complete)
  50. } else if (state == .aiPonder) {
  51. aiPonder(content: content, complete: complete)
  52. } else if state == .uploadTranslate || state == .fileTranslate { // 上传文件 || 文件翻译
  53. let aiInfo: AIInfo = AIInfoManager.default().aiInfo
  54. if aiInfo.totalToken - aiInfo.usedTimes > 1 {
  55. aiTranslationFileUpload(file: content, complete: { [weak self] wrapper in
  56. let success: Bool = wrapper.success
  57. let fileKey = wrapper.content
  58. if success {
  59. let fileData = wrapper.result
  60. complete(wrapper)
  61. } else {
  62. complete(wrapper)
  63. }
  64. })
  65. } else {
  66. memberAITranslationFileUpload(file: content, complete: { [weak self] wrapper in
  67. let success: Bool = wrapper.success
  68. let fileKey = wrapper.content
  69. if success {
  70. let fileData = wrapper.result
  71. complete(wrapper)
  72. } else {
  73. complete(wrapper)
  74. }
  75. })
  76. }
  77. } else if state == .textTranslate { // 文本翻译
  78. let aiInfo: AIInfo = AIInfoManager.default().aiInfo
  79. if aiInfo.totalToken - aiInfo.usedTimes > 1 {
  80. aiTranslationTextTrans(q: content, from: languageAbbreviation(from), to: languageAbbreviation(to), complete: complete)
  81. } else {
  82. aiMemberTranslationTextTrans(q: content, from: languageAbbreviation(from), to: languageAbbreviation(to), complete: complete)
  83. }
  84. } else if state == .extractSummaryFile { // 提取摘要
  85. let aiInfo: AIInfo = AIInfoManager.default().aiInfo
  86. if aiInfo.totalToken - aiInfo.usedTimes > 0 {
  87. extractSummaryFile(file: content, complete: complete)
  88. } else {
  89. memberExtractSummaryFile(file: content, complete: complete)
  90. }
  91. }
  92. }
  93. // MARK: Private
  94. private func uuid() -> String {
  95. return GetHardwareUUID()!
  96. }
  97. private func platform() -> String {
  98. var platform = "DMG"
  99. #if VERSION_DMG
  100. platform = "DMG"
  101. #else
  102. platform = "AiStore"
  103. #endif
  104. return platform
  105. }
  106. private func app_name() -> String {
  107. var bundleID: String!
  108. bundleID = Bundle.main.object(forInfoDictionaryKey: "CFBundleIdentifier") as! String
  109. return bundleID;
  110. }
  111. func downloadFile(filePath: String, downFileName: String, toPath: String, complete: @escaping KMRequestServerComplete) {
  112. self.downFileUrl = ""
  113. guard let fileURL = URL(string: filePath) else {
  114. let alert = NSAlert()
  115. alert.alertStyle = .critical
  116. alert.messageText = NSLocalizedString("Invalid file link", comment: "")
  117. alert.runModal()
  118. return
  119. }
  120. var destinationURL = FileManager.default.temporaryDirectory.appendingPathComponent(downFileName)
  121. if URL(fileURLWithPath: toPath) != nil {
  122. destinationURL = URL(fileURLWithPath: toPath)
  123. }
  124. if FileManager.default.fileExists(atPath: destinationURL.path) {
  125. do {
  126. try FileManager.default.removeItem(at: destinationURL)
  127. print("删除旧文件成功")
  128. } catch {
  129. print("删除旧文件失败:\(error)")
  130. }
  131. }
  132. let sessionConfiguration = URLSessionConfiguration.default
  133. let session = URLSession(configuration: sessionConfiguration)
  134. let downloadTask = session.downloadTask(with: fileURL) { (tempLocalURL, response, error) in
  135. if let error = error {
  136. let alert = NSAlert()
  137. alert.alertStyle = .critical
  138. alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Download failed", comment: ""))
  139. alert.runModal()
  140. return
  141. }
  142. guard let tempLocalURL = tempLocalURL else {
  143. let alert = NSAlert()
  144. alert.alertStyle = .critical
  145. alert.messageText = NSLocalizedString("Invalid temporary directory", comment: "")
  146. alert.runModal()
  147. return
  148. }
  149. do {
  150. try FileManager.default.moveItem(at: tempLocalURL, to: destinationURL)
  151. let wrapper = ResultWrapper(success: true, content: "")
  152. wrapper.content = destinationURL.path
  153. complete(wrapper)
  154. } catch {
  155. let alert = NSAlert()
  156. alert.alertStyle = .critical
  157. alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Failed to save file", comment: ""))
  158. alert.runModal()
  159. }
  160. }
  161. self.downFileUrl = destinationURL.path
  162. downloadTask.resume()
  163. }
  164. private func languageAbbreviation(_ language: String) -> String {
  165. if language == "Automatic" || language == "auto" {
  166. return "auto"
  167. } else if language == "English" || language == "en" {
  168. return "en"
  169. } else if language == "Simplified Chinese" || language == "zh" {
  170. return "zh"
  171. } else if language == "Traditional Chinese" || language == "cht" {
  172. return "cht"
  173. } else if language == "Japanese" || language == "jp" {
  174. return "jp"
  175. } else if language == "Korean" || language == "kor" {
  176. return "kor"
  177. } else if language == "French" || language == "fra" {
  178. return "fra"
  179. } else if language == "Spanish" || language == "spa" {
  180. return "spa"
  181. } else if language == "Italian" || language == "it" {
  182. return "it"
  183. } else if language == "German" || language == "de" {
  184. return "de"
  185. } else if language == "Portuguese" || language == "pt" {
  186. return "pt"
  187. } else if language == "Russian" || language == "ru" {
  188. return "ru"
  189. } else if language == "Vietnamese" || language == "vie" {
  190. return "vie"
  191. } else if language == "Thai" || language == "th" {
  192. return "th"
  193. } else if language == "Arabic" || language == "ara" {
  194. return "ara"
  195. } else if language == "Greek" || language == "el" {
  196. return "el"
  197. } else if language == "Bulgarian" || language == "bul" {
  198. return "bul"
  199. } else if language == "Finnish" || language == "fin" {
  200. return "fin"
  201. } else if language == "Slovene" || language == "slo" {
  202. return "slo"
  203. } else if language == "Dutch" || language == "nl" {
  204. return "nl"
  205. } else if language == "Czech" || language == "cs" {
  206. return "cs"
  207. } else if language == "Swedish" || language == "swe" {
  208. return "swe"
  209. } else if language == "Polish" || language == "pl" {
  210. return "pl"
  211. } else if language == "Danish" || language == "dan" {
  212. return "dan"
  213. } else if language == "Romanian" || language == "rom" {
  214. return "rom"
  215. } else if language == "Hungarian" || language == "hu" {
  216. return "hu"
  217. }
  218. return "auto"
  219. }
  220. // MARK: AI Action (private)
  221. /**
  222. @abstract 翻译上传
  223. @param file 文件路径
  224. @param complete 上传完成回调
  225. */
  226. private func aiTranslationFileUpload(file: String, complete: @escaping KMRequestServerComplete) {
  227. let infoDictionary = Bundle .main.infoDictionary!
  228. let urlString = AIInfoConfig().aiActionURL + "/api/AI/uploadTranslate"
  229. let fileData = FileManager.default.contents(atPath: file)
  230. let params: [String: Any] = ["file": fileData,
  231. "uuid": uuid(),
  232. "platform": platform(),
  233. "app_name": app_name(),
  234. "calculate":"1"]
  235. KMAIRequestServer.requestServer.uploadFile(urlString: urlString, params: params) { formData in
  236. let fileURL = URL(fileURLWithPath: file)
  237. try? formData.appendPart(withFileURL: fileURL, name: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream")
  238. } requestSerializer: { requestSerializer in
  239. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  240. } completion: { task, responseObject, error in
  241. if responseObject != nil {
  242. let data: NSDictionary = responseObject!["data"] as? NSDictionary ?? [:]
  243. var code: String = responseObject!["code"] as? String ?? "06005"
  244. if code == "06005" {
  245. let tempCode: Int = responseObject!["code"] as? Int ?? 0
  246. if tempCode == 501 {
  247. code = "501"
  248. }
  249. }
  250. let message: String = responseObject!["message"] as? String ?? "unknown error"
  251. let error = NSError(domain: message, code: Int(code)!)
  252. if Int(code)! == 200 {
  253. let wrapper = ResultWrapper(success: true, resultData: data)
  254. wrapper.content = data["fileKey"] as! String
  255. complete(wrapper)
  256. } else {
  257. let wrapper = ResultWrapper(success: false, resultData: data)
  258. if Int(code)! == 501 {
  259. wrapper.content = "501"
  260. } else {
  261. wrapper.content = message
  262. }
  263. complete(wrapper)
  264. }
  265. } else {
  266. complete(ResultWrapper(success: false, content: "unknown error"))
  267. }
  268. }
  269. }
  270. private func memberAITranslationFileUpload(file: String, complete: @escaping KMRequestServerComplete) {
  271. let token: String = KMMemberInfo.shared.access_token
  272. if token == "" {
  273. complete(ResultWrapper(success: false, content: "unknown error"))
  274. if(KMMemberInfo.shared.isLogin == true) {
  275. KMUserInfoViewController.refreshTokenUserInfo {[weak self] success, resDic in
  276. if(success == true) {
  277. } else {
  278. let code = resDic?.code ?? 200
  279. if(code == 304) {
  280. KMLoginWindowsController.shared.showWindow(nil)
  281. }
  282. }
  283. }
  284. } else {
  285. KMLoginWindowsController.shared.showWindow(nil)
  286. }
  287. return
  288. }
  289. let urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/v1/translate/fileUpload"
  290. let fileData = FileManager.default.contents(atPath: file)
  291. let params: [String: Any] = ["file" : fileData,
  292. "calculate" : "1"]
  293. KMAIRequestServer.requestServer.uploadFile(urlString: urlString, params: params) { formData in
  294. let fileURL = URL(fileURLWithPath: file)
  295. try? formData.appendPart(withFileURL: fileURL, name: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream")
  296. } requestSerializer: { requestSerializer in
  297. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  298. requestSerializer.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  299. } completion: { task, responseObject, error in
  300. if responseObject != nil {
  301. let data: NSDictionary = responseObject as? NSDictionary ?? [:]
  302. if data.count > 0 {
  303. let code: String = data["code"] as? String ?? "06005"
  304. if Int(code)! == 200, let dataDic = data["data"] {
  305. let wrapper = ResultWrapper(success: true, resultData: dataDic as! NSDictionary)
  306. if let value = (dataDic as! NSDictionary)["fileKey"] {
  307. wrapper.content = value as! String
  308. }
  309. complete(wrapper)
  310. } else {
  311. let wrapper = ResultWrapper(success: false, resultData: data)
  312. if let value = data["msg"] {
  313. wrapper.content = value as! String
  314. }
  315. complete(wrapper)
  316. }
  317. } else {
  318. let error = NSError(domain: "unknown error", code: 404)
  319. complete(ResultWrapper(success: false, content: "unknown error"))
  320. }
  321. } else {
  322. let error = NSError(domain: "unknown error", code: 404)
  323. complete(ResultWrapper(success: false, content: "unknown error"))
  324. }
  325. }
  326. }
  327. /**
  328. @abstract 文件翻译
  329. @param fileKey 文件Key
  330. @param from 初始语言
  331. @param to 结束语言
  332. */
  333. func aiTranslationFileTranslateHandle(fileKey: String, from: String, to: String, complete: @escaping KMRequestServerComplete) {
  334. let aiInfo: AIInfo = AIInfoManager.default().aiInfo
  335. if aiInfo.totalToken - aiInfo.usedTimes > 1 {
  336. let infoDictionary = Bundle .main.infoDictionary!
  337. let urlString = AIInfoConfig().aiActionURL + "/api/AI/fileTranslate"
  338. let paraDict = ["fileKey": fileKey,
  339. "from": languageAbbreviation(from),
  340. "to": languageAbbreviation(to),
  341. "uuid": uuid(),
  342. "platform": platform(),
  343. "app_name": app_name()]
  344. var postData = try! JSONSerialization.data(withJSONObject: paraDict)
  345. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  346. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  347. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  348. request.httpMethod = "POST"
  349. request.httpBody = postData
  350. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  351. guard let data = data else {
  352. print(String(describing: error))
  353. return
  354. }
  355. let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:]
  356. if jsonObject != nil {
  357. let data1: NSDictionary = jsonObject!["data"] as? NSDictionary ?? [:]
  358. let code: String = jsonObject!["code"] as? String ?? "06005"
  359. let message: String = jsonObject!["message"] as? String ?? "unknown error"
  360. let error = NSError(domain: message, code: Int(code)!)
  361. if Int(code)! == 200 {
  362. let fileUrl = data1["fileUrl"]
  363. let downFileUrl = data1["downFileUrl"]
  364. let ossDownUrl = data1["ossDownUrl"]
  365. let fileName = data1["fileName"]
  366. let downFileName = data1["downFileName"]
  367. let fromStr = data1["from"]
  368. let toStr = data1["to"]
  369. self.downFileName = downFileName as! String
  370. complete(ResultWrapper(success: true, content: ossDownUrl as! String))
  371. } else {
  372. complete(ResultWrapper(success: false, content: message))
  373. }
  374. } else {
  375. complete(ResultWrapper(success: false, content: "unknown error"))
  376. }
  377. }
  378. task.resume()
  379. } else {
  380. memberAITranslationFileTranslateHandle(fileKey: fileKey, from: from, to: to, complete: complete)
  381. }
  382. }
  383. func memberAITranslationFileTranslateHandle(fileKey: String, from: String, to: String, complete: @escaping KMRequestServerComplete) {
  384. let token: String = KMMemberInfo.shared.access_token
  385. let urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/v1/translate/fileTranslateHandle"
  386. let paraDict = ["fileKey": fileKey,
  387. "from": languageAbbreviation(from),
  388. "to": languageAbbreviation(to)]
  389. let postData = try! JSONSerialization.data(withJSONObject: paraDict)
  390. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  391. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  392. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  393. request.addValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  394. request.httpMethod = "POST"
  395. request.httpBody = postData
  396. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  397. guard let data = data else {
  398. print(String(describing: error))
  399. return
  400. }
  401. let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:]
  402. if jsonObject != nil {
  403. let codeStr: String = jsonObject!["code"] as! String
  404. var code: Int = 0
  405. if let numCode = Int(codeStr) {
  406. code = numCode
  407. }
  408. var result_bool: Bool = true
  409. var message: String = ""
  410. if let value = jsonObject!["message"]{
  411. message = value as! String
  412. }
  413. let result = KMMemberCenterResult(code: code, msg: message, result: result_bool)
  414. if code == 200 {
  415. if jsonObject!["data"] != nil {
  416. let dataDic = jsonObject!["data"] as? NSDictionary ?? [:]
  417. let fileUrl = dataDic["fileUrl"]
  418. let downFileUrl = dataDic["downFileUrl"]
  419. let ossDownUrl = dataDic["ossDownUrl"]
  420. let fileName = dataDic["fileName"]
  421. let downFileName = dataDic["downFileName"]
  422. let fromStr = dataDic["from"]
  423. let toStr = dataDic["to"]
  424. self.downFileName = downFileName as! String
  425. complete(ResultWrapper(success: true, content: ossDownUrl as! String))
  426. }
  427. } else {
  428. complete(ResultWrapper(success: false, content: message))
  429. }
  430. } else {
  431. complete(ResultWrapper(success: false, content: ""))
  432. }
  433. }
  434. task.resume()
  435. }
  436. /**
  437. @abstract 内容翻译
  438. @param q 选中
  439. @param from 初始语言
  440. @param to 结束语言
  441. */
  442. private func aiTranslationTextTrans(q: String, from: String, to: String, complete: @escaping KMRequestServerComplete) {
  443. let infoDictionary = Bundle .main.infoDictionary!
  444. let urlString = AIInfoConfig().aiActionURL + "/api/AI/textTranslate"
  445. var escapedString = q
  446. escapedString = String(data: escapedString.data(using: .utf8)!, encoding: .utf8)!
  447. let paraDict = ["text":escapedString,
  448. "from":from,
  449. "to":to,
  450. "uuid":uuid(),
  451. "platform": platform(),
  452. "app_name": app_name()]
  453. var postData = try! JSONSerialization.data(withJSONObject: paraDict)
  454. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  455. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  456. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  457. request.httpMethod = "POST"
  458. request.httpBody = postData
  459. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  460. guard let data = data else {
  461. print(String(describing: error))
  462. return
  463. }
  464. let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:]
  465. if jsonObject != nil {
  466. let data1: NSDictionary = jsonObject!["data"] as? NSDictionary ?? [:]
  467. let code: String = jsonObject!["code"] as? String ?? "06005"
  468. let message: String = jsonObject!["message"] as? String ?? "unknown error"
  469. let error = NSError(domain: message, code: Int(code)!)
  470. if Int(code)! == 200 {
  471. var resultStr = data1["dst"] as! String
  472. complete(ResultWrapper(success: true, content: resultStr))
  473. } else {
  474. complete(ResultWrapper(success: false, content: message))
  475. }
  476. } else {
  477. complete(ResultWrapper(success: false, content: "unknown error"))
  478. }
  479. }
  480. task.resume()
  481. }
  482. private func aiMemberTranslationTextTrans(q: String, from: String, to: String, complete: @escaping KMRequestServerComplete) {
  483. if(KMMemberInfo.shared.isLogin == true) {
  484. KMUserInfoViewController.refreshTokenUserInfo {[weak self] success, resDic in
  485. if(success == true) {
  486. self?.aiMemberTranslationTextTransReq(q: q, from: from, to: to, complete: complete)
  487. } else {
  488. let code = resDic?.code ?? 200
  489. if(code == 304) {
  490. KMLoginWindowsController.shared.showWindow(nil)
  491. }
  492. }
  493. }
  494. }
  495. }
  496. func aiMemberTranslationTextTransReq(q: String, from: String, to: String, complete: @escaping KMRequestServerComplete) {
  497. let urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/v1/translate/textTrans"
  498. let token: String = KMMemberInfo.shared.access_token
  499. var escapedString = q
  500. escapedString = String(data: escapedString.data(using: .utf8)!, encoding: .utf8)!
  501. let paraDict = ["text":escapedString,
  502. "from":from,
  503. "to":to,
  504. "uuid":uuid(),
  505. "platform": platform(),
  506. "app_name": app_name()]
  507. var postData = try! JSONSerialization.data(withJSONObject: paraDict)
  508. KMAIRequestServer.requestServer.aiMemberRewriting(urlString: urlString, params: paraDict) { formData in
  509. } requestSerializer: { requestSerializer in
  510. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  511. requestSerializer.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  512. } completion: { task, responseObject, error in
  513. if responseObject is KMMemberCenterResult {
  514. let resultObjct = responseObject as! KMMemberCenterResult
  515. let code = resultObjct.code
  516. let message: String = resultObjct.msg ?? ""
  517. if code == 200 {
  518. complete(ResultWrapper(success: true, content: message))
  519. } else {
  520. complete(ResultWrapper(success: false, content: message))
  521. }
  522. } else {
  523. complete(ResultWrapper(success: false, content: "unknown error"))
  524. }
  525. }
  526. }
  527. /**
  528. @abstract重写 & 纠错
  529. @param content 内容
  530. @param state 类型
  531. */
  532. private func aiRewriting(content: String, state: KMAIRewritingState, complete: @escaping KMRequestServerComplete) {
  533. let aiInfo: AIInfo = AIInfoManager.default().aiInfo
  534. if aiInfo.totalToken - aiInfo.usedTimes > 0 {
  535. var urlString = AIInfoConfig().aiActionURL + "/api/AI/rewrite"
  536. if state == .correctTypos {
  537. urlString = AIInfoConfig().aiActionURL + "/api/AI/correctTypos"
  538. }
  539. let params: [String: Any] = ["content": content,
  540. "uuid": uuid(),
  541. "platform": platform(),
  542. "app_name": app_name()]
  543. KMAIRequestServer.requestServer.aiRewriting(urlString: urlString, params: params) { formData in
  544. } requestSerializer: { requestSerializer in
  545. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  546. } completion: { task, responseObject, error in
  547. if responseObject != nil {
  548. let data: NSDictionary = responseObject!["data"] as? NSDictionary ?? [:]
  549. let code: String = responseObject!["code"] as? String ?? "06005"
  550. let message: String = responseObject!["message"] as? String ?? "unknown error"
  551. if Int(code)! == 200 {
  552. complete(ResultWrapper(success: true, content: data["content"] as! String))
  553. } else {
  554. complete(ResultWrapper(success: false, content: message))
  555. }
  556. } else {
  557. complete(ResultWrapper(success: false, content: "unknown error"))
  558. }
  559. }
  560. } else {
  561. if(KMMemberInfo.shared.isLogin == true) {
  562. KMUserInfoViewController.refreshTokenUserInfo {[weak self] success, resDic in
  563. if(success == true) {
  564. self?.aiMemberRewriting(content: content, state: state, complete: complete)
  565. } else {
  566. let code = resDic?.code ?? 200
  567. if(code == 304) {
  568. KMLoginWindowsController.shared.showWindow(nil)
  569. }
  570. }
  571. }
  572. }
  573. }
  574. }
  575. /**
  576. @abstract 深度思考
  577. @param content 内容
  578. @param state 类型
  579. */
  580. private func aiPonder(content: String, complete: @escaping KMRequestServerComplete) {
  581. let aiInfo: AIInfo = AIInfoManager.default().aiInfo
  582. if aiInfo.totalToken - aiInfo.usedTimes > 0 {
  583. var urlString = AIInfoConfig().aiActionURL + "/api/AI/deepSeek"
  584. let params: [String: Any] = ["content": content,
  585. "uuid": uuid(),
  586. "platform": platform(),
  587. "app_name": app_name()]
  588. KMAIRequestServer.requestServer.aiRewriting(urlString: urlString, params: params) { formData in
  589. } requestSerializer: { requestSerializer in
  590. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  591. } completion: { task, responseObject, error in
  592. if responseObject != nil {
  593. let data: NSDictionary = responseObject!["data"] as? NSDictionary ?? [:]
  594. let code: String = responseObject!["code"] as? String ?? "06005"
  595. let message: String = responseObject!["message"] as? String ?? "unknown error"
  596. if Int(code)! == 200 {
  597. complete(ResultWrapper(success: true, content: data["content"] as! String))
  598. } else {
  599. complete(ResultWrapper(success: false, content: message))
  600. }
  601. } else {
  602. complete(ResultWrapper(success: false, content: "unknown error"))
  603. }
  604. }
  605. } else {
  606. if(KMMemberInfo.shared.isLogin == true) {
  607. KMUserInfoViewController.refreshTokenUserInfo {[weak self] success, resDic in
  608. if(success == true) {
  609. self?.aiMemberPonder(content: content, complete: complete)
  610. } else {
  611. let code = resDic?.code ?? 200
  612. if(code == 304) {
  613. KMLoginWindowsController.shared.showWindow(nil)
  614. }
  615. }
  616. }
  617. }
  618. }
  619. }
  620. func aiMemberRewriting(content: String, state: KMAIRewritingState, complete: @escaping KMRequestServerComplete) {
  621. let token: String = KMMemberInfo.shared.access_token
  622. if token == "" {
  623. complete(ResultWrapper(success: false, content: "unknown error"))
  624. }
  625. var urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/api/rewrite"
  626. if state == .correctTypos {
  627. urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/api/correct-typos"
  628. }
  629. let params: [String: Any] = ["content": content]
  630. KMAIRequestServer.requestServer.aiMemberRewriting(urlString: urlString, params: params) { formData in
  631. } requestSerializer: { requestSerializer in
  632. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  633. requestSerializer.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  634. } completion: { task, responseObject, error in
  635. if responseObject is KMMemberCenterResult {
  636. let resultObjct = responseObject as! KMMemberCenterResult
  637. let code = resultObjct.code
  638. let message: String = resultObjct.msg ?? ""
  639. if code == 200 {
  640. complete(ResultWrapper(success: true, content: message))
  641. } else {
  642. complete(ResultWrapper(success: false, content: message))
  643. }
  644. } else {
  645. complete(ResultWrapper(success: false, content: "unknown error"))
  646. }
  647. }
  648. }
  649. func aiMemberPonder(content: String, complete: @escaping KMRequestServerComplete) {
  650. let token: String = KMMemberInfo.shared.access_token
  651. if token == "" {
  652. complete(ResultWrapper(success: false, content: "unknown error"))
  653. }
  654. let urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/api/deepSeek"
  655. let params: [String: Any] = ["content": content]
  656. KMAIRequestServer.requestServer.aiMemberRewriting(urlString: urlString, params: params) { formData in
  657. } requestSerializer: { requestSerializer in
  658. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  659. requestSerializer.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  660. } completion: { task, responseObject, error in
  661. if responseObject is KMMemberCenterResult {
  662. let resultObjct = responseObject as! KMMemberCenterResult
  663. let code = resultObjct.code
  664. let message: String = resultObjct.msg ?? ""
  665. if code == 200 {
  666. complete(ResultWrapper(success: true, content: message))
  667. } else {
  668. complete(ResultWrapper(success: false, content: message))
  669. }
  670. } else {
  671. complete(ResultWrapper(success: false, content: "unknown error"))
  672. }
  673. }
  674. }
  675. /**
  676. @abstract 提取摘要
  677. @param file 文件路径
  678. */
  679. private func extractSummaryFile(file: String, complete: @escaping KMRequestServerComplete) {
  680. let infoDictionary = Bundle .main.infoDictionary!
  681. let urlString = AIInfoConfig().aiActionURL + "/api/AI/extractSummaryFile"
  682. let fileData = FileManager.default.contents(atPath: file)
  683. let params: [String: Any] = ["file": fileData,
  684. "uuid": uuid(),
  685. "platform": platform(),
  686. "app_name": app_name()]
  687. KMAIRequestServer.requestServer.uploadFile(urlString: urlString, params: params) { formData in
  688. let fileURL = URL(fileURLWithPath: file)
  689. try? formData.appendPart(withFileURL: fileURL, name: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream")
  690. } requestSerializer: { requestSerializer in
  691. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  692. } completion: { task, responseObject, error in
  693. if responseObject != nil {
  694. let data: NSDictionary = responseObject!["data"] as? NSDictionary ?? [:]
  695. let code: Int = responseObject!["code"] as? Int ?? 06005
  696. let message: String = responseObject!["message"] as? String ?? "unknown error"
  697. let error = NSError(domain: message, code: code)
  698. if code == 200 {
  699. complete(ResultWrapper(success: true, content: data["summary"] as! String))
  700. } else {
  701. complete(ResultWrapper(success: false, content: message))
  702. }
  703. } else {
  704. let error = NSError(domain: "unknown error", code: 404)
  705. complete(ResultWrapper(success: false, content: "unknown error"))
  706. }
  707. }
  708. }
  709. private func memberExtractSummaryFile(file: String, complete: @escaping KMRequestServerComplete) {
  710. let token: String = KMMemberInfo.shared.access_token
  711. if token == "" {
  712. return
  713. }
  714. let urlString = AIInfoConfig().memberAIActionURL + "/member-system-website/api/extract-file-summary"
  715. let fileData = FileManager.default.contents(atPath: file)
  716. let params: [String: Any] = ["file": fileData]
  717. KMAIRequestServer.requestServer.uploadFile(urlString: urlString, params: params) { formData in
  718. let fileURL = URL(fileURLWithPath: file)
  719. try? formData.appendPart(withFileURL: fileURL, name: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream")
  720. } requestSerializer: { requestSerializer in
  721. requestSerializer.setValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  722. requestSerializer.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  723. } completion: { task, responseObject, error in
  724. if responseObject != nil {
  725. let data: NSDictionary = responseObject!["data"] as? NSDictionary ?? [:]
  726. let code: Int = responseObject!["code"] as? Int ?? 06005
  727. let message: String = responseObject!["message"] as? String ?? "unknown error"
  728. let error = NSError(domain: message, code: code)
  729. if code == 200 {
  730. complete(ResultWrapper(success: true, content: data["summary"] as! String))
  731. } else {
  732. complete(ResultWrapper(success: false, content: message))
  733. }
  734. } else {
  735. let error = NSError(domain: "unknown error", code: 404)
  736. complete(ResultWrapper(success: false, content: "unknown error"))
  737. }
  738. }
  739. }
  740. }
  741. //typealias KMHttpRequestServerComplete = (_ task: URLSessionDataTask?, _ responseObject: AnyObject?, _ error: NSError?) -> Void
  742. class KMAIRequestServer {
  743. var sessionManager: AFHTTPSessionManager!
  744. static let requestServer = KMAIRequestServer()
  745. var task: URLSessionTask?
  746. init() {
  747. let configuration: URLSessionConfiguration = URLSessionConfiguration.default
  748. sessionManager = AFHTTPSessionManager.init(sessionConfiguration: configuration)
  749. sessionManager.securityPolicy = AFSecurityPolicy.default()
  750. }
  751. /**
  752. 上传文件
  753. - 翻译
  754. - 摘要提取
  755. */
  756. func uploadFile(urlString: String,
  757. params: Dictionary<String, Any>?,
  758. body: ((_ formData:AFMultipartFormData) -> Void)?,
  759. requestSerializer: ((_ requestSerializer:AFHTTPRequestSerializer) -> Void)?,
  760. completion: KMHttpRequestServerComplete?) -> Void {
  761. sessionManager.requestSerializer.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
  762. sessionManager.requestSerializer.timeoutInterval = 60
  763. sessionManager.responseSerializer = AFJSONResponseSerializer()
  764. sessionManager.responseSerializer.acceptableContentTypes = ["application/json","text/html","text/json","text/javascript","text/plain","image/gif"]
  765. if (requestSerializer != nil) {
  766. requestSerializer!(sessionManager.requestSerializer);
  767. }
  768. if (body != nil) {
  769. self.task = sessionManager.post(urlString, parameters: params, headers: nil) { formData in
  770. body!(formData)
  771. } progress: { progress in
  772. } success: { task, responseObject in
  773. let responseObject = responseObject as AnyObject
  774. if (completion != nil) {
  775. completion!(task,responseObject,nil);
  776. }
  777. } failure: { task, error in
  778. if (completion != nil) {
  779. completion!(task, nil, error as NSError);
  780. }
  781. }
  782. } else {
  783. self.task = sessionManager.post(urlString, parameters: params, headers: nil) { progress in
  784. } success: { task, responseObject in
  785. if (completion != nil) {
  786. let responseObject = responseObject as AnyObject
  787. completion!(task,responseObject,nil);
  788. }
  789. } failure: { task, error in
  790. if (completion != nil) {
  791. completion!(task, nil, error as NSError);
  792. }
  793. }
  794. }
  795. }
  796. /**
  797. 文件翻译
  798. */
  799. func aiFileTranslateHandle(urlString: String,
  800. params: Dictionary<String, Any>?,
  801. body: ((_ formData:AFMultipartFormData) -> Void)?,
  802. requestSerializer: ((_ requestSerializer:AFHTTPRequestSerializer) -> Void)?,
  803. completion: KMHttpRequestServerComplete?) -> Void {
  804. sessionManager.requestSerializer = AFJSONRequestSerializer()
  805. sessionManager.responseSerializer = AFJSONResponseSerializer()
  806. sessionManager.responseSerializer.acceptableContentTypes = ["application/json","text/html","text/json","text/javascript","text/plain","image/gif"]
  807. if (requestSerializer != nil) {
  808. requestSerializer!(sessionManager.requestSerializer);
  809. }
  810. if (body != nil) {
  811. self.task = sessionManager.post(urlString, parameters: params, headers: nil) { formData in
  812. body!(formData)
  813. } progress: { progress in
  814. } success: { task, responseObject in
  815. let responseObject = responseObject as AnyObject
  816. if (completion != nil) {
  817. completion!(task,responseObject,nil);
  818. }
  819. } failure: { task, error in
  820. if (completion != nil) {
  821. completion!(task, nil, error as NSError);
  822. }
  823. }
  824. } else {
  825. self.task = sessionManager.post(urlString, parameters: params, headers: nil) { progress in
  826. } success: { task, responseObject in
  827. if (completion != nil) {
  828. let responseObject = responseObject as AnyObject
  829. completion!(task,responseObject,nil);
  830. }
  831. } failure: { task, error in
  832. if (completion != nil) {
  833. completion!(task, nil, error as NSError);
  834. }
  835. }
  836. }
  837. }
  838. /**
  839. 重写
  840. */
  841. func aiRewriting(urlString: String,
  842. params: Dictionary<String, Any>?,
  843. body: ((_ formData:AFMultipartFormData) -> Void)?,
  844. requestSerializer: ((_ requestSerializer:AFHTTPRequestSerializer) -> Void)?,
  845. completion: KMHttpRequestServerComplete?) -> Void {
  846. sessionManager.requestSerializer.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
  847. sessionManager.requestSerializer.timeoutInterval = 180
  848. sessionManager.responseSerializer = AFJSONResponseSerializer()
  849. sessionManager.responseSerializer.acceptableContentTypes = ["application/json","text/html","text/json","text/javascript","text/plain","image/gif"]
  850. if (requestSerializer != nil) {
  851. requestSerializer!(sessionManager.requestSerializer);
  852. }
  853. if (body != nil) {
  854. self.task = sessionManager.post(urlString, parameters: params, headers: nil) { formData in
  855. body!(formData)
  856. } progress: { progress in
  857. } success: { task, responseObject in
  858. let responseObject = responseObject as AnyObject
  859. if (completion != nil) {
  860. completion!(task,responseObject,nil);
  861. }
  862. } failure: { task, error in
  863. if (completion != nil) {
  864. completion!(task, nil, error as NSError);
  865. }
  866. }
  867. } else {
  868. self.task = sessionManager.post(urlString, parameters: params, headers: nil) { progress in
  869. } success: { task, responseObject in
  870. if (completion != nil) {
  871. let responseObject = responseObject as AnyObject
  872. completion!(task,responseObject,nil);
  873. }
  874. } failure: { task, error in
  875. if (completion != nil) {
  876. completion!(task, nil, error as NSError);
  877. }
  878. }
  879. }
  880. }
  881. func aiMemberRewriting(urlString: String,
  882. params: Dictionary<String, Any>?,
  883. body: ((_ formData:AFMultipartFormData) -> Void)?,
  884. requestSerializer: ((_ requestSerializer:AFHTTPRequestSerializer) -> Void)?,
  885. completion: KMHttpRequestServerComplete?) -> Void {
  886. let token: String = KMMemberInfo.shared.access_token
  887. let urlString = urlString
  888. let paraDict: [String: Any] = params!
  889. let postData = try! JSONSerialization.data(withJSONObject: paraDict)
  890. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: 180)
  891. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  892. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  893. request.addValue("Bearer " + token, forHTTPHeaderField: "Authorization")
  894. request.httpMethod = "POST"
  895. request.httpBody = postData
  896. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  897. guard let data = data else {
  898. print(String(describing: error))
  899. return
  900. }
  901. let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:]
  902. if jsonObject != nil {
  903. let codeStr: String = jsonObject!["code"] as? String ?? ""
  904. var code: Int = 0
  905. if let numCode = Int(codeStr) {
  906. code = numCode
  907. }
  908. var result_bool: Bool = true
  909. var message: String = ""
  910. if let value = jsonObject!["message"]{
  911. message = value as! String
  912. }
  913. if let string = jsonObject!["data"] {
  914. let dataDic = jsonObject!["data"] as? NSDictionary ?? [:]
  915. if let dataStr = dataDic["content"] {
  916. message = dataStr as! String
  917. result_bool = true
  918. }
  919. }
  920. let result = KMMemberCenterResult(code: code, msg: message, result: result_bool)
  921. if code == 200 {
  922. if (completion != nil) {
  923. completion!(nil, result, nil);
  924. }
  925. } else {
  926. if (completion != nil) {
  927. completion!(nil, result, error as? NSError);
  928. }
  929. }
  930. } else {
  931. if (completion != nil) {
  932. completion!(nil, nil, error as? NSError);
  933. }
  934. }
  935. }
  936. task.resume()
  937. }
  938. }