混凝土运输管理微信小程序、替班
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

289 lines
5.7 KiB

<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>