add bun backend and add upload bitstream component
This commit is contained in:
		
							
								
								
									
										7
									
								
								bun.lock
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								bun.lock
									
									
									
									
									
								
							@@ -13,6 +13,7 @@
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@tailwindcss/postcss": "^4.0.12",
 | 
			
		||||
        "@tsconfig/node22": "^22.0.0",
 | 
			
		||||
        "@types/bun": "^1.2.5",
 | 
			
		||||
        "@types/node": "^22.13.4",
 | 
			
		||||
        "@vitejs/plugin-vue": "^5.2.1",
 | 
			
		||||
        "@vitejs/plugin-vue-jsx": "^4.1.1",
 | 
			
		||||
@@ -231,10 +232,14 @@
 | 
			
		||||
 | 
			
		||||
    "@tsconfig/node22": ["@tsconfig/node22@22.0.0", "", {}, "sha512-twLQ77zevtxobBOD4ToAtVmuYrpeYUh3qh+TEp+08IWhpsrIflVHqQ1F1CiPxQGL7doCdBIOOCF+1Tm833faNg=="],
 | 
			
		||||
 | 
			
		||||
    "@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="],
 | 
			
		||||
 | 
			
		||||
    "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
 | 
			
		||||
 | 
			
		||||
    "@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
 | 
			
		||||
 | 
			
		||||
    "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
 | 
			
		||||
 | 
			
		||||
    "@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.1", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ=="],
 | 
			
		||||
 | 
			
		||||
    "@vitejs/plugin-vue-jsx": ["@vitejs/plugin-vue-jsx@4.1.1", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-typescript": "^7.25.9", "@vue/babel-plugin-jsx": "^1.2.5" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.0.0" } }, "sha512-uMJqv/7u1zz/9NbWAD3XdjaY20tKTf17XVfQ9zq4wY1BjsB/PjpJPMe2xiG39QpP4ZdhYNhm4Hvo66uJrykNLA=="],
 | 
			
		||||
@@ -299,6 +304,8 @@
 | 
			
		||||
 | 
			
		||||
    "bun-plugin-tailwind": ["bun-plugin-tailwind@0.0.15", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-qtAXMNGG4R0UGGI8zWrqm2B7BdXqx48vunJXBPzfDOHPA5WkRUZdTSbE7TFwO4jLhYqSE23YMWsM9NhE6ovobw=="],
 | 
			
		||||
 | 
			
		||||
    "bun-types": ["bun-types@1.2.5", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-3oO6LVGGRRKI4kHINx5PIdIgnLRb7l/SprhzqXapmoYkFl5m4j6EvALvbDVuuBFaamB46Ap6HCUxIXNLCGy+tg=="],
 | 
			
		||||
 | 
			
		||||
    "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
 | 
			
		||||
 | 
			
		||||
    "caniuse-lite": ["caniuse-lite@1.0.30001702", "", {}, "sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA=="],
 | 
			
		||||
 
 | 
			
		||||
@@ -3,12 +3,14 @@
 | 
			
		||||
  "version": "0.0.0",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "type": "module",
 | 
			
		||||
  "main": "./server/index.ts",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "bunx --bun vite",
 | 
			
		||||
    "build": "run-p type-check \"build-only {@}\" --",
 | 
			
		||||
    "preview": "bunx --bun vite preview",
 | 
			
		||||
    "build-only": "bunx --bun vite build",
 | 
			
		||||
    "type-check": "bunx --bun vue-tsc --build"
 | 
			
		||||
    "type-check": "bunx --bun vue-tsc --build",
 | 
			
		||||
    "server": "bun run ./server/index.ts"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "log-symbols": "^7.0.0",
 | 
			
		||||
@@ -20,6 +22,7 @@
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@tailwindcss/postcss": "^4.0.12",
 | 
			
		||||
    "@tsconfig/node22": "^22.0.0",
 | 
			
		||||
    "@types/bun": "^1.2.5",
 | 
			
		||||
    "@types/node": "^22.13.4",
 | 
			
		||||
    "@vitejs/plugin-vue": "^5.2.1",
 | 
			
		||||
    "@vitejs/plugin-vue-jsx": "^4.1.1",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								server/DataBase.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								server/DataBase.ts
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										39
									
								
								server/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								server/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
import { serve } from "bun";
 | 
			
		||||
 | 
			
		||||
serve({
 | 
			
		||||
  port: 3001,
 | 
			
		||||
  // hostname: "fpga.swordlost.com",
 | 
			
		||||
  routes: {
 | 
			
		||||
    // Static routes
 | 
			
		||||
    "/api/status": new Response("OK"),
 | 
			
		||||
 | 
			
		||||
    // Dynamic routes
 | 
			
		||||
    "/users/:id": req => {
 | 
			
		||||
      return new Response(`Hello User ${req.params.id}!`);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Per-HTTP method handlers
 | 
			
		||||
    "/api/posts": {
 | 
			
		||||
      GET: () => new Response("List posts"),
 | 
			
		||||
      POST: async req => {
 | 
			
		||||
        const body = await req.json();
 | 
			
		||||
 | 
			
		||||
        if (body !== null) {
 | 
			
		||||
          return Response.json({ created: true, ...body });
 | 
			
		||||
        } else {
 | 
			
		||||
          return Response.json({})
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Wildcard route for all routes that start with "/api/" and aren't otherwise matched
 | 
			
		||||
    "/api/*": Response.json({ message: "Not found" }, { status: 404 }),
 | 
			
		||||
 | 
			
		||||
    // Serve a file by buffering it in memory
 | 
			
		||||
    // "/favicon.ico": new Response(await Bun.file("../public/favicon.icon").bytes(), {
 | 
			
		||||
    //   headers: {
 | 
			
		||||
    //     "Content-Type": "image/x-icon",
 | 
			
		||||
    //   },
 | 
			
		||||
    // }),
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
@@ -1,8 +1,15 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div :class="themeSidebar">
 | 
			
		||||
    <div class="card-body flex">
 | 
			
		||||
  <div :class="[
 | 
			
		||||
    'card-dash',
 | 
			
		||||
    'sidebar-base',
 | 
			
		||||
    'transition-all',
 | 
			
		||||
    'duration-500',
 | 
			
		||||
    'ease-in-out',
 | 
			
		||||
    isClose ? 'sidebar-close' : 'sidebar-open',
 | 
			
		||||
  ]">
 | 
			
		||||
    <div class="card-body flex transition-all duration-500 ease-in-out">
 | 
			
		||||
      <!-- Avatar and Name -->
 | 
			
		||||
      <div class="flex items-center">
 | 
			
		||||
      <div :class="['flex', 'items-center', isClose ? 'flex-col' : '']">
 | 
			
		||||
        <!-- Img -->
 | 
			
		||||
        <div class="avatar h-10">
 | 
			
		||||
          <div class="rounded-full">
 | 
			
		||||
@@ -15,7 +22,7 @@
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <!-- Toggle Button -->
 | 
			
		||||
        <button class="btn btn-square rounded-lg p-2" @click="toggleSidebar">
 | 
			
		||||
        <button class="btn btn-square rounded-lg p-2 m-3" @click="toggleSidebar">
 | 
			
		||||
          <img src="../assets/left.svg" alt="Menu Button" class="opacity-50">
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
@@ -51,7 +58,7 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import iconMenu from "../assets/menu.svg"
 | 
			
		||||
import { useThemeStore } from "@/stores/theme";
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { computed, ref } from "vue";
 | 
			
		||||
import ThemeControlButton from "./ThemeControlButton.vue";
 | 
			
		||||
import ThemeControlToggle from "./ThemeControlToggle.vue";
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +72,16 @@ const items = [
 | 
			
		||||
  { id: 4, icon: iconMenu, msg: "btn4" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const themeSidebar = ref("card-dash sidebar-base sidebar-open")
 | 
			
		||||
const themeSidebar = computed(() => {
 | 
			
		||||
  return [
 | 
			
		||||
    "card-dash",
 | 
			
		||||
    "sidebar-base",
 | 
			
		||||
    "transition",
 | 
			
		||||
    "duration-300",
 | 
			
		||||
    "ease-in-out",
 | 
			
		||||
    isClose.value ? "sidebar-close" : "sidebar-open",
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function closeSidebar() {
 | 
			
		||||
  isClose.value = true;
 | 
			
		||||
@@ -80,11 +96,11 @@ function openSidebar() {
 | 
			
		||||
function toggleSidebar() {
 | 
			
		||||
  if (isClose.value) {
 | 
			
		||||
    openSidebar()
 | 
			
		||||
    themeSidebar.value = "card-dash sidebar-base sidebar-open"
 | 
			
		||||
    // themeSidebar.value = "card-dash sidebar-base sidebar-open"
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    closeSidebar()
 | 
			
		||||
    themeSidebar.value = "card-dash sidebar-base sidebar-close"
 | 
			
		||||
    // themeSidebar.value = "card-dash sidebar-base sidebar-close"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								src/components/UploadCard.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/components/UploadCard.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="card card-dash shadow-xl w-90 h-60">
 | 
			
		||||
    <div class="card-body flex">
 | 
			
		||||
 | 
			
		||||
      <!-- Title -->
 | 
			
		||||
      <h1 class="card-title place-self-center 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" @change="handleFileChange" />
 | 
			
		||||
        <label class="fieldset-label">Max size 2MB</label>
 | 
			
		||||
      </fieldset>
 | 
			
		||||
 | 
			
		||||
      <!-- Upload Button -->
 | 
			
		||||
      <div class="card-actions">
 | 
			
		||||
        <button @click="uploadBitStream" class="btn btn-primary grow">上传</button>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
var bitstream = null;
 | 
			
		||||
 | 
			
		||||
function handleFileChange(event: Event): void {
 | 
			
		||||
  const target = event.target as HTMLInputElement;
 | 
			
		||||
  const file = target.files?.[0]; // 获取选中的第一个文件
 | 
			
		||||
 | 
			
		||||
  if (!file) {
 | 
			
		||||
    console.error('未选择文件');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bitstream = file;
 | 
			
		||||
 | 
			
		||||
  console.log(bitstream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function uploadBitStream() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkFileType(file: File) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="postcss">
 | 
			
		||||
@import "../assets/main.css";
 | 
			
		||||
</style>
 | 
			
		||||
@@ -8,3 +8,5 @@ import router from './router'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const app = createApp(App).use(router).use(createPinia()).mount('#app')
 | 
			
		||||
 | 
			
		||||
console.log()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
import { createMemoryHistory, createRouter } from 'vue-router'
 | 
			
		||||
import LoginView from "@/views/LoginView.vue"
 | 
			
		||||
import UserView from '@/views/UserView.vue'
 | 
			
		||||
import TestSVG from '@/views/TestSVG.vue'
 | 
			
		||||
import TestView from '@/views/TestView.vue'
 | 
			
		||||
 | 
			
		||||
const routes = [
 | 
			
		||||
  { path: "/", redirect: "/user" },
 | 
			
		||||
  { path: "/login", name: "Login", component: LoginView },
 | 
			
		||||
  { path: "/user", name: "User", component: UserView },
 | 
			
		||||
  { path: "/test", name: "Test", component: TestSVG },
 | 
			
		||||
  { path: "/test", name: "Test", component: TestView },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const router = createRouter({
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,18 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <main>
 | 
			
		||||
    <div class="w-full h-full">
 | 
			
		||||
  <header>
 | 
			
		||||
  </header>
 | 
			
		||||
  <main class="relative">
 | 
			
		||||
    <div class="fixed left-0 top-0 z-50">
 | 
			
		||||
      <Sidebar />
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="w-screen h-screen flex items-center justify-center">
 | 
			
		||||
      <UploadCard />
 | 
			
		||||
    </div>
 | 
			
		||||
  </main>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import UploadCard from '@/components/UploadCard.vue';
 | 
			
		||||
import Sidebar from '../components/Sidebar.vue'
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,19 @@
 | 
			
		||||
{
 | 
			
		||||
  "extends": "@vue/tsconfig/tsconfig.dom.json",
 | 
			
		||||
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
 | 
			
		||||
  "exclude": ["src/**/__tests__/*"],
 | 
			
		||||
  "include": [
 | 
			
		||||
    "env.d.ts",
 | 
			
		||||
    "src/**/*",
 | 
			
		||||
    "src/**/*.vue"
 | 
			
		||||
  ],
 | 
			
		||||
  "exclude": [
 | 
			
		||||
    "src/**/__tests__/*"
 | 
			
		||||
  ],
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
 | 
			
		||||
 | 
			
		||||
    "paths": {
 | 
			
		||||
      "@/*": ["./src/*"]
 | 
			
		||||
      "@/*": [
 | 
			
		||||
        "./src/*"
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								tsconfig.bun.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								tsconfig.bun.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    // Enable latest features
 | 
			
		||||
    "lib": [
 | 
			
		||||
      "ESNext"
 | 
			
		||||
    ],
 | 
			
		||||
    "target": "ESNext",
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "moduleDetection": "force",
 | 
			
		||||
    "jsx": "react-jsx",
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
    // Bundler mode
 | 
			
		||||
    "moduleResolution": "bundler",
 | 
			
		||||
    "allowImportingTsExtensions": true,
 | 
			
		||||
    "verbatimModuleSyntax": true,
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
    // Best practices
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
    "noFallthroughCasesInSwitch": true,
 | 
			
		||||
    // Some stricter flags
 | 
			
		||||
    "noUnusedLocals": true,
 | 
			
		||||
    "noUnusedParameters": true,
 | 
			
		||||
    "noPropertyAccessFromIndexSignature": true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,6 +6,9 @@
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "path": "./tsconfig.app.json"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "path": "./tsconfig.bun.json"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user