Browse Source

初始化消毒设备项目

master
LiLongLong 2 months ago
commit
1b551e46c2
  1. 7
      .env.dev
  2. 7
      .env.pre
  3. 7
      .env.prod
  4. 7
      .env.test
  5. 27
      .gitignore
  6. 0
      .npmrc
  7. 28
      .postcssrc.js
  8. 10
      .prettierrc
  9. 23
      README.md
  10. BIN
      commitlint.config.js
  11. 19
      eslint.config.js
  12. 43
      increment-version.js
  13. 27
      index.html
  14. 10986
      package-lock.json
  15. 89
      package.json
  16. BIN
      public/favicon.ico
  17. 24
      server/index.js
  18. 33
      server/routes/auth.js
  19. 74
      server/routes/control.js
  20. 33
      server/routes/ore.js
  21. 31
      server/routes/point.js
  22. 28
      server/utils/websocket.js
  23. 17
      src/apis/user.ts
  24. 77
      src/app.vue
  25. 1
      src/assets/images/background-login.svg
  26. 1
      src/assets/images/background.svg
  27. 22
      src/assets/images/close-device.svg
  28. 1
      src/assets/images/empty.svg
  29. 1
      src/assets/images/error.svg
  30. 1
      src/assets/images/expand.svg
  31. 1
      src/assets/images/icon_add_s.svg
  32. 1
      src/assets/images/icon_arr_s.svg
  33. 1
      src/assets/images/icon_del_s.svg
  34. 1
      src/assets/images/ing.svg
  35. 23
      src/assets/images/init-device.svg
  36. 1
      src/assets/images/liquied/liquied_bottle.svg
  37. 1
      src/assets/images/login.svg
  38. 1
      src/assets/images/logo.svg
  39. 1
      src/assets/images/logout.svg
  40. 1
      src/assets/images/menuIcon/n_debug.svg
  41. 1
      src/assets/images/menuIcon/n_expe.svg
  42. 1
      src/assets/images/menuIcon/n_home.svg
  43. 1
      src/assets/images/menuIcon/n_liquid.svg
  44. 1
      src/assets/images/menuIcon/n_liquid_config.svg
  45. 1
      src/assets/images/menuIcon/n_log.svg
  46. 1
      src/assets/images/menuIcon/n_ore.svg
  47. 1
      src/assets/images/menuIcon/n_setting.svg
  48. 1
      src/assets/images/menuIcon/n_user.svg
  49. 1
      src/assets/images/menuIcon/s_debug.svg
  50. 1
      src/assets/images/menuIcon/s_expe.svg
  51. 1
      src/assets/images/menuIcon/s_home.svg
  52. 1
      src/assets/images/menuIcon/s_liquid.svg
  53. 1
      src/assets/images/menuIcon/s_liquid_config.svg
  54. 1
      src/assets/images/menuIcon/s_log.svg
  55. 1
      src/assets/images/menuIcon/s_ore.svg
  56. 1
      src/assets/images/menuIcon/s_setting.svg
  57. 1
      src/assets/images/menuIcon/s_user.svg
  58. 1
      src/assets/images/password_icon.svg
  59. 1
      src/assets/images/run.svg
  60. 1
      src/assets/images/success.svg
  61. 22
      src/assets/images/user-cancel.svg
  62. 22
      src/assets/images/user-logout.svg
  63. 1
      src/assets/images/user.svg
  64. 1
      src/assets/images/user_icon.svg
  65. 1
      src/assets/images/wait.svg
  66. 1
      src/assets/images/wifi-active.svg
  67. 1
      src/assets/images/wifi.svg
  68. 1
      src/assets/images/x.svg
  69. 1
      src/assets/images/y.svg
  70. 1
      src/assets/images/z.svg
  71. 91
      src/assets/styles/common.scss
  72. 37
      src/assets/styles/element.scss
  73. 3
      src/assets/styles/main.scss
  74. 5
      src/assets/styles/variable.scss
  75. 140
      src/components/common/FTButton/index.vue
  76. 76
      src/components/common/FTDialog/index.vue
  77. 181
      src/components/common/FTStream/index.vue
  78. 7
      src/components/common/FTTable/expand.ts
  79. 144
      src/components/common/FTTable/index.vue
  80. 21
      src/env.d.ts
  81. 25
      src/hooks/useActivateDebug.ts
  82. 29
      src/hooks/useApiData.ts
  83. 300
      src/layouts/default.vue
  84. 5
      src/libs/constant.ts
  85. 92
      src/libs/http.ts
  86. 37
      src/libs/message.ts
  87. 193
      src/libs/socket.ts
  88. 13
      src/libs/token.ts
  89. 103
      src/libs/utils.ts
  90. 27
      src/main.ts
  91. 26
      src/router/index.ts
  92. 34
      src/router/routes.ts
  93. 102
      src/stores/debugStore.ts
  94. 64
      src/stores/homeStore.ts
  95. 7
      src/stores/index.ts
  96. 217
      src/stores/systemStore.ts
  97. 18
      src/stores/useLiquidsStore.ts
  98. 14
      src/stores/useSolutionStore.ts
  99. 27
      src/types/user.d.ts
  100. 33
      src/types/websocket.d.ts

7
.env.dev

@ -0,0 +1,7 @@
# 开发环境
FT_NODE_ENV=dev
FT_WS_URL=ws://192.168.73.10:19001
FT_PROXY=http://192.168.1.200:8080
FT_API_BASE=/api

7
.env.pre

@ -0,0 +1,7 @@
# 预发环境
FT_NODE_ENV=pre
FT_WS_URL=ws://127.0.0.1:8080/ws
FT_PROXY=http://192.168.1.140
FT_API_BASE=/api

7
.env.prod

@ -0,0 +1,7 @@
# 生产环境
FT_NODE_ENV=prod
FT_WS_URL=ws://192.168.8.168:8080/ws
FT_PROXY=http://192.168.8.168:8080
FT_API_BASE=/api

7
.env.test

@ -0,0 +1,7 @@
# 测试环境
FT_NODE_ENV=test
FT_WS_URL=ws://192.168.1.199:8080/ws
FT_PROXY=http://192.168.1.199:8080
FT_API_BASE=/api

27
.gitignore

@ -0,0 +1,27 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
auto-imports.d.ts
.eslintrc-auto-import.json
pnpm-lock.yaml
node_modules
dist
dist-*
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

0
.npmrc

28
.postcssrc.js

@ -0,0 +1,28 @@
export default {
plugins: {
'postcss-import': {},
'postcss-url': {},
'postcss-aspect-ratio-mini': {},
'postcss-write-svg': {
utf8: false,
},
'postcss-px-to-viewport-8-plugin': {
viewportWidth: 1120,
viewportHeight: 736,
unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
selectorBlackList: ['.ignore', '.hairlines', ':after'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: false, // 允许在媒体查询中转换`px`
},
'postcss-viewport-units': {
filterRule: rule =>
!/::?(?:before|after)/i.test(rule.selector),
},
'cssnano': {
'autoprefixer': false,
'postcss-zindex': false,
},
},
}

10
.prettierrc

@ -0,0 +1,10 @@
{
"printWidth": 120,
"tabWidth": 2,
"endOfLine": "lf",
"singleQuote": true,
"semi": true,
"trailingComma": "none",
"bracketSpacing": true,
"arrowParens": "avoid"
}

23
README.md

@ -0,0 +1,23 @@
### 前端项目模板
##### 文件目录
- src
- components 组件目录
- apis 接口文件目录
- assets 静态资源目录
- hooks hooks目录
- libs 公共工具类
- router 页面路由
- stores 项目公共状态管理
- types 类型申明
- views 页面目录
##### 项目运行
项目采用pnpm 进行依赖构建,请先安装pnpm
[pnpm - 速度快、节省磁盘空间的软件包管理器](https://pnpm.io/)
```bash
npm install pnpm -g
```
```bash
pnpm install // 安装依赖
pnpm dev // 运行项目
```

BIN
commitlint.config.js

19
eslint.config.js

@ -0,0 +1,19 @@
// import eslint_js from '@eslint/js'
// import eslint_ts from 'typescript-eslint';
// import eslint_vue from 'eslint-plugin-vue';
// import vue_parser from 'vue-eslint-parser';
import lintConfig from '@antfu/eslint-config'
export default lintConfig({
vue: true,
markdown: true,
ignores: [],
rules: {
'no-console': 0,
'antfu/top-level-function': 0,
'ts/no-use-before-define': 0,
'no-alert': 0,
},
globals: { process: 'readonly' },
})

43
increment-version.js

@ -0,0 +1,43 @@
import { execSync } from 'node:child_process' // 引入 child_process 模块用于执行 Git 命令
import fs from 'node:fs'
import path, { dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import semver from 'semver'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const packagePath = path.resolve(__dirname, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8'))
// 读取命令行参数(默认使用 'patch')
// eslint-disable-next-line node/prefer-global/process
const versionType = process.argv[2] || 'patch'
// 递增版本
const newVersion = semver.inc(packageJson.version, versionType)
if (!newVersion) {
throw new Error(`Invalid version type: ${versionType}`)
}
packageJson.version = newVersion
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2))
console.log(`Version updated to: ${newVersion}`)
// 新增:自动提交 package.json 到远程仓库
try {
// 将 package.json 添加到暂存区
execSync('git add package.json')
console.log('Added package.json to staging area.')
// 提交更改
execSync(`git commit -m "fix: Update version to V${newVersion}"`)
console.log(`Committed changes with message: Update version to ${newVersion}`)
// 推送到远程仓库
execSync('git push')
console.log('Pushed changes to remote repository.')
}
catch (error) {
console.error('Failed to commit and push changes:', error.message)
}

27
index.html

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>消毒机</title>
<style>
html,body{
height:100%;
width:100%;
margin: 0;
padding: 0;
}
#app {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

10986
package-lock.json
File diff suppressed because it is too large
View File

89
package.json

@ -0,0 +1,89 @@
{
"name": "matrix-spray-web",
"type": "module",
"version": "0.0.8",
"description": "",
"author": "",
"license": "ISC",
"keywords": [],
"main": "index.js",
"scripts": {
"dev": "concurrently -n server,client -c green,blue \"node server/index.js\" \"vite --mode dev\"",
"test": "vite --mode test",
"prod": "vite --mode prod",
"pre": "vite --mode pre",
"build": "vite build --mode dev",
"build:test": "vite build --mode test",
"build:prod:patch": "node increment-version.js patch && vite build --mode prod",
"build:prod:minor": "node increment-version.js minor && vite build --mode prod",
"build:prod:major": "node increment-version.js major && vite build --mode prod",
"build:pre": "vite build --mode pre",
"build:dev": "vite build --mode dev",
"prepare": "husky",
"lint:lint-staged": "lint-staged",
"lint": "vue-tsc --noEmit --skipLibCheck && eslint",
"eslint": "eslint --fix --ext .ts,.vue src",
"prettier": "prettier --write ."
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"autoprefixer": "^10.4.20",
"axios": "1.8.2",
"cssnano": "^7.0.6",
"element-plus": "^2.9.5",
"express": "^5.1.0",
"konva": "^9.3.18",
"lodash": "^4.17.21",
"pinia": "^3.0.1",
"pinia-plugin-persistedstate": "^4.2.0",
"postcss": "^8.5.3",
"postcss-aspect-ratio-mini": "^1.1.0",
"postcss-import": "^16.1.0",
"postcss-px-to-viewport-8-plugin": "^1.2.5",
"postcss-url": "^10.1.3",
"postcss-viewport-units": "^0.1.6",
"postcss-write-svg": "^3.0.1",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
"ws": "^8.18.1"
},
"devDependencies": {
"@antfu/eslint-config": "^4.3.0",
"@commitlint/cli": "^19.7.1",
"@commitlint/config-conventional": "^19.7.1",
"@types/node": "^22.13.5",
"@typescript-eslint/eslint-plugin": "^8.25.0",
"@typescript-eslint/parser": "^8.25.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/eslint-config-prettier": "^10.2.0",
"concurrently": "^9.1.2",
"eslint": "^9.21.0",
"eslint-config-prettier": "^10.0.2",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-vue": "^9.32.0",
"husky": "^9.1.7",
"lint-staged": "^15.4.3",
"prettier": "^3.5.2",
"sass": "^1.85.1",
"semver": "^7.7.1",
"typescript": "^5.7.3",
"unplugin-auto-import": "^19.1.1",
"unplugin-vue-components": "^28.4.1",
"vite": "6.2.6",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-eslint": "^1.8.1",
"vue-tsc": "^2.2.4"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"eslint --fix",
"prettier --write",
"lint-staged"
]
}
}

BIN
public/favicon.ico

24
server/index.js

@ -0,0 +1,24 @@
// const express = require('express')
import express from 'express'
import { authRoutes } from './routes/auth.js'
import { debugRoutes } from './routes/control.js'
import { oreRoutes } from './routes/ore.js'
import { pointRoutes } from './routes/point.js'
import { initWebSocketServer } from './utils/websocket.js'
const app = express()
const PORT = 8080 // 可根据需要更改端口号
app.listen(PORT, () => {
console.log(`服务器已启动,正在监听端口 ${PORT}`)
})
app.use(express.json())
// 初始化 WebSocket 服务
initWebSocketServer()
// 注册路由模块
debugRoutes(app)
authRoutes(app)
oreRoutes(app)
pointRoutes(app)

33
server/routes/auth.js

@ -0,0 +1,33 @@
const baseUrl = '/api/auth'
export const authRoutes = (app) => {
app.post(`${baseUrl}/login`, (req, res) => {
// const { username, password } = req.body
const mockResponse = {
code: '0',
msg: '成功',
data: {
id: 1,
createTime: '2025-04-27 07:44:01',
updateTime: '2025-04-27 07:44:01',
username: 'admin',
nickname: 'Admin',
password: null,
role: 'ADMIN',
deleted: 'DISABLE',
fixedUser: 'ENABLE',
},
}
setTimeout(() => {
res.json(mockResponse)
}, 2000)
})
app.post(`${baseUrl}/logout`, (req, res) => {
// const { username, password } = req.body
const mockResponse = {
code: '0',
msg: '成功',
data: null,
}
res.json(mockResponse)
})
}

74
server/routes/control.js

@ -0,0 +1,74 @@
import { broadcast } from '../utils/websocket.js'
export const debugRoutes = (app) => {
const statusList = ['info', 'warn', 'success', 'error', 'finish']
app.post('/api/debug/cmd', (req, res) => {
const { commandId, command, params } = req.body
console.log('收到命令:', command, '参数:', params)
// 模拟返回数据
const mockResponse = {
code: '0',
msg: '成功',
data: null,
}
let messageNum = 0
// 异步广播消息
setTimeout(() => {
res.json(mockResponse)
const poll = setInterval(() => {
if (messageNum === 10) {
clearInterval(poll)
}
broadcast({
type: 'cmd_debug',
data: {
commandId,
command,
status: statusList[Math.floor(Math.random() * statusList.length)],
title: `步骤${messageNum}执行完成`,
content: `具体信息${messageNum}`,
},
})
messageNum++
}, Math.floor(Math.random() * (1000 - 500 + 1)) + 500)
}, 1000)
})
app.post('/api/cmd', (req, res) => {
const { commandId, command, params } = req.body
console.log('收到命令:', command, '参数:', params)
// 模拟返回数据
const mockResponse = {
code: '0',
msg: '成功',
data: null,
}
let messageNum = 0
// 异步广播消息
setTimeout(() => {
res.json(mockResponse)
const poll = setInterval(() => {
if (messageNum === 10) {
clearInterval(poll)
}
broadcast({
type: 'cmd_debug',
data: {
commandId,
command,
status: statusList[Math.floor(Math.random() * statusList.length)],
title: `步骤${messageNum}执行完成`,
content: `具体信息${messageNum}`,
},
})
messageNum++
}, Math.floor(Math.random() * (1000 - 500 + 1)) + 500)
}, 1000)
})
}

33
server/routes/ore.js

@ -0,0 +1,33 @@
const baseUrl = '/api/ores'
export const oreRoutes = (app) => {
app.get(`${baseUrl}/list`, (req, res) => {
const mockResponse = {
code: '0',
data: {
list: [
{
id: 1,
oresName: '金矿石2',
createTime: '2025-04-27 15:54:32',
updateTime: '2025-04-27 15:54:32',
craftsList: [
{
id: 1,
createTime: '2025-04-27 15:55:13',
updateTime: '2025-04-27 15:55:13',
name: '工艺2',
steps: '[{"method":"upTray"},{"method":"downTray"},{"method":"addLiquid","params":{"tubeSolList":[{"tubeNum":15,"addLiquidList":[{"solId":15,"volume":20}]}]}},{"method":"moveToSol"},{"method":"moveToHeat"},{"method":"shaking","params":{"second":6}},{"method":"startHeating","params":{"temperature":200}},{"method":"stopHeating"},{"method":"takePhoto"},{"method":"delay","params":{"second":2}}]',
oresId: 1,
},
],
},
],
total: 1,
},
msg: '成功',
}
setTimeout(() => {
res.json(mockResponse)
}, 1000)
})
}

31
server/routes/point.js

@ -0,0 +1,31 @@
const baseUrl = '/api/device-point'
export const pointRoutes = (app) => {
app.get(`${baseUrl}/list`, (req, res) => {
const mockResponse = {
code: '0',
data: [
{
id: 2,
name: '托盘夹取位置',
code: 'trayPick',
type: '直线距离',
position: null,
},
],
msg: '成功',
}
setTimeout(() => {
res.json(mockResponse)
}, 1000)
})
app.put(`${baseUrl}`, (req, res) => {
const mockResponse = {
code: '0',
data: null,
msg: '成功',
}
setTimeout(() => {
res.json(mockResponse)
}, 2000)
})
}

28
server/utils/websocket.js

@ -0,0 +1,28 @@
import { WebSocketServer } from 'ws'
export const clients = new Set()
export const broadcast = (message) => {
try {
const jsonMessage = JSON.stringify(message)
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(jsonMessage)
}
})
}
catch (e) {
console.log('广播发送失败:', e, message)
}
}
export const initWebSocketServer = () => {
const wss = new WebSocketServer({ port: 9527 })
wss.on('connection', (ws) => {
clients.add(ws)
ws.on('close', () => {
console.log('客户端断开')
})
})
}

17
src/apis/user.ts

@ -0,0 +1,17 @@
import { createWebSocket } from 'libs/socket'
const wsClient = createWebSocket()
export const login = async (params: User.Login) => {
console.log('params---', params)
const res = await wsClient.waitAndSend({
messageType: 'Command',
fnName: 'login',
className: 'UserMgrService',
messageId: `msg_${Date.now()}`,
params: {
...params,
},
})
console.log('res----', res)
return res
}

77
src/app.vue

@ -0,0 +1,77 @@
<script setup lang='ts'>
import { onMounted } from 'vue'
onMounted(async () => {
console.log('--------1----------')
})
</script>
<template>
<!-- 进度条容器 -->
<!-- <div v-if='progress < 100' class='main-content'>
<div class='progress-container'>
<div class='progress-bar' :style='{ width: `${progress}%` }' />
<div class='progress-text'>
v{{ version }}系统初始化中 {{ progress }}%
</div>
</div>
</div> -->
<router-view v-slot="{ Component }" class="main-content">
<transition name="">
<component :is="Component" />
</transition>
</router-view>
</template>
<style scoped lang='scss'>
.main-content {
width: 100%;
height: 100%;
background: url('assets/images/background.svg') no-repeat center;
background-size: cover;
overflow: hidden;
}
.login-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background: #f0f2f5;
}
img {
width: 600px;
position: absolute;
top: 40%;
right: 20%;
}
.progress-container {
width: 50%;
height: 20px;
background: #e4e7ed;
border-radius: 30px;
position: relative;
top: 90%;
margin: 0 auto;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #1989FA, #096ae0);
border-radius: 30px;
transition: width 0.3s ease;
}
.progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 12px;
line-height: 12px;
font-weight: 500;
}
</style>

1
src/assets/images/background-login.svg
File diff suppressed because it is too large
View File

1
src/assets/images/background.svg
File diff suppressed because it is too large
View File

22
src/assets/images/close-device.svg

@ -0,0 +1,22 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_447_4248)">
<circle cx="54" cy="50" r="50" fill="url(#paint0_linear_447_4248)"/>
<path d="M72.0426 33.9687L72.0427 33.9689C81.9858 43.9092 81.9857 60.0883 72.0427 70.031C69.6784 72.4061 66.8664 74.2891 63.7694 75.5711C60.6722 76.8532 57.3514 77.5088 53.9991 77.4999C50.6475 77.5091 47.3273 76.8538 44.2309 75.5718C41.134 74.2897 38.3223 72.4062 35.9587 70.0305C26.0137 60.0878 26.0137 43.9091 35.9591 33.9689L72.0426 33.9687ZM72.0426 33.9687C67.2213 29.1526 60.8158 26.5 53.9997 26.5C47.1837 26.5 40.7756 29.1525 35.9592 33.9688L72.0426 33.9687ZM53.9983 31.25L54.001 31.25C56.7285 31.2426 59.4303 31.7759 61.9501 32.8192C64.4699 33.8624 66.7576 35.3948 68.6808 37.3277L68.6818 37.3286C76.7734 45.4183 76.7734 58.5841 68.6818 66.6738L68.681 66.6746C66.7571 68.6065 64.4692 70.1381 61.9495 71.1809C59.4298 72.2237 56.7282 72.757 54.001 72.7499L53.9984 72.7499C51.2712 72.757 48.5696 72.2237 46.0499 71.1809C43.5302 70.1381 41.2422 68.6065 39.3184 66.6746L39.3176 66.6738C31.226 58.5841 31.226 45.4183 39.3176 37.3286L39.3186 37.3276C41.2417 35.3947 43.5294 33.8622 46.0492 32.819C48.569 31.7757 51.2708 31.2424 53.9983 31.25ZM63.8581 58.4937L57.3597 51.9987L63.8583 45.5036C64.079 45.283 64.254 45.0212 64.3735 44.7329C64.493 44.4447 64.5544 44.1357 64.5544 43.8237C64.5544 43.5117 64.493 43.2028 64.3735 42.9145C64.254 42.6263 64.079 42.3644 63.8583 42.1438C63.6376 41.9232 63.3756 41.7483 63.0872 41.6289C62.7989 41.5096 62.4899 41.4481 62.1778 41.4481C61.8658 41.4481 61.5568 41.5096 61.2684 41.6289C60.9801 41.7483 60.7181 41.9232 60.4974 42.1438L53.9984 48.6393L47.4995 42.1438C47.0537 41.6983 46.4493 41.4481 45.819 41.4481C45.1888 41.4481 44.5843 41.6983 44.1386 42.1438C43.6929 42.5893 43.4424 43.1936 43.4424 43.8237C43.4424 44.4539 43.6929 45.0581 44.1386 45.5036L50.6372 51.9987L44.1386 58.4938C43.6929 58.9393 43.4424 59.5435 43.4424 60.1737C43.4424 60.4857 43.5039 60.7946 43.6234 61.0829C43.7428 61.3711 43.9179 61.633 44.1386 61.8536C44.3593 62.0742 44.6213 62.2491 44.9096 62.3685C45.198 62.4878 45.507 62.5493 45.819 62.5493C46.4493 62.5493 47.0537 62.2991 47.4995 61.8536L53.9984 55.3581L60.4964 61.8525C60.4965 61.8527 60.4966 61.8528 60.4968 61.853C60.7171 62.0743 60.9789 62.25 61.2673 62.3699C61.5559 62.4898 61.8653 62.5516 62.1778 62.5516C62.4904 62.5516 62.7998 62.4898 63.0884 62.3699C63.3764 62.2501 63.638 62.0747 63.8581 61.8537C64.0789 61.6331 64.2541 61.3713 64.3736 61.083C64.4932 60.7947 64.5547 60.4857 64.5547 60.1737C64.5547 59.8616 64.4932 59.5526 64.3736 59.2644C64.2541 58.9762 64.079 58.7143 63.8583 58.4938C63.8582 58.4937 63.8582 58.4937 63.8581 58.4937Z" fill="white" stroke="white"/>
</g>
<defs>
<filter id="filter0_d_447_4248" x="0" y="0" width="108" height="108" 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.202062 0 0 0 0 0.442832 0 0 0 0 0.789146 0 0 0 1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_447_4248"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_447_4248" result="shape"/>
</filter>
<linearGradient id="paint0_linear_447_4248" x1="30.5" y1="17" x2="84.5" y2="100" gradientUnits="userSpaceOnUse">
<stop stop-color="#6DB1F7"/>
<stop offset="1" stop-color="#317BEB"/>
</linearGradient>
</defs>
</svg>

1
src/assets/images/empty.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="160" height="217" viewBox="0 0 160 217"><defs><clipPath id="master_svg0_701_8873"><rect x="0" y="0" width="160" height="217" rx="0"/></clipPath><linearGradient x1="0.8473145961761475" y1="-0.13048571348190308" x2="-0.21846741185260635" y2="0.45531219158762304" id="master_svg1_701_9703"><stop offset="0%" stop-color="#9CA0FF" stop-opacity="1"/><stop offset="100%" stop-color="#9CCFFF" stop-opacity="1"/></linearGradient><linearGradient x1="1.0152618885040283" y1="0.07957261055707932" x2="0.19026522035783114" y2="1.0885049011631125" id="master_svg2_701_9704"><stop offset="0%" stop-color="#F2F3FF" stop-opacity="1"/><stop offset="100%" stop-color="#F2F9FF" stop-opacity="1"/></linearGradient></defs><g clip-path="url(#master_svg0_701_8873)"><g><rect x="41.62646484375" y="0" width="76.74667358398438" height="42.228694915771484" rx="5" fill="url(#master_svg1_701_9703)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><rect x="0" y="21.1171875" width="160" height="195.88375854492188" rx="5" fill="url(#master_svg2_701_9704)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M108.87600390624999,94.94093875L51.01304390625,94.94093875C48.43994390625,94.94098875,46.35400390625,92.85729875,46.35400390625,90.28692875C46.35605003625,87.71803875,48.44143390625,85.6366722972,51.01304390625,85.63671875L108.87590390625,85.63671875C111.44750390625,85.6366722972,113.53290390625,87.71803875,113.53490390625,90.28692875C113.53500390625,92.85724875,111.44910390625,94.94098875,108.87600390624999,94.94093875Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M108.87600390624999,123.71047L51.01304390625,123.71047C48.43994390625,123.71052,46.35400390625,121.62683,46.35400390625,119.05646C46.35605003625,116.48757,48.44143390625,114.4062035472,51.01304390625,114.40625L108.87590390625,114.40625C111.44750390625,114.4062035472,113.53290390625,116.48757,113.53490390625,119.05646C113.53500390625,121.62678,111.44910390625,123.71052,108.87600390624999,123.71047Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M108.87600390624999,152.48000125L51.01304390625,152.48000125C48.43994390625,152.48000125,46.35400390625,150.39631125,46.35400390625,147.82599125C46.35614304625,145.25715125,48.44143390625,143.17578125,51.01304390625,143.17578125L108.87590390625,143.17578125C111.44750390625,143.17578125,113.53280390625,145.25715125,113.53490390625,147.82599125C113.53500390625,150.39631125,111.44910390625,152.48000125,108.87600390624999,152.48000125Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/error.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="master_svg0_685_8859"><rect x="0" y="0" width="80" height="80" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_685_8859)"><g><path d="M39.9853890625,4.94140625C20.7118890625,4.94140625,4.9462890625,20.70700625,4.9462890625,39.98050625C4.9462890625,59.25390625,20.7118890625,75.01950625,39.9853890625,75.01950625C59.2587890625,75.01950625,75.0243890625,59.25390625,75.0243890625,39.98050625C75.0243890625,20.70700625,59.2587890625,4.94140625,39.9853890625,4.94140625ZM56.7274890625,52.05080625C57.8993890625,53.22260625,57.8993890625,55.36330625,56.7274890625,56.52730625C56.1415890625,57.11330625,55.3681890625,57.50390625,54.3915890625,57.50390625C53.6103890625,57.50390625,52.6415890625,57.11330625,52.0556890625,56.52730625L40.7665890625,45.23830625L29.4774890625,56.52730625C28.3056890625,57.69920625,26.1650890625,57.69920625,25.0009890625,56.52730625C23.8368890625,55.35550625,23.8290890625,53.21480625,25.0009890625,52.05080625L36.2900890625,40.76170625L25.0009890625,29.47260625C24.4150890625,28.88670625,24.0243890625,28.11330625,24.0243890625,27.13670625C24.0243890625,26.35550625,24.4150890625,25.38670625,25.0009890625,24.80080625C26.1728890625,23.62890625,28.3134890625,23.62890625,29.4774890625,24.80080625L40.7665890625,36.089806249999995L52.0556890625,24.80080625C52.6415890625,24.21480625,53.4150890625,23.82420625,54.3915890625,23.82420625C55.1728890625,23.82420625,56.1415890625,24.21480625,56.7275890625,24.80080625C57.3134890625,25.38670625,57.7040890625,26.16020625,57.7040890625,27.13670625C57.7040890625,27.91800625,57.3134890625,28.88670625,56.7275890625,29.47260625L45.4384890625,40.76170625L56.7274890625,52.05080625Z" fill="#DF1515" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/expand.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="30.666667938232422" height="26.83333396911621" viewBox="0 0 30.666667938232422 26.83333396911621"><g><path d="M0,0L30.6667,0L30.6667,3.83333L0,3.83333L0,0ZM0,23L30.6667,23L30.6667,26.8333L0,26.8333L0,23 ZM0,11.5L30.6667,11.5L30.6667,15.3333L0,15.3333L0,11.5Z" fill="#1989FA" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

1
src/assets/images/icon_add_s.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="26.303199768066406" height="26.303173065185547" viewBox="0 0 26.303199768066406 26.303173065185547"><g><path d="M24.5875,14.8666L14.8674,14.8666L14.8674,24.5882C14.8674,25.5356,14.099,26.3032,13.1516,26.3032C12.2043,26.3032,11.4359,25.5356,11.4359,24.5882L11.4359,14.8666L1.71574,14.8666C0.767578,14.8666,0,14.099,0,13.1516C0,12.2046,0.767666,11.4366,1.71574,11.4366L11.4359,11.4366L11.4359,1.71495C11.4359,0.76793,12.2042,0,13.1516,0C14.099,0,14.8673,0.767959,14.8673,1.71495L14.8673,11.4367L24.5874,11.4367C25.5356,11.4367,26.3032,12.2046,26.3032,13.1515C26.3032,14.0989,25.5356,14.8665,24.5874,14.8665L24.5875,14.8666Z" fill="#479CF1" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

1
src/assets/images/icon_arr_s.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="15" height="23" viewBox="0 0 15 23"><g transform="matrix(-1,0,0,-1,30,46)"><path d="M27.436500000000002,23C27.436500000000002,23,30,25.37044,30,25.37044C30,25.37044,20.12696,34.5,20.12696,34.5C20.12696,34.5,30,43.629599999999996,30,43.629599999999996C30,43.629599999999996,27.436500000000002,46,27.436500000000002,46C27.436500000000002,46,15,34.5,15,34.5C15,34.5,27.436500000000002,23,27.436500000000002,23C27.436500000000002,23,27.436500000000002,23,27.436500000000002,23Z" fill-rule="evenodd" fill="#384D5D" fill-opacity="1"/></g></svg>

1
src/assets/images/icon_del_s.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="33" height="33" viewBox="0 0 33 33"><defs><clipPath id="master_svg0_685_8832"><rect x="0" y="0" width="33" height="33" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_685_8832)"><g><path d="M28.5707296875,29.2627375C27.6653296875,30.1682375,26.1906296875,30.1682375,25.2831296875,29.2627375L4.4580476875,8.4376975C3.5526096875,7.5301975,3.5505466875,6.0575675,4.4580476875,5.1500705C5.3614196875,4.2425705,6.8361096875000005,4.2425705,7.7477296875,5.1500705L28.5707296875,25.9730375C29.4761296875,26.8847375,29.4803296875,28.3552375,28.5707296875,29.2627375ZM28.5460296875,8.4273875L7.7229796875000005,29.2503375C6.8134196875,30.1599375,5.3407996875,30.1599375,4.4332966875,29.2503375C3.5257966875,28.3449375,3.5257966875,26.8743375,4.4353596875,25.9627375L25.2583296875,5.1418205C26.1679296875,4.2343205,27.6426296875,4.2343205,28.5460296875,5.1397585C29.4555296875,6.0472575,29.4514296875,7.519887499999999,28.5460296875,8.4273875Z" fill="#7F7F7F" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/ing.svg
File diff suppressed because it is too large
View File

23
src/assets/images/init-device.svg

@ -0,0 +1,23 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_446_4242)">
<circle cx="54" cy="50" r="50" fill="url(#paint0_linear_446_4242)"/>
<path d="M57.3791 29.6668V24L46.6994 32.2822L57.3791 40.5644V35.5204C61.158 36.2595 64.5868 38.2266 67.1323 41.1158C69.6777 44.005 71.1972 47.6542 71.4544 51.4962C71.7116 55.3381 70.6921 59.1574 68.5545 62.3601C66.4169 65.5627 63.2809 67.9693 59.6342 69.2056C55.9875 70.4419 52.0345 70.4386 48.39 69.1961C44.7454 67.9537 41.6134 65.5419 39.4812 62.3356C37.3489 59.1293 36.3359 55.3084 36.5996 51.4669C36.8632 47.6254 38.3888 43.9787 40.9392 41.0938L36.5801 37.2329C33.1358 41.1068 31.0822 46.019 30.7447 51.1917C30.4072 56.3643 31.8051 61.5017 34.7168 65.7903C37.6285 70.0789 41.8878 73.2736 46.8201 74.8683C51.7523 76.4631 57.0756 76.3668 61.947 74.5947C66.8183 72.8227 70.9593 69.4761 73.714 65.085C76.4688 60.6939 77.6799 55.5093 77.1556 50.3523C76.6313 45.1952 74.4015 40.3604 70.8193 36.6136C67.2372 32.8668 62.5074 30.4222 57.3791 29.6668Z" fill="white"/>
<path d="M43.8965 52.6771C43.8935 54.0079 44.1531 55.3262 44.6603 56.5565C45.1675 57.7869 45.9124 58.9051 46.8523 59.8472C47.7923 60.7892 48.9088 61.5366 50.1381 62.0466C51.3673 62.5566 52.685 62.8191 54.0158 62.8191C55.3466 62.8191 56.6643 62.5566 57.8935 62.0466C59.1227 61.5366 60.2392 60.7892 61.1792 59.8472C62.1191 58.9051 62.864 57.7869 63.3713 56.5565C63.8785 55.3262 64.138 54.0079 64.135 52.6771C64.138 51.3463 63.8785 50.028 63.3713 48.7977C62.864 47.5673 62.1191 46.4491 61.1792 45.507C60.2392 44.565 59.1227 43.8176 57.8935 43.3076C56.6643 42.7977 55.3466 42.5352 54.0158 42.5352C52.685 42.5352 51.3673 42.7977 50.1381 43.3076C48.9088 43.8176 47.7923 44.565 46.8523 45.507C45.9124 46.4491 45.1675 47.5673 44.6603 48.7977C44.1531 50.028 43.8935 51.3463 43.8965 52.6771Z" fill="white"/>
</g>
<defs>
<filter id="filter0_d_446_4242" x="0" y="0" width="108" height="108" 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.906392 0 0 0 0 0.608473 0 0 0 0 0.253262 0 0 0 1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_446_4242"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_446_4242" result="shape"/>
</filter>
<linearGradient id="paint0_linear_446_4242" x1="30.5" y1="17" x2="84.5" y2="100" gradientUnits="userSpaceOnUse">
<stop stop-color="#F6C058"/>
<stop offset="1" stop-color="#F29B42"/>
</linearGradient>
</defs>
</svg>

1
src/assets/images/liquied/liquied_bottle.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="162.44374084472656" height="227.99989318847656" viewBox="0 0 162.44374084472656 227.99989318847656"><g><path d="M0,54.0618L0,64.2474C0,65.1128,0.699314,65.8144,1.56196,65.8144C2.4246,65.8144,3.12392,66.516,3.12392,67.3814L3.12392,73.6495C3.12392,74.5149,2.4246,75.2165,1.56196,75.2165C0.699314,75.2165,0,75.918,0,76.7835L0,90.8866C0,91.752,0.699314,92.4536,1.56196,92.4536C2.4246,92.4536,3.12392,93.1551,3.12392,94.0206L3.12392,100.289C3.12392,101.154,2.4246,101.856,1.56196,101.856C0.699314,101.856,0,102.557,0,103.423L0,122.227C0,123.092,0.699314,123.794,1.56196,123.794C2.4246,123.794,3.12392,124.495,3.12392,125.361L3.12392,131.629C3.12392,132.494,2.4246,133.196,1.56196,133.196C0.699314,133.196,0,133.897,0,134.763L0,153.567C0,154.432,0.699314,155.134,1.56196,155.134C2.4246,155.134,3.12392,155.836,3.12392,156.701L3.12392,162.969C3.12392,163.834,2.4246,164.536,1.56196,164.536C0.699314,164.536,0,165.238,0,166.103L0,183.34C0,184.206,0.699314,184.907,1.56196,184.907C2.4246,184.907,3.12392,185.609,3.12392,186.474L3.12392,193.526C3.12392,194.391,2.4246,195.093,1.56196,195.093C0.699314,195.093,0,195.794,0,196.66L0,206.062C0,218.178,9.79038,228,21.8674,228L140.576,228C152.653,228,162.444,218.178,162.444,206.062L162.444,196.66C162.444,195.794,161.744,195.093,160.882,195.093C160.019,195.093,159.32,194.391,159.32,193.526L159.32,186.474C159.32,185.609,160.019,184.907,160.882,184.907C161.744,184.907,162.444,184.206,162.444,183.34L162.444,166.103C162.444,165.238,161.744,164.536,160.882,164.536C160.019,164.536,159.32,163.834,159.32,162.969L159.32,156.701C159.32,155.836,160.019,155.134,160.882,155.134C161.744,155.134,162.444,154.432,162.444,153.567L162.444,134.763C162.444,133.897,161.744,133.196,160.882,133.196C160.019,133.196,159.32,132.494,159.32,131.629L159.32,125.361C159.32,124.495,160.019,123.794,160.882,123.794C161.744,123.794,162.444,123.092,162.444,122.227L162.444,103.423C162.444,102.557,161.744,101.856,160.882,101.856C160.019,101.856,159.32,101.154,159.32,100.289L159.32,94.0206C159.32,93.1551,160.019,92.4536,160.882,92.4536C161.744,92.4536,162.444,91.752,162.444,90.8866L162.444,76.7835C162.444,75.918,161.744,75.2165,160.882,75.2165C160.019,75.2165,159.32,74.5149,159.32,73.6495L159.32,67.3814C159.32,66.516,160.019,65.8144,160.882,65.8144C161.744,65.8144,162.444,65.1128,162.444,64.2474L162.444,54.0618C162.444,41.9457,152.653,32.1237,140.576,32.1237L134.962,32.1237C132.711,32.1237,131.583,29.3931,133.175,27.7961C137.914,23.042,140.576,16.594,140.576,9.87062L140.576,4.70103C140.576,2.10472,138.478,0,135.89,0L26.5533,0C23.9654,0,21.8674,2.10472,21.8674,4.70103L21.8674,9.87062C21.8674,16.594,24.5297,23.042,29.2685,27.7961C30.8603,29.3931,29.7329,32.1237,27.4817,32.1237L21.8674,32.1237C9.79038,32.1237,0,41.9457,0,54.0618Z" fill="#EEEFF8" fill-opacity="1"/></g></svg>

1
src/assets/images/login.svg
File diff suppressed because it is too large
View File

1
src/assets/images/logo.svg
File diff suppressed because it is too large
View File

1
src/assets/images/logout.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="42" height="43" viewBox="0 0 42 43"><g><g><path d="M23.9012,26.80821171875L23.5184,26.80821171875C19.5186,26.80821171875,15.5189,26.80861171875,11.519,26.80821171875C10.926,26.80801171875,10.5396,26.52971171875,10.4443,26.03191171875C10.4255,25.93251171875,10.4273,25.82801171875,10.4273,25.72631171875C10.4266,22.08721171875,10.4265,18.44831171875,10.4268,14.80931171875C10.4269,14.11901171875,10.792,13.75181171875,11.4767,13.75181171875C15.4946,13.75161171875,19.5126,13.75161171875,23.5307,13.75161171875L23.9012,13.75161171875L23.9012,13.42041171875C23.9012,10.18168171875,23.9008,6.94273171875,23.9016,3.70375171875C23.9016,3.25804771875,24.1092,2.90257571875,24.4607,2.76641631875C24.8652,2.60961481875,25.224,2.68183999875,25.5289,3.01164571875C25.7037,3.20077071875,25.8941,3.3747387187499998,26.0736,3.55867171875C28.3386,5.87259171875,30.6032,8.18756171875,32.8676,10.50147171875C35.7762,13.47271171875,38.6848,16.44331171875,41.5933,19.41441171875C42.0776,19.90851171875,42.0802,20.42981171875,41.6017,20.91861171875C37.4394,25.17281171875,33.2774,29.42731171875,29.1138,33.67981171875C27.9297,34.88921171875,26.7392,36.09131171875,25.5561,37.30171171875C25.2516,37.61371171875,24.912,37.75041171875,24.4963,37.58871171875C24.092,37.43171171875,23.9017,37.10601171875,23.9017,36.59371171875C23.901,33.45751171875,23.9012,30.32081171875,23.9012,27.18461171875L23.9012,26.80821171875L23.9012,26.80821171875ZM16.4243,2.86945471875L16.4243,6.546731718749999L16.0943,6.546731718749999C13.049,6.546731718749999,10.0037,6.54631171875,6.95843,6.54694171875C5.02868,6.54723171875,3.60763,8.00513171875,3.60755,9.98472171875C3.60726,16.83461171875,3.61953,23.68451171875,3.59949,30.53391171875C3.59397,32.34621171875,4.94067,33.65191171875,6.18574,33.89041171875C6.46085,33.94251171875,6.74508,33.96611171875,7.02513,33.96681171875C10.0431,33.97221171875,13.0612,33.970111718750005,16.0793,33.970111718750005L16.4189,33.970111718750005L16.4189,37.62641171875C16.3759,37.63521171875,16.3258,37.65491171875,16.2756,37.65491171875C13.0666,37.65491171875,9.85733,37.68831171875,6.64918,37.64061171875C3.51369,37.59461171875,0.737073,35.15841171875,0.138685,32.005211718750004C0.0542352,31.56101171875,0.0129305,31.10101171875,0.0124397,30.64841171875C0.00466952,23.72381171875,-0.0132019,16.79961171875,0.0166111,9.87552171875C0.0290843,6.98330171875,1.43263,4.90707171875,3.88372,3.55774671875C4.74846,3.08148071875,5.70366,2.86639671875,6.68823,2.86388471875C9.8698,2.85509271875,13.0514,2.86053471875,16.2331,2.86074471875C16.2868,2.86078671875,16.3405,2.86560171875,16.4243,2.86945471875Z" fill="#1989FA" fill-opacity="1"/></g></g></svg>

1
src/assets/images/menuIcon/n_debug.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="master_svg0_592_42038"><rect x="19" y="18.921875" width="41" height="41" rx="0"/></clipPath></defs><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g clip-path="url(#master_svg0_592_42038)"><g><path d="M53.8413984375,21.65234443077L25.1580984375,21.65234443077C23.2666884375,21.652344090385,21.733398779614,23.17788375,21.733399121728,25.05973375L21.733399121728,47.20904375L57.2666984375,47.20904375L57.2666984375,25.05973375C57.2670984375,23.17798375,55.7333984375,21.652344090385,53.8413984375,21.65234443077ZM52.9319984375,35.12904375C52.9319984375,35.83334375,52.3579984375,36.405643749999996,51.6500984375,36.406943749999996L47.5684984375,36.406943749999996C47.3869984375,36.40704375,47.2220984375,36.30194375,47.1462984375,36.13784375L46.7859984375,35.36184375C46.7178984375,35.21544375,46.5724984375,35.11984375,46.410498437499996,35.11504375C46.2483984375,35.11024375,46.0974984375,35.19694375,46.0206984375,35.33904375L42.2247984375,42.38224375C42.0768984375,42.65614375,41.7907984375,42.828143749999995,41.478398437500005,42.83104375C41.165898437500005,42.83394375,40.8765984375,42.66724375,40.7235984375,42.39624375L34.6923984375,31.69304375C34.6111984375,31.54864375,34.4531984375,31.46415375,34.2872984375,31.47640375C34.1214984375,31.48864375,33.9777984375,31.59540375,33.9187984375,31.75014375L32.3505984375,35.85744375C32.224298437499996,36.18814375,31.9057984375,36.40684375,31.5502384375,36.406943749999996L27.3519484375,36.406943749999996C26.6425784375,36.406943749999996,26.067528437500002,35.83474375,26.067528437500002,35.12904375C26.067528437500002,34.42324375,26.6425784375,33.85104375,27.3519484375,33.85104375L29.7753884375,33.85104375C30.1312484375,33.85104375,30.4494884375,33.63214375,30.5757584375,33.30154375L33.1400984375,26.58196375C33.2582984375,26.27280375,33.5454984375,26.05956375,33.8769984375,26.03496375C34.2084984375,26.01035375,34.5243984375,26.17881375,34.687298437500004,26.46711375L41.053898437499996,37.75784375C41.1302984375,37.89354375,41.2749984375,37.97704375,41.431298437500004,37.97554375C41.587698437499995,37.974143749999996,41.7307984375,37.887943750000005,41.804598437500005,37.75084375L45.789198437500005,30.36372375C45.9430984375,30.079963749999997,46.244798437499995,29.906903749999998,46.568698437500004,29.916573749999998C46.8925984375,29.926243749999998,47.1832984375,30.11697375,47.3197984375,30.40940375L48.6858984375,33.35554375C48.8261984375,33.65754375,49.129098437500005,33.85044375,49.4632984375,33.85104375L51.6500984375,33.85104375C52.3592984375,33.85104375,52.9344984375,34.423443750000004,52.9344984375,35.12904375L52.9319984375,35.12904375ZM21.733399121728,48.66654375L21.733399121728,53.77824375C21.733398779614,55.66014375,23.2666884375,57.18564375,25.1580984375,57.18564375L53.8413984375,57.18564375C55.7327984375,57.18564375,57.2660984375,55.66014375,57.2660984375,53.77824375L57.2660984375,48.66654375L21.733399121728,48.66654375ZM42.338998437499995,52.74404375C42.3368984375,53.44894375,41.7630984375,54.01984375,41.054598437500005,54.02194375L27.3519484375,54.02194375C26.6425784375,54.02194375,26.067528437500002,53.449743749999996,26.067528437500002,52.74404375C26.067528437500002,52.03824375,26.6425784375,51.46604375,27.3519484375,51.46604375L41.0519984375,51.46604375C41.761498437499995,51.46674375,42.3368984375,52.03814375,42.338998437499995,52.74404375ZM52.9319984375,52.74404375C52.9291984375,53.447443750000005,52.3570984375,54.01724375,51.6500984375,54.02064375L46.510498437500004,54.02064375C45.8010984375,54.02064375,45.2260984375,53.44854375,45.2260984375,52.74274375C45.2260984375,52.03694375,45.8010984375,51.46484375,46.510498437500004,51.46484375L51.6500984375,51.46484375C52.358098437500004,51.46834375,52.930598437499995,52.03954375,52.9319984375,52.74404375Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></g></svg>

1
src/assets/images/menuIcon/n_expe.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M54.037,56.006L28.80688,56.006C27.22599,56.006,25.93399,54.6781,25.93399,53.0441C25.93399,51.6375,26.888939999999998,50.4627,28.16489,50.1565L28.16489,21.0455056C25.82164,21.380591,24,23.46143,24,25.96836L24,53.0523C24,55.7785,26.15066,58,28.79886,58L54.037,58C54.5706,58,55,57.5574,55,57.0072C55.004000000000005,56.457,54.5706,56.006,54.037,56.006ZM42.742000000000004,37.799800000000005L41.847300000000004,37.799800000000005L41.847300000000004,39.1815L40.5031,39.1815L40.5031,40.1081L41.847300000000004,40.1081L41.847300000000004,41.4898L42.742000000000004,41.4898L42.742000000000004,40.1081L44.090199999999996,40.1081L44.090199999999996,39.1815L42.742000000000004,39.1815L42.742000000000004,37.799800000000005ZM44.090199999999996,29.05031L40.5031,29.05031L40.5031,33.3775L39.2994,35.6817C39.817,35.5824,40.334599999999995,35.5617,40.852199999999996,35.6155C42.2605,35.7644,42.569500000000005,36.8814,44.4393,36.8814C44.985,36.8814,45.4384,36.8193,45.807500000000005,36.6952L44.090199999999996,33.3981L44.090199999999996,29.05031ZM53.2425,21L30.09086,21L30.09086,50.1276L30.5563,50.1276C30.612470000000002,50.1358,30.67266,50.1358,30.73284,50.1358L53.2425,50.1358C54.125299999999996,50.1358,54.8475,49.3912,54.8475,48.4811L54.8475,22.65888C54.8515,21.744634,54.125299999999996,21.000000315617,53.2425,21ZM49.3224,42.424800000000005C49.1619,42.6978,48.881,42.8674,48.5721,42.875699999999995L36.0212,42.875699999999995C35.7042,42.875699999999995,35.4113,42.7061,35.2508,42.424800000000005C35.0903,42.1435,35.082300000000004,41.8001,35.2348,41.5105L39.5963,33.2161L39.5963,29.05031L38.5089,29.05031C38.2521,29.05031,38.0475,28.8352,38.0475,28.57457C38.0475,28.309820000000002,38.2561,28.09884,38.5089,28.09884L46.0643,28.09884C46.3211,28.09884,46.5257,28.31395,46.5257,28.57457C46.5257,28.83933,46.317099999999996,29.05031,46.0643,29.05031L44.9769,29.05031L44.9769,33.2203L46.561800000000005,36.231899999999996L49.3425,41.5105C49.490899999999996,41.8001,49.4869,42.1434,49.3224,42.424800000000005Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/n_home.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M20.0370799,43.6256C20.866486,47.6246,22.91091,51.222300000000004,25.94731,54.0277C26.3526,54.4028,26.9106,54.5752,27.46181,54.4956C28.0134,54.4165,28.49784,54.0943,28.77694,53.6208L31.1482,49.591300000000004C31.5442,48.9178,31.451999999999998,48.070499999999996,30.92,47.4942C29.68039,46.1482,28.77662,44.537800000000004,28.28009,42.7903C28.06083,42.015,27.34183,41.4784,26.52231,41.4784L21.82395,41.4784C21.27636,41.4781,20.757754,41.7198,20.411853,42.1363C20.0647341,42.552,19.9270634,43.0991,20.0370799,43.6256ZM44.1657,51.909C43.7696,51.233000000000004,42.9726,50.8869,42.1963,51.053799999999995C40.231899999999996,51.4761,38.1899,51.3965,36.2658,50.8227C35.453900000000004,50.580600000000004,34.579,50.9191,34.1541,51.6398L31.8262,55.5982C31.5578,56.055,31.5084,56.6046,31.691000000000003,57.1004C31.872999999999998,57.5967,32.2697,57.9884,32.7742,58.1703C34.9795,58.9695,37.3089,59.375,39.695,59.375C41.6678,59.375,43.6156,59.0954,45.482600000000005,58.543C46.0156,58.3847,46.446,57.9968,46.652,57.4891C46.8572,56.9806,46.814099999999996,56.408,46.535,55.9346L44.1657,51.909ZM52.5476,24.57127C52.2201,24.3027,51.806799999999996,24.15552,51.379999999999995,24.15542C51.2742,24.15542,51.1663,24.166330000000002,51.060500000000005,24.18424C50.531,24.2771,50.0703,24.59457,49.8016,25.05176L47.4685,29.01324C47.045100000000005,29.73472,47.183499999999995,30.6473,47.802800000000005,31.2165C49.39,32.6707,50.5347,34.5286,51.1096,36.5833C51.3275,37.3604,52.0476,37.8989,52.8691,37.899100000000004L57.568,37.899100000000004C58.1145,37.8988,58.6321,37.658,58.9784,37.2432C59.3258,36.8281,59.464,36.2815,59.3546,35.7553C58.4579,31.3953,56.0407,27.42316,52.5476,24.57127ZM46.652,21.88784C46.446600000000004,21.37975,46.0159,20.99153,45.482600000000005,20.833661C43.6053,20.279568,41.6553,19.99869145,39.695,20.00000417001C37.3089,20.00000417001,34.9795,20.405219,32.7742,21.20446C31.714199999999998,21.58978,31.262,22.8179,31.8262,23.77903L34.1541,27.73687C34.579,28.457549999999998,35.453900000000004,28.79609,36.2658,28.55402C37.3775,28.22171,38.5332,28.05317,39.6953,28.05394C40.530100000000004,28.05394,41.372299999999996,28.14349,42.1963,28.32119C42.9721,28.48767,43.7685,28.14262,44.1657,27.46794L46.5353,23.44182C46.8143,22.96858,46.857299999999995,22.39608,46.652,21.88784ZM57.568,41.4781L52.8691,41.4781C52.0475,41.477599999999995,51.327,42.0163,51.1096,42.7936C50.5345,44.848299999999995,49.3898,46.7063,47.802800000000005,48.160799999999995C47.1834,48.729,47.0449,49.6411,47.4685,50.3618L49.8016,54.3249C50.07,54.7824,50.5309,55.1001,51.060500000000005,55.1927C51.1663,55.2106,51.2742,55.2196,51.379999999999995,55.2196C51.8066,55.2202,52.2199,55.0737,52.5476,54.8057C56.0407,51.9518,58.4579,47.9814,59.3546,43.622C59.4641,43.0957,59.3259,42.549099999999996,58.9784,42.134C58.6326,41.718599999999995,58.1147,41.4778,57.568,41.4781ZM20.411568,37.241C20.757316,37.6573,21.27588,37.8989,21.82367,37.8989L26.52259,37.8989C27.34233,37.8986,28.06128,37.361999999999995,28.280369999999998,36.587C28.776699999999998,34.8389,29.68048,33.2279,30.920299999999997,31.8814C31.4524,31.3057,31.544600000000003,30.4588,31.1485,29.785890000000002L28.77722,25.75641C28.49772,25.28303,28.01361,24.96039,27.46209,24.87994C27.37433,24.86765,27.28578,24.86166,27.19713,24.86203C26.73679,24.86203,26.28729,25.03413,25.9476,25.349510000000002C22.91091,28.15468,20.866486,31.7521,20.0370799,35.7513C19.9271883,36.2779,20.0647273,36.825,20.411568,37.241Z" fill="#4F85FB" fill-opacity="1"/></g></g></svg>

1
src/assets/images/menuIcon/n_liquid.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M30.42768,34.2143L30.42768,52.673C30.42768,53.4027,31.06121,54.0357,31.77429,54.0357L48.5584,54.0357C49.2714,54.0357,49.794,53.4027,49.794,52.673L49.794,34.2143L30.42768,34.2143ZM47.8574,46.726600000000005C47.8574,47.091499999999996,47.5684,47.387299999999996,47.2118,47.387299999999996C46.8553,47.387299999999996,46.5663,47.091499999999996,46.5663,46.726600000000005L46.5663,42.762299999999996C46.5663,42.397400000000005,46.8553,42.101600000000005,47.2118,42.101600000000005C47.5684,42.101600000000005,47.8574,42.397400000000005,47.8574,42.762299999999996L47.8574,46.726600000000005ZM47.2673,40.780100000000004C46.910799999999995,40.780100000000004,46.6218,40.4844,46.6218,40.1194C46.6218,39.7545,46.910799999999995,39.4587,47.2673,39.4587C47.6239,39.4587,47.9129,39.7545,47.9129,40.1194C47.9129,40.484300000000005,47.6239,40.780100000000004,47.2673,40.780100000000004ZM54.7629,21L29.21229,21C24.827023,21,24,23.26509,24,24.28292C26.44097,24.63393,26.55442,24.67522,26.55442,27.318080000000002L26.55442,52.673C26.55442,55.5922,28.92203,58,31.77429,58L48.5383,58C51.3904,58,53.6673,55.5922,53.6673,52.673L53.6673,24.96429C53.6673,23.28368,54.6596,21.803098,54.7579,21.6456C54.856300000000005,21.488186,55,21.331926,55,21.236123C55,21.139411,54.9664,21,54.7629,21ZM51.0851,24.96429L51.0851,52.673C51.0851,54.153,50.081,55.3571,48.679500000000004,55.3571L31.77429,55.3571C30.352719999999998,55.3571,29.136589999999998,54.128,29.136589999999998,52.673L29.136589999999998,27.318080000000002C29.136589999999998,26.34254,29.22487,24.24163,28.8277,23.6877C28.90202,23.62221,29.07898,23.64286,29.19211,23.64286L51.1939,23.64286C51.1345,23.64286,51.0851,24.53474,51.0851,24.96429Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/n_liquid_config.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M25.010964,27.14686L25.010964,52.3976C25.00721385,52.5305,25.0362768,52.6662,25.0915901,52.791799999999995C25.490033,53.8368,27.08099,54.6141,29.95072,55.1751C33.25546,55.7635,36.6258,56.0395,39.9999,55.9955C43.375,56.0285,46.7406,55.7525,50.0501,55.1741C52.915099999999995,54.6031,54.536100000000005,53.8083,54.9083,52.7909C54.9636,52.6662,54.992599999999996,52.5342,54.9889,52.3976L54.9889,27.14686C55.003699999999995,27.099980000000002,55.003699999999995,27.04982,54.9889,27.00294L54.9889,26.77745C54.9889,25.48132,53.3829,24.50509,50.0454,23.860689999999998C46.734700000000004,23.255981,43.3715,22.9686265,40.0037,23.00271173C36.6286,22.9697126,33.26296,23.245622,29.95353,23.824024C26.64599,24.468420000000002,25.0109623,25.44373,25.0109623,26.74078C24.999922606,26.81525,24.999922606,26.89089,25.0109623,26.96536C24.996346,27.011960000000002,24.996346,27.06176,25.0109623,27.10836L25.0109623,27.14502L25.010964,27.14686ZM46.0047,44.9994C46.0122,44.4503,46.524100000000004,44.0048,47.1578,43.9975L51.8398,43.9975L51.8398,45.9976L47.1578,45.9976C46.524100000000004,45.994,46.0122,45.548500000000004,46.0047,44.9994ZM46.0047,40.4987C46.0122,39.950500000000005,46.524100000000004,39.504999999999995,47.1578,39.497699999999995L51.7292,39.497699999999995L51.7292,41.4868L47.1578,41.4868C46.5278,41.4868,46.0122,41.047799999999995,46.0047,40.4996L46.0047,40.4987ZM46.0047,35.9888C46.0122,35.4388,46.5278,35.001599999999996,47.1578,35.001599999999996L51.8398,35.001599999999996L51.8398,36.990700000000004L47.1578,36.990700000000004C46.524100000000004,36.9824,46.0122,36.537,46.0047,35.987899999999996L46.0047,35.9888ZM29.501649999999998,45.4953C29.501649999999998,44.674,29.71822,43.8637,30.13072,43.1533C31.08773,41.4645,32.13675,39.827200000000005,33.27327,38.2483L33.27327,38.1823L33.51327,38.054L33.578900000000004,37.9981L33.96984,37.9981L33.96984,38.0531L34.035470000000004,38.1191Q34.09172,38.1191,34.09172,38.186C35.5242,39.727599999999995,36.7882,41.411100000000005,37.8633,43.209199999999996C38.841300000000004,44.8373,38.690200000000004,46.8866,37.483599999999996,48.3607C36.2789,49.8228,34.27922,50.3746,32.49232,49.730199999999996C30.70542,49.0858,29.51572,47.3928,29.52697,45.4953L29.501649999999998,45.4953ZM27.45319,27.739919999999998C28.58383,26.75362,29.8326,26.11288,31.13293,25.858060000000002C34.019059999999996,25.06777,37.0069,24.68957,40.0037,24.73517C42.9756,24.6875,45.9494,25.06699,48.8744,25.858060000000002C50.174800000000005,26.10555,51.4273,26.74628,52.5542,27.739919999999998C51.419799999999995,28.71615,50.171,29.35688,48.8744,29.62179C45.9848,30.39315,42.9988,30.76495,40.0037,30.72635C37.0084,30.76678,34.02223,30.39495,31.13293,29.62179C29.83728,29.3633,28.58383,28.72623,27.45319,27.739919999999998Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/n_log.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M32,30.00793C32.8,30.00793,33.5,29.30731,33.5,28.506610000000002L33.5,22.50132C33.5,21.700617,32.8,21,32,21C31.2,21,30.5,21.700617,30.5,22.50132L30.5,28.506610000000002C30.5,29.30731,31.2,30.00793,32,30.00793ZM45,30.00793C45.8,30.00793,46.5,29.30731,46.5,28.506610000000002L46.5,22.50132C46.5,21.700617,45.8,21,45,21C44.2,21,43.5,21.700617,43.5,22.50132L43.5,28.506610000000002C43.5,29.30731,44.2,30.00793,45,30.00793ZM40,50.0255C40,45.1212,43,40.8174,47.2,39.0159L28.5,39.0159C27.7,39.0159,27,38.315200000000004,27,37.5145C27,36.7138,27.7,36.0132,28.5,36.0132L47.5,36.0132C48.3,36.0132,49,36.7138,49,37.5145C49,37.9149,48.8,38.215199999999996,48.6,38.5154C49.7,38.215199999999996,50.8,38.015,52,38.015C52.3,38.015,52.7,38.015,53,38.1151L53,29.00705C53,26.80511,51.2,25.00352,49,25.00352L49,28.506610000000002C49,31.0088,47,33.0106,44.5,33.0106C42,33.0106,40,31.0088,40,28.506610000000002L40,25.00352L36,25.00352L36,28.506610000000002C36,31.0088,34,33.0106,31.5,33.0106C29,33.0106,27,31.0088,27,28.506610000000002L27,25.00352C24.8,25.00352,23,26.80511,23,29.00705L23,55.03C23,57.2319,24.8,59.0335,27,59.0335L44.1,59.0335C41.6,56.8315,40,53.6287,40,50.0255ZM37.5,51.026399999999995L28.5,51.026399999999995C27.7,51.026399999999995,27,50.3258,27,49.525099999999995C27,48.7244,27.7,48.0238,28.5,48.0238L37.5,48.0238C38.3,48.0238,39,48.7244,39,49.525099999999995C39,50.3258,38.3,51.026399999999995,37.5,51.026399999999995ZM37.5,45.021100000000004L28.5,45.021100000000004C27.7,45.021100000000004,27,44.320499999999996,27,43.519800000000004C27,42.7191,27.7,42.0185,28.5,42.0185L37.5,42.0185C38.3,42.0185,39,42.7191,39,43.519800000000004C39,44.320499999999996,38.3,45.021100000000004,37.5,45.021100000000004ZM52,41.0176C47,41.0176,43,45.1212,43,50.0255C43,54.9299,47.1,59.0335,52,59.0335C56.9,59.0335,61,54.9299,61,50.0255C61,45.1212,57,41.0176,52,41.0176ZM55.5,53.0282L50.5,53.0282C49.7,53.0282,49,52.327600000000004,49,51.5269L49,45.5216C49,44.7209,49.7,44.0203,50.5,44.0203C51.3,44.0203,52,44.7209,52,45.5216L52,50.0255L55.5,50.0255C56.3,50.0255,57,50.7262,57,51.5269C57,52.327600000000004,56.3,53.0282,55.5,53.0282Z" fill="#4F85FB" fill-opacity="1"/></g></g></svg>

1
src/assets/images/menuIcon/n_ore.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M51.951499999999996,39.8059C50.843199999999996,40.323899999999995,49.9413,40.7615,48.9636,41.225899999999996C48.4242,40.9535,47.7542,40.408699999999996,47.004000000000005,40.2435C44.3744,39.6987,41.8501,42.1279,41.9554,44.9411C41.9554,45.378699999999995,41.593,46.0619,41.2348,46.1958C39.8694,46.687,39.2499,47.723,39.174099999999996,49.0894C39.0982,51.2194,38.9423,53.4297,41.5467,54.2513C41.7531,54.3049,41.829,54.7693,41.959599999999995,55.0417C41.652,55.2069,41.3149,55.5329,41.0072,55.5329C37.5305,55.5597,34.0496,55.5597,30.5729,55.5597C28.97572,55.5597,27.37854,55.5865,25.78137,55.5597C23.745912,55.5061,23,54.6577,23,52.527699999999996L23,23.88686C23,21.895306,23.720627,21.0468861,25.62966,21.020094C33.539699999999996,20.99330188,41.4497,20.99330188,49.364000000000004,21.020094C51.037,21.020094,51.9136,21.895306,51.9388,23.83327C52.0021,29.18278,51.951499999999996,34.5635,51.951499999999996,39.8059ZM37.6232,24.75761C37.6232,24.730809999999998,37.6232,24.730809999999998,37.6232,24.75761C35.2001,24.75761,32.776920000000004,24.730809999999998,30.35798,24.75761C29.17379,24.75761,28.19188,25.76678,28.21717,26.86079C28.26774,27.9816,29.144289999999998,28.79876,30.35798,28.79876C35.0737,28.79876,39.763999999999996,28.79876,44.4797,28.77197C45.950500000000005,28.77197,46.591,28.00839,46.565799999999996,26.56161C46.5405,25.44081,45.765100000000004,24.78886,44.4797,24.78886C42.183,24.730809999999998,39.915800000000004,24.75761,37.6232,24.75761ZM33.7841,36.3899C35.0189,36.3899,36.2578,36.4435,37.4673,36.3631C38.445,36.3095,39.1951,35.7335,39.2963,34.6171C39.4269,33.3624,38.6515,32.4336,37.6485,32.38C35.0737,32.2416,32.46928,32.4336,29.8902,32.5184C28.68073,32.5452,28.242449999999998,33.5544,28.26774,34.568C28.29302,35.7424,29.09372,36.3988,30.25262,36.3988L33.7841,36.3988L33.7841,36.3899ZM56.9495,50.3441C57.156,51.326499999999996,56.7177,51.9294,55.8412,52.3089C54.2693,52.9921,53.856300000000005,53.7825,54.1934,55.5016C54.3999,56.5644,53.7046,57.002,53.0851,57.4128C52.4403,57.8236,51.7956,58.3952,50.893699999999995,57.6048C49.6295,56.4572,48.727599999999995,56.6225,47.210499999999996,57.5245C46.6964,57.8236,45.8198,57.7968,45.2256,57.578C44.504999999999995,57.3057,43.7549,56.8145,43.9867,55.6669C44.3491,53.8941,43.5231,52.7465,42.081900000000005,52.143699999999995C40.9988,51.6793,41.1547,50.7237,41.18,49.9869C41.2053,49.415400000000005,41.6436,48.566900000000004,42.1071,48.3213C43.5231,47.584599999999995,44.1679,47.0085,44.0415,44.6062C43.965599999999995,43.324600000000004,44.787400000000005,43.021,45.4827,42.695C45.9463,42.4494,46.8228,42.3958,47.185199999999995,42.695C48.5001,43.815799999999996,49.7348,43.7577,50.948499999999996,42.7218C52.0821,41.7662,52.7269,42.775400000000005,53.5529,43.2398C54.3536,43.6774,54.2988,44.2757,54.0923,45.0706C53.7847,46.298500000000004,54.4547,47.6917,55.6136,48.0757C56.7177,48.4062,57.0802,49.143,56.9495,50.3441ZM45.7145,49.9333C45.6892,52.143699999999995,46.9787,53.5905,49.039500000000004,53.6173C50.7673,53.6441,52.259100000000004,52.2509,52.313900000000004,50.585300000000004C52.3645,48.2365,51.0497,46.682500000000005,48.9383,46.5977C47.210499999999996,46.5486,45.7398,48.049,45.7145,49.9333Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/n_setting.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><g><path d="M57.7309,36.6424L54.4199,35.1065C52.2821,34.1115,51.0169,31.80957,51.2919,29.41513L51.7134,25.70348C49.9764,24.13487,47.9673,22.91636,45.7913,22.111649L42.809,24.29289C40.9002,25.70218,38.3223,25.67794,36.438900000000004,24.23298L33.5495,22C31.3612,22.766417,29.33189,23.9468,27.56639,25.48018L27.92691,29.18911C28.16995,31.58721,26.871940000000002,33.8705,24.71933,34.8315L21.35269,36.3074C20.9039103,38.6357,20.883231,41.0297,21.291719,43.3658L24.60269,44.9071C26.74368,45.8995,28.01241,48.202,27.73869,50.5985L27.30925,54.2911C29.0484,55.858,31.056800000000003,57.0779,33.2313,57.8884L36.1897,55.7098C38.098,54.2997,40.6759,54.3229,42.559799999999996,55.767L45.4705,58C47.6601,57.2361,49.6906,56.0565,51.456199999999995,54.5225L51.0984,50.8054C50.8651,48.409099999999995,52.158699999999996,46.1352,54.306,45.1685L57.6461,43.6953C58.0967,41.3643,58.1179,38.9679,57.7044,36.6287L57.7309,36.6424ZM39.5113,49.514700000000005C34.3981,49.514700000000005,30.25307,45.2566,30.25307,40.0041C30.25307,34.7515,34.3981,30.49349,39.5113,30.49349C44.6245,30.49349,48.7696,34.7515,48.7696,40.0041C48.7696,45.2566,44.6245,49.514700000000005,39.5113,49.514700000000005Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M39.503226597900394,32.666666984558105C35.85293659790039,32.6648691245581,32.89285659790039,35.650166984558105,32.89285659790039,39.3333369845581C32.89285659790039,43.01646698455811,35.85293659790039,46.0017669845581,39.503226597900394,45.99996698455811C43.15095659790039,45.998166984558104,46.10715659790039,43.01396698455811,46.10715659790039,39.3333369845581C46.10715659790039,35.65270698455811,43.15095659790039,32.66846320455811,39.503226597900394,32.666666984558105ZM39.503226597900394,43.0462669845581C37.535416597900394,42.95376698455811,35.98716659790039,41.316986984558106,35.98716659790039,39.329296984558106C35.98716659790039,37.34159698455811,37.535416597900394,35.704856984558106,39.503226597900394,35.61227698455811C41.495636597900386,35.7097269845581,43.08915659790039,37.317586984558105,43.185756597900394,39.3279469845581C43.17395659790039,41.372516984558104,41.52956659790039,43.024566984558106,39.503226597900394,43.0274669845581L39.503226597900394,43.0462669845581Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></g></svg>

1
src/assets/images/menuIcon/n_user.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#EEEFF8" fill-opacity="1"/></g><g><path d="M29.44471,32.3043C29.44472,37.9952,34.0687,42.608599999999996,39.772800000000004,42.608599999999996C45.4768,42.608599999999996,50.100899999999996,37.9952,50.100899999999996,32.3043C50.100899999999996,26.6134,45.4768,22,39.772800000000004,22C34.0687,22,29.44472,26.6134,29.44471,32.3043ZM55.678,46.5004L51.0002,46.5004C50.2702,46.5004,49.678200000000004,45.9097,49.678200000000004,45.1814C49.678200000000004,44.4531,50.2702,43.8625,51.0002,43.8625L55.678,43.8625C56.408,43.8625,57,44.4531,57,45.1814C57,45.9097,56.408,46.5004,55.678,46.5004ZM55.678,52.2502L47.580799999999996,52.2502C46.8508,52.2502,46.2588,51.6595,46.2588,50.931200000000004C46.2588,50.2029,46.8508,49.612300000000005,47.580799999999996,49.612300000000005L55.678,49.612300000000005C56.408,49.612300000000005,57,50.2029,57,50.931200000000004C57,51.6595,56.408,52.2502,55.678,52.2502ZM55.678,58L47.580799999999996,58C46.8508,58,46.2588,57.4094,46.2588,56.681C46.2588,55.9527,46.8508,55.3621,47.580799999999996,55.3621L55.678,55.3621C56.408,55.3621,57,55.9527,57,56.681C57,57.4094,56.408,58,55.678,58ZM41.260000000000005,52.9303C41.260000000000005,48.602900000000005,43.934200000000004,44.898700000000005,47.723299999999995,43.3724C48.3662,43.113600000000005,48.4289,42.229,47.825,41.8898C45.435,40.546099999999996,42.6911,39.782,39.772800000000004,39.782C30.50933,39.782,23,47.4797,23,56.9757C23,57.0475,23.000413211,57.1188,23.00123932,57.1901C23.0066098,57.6398,23.376768,58,23.827485,58L41.2753,58C41.865700000000004,58,42.262299999999996,57.4015,42.037099999999995,56.857C41.5364,55.6469,41.260000000000005,54.3209,41.260000000000005,52.9303Z" fill="#4F85FB" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/s_debug.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="master_svg0_592_42099"><rect x="19" y="18.921875" width="41" height="41" rx="0"/></clipPath></defs><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g clip-path="url(#master_svg0_592_42099)"><g><path d="M53.8413984375,21.65234443077L25.1580984375,21.65234443077C23.2666884375,21.652344090385,21.733398779614,23.17788375,21.733399121728,25.05973375L21.733399121728,47.20904375L57.2666984375,47.20904375L57.2666984375,25.05973375C57.2670984375,23.17798375,55.7333984375,21.652344090385,53.8413984375,21.65234443077ZM52.9319984375,35.12904375C52.9319984375,35.83334375,52.3579984375,36.405643749999996,51.6500984375,36.406943749999996L47.5684984375,36.406943749999996C47.3869984375,36.40704375,47.2220984375,36.30194375,47.1462984375,36.13784375L46.7859984375,35.36184375C46.7178984375,35.21544375,46.5724984375,35.11984375,46.410498437499996,35.11504375C46.2483984375,35.11024375,46.0974984375,35.19694375,46.0206984375,35.33904375L42.2247984375,42.38224375C42.0768984375,42.65614375,41.7907984375,42.828143749999995,41.478398437500005,42.83104375C41.165898437500005,42.83394375,40.8765984375,42.66724375,40.7235984375,42.39624375L34.6923984375,31.69304375C34.6111984375,31.54864375,34.4531984375,31.46415375,34.2872984375,31.47640375C34.1214984375,31.48864375,33.9777984375,31.59540375,33.9187984375,31.75014375L32.3505984375,35.85744375C32.224298437499996,36.18814375,31.9057984375,36.40684375,31.5502384375,36.406943749999996L27.3519484375,36.406943749999996C26.6425784375,36.406943749999996,26.067528437500002,35.83474375,26.067528437500002,35.12904375C26.067528437500002,34.42324375,26.6425784375,33.85104375,27.3519484375,33.85104375L29.7753884375,33.85104375C30.1312484375,33.85104375,30.4494884375,33.63214375,30.5757584375,33.30154375L33.1400984375,26.58196375C33.2582984375,26.27280375,33.5454984375,26.05956375,33.8769984375,26.03496375C34.2084984375,26.01035375,34.5243984375,26.17881375,34.687298437500004,26.46711375L41.053898437499996,37.75784375C41.1302984375,37.89354375,41.2749984375,37.97704375,41.431298437500004,37.97554375C41.587698437499995,37.974143749999996,41.7307984375,37.887943750000005,41.804598437500005,37.75084375L45.789198437500005,30.36372375C45.9430984375,30.079963749999997,46.244798437499995,29.906903749999998,46.568698437500004,29.916573749999998C46.8925984375,29.926243749999998,47.1832984375,30.11697375,47.3197984375,30.40940375L48.6858984375,33.35554375C48.8261984375,33.65754375,49.129098437500005,33.85044375,49.4632984375,33.85104375L51.6500984375,33.85104375C52.3592984375,33.85104375,52.9344984375,34.423443750000004,52.9344984375,35.12904375L52.9319984375,35.12904375ZM21.733399121728,48.66654375L21.733399121728,53.77824375C21.733398779614,55.66014375,23.2666884375,57.18564375,25.1580984375,57.18564375L53.8413984375,57.18564375C55.7327984375,57.18564375,57.2660984375,55.66014375,57.2660984375,53.77824375L57.2660984375,48.66654375L21.733399121728,48.66654375ZM42.338998437499995,52.74404375C42.3368984375,53.44894375,41.7630984375,54.01984375,41.054598437500005,54.02194375L27.3519484375,54.02194375C26.6425784375,54.02194375,26.067528437500002,53.449743749999996,26.067528437500002,52.74404375C26.067528437500002,52.03824375,26.6425784375,51.46604375,27.3519484375,51.46604375L41.0519984375,51.46604375C41.761498437499995,51.46674375,42.3368984375,52.03814375,42.338998437499995,52.74404375ZM52.9319984375,52.74404375C52.9291984375,53.447443750000005,52.3570984375,54.01724375,51.6500984375,54.02064375L46.510498437500004,54.02064375C45.8010984375,54.02064375,45.2260984375,53.44854375,45.2260984375,52.74274375C45.2260984375,52.03694375,45.8010984375,51.46484375,46.510498437500004,51.46484375L51.6500984375,51.46484375C52.358098437500004,51.46834375,52.930598437499995,52.03954375,52.9319984375,52.74404375Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></g></svg>

1
src/assets/images/menuIcon/s_expe.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M54.037,56.006L28.80688,56.006C27.22599,56.006,25.93399,54.6781,25.93399,53.0441C25.93399,51.6375,26.888939999999998,50.4627,28.16489,50.1565L28.16489,21.0455056C25.82164,21.380591,24,23.46143,24,25.96836L24,53.0523C24,55.7785,26.15066,58,28.79886,58L54.037,58C54.5706,58,55,57.5574,55,57.0072C55.004000000000005,56.457,54.5706,56.006,54.037,56.006ZM42.742000000000004,37.799800000000005L41.847300000000004,37.799800000000005L41.847300000000004,39.1815L40.5031,39.1815L40.5031,40.1081L41.847300000000004,40.1081L41.847300000000004,41.4898L42.742000000000004,41.4898L42.742000000000004,40.1081L44.090199999999996,40.1081L44.090199999999996,39.1815L42.742000000000004,39.1815L42.742000000000004,37.799800000000005ZM44.090199999999996,29.05031L40.5031,29.05031L40.5031,33.3775L39.2994,35.6817C39.817,35.5824,40.334599999999995,35.5617,40.852199999999996,35.6155C42.2605,35.7644,42.569500000000005,36.8814,44.4393,36.8814C44.985,36.8814,45.4384,36.8193,45.807500000000005,36.6952L44.090199999999996,33.3981L44.090199999999996,29.05031ZM53.2425,21L30.09086,21L30.09086,50.1276L30.5563,50.1276C30.612470000000002,50.1358,30.67266,50.1358,30.73284,50.1358L53.2425,50.1358C54.125299999999996,50.1358,54.8475,49.3912,54.8475,48.4811L54.8475,22.65888C54.8515,21.744634,54.125299999999996,21.000000315617,53.2425,21ZM49.3224,42.424800000000005C49.1619,42.6978,48.881,42.8674,48.5721,42.875699999999995L36.0212,42.875699999999995C35.7042,42.875699999999995,35.4113,42.7061,35.2508,42.424800000000005C35.0903,42.1435,35.082300000000004,41.8001,35.2348,41.5105L39.5963,33.2161L39.5963,29.05031L38.5089,29.05031C38.2521,29.05031,38.0475,28.8352,38.0475,28.57457C38.0475,28.309820000000002,38.2561,28.09884,38.5089,28.09884L46.0643,28.09884C46.3211,28.09884,46.5257,28.31395,46.5257,28.57457C46.5257,28.83933,46.317099999999996,29.05031,46.0643,29.05031L44.9769,29.05031L44.9769,33.2203L46.561800000000005,36.231899999999996L49.3425,41.5105C49.490899999999996,41.8001,49.4869,42.1434,49.3224,42.424800000000005Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/s_home.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M20.0370799,43.6256C20.866486,47.6246,22.91091,51.222300000000004,25.94731,54.0277C26.3526,54.4028,26.9106,54.5752,27.46181,54.4956C28.0134,54.4165,28.49784,54.0943,28.77694,53.6208L31.1482,49.591300000000004C31.5442,48.9178,31.451999999999998,48.070499999999996,30.92,47.4942C29.68039,46.1482,28.77662,44.537800000000004,28.28009,42.7903C28.06083,42.015,27.34183,41.4784,26.52231,41.4784L21.82395,41.4784C21.27636,41.4781,20.757754,41.7198,20.411853,42.1363C20.0647341,42.552,19.9270634,43.0991,20.0370799,43.6256ZM44.1657,51.909C43.7696,51.233000000000004,42.9726,50.8869,42.1963,51.053799999999995C40.231899999999996,51.4761,38.1899,51.3965,36.2658,50.8227C35.453900000000004,50.580600000000004,34.579,50.9191,34.1541,51.6398L31.8262,55.5982C31.5578,56.055,31.5084,56.6046,31.691000000000003,57.1004C31.872999999999998,57.5967,32.2697,57.9884,32.7742,58.1703C34.9795,58.9695,37.3089,59.375,39.695,59.375C41.6678,59.375,43.6156,59.0954,45.482600000000005,58.543C46.0156,58.3847,46.446,57.9968,46.652,57.4891C46.8572,56.9806,46.814099999999996,56.408,46.535,55.9346L44.1657,51.909ZM52.5476,24.57127C52.2201,24.3027,51.806799999999996,24.15552,51.379999999999995,24.15542C51.2742,24.15542,51.1663,24.166330000000002,51.060500000000005,24.18424C50.531,24.2771,50.0703,24.59457,49.8016,25.05176L47.4685,29.01324C47.045100000000005,29.73472,47.183499999999995,30.6473,47.802800000000005,31.2165C49.39,32.6707,50.5347,34.5286,51.1096,36.5833C51.3275,37.3604,52.0476,37.8989,52.8691,37.899100000000004L57.568,37.899100000000004C58.1145,37.8988,58.6321,37.658,58.9784,37.2432C59.3258,36.8281,59.464,36.2815,59.3546,35.7553C58.4579,31.3953,56.0407,27.42316,52.5476,24.57127ZM46.652,21.88784C46.446600000000004,21.37975,46.0159,20.99153,45.482600000000005,20.833661C43.6053,20.279568,41.6553,19.99869145,39.695,20.00000417001C37.3089,20.00000417001,34.9795,20.405219,32.7742,21.20446C31.714199999999998,21.58978,31.262,22.8179,31.8262,23.77903L34.1541,27.73687C34.579,28.457549999999998,35.453900000000004,28.79609,36.2658,28.55402C37.3775,28.22171,38.5332,28.05317,39.6953,28.05394C40.530100000000004,28.05394,41.372299999999996,28.14349,42.1963,28.32119C42.9721,28.48767,43.7685,28.14262,44.1657,27.46794L46.5353,23.44182C46.8143,22.96858,46.857299999999995,22.39608,46.652,21.88784ZM57.568,41.4781L52.8691,41.4781C52.0475,41.477599999999995,51.327,42.0163,51.1096,42.7936C50.5345,44.848299999999995,49.3898,46.7063,47.802800000000005,48.160799999999995C47.1834,48.729,47.0449,49.6411,47.4685,50.3618L49.8016,54.3249C50.07,54.7824,50.5309,55.1001,51.060500000000005,55.1927C51.1663,55.2106,51.2742,55.2196,51.379999999999995,55.2196C51.8066,55.2202,52.2199,55.0737,52.5476,54.8057C56.0407,51.9518,58.4579,47.9814,59.3546,43.622C59.4641,43.0957,59.3259,42.549099999999996,58.9784,42.134C58.6326,41.718599999999995,58.1147,41.4778,57.568,41.4781ZM20.411568,37.241C20.757316,37.6573,21.27588,37.8989,21.82367,37.8989L26.52259,37.8989C27.34233,37.8986,28.06128,37.361999999999995,28.280369999999998,36.587C28.776699999999998,34.8389,29.68048,33.2279,30.920299999999997,31.8814C31.4524,31.3057,31.544600000000003,30.4588,31.1485,29.785890000000002L28.77722,25.75641C28.49772,25.28303,28.01361,24.96039,27.46209,24.87994C27.37433,24.86765,27.28578,24.86166,27.19713,24.86203C26.73679,24.86203,26.28729,25.03413,25.9476,25.349510000000002C22.91091,28.15468,20.866486,31.7521,20.0370799,35.7513C19.9271883,36.2779,20.0647273,36.825,20.411568,37.241Z" fill="#FFFFFF" fill-opacity="1"/></g></g></svg>

1
src/assets/images/menuIcon/s_liquid.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M30.42768,34.2143L30.42768,52.673C30.42768,53.4027,31.06121,54.0357,31.77429,54.0357L48.5584,54.0357C49.2714,54.0357,49.794,53.4027,49.794,52.673L49.794,34.2143L30.42768,34.2143ZM47.8574,46.726600000000005C47.8574,47.091499999999996,47.5684,47.387299999999996,47.2118,47.387299999999996C46.8553,47.387299999999996,46.5663,47.091499999999996,46.5663,46.726600000000005L46.5663,42.762299999999996C46.5663,42.397400000000005,46.8553,42.101600000000005,47.2118,42.101600000000005C47.5684,42.101600000000005,47.8574,42.397400000000005,47.8574,42.762299999999996L47.8574,46.726600000000005ZM47.2673,40.780100000000004C46.910799999999995,40.780100000000004,46.6218,40.4844,46.6218,40.1194C46.6218,39.7545,46.910799999999995,39.4587,47.2673,39.4587C47.6239,39.4587,47.9129,39.7545,47.9129,40.1194C47.9129,40.484300000000005,47.6239,40.780100000000004,47.2673,40.780100000000004ZM54.7629,21L29.21229,21C24.827023,21,24,23.26509,24,24.28292C26.44097,24.63393,26.55442,24.67522,26.55442,27.318080000000002L26.55442,52.673C26.55442,55.5922,28.92203,58,31.77429,58L48.5383,58C51.3904,58,53.6673,55.5922,53.6673,52.673L53.6673,24.96429C53.6673,23.28368,54.6596,21.803098,54.7579,21.6456C54.856300000000005,21.488186,55,21.331926,55,21.236123C55,21.139411,54.9664,21,54.7629,21ZM51.0851,24.96429L51.0851,52.673C51.0851,54.153,50.081,55.3571,48.679500000000004,55.3571L31.77429,55.3571C30.352719999999998,55.3571,29.136589999999998,54.128,29.136589999999998,52.673L29.136589999999998,27.318080000000002C29.136589999999998,26.34254,29.22487,24.24163,28.8277,23.6877C28.90202,23.62221,29.07898,23.64286,29.19211,23.64286L51.1939,23.64286C51.1345,23.64286,51.0851,24.53474,51.0851,24.96429Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/s_liquid_config.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M25.010964,27.14686L25.010964,52.3976C25.00721385,52.5305,25.0362768,52.6662,25.0915901,52.791799999999995C25.490033,53.8368,27.08099,54.6141,29.95072,55.1751C33.25546,55.7635,36.6258,56.0395,39.9999,55.9955C43.375,56.0285,46.7406,55.7525,50.0501,55.1741C52.915099999999995,54.6031,54.536100000000005,53.8083,54.9083,52.7909C54.9636,52.6662,54.992599999999996,52.5342,54.9889,52.3976L54.9889,27.14686C55.003699999999995,27.099980000000002,55.003699999999995,27.04982,54.9889,27.00294L54.9889,26.77745C54.9889,25.48132,53.3829,24.50509,50.0454,23.860689999999998C46.734700000000004,23.255981,43.3715,22.9686265,40.0037,23.00271173C36.6286,22.9697126,33.26296,23.245622,29.95353,23.824024C26.64599,24.468420000000002,25.0109623,25.44373,25.0109623,26.74078C24.999922606,26.81525,24.999922606,26.89089,25.0109623,26.96536C24.996346,27.011960000000002,24.996346,27.06176,25.0109623,27.10836L25.0109623,27.14502L25.010964,27.14686ZM46.0047,44.9994C46.0122,44.4503,46.524100000000004,44.0048,47.1578,43.9975L51.8398,43.9975L51.8398,45.9976L47.1578,45.9976C46.524100000000004,45.994,46.0122,45.548500000000004,46.0047,44.9994ZM46.0047,40.4987C46.0122,39.950500000000005,46.524100000000004,39.504999999999995,47.1578,39.497699999999995L51.7292,39.497699999999995L51.7292,41.4868L47.1578,41.4868C46.5278,41.4868,46.0122,41.047799999999995,46.0047,40.4996L46.0047,40.4987ZM46.0047,35.9888C46.0122,35.4388,46.5278,35.001599999999996,47.1578,35.001599999999996L51.8398,35.001599999999996L51.8398,36.990700000000004L47.1578,36.990700000000004C46.524100000000004,36.9824,46.0122,36.537,46.0047,35.987899999999996L46.0047,35.9888ZM29.501649999999998,45.4953C29.501649999999998,44.674,29.71822,43.8637,30.13072,43.1533C31.08773,41.4645,32.13675,39.827200000000005,33.27327,38.2483L33.27327,38.1823L33.51327,38.054L33.578900000000004,37.9981L33.96984,37.9981L33.96984,38.0531L34.035470000000004,38.1191Q34.09172,38.1191,34.09172,38.186C35.5242,39.727599999999995,36.7882,41.411100000000005,37.8633,43.209199999999996C38.841300000000004,44.8373,38.690200000000004,46.8866,37.483599999999996,48.3607C36.2789,49.8228,34.27922,50.3746,32.49232,49.730199999999996C30.70542,49.0858,29.51572,47.3928,29.52697,45.4953L29.501649999999998,45.4953ZM27.45319,27.739919999999998C28.58383,26.75362,29.8326,26.11288,31.13293,25.858060000000002C34.019059999999996,25.06777,37.0069,24.68957,40.0037,24.73517C42.9756,24.6875,45.9494,25.06699,48.8744,25.858060000000002C50.174800000000005,26.10555,51.4273,26.74628,52.5542,27.739919999999998C51.419799999999995,28.71615,50.171,29.35688,48.8744,29.62179C45.9848,30.39315,42.9988,30.76495,40.0037,30.72635C37.0084,30.76678,34.02223,30.39495,31.13293,29.62179C29.83728,29.3633,28.58383,28.72623,27.45319,27.739919999999998Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/s_log.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M32,30.00793C32.8,30.00793,33.5,29.30731,33.5,28.506610000000002L33.5,22.50132C33.5,21.700617,32.8,21,32,21C31.2,21,30.5,21.700617,30.5,22.50132L30.5,28.506610000000002C30.5,29.30731,31.2,30.00793,32,30.00793ZM45,30.00793C45.8,30.00793,46.5,29.30731,46.5,28.506610000000002L46.5,22.50132C46.5,21.700617,45.8,21,45,21C44.2,21,43.5,21.700617,43.5,22.50132L43.5,28.506610000000002C43.5,29.30731,44.2,30.00793,45,30.00793ZM40,50.0255C40,45.1212,43,40.8174,47.2,39.0159L28.5,39.0159C27.7,39.0159,27,38.315200000000004,27,37.5145C27,36.7138,27.7,36.0132,28.5,36.0132L47.5,36.0132C48.3,36.0132,49,36.7138,49,37.5145C49,37.9149,48.8,38.215199999999996,48.6,38.5154C49.7,38.215199999999996,50.8,38.015,52,38.015C52.3,38.015,52.7,38.015,53,38.1151L53,29.00705C53,26.80511,51.2,25.00352,49,25.00352L49,28.506610000000002C49,31.0088,47,33.0106,44.5,33.0106C42,33.0106,40,31.0088,40,28.506610000000002L40,25.00352L36,25.00352L36,28.506610000000002C36,31.0088,34,33.0106,31.5,33.0106C29,33.0106,27,31.0088,27,28.506610000000002L27,25.00352C24.8,25.00352,23,26.80511,23,29.00705L23,55.03C23,57.2319,24.8,59.0335,27,59.0335L44.1,59.0335C41.6,56.8315,40,53.6287,40,50.0255ZM37.5,51.026399999999995L28.5,51.026399999999995C27.7,51.026399999999995,27,50.3258,27,49.525099999999995C27,48.7244,27.7,48.0238,28.5,48.0238L37.5,48.0238C38.3,48.0238,39,48.7244,39,49.525099999999995C39,50.3258,38.3,51.026399999999995,37.5,51.026399999999995ZM37.5,45.021100000000004L28.5,45.021100000000004C27.7,45.021100000000004,27,44.320499999999996,27,43.519800000000004C27,42.7191,27.7,42.0185,28.5,42.0185L37.5,42.0185C38.3,42.0185,39,42.7191,39,43.519800000000004C39,44.320499999999996,38.3,45.021100000000004,37.5,45.021100000000004ZM52,41.0176C47,41.0176,43,45.1212,43,50.0255C43,54.9299,47.1,59.0335,52,59.0335C56.9,59.0335,61,54.9299,61,50.0255C61,45.1212,57,41.0176,52,41.0176ZM55.5,53.0282L50.5,53.0282C49.7,53.0282,49,52.327600000000004,49,51.5269L49,45.5216C49,44.7209,49.7,44.0203,50.5,44.0203C51.3,44.0203,52,44.7209,52,45.5216L52,50.0255L55.5,50.0255C56.3,50.0255,57,50.7262,57,51.5269C57,52.327600000000004,56.3,53.0282,55.5,53.0282Z" fill="#FFFFFF" fill-opacity="1"/></g></g></svg>

1
src/assets/images/menuIcon/s_ore.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M51.951499999999996,39.8059C50.843199999999996,40.323899999999995,49.9413,40.7615,48.9636,41.225899999999996C48.4242,40.9535,47.7542,40.408699999999996,47.004000000000005,40.2435C44.3744,39.6987,41.8501,42.1279,41.9554,44.9411C41.9554,45.378699999999995,41.593,46.0619,41.2348,46.1958C39.8694,46.687,39.2499,47.723,39.174099999999996,49.0894C39.0982,51.2194,38.9423,53.4297,41.5467,54.2513C41.7531,54.3049,41.829,54.7693,41.959599999999995,55.0417C41.652,55.2069,41.3149,55.5329,41.0072,55.5329C37.5305,55.5597,34.0496,55.5597,30.5729,55.5597C28.97572,55.5597,27.37854,55.5865,25.78137,55.5597C23.745912,55.5061,23,54.6577,23,52.527699999999996L23,23.88686C23,21.895306,23.720627,21.0468861,25.62966,21.020094C33.539699999999996,20.99330188,41.4497,20.99330188,49.364000000000004,21.020094C51.037,21.020094,51.9136,21.895306,51.9388,23.83327C52.0021,29.18278,51.951499999999996,34.5635,51.951499999999996,39.8059ZM37.6232,24.75761C37.6232,24.730809999999998,37.6232,24.730809999999998,37.6232,24.75761C35.2001,24.75761,32.776920000000004,24.730809999999998,30.35798,24.75761C29.17379,24.75761,28.19188,25.76678,28.21717,26.86079C28.26774,27.9816,29.144289999999998,28.79876,30.35798,28.79876C35.0737,28.79876,39.763999999999996,28.79876,44.4797,28.77197C45.950500000000005,28.77197,46.591,28.00839,46.565799999999996,26.56161C46.5405,25.44081,45.765100000000004,24.78886,44.4797,24.78886C42.183,24.730809999999998,39.915800000000004,24.75761,37.6232,24.75761ZM33.7841,36.3899C35.0189,36.3899,36.2578,36.4435,37.4673,36.3631C38.445,36.3095,39.1951,35.7335,39.2963,34.6171C39.4269,33.3624,38.6515,32.4336,37.6485,32.38C35.0737,32.2416,32.46928,32.4336,29.8902,32.5184C28.68073,32.5452,28.242449999999998,33.5544,28.26774,34.568C28.29302,35.7424,29.09372,36.3988,30.25262,36.3988L33.7841,36.3988L33.7841,36.3899ZM56.9495,50.3441C57.156,51.326499999999996,56.7177,51.9294,55.8412,52.3089C54.2693,52.9921,53.856300000000005,53.7825,54.1934,55.5016C54.3999,56.5644,53.7046,57.002,53.0851,57.4128C52.4403,57.8236,51.7956,58.3952,50.893699999999995,57.6048C49.6295,56.4572,48.727599999999995,56.6225,47.210499999999996,57.5245C46.6964,57.8236,45.8198,57.7968,45.2256,57.578C44.504999999999995,57.3057,43.7549,56.8145,43.9867,55.6669C44.3491,53.8941,43.5231,52.7465,42.081900000000005,52.143699999999995C40.9988,51.6793,41.1547,50.7237,41.18,49.9869C41.2053,49.415400000000005,41.6436,48.566900000000004,42.1071,48.3213C43.5231,47.584599999999995,44.1679,47.0085,44.0415,44.6062C43.965599999999995,43.324600000000004,44.787400000000005,43.021,45.4827,42.695C45.9463,42.4494,46.8228,42.3958,47.185199999999995,42.695C48.5001,43.815799999999996,49.7348,43.7577,50.948499999999996,42.7218C52.0821,41.7662,52.7269,42.775400000000005,53.5529,43.2398C54.3536,43.6774,54.2988,44.2757,54.0923,45.0706C53.7847,46.298500000000004,54.4547,47.6917,55.6136,48.0757C56.7177,48.4062,57.0802,49.143,56.9495,50.3441ZM45.7145,49.9333C45.6892,52.143699999999995,46.9787,53.5905,49.039500000000004,53.6173C50.7673,53.6441,52.259100000000004,52.2509,52.313900000000004,50.585300000000004C52.3645,48.2365,51.0497,46.682500000000005,48.9383,46.5977C47.210499999999996,46.5486,45.7398,48.049,45.7145,49.9333Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/menuIcon/s_setting.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><g><path d="M57.7309,36.6424L54.4199,35.1065C52.2821,34.1115,51.0169,31.80957,51.2919,29.41513L51.7134,25.70348C49.9764,24.13487,47.9673,22.91636,45.7913,22.111649L42.809,24.29289C40.9002,25.70218,38.3223,25.67794,36.438900000000004,24.23298L33.5495,22C31.3612,22.766417,29.33189,23.9468,27.56639,25.48018L27.92691,29.18911C28.16995,31.58721,26.871940000000002,33.8705,24.71933,34.8315L21.35269,36.3074C20.9039103,38.6357,20.883231,41.0297,21.291719,43.3658L24.60269,44.9071C26.74368,45.8995,28.01241,48.202,27.73869,50.5985L27.30925,54.2911C29.0484,55.858,31.056800000000003,57.0779,33.2313,57.8884L36.1897,55.7098C38.098,54.2997,40.6759,54.3229,42.559799999999996,55.767L45.4705,58C47.6601,57.2361,49.6906,56.0565,51.456199999999995,54.5225L51.0984,50.8054C50.8651,48.409099999999995,52.158699999999996,46.1352,54.306,45.1685L57.6461,43.6953C58.0967,41.3643,58.1179,38.9679,57.7044,36.6287L57.7309,36.6424ZM39.5113,49.514700000000005C34.3981,49.514700000000005,30.25307,45.2566,30.25307,40.0041C30.25307,34.7515,34.3981,30.49349,39.5113,30.49349C44.6245,30.49349,48.7696,34.7515,48.7696,40.0041C48.7696,45.2566,44.6245,49.514700000000005,39.5113,49.514700000000005Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M39.503226597900394,32.666666984558105C35.85293659790039,32.6648691245581,32.89285659790039,35.650166984558105,32.89285659790039,39.3333369845581C32.89285659790039,43.01646698455811,35.85293659790039,46.0017669845581,39.503226597900394,45.99996698455811C43.15095659790039,45.998166984558104,46.10715659790039,43.01396698455811,46.10715659790039,39.3333369845581C46.10715659790039,35.65270698455811,43.15095659790039,32.66846320455811,39.503226597900394,32.666666984558105ZM39.503226597900394,43.0462669845581C37.535416597900394,42.95376698455811,35.98716659790039,41.316986984558106,35.98716659790039,39.329296984558106C35.98716659790039,37.34159698455811,37.535416597900394,35.704856984558106,39.503226597900394,35.61227698455811C41.495636597900386,35.7097269845581,43.08915659790039,37.317586984558105,43.185756597900394,39.3279469845581C43.17395659790039,41.372516984558104,41.52956659790039,43.024566984558106,39.503226597900394,43.0274669845581L39.503226597900394,43.0462669845581Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></g></svg>

1
src/assets/images/menuIcon/s_user.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><g><g><ellipse cx="40" cy="40" rx="40" ry="40" fill="#479CF1" fill-opacity="1"/></g><g><path d="M29.44471,32.3043C29.44472,37.9952,34.0687,42.608599999999996,39.772800000000004,42.608599999999996C45.4768,42.608599999999996,50.100899999999996,37.9952,50.100899999999996,32.3043C50.100899999999996,26.6134,45.4768,22,39.772800000000004,22C34.0687,22,29.44472,26.6134,29.44471,32.3043ZM55.678,46.5004L51.0002,46.5004C50.2702,46.5004,49.678200000000004,45.9097,49.678200000000004,45.1814C49.678200000000004,44.4531,50.2702,43.8625,51.0002,43.8625L55.678,43.8625C56.408,43.8625,57,44.4531,57,45.1814C57,45.9097,56.408,46.5004,55.678,46.5004ZM55.678,52.2502L47.580799999999996,52.2502C46.8508,52.2502,46.2588,51.6595,46.2588,50.931200000000004C46.2588,50.2029,46.8508,49.612300000000005,47.580799999999996,49.612300000000005L55.678,49.612300000000005C56.408,49.612300000000005,57,50.2029,57,50.931200000000004C57,51.6595,56.408,52.2502,55.678,52.2502ZM55.678,58L47.580799999999996,58C46.8508,58,46.2588,57.4094,46.2588,56.681C46.2588,55.9527,46.8508,55.3621,47.580799999999996,55.3621L55.678,55.3621C56.408,55.3621,57,55.9527,57,56.681C57,57.4094,56.408,58,55.678,58ZM41.260000000000005,52.9303C41.260000000000005,48.602900000000005,43.934200000000004,44.898700000000005,47.723299999999995,43.3724C48.3662,43.113600000000005,48.4289,42.229,47.825,41.8898C45.435,40.546099999999996,42.6911,39.782,39.772800000000004,39.782C30.50933,39.782,23,47.4797,23,56.9757C23,57.0475,23.000413211,57.1188,23.00123932,57.1901C23.0066098,57.6398,23.376768,58,23.827485,58L41.2753,58C41.865700000000004,58,42.262299999999996,57.4015,42.037099999999995,56.857C41.5364,55.6469,41.260000000000005,54.3209,41.260000000000005,52.9303Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/password_icon.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="32.66561508178711" height="39.13572692871094" viewBox="0 0 32.66561508178711 39.13572692871094"><g><path d="M29.768,16.829C29.4345,16.829,27.5584,16.8498,27.204,16.8498L27.204,10.9347C27.204,4.37387,22.9722,0.0208277,16.3641,0C9.75591,0,5.4408,4.58215,5.4408,10.9347L5.4408,16.7873C5.21149,16.7873,2.8142,16.8082,2.60574,16.8082C1.02145,16.8082,0,18.162,0,19.6199L0,36.2615C0,37.9069,0.87553,39.1357,2.56405,39.1357L29.8514,39.1357C31.1647,39.1357,32.6656,37.9485,32.6656,35.8033L32.6656,19.9948C32.6656,18.3703,32.1236,16.829,29.768,16.829ZM19.9704,31.7626C19.9704,33.8246,18.3444,35.4908,16.3432,35.4908C14.342,35.4908,12.716,33.8246,12.716,31.7626L12.716,31.7001C12.716,30.3255,13.4456,29.1175,14.5296,28.4718L14.5296,21.5986C14.5296,20.6197,15.3009,20.5155,16.2598,20.5155C17.2188,20.5155,18.1568,20.6197,18.1568,21.5986L18.1568,28.4718C19.2408,29.1175,19.9704,30.3255,19.9704,31.7001L19.9704,31.7626ZM23.6185,16.7873L9.08884,16.7873L9.08884,9.28927C9.08884,5.68603,13.1121,3.7282,16.1348,3.7282L16.8018,3.7282C19.8245,3.7282,23.6185,5.54024,23.6185,9.28927L23.6185,16.7873Z" fill="#1989FA" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

1
src/assets/images/run.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="36" height="36" viewBox="0 0 36 36"><g><path d="M0.0338876,21.6006C0.791888,25.2568,2.6603,28.5461,5.43529,31.1111C5.80569,31.454,6.31565,31.6116,6.8194,31.5389C7.3235,31.4665,7.76624,31.1719,8.02131,30.7391L10.1884,27.0549C10.5503,26.4391,10.4661,25.6645,9.97991,25.1375C8.84698,23.9069,8.02102,22.4346,7.56723,20.8368C7.36685,20.128,6.70975,19.6374,5.96078,19.6374L1.66693,19.6374C1.16648,19.6372,0.692517,19.8581,0.376395,20.2389C0.0591609,20.619,-0.0666573,21.1192,0.0338876,21.6006ZM22.0852,29.174C21.7232,28.5559,20.9949,28.2395,20.2854,28.3921C18.4901,28.7781,16.6239,28.7054,14.8655,28.1807C14.1235,27.9594,13.3239,28.2689,12.9355,28.9278L10.808,32.5469C10.5628,32.9646,10.5176,33.4671,10.6845,33.9204C10.8509,34.3741,11.2133,34.7322,11.6745,34.8985C13.6899,35.6293,15.8187,36,17.9994,36C19.8024,36,21.5824,35.7444,23.2887,35.2393C23.7758,35.0946,24.1692,34.7399,24.3574,34.2758C24.545,33.8109,24.5056,33.2873,24.2505,32.8545L22.0852,29.174ZM29.7455,4.17944C29.4462,3.9339,29.0685,3.79934,28.6784,3.79924C28.5817,3.79924,28.4831,3.80922,28.3864,3.82559C27.9025,3.91049,27.4815,4.20075,27.2359,4.61875L25.1037,8.24068C24.7167,8.90032,24.8432,9.73465,25.4092,10.255C26.8597,11.5847,27.9059,13.2833,28.4313,15.1619C28.6304,15.8724,29.2886,16.3647,30.0393,16.3649L34.3337,16.3649C34.8331,16.3646,35.3062,16.1445,35.6226,15.7652C35.9401,15.3857,36.0664,14.886,35.9664,14.4048C35.1469,10.4185,32.9378,6.78689,29.7455,4.17944ZM24.3574,1.72602C24.1697,1.26149,23.7761,0.906541,23.2887,0.762205C21.5731,0.255605,19.791,-0.00119639,17.9994,0.00000381258C15.8187,0.00000381258,13.6899,0.370486,11.6745,1.10122C10.7057,1.45352,10.2924,2.57637,10.808,3.45511L12.9355,7.07371C13.3239,7.73262,14.1235,8.04214,14.8655,7.82082C15.8814,7.51699,16.9376,7.3629,17.9996,7.3636C18.7626,7.3636,19.5323,7.44547,20.2854,7.60794C20.9944,7.76016,21.7222,7.44468,22.0852,6.82783L24.2508,3.1468C24.5058,2.71413,24.5451,2.1907,24.3574,1.72602ZM34.3337,19.6371L30.0393,19.6371C29.2884,19.6367,28.63,20.1292,28.4313,20.8399C27.9057,22.7185,26.8595,24.4171,25.4092,25.747C24.8431,26.2665,24.7165,27.1004,25.1037,27.7593L27.2359,31.3828C27.4812,31.8011,27.9024,32.0915,28.3864,32.1762C28.4832,32.1926,28.5817,32.2008,28.6784,32.2008C29.0683,32.2013,29.446,32.0673,29.7455,31.8223C32.9378,29.2131,35.1469,25.583,35.9665,21.5972C36.0665,21.1161,35.9402,20.6163,35.6226,20.2368C35.3066,19.857,34.8333,19.6368,34.3337,19.6371ZM0.376135,15.7632C0.692116,16.1438,1.16603,16.3647,1.66666,16.3647L5.96105,16.3647C6.71021,16.3644,7.36726,15.8738,7.5675,15.1652C8.02109,13.5669,8.84706,12.0941,9.98017,10.863C10.4664,10.3367,10.5507,9.56236,10.1887,8.9471L8.02157,5.263C7.76613,4.8302,7.3237,4.53522,6.81966,4.46166C6.73946,4.45042,6.65853,4.44495,6.57751,4.44528C6.1568,4.44528,5.746,4.60263,5.43555,4.89099C2.6603,7.45571,0.791888,10.7448,0.0338876,14.4012C-0.0665431,14.8826,0.0591547,15.3828,0.376135,15.7632Z" fill="#4F85FB" fill-opacity="1"/></g></svg>

1
src/assets/images/success.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="70" height="70" viewBox="0 0 70 70"><defs><clipPath id="master_svg0_685_8843"><rect x="0" y="0" width="70" height="70" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_685_8843)"><g><path d="M35,70C15.6712,70,0,54.3288,0,35C0,15.6712,15.6712,0,35,0C54.3288,0,70,15.6712,70,35C70,54.3288,54.3288,70,35,70ZM27.195,48.7433C28.6189,50.1676,30.9278,50.1676,32.3517,48.7433L54.4542,26.6408C55.8781,25.2169,55.8781,22.9081,54.4542,21.4842C53.0302,20.0602,50.7215,20.0602,49.2975,21.4842L29.6158,40.8508L20.8075,32.0425C19.3838,30.6166,17.0736,30.6158,15.6488,32.0405C14.2241,33.4653,14.225,35.7755,15.6508,37.1992L27.195,48.7433Z" fill="#14A656" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

22
src/assets/images/user-cancel.svg

@ -0,0 +1,22 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_447_4258)">
<circle cx="54" cy="50" r="50" fill="url(#paint0_linear_447_4258)"/>
<path d="M54 45.1119L71.1119 28L76 32.8881L58.8881 50L76 67.1119L71.1119 72L54 54.8881L36.8881 72L32 67.1119L49.1119 50L32 32.8881L36.8881 28L54 45.1119Z" fill="white"/>
</g>
<defs>
<filter id="filter0_d_447_4258" x="0" y="0" width="108" height="108" 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.877278 0 0 0 0 0.28742 0 0 0 0 0.421121 0 0 0 1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_447_4258"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_447_4258" result="shape"/>
</filter>
<linearGradient id="paint0_linear_447_4258" x1="30.5" y1="17" x2="84.5" y2="100" gradientUnits="userSpaceOnUse">
<stop stop-color="#F08564"/>
<stop offset="1" stop-color="#EA467D"/>
</linearGradient>
</defs>
</svg>

22
src/assets/images/user-logout.svg

@ -0,0 +1,22 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_447_4253)">
<circle cx="54" cy="50" r="50" fill="url(#paint0_linear_447_4253)"/>
<path d="M71.3306 29.3781C76.8322 34.3067 79.982 41.3379 80 48.7231C80 63.3028 68.1928 75 53.5001 75C38.8072 75 27 63.298 27 48.7267C27.0179 41.3414 30.1689 34.3103 35.6694 29.3816C36.8812 28.6627 38.5656 28.4204 40.2499 29.6167C41.9391 31.0475 42.1807 32.9597 40.9689 34.156C36.8812 37.7371 34.2302 42.7531 34.2302 48.7231C34.2302 59.2366 42.8996 67.8343 53.5001 67.8343C64.1003 67.8343 72.7696 59.2366 72.7696 48.7231C72.7696 42.9953 70.1186 37.737 66.031 34.156C65.5429 33.4365 65.0656 31.5284 66.75 29.6131C67.9691 28.3229 69.9872 28.2195 71.3306 29.3781ZM50.1838 25.5853V25.5811V48.4624C50.1838 50.3698 51.8681 52.0393 53.7993 52.0393C55.7229 52.0393 57.4108 50.3698 57.4108 48.4624V25.5811C57.4108 23.673 55.7264 22 53.7956 22C51.8717 22 50.1838 23.673 50.1838 25.5853Z" fill="white"/>
</g>
<defs>
<filter id="filter0_d_447_4253" x="0" y="0" width="108" height="108" 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.425155 0 0 0 0 0.351313 0 0 0 0 0.909232 0 0 0 1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_447_4253"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_447_4253" result="shape"/>
</filter>
<linearGradient id="paint0_linear_447_4253" x1="30.5" y1="17" x2="84.5" y2="100" gradientUnits="userSpaceOnUse">
<stop stop-color="#AC85F8"/>
<stop offset="1" stop-color="#7C6CF7"/>
</linearGradient>
</defs>
</svg>

1
src/assets/images/user.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><clipPath id="master_svg0_609_03555/609_03497"><rect x="8" y="8" width="24" height="24" rx="0"/></clipPath></defs><g><rect x="0" y="0" width="40" height="40" rx="20" fill="#1989FA" fill-opacity="1"/><g clip-path="url(#master_svg0_609_03555/609_03497)"><g><path d="M28.120604907226564,25.896875C27.67840490722656,24.849575,27.03680490722656,23.898375,26.231504907226565,23.096075C25.428604907226564,22.291475,24.47750490722656,21.649974999999998,23.430704907226563,21.207075C23.421304907226563,21.202375,23.41200490722656,21.199975000000002,23.40260490722656,21.195275000000002C24.862704907226565,20.140625,25.812004907226562,18.422655,25.812004907226562,16.484375C25.812004907226562,13.273435,23.21040490722656,10.671875,19.99946490722656,10.671875C16.788524907226563,10.671875,14.186964907226562,13.273435,14.186964907226562,16.484375C14.186964907226562,18.422655,15.136184907226562,20.140625,16.596334907226563,21.197675C16.586964907226562,21.202375,16.577584907226562,21.204675,16.56821490722656,21.209375C15.518214907226563,21.652375,14.576024907226563,22.287475,13.767434907226562,23.098475C12.962844907226563,23.901375,12.321344907226562,24.852475,11.878369907226563,25.899175C11.443186907226563,26.924075,11.208483707226563,28.022775,11.186963515026562,29.135975C11.186337956226563,29.160975,11.190725517226563,29.185875,11.199867807226562,29.209175C11.209010107226563,29.232375,11.222722007226562,29.253675,11.240195707226562,29.271575C11.257669407226562,29.289475,11.278551207226563,29.303675,11.301610907226562,29.313375C11.324669907226562,29.323175,11.349440907226562,29.328175,11.374463907226563,29.328075C11.374463907226563,29.328075,12.780714907226562,29.328075,12.780714907226562,29.328075C12.883834907226563,29.328075,12.965864907226562,29.246075,12.968214907226562,29.145275C13.015084907226562,27.335975,13.741654907226563,25.641375,15.026024907226562,24.357075000000002C16.354934907226564,23.028174999999997,18.119774907226564,22.296875,19.99946490722656,22.296875C21.879104907226562,22.296875,23.644004907226563,23.028174999999997,24.972904907226564,24.357075000000002C26.257304907226562,25.641375,26.983804907226563,27.335975,27.030704907226564,29.145275C27.033104907226562,29.248475,27.115104907226563,29.328075,27.218204907226564,29.328075C27.218204907226564,29.328075,28.624504907226562,29.328075,28.624504907226562,29.328075C28.64950490722656,29.328175,28.674304907226563,29.323175,28.697304907226563,29.313375C28.720404907226563,29.303675,28.741304907226564,29.289475,28.758704907226562,29.271575C28.776204907226564,29.253675,28.789904907226564,29.232375,28.799104907226564,29.209175C28.808204907226564,29.185875,28.81260490722656,29.160975,28.812004907226562,29.135975C28.788504907226564,28.015675,28.55650490722656,26.925775,28.120604907226564,25.896875C28.120604907226564,25.896875,28.120604907226564,25.896875,28.120604907226564,25.896875ZM19.99946490722656,20.515625C18.923684907226562,20.515625,17.911184907226563,20.096095,17.149464907226562,19.334375C16.387744907226562,18.572655,15.968214907226564,17.560155,15.968214907226564,16.484375C15.968214907226564,15.408595,16.387744907226562,14.396094999999999,17.149464907226562,13.634375C17.911184907226563,12.872655,18.923684907226562,12.453125,19.99946490722656,12.453125C21.075244907226562,12.453125,22.087704907226563,12.872655,22.84950490722656,13.634375C23.611204907226565,14.396094999999999,24.030704907226564,15.408595,24.030704907226564,16.484375C24.030704907226564,17.560155,23.611204907226565,18.572655,22.84950490722656,19.334375C22.087704907226563,20.096095,21.075244907226562,20.515625,19.99946490722656,20.515625Z" fill="#FFFFFF" fill-opacity="1"/></g></g></g></svg>

1
src/assets/images/user_icon.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="33.87468338012695" height="33.84542465209961" viewBox="0 0 33.87468338012695 33.84542465209961"><g><path d="M33.8747,32.442C33.8747,25.5468,28.9971,19.6889,22.2628,17.6265C24.8808,15.9057,26.6152,12.9605,26.6152,9.61666C26.6152,4.31204,22.275,0,16.9373,0C11.5996,0,7.25944,4.31204,7.25944,9.61259C7.25944,12.9565,8.99389,15.9017,11.6118,17.6224C4.87763,19.6889,0,25.5427,0,32.442L0,33.8454L33.8747,33.8454L33.8747,32.4623L33.8747,32.442Z" fill="#1989FA" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

1
src/assets/images/wait.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="master_svg0_685_8855"><rect x="0" y="0" width="80" height="80" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_685_8855)"><g><path d="M40.00636015625,5.01953125C20.68606015625,5.01953125,5.01416254044,20.69143125,5.01416254044,40.01173125C5.01416254044,59.33203125,20.68606015625,74.99613125,40.00636015625,74.99613125C59.32666015625,74.99613125,74.99856015625,59.32423125,74.99856015625,40.00393125C74.99856015625,20.683631249999998,59.32666015625,5.01953125,40.00636015625,5.01953125ZM21.97506015625,45.97263125C18.678260156249998,45.97263125,16.00636015625,43.30073125,16.00636015625,40.00393125C16.00636015625,36.70703125,18.678260156249998,34.03513125,21.97506015625,34.03513125C25.27196015625,34.03513125,27.94386015625,36.70703125,27.94386015625,40.00393125C27.94386015625,43.30073125,25.27196015625,45.97263125,21.97506015625,45.97263125ZM39.92046015625,45.97263125C36.62356015625,45.97263125,33.95166015625,43.30073125,33.95166015625,40.00393125C33.95166015625,36.70703125,36.62356015625,34.03513125,39.92046015625,34.03513125C43.21726015625,34.03513125,45.88916015625,36.70703125,45.88916015625,40.00393125C45.88916015625,43.30073125,43.21726015625,45.97263125,39.92046015625,45.97263125ZM57.86576015625,45.97263125C54.56886015625,45.97263125,51.89696015625,43.30073125,51.89696015625,40.00393125C51.89696015625,36.70703125,54.56886015625,34.03513125,57.86576015625,34.03513125C61.16256015625,34.03513125,63.83446015625,36.70703125,63.83446015625,40.00393125C63.83446015625,43.30073125,61.16256015625,45.97263125,57.86576015625,45.97263125Z" fill="#EE8223" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>

1
src/assets/images/wifi-active.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="42" height="34" viewBox="0 0 42 34"><g><path d="M41.5238,8.34171C30.1914,-2.78057,11.812,-2.78057,0.479575,8.34171C-0.159858,8.96929,-0.159858,9.98404,0.479575,10.6072C1.11901,11.2347,2.15289,11.2347,2.78777,10.6072C12.8459,0.735472,29.1575,0.735472,39.2156,10.6072C39.8551,11.2347,40.889,11.2347,41.5238,10.6072C42.1587,9.984,42.1587,8.96929,41.5238,8.34171ZM6.63327,15.2314C5.99383,15.859,5.99383,16.8737,6.63327,17.4968C7.2727,18.1244,8.30658,18.1244,8.94146,17.4968C15.5985,10.9632,26.3958,10.9632,33.0529,17.4968C33.6923,18.1244,34.7262,18.1244,35.3611,17.4968C36.0005,16.8692,36.0005,15.8545,35.3611,15.2314C27.4297,7.44712,14.5691,7.44712,6.63327,15.2314L6.63327,15.2314ZM29.2346,22.5395L29.2436,22.5306C24.7089,18.0799,17.358,18.0799,12.8278,22.5306C12.1883,23.1581,12.1883,24.1728,12.8278,24.7959C13.4672,25.4235,14.5011,25.4235,15.136,24.7959C18.3965,21.5959,23.6795,21.5959,26.9355,24.7959L26.9445,24.7871C26.9828,24.8337,27.0237,24.8783,27.0669,24.9206C27.7064,25.5481,28.7403,25.5481,29.3752,24.9206C30.0146,24.293,30.0146,23.2783,29.3752,22.6552C29.3253,22.6151,29.2799,22.5795,29.2346,22.5395ZM18.596,31.5966C18.596,32.924,19.6923,34,21.0448,34C22.3972,34,23.4935,32.924,23.4935,31.5966C23.4935,30.2693,22.3972,29.1932,21.0448,29.1932C19.6923,29.1932,18.596,30.2692,18.596,31.5966Z" fill="#1989FA" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

1
src/assets/images/wifi.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="42" height="34" viewBox="0 0 42 34"><g><path d="M41.5238,8.34171C30.1914,-2.78057,11.812,-2.78057,0.479575,8.34171C-0.159858,8.96929,-0.159858,9.98404,0.479575,10.6072C1.11901,11.2347,2.15289,11.2347,2.78777,10.6072C12.8459,0.735472,29.1575,0.735472,39.2156,10.6072C39.8551,11.2347,40.889,11.2347,41.5238,10.6072C42.1587,9.984,42.1587,8.96929,41.5238,8.34171ZM6.63327,15.2314C5.99383,15.859,5.99383,16.8737,6.63327,17.4968C7.2727,18.1244,8.30658,18.1244,8.94146,17.4968C15.5985,10.9632,26.3958,10.9632,33.0529,17.4968C33.6923,18.1244,34.7262,18.1244,35.3611,17.4968C36.0005,16.8692,36.0005,15.8545,35.3611,15.2314C27.4297,7.44712,14.5691,7.44712,6.63327,15.2314L6.63327,15.2314ZM29.2346,22.5395L29.2436,22.5306C24.7089,18.0799,17.358,18.0799,12.8278,22.5306C12.1883,23.1581,12.1883,24.1728,12.8278,24.7959C13.4672,25.4235,14.5011,25.4235,15.136,24.7959C18.3965,21.5959,23.6795,21.5959,26.9355,24.7959L26.9445,24.7871C26.9828,24.8337,27.0237,24.8783,27.0669,24.9206C27.7064,25.5481,28.7403,25.5481,29.3752,24.9206C30.0146,24.293,30.0146,23.2783,29.3752,22.6552C29.3253,22.6151,29.2799,22.5795,29.2346,22.5395ZM18.596,31.5966C18.596,32.924,19.6923,34,21.0448,34C22.3972,34,23.4935,32.924,23.4935,31.5966C23.4935,30.2693,22.3972,29.1932,21.0448,29.1932C19.6923,29.1932,18.596,30.2692,18.596,31.5966Z" fill="#DF1515" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

1
src/assets/images/x.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="250" height="250" viewBox="0 0 250 250"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_771_9460"><stop offset="0%" stop-color="#FE934C" stop-opacity="1"/><stop offset="100%" stop-color="#F66E12" stop-opacity="1"/></linearGradient><linearGradient x1="128.63385009765625" y1="64.17578160762787" x2="125.5" y2="160" gradientUnits="userSpaceOnUse" id="master_svg1_771_00887"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="100%" stop-color="#FFD8BF" stop-opacity="1"/></linearGradient></defs><g><g><ellipse cx="125" cy="125" rx="125" ry="125" fill="url(#master_svg0_771_9460)" fill-opacity="1"/></g><g><path d="M82.48,79.64L104.44,79.64L125.08,109.64L145.84,79.64L167.8,79.64L136.12,125.47999999999999L168.76,172.64L146.92000000000002,172.64L125.08,141.32L103.36,172.64L81.52,172.64L114.16,125.47999999999999L82.48,79.64Z" fill="url(#master_svg1_771_00887)" fill-opacity="1"/></g></g></svg>

1
src/assets/images/y.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="250" height="250" viewBox="0 0 250 250"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_771_9478"><stop offset="4.523751512169838%" stop-color="#73ACFF" stop-opacity="1"/><stop offset="99.52375292778015%" stop-color="#2D7FEE" stop-opacity="1"/></linearGradient><linearGradient x1="125" y1="90" x2="125" y2="160" gradientUnits="userSpaceOnUse" id="master_svg1_771_00997"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="100%" stop-color="#B3D3FF" stop-opacity="1"/></linearGradient></defs><g><g><ellipse cx="125" cy="125" rx="125" ry="125" fill="url(#master_svg0_771_9478)" fill-opacity="1"/></g><g><path d="M80.36,79.64L102.68,79.64L125.36,117.56L125.6,117.56L147.2,79.64L169.51999999999998,79.64L134.96,137.12L134.96,172.64L115.88,172.64L115.88,137.12L80.36,79.64Z" fill="url(#master_svg1_771_00997)" fill-opacity="1"/></g></g></svg>

1
src/assets/images/z.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="250" height="250" viewBox="0 0 250 250"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_771_9490"><stop offset="2.380894310772419%" stop-color="#9B8EFF" stop-opacity="1"/><stop offset="100%" stop-color="#7260FC" stop-opacity="1"/></linearGradient><linearGradient x1="125" y1="90" x2="125" y2="160" gradientUnits="userSpaceOnUse" id="master_svg1_771_01099"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="100%" stop-color="#DFDBFF" stop-opacity="1"/></linearGradient></defs><g><g><ellipse cx="125" cy="125" rx="125" ry="125" fill="url(#master_svg0_771_9490)" fill-opacity="1"/></g><g><path d="M93.68,172.88Q89.72,172.88,87.2,169.82Q84.68,166.76,84.68,162.68Q84.68,159.8,85.94,157.16Q87.2,154.51999999999998,89.24,152L136.88,95.96L87.8,95.96L87.8,79.64L153.68,79.64Q156.8,79.64,159.14,81.5Q161.48000000000002,83.36,162.44,86.48Q163.64,90.200005,162.62,93.38Q161.6,96.56001,159.44,99.2L110.96000000000001,156.07999999999998L164.24,156.07999999999998L164.24,172.88L93.68,172.88Z" fill="url(#master_svg1_771_01099)" fill-opacity="1"/></g></g></svg>

91
src/assets/styles/common.scss

@ -0,0 +1,91 @@
/* CSS Document */
html {
font-family: 'PingFangSC-Regular', 'PingFang SC', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
height: 100vh;
font-size: 14px;
}
html, body {
overflow: hidden;
}
html,
body,
ol,
dl,
dd,
dt,
p,
h1,
h2,
h3,
h4,
h5,
h6,
form,
fieldset,
legend,
img {
margin: 0;
padding: 0;
}
fieldset {
border: none;
}
img {
display: block;
}
address,
caption,
cite,
code,
dfn,
th,
var {
font-style: normal;
font-weight: normal;
}
ul,
ol,
li {
list-style: none;
}
a {
color: #666;
text-decoration: none;
}
* {
box-sizing: border-box !important;
}
a {
&:visited {
color: inherit;
}
}
input,
button,
select,
textarea {
outline: none;
}
textarea {
resize: none;
}
input[type='number'] {
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
}
-moz-appearance: textfield;
}
.clear {
clear: both;
}
.konvajs-content{
canvas{
border: 1px solid #ccc !important;
}
}

37
src/assets/styles/element.scss

@ -0,0 +1,37 @@
:root {
// --el-font-size-base: 50px;
// --el-button-size: 80px;
--el-color-primary: #1989fa;
//--el-button-active-bg-color: linear-gradient(90deg, #0657C0 24%, #096AE0 101%);
--text-color-primary: #17213c;
//--el-color-success: rgba(88, 162, 95, 1);
//--text-color-info: #838b99;
//--el-input-border: #dae0f2;
//--el-font-weight-primary: 400;
//--color-red: #f56c6c;
//--color-green: #67c23a;
//--color-yellow: #e6a23c;
//--color-blue: --el-color-primary;
--el-font-family: 'PingFangSC-Regular', 'PingFang SC', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
}
.el-dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
padding: 0;
.el-dialog__header {
background: rgba(0, 0, 0, .03);
padding: 10px;
}
.el-dialog__body {
padding: 10px 20px;
}
.el-dialog__footer {
padding: 10px;
}
}

3
src/assets/styles/main.scss

@ -0,0 +1,3 @@
@use './common.scss';
@use './element.scss';

5
src/assets/styles/variable.scss

@ -0,0 +1,5 @@
$primary-color: #1989FA;
$success-color: #14A656;
$danger-color: #DF1515;
$warn-color: #EE8223;
$info-color: #909399;

140
src/components/common/FTButton/index.vue

@ -0,0 +1,140 @@
<script setup lang="ts">
import { ref } from 'vue'
interface FTButton {
type?: 'default' | 'primary' | 'info'
size?: 'small' | 'default' | 'large'
disabled?: boolean
loading?: boolean
clickHandle?: () => any
}
const props = withDefaults(defineProps<FTButton>(), {
type: 'default',
size: 'default',
disabled: false,
loading: false,
clickHandle: () => {},
})
const isLoading = ref(false)
async function handleClick() {
if (!props.clickHandle || isLoading.value)
return
isLoading.value = true // loading
try {
await props.clickHandle() //
}
finally {
isLoading.value = false // loading
}
}
const setLoading = (loading: boolean) => {
isLoading.value = loading
}
defineExpose({
setLoading,
})
</script>
<template>
<div class="ft-button" :class="{ 'ft-button-disabled': disabled || isLoading, [`ft-button-${size}`]: true }" @click="handleClick">
<!-- 添加 loading 判断 -->
<div v-show="disabled || isLoading" class="my-button-shadow" /> <!-- 添加 loading 判断 -->
<div
class="my-button" :class="{
[`my-button-${type}`]: true,
[`my-button-${size}`]: true,
'button-disabled': disabled || isLoading, // loading
}"
>
<el-icon v-if="isLoading" :color="type === 'default' ? '#26509C' : '#fff'">
<!-- 添加 loading 判断 -->
<Loading class="rotate-loading" /> <!-- 添加旋转类 -->
</el-icon>
<span><slot /></span>
</div>
</div>
</template>
<style scoped lang="scss">
.ft-button {
position: relative;
display: inline-block;
margin-right: 10px;
}
.ft-button-small {
margin-right: 5px;
}
.ft-button-disabled {
pointer-events: none;
}
.my-button-shadow {
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
}
.my-button {
height: 30px;
padding: 5px 20px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 14px;
//width: fit-content;
position: relative;
.el-icon {
position: absolute;
left: 5px;
svg {
width: 35px;
}
}
}
.button-disabled {
opacity: 0.5;
}
.my-button-small {
height: 25px;
font-size: 12px;
padding: 3px 15px;
.el-icon {
position: absolute;
left: 3px;
svg {
width: 25px;
}
}
}
.my-button-default {
background: #fff;
color: $primary-color;
border: 1px solid $primary-color;
}
.my-button-primary {
background: $primary-color;
color: #fff;
border: 1px solid $primary-color;
}
.my-button-info {
background: #335AA5;
color: #fff;
border: 1px solid #335AA5;
}
.rotate-loading {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>

76
src/components/common/FTDialog/index.vue

@ -0,0 +1,76 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
const props = defineProps({
title: {
type: String,
default: '',
},
visible: {
type: Boolean,
default: false,
},
width: {
type: String,
default: '50%',
},
okHandle: {
type: Function,
default: () => {},
},
})
const emits = defineEmits(['update:visible', 'ok', 'cancel'])
const cancel = () => {
show.value = false
emits('cancel')
}
const show = ref(false)
watch(
() => props.visible,
(newVal) => {
show.value = newVal
},
{
//
deep: true,
immediate: true,
},
)
</script>
<template>
<el-dialog
v-model="show"
center
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
destroy-on-close
append-to-body
:title="title"
:width="width"
:before-close="cancel"
>
<slot />
<template #footer>
<div v-if="$slots.footer" class="dialog-footer">
<slot name="footer" />
</div>
<div v-else class="dialog-footer">
<ft-button :click-handle="cancel">
取消
</ft-button>
<ft-button type="primary" :click-handle="okHandle">
确认
</ft-button>
</div>
</template>
</el-dialog>
</template>
<style scoped lang="scss">
</style>

181
src/components/common/FTStream/index.vue

@ -0,0 +1,181 @@
<script setup lang="ts">
import { cmdNameMap } from 'libs/utils'
import { useSystemStore } from 'stores/systemStore'
import { computed, nextTick, ref, watch } from 'vue'
defineProps({
visible: {
type: Boolean,
default: false,
},
})
const systemStore = useSystemStore()
const title = computed(() => {
const commandKey = systemStore.systemList[0]?.command.replace(/^debug_/, '')
return cmdNameMap[commandKey as keyof typeof cmdNameMap] || systemStore.systemList[0]?.command
})
const maskBodyRef = ref<HTMLElement | null>(null)
const maskRef = ref<HTMLElement | null>(null)
const maskHeaderRef = ref<HTMLElement | null>(null)
const statusMap = {
error: 'danger',
fail: 'danger',
success: 'success',
finish: 'primary',
SEND: 'primary',
receive: 'primary',
start: 'primary',
result: 'primary',
}
watch(
() => systemStore.systemList,
async () => {
await nextTick()
if (maskBodyRef.value) {
maskBodyRef.value.scrollTop = maskBodyRef.value.scrollHeight
}
},
{ deep: true },
)
//
let isDragging = false
let offsetX = 0
let offsetY = 0
const handleMouseDown = (event: MouseEvent | TouchEvent) => {
if (maskRef.value && maskHeaderRef.value) {
isDragging = true
const clientX = 'clientX' in event ? event.clientX : event.touches[0].clientX
const clientY = 'clientY' in event ? event.clientY : event.touches[0].clientY
offsetX = clientX - maskRef.value.offsetLeft
offsetY = clientY - maskRef.value.offsetTop
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
document.addEventListener('touchmove', handleMouseMove)
document.addEventListener('touchend', handleMouseUp)
}
}
const handleMouseMove = (event: MouseEvent | TouchEvent) => {
if (maskRef.value && isDragging) {
const clientX = 'clientX' in event ? event.clientX : event.touches[0].clientX
const clientY = 'clientY' in event ? event.clientY : event.touches[0].clientY
// body
const bodyWidth = document.body.clientWidth
const bodyHeight = document.body.clientHeight
// body
const newLeft = Math.max(0, Math.min(clientX - offsetX, bodyWidth - maskRef.value.offsetWidth))
const newTop = Math.max(0, Math.min(clientY - offsetY, bodyHeight - maskRef.value.offsetHeight))
maskRef.value.style.left = `${newLeft}px`
maskRef.value.style.top = `${newTop}px`
}
}
const handleMouseUp = () => {
isDragging = false
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
document.removeEventListener('touchmove', handleMouseMove)
document.removeEventListener('touchend', handleMouseUp)
}
</script>
<template>
<teleport to="body">
<!-- 使用 transition 组件包裹 mask 元素 -->
<transition name="mask-fade">
<div
v-if="visible && systemStore.isDebug"
ref="maskRef"
class="mask"
>
<div
ref="maskHeaderRef" class="mask-header" @mousedown="handleMouseDown"
@touchstart="handleMouseDown"
>
<p>{{ title }}</p>
<el-icon @click="systemStore.updateStreamVisible(false)">
<Close />
</el-icon>
</div>
<div ref="maskBodyRef" class="mask-body">
<el-timeline>
<el-timeline-item
v-for="item in systemStore.systemList" :key="item"
:timestamp="JSON.stringify(item.content)"
>
<el-tag :type="statusMap[item.status as keyof typeof statusMap]" class="mask-tag">
{{ item.title }}
</el-tag>
</el-timeline-item>
</el-timeline>
</div>
</div>
</transition>
</teleport>
</template>
<style scoped lang="scss">
.mask {
width: 400px;
height: 250px;
padding: 5px 10px;
background: #fff;
box-shadow: var(--el-box-shadow-light);
position: absolute;
bottom: 20px;
right: 20px;
border-radius: 8px;
font-size: 30px;
.mask-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
font-size: 16px;
border-bottom: 1px solid #ddd;
cursor: move; //
.el-icon svg{
width: 18px;
cursor: pointer;
}
}
.mask-body {
padding: 5px 2px;
height: calc(100% - 31px);
overflow: auto;
}
}
/* 定义过渡效果 */
.mask-fade-enter-active, .mask-fade-leave-active {
transition: transform 0.5s ease;
}
.mask-fade-enter-from {
transform: translateX(100%);
}
.mask-fade-leave-to {
transform: translateX(100%);
}
:deep(.el-timeline-item__timestamp.is-bottom) {
white-space: pre-wrap; /* 保留空格和换行符,允许自动换行 */
word-wrap: break-word; /* 允许长单词或URL强制断行 */
overflow-wrap: break-word;
}
.mask-tag {
max-width: 100%;
height: fit-content;
padding: 5px;
white-space: pre-wrap;
}
</style>

7
src/components/common/FTTable/expand.ts

@ -0,0 +1,7 @@
export default {
props: ['row', 'render', 'index', 'column'],
inheritAttrs: false,
setup(props: any) {
return () => props.render(props.row)
},
}

144
src/components/common/FTTable/index.vue

@ -0,0 +1,144 @@
<script setup lang="ts">
import type { VNode } from 'vue'
import { onMounted, reactive } from 'vue'
import Expand from './expand'
defineOptions({
name: 'FtTable',
})
const props = withDefaults(defineProps<TableProp>(), {
columns: () => [],
mustInit: true,
hasHeader: true,
getDataFn: () => Promise.resolve([]),
})
const emits = defineEmits([])
enum ColumnType {
index = 'index',
selection = 'selection',
expand = 'expand',
}
interface TableColumn {
title: string
key: string
type?: ColumnType
width?: number //
fixed?: 'left' | 'right' | undefined //
render?: (row: any) => VNode //
}
interface Btn {
name: string
icon?: string
type?: string
serverUrl: string
}
interface TableProp {
columns: TableColumn[]
getDataFn: (params: any) => Promise<any> //
mustInit?: boolean // mountedgetDataFn
hasHeader?: boolean
btnList?: Btn[]
}
// const attrs = useAttrs()
async function methodParent(fn: any) {
const newFn = fn[0] === '/' ? fn.slice(1) : fn
emits(newFn as never)
}
onMounted(() => {
if (props.mustInit) {
initData()
}
})
const state = reactive({
loading: false,
dataTotal: 0,
tableData: [],
})
function initData() {
state.loading = true
props
.getDataFn({})
.then((data) => {
console.log(data)
state.tableData = data
state.loading = false
})
.finally(() => {
state.loading = false
})
}
defineExpose({
initData,
})
</script>
<template>
<div v-if="hasHeader" class="header">
<div v-for="btn in btnList" :key="btn.serverUrl">
<el-button :icon="btn.icon" :type="btn.type" @click="methodParent(btn.serverUrl)">
{{ btn.name }}
</el-button>
</div>
<div class="search">
<el-input>
<template #suffix>
<el-icon class="el-input__icon">
<search />
</el-icon>
</template>
</el-input>
</div>
</div>
<el-table
v-loading="state.loading"
:="$attrs"
:data="state.tableData"
style="width: 100%"
height="100%"
:highlight-current-row="true"
class="container-table"
header-row-class-name="header-row-class"
>
<template v-for="(column, index) in columns" :key="column.key">
<el-table-column
show-overflow-tooltip
:prop="column.key"
:label="column.title"
:width="column.width"
:type="column.type"
:fixed="column.fixed"
>
<template v-if="column.render" #default="scope">
<Expand :column="column" :row="scope.row" :render="column.render" :index="index" />
</template>
</el-table-column>
</template>
</el-table>
</template>
<style lang="scss" scoped>
.header {
display: flex;
justify-content: space-between;
align-items: center;
height: 40px;
.search {
width: 200px;
}
}
:deep(.header-row-class) {
th {
background-color: rgba(0,0,0,0.02 ) !important;
//font-weight: 500;
//border-bottom: none;
color: rgba(0, 0, 0, 0.85)
}
}
</style>

21
src/env.d.ts

@ -0,0 +1,21 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly FT_NODE_ENV: string
readonly FT_WS_URL: string
readonly FT_PROXY: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
declare const __APP_VERSION__: string
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<object, object, any>
export default component
}
declare module 'lodash'

25
src/hooks/useActivateDebug.ts

@ -0,0 +1,25 @@
import { useSystemStore } from 'stores/systemStore'
import { ref } from 'vue'
export const useActivateDebug = () => {
const systemStore = useSystemStore()
const logoClickCount = ref(0)
let clickTimeout: NodeJS.Timeout | null = null
const handleLogoClick = () => {
if (clickTimeout) {
clearTimeout(clickTimeout)
}
logoClickCount.value++
if (logoClickCount.value === 10) {
systemStore.updateDebug()
logoClickCount.value = 0 // 重置计数器
}
clickTimeout = setTimeout(() => {
logoClickCount.value = 0 // 重置计数器
}, 1000)
}
return {
handleLogoClick,
}
}

29
src/hooks/useApiData.ts

@ -0,0 +1,29 @@
import http from 'libs/http'
import { ref } from 'vue'
export default function useApiData(url: string, params?: any, init?: boolean) {
const data = ref(null)
const loading = ref(false)
const error = ref()
const fetchData = async () => {
loading.value = true
error.value = null
try {
const response = await http.post(url, params)
data.value = response.data
}
catch (err) {
error.value = err
}
finally {
loading.value = false
}
}
init && fetchData().then(() => {})
return {
data,
loading,
error,
fetchData,
}
}

300
src/layouts/default.vue

@ -0,0 +1,300 @@
<script setup lang="ts">
import { useActivateDebug } from 'hooks/useActivateDebug'
import { formatDateTime } from 'libs/utils'
import { onMounted, onUnmounted, ref } from 'vue'
const { handleLogoClick } = useActivateDebug()
const isClose = ref(false)
const currentTime = ref(formatDateTime())
const timeInterval = setInterval(() => {
currentTime.value = formatDateTime()
}, 1000)
onMounted(() => {
})
const handleLogout = () => {
console.log(1)
}
onUnmounted(() => {
clearInterval(timeInterval)
})
</script>
<template>
<el-container class="main">
<el-header class="header">
<div class="logo">
<img src="../assets/images/logo.svg" alt="" @click="handleLogoClick">
</div>
<div class="header-right">
<div>
<el-button type="primary" size="small">消毒</el-button>
<el-button type="success" size="small">加液</el-button>
<el-button type="danger" size="small">排液</el-button>
<el-button size="small">运行参数</el-button>
<el-button size="small">配方管理</el-button>
<el-button size="small">设置</el-button>
</div>
<div class="wifi-icon">
<img v-if="isClose" src="../assets/images/wifi.svg" alt="">
<img v-else src="../assets/images/wifi-active.svg" alt="">
</div>
<div class="time">
{{ currentTime }}
</div>
<div class="user">
<div class="user-dropdown">
<div class="user-dropdown-item">
<img src="../assets/images/user.svg" alt="">
</div>
</div>
</div>
</div>
</el-header>
<el-container class="container">
<el-main>
<router-view v-slot="{ Component }" class="content">
<transition name="el-fade-in-linear">
<component :is="Component" />
</transition>
</router-view>
</el-main>
</el-container>
<footer class="footer">
<div class="ip-info">IP : 192.0.0.0</div>
<div class="user-info">
<el-badge :value="1" type="warning">
<el-dropdown>
<span class="el-dropdown-link">
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item>设置</el-dropdown-item>
<el-dropdown-item @click="handleLogout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-badge>
</div>
</footer>
</el-container>
</template>
<style scoped lang="scss">
.main {
box-sizing: border-box;
height: 100%;
background: #F6F6F6;
.header, .footer {
height: 50px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 15px;
}
.header {
color: #393F46;
.logo {
height: 100%;
display: flex;
align-items: center;
.title {
margin:0 10px;
color: #8799AB;
font-weight: 600;
}
img {
height: 100%;
}
.expand-icon {
height: 15px;
transition: all 0.3s;
}
.fold-icon {
height: 15px;
transform: rotate(90deg);
transition: all 0.3s;
}
}
.header-right {
display: flex;
align-items: center;
height: 100%;
.wifi-icon {
width: 40px;
height: 100%;
background: #fff;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
img {
height: 50%;
}
}
.time {
margin:0 10px;
height: 100%;
padding: 0 10px;
display: flex;
align-items: center;
background: #fff;
border-radius: 5px;
}
}
}
.container {
height: calc(100% - 100px);
}
}
.aside {
width: 170px;
overflow: auto;
padding-left: 10px;
//transition: all 0.1s ease;
.aside-item {
width: 100%;
height: 50px;
border-radius: 10px;
color: #1989FA;
margin: 10px 0;
padding: 0 10px;
display: flex;
align-items: center;
overflow: hidden;
img {
height: 80%;
margin-right: 20px;
}
.text {
transition: opacity 0.3s ease;
white-space: nowrap;
}
}
.aside-item-active {
background: #1989FA;
color: #fff;
}
}
.aside-off {
width: 70px;
//transition: all 0.1s ease;
.aside-item {
.text {
opacity: 0
}
}
.aside-item-active {
background: rgba(0,0,0,0);
color: #fff;
}
}
.user-dropdown-item {
display: flex;
align-items: center;
height: 100%;
color: #393F46;
font-weight: bold;
img {
height: 30px;
margin-right: 10px;
}
}
.el-main {
padding: 0 15px;
height: 100%;
position: relative;
}
.content {
width: 100%;
height: 100%;
background: #fff;
border-radius: 10px;
box-shadow: 0 0 1px rgba(0, 0, 0, 0.1);
padding: 10px;
}
.footer-expand {
padding: 10px 15px 10px 85px !important;
}
.main .footer {
padding: 10px 15px 10px 185px;
.el-row {
width: 100%;
height: 100%;
.el-col {
height: 100%;
}
}
.footer-left, .footer-right {
width: 100%;
height: 100%;
background: #fff;
border-radius: 5px;
display: flex ;
align-items: center;
padding: 0 20px;
}
.footer-left {
border-right: 5px solid #F6F6F6;
img {
height: 60%;
}
.text {
color: #1C1C1C ;
margin-left: 10px;
font-size: 14px;
}
}
.footer-right {
border-left: 10px solid #F6F6F6;
.status {
width: 15px;
height: 15px;
border-radius: 50%;
background: #4EE993;
}
.text {
color: #1C1C1C ;
margin-left: 10px;
font-size: 14px;
}
}
}
.aside-item:hover {
.swing-icon {
animation: swing 1s ease-in-out;
}
}
.logout {
display: flex;
img {
width: 15px;
margin-right: 10px;
}
}
@keyframes swing {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(-30deg);
}
50% {
transform: rotate(30deg);
}
75% {
transform: rotate(-15deg);
}
100% {
transform: rotate(0deg);
}
}
</style>

5
src/libs/constant.ts

@ -0,0 +1,5 @@
// 请求头里token的名称
export const HEADER_TOKEN_KEY = 'Authorization'
// sessionStorage里token的名称
export const SESSIONSTORAGE_TOKEN_KEY = 'web_token'

92
src/libs/http.ts

@ -0,0 +1,92 @@
import { HEADER_TOKEN_KEY } from '@/libs/constant'
import axios from 'axios'
import { FtMessage } from 'libs/message'
import { getToken } from 'libs/token'
const http = axios.create({
baseURL: import.meta.env.FT_API_BASE,
timeout: 1000 * 60,
})
// 请求拦截器
http.interceptors.request.use(
(config) => {
if (getToken()) {
config.headers![HEADER_TOKEN_KEY] = getToken()
}
return config
},
(error: any) => {
return Promise.reject(error)
},
)
// 响应拦截器
http.interceptors.response.use(
(response) => {
if (
response.status === 200
&& response.data.code !== '0'
) {
// 返回错误拦截
FtMessage.error(response.data.msg)
return Promise.reject(response)
}
else if (
response.config.url?.includes('/files/download')
|| response.config.url?.includes('downloadStream')
) {
return response.data
}
else if (response.data instanceof Blob) {
return response.data
}
return response.data.data // 返回数据体
},
(error: any) => {
console.log(error)
if (error.response && error.response.status === 401) {
FtMessage.error('账号权限过期')
// TODO 登出
}
else {
if (error.message.includes('timeout')) {
FtMessage.error('请求超时')
}
else if (error.message.includes('Network')) {
FtMessage.error('网络连接错误')
}
else {
FtMessage.error('接口请求失败')
}
error.response = {
data: {
res: false,
},
}
return Promise.reject(error.response)
}
},
)
// 封装 GET 请求
export function get<T>(url: string, params?: any): Promise<T> {
return http.get(url, { params })
}
// 封装 POST 请求
export function post<T>(url: string, data?: any): Promise<T> {
return http.post(url, data)
}
// 封装 PUT 请求
export function put<T>(url: string, data?: any): Promise<T> {
return http.put(url, data)
}
// 封装 DELETE 请求
export function del<T>(url: string, params?: any): Promise<T> {
return http.delete(url, { params })
}
export default http

37
src/libs/message.ts

@ -0,0 +1,37 @@
import { ElMessage } from 'element-plus'
export const FtMessage = {
info: (message: string) => {
ElMessage({
message,
type: 'info',
grouping: true,
plain: true,
})
},
success: (message: string) => {
ElMessage({
message,
type: 'success',
grouping: true,
plain: true,
})
},
warning: (message: string) => {
ElMessage({
message,
type: 'warning',
grouping: true,
plain: true,
})
},
error: (message: string) => {
ElMessage({
message,
type: 'error',
grouping: true,
plain: true,
})
},
}

193
src/libs/socket.ts

@ -0,0 +1,193 @@
// src/utils/websocket.ts
import type { Ref } from 'vue'
import { ref, watch } from 'vue'
// 定义请求和响应类型
export interface WebSocketRequest {
messageType: 'Command'
fnName: string
className: string
messageId: string
params: Record<string, any>
}
export interface WebSocketResponse {
ackcode: number
rely: Record<string, any>
messageId: string
messageType: 'Ack'
className: string
fnName: string
timeStamp: number
}
// WebSocket客户端类
export class WebSocketClient {
private socket: WebSocket
private url: string
private isConnecting = false
public readonly isConnected: Ref<boolean> = ref(false)
public readonly connectionError: Ref<string | null> = ref(null)
private responseHandlers = new Map<string, (response: WebSocketResponse) => void>()
private eventListeners = new Map<string, ((response: WebSocketResponse) => void)[]>()
constructor(url: string) {
this.url = url
this.socket = this.createWebSocket()
}
// 创建WebSocket实例
private createWebSocket() {
const socket = new WebSocket(this.url)
socket.onopen = () => {
this.isConnecting = false
this.isConnected.value = true
this.connectionError.value = null
}
socket.onclose = (event) => {
this.isConnected.value = false
this.connectionError.value = `连接关闭: ${event.code} ${event.reason}`
// 非正常关闭时尝试重连
if (event.code !== 1000) {
this.scheduleReconnect()
}
}
socket.onerror = (error) => {
this.isConnected.value = false
this.connectionError.value = `连接错误: ${(error as any).message || '未知错误'}`
this.scheduleReconnect()
}
socket.onmessage = (event) => {
try {
const response: WebSocketResponse = JSON.parse(event.data)
// 处理特定请求的响应
const handler = this.responseHandlers.get(response.messageId)
if (handler) {
handler(response)
this.responseHandlers.delete(response.messageId)
return
}
// 处理事件订阅
const listeners = this.eventListeners.get(response.className) || []
listeners.forEach(listener => listener(response))
// 全局事件监听
const globalListeners = this.eventListeners.get('*') || []
globalListeners.forEach(listener => listener(response))
}
catch (parseError) {
console.error('解析WebSocket消息失败', parseError)
}
}
return socket
}
public async waitAndSend<T = Record<string, any>>(
request: WebSocketRequest,
): Promise<WebSocketResponse & { rely: T }> {
// 等待连接建立
await new Promise<void>((resolve) => {
if (this.isConnected.value) {
resolve()
}
else {
const watcher = watch(this.isConnected, (connected) => {
if (connected) {
watcher() // 停止监听
resolve()
}
})
}
})
// 连接建立后发送请求
return this.sendRequest(request)
}
// 发送请求
public sendRequest<T = Record<string, any>>(
request: WebSocketRequest,
): Promise<WebSocketResponse & { rely: T }> {
console.log('this.isConnected.value---', this.isConnected.value)
return new Promise((resolve, reject) => {
if (this.isConnected.value) {
this.socket.send(JSON.stringify(request))
this.responseHandlers.set(request.messageId, (response) => {
resolve(response as WebSocketResponse & { rely: T })
})
// 设置超时
setTimeout(() => {
if (this.responseHandlers.has(request.messageId)) {
this.responseHandlers.delete(request.messageId)
reject(new Error(`请求超时: ${request.messageId}`))
}
}, 10000) // 10秒超时
}
else {
if (!this.isConnecting) {
this.reconnect()
}
}
})
}
// 订阅事件
public subscribe(className: string | '*', callback: (response: WebSocketResponse) => void) {
if (!this.eventListeners.has(className)) {
this.eventListeners.set(className, [])
}
this.eventListeners.get(className)?.push(callback)
return () => {
const listeners = this.eventListeners.get(className)
if (listeners) {
const index = listeners.indexOf(callback)
if (index !== -1) {
listeners.splice(index, 1)
}
}
}
}
// 重连逻辑
private reconnect() {
this.isConnecting = true
if (this.socket.readyState !== WebSocket.CLOSED && this.socket.readyState !== WebSocket.CLOSING) {
this.socket.close()
}
this.socket = this.createWebSocket()
}
// 安排重连
private scheduleReconnect() {
if (this.isConnecting) {
return
}
this.isConnecting = true
setTimeout(() => {
this.isConnecting = false
this.reconnect()
}, 3000) // 3秒后重连
}
// 手动关闭连接
public close() {
this.responseHandlers.clear()
this.eventListeners.clear()
this.socket.close()
}
}
// 存储已创建的WebSocket实例
const urlSocketMap = new Map<string, WebSocketClient>()
// 创建WebSocket客户端的工厂函数
export const createWebSocket = (url?: string): WebSocketClient => {
url = url || import.meta.env.FT_WS_URL
if (urlSocketMap.has(url)) {
return urlSocketMap.get(url)!
}
else {
const client = new WebSocketClient(url)
urlSocketMap.set(url, client)
return client
}
}

13
src/libs/token.ts

@ -0,0 +1,13 @@
import { SESSIONSTORAGE_TOKEN_KEY } from './constant'
export function getToken() {
return sessionStorage[SESSIONSTORAGE_TOKEN_KEY]
}
export function setToken(token: string) {
sessionStorage[SESSIONSTORAGE_TOKEN_KEY] = token
}
export function delToken() {
sessionStorage.removeItem(SESSIONSTORAGE_TOKEN_KEY)
}

103
src/libs/utils.ts

@ -0,0 +1,103 @@
export const cmdNameMap = {
door_open: '开门',
door_close: '关门',
door_stop: '停止开关门',
liquid_arm_rotation: '加液机械臂启动',
liquid_arm_reset: '加液机械臂复位',
liquid_arm_stop: '加液机械臂停止',
liquid_pump_start: '启动加液泵',
liquid_pump_stop: '停止加液泵',
liquid_pump_pre_filling: '预充加液头',
liquid_pump_pre_evacuation: '排空加液头',
shaker_start: '摇匀',
shaker_stop: '停止摇匀',
pallet_elevator_lift_up: '托盘上升',
pallet_elevator_lift_down: '托盘下降',
pallet_elevator_stop: '托盘停止',
heater_start: '开始加热',
heater_stop: '停止加热',
heater_start_heat_maintaining: '启动恒温',
heater_stop_heat_maintaining: '停止恒温',
cold_trap_start_refrigeration: '启动制冷',
cold_trap_stop_refrigeration: '停止制冷',
fan_start: '打开风扇',
fan_stop: '关闭风扇',
transportation_arm_move: '龙门架机械臂移动',
transportation_arm_stop: '龙门架机械臂停止移动',
transportation_arm_reset: '龙门架机械臂复位',
holding_jaw_open: '打开夹爪',
holding_jaw_pause: '暂停夹爪',
holding_jaw_close: '闭合夹爪',
cover_elevator_lift_up: '拍子抬升',
cover_elevator_stop: '拍子停止',
cover_elevator_reset: '拍子复位',
cover_elevator_lift_down: '拍子下降',
cold_trap_start_recycle: '开启循环',
cold_trap_stop_recycle: '停止循环',
solution_add: '加液',
move_to_heat_area: '移至加热',
move_to_solution_area: '移至加液',
heat_start: '开始加热',
heat_stop: '停止加热',
take_photo: '拍照',
tray_up: '抬起托盘',
tray_down: '降下托盘',
shake_start: '开始摇匀',
shake_stop: '停止摇匀',
}
export const generateColors = (count: number): string[] => {
const colors: string[] = []
for (let i = 0; i < count; i++) {
// Increase hue step to make colors more distinct
const hue = (i * 360) / count
// Introduce variation in saturation and lightness with larger steps
const saturation = 30 + (i % 5) * 20 // Alternate between 30, 50, 70, 90, 110
const lightness = 30 + (i % 4) * 20 // Alternate between 30, 50, 70, 90
// Convert HSL to RGB
const rgb = hslToRgb(hue, saturation, lightness)
// Convert RGB to hex
const hex = rgbToHex(rgb.r, rgb.g, rgb.b)
colors.push(hex)
}
return colors
}
const hslToRgb = (h: number, s: number, l: number): { r: number, g: number, b: number } => {
s /= 100
l /= 100
const k = (n: number) => (n + h / 30) % 12
const a = s * Math.min(l, 1 - l)
const f = (n: number) =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)))
return {
r: Math.round(f(0) * 255),
g: Math.round(f(8) * 255),
b: Math.round(f(4) * 255),
}
}
const rgbToHex = (r: number, g: number, b: number): string => {
const toHex = (c: number) => `0${c.toString(16)}`.slice(-2)
return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}
export const colors = generateColors(100)
export function isNumber(value: any) {
return typeof value === 'number' && !Number.isNaN(value)
}
export function formatDateTime(template: string = 'YYYY/MM/DD HH:mm:ss'): string {
const now = new Date()
const tokens: Record<string, string> = {
YYYY: String(now.getFullYear()),
MM: String(now.getMonth() + 1).padStart(2, '0'),
DD: String(now.getDate()).padStart(2, '0'),
HH: String(now.getHours()).padStart(2, '0'),
mm: String(now.getMinutes()).padStart(2, '0'),
ss: String(now.getSeconds()).padStart(2, '0'),
}
return template.replace(/YYYY|MM|DD|HH|mm|ss/g, token => tokens[token]!)
}

27
src/main.ts

@ -0,0 +1,27 @@
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import FtButton from 'components/common/FTButton/index.vue'
import FtDialog from 'components/common/FTDialog/index.vue'
import FtStream from 'components/common/FTStream/index.vue'
import FtTable from 'components/common/FTTable/index.vue'
import ElementPlus from 'element-plus'
import locale from 'element-plus/es/locale/lang/zh-cn'
import pinia from 'stores/index'
import { createApp } from 'vue'
import App from './app.vue'
import router from './router'
import 'element-plus/dist/index.css'
import 'assets/styles/main.scss'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(pinia)
app.component('FtTable', FtTable)
app.component('FtButton', FtButton)
app.component('FtDialog', FtDialog)
app.component('FtStream', FtStream)
app
.use(router)
.use(ElementPlus, { locale, zIndex: 3000 })
.mount('#app')

26
src/router/index.ts

@ -0,0 +1,26 @@
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
import { getToken } from '@/libs/token'
import { createRouter, createWebHashHistory } from 'vue-router'
import routes from './routes'
const router = createRouter({
history: createWebHashHistory(),
routes,
})
router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
if (getToken()) {
next()
}
else {
// 未登录
if (to.name === 'login') {
next()
}
else {
next({ name: 'login' })
}
}
})
export default router

34
src/router/routes.ts

@ -0,0 +1,34 @@
import type { RouteRecordRaw } from 'vue-router'
import n_home from 'assets/images/menuIcon/n_home.svg'
import s_home from 'assets/images/menuIcon/s_home.svg'
const authRoutes: RouteRecordRaw[] = [
{
path: '/home',
name: 'home',
component: () => import('views/home/index.vue'),
meta: {
isDefault: true,
title: '消毒',
icon: n_home,
activeIcon: s_home,
},
},
]
const routes: RouteRecordRaw[] = [
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue'),
},
{
path: '/',
component: () => import('../layouts/default.vue'),
redirect: '/home',
children: authRoutes,
},
]
export { authRoutes }
export default routes

102
src/stores/debugStore.ts

@ -0,0 +1,102 @@
import { debugControl } from 'apis/system'
import { FtMessage } from 'libs/message'
import { cmdNameMap } from 'libs/utils'
import { defineStore } from 'pinia'
import { useSystemStore } from 'stores/systemStore'
export const useDebugStore = defineStore('debug', {
state: (): Debug.DebugStore => ({
formData: {
// 加液机械臂
liquidArmData: {
largeArmAngle: undefined,
smallArmAngle: undefined,
largeArmRotationVelocity: undefined,
smallArmRotationVelocity: undefined,
},
// 加液泵
liquidPumpData: {
index: undefined,
// direction: 'forward',
volume: 20,
velocity: 3,
},
// 摇匀速度
shakeSpeed: {
velocity: undefined,
},
// 加热区
heatArea: {
index: 'heat_module_01',
heatMotorData: {
distance: undefined,
velocity: undefined,
times: undefined,
},
heatTemperature: {
temperature: undefined,
},
coldTrap: {
temperature: undefined,
},
},
// 转运模组
transferModule: {
// X轴
xMotorData: {
xDimDistance: undefined,
xDimVelocity: undefined,
times: undefined,
direction: 'backward',
},
// y轴
yMotorData: {
yDimDistance: undefined,
yDimVelocity: undefined,
times: undefined,
direction: 'backward',
},
// z轴
zMotorData: {
zDimDistance: undefined,
zDimVelocity: undefined,
times: undefined,
direction: 'forward',
},
// 夹爪
JawData: {
velocity: undefined,
openDistance: undefined,
closeDistance: undefined,
times: undefined,
},
},
// 拍子模组
lidData: {
velocity: undefined,
distance: undefined,
},
},
}),
actions: {
async sendControl(params: System.CmdControlParams<{ [key: string]: any }>) {
if (!params.commandId) {
params.commandId = Date.now().toString()
}
const systemStore = useSystemStore()
systemStore.systemList = []
// 提取 params.command 中的 xxx 部分
const commandKey = params.command.replace(/^debug_/, '')
// 使用提取的 key 匹配 cmdNameMap
const cmdName = cmdNameMap[commandKey as keyof typeof cmdNameMap] || params.command
await debugControl(params)
systemStore.updateStreamVisible(true)
FtMessage.success(`[${cmdName}]已发送`)
},
},
persist: true,
})

64
src/stores/homeStore.ts

@ -0,0 +1,64 @@
import { control } from 'apis/system'
import { FtMessage } from 'libs/message'
import { cmdNameMap } from 'libs/utils'
import { defineStore } from 'pinia'
import { useSystemStore } from 'stores/systemStore'
export const useHomeStore = defineStore('home', {
state: (): Home.HomeStore => ({
heatAreaList: [
{
label: 'A-1',
value: 'heat_module_01',
selected: false,
},
{
label: 'A-2',
value: 'heat_module_02',
selected: false,
},
{
label: 'A-3',
value: 'heat_module_03',
selected: false,
},
{
label: 'A-4',
value: 'heat_module_04',
selected: false,
},
{
label: 'A-5',
value: 'heat_module_05',
selected: false,
},
{
label: 'A-6',
value: 'heat_module_06',
selected: false,
},
],
}),
actions: {
selectChange(index: number) {
this.heatAreaList[index].selected = !this.heatAreaList[index].selected
console.log(this.heatAreaList)
},
async sendControl(params: System.CmdControlParams<{ [key: string]: any }>) {
if (!params.commandId) {
params.commandId = Date.now().toString()
}
const systemStore = useSystemStore()
systemStore.systemList = []
// 使用提取的 key 匹配 cmdNameMap
const cmdName = cmdNameMap[params.command as keyof typeof cmdNameMap] || params.command
await control(params)
systemStore.updateStreamVisible(true)
FtMessage.success(`[${cmdName}]已发送`)
},
},
persist: false,
})

7
src/stores/index.ts

@ -0,0 +1,7 @@
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
export default pinia

217
src/stores/systemStore.ts

@ -0,0 +1,217 @@
import { defineStore } from 'pinia'
export const useSystemStore = defineStore('system', {
state: (): System.SystemStore => ({
systemStatus: {
virtual: false,
initComplete: true,
selfTest: true,
emergencyStop: false,
door: {
status: false,
},
gantryArm: {
idle: true,
},
solutionModule: {
idle: true,
shaking: false,
trayStatus: 0,
solutionContainer: [
{
id: 1,
type: 'solution',
empty: false,
full: false,
},
{
id: 2,
type: 'solution',
empty: false,
full: false,
},
{
id: 3,
type: 'solution',
empty: false,
full: false,
},
{
id: 4,
type: 'solution',
empty: false,
full: false,
},
{
id: 5,
type: 'solution',
empty: false,
full: false,
},
{
id: 6,
type: 'solution',
empty: false,
full: false,
},
{
id: 7,
type: 'solution',
empty: false,
full: false,
},
{
id: 8,
type: 'solution',
empty: false,
full: false,
},
{
id: 9,
type: 'neutralization',
empty: false,
full: false,
},
],
pumping: false,
},
heatModule: [
{
moduleCode: 'heat_module_01',
trayStatus: 1,
heating: false,
capExist: false,
temperature: 0,
targetTemperature: 0,
},
{
moduleCode: 'heat_module_02',
trayStatus: 1,
heating: false,
capExist: false,
temperature: 100,
targetTemperature: 0,
},
{
moduleCode: 'heat_module_03',
trayStatus: 2,
heating: true,
capExist: false,
temperature: 130,
targetTemperature: 0,
},
{
moduleCode: 'heat_module_04',
trayStatus: 2,
heating: false,
capExist: false,
temperature: 0,
targetTemperature: 0,
},
{
moduleCode: 'heat_module_05',
trayStatus: 1,
heating: false,
capExist: false,
temperature: 0,
targetTemperature: 0,
},
{
moduleCode: 'heat_module_06',
trayStatus: 0,
heating: false,
capExist: false,
temperature: 0,
targetTemperature: 0,
},
],
tray: [
{
uuid: '111',
heatModuleId: 'heat_module_01',
inSolutionArea: false,
inHeatModule: true,
tubes: [
{
tubeNum: 1,
addSolution: true,
exists: true,
},
],
crafts: {
state: 'READY',
},
},
{
uuid: '',
heatModuleId: 'heat_module_02',
inSolutionArea: false,
inHeatModule: true,
tubes: [
{
tubeNum: 1,
addSolution: true,
exists: true,
},
],
crafts: {
state: 'RUNNING',
craft: {
id: 1,
name: '菱锌矿硫酸溶解法',
steps: '',
},
},
},
{
uuid: '',
heatModuleId: 'heat_module_04',
inSolutionArea: false,
inHeatModule: true,
tubes: [
{
tubeNum: 1,
addSolution: true,
exists: true,
},
],
// crafts: {
// state: 'ERROR',
// },
},
],
},
systemUser: {
username: '',
},
loginForm: {
username: import.meta.env.FT_NODE_ENV !== 'prod' ? 'admin' : '',
password: import.meta.env.FT_NODE_ENV !== 'prod' ? '123456' : '',
},
menuExpand: true,
isDebug: import.meta.env.FT_NODE_ENV !== 'prod',
streamVisible: false,
systemList: [],
}),
actions: {
updateDebug() {
this.isDebug = !this.isDebug
},
updateSystemStatus(data: System.SystemStatus) {
this.systemStatus = data
},
updateStreamVisible(bool: boolean) {
this.streamVisible = bool
},
updateMenuExpand() {
this.menuExpand = !this.menuExpand
},
updateSystemUser(data: System.SystemUser) {
this.systemUser = data
},
pushSystemList(text: any) {
this.systemList.push(text)
},
},
persist: false,
})

18
src/stores/useLiquidsStore.ts

@ -0,0 +1,18 @@
import { defineStore } from 'pinia'
interface liquids {
id: number
name: string
}
export const useLiquidStore = defineStore('liquid', () => {
const liquids: liquids[] = [{
id: 1,
name: '硫酸',
}, {
id: 2,
name: '硝酸',
}]
return {
liquids,
}
})

14
src/stores/useSolutionStore.ts

@ -0,0 +1,14 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useSolutionStore = defineStore('solution', () => {
const solutionList = ref<Solution.SolutionItem[]>([])
const updateSolution = (list: Solution.SolutionItem[]) => {
solutionList.value = list
}
return {
solutionList,
updateSolution,
}
})

27
src/types/user.d.ts

@ -0,0 +1,27 @@
declare namespace User {
interface User {
id: number
createTime?: string
updateTime?: string
username: string
nickname: string
password?: string | null
role: string
deleted: string
fixedUser?: string
}
interface AddUser {
username: string | number
nickname: string | number
password: string | number
role: string | number
fixedUser?: string | number
deleted: string | number
}
interface Login {
username: string
password: string
}
}

33
src/types/websocket.d.ts

@ -0,0 +1,33 @@
declare namespace Websocket {
// 发送请求的数据结构类型
interface WebSocketRequest {
messageType: 'Command'
fnName: string
className: string
messageId: string
params: Record<string, any>
}
// 接收响应的基础数据结构类型
interface WebSocketResponse {
ackcode: number
rely: Record<string, any>
messageId: string
messageType: 'Ack'
className: string
fnName: string
timeStamp: number
}
// AddLiquidService的getState方法响应结构
interface AddLiquidServiceState {
nowLiquid: number
workState: 'idle' | 'working' | 'error'
workStateDisplay: string
}
// 扩展WebSocketResponse以包含特定服务的响应类型
type TypedWebSocketResponse<T = Record<string, any>> = Omit<WebSocketResponse, 'rely'> & {
rely: T
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save