-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Expand file tree
/
Copy pathUploadInput.vue
More file actions
123 lines (114 loc) · 3.53 KB
/
UploadInput.vue
File metadata and controls
123 lines (114 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<template>
<el-upload
style="width: 100%"
v-loading="loading"
action="#"
v-bind="$attrs"
:auto-upload="false"
:on-change="(file: any, fileList: any) => uploadFile(file, fileList)"
v-model:file-list="model_value"
multiple
>
<el-button type="primary">{{ $t('chat.uploadFile.label') }}</el-button>
<template #file="{ file, index }"
><el-card style="--el-card-padding: 0" shadow="never">
<div
:class="[inputDisabled ? 'is-disabled' : '']"
style="
padding: 0 8px 0 8px;
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
"
>
<el-tooltip class="box-item" effect="dark" :content="file.name" placement="top-start">
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 40%">
{{ file.name }}
</div></el-tooltip
>
<div>{{ formatSize(file.size) }}</div>
<el-icon @click="deleteFile(file)" style="cursor: pointer"><DeleteFilled /></el-icon>
</div>
</el-card>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { computed, inject, ref, useAttrs } from 'vue'
import { ElMessage } from 'element-plus'
import type { FormField } from '@/components/dynamics-form/type'
import { t } from '@/locales'
import { useFormDisabled } from 'element-plus'
const inputDisabled = useFormDisabled()
const attrs = useAttrs() as any
const upload = inject('upload') as any
const props = withDefaults(defineProps<{ modelValue?: any; formField: FormField }>(), {
modelValue: () => [],
})
const emit = defineEmits(['update:modelValue'])
function formatSize(sizeInBytes: number) {
const units = ['B', 'KB', 'MB', 'GB', 'TB']
let size = sizeInBytes
let unitIndex = 0
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024
unitIndex++
}
return size.toFixed(2) + ' ' + units[unitIndex]
}
const deleteFile = (file: any) => {
if (inputDisabled.value) {
return
}
fileArray.value = fileArray.value.filter((f: any) => f.uid != file.uid)
emit('update:modelValue', fileArray.value)
}
const model_value = computed({
get: () => {
if (!model_value) {
emit('update:modelValue', [])
}
return props.modelValue
},
set: (v: Array<any>) => {
emit('update:modelValue', v)
},
})
const fileArray = ref<any>([])
const loading = ref<boolean>(false)
const uploadFile = async (file: any, fileList: Array<any>) => {
fileList.splice(fileList.indexOf(file), 1)
if (fileArray.value.find((f: any) => f.name === file.name)) {
ElMessage.warning(t('chat.uploadFile.fileRepeat'))
return
}
const max_file_size = (props.formField as any).max_file_size
if (file.size / 1024 / 1024 > max_file_size) {
ElMessage.warning(t('chat.uploadFile.sizeLimit') + max_file_size + 'MB')
return
}
if (fileList.length > attrs.limit) {
ElMessage.warning(
t('chat.uploadFile.limitMessage1') + attrs.limit + t('chat.uploadFile.limitMessage2'),
)
return
}
upload(file.raw, loading).then((ok: any) => {
const split_path = ok.data.split('/')
const file_id = split_path[split_path.length - 1]
fileArray.value?.push({ name: file.name, file_id, size: file.size })
emit('update:modelValue', fileArray.value)
})
}
</script>
<style lang="scss">
.is-disabled {
background-color: var(--el-fill-color-light);
color: var(--el-text-color-placeholder);
cursor: not-allowed;
&:hover {
cursor: not-allowed;
}
}
</style>