MainFileViewController.swift 47 KB

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