FPGA_WebLab/src/components/UploadCard.vue

106 lines
2.5 KiB
Vue

<template>
<div class="flex flex-col bg-base-100 justify-center items-center">
<!-- Title -->
<h1 class="font-bold text-2xl">上传比特流文件</h1>
<!-- Input File -->
<fieldset class="fieldset w-full">
<legend class="fieldset-legend text-sm">选择或拖拽上传文件</legend>
<input type="file" class="file-input w-full" @change="handleFileChange" />
<label class="fieldset-label">文件最大容量: {{ maxMemory }}MB</label>
</fieldset>
<!-- Upload Button -->
<div class="card-actions w-full">
<button @click="handleClick" class="btn btn-primary grow">
{{ buttonText }}
</button>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import { useDialogStore } from "@/stores/dialog";
import { isNull, isUndefined } from "lodash";
const dialog = useDialogStore();
const buttonText = computed(() => {
return isUndefined(props.downloadEvent) ? "上传" : "上传并下载";
});
var bitstream: File | null = null;
function handleFileChange(event: Event): void {
const target = event.target as HTMLInputElement;
const file = target.files?.[0]; // 获取选中的第一个文件
if (!file) {
return;
}
bitstream = file;
}
function checkFile(file: File | null): boolean {
if (isNull(file)) {
dialog.error(`未选择文件`);
return false;
}
const maxBytes = props.maxMemory! * 1024 * 1024; // 将最大容量从 MB 转换为字节
if (file.size > maxBytes) {
dialog.error(`文件大小超过最大限制: ${props.maxMemory}MB`);
return false;
}
return true;
}
async function handleClick(event: Event): Promise<void> {
if (!checkFile(bitstream)) return;
if (isUndefined(props.uploadEvent)) {
dialog.error("无法上传");
return;
}
// Upload
try {
const ret = await props.uploadEvent(event, bitstream);
if (isUndefined(props.downloadEvent)) {
if (ret) dialog.info("上传成功");
else dialog.error("上传失败");
return;
}
} catch (e) {
dialog.error("上传失败");
console.error(e);
return;
}
// Download
try {
const ret = await props.downloadEvent();
if (ret) dialog.info("下载成功");
else dialog.error("下载失败");
} catch (e) {
dialog.error("下载失败");
console.error(e);
}
}
interface Props {
uploadEvent?: Function;
downloadEvent?: Function;
maxMemory?: number;
}
const props = withDefaults(defineProps<Props>(), {
maxMemory: 4,
});
</script>
<style scoped lang="postcss">
@import "../assets/main.css";
</style>