<template>
|
|
<view class="input-image-container">
|
|
<view class="upload-area" v-if="showUploadBtn">
|
|
<view class="upload-btn" @click="chooseImage">
|
|
<view v-if="showPlaceholder" class="placeholder-area" :style="{ height: placeholderHeight }">
|
|
<!-- 占位区域 -->
|
|
</view>
|
|
<view class="upload-icon">
|
|
<image style="width:110rpx;height:110rpx" src="/static/re/ico.png" />
|
|
</view>
|
|
<view v-if="hasImage" class="image-preview" :style="{ height: imageHeight }">
|
|
<image
|
|
:style="{ height: imageDisplayHeight }"
|
|
:src="imageUrl"
|
|
mode="scaleToFill"
|
|
class="preview-image"
|
|
/>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 显示已上传的图片 -->
|
|
<view v-if="showImageOnly" class="image-display" :style="{ height: 'auto' }">
|
|
<image
|
|
:style="{ height: 'auto' }"
|
|
:src="displayImageUrl"
|
|
mode="widthFix"
|
|
class="display-image"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 多图上传模式 -->
|
|
<view v-if="multiple" class="multiple-upload">
|
|
<uv-upload
|
|
:fileList="fileList"
|
|
:multiple="true"
|
|
:maxCount="maxCount"
|
|
:width="uploadWidth"
|
|
:height="uploadHeight"
|
|
@afterRead="afterRead"
|
|
@delete="deleteImage"
|
|
>
|
|
<image
|
|
src="/static/re/ico.png"
|
|
mode="aspectFill"
|
|
:style="{ width: uploadWidth, height: uploadHeight }"
|
|
/>
|
|
</uv-upload>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'InputImage',
|
|
props: {
|
|
// 是否显示上传按钮
|
|
showUploadBtn: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
// 是否显示占位区域
|
|
showPlaceholder: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 占位区域高度
|
|
placeholderHeight: {
|
|
type: String,
|
|
default: '200rpx'
|
|
},
|
|
// 是否有图片
|
|
hasImage: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 图片URL
|
|
imageUrl: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 图片高度
|
|
imageHeight: {
|
|
type: String,
|
|
default: '300rpx'
|
|
},
|
|
// 图片显示高度
|
|
imageDisplayHeight: {
|
|
type: String,
|
|
default: '300rpx'
|
|
},
|
|
// 只显示图片模式
|
|
showImageOnly: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 显示的图片URL
|
|
displayImageUrl: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 是否多图上传
|
|
multiple: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 最大上传数量
|
|
maxCount: {
|
|
type: Number,
|
|
default: 3
|
|
},
|
|
// 上传区域宽度
|
|
uploadWidth: {
|
|
type: String,
|
|
default: '180rpx'
|
|
},
|
|
// 上传区域高度
|
|
uploadHeight: {
|
|
type: String,
|
|
default: '180rpx'
|
|
},
|
|
// 文件列表
|
|
fileList: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
internalFileList: []
|
|
}
|
|
},
|
|
mounted() {
|
|
this.internalFileList = [...this.fileList];
|
|
},
|
|
watch: {
|
|
fileList: {
|
|
handler(newVal) {
|
|
this.internalFileList = [...newVal];
|
|
},
|
|
deep: true
|
|
}
|
|
},
|
|
methods: {
|
|
// 选择图片
|
|
chooseImage() {
|
|
uni.chooseImage({
|
|
count: 1,
|
|
sizeType: ['compressed'],
|
|
sourceType: ['album', 'camera'],
|
|
success: (res) => {
|
|
const tempFilePath = res.tempFilePaths[0];
|
|
this.$emit('imageSelected', tempFilePath);
|
|
|
|
// 模拟上传到OSS
|
|
this.uploadToOss(tempFilePath);
|
|
},
|
|
fail: (err) => {
|
|
console.error('选择图片失败:', err);
|
|
uni.showToast({
|
|
title: '选择图片失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
// 模拟上传到OSS
|
|
uploadToOss(filePath) {
|
|
uni.showLoading({
|
|
title: '上传中...'
|
|
});
|
|
|
|
// 模拟上传过程
|
|
setTimeout(() => {
|
|
uni.hideLoading();
|
|
|
|
// 模拟生成OSS URL
|
|
const mockOssUrl = `https://relief.oss-cn-hangzhou.aliyuncs.com/mock_${Date.now()}.jpg`;
|
|
|
|
this.$emit('uploadSuccess', {
|
|
localPath: filePath,
|
|
ossUrl: mockOssUrl
|
|
});
|
|
|
|
uni.showToast({
|
|
title: '上传成功',
|
|
icon: 'success'
|
|
});
|
|
}, 1000); // 模拟1秒上传时间
|
|
},
|
|
|
|
// 多图上传后处理
|
|
afterRead(e) {
|
|
const files = Array.isArray(e.file) ? e.file : [e.file];
|
|
|
|
files.forEach(file => {
|
|
this.uploadToOssMultiple(file.url);
|
|
});
|
|
},
|
|
|
|
// 模拟多图上传到OSS
|
|
uploadToOssMultiple(filePath) {
|
|
// 模拟上传过程
|
|
setTimeout(() => {
|
|
// 模拟生成OSS URL
|
|
const mockOssUrl = `https://relief.oss-cn-hangzhou.aliyuncs.com/mock_${Date.now()}.jpg`;
|
|
|
|
this.internalFileList.push({
|
|
url: mockOssUrl
|
|
});
|
|
|
|
this.$emit('update:fileList', this.internalFileList);
|
|
this.$emit('multipleUploadSuccess', this.internalFileList);
|
|
}, 500); // 模拟0.5秒上传时间
|
|
},
|
|
|
|
// 删除图片
|
|
deleteImage(e) {
|
|
this.internalFileList.splice(e.index, 1);
|
|
this.$emit('update:fileList', this.internalFileList);
|
|
this.$emit('imageDeleted', e.index);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.input-image-container {
|
|
position: relative;
|
|
}
|
|
|
|
.upload-area {
|
|
position: relative;
|
|
}
|
|
|
|
.upload-btn {
|
|
position: relative;
|
|
border: 2rpx dashed #ddd;
|
|
border-radius: 10rpx;
|
|
padding: 20rpx;
|
|
text-align: center;
|
|
background-color: #fafafa;
|
|
transition: all 0.3s;
|
|
|
|
&:active {
|
|
background-color: #f0f0f0;
|
|
}
|
|
}
|
|
|
|
.placeholder-area {
|
|
width: 100%;
|
|
background-color: #f5f5f5;
|
|
border-radius: 8rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.upload-icon {
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.image-preview {
|
|
width: 100%;
|
|
border-radius: 8rpx;
|
|
overflow: hidden;
|
|
|
|
.preview-image {
|
|
width: 100%;
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
|
|
.image-display {
|
|
width: 100%;
|
|
border-radius: 8rpx;
|
|
overflow: hidden;
|
|
|
|
.display-image {
|
|
width: 100%;
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
|
|
.multiple-upload {
|
|
padding: 20rpx;
|
|
background-color: #fff;
|
|
border-radius: 10rpx;
|
|
}
|
|
</style>
|