|
|
@@ -0,0 +1,88 @@
|
|
|
+<script lang="ts" setup>
|
|
|
+import { useUserStore } from '@/stores/user'
|
|
|
+import { ACCESS_TOKEN } from '@/utils/constants'
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
+import { isAbsolutePath, ossUpload } from '@/utils/utils'
|
|
|
+import config from '@/config/defaultSetting'
|
|
|
+import type { UploadProps, UploadFile } from 'element-plus'
|
|
|
+import type { BasicFormItem } from '@/types/form'
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ item: BasicFormItem
|
|
|
+ modelValue: any
|
|
|
+ fileSize?: number | string
|
|
|
+ uploadApi?: string
|
|
|
+ oss?: boolean
|
|
|
+}
|
|
|
+const props = withDefaults(defineProps<Props>(), {
|
|
|
+ uploadApi: config.uploadApi,
|
|
|
+ fileSize: 100,
|
|
|
+ oss: config.oss
|
|
|
+})
|
|
|
+const emits = defineEmits(['update:modelValue'])
|
|
|
+
|
|
|
+const modelValue = computed({
|
|
|
+ get: () => props.modelValue,
|
|
|
+ set: value => emits('update:modelValue', value)
|
|
|
+})
|
|
|
+
|
|
|
+const user = useUserStore()
|
|
|
+const baseApi = import.meta.env.VITE_BASE_API
|
|
|
+const headers = reactive({
|
|
|
+ [ACCESS_TOKEN]: user.token
|
|
|
+})
|
|
|
+
|
|
|
+// 在上传之前对文件进行验证
|
|
|
+const fileSize = Number(props.fileSize) || 100
|
|
|
+const beforeUpload: UploadProps['beforeUpload'] = rawFile => {
|
|
|
+ if (rawFile.size / 1024 / 1024 > fileSize) {
|
|
|
+ ElMessage.error(`文件大小不能超过${fileSize}MB!`)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+// 上传成功
|
|
|
+const handleUploadSuccess: UploadProps['onSuccess'] = (response, uploadFile: UploadFile) => {
|
|
|
+ if (response.success || response.code === 200) {
|
|
|
+ // 附加oss路径
|
|
|
+ modelValue.value.forEach((item: any) => {
|
|
|
+ if (item.uid === uploadFile.uid) {
|
|
|
+ item.extra = {
|
|
|
+ url: props.oss ? response.url : config.uploadSuccessCb(response),
|
|
|
+ name: uploadFile.name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ ElMessage.error(response.msg)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 接口需要的属性
|
|
|
+props.item.extra = computed(() => modelValue.value.map((item: any) => item.extra))
|
|
|
+
|
|
|
+// 动态属性
|
|
|
+const attrs: any = props.oss ? { 'http-request': ossUpload } : {}
|
|
|
+if (!props.item.props?.onSuccess) {
|
|
|
+ attrs['on-success'] = handleUploadSuccess
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="modelValue"
|
|
|
+ :action="isAbsolutePath(props.uploadApi) ? props.uploadApi : baseApi + props.uploadApi"
|
|
|
+ :headers="headers"
|
|
|
+ :before-upload="beforeUpload"
|
|
|
+ v-bind="{ ...attrs, ...$attrs }"
|
|
|
+ >
|
|
|
+ <template #[slot.name]="slotProps" v-for="slot in item.slots" :key="slot.alias">
|
|
|
+ <slot :name="slot.alias" v-bind="slotProps">
|
|
|
+ <el-button type="primary">上传</el-button>
|
|
|
+ </slot>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped></style>
|