index.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <!--
  2. * @Author: ChenYaJin
  3. * @Date: 2021-06-07 17:46:34
  4. * @LastEditors: LiZhiWei
  5. * @LastEditTime: 2025-04-16 10:20:31
  6. * @Description: 文件柜-文件详情
  7. -->
  8. <template>
  9. <div>
  10. <div class="detail-box">
  11. <header class="header-box">
  12. <span class="title">文件信息</span>
  13. </header>
  14. <div class="content-box" v-loading="loading || loadingFile">
  15. <div class="info-item">
  16. <i class="el-icon-document"></i>
  17. <div class="info-content">
  18. <div class="label">文件名</div>
  19. <div class="value">{{fileDetail.name || '-'}}</div>
  20. </div>
  21. </div>
  22. <div class="info-item">
  23. <i class="el-icon-tickets"></i>
  24. <div class="info-content">
  25. <div class="label">文件类型</div>
  26. <div class="value">{{fileDetail.type || '-'}}</div>
  27. </div>
  28. </div>
  29. <div class="info-item">
  30. <i class="el-icon-files"></i>
  31. <div class="info-content">
  32. <div class="label">文件大小</div>
  33. <div class="value">{{getFileSize || '-'}}</div>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="operation-footer">
  38. <el-button
  39. type="success"
  40. @click="onDownload"
  41. :loading="downloadLoading"
  42. v-hasAuth="'FileDownload'"
  43. icon="el-icon-download">
  44. 下载
  45. </el-button>
  46. </div>
  47. </div>
  48. </div>
  49. </template>
  50. <style lang="less" scoped>
  51. </style>
  52. <script>
  53. import { mapActions, mapState } from 'vuex'
  54. import { debounce } from 'lodash-es'
  55. import { downloadWithProgress } from '../../ libs/util'
  56. import commJs from '../../comm_js/index'
  57. import { downloadFile } from '../../ libs/file'
  58. // import EditFileModal from '../../components/file_list/modal/edit_file'
  59. // import PasswordConfirmModal from '../password_confirm'
  60. export default {
  61. name: 'FileDetailModal',
  62. components: {
  63. // PasswordConfirmModal,
  64. // EditFileModal
  65. },
  66. props: {
  67. id: {
  68. type: String,
  69. default: null
  70. },
  71. showClose: {
  72. type: Boolean,
  73. default: false
  74. },
  75. file: {
  76. type: Object,
  77. default: () => {
  78. return {}
  79. }
  80. },
  81. loadingFile: {
  82. type: Boolean,
  83. default: true
  84. }
  85. },
  86. data () {
  87. return {
  88. fileDetail: {},
  89. fileInfo: {
  90. isShow: false,
  91. row: this.file
  92. },
  93. passwordConfirmInfo: {
  94. isShow: false,
  95. id: '',
  96. okType: 'danger',
  97. tips: '',
  98. row: {}
  99. },
  100. loading: false,
  101. downloadLoading: false,
  102. deleteLoading: false
  103. }
  104. },
  105. computed: {
  106. ...mapState({
  107. directoryTree: state => state.fileManage.directoryTree
  108. }),
  109. getSecretLevel () {
  110. return this.file.secretLevel === 'secret' ? '机密' : '普通'
  111. },
  112. getFileSize () {
  113. return commJs.fileSizeFormat(this.file.size, 'KB')
  114. }
  115. },
  116. watch: {
  117. 'file': {
  118. handler (value) {
  119. if (value) {
  120. this.fileDetail = JSON.parse(JSON.stringify(value))
  121. }
  122. },
  123. immediate: true,
  124. deep: true
  125. }
  126. },
  127. methods: {
  128. ...mapActions('fileManage', ['getFileDetail', 'deleteFile']),
  129. updateSuccess () {
  130. this.$emit('updateSuccess')
  131. this.getFileDetailFun()
  132. },
  133. getFileDetailFun () {
  134. if (!this.id) {
  135. return
  136. }
  137. this.loading = true
  138. this.getFileDetail(this.id)
  139. .then(res => {
  140. this.fileDetail = res
  141. const stringArr = commJs.getParentList(this.directoryTree, res.cabinetDirectoryId)
  142. this.fileDetail.directoryName = stringArr.join('/')
  143. })
  144. .finally(_ => {
  145. this.loading = false
  146. })
  147. },
  148. handleClose () {
  149. this.$emit('close')
  150. },
  151. toEdit () {
  152. this.fileInfo.isShow = true
  153. this.fileInfo.row = JSON.parse(JSON.stringify(this.fileDetail))
  154. },
  155. onClose () {
  156. this.fileInfo.isShow = false
  157. this.passwordConfirmInfo.isShow = false
  158. },
  159. onDownload () {
  160. if (this.fileDetail.secretLevel === 'secret') {
  161. this.passwordConfirmInfo = {
  162. isShow: true,
  163. type: 'download',
  164. okType: 'warning',
  165. tips: '为防止他人恶意下载导致文件泄露,请输入登录密码确认后再批量下载。下载后,请勿随意传播,如因个人传播泄密导致公司利益受损,将追求个人的法律责任。',
  166. row: this.fileDetail
  167. }
  168. } else {
  169. this.downloadFileFun2(this.fileDetail.url)
  170. }
  171. },
  172. downloadFileFun: debounce(function (fileId) {
  173. this.downloadLoading = true
  174. const { name, type, size } = this.fileDetail
  175. const url = `serve/cabinetFile/download/${fileId}`
  176. const fileInfo = { name: name + '.' + type, size: size }
  177. downloadWithProgress(url, this, 'downloadLoading', fileInfo)
  178. }, 500),
  179. downloadFileFun2 :debounce(function (url) {
  180. this.downloadLoading = true
  181. const { name, type, size } = this.fileDetail
  182. const fileInfo = { name: name + '.' + type, size: size }
  183. downloadWithProgress(url, this, 'downloadLoading', fileInfo)
  184. }, 500),
  185. onDeleteFile () {
  186. if (this.fileDetail.secretLevel === 'secret') {
  187. this.passwordConfirmInfo = {
  188. isShow: true,
  189. type: 'delete',
  190. okType: 'danger',
  191. tips: '删除后不可查看或下载,为防止他人恶意操作,请输入账登录密码确认删除。',
  192. row: this.fileDetail
  193. }
  194. } else {
  195. this.$confirm(
  196. '删除后不可查看或下载,请谨慎操作!',
  197. '确认删除文件?',
  198. {
  199. confirmButtonText: '确定',
  200. cancelButtonText: '取消',
  201. type: 'error'
  202. })
  203. .then(_ => {
  204. this.deleteFileFun()
  205. })
  206. }
  207. },
  208. deleteFileFun (id) {
  209. this.deleteLoading = true
  210. this.deleteFile(this.fileDetail.id)
  211. .then(res => {
  212. this.$message.success('删除文件成功')
  213. this.passwordConfirmInfo.isShow = false
  214. this.back()
  215. })
  216. .finally(_ => {
  217. this.deleteLoading = false
  218. })
  219. },
  220. back () {
  221. this.$emit('back', true) // 返回需要刷新数据
  222. }
  223. }
  224. }
  225. </script>
  226. <style lang="less">
  227. @import './index.less';
  228. .detail-box {
  229. background: #fff;
  230. border-radius: 8px;
  231. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  232. .header-box {
  233. padding: 20px;
  234. border-bottom: 1px solid #ebeef5;
  235. .title {
  236. font-size: 16px;
  237. font-weight: 500;
  238. color: #303133;
  239. position: relative;
  240. padding-left: 12px;
  241. // &::before {
  242. // content: '';
  243. // position: absolute;
  244. // left: 0;
  245. // top: 50%;
  246. // transform: translateY(-50%);
  247. // width: 4px;
  248. // height: 16px;
  249. // background: #409eff;
  250. // border-radius: 2px;
  251. // }
  252. }
  253. }
  254. .content-box {
  255. padding: 20px;
  256. min-height: 200px;
  257. .info-item {
  258. display: flex;
  259. align-items: flex-start;
  260. margin-bottom: 24px;
  261. &:last-child {
  262. margin-bottom: 0;
  263. }
  264. i {
  265. font-size: 20px;
  266. color: #409eff;
  267. margin-right: 12px;
  268. margin-top: 2px;
  269. }
  270. .info-content {
  271. flex: 1;
  272. .label {
  273. font-size: 14px;
  274. color: #909399;
  275. margin-bottom: 8px;
  276. }
  277. .value {
  278. font-size: 14px;
  279. color: #303133;
  280. word-break: break-all;
  281. line-height: 1.4;
  282. }
  283. }
  284. }
  285. }
  286. .operation-footer {
  287. border-top: 1px solid #ebeef5;
  288. .el-button {
  289. padding: 9px 20px;
  290. [class^="el-icon-"] {
  291. margin-right: 4px;
  292. }
  293. }
  294. }
  295. }
  296. .el-loading-mask {
  297. background-color: rgba(255, 255, 255, 0.9);
  298. border-radius: 8px;
  299. }
  300. </style>