Compare commits
	
		
			1 Commits
		
	
	
		
			d6a5246f17
			...
			dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | a1a923772d | 
							
								
								
									
										80
									
								
								src/project/lianhuaH5/AppPatrolReport/AiImage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/project/lianhuaH5/AppPatrolReport/AiImage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| <template> | ||||
|   <section class="AiImage"> | ||||
|     <div v-if="$slots.default" @tap="prev"> | ||||
|       <slot/> | ||||
|     </div> | ||||
|     <u-image v-else :src="image" @tap="prev"> | ||||
|       <image v-if="link" class="errorImage" slot="error" :src="$cdn+'link.png'"/> | ||||
|       <image v-else-if="miniapp" class="errorImage" slot="error" :src="$cdn+'miniwxmp.jpg'"/> | ||||
|       <div v-else-if="$slots.errorImage" slot="error"> | ||||
|         <slot name="errorImage"/> | ||||
|       </div> | ||||
|       <image v-else class="errorImage" slot="error" :src="$cdn+'file.png'"/> | ||||
|     </u-image> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapActions} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "AiImage", | ||||
|   data() { | ||||
|     return { | ||||
|       dialog: false | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     image() { | ||||
|       return this.src?.replace(/\\/g, '/') | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     src: String, | ||||
|     preview: Boolean, | ||||
|     link: Boolean, | ||||
|     miniapp: Boolean, | ||||
|     file: { | ||||
|       default: () => { | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions(['previewFile', 'injectJWeixin']), | ||||
|     prev() { | ||||
|       if (this.preview) { | ||||
|         if (!!this.image) { | ||||
|           uni.previewImage({ | ||||
|             current: this.image, | ||||
|             urls: [this.image], | ||||
|             success() { | ||||
|               sessionStorage.setItem("previewImage", " 1") | ||||
|             } | ||||
|           }) | ||||
|         } else { | ||||
|           this.previewFile({size: 1, ...this.file}) | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AiImage { | ||||
|   ::v-deep image { | ||||
|     width: 160px; | ||||
|     height: 160px; | ||||
|     object-fit: cover; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .u-image__error { | ||||
|     position: relative; | ||||
|   } | ||||
|  | ||||
|   .errorImage { | ||||
|     width: 80px; | ||||
|     height: 80px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										283
									
								
								src/project/lianhuaH5/AppPatrolReport/AiUploader.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								src/project/lianhuaH5/AppPatrolReport/AiUploader.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,283 @@ | ||||
| <template> | ||||
|   <div class="ai-uploader"> | ||||
|     <div class="fileList"> | ||||
|       <div class="item" v-for="(item, i) in fileList" :key="i"> | ||||
|         <template v-if="type == 'image'"> | ||||
|           <ai-image :src="item.url" :preview="preview"/> | ||||
|           <u-icon v-if="!disabled" class="delBtn" color="#f46" name="close-circle-fill" size="40" @click="remove(i)"/> | ||||
|         </template> | ||||
|         <template v-else-if="type == 'video'"> | ||||
|           <video :src="item.url" :poster="item.thumb"/> | ||||
|           <u-icon v-if="!disabled" class="delBtn" color="#f46" name="close-circle-fill" size="40" @click="remove(i)"/> | ||||
|         </template> | ||||
|         <div class="file" v-else> | ||||
|           <ai-image :preview="preview" :file="item"/> | ||||
|           <div class="info"> | ||||
|             <span>{{ item.name }} </span> | ||||
|             <i>{{ item.fileSizeStr }}</i> | ||||
|           </div> | ||||
|           <template v-if="!disabled"> | ||||
|             <div btn @tap="handleReUpload(i)"> | ||||
|               重新上传 | ||||
|             </div> | ||||
|             <div btn @tap="remove(i)"> | ||||
|               删除 | ||||
|             </div> | ||||
|           </template> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div v-if="!disabled&&(fileList.length == 0 || (multiple && fileList.length < limit))" class="default" | ||||
|            @click="upload"> | ||||
|         <i class="iconfont iconfont-iconAdd"/> | ||||
|         <span>{{ placeholder }}</span> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from 'vuex' | ||||
| import AiImage from './AiImage' | ||||
|  | ||||
| export default { | ||||
|   name: 'AiUploader', | ||||
|   components: {AiImage}, | ||||
|   props: { | ||||
|     limit: {default: 1}, //数量 | ||||
|     placeholder: {default: '添加图片'}, // 文字提示 | ||||
|     type: {default: 'image'}, // 文件类型,image还是file | ||||
|     multiple: { | ||||
|       type: Boolean, | ||||
|       default: false, | ||||
|     }, | ||||
|     fileId: String, | ||||
|     mediaId: String, | ||||
|     def: {default: () => []}, | ||||
|     action: String, | ||||
|     preview: Boolean, | ||||
|     size: {default: 10 * 1024 * 1024}, | ||||
|     disabled: Boolean, | ||||
|     sourceType: {default: () => ['album', 'camera']}, | ||||
|     withoutToken: { | ||||
|       type: Number, | ||||
|       default: 0, | ||||
|     }, | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['token']), | ||||
|     errorImage: v => v.$cdn + 'file.png', | ||||
|     api() { | ||||
|       if (this.action) return this.action | ||||
|       else return { | ||||
|         image: '/admin/file/add', | ||||
|         file: '/admin/file/add', | ||||
|         video: '/admin/file/addVideo', | ||||
|       }[this.type] | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     def: { | ||||
|       handler(v) { | ||||
|         if (!!v?.toString()) { | ||||
|           if (this.multiple) { | ||||
|             this.fileList = v | ||||
|           } else if (v?.url) { | ||||
|             this.fileList = [v] | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       immediate: true, | ||||
|       deep: true | ||||
|     }, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       fileList: [], | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     remove(index) { | ||||
|       this.fileList.splice(index, 1) | ||||
|       this.$emit('list', this.fileList) | ||||
|     }, | ||||
|     upload(wait) { | ||||
|       typeof wait == 'function' && wait() | ||||
|       let count = this.limit - (this.fileList?.length || 0) | ||||
|       if (count > 0) { | ||||
|         let params = { | ||||
|           count, | ||||
|           sizeType: ['compressed'], | ||||
|           sourceType: [this.sourceType].flat(), | ||||
|           success: (res) => { | ||||
|             let count = this.fileList?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0) | ||||
|             if (count > this.limit && this.limit !== 1) { | ||||
|               return this.$u.toast(`不能超过${this.limit}个`) | ||||
|             } | ||||
|             if (res.tempFiles?.length > 0) { | ||||
|               res.tempFiles.map(this.uploadFile) | ||||
|             } else if (res?.tempFile) { | ||||
|               this.uploadFile(res.tempFile) | ||||
|             } | ||||
|           }, | ||||
|         } | ||||
|         if (this.type == 'image') { | ||||
|           uni.chooseImage(params) | ||||
|         } else if (this.type == 'video') { | ||||
|           uni.chooseVideo(params) | ||||
|         } else { | ||||
|           uni.chooseFile(params) | ||||
|         } | ||||
|       } else { | ||||
|         this.$u.toast(`不能超过${this.limit}个`) | ||||
|       } | ||||
|     }, | ||||
|     uploadFile(img) { | ||||
|       if (this.size > 0 && img.size > this.size) { | ||||
|         return this.$u.toast(`不能超过${Math.ceil(this.size / 1024 / 1024)}MB`) | ||||
|       } | ||||
|       uni.showLoading({title: '上传中'}) | ||||
|       let formData = new FormData() | ||||
|       formData.append('file', img) | ||||
|       if (this.manual) { | ||||
|         this.$emit('manual', img) | ||||
|         uni.hideLoading() | ||||
|       } else { | ||||
|         this.$http.post(this.api, formData, { | ||||
|           params: {type: this.type}, | ||||
|           withoutToken: this.withoutToken == 1 ? true : false, | ||||
|         }).then((res) => { | ||||
|           if (res?.data) { | ||||
|             this.$emit('data', res.data) | ||||
|             this.$u.toast('上传成功!') | ||||
|             if (!this.action) { | ||||
|               if (this.type == 'image') { | ||||
|                 const [image = "",] = res.data | ||||
|                 this.fileList.push({url: image.split(";")[0], id: image.split(";")?.[1]}) | ||||
|               } else if (this.type == 'video') { | ||||
|                 const [video = "", thumb = ""] = res.data | ||||
|                 this.fileList.push({url: video.split(";")[0], id: video.split(";")?.[1], thumb: thumb.split(";")[0]}) | ||||
|               } | ||||
|             } else if (this.api == '/app/wxcp/upload/uploadFile') { | ||||
|               this.$emit('update:mediaId', res.data?.media?.mediaId) | ||||
|               this.$emit('update:fileId', res.data.file.id) | ||||
|               this.fileList.push(res.data.file) | ||||
|             } else if (this.api == '/admin/file/add2') { | ||||
|               let info = res.data | ||||
|               this.$emit('update:fileId', info?.id) | ||||
|               this.fileList.push(res.data) | ||||
|             } else if (this.api == '/admin/file/add-portrait') { | ||||
|               this.fileList.push({url: res.data?.split(";")?.[0], id: res.data?.split(";")?.[1]}) | ||||
|             } | ||||
|             this.$emit("update:def", this.fileList) | ||||
|             this.$emit("list", this.fileList) | ||||
|           } else { | ||||
|             this.$u.toast(res.msg) | ||||
|           } | ||||
|         }).catch(err => { | ||||
|           this.$u.toast(err) | ||||
|         }).finally(() => uni.hideLoading()) | ||||
|       } | ||||
|  | ||||
|     }, | ||||
|     handleReUpload(i) { | ||||
|       this.upload(() => this.remove(i)) | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .ai-uploader { | ||||
|   width: 100%; | ||||
|   line-height: normal; | ||||
|   margin-bottom: 16px; | ||||
|  | ||||
|   ::v-deep.fileList { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|  | ||||
|     .item { | ||||
|       width: initial; | ||||
|       padding: 0 10px 10px 0; | ||||
|       position: relative; | ||||
|  | ||||
|       .delBtn { | ||||
|         position: absolute; | ||||
|         right: -8px; | ||||
|         top: -8px; | ||||
|         z-index: 2; | ||||
|         border-radius: 50%; | ||||
|         overflow: hidden; | ||||
|         background-color: #fff; | ||||
|         height: 40px; | ||||
|       } | ||||
|  | ||||
|       image, video { | ||||
|         width: 29vw; | ||||
|         height: 29vw; | ||||
|       } | ||||
|  | ||||
|       i { | ||||
|         font-style: normal; | ||||
|         color: #9b9b9b; | ||||
|       } | ||||
|  | ||||
|       .info { | ||||
|         flex: 1; | ||||
|         min-width: 0; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         align-items: flex-start; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|  | ||||
|         & > span { | ||||
|           flex: 1; | ||||
|           min-width: 0; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       div[btn] { | ||||
|         color: $uni-color-primary; | ||||
|       } | ||||
|  | ||||
|       div:nth-child(4) { | ||||
|         color: #f72c27; | ||||
|       } | ||||
|  | ||||
|       & > * + * { | ||||
|         margin-left: 20px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .default { | ||||
|       width: 30vw; | ||||
|       height: 30vw; | ||||
|       box-sizing: border-box; | ||||
|       border-radius: 8px; | ||||
|       background: #f3f4f7; | ||||
|       color: #89b; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       justify-content: center; | ||||
|       align-items: center; | ||||
|  | ||||
|       .iconfont-iconAdd { | ||||
|         font-size: 64px; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         display: block; | ||||
|         text-align: center; | ||||
|         font-size: 28px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .file { | ||||
|       width: 100vw; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -50,9 +50,11 @@ | ||||
|  | ||||
| <script> | ||||
| import {mapState} from 'vuex' | ||||
| import AiUploader from './AiUploader' | ||||
| export default { | ||||
|   name: 'AppPatrolReport', | ||||
|   appName: '事件添加', | ||||
|   components: {AiUploader}, | ||||
|   data() { | ||||
|     return { | ||||
|       forms: { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user