cloudDisk.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. <template>
  2. <div id="cloud-disk-container">
  3. <div class="top-zone">
  4. <div class="button-zone" v-show="tableSelection && tableSelection.length!=0">
  5. <el-button v-permission="permissionBtn.cloudDisk.cloudDisk_download"
  6. class="download-button" @click="downloadBatch">{{$t('ReportManage.CloudPage.column_download_btn')}}</el-button>
  7. <el-button v-permission="permissionBtn.cloudDisk.cloudDisk_del"
  8. type="danger" style="min-width: 112px;" @click="removeBatch" v-if="buttonPermission.batchDelete">{{$t('ReportManage.CloudPage.column_delete_btn')}}</el-button>
  9. </div>
  10. <div class="button-zone" v-show="(!tableSelection || tableSelection.length==0) && keyword==''">
  11. <el-button type="primary" v-permission="permissionBtn.cloudDisk.cloudDisk_newDir"
  12. @click="newFloder" v-if="buttonPermission.createMenuAuth">{{ $t('ReportManage.CloudPage.folder_btn') }}</el-button>
  13. <template v-if="buttonPermission.uploadResourceAuth">
  14. <el-button v-permission="permissionBtn.cloudDisk.cloudDisk_uploadFile"
  15. type="primary" style="min-width: 112px;"
  16. @click="uploadFilePre" :loading="isUploading">{{ $t('ReportManage.CloudPage.upload_btn') }}</el-button>
  17. <el-upload
  18. action="#"
  19. ref="upload"
  20. style="height: 0;width: 0;"
  21. multiple
  22. :show-file-list="false"
  23. :auto-upload="false"
  24. :on-change="fileChange">
  25. </el-upload>
  26. </template>
  27. </div>
  28. <div class="search-zone">
  29. <el-input v-model.trim="keyword" prefix-icon="el-icon-search"
  30. style="width: 317px;" :placeholder="$t('ReportManage.CloudPage.input_content')" clearable @input="getFileList(null,0)" ></el-input>
  31. </div>
  32. </div>
  33. <div class="table-zone" >
  34. <div class="bread-crumb-row" v-show="keyword==''">
  35. <el-breadcrumb>
  36. <el-breadcrumb-item class="bread-crumb-item" v-for="item in breadCrumbsList" :key="item.name">
  37. <span @click="breadcrumbsNavigate(item)">{{ item.MenuName }}</span>
  38. </el-breadcrumb-item>
  39. </el-breadcrumb>
  40. </div>
  41. <div class="table-item">
  42. <el-table :data="tableData" max-height="700" ref="tableRef" header-row-class-name="custom-table-header"
  43. @selection-change="selectionChange" @sort-change="sortChange" :select-on-indeterminate="false"
  44. @row-click="tableRowClick" :row-class-name="setRowClass">
  45. <el-table-column
  46. type="selection" class="select-column"
  47. width="37" align="right">
  48. </el-table-column>
  49. <el-table-column prop="ItemName" show-overflow-tooltip >
  50. <template slot="header" slot-scope="scope">
  51. {{ tableSelection.length>0?/* `已选中${tableSelection.length}个文件/文件夹` */$t('ReportManage.CloudPage.selected_msg',{num:tableSelection.length}):$t('ReportManage.CloudPage.column_name') }}
  52. </template>
  53. <template slot-scope="{row}">
  54. <div class="file-name">
  55. <img :src="iconGetMap(row)" />
  56. <span class="active-file-name">{{ row.ItemName }}</span>
  57. </div>
  58. </template>
  59. </el-table-column>
  60. <el-table-column :label="$t('ReportManage.CloudPage.column_author')" prop="AdminName" width="112" show-overflow-tooltip>
  61. <template slot-scope="{row}">
  62. {{ row.AdminName }}
  63. </template>
  64. </el-table-column>
  65. <el-table-column :label="$t('ReportManage.CloudPage.column_creation_time')" prop="CreateTime" sortable="custom" width="190">
  66. <template slot-scope="{row}">
  67. {{ row.CreateTime }}
  68. </template>
  69. </el-table-column>
  70. <el-table-column :label="$t('ReportManage.CloudPage.column_font')" prop="SizeName" width="140" show-overflow-tooltip>
  71. <template slot="header" slot-scope="scope">
  72. {{ keyword==''? $t('ReportManage.CloudPage.column_font'):'所在目录' }}
  73. </template>
  74. <template slot-scope="{row}">
  75. <span v-show="keyword==''">{{row.SizeName}}</span>
  76. <span v-show="keyword!=''" @click="navigateFolder(row)" class="file-parent-menu" >{{row.ParentName || '--'}}</span>
  77. </template>
  78. </el-table-column>
  79. <el-table-column width="40">
  80. <template slot-scope="{row}" >
  81. <el-dropdown v-if="isDropDownShow"
  82. @command="(type)=>handleCommand(type,row)" class="more-operation" >
  83. <span class="el-dropdown-link" @click="(e)=> e.stopPropagation()">
  84. <i class="el-icon-more el-icon--right" style="font-size: 24px;cursor: pointer;"></i>
  85. </span>
  86. <el-dropdown-menu slot="dropdown">
  87. <el-dropdown-item command="rename" v-permission="permissionBtn.cloudDisk.cloudDisk_rename"
  88. v-if="row.ButtonAuth.RenameAuth">{{$t('ReportManage.CloudPage.column_rename_btn')}}</el-dropdown-item>
  89. <el-dropdown-item command="download" v-permission="permissionBtn.cloudDisk.cloudDisk_download"
  90. >{{$t('ReportManage.CloudPage.column_download_btn')}}</el-dropdown-item>
  91. <el-dropdown-item command="remove" v-permission="permissionBtn.cloudDisk.cloudDisk_del"
  92. ><span style="color:#D1433A ;" v-if="row.ButtonAuth.DelAuth" >{{$t('ReportManage.CloudPage.column_delete_btn')}}</span></el-dropdown-item>
  93. </el-dropdown-menu>
  94. </el-dropdown>
  95. </template>
  96. </el-table-column>
  97. <template slot="empty" >
  98. <div style="padding: 140px 0">
  99. <tableNoData :text="$t('ReportManage.CloudPage.table_no_file')"/>
  100. </div>
  101. </template>
  102. </el-table>
  103. </div>
  104. </div>
  105. <!-- 新建文件夹、重命名弹窗 -->
  106. <el-dialog :title="dialogTitle" :visible.sync="newDialogShow" :close-on-click-modal="false"
  107. :modal-append-to-body="false" @closed="closeNewDialog" width="408px" id="newOrRename">
  108. <el-form :model="newOrRenameForm" ref="newOrRenameForm">
  109. <el-form-item prop="itemValue" :rules="{required:true,message:$t('ReportManage.CloudPage.rules_prompt'),trigger:'blur'}">
  110. <el-input v-model="newOrRenameForm.itemValue" :placeholder="$t('ReportManage.CloudPage.input_file_name')" style="width: 100%;"></el-input>
  111. </el-form-item>
  112. </el-form>
  113. <template slot="footer">
  114. <el-button @click="newDialogShow=false" size="small">{{$t('Dialog.cancel_btn')}}</el-button>
  115. <el-button type="primary" @click="newOrRenameConFirm" size="small" style="margin-left: 4px;" >
  116. {{ dialogTitle==$t('ReportManage.CloudPage.folder_btn')?$t('ReportManage.CloudPage.create_btn') :$t('Dialog.confirm_btn')}}
  117. </el-button>
  118. </template>
  119. </el-dialog>
  120. <!-- 选择文件夹弹窗 -->
  121. <el-dialog :title="dialogTitle" :visible.sync="chooseFolderDiaShow" :close-on-click-modal="false" top="5vh"
  122. append-to-body width="640px" @closed="closeChooseFolderDia" >
  123. <div class="choose-folder-box" id="choose-folder-box">
  124. <div class="folder-item">
  125. {{$t('ReportManage.CloudPage.folder_location')}}:<span>{{ folderPath || '--' }}</span>
  126. </div>
  127. <el-scrollbar style="height:470px;overflow-x: hidden;width: 100%;">
  128. <el-tree :data="treeData" icon-class="none" @node-click="chooseFolder"
  129. :props="{label:'MenuName',value:'MenuId',children:'Children'}" :indent="42" node-key="id" v-if="chooseFolderDiaShow">
  130. <div slot-scope="{ node, data }" class="folder-tree-item">
  131. <div class="folder-tree-name">
  132. <img src="../../assets/icons/folder.svg" />
  133. <span :style="{'color':node.isCurrent?'#409EFF':'unset'}">{{ node.label}}</span>
  134. </div>
  135. <i class="el-icon-caret-bottom" style="color: #C0C4CC;transition: all .3s ease-in;"
  136. :style="{'transform':node.expanded?'rotate(180deg)':''}"
  137. v-show="node.childNodes.length>0"></i>
  138. </div>
  139. </el-tree>
  140. </el-scrollbar>
  141. </div>
  142. <div class="choose-dialog-footer">
  143. <el-button type="primary" @click="chooseFolderconFirm" size="medium" style="margin-left: 26px;width: 100px;">{{$t('Dialog.confirm_btn')}}</el-button>
  144. <el-button @click="chooseFolderDiaShow=false" size="medium" style="width: 100px;">{{$t('Dialog.cancel_btn')}}</el-button>
  145. </div>
  146. </el-dialog>
  147. </div>
  148. </template>
  149. <script>
  150. import {cloudDiskInterface} from '@/api/api.js'
  151. import {downloadByFlow} from '@/utils/common.js'
  152. import {downloadFileByUrl} from '@/api/http.js'
  153. import streamSaver from 'streamsaver'
  154. import 'streamsaver/examples/zip-stream'
  155. export default {
  156. name:"cloudDisk",
  157. watch:{
  158. currentMenuId(value){
  159. // 保存目录ID
  160. sessionStorage.setItem('cloudDiskMenuId',value)
  161. }
  162. },
  163. data() {
  164. return {
  165. keyword:'',
  166. currentMenuId:0,
  167. // 上传的目录ID
  168. uploadMenuId:0,
  169. sortType:0,
  170. tableData:[],
  171. // 操作按钮权限
  172. buttonPermission:{
  173. createMenuAuth:false,
  174. uploadResourceAuth:false,
  175. batchDelete:false
  176. },
  177. treeData:[],
  178. breadCrumbsList:[],
  179. tableSelection:[],
  180. currentRow:{},
  181. // 是否需要重新请求树形文件夹数据
  182. shouldRequestTree:false,
  183. // -----------------------------------------------------弹窗
  184. // 弹窗标题 会用来判断是 重命名 还是 新建文件夹
  185. dialogTitle:'',
  186. // -----------新建文件夹、重命名弹窗
  187. newDialogShow:false,
  188. newOrRenameForm:{
  189. itemValue:''
  190. },
  191. //-------上传
  192. timer:null,
  193. // 是否在上传中
  194. isUploading:false,
  195. folderPath:'',
  196. // 选择文件弹窗
  197. chooseFolderDiaShow:false,
  198. staticFileIco: require('@/assets/img/cloudDisk/file_icon.png'),
  199. staticImageIco: require('@/assets/img/cloudDisk/img_icon.png'),
  200. staticWordIco: require('@/assets/img/cloudDisk/word_icon.png'),
  201. staticExcelIco: require('@/assets/img/cloudDisk/excel_icon.png'),
  202. staticPptIco: require('@/assets/img/cloudDisk/ppt_icon.png'),
  203. staticPdfIco: require('@/assets/img/cloudDisk/pdf_icon.png'),
  204. staticVideoIco: require('@/assets/img/cloudDisk/video_icon.png'),
  205. staticAudioIco: require('@/assets/img/cloudDisk/audio_icon.png'),
  206. staticConfigIco: require('@/assets/img/cloudDisk/config_icon.png'),
  207. }
  208. },
  209. watch:{
  210. shouldRequestTree(value){
  211. if(value){
  212. // 重新请求树形文件夹数据
  213. this.getMenuTree()
  214. this.shouldRequestTree=false
  215. }
  216. }
  217. },
  218. computed:{
  219. //是否展示el-dropdown
  220. isDropDownShow(){
  221. return this.permissionBtn.checkPermissionBtn(
  222. this.permissionBtn.cloudDisk.cloudDisk_rename
  223. )||this.permissionBtn.checkPermissionBtn(
  224. this.permissionBtn.cloudDisk.cloudDisk_download
  225. )||this.permissionBtn.checkPermissionBtn(
  226. this.permissionBtn.cloudDisk.cloudDisk_del
  227. )
  228. }
  229. },
  230. methods:{
  231. // 获取文件夹dom树
  232. getMenuTree(){
  233. cloudDiskInterface.fileTreeList().then(res=>{
  234. if(res.Ret == 200){
  235. this.treeData = res.Data || []
  236. }
  237. })
  238. },
  239. // 获取文件列表
  240. getFileList(menuId,sortType){
  241. this.sortType=(sortType || sortType==0)?sortType:this.sortType
  242. this.currentMenuId=(menuId || menuId==0)?menuId:this.currentMenuId
  243. let params={
  244. Keyword:this.keyword,
  245. SortType:this.sortType,
  246. MenuId:this.currentMenuId
  247. }
  248. cloudDiskInterface.filelist(params).then(res=>{
  249. if(res.Ret == 200){
  250. this.tableData = res.Data.List || []
  251. this.buttonPermission.createMenuAuth = res.Data.CreateMenuAuth
  252. this.buttonPermission.uploadResourceAuth = res.Data.UploadResourceAuth
  253. this.buttonPermission.batchDelete = res.Data.BatchDelAuth
  254. let temArr = res.Data.ListPath || []
  255. this.breadCrumbsList = res.Data.ListPath?[{MenuId:0,MenuName:this.$t('ReportManage.CloudPage.everything'),Selected:false,Sort:0}].concat(temArr):[]
  256. }
  257. })
  258. },
  259. // 刷新列表 - 节流
  260. refreshFileList:_.throttle(function(){
  261. this.getFileList(null,0)
  262. this.$refs.tableRef.clearSort()
  263. }, 500,{
  264. leading: false,
  265. trailing: true
  266. }),
  267. // 面包屑跳转
  268. breadcrumbsNavigate(item){
  269. if(item.Selected){
  270. return
  271. }
  272. this.$refs.tableRef.clearSort()
  273. this.getFileList(item.MenuId,0)
  274. },
  275. // 新建文件夹
  276. newFloder(){
  277. this.dialogTitle= this.$t('ReportManage.CloudPage.folder_btn')
  278. this.newDialogShow=true
  279. this.newOrRenameForm.itemValue=""
  280. },
  281. // 上传文件
  282. uploadFilePre(){
  283. if(this.currentMenuId == 0){
  284. this.dialogTitle= this.$t('ReportManage.CloudPage.select_folder_title')
  285. this.chooseFolderDiaShow=true
  286. }else{
  287. this.uploadMenuId = this.currentMenuId
  288. this.$refs.upload.$el.getElementsByTagName('input')[0].click()
  289. }
  290. },
  291. chooseFolder(data,Node){
  292. // console.log(Node);
  293. let pathArray = []
  294. const getPath=(Node)=>{
  295. pathArray.unshift(Node.data.MenuName)
  296. if(Node.parent && Node.parent.level!=0){
  297. getPath(Node.parent)
  298. }
  299. }
  300. getPath(Node)
  301. this.folderPath=pathArray.join(' / ')
  302. this.uploadMenuId = Node.data.MenuId
  303. },
  304. // 选择文件夹确认
  305. chooseFolderconFirm(){
  306. if(!this.uploadMenuId || this.uploadMenuId==0){
  307. this.$message.error( this.$t('ReportManage.CloudPage.upload_folder_error_msg'))
  308. return
  309. }
  310. this.$refs.upload.$el.getElementsByTagName('input')[0].click()
  311. },
  312. closeChooseFolderDia(){
  313. this.folderPath=''
  314. this.uploadMenuId=0
  315. },
  316. //上传文件 - 文件改变 - 收集所有上传的文件
  317. fileChange(fileList){
  318. let realFileList = fileList
  319. if(!Array.isArray(fileList)){
  320. realFileList=[fileList]
  321. }
  322. this.checkFileRepeat(realFileList)
  323. },
  324. // 检测文件是否重复
  325. checkFileRepeat(fileList){
  326. if (this.timer) {
  327. clearTimeout(this.timer);
  328. this.timer = null;
  329. }
  330. this.timer = setTimeout(() => {
  331. // 上传之前先检验
  332. let fileNames = fileList.map(it => it.name)
  333. cloudDiskInterface.checkFileNamesIsRepeat({MenuId:parseInt(this.uploadMenuId),FileNames:fileNames}).then(res=>{
  334. // 文件名列表中只要有重名的,提示重名
  335. if(res.Ret == 200){
  336. let result = res.Data || []
  337. let haveRepeatFiles = result.filter(item => {
  338. if(item.IsRepeat){
  339. return item
  340. }
  341. })
  342. // console.log(haveRepeatFiles);
  343. if(haveRepeatFiles && haveRepeatFiles.length>0){
  344. // 有重复
  345. this.$confirm(haveRepeatFiles.map(it => it.OriginName).join(',')+this.$t('ReportManage.CloudPage.upload_please_error_msg'), this.$t('Confirm.prompt'),{
  346. type:'warning',
  347. confirmButtonText: this.$t('ReportManage.CloudPage.upload_confirm_btn'),
  348. }).then(res=>{
  349. this.uploadFiles(fileList,result)
  350. }).catch(() => {
  351. this.$refs.upload.clearFiles()
  352. this.chooseFolderDiaShow=false
  353. })
  354. }else{
  355. this.uploadFiles(fileList,result)
  356. }
  357. }
  358. })
  359. }, 500);
  360. },
  361. // 上传文件
  362. uploadFiles(files,nameList){
  363. this.isUploading=true
  364. let uploadLoading=this.$message({
  365. type:"info",
  366. message:/* '上传中,请稍后······' */this.$t('ReportManage.CloudPage.upload_msg'),
  367. duration:0,
  368. iconClass:'el-icon-loading'
  369. })
  370. let uploadNumber = 0
  371. files.map((item,index) =>{
  372. let formData = new FormData()
  373. formData.append('file',item.raw)
  374. formData.append('MenuId',this.uploadMenuId)
  375. formData.append('OriginName',nameList[index].AvailableName)
  376. cloudDiskInterface.uploadFile(formData).then(res=>{
  377. if(res.Ret == 200){
  378. this.$message.success(`${res.Data.ResourceName}${res.Data.ResourceSuffix}` + this.$t('ReportManage.CloudPage.upload_success_msg') )
  379. this.refreshFileList()
  380. }
  381. }).finally(()=>{
  382. uploadNumber++
  383. if(uploadNumber == files.length){
  384. uploadLoading.close()
  385. this.isUploading=false
  386. this.chooseFolderDiaShow=false
  387. this.$refs.upload.clearFiles()
  388. }
  389. })
  390. })
  391. },
  392. // 重命名
  393. renameFile(row){
  394. this.currentRow=row
  395. this.dialogTitle=this.$t('ReportManage.CloudPage.column_rename_btn')
  396. this.newDialogShow=true
  397. let realName;
  398. if(row.ItemType == 1){
  399. // 文件夹
  400. realName=row.ItemName
  401. }else if(row.ItemType == 2){
  402. // 文件 - 去掉后缀
  403. let lastIndex = row.ItemName.lastIndexOf('.')
  404. realName = row.ItemName.substring(0,lastIndex)
  405. }
  406. this.newOrRenameForm.itemValue=realName
  407. },
  408. // 去对应文件夹
  409. navigateFolder(row){
  410. window.event.stopPropagation()
  411. this.keyword=''
  412. this.getFileList(row.ParentId,0)
  413. },
  414. // 下载文件夹 - 压缩包
  415. downloadFloder(zipName = '新建文件夹.zip',files){
  416. const that=this;
  417. return new Promise((resolve,reject)=>{
  418. try {
  419. const zipFileOutputStream = streamSaver.createWriteStream(zipName);
  420. const fileIterator = files.values();
  421. const readableZipStream = new ZIP({
  422. async pull(ctrl) {
  423. const fileInfo = fileIterator.next();
  424. if (fileInfo.done) {//迭代终止
  425. ctrl.close();
  426. } else {
  427. const {ResourceName, ResourceUrl} = fileInfo.value;
  428. return fetch(ResourceUrl).then(res => {
  429. ctrl.enqueue({
  430. name:ResourceName,
  431. stream: () => res.body
  432. });
  433. }).catch((err)=>{
  434. that.$message.error(err.message)
  435. reject(err.message)
  436. })
  437. }
  438. }
  439. })
  440. if (window.WritableStream && readableZipStream.pipeTo) {
  441. // 开始下载
  442. readableZipStream
  443. .pipeTo(zipFileOutputStream)
  444. .then(() => {
  445. resolve()
  446. });
  447. }else{
  448. this.$message.error(/* '浏览器不支持' */this.$t('MsgPrompt.browser_not_support'))
  449. reject('浏览器不支持')
  450. }
  451. } catch (error) {
  452. this.$message.error(error.message)
  453. reject(error.message)
  454. }
  455. })
  456. },
  457. // 下载文件
  458. downloadFile(row){
  459. if(row.Size === 0) return this.$message.warning(this.$t('ReportManage.CloudPage.download_msg'))
  460. let downloadHint = this.$message({
  461. type:"info",
  462. message:row.ItemName+/* '开始下载,请勿重复下载' */this.$t('ReportManage.CloudPage.download_info_msg'),
  463. duration:0,
  464. iconClass:'el-icon-loading'
  465. })
  466. if(row.ItemType==1){
  467. // 下载压缩包
  468. cloudDiskInterface.getFilesByMenuId({MenuId:row.ItemId}).then(res=>{
  469. if(res.Ret == 200){
  470. this.downloadFloder(row.ItemName+'.zip',res.Data || []).then(res=>{
  471. this.$message.success(row.ItemName + this.$t('ReportManage.CloudPage.download_success_msg') )
  472. }).finally(()=>{
  473. downloadHint.close()
  474. })
  475. }
  476. }).catch(()=>{
  477. downloadHint.close()
  478. })
  479. }else if(row.ItemType==2){
  480. this.handleDownloadResource(row.ResourceUrl,row.ItemName,()=>{
  481. this.$message.success(row.ItemName + this.$t('ReportManage.CloudPage.download_success_msg'))
  482. downloadHint.close()
  483. },()=>{
  484. this.$message.error(row.ItemName + /* '下载失败' */this.$t('ReportManage.CloudPage.download_fail_msg'))
  485. downloadHint.close()
  486. })
  487. }
  488. },
  489. downloadBatch(){
  490. if(!this.tableSelection || this.tableSelection.length==0){
  491. this.$message.warning(/* '请至少选择一个文件/文件夹' */ this.$t('ReportManage.CloudPage.download_banch_msg'))
  492. return
  493. }
  494. let emptyFolders=this.tableSelection.filter(it => it.Size==0)
  495. let downloadHint = this.$message({
  496. type:"info",
  497. message:this.$t('ReportManage.CloudPage.download_info_msg'),
  498. duration:0,
  499. iconClass:'el-icon-loading'
  500. })
  501. setTimeout(()=>{
  502. if(emptyFolders.length==0) return
  503. if(emptyFolders.length == this.tableSelection.length){
  504. downloadHint.close()
  505. this.$refs.tableRef.clearSelection()
  506. }
  507. this.$message.warning(`【${emptyFolders.map(it => it.ItemName).join('、')}】`+/* '文件夹为空,暂不支持下载' */this.$t('ReportManage.CloudPage.download_msg'))
  508. },0)
  509. let downNumber = 0
  510. let selectLength = this.tableSelection.length-emptyFolders.length
  511. this.tableSelection.map(item=>{
  512. if(item.Size == 0) return
  513. if(item.ItemType==1){
  514. // 下载压缩包
  515. cloudDiskInterface.getFilesByMenuId({MenuId:item.ItemId}).then(res=>{
  516. if(res.Ret == 200){
  517. this.downloadFloder(item.ItemName+'.zip',res.Data || []).then(res=>{
  518. this.$message.success(item.ItemName + this.$t('ReportManage.CloudPage.download_success_msg'))
  519. }).finally(()=>{
  520. downNumber++
  521. // 请求下载的数量等于所选的数组长度时,去掉loading
  522. if(downNumber == selectLength){
  523. downloadHint.close()
  524. this.$refs.tableRef.clearSelection()
  525. }
  526. })
  527. }else{
  528. downNumber++
  529. }
  530. }).catch(()=>{
  531. downNumber++
  532. // 请求下载的数量等于所选的数组长度时,去掉loading
  533. if(downNumber == selectLength){
  534. downloadHint.close()
  535. this.$refs.tableRef.clearSelection()
  536. }
  537. })
  538. }else if(item.ItemType==2){
  539. // 下载文件
  540. const that = this
  541. this.handleDownloadResource(item.ResourceUrl,item.ItemName,()=>{
  542. this.$message.success(item.ItemName + this.$t('ReportManage.CloudPage.download_success_msg'))
  543. downloadHint.close()
  544. downNumber++
  545. if(downNumber == selectLength){
  546. downloadHint.close()
  547. that.$refs.tableRef.clearSelection()
  548. }
  549. },()=>{
  550. this.$message.error(item.ItemName + /* '下载失败' */this.$t('ReportManage.CloudPage.download_fail_msg'))
  551. downloadHint.close()
  552. downNumber++
  553. if(downNumber == selectLength){
  554. downloadHint.close()
  555. that.$refs.tableRef.clearSelection()
  556. }
  557. })
  558. }
  559. })
  560. },
  561. // 删除文件
  562. removeFile(row){
  563. let prop = row.ItemType==1?'removeFolder':'removeFile'
  564. let params=row.ItemType==1?{MenuId:row.ItemId}:{ResourceId:row.ItemId}
  565. this.$confirm(this.$t('MsgPrompt.delete_info_msg'),this.$t('ReportManage.CloudPage.column_delete_btn'),{
  566. type:'warning'
  567. }).then(res=>{
  568. cloudDiskInterface[prop](params).then(res=>{
  569. if(res.Ret == 200){
  570. this.$message.success(this.$t('ReportManage.CloudPage.delete_success_msg'))
  571. this.shouldRequestTree=true
  572. this.getFileList()
  573. }
  574. })
  575. }).catch(() => {})
  576. },
  577. removeBatch(){
  578. if(!this.tableSelection || this.tableSelection.length==0){
  579. this.$message.warning(/* '请至少选择一个文件/文件夹' */this.$t('ReportManage.CloudPage.download_banch_msg'))
  580. return
  581. }
  582. this.$confirm(this.$t('MsgPrompt.delete_info_msg'),this.$t('ReportManage.CloudPage.column_delete_btn'),{
  583. type:'warning'
  584. }).then(res=>{
  585. let MenuIdsArr=[]
  586. let ResourceIdsArr=[]
  587. // 分类文件夹和文件的Id
  588. this.tableSelection.map(it =>{
  589. if(it.ItemType==1){
  590. MenuIdsArr.push(it.ItemId)
  591. }else if(it.ItemType==2){
  592. ResourceIdsArr.push(it.ItemId)
  593. }
  594. })
  595. let params={
  596. MenuId:parseInt(this.currentMenuId),
  597. MenuIds:MenuIdsArr.join(','),
  598. ResourceIds:ResourceIdsArr.join(','),
  599. }
  600. cloudDiskInterface.removeFolderBatch(params).then(res=>{
  601. if(res.Ret == 200){
  602. this.$message.success(this.$t('ReportManage.CloudPage.delete_success_msg'))
  603. this.shouldRequestTree=true
  604. this.getFileList()
  605. }
  606. })
  607. }).catch(() => {})
  608. },
  609. // 新建、重命名弹窗关闭回调
  610. closeNewDialog(){
  611. this.newOrRenameForm.itemValue=''
  612. this.$refs.newOrRenameForm.clearValidate()
  613. },
  614. // 新建、重命名-确认
  615. newOrRenameConFirm(){
  616. this.$refs.newOrRenameForm.validate((valid)=>{
  617. if(valid){
  618. if(this.dialogTitle == this.$t('ReportManage.CloudPage.folder_btn')){
  619. // 新建
  620. cloudDiskInterface.addFolder({
  621. ParentId:this.currentMenuId,
  622. MenuName:this.newOrRenameForm.itemValue
  623. }).then(res=>{
  624. if(res.Ret == 200){
  625. this.$message.success(this.$t('ReportManage.CloudPage.folder_success_msg'))
  626. this.shouldRequestTree=true
  627. this.newDialogShow=false
  628. this.$refs.tableRef.clearSort()
  629. this.getFileList(null,0)
  630. }
  631. })
  632. }else if(this.dialogTitle == this.$t('ReportManage.CloudPage.column_rename_btn')){
  633. if(this.currentRow.ItemName == this.newOrRenameForm.itemValue){
  634. this.newDialogShow=false
  635. return
  636. }
  637. // 重命名 1 - 文件夹 2 - 文件
  638. let prop = this.currentRow.ItemType == 1?'renameFolder':'renameFile'
  639. let params=this.currentRow.ItemType == 1?{
  640. MenuId:this.currentRow.ItemId,
  641. MenuName:this.newOrRenameForm.itemValue
  642. }:{
  643. ResourceId:this.currentRow.ItemId,
  644. ResourceName:this.newOrRenameForm.itemValue
  645. }
  646. cloudDiskInterface[prop](params).then(res=>{
  647. if(res.Ret == 200){
  648. this.$message.success(this.$t('ReportManage.CloudPage.rename_dialog_success_msg'))
  649. this.shouldRequestTree=true
  650. this.newDialogShow=false
  651. this.getFileList()
  652. }
  653. })
  654. }
  655. }
  656. })
  657. },
  658. // 设置选中行的样式
  659. setRowClass({row}){
  660. // console.log(row,this.tableSelection);
  661. if(this.tableSelection.some(item => item.ItemId == row.ItemId)){
  662. return "hover-row-actice"
  663. }
  664. return ''
  665. },
  666. // 排序
  667. sortChange({order}){
  668. this.sortType = order == 'descending'?1:order == 'ascending'?2:0
  669. this.getFileList()
  670. },
  671. // 复选框变化
  672. selectionChange(value){
  673. this.tableSelection=value
  674. },
  675. // 表格行点击事件
  676. tableRowClick(row){
  677. if(row.ItemType == 1){
  678. this.currentMenuId = row.ItemId
  679. this.keyword=''
  680. this.getFileList(row.ItemId,0)
  681. }else if(row.ItemType == 2){
  682. // 预览文件
  683. let href;
  684. if(row.ResourceUrl.endsWith('.doc') || row.ResourceUrl.endsWith('.docx')||row.ResourceUrl.endsWith('.ppt')||
  685. row.ResourceUrl.endsWith('.pptx') || row.ResourceUrl.endsWith('.xls')||row.ResourceUrl.endsWith('.xlsx')){
  686. //是否是 ppt、doc、xls
  687. href = 'https://view.officeapps.live.com/op/view.aspx?src='+row.ResourceUrl
  688. }else{
  689. href=row.ResourceUrl
  690. }
  691. window.open(href, "_blank")
  692. }
  693. },
  694. handleCommand(type,row){
  695. if(type=='rename'){
  696. this.renameFile(row)
  697. }else if(type == 'remove'){
  698. this.removeFile(row)
  699. }else{
  700. this.downloadFile(row)
  701. }
  702. // console.log(type,row);
  703. },
  704. //静态icon资源
  705. iconGetMap(item) {
  706. //文件夹icon
  707. if(item.ItemIcon.includes('file_type_menu')) return this.staticFileIco
  708. //img icon
  709. if(item.ItemIcon.includes('file_type_pic')) return this.staticImageIco
  710. //其他icon
  711. if(item.ItemIcon.includes('file_type_unknown')) return this.staticConfigIco
  712. //音频icon
  713. if(item.ItemIcon.includes('file_type_audio')) return this.staticAudioIco
  714. //视频icon
  715. if(item.ItemIcon.includes('file_type_video')) return this.staticVideoIco
  716. //word icon
  717. if(item.ItemIcon.includes('file_type_docx')) return this.staticWordIco
  718. //excel icon
  719. if(item.ItemIcon.includes('file_type_xlsx')) return this.staticExcelIco
  720. //ppt icon
  721. if(item.ItemIcon.includes('file_type_ppt')) return this.staticPptIco
  722. //pdf icon
  723. if(item.ItemIcon.includes('file_type_pdf')) return this.staticPdfIco
  724. }
  725. },
  726. created(){
  727. this.currentMenuId=sessionStorage.getItem('cloudDiskMenuId') || 0
  728. this.getFileList()
  729. this.getMenuTree()
  730. }
  731. }
  732. </script>
  733. <style lang="scss" scoped>
  734. #cloud-disk-container{
  735. min-height: calc(100vh - 120px);
  736. box-sizing: border-box;
  737. .top-zone{
  738. display: flex;
  739. align-items: center;
  740. justify-content: space-between;
  741. flex-wrap: wrap;
  742. padding: 20px 30px;
  743. margin-bottom: 20px;
  744. background-color: white;
  745. .button-zone{
  746. .download-button{
  747. min-width: 112px;
  748. background: #ECF5FF;
  749. border: 1px solid #95C8FF;
  750. color: #409EFF;
  751. }
  752. }
  753. }
  754. .table-zone{
  755. background-color: white;
  756. padding: 6px 10px 20px;
  757. min-height: 700px;
  758. box-sizing: border-box;
  759. .bread-crumb-row{
  760. padding:14px 10px 20px 50px;
  761. border-bottom: solid 1px #DCDFE6;
  762. .bread-crumb-item{
  763. cursor: pointer;
  764. font-size: 14px;
  765. &:last-child{
  766. cursor: text;
  767. span{
  768. color: #409EFF;
  769. }
  770. }
  771. }
  772. }
  773. .table-item{
  774. padding-left: 10px;
  775. .file-name{
  776. display: flex;
  777. align-items: center;
  778. flex-wrap: nowrap;
  779. img{
  780. height: 32px;
  781. width: 32px;
  782. margin-right: 10px;
  783. }
  784. span{
  785. white-space: nowrap;
  786. overflow: hidden;
  787. text-overflow: ellipsis;
  788. }
  789. }
  790. .more-operation{
  791. visibility: hidden;
  792. }
  793. }
  794. }
  795. }
  796. // 上传文件弹窗
  797. .choose-folder-box{
  798. min-height: 500px;
  799. padding: 0 80px;
  800. .folder-item{
  801. font-size: 16px;
  802. color: #333333;
  803. margin-bottom: 6px;
  804. }
  805. .folder-tree-item{
  806. border-bottom: 1px solid #DCDFE6;
  807. width: 100%;
  808. display: flex;
  809. align-items: center;
  810. justify-content: space-between;
  811. padding:15px 8px 15px 0;
  812. overflow: hidden;
  813. .folder-tree-name{
  814. overflow: hidden;
  815. display: flex;
  816. align-items: center;
  817. color: #333333;
  818. span{
  819. white-space: nowrap;
  820. overflow: hidden;
  821. text-overflow: ellipsis;
  822. }
  823. img{
  824. height: 32px;
  825. width: 32px;
  826. margin-right: 10px;
  827. }
  828. }
  829. }
  830. }
  831. .choose-dialog-footer{
  832. padding: 40px 0;
  833. text-align: center;
  834. }
  835. </style>
  836. <style lang="scss">
  837. #cloud-disk-container{
  838. .el-table{
  839. .custom-table-header{
  840. th{
  841. background-color: white!important;
  842. font-weight: 400;
  843. padding:7px 0;
  844. }
  845. }
  846. .el-table__body{
  847. .hover-row-actice{
  848. background-color: #F0F4FF;
  849. .active-file-name{
  850. color: #409EFF;
  851. }
  852. .file-parent-menu{
  853. text-decoration: underline;
  854. }
  855. .more-operation{
  856. visibility: visible;
  857. }
  858. }
  859. tr{
  860. cursor: pointer;
  861. }
  862. }
  863. tr{
  864. th,td{
  865. &:first-child{
  866. border: none;
  867. }
  868. }
  869. }
  870. .cell{
  871. color: #333333;
  872. padding-left: 0;
  873. padding-right: 10px;
  874. }
  875. }
  876. .el-table--enable-row-hover{
  877. .el-table__body{
  878. tr:hover{
  879. td{
  880. background-color: #F0F4FF;
  881. }
  882. .active-file-name{
  883. color: #409EFF;
  884. }
  885. .file-parent-menu{
  886. text-decoration: underline;
  887. }
  888. .more-operation{
  889. visibility: visible;
  890. }
  891. }
  892. }
  893. }
  894. // 新建/重命名弹窗
  895. #newOrRename{
  896. .el-dialog__footer{
  897. box-shadow: inset 0px 1px 0px #F0F0F0;
  898. padding-bottom: 10px;
  899. }
  900. }
  901. }
  902. #choose-folder-box{
  903. .el-scrollbar__wrap{
  904. overflow: auto;
  905. }
  906. .el-tree-node__content{
  907. height: unset;
  908. .el-tree-node__expand-icon{
  909. padding: 0;
  910. }
  911. }
  912. }
  913. </style>