index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <template>
  2. <div class="img">
  3. <a-upload
  4. name="file"
  5. list-type="picture-card"
  6. :multiple="isMultiple"
  7. :action="uploadAction"
  8. :headers="headers"
  9. :data="{}"
  10. :file-list="fileList"
  11. :before-upload="beforeUpload"
  12. :disabled="disabled"
  13. :is-multiple="isMultiple"
  14. :class="[!isMultiple?'imgupload':'', (!isMultiple && picUrl)?'image-upload-single-over':'' ]"
  15. @change="handleChange"
  16. @preview="handlePreview"
  17. >
  18. <div>
  19. <!--<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="width:100%;height:100%"/>-->
  20. <div class="iconp">
  21. <a-icon :type="uploadLoading ? 'loading' : 'plus'" />
  22. <div class="ant-upload-text">{{ text }}</div>
  23. </div>
  24. </div>
  25. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
  26. <img alt="example" style="width: 100%" :src="previewImage">
  27. </a-modal>
  28. </a-upload>
  29. </div>
  30. </template>
  31. <script>
  32. import Vue from 'vue'
  33. import { getToken } from '@/utils/auth'
  34. import { getFileAccessHttpUrl } from '@/utils/util'
  35. const uidGenerator = () => {
  36. return '-' + parseInt(Math.random() * 10000 + 1, 10)
  37. }
  38. const getFileName = (path) => {
  39. if (path.lastIndexOf('\\') >= 0) {
  40. const reg = new RegExp('\\\\', 'g')
  41. path = path.replace(reg, '/')
  42. }
  43. return path.substring(path.lastIndexOf('/') + 1)
  44. }
  45. export default {
  46. name: 'JImageUpload',
  47. model: {
  48. prop: 'value',
  49. event: 'change'
  50. },
  51. props: {
  52. text: {
  53. type: String,
  54. required: false,
  55. default: '上传'
  56. },
  57. /* 这个属性用于控制文件上传的业务路径*/
  58. bizPath: {
  59. type: String,
  60. required: false,
  61. default: 'temp'
  62. },
  63. value: {
  64. type: [String, Array],
  65. required: false
  66. },
  67. disabled: {
  68. type: Boolean,
  69. required: false,
  70. default: false
  71. },
  72. isMultiple: {
  73. type: Boolean,
  74. required: false,
  75. default: false
  76. },
  77. // update-begin-author:wangshuai date:20201021 for:LOWCOD-969 新增number属性,用于判断上传数量
  78. number: {
  79. type: Number,
  80. required: false,
  81. default: 0
  82. }
  83. // update-end-author:wangshuai date:20201021 for:LOWCOD-969 新增number属性,用于判断上传数量
  84. },
  85. data() {
  86. return {
  87. uploadAction: process.env.VUE_APP_BASE_API + '/common/upload',
  88. uploadLoading: false,
  89. picUrl: false,
  90. headers: {},
  91. fileList: [],
  92. previewImage: '',
  93. previewVisible: false
  94. }
  95. },
  96. watch: {
  97. value: {
  98. handler(val, oldValue) {
  99. if (val instanceof Array) {
  100. this.initFileList(val.join(','))
  101. } else {
  102. this.initFileList(val)
  103. }
  104. if (!val || val.length == 0) {
  105. this.picUrl = false
  106. }
  107. },
  108. // 立刻执行handler
  109. immediate: true
  110. }
  111. },
  112. created() {
  113. this.headers['Authorization'] = getToken()
  114. },
  115. methods: {
  116. initFileList(paths) {
  117. if (!paths || paths.length == 0) {
  118. this.fileList = []
  119. return
  120. }
  121. this.picUrl = true
  122. const fileList = []
  123. const arr = paths.split(',')
  124. for (var a = 0; a < arr.length; a++) {
  125. const url = getFileAccessHttpUrl(arr[a])
  126. fileList.push({
  127. uid: uidGenerator(),
  128. name: getFileName(arr[a]),
  129. status: 'done',
  130. url: url,
  131. response: {
  132. status: 'history',
  133. message: arr[a]
  134. }
  135. })
  136. }
  137. this.fileList = fileList
  138. },
  139. beforeUpload: function(file) {
  140. var fileType = file.type
  141. if (fileType.indexOf('image') < 0) {
  142. this.$message.warning('请上传图片')
  143. return false
  144. }
  145. },
  146. handleChange(info) {
  147. this.picUrl = false
  148. let fileList = info.fileList
  149. // update-begin-author:wangshuai date:20201022 for:LOWCOD-969 判断number是否大于0和是否多选,返回选定的元素。
  150. if (this.number > 0 && this.isMultiple) {
  151. fileList = fileList.slice(-this.number)
  152. }
  153. // update-end-author:wangshuai date:20201022 for:LOWCOD-969 判断number是否大于0和是否多选,返回选定的元素。
  154. if (info.file.status === 'done') {
  155. if (info.file.response.code === 200) {
  156. this.picUrl = true
  157. fileList = fileList.map((file) => {
  158. if (file.response) {
  159. file.url = file.response.url
  160. }
  161. return file
  162. })
  163. }
  164. // this.$message.success(`${info.file.name} 上传成功!`);
  165. } else if (info.file.status === 'error') {
  166. this.$message.error(`${info.file.name} 上传失败.`)
  167. } else if (info.file.status === 'removed') {
  168. this.handleDelete(info.file)
  169. }
  170. this.fileList = fileList
  171. if (info.file.status === 'done' || info.file.status === 'removed') {
  172. this.handlePathChange()
  173. }
  174. },
  175. // 预览
  176. handlePreview(file) {
  177. this.previewImage = file.url || file.thumbUrl
  178. this.previewVisible = true
  179. },
  180. getAvatarView() {
  181. if (this.fileList.length > 0) {
  182. const url = this.fileList[0].url
  183. return getFileAccessHttpUrl(url)
  184. }
  185. },
  186. handlePathChange() {
  187. const uploadFiles = this.fileList
  188. let path = ''
  189. if (!uploadFiles || uploadFiles.length == 0) {
  190. path = ''
  191. }
  192. const arr = []
  193. if (!this.isMultiple && uploadFiles.length > 0) {
  194. arr.push(uploadFiles[uploadFiles.length - 1].response.url)
  195. } else {
  196. for (let a = 0; a < uploadFiles.length; a++) {
  197. // update-begin-author:taoyan date:20200819 for:【开源问题z】上传图片组件 LOWCOD-783
  198. if (uploadFiles[a].status === 'done') {
  199. arr.push(uploadFiles[a].response.url)
  200. } else {
  201. return
  202. }
  203. // update-end-author:taoyan date:20200819 for:【开源问题z】上传图片组件 LOWCOD-783
  204. }
  205. }
  206. if (arr.length > 0) {
  207. path = arr.join(',')
  208. }
  209. this.$emit('change', path)
  210. },
  211. handleDelete(file) {
  212. // 如有需要新增 删除逻辑
  213. console.log(file)
  214. },
  215. handleCancel() {
  216. this.close()
  217. this.previewVisible = false
  218. },
  219. close() {
  220. }
  221. }
  222. }
  223. </script>
  224. <style scoped>
  225. /* update--begin--autor:lvdandan-----date:20201016------for:j-image-upload图片组件单张图片详情回显空白
  226. * https://github.com/zhangdaiscott/jeecg-boot/issues/1810
  227. * https://github.com/zhangdaiscott/jeecg-boot/issues/1779
  228. */
  229. /deep/ .imgupload .iconp{padding:20px;}
  230. /* update--end--autor:lvdandan-----date:20201016------for:j-image-upload图片组件单张图片详情回显空白*/
  231. /deep/ .image-upload-single-over .ant-upload-select{display: none}
  232. </style>