ui-upload-image-lv2.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <template>
  2. <view class="upload-image">
  3. <view class="pull-left" :class="itemClass" v-for="(item, index) in value" :key="item.url">
  4. <view class="imgwarp">
  5. <view style="margin-bottom: 100%;" class="text-center">
  6. <!-- <u-loading-page v-if="item.loading" font-size="28" :loading="true"></u-loading-page> -->
  7. <view style="margin-top: 20px;" v-if="item.loading" class="">
  8. <u-loading-icon ></u-loading-icon>
  9. </view>
  10. <view class="img-square-warp" v-else @click="clickImg(index)" style="position: absolute;top: 0;right: 0;left: 0;bottom: 0;">
  11. <image :src="item.type=='image' ? item.url+'?x-oss-process=image/resize,m_fill,h_200,w_200,limit_0' : item.video_img" mode="widthFix" class="img-max img-square"/>
  12. </view>
  13. </view>
  14. <span v-if="showRemove" class="img-remove" @click="remove(index)"></span>
  15. </view>
  16. </view>
  17. <view class="pull-left" :class="itemClass">
  18. <view class="imgwarp ui-flex ui-flex-align-center ui-flex-center" v-if="max > value.length" @click="choose()">
  19. <u-icon name="camera-fill" size="48" ></u-icon>
  20. </view>
  21. </view>
  22. <u-popup :show="showPopup" mode="bottom" @close="showPopup = false">
  23. <view class="ui-flex-row u-border-bottom">
  24. <view class="ui-flex-1 ui-p f12 text-center u-border-right">照片</view>
  25. <!-- <view class="ui-flex-1 ui-p f12 text-center" v-if="chooseVideo">视频</view> -->
  26. </view>
  27. <view class="ui-flex-row">
  28. <view class="ui-flex-1 ui-p" @click="choose('image', 'camera')">
  29. <u-icon label="拍摄照片" size="28px" space="7px" labelSize="12px" labelPos="bottom" name="camera"></u-icon>
  30. </view>
  31. <view class="ui-flex-1 ui-p u-border-right" @click="choose('image', 'album')">
  32. <u-icon label="选择照片" size="28px" space="7px" labelSize="12px" labelPos="bottom" name="photo"></u-icon>
  33. </view>
  34. <!-- <view class="ui-flex-1 ui-p" @click="choose('video', 'camera')" v-if="chooseVideo">
  35. <u-icon label="拍摄视频" size="28px" space="7px" labelSize="12px" labelPos="bottom" name="play-circle"></u-icon>
  36. </view>
  37. <view class="ui-flex-1 ui-p" @click="choose('video', 'album')" v-if="chooseVideo">
  38. <u-icon label="选择视频" size="28px" space="7px" labelSize="12px" labelPos="bottom" name="plus-circle"></u-icon>
  39. </view> -->
  40. </view>
  41. </u-popup>
  42. </view>
  43. </template>
  44. <script>
  45. // import Request from '@/common/base-request.js'
  46. // import uLoadingIcon from '@/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue'
  47. export default {
  48. comments : {
  49. },
  50. props : {
  51. max : {
  52. default : 1
  53. },
  54. dir : {
  55. required: false
  56. },
  57. itemClass : {
  58. type : String,
  59. default : '',
  60. },
  61. value : {
  62. type : Array,
  63. default : function(){
  64. return []
  65. },
  66. },
  67. showRemove : {
  68. default : true,
  69. },
  70. crop : {
  71. type : [Object, undefined],
  72. default: undefined
  73. },
  74. type : {
  75. type : String,
  76. default : 'image'
  77. }
  78. },
  79. computed : {
  80. chooseVideo (){
  81. if(this.type != 'all'){
  82. return false;
  83. }
  84. return true;
  85. }
  86. },
  87. data() {
  88. return {
  89. showPopup : false,
  90. video: {
  91. // isVideo : true,
  92. // loading : true,
  93. // videoUrl : 'xxx',
  94. // videoCover : 'xxx'
  95. }
  96. }
  97. },
  98. methods : {
  99. remove : function(index){
  100. this.value.splice(index, 1);
  101. this.$emit("input",this.value)
  102. },
  103. clickImg(index){
  104. if(this.showRemove){
  105. return
  106. }
  107. this.selectIndex = index;
  108. return this.showPopup = true;
  109. },
  110. choose(type, sourceType){
  111. if(!type){
  112. this.selectIndex = null;
  113. return this.showPopup = true;
  114. }
  115. this.showPopup = false;
  116. if(type == 'image'){
  117. uni.chooseImage({
  118. count: this.max - this.value.length, //默认9
  119. sourceType : [sourceType],
  120. sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
  121. crop : this.crop,
  122. // sourceType: ['album'], //从相册选择
  123. success: (fileList) => {
  124. this.toUploadImgs(fileList);
  125. },
  126. })
  127. }else{
  128. uni.chooseVideo({
  129. sourceType: [sourceType],
  130. maxDuration : 60,
  131. success: (res) => {
  132. // console.log(res);
  133. // self.src = res.tempFilePath;
  134. this.video = {
  135. isVideo : true,
  136. loading : true,
  137. videoUrl : '',
  138. videoCover : '',
  139. }
  140. let filePath = {
  141. filePath : res.tempFilePath,
  142. // #ifdef H5
  143. fileInfo : res.tempFile
  144. // #endif
  145. };
  146. this.value.push({
  147. loading :true,
  148. type : 'video',
  149. })
  150. let index=this.value.length-1
  151. this.$emit("input",this.value)
  152. this.$uploadOSS('/leapi/upload', filePath, this.dir + '/', (res) => {
  153. if(res){
  154. let obj={
  155. url : res.imgurl,
  156. video_img : res.imgurl + '?x-oss-process=video/snapshot,t_1000,f_jpg,w_300,h_300,m_fast',
  157. loading : false,
  158. type : 'video',
  159. }
  160. this.$set(this.value,index,obj)
  161. // this.list[index].url = res.imgurl
  162. // this.list[index].video_img = res.imgurl + '?x-oss-process=video/snapshot,t_1000,f_jpg,w_300,h_300,m_fast';
  163. // this.list[index].loading = false
  164. this.video.loading = false,
  165. this.video.videoUrl = res.imgurl;
  166. this.video.videoCover = res.imgurl + '?x-oss-process=video/snapshot,t_1000,f_jpg,w_300,h_300,m_fast';
  167. this.$emit("input",this.value)
  168. }
  169. })
  170. }
  171. });
  172. }
  173. },
  174. toUploadImgs : function(fileList){
  175. console.log(fileList,"filelist");
  176. if(!fileList.tempFilePaths){
  177. return;
  178. }
  179. fileList.tempFilePaths.forEach((filePath, index) => {
  180. let file={
  181. filePath : filePath,
  182. // #ifdef H5
  183. fileInfo : fileList.tempFiles[index]
  184. // #endif
  185. }
  186. this.value.push({
  187. file :file,
  188. loading :true,
  189. type : 'image',
  190. })
  191. let list_index=this.value.length-1
  192. console.log(list_index,"list_indexlist_index",file)
  193. uni.uploadFile({
  194. url: 'http://125.124.170.221:8000/api/upload',
  195. filePath: file.filePath,
  196. name: 'file',
  197. success: (myres) => {
  198. console.log(myres,"mures");
  199. let { data } = JSON.parse(myres.data);
  200. console.log(data,"data");
  201. let obj={
  202. url : data.url,
  203. loading : false,
  204. type : 'image'
  205. }
  206. this.$set(this.value,list_index,obj)
  207. this.value[list_index].url = data.url
  208. this.value[list_index].loading = false
  209. this.value[list_index].type = 'image'
  210. delete this.value[list_index].file
  211. this.$emit("input",this.value)
  212. },
  213. fail : (err=>{
  214. console.log(err,"err");
  215. })
  216. });
  217. // this.$uploadOSS('/leapi/upload', file, this.dir + '/', (res) => {
  218. // if(res){
  219. // let obj={
  220. // url : res.imgurl,
  221. // thumburl : res.imgurl + '?x-oss-process=style%2Fsquare200',
  222. // loading : false,
  223. // type : 'image'
  224. // }
  225. // this.$set(this.value,list_index,obj)
  226. // // this.value[list_index].url = res.imgurl
  227. // // this.value[list_index].thumburl = res.imgurl + '?x-oss-process=style%2Fsquare200',
  228. // // this.value[list_index].loading = false
  229. // // this.value[list_index].type = 'image'
  230. // // delete this.value[list_index].file
  231. // // this.list[index].loading = false,
  232. // // this.list[index].thumburl = res.imgurl + '?x-oss-process=style%2Fsquare200';
  233. // // this.list[index].imgurl = res.imgurl;
  234. // }
  235. // //
  236. // this.$emit("input",this.value)
  237. // })
  238. });
  239. }
  240. },
  241. }
  242. </script>
  243. <style scoped>
  244. .upload-image .img-max{
  245. width: 90%;
  246. margin: 5%;
  247. }
  248. .upload-image .imgwarp{
  249. width: 76px;
  250. height: 76px;
  251. line-height: 76px;
  252. margin-right: 10px;
  253. margin-bottom: 10px;
  254. color: #ccc;
  255. border: 1px dashed;
  256. position: relative;
  257. box-sizing: content-box;
  258. }
  259. .upload-image .img-remove{
  260. position: absolute;
  261. right: -10px;
  262. top: -8px;
  263. width: 40px;
  264. height: 40px;
  265. z-index: 100;
  266. text-align: right;
  267. line-height: normal;
  268. background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4NDEwQzFDNTFFMEExMUU0QURCREEwODgzQjUwQjFDRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4NDEwQzFDNjFFMEExMUU0QURCREEwODgzQjUwQjFDRiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjg0MTBDMUMzMUUwQTExRTRBREJEQTA4ODNCNTBCMUNGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjg0MTBDMUM0MUUwQTExRTRBREJEQTA4ODNCNTBCMUNGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+9KF98QAABA1JREFUeNrMmmlIVFEYhr8ZjfYoMtsjTIkWQtMsXCqkspQWyB8SlmWiSSq0+L/fbbSbWZZZ4Q+DiBYEi8olkzYistL21JnIjGiXrPebORPXcWa8Z+be8b7wcmaGOec898y93znnO2MiH5W6Pns4ivnCs+BJcDA8WHzlG/wBfgs/gqvhm+Wnij770q/JS9j+KFLgNHgxHCDZxB+4Ci6DK3ARv3QFB/BAFDnwVng8aaNWeA9ciAv4oTk4oJehOAhPIX30As4D/FVNwAE8AMVeMdL+UCH/oriAn16DA3o0iktwFPlX9+EkwFulwQEdgqISDqW+UTO8BPCvVIMDeoIIW5Opb/Uajgf8+17BAT0IRQ0cQcbQAzgO8N+VH5pdfHGfgaBJsOz3OOIY7SQUl8mYSsaoX+kBLsLeYx3jtK96Cc9whEnlrZJjYGhWiHIuMSvWHttlW1qRlEjzoiOlCebHzqOsDWlkNptlqxaIO4MCxQe8YBon08LK5KWUmrKKurq6bO/rG+6phs7OWGeDNsHFJ8/8b0OFxsKr4bOOS14rO9IMbfvJ0Hle9kZVI6+EZi2Mi6HM9DWyo25jNYv19CKZmh/b27uNkhp4Z2gWt/H0+QtZ8EXMHDAzPCoRb6Qu+11LK1msVpozO5xMJntg4jI6MoJaLRZ639KmCrqo5DTdqq2XBedG6hk8Ey9iZGszfJsF8JGe4eNj5tKmjelaQTvUwg/nNG9r3264aytzszP+gzluG1a/wEA9oFnTGDzMlxZ6g9cBmhXK4GN8bcUdvFIaQrOCuPVhWrTE8IeKSlzGZI2hWUPMpKECAtxv9n93dmo6/zP4Fy0a4uiRk5nuchqXmaRU6iv3YtEC2lX0kJ2kZOZA7qlJD2i+pw8fK9ELvpmjylNepGsNrXwQN2e5DpVqF2Yu1MgzJ2enUvWCll0eqNROBufcRYGb/adP0DrBc94x1yyyplVS8+3UsB7QR0+UeozTdXd6xnluIzgoSHa0r4G5w9F7mUzN46Xn6EZNXTfo6ro70pNUecUFunilUha8TLkDOg/vEjuMXsUd887lL8rGZ02qoJ2XB6OCRnoDzfdUhfMufwvZk5tG1jbcJnudd/mFIgVgVDHbkR6ZLJGvyDMweL4y9dxtVfT44b0mhMeJeDnbYNAnAb27t9xhPvzQQNDMkutqddhNIiu6HH5jAGhmWO6cqXU34iTy0Ql9/LBy3wmucuPkaZpHBa4YS/ZjDX+L+4wVDCQFLuAtAv6YH6GLBLTHfYLMcSHnzg+QQY4LVZ8Ii1BZjJefyH70PVQjYJ7Gd8AZgG5UW8nXI/F08RB7cyR+HS4lfxyJu7mIESgWiGdhOtkT8Hw+OsSxsYWtIko8gWvJ/ieEDl/6/SfAACQq2Uox69/XAAAAAElFTkSuQmCC) no-repeat 15px 0;
  269. background-size: 23px auto;
  270. }
  271. .upload-image:after{
  272. content: ' ';
  273. display: block;
  274. clear: both;
  275. }
  276. .uloading{
  277. position: absolute;
  278. top : calc(50% - 7px);
  279. left: calc(50% - 7px);
  280. /* #ifndef H5 */
  281. top : 0;
  282. /* #endif */
  283. }
  284. </style>