<template>
<view class="upload-container">
<!-- 上传按钮 -->
<view class="upload-btn" @click="selectFile">
<uni-icons type="plusempty" size="24"></uni-icons>
<text>上传图片</text>
</view>
<!-- 循环显示已上传的图片 -->
<view class="upload-pic">
<view v-for="(item, index) in imageList" :key="index" class="file-info">
<img class="file-preview" :src="item.url" mode="aspectFit" />
<view class="file-name">{{ item.name }}</view>
<view class="delete-btn" @click="deleteFile(index)">
<uni-icons type="trash" size="20" color="#ff0000"></uni-icons>
</view>
</view>
</view>
</view>
</template>
<script>
import constant from "@/constant/index.js"
export default {
props: {
label: String,
value: {
type: Array,
default: () => [],
},
maxCount: {
type: Number,
default: 9,
},
},
data() {
return {
imageList: [],
myValue: [],
}
},
watch: {
value: {
handler(newVal) {
if (Array.isArray(newVal) && newVal.length > 0) {
this.imageList = newVal.map((item) => ({
url: `/wdxx/cos-appconfig/common/f3100202/file/${item}`,
name: `${this.label || "file"}.jpg`,
}))
this.myValue = [...newVal]
} else {
this.imageList = []
this.myValue = []
}
},
immediate: true,
},
},
methods: {
selectFile() {
// 调用实际的文件选择逻辑
SystemUtils.postMessage(
'{"type": "pickFileBase64","params":{},"callback": "handlePickFileBase64"}'
)
window.handlePickFileBase64 = this.handlePickFileBase64
},
async handlePickFileBase64(result) {
if (!result) return
const resultType = await this.$util.detectType(result)
const allowedTypes = ["image/jpeg", "image/png", "image/gif"]
if (!allowedTypes.includes(resultType)) {
uni.showToast({
icon: "none",
title: "请上传图片格式文件",
duration: 1500,
})
return
}
if (this.maxCount && this.imageList.length >= this.maxCount) {
uni.showToast({
icon: "none",
title: `最多只能上传${this.maxCount}张图片`,
duration: 1500,
})
return
}
const data = {
name: `${this.label}`,
suffix: resultType.split("/")[1],
base64: result,
}
this.$http.post({
url: constant.personNameSignUpload,
data: data,
success: (res) => {
console.log(res, "cjc")
// 添加新图片到列表
const newImage = {
url: `data:image/${data.suffix};base64,${result}`,
name: `${this.label}.${data.suffix}`,
}
this.imageList.push(newImage)
this.myValue.push(res.s00500)
// 同步更新父组件的值
this.$emit("input", [...this.myValue])
this.$emit("update:value", [...this.myValue])
},
complete: (res) => {},
})
},
deleteFile(index) {
this.imageList.splice(index, 1)
this.myValue.splice(index, 1)
// 通知父组件值已更新
this.$emit("input", [...this.myValue])
this.$emit("update:value", [...this.myValue])
},
},
}
</script>
<style scoped lang="scss">
.upload-container {
width: 100%;
padding: 20rpx;
}
.upload-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120px;
height: 120px;
border: 2px dashed #007AFF;
border-radius: 8px;
background-color: #F5F5F5;
cursor: pointer;
}
.upload-btn text {
margin-top: 10rpx;
font-size: 28rpx;
color: #007AFF;
}
.upload-pic{
display: flex;
flex-wrap: wrap;
gap:10rpx;
margin-top: 10rpx;
.file-info {
position: relative;
width: 100px;
height: 100px;
border: 2px solid #007AFF;
border-radius: 8px;
overflow: hidden;
}
}
.file-preview {
width: 100%;
height: 100%;
object-fit: cover;
}
.file-name {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 5rpx;
font-size: 24rpx;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.delete-btn {
position: absolute;
top: 0;
right: 0;
padding: 5rpx;
border-radius: 50%;
z-index: 10;
background-color: rgba(255, 255, 255, 0.8);
}
</style>