first push

main
donghao 2 months ago
parent 8870548ca0
commit 05b35e1046

@ -0,0 +1,74 @@
{
"globals": {
"Component": true,
"ComponentPublicInstance": true,
"ComputedRef": true,
"EffectScope": true,
"ExtractDefaultPropTypes": true,
"ExtractPropTypes": true,
"ExtractPublicPropTypes": true,
"InjectionKey": true,
"PropType": true,
"Ref": true,
"VNode": true,
"WritableComputedRef": true,
"computed": true,
"createApp": true,
"customRef": true,
"defineAsyncComponent": true,
"defineComponent": true,
"effectScope": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"inject": true,
"isProxy": true,
"isReactive": true,
"isReadonly": true,
"isRef": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onUnmounted": true,
"onUpdated": true,
"provide": true,
"reactive": true,
"readonly": true,
"ref": true,
"resolveComponent": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"toRaw": true,
"toRef": true,
"toRefs": true,
"toValue": true,
"triggerRef": true,
"unref": true,
"useAttrs": true,
"useCssModule": true,
"useCssVars": true,
"useSlots": true,
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true,
"DirectiveBinding": true,
"MaybeRef": true,
"MaybeRefOrGetter": true,
"onWatcherCleanup": true,
"useId": true,
"useModel": true,
"useTemplateRef": true
}
}

24
.gitignore vendored

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

71
auto-imports.d.ts vendored

@ -0,0 +1,71 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useModel: typeof import('vue')['useModel']
const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}

@ -0,0 +1,3 @@
VITE_PORT=5050
VITE_API_BASE=/api
VITE_MOCK_ENABLED=true

@ -0,0 +1,10 @@
###
# @Author: donghao donghao@supervision.ltd
# @Date: 2025-03-06 11:36:56
# @LastEditors: donghao donghao@supervision.ltd
# @LastEditTime: 2025-03-06 11:37:31
# @FilePath: \vite-ai\data-dashboard\env\.env.production
# @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
###
VITE_API_BASE=http://test-api.example.com
VITE_MOCK_ENABLED=false

10
env/.env.test vendored

@ -0,0 +1,10 @@
###
# @Author: donghao donghao@supervision.ltd
# @Date: 2025-03-06 11:36:48
# @LastEditors: donghao donghao@supervision.ltd
# @LastEditTime: 2025-03-06 11:37:50
# @FilePath: \vite-ai\data-dashboard\env\.env.test
# @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
###
VITE_API_BASE=http://api.example.com
VITE_MOCK_ENABLED=false

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

@ -0,0 +1,28 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 11:37:14
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 11:38:11
* @FilePath: \vite-ai\data-dashboard\mock\user.ts
* @Description:
*/
export default [
{
url: '/api/login',
method: 'post',
response: ({ body }) => {
if (body.username === 'admin' && body.password === 'admin123') {
return {
code: 200,
data: {
token: 'MOCK_TOKEN_' + Date.now()
}
}
}
return {
code: 401,
message: '用户名或密码错误'
}
}
}
]

4583
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,38 @@
{
"name": "data-dashboard",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "cross-env NODE_ENV=development vite",
"test": "cross-env NODE_ENV=test vite build",
"build": "cross-env NODE_ENV=production vite build",
"preview": "vite preview --port 5050"
},
"dependencies": {
"echarts": "^5.6.0",
"postcss-scss": "^4.0.9",
"sass": "^1.85.1",
"unplugin-auto-import": "^19.1.1",
"vue": "^3.5.13"
},
"devDependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/postcss": "^4.0.10",
"@types/echarts": "^5.0.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/tsconfig": "^0.7.0",
"autoprefixer": "^10.4.20",
"cross-env": "^7.0.3",
"element-plus": "^2.9.5",
"pinia": "^3.0.1",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "~5.7.2",
"vite": "^6.2.0",
"vite-plugin-mock": "^3.0.2",
"vue-router": "^4.5.0",
"vue-tsc": "^2.2.4"
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,16 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 16:22:19
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:07:24
* @FilePath: \vite-ai\data-dashboard\postcss.config.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import autoprefixer from 'autoprefixer';
import tailwindcss from 'tailwindcss';
export default {
plugins: [
tailwindcss(),
autoprefixer()
]
};

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,145 @@
<template>
<!-- 全局容器 -->
<div class="app-container">
<!-- 路由视图容器 -->
<router-view v-slot="{ Component, route }">
<!-- 智能缓存仅缓存带有 meta.keepAlive 的路由 -->
<keep-alive :include="cachedRoutes">
<component
:is="Component"
:key="route.fullPath"
class="router-view-container"
:class="{ 'has-header': showHeader }"
/>
</keep-alive>
</router-view>
<!-- 大屏适配容器用于缩放内容 -->
<div
v-if="isDashboardPage"
ref="scaleContainer"
class="scale-container"
:style="scaleStyle"
>
<!-- 实际内容会被挂载到这里 -->
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref, onMounted, onUnmounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const scaleContainer = ref<HTMLElement>()
const scaleValue = ref(1)
//
const cachedRoutes = ref<string[]>([])
//
const showHeader = computed(() => route.meta.showHeader ?? true)
//
const isDashboardPage = computed(() => route.meta.isDashboard ?? false)
//
const scaleStyle = computed(() => ({
transform: `scale(${scaleValue.value}) translate(-50%, -50%)`,
width: `${(1 / scaleValue.value) * 100}%`,
height: `${(1 / scaleValue.value) * 100}%`
}))
//
const calculateScale = () => {
if (!isDashboardPage.value || !scaleContainer.value) return
const baseWidth = 1920 // 稿
const baseHeight = 1080 // 稿
const currentWidth = window.innerWidth
const currentHeight = window.innerHeight
//
const widthRatio = currentWidth / baseWidth
const heightRatio = currentHeight / baseHeight
scaleValue.value = Math.min(widthRatio, heightRatio)
}
//
watch(
() => route.path,
(newVal) => {
//
if (route.meta.keepAlive && route.name) {
cachedRoutes.value = [...new Set([...cachedRoutes.value, route.name as string])]
}
//
if (isDashboardPage.value) {
nextTick(() => {
//
const view = document.querySelector('.router-view-container')
if (view && scaleContainer.value) {
scaleContainer.value.appendChild(view)
}
calculateScale()
})
}
}
)
// resize
let resizeTimer: number
const onResize = () => {
clearTimeout(resizeTimer)
resizeTimer = setTimeout(calculateScale, 300)
}
onMounted(() => {
window.addEventListener('resize', onResize)
calculateScale()
})
onUnmounted(() => {
window.removeEventListener('resize', onResize)
})
</script>
<style lang="scss">
/* 全局样式重置 */
html, body, #app {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden; /* 禁用全局滚动条 */
}
.app-container {
position: relative;
width: 100%;
height: 100%;
/* 路由视图基础样式 */
.router-view-container {
width: 100%;
height: 100%;
}
/* 大屏适配容器样式 */
.scale-container {
position: fixed;
top: 50%;
left: 50%;
transform-origin: 0 0;
transition: transform 0.3s;
/* 大屏页面特殊处理 */
.router-view-container {
background: #030409; /* 深色背景 */
color: #fff;
}
}
}
</style>

@ -0,0 +1,33 @@
<svg width="1859" height="767" viewBox="0 0 1859 767" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_iii_9388_53122)">
<path d="M2 749.13V3H1842.77L1858 21.6778V749.13L1844.24 766H15.76L2 749.13Z" fill="#00183E" fill-opacity="0.9"/>
</g>
<path d="M2 749.13V3H1842.77L1858 21.6778V749.13L1844.24 766H15.76L2 749.13Z" stroke="#20A0FD" stroke-opacity="0.4" stroke-width="1.5"/>
<path d="M1833 12.88L1835.88 10L1845 19.12L1842.12 22L1833 12.88Z" fill="white"/>
<path d="M1804 3H1842.86L1858 20.6882V50" stroke="#2ABAF0" stroke-width="2"/>
<path d="M2 37V2H74" stroke="#2CCAFF" stroke-width="3"/>
<defs>
<filter id="filter0_iii_9388_53122" x="1.25" y="-1.75" width="1857.5" height="772.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_9388_53122"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect1_innerShadow_9388_53122" result="effect2_innerShadow_9388_53122"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect2_innerShadow_9388_53122" result="effect3_innerShadow_9388_53122"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 448 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 483 KiB

@ -0,0 +1,30 @@
<svg width="430" height="50" viewBox="0 0 430 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8677_100865)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H448.786V50H0V0Z" fill="url(#paint0_linear_8677_100865)"/>
<line y1="49.5" x2="8" y2="49.5" stroke="#3656C8"/>
<line x1="10" y1="49.5" x2="18" y2="49.5" stroke="#3656C8" stroke-opacity="0.6"/>
<line x1="20" y1="49.5" x2="28" y2="49.5" stroke="#3656C8" stroke-opacity="0.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H448.786V2H0V0Z" fill="url(#paint1_linear_8677_100865)"/>
<rect y="17" width="2" height="16" fill="#3656C8"/>
</g>
<path opacity="0.3" d="M402.464 49.0007H34L34.7086 50C35.042 49.9963 402.909 49.9364 402.874 49.9963L406 46.0029C406 45.9993 405.479 45 405.479 45L402.464 49.0007Z" fill="#3656C8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M202.476 49H227.524V50H202.476V49Z" fill="url(#paint2_linear_8677_100865)"/>
<defs>
<linearGradient id="paint0_linear_8677_100865" x1="0" y1="33.7505" x2="448.786" y2="33.7505" gradientUnits="userSpaceOnUse">
<stop stop-color="#3252C6" stop-opacity="0"/>
<stop stop-color="#3252C6" stop-opacity="0.4"/>
<stop offset="1" stop-color="#3252C6" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_8677_100865" x1="-2.08574e-06" y1="1.00164" x2="448.786" y2="1.00164" gradientUnits="userSpaceOnUse">
<stop stop-color="#3656C8"/>
<stop offset="1" stop-color="#2994FC" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_8677_100865" x1="215" y1="49" x2="215" y2="50" gradientUnits="userSpaceOnUse">
<stop stop-color="#FEF643"/>
<stop offset="1" stop-color="#FFA217"/>
</linearGradient>
<clipPath id="clip0_8677_100865">
<rect width="430" height="50" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

@ -0,0 +1,64 @@
<svg width="433" height="605" viewBox="0 0 433 605" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_iii_8677_100884)">
<path d="M2 587.13V2H416.766L432 20.6778V587.13L418.24 604H15.76L2 587.13Z" fill="#00183E" fill-opacity="0.9"/>
</g>
<path d="M2 587.13V2H416.766L432 20.6778V587.13L418.24 604H15.76L2 587.13Z" stroke="#20A0FD" stroke-opacity="0.4" stroke-width="1.5"/>
<path d="M413 27.88L415.88 25L425 34.12L422.12 37L413 27.88Z" fill="white"/>
<path d="M378 2H416.86L432 19.6882V49" stroke="#2ABAF0" stroke-width="2"/>
<g clip-path="url(#clip0_8677_100884)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 0H451.786V50H3V0Z" fill="url(#paint0_linear_8677_100884)"/>
<line x1="3" y1="49.5" x2="11" y2="49.5" stroke="#3656C8"/>
<line x1="13" y1="49.5" x2="21" y2="49.5" stroke="#3656C8" stroke-opacity="0.6"/>
<line x1="23" y1="49.5" x2="31" y2="49.5" stroke="#3656C8" stroke-opacity="0.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 0H451.786V2H3V0Z" fill="url(#paint1_linear_8677_100884)"/>
<rect x="3" y="17" width="2" height="16" fill="#3656C8"/>
</g>
<path opacity="0.3" d="M405.464 49.0007H37L37.7086 50C38.042 49.9963 405.909 49.9364 405.874 49.9963L409 46.0029C409 45.9993 408.479 45 408.479 45L405.464 49.0007Z" fill="#3656C8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M205.476 49H230.524V50H205.476V49Z" fill="url(#paint2_linear_8677_100884)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M405.528 47H421.554L418.027 50H402L405.528 47Z" fill="url(#paint3_linear_8677_100884)"/>
<path d="M2 37V2H74" stroke="#2CCAFF" stroke-width="3"/>
<defs>
<filter id="filter0_iii_8677_100884" x="1.25" y="-2.75" width="431.5" height="611.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_8677_100884"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect1_innerShadow_8677_100884" result="effect2_innerShadow_8677_100884"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect2_innerShadow_8677_100884" result="effect3_innerShadow_8677_100884"/>
</filter>
<linearGradient id="paint0_linear_8677_100884" x1="3" y1="33.7505" x2="451.786" y2="33.7505" gradientUnits="userSpaceOnUse">
<stop stop-color="#3252C6" stop-opacity="0"/>
<stop stop-color="#3252C6" stop-opacity="0.4"/>
<stop offset="1" stop-color="#3252C6" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_8677_100884" x1="3" y1="1.00164" x2="451.786" y2="1.00164" gradientUnits="userSpaceOnUse">
<stop stop-color="#3656C8"/>
<stop offset="1" stop-color="#2994FC" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_8677_100884" x1="218" y1="49" x2="218" y2="50" gradientUnits="userSpaceOnUse">
<stop stop-color="#FEF643"/>
<stop offset="1" stop-color="#FFA217"/>
</linearGradient>
<linearGradient id="paint3_linear_8677_100884" x1="411.777" y1="47" x2="411.777" y2="50" gradientUnits="userSpaceOnUse">
<stop stop-color="#FEF643"/>
<stop offset="1" stop-color="#FFA217"/>
</linearGradient>
<clipPath id="clip0_8677_100884">
<rect width="430" height="50" fill="white" transform="translate(3)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,64 @@
<svg width="433" height="292" viewBox="0 0 433 292" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_iii_8677_100860)">
<path d="M2 274.13V3H416.766L432 21.6778V274.13L418.24 291H15.76L2 274.13Z" fill="#00183E" fill-opacity="0.9"/>
</g>
<path d="M2 274.13V3H416.766L432 21.6778V274.13L418.24 291H15.76L2 274.13Z" stroke="#20A0FD" stroke-opacity="0.4" stroke-width="1.5"/>
<path d="M413 12.88L415.88 10L425 19.12L422.12 22L413 12.88Z" fill="white"/>
<path d="M378 3H416.86L432 20.6882V50" stroke="#2ABAF0" stroke-width="2"/>
<g clip-path="url(#clip0_8677_100860)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 1H451.786V51H3V1Z" fill="url(#paint0_linear_8677_100860)"/>
<line x1="3" y1="50.5" x2="11" y2="50.5" stroke="#3656C8"/>
<line x1="13" y1="50.5" x2="21" y2="50.5" stroke="#3656C8" stroke-opacity="0.6"/>
<line x1="23" y1="50.5" x2="31" y2="50.5" stroke="#3656C8" stroke-opacity="0.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 1H451.786V3H3V1Z" fill="url(#paint1_linear_8677_100860)"/>
<rect x="3" y="18" width="2" height="16" fill="#3656C8"/>
</g>
<path opacity="0.3" d="M405.464 50.0007H37L37.7086 51C38.042 50.9963 405.909 50.9364 405.874 50.9963L409 47.0029C409 46.9993 408.479 46 408.479 46L405.464 50.0007Z" fill="#3656C8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M205.476 50H230.524V51H205.476V50Z" fill="url(#paint2_linear_8677_100860)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M405.528 48H421.554L418.027 51H402L405.528 48Z" fill="url(#paint3_linear_8677_100860)"/>
<path d="M2 37V2H74" stroke="#2CCAFF" stroke-width="3"/>
<defs>
<filter id="filter0_iii_8677_100860" x="1.25" y="-1.75" width="431.5" height="297.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_8677_100860"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect1_innerShadow_8677_100860" result="effect2_innerShadow_8677_100860"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="4"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.109804 0 0 0 0 0.498039 0 0 0 0 0.94902 0 0 0 0.6 0"/>
<feBlend mode="normal" in2="effect2_innerShadow_8677_100860" result="effect3_innerShadow_8677_100860"/>
</filter>
<linearGradient id="paint0_linear_8677_100860" x1="3" y1="34.7505" x2="451.786" y2="34.7505" gradientUnits="userSpaceOnUse">
<stop stop-color="#3252C6" stop-opacity="0"/>
<stop stop-color="#3252C6" stop-opacity="0.4"/>
<stop offset="1" stop-color="#3252C6" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_8677_100860" x1="3" y1="2.00164" x2="451.786" y2="2.00164" gradientUnits="userSpaceOnUse">
<stop stop-color="#3656C8"/>
<stop offset="1" stop-color="#2994FC" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_8677_100860" x1="218" y1="50" x2="218" y2="51" gradientUnits="userSpaceOnUse">
<stop stop-color="#FEF643"/>
<stop offset="1" stop-color="#FFA217"/>
</linearGradient>
<linearGradient id="paint3_linear_8677_100860" x1="411.777" y1="48" x2="411.777" y2="51" gradientUnits="userSpaceOnUse">
<stop stop-color="#FEF643"/>
<stop offset="1" stop-color="#FFA217"/>
</linearGradient>
<clipPath id="clip0_8677_100860">
<rect width="430" height="50" fill="white" transform="translate(3 1)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,27 @@
<svg width="42" height="34" viewBox="0 0 42 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_ii_9562_48030)">
<path d="M37.9737 32.8229H3.3414L0.651367 30.6782V24.4139L2.15286 23.2867L2.1779 10.4887L0.651367 9.26178V3.0673L3.3414 0.932617H37.9737L40.6512 3.0673V30.6782L37.9737 32.8229Z" fill="#009DFF" fill-opacity="0.1"/>
</g>
<path opacity="0.6" d="M38.3223 33H3.69003L1 30.848V24.562L2.50149 23.431L2.52654 10.589L1 9.35782V3.14202L3.69003 1H38.3223L40.9999 3.14202V30.848L38.3223 33Z" stroke="#27ACFF" stroke-width="0.58" stroke-miterlimit="10"/>
<path d="M15 24V14C15 10.134 18.134 7 22 7C25.866 7 29 10.134 29 14V24M12 24H32H12Z" fill="#009DFF"/>
<path d="M15 24V14C15 10.134 18.134 7 22 7C25.866 7 29 10.134 29 14V24M12 24H32" stroke="#009DFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M22 27C23.3807 27 24.5 25.8807 24.5 24.5V24H19.5V24.5C19.5 25.8807 20.6193 27 22 27Z" fill="#009DFF" stroke="#009DFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<filter id="filter0_ii_9562_48030" x="0.651367" y="-1.06738" width="40" height="35.8904" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0361115 0 0 0 0 0.4795 0 0 0 0 1 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_9562_48030"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-2"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0352941 0 0 0 0 0.478431 0 0 0 0 1 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="effect1_innerShadow_9562_48030" result="effect2_innerShadow_9562_48030"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

@ -0,0 +1,3 @@
<svg width="12" height="22" viewBox="0 0 12 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 22V0H6.31579L12 11L6.31579 22H0Z" fill="#2DE6FF"/>
</svg>

After

Width:  |  Height:  |  Size: 166 B

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 22C14.7614 22 17.2614 20.8807 19.0711 19.0711C20.8807 17.2614 22 14.7614 22 12C22 9.2386 20.8807 6.7386 19.0711 4.92893C17.2614 3.11929 14.7614 2 12 2C9.2386 2 6.7386 3.11929 4.92893 4.92893C3.11929 6.7386 2 9.2386 2 12C2 14.7614 3.11929 17.2614 4.92893 19.0711C6.7386 20.8807 9.2386 22 12 22Z" stroke="#FAAD14" stroke-width="1.5" stroke-linejoin="round"/>
<path d="M12 14.3125V12.3125C13.6568 12.3125 15 10.9693 15 9.3125C15 7.65565 13.6568 6.3125 12 6.3125C10.3432 6.3125 9 7.65565 9 9.3125" stroke="#FAAD14" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 18.8125C12.6904 18.8125 13.25 18.2529 13.25 17.5625C13.25 16.8722 12.6904 16.3125 12 16.3125C11.3097 16.3125 10.75 16.8722 10.75 17.5625C10.75 18.2529 11.3097 18.8125 12 18.8125Z" fill="#FAAD14"/>
</svg>

After

Width:  |  Height:  |  Size: 945 B

@ -0,0 +1,71 @@
<svg width="368" height="37" viewBox="0 0 368 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_9562_48043)">
<path d="M359.521 11.6994C353.262 12.1634 346.859 12.4507 340.312 12.5611C339.538 12.5611 338.93 12.4175 338.487 12.1303C338.067 11.8431 337.857 11.4453 337.857 10.9371C337.857 10.2743 338.244 9.58933 339.018 8.88229C342.535 5.54591 345.377 2.58514 347.545 0H351.857C349.225 3.31429 346.262 6.46286 342.966 9.44571C347.058 9.42362 352.09 9.18057 358.062 8.71657L355.242 2.91657H358.758L364 13.224H360.284L359.521 11.6994ZM359.853 28.2046H338.023L339.25 18.4274C339.472 16.4168 340.555 15.4114 342.502 15.4114H358.36C360.13 15.4114 361.014 16.2069 361.014 17.7977C361.014 18.0629 361.003 18.2617 360.981 18.3943L359.853 28.2046ZM341.805 25.1554H356.668L357.498 18.328H342.668L341.805 25.1554Z" fill="url(#paint0_linear_9562_48043)"/>
<path d="M316.856 28.7681H313.373L314.733 17.8309H302.955L303.32 14.6492H315.131L316.358 4.70637H305.609L305.974 1.65723H330.658L330.293 4.70637H319.809L318.581 14.6492H330.558L330.226 17.8309H318.183L316.856 28.7681ZM307.998 6.1978H311.15L312.245 13.1247H308.927L307.998 6.1978ZM325.25 13.1909H321.965L324.653 6.26408H327.937L325.25 13.1909Z" fill="url(#paint1_linear_9562_48043)"/>
<path d="M295.623 26.0502C295.534 26.9561 295.291 27.6189 294.893 28.0387C294.495 28.4806 293.931 28.7016 293.201 28.7016C293.046 28.7016 292.792 28.6795 292.438 28.6353C291.089 28.4143 289.894 28.0829 288.855 27.641L289.319 24.4924C290.049 24.7797 290.967 25.078 292.073 25.3873L292.405 25.4536C292.537 25.4536 292.626 25.4204 292.67 25.3542C292.714 25.2658 292.758 25.1111 292.803 24.8902L295.656 0.463867H298.675L295.623 26.0502ZM271.669 0.894725L276.911 3.87758L276.513 7.09244L271.271 4.10958L271.669 0.894725ZM286.134 1.29244C286.997 1.29244 287.627 1.4692 288.025 1.82272C288.446 2.15415 288.656 2.71758 288.656 3.51301C288.656 3.77815 288.645 3.98806 288.622 4.14272L286.864 19.1564H284.276L286.101 3.97701H280.461L278.703 19.1564H276.082L277.906 3.94387C278.017 2.94958 278.293 2.26463 278.736 1.88901C279.178 1.4913 279.886 1.29244 280.859 1.29244H286.134ZM290.613 3.14844H293.466L291.243 21.4433H288.357L290.613 3.14844ZM283.414 14.3839C283.259 15.798 283.027 17.1016 282.717 18.2947C283.248 19.0681 284.066 20.3385 285.172 22.1062C285.637 22.8795 286.389 24.1942 287.428 26.0502L284.873 27.177C284.785 27.0223 284.685 26.8456 284.575 26.6467C284.486 26.4479 284.376 26.2269 284.243 25.9839C283.248 24.0837 282.407 22.537 281.722 21.3439C281.169 22.7138 280.505 23.9842 279.731 25.1553C278.957 26.3043 278.061 27.4532 277.044 28.6022L274.522 27.4422C276.336 25.6303 277.729 23.7633 278.703 21.841C279.786 19.7199 280.516 17.201 280.892 14.2844L281.821 5.79987H284.376L283.414 14.3839ZM269.944 7.7553L275.319 10.7713L274.954 14.0193L269.48 10.9702L269.944 7.7553ZM275.65 16.5382C274.965 18.814 274.29 20.913 273.627 22.8353C272.875 25.0227 272.178 26.8345 271.536 28.2707H268.285C270.055 24.0063 271.47 20.0955 272.532 16.5382H275.65Z" fill="url(#paint2_linear_9562_48043)"/>
<path d="M240.55 15.047C239.643 16.7483 238.526 18.5049 237.199 20.3167L234.777 18.8916C237.387 15.4668 239.554 11.9868 241.279 8.45155H237.199L237.597 5.53498H241.744L242.407 0.0664062H245.493L244.829 5.53498H248.014L247.649 8.45155H244.464L244.332 9.61155C245.88 12.4397 247.063 14.8039 247.882 16.7041L245.46 18.0298L245.128 17.1018C244.597 15.6656 244.155 14.5498 243.801 13.7544L241.976 28.5693H238.891L240.55 15.047ZM265.664 11.9647L262.579 12.495L258.963 3.67898H254.152L249.341 12.6275L246.057 11.6664L251.697 1.95555C251.962 1.51364 252.25 1.20431 252.56 1.02755C252.869 0.828691 253.223 0.729263 253.621 0.729263H259.493C259.869 0.729263 260.234 0.828691 260.588 1.02755C260.964 1.22641 261.241 1.52469 261.418 1.92241L265.664 11.9647ZM251.564 9.18069H260.688L260.356 11.8984H251.232L251.564 9.18069ZM252.858 13.8538H255.711L257.304 22.9018C258.432 20.4051 259.571 17.4222 260.721 13.9533H263.939L261.749 19.7533C261.219 21.1453 260.478 22.935 259.527 25.1224H264.238L263.906 28.0058H245.161L245.493 25.1224H256.308L257.271 23.0013H254.351L252.858 13.8538ZM249.375 23.1007L247.815 13.9533H250.668L252.327 23.1007H249.375Z" fill="url(#paint3_linear_9562_48043)"/>
<path d="M215.103 8.45185C212.802 8.84956 209.894 9.18099 206.377 9.44614C205.846 9.49033 205.382 9.42404 204.984 9.24728C204.586 9.07052 204.309 8.82747 204.154 8.51814C204.044 8.29718 203.988 8.07623 203.988 7.85528C203.988 7.36918 204.232 6.84995 204.718 6.29756C205.913 4.94975 207.439 2.92804 209.297 0.232422H212.979C212.227 1.42557 211.409 2.61871 210.524 3.81185C209.861 4.69566 209.12 5.59052 208.301 6.49642C210.602 6.34175 212.648 6.08766 214.439 5.73414L213.709 2.51928H216.562L218.42 10.0096H215.468L215.103 8.45185ZM230.696 5.03814C228.816 5.72309 226.139 6.3749 222.667 6.99356L222.468 8.94899C222.446 9.01528 222.435 9.10366 222.435 9.21414C222.435 9.63395 222.722 9.84385 223.297 9.84385H225.454C227.555 9.84385 229.501 9.40195 231.293 8.51814L230.862 11.7993C229.424 12.44 227.489 12.7604 225.056 12.7604H221.937C221.008 12.7604 220.322 12.5726 219.88 12.197C219.46 11.7993 219.25 11.2248 219.25 10.4736C219.25 10.2305 219.261 10.0317 219.283 9.87699L220.278 0.298707H223.364L222.966 4.17642C225 3.77871 227.688 3.06061 231.027 2.02214L230.696 5.03814ZM213.046 22.9021H206.576L205.979 28.6027H203.026L204.586 13.4233C204.696 12.4511 204.962 11.7551 205.382 11.3353C205.824 10.9155 206.51 10.7056 207.439 10.7056H214.505C216.12 10.7056 216.927 11.4347 216.927 12.893C216.927 13.1581 216.916 13.357 216.894 13.4896L215.799 25.7524C215.667 26.813 215.379 27.5642 214.937 28.0061C214.517 28.448 213.842 28.669 212.913 28.669C212.294 28.669 211.619 28.6138 210.889 28.5033C210.159 28.4149 209.606 28.2934 209.23 28.1387L209.463 25.3216C210.657 25.6309 211.542 25.7856 212.117 25.7856C212.382 25.7856 212.559 25.7303 212.648 25.6199C212.758 25.5094 212.836 25.2663 212.88 24.8907L213.046 22.9021ZM213.875 13.4896H207.572L207.339 15.5444H213.676L213.875 13.4896ZM229.501 19.3559C228.506 19.7094 227.245 20.0629 225.719 20.4164C223.972 20.8141 222.512 21.1124 221.34 21.3113L220.975 24.5924C220.864 25.1669 221.13 25.4541 221.771 25.4541H223.994C224.967 25.4541 225.996 25.3437 227.079 25.1227C228.185 24.8797 229.181 24.5372 230.065 24.0953L229.634 27.4096C228.904 27.7189 227.997 27.9619 226.914 28.1387C225.83 28.3155 224.724 28.4039 223.596 28.4039H220.444C219.515 28.4039 218.83 28.205 218.387 27.8073C217.967 27.4317 217.757 26.8682 217.757 26.117C217.757 25.8519 217.768 25.6419 217.79 25.4873L219.051 13.9536H222.136L221.638 18.3616C224.669 17.765 227.4 17.08 229.833 16.3067L229.501 19.3559ZM213.444 18.1959H207.074L206.842 20.2507H213.278L213.444 18.1959Z" fill="url(#paint4_linear_9562_48043)"/>
<path d="M173.4 4.60697C173.046 4.60697 172.77 4.54069 172.571 4.40812C172.372 4.25345 172.272 4.05459 172.272 3.81154C172.272 3.63478 172.35 3.39173 172.504 3.0824L173.898 0.331543H177.116L176.353 2.02183H185.078L184.68 4.60697H180.765C180.655 5.24773 180.467 6.01002 180.201 6.89383H185.145L184.813 9.51212H179.306C181.097 10.4622 182.911 11.6222 184.747 12.9921L182.623 14.8481C181.274 13.8538 180.411 13.202 180.035 12.8927C179.261 12.3403 178.542 11.8542 177.879 11.4344C176.508 13.2462 174.716 14.8039 172.504 16.1075L169.983 14.2515C171.332 13.5003 172.471 12.7491 173.4 11.9978C174.329 11.2466 175.103 10.418 175.722 9.51212H170.879L171.21 6.89383H177.083C177.37 6.14259 177.58 5.38031 177.713 4.60697H173.4ZM196.723 13.887H185.211L186.439 4.0104C186.527 3.30335 186.792 2.75097 187.235 2.35326C187.677 1.95554 188.252 1.75669 188.96 1.75669H195.662C196.392 1.75669 196.978 2.01078 197.42 2.51897C197.862 3.00507 198.028 3.59059 197.918 4.27554L196.723 13.887ZM188.562 11.2355H194.036L194.766 4.40812H189.391L188.562 11.2355ZM193.372 28.5361H172.538L173.964 17.5327C174.053 16.8698 174.34 16.3285 174.827 15.9087C175.335 15.4889 175.944 15.279 176.651 15.279H192.244C192.974 15.279 193.549 15.4668 193.97 15.8424C194.39 16.218 194.6 16.7373 194.6 17.4001C194.6 17.6211 194.589 17.7868 194.567 17.8973L193.372 28.5361ZM191.349 18.063H177.05L176.718 20.5818H191.05L191.349 18.063ZM176.087 25.7521H190.486L190.751 23.2333H176.386L176.087 25.7521Z" fill="url(#paint5_linear_9562_48043)"/>
<path d="M163.845 24.0617L163.513 27.1771H136.773L137.138 24.0617H147.92L150.176 5.76686H139.759L140.124 2.68457H163.812L163.447 5.76686H153.726L151.47 24.0617H163.845Z" fill="url(#paint6_linear_9562_48043)"/>
<path d="M121.18 0.198975C120.892 2.45269 120.472 4.69536 119.919 6.92697C121.114 10.9925 122.717 14.6824 124.73 17.9967C126.743 21.2889 129.176 24.2938 132.029 27.0115L128.346 28.5361C126.311 26.4592 124.409 24.0066 122.64 21.1784C120.893 18.3502 119.422 15.3342 118.227 12.1304C115.617 18.6927 111.614 24.1834 106.217 28.6024L102.634 27.111C106.815 23.6199 110.143 19.7091 112.62 15.3784C115.23 10.7384 116.845 5.67859 117.464 0.198975H121.18Z" fill="url(#paint7_linear_9562_48043)"/>
<path d="M87.705 4.90523C87.3953 6.96008 87.0967 8.79399 86.8092 10.4069C86.8092 10.3407 86.765 10.5506 86.6765 11.0367H98.5206L98.1224 14.2847H86.8756C88.269 16.9803 89.8946 19.3666 91.7525 21.4435C93.6104 23.5205 95.7337 25.4428 98.1224 27.2104L94.7052 29.0001C90.3702 25.3323 87.0304 21.2447 84.6859 16.7372C83.4915 19.1235 81.9101 21.322 79.9416 23.3327C77.9953 25.3212 75.6508 27.2104 72.9082 29.0001L69.8228 27.1772C73.1404 24.9456 75.7724 22.8024 77.7188 20.7475C79.6873 18.7148 81.1581 16.5605 82.1313 14.2847H71.8134L72.1451 11.0367H83.1598L83.2925 10.3738C83.6021 8.67246 83.8675 7.15894 84.0887 5.83323C84.1772 5.36923 84.2325 5.05989 84.2546 4.90523H74.2352L74.567 1.65723H97.4257L97.0276 4.90523H87.705Z" fill="url(#paint8_linear_9562_48043)"/>
<path d="M53.9971 5.96614H57.1821L57.8788 0.232422H61.0969L60.4002 5.96614H65.8412L65.5094 8.98214H60.0353L59.3386 14.8816H64.7463L64.3814 17.8644H59.0068L58.111 25.2553H65.5094L65.1445 28.3044H48.1248L48.4566 25.2553H54.8265L55.7223 17.8644H50.4804L50.8453 14.8816H56.0872L56.8171 8.98214H51.8406C51.3762 8.98214 51.0112 8.88271 50.7458 8.68385C50.5025 8.48499 50.3809 8.2088 50.3809 7.85528C50.3809 7.67852 50.414 7.47966 50.4804 7.25871L52.2719 1.85642H55.2578L53.9971 5.96614ZM47.1959 25.653C47.0632 26.6915 46.7757 27.4096 46.3333 27.8073C45.9131 28.2271 45.2716 28.4039 44.4091 28.3376C43.2589 28.2492 42.1199 28.0503 40.9919 27.741L41.39 24.9901C42.0756 25.189 42.8719 25.3658 43.7787 25.5204L43.9778 25.5536C44.1105 25.5536 44.1989 25.5094 44.2432 25.421C44.2874 25.3105 44.3427 25.1227 44.4091 24.8576L45.1389 18.5604H41.1577C40.8923 20.5711 40.5274 22.4271 40.0629 24.1284C39.4436 26.2054 38.8686 27.7079 38.3377 28.6359L35.6836 27.6084C36.8558 25.2 37.7074 22.1619 38.2382 18.4941L40.1624 3.44728C40.273 2.58556 40.5274 1.95585 40.9255 1.55813C41.3457 1.13833 41.965 0.928421 42.7834 0.928421H47.6604C48.4787 0.928421 49.0648 1.08309 49.4187 1.39242C49.7947 1.70175 49.9827 2.22099 49.9827 2.95014C49.9827 3.1048 49.9606 3.38099 49.9164 3.77871L47.1959 25.653ZM46.8973 3.81185H43.1483L42.518 8.35242H46.3665L46.8973 3.81185ZM46.0347 11.1364H42.153L41.5227 15.8096H45.4707L46.0347 11.1364Z" fill="url(#paint9_linear_9562_48043)"/>
<path d="M22.977 0.331543H26.2947L25.9298 3.04926H32.731L32.3329 6.0984H25.5648L25.2331 8.78297H21.9486L22.2803 6.0984H15.1805L14.8488 8.78297H11.5643L11.896 6.0984H5.39342L5.79154 3.04926H12.261L12.6259 0.331543H15.9436L15.5787 3.04926H22.6453L22.977 0.331543ZM19.1286 7.78869L18.7304 10.9041H24.6691C25.598 10.9041 26.2726 11.0919 26.6928 11.4675C27.1131 11.8211 27.3232 12.3845 27.3232 13.1578C27.3232 13.4451 27.3121 13.666 27.29 13.8207C27.2679 14.2847 27.1352 15.4668 26.8919 17.367C26.7592 18.4717 26.527 20.1178 26.1952 22.3053C25.9298 24.1392 25.7418 25.2992 25.6312 25.7853C25.41 26.7795 25.0893 27.4645 24.6691 27.8401C24.2488 28.2378 23.5853 28.4367 22.6785 28.4367C21.661 28.4367 20.4003 28.271 18.8963 27.9395C17.6798 27.6744 16.8062 27.3982 16.2754 27.111L16.6071 24.1281C17.1158 24.327 17.8789 24.5479 18.8963 24.791C20.0686 25.1445 21.0307 25.3213 21.7827 25.3213C22.026 25.3213 22.1919 25.2771 22.2803 25.1887C22.3688 25.0782 22.4462 24.8794 22.5126 24.5921C22.5789 24.2828 22.7338 23.2774 22.977 21.5761L23.2756 19.3555L23.5742 17.1018C23.7733 15.6435 23.8949 14.583 23.9392 13.9201H18.1996C16.8947 19.2893 13.7208 24.3049 8.67791 28.967L5.45977 27.6081C8.09179 25.1555 10.1709 22.8355 11.697 20.6481C13.2452 18.4386 14.3179 16.1959 14.9151 13.9201H6.62096L6.95272 10.9041H15.4791L15.9436 7.78869H19.1286ZM31.3044 15.5441L32.2002 23.4984H29.2143L28.3848 15.5441H31.3044ZM10.3367 15.8424L7.25131 23.0675H4L7.21814 15.8424H10.3367Z" fill="url(#paint10_linear_9562_48043)"/>
</g>
<defs>
<filter id="filter0_d_9562_48043" x="0" y="0" width="368" height="37" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_9562_48043"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_9562_48043" result="shape"/>
</filter>
<linearGradient id="paint0_linear_9562_48043" x1="350.929" y1="0" x2="350.929" y2="28.2046" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint1_linear_9562_48043" x1="316.806" y1="1.65723" x2="316.806" y2="28.7681" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint2_linear_9562_48043" x1="283.48" y1="0.463867" x2="283.48" y2="28.7016" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint3_linear_9562_48043" x1="250.221" y1="0.0664062" x2="250.221" y2="28.5693" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint4_linear_9562_48043" x1="217.16" y1="0.232422" x2="217.16" y2="28.669" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint5_linear_9562_48043" x1="183.967" y1="0.331543" x2="183.967" y2="28.5361" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint6_linear_9562_48043" x1="150.309" y1="2.68457" x2="150.309" y2="27.1771" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint7_linear_9562_48043" x1="117.332" y1="0.198975" x2="117.332" y2="28.6024" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint8_linear_9562_48043" x1="84.1717" y1="1.65723" x2="84.1717" y2="29.0001" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint9_linear_9562_48043" x1="50.7624" y1="0.232422" x2="50.7624" y2="28.6359" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
<linearGradient id="paint10_linear_9562_48043" x1="18.3655" y1="0.331543" x2="18.3655" y2="28.967" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#A6CDF6"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,26 @@
<svg width="42" height="34" viewBox="0 0 42 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_ii_9562_48037)">
<path d="M38.582 32.8229H3.93728L1.25977 30.6782V24.4139L2.7611 23.2867L2.78615 10.4887L1.25977 9.26178V3.0673L3.93728 0.932617H38.582L41.2595 3.0673V30.6782L38.582 32.8229Z" fill="#009DFF" fill-opacity="0.1"/>
</g>
<path opacity="0.6" d="M38.3222 33H3.67751L1 30.848V24.562L2.50134 23.431L2.52638 10.589L1 9.35782V3.14202L3.67751 1H38.3222L40.9997 3.14202V30.848L38.3222 33Z" stroke="#009DFF" stroke-width="0.58" stroke-miterlimit="10"/>
<path d="M21 15C22.933 15 24.5 13.433 24.5 11.5C24.5 9.56701 22.933 8 21 8C19.067 8 17.5 9.56701 17.5 11.5C17.5 13.433 19.067 15 21 15Z" fill="#009DFF" stroke="#009DFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 25.4V26H30V25.4C30 23.1598 30 22.0397 29.5641 21.184C29.1806 20.4314 28.5686 19.8195 27.816 19.436C26.9603 19 25.8402 19 23.6 19H18.4C16.1598 19 15.0397 19 14.1841 19.436C13.4314 19.8195 12.8195 20.4314 12.436 21.184C12 22.0397 12 23.1598 12 25.4Z" fill="#009DFF" stroke="#009DFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<filter id="filter0_ii_9562_48037" x="1.25977" y="-1.06738" width="39.9995" height="35.8904" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0361115 0 0 0 0 0.4795 0 0 0 0 1 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_9562_48037"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-2"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0352941 0 0 0 0 0.478431 0 0 0 0 1 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="effect1_innerShadow_9562_48037" result="effect2_innerShadow_9562_48037"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

After

Width:  |  Height:  |  Size: 496 B

@ -0,0 +1,13 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 15:52:40
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:14:46
* @FilePath: \vite-ai\data-dashboard\src\components\contentHeader.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="ContentHeader">
<!-- 标题组件 -->
</div>
</template>

@ -0,0 +1,71 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 15:00:26
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 15:51:05
* @FilePath: \vite-ai\data-dashboard\src\views\dashboard\components\footer.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="footer-box">
<ul class="nav-list">
<li v-for="item in navList" :key="item.path" :class="{ active: isActive(item.fullPath) }">
<router-link :to="item.fullPath" class="nav-item">
<div class="nav-icon"></div>
<div>{{ item?.meta?.title }}</div>
</router-link>
</li>
</ul>
</div>
</template>
<script lang="ts" setup>
import { useRoute } from 'vue-router';
import { dashboardRoutes } from '@/router/dashboard';
//
const navList = computed(() => dashboardRoutes?.children)
const route = useRoute();
//
const isActive = (path: string) => {
console.log(route.path, "isActive", path);
return route.path.startsWith(path) || route.path === path;
};
</script>
<style scoped lang="scss">
.footer-box {
margin-top: 30px;
.nav-list {
display: flex;
justify-content: center;
gap: 40px;
padding: 0;
.nav-item {
text-align: center;
cursor: pointer;
transition: color 0.3s;
.nav-icon {
width: 40px;
height: 40px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>') no-repeat center;
background-size: 80%;
margin-bottom: 5px;
}
}
.active {
color: #42a5f5;
.nav-icon {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>'), linear-gradient(45deg, #42a5f5, #1976d2);
background-blend-mode: multiply;
filter: drop-shadow(0 0 5px #42a5f5);
}
}
}
}
</style>

@ -0,0 +1,163 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 15:42:11
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:29:16
* @FilePath: \vite-ai\data-dashboard\src\components\Navbar.vue
* @Description: 标题栏
-->
<script setup lang="ts">
// import { useNav } from "@/layout/hooks/useNav";
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const logout = () => {
userStore.logout()
}
// TODO
defineOptions({
name: "DsNavbar"
});
// const { logout } = useNav();
//
const currTime = ref({
date: "",
time: "",
week: ""
});
function _formatNum(value) {
if (value <= 9) {
return "0" + value;
}
return value;
}
function getTime() {
const nowDate = new Date();
const date =
nowDate.getFullYear() +
"/" +
_formatNum(nowDate.getMonth() + 1) +
"/" +
_formatNum(nowDate.getDate());
const time =
_formatNum(nowDate.getHours()) +
":" +
_formatNum(nowDate.getMinutes()) +
":" +
_formatNum(nowDate.getSeconds());
let week = "";
switch (nowDate.getDay()) {
case 0:
week = "星期天";
break;
case 1:
week = "星期一";
break;
case 2:
week = "星期二";
break;
case 3:
week = "星期三";
break;
case 4:
week = "星期四";
break;
case 5:
week = "星期五";
break;
case 6:
week = "星期六";
break;
default:
break;
}
return {
date,
time,
week
};
}
const getDataTime = () => {
currTime.value = getTime();
setTimeout(getDataTime, 1000);
};
onMounted(() => {
getDataTime();
});
</script>
<template>
<div class="flex justify-between h-full align-middle Navbar_wrap">
<div class="flex items-center left">
<div class="bg_logo" />
</div>
<div class="flex">
<div class="center_title" />
<h1>5G铁路货车装卸作业智能监控平台</h1>
</div>
<div class="flex items-center justify-end right">
<div class="date_box ff1">
<span>{{ currTime.date }}</span><span>{{ currTime.week }}</span><span>{{ currTime.time }}</span>
</div>
<div class="bg_user_icon" @click="logout" />
</div>
</div>
</template>
<style lang="scss" scoped>
.Navbar_wrap {
// bgNav
// background: url("@/assets/dataScreen/common/bgNav.svg") no-repeat;
background-size: cover;
width: 100%;
height: 64px;
.left {
width: 30vw;
padding-left: 24px;
.bg_logo {
// background: url("@/assets/dataScreen/common/logo.svg") no-repeat;
width: 111px;
height: 36px;
}
}
.center_title {
margin-top: 19px;
// background: url("@/assets/dataScreen/common/title.svg") no-repeat center center;
width: 370px;
height: 36px;
line-height: 2;
}
.right {
width: 30vw;
.date_box {
color: #009dff;
font-size: 16px;
margin-right: 15px;
&>span {
padding-left: 5px;
}
}
.bg_user_icon {
background: url("@/assets/common/userIcon.svg") no-repeat;
width: 40px;
height: 32px;
// border: 1px solid #009dff;
opacity: 0.6;
margin-right: 15px;
}
}
}
</style>

@ -0,0 +1,40 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 13:56:12
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 16:59:33
* @FilePath: \vite-ai\data-dashboard\src\views\dashboard\home.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="data-screen">
<!-- 顶部标题栏 -->
<header>
<NavbarComp />
</header>
<main class="app-main">
<router-view v-slot="{ Component, route }">
<transition name="fade">
<component :is="Component" :key="route.path" />
</transition>
</router-view>
</main>
<footer>
<FooterComp />
</footer>
</div>
</template>
<script setup>
import NavbarComp from '@/components/Navbar.vue'
import FooterComp from '@/components/Footer.vue'
</script>
<style scoped lang="scss">
.data-screen {
background: #002a5c;
color: white;
padding: 20px;
font-family: 'Arial', sans-serif;
}
</style>

@ -0,0 +1,79 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 11:27:03
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 16:54:29
* @FilePath: \vite-ai\data-dashboard\src\main.ts
* @Description:
*/
// src/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
// import { mockServer } from './mock' // Mock服务初始化
// import { registerGlobalDirectives } from '@/directives' // 全局指令注册
import { registerErrorHandler } from '@/utils/error' // 全局错误处理
// ================== 初始化核心配置 ==================
const app = createApp(App)
const pinia = createPinia()
// ================== Element Plus 完整引入方案 ==================
import ElementPlus from 'element-plus'
import "@/styles/tailwind.scss";
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css' // 暗黑主题
// ================== 自动导入配置检查 ==================
// 确保vite.config.ts中已配置以下内容
// AutoImport({ resolvers: [ElementPlusResolver()] })
// Components({ resolvers: [ElementPlusResolver()] })
// ================== 全局样式导入 ==================
import '@/styles/index.scss' // 主样式文件
// import 'virtual:svg-icons-register' // SVG图标注册如果使用vite-plugin-svg-icons
// ================== 环境相关配置 ==================
// if (import.meta.env.VITE_MOCK_ENABLED === 'true') {
// mockServer() // 初始化Mock服务
// }
// ================== 全局配置 ==================
app.config.globalProperties.$version = import.meta.env.VITE_APP_VERSION // 注入版本信息
// ================== 插件安装顺序 ==================
app
.use(pinia) // 优先安装Pinia
.use(router) // 其次安装路由
.use(ElementPlus, {
size: 'large', // 全局组件尺寸
zIndex: 3000 // 全局z-index
})
// ================== 全局注册 ==================
// registerGlobalDirectives(app) // 注册自定义指令如权限指令v-permission
// registerGlobalComponents(app) // 注册全局组件(如有)
// ================== 错误处理 ==================
registerErrorHandler(app) // 注册全局错误处理
// ================== 大屏适配初始化 ==================
if (import.meta.env.MODE === 'development') {
// 开发环境显示适配基准线
import('@/utils/screen-helper').then(({ showDesignHelper }) => {
showDesignHelper(1920, 1080) // 根据设计稿尺寸显示辅助线
})
}
// ================== 挂载主应用 ==================
app.mount('#app')
// ================== 生产环境性能监控 ==================
// if (import.meta.env.PROD) {
// import('@/utils/performance').then(({ initPerformance }) => {
// initPerformance()
// })
// }

@ -0,0 +1,18 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 14:07:14
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 14:07:20
* @FilePath: \vite-ai\data-dashboard\src\mock\index.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { createMockServer } from 'vite-plugin-mock/client'
export function mockServer() {
createMockServer({
// 配置自动导入mock目录下所有文件
include: ['src/mock/**/*.ts'],
// 生产环境强制关闭mock即使忘记修改配置
ignore: import.meta.env.PROD ? [/.*/] : undefined
})
}

@ -0,0 +1,44 @@
// 路由配置示例router/index.ts
// import PoleMonitor from "../views/PoleMonitor.vue";
// import DeviceStatus from "../views/DeviceStatus.vue";
export const dashboardRoutes = {
path: "/dashboard",
fullPath: "/dashboard",
redirect: "/dashboard/dataOverview",
component: () => import("@/layouts/MainLayout.vue"),
meta: { requiresAuth: true , isDashboard: true, keepAlive: false,},
children: [
{
path: "dataOverview",
fullPath: "/dashboard/dataOverview",
name: "DataOverview",
component: () => import("@/views/dashboard/DataOverview.vue"),
meta: { title: "数据总览" },
},
{
path: "monitor",
name: "AppearanceMonitor",
fullPath: "/dashboard/monitor",
component: () => import("@/views/dashboard/AppearanceMonitor.vue"),
meta: { title: "外观监测" },
},
{
path: "pole",
name: "PoleMonitor",
fullPath: "/dashboard/pole",
component: () => import("@/views/dashboard/PoleMonitor.vue"),
meta: { title: "撑杆监测" },
},
{
path: "device",
name: "DeviceStatus",
fullPath: "/dashboard/device",
component: () => import("@/views/dashboard/DeviceStatus.vue"),
meta: { title: "设备状态" },
},
// { path: "pole", name: "PoleMonitor", component: PoleMonitor },
// { path: "device", name: "DeviceStatus", component: DeviceStatus },
],
};

@ -0,0 +1,56 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 13:53:22
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:45:39
* @FilePath: \vite-ai\data-dashboard\src\router\index.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { createRouter, createWebHistory } from "vue-router";
import { useUserStore } from "@/stores/user";
import { dashboardRoutes } from "./dashboard";
import { buildHierarchyTree } from "@/utils/tree";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/login",
fullPath: "/login",
component: () => import("@/views/login/Login.vue"),
meta: {
keepAlive: false,
requiresAuth: false,
},
},
{
path: "/",
redirect: "/dashboard",
},
{ ...dashboardRoutes },
],
});
router.beforeEach((to) => {
const userStore = useUserStore();
if (to.meta.requiresAuth && !userStore.token) {
return "/login";
}
// if (to.path === "/login" && userStore.token) {
// return "/dashboard";
// }
});
/** 重置路由 */
export function resetRouter() {
router.getRoutes().forEach(route => {
const { name, meta } = route;
if (name && router.hasRoute(name) && meta?.backstage) {
router.removeRoute(name);
}
});
}
export default router;

@ -0,0 +1,32 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 13:51:46
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:45:26
* @FilePath: \vite-ai\data-dashboard\src\stores\user.ts
* @Description:
*/
import { defineStore } from "pinia";
import router, { resetRouter } from "@/router";
interface UserState {
token: string | null;
}
export const useUserStore = defineStore("user", {
state: (): UserState => ({
token: localStorage.getItem("token"),
}),
actions: {
login(token: string) {
this.token = token;
localStorage.setItem("token", token);
},
logout() {
this.token = null;
localStorage.removeItem("token");
resetRouter();
router.replace("/login");
},
},
});

@ -0,0 +1,76 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
// background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 重置默认样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
line-height: 1.5;
color: rgba(255, 255, 255, 0.8);
background-color: #002a5c;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: normal;
}
ul,
ol {
list-style: none;
}
a {
color: inherit;
text-decoration: none;
&:hover {
text-decoration: none;
}
}
button {
border: none;
background: transparent;
cursor: pointer;
color: inherit;
font-family: inherit;
}
input,
textarea {
border: none;
outline: none;
background: transparent;
color: inherit;
font-family: inherit;
&::placeholder {
color: rgba(255, 255, 255, 0.5);
}
}
// current
// .flex {
// display: flex;
// }

@ -0,0 +1,42 @@
/* 引入 Tailwind 基础层 */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* 修复与 Element Plus 的样式冲突 */
@layer base {
.el-button {
@apply font-normal; // Element
}
.el-menu {
@apply border-none; //
}
.el-form-item__label {
@apply text-gray-600; //
}
}
/* 自定义组件类 */
@layer components {
.dashboard-card {
@apply bg-white rounded-lg shadow-sm p-6 hover:shadow-md transition-shadow;
&-title {
@apply text-lg font-medium mb-4 text-gray-700;
}
}
.data-badge {
@apply inline-flex items-center px-3 py-1 rounded-full text-sm;
&.success {
@apply bg-green-100 text-green-800;
}
&.warning {
@apply bg-yellow-100 text-yellow-800;
}
}
}

@ -0,0 +1,25 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 14:07:41
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 14:07:46
* @FilePath: \vite-ai\data-dashboard\src\utils\error.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export function registerErrorHandler(app: App) {
// Vue错误捕获
app.config.errorHandler = (err, instance, info) => {
console.error('Vue Error:', err)
// 发送错误日志...
}
// 全局未捕获异常
window.addEventListener('error', event => {
console.error('Global Error:', event.error)
})
// 未处理的Promise拒绝
window.addEventListener('unhandledrejection', event => {
console.error('Unhandled Rejection:', event.reason)
})
}

@ -0,0 +1,33 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 14:07:57
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 14:36:56
* @FilePath: \vite-ai\data-dashboard\src\utils\screen-helper.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export function showDesignHelper(designWidth: number, designHeight: number) {
// 创建基准线容器
const helper = document.createElement('div')
helper.style.cssText = `
position: fixed;
z-index: 9999;
pointer-events: none;
width: ${designWidth}px;
height: ${designHeight}px;
transform-origin: 0 0;
`
document.body.appendChild(helper)
// 动态更新缩放比例
const updateScale = () => {
const scale = Math.min(
window.innerWidth / designWidth,
window.innerHeight / designHeight
)
helper.style.transform = `scale(${scale})`
}
window.addEventListener('resize', updateScale)
updateScale()
}

@ -0,0 +1,188 @@
/**
* @description uniqueId
* @param tree
* @returns uniqueId
*/
export const extractPathList = (tree: any[]): any => {
if (!Array.isArray(tree)) {
console.warn("tree must be an array");
return [];
}
if (!tree || tree.length === 0) return [];
const expandedPaths: Array<number | string> = [];
for (const node of tree) {
const hasChildren = node.children && node.children.length > 0;
if (hasChildren) {
extractPathList(node.children);
}
expandedPaths.push(node.uniqueId);
}
return expandedPaths;
};
/**
* @description childrenlength1childrenuniqueId
* @param tree
* @param pathList id
* @returns uniqueId
*/
export const deleteChildren = (tree: any[], pathList = []): any => {
if (!Array.isArray(tree)) {
console.warn("menuTree must be an array");
return [];
}
if (!tree || tree.length === 0) return [];
for (const [key, node] of tree.entries()) {
if (node.children && node.children.length === 1) delete node.children;
node.id = key;
node.parentId = pathList.length ? pathList[pathList.length - 1] : null;
node.pathList = [...pathList, node.id];
node.uniqueId =
node.pathList.length > 1 ? node.pathList.join("-") : node.pathList[0];
const hasChildren = node.children && node.children.length > 0;
if (hasChildren) {
deleteChildren(node.children, node.pathList);
}
}
return tree;
};
/**
* @description
* @param tree
* @param pathList id
* @returns
*/
export const buildHierarchyTree = (tree: any[], pathList = []): any => {
if (!Array.isArray(tree)) {
console.warn("tree must be an array");
return [];
}
if (!tree || tree.length === 0) return [];
for (const [key, node] of tree.entries()) {
node.id = key;
node.parentId = pathList.length ? pathList[pathList.length - 1] : null;
node.pathList = [...pathList, node.id];
const hasChildren = node.children && node.children.length > 0;
if (hasChildren) {
buildHierarchyTree(node.children, node.pathList);
}
}
return tree;
};
/**
* @description 广uniqueId
* @param tree
* @param uniqueId uniqueId
* @returns
*/
export const getNodeByUniqueId = (
tree: any[],
uniqueId: number | string
): any => {
if (!Array.isArray(tree)) {
console.warn("menuTree must be an array");
return [];
}
if (!tree || tree.length === 0) return [];
const item = tree.find(node => node.uniqueId === uniqueId);
if (item) return item;
const childrenList = tree
.filter(node => node.children)
.map(i => i.children)
.flat(1) as unknown;
return getNodeByUniqueId(childrenList as any[], uniqueId);
};
/**
* @description uniqueId
* @param tree
* @param uniqueId uniqueId
* @param fields
* @returns
*/
export const appendFieldByUniqueId = (
tree: any[],
uniqueId: number | string,
fields: object
): any => {
if (!Array.isArray(tree)) {
console.warn("menuTree must be an array");
return [];
}
if (!tree || tree.length === 0) return [];
for (const node of tree) {
const hasChildren = node.children && node.children.length > 0;
if (
node.uniqueId === uniqueId &&
Object.prototype.toString.call(fields) === "[object Object]"
)
Object.assign(node, fields);
if (hasChildren) {
appendFieldByUniqueId(node.children, uniqueId, fields);
}
}
return tree;
};
/**
* @description
* @param data
* @param id id id
* @param parentId parentId
* @param children children
* @returns
*/
export const handleTree = (
data: any[],
id?: string,
parentId?: string,
children?: string
): any => {
if (!Array.isArray(data)) {
console.warn("data must be an array");
return [];
}
const config = {
id: id || "id",
parentId: parentId || "parentId",
childrenList: children || "children"
};
const childrenListMap: any = {};
const nodeIds: any = {};
const tree = [];
for (const d of data) {
const parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (const d of data) {
const parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (const t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o: Record<string, any>) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (const c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
return tree;
};

@ -0,0 +1,3 @@
<template>
数据监测
</template>

@ -0,0 +1,218 @@
<template>
<div class="data-overview-wrap">
<!-- 检测总量汇总 -->
<div class="grid-container">
<div class="grid-item">
<div class="module-header">检测总量汇总</div>
<div class="chart-container" id="totalChart"></div>
</div>
<!-- 设备信息 -->
<div class="grid-item">
<div class="module-header">设备信息</div>
<div class="device-info">
<div class="total-device">
<div class="device-icon"></div>
<div class="device-count">
<div>设备总数</div>
<div class="count-number">37</div>
</div>
</div>
<div class="device-list">
<div class="device-card">
<div>车体检测设备: 12</div>
<div class="status-bar">
<el-progress type="line" :percentage="(8 / 12) * 100" status="success"></el-progress>
<el-progress type="line" :percentage="(2 / 12) * 100" status="warning"></el-progress>
<el-progress type="line" :percentage="(2 / 12) * 100" status="danger"></el-progress>
</div>
</div>
<div class="device-card">
<div>撑杆检测设备: 10</div>
<div class="status-bar">
<el-progress type="line" :percentage="(9 / 10) * 100" status="success"></el-progress>
<el-progress type="line" :percentage="(1 / 10) * 100" status="warning"></el-progress>
<el-progress type="line" :percentage="(0 / 10) * 100" status="danger"></el-progress>
</div>
</div>
<div class="device-card">
<div>钩机检测设备: 15</div>
<div class="status-bar">
<el-progress type="line" :percentage="(8 / 15) * 100" status="success"></el-progress>
<el-progress type="line" :percentage="(2 / 15) * 100" status="warning"></el-progress>
<el-progress type="line" :percentage="(2 / 15) * 100" status="danger"></el-progress>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 中部检测模块 -->
<div class="grid-container">
<div class="grid-item">
<div class="module-header">车体检测</div>
<div class="chart-container" id="bodyChart"></div>
</div>
<div class="grid-item">
<div class="module-header">撑杆检测</div>
<div class="chart-container" id="poleChart"></div>
</div>
<div class="grid-item">
<div class="module-header">实时监控画面</div>
<div class="monitor-images">
<img src="https://picsum.photos/300/200?random=1" alt="监控画面">
<img src="https://picsum.photos/300/200?random=2" alt="监控画面">
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts';
onMounted(() => {
//
const totalChart = echarts.init(document.getElementById('totalChart') as HTMLDivElement);
totalChart.setOption({
xAxis: {
data: ['1月', '2月', '3月', '4月', '5月', '6月']
},
yAxis: {},
series: [
{
name: '车体检测',
type: 'bar',
data: [200, 200, 150, 150, 120, 220]
},
{
name: '撑杆检测',
type: 'bar',
data: [80, 150, 80, 100, 180, 80]
}
]
});
//
const bodyChart = echarts.init(document.getElementById('bodyChart') as HTMLDivElement);
bodyChart.setOption({
series: [
{
name: '车体检测',
type: 'pie',
radius: '70%',
data: [
{ value: 26, name: '搭扣未搭' },
{ value: 35, name: '下侧门缺失' },
{ value: 15, name: '小门搭扣丢失' },
{ value: 15, name: '门折页脱落' },
{ value: 10, name: '小门外翘' },
{ value: 5, name: '小窗裂纹' }
]
}
]
});
//
const poleChart = echarts.init(document.getElementById('poleChart') as HTMLDivElement);
poleChart.setOption({
series: [
{
name: '撑杆检测',
type: 'pie',
radius: ['50%', '70%'],
data: [
{ value: 65, name: '撑杆断裂' },
{ value: 35, name: '撑杆弯曲' }
]
}
]
});
});
</script>
<style scoped lang="scss">
.data-overview-wrap {
background: #002a5c;
color: white;
padding: 20px;
font-family: 'Arial', sans-serif;
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin: 20px 0;
.grid-item {
background: rgba(74, 126, 191, 0.1);
border-radius: 8px;
padding: 15px;
.module-header {
color: #4a7ebf;
margin-bottom: 15px;
}
.chart-container {
height: 300px;
}
}
}
.device-info {
.total-device {
display: flex;
align-items: center;
margin-bottom: 15px;
.device-icon {
width: 40px;
height: 40px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>') no-repeat center;
background-size: 80%;
}
.device-count {
margin-left: 15px;
.count-number {
font-size: 24px;
font-weight: bold;
}
}
}
.device-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
.device-card {
background: rgba(74, 126, 191, 0.1);
padding: 10px;
border-radius: 4px;
.status-bar {
margin-top: 5px;
}
}
}
}
.monitor-images {
display: flex;
gap: 10px;
margin-top: 15px;
img {
width: 100%;
height: auto;
}
}
}
</style>

@ -0,0 +1,11 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 15:15:47
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 15:15:53
* @FilePath: \vite-ai\data-dashboard\src\views\dashboard\DeviceStatus.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
设备状态
</template>

@ -0,0 +1,11 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 15:15:01
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 15:15:26
* @FilePath: \vite-ai\data-dashboard\src\views\dashboard\PoleMonitor.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
撑杆监测
</template>

@ -0,0 +1,160 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 13:56:27
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:22:49
* @FilePath: \vite-ai\data-dashboard\src\views\login\login.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="login-container">
<div class="login-box">
<div class="title">
欢迎登录
</div>
<el-form :model="form" :rules="rules" ref="formRef" label-width="0" class="login-form">
<el-form-item prop="username">
<el-input v-model="form.username" placeholder="请输入您的账号" prefix-icon="el-icon-user"
class="input-item" />
</el-form-item>
<el-form-item prop="password">
<el-input v-model="form.password" placeholder="请输入登录密码" prefix-icon="el-icon-lock" type="password"
class="input-item" />
</el-form-item>
<el-form-item class="remember-item">
<el-checkbox v-model="form.remember"></el-checkbox>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleLogin" class="login-btn">
登录
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script setup lang="ts">
import { useUserStore } from '@/stores/user'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
const router = useRouter()
const userStore = useUserStore()
const form = reactive({
username: 'admin',
password: 'admin123'
})
const handleLogin = async () => {
if (form.username !== 'admin' || form.password !== 'admin123') {
ElMessage.error('用户名或密码错误')
return
}
try {
//
const res = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify(form)
})
const data = await res.json()
if (data.code === 200) {
userStore.login(data.data.token)
router.push('/dashboard')
}
} catch (err) {
ElMessage.error('登录失败')
}
}
</script>
<style scoped lang="scss">
.login-container {
height: 100vh;
// background: linear-gradient(45deg, #0a224a, #001233);
display: flex;
justify-content: center;
align-items: center;
// background-image: url('https://via.placeholder.com/1920x1080?text=');
background-size: cover;
background-position: center;
.login-box {
background: rgba(10, 34, 74, 0.9);
padding: 40px 60px;
border-radius: 20px;
box-shadow: 0 0 30px rgba(58, 145, 255, 0.6);
position: relative;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 2px solid rgba(58, 145, 255, 0.3);
border-radius: 20px;
}
.title {
color: #87ceeb;
text-align: center;
font-size: 20px;
margin-bottom: 30px;
position: relative;
&::before,
&::after {
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: #87ceeb;
}
&::before {
left: -30px;
}
&::after {
right: -30px;
}
}
.login-form {
.input-item {
margin-bottom: 20px;
.el-input__inner {
background: rgba(58, 145, 255, 0.1);
border: 1px solid rgba(58, 145, 255, 0.3);
color: white;
&::placeholder {
color: rgba(255, 255, 255, 0.6);
}
}
}
.remember-item {
margin: 15px 0;
}
.login-btn {
width: 100%;
background: linear-gradient(135deg, #42a5f5, #1976d2);
border: none;
box-shadow: 0 4px 12px rgba(58, 145, 255, 0.4);
&:hover {
background: linear-gradient(135deg, #1976d2, #42a5f5);
}
}
}
}
}
</style>

@ -0,0 +1,162 @@
<template>
<div class="login-container">
<div class="login-box">
<div class="title">
>> 欢迎登录 <<
</div>
<el-form
:model="form"
:rules="rules"
ref="formRef"
label-width="0"
class="login-form"
>
<el-form-item prop="username">
<el-input
v-model="form.username"
placeholder="请输入您的账号"
prefix-icon="el-icon-user"
class="input-item"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="form.password"
placeholder="请输入登录密码"
prefix-icon="el-icon-lock"
type="password"
class="input-item"
/>
</el-form-item>
<el-form-item class="remember-item">
<el-checkbox v-model="form.remember"></el-checkbox>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="handleLogin"
class="login-btn"
>
登录
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const formRef = ref<any>();
const form = ref({
username: '',
password: '',
remember: false
});
const rules = ref({
username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
});
const handleLogin = () => {
formRef.value?.validate((valid) => {
if (valid) {
//
router.push('/data-display');
}
});
};
</script>
<style scoped lang="scss">
.login-container {
height: 100vh;
background: linear-gradient(45deg, #0a224a, #001233);
display: flex;
justify-content: center;
align-items: center;
background-image: url('https://via.placeholder.com/1920x1080?text=铁路货车背景图');
background-size: cover;
background-position: center;
.login-box {
background: rgba(10, 34, 74, 0.9);
padding: 40px 60px;
border-radius: 20px;
box-shadow: 0 0 30px rgba(58, 145, 255, 0.6);
position: relative;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 2px solid rgba(58, 145, 255, 0.3);
border-radius: 20px;
}
.title {
color: #87ceeb;
text-align: center;
font-size: 20px;
margin-bottom: 30px;
position: relative;
&::before,
&::after {
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: #87ceeb;
}
&::before {
left: -30px;
}
&::after {
right: -30px;
}
}
.login-form {
.input-item {
margin-bottom: 20px;
.el-input__inner {
background: rgba(58, 145, 255, 0.1);
border: 1px solid rgba(58, 145, 255, 0.3);
color: white;
&::placeholder {
color: rgba(255, 255, 255, 0.6);
}
}
}
.remember-item {
margin: 15px 0;
}
.login-btn {
width: 100%;
background: linear-gradient(135deg, #42a5f5, #1976d2);
border: none;
box-shadow: 0 4px 12px rgba(58, 145, 255, 0.4);
&:hover {
background: linear-gradient(135deg, #1976d2, #42a5f5);
}
}
}
}
}
</style>

1
src/vite-env.d.ts vendored

@ -0,0 +1 @@
/// <reference types="vite/client" />

@ -0,0 +1,18 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: "class",
corePlugins: {
preflight: false
},
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
bg_color: "var(--el-bg-color)",
primary: "var(--el-color-primary)",
text_color_primary: "var(--el-text-color-primary)",
text_color_regular: "var(--el-text-color-regular)"
}
}
}
};

@ -0,0 +1,14 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}

@ -0,0 +1,51 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-03-06 11:27:03
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-03-06 17:11:57
* @FilePath: \vite-ai\data-dashboard\vite.config.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { defineConfig, loadEnv } from 'vite'
import { resolve } from "path";
import vue from '@vitejs/plugin-vue'
import { viteMockServe } from 'vite-plugin-mock'
import AutoImport from "unplugin-auto-import/vite";
/** 路径查找 */
const pathResolve = (dir: string): string => {
return resolve(__dirname, ".", dir);
};
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
return {
resolve: {
alias: [
{ find: /^@\//, replacement: resolve(__dirname, "src") + "/" },
{ find: /^~/, replacement: "" },
{ find: /^@build\//, replacement: pathResolve("build") }
]
},
plugins: [
vue(),
viteMockServe({
mockPath: 'mock',
localEnabled: env.VITE_MOCK_ENABLED === 'true'
}),
AutoImport({
imports: ["vue"],
eslintrc: {
enabled: true
}
})
],
server: {
port: parseInt(env.VITE_PORT) || 5050
},
define: {
'process.env': env
}
}
})
Loading…
Cancel
Save