mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-23 05:40:20 +08:00
♻️ Refactoring code. 增加头像上传组件和文件上传组件
This commit is contained in:
parent
4a94568669
commit
43200a601a
114
src/components/Upload/Image.vue
Normal file
114
src/components/Upload/Image.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<!--图片上传组件-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
ref="fileUpload"
|
||||
class="avatar-uploader"
|
||||
:action="props.uploadFileUrl"
|
||||
:show-file-list="false"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
:headers="headers"
|
||||
>
|
||||
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="upload-image">
|
||||
|
||||
import {useMessage} from "/@/hooks/message";
|
||||
import {Session} from "/@/utils/storage";
|
||||
import {watch} from "vue";
|
||||
|
||||
const imageUrl = ref('')
|
||||
const fileUpload = ref()
|
||||
const emit = defineEmits(['update:value','change']);
|
||||
|
||||
const props = defineProps({
|
||||
value: [String, Array],
|
||||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
uploadFileUrl: {
|
||||
type: String,
|
||||
default: '/admin/sys-file/upload'
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => props.value,(val) => {
|
||||
if(val){
|
||||
imageUrl.value = val
|
||||
}
|
||||
},{ deep: true, immediate: true })
|
||||
|
||||
|
||||
const handleAvatarSuccess = (res, file) => {
|
||||
if(res.code === 0){
|
||||
imageUrl.value = res.data.url
|
||||
emit("change", imageUrl.value);
|
||||
emit("update:value", imageUrl.value);
|
||||
}else{
|
||||
fileUpload.value.handleRemove(file);
|
||||
}
|
||||
}
|
||||
|
||||
const beforeAvatarUpload = (rawFile: any) => {
|
||||
if (rawFile.type !== 'image/jpeg') {
|
||||
useMessage().error(`文件格式不正确, 请上传 image/jpeg 格式文件!`)
|
||||
return false
|
||||
}
|
||||
// 校检文件大小
|
||||
if (props.fileSize) {
|
||||
const isLt = rawFile.size / 1024 / 1024 < props.fileSize;
|
||||
if (!isLt) {
|
||||
useMessage().error(`上传文件大小不能超过 ${props.fileSize} MB!`)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const headers = reactive({
|
||||
Authorization: ''
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (Session.get('token')) {
|
||||
headers.Authorization = `Bearer ${Session.get('token')}`;
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.el-icon.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar{
|
||||
width: 178px;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
171
src/components/Upload/index.vue
Normal file
171
src/components/Upload/index.vue
Normal file
@ -0,0 +1,171 @@
|
||||
<!--文件上传组件-->
|
||||
<template>
|
||||
<div class="upload-file">
|
||||
<el-upload
|
||||
multiple
|
||||
:action="props.uploadFileUrl"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:file-list="fileList"
|
||||
:limit="limit"
|
||||
:on-error="handleUploadError"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-remove="handleRemove"
|
||||
:headers="headers"
|
||||
class="upload-file-uploader"
|
||||
ref="fileUpload"
|
||||
>
|
||||
<el-button type="primary">选取文件</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip" v-if="props.isShowTip">
|
||||
请上传
|
||||
<template v-if="props.fileSize"> 大小不超过 <b style="color: #f56c6c">{{ props.fileSize }}MB</b> </template>
|
||||
<template v-if="props.fileType"> 格式为 <b style="color: #f56c6c">{{ props.fileType.join("/") }}</b> </template>
|
||||
的文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="upload-file">
|
||||
import {useMessage} from "/@/hooks/message";
|
||||
import {Session} from "/@/utils/storage";
|
||||
|
||||
const props = defineProps({
|
||||
value: [String, Array],
|
||||
// 数量限制
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: {
|
||||
type: Array,
|
||||
default: () => ["doc", "xls", "ppt", "txt", "pdf","docx", "xlsx", "pptx"],
|
||||
},
|
||||
// 是否显示提示
|
||||
isShowTip: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
uploadFileUrl: {
|
||||
type: String,
|
||||
default: '/admin/sys-file/upload'
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue','change']);
|
||||
|
||||
const number = ref(0);
|
||||
const fileList = ref([]);
|
||||
const uploadList = ref([]);
|
||||
const fileUpload = ref()
|
||||
const headers = reactive({
|
||||
Authorization: ''
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
if (Session.get('token')) {
|
||||
headers.Authorization = `Bearer ${Session.get('token')}`;
|
||||
}
|
||||
})
|
||||
|
||||
// 上传前校检格式和大小
|
||||
const handleBeforeUpload = (file: File) => {
|
||||
// 校检文件类型
|
||||
if (props.fileType.length) {
|
||||
const fileName = file.name.split('.');
|
||||
const fileExt = fileName[fileName.length - 1];
|
||||
const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
|
||||
if (!isTypeOk) {
|
||||
useMessage().error(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 校检文件大小
|
||||
if (props.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||
if (!isLt) {
|
||||
useMessage().error(`上传文件大小不能超过 ${props.fileSize} MB!`)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
number.value++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 上传成功回调
|
||||
function handleUploadSuccess(res, file) {
|
||||
if (res.code === 0) {
|
||||
uploadList.value.push({ name: res.data.fileName, url: res.data.url });
|
||||
uploadedSuccessfully();
|
||||
} else {
|
||||
number.value--;
|
||||
useMessage().error(res.msg);
|
||||
fileUpload.value.handleRemove(file);
|
||||
uploadedSuccessfully();
|
||||
}
|
||||
}
|
||||
|
||||
// 上传结束处理
|
||||
const uploadedSuccessfully = () => {
|
||||
if (number.value > 0 && uploadList.value.length === number.value) {
|
||||
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
|
||||
uploadList.value = [];
|
||||
number.value = 0;
|
||||
emit("change", listToString(fileList.value));
|
||||
}
|
||||
}
|
||||
|
||||
const handleRemove = (file: any) => {
|
||||
fileList.value = fileList.value.filter(f => !(f === file.url))
|
||||
emit("change", listToString(fileList.value));
|
||||
}
|
||||
|
||||
// 对象转成指定字符串分隔
|
||||
const listToString = (list, separator = ',') => {
|
||||
let strs = "";
|
||||
separator = separator || ",";
|
||||
for (let i in list) {
|
||||
if (list[i].url) {
|
||||
strs += list[i].url + separator;
|
||||
}
|
||||
}
|
||||
return strs != '' ? strs.substr(0, strs.length - 1) : '';
|
||||
}
|
||||
|
||||
const handleUploadError = () => {
|
||||
useMessage().error("上传文件失败")
|
||||
}
|
||||
|
||||
watch(() => props.value, val => {
|
||||
if (val) {
|
||||
let temp = 1;
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.value.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map(item => {
|
||||
if (typeof item === "string") {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
item.uid = item.uid || new Date().getTime() + temp++;
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
},{ deep: true, immediate: true });
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -48,22 +48,7 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
||||
title: 'hzxc',
|
||||
isKeepAlive: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: () => import('/@/views/home/index.vue'),
|
||||
meta: {
|
||||
title: 'router.home',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: true,
|
||||
isIframe: false,
|
||||
icon: 'iconfont icon-shouye',
|
||||
},
|
||||
},
|
||||
],
|
||||
children: []
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -43,6 +43,7 @@ import {downBlobFile} from "/@/utils/other";
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
const UploadImage = defineAsyncComponent(() => import('/@/components/Upload/Image.vue'))
|
||||
const { t } = useI18n()
|
||||
// 定义查询字典
|
||||
|
||||
@ -78,6 +79,7 @@ const download = (row: any) => {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 删除操作
|
||||
const handleDelete = (row: any) => {
|
||||
if (!row) {
|
||||
|
Loading…
Reference in New Issue
Block a user