upload-image.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <template>
  2. <view class="upload_box">
  3. <!-- #ifdef APP -->
  4. <template v-if="authList['WRITE_EXTERNAL_STORAGE']&&authList['CAMERA']">
  5. <u-upload
  6. :deletable="!isDetail"
  7. :fileList="fileList1"
  8. @afterRead="afterRead"
  9. @delete="deletePic"
  10. :name="name"
  11. :multiple="multiple"
  12. :maxCount="limit"
  13. :width="width"
  14. :height="height"
  15. :previewFullImage="true"
  16. >
  17. <view class="upload_btn">
  18. <u-image :radius="radius" :width="width" :height="height" :showError="false" :showLoading="false" :src="`${$IMG_URL}/static/contract/icon_increase1-2.png`"></u-image>
  19. </view>
  20. </u-upload>
  21. </template>
  22. <view v-else-if="!authList['WRITE_EXTERNAL_STORAGE']" class="upload_btn_auth" @tap.stop="openAuth('WRITE_EXTERNAL_STORAGE')">
  23. <view class="upload_btn">
  24. <u-image :radius="radius" :width="width" :height="height" :showError="false" :showLoading="false" :src="`${$IMG_URL}/static/common/upload-img.png`"></u-image>
  25. </view>
  26. </view>
  27. <view v-else class="upload_btn_auth" @tap.stop="openAuth('CAMERA')">
  28. <view class="upload_btn">
  29. <u-image :radius="radius" :width="width" :height="height" :showError="false" :showLoading="false" :src="`${$IMG_URL}/static/common/upload-img.png`"></u-image>
  30. </view>
  31. </view>
  32. <yk-authpup ref="authpup" type="top" @changeAuth="changeAuth" :permissionID="permissionID"></yk-authpup>
  33. <!-- #endif -->
  34. <!-- #ifndef APP -->
  35. <u-upload
  36. :deletable="!isDetail"
  37. :fileList="fileList1"
  38. @afterRead="afterRead"
  39. @delete="deletePic"
  40. :name="name"
  41. :multiple="multiple"
  42. :maxCount="limit"
  43. :width="width"
  44. :height="height"
  45. :radius="radius"
  46. :previewFullImage="true"
  47. >
  48. <view class="upload_btn">
  49. <u-image :radius="radius" :width="width" :height="height" :showError="false" :showLoading="false" :src="`${$IMG_URL}/static/common/upload-img.png`"></u-image>
  50. </view>
  51. </u-upload>
  52. <!-- #endif -->
  53. </view>
  54. </template>
  55. <script>
  56. import { mapGetters } from 'vuex'
  57. import ykAuthpup from '@/components/yk-authpup/yk-authpup'
  58. export default {
  59. name: 'UploadImage',
  60. components: {
  61. ykAuthpup
  62. },
  63. props: {
  64. // 值
  65. value: [String, Object, Array],
  66. // 宽度
  67. width: {
  68. type: String,
  69. default: '180rpx'
  70. },
  71. // 高度
  72. height: {
  73. type: String,
  74. default: '180rpx'
  75. },
  76. // 圆角
  77. radius: {
  78. type: String,
  79. default: '12rpx'
  80. },
  81. // 数量限制
  82. limit: {
  83. type: Number,
  84. default: 9
  85. },
  86. // 大小限制(MB)
  87. fileSize: {
  88. type: Number,
  89. default: 20
  90. },
  91. // 文件类型, 例如['png', 'jpg', 'jpeg']
  92. fileType: {
  93. type: Array,
  94. default: () => []
  95. },
  96. // 标识name
  97. name: {
  98. type: String,
  99. default: '1'
  100. },
  101. // 是否多选
  102. multiple: {
  103. type: Boolean,
  104. default: true
  105. },
  106. // 是否显示提示
  107. isShowTip: {
  108. type: Boolean,
  109. default: false
  110. },
  111. // 是否详情
  112. isDetail: {
  113. type: Boolean,
  114. default: false
  115. },
  116. // 是否在上传的时候回显图片
  117. showImg: {
  118. type: Boolean,
  119. default: true
  120. }
  121. },
  122. data() {
  123. return {
  124. // 权限判断
  125. permissionID: '',
  126. fileList1: [] //图片上传的文件
  127. }
  128. },
  129. watch: {
  130. value: {
  131. async handler(val) {
  132. if (val) {
  133. if (this[`fileList${this.name}`].length > 0) return
  134. // 首先将值转为数组
  135. const list = Array.isArray(val) ? val : this.value.split(',')
  136. const files = []
  137. // 然后将数组转为对象数组
  138. for (let i = 0; i < list.length; i++) {
  139. let item = list[i]
  140. if (typeof item === 'string') {
  141. let name = item + ''
  142. item = {
  143. url: this.getUrl(item),
  144. fullurl: item,
  145. status: 'success'
  146. }
  147. }
  148. files.push(item)
  149. }
  150. this[`fileList${this.name}`] = files
  151. } else {
  152. this[`fileList${this.name}`] = []
  153. return []
  154. }
  155. },
  156. deep: true,
  157. immediate: true
  158. }
  159. },
  160. computed: {
  161. // 是否显示提示
  162. showTip() {
  163. return this.isShowTip && (this.fileType || this.fileSize)
  164. },
  165. ...mapGetters('auth', ['authList', 'onceIn']),
  166. },
  167. mounted() {
  168. // #ifdef APP
  169. // if (this.onceIn) {
  170. // this.$store.commit('auth/edit', {data: false, index: 'onceIn'})
  171. // this.openAuth('WRITE_EXTERNAL_STORAGE')
  172. // }
  173. // #endif
  174. },
  175. methods: {
  176. //打开自定义权限目的弹框
  177. openAuth(permissionID) {
  178. this.permissionID = permissionID //这个是对应的权限 ACCESS_FINE_LOCATION 位置权限 / WRITE_EXTERNAL_STORAGE 存储空间/照片权限 / CAMERA相机权限 / CALL_PHONE 拨打电话
  179. setTimeout(() => {
  180. this.$refs['authpup'].open()
  181. }, 500)
  182. },
  183. //用户授权权限后的回调
  184. changeAuth() {
  185. //这里是权限通过后执行自己的代码逻辑
  186. console.log('权限已授权,可执行自己的代码逻辑了')
  187. this.authList[this.permissionID] = true
  188. const list = {...this.authList}
  189. this.$store.commit('auth/edit', {data: list, index: 'authList'})
  190. if (!this.authList['CAMERA']) {
  191. this.openAuth('CAMERA')
  192. }
  193. },
  194. // 删除图片
  195. deletePic(event) {
  196. this[`fileList${event.name}`].splice(event.index, 1)
  197. const files = this[`fileList${event.name}`].length ? this[`fileList${event.name}`].map((item) => item.fullurl).join(',') : ''
  198. this.$emit('input', files)
  199. },
  200. // 新增图片
  201. async afterRead(event) {
  202. // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
  203. let lists = [].concat(event.file)
  204. let fileListLen = this[`fileList${event.name}`].length
  205. lists.map((item) => {
  206. this[`fileList${event.name}`].push({
  207. ...item,
  208. status: 'uploading',
  209. message: '上传中'
  210. })
  211. })
  212. let successNum = 0
  213. let failNum = 0
  214. for (let i = 0; i < lists.length; i++) {
  215. const result = await this.uploadFilePromise(lists[i].url)
  216. let item = this[`fileList${event.name}`][fileListLen]
  217. if (result.code === 1) {
  218. successNum++
  219. } else {
  220. failNum++
  221. }
  222. this[`fileList${event.name}`].splice(
  223. fileListLen,
  224. 1,
  225. Object.assign(item, {
  226. status: result.code === 1 ? 'success' : 'fail',
  227. message: result.code === 1 ? '' : '上传失败',
  228. url: result.code === 1 ? result.data.fullurl : '',
  229. fullurl: result.code === 1 ? result.data.url : ''
  230. })
  231. )
  232. fileListLen++
  233. }
  234. if(!this.showImg) {
  235. const files = this[`fileList${event.name}`].length ? this[`fileList${event.name}`][0] : ''
  236. this[`fileList${event.name}`] = []
  237. this.$emit('change',files)
  238. return
  239. }
  240. if (lists.length > 1) {
  241. uni.showModal({
  242. content: `本次上传成功${successNum}个,失败${failNum}个`,
  243. showCancel: false
  244. })
  245. }
  246. this[`fileList${event.name}`] = this[`fileList${event.name}`].filter((item) => item.status === 'success')
  247. const files = this[`fileList${event.name}`].length ? this[`fileList${event.name}`].map((item) => item.fullurl).join(',') : ''
  248. this.$emit('input', files)
  249. },
  250. uploadFilePromise(url) {
  251. return new Promise((resolve, reject) => {
  252. let a = uni.uploadFile({
  253. url: this.$UPLOAD_URL, //
  254. filePath: url,
  255. name: 'file',
  256. header: {
  257. token: `${this.$store.getters.token}`
  258. },
  259. success: (res) => {
  260. let data = JSON.parse(res.data)
  261. resolve(data)
  262. }
  263. })
  264. })
  265. },
  266. // 设置域名
  267. getUrl(url) {
  268. if (url.indexOf('http') === -1) url = this.$UPLOAD_BASE + url
  269. return url
  270. }
  271. }
  272. }
  273. </script>
  274. <style lang="scss" scoped>
  275. .upload_box {
  276. position: relative;
  277. .upload_btn_auth {
  278. // width: 180rpx;
  279. // height: 180rpx;
  280. }
  281. .upload_btn {
  282. // width: 180rpx;
  283. // height: 180rpx;
  284. position: relative;
  285. }
  286. }
  287. </style>