O2BaseJsMessageHandler.swift 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. //
  2. // O2BaseJsMessageHandler.swift
  3. // O2Platform
  4. //
  5. // Created by FancyLou on 2019/4/26.
  6. // Copyright © 2019 zoneland. All rights reserved.
  7. //
  8. import UIKit
  9. import WebKit
  10. import Alamofire
  11. import ObjectMapper
  12. import CocoaLumberjack
  13. import BSImagePicker
  14. import Photos
  15. class O2BaseJsMessageHandler: NSObject, O2WKScriptMessageHandlerImplement {
  16. let viewController: BaseWebViewUIViewController
  17. var uploadImageData: O2WebViewUploadImage? = nil
  18. init(viewController: BaseWebViewUIViewController) {
  19. self.viewController = viewController
  20. }
  21. func userController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  22. let name = message.name
  23. switch name {
  24. case "o2mLog":
  25. if message.body is NSString {
  26. let log = message.body as! NSString
  27. DDLogDebug("console.log: \(log)")
  28. }else {
  29. DDLogDebug("console.log: unkown type \(message.body)")
  30. }
  31. break
  32. case "ReplyAction":
  33. DDLogDebug("回复 帖子 message.body = \(message.body)")
  34. if !O2AuthSDK.shared.isBBSMute() {
  35. let pId : String?
  36. if message.body is NSDictionary {
  37. let parentId:NSDictionary = message.body as! NSDictionary
  38. pId = parentId["body"] as? String
  39. }else if message.body is NSString {
  40. pId = String(message.body as! NSString)
  41. }else {
  42. pId = nil
  43. }
  44. self.viewController.performSegue(withIdentifier: "showReplyActionSegue", sender: pId)
  45. } else {
  46. DDLogError("当前用户已被禁言!")
  47. }
  48. break
  49. case "openO2Work":
  50. DDLogDebug("打开工作界面。。。。。")
  51. let body = message.body
  52. if body is NSDictionary {
  53. let dic = body as! NSDictionary
  54. let work = dic["work"] as? String
  55. let workCompleted = dic["workCompleted"] as? String
  56. let title = dic["title"] as? String
  57. self.openWork(work: (work ?? ""), workCompleted: (workCompleted ?? ""), title: (title ?? ""))
  58. }else {
  59. DDLogError("message body 不是一个字典。。。。。。")
  60. }
  61. break
  62. case "openO2WorkSpace":
  63. DDLogDebug("打开工作列表。。。。。")
  64. if message.body is NSString {
  65. let type = message.body as! NSString
  66. self.openO2WorkSpace(type: String(type))
  67. }else {
  68. DDLogError("打开工作列表失败, type不存在!!!!!")
  69. }
  70. break
  71. case "openO2CmsApplication":
  72. DDLogDebug("打开cms栏目。。。。。")
  73. if message.body is NSString {
  74. let appId = message.body as! NSString
  75. self.openCmsApplication(appId: String(appId))
  76. }else if message.body is NSDictionary {
  77. let appBody = message.body as! NSDictionary
  78. if let appId = appBody["appId"] {
  79. self.openCmsApplication(appId: (appId as! String))
  80. }
  81. }else {
  82. DDLogError("打开cms栏目失败, appId不存在!!!!!")
  83. }
  84. break
  85. case "openO2CmsDocument":
  86. DDLogDebug("打开cms 文档。。。。。")
  87. if message.body is NSDictionary {
  88. let appBody = message.body as! NSDictionary
  89. let docId = appBody["docId"] as? String
  90. let docTitle = appBody["docTitle"] as? String
  91. var readonly = true
  92. if let options = appBody["options"] as? String {
  93. DDLogDebug("options json: \(options)")
  94. let optionJson = JSON(parseJSON: options)
  95. if let re = optionJson["readonly"].bool {
  96. readonly = re
  97. }
  98. }
  99. self.openCmsDocument(docId: (docId ?? "" ), docTitle: (docTitle ?? ""), readonly: readonly)
  100. }else {
  101. DDLogError("打开cms文档失败, 参数不存在!!!!!")
  102. }
  103. break
  104. case "openO2Meeting":
  105. DDLogDebug("打开会议管理。。。。。")
  106. self.openO2Meeting()
  107. break
  108. case "openO2Calendar":
  109. DDLogDebug("打开日程管理。。。。。")
  110. self.openO2Calendar()
  111. break
  112. case "openScan":
  113. self.openScan()
  114. break
  115. case "openO2Alert":
  116. if message.body is NSString {
  117. let msg = message.body as! NSString
  118. self.openO2Alert(message: String(msg))
  119. }
  120. break
  121. case "closeNativeWindow":
  122. DDLogDebug("关闭窗口!!!!")
  123. self.viewController.delegate?.closeUIViewWindow()
  124. break
  125. case "openDingtalk":
  126. self.openDingtalk()
  127. break
  128. case "actionBarLoaded":
  129. self.viewController.delegate?.actionBarLoaded(show: true)
  130. break
  131. case "uploadImage2FileStorage":
  132. DDLogDebug("这里进入了上传图片控件。。。。。。。。。。。。。。。")
  133. if message.body is NSString {
  134. let json = message.body as! NSString
  135. DDLogDebug("上传图片:\(json)")
  136. if let uploadImage = O2WebViewUploadImage.deserialize(from: String(json)) {
  137. self.uploadImageData = uploadImage
  138. self.uploadImageData?.scale = 800
  139. // 显示菜单 选择拍照或相册
  140. DispatchQueue.main.async {
  141. self.viewController.showSheetAction(title: "提示", message: "请选择方式", actions: [
  142. UIAlertAction(title: "从相册选择", style: .default, handler: { (action) in
  143. self.chooseFromAlbum()
  144. }),
  145. UIAlertAction(title: "拍照", style: .default, handler: { (action) in
  146. self.takePhoto()
  147. })
  148. ])
  149. }
  150. }else {
  151. DDLogError("解析json失败")
  152. self.viewController.showError(title: "参数不正确!")
  153. }
  154. }else {
  155. DDLogError("传入参数类型不正确!")
  156. self.viewController.showError(title: "参数不正确!")
  157. }
  158. break
  159. default:
  160. DDLogError("传入js变量名称不正确,name:\(name)")
  161. if message.body is NSString {
  162. let json = message.body as! NSString
  163. DDLogDebug("console.log: \(json)")
  164. }
  165. break
  166. }
  167. }
  168. private func openO2Alert(message: String) {
  169. DDLogDebug("O2 alert msg:\(message)")
  170. self.viewController.showSystemAlert(title: "", message: message) { (action) in
  171. DDLogDebug("O2 alert ok button clicked! ")
  172. }
  173. }
  174. private func openWork(work: String, workCompleted: String, title: String) {
  175. let storyBoard = UIStoryboard(name: "task", bundle: nil)
  176. let destVC = storyBoard.instantiateViewController(withIdentifier: "todoTaskDetailVC") as! TodoTaskDetailViewController
  177. let json = """
  178. {"work":"\(work)", "workCompleted":"\(workCompleted)", "title":"\(title)"}
  179. """
  180. DDLogDebug("openWork json: \(json)")
  181. let todo = TodoTask(JSONString: json)
  182. destVC.todoTask = todo
  183. destVC.backFlag = 3 //隐藏就行
  184. self.viewController.show(destVC, sender: nil)
  185. }
  186. // task taskCompleted read readCompleted
  187. private func openO2WorkSpace(type: String) {
  188. let storyBoard = UIStoryboard(name: "task", bundle: nil)
  189. let destVC = storyBoard.instantiateViewController(withIdentifier: "todoTask")
  190. let nsType = NSString(string: type).lowercased
  191. DDLogDebug("打开工作区, type:\(nsType)")
  192. if "taskcompleted" == nsType {
  193. AppConfigSettings.shared.taskIndex = 2
  194. }else if "read" == nsType {
  195. AppConfigSettings.shared.taskIndex = 1
  196. }else if "readcompleted" == nsType {
  197. AppConfigSettings.shared.taskIndex = 3
  198. }else {
  199. AppConfigSettings.shared.taskIndex = 0
  200. }
  201. self.viewController.show(destVC, sender: nil)
  202. }
  203. private func openCmsApplication(appId: String) {
  204. DDLogInfo("打开栏目, appId:\(appId)")
  205. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(CMSContext.cmsContextKey, query: CMSContext.cmsCategoryListQuery, parameter: ["##appId##": appId as AnyObject])
  206. self.viewController.showLoading(title: "Loading...")
  207. AF.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
  208. switch response.result {
  209. case .success(let val):
  210. let categroyList = Mapper<CMSCategoryData>().map(JSONObject: val)
  211. if let count = categroyList?.data?.count {
  212. if count > 0 {
  213. let storyBoard = UIStoryboard(name: "information", bundle: nil)
  214. let destVC = storyBoard.instantiateViewController(withIdentifier: "CMSCategoryListController") as! CMSCategoryListViewController
  215. destVC.title = categroyList?.data?.first?.appName ?? ""
  216. let d = CMSData(JSONString: "{\"id\":\"\"}")
  217. d?.wrapOutCategoryList = categroyList?.data
  218. destVC.cmsData = d
  219. self.viewController.show(destVC, sender: nil)
  220. }
  221. }
  222. self.viewController.hideLoading()
  223. case .failure(let err):
  224. DDLogError(err.localizedDescription)
  225. self.viewController.hideLoading()
  226. }
  227. }
  228. }
  229. private func openCmsDocument(docId: String, docTitle: String, readonly: Bool) {
  230. DDLogInfo("打开文档, docId:\(docId) , docTitle:\(docTitle) , readonly: \(readonly)")
  231. let storyBoard = UIStoryboard(name: "information", bundle: nil)
  232. let destVC = storyBoard.instantiateViewController(withIdentifier: "CMSSubjectDetailVC") as! CMSItemDetailViewController
  233. let json = """
  234. {"title":"\(docTitle)", "id":"\(docId)", "readonly": \(readonly)}
  235. """
  236. destVC.itemData = CMSCategoryItemData(JSONString: json)
  237. self.viewController.show(destVC, sender: nil)
  238. }
  239. private func openO2Meeting() {
  240. let storyBoard = UIStoryboard(name: "meeting", bundle: nil)
  241. if let destVC = storyBoard.instantiateInitialViewController() {
  242. self.viewController.show(destVC, sender: nil)
  243. }else {
  244. DDLogError("会议 模块打开失败,没有找到vc")
  245. }
  246. }
  247. private func openO2Calendar() {
  248. let storyBoard = UIStoryboard(name: "calendar", bundle: nil)
  249. if let destVC = storyBoard.instantiateInitialViewController() {
  250. self.viewController.show(destVC, sender: nil)
  251. }else {
  252. DDLogError("calendar 模块打开失败,没有找到vc")
  253. }
  254. }
  255. private func openScan() {
  256. ScanHelper.openScan(vc: self.viewController)
  257. }
  258. private func openDingtalk() {
  259. UIApplication.shared.open(URL(string: "dingtalk://dingtalkclient/")!, options: [:]) { (result) in
  260. DDLogInfo("打开了钉钉。。。。\(result)")
  261. }
  262. }
  263. // 表单图片控件 从相册选择
  264. private func chooseFromAlbum() {
  265. let vc = FileBSImagePickerViewController().bsImagePicker()
  266. self.viewController.presentImagePicker(vc, select: nil, deselect: nil, cancel: nil, finish: { (arr) in
  267. let count = arr.count
  268. DDLogDebug("选择了照片数量:\(count)")
  269. if count > 0 {
  270. //获取照片
  271. let asset = arr[0]
  272. if asset.mediaType == .image {
  273. let options = PHImageRequestOptions()
  274. options.isSynchronous = true
  275. options.deliveryMode = .fastFormat
  276. options.resizeMode = .fast //.none
  277. var fName = (asset.value(forKey: "filename") as? String) ?? "untitle.png"
  278. // 判断是否是heif
  279. var isHEIF = false
  280. if #available(iOS 9.0, *) {
  281. let resList = PHAssetResource.assetResources(for: asset)
  282. resList.forEachEnumerated { (idx, res) in
  283. let uti = res.uniformTypeIdentifier
  284. if uti == "public.heif" || uti == "public.heic" {
  285. isHEIF = true
  286. }
  287. }
  288. } else {
  289. if let uti = asset.value(forKey: "uniformTypeIdentifier") as? String {
  290. if uti == "public.heif" || uti == "public.heic" {
  291. isHEIF = true
  292. }
  293. }
  294. }
  295. PHImageManager.default().requestImageData(for: asset, options: options, resultHandler: { (imageData, result, imageOrientation, dict) in
  296. DispatchQueue.main.async {
  297. self.viewController.showLoading(title: "上传中...")
  298. }
  299. var newData = imageData
  300. if isHEIF {
  301. let image: UIImage = UIImage(data: imageData!)!
  302. newData = image.jpegData(compressionQuality: 1.0)!
  303. fName += ".jpg"
  304. }
  305. //处理图片旋转的问题
  306. if imageOrientation != UIImage.Orientation.up && newData != nil {
  307. let newImage = UIImage(data: newData!)?.fixOrientation()
  308. if newImage != nil {
  309. newData = newImage?.pngData()
  310. }
  311. }
  312. self.uploadImage2Server(imageData: newData!, fName: fName)
  313. })
  314. }else {
  315. DDLogError("选择类型不正确,不是照片")
  316. }
  317. }
  318. }, completion: nil)
  319. }
  320. // 表单图片控件 拍照功能
  321. private func takePhoto() {
  322. self.viewController.takePhoto(delegate: self)
  323. }
  324. //表单图片控件 上传图片到服务器
  325. private func uploadImage2Server(imageData: Data, fName: String) {
  326. guard let data = self.uploadImageData else {
  327. self.viewController.showError(title: "参数传入为空,无法上传图片")
  328. return
  329. }
  330. if data.callback == nil || data.callback.isEmpty || data.reference == nil || data.reference.isEmpty
  331. || data.referencetype == nil || data.referencetype.isEmpty {
  332. self.viewController.showError(title: "参数传入为空,无法上传图片")
  333. return
  334. }
  335. let fileUploadURL = AppDelegate.o2Collect
  336. .generateURLWithAppContextKey(
  337. FileContext.fileContextKey,
  338. query: FileContext.fileUploadReference,
  339. parameter: [
  340. "##referencetype##": data.referencetype as AnyObject,
  341. "##reference##": data.reference as AnyObject,
  342. "##scale##": String(data.scale) as AnyObject
  343. ],
  344. coverted: true)!
  345. DDLogDebug(fileUploadURL)
  346. let tokenName = O2AuthSDK.shared.tokenName()
  347. let headers:HTTPHeaders = [tokenName:(O2AuthSDK.shared.myInfo()?.token!)!]
  348. DispatchQueue.global(qos: .userInitiated).async {
  349. AF.upload(multipartFormData: { (mData) in
  350. mData.append(imageData, withName: "file", fileName: fName, mimeType: "image/png")
  351. }, to: fileUploadURL, method: .put, headers: headers).responseJSON { (response) in
  352. if let err = response.error {
  353. DispatchQueue.main.async {
  354. DDLogError(err.localizedDescription)
  355. self.viewController.showError(title: "上传图片失败")
  356. }
  357. } else {
  358. if let resData = response.data {
  359. let attachId = JSON(resData)["data"]["id"].string!
  360. data.fileId = attachId
  361. }
  362. let callback = data.callback!
  363. let callbackParameterJson = data.toJSONString()
  364. if callbackParameterJson != nil {
  365. DDLogDebug("json:\(callbackParameterJson!)")
  366. DispatchQueue.main.async {
  367. let callJS = "\(callback)('\(callbackParameterJson!)')"
  368. DDLogDebug("执行js:\(callJS)")
  369. self.viewController.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  370. self.viewController.showSuccess(title: "上传成功")
  371. })
  372. }
  373. }
  374. }
  375. }
  376. }
  377. }
  378. }
  379. // MARK: - 拍照返回
  380. extension O2BaseJsMessageHandler: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
  381. func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
  382. if let image = info[.editedImage] as? UIImage, let newData = image.pngData() {
  383. let fileName = "\(UUID().uuidString).png"
  384. // let size = image.size
  385. self.uploadImage2Server(imageData: newData, fName: fileName)
  386. } else {
  387. DDLogError("没有选择到图片!")
  388. }
  389. picker.dismiss(animated: true, completion: nil)
  390. }
  391. }