|
@@ -0,0 +1,78 @@
|
|
|
+<template>
|
|
|
+ <div v-if="!src" class="upload d-flex align-center justify-center" @click="openFileInput">
|
|
|
+ <v-icon color="#ccc" size="50">mdi-plus</v-icon>
|
|
|
+ <input
|
|
|
+ type="file"
|
|
|
+ ref="fileInput"
|
|
|
+ accept="image/*"
|
|
|
+ style="display: none;"
|
|
|
+ @change="handleUploadFile"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div v-else style="position: relative;">
|
|
|
+ <v-img :src="src" width="120" height="120" rounded></v-img>
|
|
|
+ <v-icon color="primary" class="close" @click="handleClose">mdi-close-circle</v-icon>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+// 图片上传
|
|
|
+defineOptions({ name: 'upload-img'})
|
|
|
+import { ref } from 'vue'
|
|
|
+import { uploadFile } from '@/api/common'
|
|
|
+import { useI18n } from '@/hooks/web/useI18n'
|
|
|
+import Snackbar from '@/plugins/snackbar'
|
|
|
+
|
|
|
+const emit = defineEmits(['success', 'delete'])
|
|
|
+
|
|
|
+const { t } = useI18n()
|
|
|
+const src = ref('')
|
|
|
+
|
|
|
+// 选择文件
|
|
|
+const fileInput = ref()
|
|
|
+const clicked = ref(false)
|
|
|
+const openFileInput = () => {
|
|
|
+ if (clicked.value) return
|
|
|
+ clicked.value = true
|
|
|
+ fileInput.value.click()
|
|
|
+ clicked.value = false
|
|
|
+}
|
|
|
+
|
|
|
+// 文件上传
|
|
|
+const handleUploadFile = async (e) => {
|
|
|
+ const file = e.target.files[0]
|
|
|
+ const size = file.size
|
|
|
+ if (size / (1024*1024) > 10) {
|
|
|
+ Snackbar.warning(t('common.fileSizeExceed'))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', file)
|
|
|
+ const { data } = await uploadFile(formData)
|
|
|
+ if (!data) return Snackbar.error('上传失败')
|
|
|
+ src.value = data
|
|
|
+ Snackbar.success(t('common.uploadSucMsg'))
|
|
|
+ emit('success', data)
|
|
|
+}
|
|
|
+
|
|
|
+const handleClose = () => {
|
|
|
+ src.value = ''
|
|
|
+ emit('delete')
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.upload {
|
|
|
+ width: 120px;
|
|
|
+ height: 120px;
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.close {
|
|
|
+ position: absolute;
|
|
|
+ top: -10px;
|
|
|
+ right: -10px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+</style>
|