file.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. import * as Vue from 'vue'
  2. import router from '@/router'
  3. import config from '@/config/reSource'
  4. import { message } from 'ant-design-vue'
  5. import { fileImgMap, unknownImg, fileSuffixCodeModeMap, markdownFileType } from '@/libs/map.js'
  6. import { officeFileType } from '@/libs/map.js'
  7. import fileOperationPlugins from '@/libs/fileOperationPlugins.js'
  8. import { useMyResourceStore } from '@/store/myResource'
  9. // 全局函数 - 文件相关
  10. const fileFunction = {
  11. /**
  12. * 格式化文件大小
  13. * @param {number} size 文件大小
  14. * @param {boolean} isInteger 是否只显示整数位,默认不截取
  15. * @returns {string} 文件大小(带单位)
  16. */
  17. calculateFileSize(size, isInteger = false) {
  18. const B = 1024
  19. const KB = Math.pow(1024, 2)
  20. const MB = Math.pow(1024, 3)
  21. const GB = Math.pow(1024, 4)
  22. if (isInteger) {
  23. // 截取为整数
  24. if (size < B) {
  25. return `${size}B`
  26. } else if (size < KB) {
  27. return `${(size / B).toFixed(0)}KB`
  28. } else if (size < MB) {
  29. return `${(size / KB).toFixed(0)}MB`
  30. } else if (size < GB) {
  31. return `${(size / MB).toFixed(0)}GB`
  32. } else {
  33. return `${(size / GB).toFixed(0)}TB`
  34. }
  35. } else {
  36. // 保留小数位
  37. if (size < B) {
  38. return `${size}B`
  39. } else if (size < KB) {
  40. return `${(size / B).toFixed(0)}KB`
  41. } else if (size < MB) {
  42. return `${(size / KB).toFixed(1)}MB`
  43. } else if (size < GB) {
  44. return `${(size / MB).toFixed(2)}GB`
  45. } else {
  46. return `${(size / GB).toFixed(3)}TB`
  47. }
  48. }
  49. },
  50. /**
  51. * 获取流式的缩略图、视频封面图
  52. * @param {object} row 文件信息
  53. * @returns {string} 流式图片
  54. */
  55. getMinImgStream(row) {
  56. return `${config.baseContext}/filetransfer/preview?userFileId=${row.userFileId}&isMin=true&shareBatchNum=${
  57. row.shareBatchNum == null ? '' : row.shareBatchNum
  58. }&extractionCode=${row.extractionCode == null ? '' : row.extractionCode}`
  59. },
  60. /**
  61. * 获取文件查看路径
  62. * @param {object} row 文件信息
  63. * @returns {string} 文件路径
  64. */
  65. getViewFilePath(row) {
  66. return `${config.baseContext}/filetransfer/preview?userFileId=${row.userFileId}&isMin=false&shareBatchNum=${
  67. row.shareBatchNum == null ? '' : row.shareBatchNum
  68. }&extractionCode=${row.extractionCode == null ? '' : row.extractionCode}`
  69. },
  70. /**
  71. * 获取文件下载路径
  72. * @param {object} row 文件信息
  73. * @returns {string} 文件下载路径
  74. */
  75. getDownloadFilePath(row) {
  76. return `${config.baseContext}/filetransfer/downloadfile?userFileId=${row.userFileId}&shareBatchNum=${
  77. row.shareBatchNum == null ? '' : row.shareBatchNum
  78. }&extractionCode=${row.extractionCode == null ? '' : row.extractionCode}`
  79. },
  80. getDownloadFilePath2(row) {
  81. return `${config.baseContext}/filetransfer/downloadfile?userFileId=${row.userFileId}&shareBatchNum=${
  82. row.shareBatchNum == null ? '' : row.shareBatchNum
  83. }&extractionCode=${row.extractionCode == null ? '' : row.extractionCode}&admin=true`
  84. },
  85. /**
  86. * 获取 Onlyoffice 文件创建路径
  87. * @param {object} row
  88. * @returns {string} office 文件创建路径
  89. */
  90. createFileOnlineByOffice(data) {
  91. let fileUrl = `${location.protocol}//${location.host}${config.baseContext}`
  92. const { href } = router.resolve({
  93. name: 'Onlyoffice',
  94. query: {
  95. fileUrl: fileUrl,
  96. fileName: data.fileName,
  97. filePath: data.filePath,
  98. extendName: data.extendName,
  99. ot: 'add'
  100. }
  101. })
  102. window.open(href, '_blank')
  103. },
  104. /**
  105. * 获取 Onlyoffice 文件在线预览路径
  106. * @param {object} row
  107. * @returns {string} office 文件在线预览路径
  108. */
  109. getFileOnlineViewPathByOffice(row) {
  110. let userFileId = row.userFileId
  111. const { href } = router.resolve({
  112. name: 'Onlyoffice',
  113. query: {
  114. userFileId: userFileId,
  115. ot: 'detail'
  116. }
  117. })
  118. window.open(href, '_blank')
  119. },
  120. /**
  121. * 获取 Onlyoffice 文件在线编辑路径
  122. * @param {object} row
  123. * @returns {string} office 文件在线编辑路径
  124. */
  125. getFileOnlineEditPathByOffice(row) {
  126. let userFileId = row.userFileId
  127. const { href } = router.resolve({
  128. name: 'Onlyoffice',
  129. query: {
  130. userFileId: userFileId,
  131. ot: 'edit'
  132. }
  133. })
  134. window.open(href, '_blank')
  135. },
  136. /**
  137. * 获取分享链接
  138. * @param {string} shareBatchNum
  139. * @returns {string} 完整的分享链接
  140. */
  141. getShareLink(shareBatchNum) {
  142. return `${location.protocol}//${location.host}/share/${shareBatchNum}`
  143. },
  144. /**
  145. * 复制分享链接
  146. * @param {string} shareBatchNum
  147. * @param {string} extractionCode
  148. */
  149. copyShareLink(shareBatchNum, extractionCode) {
  150. let input = document.createElement('textarea') // 直接构建textarea以保持换行
  151. input.value =
  152. extractionCode === null
  153. ? `分享链接:${this.getShareLink(shareBatchNum)}\n复制链接到浏览器中并输入提取码即可查看文件`
  154. : `分享链接:${this.getShareLink(
  155. shareBatchNum
  156. )}\n提取码:${extractionCode}\n复制链接到浏览器中并输入提取码即可查看文件` // 设置内容
  157. document.body.appendChild(input) // 添加临时实例
  158. input.select() // 选择实例内容
  159. document.execCommand('Copy') // 执行复制
  160. document.body.removeChild(input) // 删除临时实例
  161. message.success('复制成功')
  162. },
  163. /**
  164. * 根据文件扩展名设置文件图片
  165. * @param {object} file 文件信息
  166. */
  167. setFileImg(file) {
  168. if (file.isDir === 1) {
  169. // 文件夹
  170. return fileImgMap.get('dir')
  171. } else if (
  172. Number(router.currentRoute.value.query.fileType) !== 6 &&
  173. ['jpg', 'png', 'jpeg', 'gif', 'mp4', 'webp'].includes(file.extendName.toLowerCase())
  174. ) {
  175. // 图片、视频类型,直接显示缩略图
  176. return this.getMinImgStream(file)
  177. } else if (fileImgMap.has(file.extendName.toLowerCase())) {
  178. // 可以识别文件类型的文件
  179. return fileImgMap.get(file.extendName.toLowerCase())
  180. } else {
  181. // 无法识别文件类型的文件
  182. return unknownImg
  183. }
  184. },
  185. /**
  186. * 判断是否是视频文件
  187. * @param {object} file 文件信息
  188. */
  189. isVideoFile(file) {
  190. if (['avi', 'mp4', 'mpg', 'mov', 'swf'].includes(file.extendName?.toLowerCase())) {
  191. return true
  192. } else {
  193. return false
  194. }
  195. },
  196. /**
  197. * 图片预览
  198. * @param {*} currentIndex 当前图片索引
  199. * @param {*} imgInfo 单个图片信息
  200. * @param {*} imgInfoList 多个图片列表
  201. */
  202. handleImgPreview(currentIndex, imgInfo = {}, imgInfoList = []) {
  203. console.log('handleImgPreview', currentIndex, imgInfo, imgInfoList)
  204. console.log('handleImgPreview--', router.currentRoute.value.query.fileType)
  205. // 图片分类下 - 传递整个页面的图片列表;非图片分类下 - 由单个图片构建图片列表
  206. const imgList =
  207. router.currentRoute.value.query.fileType && Number(router.currentRoute.value.query.fileType) === 1
  208. ? imgInfoList.map((item) => {
  209. return {
  210. ...item,
  211. fileUrl: this.getViewFilePath(item),
  212. downloadLink: this.getDownloadFilePath(item)
  213. }
  214. })
  215. : [
  216. {
  217. ...imgInfo,
  218. fileUrl: this.getViewFilePath(imgInfo),
  219. downloadLink: this.getDownloadFilePath(imgInfo)
  220. }
  221. ]
  222. const defaultIndex =
  223. router.currentRoute.value.query.fileType && Number(router.currentRoute.value.query.fileType) === 1
  224. ? currentIndex
  225. : 0
  226. fileOperationPlugins.openBox.imgPreview({ imgList, defaultIndex })
  227. },
  228. /**
  229. * 视频预览
  230. * @param {*} currentIndex 当前视频索引
  231. * @param {*} videoInfo 单个视频信息
  232. * @param {*} videoInfoList 多个视频列表
  233. */
  234. handleVideoPreview(currentIndex, videoInfo = {}, videoInfoList = []) {
  235. // 视频分类下 - 传递整个页面的视频列表;非视频分类下 - 由单个视频构建视频列表
  236. const videoList =
  237. router.currentRoute.value.query.fileType && Number(router.currentRoute.value.query.fileType) === 3
  238. ? videoInfoList.map((item) => {
  239. return {
  240. ...item,
  241. fileUrl: this.getViewFilePath(item),
  242. downloadLink: this.getDownloadFilePath(item)
  243. }
  244. })
  245. : [
  246. {
  247. ...videoInfo,
  248. fileUrl: this.getViewFilePath(videoInfo),
  249. downloadLink: this.getDownloadFilePath(videoInfo)
  250. }
  251. ]
  252. const defaultIndex =
  253. router.currentRoute.value.query.fileType && Number(router.currentRoute.value.query.fileType) === 3
  254. ? currentIndex
  255. : 0
  256. fileOperationPlugins.openBox.videoPreview({ videoList, defaultIndex })
  257. },
  258. /**
  259. * 音频预览
  260. * @param {*} currentIndex 当前音频索引
  261. * @param {*} audioInfo 单个音频信息
  262. * @param {*} audioInfoList 多个音频列表
  263. */
  264. handleAudioPreview(currentIndex, audioInfo = {}, audioInfoList = []) {
  265. // 音频分类下 - 传递整个页面的音频列表;非音频分类下 - 由单个音频构建音频列表
  266. const audioList =
  267. router.currentRoute.value.query.fileType && Number(router.currentRoute.value.query.fileType) === 4
  268. ? audioInfoList.map((item) => {
  269. return {
  270. ...item,
  271. fileUrl: this.getViewFilePath(item),
  272. downloadLink: this.getDownloadFilePath(item)
  273. }
  274. })
  275. : [
  276. {
  277. ...audioInfo,
  278. fileUrl: this.getViewFilePath(audioInfo),
  279. downloadLink: this.getDownloadFilePath(audioInfo)
  280. }
  281. ]
  282. const defaultIndex =
  283. router.currentRoute.value.query.fileType && Number(router.currentRoute.value.query.fileType) === 4
  284. ? currentIndex
  285. : 0
  286. fileOperationPlugins.openBox.audioPreview({ audioList, defaultIndex })
  287. },
  288. /**
  289. * 文件预览
  290. * @description 若当前点击的为文件夹,则进入文件夹内部;若是文件,则进行相应的预览。
  291. * @param {object} row 文件信息
  292. * @param {number} currentIndex 当前文件索引
  293. * @param {array} fileList 文件列表
  294. */
  295. handleFileNameClick(row, currentIndex, fileList = []) {
  296. const myResourceStore = useMyResourceStore()
  297. // 如果当前文件在回收站中,则不允许预览
  298. if (row.deleteFlag !== undefined && row.deleteFlag !== 0) {
  299. return false
  300. }
  301. // 若是文件夹则进入该文件夹
  302. if (row.isDir) {
  303. if (router.currentRoute.value.name === 'Share') {
  304. // 当前是查看他人分享列表的页面
  305. myResourceStore.changeQuery({
  306. filePath: `${row.shareFilePath === '/' ? '' : row.shareFilePath}/${row.fileName}`
  307. })
  308. // router.push({
  309. // query: {
  310. // filePath: `${row.shareFilePath === '/' ? '' : row.shareFilePath}/${row.fileName}`
  311. // }
  312. // })
  313. } else if (Number(router.currentRoute.value.query.fileType) === 8) {
  314. // 当前是我的已分享列表页面
  315. myResourceStore.changeQuery({
  316. fileType: 8,
  317. filePath: `${row.shareFilePath === '/' ? '' : row.shareFilePath}/${row.fileName}`,
  318. shareBatchNum: row.shareBatchNum
  319. })
  320. // router.push({
  321. // query: {
  322. // fileType: 8,
  323. // filePath: `${row.shareFilePath === '/' ? '' : row.shareFilePath}/${row.fileName}`,
  324. // shareBatchNum: row.shareBatchNum
  325. // }
  326. // })
  327. } else if (Number(router.currentRoute.value.query.fileType) !== 6) {
  328. // 回收站页面不允许打开文件夹
  329. // 网盘页面
  330. myResourceStore.changeQuery({
  331. filePath: `${row.filePath === '/' ? '' : row.filePath}/${row.fileName}`,
  332. fileType: 0
  333. })
  334. // router.push({
  335. // query: {
  336. // filePath: `${row.filePath === '/' ? '' : row.filePath}/${row.fileName}`,
  337. // fileType: 0
  338. // }
  339. // })
  340. }
  341. }
  342. // 若是文件,则进行相应的预览
  343. else {
  344. // 若当前点击项是图片
  345. const PIC = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp']
  346. if (PIC.includes(row.extendName.toLowerCase())) {
  347. this.handleImgPreview(currentIndex, row, fileList)
  348. return false
  349. }
  350. // 若当前点击项是可以使用office在线预览的
  351. if ([...officeFileType].includes(row.extendName.toLowerCase())) {
  352. // this.getFileOnlineViewPathByOffice(row)
  353. return false
  354. }
  355. // 若当前点击项是pdf
  356. if (row.extendName.toLowerCase() === 'pdf') {
  357. // window.open(this.getViewFilePath(row), '_blank')
  358. }
  359. // 若当前点击项是代码或文本文件
  360. let codeFileSuffix = row.extendName.toLowerCase()
  361. if (codeFileSuffix === 'yaml') {
  362. codeFileSuffix = 'yml'
  363. }
  364. // 无格式文件也可以在线编辑
  365. if (fileSuffixCodeModeMap.has(codeFileSuffix) || (row.isDir === 0 && row.extendName === '')) {
  366. fileOperationPlugins.openBox.codePreview({ fileInfo: row, isEdit: false })
  367. return false
  368. }
  369. // 若当前点击项是 markdown 文档
  370. if (markdownFileType.includes(row.extendName.toLowerCase())) {
  371. fileOperationPlugins.openBox.markdownPreview({
  372. fileInfo: row,
  373. editable: false
  374. })
  375. return false
  376. }
  377. // 若当前点击项是视频mp4格式
  378. const VIDEO = ['mp4']
  379. if (VIDEO.includes(row.extendName.toLowerCase())) {
  380. this.handleVideoPreview(currentIndex, row, fileList)
  381. return false
  382. }
  383. // 若当前点击项是音频 mp3、flac 格式
  384. const AUDIO = ['mp3', 'flac']
  385. if (AUDIO.includes(row.extendName.toLowerCase())) {
  386. this.handleAudioPreview(currentIndex, row, fileList)
  387. return false
  388. }
  389. }
  390. },
  391. /**
  392. * 文件名称拼接,包括文件名称 + 文件后缀
  393. * @param {object} file 文件信息
  394. * @param {boolean} isHighlight 是否需要展示高亮效果,默认不需要
  395. * @returns {string} 完整文件名称
  396. */
  397. getFileNameComplete(file, isHighlight = false) {
  398. return isHighlight === true && file.highlightFields
  399. ? `${file.highlightFields}${file.isDir === 0 && file.extendName ? `.${file.extendName}` : ''}`
  400. : `${file.fileName}${file.isDir === 0 && file.extendName ? `.${file.extendName}` : ''}`
  401. },
  402. /**
  403. * 文件类型
  404. * @param {object} file 文件信息
  405. */
  406. getFileType(file) {
  407. return file.isDir === 1 ? '文件夹' : file.extendName ? file.extendName : '文件'
  408. },
  409. /**
  410. * 获取文件分享过期状态
  411. * @param {string} time 日期
  412. * @returns {boolean} 是否过期
  413. */
  414. getFileShareStatus(time) {
  415. if (new Date(time).getTime() > new Date().getTime()) {
  416. return false
  417. } else {
  418. return true
  419. }
  420. }
  421. }
  422. export default fileFunction