file.js 13 KB

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