6cd8f68534985574288436db3191faabe2b411bb.svn-base 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <div>
  3. <template v-if="hasFile" v-for="(file, fileKey) of [innerFile || {}]">
  4. <a-input
  5. :key="fileKey"
  6. :readOnly="true"
  7. :value="file.name"
  8. >
  9. <template slot="addonBefore" style="width: 30px">
  10. <a-tooltip v-if="file.status === 'uploading'" :title="`上传中(${Math.floor(file.percent)}%)`">
  11. <a-icon type="loading"/>
  12. </a-tooltip>
  13. <a-tooltip v-else-if="file.status === 'done'" title="上传完成">
  14. <a-icon type="check-circle" style="color:#00DB00;"/>
  15. </a-tooltip>
  16. <a-tooltip v-else :title="file.message||'上传失败'">
  17. <a-icon type="exclamation-circle" style="color:red;"/>
  18. </a-tooltip>
  19. </template>
  20. <span v-if="file.status === 'uploading'" slot="addonAfter">{{ Math.floor(file.percent) }}%</span>
  21. <template v-else-if="originColumn.allowDownload !== false || originColumn.allowRemove !== false" slot="addonAfter">
  22. <a-dropdown :trigger="['click']" placement="bottomRight">
  23. <a-tooltip title="操作">
  24. <a-icon
  25. type="setting"
  26. style="cursor: pointer;"/>
  27. </a-tooltip>
  28. <a-menu slot="overlay">
  29. <!-- <a-menu-item @click="handleClickPreviewFile">-->
  30. <!-- <span><a-icon type="eye"/>&nbsp;预览</span>-->
  31. <!-- </a-menu-item>-->
  32. <a-menu-item v-if="originColumn.allowDownload !== false" @click="handleClickDownloadFile">
  33. <span><a-icon type="download"/>&nbsp;下载</span>
  34. </a-menu-item>
  35. <a-menu-item v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile">
  36. <span><a-icon type="delete"/>&nbsp;删除</span>
  37. </a-menu-item>
  38. </a-menu>
  39. </a-dropdown>
  40. </template>
  41. </a-input>
  42. </template>
  43. <a-upload
  44. v-show="!hasFile"
  45. name="file"
  46. :data="{'isup': 1}"
  47. :multiple="false"
  48. :action="originColumn.action"
  49. :headers="uploadHeaders"
  50. :showUploadList="false"
  51. v-bind="cellProps"
  52. @change="handleChangeUpload"
  53. >
  54. <a-button icon="upload">{{originColumn.btnText || '点击上传'}}</a-button>
  55. </a-upload>
  56. </div>
  57. </template>
  58. <script>
  59. import JVxeCellMixins from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
  60. import { ACCESS_TOKEN } from '@/store/mutation-types'
  61. import { getFileAccessHttpUrl } from '@api/manage'
  62. export default {
  63. name: 'JVxeUploadCell',
  64. mixins: [JVxeCellMixins],
  65. props: {},
  66. data() {
  67. return {
  68. innerFile: null,
  69. }
  70. },
  71. computed: {
  72. /** upload headers */
  73. uploadHeaders() {
  74. let {originColumn: col} = this
  75. let headers = {}
  76. if (col.token === true) {
  77. headers['X-Access-Token'] = this.$ls.get(ACCESS_TOKEN)
  78. }
  79. return headers
  80. },
  81. hasFile() {
  82. return this.innerFile != null
  83. },
  84. },
  85. watch: {
  86. innerValue: {
  87. immediate: true,
  88. handler() {
  89. if (this.innerValue) {
  90. this.innerFile = this.innerValue
  91. } else {
  92. this.innerFile = null
  93. }
  94. },
  95. },
  96. },
  97. methods: {
  98. handleChangeUpload(info) {
  99. let {row, originColumn: col} = this
  100. let {file} = info
  101. let value = {
  102. name: file.name,
  103. type: file.type,
  104. size: file.size,
  105. status: file.status,
  106. percent: file.percent
  107. }
  108. if (col.responseName && file.response) {
  109. value['responseName'] = file.response[col.responseName]
  110. }
  111. if (file.status === 'done') {
  112. if (typeof file.response.success === 'boolean') {
  113. if (file.response.success) {
  114. value['path'] = file.response[col.responseName]
  115. } else {
  116. value['status'] = 'error'
  117. value['message'] = file.response.message || '未知错误'
  118. }
  119. } else {
  120. // 考虑到如果设置action上传路径为非jeecg-boot后台,可能不会返回 success 属性的情况,就默认为成功
  121. value['path'] = file.response[col.responseName]
  122. }
  123. } else if (file.status === 'error') {
  124. value['message'] = file.response.message || '未知错误'
  125. }
  126. this.innerFile = value
  127. },
  128. // handleClickPreviewFile(id) {
  129. // this.$message.info('尚未实现')
  130. // },
  131. handleClickDownloadFile(id) {
  132. let {path} = this.value || {}
  133. if (path) {
  134. let url = getFileAccessHttpUrl(path)
  135. window.open(url)
  136. }
  137. },
  138. handleClickDeleteFile() {
  139. this.handleChangeCommon(null)
  140. },
  141. },
  142. // 【组件增强】注释详见:JVxeCellMixins.js
  143. enhanced: {
  144. switches: {visible: true},
  145. getValue: value => fileGetValue(value),
  146. setValue: value => fileSetValue(value),
  147. }
  148. }
  149. function fileGetValue(value) {
  150. if (value && value.path) {
  151. return value.path
  152. }
  153. return value
  154. }
  155. function fileSetValue(value) {
  156. if (value) {
  157. let first = value.split(',')[0]
  158. let name = first.substring(first.lastIndexOf('/') + 1)
  159. return {
  160. name: name,
  161. path: value,
  162. status: 'done',
  163. }
  164. }
  165. return value
  166. }
  167. </script>
  168. <style scoped>
  169. </style>