From 60d0235013e4df2fa18a4027bff6b2b8aa10594c Mon Sep 17 00:00:00 2001
From: suixy <2277317060@qq.com>
Date: Mon, 15 Jun 2026 15:06:13 +0800
Subject: [PATCH] init
---
.gitignore | 30 ++
index.html | 12 +
package.json | 21 +
src/App.vue | 3 +
src/main.js | 17 +
src/router/index.js | 21 +
src/style.css | 243 ++++++++++++
src/view/blocked-data/index.vue | 83 ++++
src/view/config/index.vue | 108 +++++
src/view/history-data/index.vue | 91 +++++
src/view/login/index.vue | 238 +++++++++++
src/view/map/index.vue | 682 ++++++++++++++++++++++++++++++++
src/view/serve/index.vue | 0
src/view/video/index.vue | 206 ++++++++++
vite.config.js | 10 +
15 files changed, 1765 insertions(+)
create mode 100644 .gitignore
create mode 100644 index.html
create mode 100644 package.json
create mode 100644 src/App.vue
create mode 100644 src/main.js
create mode 100644 src/router/index.js
create mode 100644 src/style.css
create mode 100644 src/view/blocked-data/index.vue
create mode 100644 src/view/config/index.vue
create mode 100644 src/view/history-data/index.vue
create mode 100644 src/view/login/index.vue
create mode 100644 src/view/map/index.vue
create mode 100644 src/view/serve/index.vue
create mode 100644 src/view/video/index.vue
create mode 100644 vite.config.js
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6d59a54
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+.DS_Store
+.history
+node_modules/
+dist/
+release/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+**/*.log
+
+tests/**/coverage/
+tests/e2e/reports
+selenium-debug.log
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.local
+
+package-lock.json
+yarn.lock
+pnpm-lock.yaml
+
+# 编译生成的文件
+auto-imports.d.ts
+components.d.ts
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..9849ba8
--- /dev/null
+++ b/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ 塔架 FOD
+
+
+
+
+
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..01aca3c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "tower-fod",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite --host 0.0.0.0",
+ "build": "vite build",
+ "preview": "vite preview --host 0.0.0.0"
+ },
+ "dependencies": {
+ "@element-plus/icons-vue": "^2.3.1",
+ "element-plus": "^2.11.8",
+ "vue": "^3.5.24",
+ "vue-router": "^4.6.4"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^6.0.2",
+ "vite": "^7.2.6"
+ }
+}
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..98240ae
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..03f373a
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,17 @@
+import { createApp } from 'vue'
+import ElementPlus from 'element-plus'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+import 'element-plus/dist/index.css'
+import './style.css'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+ app.component(key, component)
+}
+
+app.use(ElementPlus)
+app.use(router)
+app.mount('#app')
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..2d7eee2
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,21 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import LoginView from '../view/login/index.vue'
+import MapView from '../view/map/index.vue'
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes: [
+ {
+ path: '/login',
+ name: 'login',
+ component: LoginView,
+ },
+ {
+ path: '/',
+ name: 'map',
+ component: MapView,
+ },
+ ],
+})
+
+export default router
diff --git a/src/style.css b/src/style.css
new file mode 100644
index 0000000..4625497
--- /dev/null
+++ b/src/style.css
@@ -0,0 +1,243 @@
+:root {
+ font-family:
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
+ sans-serif;
+ color: #eef5ff;
+ background: #030712;
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ min-width: 320px;
+ min-height: 100vh;
+ overflow: hidden;
+}
+
+#app {
+ min-height: 100vh;
+}
+
+.monitor-page {
+ position: relative;
+ width: 100vw;
+ height: 100vh;
+ overflow: hidden;
+ background:
+ radial-gradient(circle at 18% 12%, rgba(45, 212, 191, 0.18), transparent 32%),
+ linear-gradient(135deg, #020617 0%, #111827 52%, #07111f 100%);
+}
+
+.stream-video {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ background: #020617;
+}
+
+.video-backdrop {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ background:
+ linear-gradient(90deg, rgba(148, 163, 184, 0.08) 1px, transparent 1px),
+ linear-gradient(0deg, rgba(148, 163, 184, 0.08) 1px, transparent 1px);
+ background-size: 56px 56px;
+ mix-blend-mode: screen;
+}
+
+.video-backdrop::after {
+ position: absolute;
+ inset: 0;
+ content: "";
+ background: linear-gradient(180deg, rgba(2, 6, 23, 0.28), transparent 34%, rgba(2, 6, 23, 0.52));
+}
+
+.scan-line {
+ position: absolute;
+ top: -12%;
+ left: 0;
+ width: 100%;
+ height: 16%;
+ background: linear-gradient(180deg, transparent, rgba(34, 211, 238, 0.16), transparent);
+ animation: scan-move 5.8s linear infinite;
+}
+
+.signal-grid {
+ position: absolute;
+ inset: 24px;
+ border: 1px solid rgba(125, 211, 252, 0.24);
+ box-shadow: inset 0 0 44px rgba(8, 145, 178, 0.12);
+}
+
+.stream-status {
+ position: absolute;
+ left: 24px;
+ bottom: 24px;
+ z-index: 2;
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ max-width: calc(100vw - 48px);
+ min-height: 38px;
+ padding: 0 14px;
+ border: 1px solid rgba(148, 163, 184, 0.24);
+ border-radius: 8px;
+ color: #dbeafe;
+ background: rgba(2, 6, 23, 0.62);
+ backdrop-filter: blur(14px);
+}
+
+.stream-status strong {
+ overflow: hidden;
+ color: #93c5fd;
+ font-size: 12px;
+ font-weight: 600;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.status-dot {
+ width: 8px;
+ height: 8px;
+ flex: 0 0 auto;
+ border-radius: 999px;
+ background: #f59e0b;
+ box-shadow: 0 0 14px rgba(245, 158, 11, 0.85);
+}
+
+.status-dot.online {
+ background: #22c55e;
+ box-shadow: 0 0 14px rgba(34, 197, 94, 0.9);
+}
+
+.control-panel {
+ position: absolute;
+ top: 24px;
+ right: 24px;
+ z-index: 3;
+ width: 236px;
+ padding: 14px;
+ border: 1px solid rgba(186, 230, 253, 0.28);
+ border-radius: 8px;
+ background: rgba(3, 7, 18, 0.66);
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.34);
+ backdrop-filter: blur(18px);
+}
+
+.direction-pad {
+ display: grid;
+ grid-template-areas:
+ ". up ."
+ "left center right"
+ ". down .";
+ grid-template-columns: repeat(3, 48px);
+ grid-template-rows: repeat(3, 42px);
+ justify-content: center;
+ gap: 8px;
+}
+
+.control-btn,
+.zoom-btn {
+ width: 100%;
+ height: 100%;
+ margin: 0 !important;
+ border-color: rgba(147, 197, 253, 0.34);
+ border-radius: 8px;
+ color: #eff6ff;
+ background: rgba(15, 23, 42, 0.74);
+}
+
+.control-btn:hover,
+.zoom-btn:hover,
+.function-btn:hover {
+ border-color: rgba(34, 211, 238, 0.86);
+ color: #ffffff;
+ background: rgba(8, 145, 178, 0.76);
+}
+
+.control-btn.up {
+ grid-area: up;
+}
+
+.control-btn.left {
+ grid-area: left;
+}
+
+.control-btn.center {
+ grid-area: center;
+}
+
+.control-btn.right {
+ grid-area: right;
+}
+
+.control-btn.down {
+ grid-area: down;
+}
+
+.zoom-controls {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 8px;
+ height: 40px;
+ margin-top: 12px;
+}
+
+.function-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px;
+ margin-top: 12px;
+}
+
+.function-btn {
+ min-width: 0;
+ height: 36px;
+ margin: 0 !important;
+ border-color: rgba(148, 163, 184, 0.24);
+ border-radius: 8px;
+ color: #dbeafe;
+ background: rgba(15, 23, 42, 0.7);
+}
+
+@keyframes scan-move {
+ from {
+ transform: translateY(0);
+ }
+
+ to {
+ transform: translateY(760%);
+ }
+}
+
+@media (max-width: 680px) {
+ .control-panel {
+ top: 12px;
+ right: 12px;
+ width: 212px;
+ padding: 12px;
+ }
+
+ .direction-pad {
+ grid-template-columns: repeat(3, 42px);
+ grid-template-rows: repeat(3, 38px);
+ gap: 7px;
+ }
+
+ .stream-status {
+ left: 12px;
+ right: 12px;
+ bottom: 12px;
+ max-width: none;
+ }
+}
diff --git a/src/view/blocked-data/index.vue b/src/view/blocked-data/index.vue
new file mode 100644
index 0000000..2b4dbca
--- /dev/null
+++ b/src/view/blocked-data/index.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
diff --git a/src/view/config/index.vue b/src/view/config/index.vue
new file mode 100644
index 0000000..0cd77e1
--- /dev/null
+++ b/src/view/config/index.vue
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 秒
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/history-data/index.vue b/src/view/history-data/index.vue
new file mode 100644
index 0000000..9007f5d
--- /dev/null
+++ b/src/view/history-data/index.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
diff --git a/src/view/login/index.vue b/src/view/login/index.vue
new file mode 100644
index 0000000..a8e9cd5
--- /dev/null
+++ b/src/view/login/index.vue
@@ -0,0 +1,238 @@
+
+
+
+
+
AIRFIELD FOD MONITOR
+
机场道面外来物检测系统
+
道面监控、异物识别、处置闭环统一入口
+
+
+
+
+ 系统登录
+ Secure Access
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+
+
+
diff --git a/src/view/map/index.vue b/src/view/map/index.vue
new file mode 100644
index 0000000..e5dddf9
--- /dev/null
+++ b/src/view/map/index.vue
@@ -0,0 +1,682 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {{ item.label }}
+ - {{ item.value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/serve/index.vue b/src/view/serve/index.vue
new file mode 100644
index 0000000..e69de29
diff --git a/src/view/video/index.vue b/src/view/video/index.vue
new file mode 100644
index 0000000..2f6ee34
--- /dev/null
+++ b/src/view/video/index.vue
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..6db2aa6
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,10 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+export default defineConfig({
+ plugins: [vue()],
+ server: {
+ host: '0.0.0.0',
+ port: 5173,
+ },
+})