Merge branch 'master' of ssh://git.swordlost.top:222/SikongJueluo/FPGA_WebLab

This commit is contained in:
alivender
2025-08-01 20:00:00 +08:00
20 changed files with 947 additions and 520 deletions

View File

@@ -1,11 +0,0 @@
<template>
<button class="btn transition-transform duration-150 ease-in-out hover:scale-120">
Button A
</button>
</template>
<script lang="ts" setup></script>
<style scoped lang="postcss">
@import "@/assets/main.css";
</style>

View File

@@ -1,162 +0,0 @@
<template>
<div
class="card card-dash shadow-xl h-screen"
:class="[sidebar.isClose ? 'w-31' : 'w-80']"
>
<div
class="card-body flex relative transition-all duration-500 ease-in-out"
>
<!-- Avatar and Name -->
<div class="relative" :class="sidebar.isClose ? 'h-50' : 'h-20'">
<!-- Img -->
<div
class="avatar h-10 fixed top-10"
:class="sidebar.isClose ? 'left-10' : 'left-7'"
>
<div class="rounded-full">
<img src="../assets/user.svg" alt="User" />
</div>
</div>
<!-- Text -->
<Transition>
<div v-if="!sidebar.isClose" class="mx-5 grow fixed left-20 top-11">
<label class="text-2xl">用户名</label>
</div>
</Transition>
</div>
<!-- Toggle Button -->
<button
class="btn btn-square rounded-lg p-2 m-3 fixed"
:class="sidebar.isClose ? 'left-7 top-23' : 'left-60 top-7'"
@click="sidebar.toggleSidebar"
>
<svg
t="1741694970690"
:class="sidebar.isClose ? 'rotate-0' : 'rotate-540'"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4546"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200"
height="200"
>
<path
d="M803.758 514.017c-0.001-0.311-0.013-0.622-0.018-0.933-0.162-23.974-9.386-47.811-27.743-65.903-0.084-0.082-0.172-0.157-0.256-0.239-0.154-0.154-0.296-0.315-0.451-0.468L417.861 94.096c-37.685-37.153-99.034-37.476-136.331-0.718-37.297 36.758-36.979 97.231 0.707 134.384l290.361 286.257-290.362 286.257c-37.685 37.153-38.004 97.625-0.707 134.383 37.297 36.758 98.646 36.435 136.331-0.718l357.43-352.378c0.155-0.153 0.297-0.314 0.451-0.468 0.084-0.082 0.172-0.157 0.256-0.239 18.354-18.089 27.578-41.922 27.743-65.892 0.004-0.315 0.017-0.631 0.018-0.947z"
:fill="theme.isLightTheme() ? '#828282' : '#C0C3C8'"
p-id="4547"
></path>
</svg>
</button>
<div class="divider"></div>
<ul class="menu h-full w-full">
<li v-for="item in props.items" class="text-xl my-1">
<a @click="router.push(item.page)">
<svg
t="1741694797806"
class="icon h-[1.5em] w-[1.5em] opacity-50 mx-1"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2622"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200"
height="200"
>
<path
d="M192 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z"
p-id="2623"
></path>
<path
d="M192 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z"
p-id="2624"
></path>
<path
d="M192 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z"
p-id="2625"
></path>
<path
d="M864 160H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32zM864 480H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32zM864 800H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32z"
p-id="2626"
></path>
</svg>
<Transition>
<p class="break-keep" v-if="!sidebar.isClose">{{ item.text }}</p>
</Transition>
</a>
</li>
</ul>
<div class="divider"></div>
<ul class="menu w-full">
<li>
<a @click="theme.toggleTheme" class="text-xl">
<ThemeControlButton />
<Transition>
<p v-if="!sidebar.isClose" class="break-keep">改变主题</p>
</Transition>
<Transition>
<ThemeControlToggle v-if="!sidebar.isClose" />
</Transition>
</a>
</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import iconMenu from "../assets/menu.svg";
import "../router";
import { useThemeStore } from "@/stores/theme";
import { useSidebarStore } from "@/stores/sidebar";
import ThemeControlButton from "./ThemeControlButton.vue";
import ThemeControlToggle from "./ThemeControlToggle.vue";
import router from "../router";
const theme = useThemeStore();
const sidebar = useSidebarStore();
type Item = {
id: number;
icon: string;
text: string;
page: string;
};
interface Props {
items?: Array<Item>;
}
const props = withDefaults(defineProps<Props>(), {
items: () => [
{ id: 1, icon: iconMenu, text: "btn1", page: "/" },
{ id: 2, icon: iconMenu, text: "btn2", page: "/" },
{ id: 3, icon: iconMenu, text: "btn3", page: "/" },
{ id: 4, icon: iconMenu, text: "btn4", page: "/" },
],
});
</script>
<style scoped lang="postcss">
@reference "../assets/main.css";
* {
@apply transition-all duration-500 ease-in-out;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.3s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>

View File

@@ -8,21 +8,35 @@
<p>
IDCode: 0x{{ jtagIDCode.toString(16).padStart(8, "0").toUpperCase() }}
</p>
<button class="btn btn-circle w-6 h-6" :disabled="isGettingIDCode" :onclick="getIDCode">
<RefreshCcwIcon class="icon" :class="{ 'animate-spin': isGettingIDCode }" />
<button
class="btn btn-circle w-6 h-6"
:disabled="isGettingIDCode"
:onclick="getIDCode"
>
<RefreshCcwIcon
class="icon"
:class="{ 'animate-spin': isGettingIDCode }"
/>
</button>
</div>
</div>
<div class="divider"></div>
<UploadCard class="bg-base-200" :upload-event="eqps.jtagUploadBitstream"
:download-event="eqps.jtagDownloadBitstream" :bitstream-file="eqps.jtagBitstream"
:exam-id="examId"
@update:bitstream-file="handleBitstreamChange">
<UploadCard
class="bg-base-200"
:upload-event="eqps.jtagUploadBitstream"
:download-event="eqps.jtagDownloadBitstream"
:bitstream-file="eqps.jtagBitstream"
@update:bitstream-file="handleBitstreamChange"
>
</UploadCard>
<div class="divider"></div>
<div class="w-full">
<legend class="fieldset-legend text-sm mb-0.3">Jtag运行频率</legend>
<select class="select w-full" @change="handleSelectJtagSpeed" :value="props.jtagFreq">
<select
class="select w-full"
@change="handleSelectJtagSpeed"
:value="props.jtagFreq"
>
<option v-for="option in selectJtagSpeedOptions" :value="option.id">
{{ option.text }}
</option>
@@ -31,12 +45,23 @@
<div class="flex flex-row items-center">
<fieldset class="fieldset w-70">
<legend class="fieldset-legend text-sm">边界扫描刷新率 / Hz</legend>
<input type="number" class="input validator" required placeholder="Type a number between 1 to 1000" min="1"
max="1000" v-model="jtagBoundaryScanFreq" title="Type a number between 1 to 1000" />
<input
type="number"
class="input validator"
required
placeholder="Type a number between 1 to 1000"
min="1"
max="1000"
v-model="jtagBoundaryScanFreq"
title="Type a number between 1 to 1000"
/>
<p class="validator-hint">输入一个1 ~ 1000的数</p>
</fieldset>
<button class="btn btn-primary grow mx-4" :class="eqps.enableJtagBoundaryScan ? '' : 'btn-soft'"
:onclick="toggleJtagBoundaryScan">
<button
class="btn btn-primary grow mx-4"
:class="eqps.enableJtagBoundaryScan ? '' : 'btn-soft'"
:onclick="toggleJtagBoundaryScan"
>
{{ eqps.enableJtagBoundaryScan ? "关闭边界扫描" : "启动边界扫描" }}
</button>
</div>
@@ -44,8 +69,12 @@
<h1 class="font-bold text-center text-2xl">外设</h1>
<div class="flex flex-row justify-center">
<div class="flex flex-row">
<input type="checkbox" class="checkbox" :checked="eqps.enableMatrixKey"
@change="handleMatrixkeyCheckboxChange" />
<input
type="checkbox"
class="checkbox"
:checked="eqps.enableMatrixKey"
@change="handleMatrixkeyCheckboxChange"
/>
<p class="mx-2">启用矩阵键盘</p>
</div>
</div>
@@ -119,7 +148,7 @@ async function handleMatrixkeyCheckboxChange(event: Event) {
}
async function toggleJtagBoundaryScan() {
eqps.enableJtagBoundaryScan = !eqps.enableJtagBoundaryScan;
eqps.jtagBoundaryScanSetOnOff(!eqps.enableJtagBoundaryScan);
}
const isGettingIDCode = ref(false);