ufutx_official_website/src/components/upload/imageUpload.vue
2026-03-03 15:50:38 +08:00

186 lines
4.5 KiB
Vue

<script setup>
import {ref} from 'vue'
import service from '@/utils/request.js'
import { watch } from 'vue'
const props = defineProps({
modelValue: File,
placeholder: {
type: String,
default: '点击上传'
},
accept: {
type: String,
default: 'image/*'
},
backgroundImage: {
type: String,
default: 'https://images.health.ufutx.com/202504/23/a1d99b1cecd936185be30d1230dc5cbc.png'
},
dimension: {
type: Object,
default: () => ({
width: '230px', // 改为百分比单位
height: '140px', // 自动高度
})
}
})
const emit = defineEmits(['update:modelValue'])
const fileInput = ref(null)
const previewImage = ref('')
const host = ref('')
const ossConfig = ref('')
watch(
() => props.modelValue,
(newVal) => {
if (typeof newVal === 'string') {
previewImage.value = newVal
}
},
{ immediate: true }
)
const handleFileUpload = (e) => {
const file = e.target.files[0]
console.log(file,'fff===')
if (file) {
getSignature(file)
}
}
const getSignature = (file) => {
const self = this
service.get('api/get/oss/config').then(res => {
let result = res.data
host.value = result.host
ossConfig.value = result
upload(file)
}).catch(() => {
console.log('出错了~')
})
}
const newGuid = () => {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
}
return S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4()
}
const getExtension = (file) => {
if (file) {
// 通过正则表达式提取文件后缀名
const regex = /(?:\.([^.]+))?$/
const result = regex.exec(file.name)
return result?.[1] || null
}
return null // 处理输入为 null 的情况
}
const upload = (file) => {
console.log(file,'file')
let formData = new FormData()
const fileGuid = newGuid()
const fileSuffix = getExtension(file)
let fileName = fileGuid + '.' + fileSuffix
let filePath = host.value + '/' + ossConfig.value.dir + fileName
formData.append('name', ossConfig.value.dir + fileName)
formData.append('key', ossConfig.value.dir + fileName)
formData.append('policy', ossConfig.value.policy)
formData.append('OSSAccessKeyId', ossConfig.value.access_id)
formData.append('success_action_status', '200')
formData.append('signature', ossConfig.value.signature)
formData.append('filename', file.name)
// formData.append('fileData', file)
formData.append('file', file)
console.log(ossConfig,'ossConfig----')
service.post(ossConfig.value.host,formData,{ headers: { 'Content-Type': 'multipart/form-data' }}).then(({code,data}) => {
if ( document.location.hostname === 'localhost') {
filePath = filePath.split('/')[0] + '//local-pictures.oss-cn-shenzhen.aliyuncs.com/' + filePath.split('/')[3] + '/' + filePath.split('/')[4] + '/' + filePath.split('/')[5]
} else {
filePath = host.value + '/' + filePath.split('/')[3] + '/' + filePath.split('/')[4] + '/' + filePath.split('/')[5]
}
emit('update:modelValue', filePath)
previewImage.value = filePath
// newFileList.value.push({url:filePath})
// emit('update:fileList',newFileList.value)
// loading.value = false
})
}
const triggerUpload = () => {
fileInput.value.click()
}
</script>
<template>
<div class="image-uploader">
<input
type="file"
ref="fileInput"
:accept="accept"
@change="handleFileUpload"
class="hidden-input"
>
<div class="upload-wrapper">
<div
class="upload-btn"
:style="{backgroundImage: `url(${backgroundImage})`}"
@click="triggerUpload"
>
<img
src="https://images.health.ufutx.com/202504/23/a1d99b1cecd936185be30d1230dc5cbc.png"
class="upload-icon"
alt=''
>
<img
v-if="previewImage"
:src="previewImage"
class="preview-image"
alt=''
>
</div>
</div>
</div>
</template>
<style scoped>
.hidden-input {
display: none;
}
.upload-btn {
position: relative;
width: 230px;
height: 144px;
background-size: contain; /* 新增背景图适配 */
background-repeat: no-repeat;
}
.upload-wrapper{
position: relative;
}
.upload-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 30px;
height: 30px;
z-index: 1;
}
.upload-btn:hover {
border-color: #79BBFF;
background-color: rgba(121, 187, 255, 0.1);
}
.preview-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 8px;
border: 1px solid #eee;
z-index: 2;
background: #ffffff;
}
</style>