186 lines
4.5 KiB
Vue
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>
|