|
@@ -1,25 +1,42 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="upload-wrap">
|
|
|
|
|
- <div class="tips tips-text" v-if="tipText?.length>0">
|
|
|
|
|
- <span>{{tipText}}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="tips" v-if="!textShow">
|
|
|
|
|
- <el-icon class="icon" size="16"><Warning /></el-icon>
|
|
|
|
|
- <span>上传照片可精准预测最佳病虫防治时间</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <uploader class="uploader" v-model="fileList" :multiple="props.maxCount > 1" :max-count="props.maxCount" :after-read="afterRead" @delete="deleteImg">
|
|
|
|
|
- <template v-if="exampleImg">
|
|
|
|
|
- <slot v-if="!fileList.length"></slot>
|
|
|
|
|
- <img class="plus" v-else src="@/assets/img/home/plus.png" alt="">
|
|
|
|
|
- </template>
|
|
|
|
|
- <img class="plus" v-else src="@/assets/img/home/plus.png" alt="">
|
|
|
|
|
- </uploader>
|
|
|
|
|
|
|
+ <div class="upload-wrap">
|
|
|
|
|
+ <div class="tips tips-text" v-if="tipText?.length > 0">
|
|
|
|
|
+ <span>{{ tipText }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="tips" v-if="!textShow">
|
|
|
|
|
+ <el-icon class="icon" size="16">
|
|
|
|
|
+ <Warning />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ <span>上传照片可精准预测最佳病虫防治时间</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <img v-if="exampleImg" @click="showExample" class="example" src="@/assets/img/home/example-4.png" alt="" />
|
|
|
|
|
+ <uploader class="uploader" :class="{ 'uploader-list': exampleImg }" v-model="fileList" :multiple="props.maxCount > 1"
|
|
|
|
|
+ :max-count="props.maxCount" :after-read="afterRead" @delete="deleteImg">
|
|
|
|
|
+ <template v-if="exampleImg">
|
|
|
|
|
+ <slot v-if="!fileList.length"></slot>
|
|
|
|
|
+ <img class="plus" v-else src="@/assets/img/home/plus.png" alt="">
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <img class="plus" v-else src="@/assets/img/home/plus.png" alt="">
|
|
|
|
|
+ </uploader>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 示例照片 -->
|
|
|
|
|
+ <popup v-model:show="showExamplePopup" overlay-class="example-overlay" class="example-popup">
|
|
|
|
|
+ <div class="example-content">
|
|
|
|
|
+ <!-- <img src="@/assets/img/home/example-4.png" alt="" /> -->
|
|
|
|
|
+ <img class="example-img"
|
|
|
|
|
+ src="https://birdseye-img-ali-cdn.sysuimars.com/birdseye-look-mini/94379/1768801082504.png" alt="" />
|
|
|
|
|
+ <div class="example-tips">
|
|
|
|
|
+ 拍摄要求:请采集代表农场作物物候期的照片,请采集代表农场作物物候期的照片。
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </popup>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { onMounted, ref} from "vue";
|
|
|
|
|
-import { Uploader } from "vant";
|
|
|
|
|
|
|
+import { onMounted, ref } from "vue";
|
|
|
|
|
+import { Uploader, Popup } from "vant";
|
|
|
import eventBus from "@/api/eventBus";
|
|
import eventBus from "@/api/eventBus";
|
|
|
import { base_img_url2 } from "@/api/config";
|
|
import { base_img_url2 } from "@/api/config";
|
|
|
import { getFileExt } from "@/utils/util";
|
|
import { getFileExt } from "@/utils/util";
|
|
@@ -33,7 +50,7 @@ const props = defineProps({
|
|
|
type: String,
|
|
type: String,
|
|
|
default: ''
|
|
default: ''
|
|
|
},
|
|
},
|
|
|
- fullPath:{
|
|
|
|
|
|
|
+ fullPath: {
|
|
|
type: Boolean,
|
|
type: Boolean,
|
|
|
default: true
|
|
default: true
|
|
|
},
|
|
},
|
|
@@ -63,115 +80,181 @@ const fileArr = ref([])
|
|
|
const imgArr = ref([])
|
|
const imgArr = ref([])
|
|
|
const uploadFileObj = new UploadFile();
|
|
const uploadFileObj = new UploadFile();
|
|
|
|
|
|
|
|
|
|
+const showExamplePopup = ref(false);
|
|
|
|
|
+const showExample = () => {
|
|
|
|
|
+ showExamplePopup.value = true;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const afterRead = async (files) => {
|
|
const afterRead = async (files) => {
|
|
|
- if (!Array.isArray(files)) {
|
|
|
|
|
- files = [files];
|
|
|
|
|
- }
|
|
|
|
|
- // 如果 maxCount 为 1,先清空之前的图片数组
|
|
|
|
|
- if (props.maxCount === 1) {
|
|
|
|
|
- fileArr.value = [];
|
|
|
|
|
- imgArr.value = [];
|
|
|
|
|
- }
|
|
|
|
|
- for(let file of files){
|
|
|
|
|
- // 将文件上传至服务器
|
|
|
|
|
- let fileVal = file.file;
|
|
|
|
|
- file.status = "uploading";
|
|
|
|
|
- file.message = "上传中...";
|
|
|
|
|
- let ext = getFileExt(fileVal.name);
|
|
|
|
|
- let key = `birdseye-look-mini/${miniUserId}/${new Date().getTime()}.${ext}`;
|
|
|
|
|
- let resFilename = await uploadFileObj.put(key, fileVal)
|
|
|
|
|
- file.status = "done";
|
|
|
|
|
- file.message = "";
|
|
|
|
|
- if(resFilename){
|
|
|
|
|
- fileArr.value.push(props.fullPath ? base_img_url2 + resFilename : resFilename)
|
|
|
|
|
- imgArr.value.push(resFilename)
|
|
|
|
|
- eventBus.emit('upload:change',fileArr.value)
|
|
|
|
|
- eventBus.emit('upload:changeArr',imgArr.value)
|
|
|
|
|
- emit('handleUpload',{imgArr:imgArr.value,fileList:fileArr.value})
|
|
|
|
|
- }else{
|
|
|
|
|
- fileList.value.pop()
|
|
|
|
|
- file.status = 'failed';
|
|
|
|
|
- file.message = '上传失败';
|
|
|
|
|
- ElMessage.error('图片上传失败,请稍后再试!')
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!Array.isArray(files)) {
|
|
|
|
|
+ files = [files];
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果 maxCount 为 1,先清空之前的图片数组
|
|
|
|
|
+ if (props.maxCount === 1) {
|
|
|
|
|
+ fileArr.value = [];
|
|
|
|
|
+ imgArr.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ for (let file of files) {
|
|
|
|
|
+ // 将文件上传至服务器
|
|
|
|
|
+ let fileVal = file.file;
|
|
|
|
|
+ file.status = "uploading";
|
|
|
|
|
+ file.message = "上传中...";
|
|
|
|
|
+ let ext = getFileExt(fileVal.name);
|
|
|
|
|
+ let key = `birdseye-look-mini/${miniUserId}/${new Date().getTime()}.${ext}`;
|
|
|
|
|
+ let resFilename = await uploadFileObj.put(key, fileVal)
|
|
|
|
|
+ file.status = "done";
|
|
|
|
|
+ file.message = "";
|
|
|
|
|
+ if (resFilename) {
|
|
|
|
|
+ fileArr.value.push(props.fullPath ? base_img_url2 + resFilename : resFilename)
|
|
|
|
|
+ imgArr.value.push(resFilename)
|
|
|
|
|
+ eventBus.emit('upload:change', fileArr.value)
|
|
|
|
|
+ eventBus.emit('upload:changeArr', imgArr.value)
|
|
|
|
|
+ emit('handleUpload', { imgArr: imgArr.value, fileList: fileArr.value })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ fileList.value.pop()
|
|
|
|
|
+ file.status = 'failed';
|
|
|
|
|
+ file.message = '上传失败';
|
|
|
|
|
+ ElMessage.error('图片上传失败,请稍后再试!')
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const deleteImg = (file,e) => {
|
|
|
|
|
- fileArr.value.splice(e.index,1)
|
|
|
|
|
- imgArr.value.splice(e.index,1)
|
|
|
|
|
- eventBus.emit('upload:change',fileArr.value)
|
|
|
|
|
- eventBus.emit('upload:changeArr',imgArr.value)
|
|
|
|
|
- emit('handleUpload',{imgArr:imgArr.value,fileList:fileArr.value})
|
|
|
|
|
|
|
+const deleteImg = (file, e) => {
|
|
|
|
|
+ fileArr.value.splice(e.index, 1)
|
|
|
|
|
+ imgArr.value.splice(e.index, 1)
|
|
|
|
|
+ eventBus.emit('upload:change', fileArr.value)
|
|
|
|
|
+ eventBus.emit('upload:changeArr', imgArr.value)
|
|
|
|
|
+ emit('handleUpload', { imgArr: imgArr.value, fileList: fileArr.value })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function uploadReset(){
|
|
|
|
|
- fileList.value = []
|
|
|
|
|
- fileArr.value = []
|
|
|
|
|
- imgArr.value = []
|
|
|
|
|
|
|
+function uploadReset() {
|
|
|
|
|
+ fileList.value = []
|
|
|
|
|
+ fileArr.value = []
|
|
|
|
|
+ imgArr.value = []
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
|
defineExpose({
|
|
|
- uploadReset
|
|
|
|
|
|
|
+ uploadReset
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-onMounted(()=>{
|
|
|
|
|
- eventBus.off('upload:reset',uploadReset)
|
|
|
|
|
- eventBus.on('upload:reset',uploadReset)
|
|
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ eventBus.off('upload:reset', uploadReset)
|
|
|
|
|
+ eventBus.on('upload:reset', uploadReset)
|
|
|
})
|
|
})
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
-
|
|
|
|
|
.upload-wrap {
|
|
.upload-wrap {
|
|
|
- .tips {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- color: #2199F8;
|
|
|
|
|
- background: #E9F5FF;
|
|
|
|
|
- border-radius: 4px;
|
|
|
|
|
- padding: 2px 10px;
|
|
|
|
|
- box-sizing: border-box;
|
|
|
|
|
- margin-bottom: 10px;
|
|
|
|
|
- .icon {
|
|
|
|
|
- margin-right: 2px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ .tips {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ color: #2199F8;
|
|
|
|
|
+ background: #E9F5FF;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ padding: 2px 10px;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+
|
|
|
|
|
+ .icon {
|
|
|
|
|
+ margin-right: 2px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .tips-text {
|
|
|
|
|
+ background: linear-gradient(240deg, #FFFFFF 22%, rgba(33, 153, 248, 0.2) 100%);
|
|
|
|
|
+ border-radius: 20px 0 0 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ::v-deep {
|
|
|
|
|
+ .van-uploader__input-wrapper {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-select__wrapper:hover {
|
|
|
|
|
+ box-shadow: 0 0 0 1px #dcdfe6 inset;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .avatar-uploader .el-upload {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border: 1px dashed #dddddd;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
}
|
|
|
- .tips-text{
|
|
|
|
|
- background: linear-gradient(240deg,#FFFFFF 22%,rgba(33, 153, 248,0.2) 100%);
|
|
|
|
|
- border-radius: 20px 0 0 20px;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ .el-icon.avatar-uploader-icon {
|
|
|
|
|
+ font-size: 28px;
|
|
|
|
|
+ color: #8c939d;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 128px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ background: #f6f6f6;
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .uploader {
|
|
|
|
|
+ .plus {
|
|
|
|
|
+ width: calc((100vw - 68px) / 3);
|
|
|
|
|
+ height: calc((100vw - 68px) / 3);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .uploader-list {
|
|
|
::v-deep {
|
|
::v-deep {
|
|
|
- .van-uploader__input-wrapper{
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- }
|
|
|
|
|
- .el-select__wrapper:hover {
|
|
|
|
|
- box-shadow: 0 0 0 1px #dcdfe6 inset;
|
|
|
|
|
- }
|
|
|
|
|
- .avatar-uploader .el-upload {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- border: 1px dashed #dddddd;
|
|
|
|
|
- border-radius: 6px;
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- position: relative;
|
|
|
|
|
- overflow: hidden;
|
|
|
|
|
|
|
+ .van-uploader__wrapper {
|
|
|
|
|
+ >div:first-child {
|
|
|
|
|
+ margin-left: calc((100vw - 68px) / 3 + 8px);
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- .el-icon.avatar-uploader-icon {
|
|
|
|
|
- font-size: 28px;
|
|
|
|
|
- color: #8c939d;
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- height: 128px;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- background: #f6f6f6;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .van-uploader__preview-image {
|
|
|
|
|
+ width: calc((100vw - 68px) / 3);
|
|
|
|
|
+ height: calc((100vw - 68px) / 3);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- .uploader{
|
|
|
|
|
- .plus{
|
|
|
|
|
- width: 80px;
|
|
|
|
|
- height: 80px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .example {
|
|
|
|
|
+ width: calc((100vw - 68px) / 3);
|
|
|
|
|
+ height: calc((100vw - 68px) / 3);
|
|
|
|
|
+ margin: 0 12px 8px 0;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ z-index: 2;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+.example-popup {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border-radius: 0;
|
|
|
|
|
+ background: none;
|
|
|
|
|
+ max-width: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ .example-content {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+
|
|
|
|
|
+ .example-img {
|
|
|
|
|
+ width: 100%;
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .example-tips {
|
|
|
|
|
+ margin: 16px 12px 6px 12px;
|
|
|
|
|
+ background: #3d3d3d;
|
|
|
|
|
+ padding: 8px 10px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ backdrop-filter: blur(4px);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ line-height: 21px;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|