FileList.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  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="onSelect">
  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() {
  295. this.dataList = []
  296. getFileList(this.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. onSelect() {
  329. this.currentPage = 1
  330. this.searchForm.page = this.currentPage
  331. this.getData(this.searchForm)
  332. },
  333. search() {
  334. this.currentPage = 1
  335. this.searchForm.page = this.currentPage
  336. this.getData(this.searchForm)
  337. },
  338. handleSelectionChange(val) {
  339. this.multipleSelection = val
  340. },
  341. goToUpload() {
  342. const path = '/disk/upload'
  343. if (this.$route.path === path) {
  344. this.$router.go(0)
  345. return
  346. }
  347. this.$router.push(path)
  348. },
  349. downloadFile() {
  350. console.log('下载文件')
  351. },
  352. deleteMultiple() {
  353. if (this.multipleSelection.length === 0) {
  354. this.$notify({
  355. message: '至少应选中一行',
  356. type: 'warning',
  357. duration: 3000
  358. })
  359. return
  360. }
  361. var fileIds = []
  362. for (const item of this.multipleSelection) {
  363. fileIds.push(item.fileId)
  364. }
  365. this.$confirm('确定要删除文件?', '提示', {
  366. confirmButtonText: '确定',
  367. cancelButtonText: '取消',
  368. type: 'warning'
  369. }).then(() => {
  370. deleteDiskFile(fileIds).then(resp => {
  371. if (resp.code === 0) {
  372. this.$refs.multipleTable.clearSelection()
  373. this.$notify({
  374. message: resp.msg,
  375. type: 'warning',
  376. duration: 3000
  377. })
  378. } else {
  379. this.$notify({
  380. title: '提示',
  381. message: resp.msg,
  382. type: 'warning',
  383. duration: 3000
  384. })
  385. }
  386. }).catch(error => {
  387. this.$notify({
  388. title: '提示',
  389. message: error.message,
  390. type: 'error',
  391. duration: 3000
  392. })
  393. })
  394. }).catch(() => {
  395. this.$message({
  396. type: 'info',
  397. message: '已取消'
  398. })
  399. })
  400. },
  401. handleFile(item) {
  402. console.log(item)
  403. const fileType = item.fileType
  404. if (fileType === 1000) {
  405. const filename = item.filename
  406. const namePath = this.parentDirs[this.parentDirs.length - 1]
  407. let currentPath
  408. if (namePath.filename === '/') {
  409. currentPath = namePath.path + filename
  410. } else {
  411. currentPath = namePath.path + '/' + filename
  412. }
  413. this.searchForm.path = currentPath
  414. this.getData(this.searchForm)
  415. } else {
  416. const fileId = item.fileId
  417. this.previewFile(fileType, fileId)
  418. }
  419. },
  420. goTo(path) {
  421. this.searchForm.page = 1
  422. this.searchForm.path = path
  423. this.getData(this.searchForm)
  424. },
  425. previewFile(fileType, fileId) {
  426. getFileUrl(fileType, fileId).then(resp => {
  427. if (resp.code === 0) {
  428. this.fileDetail = resp.data
  429. this.previewFileDialog = true
  430. }
  431. }).catch(error => {
  432. this.$notify({
  433. title: '请求错误',
  434. message: error.message,
  435. type: 'error',
  436. duration: 3000
  437. })
  438. })
  439. },
  440. createNewFolder() {
  441. this.createFolderDialog = true
  442. },
  443. onCreateFolder() {
  444. this.createFolderForm.parent = this.currentDir
  445. addDiskFolder(this.createFolderForm).then(resp => {
  446. if (resp.code === 0) {
  447. this.$router.go(0)
  448. } else {
  449. this.$notify({
  450. message: resp.msg,
  451. type: 'warning',
  452. duration: 3000
  453. })
  454. }
  455. })
  456. },
  457. move(type) {
  458. if (this.multipleSelection.length === 0) {
  459. this.$notify({
  460. message: '至少应选中一行',
  461. type: 'warning',
  462. duration: 3000
  463. })
  464. return
  465. }
  466. this.moveForm.type = type
  467. for (const item of this.multipleSelection) {
  468. this.moveForm.fileIds.push(item.fileId)
  469. }
  470. getFolderTree().then(resp => {
  471. if (resp.code === 0) {
  472. this.treeNode = resp.data
  473. this.moveDialog = true
  474. } else {
  475. this.$notify({
  476. title: '提示',
  477. message: resp.msg,
  478. type: 'error',
  479. duration: 3000
  480. })
  481. }
  482. }).catch(error => {
  483. this.$notify({
  484. title: '提示',
  485. message: error.message,
  486. type: 'warning',
  487. duration: 3000
  488. })
  489. })
  490. },
  491. handleNodeClick(data) {
  492. this.moveForm.pid = data.fileId
  493. },
  494. onMove() {
  495. moveDiskFile(this.moveForm).then(resp => {
  496. if (resp.code === 0) {
  497. this.moveDialog = false
  498. this.$refs.multipleTable.clearSelection()
  499. }
  500. })
  501. },
  502. share() {
  503. this.$notify({
  504. title: '提示',
  505. message: '分享文件接口未实现',
  506. type: 'info',
  507. duration: 3000
  508. })
  509. }
  510. }
  511. }
  512. </script>
  513. <style>
  514. </style>