file-row.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <div class="file-row" >
  3. <span class="file-row__file-name">{{file.name}}</span>
  4. <!-- 进度条仅在当前页面上传的文件中显示-->
  5. <template v-if="file.status !== 'success' && file.percentage <= 100">
  6. <el-progress style="flex-grow: 2" :percentage="file.percentage" :status="file.status"></el-progress>
  7. <div>
  8. ({{parseFileSize(file.loaded)}}/{{parseFileSize(file.total)}})
  9. <cip-table-button v-if="!file.status" type="danger" @click="cancelUpload(file)">取消</cip-table-button>
  10. </div>
  11. </template>
  12. <template v-else>
  13. <div class="handle-button-wrapper">
  14. <cip-table-button size="medium" :type="isPreview?'visited':undefined" :loading="previewLoading" v-if="previewAble" @click="previewFile">
  15. 预览
  16. </cip-table-button>
  17. <cip-table-button size="medium" :type="isDownload?'visited':undefined" :loading="downloadLoading" v-if="downloadAble" @click="downloadFile">
  18. 下载
  19. </cip-table-button>
  20. <template v-if="removable">
  21. <cip-table-button size="medium" @click="remove" :loading="removeLoading">
  22. 删除
  23. </cip-table-button>
  24. </template>
  25. </div>
  26. </template>
  27. </div>
  28. </template>
  29. <script>
  30. import { computed, ref } from 'vue'
  31. import { ElMessageBox, ElProgress } from 'element-plus'
  32. import { Dialog as VanDialog } from 'vant'
  33. import CipTableButton from '@cip/components/cip-table-button'
  34. import { download } from './upload'
  35. import { getEquipmentType, isEmpty } from '@cip/utils/util'
  36. export default {
  37. components: { CipTableButton, ElProgress },
  38. props: {
  39. file: {
  40. type: Object,
  41. default: () => { return {} }
  42. },
  43. config: Object,
  44. dependOnValues: Object,
  45. removable: Boolean
  46. },
  47. setup (props, { emit }) {
  48. const isMobile = getEquipmentType() === 'mobile'
  49. const previewLoading = ref(false)
  50. const downloadLoading = ref(false)
  51. const removeLoading = ref(false)
  52. const fileValue = computed(() => {
  53. return props.file
  54. })
  55. // 根据文件大小 显示 B kb mb
  56. const parseFileSize = (size) => {
  57. let unit = 'k'
  58. if (size > 1024) {
  59. size = size / 1024
  60. unit = 'kb'
  61. }
  62. if (size > 1024) {
  63. size = size / 1024
  64. unit = 'mb'
  65. }
  66. return `${Math.floor(size)}${unit}`
  67. }
  68. const cancelUpload = (file) => {
  69. file.abort()
  70. }
  71. const previewAble = computed(() => {
  72. if (typeof props.config.previewAble === 'boolean') return props.config.previewAble
  73. return props.config.previewAble?.(props.dependOnValues)
  74. })
  75. const isPreview = computed(() => {
  76. return !!props.file.read
  77. })
  78. const isDownload = computed(() => {
  79. return !!props.file.download
  80. })
  81. const previewFile = async () => {
  82. previewLoading.value = true
  83. try {
  84. await props.config.previewFile?.(fileValue.value)
  85. } finally {
  86. previewLoading.value = false
  87. }
  88. }
  89. const downloadAble = computed(() => {
  90. if (isEmpty(props.config.downloadAble)) return true
  91. if (typeof props.config.downloadAble === 'boolean') return props.config.downloadAble
  92. return props.config.downloadAble(props.dependOnValues)
  93. })
  94. const downloadFile = async () => {
  95. try {
  96. downloadLoading.value = true
  97. if (isEmpty(props.config.downloadFile)) {
  98. await download(fileValue.value)
  99. } else {
  100. await props.config.downloadFile(fileValue.value)
  101. }
  102. } finally {
  103. downloadLoading.value = false
  104. }
  105. }
  106. const remove = async () => {
  107. removeLoading.value = true
  108. try {
  109. isMobile
  110. ? await VanDialog.confirm({
  111. title: '警告',
  112. message: `确认删除《${fileValue.value.name}》`
  113. })
  114. : await ElMessageBox.confirm(`确认删除《${fileValue.value.name}》`, '警告', { type: 'warning' })
  115. if (props.config.deleteFile) {
  116. await props.config.deleteFile?.(fileValue.value)
  117. }
  118. emit('after-remove', fileValue.value)
  119. } catch (e) {
  120. } finally {
  121. removeLoading.value = false
  122. }
  123. }
  124. return {
  125. parseFileSize,
  126. cancelUpload,
  127. previewAble,
  128. previewLoading,
  129. previewFile,
  130. downloadAble,
  131. downloadLoading,
  132. downloadFile,
  133. remove,
  134. removeLoading,
  135. isPreview,
  136. isDownload
  137. }
  138. }
  139. }
  140. </script>
  141. <style lang="less">
  142. .file-row{
  143. width: 100%;
  144. font-size: 14px;
  145. //line-height: 1.1em;
  146. line-height: @formItemLineHeight;
  147. padding: 4px 6px;
  148. /*display: flex;*/
  149. /*justify-content: space-between;*/
  150. /*align-items: center;*/
  151. flex-wrap: nowrap;
  152. position: relative;
  153. overflow: hidden;
  154. &:hover{
  155. background: #e6f7ff;
  156. .handle-button-wrapper{
  157. visibility: visible;
  158. top:0;
  159. left: 0;
  160. bottom: 0;
  161. }
  162. }
  163. &__file-name{
  164. display: inline-block;
  165. margin-left: 8px;
  166. text-overflow: ellipsis;
  167. white-space: nowrap;
  168. }
  169. &__process{
  170. display: flex;
  171. align-items: center;
  172. justify-content: space-between;
  173. }
  174. .handle-button-wrapper{
  175. display: flex;
  176. align-items: center;
  177. position: absolute;
  178. left: -100%;
  179. background: rgba(255,255,255,0.8);
  180. visibility: hidden;
  181. opacity: 0.9;
  182. transition: all 0.3s;
  183. padding: 0 8px;
  184. .el-button{
  185. padding: 0 4px;
  186. + .el-button{
  187. margin-left: 4px;
  188. }
  189. }
  190. }
  191. &__button{
  192. cursor: pointer;
  193. flex-shrink: 0;
  194. &+.file-row__button{
  195. margin-left:4px;
  196. }
  197. }
  198. }
  199. </style>