FileList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <el-row>
  3. <el-row>
  4. <el-form :inline="true" :model="searchForm" class="demo-form-inline" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
  5. <el-form-item>
  6. <el-button size="mini" type="danger" @click="goToUpload">上传</el-button>
  7. <el-button size="mini" type="danger" @click="downloadFile">下载</el-button>
  8. <el-button size="mini" type="danger" @click="deleteMultiple">删除</el-button>
  9. <el-button size="mini" type="danger" @click="createNewFolder">新建文件夹</el-button>
  10. <el-button size="mini" type="danger" @click="move(1)">移动</el-button>
  11. <el-button size="mini" type="danger" @click="move(2)">复制</el-button>
  12. <el-button size="mini" type="danger" @click="share">分享</el-button>
  13. </el-form-item>
  14. <el-form-item>
  15. <el-select v-model="searchForm.fileType" placeholder="文件类型" @change="search">
  16. <el-option label="全部" value="0" />
  17. <el-option label="图片" value="1001" />
  18. <el-option label="视频" value="1002" />
  19. <el-option label="音频" value="1003" />
  20. <el-option label="文本" value="1004" />
  21. </el-select>
  22. </el-form-item>
  23. <el-form-item>
  24. <el-input v-model="searchForm.filename" placeholder="" />
  25. </el-form-item>
  26. <el-form-item>
  27. <el-button size="mini" type="warning" @click="search">查询</el-button>
  28. </el-form-item>
  29. </el-form>
  30. </el-row>
  31. <el-row>
  32. <el-col :md="2">
  33. <span>当前路径:</span>
  34. </el-col>
  35. <el-col :md="22">
  36. <el-breadcrumb separator-class="el-icon-arrow-right" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
  37. <el-breadcrumb-item v-for="(item, index) of parentDirs" :key="index">
  38. <a href="javascript:void(0)" style="text-decoration-line: none" @click="goTo(item.path)">{{ item.filename }}</a>
  39. </el-breadcrumb-item>
  40. </el-breadcrumb>
  41. </el-col>
  42. </el-row>
  43. <el-row>
  44. <el-table
  45. ref="multipleTable"
  46. :data="dataList"
  47. border
  48. style="width: 100%"
  49. @selection-change="handleSelectionChange"
  50. >
  51. <el-table-column
  52. type="selection"
  53. />
  54. <el-table-column
  55. prop="filename"
  56. label="文件名"
  57. width="400px"
  58. >
  59. <template slot-scope="scope">
  60. <a href="javascript:void(0)" style="text-decoration-line: none" @click="handleFile(scope.row)">
  61. <el-image :src="scope.row.icon" min-width="16" height="16" />
  62. <el-tooltip
  63. :content="scope.row.filename"
  64. raw-content
  65. placement="top-start"
  66. >
  67. <span v-if="scope.row.filename.length <= 60">
  68. {{ scope.row.filename }}
  69. </span>
  70. <span v-else>
  71. {{ scope.row.filename.substr(0, 55) + "..." }}
  72. </span>
  73. </el-tooltip>
  74. </a>
  75. </template>
  76. </el-table-column>
  77. <el-table-column
  78. prop="owner"
  79. label="修改时间"
  80. />
  81. <el-table-column
  82. prop="size"
  83. label="大小"
  84. />
  85. <el-table-column
  86. prop="fileType"
  87. label="文件类型"
  88. >
  89. <template slot-scope="scope">
  90. <el-tag v-if="scope.row.fileType === 1000" :type="'warning'" disable-transitions>
  91. 目录
  92. </el-tag>
  93. <el-tag v-else-if="scope.row.fileType === 1001" :type="'warning'" disable-transitions>
  94. 图片
  95. </el-tag>
  96. <el-tag v-else-if="scope.row.fileType === 1002" :type="'success'" disable-transitions>
  97. 视频
  98. </el-tag>
  99. <el-tag v-else-if="scope.row.fileType === 1003" :type="'danger'" disable-transitions>
  100. 音频
  101. </el-tag>
  102. <el-tag v-else-if="scope.row.fileType === 1004" :type="'danger'" disable-transitions>
  103. 文本
  104. </el-tag>
  105. <el-tag v-else :type="'danger'" disable-transitions>
  106. 其他
  107. </el-tag>
  108. </template>
  109. </el-table-column>
  110. <el-table-column
  111. label="操作"
  112. >
  113. <template slot-scope="scope">
  114. <el-button
  115. size="mini"
  116. @click="getDetail(scope.row.fileId)"
  117. >详情</el-button>
  118. <el-button
  119. size="mini"
  120. @click="cache(scope.row)"
  121. >分享</el-button>
  122. <el-button
  123. size="mini"
  124. @click="cache(scope.row)"
  125. >删除</el-button>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. </el-row>
  130. <el-row>
  131. <el-pagination
  132. background
  133. :small="screenWidth <= 768"
  134. layout="prev, pager, next"
  135. :page-size="pageSize"
  136. :current-page="currentPage"
  137. :total="totalSize"
  138. @current-change="handleCurrentChange"
  139. @prev-click="handleCurrentChange"
  140. @next-click="handleCurrentChange"
  141. />
  142. </el-row>
  143. <!--创建新目录弹窗-->
  144. <el-dialog
  145. title="创建新目录"
  146. append-to-body
  147. :visible.sync="createFolderDialog"
  148. width="30%"
  149. center
  150. >
  151. <el-form ref="form" :model="createFolderForm">
  152. <el-form-item label="目录名">
  153. <el-input
  154. v-model="createFolderForm.folderName"
  155. placeholder="新目录名"
  156. style="width: 70%; padding-right: 2px"
  157. clearable
  158. />
  159. </el-form-item>
  160. <el-form-item>
  161. <el-button
  162. type="primary"
  163. @click="onCreateFolder"
  164. >创建</el-button>
  165. </el-form-item>
  166. </el-form>
  167. </el-dialog>
  168. <!--文件预览弹窗-->
  169. <el-dialog
  170. title="预览文件"
  171. append-to-body
  172. :visible.sync="previewFileDialog"
  173. width="70%"
  174. center
  175. >
  176. <div v-if="fileDetail !== null">
  177. <div v-if="fileDetail.fileType === 1001">
  178. <el-image :src="fileDetail.originalUrl" />
  179. </div>
  180. <div v-else-if="fileDetail.fileType === 1002">
  181. <video-preview-player :video-prop.sync="videoProp" />
  182. </div>
  183. <div v-else-if="fileDetail.fileType === 1003">
  184. <span>音频文件</span>
  185. </div>
  186. <div v-else-if="fileDetail.fileType === 1004">
  187. <span>文本文件</span>
  188. </div>
  189. <div v-else>
  190. <span>文件没有预览</span>
  191. </div>
  192. </div>
  193. </el-dialog>
  194. <!--移动/复制弹窗-->
  195. <el-dialog
  196. title="移动文件"
  197. append-to-body
  198. :visible.sync="moveDialog"
  199. width="50%"
  200. center
  201. >
  202. <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
  203. <el-card class="box-card" :body-style="{ paddingTop: '0px' }">
  204. <div slot="header" class="clearfix">
  205. <span>选择目录</span>
  206. <el-button style="float: right; padding: 3px 0" type="text" @click="onMove">确定</el-button>
  207. </div>
  208. <div class="item">
  209. <el-tree
  210. :accordion="true"
  211. :data="treeNode"
  212. :props="defaultProps"
  213. highlight-current
  214. @node-click="handleNodeClick"
  215. >
  216. <span slot-scope="{ node, data }">
  217. <span :class="data.icon">{{ node.label }}</span>
  218. </span>
  219. </el-tree>
  220. </div>
  221. </el-card>
  222. </el-row>
  223. </el-dialog>
  224. </el-row>
  225. </template>
  226. <script>
  227. import VideoPreviewPlayer from 'components/VideoPreviewPlayer'
  228. import {
  229. getFileList,
  230. deleteDiskFile,
  231. addDiskFolder,
  232. getFileDetail,
  233. getFileUrl,
  234. getFolderTree,
  235. moveDiskFile
  236. } from '@/api/disk'
  237. export default {
  238. name: 'FileList',
  239. components: { VideoPreviewPlayer },
  240. data() {
  241. return {
  242. // 屏幕宽度, 为了控制分页条的大小
  243. screenWidth: document.body.clientWidth,
  244. currentPage: 1,
  245. pageSize: 10,
  246. totalSize: 0,
  247. dataList: [],
  248. searchForm: {
  249. page: 1,
  250. path: '/',
  251. fileType: '0',
  252. filename: null
  253. },
  254. currentDir: '/',
  255. multipleSelection: [],
  256. parentDirs: [],
  257. createFolderDialog: false,
  258. createFolderForm: {
  259. parent: null,
  260. folderName: null
  261. },
  262. previewFileDialog: false,
  263. fileDetail: null,
  264. moveDialog: false,
  265. treeNode: [],
  266. defaultProps: {
  267. children: 'children',
  268. label: 'label',
  269. value: 'value'
  270. },
  271. moveForm: {
  272. type: 1,
  273. pid: null,
  274. fileIds: []
  275. }
  276. }
  277. },
  278. created() {
  279. const path = this.$route.query.path
  280. if (path !== undefined && path !== null) {
  281. this.searchForm.path = path
  282. }
  283. document.title = '文件列表'
  284. this.getData(this.searchForm)
  285. },
  286. methods: {
  287. handleCurrentChange(pageNumber) {
  288. this.currentPage = pageNumber
  289. this.searchForm.page = this.currentPage
  290. this.getData(this.searchForm)
  291. // 回到顶部
  292. scrollTo(0, 0)
  293. },
  294. getData(searchForm) {
  295. this.dataList = []
  296. getFileList(searchForm).then(resp => {
  297. if (resp.code === 0) {
  298. this.dataList = resp.data.fileList.list
  299. this.totalSize = resp.data.fileList.totalSize
  300. this.parentDirs = resp.data.pathList
  301. this.currentDir = this.parentDirs[this.parentDirs.length - 1].path
  302. } else {
  303. this.$notify({
  304. title: '提示',
  305. message: resp.msg,
  306. type: 'warning',
  307. duration: 3000
  308. })
  309. }
  310. }).catch(error => {
  311. this.$notify({
  312. title: '提示',
  313. message: error.message,
  314. type: 'error',
  315. duration: 3000
  316. })
  317. })
  318. },
  319. getDetail(fileId) {
  320. getFileDetail(fileId).then(resp => {
  321. if (resp.code === 0) {
  322. console.log(resp.data)
  323. }
  324. })
  325. },
  326. cache(row) {
  327. },
  328. search() {
  329. this.currentPage = 1
  330. this.searchForm.page = this.currentPage
  331. this.getData(this.searchForm)
  332. },
  333. handleSelectionChange(val) {
  334. this.multipleSelection = val
  335. },
  336. goToUpload() {
  337. const path = '/disk/upload'
  338. if (this.$route.path === path) {
  339. this.$router.go(0)
  340. return
  341. }
  342. this.$router.push(path)
  343. },
  344. downloadFile() {
  345. console.log('下载文件')
  346. },
  347. deleteMultiple() {
  348. if (this.multipleSelection.length === 0) {
  349. this.$notify({
  350. message: '至少应选中一行',
  351. type: 'warning',
  352. duration: 3000
  353. })
  354. return
  355. }
  356. var fileIds = []
  357. for (const item of this.multipleSelection) {
  358. fileIds.push(item.fileId)
  359. }
  360. this.$confirm('确定要删除文件?', '提示', {
  361. confirmButtonText: '确定',
  362. cancelButtonText: '取消',
  363. type: 'warning'
  364. }).then(() => {
  365. deleteDiskFile(fileIds).then(resp => {
  366. if (resp.code === 0) {
  367. this.$refs.multipleTable.clearSelection()
  368. this.$notify({
  369. message: resp.msg,
  370. type: 'warning',
  371. duration: 3000
  372. })
  373. } else {
  374. this.$notify({
  375. title: '提示',
  376. message: resp.msg,
  377. type: 'warning',
  378. duration: 3000
  379. })
  380. }
  381. }).catch(error => {
  382. this.$notify({
  383. title: '提示',
  384. message: error.message,
  385. type: 'error',
  386. duration: 3000
  387. })
  388. })
  389. }).catch(() => {
  390. this.$message({
  391. type: 'info',
  392. message: '已取消'
  393. })
  394. })
  395. },
  396. handleFile(item) {
  397. const fileType = item.fileType
  398. if (fileType === 1000) {
  399. const filename = item.filename
  400. const namePath = this.parentDirs[this.parentDirs.length - 1]
  401. let currentPath
  402. if (namePath.filename === '/') {
  403. currentPath = namePath.path + filename
  404. } else {
  405. currentPath = namePath.path + '/' + filename
  406. }
  407. this.searchForm.path = currentPath
  408. this.getData(this.searchForm)
  409. } else {
  410. const fileId = item.fileId
  411. this.previewFile(fileType, fileId)
  412. }
  413. },
  414. goTo(path) {
  415. this.searchForm.page = 1
  416. this.searchForm.path = path
  417. this.getData(this.searchForm)
  418. },
  419. previewFile(fileType, fileId) {
  420. getFileUrl(fileType, fileId).then(resp => {
  421. if (resp.code === 0) {
  422. this.fileDetail = resp.data
  423. this.previewFileDialog = true
  424. }
  425. })
  426. },
  427. createNewFolder() {
  428. this.createFolderDialog = true
  429. },
  430. onCreateFolder() {
  431. this.createFolderForm.parent = this.currentDir
  432. addDiskFolder(this.createFolderForm).then(resp => {
  433. if (resp.code === 0) {
  434. this.$router.go(0)
  435. } else {
  436. this.$notify({
  437. message: resp.msg,
  438. type: 'warning',
  439. duration: 3000
  440. })
  441. }
  442. })
  443. },
  444. move(type) {
  445. if (this.multipleSelection.length === 0) {
  446. this.$notify({
  447. message: '至少应选中一行',
  448. type: 'warning',
  449. duration: 3000
  450. })
  451. return
  452. }
  453. this.moveForm.type = type
  454. for (const item of this.multipleSelection) {
  455. this.moveForm.fileIds.push(item.fileId)
  456. }
  457. getFolderTree().then(resp => {
  458. if (resp.code === 0) {
  459. this.treeNode = resp.data
  460. this.moveDialog = true
  461. } else {
  462. this.$notify({
  463. title: '提示',
  464. message: resp.msg,
  465. type: 'error',
  466. duration: 3000
  467. })
  468. }
  469. }).catch(error => {
  470. this.$notify({
  471. title: '提示',
  472. message: error.message,
  473. type: 'warning',
  474. duration: 3000
  475. })
  476. })
  477. },
  478. handleNodeClick(data) {
  479. this.moveForm.pid = data.fileId
  480. },
  481. onMove() {
  482. moveDiskFile(this.moveForm).then(resp => {
  483. if (resp.code === 0) {
  484. this.moveDialog = false
  485. this.$refs.multipleTable.clearSelection()
  486. }
  487. })
  488. },
  489. share() {
  490. console.log('分享文件')
  491. }
  492. }
  493. }
  494. </script>
  495. <style>
  496. </style>