Files
familyactivity-front/src/components/AttachmentUpload.vue
T
2026-09-20 18:00:18 +08:00

133 lines
4.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>