MainFileViewController.swift 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. //
  2. // MainFileViewController.swift
  3. // O2Platform
  4. //
  5. // Created by 刘振兴 on 16/8/17.
  6. // Copyright © 2016年 zoneland. All rights reserved.
  7. //
  8. import UIKit
  9. import Alamofire
  10. import AlamofireImage
  11. import AlamofireObjectMapper
  12. import SwiftyJSON
  13. import ObjectMapper
  14. import BSImagePicker
  15. import Photos
  16. import QuickLook
  17. import GradientCircularProgress
  18. import CocoaLumberjack
  19. import O2OA_Auth_SDK
  20. private let kLivelyRedColor = base_color
  21. class MainFileViewController: UIViewController {
  22. @IBOutlet weak var tableView: ZLBaseTableView!
  23. var myFiles:[OOFile] = []
  24. var myFileShare:[FileShare] = []
  25. var myFileRecive:[FileShare] = []
  26. //移动选择的文件夹
  27. var moveSourceFile:OOFile?
  28. var moveTargeFolder:OOFile?
  29. //分享的人员列表
  30. var sharedPersons:[PersonV2] = []
  31. //分享的文件
  32. var currentSharedFile:OOFile?
  33. //文件夹深度队列
  34. var folderQueue:[OOFile] = []
  35. var segmentedControl:SegmentedControl?{
  36. didSet {
  37. tabIndex = (segmentedControl?.selectedIndex)!
  38. }
  39. }
  40. var tabIndex:Int = 0
  41. //预览
  42. let quickLookController = QLPreviewController()
  43. var fileURLs = [URL]()
  44. override func viewDidLoad() {
  45. super.viewDidLoad()
  46. //self.tableView.registerClass(Class() , forCellReuseIdentifier: "FileShareTableViewCell")
  47. setupUI()
  48. self.tableView.contentInset = UIEdgeInsets(top: 40.0, left: 0, bottom: 0, right: 0)
  49. self.tableView.delegate = self
  50. self.tableView.dataSource = self
  51. self.tableView.mj_header = MJRefreshNormalHeader(refreshingBlock: {
  52. self.loadDataByTabIndex(tabIndex: self.tabIndex)
  53. })
  54. self.loadDataByTabIndex(tabIndex:tabIndex)
  55. quickLookController.dataSource = self
  56. quickLookController.delegate = self
  57. }
  58. func loadDataRequestFileCompleted(_ url:String){
  59. ProgressHUD.show("加载中")
  60. Alamofire.request(url).responseJSON { response in
  61. self.myFiles.removeAll()
  62. switch response.result {
  63. case .success(let val):
  64. let type = JSON(val)["type"]
  65. if type == "success" {
  66. let json = JSON(val)["data"]
  67. let files = Mapper<OOFile>().mapArray(JSONString:json["attachmentList"].description)
  68. let folders = Mapper<OOFile>().mapArray(JSONString:json["folderList"].description)
  69. DispatchQueue.main.async {
  70. self.myFiles.append(contentsOf: files!)
  71. self.myFiles.append(contentsOf: folders!)
  72. self.tableView.reloadData()
  73. ProgressHUD.showSuccess("加载完成")
  74. }
  75. }else{
  76. DispatchQueue.main.async {
  77. DDLogError(JSON(val).description)
  78. self.tableView.reloadData()
  79. ProgressHUD.showError("加载失败")
  80. }
  81. }
  82. case .failure(let err):
  83. DispatchQueue.main.async {
  84. DDLogError(err.localizedDescription)
  85. self.tableView.reloadData()
  86. ProgressHUD.showError("加载失败")
  87. }
  88. }
  89. DispatchQueue.main.async {
  90. if self.tableView.mj_header.isRefreshing(){
  91. self.tableView.mj_header.endRefreshing()
  92. }
  93. }
  94. }
  95. }
  96. func loadDataRequestFileShareCompleted(_ url:String){
  97. ProgressHUD.show("加载中")
  98. Alamofire.request(url).responseArray(queue: nil, keyPath: "data", context: nil)
  99. { (response:DataResponse<[FileShare]>) in
  100. self.myFileShare.removeAll()
  101. debugPrint(response.result)
  102. switch response.result {
  103. case .success(let shares):
  104. DispatchQueue.main.async {
  105. self.myFileShare.append(contentsOf: shares)
  106. self.tableView.reloadData()
  107. ProgressHUD.showSuccess("加载完成")
  108. }
  109. case .failure(let err):
  110. DispatchQueue.main.async {
  111. DDLogError(err.localizedDescription)
  112. self.tableView.reloadData()
  113. ProgressHUD.showError("加载失败")
  114. }
  115. }
  116. DispatchQueue.main.async {
  117. if self.tableView.mj_header.isRefreshing(){
  118. self.tableView.mj_header.endRefreshing()
  119. }
  120. }
  121. }
  122. }
  123. func loadDataRequestFileReciveCompleted(_ url:String) {
  124. ProgressHUD.show("加载中")
  125. Alamofire.request(url).responseArray(queue: nil, keyPath: "data", context: nil) {
  126. (response:DataResponse<[FileShare]>) in
  127. self.myFileRecive.removeAll()
  128. switch response.result {
  129. case .success(let shares):
  130. DispatchQueue.main.async {
  131. self.myFileRecive.append(contentsOf: shares)
  132. self.tableView.reloadData()
  133. ProgressHUD.showSuccess("加载完成")
  134. }
  135. case .failure(let err):
  136. DispatchQueue.main.async {
  137. DDLogError(err.localizedDescription)
  138. self.tableView.reloadData()
  139. ProgressHUD.showError("加载失败")
  140. }
  141. }
  142. DispatchQueue.main.async {
  143. if self.tableView.mj_header.isRefreshing(){
  144. self.tableView.mj_header.endRefreshing()
  145. }
  146. }
  147. }
  148. }
  149. func loadDataByTabIndex(tabIndex index:Int){
  150. //计算URL
  151. var url = ""
  152. switch index {
  153. case 0:
  154. self.tableView.emptyTitle = "没有文件数据"
  155. if self.folderQueue.count <= 0 {
  156. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileTopListQuery, parameter: nil)!
  157. self.loadDataRequestFileCompleted(url)
  158. }else{
  159. let f = self.folderQueue.last
  160. //读取
  161. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderItemIdQuery, parameter: ["##id##":f!.id! as AnyObject])
  162. self.loadDataRequestFileCompleted(url!)
  163. }
  164. case 1:
  165. self.tableView.emptyTitle = "没有收到共享的文件"
  166. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileShareQuery, parameter: nil)!
  167. self.loadDataRequestFileShareCompleted(url)
  168. case 2:
  169. self.tableView.emptyTitle = "没有共享文件给其它人"
  170. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileEditorQuery, parameter: nil)!
  171. self.loadDataRequestFileReciveCompleted(url)
  172. default:
  173. url = ""
  174. }
  175. }
  176. func setupUI(){
  177. self.initSegmentedControl()
  178. }
  179. func initSegmentedControl(){
  180. let titleStrings = ["我的文件","共享文件","收到文件"]
  181. let titles: [NSAttributedString] = {
  182. let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.black]
  183. var titles = [NSAttributedString]()
  184. for titleString in titleStrings {
  185. let title = NSAttributedString(string: titleString, attributes: attributes)
  186. titles.append(title)
  187. }
  188. return titles
  189. }()
  190. let selectedTitles: [NSAttributedString] = {
  191. let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: kLivelyRedColor]
  192. var selectedTitles = [NSAttributedString]()
  193. for titleString in titleStrings {
  194. let selectedTitle = NSAttributedString(string: titleString, attributes: attributes)
  195. selectedTitles.append(selectedTitle)
  196. }
  197. return selectedTitles
  198. }()
  199. self.segmentedControl = SegmentedControl.initWithTitles(titles, selectedTitles: selectedTitles)
  200. self.segmentedControl!.delegate = self
  201. self.segmentedControl!.backgroundColor = toolbar_background_color
  202. self.segmentedControl!.autoresizingMask = [.flexibleRightMargin, .flexibleWidth]
  203. self.segmentedControl!.selectionIndicatorStyle = .bottom
  204. self.segmentedControl!.selectionIndicatorColor = kLivelyRedColor
  205. self.segmentedControl!.selectionIndicatorHeight = 3
  206. self.segmentedControl!.segmentWidth = SCREEN_WIDTH / 3
  207. self.segmentedControl!.frame.origin.y = 0
  208. self.segmentedControl!.frame.size = CGSize(width: UIScreen.main.bounds.width, height: 40)
  209. view.insertSubview(self.segmentedControl!, belowSubview: navigationController!.navigationBar)
  210. }
  211. override func didReceiveMemoryWarning() {
  212. super.didReceiveMemoryWarning()
  213. }
  214. @IBAction func showMyFile(_ sender: UIBarButtonItem) {
  215. self.performSegue(withIdentifier: "showMyDownloadSegue", sender: nil)
  216. }
  217. @IBAction func backToHome(_ sender: UIBarButtonItem) {
  218. let backType = AppConfigSettings.shared.appBackType
  219. if backType == 1 {
  220. self.performSegue(withIdentifier: "backToMain", sender: nil)
  221. }else if backType == 2 {
  222. self.performSegue(withIdentifier: "backToApps", sender: nil)
  223. }
  224. }
  225. @IBAction func uploadFileMenu(_ sender: UIBarButtonItem) {
  226. let menuAlertController = UIAlertController(title: "文件操作", message: "文件或文件夹操作", preferredStyle: .actionSheet)
  227. let fileUploadAlert = UIAlertAction(title: "上传文件", style: .destructive) { (fileUploadAction) in
  228. self.uploadFile()
  229. }
  230. let folderCreateAlert = UIAlertAction(title: "创建文件夹", style: .default) { (createFolderAction) in
  231. self.createFolder()
  232. }
  233. let cancelAlert = UIAlertAction(title: "取消", style: .cancel) { (cancelAction) in
  234. }
  235. menuAlertController.addAction(fileUploadAlert)
  236. menuAlertController.addAction(folderCreateAlert)
  237. menuAlertController.addAction(cancelAlert)
  238. self.present(menuAlertController, animated: true, completion: nil)
  239. }
  240. func uploadFile(){
  241. let vc = FileBSImagePickerViewController()
  242. var url = ""
  243. if self.folderQueue.count == 0 {
  244. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileUploadTopQuery, parameter: nil,coverted: true)!
  245. }else{
  246. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileUploadSubQuery, parameter: ["##id##":(self.folderQueue.last?.id!)! as AnyObject],coverted: true)!
  247. }
  248. url = url.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
  249. bs_presentImagePickerController(vc, animated: true,
  250. select: { (asset: PHAsset) -> Void in
  251. // User selected an asset.
  252. // Do something with it, start upload perhaps?
  253. }, deselect: { (asset: PHAsset) -> Void in
  254. // User deselected an assets.
  255. // Do something, cancel upload?
  256. }, cancel: { (assets: [PHAsset]) -> Void in
  257. // User cancelled. And this where the assets currently selected.
  258. }, finish: { (assets: [PHAsset]) -> Void in
  259. for asset in assets {
  260. switch asset.mediaType {
  261. case .audio:
  262. DDLogDebug("Audio")
  263. case .image:
  264. let options = PHImageRequestOptions()
  265. options.isSynchronous = true
  266. options.deliveryMode = .fastFormat
  267. options.resizeMode = .none
  268. let headers:HTTPHeaders = ["x-token":(O2AuthSDK.shared.myInfo()?.token!)!]
  269. PHImageManager.default().requestImageData(for: asset, options: options, resultHandler: { (imageData, result, imageOrientation, dict) in
  270. //debugPrint(imageData,result,imageOrientation,dict)
  271. //DDLogDebug("result = \(result) imageOrientation = \(imageOrientation) \(dict)")
  272. let fileURL = dict?["PHImageFileURLKey"] as! URL
  273. let fileSrcName = fileURL.description
  274. let fName = fileSrcName.components(separatedBy: "/").last!
  275. let fExtName = fName.components(separatedBy: ".").last!
  276. let fPreName = fName.components(separatedBy: ".").first!
  277. DispatchQueue.main.async {
  278. ProgressHUD.show("上传中...", interaction: false)
  279. Alamofire.upload(multipartFormData: { (mData) in
  280. let formatter = DateFormatter()
  281. formatter.dateFormat = "yyyyMMddHHmmss"
  282. let str = formatter.string(from: Date())
  283. let fileName = "\(fPreName.lowercased())_\(str).\(fExtName.lowercased())"
  284. mData.append(imageData!, withName: "file", fileName: fileName, mimeType: "image/\(fExtName)")
  285. }, to: url,headers:headers,encodingCompletion: { (encodingResult) in
  286. switch encodingResult {
  287. case .success(let upload,_,_):
  288. debugPrint(upload)
  289. upload.responseJSON { response in
  290. debugPrint(response)
  291. DispatchQueue.main.async {
  292. ProgressHUD.showSuccess("上传成功")
  293. Timer.after(0.8, {
  294. self.tableView.mj_header.beginRefreshing()
  295. })
  296. }
  297. }
  298. case .failure(let errType):
  299. DispatchQueue.main.async {
  300. DDLogError(errType.localizedDescription)
  301. DispatchQueue.main.async {
  302. ProgressHUD.showError("上传失败")
  303. }
  304. }
  305. }
  306. })
  307. }
  308. //// Alamofire.upload(.POST, url, headers:nil, multipartFormData: { (mData) in
  309. ////
  310. //// let formatter = DateFormatter()
  311. //// formatter.dateFormat = "yyyyMMddHHmmss"
  312. //// let str = formatter.string(from: Date())
  313. //// let fileName = "\(fPreName.lowercased())_\(str).\(fExtName.lowercased())"
  314. //// mData.appendBodyPart(data: imageData!, name: "file", fileName: fileName, mimeType: "image/png;*/*")
  315. ////
  316. //// }, encodingMemoryThreshold: SessionManager.MultipartFormDataEncodingMemoryThreshold, encodingCompletion: { (responseResult:SessionManager.MultipartFormDataEncodingResult) in
  317. //// switch responseResult {
  318. //// case .success:
  319. //// //self.loadDataByTabIndex(tabIndex: 0)
  320. //// DispatchQueue.main.async{
  321. //// ProgressHUD.showSuccess("上传成功")
  322. //// }
  323. //// case .failure(let errType):
  324. //// DDLogError(errType)
  325. //// DispatchQueue.main.async{
  326. //// ProgressHUD.showError("上传失败")
  327. //// }
  328. ////
  329. ////
  330. //// }
  331. //// })
  332. })
  333. case .video:
  334. let options = PHVideoRequestOptions()
  335. options.deliveryMode = .fastFormat
  336. options.isNetworkAccessAllowed = true
  337. options.progressHandler = { (progress,err, stop,dict) in
  338. DDLogDebug("progress = \(progress) dict = \(dict)")
  339. }
  340. PHImageManager.default().requestAVAsset(forVideo: asset, options: options, resultHandler: { (avAsset, avAudioMx, dict) in
  341. })
  342. case .unknown:
  343. DDLogDebug("Unknown")
  344. }
  345. }
  346. }, completion: nil)
  347. }
  348. func createFolder(){
  349. let createAlertController = UIAlertController(title: "创建文件夹", message: "", preferredStyle: .alert)
  350. let okAction = UIAlertAction(title: "确定", style: .destructive) { ok in
  351. DDLogDebug("ok Click")
  352. let textInputField = createAlertController.textFields![0]
  353. if let text = textInputField.text {
  354. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderCreateQuery, parameter: nil)
  355. let s = self.folderQueue.count == 0 ? "":self.folderQueue.last?.id!
  356. let parameter = ["name":text,"superior":s!]
  357. Alamofire.request(url!, method:.post, parameters: parameter, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: { (response) in
  358. switch response.result {
  359. case .success(let val):
  360. let json = JSON(val)
  361. if json["type"] == "success" {
  362. DispatchQueue.main.async {
  363. ProgressHUD.showSuccess("创建成功")
  364. Timer.after(0.5, {
  365. self.tableView.mj_header.beginRefreshing()
  366. })
  367. }
  368. }else{
  369. DispatchQueue.main.async {
  370. DDLogError(json.description)
  371. ProgressHUD.showError("创建失败")
  372. }
  373. }
  374. case .failure(let err):
  375. DispatchQueue.main.async {
  376. DDLogError(err.localizedDescription)
  377. ProgressHUD.showError("创建失败")
  378. }
  379. }
  380. })
  381. // Alamofire.request(.POST, url!, parameters: parameter, encoding: .json, headers: nil).responseJSON(completionHandler: { (response) in
  382. // switch response.result {
  383. // case .success(let val):
  384. // let json = JSON(val)
  385. // if json["type"] == "success" {
  386. // ProgressHUD.showSuccess("创建成功")
  387. // }else{
  388. // DDLogError(json)
  389. // ProgressHUD.showError("创建失败")
  390. // }
  391. // case .failure(let err):
  392. // ProgressHUD.showError("创建失败")
  393. // DDLogError(err.localizedDescription)
  394. // }
  395. // })
  396. }
  397. }
  398. let cancelAction = UIAlertAction(title: "取消", style: .cancel) { (cancel) in
  399. DDLogDebug("cancel Click")
  400. }
  401. createAlertController.addTextField { (folderInputTextField) in
  402. }
  403. createAlertController.addAction(okAction)
  404. createAlertController.addAction(cancelAction)
  405. self.present(createAlertController, animated: true, completion: nil)
  406. }
  407. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  408. if segue.identifier == "showSharePersonSegue" {
  409. // TODO: 这里需要修改,----后续。
  410. // let navVC = segue.destination as! ZLNavigationController
  411. // let destVC = navVC.topViewController as! MeetingPersonListViewController
  412. // destVC.delegate = self
  413. // destVC.selectPersons = self.sharedPersons
  414. }else if segue.identifier == "showSelectFolderSegue"{
  415. let navVC = segue.destination as! ZLNavigationController
  416. let destVC = navVC.topViewController as! FileFolderSelectViewController
  417. destVC.delegate = self
  418. }else if segue.identifier == "showMyShareSegue" {
  419. // let navVC = segue.destinationViewController as! ZLNavigationController
  420. // let destVC = navVC.topViewController as! FileMyShareListViewController
  421. let destVC = segue.destination as! FileMyShareListViewController
  422. destVC.myFileURL = sender as? String
  423. }
  424. }
  425. }
  426. //extension MainFileViewController:MeetingPersonListPassValue {
  427. // func selectPersonPassValue(_ persons: [PersonV2]) {
  428. // self.sharedPersons.removeAll()
  429. // self.sharedPersons.append(contentsOf: persons)
  430. // self.fileShareAction()
  431. // }
  432. //}
  433. extension MainFileViewController: SegmentedControlDelegate {
  434. func segmentedControl(_ segmentedControl: SegmentedControl, didSelectIndex selectedIndex: Int) {
  435. print("Did select index \(selectedIndex)")
  436. tabIndex = selectedIndex
  437. self.loadDataByTabIndex(tabIndex: tabIndex)
  438. switch segmentedControl.style {
  439. case .text:
  440. print("The title is “\(segmentedControl.titles[selectedIndex].string)”\n")
  441. case .image:
  442. print("The image is “\(segmentedControl.images[selectedIndex])”\n")
  443. }
  444. }
  445. func segmentedControl(_ segmentedControl: SegmentedControl, didLongPressIndex longPressIndex: Int) {
  446. print("Did long press index \(longPressIndex)")
  447. if UIDevice.current.userInterfaceIdiom == .pad {
  448. let viewController = UIViewController()
  449. viewController.modalPresentationStyle = .popover
  450. viewController.preferredContentSize = CGSize(width: 200, height: 300)
  451. if let popoverController = viewController.popoverPresentationController {
  452. popoverController.sourceView = view
  453. let yOffset: CGFloat = 10
  454. popoverController.sourceRect = view.convert(CGRect(origin: CGPoint(x: 70 * CGFloat(longPressIndex), y: yOffset), size: CGSize(width: 70, height: 30)), from: navigationItem.titleView)
  455. popoverController.permittedArrowDirections = .any
  456. present(viewController, animated: true, completion: nil)
  457. }
  458. } else {
  459. let message = segmentedControl.style == .text ? "Long press title “\(segmentedControl.titles[longPressIndex].string)”" : "Long press image “\(segmentedControl.images[longPressIndex])”"
  460. let alert = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
  461. let cancelAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
  462. alert.addAction(cancelAction)
  463. present(alert, animated: true, completion: nil)
  464. }
  465. }
  466. }
  467. extension MainFileViewController:UITableViewDelegate,UITableViewDataSource{
  468. func numberOfSections(in tableView: UITableView) -> Int {
  469. // switch tabIndex {
  470. // case 0:
  471. // return 1
  472. // case 1:
  473. // return self.myFileShare.count > 0 ? self.myFileShare.count : 1
  474. // case 2:
  475. // return self.myFileRecive.count > 0 ? self.myFileRecive.count : 1
  476. // default:
  477. // return 1
  478. // }
  479. return 1
  480. }
  481. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  482. switch tabIndex {
  483. case 0:
  484. return self.myFiles.count
  485. case 1:
  486. return self.myFileShare.count
  487. case 2:
  488. return self.myFileRecive.count
  489. default:
  490. return 0
  491. }
  492. }
  493. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  494. //按不同类型生成相应的cell
  495. switch tabIndex {
  496. case 0:
  497. let file = self.myFiles[(indexPath as NSIndexPath).row]
  498. let cell = tableView.dequeueReusableCell(withIdentifier: "FileTableViewCell", for: indexPath) as! FileTableViewCell
  499. cell.delegate = self
  500. cell.file = file
  501. return cell
  502. case 1:
  503. let fileShare = self.myFileShare[(indexPath as NSIndexPath).row]
  504. let cell = tableView.dequeueReusableCell(withIdentifier: "FileShareTableViewCell",for: indexPath) as! FileShareTableViewCell
  505. cell.fileShare = fileShare
  506. return cell
  507. case 2:
  508. let fileRecive = self.myFileRecive[(indexPath as NSIndexPath).row]
  509. let cell = tableView.dequeueReusableCell(withIdentifier: "FileShareTableViewCell", for: indexPath) as! FileShareTableViewCell
  510. cell.fileShare = fileRecive
  511. return cell
  512. default:
  513. return UITableViewCell()
  514. }
  515. }
  516. func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  517. if tabIndex == 0 {
  518. return 40.0
  519. }else{
  520. return 0.0
  521. }
  522. }
  523. func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  524. if tabIndex == 0 {
  525. let headerView = FolderHeaderView()
  526. headerView.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: 40)
  527. headerView.folderQueue = self.folderQueue
  528. headerView.delegate = self
  529. return headerView
  530. }else{
  531. return UIView()
  532. }
  533. }
  534. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  535. DDLogDebug("cell clicked row = \(indexPath.row)")
  536. if tabIndex == 0 {
  537. //我的文件
  538. let f = self.myFiles[indexPath.row]
  539. if f.fileType == .folder {
  540. //文件夹显示文件夹内容
  541. self.folderQueue.append(f)
  542. //读取
  543. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderItemIdQuery, parameter: ["##id##":f.id! as AnyObject])
  544. self.loadDataRequestFileCompleted(url!)
  545. }else{
  546. self.filePreview(f)
  547. }
  548. }else if tabIndex == 1 {
  549. //共享文件
  550. let fileShare = self.myFileShare[(indexPath as NSIndexPath).row]
  551. //读取共享文件列表
  552. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileMyShareListQuery, parameter: ["##name##":fileShare.name! as AnyObject])
  553. self.performSegue(withIdentifier: "showMyShareSegue", sender: url)
  554. }else if tabIndex == 2 {
  555. let fileRecive = self.myFileRecive[(indexPath as NSIndexPath).row]
  556. //接收的文件
  557. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileMyEditorListQuery, parameter: ["##name##":fileRecive.name! as AnyObject])
  558. self.performSegue(withIdentifier: "showMyShareSegue", sender: url)
  559. }
  560. }
  561. func filePreview(_ f:OOFile){
  562. //文件就打开
  563. let fileURL = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileDownloadItemIdQuery, parameter: ["##id##":f.id! as AnyObject])
  564. //缓存到本地
  565. var fileLocalURL:URL?
  566. let destination:DownloadRequest.DownloadFileDestination = { temporaryURL, response in
  567. let baseURL = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
  568. let folder = URL(fileURLWithPath:baseURL).appendingPathComponent("tmpFile", isDirectory: true)
  569. //判断文件夹是否存在,不存在则创建
  570. let exist = FileManager.default.fileExists(atPath: folder.path)
  571. if !exist {
  572. try! FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true,
  573. attributes: nil)
  574. }
  575. //增加随机数
  576. let preName = f.name?.components(separatedBy: ".").first!
  577. let extName = f.name?.components(separatedBy: ".").last!
  578. let timestamp = Date().timeIntervalSince1970.description
  579. fileLocalURL = folder.appendingPathComponent("\(preName!)_\(timestamp).\(extName!)")
  580. return (fileLocalURL!,[.removePreviousFile, .createIntermediateDirectories])
  581. }
  582. ProgressHUD.show("", interaction: false)
  583. Alamofire.download(fileURL!,to: destination).downloadProgress(closure: { (progress) in
  584. print("progress.fractionCompleted = \(progress.fractionCompleted)")
  585. if progress.completedUnitCount == progress.totalUnitCount {
  586. DispatchQueue.main.async {
  587. ProgressHUD.dismiss()
  588. }
  589. }
  590. }).responseData { resp in
  591. switch resp.result {
  592. case .success(_):
  593. DispatchQueue.main.async {
  594. ProgressHUD.dismiss()
  595. }
  596. self.fileURLs.removeAll(keepingCapacity: true)
  597. if QLPreviewController.canPreview(fileLocalURL! as QLPreviewItem){
  598. self.fileURLs.append(fileLocalURL!)
  599. self.quickLookController.reloadData()
  600. self.quickLookController.currentPreviewItemIndex = 0
  601. self.navigationController?.pushViewController(self.quickLookController, animated: true)
  602. }
  603. case .failure(let err):
  604. DDLogError(err.localizedDescription)
  605. }
  606. }
  607. // .response { (request, response, data, error) in
  608. // if let err = error {
  609. // DDLogError(err.localizedDescription)
  610. // }else{
  611. // ProgressHUD.dismiss()
  612. // self.fileURLs.removeAll()
  613. // if QLPreviewController.canPreview(fileLocalURL!){
  614. // self.fileURLs.append(fileLocalURL!)
  615. // self.quickLookController.reloadData()
  616. // self.quickLookController.currentPreviewItemIndex = 0
  617. // self.navigationController?.pushViewController(self.quickLookController, animated: true)
  618. // }
  619. // }
  620. // }
  621. }
  622. override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  623. DDLogDebug("touch")
  624. for touch in touches {
  625. DDLogDebug("touch view = \(touch.view)")
  626. }
  627. }
  628. }
  629. private let FileMenu = ["重命名","删除","移动","下载","分享"]
  630. private let FileFolderMenu = ["重命名","删除","移动"]
  631. private let FileMenuColor = [UIColor.white,
  632. UIColor.purple,
  633. UIColor.cyan,
  634. UIColor.yellow,
  635. UIColor.green]
  636. private let FileFolderMenuColor = [UIColor.white,
  637. UIColor.purple,
  638. UIColor.cyan]
  639. extension MainFileViewController:FileTableViewCellDelegate{
  640. func cellDidClicked(_ cell: FileTableViewCell, file: OOFile) {
  641. DDLogDebug("tableView contentOffset = \(self.tableView.contentOffset)")
  642. DDLogDebug("file clicked id = \(file.id!)")
  643. let startX = SCREEN_WIDTH - 10
  644. //let startY = self.tableView.contentOffset.y > 0 ? cell.center.y - self.tableView.contentOffset.y : cell.center.y
  645. let startY = cell.center.y - self.tableView.contentOffset.y
  646. DDLogDebug("startx = \(startX),starty = \(startY)")
  647. let startPoint = CGPoint(x: startX, y: startY)
  648. if file.fileType == .folder {
  649. //显示文件夹上下文菜单
  650. AZPopMenu.show(self.view, startPoint: startPoint, items: FileFolderMenu, colors: FileFolderMenuColor, selected: { (itemSelected) in
  651. DDLogDebug("\(itemSelected)")
  652. switch itemSelected {
  653. case 0:
  654. self.fileRename(file)
  655. case 1:
  656. self.fileDelete(file)
  657. case 2:
  658. self.fileMove(file)
  659. default:
  660. DDLogDebug("no action")
  661. }
  662. })
  663. }else if file.fileType == .file {
  664. //显示文件上下文菜单
  665. AZPopMenu.show(self.view, startPoint: startPoint, items: FileMenu, colors: FileMenuColor, selected: { (itemSelected) in
  666. DDLogDebug("\(itemSelected)")
  667. switch itemSelected {
  668. case 0:
  669. self.fileRename(file)
  670. case 1:
  671. self.fileDelete(file)
  672. case 2:
  673. self.fileMove(file)
  674. case 3:
  675. self.fileDownload(file)
  676. case 4:
  677. self.fileShare(file)
  678. default:
  679. DDLogDebug("no action")
  680. }
  681. })
  682. }
  683. }
  684. fileprivate func renameFileAction(sourceFile f:OOFile,newFileName name:String){
  685. var url = ""
  686. var parameter:Dictionary<String,String> = [:]
  687. if f.fileType == .file {
  688. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileRenameQuery, parameter: ["##id##":f.id! as AnyObject])!
  689. parameter["name"] = name
  690. parameter["folder"] = f.folder!
  691. }else if f.fileType == .folder {
  692. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderActionIdQuery,parameter: ["##id##":f.id! as AnyObject])!
  693. parameter["name"] = name
  694. parameter["superior"] = f.superior!
  695. }
  696. ProgressHUD.show("更新中", interaction: false)
  697. Alamofire.request(url, method: .put, parameters: parameter, encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
  698. switch response.result {
  699. case .success(let val):
  700. let json = JSON(val)
  701. if json["type"] == "success" {
  702. self.myFiles.forEachEnumerated({ (index, file) in
  703. if file.id == f.id {
  704. file.name = name
  705. }
  706. })
  707. DispatchQueue.main.async {
  708. self.tableView.reloadData()
  709. ProgressHUD.showSuccess("重命名完成")
  710. }
  711. }else{
  712. }
  713. case .failure(let err):
  714. DispatchQueue.main.async {
  715. DDLogError(err.localizedDescription)
  716. ProgressHUD.showError("重命名失败")
  717. }
  718. }
  719. }
  720. }
  721. //重命名
  722. func fileRename(_ f:OOFile){
  723. let renameViewController = UIAlertController(title: "重命名", message: "原名称:\(f.name!)", preferredStyle: .alert)
  724. let okAction = UIAlertAction(title: "确定", style: .destructive) { (okAction) in
  725. let textField = renameViewController.textFields![0]
  726. if let text = textField.text {
  727. if text.isEmpty {
  728. DDLogDebug("empty name = \(text)")
  729. }else{
  730. DDLogDebug("new name = \(text)")
  731. self.renameFileAction(sourceFile: f, newFileName: text)
  732. }
  733. }
  734. }
  735. let cancelAction = UIAlertAction(title: "取消", style: .cancel) { (cancelAction) in
  736. }
  737. renameViewController.addTextField { (textField) in
  738. textField.placeholder = "请输入新名称"
  739. textField.textColor = UIColor.red
  740. }
  741. renameViewController.addAction(okAction)
  742. renameViewController.addAction(cancelAction)
  743. self.present(renameViewController, animated: true, completion: nil)
  744. }
  745. fileprivate func deleteFileAction(_ f:OOFile){
  746. var url = ""
  747. if f.fileType == .file {
  748. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileDeleteQuery, parameter: ["##id##":f.id! as AnyObject])!
  749. }else if f.fileType == .folder {
  750. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderActionIdQuery, parameter: ["##id##":f.id! as AnyObject])!
  751. }
  752. ProgressHUD.show("删除中", interaction: false)
  753. Alamofire.request(url,method:.delete, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
  754. switch response.result {
  755. case .success(let val):
  756. let json = JSON(val)
  757. if json["type"] == "success" {
  758. self.myFiles.remove(at: self.myFiles.index(where: { (file) -> Bool in
  759. if f.id == file.id {
  760. return true
  761. }else{
  762. return false
  763. }
  764. })!)
  765. DispatchQueue.main.async {
  766. self.tableView.reloadData()
  767. ProgressHUD.showSuccess("删除成功")
  768. }
  769. }else{
  770. DispatchQueue.main.async {
  771. DDLogError("删除失败:\(json)")
  772. ProgressHUD.showError("删除失败")
  773. }
  774. }
  775. case .failure(let err):
  776. DispatchQueue.main.async {
  777. DDLogError("删除失败:\(err)")
  778. ProgressHUD.showError("删除失败")
  779. }
  780. }
  781. }
  782. }
  783. //删除
  784. func fileDelete(_ f:OOFile){
  785. let deleViewController = UIAlertController(title: "删除", message: "删除文件:\(f.name!)", preferredStyle: .alert)
  786. let okAction = UIAlertAction(title: "确定", style: .destructive) { (okAction) in
  787. //执行删除
  788. self.deleteFileAction(f)
  789. }
  790. let cancelAction = UIAlertAction(title: "取消", style: .cancel, handler: nil)
  791. deleViewController.addAction(okAction)
  792. deleViewController.addAction(cancelAction)
  793. self.present(deleViewController,animated: true,completion: nil)
  794. }
  795. func fileMoveAction(){
  796. //移动
  797. var url = ""
  798. var parameter:[String:AnyObject] = [:]
  799. if moveSourceFile?.fileType == .file {
  800. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileRenameQuery, parameter: ["##id##":(moveSourceFile?.id)! as AnyObject])!
  801. parameter["name"] = moveSourceFile?.name as AnyObject?
  802. parameter["folder"] = moveTargeFolder?.id as AnyObject?
  803. }else if moveSourceFile?.fileType == .folder {
  804. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderActionIdQuery, parameter: ["##id##":(moveSourceFile?.id)! as AnyObject])!
  805. parameter["name"] = moveSourceFile?.name as AnyObject?
  806. parameter["superior"] = moveTargeFolder?.id as AnyObject?
  807. }
  808. Alamofire.request(url,method:.put, parameters: parameter, encoding: JSONEncoding.default , headers: nil).responseJSON { (response) in
  809. switch response.result {
  810. case .success(let val):
  811. let json = JSON(val)
  812. if json["type"] == "success" {
  813. self.myFiles.remove(at: self.myFiles.index(where: { (file) -> Bool in
  814. if self.moveSourceFile?.id == file.id {
  815. return true
  816. }else{
  817. return false
  818. }
  819. })!)
  820. DispatchQueue.main.async {
  821. self.tableView.reloadData()
  822. ProgressHUD.showSuccess("移动完成")
  823. }
  824. }else{
  825. DispatchQueue.main.async {
  826. DDLogError(json.description)
  827. ProgressHUD.showError("移动失败")
  828. }
  829. }
  830. case .failure(let err):
  831. DispatchQueue.main.async {
  832. DDLogError(err.localizedDescription)
  833. ProgressHUD.showError("移动失败")
  834. }
  835. }
  836. }
  837. }
  838. //移动
  839. func fileMove(_ f:OOFile){
  840. self.moveSourceFile = f
  841. self.performSegue(withIdentifier: "showSelectFolderSegue", sender: nil)
  842. }
  843. func getRect() -> CGRect {
  844. return CGRect(
  845. x: view.centerX - 100 / 2,
  846. y: view.centerY - 100 / 2 - 33,
  847. width: 100,
  848. height: 100)
  849. }
  850. //下载
  851. func fileDownload(_ f:OOFile){
  852. //存储到私有目录
  853. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileDownloadItemIdQuery, parameter: ["##id##":f.id! as AnyObject])
  854. let destination:DownloadRequest.DownloadFileDestination = { temporaryURL, response in
  855. let baseURL = NSSearchPathForDirectoriesInDomains(.downloadsDirectory, .userDomainMask, true)[0]
  856. let folder = URL(fileURLWithPath:baseURL).appendingPathComponent("file", isDirectory: true)
  857. //判断文件夹是否存在,不存在则创建
  858. let exist = FileManager.default.fileExists(atPath: folder.path)
  859. if !exist {
  860. try! FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true,
  861. attributes: nil)
  862. }
  863. return (folder.appendingPathComponent(f.name!), [.removePreviousFile, .createIntermediateDirectories])
  864. }
  865. let progressHUD = GradientCircularProgress()
  866. let frame = CGRect(x: (SCREEN_WIDTH - 100)/2, y: (SCREEN_HEIGHT - 100)/2, w: 100, h: 100)
  867. let progressView = progressHUD.showAtRatio(frame: frame, display: true, style: MyDownloadStyle())
  868. progressView?.layer.cornerRadius = 12.0
  869. //progressView?.backgroundColor = UIColor(colorLiteralRed: 18, green: 18, blue: 18, alpha: 0.7)
  870. self.view.insertSubview(progressView!, at: 99)
  871. //progressView?.bringSubview(toFront: self.view)
  872. progressHUD.updateRatio(0.0)
  873. let utilityQueue = DispatchQueue.global(qos: .utility)
  874. Alamofire.download(url!, to: destination).downloadProgress(queue: utilityQueue) { (progress) in
  875. print("progress.fractionCompleted = \(progress.fractionCompleted)")
  876. DispatchQueue.main.async {
  877. progressHUD.updateRatio(CGFloat(progress.fractionCompleted))
  878. }
  879. }.responseData { (resp) in
  880. DispatchQueue.main.async {
  881. progressHUD.dismiss(progress: progressView!)
  882. }
  883. switch resp.result {
  884. case .success( _):
  885. DispatchQueue.main.async {
  886. ProgressHUD.showSuccess("下载完成")
  887. }
  888. case .failure(let err):
  889. DispatchQueue.main.async {
  890. DDLogError(err.localizedDescription)
  891. ProgressHUD.showError("下载失败")
  892. }
  893. }
  894. }
  895. }
  896. //分享
  897. func fileShare(_ f:OOFile){
  898. currentSharedFile = f
  899. self.performSegue(withIdentifier: "showSharePersonSegue", sender: nil)
  900. }
  901. func fileShareAction(){
  902. var names:[String] = []
  903. sharedPersons.forEach { (p) in
  904. names.append(p.name!)
  905. }
  906. let url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileShareActionQuery, parameter: ["##id##":(currentSharedFile?.id)! as AnyObject])
  907. ProgressHUD.show("分享中...")
  908. Alamofire.request(url!, method:.put , parameters: ["shareList":names], encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
  909. switch response.result {
  910. case .success(let val):
  911. let json = JSON(val)
  912. if json["type"] == "success" {
  913. DispatchQueue.main.async {
  914. ProgressHUD.showSuccess("分享成功")
  915. }
  916. }else{
  917. DispatchQueue.main.async {
  918. ProgressHUD.showError("分享失败")
  919. }
  920. }
  921. case .failure(let err):
  922. DispatchQueue.main.async {
  923. DDLogError(err.localizedDescription)
  924. ProgressHUD.showError("分享失败")
  925. }
  926. }
  927. }
  928. }
  929. }
  930. extension MainFileViewController:FileFolderPassValueDelegate{
  931. func selectedFolder(_ f: OOFile) {
  932. self.moveTargeFolder = f
  933. self.fileMoveAction()
  934. }
  935. }
  936. extension MainFileViewController:FolderHeaderViewDelegate{
  937. func headerClickSelected(currentFile f: OOFile, folderQueue fQueue: [OOFile]) {
  938. self.folderQueue = fQueue
  939. var url = ""
  940. if f.id == "0" {
  941. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileTopListQuery, parameter: nil)!
  942. }else{
  943. url = AppDelegate.o2Collect.generateURLWithAppContextKey(FileContext.fileContextKey, query: FileContext.fileFolderItemIdQuery, parameter: ["##id##":f.id! as AnyObject])!
  944. }
  945. self.loadDataRequestFileCompleted(url)
  946. }
  947. }
  948. //quick look
  949. extension MainFileViewController:QLPreviewControllerDataSource,QLPreviewControllerDelegate{
  950. func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
  951. return fileURLs.count
  952. }
  953. func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
  954. return fileURLs[index] as QLPreviewItem
  955. }
  956. }