133 lines
4.6 KiB
Vue
133 lines
4.6 KiB
Vue
<template>
|
||
<div class="attachment-upload">
|
||
<!-- 活动附件上传(消息 / 规程 / 名单 / 报名表等) -->
|
||
<div class="upload-row">
|
||
<Upload
|
||
:on-success="encloSuccess"
|
||
:on-remove="encloRemove"
|
||
:default-file-list="defaultList"
|
||
:action="uploadFileUrl"
|
||
:accept="fileType"
|
||
:multiple="isMultiple"
|
||
:before-upload="handleUpload"
|
||
:format="formatArr"
|
||
:max-size="maxSize"
|
||
:on-format-error="handleFormatError"
|
||
:on-exceeded-size="handleExceeded"
|
||
>
|
||
<Button><Icon type="ios-cloud-upload-outline"></Icon>选择文件</Button>
|
||
</Upload>
|
||
<span class="upload-tip">提示:附件大小不超过{{ maxFileSize }}</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
/*
|
||
* 活动附件上传(Vue3)。
|
||
* v-model 为已上传附件 fileid 数组;编辑时经 defaultList 回显已有附件。
|
||
*/
|
||
import { Message, Notice } from "view-ui-plus";
|
||
import config from "@/assets/config/host.config";
|
||
|
||
export default {
|
||
name: "AttachmentUpload",
|
||
props: {
|
||
defaultList: { type: Array as () => any[], default: () => [] },
|
||
fileids: { type: Array as () => number[], default: () => [] },
|
||
fileType: { type: String, default: "" },
|
||
multiple: { type: Boolean, default: false },
|
||
},
|
||
emits: ["update:fileids"],
|
||
data() {
|
||
return {
|
||
isMultiple: !this.multiple || false,
|
||
uploadFileUrl: (config.isMock ? "" : config.serviceHost) + "/api/base/FileUpload",
|
||
formatArr: ["jpg", "gif", "png", "bmp", "xls", "doc", "txt", "docx", "xlsx", "zip", "rar", "pdf", "ppt", "pptx", "wps"],
|
||
maxFileSize: "200MB",
|
||
maxSize: 204800,
|
||
};
|
||
},
|
||
methods: {
|
||
encloSuccess(resp: any, file: any) {
|
||
if (resp.code !== 0) {
|
||
Message.error(resp.msg || "上传失败");
|
||
return;
|
||
}
|
||
this.fileids.push(resp.data.fileid);
|
||
this.$emit("update:fileids", this.fileids);
|
||
},
|
||
encloRemove(file: any) {
|
||
// 删除文件:默认列表项带 fileid,刚上传的取 response
|
||
const list = file.fileid ? file : file.response;
|
||
const fileid = list?.fileid || list?.data?.fileid;
|
||
const arry = this.fileids.filter((element: number) => element != fileid);
|
||
this.$emit("update:fileids", arry);
|
||
},
|
||
handleUpload() {
|
||
if (!this.isMultiple && this.fileids.length > 0) {
|
||
Message.info("仅允许上传一个附件!");
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
handleFormatError() {
|
||
Notice.info({
|
||
title: "不支持的上传类型!",
|
||
desc: "请上传指定的文件类型",
|
||
});
|
||
},
|
||
handleExceeded() {
|
||
Notice.warning({
|
||
title: "超出大小限制",
|
||
desc: "最大文件大小为" + this.maxFileSize + "!",
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.attachment-upload {
|
||
display: block;
|
||
.upload-row {
|
||
display: flex;
|
||
/* 文件列表换行后,右侧提示文字仍与按钮首行对齐(不再整体垂直居中) */
|
||
align-items: flex-start;
|
||
flex-wrap: wrap;
|
||
}
|
||
/*
|
||
* Upload 根节点必须是 block,不能是 flex/inline-flex。
|
||
* view-ui-plus 的 Upload 内部是两个兄弟节点:
|
||
* .ivu-upload-select(「选择文件」触发器) + ul.ivu-upload-list(已上传文件列表)
|
||
* 根节点一旦是 flex,作为 flex 项的 ul 就会被排到按钮同一行的右侧,
|
||
* 附件名紧贴按钮右边(即「附件显示在按钮旁边」)。改回 block 后,
|
||
* ul 恢复块级流,自然落到按钮下方一行。
|
||
*/
|
||
:deep(.ivu-upload) {
|
||
display: block;
|
||
flex: 0 1 auto;
|
||
}
|
||
/* 只让触发器内部水平对齐,不影响它的兄弟节点 */
|
||
:deep(.ivu-upload-select) {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
}
|
||
/* 文件列表整体另起一行,每项独占一行,不再与按钮挤在一起 */
|
||
:deep(.ivu-upload-list) {
|
||
display: block;
|
||
margin-top: 8px;
|
||
}
|
||
:deep(.ivu-upload-list-file) {
|
||
padding: 4px 0;
|
||
}
|
||
.upload-tip {
|
||
margin-left: 10px;
|
||
color: #f90;
|
||
font-size: 12px;
|
||
/* 与「选择文件」按钮同高,保证首行视觉居中对齐 */
|
||
line-height: 32px;
|
||
}
|
||
}
|
||
</style>
|