feat: 提交家校活动前端工程源码(Vue3 + Vite + view-ui-plus)
build / build (push) Successful in 5m24s

This commit is contained in:
lijing
2026-09-20 18:00:18 +08:00
parent 267ba04af2
commit 66ad7fc6c3
333 changed files with 33141 additions and 2 deletions
+132
View File
@@ -0,0 +1,132 @@
<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>