init
|
@ -0,0 +1,14 @@
|
|||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*] # 表示所有文件适用
|
||||
charset = utf-8 # 设置文件字符集为 utf-8
|
||||
end_of_line = lf # 控制换行类型(lf | cr | crlf)
|
||||
insert_final_newline = false # 始终在文件末尾插入一个新行
|
||||
indent_style = tab # 缩进风格(tab | space)
|
||||
indent_size = 2 # 缩进大小
|
||||
max_line_length = 130 # 最大行长度
|
||||
|
||||
[*.md] # 表示仅 md 文件适用以下规则
|
||||
max_line_length = off # 关闭最大行长度限制
|
||||
trim_trailing_whitespace = false # 关闭末尾空格修剪
|
|
@ -0,0 +1,31 @@
|
|||
# 基础请求路径
|
||||
VITE_BASE_API="/api"
|
||||
|
||||
# 模拟请求路径
|
||||
VITE_MOCK_BASE_API="/mock"
|
||||
|
||||
# 线上环境接口地址
|
||||
VITE_APP_URL=http://localhost:8800
|
||||
|
||||
# 线上环境接口地址
|
||||
VITE_APP_MOCK_URL=http://localhost:6262
|
||||
|
||||
# 网络请求延迟时间
|
||||
VITE_BASE_API_TIMEOUT=15000
|
||||
|
||||
# 失败重试次数
|
||||
VITE_BASE_API_RETRY=5
|
||||
|
||||
# 失败重试时间
|
||||
VITE_BASE_API_RETRY_DELAY=3000
|
||||
|
||||
# 端口号
|
||||
VITE_PORT=6262
|
||||
|
||||
# 是否使用CDN加速
|
||||
VITE_CDN=true
|
||||
|
||||
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
||||
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
VITE_COMPRESSION="both"
|
|
@ -0,0 +1,31 @@
|
|||
# 基础请求路径
|
||||
VITE_BASE_API="/api"
|
||||
|
||||
# 模拟请求路径
|
||||
VITE_MOCK_BASE_API="/mock"
|
||||
|
||||
# 线上环境接口地址
|
||||
VITE_APP_URL=http://localhost:8800
|
||||
|
||||
# 线上环境接口地址
|
||||
VITE_APP_MOCK_URL=http://localhost:6262
|
||||
|
||||
# 网络请求延迟时间
|
||||
VITE_BASE_API_TIMEOUT=15000
|
||||
|
||||
# 失败重试次数
|
||||
VITE_BASE_API_RETRY=5
|
||||
|
||||
# 失败重试时间
|
||||
VITE_BASE_API_RETRY_DELAY=3000
|
||||
|
||||
# 端口号
|
||||
VITE_PORT=6262
|
||||
|
||||
# 是否使用CDN加速
|
||||
VITE_CDN=true
|
||||
|
||||
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
||||
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
VITE_COMPRESSION="both"
|
|
@ -0,0 +1,22 @@
|
|||
# eslint 忽略检查 (根据项目需要自行添加)
|
||||
*.sh
|
||||
node_modules
|
||||
*.md
|
||||
*.woff
|
||||
*.ttf
|
||||
.vscode
|
||||
.idea
|
||||
dist
|
||||
html
|
||||
/public
|
||||
/docs
|
||||
.husky
|
||||
.local
|
||||
/bin
|
||||
.eslintrc.js
|
||||
.prettierrc.js
|
||||
.stylelintrc.js
|
||||
lint-staged.config.js
|
||||
/src/mock/*
|
||||
src/utils/request.js
|
||||
list
|
|
@ -0,0 +1,67 @@
|
|||
// @see: http://eslint.cn
|
||||
export default {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
/* 指定如何解析语法 */
|
||||
parser: 'vue-eslint-parser',
|
||||
/* 优先级低于 parse 的语法解析配置 */
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
jsxPragma: 'React',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
/* 继承某些已有的规则 */
|
||||
extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended'],
|
||||
/*
|
||||
* "off" 或 0 ==> 关闭规则
|
||||
* "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行)
|
||||
* "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错)
|
||||
*/
|
||||
rules: {
|
||||
// eslint (http://eslint.cn/docs/rules)
|
||||
'no-var': 'error', // 要求使用 let 或 const 而不是 var
|
||||
'no-multiple-empty-lines': ['error', { max: 1 }], // 不允许多个空行
|
||||
'no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们
|
||||
'prefer-const': 'off', // 此规则旨在标记使用 let 关键字声明但在初始分配后从未重新分配的变量,要求使用 const
|
||||
'no-irregular-whitespace': 'off', // 禁止不规则的空白
|
||||
|
||||
// typeScript (https://typescript-eslint.io/rules)
|
||||
'@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
|
||||
'@typescript-eslint/no-inferrable-types': 'off', // 可以轻松推断的显式类型可能会增加不必要的冗长
|
||||
'@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
|
||||
'@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
|
||||
'@typescript-eslint/ban-types': 'off', // 禁止使用特定类型
|
||||
'@typescript-eslint/explicit-function-return-type': 'off', // 不允许对初始化为数字、字符串或布尔值的变量或参数进行显式类型声明
|
||||
'@typescript-eslint/no-var-requires': 'off', // 不允许在 import 语句中使用 require 语句
|
||||
'@typescript-eslint/no-empty-function': 'off', // 禁止空函数
|
||||
'@typescript-eslint/no-use-before-define': 'off', // 禁止在变量定义之前使用它们
|
||||
'@typescript-eslint/ban-ts-comment': 'off', // 禁止 @ts-<directive> 使用注释或要求在指令后进行描述
|
||||
'@typescript-eslint/no-non-null-assertion': 'off', // 不允许使用后缀运算符的非空断言(!)
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off', // 要求导出函数和类的公共类方法的显式返回和参数类型
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
|
||||
// vue (https://eslint.vuejs.org/rules)
|
||||
'vue/no-v-html': 'off', // 禁止使用 v-html
|
||||
'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用,此规则仅在启用该no-unused-vars规则时有效。
|
||||
'vue/v-slot-style': 'error', // 强制执行 v-slot 指令样式
|
||||
'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
|
||||
'vue/custom-event-name-casing': 'off', // 为自定义事件名称强制使用特定大小写
|
||||
'vue/attributes-order': 'off', // vue api使用顺序,强制执行属性顺序
|
||||
'vue/one-component-per-file': 'off', // 强制每个组件都应该在自己的文件中
|
||||
'vue/html-closing-bracket-newline': 'off', // 在标签的右括号之前要求或禁止换行
|
||||
'vue/max-attributes-per-line': 'off', // 强制每行的最大属性数
|
||||
'vue/multiline-html-element-content-newline': 'off', // 在多行元素的内容之前和之后需要换行符
|
||||
'vue/singleline-html-element-content-newline': 'off', // 在单行元素的内容之前和之后需要换行符
|
||||
'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
|
||||
'vue/require-default-prop': 'off', // 此规则要求为每个 prop 为必填时,必须提供默认值
|
||||
'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
|
||||
},
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm run lint:lint-staged
|
|
@ -0,0 +1,10 @@
|
|||
list
|
||||
/dist/*
|
||||
/html/*
|
||||
.local
|
||||
/node_modules/**
|
||||
|
||||
**/*.svg
|
||||
**/*.sh
|
||||
|
||||
/public/*
|
|
@ -0,0 +1,39 @@
|
|||
// @see: https://www.prettier.cn
|
||||
|
||||
export default {
|
||||
// 超过最大值换行
|
||||
printWidth: 130,
|
||||
// 缩进字节数
|
||||
tabWidth: 1,
|
||||
// 使用制表符而不是空格缩进行
|
||||
useTabs: true,
|
||||
// 结尾不用分号(true有,false没有)
|
||||
semi: true,
|
||||
// 使用单引号(true单引号,false双引号)
|
||||
singleQuote: true,
|
||||
// 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
|
||||
quoteProps: "as-needed",
|
||||
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
|
||||
bracketSpacing: true,
|
||||
// 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>",默认none
|
||||
trailingComma: "all",
|
||||
// 在JSX中使用单引号而不是双引号
|
||||
jsxSingleQuote: true,
|
||||
// (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号 ,always:不省略括号
|
||||
arrowParens: "avoid",
|
||||
// 如果文件顶部已经有一个 doclock,这个选项将新建一行注释,并打上@format标记。
|
||||
insertPragma: false,
|
||||
// 指定要使用的解析器,不需要写文件开头的 @prettier
|
||||
requirePragma: false,
|
||||
// 默认值。因为使用了一些折行敏感型的渲染器(如GitHub comment)而按照markdown文本样式进行折行
|
||||
proseWrap: "preserve",
|
||||
// 在html中空格是否是敏感的 "css" - 遵守CSS显示属性的默认值, "strict" - 空格被认为是敏感的 ,"ignore" - 空格被认为是不敏感的
|
||||
htmlWhitespaceSensitivity: "css",
|
||||
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
|
||||
endOfLine: "auto",
|
||||
// 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
|
||||
rangeStart: 0,
|
||||
rangeEnd: Infinity,
|
||||
|
||||
vueIndentScriptAndStyle: false // Vue文件脚本和样式标签缩进
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
# .stylelintignore
|
||||
# 旧的不需打包的样式库
|
||||
*.min.css
|
||||
|
||||
# 其他类型文件
|
||||
*.js
|
||||
*.jpg
|
||||
*.woff
|
||||
|
||||
# 测试和打包目录
|
||||
/test/
|
||||
/dist/*
|
||||
/public/*
|
||||
public/*
|
||||
/node_modules/
|
||||
.eslintrc.js
|
||||
.prettierrc.js
|
||||
.stylelintrc.js
|
||||
lint-staged.config.js
|
|
@ -0,0 +1,62 @@
|
|||
// @see: https://stylelint.io
|
||||
|
||||
export default {
|
||||
root: true,
|
||||
defaultSeverity: "error",
|
||||
plugins: ["stylelint-order", "stylelint-scss"],
|
||||
/* 继承某些已有的规则 */
|
||||
extends: [
|
||||
"stylelint-config-standard", // 配置stylelint拓展插件
|
||||
"stylelint-config-html/html", // the shareable html config for Stylelint.
|
||||
"stylelint-config-html/vue", // 配置 vue 中 template 样式格式化
|
||||
"stylelint-config-recess-order", // 配置stylelint css属性书写顺序插件,
|
||||
"stylelint-config-prettier" // 配置stylelint和prettier兼容
|
||||
],
|
||||
overrides: [
|
||||
// 扫描 .vue/html 文件中的<style>标签内的样式
|
||||
{
|
||||
files: ["**/*.{vue,html}"],
|
||||
customSyntax: "postcss-html",
|
||||
rules: {
|
||||
// 禁止未知的伪类选择器
|
||||
"selector-pseudo-class-no-unknown": [true, { ignorePseudoClasses: ["deep", "global"] }],
|
||||
// 禁止未知的伪元素选择器
|
||||
"selector-pseudo-element-no-unknown": [true, { ignorePseudoElements: ["v-deep", "v-global", "v-slotted"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["*.less", "**/*.less", "*.scss", "**/*.scss"],
|
||||
customSyntax: "postcss-less",
|
||||
rules: {
|
||||
"less/color-no-invalid-hex": true,
|
||||
"less/no-duplicate-variables": true
|
||||
}
|
||||
}
|
||||
],
|
||||
/**
|
||||
* null => 关闭该规则
|
||||
*/
|
||||
rules: {
|
||||
"value-keyword-case": null, // 在 css 中使用 v-bind,不报错
|
||||
"no-descending-specificity": null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
|
||||
"function-url-quotes": "always", // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
|
||||
"string-quotes": "double", // 指定字符串使用单引号或双引号
|
||||
"unit-case": null, // 指定单位的大小写 "lower(全小写)"|"upper(全大写)"
|
||||
"color-hex-case": "lower", // 指定 16 进制颜色的大小写 "lower(全小写)"|"upper(全大写)"
|
||||
"color-hex-length": "long", // 指定 16 进制颜色的简写或扩写 "short(16进制简写)"|"long(16进制扩写)"
|
||||
"rule-empty-line-before": "never", // 要求或禁止在规则之前的空行 "always(规则之前必须始终有一个空行)"|"never(规则前绝不能有空行)"|"always-multi-line(多行规则之前必须始终有一个空行)"|"never-multi-line(多行规则之前绝不能有空行。)"
|
||||
"font-family-no-missing-generic-family-keyword": null, // 禁止在字体族名称列表中缺少通用字体族关键字
|
||||
"block-opening-brace-space-before": "always", // 要求在块的开大括号之前必须有一个空格或不能有空白符 "always(大括号前必须始终有一个空格)"|"never(左大括号之前绝不能有空格)"|"always-single-line(在单行块中的左大括号之前必须始终有一个空格)"|"never-single-line(在单行块中的左大括号之前绝不能有空格)"|"always-multi-line(在多行块中,左大括号之前必须始终有一个空格)"|"never-multi-line(多行块中的左大括号之前绝不能有空格)"
|
||||
"property-no-unknown": null, // 禁止未知的属性(true 为不允许)
|
||||
"no-empty-source": null, // 禁止空源码
|
||||
"declaration-block-trailing-semicolon": null, // 要求或不允许在声明块中使用尾随分号 string:"always(必须始终有一个尾随分号)"|"never(不得有尾随分号)"
|
||||
"selector-class-pattern": null, // 强制选择器类名的格式
|
||||
"value-no-vendor-prefix": null, // 关闭 vendor-prefix(为了解决多行省略 -webkit-box)
|
||||
"selector-pseudo-class-no-unknown": [
|
||||
true,
|
||||
{
|
||||
ignorePseudoClasses: ["global", "v-deep", "deep"]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Y_Lao
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,312 @@
|
|||
# Vite相关使用
|
||||
|
||||
## .env文件
|
||||
|
||||
### 文件名简介
|
||||
|
||||
- `.env`:公用配置文件
|
||||
- `.env.development`:开发环境配置
|
||||
- `.env.production`:生产话就配置
|
||||
|
||||
### 修改环境前缀
|
||||
|
||||
在配置文件中加上`envPrefix`
|
||||
|
||||
```ts
|
||||
export default defineConfig(
|
||||
(): UserConfig => ({
|
||||
envPrefix: 'BUNNY',
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
## 使用gzip
|
||||
|
||||
安装
|
||||
|
||||
```sh
|
||||
npm i vite-plugin-compress
|
||||
```
|
||||
|
||||
需要文件中引入
|
||||
|
||||
```js
|
||||
import compress from 'vite-plugin-compress';
|
||||
|
||||
export default {
|
||||
plugins: [compress()],
|
||||
};
|
||||
```
|
||||
|
||||
## 动态加载路由
|
||||
|
||||
```ts
|
||||
import { routeFilenameHelper } from '@/utils/file/routeFileUtil';
|
||||
import _ from 'lodash';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
// * 最终路由
|
||||
const routeMap: Record<string, RouteRecordRaw> = {};
|
||||
|
||||
// * 所有处理的路由
|
||||
const contexts = [
|
||||
{ context: import.meta.glob('@/views/**/index.vue', { eager: true, import: 'default' }), isIndex: true },
|
||||
{ context: import.meta.glob('@/views/**/page.ts', { eager: true, import: 'default' }), isIndex: false },
|
||||
];
|
||||
|
||||
/**
|
||||
* 构建路由信息
|
||||
* @param context 上下文信息
|
||||
* @param isIndex 是否第一次遍历
|
||||
* @param route 路由内容
|
||||
*/
|
||||
function buildRouteTree(context: any, isIndex: boolean, route: any) {
|
||||
// 遍历当前子路由
|
||||
Object.entries(context).forEach(([filePath, _]) => {
|
||||
// 获取子路由下所有文件对象格式
|
||||
const childrenFileInfo = routeFilenameHelper(filePath);
|
||||
// 组装子路由对象
|
||||
const childrenRoute: any = {
|
||||
name: childrenFileInfo?.name,
|
||||
path: childrenFileInfo!.path,
|
||||
component: isIndex ? context[filePath] : undefined,
|
||||
children: [],
|
||||
meta: { isFullScreen: false },
|
||||
};
|
||||
// 如果当前路由对象等于当前遍历的路由子对象,将子路由推到父级路由中
|
||||
if (childrenFileInfo?.path.includes(route.path) && childrenFileInfo?.path !== route.path) {
|
||||
route.children.push(childrenRoute);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 遍历路由信息
|
||||
* @param context 路由上下文
|
||||
* @param isIndex 是否为索引遍历
|
||||
*/
|
||||
const createRouteList = (context: any, isIndex: boolean) => {
|
||||
Object.entries(context).forEach(([filePath, exportRouteConfig]) => {
|
||||
const fileInfo = routeFilenameHelper(filePath);
|
||||
// 组装路由对象
|
||||
const route: any = {
|
||||
name: fileInfo?.name,
|
||||
path: fileInfo!.path,
|
||||
component: isIndex ? context[filePath] : undefined,
|
||||
children: [],
|
||||
meta: { isFullScreen: false },
|
||||
};
|
||||
|
||||
// 初始化赋值
|
||||
if (isIndex) {
|
||||
routeMap[route.path] = route;
|
||||
buildRouteTree(context, isIndex, route);
|
||||
} else {
|
||||
// 导出当前存在的路由并重新赋值
|
||||
const existingRoute = routeMap[route.path];
|
||||
// 当前路由存在
|
||||
if (existingRoute) {
|
||||
// 使用loadsh合并对象
|
||||
routeMap[route.path] = _.merge(existingRoute, exportRouteConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// * 生成路由信息
|
||||
contexts.forEach(({ context, isIndex }) => createRouteList(context, isIndex));
|
||||
|
||||
export const pageRoutes: Array<RouteRecordRaw> = Object.values(routeMap);
|
||||
```
|
||||
|
||||
> 需要注意的是,为了动态导入生产环境也可以运行,需要`context[filePath]`需要使用这段话,才可以
|
||||
|
||||
## 输出环境变量内容
|
||||
|
||||
```ts
|
||||
console.log(import.meta.env);
|
||||
```
|
||||
|
||||
## 动态加载CDN
|
||||
|
||||
在Module中配置相关内容,相关文档查看:https://www.npmjs.com/package/vite-plugin-cdn-import
|
||||
|
||||
```ts
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import { resolve } from 'path';
|
||||
import { defineConfig, UserConfig } from 'vite';
|
||||
import cdn from 'vite-plugin-cdn-import';
|
||||
|
||||
export default defineConfig(
|
||||
(): UserConfig => ({
|
||||
plugins: [
|
||||
cdn({
|
||||
modules: [],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
> ```
|
||||
> npm i vite-plugin-cdn-import
|
||||
> ```
|
||||
|
||||
## 兼容老版本浏览器
|
||||
|
||||
在plugin中加入
|
||||
|
||||
```ts
|
||||
legacy({ targets: ["defaults", "not IE 11"] }),
|
||||
```
|
||||
|
||||
详细配置查看:https://www.npmjs.com/package/@vitejs/plugin-legacy
|
||||
|
||||
## 打包设置
|
||||
|
||||
如果打包中包含`node_module`包全部放到`vendor-[hash].js`中
|
||||
|
||||
![image-20240527152054024](./images/image-20240527152054024.png)
|
||||
|
||||
## 配置跨域
|
||||
|
||||
`process.env.BUNNY_APP_URL`设置在这三个文件中,读取是这三个配置
|
||||
|
||||
![image-20240527152136447](./images/image-20240527152136447.png)
|
||||
|
||||
```ts
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
port
|
||||
:
|
||||
6261,
|
||||
open
|
||||
:
|
||||
true,
|
||||
cors
|
||||
:
|
||||
true,
|
||||
proxy
|
||||
:
|
||||
{
|
||||
"/api"
|
||||
:
|
||||
{
|
||||
target: process.env.BUNNY_APP_URL,
|
||||
changeOrigin
|
||||
:
|
||||
true,
|
||||
rewrite
|
||||
:
|
||||
(path: string) => path.replace(/^\/api/, "/api")
|
||||
}
|
||||
,
|
||||
"/mock"
|
||||
:
|
||||
{
|
||||
target: process.env.BUNNY_APP_URL,
|
||||
changeOrigin
|
||||
:
|
||||
true,
|
||||
rewrite
|
||||
:
|
||||
(path: string) => path.replace(/^\/mock/, "/mock")
|
||||
}
|
||||
}
|
||||
}
|
||||
,
|
||||
```
|
||||
|
||||
## 配置JSX
|
||||
|
||||
项目中已经设置好了JSX相关功能
|
||||
|
||||
![image-20240527152316666](./images/image-20240527152316666.png)
|
||||
|
||||
## Mock和多语言
|
||||
|
||||
### Mock设置
|
||||
|
||||
在环境已经设置好了Mock,只需要在`/src/mock`中写代码即可。
|
||||
|
||||
### 多语言设置
|
||||
|
||||
多语言现在作为网络请求来发送,在pinia中设置本地持久存储。
|
||||
|
||||
后端需要按照返回格式进行传送
|
||||
|
||||
![image-20240527152545485](./images/image-20240527152545485.png)
|
||||
|
||||
发送请求和初始化放在`App.vue`中
|
||||
|
||||
![image-20240527153132792](./images/image-20240527153132792.png)
|
||||
|
||||
#### 多语言只做本地化
|
||||
|
||||
只需要在`i18n`中加入你的语言,之后在`index.ts`中引用即可
|
||||
|
||||
![image-20240527153316912](./images/image-20240527153316912.png)
|
||||
|
||||
格式大致如下
|
||||
|
||||
![image-20240527153421787](./images/image-20240527153421787.png)
|
||||
|
||||
#### 后端返回多语言格式
|
||||
|
||||
这个格式也可以改,默认的如下。需要包含默认语言`local:xxx`
|
||||
|
||||
```
|
||||
{
|
||||
"i18n": {
|
||||
"zh_cn": {
|
||||
"login": {
|
||||
"reset": "重置",
|
||||
"register": "登录"
|
||||
},
|
||||
"home": {
|
||||
"articleModeAlbum": "相册模式",
|
||||
"articleModeList": "列表模式"
|
||||
},
|
||||
"tabs": {},
|
||||
"header": {
|
||||
"fullScreen": "全屏",
|
||||
"exitFullScreen": "退出全屏",
|
||||
"personalData": "个人信息",
|
||||
"changePassword": "修改密码",
|
||||
"logout": "退出登录"
|
||||
},
|
||||
"tip": {
|
||||
"loading": "加载中..."
|
||||
}
|
||||
},
|
||||
"en": {
|
||||
"login": {
|
||||
"reset": "reset",
|
||||
"register": "register"
|
||||
},
|
||||
"home": {
|
||||
"articleModeAlbum": "Album Mode",
|
||||
"articleModeList": "List Mode"
|
||||
},
|
||||
"tabs": {},
|
||||
"header": {
|
||||
"fullScreen": "Full Screen",
|
||||
"exitFullScreen": "Exit Full Screen",
|
||||
"personalData": "Personal Data",
|
||||
"changePassword": "Change Password",
|
||||
"logout": "Logout"
|
||||
},
|
||||
"tip": {
|
||||
"loading": "Loading..."
|
||||
}
|
||||
},
|
||||
"local": "zh_cn"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Vue指令
|
||||
|
||||
配置了打印、复制、水印等指令
|
||||
|
||||
![image-20240527153512670](./images/image-20240527153512670.png)
|
|
@ -0,0 +1,50 @@
|
|||
import type { BuildOptions } from 'vite';
|
||||
|
||||
export const buildEnvironment = () => {
|
||||
const environment: BuildOptions = {
|
||||
assetsInlineLimit: 20000,
|
||||
// 构建输出的目录,默认值为"dist"
|
||||
outDir: 'dist',
|
||||
// 用于指定使用的代码压缩工具。在这里,minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
|
||||
// esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
|
||||
minify: 'terser',
|
||||
// 用于配置 Terser 的选项
|
||||
terserOptions: {
|
||||
// 用于配置压缩选项
|
||||
compress: {
|
||||
drop_console: true, // 是否删除代码中的 console 语句, 默认值false
|
||||
drop_debugger: true, // 是否删除代码中的 debugger 语句, 默认值false
|
||||
},
|
||||
},
|
||||
// 禁用 gzip 压缩大小报告,可略微减少打包时间
|
||||
reportCompressedSize: false,
|
||||
// 用于指定是否生成源映射文件。源映射文件可以帮助调试和定位源代码中的错误。当设置为false时,构建过程不会生成源映射文件
|
||||
sourcemap: false,
|
||||
// 用于配置 CommonJS 模块的选项
|
||||
commonjsOptions: {
|
||||
// 用于指定是否忽略 CommonJS 模块中的 try-catch 语句。当设置为false时,构建过程会保留 CommonJS 模块中的 try-catch 语句
|
||||
ignoreTryCatch: false,
|
||||
},
|
||||
// 规定触发警告的 chunk 大小, 当某个代码分块的大小超过该限制时,Vite 会发出警告
|
||||
chunkSizeWarningLimit: 2000,
|
||||
// 用于配置 Rollup 打包工具的选项
|
||||
rollupOptions: {
|
||||
// 用于配置输出选项
|
||||
output: {
|
||||
// 静态资源分类和包装
|
||||
chunkFileNames: 'js/[name]-[hash].js', // 用于指定代码分块的输出文件名格式
|
||||
entryFileNames: 'js/[name]-[hash].js', // 用于指定入口文件的输出文件名格式
|
||||
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]', // 用于指定静态资源的输出文件名格式
|
||||
// ? 配置文件生成方式
|
||||
manualChunks: (id, meta) => {
|
||||
// 如果是包含在包中则打包成 vendor
|
||||
if (id.includes('node_modules')) {
|
||||
return 'vendor';
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return environment;
|
||||
};
|
|
@ -0,0 +1,55 @@
|
|||
import { Plugin as importToCDN } from "vite-plugin-cdn-import";
|
||||
|
||||
/**
|
||||
* @description 打包时采用`cdn`模式,仅限外网使用(默认不采用,如果需要采用cdn模式,请在 .env.production 文件,将 VITE_CDN 设置成true)
|
||||
* 平台采用国内cdn:https://www.bootcdn.cn,当然你也可以选择 https://unpkg.com 或者 https://www.jsdelivr.com
|
||||
* 注意:上面提到的仅限外网使用也不是完全肯定的,如果你们公司内网部署的有相关js、css文件,也可以将下面配置对应改一下,整一套内网版cdn
|
||||
*/
|
||||
export const cdn = importToCDN({
|
||||
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
||||
// prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
|
||||
prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
|
||||
modules: [
|
||||
{
|
||||
name: 'vue',
|
||||
var: 'Vue',
|
||||
path: 'dist/vue.global.js',
|
||||
},
|
||||
{
|
||||
name: 'vue-router',
|
||||
var: 'VueRouter',
|
||||
path: 'dist/vue-router.global.js',
|
||||
},
|
||||
{
|
||||
name: 'vue-i18n',
|
||||
var: 'VueI18n',
|
||||
path: 'dist/vue-i18n.global.js',
|
||||
},
|
||||
// 项目中没有直接安装vue-demi,但是pinia用到了,所以需要在引入pinia前引入vue-demi(https://github.com/vuejs/pinia/blob/v2/packages/pinia/package.json#L77)
|
||||
{
|
||||
name: 'vue-demi',
|
||||
var: 'VueDemi',
|
||||
path: 'lib/index.iife.js',
|
||||
},
|
||||
{
|
||||
name: 'pinia',
|
||||
var: 'Pinia',
|
||||
path: 'dist/pinia.iife.js',
|
||||
},
|
||||
{
|
||||
name: 'axios',
|
||||
var: 'axios',
|
||||
path: 'dist/axios.min.js',
|
||||
},
|
||||
{
|
||||
name: 'dayjs',
|
||||
var: 'dayjs',
|
||||
path: 'dayjs.min.js',
|
||||
},
|
||||
{
|
||||
name: 'echarts',
|
||||
var: 'echarts',
|
||||
path: 'dist/echarts.js',
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,57 @@
|
|||
import type { Plugin } from 'vite';
|
||||
import { isArray } from '@pureadmin/utils';
|
||||
import compressPlugin from 'vite-plugin-compression';
|
||||
|
||||
export const configCompressPlugin = (compress: any): Plugin | Plugin[] | null => {
|
||||
if (compress === 'none' || compress === void 0) return null;
|
||||
|
||||
const gz = {
|
||||
// 生成的压缩包后缀
|
||||
ext: '.gz',
|
||||
// 体积大于threshold才会被压缩
|
||||
threshold: 0,
|
||||
// 默认压缩.js|mjs|json|css|html后缀文件,设置成true,压缩全部文件
|
||||
filter: () => true,
|
||||
// 压缩后是否删除原始文件
|
||||
deleteOriginFile: false,
|
||||
};
|
||||
const br = {
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
threshold: 0,
|
||||
filter: () => true,
|
||||
deleteOriginFile: false,
|
||||
};
|
||||
|
||||
const codeList = [
|
||||
{ k: 'gzip', v: gz },
|
||||
{ k: 'brotli', v: br },
|
||||
{ k: 'both', v: [gz, br] },
|
||||
];
|
||||
|
||||
const plugins: Plugin[] = [];
|
||||
|
||||
codeList.forEach(item => {
|
||||
if (compress.includes(item.k)) {
|
||||
if (compress.includes('clear')) {
|
||||
if (isArray(item.v)) {
|
||||
item.v.forEach(vItem => {
|
||||
plugins.push(compressPlugin(Object.assign(vItem, { deleteOriginFile: true })));
|
||||
});
|
||||
} else {
|
||||
plugins.push(compressPlugin(Object.assign(item.v, { deleteOriginFile: true })));
|
||||
}
|
||||
} else {
|
||||
if (isArray(item.v)) {
|
||||
item.v.forEach(vItem => {
|
||||
plugins.push(compressPlugin(vItem));
|
||||
});
|
||||
} else {
|
||||
plugins.push(compressPlugin(item.v));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return plugins;
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
import boxen, { type Options as BoxenOptions } from 'boxen';
|
||||
import dayjs, { type Dayjs } from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import gradientString from 'gradient-string';
|
||||
import type { Plugin } from 'vite';
|
||||
import { loadEnv } from 'vite';
|
||||
import { getPackageSize, root, wrapperEnv } from './utils';
|
||||
|
||||
dayjs.extend(duration);
|
||||
const { VITE_PORT } = wrapperEnv(loadEnv('dev', root));
|
||||
|
||||
const welcomeMessage = gradientString('cyan', 'magenta').multiline(
|
||||
`您好! 欢迎使用 bunny 系列开发模板
|
||||
项目访问地址如下:
|
||||
http://localhost:${VITE_PORT}`,
|
||||
);
|
||||
|
||||
const boxenOptions: BoxenOptions = {
|
||||
padding: 0.5,
|
||||
borderColor: 'cyan',
|
||||
borderStyle: 'round',
|
||||
};
|
||||
|
||||
export function viteBuildInfo(): Plugin {
|
||||
let config: { command: string };
|
||||
let startTime: Dayjs;
|
||||
let endTime: Dayjs;
|
||||
let outDir: string;
|
||||
return {
|
||||
name: 'vite:buildInfo',
|
||||
configResolved(resolvedConfig) {
|
||||
config = resolvedConfig;
|
||||
outDir = resolvedConfig.build?.outDir ?? 'dist';
|
||||
},
|
||||
buildStart() {
|
||||
console.log(boxen(welcomeMessage, boxenOptions));
|
||||
if (config.command === 'build') {
|
||||
startTime = dayjs(new Date());
|
||||
}
|
||||
},
|
||||
closeBundle() {
|
||||
if (config.command === 'build') {
|
||||
endTime = dayjs(new Date());
|
||||
getPackageSize({
|
||||
folder: outDir,
|
||||
callback: (size: string) => {
|
||||
console.log(
|
||||
boxen(
|
||||
gradientString('cyan', 'magenta').multiline(
|
||||
`🎉 恭喜打包完成(总用时${dayjs.duration(endTime.diff(startTime)).format('mm分ss秒')},打包后的大小为${size})`,
|
||||
),
|
||||
boxenOptions,
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* 此文件作用于 `vite.config.ts` 的 `optimizeDeps.include` 依赖预构建配置项
|
||||
* 依赖预构建,`vite` 启动时会将下面 include 里的模块,编译成 esm 格式并缓存到 node_modules/.vite 文件夹,页面加载到对应模块时如果浏览器有缓存就读取浏览器缓存,如果没有会读取本地缓存并按需加载
|
||||
* 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里,否则会遇到开发环境切换页面卡顿的问题(vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
|
||||
* 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
|
||||
*/
|
||||
const include = [
|
||||
// 'qs',
|
||||
'mitt',
|
||||
'tailwindcss',
|
||||
// 'xlsx',
|
||||
'dayjs',
|
||||
'axios',
|
||||
'pinia',
|
||||
// 'typeit',
|
||||
// 'swiper',
|
||||
// 'qrcode',
|
||||
// 'intro.js',
|
||||
'vue-i18n',
|
||||
// 'vxe-table',
|
||||
// 'vue-types',
|
||||
// 'js-cookie',
|
||||
// 'vue-tippy',
|
||||
// 'cropperjs',
|
||||
// 'jsbarcode',
|
||||
// 'pinyin-pro',
|
||||
// 'sortablejs',
|
||||
// 'swiper/vue',
|
||||
// 'mint-filter',
|
||||
// '@vueuse/core',
|
||||
// 'vue3-danmaku',
|
||||
// 'v-contextmenu',
|
||||
// 'vue-pdf-embed',
|
||||
// 'wavesurfer.js',
|
||||
// 'swiper/modules',
|
||||
// 'china-area-data',
|
||||
// 'vue-json-pretty',
|
||||
// '@logicflow/core',
|
||||
'@pureadmin/utils',
|
||||
// '@wangeditor/editor',
|
||||
// 'responsive-storage',
|
||||
// 'plus-pro-components',
|
||||
// '@howdyjs/mouse-menu',
|
||||
// '@logicflow/extension',
|
||||
// 'vue-virtual-scroller',
|
||||
// '@amap/amap-jsapi-loader',
|
||||
// 'el-table-infinite-scroll',
|
||||
// 'vue-waterfall-plugin-next',
|
||||
// '@infectoone/vue-ganttastic',
|
||||
// '@wangeditor/editor-for-vue',
|
||||
// 'vuedraggable/src/vuedraggable',
|
||||
];
|
||||
|
||||
/**
|
||||
* 在预构建中强制排除的依赖项
|
||||
* 温馨提示:所有以 `@iconify-icons/` 开头引入的的本地图标模块,都应该加入到下面的 `exclude` 里,因为平台推荐的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好
|
||||
*/
|
||||
const exclude = ['@iconify-icons/ep', '@iconify-icons/ri', '@pureadmin/theme/dist/browser-utils'];
|
||||
|
||||
export { include, exclude };
|
|
@ -0,0 +1,44 @@
|
|||
import { cdn } from './cdn';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import type { PluginOption } from 'vite';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
import legacy from '@vitejs/plugin-legacy';
|
||||
import { compression } from 'vite-plugin-compression2';
|
||||
import { viteMockServe } from 'vite-plugin-mock';
|
||||
import { viteBuildInfo } from './info';
|
||||
import { configCompressPlugin } from './compress.ts';
|
||||
|
||||
export function getPluginsList(VITE_CDN: boolean, VITE_COMPRESSION: any): PluginOption[] {
|
||||
return [
|
||||
vue(),
|
||||
legacy({
|
||||
targets: ['android 4', 'ios 8', 'chrome 30', 'ie 6'],
|
||||
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
|
||||
renderLegacyChunks: true,
|
||||
polyfills: [
|
||||
'es.symbol',
|
||||
'es.array.filter',
|
||||
'es.promise',
|
||||
'es.promise.finally',
|
||||
'es/map',
|
||||
'es/set',
|
||||
'es.array.for-each',
|
||||
'es.object.define-properties',
|
||||
'es.object.define-property',
|
||||
'es.object.get-own-property-descriptor',
|
||||
'es.object.get-own-property-descriptors',
|
||||
'es.object.keys',
|
||||
'es.object.to-string',
|
||||
'web.dom-collections.for-each',
|
||||
'esnext.global-this',
|
||||
'esnext.string.match-all',
|
||||
],
|
||||
}),
|
||||
vueJsx(),
|
||||
compression(),
|
||||
viteBuildInfo(),
|
||||
VITE_CDN ? cdn : null,
|
||||
configCompressPlugin(VITE_COMPRESSION),
|
||||
viteMockServe({ mockPath: 'src/api/mock' }),
|
||||
];
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { loadEnv, type ServerOptions } from 'vite';
|
||||
import { root, wrapperEnv } from './utils';
|
||||
|
||||
export const serverOptions = (mode: string) => {
|
||||
const { VITE_APP_URL, VITE_APP_MOCK_URL, VITE_PORT } = wrapperEnv(loadEnv(mode, root));
|
||||
|
||||
const options: ServerOptions = {
|
||||
port: VITE_PORT,
|
||||
host: '0.0.0.0',
|
||||
open: true,
|
||||
cors: true,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: VITE_APP_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/api/, '/api'),
|
||||
},
|
||||
'/mock': {
|
||||
target: VITE_APP_MOCK_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/mock/, '/mock'),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return options;
|
||||
};
|
|
@ -0,0 +1,89 @@
|
|||
import { Recordable, formatBytes, sum } from '@pureadmin/utils';
|
||||
import { readdir, stat } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
/** 启动`node`进程时所在工作目录的绝对路径 */
|
||||
const root: string = process.cwd();
|
||||
|
||||
const fileListTotal: number[] = [];
|
||||
|
||||
/** 获取指定文件夹中所有文件的总大小 */
|
||||
const getPackageSize = (options: any) => {
|
||||
const { folder = 'dist', callback, format = true } = options;
|
||||
readdir(folder, (err, files: string[]) => {
|
||||
if (err) throw err;
|
||||
let count = 0;
|
||||
const checkEnd = () => {
|
||||
++count == files.length && callback(format ? formatBytes(sum(fileListTotal)) : sum(fileListTotal));
|
||||
};
|
||||
files.forEach((item: string) => {
|
||||
stat(`${folder}/${item}`, async (err, stats) => {
|
||||
if (err) throw err;
|
||||
if (stats.isFile()) {
|
||||
fileListTotal.push(stats.size);
|
||||
checkEnd();
|
||||
} else if (stats.isDirectory()) {
|
||||
getPackageSize({
|
||||
folder: `${folder}/${item}/`,
|
||||
callback: checkEnd,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
files.length === 0 && callback(0);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 根据可选的路径片段生成一个新的绝对路径
|
||||
* @param dir 路径片段,默认`build`
|
||||
* @param metaUrl 模块的完整`url`,如果在`build`目录外调用必传`import.meta.url`
|
||||
*/
|
||||
const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
|
||||
// 当前文件目录的绝对路径
|
||||
const currentFileDir = dirname(fileURLToPath(metaUrl));
|
||||
// build 目录的绝对路径
|
||||
const buildDir = resolve(currentFileDir, 'build');
|
||||
// 解析的绝对路径
|
||||
const resolvedPath = resolve(currentFileDir, dir);
|
||||
// 检查解析的绝对路径是否在 build 目录内
|
||||
if (resolvedPath.startsWith(buildDir)) {
|
||||
// 在 build 目录内,返回当前文件路径
|
||||
return fileURLToPath(metaUrl);
|
||||
}
|
||||
// 不在 build 目录内,返回解析后的绝对路径
|
||||
return resolvedPath;
|
||||
};
|
||||
|
||||
/** 处理环境变量 */
|
||||
const wrapperEnv = (envConf: Recordable): any => {
|
||||
// TODO 默认值
|
||||
const ret: any = {
|
||||
VITE_BASE_API: '',
|
||||
VITE_MOCK_BASE_API: '',
|
||||
VITE_PORT: 6262,
|
||||
VITE_APP_URL: '',
|
||||
VITE_APP_MOCK_URL: '',
|
||||
VITE_CDN: false,
|
||||
};
|
||||
|
||||
for (const envName of Object.keys(envConf)) {
|
||||
let realName = envConf[envName].replace(/\\n/g, '\n');
|
||||
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
||||
|
||||
if (envName === 'VITE_PORT') {
|
||||
realName = Number(realName);
|
||||
}
|
||||
ret[envName] = realName;
|
||||
if (typeof realName === 'string') {
|
||||
process.env[envName] = realName;
|
||||
} else if (typeof realName === 'object') {
|
||||
process.env[envName] = JSON.stringify(realName);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
export { getPackageSize, pathResolve, root, wrapperEnv };
|
|
@ -0,0 +1,145 @@
|
|||
// 使用细节:
|
||||
// 1、导入方式:在 src 文件夹中使用可以 const version = require('@/utils/version') 这样引入使用,在根目录也就是 src 之外的文件夹则只能 const version = require('./src/utils/version') 这样引入使用
|
||||
|
||||
// 引入请求库(如果想使用 axios 请求,打开注释即可,下面 get 方法中也需要打开注释,默认使用JS原生请求)
|
||||
// const axios = require('axios')
|
||||
// 引入文件管理模块(基于 node 环境,如果为原生前端开发,则注释掉 fs 相关的代码即可,直接手动创建一个文件使用 get 方法获取即可,注意统一存储内容格式看 create 方法注释)
|
||||
import fs from 'fs';
|
||||
|
||||
// 本地版本号缓存 key
|
||||
const storageKey = 'currentVersion';
|
||||
|
||||
// 创建版本文件(由于 fs 基于 node,且只需要每次编译时创建更新一遍,所以推荐放置于 vue.config.js 文件顶部使用,然后使用 build 命令时会被成功执行创建好文件)
|
||||
// path: 文件路径以及文件名称(例如:verify.text, public/verify.json 都是存在 public 文件夹中)
|
||||
// version: 版本号(例如:版本号、时间戳 ...,统一存储内容为:{ version: xxx })
|
||||
// result: 回调创建于写入结果
|
||||
function create(path = 'public/verify.json', version = new Date().getTime(), result) {
|
||||
// 在指定目录中添加校验文件
|
||||
fs.writeFile(path, JSON.stringify({ version }), err => {
|
||||
const isOK = !!err;
|
||||
if (result) {
|
||||
result({ isOK });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取版本号(下面 get 方法)升级版(返回:当前版本号、是否有新版本。样例:{ version: xxx,new: true },并缓存好新的版本号,可选择直接刷新页面。vue 推荐放到路由守卫 router.afterEach(路由跳转后) 回调中,切换页面时随时检查版本是否更新,这个请求很快的,占用的时间几乎可以忽略,而且就是切换页面完成之后,就算失败或者网不好也不影响正常操作)
|
||||
// path: 看下面 get 方法中的注释
|
||||
// isReload: 如果有新版本使用,是否重新加载当前页面,强制浏览器重服务器获取当前页面资源,false 为后续自行手动刷新
|
||||
function getPro(path = 'verify.json', isReload = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 获取版本号
|
||||
get(path)
|
||||
.then(res => {
|
||||
// 服务器版本号
|
||||
const version = res.version;
|
||||
// 检查是否有新版本
|
||||
const isNew = isNewAvailable(version);
|
||||
// 缓存版本号
|
||||
save(version);
|
||||
// 有新版本的话是否重新从服务器加载页面数据
|
||||
if (isNew && isReload) {
|
||||
reload();
|
||||
}
|
||||
// 返回
|
||||
resolve({ version: version, new: isNew });
|
||||
})
|
||||
.catch(err => {
|
||||
// 返回
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 获取版本号(返回:当前版本号。样例:{ version: xxx },vue 推荐放到路由守卫 router.afterEach(路由跳转后) 回调中,切换页面时随时检查版本是否更新,这个请求很快的,占用的时间几乎可以忽略,而且就是切换页面完成之后,就算失败或者网不好也不影响正常操作)
|
||||
// path: 服务器文件路径(例如上 create() 中的路径,文件存 build 后存放在 public 文件夹中,服务器路径则直接域 + 文件名既可,如果为原生前端开发也是一样)
|
||||
function get(path = 'verify.json') {
|
||||
// 服务器文件路径
|
||||
const url = `${window.location.origin}/${path}?timestamp=${new Date().getTime()}`;
|
||||
|
||||
// axios 请求
|
||||
// return new Promise((resolve, reject) => {
|
||||
// // 获取内容
|
||||
// axios.get(url).then(res => {
|
||||
// resolve(res)
|
||||
// }).catch(err => {
|
||||
// reject(err)
|
||||
// })
|
||||
// })
|
||||
|
||||
// JS原生请求
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建 XMLHttpRequest 对象
|
||||
var xhr = null;
|
||||
if (window.XMLHttpRequest) {
|
||||
// 现代主流浏览器的写法
|
||||
xhr = new XMLHttpRequest();
|
||||
} else {
|
||||
// IE浏览器的写法
|
||||
xhr = new ActiveXObject('Microsoft.XMLHTTP');
|
||||
}
|
||||
// 创建网络请求对象
|
||||
xhr.open('get', url, true);
|
||||
// 发送请求
|
||||
xhr.send();
|
||||
// 请求回调
|
||||
xhr.onreadystatechange = () => {
|
||||
// 连接成功
|
||||
if (xhr.status === 200) {
|
||||
// 请求成功
|
||||
if (xhr.readyState === 4) {
|
||||
// 返回
|
||||
resolve(JSON.parse(xhr.responseText));
|
||||
}
|
||||
} else {
|
||||
// 连接失败
|
||||
reject(new Error('获取失败'));
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// 缓存版本号
|
||||
// version: 版本号(服务器获取到的版本号)
|
||||
function save(version) {
|
||||
localStorage.setItem(storageKey, version);
|
||||
}
|
||||
|
||||
// 检查是否有新版本(true:有新版本 false:没有新版本)
|
||||
// version: 版本号(服务器获取到的版本号)
|
||||
function isNewAvailable(version) {
|
||||
// 没值(不清楚是否为新版本,默认返回 false, 如果这种情况下需要刷新,可修改返回 true)
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
// 获取本地缓存的版本号
|
||||
const storageVersion = localStorage.getItem(storageKey);
|
||||
// 本地没有版本号,说明本机第一次加载,不算新版本
|
||||
if (!storageVersion || storageVersion === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
// 本地有版本号,进行对比
|
||||
return `${version}` !== `${storageVersion}`;
|
||||
}
|
||||
|
||||
// 刷新当前网页
|
||||
function reload() {
|
||||
// 重新加载当前页面,强制浏览器重服务器获取当前页面资源
|
||||
window.location.reload(true);
|
||||
}
|
||||
|
||||
// 导出
|
||||
export {
|
||||
// 创建版本文件
|
||||
create,
|
||||
// 获取版本号
|
||||
get,
|
||||
// 获取版本号升级版
|
||||
getPro,
|
||||
// 缓存版本号
|
||||
save,
|
||||
// 检查是否有新版本
|
||||
isNewAvailable,
|
||||
// 刷新当前页面,强制浏览器重服务器获取当前页面资源
|
||||
reload,
|
||||
};
|
|
@ -0,0 +1,108 @@
|
|||
// @see: https://cz-git.qbenben.com/zh/guide
|
||||
/** @type {import("cz-git").UserConfig} */
|
||||
|
||||
export default {
|
||||
ignores: [commit => commit === "init"],
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
rules: {
|
||||
// @see: https://commitlint.js.org/#/reference-rules
|
||||
"body-leading-blank": [2, "always"],
|
||||
"footer-leading-blank": [1, "always"],
|
||||
"header-max-length": [2, "always", 108],
|
||||
"subject-empty": [2, "never"],
|
||||
"type-empty": [2, "never"],
|
||||
"subject-case": [0],
|
||||
"type-enum": [
|
||||
2,
|
||||
"always",
|
||||
[
|
||||
"init",
|
||||
"feat",
|
||||
"page",
|
||||
"media",
|
||||
"completepage",
|
||||
"fix",
|
||||
"fixbug",
|
||||
"docs",
|
||||
"style",
|
||||
"refactor",
|
||||
"perf",
|
||||
"test",
|
||||
"build",
|
||||
"ci",
|
||||
"chore",
|
||||
"revert",
|
||||
"wip",
|
||||
"workflow",
|
||||
"types",
|
||||
"release",
|
||||
"optimize"
|
||||
]
|
||||
]
|
||||
},
|
||||
prompt: {
|
||||
messages: {
|
||||
type: "选择你要提交的类型 :",
|
||||
scope: "选择一个提交范围(可选):",
|
||||
customScope: "请输入自定义的提交范围 :",
|
||||
subject: "填写简短精炼的变更描述 :\n",
|
||||
body: "填写更加详细的变更描述(可选)。使用 \"|\" 换行 :\n",
|
||||
breaking: "列举非兼容性重大的变更(可选)。使用 \"|\" 换行 :\n",
|
||||
footerPrefixsSelect: "选择关联issue前缀(可选):",
|
||||
customFooterPrefixs: "输入自定义issue前缀 :",
|
||||
footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
|
||||
confirmCommit: "是否提交或修改commit ?"
|
||||
},
|
||||
types: [
|
||||
{ value: "init", name: "初始化: ⏳ 初始化项目", emoji: "⏳" },
|
||||
{ value: "optimize", name: "优化代码: ♻️ 优化项目代码", emoji: "♻️" },
|
||||
{ value: "feat", name: "新增: 🚀 新增功能", emoji: "🚀" },
|
||||
{ value: "media", name: "媒体: 🎁 新增媒体资源", emoji: "🎁" },
|
||||
{ value: "page", name: "页面: 📄 新增页面", emoji: "📄" },
|
||||
{ value: "completepage", name: "完成页面: 🍻 完成页面", emoji: "🍻" },
|
||||
{ value: "fixbug", name: "bug: 🐛 修改bug", emoji: "🐛" },
|
||||
{ value: "fix", name: "修复: 🧩 修复缺陷", emoji: "🧩" },
|
||||
{ value: "docs", name: "文档: 📚 文档变更", emoji: "📚" },
|
||||
{ value: "style", name: "格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)", emoji: "🎨" },
|
||||
{ value: "refactor", name: "重构: 〽️ 代码重构(不包括 bug 修复、功能新增)", emoji: "〽️" },
|
||||
{ value: "perf", name: "性能: ⚡️ 性能优化", emoji: "⚡️" },
|
||||
{ value: "test", name: "测试: ✅ 添加疏漏测试或已有测试改动", emoji: "✅" },
|
||||
{
|
||||
value: "chore",
|
||||
name: "构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)",
|
||||
emoji: "📦️"
|
||||
},
|
||||
{ value: "ci", name: "集成: 🎡 修改 CI 配置、脚本", emoji: "🎡" },
|
||||
{ value: "revert", name: "回退: ⏪️ 回滚 commit", emoji: "⏪️" },
|
||||
{ value: "build", name: "打包: 🔨 项目打包发布", emoji: "🔨" }
|
||||
],
|
||||
useEmoji: true,
|
||||
themeColorCode: "",
|
||||
scopes: [],
|
||||
allowCustomScopes: true,
|
||||
allowEmptyScopes: true,
|
||||
customScopesAlign: "bottom",
|
||||
customScopesAlias: "custom",
|
||||
emptyScopesAlias: "empty",
|
||||
upperCaseSubject: false,
|
||||
allowBreakingChanges: ["feat", "fix"],
|
||||
breaklineNumber: 100,
|
||||
breaklineChar: "|",
|
||||
skipQuestions: [],
|
||||
issuePrefixs: [{ value: "closed", name: "closed: ISSUES has been processed" }],
|
||||
customIssuePrefixsAlign: "top",
|
||||
emptyIssuePrefixsAlias: "skip",
|
||||
customIssuePrefixsAlias: "custom",
|
||||
allowCustomIssuePrefixs: true,
|
||||
allowEmptyIssuePrefixs: true,
|
||||
confirmColorize: true,
|
||||
maxHeaderLength: Infinity,
|
||||
maxSubjectLength: Infinity,
|
||||
minSubjectLength: 0,
|
||||
scopeOverrides: undefined,
|
||||
defaultBody: "",
|
||||
defaultIssues: "",
|
||||
defaultScope: "",
|
||||
defaultSubject: ""
|
||||
}
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
# 使用官方的 Nginx 镜像作为基础镜像
|
||||
FROM nginx
|
||||
|
||||
# 删除默认的 Nginx 配置文件
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
|
||||
# 将自定义的 Nginx 配置文件复制到容器中
|
||||
COPY nginx.conf /etc/nginx/conf.d/
|
||||
|
||||
# 创建一个目录来存放前端项目文件
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
# 将前端项目打包文件复制到 Nginx 的默认静态文件目录
|
||||
COPY dist/ /usr/share/nginx/html
|
||||
# 复制到nginx目录下
|
||||
COPY dist/ /etc/nginx/html
|
||||
|
||||
# 暴露 Nginx 的默认端口
|
||||
EXPOSE 80
|
||||
|
||||
# 自动启动 Nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
root /etc/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
# 后端跨域请求
|
||||
location ~/api/ {
|
||||
proxy_pass http://192.168.3.98:1001;
|
||||
}
|
||||
|
||||
# mock 跨域
|
||||
location ~/mock/ {
|
||||
proxy_pass http://192.168.3.98:1001;
|
||||
}
|
||||
|
||||
error_page 404 404.html;
|
||||
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 119 KiB |
After Width: | Height: | Size: 184 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue + TS</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
export default {
|
||||
'*.{js,jsx,ts,tsx}': ['prettier --write'],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
|
||||
'package.json': ['prettier --write'],
|
||||
// "*.vue": ["eslint --fix", "prettier --write"],
|
||||
'*.{scss,less,styl,html}': ['prettier --write'], // 'stylelint --fix',
|
||||
'*.md': ['prettier --write'],
|
||||
};
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"name": "vite_ts_auto",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"description": "Bunny-Vite模板",
|
||||
"author": {
|
||||
"name": "Bunny0212",
|
||||
"email": "1319900154@qq.com",
|
||||
"url": "https://github.com/BunnyMaster"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"bunny-cli",
|
||||
"tailwindcss",
|
||||
"typescript",
|
||||
"pinia",
|
||||
"vue3",
|
||||
"vite",
|
||||
"esm"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"serve": "vite",
|
||||
"start": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
|
||||
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
|
||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
||||
"lint:lint-staged": "lint-staged",
|
||||
"prepare": "husky install",
|
||||
"commit": "git pull && git add -A && git-cz && git push"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pureadmin/utils": "^2.4.7",
|
||||
"@vitejs/plugin-legacy": "^5.4.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
"@vitejs/plugin-vue2-jsx": "^1.1.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"axios": "^1.6.7",
|
||||
"boxen": "^7.1.1",
|
||||
"compression-webpack-plugin": "^11.1.0",
|
||||
"core-js": "^3.36.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"dotenv": "^16.4.5",
|
||||
"echarts": "^5.5.0",
|
||||
"gradient-string": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mitt": "^3.0.1",
|
||||
"moment": "^2.30.1",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"postcss-import": "^16.1.0",
|
||||
"punycode": "^2.3.1",
|
||||
"stylelint-scss": "^6.3.0",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"uuid": "^9.0.1",
|
||||
"vite-plugin-cdn-import": "^1.0.1",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-compression2": "^1.1.1",
|
||||
"vue": "^3.4.21",
|
||||
"vue-cookies": "^1.8.3",
|
||||
"vue-demi": "^0.14.8",
|
||||
"vue-i18n": "^9.13.1",
|
||||
"vue-lazyload": "^3.0.0",
|
||||
"vue-router": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.8.1",
|
||||
"@commitlint/config-conventional": "^17.8.1",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/node": "^20.12.10",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/cli-plugin-babel": "~5.0.8",
|
||||
"@vue/cli-plugin-eslint": "~5.0.8",
|
||||
"@vue/cli-plugin-router": "~5.0.8",
|
||||
"@vue/cli-plugin-typescript": "~5.0.8",
|
||||
"@vue/cli-service": "~5.0.8",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
"commitizen": "^4.3.0",
|
||||
"cz-git": "^1.9.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-vue": "^9.22.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"husky": "^8.0.1",
|
||||
"lint-staged": "^15.2.2",
|
||||
"mockjs": "^1.1.0",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss-html": "^1.6.0",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.71.1",
|
||||
"sass-loader": "^14.1.1",
|
||||
"typescript": "~5.3.3",
|
||||
"vite": "^5.2.0",
|
||||
"vite-plugin-mock": "^3.0.2",
|
||||
"vue-tsc": "^2.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
||||
"pnpm": ">=8.6.10"
|
||||
},
|
||||
"pnpm": {
|
||||
"allowedDeprecatedVersions": {
|
||||
"sourcemap-codec": "*",
|
||||
"domexception": "*",
|
||||
"w3c-hr-time": "*",
|
||||
"stable": "*",
|
||||
"abab": "*"
|
||||
},
|
||||
"peerDependencyRules": {
|
||||
"allowedVersions": {
|
||||
"eslint": "9"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "node_modules/cz-git"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// @ts-check
|
||||
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
export default {
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'tailwindcss/nesting': {},
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}),
|
||||
},
|
||||
};
|
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1 @@
|
|||
{"version":1720007747647}
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<RouterView />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { userI18nStore } from '@/store/i18n.ts';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const i18nStore = userI18nStore();
|
||||
const i18n = useI18n();
|
||||
/**
|
||||
* * 设置多语言内容
|
||||
*/
|
||||
const setI18n = async () => {
|
||||
await i18nStore.fetchI18n();
|
||||
const languageData = JSON.parse(localStorage.getItem('i18nStore') as any);
|
||||
const local = languageData.i18n.local;
|
||||
|
||||
// 初始化设置多语言内容
|
||||
i18n.locale.value = local;
|
||||
i18n.mergeLocaleMessage(local, languageData.i18n[local]);
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await setI18n();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,8 @@
|
|||
import Request from '@/api/service/request-mock.ts';
|
||||
|
||||
export const fetchGetI18n = () => {
|
||||
return Request({
|
||||
url: '/getI18n',
|
||||
method: 'GET',
|
||||
});
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import Request from '@/api/service/request';
|
||||
|
||||
export const fetchTestApi = () => {
|
||||
return Request({ url: '/user/getCurrentUserInfo', method: 'GET' });
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
// src/api/mock/i18n/modules/zh_cn.ts
|
||||
var zh_cn = {
|
||||
login: {
|
||||
reset: "\u91CD\u7F6E",
|
||||
register: "\u767B\u5F55"
|
||||
},
|
||||
home: {},
|
||||
tabs: {},
|
||||
header: {
|
||||
fullScreen: "\u5168\u5C4F",
|
||||
exitFullScreen: "\u9000\u51FA\u5168\u5C4F",
|
||||
personalData: "\u4E2A\u4EBA\u4FE1\u606F",
|
||||
changePassword: "\u4FEE\u6539\u5BC6\u7801",
|
||||
logout: "\u9000\u51FA\u767B\u5F55"
|
||||
},
|
||||
tip: {
|
||||
loading: "\u52A0\u8F7D\u4E2D..."
|
||||
}
|
||||
};
|
||||
|
||||
// src/api/mock/i18n/modules/en.ts
|
||||
var en = {
|
||||
login: {
|
||||
reset: "reset",
|
||||
register: "register"
|
||||
},
|
||||
home: {},
|
||||
tabs: {},
|
||||
header: {
|
||||
fullScreen: "Full Screen",
|
||||
exitFullScreen: "Exit Full Screen",
|
||||
personalData: "Personal Data",
|
||||
changePassword: "Change Password",
|
||||
logout: "Logout"
|
||||
},
|
||||
tip: {
|
||||
loading: "Loading..."
|
||||
}
|
||||
};
|
||||
|
||||
// src/api/mock/i18n/index.ts
|
||||
var list = [
|
||||
{
|
||||
url: "/mock/getI18n",
|
||||
method: "get",
|
||||
response: () => ({ data: { zh_cn, en, local: "zh_cn" } })
|
||||
}
|
||||
];
|
||||
var i18n_default = list;
|
||||
export {
|
||||
i18n_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2FwaS9tb2NrL2kxOG4vbW9kdWxlcy96aF9jbi50cyIsICJzcmMvYXBpL21vY2svaTE4bi9tb2R1bGVzL2VuLnRzIiwgInNyYy9hcGkvbW9jay9pMThuL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX2luamVjdGVkX2ZpbGVuYW1lX18gPSBcIkQ6XFxcXFByb2plY3RcXFxcd2ViXFxcXEJ1bm55LUNsaVxcXFx0ZW1wbGF0ZVxcXFx2dWVcXFxcdml0ZV90c19hdXRvXFxcXHNyY1xcXFxhcGlcXFxcbW9ja1xcXFxpMThuXFxcXG1vZHVsZXNcXFxcemhfY24udHNcIjtjb25zdCBfX2luamVjdGVkX2Rpcm5hbWVfXyA9IFwiRDpcXFxcUHJvamVjdFxcXFx3ZWJcXFxcQnVubnktQ2xpXFxcXHRlbXBsYXRlXFxcXHZ1ZVxcXFx2aXRlX3RzX2F1dG9cXFxcc3JjXFxcXGFwaVxcXFxtb2NrXFxcXGkxOG5cXFxcbW9kdWxlc1wiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vRDovUHJvamVjdC93ZWIvQnVubnktQ2xpL3RlbXBsYXRlL3Z1ZS92aXRlX3RzX2F1dG8vc3JjL2FwaS9tb2NrL2kxOG4vbW9kdWxlcy96aF9jbi50c1wiO2V4cG9ydCBjb25zdCB6aF9jbiA9IHtcclxuXHRsb2dpbjoge1xyXG5cdFx0cmVzZXQ6ICdcdTkxQ0RcdTdGNkUnLFxyXG5cdFx0cmVnaXN0ZXI6ICdcdTc2N0JcdTVGNTUnLFxyXG5cdH0sXHJcblx0aG9tZToge30sXHJcblx0dGFiczoge30sXHJcblx0aGVhZGVyOiB7XHJcblx0XHRmdWxsU2NyZWVuOiAnXHU1MTY4XHU1QzRGJyxcclxuXHRcdGV4aXRGdWxsU2NyZWVuOiAnXHU5MDAwXHU1MUZBXHU1MTY4XHU1QzRGJyxcclxuXHRcdHBlcnNvbmFsRGF0YTogJ1x1NEUyQVx1NEVCQVx1NEZFMVx1NjA2RicsXHJcblx0XHRjaGFuZ2VQYXNzd29yZDogJ1x1NEZFRVx1NjUzOVx1NUJDNlx1NzgwMScsXHJcblx0XHRsb2dvdXQ6ICdcdTkwMDBcdTUxRkFcdTc2N0JcdTVGNTUnLFxyXG5cdH0sXHJcblx0dGlwOiB7XHJcblx0XHRsb2FkaW5nOiAnXHU1MkEwXHU4RjdEXHU0RTJELi4uJyxcclxuXHR9LFxyXG59O1xyXG4iLCAiY29uc3QgX19pbmplY3RlZF9maWxlbmFtZV9fID0gXCJEOlxcXFxQcm9qZWN0XFxcXHdlYlxcXFxCdW5ueS1DbGlcXFxcdGVtcGxhdGVcXFxcdnVlXFxcXHZpdGVfdHNfYXV0b1xcXFxzcmNcXFxcYXBpXFxcXG1vY2tcXFxcaTE4blxcXFxtb2R1bGVzXFxcXGVuLnRzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIkQ6XFxcXFByb2plY3RcXFxcd2ViXFxcXEJ1bm55LUNsaVxcXFx0ZW1wbGF0ZVxcXFx2dWVcXFxcdml0ZV90c19hdXRvXFxcXHNyY1xcXFxhcGlcXFxcbW9ja1xcXFxpMThuXFxcXG1vZHVsZXNcIjtjb25zdCBfX2luamVjdGVkX2ltcG9ydF9tZXRhX3VybF9fID0gXCJmaWxlOi8vL0Q6L1Byb2plY3Qvd2ViL0J1bm55LUNsaS90ZW1wbGF0ZS92dWUvdml0ZV90c19hdXRvL3NyYy9hcGkvbW9jay9pMThuL21vZHVsZXMvZW4udHNcIjtleHBvcnQgY29uc3QgZW4gPSB7XHJcblx0bG9naW46IHtcclxuXHRcdHJlc2V0OiAncmVzZXQnLFxyXG5cdFx0cmVnaXN0ZXI6ICdyZWdpc3RlcicsXHJcblx0fSxcclxuXHRob21lOiB7fSxcclxuXHR0YWJzOiB7fSxcclxuXHRoZWFkZXI6IHtcclxuXHRcdGZ1bGxTY3JlZW46ICdGdWxsIFNjcmVlbicsXHJcblx0XHRleGl0RnVsbFNjcmVlbjogJ0V4aXQgRnVsbCBTY3JlZW4nLFxyXG5cdFx0cGVyc29uYWxEYXRhOiAnUGVyc29uYWwgRGF0YScsXHJcblx0XHRjaGFuZ2VQYXNzd29yZDogJ0NoYW5nZSBQYXNzd29yZCcsXHJcblx0XHRsb2dvdXQ6ICdMb2dvdXQnLFxyXG5cdH0sXHJcblx0dGlwOiB7XHJcblx0XHRsb2FkaW5nOiAnTG9hZGluZy4uLicsXHJcblx0fSxcclxufTtcclxuIiwgImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiRDpcXFxcUHJvamVjdFxcXFx3ZWJcXFxcQnVubnktQ2xpXFxcXHRlbXBsYXRlXFxcXHZ1ZVxcXFx2aXRlX3RzX2F1dG9cXFxcc3JjXFxcXGFwaVxcXFxtb2NrXFxcXGkxOG5cXFxcaW5kZXgudHNcIjtjb25zdCBfX2luamVjdGVkX2Rpcm5hbWVfXyA9IFwiRDpcXFxcUHJvamVjdFxcXFx3ZWJcXFxcQnVubnktQ2xpXFxcXHRlbXBsYXRlXFxcXHZ1ZVxcXFx2aXRlX3RzX2F1dG9cXFxcc3JjXFxcXGFwaVxcXFxtb2NrXFxcXGkxOG5cIjtjb25zdCBfX2luamVjdGVkX2ltcG9ydF9tZXRhX3VybF9fID0gXCJmaWxlOi8vL0Q6L1Byb2plY3Qvd2ViL0J1bm55LUNsaS90ZW1wbGF0ZS92dWUvdml0ZV90c19hdXRvL3NyYy9hcGkvbW9jay9pMThuL2luZGV4LnRzXCI7aW1wb3J0IHsgTW9ja01ldGhvZCB9IGZyb20gJ3ZpdGUtcGx1Z2luLW1vY2snO1xyXG5pbXBvcnQgeyB6aF9jbiB9IGZyb20gJy4vbW9kdWxlcy96aF9jbi50cyc7XHJcbmltcG9ydCB7IGVuIH0gZnJvbSAnLi9tb2R1bGVzL2VuLnRzJztcclxuXHJcbmNvbnN0IGxpc3Q6IE1vY2tNZXRob2RbXSA9IFtcclxuXHR7XHJcblx0XHR1cmw6ICcvbW9jay9nZXRJMThuJyxcclxuXHRcdG1ldGhvZDogJ2dldCcsXHJcblx0XHRyZXNwb25zZTogKCkgPT4gKHsgZGF0YTogeyB6aF9jbiwgZW4sIGxvY2FsOiAnemhfY24nIH0gfSksXHJcblx0fSxcclxuXTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGxpc3Q7XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBcVksSUFBTSxRQUFRO0FBQUEsRUFDbFosT0FBTztBQUFBLElBQ04sT0FBTztBQUFBLElBQ1AsVUFBVTtBQUFBLEVBQ1g7QUFBQSxFQUNBLE1BQU0sQ0FBQztBQUFBLEVBQ1AsTUFBTSxDQUFDO0FBQUEsRUFDUCxRQUFRO0FBQUEsSUFDUCxZQUFZO0FBQUEsSUFDWixnQkFBZ0I7QUFBQSxJQUNoQixjQUFjO0FBQUEsSUFDZCxnQkFBZ0I7QUFBQSxJQUNoQixRQUFRO0FBQUEsRUFDVDtBQUFBLEVBQ0EsS0FBSztBQUFBLElBQ0osU0FBUztBQUFBLEVBQ1Y7QUFDRDs7O0FDakIrWCxJQUFNLEtBQUs7QUFBQSxFQUN6WSxPQUFPO0FBQUEsSUFDTixPQUFPO0FBQUEsSUFDUCxVQUFVO0FBQUEsRUFDWDtBQUFBLEVBQ0EsTUFBTSxDQUFDO0FBQUEsRUFDUCxNQUFNLENBQUM7QUFBQSxFQUNQLFFBQVE7QUFBQSxJQUNQLFlBQVk7QUFBQSxJQUNaLGdCQUFnQjtBQUFBLElBQ2hCLGNBQWM7QUFBQSxJQUNkLGdCQUFnQjtBQUFBLElBQ2hCLFFBQVE7QUFBQSxFQUNUO0FBQUEsRUFDQSxLQUFLO0FBQUEsSUFDSixTQUFTO0FBQUEsRUFDVjtBQUNEOzs7QUNiQSxJQUFNLE9BQXFCO0FBQUEsRUFDMUI7QUFBQSxJQUNDLEtBQUs7QUFBQSxJQUNMLFFBQVE7QUFBQSxJQUNSLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLElBQUksT0FBTyxRQUFRLEVBQUU7QUFBQSxFQUN4RDtBQUNEO0FBRUEsSUFBTyxlQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
|
|
@ -0,0 +1,13 @@
|
|||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { zh_cn } from './modules/zh_cn.ts';
|
||||
import { en } from './modules/en.ts';
|
||||
|
||||
const list: MockMethod[] = [
|
||||
{
|
||||
url: '/mock/getI18n',
|
||||
method: 'get',
|
||||
response: () => ({ data: { zh_cn, en, local: 'zh_cn' } }),
|
||||
},
|
||||
];
|
||||
|
||||
export default list;
|
|
@ -0,0 +1,18 @@
|
|||
export const en = {
|
||||
login: {
|
||||
reset: 'reset',
|
||||
register: 'register',
|
||||
},
|
||||
home: {},
|
||||
tabs: {},
|
||||
header: {
|
||||
fullScreen: 'Full Screen',
|
||||
exitFullScreen: 'Exit Full Screen',
|
||||
personalData: 'Personal Data',
|
||||
changePassword: 'Change Password',
|
||||
logout: 'Logout',
|
||||
},
|
||||
tip: {
|
||||
loading: 'Loading...',
|
||||
},
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
export const zh_cn = {
|
||||
login: {
|
||||
reset: '重置',
|
||||
register: '登录',
|
||||
},
|
||||
home: {},
|
||||
tabs: {},
|
||||
header: {
|
||||
fullScreen: '全屏',
|
||||
exitFullScreen: '退出全屏',
|
||||
personalData: '个人信息',
|
||||
changePassword: '修改密码',
|
||||
logout: '退出登录',
|
||||
},
|
||||
tip: {
|
||||
loading: '加载中...',
|
||||
},
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
import axios from 'axios';
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: import.meta.env.VITE_MOCK_BASE_API,
|
||||
timeout: import.meta.env.VITE_BASE_API_TIMEOUT,
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(config => {
|
||||
return config;
|
||||
});
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
response => {
|
||||
return response.data;
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
return Promise.reject(new Error('网络错误'));
|
||||
},
|
||||
);
|
||||
|
||||
export default request;
|
|
@ -0,0 +1,95 @@
|
|||
import router from '@/router';
|
||||
import { localGet, localRemove } from '@/utils/util.ts';
|
||||
import axios from 'axios';
|
||||
import mittBus from '@/utils/mittBus.ts';
|
||||
|
||||
const request = axios.create({
|
||||
// 默认请求地址
|
||||
baseURL: import.meta.env.VITE_BASE_API,
|
||||
// 设置超时时间
|
||||
timeout: import.meta.env.VITE_BASE_API_TIMEOUT,
|
||||
// @ts-ignore
|
||||
retry: import.meta.env.VITE_BASE_API_RETRY, //设置全局重试请求次数(最多重试几次请求)
|
||||
retryDelay: import.meta.env.VITE_BASE_API_RETRY_DELAY, //设置全局请求间隔
|
||||
// 跨域允许携带凭证
|
||||
// withCredentials: true,
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(config => {
|
||||
// TODO 当本地有token表示登录了,请求时将token带上
|
||||
const token = localGet('token');
|
||||
|
||||
if (token !== null) {
|
||||
config.headers['token'] = token;
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
(response: any) => {
|
||||
// 返回相应数据
|
||||
const data = response.data;
|
||||
|
||||
// 登录过期
|
||||
if (data.code === 208) {
|
||||
// TODO 登录过期
|
||||
console.log('登录过期');
|
||||
router.push('/').then();
|
||||
localRemove('token');
|
||||
}
|
||||
|
||||
// 账户被封禁
|
||||
if (data.code === 209) {
|
||||
// TODO 账户被封禁
|
||||
console.log('账户被封禁');
|
||||
router.push('/').then();
|
||||
localRemove('token');
|
||||
}
|
||||
|
||||
// 统一处理异常
|
||||
if (data.code !== 200 && data.code < 300) {
|
||||
// TODO 统一处理异常
|
||||
console.log('统一处理异常');
|
||||
} else if (data.code > 300) {
|
||||
console.log('统一处理异常');
|
||||
}
|
||||
|
||||
// 返回消息内容
|
||||
mittBus.emit('system-request-error', { retry: 0, retryCount: 0, isSuccess: true });
|
||||
return data;
|
||||
},
|
||||
async error => {
|
||||
const config = error.config;
|
||||
// 重试次数
|
||||
const retry = config.retry;
|
||||
// 重试时间
|
||||
const retryDelay = config.retryDelay;
|
||||
// 当前重试次数
|
||||
config._retryCount = config._retryCount || 0;
|
||||
|
||||
// 如果重试次数大于定义次数返回错误
|
||||
if (config._retryCount > retry) {
|
||||
return Promise.reject(new Error(error.response.statusText));
|
||||
}
|
||||
|
||||
// 失败后打开到500页面
|
||||
await router.push('/500');
|
||||
mittBus.emit('system-request-error', { retry, retryCount: config._retryCount, isSuccess: false });
|
||||
|
||||
// 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间
|
||||
const backoff = new Promise(function (resolve) {
|
||||
setTimeout(() => resolve(true), retryDelay || 1000);
|
||||
});
|
||||
|
||||
// 如果失败次数加1
|
||||
config._retryCount += 1;
|
||||
|
||||
// 再次发送请求
|
||||
return backoff.then(() => request(error.config));
|
||||
},
|
||||
);
|
||||
|
||||
export default request;
|
|
@ -0,0 +1,603 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v5.3.0-alpha1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2022 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text: #0a58ca;
|
||||
--bs-secondary-text: #6c757d;
|
||||
--bs-success-text: #146c43;
|
||||
--bs-info-text: #087990;
|
||||
--bs-warning-text: #997404;
|
||||
--bs-danger-text: #b02a37;
|
||||
--bs-light-text: #6c757d;
|
||||
--bs-dark-text: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #f8f9fa;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #e9ecef;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-2xl: 2rem;
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(var(--bs-body-color-rgb), 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(var(--bs-body-color-rgb), 0.075);
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-form-control-bg: var(--bs-body-bg);
|
||||
--bs-form-control-disabled-bg: var(--bs-secondary-bg);
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-breakpoint-xs: 0;
|
||||
--bs-breakpoint-sm: 576px;
|
||||
--bs-breakpoint-md: 768px;
|
||||
--bs-breakpoint-lg: 992px;
|
||||
--bs-breakpoint-xl: 1200px;
|
||||
--bs-breakpoint-xxl: 1400px;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
--bs-body-color: #adb5bd;
|
||||
--bs-body-color-rgb: 173, 181, 189;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #f8f9fa;
|
||||
--bs-emphasis-color-rgb: 248, 249, 250;
|
||||
--bs-secondary-color: rgba(173, 181, 189, 0.75);
|
||||
--bs-secondary-color-rgb: 173, 181, 189;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(173, 181, 189, 0.5);
|
||||
--bs-tertiary-color-rgb: 173, 181, 189;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-primary-text: #6ea8fe;
|
||||
--bs-secondary-text: #dee2e6;
|
||||
--bs-success-text: #75b798;
|
||||
--bs-info-text: #6edff6;
|
||||
--bs-warning-text: #ffda6a;
|
||||
--bs-danger-text: #ea868f;
|
||||
--bs-light-text: #f8f9fa;
|
||||
--bs-dark-text: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #212529;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #495057;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #055160;
|
||||
--bs-warning-border-subtle: #664d03;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: #fff;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #9ec5fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 158, 197, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color, inherit);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
legend + * {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
/* rtl:raw:
|
||||
[types="tel"],
|
||||
[types="url"],
|
||||
[types="email"],
|
||||
[types="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
*/
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
|
@ -0,0 +1,588 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v5.3.0-alpha1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2022 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text: #0a58ca;
|
||||
--bs-secondary-text: #6c757d;
|
||||
--bs-success-text: #146c43;
|
||||
--bs-info-text: #087990;
|
||||
--bs-warning-text: #997404;
|
||||
--bs-danger-text: #b02a37;
|
||||
--bs-light-text: #6c757d;
|
||||
--bs-dark-text: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #f8f9fa;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #e9ecef;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-2xl: 2rem;
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(var(--bs-body-color-rgb), 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(var(--bs-body-color-rgb), 0.075);
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-form-control-bg: var(--bs-body-bg);
|
||||
--bs-form-control-disabled-bg: var(--bs-secondary-bg);
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-breakpoint-xs: 0;
|
||||
--bs-breakpoint-sm: 576px;
|
||||
--bs-breakpoint-md: 768px;
|
||||
--bs-breakpoint-lg: 992px;
|
||||
--bs-breakpoint-xl: 1200px;
|
||||
--bs-breakpoint-xxl: 1400px;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
--bs-body-color: #adb5bd;
|
||||
--bs-body-color-rgb: 173, 181, 189;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #f8f9fa;
|
||||
--bs-emphasis-color-rgb: 248, 249, 250;
|
||||
--bs-secondary-color: rgba(173, 181, 189, 0.75);
|
||||
--bs-secondary-color-rgb: 173, 181, 189;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(173, 181, 189, 0.5);
|
||||
--bs-tertiary-color-rgb: 173, 181, 189;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-primary-text: #6ea8fe;
|
||||
--bs-secondary-text: #dee2e6;
|
||||
--bs-success-text: #75b798;
|
||||
--bs-info-text: #6edff6;
|
||||
--bs-warning-text: #ffda6a;
|
||||
--bs-danger-text: #ea868f;
|
||||
--bs-light-text: #f8f9fa;
|
||||
--bs-dark-text: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #212529;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #495057;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #055160;
|
||||
--bs-warning-border-subtle: #664d03;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: #fff;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #9ec5fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 158, 197, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color, inherit);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: right;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
|
@ -0,0 +1,8 @@
|
|||
@import 'bootstrap/bootstrap.css';
|
||||
@import 'utils';
|
||||
|
||||
:root {
|
||||
--primary-color: #eaa261;
|
||||
--primary-color-hover: #f1b27c;
|
||||
--bg-color-dialog: #7f7f7f7f;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.flex-c {
|
||||
@apply flex justify-center items-center;
|
||||
}
|
||||
|
||||
.flex-ac {
|
||||
@apply flex justify-around items-center;
|
||||
}
|
||||
|
||||
.flex-bc {
|
||||
@apply flex justify-between items-center;
|
||||
}
|
||||
|
||||
.navbar-bg-hover {
|
||||
@apply dark:text-white dark:hover:!bg-[#242424];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* 选中文字颜色 */
|
||||
*::selection {
|
||||
color: #1f1f1f;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
/*定义滚动条高宽及背景高宽分别对应横竖滚动条的尺寸*/
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/*定义滚动条轨道内阴影+圆角*/
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px #ccc;
|
||||
border-radius: 5px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/*定义滑块内阴影+圆角*/
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: inset 0 0 6px #ccc;
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.thumb {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hover-text {
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: var(--bs-link-hover-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标移入,显示手指+下划线
|
||||
.hover-text-pointer-underline {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
text-decoration: none;
|
||||
color: var(--bs-link-hover-color) !important;
|
||||
}
|
||||
|
||||
.img-hover {
|
||||
transition: all 0.5s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.2);
|
||||
transform-origin: center;
|
||||
}
|
||||
}
|
||||
|
||||
.none-select {
|
||||
-webkit-user-drag: none; /* Safari */
|
||||
user-drag: none; /* 其他浏览器 */
|
||||
-moz-user-select: none; /* 禁止选择,针对 Firefox */
|
||||
-webkit-user-select: none; /* 禁止选择,针对 Safari 和 Chrome */
|
||||
-ms-user-select: none; /* 禁止选择,针对 IE/Edge */
|
||||
user-select: none; /* 其他浏览器 */
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.5303 6.53033C18.8232 6.23744 18.8232 5.76256 18.5303 5.46967C18.2374 5.17678 17.7626 5.17678 17.4697 5.46967L12 10.9393L6.53033 5.46967C6.23744 5.17678 5.76256 5.17678 5.46967 5.46967C5.17678 5.76256 5.17678 6.23744 5.46967 6.53033L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0607L17.4697 18.5303C17.7626 18.8232 18.2374 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53033Z" fill="currentColor"/>
|
||||
</svg>
|
After Width: | Height: | Size: 645 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680886419224" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6634" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M768 64q59.008 0.992 106.016 32t70.016 85.504 12.512 110.016-51.488 98.016-96.512 54.496-110.496-8.992l-218.016 290.016v171.008h96q14.016 0 23.008 8.992t8.992 23.008-8.992 23.008-23.008 8.992h-256q-14.016 0-23.008-8.992t-8.992-23.008 8.992-23.008 23.008-8.992h96v-171.008L77.024 274.048q-12.992-18.016-12.992-39.008v-11.008q0-12.992 8.992-22.016T96.032 192h72L102.016 108.992q-8-11.008-6.496-24T108.032 64t23.488-6.496 21.504 11.488l96 123.008h338.016q20.992-58.016 70.016-92.512T768.064 64z m-111.008 128H800q14.016 0.992 23.008 10.016t8.992 22.016v11.008q0 20.992-12.992 38.016l-80 108q48.992 10.016 91.008-12.992t58.016-71.008-3.008-92-64.992-64.512-91.488-6.016-71.488 58.496v-0.992zM299.008 256l128.992 166.016q8 11.008 6.496 23.488t-12 20.512-23.008 7.008-21.504-11.008L217.984 256H143.968l304 404.992L751.968 256H298.976z" p-id="6635"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1681139654009" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2528" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M433.834667 337.706667a21.333333 21.333333 0 0 1 1.493333-32.768 29.397333 29.397333 0 0 1 37.461333 0.938666l202.709334 190.037334a21.077333 21.077333 0 0 1 1.365333 30.421333c-0.341333 0.426667-204.117333 191.573333-204.117333 191.573333a29.354667 29.354667 0 0 1-37.632 1.152 21.333333 21.333333 0 0 1-1.28-32.938666l185.813333-174.293334-185.813333-174.122666z" fill="#707070" p-id="2529"></path></svg>
|
After Width: | Height: | Size: 737 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1683095054996" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14355" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M258.048 568.832l253.952 279.04 253.952-279.04c22.016-24.064 13.312-43.52-18.944-43.52l-117.248 0 0-322.56c0-32.76800001-26.112-58.88000001-58.368-58.88l-117.248 0c-32.25599999 0-58.36799999 26.112-58.88 58.368l0 323.072-117.248 0c-32.76800001 0-41.47199999 19.456-19.968 43.52z" p-id="14356" fill="#D03050"></path></svg>
|
After Width: | Height: | Size: 653 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680624798338" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2733" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M392.533333 806.4L85.333333 503.466667l59.733334-59.733334 247.466666 247.466667L866.133333 213.333333l59.733334 59.733334L392.533333 806.4z" fill="#ffffff" p-id="2734"></path></svg>
|
After Width: | Height: | Size: 513 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1681015819371" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="30341" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M626.504285 375.563329a26.383253 26.383253 0 0 1-25.98523-26.724415c0-73.918596-58.338831-134.020101-129.983009-134.020101a26.383253 26.383253 0 0 1-25.985229-26.724416c0-14.783719 11.656394-26.838136 25.985229-26.838136 71.644178 0 129.983008-60.101505 129.983009-133.963241 0-14.783719 11.656394-26.781276 25.98523-26.781276 14.385696 0 25.98523 11.997557 25.985229 26.781276 0 73.861736 58.338831 133.963241 129.983009 133.963241 14.328836 0 25.98523 11.997557 25.985229 26.781276s-11.656394 26.781276-25.985229 26.781276c-71.644178 0-129.983008 60.158365-129.983009 133.96324 0 14.783719-11.599534 26.781276-25.985229 26.781276zM564.185222 188.037537c25.473485 15.920928 46.966739 37.925926 62.319063 64.252318 15.352324-26.269532 36.845577-48.33139 62.375923-64.252318a186.729746 186.729746 0 0 1-62.375923-64.252318c-15.352324 26.269532-36.788717 48.38825-62.319063 64.252318zM106.629111 536.307846a26.383253 26.383253 0 0 1-25.98523-26.724415 26.383253 26.383253 0 0 0-25.985229-26.838137A26.383253 26.383253 0 0 1 28.673422 455.964018c0-14.783719 11.656394-26.781276 25.98523-26.781276a26.383253 26.383253 0 0 0 25.985229-26.838137c0-14.783719 11.656394-26.724416 25.98523-26.724415 14.385696 0 26.04209 11.940696 26.04209 26.724415s11.599534 26.838136 25.98523 26.838137c14.328836 0 25.98523 11.940696 25.985229 26.724416s-11.656394 26.838136-25.985229 26.838136a26.383253 26.383253 0 0 0-25.98523 26.781276c0 14.783719-11.656394 26.781276-26.04209 26.781276zM972.102152 854.555833l-550.40924-567.239935a76.420456 76.420456 0 0 0-110.309289 0l-30.420346 31.443833c-14.726859 15.124882-22.744183 35.253484-22.744183 56.860459 0 21.493253 8.074185 41.621856 22.744183 56.860459l550.35238 567.183075a76.420456 76.420456 0 0 0 110.309289 0l30.477206-31.443834c14.669998-15.124882 22.744183-35.253484 22.744184-56.860459 0-21.493253-8.131046-41.678716-22.744184-56.860458zM342.656875 334.73752a25.587206 25.587206 0 0 1 36.788717 0l74.771503 77.102782-53.27825 50.605808L326.053621 385.400189a27.406741 27.406741 0 0 1 0-37.869066l16.489533-12.736742z m567.012494 617.618302a25.416625 25.416625 0 0 1-36.674996 0L434.259074 500.201455l54.017436-50.890111 438.735299 452.211228a27.406741 27.406741 0 0 1 0 37.869066l-17.34244 12.964184zM210.62689 268.438225a26.383253 26.383253 0 0 1-25.98523-26.838136c0-44.294297-34.969182-80.343828-78.012549-80.343828a26.383253 26.383253 0 0 1-25.98523-26.781276c0-14.783719 11.656394-26.781276 25.98523-26.781276 43.043367 0 78.012549-36.106391 78.012549-80.400689 0-14.783719 11.656394-26.781276 25.98523-26.781276s25.98523 11.997557 25.98523 26.781276c0 44.351158 34.969182 80.400689 78.012549 80.400689 14.328836 0 25.98523 11.940696 25.985229 26.724415s-11.656394 26.838136-25.985229 26.838137c-43.043367 0-78.012549 36.049531-78.012549 80.343828 0 14.783719-11.656394 26.838136-25.98523 26.838136z m-26.098951-133.96324c9.89372 7.676162 18.65023 16.716975 26.098951 26.894997a134.190682 134.190682 0 0 1 26.09895-26.894997 134.190682 134.190682 0 0 1-26.09895-26.894997 134.190682 134.190682 0 0 1-26.098951 26.894997zM210.62689 804.234327a26.383253 26.383253 0 0 1-25.98523-26.781276c0-44.351158-34.969182-80.400689-78.012549-80.400688a26.383253 26.383253 0 0 1-25.98523-26.724416c0-14.783719 11.656394-26.838136 25.98523-26.838136 43.043367 0 78.012549-36.049531 78.012549-80.400689 0-14.783719 11.656394-26.724416 25.98523-26.724415s25.98523 11.940696 25.98523 26.724415c0 44.351158 34.969182 80.400689 78.012549 80.400689 14.328836 0 25.98523 11.997557 25.985229 26.781276s-11.656394 26.781276-25.985229 26.781276c-43.043367 0-78.012549 36.049531-78.012549 80.400688 0 14.783719-11.656394 26.781276-25.98523 26.781276z m-26.098951-133.96324c9.89372 7.676162 18.65023 16.716975 26.098951 26.894997a134.190682 134.190682 0 0 1 26.09895-26.894997 134.190682 134.190682 0 0 1-26.09895-26.894997 134.190682 134.190682 0 0 1-26.098951 26.894997z" fill="#001529" p-id="30342"></path></svg>
|
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1679578965190" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15232" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M335.22 240.91c0-57.08 10.68-111.66 30.15-161.87-167.51 64.86-286.3 227.51-286.3 417.92 0 247.42 200.58 448 448 448 190.34 0 352.95-118.71 417.85-286.13-50.16 19.42-104.69 30.08-161.71 30.08-247.41 0-447.99-200.57-447.99-448z" fill="#FFD500" p-id="15233"></path></svg>
|
After Width: | Height: | Size: 600 B |
|
@ -0,0 +1,8 @@
|
|||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08337 6.66699C7.77373 6.66699 8.33337 6.10735 8.33337 5.41699C8.33337 4.72664 7.77373 4.16699 7.08337 4.16699C6.39302 4.16699 5.83337 4.72664 5.83337 5.41699C5.83337 6.10735 6.39302 6.66699 7.08337 6.66699Z" fill="#666666"/>
|
||||
<path d="M12.9167 6.66699C13.6071 6.66699 14.1667 6.10735 14.1667 5.41699C14.1667 4.72664 13.6071 4.16699 12.9167 4.16699C12.2264 4.16699 11.6667 4.72664 11.6667 5.41699C11.6667 6.10735 12.2264 6.66699 12.9167 6.66699Z" fill="#666666"/>
|
||||
<path d="M8.33337 10.0003C8.33337 10.6907 7.77373 11.2503 7.08337 11.2503C6.39302 11.2503 5.83337 10.6907 5.83337 10.0003C5.83337 9.30997 6.39302 8.75033 7.08337 8.75033C7.77373 8.75033 8.33337 9.30997 8.33337 10.0003Z" fill="#666666"/>
|
||||
<path d="M12.9167 11.2503C13.6071 11.2503 14.1667 10.6907 14.1667 10.0003C14.1667 9.30997 13.6071 8.75033 12.9167 8.75033C12.2264 8.75033 11.6667 9.30997 11.6667 10.0003C11.6667 10.6907 12.2264 11.2503 12.9167 11.2503Z" fill="#666666"/>
|
||||
<path d="M8.33337 14.5837C8.33337 15.274 7.77373 15.8337 7.08337 15.8337C6.39302 15.8337 5.83337 15.274 5.83337 14.5837C5.83337 13.8933 6.39302 13.3337 7.08337 13.3337C7.77373 13.3337 8.33337 13.8933 8.33337 14.5837Z" fill="#666666"/>
|
||||
<path d="M12.9167 15.8337C13.6071 15.8337 14.1667 15.274 14.1667 14.5837C14.1667 13.8933 13.6071 13.3337 12.9167 13.3337C12.2264 13.3337 11.6667 13.8933 11.6667 14.5837C11.6667 15.274 12.2264 15.8337 12.9167 15.8337Z" fill="#666666"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1631454216260" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2219" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M697.652 256c-23.565 0-42.667-19.103-42.667-42.667s19.102-42.666 42.667-42.666h124.651c40.288 0 73.697 31.956 73.697 72.347v85.783c0 23.564-19.103 42.667-42.667 42.667s-42.666-19.103-42.666-42.667V256H697.652z m113.015 597.333V496.565c0-23.564 19.102-42.666 42.666-42.666C876.897 453.899 896 473 896 496.565V866.32c0 40.391-33.41 72.348-73.697 72.348H201.697c-40.288 0-73.697-31.957-73.697-72.348V243.014c0-40.39 33.41-72.347 73.697-72.347h124.727c23.564 0 42.667 19.102 42.667 42.666 0 23.564-19.103 42.667-42.667 42.667h-113.09v597.333h597.333zM368.485 541.418c-23.564 0-42.667-19.102-42.667-42.666 0-23.564 19.103-42.667 42.667-42.667h320c23.564 0 42.667 19.103 42.667 42.667s-19.103 42.666-42.667 42.666h-320z m58.182-370.751c-23.564 0-42.667 19.102-42.667 42.666C384 236.897 403.103 256 426.667 256h170.666C620.897 256 640 236.897 640 213.333s-19.103-42.666-42.667-42.666H426.667z m0-85.334h170.666c70.693 0 128 57.308 128 128 0 70.693-57.307 128-128 128H426.667c-70.693 0-128-57.307-128-128 0-70.692 57.307-128 128-128zM368.485 696.57c-23.564 0-42.667-19.103-42.667-42.667s19.103-42.666 42.667-42.666h320c23.564 0 42.667 19.102 42.667 42.666 0 23.564-19.103 42.667-42.667 42.667h-320z" p-id="2220" fill="#f49776"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1683094815057" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14060" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M765.792 455.168L512.032 176l-253.76 279.168c-21.856 24.064-13.312 43.52 19.04 43.52H394.72V821.28c0 32.544 26.24 58.752 58.624 58.752h117.44a58.56 58.56 0 0 0 58.624-58.752V498.656h117.408c32.192 0 40.832-19.456 18.976-43.488z" p-id="14061" fill="#18A058"></path></svg>
|
After Width: | Height: | Size: 602 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1631454148586" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1906" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M826.666667 644.266667A341.333333 341.333333 0 0 0 342.613333 215.594667l-42.325333-74.112A426.666667 426.666667 0 0 1 900.992 687.36l57.258667 33.024-177.706667 94.549333-7.04-201.130666 53.162667 30.677333zM197.333333 379.733333A341.333333 341.333333 0 0 0 681.386667 808.405333l42.325333 74.112A426.666667 426.666667 0 0 1 123.008 336.64L65.706667 303.658667 243.2 209.066667l7.253333 201.258666L197.290667 379.733333zM554.666667 577.536h128v85.333333h-128v85.333334h-85.333334v-85.333334H341.333333v-85.333333h128v-42.666667H341.333333v-85.333333h110.336L361.130667 358.997333 421.546667 298.666667 512 389.162667 602.496 298.666667l60.373333 60.330666-90.538666 90.538667H682.666667v85.333333h-128v42.666667z" p-id="1907" fill="#b37feb"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1679577781791" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2924" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M501.48 493.55m-233.03 0a233.03 233.03 0 1 0 466.06 0 233.03 233.03 0 1 0-466.06 0Z" fill="#F9C626" p-id="2925"></path><path d="M501.52 185.35H478.9c-8.28 0-15-6.72-15-15V87.59c0-8.28 6.72-15 15-15h22.62c8.28 0 15 6.72 15 15v82.76c0 8.28-6.72 15-15 15zM281.37 262.76l-16 16c-5.86 5.86-15.36 5.86-21.21 0l-58.52-58.52c-5.86-5.86-5.86-15.36 0-21.21l16-16c5.86-5.86 15.36-5.86 21.21 0l58.52 58.52c5.86 5.86 5.86 15.35 0 21.21zM185.76 478.48v22.62c0 8.28-6.72 15-15 15H88c-8.28 0-15-6.72-15-15v-22.62c0-8.28 6.72-15 15-15h82.76c8.28 0 15 6.72 15 15zM270.69 698.63l16 16c5.86 5.86 5.86 15.36 0 21.21l-58.52 58.52c-5.86 5.86-15.36 5.86-21.21 0l-16-16c-5.86-5.86-5.86-15.36 0-21.21l58.52-58.52c5.85-5.86 15.35-5.86 21.21 0zM486.41 794.24h22.62c8.28 0 15 6.72 15 15V892c0 8.28-6.72 15-15 15h-22.62c-8.28 0-15-6.72-15-15v-82.76c0-8.28 6.72-15 15-15zM706.56 709.31l16-16c5.86-5.86 15.36-5.86 21.21 0l58.52 58.52c5.86 5.86 5.86 15.36 0 21.21l-16 16c-5.86 5.86-15.36 5.86-21.21 0l-58.52-58.52c-5.86-5.85-5.86-15.35 0-21.21zM802.17 493.59v-22.62c0-8.28 6.72-15 15-15h82.76c8.28 0 15 6.72 15 15v22.62c0 8.28-6.72 15-15 15h-82.76c-8.28 0-15-6.72-15-15zM717.24 273.44l-16-16c-5.86-5.86-5.86-15.36 0-21.21l58.52-58.52c5.86-5.86 15.36-5.86 21.21 0l16 16c5.86 5.86 5.86 15.36 0 21.21l-58.52 58.52c-5.86 5.86-15.35 5.86-21.21 0z" fill="#F9C626" p-id="2926"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1631453917190" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1531" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M300.032 558.08V427.52c0-19.968 13.312-35.84 29.696-35.84s29.696 15.872 29.696 35.84V558.08c0 19.968-13.312 35.84-29.696 35.84s-29.696-15.872-29.696-35.84zM480.256 558.08V363.52c0-19.968 13.312-35.84 29.696-35.84 16.384 0 29.696 15.872 29.696 35.84v194.56c0 19.968-13.312 35.84-29.696 35.84-16.384 0-29.696-15.872-29.696-35.84zM660.48 558.08V299.52c0-19.968 13.312-35.84 29.696-35.84s29.696 15.872 29.696 35.84V558.08c0 19.968-13.312 35.84-29.696 35.84s-29.696-15.872-29.696-35.84z" p-id="1532" fill="#2d8cf0"></path><path d="M861.696 781.312H568.32v117.248h146.944c16.384 0 29.184 13.312 29.184 29.184 0 16.384-13.312 29.184-29.184 29.184H362.496c-16.384-1.024-28.672-14.848-27.648-30.72 1.024-14.848 12.8-27.136 27.648-27.648h146.944v-117.248H157.184c-65.024 0-117.248-52.736-117.248-117.248V194.048C39.936 129.024 92.16 76.8 157.184 76.8h704.512c65.024 0 117.248 52.736 117.248 117.248v470.016c0.512 64.512-52.224 117.248-117.248 117.248z m58.88-587.264c0-32.256-26.112-58.88-58.88-58.88H157.184c-32.256 0-58.88 26.112-58.88 58.88v470.016c0 32.256 26.112 58.88 58.88 58.88h704.512c32.256 0 58.88-26.112 58.88-58.88V194.048z" p-id="1533" fill="#2d8cf0"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |