效果图
1. 云函数
2. 代码
1 <template> 2 <view> 3 <view class="feedback-title">意见反馈:</view> 4 <view class="feedback-content"> 5 <textarea 6 class="feedback-textarea" 7 v-model="content" 8 placeholder="请输入您要反馈的问题" 9 /> 10 </view> 11 <view class="feedback-title">反馈图片:</view> 12 <view class="feedback-image-box"> 13 <view 14 class="feedback-image-item" 15 v-for="(item, index) in imageLists" 16 :key="index" 17 > 18 <view class="close-icon" @click="del(index)"> 19 <uni-icons type="closeempty" size="18" color="#fff"></uni-icons> 20 </view> 21 <view class="image-box"> 22 <image :src="item.url" mode="aspectFill"></image> 23 </view> 24 </view> 25 <view 26 v-if="imageLists.length < 5" 27 class="feedback-image-item" 28 @click="addImage" 29 > 30 <view class="image-box"> 31 <uni-icons type="plusempty" size="50" color="#eee"></uni-icons> 32 </view> 33 </view> 34 </view> 35 <button class="feedback-button" type="primary" @click="submit"> 36 提交反馈意见 37 </button> 38 </view> 39 </template> 40 41 <script> 42 export default { 43 data() { 44 return { 45 content: "", 46 imageLists: [], 47 }; 48 }, 49 methods: { 50 // 删除图片 51 del(index) { 52 this.imageLists.splice(index, 1); 53 }, 54 // 添加图片 55 addImage() { 56 const count = 5 - this.imageLists.length; 57 uni.chooseImage({ 58 count: count, // h5页面,此字段是不生效的 59 success: (res) => { 60 // 注意此处的箭头,否则 this将指向uni.chooseImage 61 const tempfilepaths = res.tempFilePaths; 62 tempfilepaths.forEach((item, index) => { 63 // 处理 h5 多选的状况 64 if (index < count) { 65 this.imageLists.push({ 66 url: item, 67 }); 68 } 69 }); 70 }, 71 }); 72 }, 73 async submit() { 74 // 存放已经上传的图片的网络路径 75 let imagesPath = []; 76 uni.showLoading(); 77 // 不支持多图上传,一次上传一张 78 // 不能使用 forEach 异步的方法,要不然不知道将来上传的是哪一张 79 for (let i = 0; i < this.imageLists.length; i++) { 80 const filePath = this.imageLists[i].url; 81 filePath = await this.uploadFiles(filePath, i); // 调用下面的函数 82 imagesPath.push(filePath); // 存放已经上传的图片的网络路径 83 } 84 // console.log(imagesPath); 85 // 图片上传成功后,更新图片的网络地址到 feedback 数据库 (手动创建) 86 this.updateFeedback({ 87 content: this.content, 88 feedbackImages: imagesPath, 89 }); 90 }, 91 // 上传图片 92 async uploadFiles(filePath, i) { 93 const result = await uniCloud.uploadFile({ 94 filePath: filePath, 95 cloudPath: i + ".jpg", // 云文件名 96 }); 97 // console.log(result); 98 return result.fileID; // fileID 文件上传成功后的网络路径 99 }, 100 // 更新网络图片地址到数据库 101 updateFeedback({ content, feedbackImages }) { 102 this.$api 103 .update_feedback({ content, feedbackImages }) 104 .then((res) => { 105 uni.hideLoading(); 106 uni.showToast({ 107 title: "反馈提交成功", 108 icon: "none", 109 }); 110 setTimeout(() => { 111 uni.switchTab({ 112 url: "/pages/tabbar/my/my", 113 }); 114 }, 2000); 115 }) 116 .catch(() => { 117 uni.hideLoading(); 118 uni.showToast({ 119 title: "反馈提交失败 ", 120 icon: "none", 121 }); 122 }); 123 }, 124 }, 125 }; 126 </script> 127 128 <style lang="scss"> 129 .feedback-title { 130 margin: 15px; 131 margin-bottom: 0; 132 font-size: 14px; 133 color: #666; 134 } 135 136 .feedback-content { 137 margin: 15px; 138 padding: 10px; 139 box-sizing: border-box; 140 border: 1px #eee solid; 141 .feedback-textarea { 142 font-size: 12px; 143 width: 100%; 144 height: 100px; 145 } 146 } 147 .feedback-image-box { 148 display: flex; 149 flex-wrap: wrap; 150 padding: 10px; 151 .feedback-image-item { 152 position: relative; 153 width: 33.33%; 154 height: 0; 155 padding-top: 33.33%; 156 box-sizing: border-box; 157 .close-icon { 158 display: flex; 159 justify-content: center; 160 align-items: center; 161 position: absolute; 162 right: 0; 163 top: 0; 164 width: 22px; 165 height: 22px; 166 border-radius: 50%; 167 background-color: #ff5a5f; 168 z-index: 2; 169 } 170 .image-box { 171 display: flex; 172 justify-content: center; 173 align-items: center; 174 position: absolute; 175 top: 5px; 176 right: 5px; 177 bottom: 5px; 178 left: 5px; 179 border: 1px #eee solid; 180 border-radius: 5px; 181 overflow: hidden; 182 image { 183 width: 100%; 184 height: 100%; 185 } 186 } 187 } 188 } 189 .feedback-button { 190 margin: 0 15px; 191 background-color: $mk-base-color; 192 } 193 </style>