|
@@ -0,0 +1,92 @@
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { ref, watch } from 'vue'
|
|
|
|
|
+import { Plus, Upload } from '@element-plus/icons-vue'
|
|
|
|
|
+import { ElButton, ElUpload, } from 'element-plus'
|
|
|
|
|
+import type {UploadProgressEvent, UploadFile, UploadFiles } from 'element-plus'
|
|
|
|
|
+import { toast } from 'vue-sonner'
|
|
|
|
|
+import { BASE_URL } from '@/api/index'
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const props = defineProps<{
|
|
|
|
|
+ // 外部传入的 "当前文件",可以是单个 UploadFile 对象,或 null,或 undefined
|
|
|
|
|
+ 'modelValue'?: UploadFile | null | undefined
|
|
|
|
|
+ // 添加其他 props...
|
|
|
|
|
+}>()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ // 上传成功时 emit 事件
|
|
|
|
|
+ 'success': [response: any, file: UploadFile, fileList: UploadFiles]
|
|
|
|
|
+ // 更新 v-model: 必须命名为 'update:modelValue' 以支持 v-model
|
|
|
|
|
+ 'update:modelValue': [value: UploadFile | null]
|
|
|
|
|
+}>()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const internalFileList = ref<UploadFiles>(props.modelValue ? [props.modelValue] : [])
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => props.modelValue,
|
|
|
|
|
+ (newVal) => {
|
|
|
|
|
+ // 如果父组件的 modelValue 变为 null/undefined,清空内部列表
|
|
|
|
|
+ if (!newVal) {
|
|
|
|
|
+ internalFileList.value = []
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果有新值,更新(避免重复添加)
|
|
|
|
|
+ if (internalFileList.value[0]?.uid !== newVal.uid) {
|
|
|
|
|
+ internalFileList.value = [newVal]
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+function handleUploadSuccess(response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) {
|
|
|
|
|
+ console.log('【上传成功】响应:', response)
|
|
|
|
|
+ console.log('【上传成功】文件对象:', uploadFile) // 这是最新的文件对象 (包含 url 等)
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ emit('update:modelValue', uploadFile)
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 触发成功事件
|
|
|
|
|
+ emit('success', response, uploadFile, uploadFiles)
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 8. 上传失败的回调
|
|
|
|
|
+function handleUploadError(error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) {
|
|
|
|
|
+ console.error('【上传失败】:', error, uploadFile)
|
|
|
|
|
+ emit('update:modelValue', null) // 失败时也通知父组件
|
|
|
|
|
+ toast.error('文件上传失败')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleProgress (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ console.log(evt, uploadFile, uploadFiles)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<template>
|
|
|
|
|
+ <ElUpload
|
|
|
|
|
+ v-model:file-list="internalFileList"
|
|
|
|
|
+ :action="`${BASE_URL}/anycall/import`"
|
|
|
|
|
+ :show-file-list="false"
|
|
|
|
|
+ :headers="{
|
|
|
|
|
+ 'accessToken': 'rcOBHJ0Hb8h5xgM/CWtNd8RBhA6WS4OPyJcxrxk4xPZtzeh5PtRXVDA7Um0NZA6NQmnbnZgWB0nNPb8iCrneQj4badFveWLrFq4LrySto3pIo/Zg1dJubbwmu3Vr1LCbSYyVIFrrgt9PXiA85kb9g38FSG3KTSi3AEY/UgjLNLBtH2+91YXKEy2KRZV3v75f'
|
|
|
|
|
+ }"
|
|
|
|
|
+ :limit="1"
|
|
|
|
|
+ @success="handleUploadSuccess"
|
|
|
|
|
+ @progress="handleProgress"
|
|
|
|
|
+ @error="handleUploadError"
|
|
|
|
|
+ :auto-upload="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <ElButton :loading="loading" type="primary" :icon="Upload">Import</ElButton>
|
|
|
|
|
+ </ElUpload>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<!-- 可选:添加 scoped style -->
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+/* .your-style { ... } */
|
|
|
|
|
+</style>
|