feat: uploadImg 组件

pull/2/head
xingyu4j 2022-11-29 18:00:44 +08:00
parent ba547e9e2d
commit 93dd8b7b56
5 changed files with 183 additions and 4 deletions

View File

@ -14,7 +14,7 @@ const { variables } = useDesign()
const appStore = useAppStore()
const props = defineProps({
size: propTypes.oneOf<ElementPlusSize[]>(['default', 'small', 'large']).def('default')
size: propTypes.oneOf<ElementPlusSize>(['default', 'small', 'large']).def('default')
})
provide('configGlobal', props)

View File

@ -0,0 +1,3 @@
import UploadImg from './src/UploadImg.vue'
export { UploadImg }

View File

@ -0,0 +1,169 @@
<template>
<el-upload
ref="uploadRef"
:multiple="limit > 1"
name="file"
list-type="picture-card"
v-model:file-list="fileList"
:show-file-list="true"
:action="updateUrl"
:headers="uploadHeaders"
:limit="limit"
:before-upload="beforeUpload"
:on-exceed="handleExceed"
:on-success="handleFileSuccess"
:on-error="excelUploadError"
:on-remove="handleRemove"
:on-preview="handlePictureCardPreview"
:class="{ hide: fileList.length >= limit }"
>
<Icon icon="ep:upload-filled" />
</el-upload>
<!-- 文件列表 -->
<Dialog v-model="dialogVisible" title="预览" width="800" append-to-body>
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
</Dialog>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useMessage } from '@/hooks/web/useMessage'
import { propTypes } from '@/utils/propTypes'
import { getAccessToken, getTenantId } from '@/utils/auth'
import { ElUpload, UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus'
const message = useMessage() //
const emit = defineEmits(['input'])
const props = defineProps({
imgs: propTypes.oneOfType([String, Object, Array]),
title: propTypes.string.def('图片上传'),
updateUrl: propTypes.string.def(import.meta.env.VITE_UPLOAD_URL),
fileType: propTypes.array.def(['jpg', 'png', 'gif', 'jpeg']), // , ['png', 'jpg', 'jpeg']
fileSize: propTypes.number.def(5), // (MB)
limit: propTypes.number.def(1), //
isShowTip: propTypes.bool.def(false) //
})
// ========== ==========
const uploadRef = ref<UploadInstance>()
const uploadList = ref<UploadUserFile[]>([])
const fileList = ref<UploadUserFile[]>([])
const uploadNumber = ref<number>(0)
const dialogImageUrl = ref()
const dialogVisible = ref(false)
const uploadHeaders = ref({
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
})
watch(
() => props.imgs,
(val) => {
if (val) {
// , 穿map
const list = Array.isArray(props.imgs)
? props.imgs
: Array.isArray(props.imgs?.split(','))
? props.imgs?.split(',')
: Array.of(props.imgs)
//
fileList.value = list.map((item) => {
if (typeof item === 'string') {
// edit by
item = { name: item, url: item }
}
return item
})
} else {
fileList.value = []
return []
}
},
{
deep: true,
immediate: true
}
)
//
const beforeUpload: UploadProps['beforeUpload'] = (file: UploadRawFile) => {
let fileExtension = ''
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
}
const isImg = props.fileType.some((type: string) => {
if (file.type.indexOf(type) > -1) return true
return !!(fileExtension && fileExtension.indexOf(type) > -1)
})
const isLimit = file.size < props.fileSize * 1024 * 1024
if (!isImg) {
message.error(`文件格式不正确, 请上传${props.fileType.join('/')}格式!`)
return false
}
if (!isLimit) {
message.error(`上传文件大小不能超过${props.fileSize}MB!`)
return false
}
message.success('正在上传文件,请稍候...')
uploadNumber.value++
}
//
// const handleFileChange = (uploadFile: UploadFile): void => {
// uploadRef.value.data.path = uploadFile.name
// }
//
const handleFileSuccess: UploadProps['onSuccess'] = (res: any): void => {
message.success('上传成功')
console.info(uploadList.value)
console.info(fileList.value)
uploadList.value.push({ name: res.data, url: res.data })
if (uploadList.value.length == uploadNumber.value) {
fileList.value = fileList.value.concat(uploadList.value)
uploadList.value = []
uploadNumber.value = 0
emit('input', listToString(fileList.value))
}
}
//
const handleExceed: UploadProps['onExceed'] = (): void => {
message.error(`上传文件数量不能超过${props.limit}个!`)
}
//
const excelUploadError: UploadProps['onError'] = (): void => {
message.error('导入数据失败,请您重新上传!')
}
//
const handleRemove = (file) => {
const findex = fileList.value.map((f) => f.name).indexOf(file.name)
if (findex > -1) {
fileList.value.splice(findex, 1)
emit('input', listToString(fileList.value))
}
}
//
const listToString = (list: UploadUserFile[], separator?: string) => {
let strs = ''
separator = separator || ','
for (let i in list) {
strs += list[i].url + separator
}
return strs != '' ? strs.substr(0, strs.length - 1) : ''
}
//
const handlePictureCardPreview: UploadProps['onPreview'] = (file) => {
dialogImageUrl.value = file.url
dialogVisible.value = true
}
</script>
<style scoped lang="scss">
// .el-upload--picture-card
:deep(.hide .el-upload--picture-card) {
display: none;
}
//
:deep(.el-list-enter-active, .el-list-leave-active) {
transition: all 0s;
}
:deep(.el-list-enter, .el-list-leave-active) {
opacity: 0;
transform: translateY(0);
}
</style>

View File

@ -12,7 +12,6 @@ export const rules = reactive({
clientId: [required],
secret: [required],
name: [required],
logo: [required],
status: [required],
accessTokenValiditySeconds: [required],
refreshTokenValiditySeconds: [required],

View File

@ -61,7 +61,11 @@
v-if="['create', 'update'].includes(actionType)"
:schema="allSchemas.formSchema"
:rules="rules"
/>
>
<template #logo>
<UploadImg :imgs="uploadLogo" :limit="1" />
</template>
</Form>
<!-- 表单详情 -->
<Descriptions
v-if="actionType === 'detail'"
@ -138,6 +142,7 @@ import { useMessage } from '@/hooks/web/useMessage'
import { useVxeGrid } from '@/hooks/web/useVxeGrid'
import { VxeGridInstance } from 'vxe-table'
import { FormExpose } from '@/components/Form'
import { UploadImg } from '@/components/UploadFile'
// import
import * as ClientApi from '@/api/system/oauth2/client'
import { rules, allSchemas } from './client.data'
@ -159,7 +164,7 @@ const actionType = ref('') // 操作按钮的类型
const actionLoading = ref(false) // Loading
const formRef = ref<FormExpose>() // Ref
const detailRef = ref() // Ref
const uploadLogo = ref('')
//
const setDialogTile = (type: string) => {
dialogTitle.value = t('action.' + type)
@ -169,6 +174,7 @@ const setDialogTile = (type: string) => {
//
const handleCreate = () => {
uploadLogo.value = ''
setDialogTile('create')
}
@ -177,6 +183,7 @@ const handleUpdate = async (rowId: number) => {
setDialogTile('update')
//
const res = await ClientApi.getOAuth2ClientApi(rowId)
uploadLogo.value = res.logo
unref(formRef)?.setValues(res)
}
@ -202,6 +209,7 @@ const submitForm = async () => {
//
try {
const data = unref(formRef)?.formModel as ClientApi.OAuth2ClientVO
data.logo = uploadLogo.value
if (actionType.value === 'create') {
await ClientApi.createOAuth2ClientApi(data)
message.success(t('common.createSuccess'))