feat: init
commit
d2378f8782
|
|
@ -0,0 +1,28 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/dist/*
|
||||
.local
|
||||
.output.js
|
||||
.github
|
||||
.vscode
|
||||
/node_modules/**
|
||||
|
||||
*.html
|
||||
**/*.svg
|
||||
**/*.sh
|
||||
|
||||
/public/**
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"printWidth": 160,
|
||||
"arrowParens": "always",
|
||||
"bracketSameLine": true,
|
||||
"bracketSpacing": true,
|
||||
"semi": true,
|
||||
"singleAttributePerLine": false,
|
||||
"vueIndentScriptAndStyle": true,
|
||||
"htmlWhitespaceSensitivity": "ignore"
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA2SOM6Heb+BNGha/ucoV+GopddM7ckyGWALhGPJp/Z7P5jgw6
|
||||
NSJ1G/E7CFEukaLC50eupji9mA4o8Emtrgn8y7uMIc5lafHe0IPy+WA90PZyien4
|
||||
0u7dD0NrEbKH41SIEuZFbGev0CgQJsxmkS8CmOytmglyJ0JDBpJD9tQLwSuG9kad
|
||||
DrYPArQdQu+ZALt4gyG7m14c4mZ2hAcIUwNYqFY9g/HIp0q9al8SW3WqzkB1U7GS
|
||||
kh3i/MwtUvZWPI16aKW4/tdUX7y8PPguHQ1MWLd6DI0iGo9tqTQt35o9ax41O+0S
|
||||
EY4MgU1Q3XJaMrmrYUpZ2/Y4xJbHOHgyi6afzQIDAQABAoIBAGms4ovUgkSmZOD1
|
||||
MU/s5eVWx4rsje7RHqa1CAHAkxbOQTq/eqiXX3U83qT6lXZtRvu2KCpfXO4eng/r
|
||||
W6pi0/P3D4j4YOTBwNWsEdkJ3KvQ9QdnpiBJ/a3K+tW/FGEvp5XDGbBbefYNOWcY
|
||||
fSZVQadZMFfSFwtCNUqCbq82nY3hkoFVGiQ9EHUlvNCQM4y5VeJuCPzsl8rzAsyo
|
||||
gpkHyKxU/CNg+f5UuPwostR5eTXgkp6nlpa65yDK0szsww78keE/J1tOB0d4r+Oe
|
||||
12ZVzYLQrzQwt2CwIGT9KkAUv7eO7ZTMDsG8MYNnRPGXKgjSZqBSW0MCq7ksz1/P
|
||||
dHTJmSECgYEA9Q8VbnLkdk5NlRCNTONfjLhNUGmAqt/qLPi7tnJa0wfSpr3tg1Aj
|
||||
AxnV455fT81vbDP8V8tGDNx+/d5jBkIsdsCYOMa6dqZr1HOfSgbH8wETtU9mbKdB
|
||||
Gt/frdM3rkJvyd5RjoqMex4U7x4f1OWfThHVzvi8TzqfRSXNpbXBMdUCgYEA4tVa
|
||||
TBQhwgnjMHl9OYrW1urtf2fKEGOZA/uGJI55O7IL2SoYnVjFUHjlE4D94K/hdijp
|
||||
l2oFydD0GrWVkWULPvTdUFzMTRPH+SUfXbVqXBMJfHJYrRuZHsJBH2jIwIzu4LaA
|
||||
hliletIdJUtK8mUvwEb+4TlVUwfCYqkveu1EuhkCgYAHjK5pV6rIJkNnmznvK3YP
|
||||
HMJs/sMTAJDzT7pgtYcsxynrLyC5EefyOYKIX6GqELclCzjz73Q6AzT6VzaPw8wg
|
||||
4HAQF7c43oml4uX+XtUcHGViCY8rO7/atxjp/v7RJITTIEE89fG7/UJB15i9c1GE
|
||||
EzKWDL2oZzLu62o5d676/QKBgQDgiCBhvmvMDs18ZkW2d+BBzTpaKvqxTmVgs9EM
|
||||
zpripFNmG21SE1T9Wy4mKEEl7/NVaxoObzxbkSKQbb4ntcV0BB4uNi1k/ner/zsV
|
||||
H0aw7YcuUGHGuNLQx6h+1tIhB2BNv1lposXq1aFUETuWxOKHib8yYfY7wiqATshY
|
||||
/hRRwQKBgCkT2Wt/XjbXLCpX1viEJOLzYYQkrNyPvruXknCnQQ+0/cq4LoRqWZZR
|
||||
4RjS0RkoOF4vM38u/hgICiUUCR4bYUy/4O7uhNu5tDle6lIeB+ZxVpRRedE0OfQT
|
||||
tCpQd0yN9iONBlGyfAtpq7oNzuXgsl1OR4usZ8wCinfImChAl6wv
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/icons/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "vue-app-template",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host 0.0.0.0",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"upload": "bash ./upload.sh",
|
||||
"build-and-upload": "pnpm run build && pnpm run upload",
|
||||
"preview": "vite preview",
|
||||
"check-env": "node ./scripts/checkVersions.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/node": "^22.10.1",
|
||||
"@unocss/reset": "^66.1.1",
|
||||
"axios": "^1.7.9",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"gsap": "^3.13.0",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia-plugin-persistedstate": "^4.1.3",
|
||||
"semver": "^7.6.3",
|
||||
"unocss-preset-px-to-vw-or-vh": "^1.0.6",
|
||||
"unocss-preset-scrollbar-hide": "^1.0.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "4",
|
||||
"vue-virtual-draglist": "^3.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/carbon": "^1.2.8",
|
||||
"@types/gsap": "^3.0.0",
|
||||
"@types/qs": "^6.9.17",
|
||||
"@unocss/preset-wind": "^0.65.2",
|
||||
"@vitejs/plugin-basic-ssl": "^1.2.0",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vueuse/core": "^13.4.0",
|
||||
"prettier": "3.4.2",
|
||||
"sass-embedded": "^1.86.0",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"typescript": "~5.6.2",
|
||||
"unocss": "^0.65.2",
|
||||
"unplugin-auto-import": "^0.19.0",
|
||||
"vite": "^6.0.1",
|
||||
"vue-tsc": "^2.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.11.0",
|
||||
"pnpm": ">=9.13.2"
|
||||
},
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
// /plugins/svgBuilder.ts
|
||||
import {readFileSync, readdirSync} from 'fs'
|
||||
import {join as pathJoin} from 'path'
|
||||
import {Plugin} from 'vite'
|
||||
|
||||
let idPrefix = ''
|
||||
const svgTitle = /<svg([^>+].*?)>/
|
||||
const clearHeightWidth = /(width|height)="([^>+].*?)"/g
|
||||
const clearFill = /fill="[^>+].*?"/g;
|
||||
|
||||
const hasViewBox = /(viewBox="[^>+].*?")/g
|
||||
|
||||
const clearReturn = /(\r)|(\n)/g
|
||||
|
||||
const findSvgFile = (dir: string) => {
|
||||
const svgRes: string[] = []
|
||||
const directory = readdirSync(dir, {withFileTypes: true})
|
||||
for (const dirent of directory) {
|
||||
if (dirent?.isDirectory()) {
|
||||
svgRes.push(...findSvgFile(pathJoin(dir, dirent.name, '/')))
|
||||
} else {
|
||||
const svg = readFileSync(pathJoin(dir, dirent.name))
|
||||
.toString()
|
||||
.replace(clearReturn, '')
|
||||
.replace(clearFill,'')
|
||||
.replace(svgTitle, (_$1: string, $2: string) => {
|
||||
let width = '0'
|
||||
let height = '0'
|
||||
let content = $2.replace(
|
||||
clearHeightWidth,
|
||||
(_s1, s2:string, s3:string) => {
|
||||
if (s2 === 'width') {
|
||||
width = s3
|
||||
} else if (s2 === 'height') {
|
||||
height = s3
|
||||
}
|
||||
return ''
|
||||
}
|
||||
)
|
||||
if (!hasViewBox.test($2)) {
|
||||
content += `viewBox="0 0 ${width} ${height}"`
|
||||
}
|
||||
return `<symbol id="${idPrefix}-${dirent.name.replace(
|
||||
'.svg',
|
||||
''
|
||||
)}" ${content}>`
|
||||
})
|
||||
.replace('</svg>', '</symbol>')
|
||||
svgRes.push(svg)
|
||||
}
|
||||
}
|
||||
return svgRes
|
||||
}
|
||||
|
||||
const svgBuilder = (path: string, prefix = 'icon'): Plugin => {
|
||||
idPrefix = prefix
|
||||
const res = findSvgFile(path)
|
||||
return {
|
||||
name: 'svg-transform',
|
||||
transformIndexHtml(html) {
|
||||
return html.replace(
|
||||
'<body>',
|
||||
`<body><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">${res.join('')}</svg>`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default svgBuilder
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,39 @@
|
|||
// timer.worker.js
|
||||
let timer = null;
|
||||
let interval = 1000;
|
||||
|
||||
self.addEventListener('message', (e) => {
|
||||
switch (e.data.command) {
|
||||
case 'start':
|
||||
startTimer(e.data.interval);
|
||||
break;
|
||||
case 'stop':
|
||||
stopTimer();
|
||||
break;
|
||||
case 'update':
|
||||
interval = e.data.interval;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// 关闭时的清理逻辑
|
||||
self.addEventListener('close', () => {
|
||||
stopTimer();
|
||||
});
|
||||
|
||||
function startTimer(newInterval) {
|
||||
interval = newInterval || interval;
|
||||
stopTimer(); // 先停止已有定时器
|
||||
self.postMessage({ type: 'tick', timestamp:performance.now() });
|
||||
timer = setInterval(() => {
|
||||
const timestamp = performance.now();
|
||||
self.postMessage({ type: 'tick', timestamp });
|
||||
}, interval);
|
||||
}
|
||||
|
||||
function stopTimer() {
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
const semver = require('semver')
|
||||
const { engines } = require('../package')// 这里的package是你的package.json文件路径
|
||||
const version = engines.node
|
||||
|
||||
if (!semver.satisfies(process.version, version)) {
|
||||
console.log(
|
||||
[
|
||||
'node环境变量版本错误',
|
||||
'你的node环境启动位置' + process.execPath + '.',
|
||||
'要求环境版本' + version,
|
||||
'你的环境版本' + process.version
|
||||
].join('\n')
|
||||
)
|
||||
process.exit(1)
|
||||
}else{
|
||||
console.log(`echo check environment successfully`)
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<router-view v-slot="{ Component,route }">
|
||||
<keep-alive :include="include" :exclude="excludes">
|
||||
<component :is="Component" :key="route.path"/>
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { excludes } from '@/router/keepAlive'
|
||||
|
||||
const include:string[] = []
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 过渡动画:左右滑动并且淡入淡出 */
|
||||
|
||||
.fade-slide-enter-active, .fade-slide-leave-active {
|
||||
transition: transform 1s ease, opacity 1s ease;
|
||||
}
|
||||
|
||||
/* 进入动画:从右侧进入 */
|
||||
.fade-slide-enter {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 离开动画:从左侧离开 */
|
||||
.fade-slide-leave-to {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import { useUserStore } from "@/store/user";
|
||||
|
||||
/*
|
||||
* @Author: HideInMatrix
|
||||
* @Date: 2024-07-15
|
||||
* @LastEditors: error: git config user.name & please set dead value or install git
|
||||
* @LastEditTime: 2024-09-01
|
||||
* @Description: 请求封装
|
||||
*/
|
||||
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
|
||||
|
||||
interface FetchOptions extends RequestInit {
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
interface ApiResponse {
|
||||
result?: unknown;
|
||||
error?: string;
|
||||
code?: number;
|
||||
success?: boolean;
|
||||
message?:string;
|
||||
}
|
||||
|
||||
const apiClient = (method: HttpMethod) => {
|
||||
return async (
|
||||
url: string,
|
||||
data?: unknown,
|
||||
options: FetchOptions = {}
|
||||
): Promise<ApiResponse> => {
|
||||
const userStore = useUserStore();
|
||||
const accessToken = userStore.getAccessToken
|
||||
const config: FetchOptions = {
|
||||
method,
|
||||
headers:{ Authorization: `Bearer ${accessToken}`},
|
||||
...options,
|
||||
};
|
||||
|
||||
if (method !== "GET" && data) {
|
||||
config.body = JSON.stringify(data);
|
||||
} else if (method === "GET" && data) {
|
||||
const _params = [];
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
_params.push(`${key}=${value}`);
|
||||
}
|
||||
url += `?${_params.join("&")}`;
|
||||
}
|
||||
|
||||
const response = await fetch(`${url}`, config);
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
error: result.message || "Request failed",
|
||||
code: response.status,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
export const getRequest = apiClient("GET");
|
||||
export const postRequest = apiClient("POST");
|
||||
export const putRequest = apiClient("PUT");
|
||||
export const deleteRequest = apiClient("DELETE");
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
const baseUrl = "http://api.screen.jinze.ycymedu.com";
|
||||
|
||||
export const getPaymentUrl = () => `${baseUrl}/api/bigScreenData/bigScreenData`;
|
||||
|
||||
export const getGainUrl = () => `${baseUrl}/api/bigScreenData/bigScreenCustomerAcq`;
|
||||
|
||||
export const getAcqTrend = () => `${baseUrl}/api/bigScreenData/bigScreenAcqTrend`;
|
||||
|
||||
export const getSegmentStatic = () => `${baseUrl}/api/bigScreenData/bigScreenStages`;
|
||||
|
||||
export const getBigScreenRanking = () => `${baseUrl}/api/bigScreenData/bigScreenRanks`;
|
||||
|
||||
export const getSixStatisticsUrl = () => `${baseUrl}/api/bigScreenData/wechatData`
|
||||
|
||||
export const postLoginUrl=() => `${baseUrl}/api/sysAuth/BigScreenLogin`
|
||||
|
||||
export const getUserInfoUrl = ()=> `${baseUrl}/api/sysAuth/userInfo`
|
||||
|
||||
export const getLogoutUrl = () => `${baseUrl}/api/sysAuth/logout`
|
||||
|
|
@ -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="14.13671875" height="17.787841796875" viewBox="0 0 14.13671875 17.787841796875"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_110_5610"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="51.01040005683899%" stop-color="#97BBFF" stop-opacity="1"/><stop offset="52.34435796737671%" stop-color="#1168FF" stop-opacity="1"/><stop offset="100%" stop-color="#1185FF" stop-opacity="1"/></linearGradient><linearGradient x1="0.24648989737033844" y1="0" x2="0.3002182700303045" y2="0.8341024570154847" id="master_svg1_110_5613"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="100%" stop-color="#2D8CFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_110_5623"><stop offset="0%" stop-color="#66E0FF" stop-opacity="0"/><stop offset="100%" stop-color="#1164FF" stop-opacity="0.5"/></linearGradient></defs><g><g style="opacity:0.30000001192092896;"><path d="M0.5,2.60546875L13.1633,10.46999875L0.5,17.78786875L0.5,15.87376875L5.18962,10.46999875L0.5,4.66468875L0.5,2.60546875Z" fill-rule="evenodd" fill="#044BB8" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M0.5,0.8990478515625L13.1633,8.7635778515625L0.5,16.0814478515625L0.5,14.1673478515625L5.18962,8.7635778515625L0.5,2.9582678515625L0.5,0.8990478515625Z" fill-rule="evenodd" fill="url(#master_svg0_110_5610)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M0,0L0,2.95833L0,3.13506L4.53757,8.75214L0,13.9807L0,16.948L14.1359,8.77909L0,0ZM1,2.78161L5.84168,8.77514L1,14.3541L1,15.2151L12.1907,8.74819L1,1.79821L1,2.78161Z" fill-rule="evenodd" fill="url(#master_svg1_110_5613)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g><g><path d="M0.5,0.89892578125L13.1633,8.76345578125L5.18962,8.76345578125L0.5,2.95814578125L0.5,0.89892578125Z" fill-rule="evenodd" fill="url(#master_svg2_110_5623)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" viewBox="0 0 544.5 210.75"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_95_7905"><stop offset="0%" stop-color="#23518C" stop-opacity="0.20000000298023224"/><stop offset="100%" stop-color="#17439D" stop-opacity="0.10000000149011612"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg1_95_7906" gradientTransform="translate(272.25 210.5) rotate(90) scale(33.016276359558105 293.6848504078262)"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.10000000149011612"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg2_95_7907" gradientTransform="translate(272.25 210.5) rotate(90) scale(7.3813605308532715 170.33950726831247)"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.20000000298023224"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg3_95_7908" gradientTransform="translate(272.25 210.5) rotate(90) scale(3.5998570919036865 121.80235547062695)"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.5"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="0.5" y1="0.05106060206890106" x2="0.5" y2="1" id="master_svg4_81_5443"><stop offset="0%" stop-color="#525DFF" stop-opacity="0"/><stop offset="100%" stop-color="#525DFF" stop-opacity="0.47999998927116394"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg5_13_2169" gradientTransform="translate(250.49790859222412 0.5) rotate(0) scale(5.699835777282715 Infinity)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg6_13_2170"><stop offset="0%" stop-color="#36C8FF" stop-opacity="0"/><stop offset="53.635478019714355%" stop-color="#27AEFF" stop-opacity="1"/><stop offset="100%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/></linearGradient></defs><g><g><path d="M0.25 0.5C0.25 0.5 0.25 0.5 0.25 0.5L544.25 0.5C544.25 0.5 544.25 0.5 544.25 0.5L544.25 210.5C544.25 210.5 544.25 210.5 544.25 210.5L0.25 210.5C0.25 210.5 0.25 210.5 0.25 210.5Z" fill="#000000" fill-opacity="0.25"/><path d="M0.25 0.5C0.25 0.5 0.25 0.5 0.25 0.5L544.25 0.5C544.25 0.5 544.25 0.5 544.25 0.5L544.25 210.5C544.25 210.5 544.25 210.5 544.25 210.5L0.25 210.5C0.25 210.5 0.25 210.5 0.25 210.5Z" fill="url(#master_svg0_95_7905)" fill-opacity="1"/><path d="M0.25 0.5C0.25 0.5 0.25 0.5 0.25 0.5L544.25 0.5C544.25 0.5 544.25 0.5 544.25 0.5L544.25 210.5C544.25 210.5 544.25 210.5 544.25 210.5L0.25 210.5C0.25 210.5 0.25 210.5 0.25 210.5Z" fill="url(#master_svg1_95_7906)" fill-opacity="1"/><path d="M0.25 0.5C0.25 0.5 0.25 0.5 0.25 0.5L544.25 0.5C544.25 0.5 544.25 0.5 544.25 0.5L544.25 210.5C544.25 210.5 544.25 210.5 544.25 210.5L0.25 210.5C0.25 210.5 0.25 210.5 0.25 210.5Z" fill="url(#master_svg2_95_7907)" fill-opacity="1"/><path d="M0.25 0.5C0.25 0.5 0.25 0.5 0.25 0.5L544.25 0.5C544.25 0.5 544.25 0.5 544.25 0.5L544.25 210.5C544.25 210.5 544.25 210.5 544.25 210.5L0.25 210.5C0.25 210.5 0.25 210.5 0.25 210.5Z" fill="url(#master_svg3_95_7908)" fill-opacity="1"/><path d="M0.25 0.5C0.25 0.5 0.25 0.5 0.25 0.5L544.25 0.5C544.25 0.5 544.25 0.5 544.25 0.5L544.25 210.5C544.25 210.5 544.25 210.5 544.25 210.5L0.25 210.5C0.25 210.5 0.25 210.5 0.25 210.5Z" stroke="url(#master_svg4_81_5443)" fill-opacity="0" fill="none" stroke-width="0.5"/></g><g style="opacity:0.44999998807907104;"><path d="M480.25,1L289.725,1L245.498,1L64.25,1L64.25,0L245.498,0L289.725,0L480.25,0L480.25,1Z" fill-rule="evenodd" fill="url(#master_svg5_13_2169)" fill-opacity="1"/><path d="M480.25,1L289.725,1L245.498,1L64.25,1L64.25,0L245.498,0L289.725,0L480.25,0L480.25,1Z" fill-rule="evenodd" fill="url(#master_svg6_13_2170)" fill-opacity="1"/></g></g></svg>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" viewBox="0 0 188 36"><defs><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg0_110_5669"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.4000000059604645"/><stop offset="23.317307233810425%" stop-color="#2773FF" stop-opacity="0.25"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.05999999865889549"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg1_110_4138" gradientTransform="translate(132.2986946851015 34.756103515625) rotate(76.51046439419082) scale(17.356884100084887 29.26667369717238)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg2_110_4139"><stop offset="0%" stop-color="#36C8FF" stop-opacity="0"/><stop offset="53.635478019714355%" stop-color="#27AEFF" stop-opacity="1"/><stop offset="100%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg3_110_5664"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg4_110_5643"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/><stop offset="18.59523504972458%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg5_110_5664"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient></defs><g><g><path d="M0,1L177.338,1L138.238,30.561L0,30.561L0,1Z" fill-rule="evenodd" fill="url(#master_svg0_110_5669)" fill-opacity="1"/></g><g><path d="M183.644,1.5L295.5,1.5L295.5,0.5L183.306,0.5L139.079,34.2561L0,34.2561L0,35.2561L139.417,35.2561L183.644,1.5Z" fill-rule="evenodd" fill="url(#master_svg1_110_4138)" fill-opacity="1"/><path d="M183.644,1.5L295.5,1.5L295.5,0.5L183.306,0.5L139.079,34.2561L0,34.2561L0,35.2561L139.417,35.2561L183.644,1.5Z" fill-rule="evenodd" fill="url(#master_svg2_110_4139)" fill-opacity="1"/></g><g><g><path d="M182.97852,1L294.145,1L288.074,6.2439L176,6.2439L182.97852,1Z" fill-rule="evenodd" fill="url(#master_svg3_110_5664)" fill-opacity="1"/></g><g><path d="M182.999984375,1L263.919784375,1L251.97318437500002,11.4878L169.146484375,11.4878L182.999984375,1Z" fill-rule="evenodd" fill="url(#master_svg4_110_5643)" fill-opacity="1"/></g><g style="opacity:0.5;"><g><path d="M184.1035,1L295.464,1L295.464,23.0244L155,23.0244L184.1035,1Z" fill-rule="evenodd" fill="url(#master_svg5_110_5664)" fill-opacity="1"/></g></g></g></g></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" viewBox="0 0 255 36"><defs><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg0_110_5669"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.4000000059604645"/><stop offset="23.317307233810425%" stop-color="#2773FF" stop-opacity="0.25"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.05999999865889549"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg1_110_4537" gradientTransform="translate(114.16638627648354 34.756103515625) rotate(78.3045141357308) scale(17.2358897800393 25.079449849220687)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1.578010082244873" y1="0.6616930961608887" x2="-0.00028524507193582627" y2="0.6588591327853952" id="master_svg2_110_4538"><stop offset="0%" stop-color="#36C8FF" stop-opacity="0"/><stop offset="53.635478019714355%" stop-color="#27AEFF" stop-opacity="1"/><stop offset="100%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg3_110_5566" gradientTransform="translate(538.6601538022733 1) rotate(0) scale(9.584570288854593 Infinity)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg4_110_5567"><stop offset="0%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/><stop offset="100%" stop-color="#27AEFF" stop-opacity="1"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg5_110_5664"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg6_110_5643"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/><stop offset="18.59523504972458%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0.06541949510574341" y2="0.5" id="master_svg7_110_5455"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient></defs><g><g><g><path d="M0,1L217.337,1L178.239,30.561L0,30.561L0,1Z" fill-rule="evenodd" fill="url(#master_svg0_110_5669)" fill-opacity="1"/></g><g><path d="M225.643,1.5L255,1.5L255,0.5L225.305,0.5L181.079,34.2561L0,34.2561L0,35.2561L181.417,35.2561L225.643,1.5Z" fill-rule="evenodd" fill="url(#master_svg1_110_4537)" fill-opacity="1"/><path d="M225.643,1.5L255,1.5L255,0.5L225.305,0.5L181.079,34.2561L0,34.2561L0,35.2561L181.417,35.2561L225.643,1.5Z" fill-rule="evenodd" fill="url(#master_svg2_110_4538)" fill-opacity="1"/></g></g><g><g><path d="M925.000609375,1.5L225.474609375,1.5L225.474609375,0.5L925.000609375,0.5L925.000609375,1.5Z" fill-rule="evenodd" fill="url(#master_svg3_110_5566)" fill-opacity="1"/><path d="M925.000609375,1.5L225.474609375,1.5L225.474609375,0.5L925.000609375,0.5L925.000609375,1.5Z" fill-rule="evenodd" fill="url(#master_svg4_110_5567)" fill-opacity="1"/></g><g><path d="M225.97852,1L924.145,1L918.074,6.2439L219,6.2439L225.97852,1Z" fill-rule="evenodd" fill="url(#master_svg5_110_5664)" fill-opacity="1"/></g><g><path d="M225.3535,1L893.92,1L881.973,11.4878L211.5,11.4878L225.3535,1Z" fill-rule="evenodd" fill="url(#master_svg6_110_5643)" fill-opacity="1"/></g><g><path d="M225.1035,0L924.964,0L924.964,22.0244L197,22.0244L225.1035,0Z" fill-rule="evenodd" fill="url(#master_svg7_110_5455)" fill-opacity="1"/></g></g></g></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" viewBox="188 0 108 36"><defs><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg0_110_4138" gradientTransform="translate(132.2986946851015 34.756103515625) rotate(76.51046439419082) scale(17.356884100084887 29.26667369717238)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg1_110_4139"><stop offset="0%" stop-color="#36C8FF" stop-opacity="0"/><stop offset="53.635478019714355%" stop-color="#27AEFF" stop-opacity="1"/><stop offset="100%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg2_110_5664"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg3_110_5643"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/><stop offset="18.59523504972458%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg4_110_5664"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient><linearGradient x1="0.9886833429336548" y1="0.5" x2="0" y2="0.5" id="master_svg5_110_5647"><stop offset="0%" stop-color="#02DBFF" stop-opacity="0"/><stop offset="100%" stop-color="#01B5FF" stop-opacity="1"/></linearGradient></defs><g><g><path d="M183.644,1.5L295.5,1.5L295.5,0.5L183.306,0.5L139.079,34.2561L0,34.2561L0,35.2561L139.417,35.2561L183.644,1.5Z" fill-rule="evenodd" fill="url(#master_svg0_110_4138)" fill-opacity="1"/><path d="M183.644,1.5L295.5,1.5L295.5,0.5L183.306,0.5L139.079,34.2561L0,34.2561L0,35.2561L139.417,35.2561L183.644,1.5Z" fill-rule="evenodd" fill="url(#master_svg1_110_4139)" fill-opacity="1"/></g><g><g><path d="M182.97852,1L294.145,1L288.074,6.2439L176,6.2439L182.97852,1Z" fill-rule="evenodd" fill="url(#master_svg2_110_5664)" fill-opacity="1"/></g><g><path d="M182.999984375,1L263.919784375,1L251.97318437500002,11.4878L169.146484375,11.4878L182.999984375,1Z" fill-rule="evenodd" fill="url(#master_svg3_110_5643)" fill-opacity="1"/></g><g style="opacity:0.5;"><g><path d="M184.1035,1L295.464,1L295.464,23.0244L155,23.0244L184.1035,1Z" fill-rule="evenodd" fill="url(#master_svg4_110_5664)" fill-opacity="1"/></g><g><g><path d="M268.89489541992185,5.195068359375L263.72240541992187,10.438968359375L260.8193054199219,10.438968359375L265.9917854199219,5.195068359375L268.89489541992185,5.195068359375ZM274.9515054199219,5.195068359375L269.78065541992186,10.438968359375L266.8759454199219,10.438968359375L272.0493054199219,5.195068359375L274.9515054199219,5.195068359375ZM281.00820541992186,5.195068359375L275.83480541992185,10.438968359375L272.93260541992186,10.438968359375L278.10600541992187,5.195068359375L281.00820541992186,5.195068359375ZM287.06480541992187,5.195068359375L281.89140541992185,10.438968359375L278.98920541992186,10.438968359375L284.1601054199219,5.195068359375L287.06480541992187,5.195068359375ZM286.9392054199219,10.438968359375L292.11170541992186,5.195068359375L289.20860541992187,5.195068359375L284.03610541992185,10.438968359375L286.9392054199219,10.438968359375Z" fill-rule="evenodd" fill="url(#master_svg5_110_5647)" fill-opacity="1"/></g></g></g></g></g></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" viewBox="256 0 669 36"><defs><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg0_110_5566" gradientTransform="translate(538.6601538022733 1) rotate(0) scale(9.584570288854593 Infinity)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg1_110_5567"><stop offset="0%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/><stop offset="100%" stop-color="#27AEFF" stop-opacity="1"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg2_110_5664"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg3_110_5643"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/><stop offset="18.59523504972458%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></linearGradient><linearGradient x1="1" y1="0.5" x2="0.06541949510574341" y2="0.5" id="master_svg4_110_5455"><stop offset="0%" stop-color="#2773FF" stop-opacity="0"/><stop offset="81.4047634601593%" stop-color="#2773FF" stop-opacity="0.21617308259010315"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0.30000001192092896"/></linearGradient><linearGradient x1="0.9886833429336548" y1="0.5" x2="0" y2="0.5" id="master_svg5_110_5647"><stop offset="0%" stop-color="#02DBFF" stop-opacity="0"/><stop offset="100%" stop-color="#01B5FF" stop-opacity="1"/></linearGradient></defs><g><g><g><path d="M925.000609375,1.5L225.474609375,1.5L225.474609375,0.5L925.000609375,0.5L925.000609375,1.5Z" fill-rule="evenodd" fill="url(#master_svg0_110_5566)" fill-opacity="1"/><path d="M925.000609375,1.5L225.474609375,1.5L225.474609375,0.5L925.000609375,0.5L925.000609375,1.5Z" fill-rule="evenodd" fill="url(#master_svg1_110_5567)" fill-opacity="1"/></g><g><path d="M225.97852,1L924.145,1L918.074,6.2439L219,6.2439L225.97852,1Z" fill-rule="evenodd" fill="url(#master_svg2_110_5664)" fill-opacity="1"/></g><g><path d="M225.3535,1L893.92,1L881.973,11.4878L211.5,11.4878L225.3535,1Z" fill-rule="evenodd" fill="url(#master_svg3_110_5643)" fill-opacity="1"/></g><g><path d="M225.1035,0L924.964,0L924.964,22.0244L197,22.0244L225.1035,0Z" fill-rule="evenodd" fill="url(#master_svg4_110_5455)" fill-opacity="1"/></g><g><path d="M898.3959025,4.195068359375L893.2234125,9.438968359375L890.3203125,9.438968359375L895.4927925,4.195068359375L898.3959025,4.195068359375ZM904.4525125,4.195068359375L899.2816625,9.438968359375L896.3769525,9.438968359375L901.5503125,4.195068359375L904.4525125,4.195068359375ZM910.5092125,4.195068359375L905.3358125,9.438968359375L902.4336125,9.438968359375L907.6070125,4.195068359375L910.5092125,4.195068359375ZM916.5658125,4.195068359375L911.3924125,9.438968359375L908.4902125,9.438968359375L913.6611125,4.195068359375L916.5658125,4.195068359375ZM916.4402125,9.438968359375L921.6127125,4.195068359375L918.7096125,4.195068359375L913.5371125,9.438968359375L916.4402125,9.438968359375Z" fill-rule="evenodd" fill="url(#master_svg5_110_5647)" fill-opacity="1"/></g></g></g></svg>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -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="480" height="48" viewBox="0 0 480 48"><g><path d="M0,48L480,48L480,0L10.1181,0L0,12.5L0,48L0,48Z" fill="#061E3A" fill-opacity="1"/><path d="M480,48L480,0L10.1181,0L0,12.5L0,48L480,48ZM1,47L479,47L479,1L10.5952,1L1,12.854L1,47Z" fill-rule="evenodd" fill="#2A8EFE" fill-opacity="1"/></g></svg>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" viewBox="0 0 14 22"><defs><pattern x="1.9090908765792847" y="3" width="10.181818008422852" height="16" patternUnits="userSpaceOnUse" id="master_svg0_120_993"><image x="0" y="0" width="42" height="66" transform="scale(0.2424242382957822,0.24242424242424243)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAABCCAYAAAAhZERsAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAOFSURBVGiB7dk/bBN3FMDx77vYlH9qJFKwQQIkaLsUIXXoAgssDIEyVIz8ERJ0AaXAUrUm7YnYAfEnXZspVZmqDqUIZgSICYQU/qwUKSj2ORJDqColuPcYEreWdbbPd7/f7xbedu89nT96z3e+k+F9OI6JGV2VtQHA69Uw/wGDF6r6hQtMt+gJ9TdIzfP4tFLVvS5AqWOspr9lie050f8ahREVprLCxoaWChIgnFXhVhbY2FCA8wX5A+H3LLB9QQEaOUaAOdfYvqH+kMx7yjFgpUts31CA7zfKXVV+Ala7wiaCAgz+TQl4hiNsYujIJ7IQCoeBRRxgE0MBfijINPDj8qFVbCooQKPAZYUHy4fWsGLiJBcD3favMg2sXU79I8qB0ka5Y+L8YGCiAN8V5IXA2ZaU8ckamWgzyjW9CXzZkjI2WSMTbUYDTgBzLSljkzUK9YtSV+HrtrQRrFEowGhBbgBTbenUWONQgPwA3wAv29KpsFag366XN4QcA8K2UmKsFSjA+U1yT4VrEaVEWGtQgMF5RoGnEaW+sUbvo1FRCXSnKg+BFRHl2PdZqxMFKBXkCcpoh3LsyVqHAjSKXFXhfodyLKwTqC8SsvT68qZDS0+sEyjAaFH+EjjTpaUr1vrF1B6Vmv6pcLBLS+QF5myizXgLJ4F6l5bIyTqH+kWpK4z3aFutwk1/Rtc1E86hV2q6RuB0j7ZQhFP+ZnndTDiHLsI14OMuLaEIx0sF+bU16fRiGqvqsAi3u7REIsEhdPyVDoU5ngHFDi0dkeBw9ZrnZxIiwRG0HOgRVQ51KPdEgoPVX5rVLQ2PJ8BgRDkWEixPVFWl4fELKZFgGVoOOANE/Xb3hQSLq79Q1c884RGwsq3UNxIsTXRSNe/BdQwhwRJ0LsBH+LwtnRgJFlZfDnQXyj1goCWdCgmGoVdqumYBpoHtLenUSDC8+gWYwAISDE60UtX9KtxqSRlDgiGoP6sf5Tye8v9vuVEkGFp9XpjEIhIMQCuBHlXhq+VDK0hIufryrG5l6YHjQywiIcVEVVVYeuCwjoQU0PE654A9OEBCwtVXarpD4RGQd4GEJH+DP9cVuvTA4QwJCaADQ/jATpfIvmM80N3lmi5WAj3q+rNjf0f9uq7NhTwWoZzFJHNxG/MhV8kIGTvGqjpcDvRI1o6u4c/ourFA92Xt6BmXXmvUq+776BTvAA46hzw7ExF1AAAAAElFTkSuQmCC"/></pattern></defs><g><g><rect x="1.9090908765792847" y="3" width="10.181818008422852" height="16" rx="0" fill="url(#master_svg0_120_993)" fill-opacity="1"/></g></g></svg>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -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="127" height="104" viewBox="0 0 127 104"><defs><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg0_85_02406" gradientTransform="translate(62.63833460211754 261.1206922531128) rotate(90) scale(129.7585763875395 128.02340110725947)"><stop offset="0%" stop-color="#4EAAFF" stop-opacity="1"/><stop offset="36.93000078201294%" stop-color="#0066FF" stop-opacity="0.5"/><stop offset="100%" stop-color="#000000" stop-opacity="0"/></radialGradient></defs><g><g transform="matrix(1,0,0,-1,0,262)" style="opacity:0.10000000149011612;"><path d="M63.5,131C28.4311,131,0,189.2103,0,261C0,261,127,261,127,261C127,189.1801,98.5743,131,63.5,131C63.5,131,63.5,131,63.5,131Z" fill="url(#master_svg0_85_02406)" fill-opacity="1"/></g><g style="opacity:0.20000000298023224;"><path d="M127,102.5L1,102.5L1,101.5L127,101.5L127,102.5Z" fill-rule="evenodd" fill="#0867A2" fill-opacity="1"/></g><g><path d="M126,1.5L0,1.5L0,0.5L126,0.5L126,1.5Z" fill-rule="evenodd" fill="#0867A2" fill-opacity="1"/></g><g><path d="M12,1.5L0,1.5L0,0.5L12,0.5L12,1.5Z" fill-rule="evenodd" fill="#00AAFF" fill-opacity="1"/></g></g></svg>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" viewBox="0 0 55 121"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_85_7578"><stop offset="0%" stop-color="#0085FF" stop-opacity="0.5"/><stop offset="100%" stop-color="#0047FF" stop-opacity="0"/></linearGradient><linearGradient x1="0.49977484345436096" y1="0.9948660731315613" x2="0.49977484345436096" y2="0.000026565079679130577" id="master_svg1_73_6481"><stop offset="0%" stop-color="#0058FF" stop-opacity="0"/><stop offset="100%" stop-color="#00AAFF" stop-opacity="0.5"/></linearGradient><linearGradient x1="0" y1="0.5" x2="1.0000001192092896" y2="0.5" id="master_svg2_73_6482"><stop offset="0%" stop-color="#0066FF" stop-opacity="1"/><stop offset="12.5%" stop-color="#0066FF" stop-opacity="1"/><stop offset="49.73750710487366%" stop-color="#87D4FF" stop-opacity="1"/><stop offset="91.14583134651184%" stop-color="#0075FF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5000787973403931" y1="0.9994168281555176" x2="0.5000787973403931" y2="0" id="master_svg3_85_5542"><stop offset="0%" stop-color="#00C9FF" stop-opacity="1"/><stop offset="100%" stop-color="#0072DD" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg4_13_2583"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="0"/><stop offset="100%" stop-color="#FFFFFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5000787973403931" y1="0.9994168281555176" x2="0.5000787973403931" y2="0" id="master_svg5_85_5542"><stop offset="0%" stop-color="#00C9FF" stop-opacity="1"/><stop offset="100%" stop-color="#0072DD" stop-opacity="1"/></linearGradient><linearGradient x1="0.5000787973403931" y1="0.9994168281555176" x2="0.5000787973403931" y2="0" id="master_svg6_85_5542"><stop offset="0%" stop-color="#00C9FF" stop-opacity="1"/><stop offset="100%" stop-color="#0072DD" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg7_13_2583"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="0"/><stop offset="100%" stop-color="#FFFFFF" stop-opacity="1"/></linearGradient></defs><g><g style="opacity:0.30000001192092896;"><path d="M1,111C1,113.761,3.23858,116,6,116L49,116C51.7614,116,54,113.761,54,111L54,4L1,4L1,111Z" fill="url(#master_svg0_85_7578)" fill-opacity="1"/></g><g><rect x="1" y="85" width="53" height="30" rx="0" fill="url(#master_svg1_73_6481)" fill-opacity="1" id="pw1" /><rect id="pw2" x="1" y="85" width="53" height="30" rx="0" fill="url(#master_svg2_73_6482)" fill-opacity="0.6000000238418579"/></g><g><ellipse cx="27.5" cy="5" rx="26.5" ry="5" fill="url(#master_svg3_85_5542)" fill-opacity="1"/></g><g><path d="M53.3333,5C53.3333,5.498801,52.8377,6.0743100000000005,51.576,6.68445C50.3307,7.28672,48.4753,7.85205,46.1077,8.33633C41.3823,9.30283,34.8033,9.909089999999999,27.5,9.909089999999999C27.5,9.909089999999999,27.5,11,27.5,11C34.924,11,41.6783,10.38521,46.6047,9.37758C49.063,8.87476,51.1127,8.26474,52.5663,7.56187C54.0033,6.86686,55,6.00743,55,5C55,5,53.3333,5,53.3333,5C53.3333,5,53.3333,5,53.3333,5ZM27.5,9.909089999999999C20.1965,9.909089999999999,13.6176,9.30283,8.89237,8.33633C6.52483,7.85205,4.6695,7.28672,3.42413,6.68445C2.16246,6.0743100000000005,1.66667,5.498801,1.66667,5C1.66667,5,0,5,0,5C0,6.00743,0.996595,6.86686,2.43374,7.56187C3.88718,8.26474,5.9371,8.87476,8.39527,9.37758C13.3215,10.38521,20.0759,11,27.5,11C27.5,11,27.5,9.909089999999999,27.5,9.909089999999999C27.5,9.909089999999999,27.5,9.909089999999999,27.5,9.909089999999999Z" fill="url(#master_svg4_13_2583)" fill-opacity="1"/></g><g><ellipse id="ellipse1" cx="27.5" cy="85" rx="26.5" ry="5" fill="url(#master_svg5_85_5542)" fill-opacity="1"/></g><g><ellipse cx="27.5" cy="115" rx="26.5" ry="5" fill="url(#master_svg6_85_5542)" fill-opacity="1"/></g><g><path d="M53.3333,115C53.3333,115.498801,52.8377,116.07431,51.576,116.68445C50.3307,117.28672,48.4753,117.85205,46.1077,118.33633C41.3823,119.30283,34.8033,119.90909,27.5,119.90909C27.5,119.90909,27.5,121,27.5,121C34.924,121,41.6783,120.38521,46.6047,119.37758C49.063,118.87476,51.1127,118.26474,52.5663,117.56187C54.0033,116.86686,55,116.00743,55,115C55,115,53.3333,115,53.3333,115C53.3333,115,53.3333,115,53.3333,115ZM27.5,119.90909C20.1965,119.90909,13.6176,119.30283,8.89237,118.33633C6.52483,117.85205,4.6695,117.28672,3.42413,116.68445C2.16246,116.07431,1.66667,115.498801,1.66667,115C1.66667,115,0,115,0,115C0,116.00743,0.996595,116.86686,2.43374,117.56187C3.88718,118.26474,5.9371,118.87476,8.39527,119.37758C13.3215,120.38521,20.0759,121,27.5,121C27.5,121,27.5,119.90909,27.5,119.90909C27.5,119.90909,27.5,119.90909,27.5,119.90909Z" fill="url(#master_svg7_13_2583)" fill-opacity="1"/></g></g></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="312.5" height="210.75" viewBox="0 0 312.5 210.75"><defs><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg0_95_7905"><stop offset="0%" stop-color="#23518C" stop-opacity="0.20000000298023224"/><stop offset="100%" stop-color="#17439D" stop-opacity="0.10000000149011612"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg1_95_7906" gradientTransform="translate(156.25 210.5) rotate(90) scale(33.016276359558105 168.4368994986062)"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.10000000149011612"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg2_95_7907" gradientTransform="translate(156.25 210.5) rotate(90) scale(7.3813605308532715 97.69471740388508)"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.20000000298023224"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg3_95_7908" gradientTransform="translate(156.25 210.5) rotate(90) scale(3.5998570919036865 69.85723328462429)"><stop offset="0%" stop-color="#2773FF" stop-opacity="0.5"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="0.5" y1="0.05106060206890106" x2="0.5" y2="1" id="master_svg4_81_5443"><stop offset="0%" stop-color="#525DFF" stop-opacity="0"/><stop offset="100%" stop-color="#525DFF" stop-opacity="0.47999998927116394"/></linearGradient><radialGradient cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" id="master_svg5_13_2169" gradientTransform="translate(139.9359314441681 0.5) rotate(0) scale(4.274876832962036 Infinity)"><stop offset="0%" stop-color="#4FE4FF" stop-opacity="1"/><stop offset="100%" stop-color="#2773FF" stop-opacity="0"/></radialGradient><linearGradient x1="1" y1="0.5" x2="0" y2="0.5" id="master_svg6_13_2170"><stop offset="0%" stop-color="#36C8FF" stop-opacity="0"/><stop offset="53.635478019714355%" stop-color="#27AEFF" stop-opacity="1"/><stop offset="100%" stop-color="#1997FF" stop-opacity="0.20000000298023224"/></linearGradient></defs><g><g><path d="M0.25,0.5L312.25,0.5L312.25,210.5L0.25,210.5L0.25,0.5Z" fill-rule="evenodd" fill="#000000" fill-opacity="0.25"/><path d="M0.25,0.5L312.25,0.5L312.25,210.5L0.25,210.5L0.25,0.5Z" fill-rule="evenodd" fill="url(#master_svg0_95_7905)" fill-opacity="1"/><path d="M0.25,0.5L312.25,0.5L312.25,210.5L0.25,210.5L0.25,0.5Z" fill-rule="evenodd" fill="url(#master_svg1_95_7906)" fill-opacity="1"/><path d="M0.25,0.5L312.25,0.5L312.25,210.5L0.25,210.5L0.25,0.5Z" fill-rule="evenodd" fill="url(#master_svg2_95_7907)" fill-opacity="1"/><path d="M0.25,0.5L312.25,0.5L312.25,210.5L0.25,210.5L0.25,0.5Z" fill-rule="evenodd" fill="url(#master_svg3_95_7908)" fill-opacity="1"/><path d="M312.5,0.25L0,0.25L0,210.75L312.5,210.75L312.5,0.25ZM0.5,210.25L0.5,0.75L312,0.75L312,210.25L0.5,210.25Z" fill-rule="evenodd" fill="url(#master_svg4_81_5443)" fill-opacity="1"/></g><g style="opacity:0.4000000059604645;"><path d="M312.25,1L220.432,1L177.243,1L0.25,1L0.25,0L177.243,0L220.432,0L312.25,0L312.25,1Z" fill-rule="evenodd" fill="url(#master_svg5_13_2169)" fill-opacity="1"/><path d="M312.25,1L220.432,1L177.243,1L0.25,1L0.25,0L177.243,0L220.432,0L312.25,0L312.25,1Z" fill-rule="evenodd" fill="url(#master_svg6_13_2170)" fill-opacity="1"/></g></g></svg>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,88 @@
|
|||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const createPinia: typeof import('pinia')['createPinia']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const defineStore: typeof import('pinia')['defineStore']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const getActivePinia: typeof import('pinia')['getActivePinia']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const mapActions: typeof import('pinia')['mapActions']
|
||||
const mapGetters: typeof import('pinia')['mapGetters']
|
||||
const mapState: typeof import('pinia')['mapState']
|
||||
const mapStores: typeof import('pinia')['mapStores']
|
||||
const mapWritableState: typeof import('pinia')['mapWritableState']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const setActivePinia: typeof import('pinia')['setActivePinia']
|
||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const storeToRefs: typeof import('pinia')['storeToRefs']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useId: typeof import('vue')['useId']
|
||||
const useLink: typeof import('vue-router')['useLink']
|
||||
const useModel: typeof import('vue')['useModel']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<div class="error-container flex flex-col items-center justify-center w-full h-full">
|
||||
<SvgIcon name="error" class="w-[48px] h-[48px] text-red-500 mb-2"/>
|
||||
<div class="text-red-500 text-sm">加载失败</div>
|
||||
<button
|
||||
class="mt-2 px-4 py-1 bg-[#45A2FF] text-white rounded hover:bg-[#3d8fe0] transition-colors"
|
||||
@click="retry"
|
||||
>
|
||||
重试
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import SvgIcon from "@/components/svg-icon/SvgIcon.vue";
|
||||
|
||||
const emit = defineEmits(['retry']);
|
||||
|
||||
const retry = () => {
|
||||
emit('retry');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.error-container {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<template>
|
||||
<div class="loading-container flex items-center justify-center w-full h-full">
|
||||
<div class="loading-spinner"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loading-container {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 3px solid #f3f3f3;
|
||||
border-top: 3px solid #45A2FF;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<div v-html="content">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
content:{
|
||||
type:String,
|
||||
default: ""
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
:deep(svg){
|
||||
width:100%;
|
||||
height:100%;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
export const useDate = () => {
|
||||
const hours = ref("00");
|
||||
const minutes = ref("00");
|
||||
const seconds = ref("00");
|
||||
const year = ref("");
|
||||
const month = ref("");
|
||||
const day = ref("");
|
||||
const weekday = ref(""); // 新增星期几变量
|
||||
|
||||
let timer: number | null = null;
|
||||
|
||||
const formateTime = () => {
|
||||
const now = new Date();
|
||||
|
||||
hours.value = now.getHours().toString().padStart(2, "0");
|
||||
minutes.value = now.getMinutes().toString().padStart(2, "0");
|
||||
seconds.value = now.getSeconds().toString().padStart(2, "0");
|
||||
|
||||
year.value = now.getFullYear().toString();
|
||||
month.value = (now.getMonth() + 1).toString().padStart(2, "0");
|
||||
day.value = now.getDate().toString().padStart(2, "0");
|
||||
|
||||
// 获取星期几并转换为中文格式
|
||||
const weekdayNumber = now.getDay(); // 0是星期日,1-6是星期一至星期六
|
||||
const weekdayNames = ["日", "一", "二", "三", "四", "五", "六"];
|
||||
weekday.value = "星期" + weekdayNames[weekdayNumber];
|
||||
};
|
||||
|
||||
return {
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
weekday, // 返回星期几
|
||||
timer,
|
||||
formateTime,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 自定义 Hook
|
||||
export const useScreenAuto = (designWidth = 1920, designHeight = 1080) => {
|
||||
|
||||
const screenEl = useTemplateRef<HTMLDivElement>("screen")
|
||||
const handleScreenAuto = () => {
|
||||
const clientWidth = document.documentElement.clientWidth
|
||||
const clientHeight = document.documentElement.clientHeight
|
||||
|
||||
const scale = clientWidth / clientHeight < designWidth / designHeight
|
||||
? clientWidth / designWidth
|
||||
: clientHeight / designHeight
|
||||
|
||||
if (screenEl.value) {
|
||||
screenEl.value.style.transform = `scale(${scale}) translate(-50%, -50%)`
|
||||
screenEl.value.classList.add('screen')
|
||||
}
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
handleScreenAuto()
|
||||
window.addEventListener('resize', handleScreenAuto)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleScreenAuto)
|
||||
})
|
||||
|
||||
return {
|
||||
handleScreenAuto
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
|
||||
// 定义二进制数字类型
|
||||
type BinaryDigits = Record<string, boolean[]>;
|
||||
type CanvasRef = HTMLCanvasElement | null;
|
||||
|
||||
/**
|
||||
* 数字电子表Hook
|
||||
* @returns {Object} - 包含canvas引用和初始化方法
|
||||
*/
|
||||
export const useDigitalWatch = () => {
|
||||
const canvasRef = ref<CanvasRef>(null)
|
||||
let animationTimer: number | null = null
|
||||
|
||||
// 二进制表示数字的配置
|
||||
const binary: BinaryDigits = {
|
||||
"0": [true, true, true, false, true, true, true],
|
||||
"1": [false, false, true, false, false, true, false],
|
||||
"2": [true, false, true, true, true, false, true],
|
||||
"3": [true, false, true, true, false, true, true],
|
||||
"4": [false, true, true, true, false, true, false],
|
||||
"5": [true, true, false, true, false, true, true],
|
||||
"6": [true, true, false, true, true, true, true],
|
||||
"7": [true, true, true, false, false, true, false],
|
||||
"8": [true, true, true, true, true, true, true],
|
||||
"9": [true, true, true, true, false, true, false]
|
||||
}
|
||||
|
||||
// 样式配置
|
||||
let on = "#44F1FF" // 激活颜色
|
||||
let off = "#031743" // 未激活颜色
|
||||
|
||||
// 缩放比例
|
||||
let scale = 1
|
||||
|
||||
// 工具函数 - 格式化数字为两位(补零)
|
||||
const formatZero = (n: number): string => {
|
||||
return n >= 10 ? n.toString() : `0${n}`
|
||||
}
|
||||
|
||||
// 渲染数字的一个区段
|
||||
const renderDigit = (ctx: CanvasRenderingContext2D, x = 0, y = 0, binaryPattern: boolean[]) => {
|
||||
const s = scale
|
||||
// top
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 20 * s, y + 5 * s)
|
||||
ctx.lineTo(x + 35 * s, y)
|
||||
ctx.lineTo(x + 105 * s, y)
|
||||
ctx.lineTo(x + 120 * s, y + 5 * s)
|
||||
ctx.lineTo(x + 105 * s, y + 20 * s)
|
||||
ctx.lineTo(x + 35 * s, y + 20 * s)
|
||||
ctx.lineTo(x + 20 * s, y + 5 * s)
|
||||
ctx.fillStyle = binaryPattern[0] ? on : off
|
||||
ctx.fill()
|
||||
|
||||
// top-left
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 15 * s, y + 10 * s)
|
||||
ctx.lineTo(x + 10 * s, y + 25 * s)
|
||||
ctx.lineTo(x + 10 * s, y + 95 * s)
|
||||
ctx.lineTo(x + 15 * s, y + 110 * s)
|
||||
ctx.lineTo(x + 30 * s, y + 95 * s)
|
||||
ctx.lineTo(x + 30 * s, y + 25 * s)
|
||||
ctx.fillStyle = binaryPattern[1] ? on : off
|
||||
ctx.fill()
|
||||
|
||||
// top-right
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 125 * s, y + 10 * s)
|
||||
ctx.lineTo(x + 130 * s, y + 25 * s)
|
||||
ctx.lineTo(x + 130 * s, y + 95 * s)
|
||||
ctx.lineTo(x + 125 * s, y + 110 * s)
|
||||
ctx.lineTo(x + 110 * s, y + 95 * s)
|
||||
ctx.lineTo(x + 110 * s, y + 25 * s)
|
||||
ctx.fillStyle = binaryPattern[2] ? on : off
|
||||
ctx.fill()
|
||||
|
||||
// middle
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 20 * s, y + 115 * s)
|
||||
ctx.lineTo(x + 35 * s, y + 100 * s)
|
||||
ctx.lineTo(x + 105 * s, y + 100 * s)
|
||||
ctx.lineTo(x + 120 * s, y + 115 * s)
|
||||
ctx.lineTo(x + 105 * s, y + 130 * s)
|
||||
ctx.lineTo(x + 35 * s, y + 130 * s)
|
||||
ctx.fillStyle = binaryPattern[3] ? on : off
|
||||
ctx.fill()
|
||||
|
||||
// bottom-left
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 15 * s, y + 120 * s)
|
||||
ctx.lineTo(x + 10 * s, y + 135 * s)
|
||||
ctx.lineTo(x + 10 * s, y + 205 * s)
|
||||
ctx.lineTo(x + 15 * s, y + 220 * s)
|
||||
ctx.lineTo(x + 30 * s, y + 205 * s)
|
||||
ctx.lineTo(x + 30 * s, y + 135 * s)
|
||||
ctx.fillStyle = binaryPattern[4] ? on : off
|
||||
ctx.fill()
|
||||
|
||||
// bottom-right
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 125 * s, y + 120 * s)
|
||||
ctx.lineTo(x + 130 * s, y + 135 * s)
|
||||
ctx.lineTo(x + 130 * s, y + 205 * s)
|
||||
ctx.lineTo(x + 125 * s, y + 220 * s)
|
||||
ctx.lineTo(x + 110 * s, y + 205 * s)
|
||||
ctx.lineTo(x + 110 * s, y + 135 * s)
|
||||
ctx.fillStyle = binaryPattern[5] ? on : off
|
||||
ctx.fill()
|
||||
|
||||
// bottom
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x + 20 * s, y + 225 * s)
|
||||
ctx.lineTo(x + 35 * s, y + 210 * s)
|
||||
ctx.lineTo(x + 105 * s, y + 210 * s)
|
||||
ctx.lineTo(x + 120 * s, y + 225 * s)
|
||||
ctx.lineTo(x + 105 * s, y + 235 * s)
|
||||
ctx.lineTo(x + 35 * s, y + 235 * s)
|
||||
ctx.lineTo(x + 20 * s, y + 225 * s)
|
||||
ctx.fillStyle = binaryPattern[6] ? on : off
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
// 计算合适的缩放比例
|
||||
const calculateScale = (width: number, height: number): number => {
|
||||
// 原始设计下,整个表宽约为940,高约为240
|
||||
const originalWidth = 940
|
||||
const originalHeight = 240
|
||||
|
||||
const scaleX = width / originalWidth
|
||||
const scaleY = height / originalHeight
|
||||
|
||||
// 取较小的缩放比例,确保完全显示
|
||||
return Math.min(scaleX, scaleY) * 0.9 // 稍微缩小一点,留出边距
|
||||
}
|
||||
|
||||
// 绘制时间
|
||||
const drawTime = () => {
|
||||
if (!canvasRef.value) return
|
||||
|
||||
const canvas = canvasRef.value
|
||||
const ctx = canvas.getContext('2d')
|
||||
if (!ctx) return
|
||||
|
||||
// 清除画布
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
|
||||
// 获取当前时间
|
||||
const date = new Date()
|
||||
|
||||
// 格式化时间数字
|
||||
const [hour_ten_digit, hour_one_digit] = formatZero(date.getHours()).split("")
|
||||
const [minute_ten_digit, minute_one_digit] = formatZero(date.getMinutes()).split("")
|
||||
const [second_ten_digit, second_one_digit] = formatZero(date.getSeconds()).split("")
|
||||
|
||||
// 计算中心位置,使表居中
|
||||
const centerY = (canvas.height - 240 * scale) / 2 + 20 * scale
|
||||
const startX = (canvas.width - 940 * scale) / 2 + 20 * scale
|
||||
|
||||
// 使用指定的间距渲染每个数字
|
||||
const spacing = 140 * scale
|
||||
|
||||
// 渲染每个数字
|
||||
renderDigit(ctx, startX, centerY, binary[hour_ten_digit])
|
||||
renderDigit(ctx, startX + spacing, centerY, binary[hour_one_digit])
|
||||
renderDigit(ctx, startX + spacing * 2.5, centerY, binary[minute_ten_digit])
|
||||
renderDigit(ctx, startX + spacing * 3.5, centerY, binary[minute_one_digit])
|
||||
renderDigit(ctx, startX + spacing * 5, centerY, binary[second_ten_digit])
|
||||
renderDigit(ctx, startX + spacing * 6, centerY, binary[second_one_digit])
|
||||
}
|
||||
|
||||
// 初始化函数
|
||||
const initWatch = (width = 1000, height = 300, interval = 500) => {
|
||||
if (!canvasRef.value) return
|
||||
|
||||
const canvas = canvasRef.value
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
|
||||
// 计算适合的缩放比例
|
||||
scale = calculateScale(width, height)
|
||||
|
||||
// 启动定时器更新时间显示
|
||||
drawTime() // 立即首次绘制
|
||||
animationTimer = window.setInterval(() => {
|
||||
drawTime()
|
||||
}, interval)
|
||||
}
|
||||
|
||||
// 停止计时器
|
||||
const stopWatch = () => {
|
||||
if (animationTimer) {
|
||||
clearInterval(animationTimer)
|
||||
animationTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
// 自动清理
|
||||
onBeforeUnmount(() => {
|
||||
stopWatch()
|
||||
})
|
||||
|
||||
// 返回需要暴露的内容
|
||||
return {
|
||||
canvasRef,
|
||||
initWatch,
|
||||
stopWatch,
|
||||
drawTime,
|
||||
// 自定义选项
|
||||
setColors: (onColor: string, offColor: string) => {
|
||||
on = onColor
|
||||
off = offColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
/**
|
||||
* 绘制3d图
|
||||
* @param pieData 总数据
|
||||
* @param internalDiameterRatio:透明的空心占比
|
||||
* @param distance 视角到主体的距离
|
||||
* @param alpha 旋转角度
|
||||
* @param pieHeight 立体的高度
|
||||
* @param opacity 饼或者环的透明度
|
||||
*/
|
||||
|
||||
// 定义饼图数据项接口
|
||||
interface PieDataItem {
|
||||
name: string;
|
||||
value: number;
|
||||
itemStyle?: {
|
||||
color?: string;
|
||||
opacity?: number;
|
||||
};
|
||||
startRatio?: number;
|
||||
endRatio?: number;
|
||||
}
|
||||
|
||||
// 定义图例数据项接口
|
||||
interface LegendItem {
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
// 参数方程接口
|
||||
interface ParametricEquation {
|
||||
u: {
|
||||
min: number;
|
||||
max: number;
|
||||
step: number;
|
||||
};
|
||||
v: {
|
||||
min: number;
|
||||
max: number;
|
||||
step: number;
|
||||
};
|
||||
x: (u: number, v: number) => number;
|
||||
y: (u: number, v: number) => number;
|
||||
z: (u: number, v: number) => number;
|
||||
}
|
||||
|
||||
// ECharts配置相关类型
|
||||
interface EChartsOption {
|
||||
series: SeriesItem[];
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
// 定义图表系列项接口
|
||||
interface SeriesItem {
|
||||
name: string;
|
||||
type: string;
|
||||
parametric: boolean;
|
||||
wireframe: {
|
||||
show: boolean;
|
||||
};
|
||||
pieData: PieDataItem;
|
||||
pieStatus: {
|
||||
selected: boolean;
|
||||
hovered: boolean;
|
||||
k: number;
|
||||
};
|
||||
center: string[];
|
||||
itemStyle?: {
|
||||
color?: string | number;
|
||||
opacity?: number;
|
||||
};
|
||||
parametricEquation?: ParametricEquation;
|
||||
}
|
||||
|
||||
const getPie3D = (
|
||||
pieData: PieDataItem[],
|
||||
internalDiameterRatio: number,
|
||||
distance: number,
|
||||
alpha: number,
|
||||
pieHeight: number,
|
||||
opacity: number = 1
|
||||
): EChartsOption => {
|
||||
const series: SeriesItem[] = []
|
||||
let sumValue: number = 0
|
||||
let startValue: number = 0
|
||||
let endValue: number = 0
|
||||
let legendData: LegendItem[] = []
|
||||
let legendBfb: LegendItem[] = []
|
||||
const k: number = 1 - internalDiameterRatio
|
||||
pieData.sort((a: PieDataItem, b: PieDataItem) => {
|
||||
return b.value - a.value
|
||||
})
|
||||
// 为每一个饼图数据,生成一个 series-surface 配置
|
||||
for (let i = 0; i < pieData.length; i++) {
|
||||
sumValue += pieData[i].value
|
||||
const seriesItem: SeriesItem = {
|
||||
name:
|
||||
typeof pieData[i].name === 'undefined'
|
||||
? `series${i}`
|
||||
: pieData[i].name,
|
||||
type: 'surface',
|
||||
parametric: true,
|
||||
wireframe: {
|
||||
show: false
|
||||
},
|
||||
pieData: pieData[i],
|
||||
pieStatus: {
|
||||
selected: false,
|
||||
hovered: false,
|
||||
k: k
|
||||
},
|
||||
center: ['10%', '50%']
|
||||
}
|
||||
if (typeof pieData[i].itemStyle !== 'undefined') {
|
||||
const itemStyle: { color?: string | number; opacity?: number } = {}
|
||||
itemStyle.color =
|
||||
typeof pieData[i].itemStyle?.color !== 'undefined'
|
||||
? pieData[i].itemStyle?.color
|
||||
: opacity
|
||||
itemStyle.opacity =
|
||||
typeof pieData[i].itemStyle?.opacity !== 'undefined'
|
||||
? pieData[i].itemStyle?.opacity
|
||||
: opacity
|
||||
seriesItem.itemStyle = itemStyle
|
||||
}
|
||||
series.push(seriesItem)
|
||||
}
|
||||
|
||||
// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
|
||||
// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
|
||||
legendData = []
|
||||
legendBfb = []
|
||||
for (let i = 0; i < series.length; i++) {
|
||||
endValue = startValue + series[i].pieData.value
|
||||
series[i].pieData.startRatio = startValue / sumValue
|
||||
series[i].pieData.endRatio = endValue / sumValue
|
||||
series[i].parametricEquation = getParametricEquation(
|
||||
series[i].pieData.startRatio || 0,
|
||||
series[i].pieData.endRatio || 0,
|
||||
false,
|
||||
false,
|
||||
k,
|
||||
series[i].pieData.value
|
||||
)
|
||||
startValue = endValue
|
||||
const bfb = fomatFloat(series[i].pieData.value / sumValue, 4)
|
||||
if (typeof bfb === 'string') {
|
||||
legendData.push({
|
||||
name: series[i].name,
|
||||
value: parseFloat(bfb)
|
||||
})
|
||||
legendBfb.push({
|
||||
name: series[i].name,
|
||||
value: parseFloat(bfb)
|
||||
})
|
||||
}
|
||||
}
|
||||
const boxHeight = getHeight3D(series, pieHeight) // 通过pieHeight设定3d饼/环的高度,单位是px
|
||||
// 准备待返回的配置项,把准备好的 legendData、series 传入。
|
||||
const option: EChartsOption = {
|
||||
// legend: {
|
||||
// show: false,
|
||||
// data: legendData,
|
||||
// orient: 'vertical',
|
||||
// left: 10,
|
||||
// top: 10,
|
||||
// itemGap: 10,
|
||||
// textStyle: {
|
||||
// color: '#A1E2FF'
|
||||
// },
|
||||
// icon: 'circle',
|
||||
// formatter: function (param: string) {
|
||||
// const item = legendBfb.filter(item => item.name === param)[0]
|
||||
// if (item) {
|
||||
// const bfs = fomatFloat(item.value * 100, 2)
|
||||
// if (typeof bfs === 'string') {
|
||||
// return `${item.name} ${bfs}%`
|
||||
// }
|
||||
// }
|
||||
// return ''
|
||||
// }
|
||||
// },
|
||||
labelLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'outside',
|
||||
formatter: '{b} \n{c} {d}%'
|
||||
},
|
||||
tooltip: {
|
||||
backgroundColor: '#033b77',
|
||||
borderColor: '#21f2c4',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 13
|
||||
},
|
||||
formatter: (_params: any) => {
|
||||
// if (
|
||||
// params.seriesName !== 'mouseoutSeries' &&
|
||||
// params.seriesName !== 'pie2d'
|
||||
// ) {
|
||||
// // 确保params.seriesIndex存在且在option.series范围内
|
||||
// if (params.seriesIndex !== undefined && option.series && option.series[params.seriesIndex] && option.series[params.seriesIndex].pieData) {
|
||||
// const bfb = (
|
||||
// ((option.series[params.seriesIndex].pieData.endRatio || 0) -
|
||||
// (option.series[params.seriesIndex].pieData.startRatio || 0)) *
|
||||
// 100
|
||||
// ).toFixed(2)
|
||||
// return (
|
||||
// `${params.seriesName}<br/>` +
|
||||
// `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>` +
|
||||
// `${bfb}%`
|
||||
// )
|
||||
// }
|
||||
// // 如果索引无效,返回简单的系列名称
|
||||
// return `${params.seriesName}`
|
||||
// }
|
||||
return ''
|
||||
}
|
||||
},
|
||||
xAxis3D: {
|
||||
min: -1,
|
||||
max: 1
|
||||
},
|
||||
yAxis3D: {
|
||||
min: -1,
|
||||
max: 1
|
||||
},
|
||||
zAxis3D: {
|
||||
min: -1,
|
||||
max: 1
|
||||
},
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: boxHeight, // 圆环的高度
|
||||
viewControl: {
|
||||
// 3d效果可以放大、旋转等,请自己去查看官方配置
|
||||
alpha, // 角度
|
||||
distance, // 调整视角到主体的距离,类似调整zoom
|
||||
rotateSensitivity: 0, // 设置为0无法旋转
|
||||
zoomSensitivity: 0, // 设置为0无法缩放
|
||||
panSensitivity: 0, // 设置为0无法平移
|
||||
autoRotate: false // 自动旋转
|
||||
}
|
||||
},
|
||||
series: series
|
||||
}
|
||||
return option
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
|
||||
*/
|
||||
const getParametricEquation = (
|
||||
startRatio: number,
|
||||
endRatio: number,
|
||||
isSelected: boolean,
|
||||
isHovered: boolean,
|
||||
k: number,
|
||||
h: number
|
||||
): ParametricEquation => {
|
||||
// 计算
|
||||
const midRatio = (startRatio + endRatio) / 2
|
||||
const startRadian = startRatio * Math.PI * 2
|
||||
const endRadian = endRatio * Math.PI * 2
|
||||
const midRadian = midRatio * Math.PI * 2
|
||||
// 如果只有一个扇形,则不实现选中效果。
|
||||
if (startRatio === 0 && endRatio === 1) {
|
||||
isSelected = false
|
||||
}
|
||||
// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
||||
k = typeof k !== 'undefined' ? k : 1 / 3
|
||||
// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
||||
const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0
|
||||
const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0
|
||||
// 计算高亮效果的放大比例(未高亮,则比例为 1)
|
||||
const hoverRate = isHovered ? 1.05 : 1
|
||||
// 返回曲面参数方程
|
||||
return {
|
||||
u: {
|
||||
min: -Math.PI,
|
||||
max: Math.PI * 3,
|
||||
step: Math.PI / 32
|
||||
},
|
||||
v: {
|
||||
min: 0,
|
||||
max: Math.PI * 2,
|
||||
step: Math.PI / 20
|
||||
},
|
||||
x: function (u: number, v: number): number {
|
||||
if (u < startRadian) {
|
||||
return (
|
||||
offsetX +
|
||||
Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
||||
)
|
||||
}
|
||||
if (u > endRadian) {
|
||||
return (
|
||||
offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
||||
)
|
||||
}
|
||||
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
|
||||
},
|
||||
y: function (u: number, v: number): number {
|
||||
if (u < startRadian) {
|
||||
return (
|
||||
offsetY +
|
||||
Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
|
||||
)
|
||||
}
|
||||
if (u > endRadian) {
|
||||
return (
|
||||
offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
|
||||
)
|
||||
}
|
||||
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
|
||||
},
|
||||
z: function (u: number, v: number): number {
|
||||
if (u < -Math.PI * 0.5) {
|
||||
return Math.sin(u)
|
||||
}
|
||||
if (u > Math.PI * 2.5) {
|
||||
return Math.sin(u) * h * 0.1
|
||||
}
|
||||
return Math.sin(v) > 0 ? 1 * h * 0.1 : -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取3d丙图的最高扇区的高度
|
||||
*/
|
||||
const getHeight3D = (series: SeriesItem[], height: number): number => {
|
||||
series.sort((a: SeriesItem, b: SeriesItem) => {
|
||||
return b.pieData.value - a.pieData.value
|
||||
})
|
||||
return (height * 25) / series[0].pieData.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化浮点数
|
||||
*/
|
||||
const fomatFloat = (num: number, n: number): string | boolean => {
|
||||
let f = parseFloat(num.toString())
|
||||
if (isNaN(f)) {
|
||||
return false
|
||||
}
|
||||
f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n) // n 幂
|
||||
let s = f.toString()
|
||||
let rs = s.indexOf('.')
|
||||
// 判定如果是整数,增加小数点再补0
|
||||
if (rs < 0) {
|
||||
rs = s.length
|
||||
s += '.'
|
||||
}
|
||||
while (s.length <= rs + n) {
|
||||
s += '0'
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
export { getPie3D, getParametricEquation }
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import LoadingComponent from "@/components/LoadingComponent.vue";
|
||||
import ErrorComponent from "@/components/ErrorComponent.vue";
|
||||
|
||||
|
||||
export const asyncComponentConfig = {
|
||||
loadingComponent: LoadingComponent,
|
||||
errorComponent: ErrorComponent,
|
||||
onError: (_error: Error, retry: () => void, fail: () => void, attempts: number) => {
|
||||
if (attempts <= 3) {
|
||||
retry();
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// 定义函数类型,支持任意参数
|
||||
type PollingCallback = (...args: any[]) => void;
|
||||
|
||||
export const requestArray = new Map<string, { callback: PollingCallback; args?: any[] }>();
|
||||
// 添加函数到 Map
|
||||
export const addRequest = (key: string, callback: PollingCallback, args?: any[]) => {
|
||||
requestArray.set(key, { callback, args });
|
||||
};
|
||||
|
||||
// 从 Map 中移除函数
|
||||
export const removeRequest = (key: string) => {
|
||||
requestArray.delete(key);
|
||||
};
|
||||
|
||||
export const runImmediatelyByKey = (key: string) => {
|
||||
const { callback, args } = requestArray.get(key) || {};
|
||||
if (callback) {
|
||||
callback(...(args || []));
|
||||
}
|
||||
};
|
||||
|
||||
export const runImmediatelyAll = () => {
|
||||
updateTime.value = new Date().getTime();
|
||||
requestArray.forEach(({ callback, args }) => {
|
||||
if (args) {
|
||||
callback(...args);
|
||||
}else{
|
||||
callback()
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export let updateTime = ref(0);
|
||||
|
||||
export const usePolling = () => {
|
||||
const pollingWorker = new Worker("/js/polling.worker.js");
|
||||
|
||||
pollingWorker.onmessage = (_e: any) => {
|
||||
// 执行所有存储的函数
|
||||
updateTime.value = new Date().getTime();
|
||||
requestArray.forEach(({ callback, args }) => {
|
||||
if (args) {
|
||||
callback(...args);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
pollingWorker.postMessage({ command: "start", interval: 1000 * 60 * 60 });
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
pollingWorker.postMessage({ command: "stop" });
|
||||
// 清理所有存储的函数
|
||||
requestArray.clear();
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import * as ECharts from "echarts";
|
||||
|
||||
const HANDLER = "_vue_resize_handler";
|
||||
export const vEchartResize = {
|
||||
mounted(el:any,binding:any){
|
||||
el[HANDLER] = binding.value
|
||||
? binding.value
|
||||
: () => {
|
||||
let chart = ECharts.getInstanceByDom(el);
|
||||
if (!chart) {
|
||||
return;
|
||||
}
|
||||
chart.resize();
|
||||
};
|
||||
window.addEventListener("resize",el[HANDLER]);
|
||||
},
|
||||
beforeUnmount(el:any){
|
||||
window.removeEventListener("resize",el[HANDLER]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { createApp } from 'vue'
|
||||
import '@unocss/reset/tailwind-compat.css'
|
||||
import './style.css'
|
||||
import 'uno.css';
|
||||
import App from './App.vue'
|
||||
// Pinia 持久化
|
||||
import store from '@/store/index'
|
||||
//导入路由
|
||||
import router from '@/router/index'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
// 注册已经加上了持久化的pinia
|
||||
app.use(store)
|
||||
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { publicRoutes } from "./publicRoutes";
|
||||
import { privateRoutes } from "./privateRoutes";
|
||||
import { useUserStore } from "@/store/user";
|
||||
|
||||
function getRoutes() {
|
||||
const routes = [
|
||||
// 私有路由,请在这里添加
|
||||
...privateRoutes,
|
||||
|
||||
// 公共路由
|
||||
...publicRoutes,
|
||||
];
|
||||
/**
|
||||
* 如果要对 routes 做一些处理,请在这里修改
|
||||
*/
|
||||
return routes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: getRoutes(),
|
||||
});
|
||||
|
||||
// 全局前置守卫,这边可以对身份进行验证
|
||||
router.beforeEach((to, _from, next) => {
|
||||
const userStore = useUserStore()
|
||||
let userRole = "";
|
||||
let hasLogin = userStore.getAccessToken;
|
||||
|
||||
// 如果目标路由没有角色限制
|
||||
if (!to.meta.role) {
|
||||
next();
|
||||
}
|
||||
|
||||
// 判断当前用户角色是否在目标路由的允许角色列表中
|
||||
if ((to.meta.role as string[]).includes(userRole)) {
|
||||
// 如果角色匹配,允许进入目标路由
|
||||
next();
|
||||
}else if(hasLogin){
|
||||
next();
|
||||
} else {
|
||||
// 如果角色不匹配,跳转到 unauthorized 页面
|
||||
next({ path: "/login" });
|
||||
}
|
||||
});
|
||||
|
||||
// 监听路由变化,动态设置网页标题
|
||||
router.afterEach((to) => {
|
||||
if (to.meta.title) {
|
||||
document.title = to.meta.title as string;
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { ComponentInternalInstance, ref } from 'vue'
|
||||
|
||||
export const excludes = ref<string[]>([])
|
||||
|
||||
export function removeKeepAliveCache(instance: ComponentInternalInstance) {
|
||||
if (!excludes.value.includes(instance.type.name!)) {
|
||||
excludes.value.push(instance.type.name!)
|
||||
}
|
||||
}
|
||||
|
||||
export function resetKeepAliveCache(instance: ComponentInternalInstance) {
|
||||
excludes.value = excludes.value.filter((item) => item !== instance.type.name)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export const privateRoutes = [];
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
export const publicRoutes = [
|
||||
|
||||
{
|
||||
path:"/unauthorized",
|
||||
name:'unauthorized',
|
||||
meta:{
|
||||
title:'unauthorized'
|
||||
},
|
||||
component:()=>import('../views/unauthorized.vue')
|
||||
},
|
||||
{
|
||||
path:"/",
|
||||
name:'home',
|
||||
meta:{
|
||||
title:'锦泽健康智慧养老服务平台',
|
||||
},
|
||||
component:()=>import('../views/home.vue')
|
||||
},
|
||||
|
||||
]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// pinia数据持久化存储
|
||||
import { createPinia } from 'pinia'
|
||||
import { createPersistedState } from 'pinia-plugin-persistedstate'
|
||||
import { SelfStorage } from './secureStore'
|
||||
|
||||
// 第一个参数是应用程序中 store 的唯一 id
|
||||
const store = createPinia()
|
||||
store.use(
|
||||
createPersistedState({
|
||||
storage: SelfStorage
|
||||
})
|
||||
)
|
||||
export default store
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { StorageLike } from 'pinia-plugin-persistedstate'
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
const SECRET_KEY = import.meta.env.VITE_SECRET_KEY // 自定义加密密钥
|
||||
|
||||
// 自定义加密存储
|
||||
export const SelfStorage: StorageLike = {
|
||||
setItem(key: string, value: string) {
|
||||
// 加密值
|
||||
const encryptedValue = CryptoJS.AES.encrypt(value, SECRET_KEY).toString()
|
||||
|
||||
// 存储加密后的值
|
||||
localStorage.setItem(key, encryptedValue)
|
||||
},
|
||||
getItem(key: string): string | null {
|
||||
// 获取加密值
|
||||
const encryptedValue = localStorage.getItem(key)
|
||||
if (encryptedValue) {
|
||||
// 解密
|
||||
const bytes = CryptoJS.AES.decrypt(encryptedValue, SECRET_KEY)
|
||||
const decryptedValue = bytes.toString(CryptoJS.enc.Utf8)
|
||||
return decryptedValue || null
|
||||
}
|
||||
return null
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { defineStore } from "pinia";
|
||||
export const useUserStore = defineStore("user", {
|
||||
persist:true,
|
||||
state:()=>({
|
||||
accessToken:"",
|
||||
refreshToken:""
|
||||
}),
|
||||
getters:{
|
||||
getAccessToken(state){
|
||||
return state.accessToken;
|
||||
},
|
||||
getRefreshToken(state){
|
||||
return state.refreshToken
|
||||
}
|
||||
},
|
||||
actions:{
|
||||
setAccessToken(token:string){
|
||||
this.accessToken = token;
|
||||
},
|
||||
setRefreshToken(token:string){
|
||||
this.refreshToken = token
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@media (max-width: 1919px){
|
||||
html{
|
||||
font-size: calc(100vw / 93.75);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.border-image {
|
||||
border: 1px solid;
|
||||
border-image: linear-gradient(
|
||||
90deg,
|
||||
#217ac600,
|
||||
#227cc8,
|
||||
#217ac600
|
||||
)
|
||||
1 1;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
.text-color{
|
||||
position: relative;
|
||||
color: #8FC8FF;
|
||||
&::after {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: auto;
|
||||
color: #fff;
|
||||
-webkit-mask: var(--mask-gradient, linear-gradient(to bottom, transparent, #000));
|
||||
white-space: nowrap;
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// 使用 scss 的 math 函数,https://sass-lang.com/documentation/breaking-changes/slash-div
|
||||
@use "sass:math";
|
||||
|
||||
// 默认设计稿的宽度
|
||||
$designWidth: 1920;
|
||||
// 默认设计稿的高度
|
||||
$designHeight: 1080;
|
||||
|
||||
// px 转为 vw 的函数
|
||||
@function vw($px) {
|
||||
@return math.div($px, $designWidth) * 100vw;
|
||||
}
|
||||
|
||||
// px 转为 vh 的函数
|
||||
@function vh($px) {
|
||||
@return math.div($px, $designHeight) * 100vh;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* uni-app API 类型声明
|
||||
*/
|
||||
declare const uni: {
|
||||
postMessage: (options: { data: Record<string, any> }) => void;
|
||||
getEnv: (callback: (res: any) => void) => void;
|
||||
switchTab: (options: { url: string }) => void;
|
||||
reLaunch: (options: { url: string }) => void;
|
||||
navigateBack: (options: { delta: number }) => void;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
export function convertNumber(n: number): string {
|
||||
if (n >= 10000) {
|
||||
const value = n / 10000;
|
||||
return `${value.toString().replace(/\.0$/, '')}W`;
|
||||
} else if (n >= 1000) {
|
||||
const value = n / 1000;
|
||||
return `${value.toString().replace(/\.0$/, '')}K`;
|
||||
} else if (n >= 1) {
|
||||
const value = n / 1000;
|
||||
return `${value.toString().replace(/0+$/, '').replace(/\.$/, '')}K`;
|
||||
}
|
||||
return n.toString();
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* 将毫秒时间戳转换为 "月.日 时:分:秒" 的格式
|
||||
* @param timestamp 时间戳(毫秒)
|
||||
* @returns 格式化后的时间字符串,如 "6.12 12:00:00"
|
||||
*/
|
||||
export const formatDatetime = (timestamp: number): string => {
|
||||
const date = new Date(timestamp);
|
||||
|
||||
// 获取月份(注意:getMonth 返回的月份是从0开始的,所以需要+1)
|
||||
const month = date.getMonth() + 1;
|
||||
|
||||
// 获取日期
|
||||
const day = date.getDate();
|
||||
|
||||
// 获取小时
|
||||
const hours = date.getHours().toString().padStart(2, '0');
|
||||
|
||||
// 获取分钟
|
||||
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||||
|
||||
// 获取秒数
|
||||
const seconds = date.getSeconds().toString().padStart(2, '0');
|
||||
|
||||
// 组合成最终格式
|
||||
return `${month}.${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前时间的毫秒时间戳
|
||||
* @returns 当前时间的毫秒时间戳
|
||||
*/
|
||||
export const getCurrentTimestamp = (): number => {
|
||||
return Date.now();
|
||||
};
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
export const usePlatformType = () => {
|
||||
const userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
// 判断是否为移动设备
|
||||
const isMobile = /mobile|android|iphone|ipad|ipod|windows phone/i.test(userAgent);
|
||||
|
||||
// 判断是否为 APP 环境(这里假设 APP 环境会在 userAgent 中包含特定标识)
|
||||
const isApp = /myapp|appname/i.test(userAgent); // 请根据实际 APP 的标识修改
|
||||
|
||||
const isWechat = /micromessenger/i.test(userAgent);
|
||||
|
||||
return {
|
||||
isMobile,
|
||||
isApp,
|
||||
isPC: !isMobile,
|
||||
isWechat
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
// 根据设计稿来放大缩小字体
|
||||
export const fitChartSize = (size:number,defaultWidth = 1920) => {
|
||||
let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
|
||||
if (!clientWidth) return size;
|
||||
let scale = (clientWidth / defaultWidth);
|
||||
return Number((size*scale).toFixed(3));
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<script setup lang="ts">
|
||||
// import { usePlatformType } from '@/utils/device'
|
||||
|
||||
// 获取设备类型
|
||||
// const { isMobile } = usePlatformType()
|
||||
|
||||
// 跳转URL配置
|
||||
const jumpUrls = {
|
||||
// 机构运营管理平台
|
||||
mechanism: {
|
||||
pc: 'https://icaring.cn/operation',
|
||||
mobile: 'https://icaring.cn/nurse',
|
||||
icon:"/images/mechanism.webp",
|
||||
type:'mechanism'
|
||||
},
|
||||
// 居家运营管理平台
|
||||
home: {
|
||||
pc: 'https://ky.jinzejk.com/admin/login.php',
|
||||
mobile: 'https://icaring.cn/nurse',
|
||||
icon: "/images/home.webp",
|
||||
type:"home"
|
||||
}
|
||||
}
|
||||
|
||||
// 处理图片点击事件
|
||||
const handleImageClick = (type: 'mechanism' | 'home') => {
|
||||
const urls = jumpUrls[type]
|
||||
const targetUrl = urls.pc
|
||||
|
||||
// 在新窗口打开链接
|
||||
window.open(targetUrl, '_blank')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen w-full bg-[url('/images/background.webp')] bg-cover bg-center bg-no-repeat font-sans flex flex-col relative overflow-auto">
|
||||
<!-- 顶部logo -->
|
||||
<div class="flex items-center shrink-0 mt-[2rem] px-10">
|
||||
<img src="/images/logo.webp" alt="Logo" class="md:h-[4rem] w-auto h-[8rem]" />
|
||||
</div>
|
||||
|
||||
<!-- 底部图片区域 -->
|
||||
<div class="flex-1 flex items-center justify-center mt-16">
|
||||
<div class="w-full flex items-center justify-evenly flex-col md:flex-row overflow-hidden">
|
||||
<div v-for="val in jumpUrls" class="flex justify-center items-center cursor-pointer " @click="handleImageClick(val.type as any)">
|
||||
<img :src="val.icon" alt="Mechanism" class="w-full h-auto md:max-h-[28rem] object-contain transition-transform duration-300 ease-out overflow-hidden transition-transform duration-300 ease-out hover:scale-105" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div>401 - Unauthorized</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
interface Window {
|
||||
}
|
||||
|
||||
declare module 'echarts-gl/charts';
|
||||
declare module 'echarts-gl/components';
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/composables/useDigitalWatch.js"]
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
},
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts","./plugins/*"]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { defineConfig, presetIcons,presetUno } from "unocss";
|
||||
// import presetWind from "@unocss/preset-wind";
|
||||
import { presetScrollbarHide } from 'unocss-preset-scrollbar-hide'
|
||||
// import { presetPxToViewport } from "unocss-preset-px-to-vw-or-vh";
|
||||
|
||||
export default defineConfig({
|
||||
presets: [
|
||||
// presetPxToViewport({
|
||||
// // 可选:自定义设计尺寸(默认为 1920x1080)
|
||||
// designWidth: 1920,
|
||||
// designHeight: 1080,
|
||||
// keyToVw: ["font-size"],
|
||||
// }),
|
||||
presetUno(),
|
||||
// presetWind(),
|
||||
presetScrollbarHide(),
|
||||
presetIcons({
|
||||
scale: 1,
|
||||
warn: true,
|
||||
extraProperties: {
|
||||
display: "inline-block",
|
||||
"vertical-align": "middle",
|
||||
},
|
||||
}),
|
||||
],
|
||||
rules: [["pb-safe", { "padding-bottom": "calc(env(safe-area-inset-bottom) + 52rpx)" }]],
|
||||
});
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
#!/bin/bash
|
||||
|
||||
# 服务器信息
|
||||
SERVER_USER="root"
|
||||
SERVER_HOST="106.14.30.150"
|
||||
SERVER_PATH="/opt/1panel/apps/openresty/openresty/www/sites/screen.jinze.ycymedu.com/index"
|
||||
PRIVATE_KEY="ALIYUN.pem"
|
||||
BACKUP_PATH="${SERVER_PATH}-backup-$(date +%Y%m%d%H%M%S).zip"
|
||||
DINGDING_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=fca104958fea6273c9c7ef3f08b3d552645c214f929066785e8caf6e1885a5a6"
|
||||
|
||||
# 在上传之前备份原来的文件并压缩
|
||||
ssh -i $PRIVATE_KEY $SERVER_USER@$SERVER_HOST "cd $(dirname $SERVER_PATH) && zip -r $(basename $BACKUP_PATH) $(basename $SERVER_PATH)"
|
||||
|
||||
# 使用 scp 上传文件
|
||||
scp -i $PRIVATE_KEY -r dist/* $SERVER_USER@$SERVER_HOST:$SERVER_PATH
|
||||
|
||||
# 提示上传完成
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "上传成功!备份存储于 $BACKUP_PATH"
|
||||
|
||||
# 发送钉钉通知
|
||||
curl -X POST "$DINGDING_WEBHOOK" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"msgtype": "text",
|
||||
"text": {
|
||||
"content": "single html| upload success!!! backup to'"$BACKUP_PATH"'"
|
||||
}
|
||||
}'
|
||||
else
|
||||
echo "上传失败,请检查错误信息。"
|
||||
|
||||
# 发送钉钉通知
|
||||
curl -X POST "$DINGDING_WEBHOOK" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"msgtype": "text",
|
||||
"text": {
|
||||
"content": "single html|upload fail,please check error info。"
|
||||
}
|
||||
}'
|
||||
fi
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import { resolve } from "path";
|
||||
import AutoComplete from "unplugin-auto-import/vite";
|
||||
import UnoCSS from 'unocss/vite'
|
||||
|
||||
|
||||
import svgBuilder from "./plugins/svgBuilder";
|
||||
|
||||
const pathSrc = resolve(__dirname, "src");
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
assetsInclude: ["**/*.svg"],
|
||||
base: "./" /* 这个就是webpack里面的publicPath */,
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 最小化拆分包
|
||||
manualChunks: (id) => {
|
||||
if (id.includes("node_modules")) {
|
||||
return id.toString().split("node_modules/")[1].split("/")[0].toString();
|
||||
}
|
||||
}, // 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
|
||||
entryFileNames: "js/[name].[hash].js", // 用于命名代码拆分时创建的共享块的输出命名
|
||||
chunkFileNames: "js/[name].[hash].js", // 用于输出静态资源的命名,[ext]表示文件扩展名
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
UnoCSS(),
|
||||
svgBuilder(resolve("./public/icons")), // svg存储的名字
|
||||
AutoComplete({
|
||||
imports: [
|
||||
"vue",
|
||||
"vue-router",
|
||||
"pinia", // 自动导入 Pinia API(如 defineStore)
|
||||
],
|
||||
dts: resolve(pathSrc, "auto-imports.d.ts"),
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@/": `${pathSrc}/`,
|
||||
},
|
||||
},
|
||||
server: {
|
||||
host: "localhost",
|
||||
port: 3001,
|
||||
proxy:{
|
||||
'/api':{
|
||||
target:'http://192.168.31.149:5006',
|
||||
changeOrigin:true,
|
||||
}
|
||||
}
|
||||
},
|
||||
esbuild: {
|
||||
drop: ["debugger"],
|
||||
},
|
||||
optimizeDeps: { // 在开发服务器启动时预构建依赖,将 CommonJS/UMD 模块转换为 ESM 格式,并缓存结果以提高性能。
|
||||
include: [],
|
||||
},
|
||||
css:{
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@use "@/styles/utils.scss" as cssUtils;`,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Loading…
Reference in New Issue