CMSItemDetailViewController.swift 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. //
  2. // CMSItemDetailViewController.swift
  3. // O2Platform
  4. //
  5. // Created by 刘振兴 on 2016/12/9.
  6. // Copyright © 2016年 zoneland. All rights reserved.
  7. //
  8. import UIKit
  9. import WebKit
  10. import Alamofire
  11. import AlamofireObjectMapper
  12. import SwiftyJSON
  13. import ObjectMapper
  14. import QuickLook
  15. import Photos
  16. import CocoaLumberjack
  17. class CMSItemDetailViewController: BaseWebViewUIViewController {
  18. private let qlController = TaskAttachmentPreviewController()
  19. fileprivate var currentFileURLS:[NSURL] = []
  20. var itemData:CMSCategoryItemData? {
  21. didSet {
  22. title = itemData?.title
  23. itemUrl = AppDelegate.o2Collect.genrateURLWithWebContextKey(DesktopContext.DesktopContextKey, query: DesktopContext.cmsItemDetailQuery, parameter: ["##documentId##":itemData?.id as AnyObject])!
  24. }
  25. }
  26. var documentId:String?{
  27. didSet {
  28. itemUrl = AppDelegate.o2Collect.genrateURLWithWebContextKey(DesktopContext.DesktopContextKey, query: DesktopContext.cmsItemDetailQuery, parameter: ["##documentId##":documentId as AnyObject])!
  29. }
  30. }
  31. var itemUrl = ""
  32. var fromCreateDocVC = false
  33. //cms操作control
  34. var myControl: [String : AnyObject]?
  35. //cms底部操作按钮 toolbar
  36. var toolbarView: UIToolbar!
  37. //webview的容器
  38. @IBOutlet weak var webViewContainer: UIView!
  39. @IBOutlet weak var progressView: UIProgressView!
  40. override func viewWillAppear(_ animated: Bool) {
  41. super.viewWillAppear(animated)
  42. //监控进度
  43. webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
  44. }
  45. override func viewWillDisappear(_ animated: Bool) {
  46. super.viewWillDisappear(animated)
  47. webView.removeObserver(self, forKeyPath: "estimatedProgress")
  48. }
  49. override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  50. if keyPath == "estimatedProgress" {
  51. progressView.isHidden = webView.estimatedProgress == 1
  52. progressView.setProgress(Float(webView.estimatedProgress), animated: true)
  53. }
  54. }
  55. override func viewDidLoad() {
  56. super.viewDidLoad()
  57. //自定义返回按钮
  58. self.navigationItem.hidesBackButton = true
  59. self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "icon_fanhui"), style: .plain, target: self, action: #selector(goBack))
  60. self.navigationItem.leftItemsSupplementBackButton = true
  61. // 底部操作按钮toolbar
  62. self.toolbarView = UIToolbar(frame: CGRect(x: 0, y: self.view.height - 44, width: self.view.width, height: 44))
  63. self.automaticallyAdjustsScrollViewInsets = false
  64. //先添加js注入
  65. addScriptMessageHandler(key: "cmsFormLoaded", handler: self)
  66. addScriptMessageHandler(key: "uploadAttachment", handler: self)
  67. addScriptMessageHandler(key: "downloadAttachment", handler: self)
  68. addScriptMessageHandler(key: "replaceAttachment", handler: self)
  69. addScriptMessageHandler(key: "openDocument", handler: self)
  70. addScriptMessageHandler(key: "closeDocumentWindow", handler: self)
  71. self.theWebView()
  72. self.qlInit()
  73. }
  74. override func didReceiveMemoryWarning() {
  75. super.didReceiveMemoryWarning()
  76. // Dispose of any resources that can be recreated.
  77. }
  78. override func theWebView(){
  79. super.theWebView()
  80. self.webViewContainer.addSubview(self.webView)
  81. self.webView.translatesAutoresizingMaskIntoConstraints = false
  82. let top = NSLayoutConstraint(item: self.webView as Any, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.webViewContainer, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
  83. let bottom = NSLayoutConstraint(item: self.webView as Any, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.webViewContainer, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
  84. let trailing = NSLayoutConstraint(item: self.webView as Any, attribute: NSLayoutConstraint.Attribute.trailing, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.webViewContainer, attribute: NSLayoutConstraint.Attribute.trailing, multiplier: 1, constant: 0)
  85. let leading = NSLayoutConstraint(item: self.webView as Any, attribute: NSLayoutConstraint.Attribute.leading, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.webViewContainer, attribute: NSLayoutConstraint.Attribute.leading, multiplier: 1, constant: 0)
  86. self.webViewContainer.addConstraints([top, bottom, trailing, leading])
  87. webView.navigationDelegate = self
  88. webView.uiDelegate = self
  89. webView.allowsBackForwardNavigationGestures = true
  90. loadItemDetail()
  91. }
  92. @objc func goBack() {
  93. if self.fromCreateDocVC {//创建文档页面跳过来的 返回的时候就多跳一级
  94. self.performSegue(withIdentifier: "back2DocumentListSegue", sender: nil)
  95. } else {
  96. self.navigationController?.popViewController(animated: false)
  97. }
  98. }
  99. private func qlInit(){
  100. // 文档查看器
  101. self.qlController.dataSource = qlController
  102. self.qlController.delegate = qlController
  103. }
  104. private func loadItemDetail() {
  105. DDLogDebug("url:\(itemUrl)")
  106. if let urlR = URL(string: itemUrl) {
  107. let req = URLRequest(url: urlR)
  108. webView.load(req)
  109. }else {
  110. webView.loadHTMLString("<h2>没有获取到正确的URL!</h2>", baseURL: nil)
  111. }
  112. }
  113. @objc private func qlCloseWindow(){
  114. self.dismiss(animated: true, completion: {
  115. })
  116. }
  117. private func setupBottomToolbar() {
  118. var items: [UIBarButtonItem] = []
  119. if self.myControl != nil {
  120. let spaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
  121. if let allowDelete = self.myControl!["allowDeleteDocument"] as? Bool {
  122. if allowDelete { //删除文档
  123. DDLogDebug("删除文档。。。。。。。。。。。。。。。。。。。。。。安装按钮")
  124. let deleteBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
  125. deleteBtn.setTitle("删除", for: .normal)
  126. deleteBtn.setTitleColor(base_color, for: .normal)
  127. deleteBtn.addTapGesture { (tap) in
  128. self.itemBtnDocDeleteAction()
  129. }
  130. let deleteItem = UIBarButtonItem(customView: deleteBtn)
  131. items.append(spaceItem)
  132. items.append(deleteItem)
  133. items.append(spaceItem)
  134. }
  135. }
  136. if let allowPublishDocument = self.myControl!["allowPublishDocument"] as? Bool {
  137. if allowPublishDocument { //发布文档
  138. DDLogDebug("发布文档。。。。。。。。。。。。。。。。。。。。。。安装按钮")
  139. let publishBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
  140. publishBtn.setTitle("发布", for: .normal)
  141. publishBtn.setTitleColor(base_color, for: .normal)
  142. publishBtn.addTapGesture { (tap) in
  143. self.itemBtnDocPublishAction()
  144. }
  145. let publishItem = UIBarButtonItem(customView: publishBtn)
  146. items.append(spaceItem)
  147. items.append(publishItem)
  148. items.append(spaceItem)
  149. }
  150. }
  151. self.layoutBottomBar(items: items)
  152. }
  153. }
  154. private func layoutBottomBar(items: [UIBarButtonItem]) {
  155. if items.count > 0 {
  156. self.toolbarView.items = items
  157. self.view.addSubview(self.toolbarView)
  158. self.toolbarView.translatesAutoresizingMaskIntoConstraints = false
  159. let heightC = NSLayoutConstraint(item: self.toolbarView as Any, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 0.0, constant: 44)
  160. self.toolbarView.addConstraint(heightC)
  161. let bottom = NSLayoutConstraint(item: self.toolbarView as Any, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
  162. let trailing = NSLayoutConstraint(item: self.toolbarView as Any, attribute: NSLayoutConstraint.Attribute.trailing, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.trailing, multiplier: 1, constant: 0)
  163. let leading = NSLayoutConstraint(item: self.toolbarView as Any, attribute: NSLayoutConstraint.Attribute.leading, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.leading, multiplier: 1, constant: 0)
  164. self.view.addConstraints([bottom, leading, trailing])
  165. self.view.constraints.forEach { (constraint) in
  166. if constraint.identifier == "webViewContainerBottom" {
  167. self.view.removeConstraint(constraint)
  168. }
  169. }
  170. let webcTop = NSLayoutConstraint(item: self.webViewContainer as Any, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.toolbarView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
  171. self.view.addConstraint(webcTop)
  172. self.view.layoutIfNeeded()
  173. }
  174. }
  175. //删除文档
  176. private func itemBtnDocDeleteAction() {
  177. self.showDefaultConfirm(title: "提示", message: "你确定要删除当前文档?") { (action) in
  178. let callJS = "layout.appForm.deleteDocumentForMobile()"
  179. self.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  180. //
  181. })
  182. }
  183. }
  184. //发布文档 layout.appForm.publishDocument()
  185. private func itemBtnDocPublishAction() {
  186. let callJS = "layout.appForm.publishDocument()"
  187. self.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  188. //
  189. })
  190. }
  191. }
  192. extension CMSItemDetailViewController:WKNavigationDelegate,WKUIDelegate {
  193. func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
  194. DDLogDebug("didFailProvisionalNavigation \(String(describing: navigation)) error = \(error)")
  195. }
  196. func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
  197. DDLogDebug("didStartProvisionalNavigation \(String(describing: navigation))")
  198. }
  199. func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
  200. DDLogDebug("didCommit")
  201. }
  202. func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
  203. DDLogDebug("didFinish")
  204. //self.setupData()
  205. }
  206. func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
  207. DDLogDebug("didFail")
  208. DDLogError(error.localizedDescription)
  209. }
  210. }
  211. //MARK: js脚本
  212. extension CMSItemDetailViewController: O2WKScriptMessageHandlerImplement {
  213. func userController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  214. let name = message.name
  215. switch name {
  216. case "cmsFormLoaded":
  217. DDLogDebug("cmsFormLoaded start。。。。")
  218. if let newControls = (message.body as? NSString) {
  219. let str = newControls as String
  220. DDLogDebug("cmsFormLoaded , controls :\(str)")
  221. let json = JSON.init(parseJSON: str)
  222. self.myControl = json.dictionaryObject! as [String: AnyObject]
  223. self.setupBottomToolbar()
  224. }
  225. break
  226. case "uploadAttachment":
  227. ZonePermissions.requestImagePickerAuthorization(callback: { (zoneStatus) in
  228. if zoneStatus == ZoneAuthorizationStatus.zAuthorizationStatusAuthorized {
  229. let site = (message.body as! NSDictionary)["site"]
  230. self.uploadAttachment(site as! String)
  231. }else {
  232. self.gotoApplicationSettings(alertMessage: "需要照片允许访问权限,是否跳转到手机设置页面开启相机权限?")
  233. }
  234. })
  235. break
  236. case "downloadAttachment":
  237. let attachmentId = (message.body as! NSDictionary)["id"]
  238. self.downloadAttachment(attachmentId as! String)
  239. break
  240. case "replaceAttachment":
  241. let attachmentId = (message.body as! NSDictionary)["id"] as! String
  242. let site = (message.body as! NSDictionary)["site"] as? String
  243. self.replaceAttachment(attachmentId, site ?? "")
  244. break
  245. case "openDocument":
  246. let url = (message.body as! NSString)
  247. self.downloadDocumentAndPreview(String(url))
  248. break
  249. case "closeDocumentWindow":
  250. self.goBack()
  251. break
  252. default:
  253. DDLogError("未知方法名:\(name)!")
  254. break
  255. }
  256. }
  257. //上传附件
  258. private func uploadAttachment(_ site:String){
  259. //选择附件上传
  260. var id = ""
  261. if self.documentId != nil {
  262. id = self.documentId!
  263. }else {
  264. id = self.itemData!.id!
  265. }
  266. let updloadURL = AppDelegate.o2Collect.generateURLWithAppContextKey(CMSContext.cmsContextKey, query: CMSContext.cmsAttachmentUpload, parameter: ["##docId##":id as AnyObject])
  267. self.uploadAttachment(site, uploadURL: updloadURL!)
  268. }
  269. private func uploadAttachment(_ site:String,uploadURL url:String){
  270. let vc = FileBSImagePickerViewController().bsImagePicker()
  271. presentImagePicker(vc, select: { (asset: PHAsset) -> Void in
  272. // User selected an asset.
  273. // Do something with it, start upload perhaps?
  274. }, deselect: { (asset: PHAsset) -> Void in
  275. // User deselected an assets.
  276. // Do something, cancel upload?
  277. }, cancel: { (assets: [PHAsset]) -> Void in
  278. // User cancelled. And this where the assets currently selected.
  279. }, finish: { (assets: [PHAsset]) -> Void in
  280. for asset in assets {
  281. switch asset.mediaType {
  282. case .audio:
  283. DDLogDebug("Audio")
  284. case .image:
  285. let options = PHImageRequestOptions()
  286. options.isSynchronous = true
  287. options.deliveryMode = .fastFormat
  288. options.resizeMode = .none
  289. let fName = (asset.value(forKey: "filename") as? String) ?? "untitle.png"
  290. PHImageManager.default().requestImageData(for: asset, options: options, resultHandler: { (imageData, result, imageOrientation, dict) in
  291. //DDLogDebug("result = \(result) imageOrientation = \(imageOrientation) \(dict)")
  292. // let fileURL = dict?["PHImageFileURLKey"] as! URL
  293. DispatchQueue.main.async {
  294. self.showLoading(title: "上传中...")
  295. }
  296. DispatchQueue.global(qos: .userInitiated).async {
  297. // MARK: - 这里需要修改
  298. AF.upload(multipartFormData: { (mData) in
  299. //mData.append(fileURL, withName: "file")
  300. mData.append(imageData!, withName: "file", fileName: fName, mimeType: "application/octet-stream")
  301. let siteData = site.data(using: String.Encoding.utf8, allowLossyConversion: false)
  302. mData.append(siteData!, withName: "site")
  303. }, to: url).responseJSON(completionHandler: { (reponse) in
  304. print(reponse)
  305. if let err = reponse.error {
  306. DispatchQueue.main.async {
  307. DDLogError(err.localizedDescription)
  308. self.showError(title: "上传失败")
  309. }
  310. }else {
  311. let attachId = JSON(reponse.data)["data"]["id"].string!
  312. DispatchQueue.main.async {
  313. let callJS = "layout.appForm.uploadedAttachment(\"\(site)\", \"\(attachId)\")"
  314. self.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  315. self.showSuccess(title: "上传成功")
  316. })
  317. }
  318. }
  319. })
  320. // AF.upload(multipartFormData: { (mData) in
  321. // //mData.append(fileURL, withName: "file")
  322. // mData.append(imageData!, withName: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream")
  323. // let siteData = site.data(using: String.Encoding.utf8, allowLossyConversion: false)
  324. // mData.append(siteData!, withName: "site")
  325. // }, to: url, encodingCompletion: { (encodingResult) in
  326. // switch encodingResult {
  327. // case .success(let upload, _, _):
  328. // debugPrint(upload)
  329. // upload.responseJSON {
  330. // respJSON in
  331. // switch respJSON.result {
  332. // case .success(let val):
  333. // let attachId = JSON(val)["data"]["id"].string!
  334. // DispatchQueue.main.async {
  335. // //ProgressHUD.showSuccess("上传成功")
  336. // let callJS = "layout.appForm.uploadedAttachment(\"\(site)\", \"\(attachId)\")"
  337. // self.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  338. // self.showSuccess(title: "上传成功")
  339. // })
  340. // }
  341. // case .failure(let err):
  342. // DispatchQueue.main.async {
  343. // DDLogError(err.localizedDescription)
  344. // self.showError(title: "上传失败")
  345. // }
  346. // break
  347. // }
  348. //
  349. // }
  350. // case .failure(let errType):
  351. // DispatchQueue.main.async {
  352. // DDLogError(errType.localizedDescription)
  353. // self.showError(title: "上传失败")
  354. // }
  355. // }
  356. //
  357. // })
  358. }
  359. })
  360. case .video:
  361. DDLogDebug("video")
  362. case .unknown:
  363. DDLogDebug("Unknown")
  364. @unknown default:
  365. DDLogDebug("Unknown")
  366. }
  367. }
  368. }, completion: nil)
  369. }
  370. //下载预览附件
  371. private func downloadAttachment(_ attachmentId:String){
  372. //文档id
  373. var id: String?
  374. if self.documentId != nil {
  375. id = self.documentId
  376. }else {
  377. id = self.itemData?.id
  378. }
  379. if id == nil {
  380. self.showError(title: "下载文件出错")
  381. return
  382. }
  383. //
  384. let attachInfoURL = AppDelegate.o2Collect.generateURLWithAppContextKey(CMSContext.cmsContextKey, query: CMSContext.cmsAttachmentGET, parameter: ["##attachId##":attachmentId as AnyObject, "##documentId##": id as AnyObject])
  385. //附件下载链接
  386. let downURL = AppDelegate.o2Collect.generateURLWithAppContextKey(CMSContext.cmsContextKey, query: CMSContext.cmsAttachmentDownloadNewQuery, parameter: ["##attachId##":attachmentId as AnyObject])
  387. self.showLoading(title: "下载中...")
  388. // 先获取附件对象
  389. AF.request(attachInfoURL!).responseJSON { (response) in
  390. switch response.result {
  391. case .success(let val):
  392. let info = Mapper<CMSAttachmentInfoResponse>().map(JSONString: JSON(val).description)
  393. if let fileName = info?.data?.name {
  394. //执行下载
  395. let destination: DownloadRequest.Destination = { _, _ in
  396. let documentsURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
  397. let fileURL = documentsURL.appendingPathComponent(fileName)
  398. return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
  399. }
  400. //然后下载附件
  401. AF.download(downURL!, to: destination).response(completionHandler: { (response) in
  402. if response.error == nil , let fileurl = response.fileURL?.path {
  403. //打开文件
  404. self.hideLoading()
  405. self.previewAttachment(fileurl)
  406. }else{
  407. DispatchQueue.main.async {
  408. self.showError(title: "下载文件出错")
  409. }
  410. }
  411. })
  412. }else {
  413. DispatchQueue.main.async {
  414. self.showError(title: "下载文件出错")
  415. }
  416. }
  417. break
  418. case .failure(let err):
  419. DDLogError(err.localizedDescription)
  420. DispatchQueue.main.async {
  421. self.showError(title: "下载文件出错")
  422. }
  423. break
  424. }
  425. }
  426. }
  427. //替换附件
  428. private func replaceAttachment(_ attachmentId:String, _ site:String){
  429. var id = ""
  430. if self.documentId != nil {
  431. id = self.documentId!
  432. }else {
  433. id = self.itemData!.id!
  434. }
  435. let replaceURL = AppDelegate.o2Collect.generateURLWithAppContextKey(CMSContext.cmsContextKey, query: CMSContext.cmsAttachmentReplace, parameter: ["##attachId##":attachmentId as AnyObject,"##docId##": id as AnyObject])!
  436. self.replaceAttachment(site, attachmentId, replaceURL: replaceURL)
  437. }
  438. /**
  439. * 下载公文 并阅览
  440. **/
  441. private func downloadDocumentAndPreview(_ url: String) {
  442. DDLogDebug("文档下载地址:\(url)")
  443. self.showLoading(title: "下载中...")
  444. // 文件地址
  445. let localFileDestination: DownloadRequest.Destination = { _, response in
  446. let documentsURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
  447. let fileURL = documentsURL.appendingPathComponent(response.suggestedFilename!)
  448. // 有重名文件就删除重建
  449. return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
  450. }
  451. AF.download(url, to: localFileDestination).response(completionHandler: { (response) in
  452. if response.error == nil , let fileurl = response.fileURL?.path {
  453. DDLogDebug("文件地址:\(fileurl)")
  454. //打开文件
  455. self.hideLoading()
  456. self.previewAttachment(fileurl)
  457. }else{
  458. let msg = response.error?.localizedDescription ?? ""
  459. DDLogError("下载文件出错,\(msg)")
  460. DispatchQueue.main.async {
  461. self.showError(title: "预览文件出错")
  462. }
  463. }
  464. })
  465. }
  466. private func previewAttachment(_ url:String){
  467. let currentURL = NSURL(fileURLWithPath: url)
  468. if QLPreviewController.canPreview(currentURL) {
  469. self.qlController.currentFileURLS.removeAll(keepingCapacity: true)
  470. self.qlController.currentFileURLS.append(currentURL)
  471. self.qlController.reloadData()
  472. if #available(iOS 10, *) {
  473. let navVC = ZLNormalNavViewController(rootViewController: qlController)
  474. qlController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "关闭", style: .plain, target: qlController, action: #selector(qlController.qlCloseWindow))
  475. self.presentVC(navVC)
  476. }else{
  477. self.pushVC(qlController)
  478. }
  479. }else{
  480. self.showError(title: "此文件无法预览,请在PC端查看")
  481. }
  482. }
  483. private func replaceAttachment(_ site:String,_ attachmentId:String,replaceURL url:String){
  484. let vc = FileBSImagePickerViewController().bsImagePicker()
  485. presentImagePicker(vc, select: { (asset: PHAsset) -> Void in
  486. // User selected an asset.
  487. // Do something with it, start upload perhaps?
  488. }, deselect: { (asset: PHAsset) -> Void in
  489. // User deselected an assets.
  490. // Do something, cancel upload?
  491. }, cancel: { (assets: [PHAsset]) -> Void in
  492. // User cancelled. And this where the assets currently selected.
  493. }, finish: { (assets: [PHAsset]) -> Void in
  494. for asset in assets {
  495. switch asset.mediaType {
  496. case .audio:
  497. DDLogDebug("Audio")
  498. case .image:
  499. let options = PHImageRequestOptions()
  500. options.isSynchronous = true
  501. options.deliveryMode = .fastFormat
  502. options.resizeMode = .none
  503. let fName = (asset.value(forKey: "filename") as? String) ?? "untitle.png"
  504. PHImageManager.default().requestImageData(for: asset, options: options, resultHandler: { (imageData, result, imageOrientation, dict) in
  505. //DDLogDebug("result = \(result) imageOrientation = \(imageOrientation) \(dict)")
  506. // let fileURL = dict?["PHImageFileURLKey"] as! URL
  507. DispatchQueue.main.async {
  508. self.showLoading(title: "上传中...")
  509. }
  510. AF.upload(multipartFormData: { (mData) in
  511. //mData.append(fileURL, withName: "file")
  512. mData.append(imageData!, withName: "file", fileName: fName, mimeType: "application/octet-stream")
  513. let siteData = site.data(using: String.Encoding.utf8, allowLossyConversion: false)
  514. mData.append(siteData!, withName: "site")
  515. }, to: url, method: .put).responseJSON { (response) in
  516. if let err = response.error {
  517. DispatchQueue.main.async {
  518. DDLogError(err.localizedDescription)
  519. self.showError(title: "替换失败")
  520. }
  521. }else {
  522. DispatchQueue.main.async {
  523. let callJS = "layout.appForm.replacedAttachment(\"\(site)\", \"\(attachmentId)\")"
  524. self.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  525. self.showSuccess(title: "替换成功")
  526. })
  527. }
  528. }
  529. }
  530. // DispatchQueue.global(qos: .userInitiated).async {
  531. // AF.upload(multipartFormData: { (mData) in
  532. // //mData.append(fileURL, withName: "file")
  533. // mData.append(imageData!, withName: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream")
  534. // let siteData = site.data(using: String.Encoding.utf8, allowLossyConversion: false)
  535. // mData.append(siteData!, withName: "site")
  536. // }, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: url, method: .put, headers: nil, encodingCompletion: { (encodingResult) in
  537. // switch encodingResult {
  538. // case .success(let upload, _, _):
  539. // debugPrint(upload)
  540. // upload.responseJSON {
  541. // respJSON in
  542. // switch respJSON.result {
  543. // case .success( _):
  544. // DispatchQueue.main.async {
  545. // let callJS = "layout.appForm.replacedAttachment(\"\(site)\", \"\(attachmentId)\")"
  546. // self.webView.evaluateJavaScript(callJS, completionHandler: { (result, err) in
  547. // self.showSuccess(title: "替换成功")
  548. // })
  549. // }
  550. // case .failure(let err):
  551. // DispatchQueue.main.async {
  552. // DDLogError(err.localizedDescription)
  553. // self.showError(title: "替换失败")
  554. // }
  555. // break
  556. // }
  557. //
  558. // }
  559. // case .failure(let errType):
  560. // DispatchQueue.main.async {
  561. // DDLogError(errType.localizedDescription)
  562. // self.showError(title: "替换失败")
  563. // }
  564. // }
  565. //
  566. // })
  567. // }
  568. })
  569. case .video:
  570. DDLogDebug("video")
  571. case .unknown:
  572. DDLogDebug("Unknown")
  573. @unknown default:
  574. DDLogDebug("Unknown")
  575. }
  576. }
  577. }, completion: nil)
  578. }
  579. }