Compare commits
244 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
cc00c8f03a | ||
|
c7b6a3fbec | ||
|
40c1e13b50 | ||
|
288d586dbc | ||
|
7d69992694 | ||
|
6c14bfe6a9 | ||
|
6773659e89 | ||
|
9455ad9a4f | ||
|
428d41b485 | ||
|
74772a1f03 | ||
|
1f3e6e4fac | ||
|
41b3bcb445 | ||
|
8e801dd790 | ||
|
d6b1530720 | ||
|
b632b7ffed | ||
|
1b45b71f20 | ||
|
149d22a4a4 | ||
|
83a2e01070 | ||
|
11d615f807 | ||
|
853745587d | ||
|
f29108aa14 | ||
|
abd02d1990 | ||
|
65ac69ef71 | ||
|
8998581b99 | ||
|
468b4bb0e1 | ||
|
88e535f63c | ||
|
13d0c4153a | ||
|
331b14e74d | ||
|
c29b887eb2 | ||
|
8a1ec938e7 | ||
|
c045e3fe4e | ||
|
811f820644 | ||
|
fe8cab3d1c | ||
|
78efd7793a | ||
|
82c4b09b94 | ||
|
a539112a0f | ||
|
22c05674f8 | ||
|
7dd7c71d01 | ||
|
22c90257de | ||
|
3d03d6ddb5 | ||
|
6fbde1eb57 | ||
|
0ee16e0228 | ||
|
af74046124 | ||
|
d823ee5684 | ||
|
f7ca2782b0 | ||
|
af8c133914 | ||
|
21b6fb697e | ||
|
3e0cc8c2c1 | ||
|
3540b75557 | ||
|
73ce53a388 | ||
|
f408ea017c | ||
|
c5ba63182e | ||
|
07325a4236 | ||
|
7240be8495 | ||
|
71a753f323 | ||
|
639c4458be | ||
|
1ad92a2d1b | ||
|
49f95c4e45 | ||
|
44ab07779e | ||
|
40ecc320a5 | ||
|
695ec7e50d | ||
|
85901d2d5e | ||
|
97e2ffddf4 | ||
|
907cf44cc1 | ||
|
d9324f07b5 | ||
|
d7f5bf3373 | ||
|
36f06bc899 | ||
|
182dac0d2e | ||
|
f4d37cf7f0 | ||
|
16dce9a4ce | ||
|
0f0cd0b759 | ||
|
472f93bfc1 | ||
|
77572855c3 | ||
|
19942625d5 | ||
|
dbd676095b | ||
|
ed9cd6ce39 | ||
|
ee434b465a | ||
|
2aba58c973 | ||
|
2c56233155 | ||
|
8d11a6affc | ||
|
f6b61418e5 | ||
|
7f9c98ab8d | ||
|
02992dc02d | ||
|
b32bca4984 | ||
|
c37d0ac788 | ||
|
35aeedf320 | ||
|
94ff787053 | ||
|
d0823b030b | ||
|
2d722db243 | ||
|
6143605297 | ||
|
e2d6554313 | ||
|
872bb84502 | ||
|
ee7eb3ac0d | ||
|
dd1132482e | ||
|
c33b5ebfef | ||
|
711a4ae34f | ||
|
d9cfeabb47 | ||
|
296b154be5 | ||
|
cec0f25c6b | ||
|
b18c49e9d2 | ||
|
f64bc91ce2 | ||
|
b60db89801 | ||
|
da407b6653 | ||
|
6a9a362caa | ||
|
aa2f78a86f | ||
|
a444731e9e | ||
|
1523c7b075 | ||
|
896e6f2eac | ||
|
8dcfbb29f9 | ||
|
750000ec66 | ||
|
a792bb5cb3 | ||
|
973ab14442 | ||
|
3fe4e92f4a | ||
|
9ce58073dd | ||
|
e2727e6fa1 | ||
|
73fa3d14c5 | ||
|
ea1a336535 | ||
|
69e39c142e | ||
|
718c36263e | ||
|
5c1b086cb4 | ||
|
414ccbe360 | ||
|
41147b34fa | ||
|
894b0f1c18 | ||
|
d214bb2f2a | ||
|
9518372fe0 | ||
|
afa0134fdd | ||
|
c6ed9b1558 | ||
|
0523f08382 | ||
|
8237adb9c0 | ||
|
65c21812bb | ||
|
c3c975ee11 | ||
|
833018a831 | ||
|
3eb7f6f593 | ||
|
efcfa576d5 | ||
|
487213b648 | ||
|
4ee0d94f1b | ||
|
5fa822f4d4 | ||
|
8e6e787543 | ||
|
9917b5e53c | ||
|
8f3e855f41 | ||
|
808051b29d | ||
|
906aed5e75 | ||
|
2d64a2e57c | ||
|
0c70a9e083 | ||
|
08d83ecbea | ||
|
4122685803 | ||
|
434ab1c560 | ||
|
ae99e57c52 | ||
|
e3c4a6ece6 | ||
|
c8717c25b8 | ||
|
e9656c6e76 | ||
|
fd78791229 | ||
|
de09f82586 | ||
|
c7762490de | ||
|
4558c24d1c | ||
|
d9ac7e4de0 | ||
|
6a5a357f50 | ||
|
44b022aefd | ||
|
0a46ea0844 | ||
|
39854a492b | ||
|
4c2f535a9b | ||
|
be45d83766 | ||
|
d28b9039bb | ||
|
8f6d6ce3cb | ||
|
07baac7cf8 | ||
|
7487ab79b3 | ||
|
a70e4161be | ||
|
095c432363 | ||
|
028096e53f | ||
|
44ab55d594 | ||
|
4b80a66114 | ||
|
cc0bb088ec | ||
|
3e4f9e2824 | ||
|
ebd16a4d1a | ||
|
84cb07baec | ||
|
0811ffa5ae | ||
|
3f822a7d76 | ||
|
a1c7e10574 | ||
|
50d7ccd82d | ||
|
e0233061d3 | ||
|
a0c405dadd | ||
|
60f912508b | ||
|
3590b65e22 | ||
|
92b8406444 | ||
|
e7ad08685e | ||
|
14c145eef1 | ||
|
518f7eed28 | ||
|
21e63998d0 | ||
|
38ee2a62cd | ||
|
716528206e | ||
|
b81143e55e | ||
|
0243b27505 | ||
|
909c12d3c6 | ||
|
01d0bcbfd0 | ||
|
ba07b695dd | ||
|
3d8befa376 | ||
|
97c92626cc | ||
|
55ddc9cab0 | ||
|
401f0c748d | ||
|
d5c751153c | ||
|
69d51318ff | ||
|
de5fb84215 | ||
|
c275f2632c | ||
|
e899914426 | ||
|
861c8b9852 | ||
|
a782461453 | ||
|
e8488e4d52 | ||
|
889c859865 | ||
|
3c8dd772f8 | ||
|
251b5b9664 | ||
|
41e46a5d80 | ||
|
5c75e9d958 | ||
|
7f4350aeb6 | ||
|
807448aec5 | ||
|
b9c5c34979 | ||
|
20347b7d65 | ||
|
dbeb595c0b | ||
|
c9d3e5a3fd | ||
|
5e276421ad | ||
|
219f87f467 | ||
|
b35ed8960d | ||
|
24010d05fb | ||
|
ec0776e268 | ||
|
cecce83bc3 | ||
|
4eb46ea3dd | ||
|
e8b534b84e | ||
|
46e1ae7825 | ||
|
60a55a776e | ||
|
bed4292ed3 | ||
|
6bed9ead38 | ||
|
3fb13ca9e7 | ||
|
2d6d179d66 | ||
|
eebb753884 | ||
|
bb1bbf2724 | ||
|
df56abe18d | ||
|
ca2dfa6185 | ||
|
bbfdcc8276 | ||
|
1715504789 | ||
|
9a90f18e77 | ||
|
21645537d5 | ||
|
e6c26fcb4a | ||
|
20911dd882 | ||
|
cd7ca8f4c7 | ||
|
ca707a456b |
@@ -1,45 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
types: [
|
|
||||||
{ value: 'feat', name: 'feat: 新增功能' },
|
|
||||||
{ value: 'fix', name: 'fix: 修复bug' },
|
|
||||||
{ value: 'docs', name: 'docs: 文档变更' },
|
|
||||||
{ value: 'style', name: 'style: 代码格式(不影响功能,例如空格、分号等格式修正)' },
|
|
||||||
{ value: 'refactor', name: 'refactor: 代码重构(不包括 bug 修复、功能新增)' },
|
|
||||||
{ value: 'perf', name: 'perf: 性能优化' },
|
|
||||||
{ value: 'test', name: 'test: 添加、修改测试用例' },
|
|
||||||
{ value: 'build', name: 'build: 构建流程、外部依赖变更(如升级 npm 包、修改 脚手架 配置等)' },
|
|
||||||
{ value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
|
|
||||||
{ value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)' },
|
|
||||||
{ value: 'revert', name: 'revert: 回滚 commit' }
|
|
||||||
],
|
|
||||||
scopes: [
|
|
||||||
['projects', '项目搭建'],
|
|
||||||
['components', '组件相关'],
|
|
||||||
['hooks', 'hook 相关'],
|
|
||||||
['utils', 'utils 相关'],
|
|
||||||
['types', 'ts类型相关'],
|
|
||||||
['styles', '样式相关'],
|
|
||||||
['deps', '项目依赖'],
|
|
||||||
['auth', '对 auth 修改'],
|
|
||||||
['other', '其他修改'],
|
|
||||||
['custom', '以上都不是?我要自定义']
|
|
||||||
].map(([value, description]) => {
|
|
||||||
return {
|
|
||||||
value,
|
|
||||||
name: `${value.padEnd(30)} (${description})`
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
messages: {
|
|
||||||
type: '确保本次提交遵循 Angular 规范!\n选择你要提交的类型:',
|
|
||||||
scope: '\n选择一个 scope(可选):',
|
|
||||||
customScope: '请输入自定义的 scope:',
|
|
||||||
subject: '填写简短精炼的变更描述:\n',
|
|
||||||
body: '填写更加详细的变更描述(可选)。使用 "|" 换行:\n',
|
|
||||||
breaking: '列举非兼容性重大的变更(可选):\n',
|
|
||||||
footer: '列举出所有变更的 ISSUES CLOSED(可选)。 例如: #31, #34:\n',
|
|
||||||
confirmCommit: '确认提交?'
|
|
||||||
},
|
|
||||||
allowBreakingChanges: ['feat', 'fix'],
|
|
||||||
subjectLimit: 100,
|
|
||||||
breaklineChar: '|'
|
|
||||||
}
|
|
13
.env
@@ -6,4 +6,15 @@ VITE_APP_TITLE=Soybean管理系统
|
|||||||
|
|
||||||
VITE_APP_DESC=SoybeanAdmin是一个中后台管理系统模版
|
VITE_APP_DESC=SoybeanAdmin是一个中后台管理系统模版
|
||||||
|
|
||||||
VITE_HTTP_PROXY=true
|
# 权限路由模式: static | dynamic
|
||||||
|
VITE_AUTH_ROUTE_MODE=dynamic
|
||||||
|
|
||||||
|
# 路由首页(根路由重定向), 用于static模式的权限路由,dynamic模式取决于后端返回的路由首页
|
||||||
|
VITE_ROUTE_HOME_PATH=/dashboard/analysis
|
||||||
|
|
||||||
|
# iconify图标作为组件的前缀
|
||||||
|
VITE_ICON_PREFFIX=icon
|
||||||
|
|
||||||
|
# 本地SVG图标作为组件的前缀, 请注意一定要包含 VITE_ICON_PREFFIX
|
||||||
|
# 格式 {VITE_ICON_PREFFIX}-{本地图标集合名称}
|
||||||
|
VITE_ICON_LOCAL_PREFFIX=icon-local
|
||||||
|
@@ -1,38 +1,36 @@
|
|||||||
/** 请求环境配置 */
|
/** 请求服务的环境配置 */
|
||||||
type ServiceEnv = Record<
|
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>;
|
||||||
EnvType,
|
|
||||||
{
|
|
||||||
/** 请求地址 */
|
|
||||||
url: string;
|
|
||||||
/** 代理地址 */
|
|
||||||
proxy: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
/** 请求的环境 */
|
/** 不同请求服务的环境配置 */
|
||||||
const serviceEnvConfig: ServiceEnv = {
|
const serviceEnv: ServiceEnv = {
|
||||||
dev: {
|
dev: {
|
||||||
url: 'http://localhost:8080',
|
url: 'http://localhost:8080',
|
||||||
proxy: '/api',
|
urlPattern: '/url-pattern',
|
||||||
|
secondUrl: 'http://localhost:8081',
|
||||||
|
secondUrlPattern: '/second-url-pattern'
|
||||||
},
|
},
|
||||||
test: {
|
test: {
|
||||||
url: 'http://localhost:8080',
|
url: 'http://localhost:8080',
|
||||||
proxy: '/api',
|
urlPattern: '/url-pattern',
|
||||||
|
secondUrl: 'http://localhost:8081',
|
||||||
|
secondUrlPattern: '/second-url-pattern'
|
||||||
},
|
},
|
||||||
prod: {
|
prod: {
|
||||||
url: 'http://localhost:8080',
|
url: 'http://localhost:8080',
|
||||||
proxy: '/api',
|
urlPattern: '/url-pattern',
|
||||||
},
|
secondUrl: 'http://localhost:8081',
|
||||||
|
secondUrlPattern: '/second-url-pattern'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取环境配置
|
* 获取当前环境模式下的请求服务的配置
|
||||||
* @param env 环境描述
|
* @param env 环境
|
||||||
*/
|
*/
|
||||||
export function getEnvConfig(env: ImportMetaEnv) {
|
export function getServiceEnvConfig(env: ImportMetaEnv) {
|
||||||
const { VITE_ENV_TYPE = 'dev' } = env;
|
const { VITE_SERVICE_ENV = 'dev' } = env;
|
||||||
const envConfig = {
|
|
||||||
http: serviceEnvConfig[VITE_ENV_TYPE],
|
const config = serviceEnv[VITE_SERVICE_ENV];
|
||||||
};
|
|
||||||
return envConfig;
|
return config;
|
||||||
}
|
}
|
||||||
|
@@ -1,2 +1 @@
|
|||||||
# 是否开启打包文件大小结果分析
|
VITE_HTTP_PROXY=Y
|
||||||
VITE_VISUALIZER=false
|
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
VITE_VISUALIZER=N
|
||||||
|
|
||||||
|
VITE_COMPRESS=N
|
||||||
|
|
||||||
|
# gzip | brotliCompress | deflate | deflateRaw
|
||||||
|
VITE_COMPRESS_TYPE=gzip
|
||||||
|
@@ -1,15 +1,3 @@
|
|||||||
*.sh
|
|
||||||
node_modules
|
|
||||||
lib
|
|
||||||
*.md
|
|
||||||
*.woff
|
|
||||||
*.ttf
|
|
||||||
.vscode
|
|
||||||
.idea
|
|
||||||
/dist/
|
|
||||||
/public
|
|
||||||
/docs
|
|
||||||
.vscode
|
|
||||||
.local
|
|
||||||
package.json
|
|
||||||
!.env-config.ts
|
!.env-config.ts
|
||||||
|
components.d.ts
|
||||||
|
router-page.d.ts
|
||||||
|
199
.eslintrc.js
@@ -1,34 +1,17 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
extends: ['soybeanjs-vue'],
|
||||||
browser: true,
|
overrides: [
|
||||||
es2021: true,
|
{
|
||||||
'vue/setup-compiler-macros': true,
|
files: ['./scripts/*.ts'],
|
||||||
},
|
rules: {
|
||||||
globals: {
|
'no-unused-expressions': 'off'
|
||||||
PROJECT_BUILD_TIME: 'readonly',
|
}
|
||||||
AMap: 'readonly',
|
}
|
||||||
BMap: 'readonly',
|
],
|
||||||
TMap: 'readonly',
|
settings: {
|
||||||
},
|
'import/core-modules': ['uno.css', '~icons/*', 'virtual:svg-icons-register']
|
||||||
parser: 'vue-eslint-parser',
|
},
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
plugins: ['vue', '@typescript-eslint'],
|
|
||||||
extends: [
|
|
||||||
'airbnb-base',
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:vue/vue3-recommended',
|
|
||||||
'plugin:prettier/recommended',
|
|
||||||
'@vue/eslint-config-typescript/recommended',
|
|
||||||
'@vue/eslint-config-prettier',
|
|
||||||
'@vue/typescript/recommended',
|
|
||||||
],
|
|
||||||
rules: {
|
rules: {
|
||||||
'import/extensions': 'off',
|
|
||||||
'import/no-extraneous-dependencies': 'off',
|
|
||||||
'import/order': [
|
'import/order': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
@@ -38,174 +21,106 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
pattern: 'vue',
|
pattern: 'vue',
|
||||||
group: 'external',
|
group: 'external',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'vue-router',
|
pattern: 'vue-router',
|
||||||
group: 'external',
|
group: 'external',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: 'vuex',
|
|
||||||
group: 'external',
|
|
||||||
position: 'before',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'pinia',
|
pattern: 'pinia',
|
||||||
group: 'external',
|
group: 'external',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'naive-ui',
|
||||||
|
group: 'external',
|
||||||
|
position: 'before'
|
||||||
},
|
},
|
||||||
// ui framework, such as "naive-ui"
|
|
||||||
// {
|
|
||||||
// pattern: 'naive-ui',
|
|
||||||
// group: 'external',
|
|
||||||
// position: 'before'
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
pattern: '@/config',
|
pattern: '@/config',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/settings',
|
pattern: '@/settings',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/enum',
|
pattern: '@/enum',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/plugins',
|
pattern: '@/plugins',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/layouts',
|
pattern: '@/layouts',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/views',
|
pattern: '@/views',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/components',
|
pattern: '@/components',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/router',
|
pattern: '@/router',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: '@/store',
|
|
||||||
group: 'internal',
|
|
||||||
position: 'before',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: '@/composables',
|
|
||||||
group: 'internal',
|
|
||||||
position: 'before',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: '@/hooks',
|
|
||||||
group: 'internal',
|
|
||||||
position: 'before',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/service',
|
pattern: '@/service',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: '@/store',
|
||||||
|
group: 'internal',
|
||||||
|
position: 'before'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: '@/context',
|
||||||
|
group: 'internal',
|
||||||
|
position: 'before'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: '@/composables',
|
||||||
|
group: 'internal',
|
||||||
|
position: 'before'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: '@/hooks',
|
||||||
|
group: 'internal',
|
||||||
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/utils',
|
pattern: '@/utils',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/assets',
|
pattern: '@/assets',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: '@/**',
|
pattern: '@/**',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'before',
|
position: 'before'
|
||||||
},
|
}
|
||||||
{
|
|
||||||
pattern: '@/interface',
|
|
||||||
group: 'internal',
|
|
||||||
position: 'before',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
pathGroupsExcludedImportTypes: [
|
|
||||||
'vue',
|
|
||||||
'vue-router',
|
|
||||||
'vuex',
|
|
||||||
'pinia',
|
|
||||||
// 'naive-ui'
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'import/no-unresolved': 'off',
|
|
||||||
'import/prefer-default-export': 'off',
|
|
||||||
'max-classes-per-file': 'off',
|
|
||||||
'no-param-reassign': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
props: true,
|
|
||||||
ignorePropertyModificationsFor: ['state', 'acc', 'e'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-plusplus': 'off',
|
|
||||||
'no-shadow': 'off',
|
|
||||||
'no-unused-vars': 'off',
|
|
||||||
'no-use-before-define': 'off',
|
|
||||||
'vue/multi-word-component-names': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignores: ['index'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
'@typescript-eslint/ban-types': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
types: {
|
|
||||||
'{}': {
|
|
||||||
message: 'Use object instead',
|
|
||||||
fixWith: 'object',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@typescript-eslint/no-empty-interface': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
allowSingleExtends: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-shadow': 'error',
|
|
||||||
'@typescript-eslint/no-unused-vars': ['warn', { ignoreRestSiblings: true, varsIgnorePattern: '^_' }],
|
|
||||||
'@typescript-eslint/no-use-before-define': ['error', { classes: true, functions: false, typedefs: false }],
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.vue'],
|
|
||||||
rules: {
|
|
||||||
'no-undef': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['*.html'],
|
|
||||||
rules: {
|
|
||||||
'vue/comment-directive': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
|
pathGroupsExcludedImportTypes: ['vue', 'vue-router', 'pinia', 'naive-ui']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
16
.gitattributes
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
"*.vue" eol=lf
|
||||||
|
"*.js" eol=lf
|
||||||
|
"*.ts" eol=lf
|
||||||
|
"*.jsx" eol=lf
|
||||||
|
"*.tsx" eol=lf
|
||||||
|
"*.cjs" eol=lf
|
||||||
|
"*.cts" eol=lf
|
||||||
|
"*.mjs" eol=lf
|
||||||
|
"*.mts" eol=lf
|
||||||
|
"*.json" eol=lf
|
||||||
|
"*.html" eol=lf
|
||||||
|
"*.css" eol=lf
|
||||||
|
"*.less" eol=lf
|
||||||
|
"*.scss" eol=lf
|
||||||
|
"*.sass" eol=lf
|
||||||
|
"*.styl" eol=lf
|
5
.gitignore
vendored
@@ -28,3 +28,8 @@ stats.html
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
/src/typings/components.d.ts
|
||||||
|
/src/typings/router-page.d.ts
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
npx --no-install commitlint --edit
|
pnpm soybean git-commit-verify
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
npm run lint && npm run typecheck
|
pnpm lint && pnpm typecheck
|
||||||
|
4
.npmrc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
registry=https://registry.npmmirror.com/
|
||||||
|
shamefully-hoist=true
|
||||||
|
strict-peer-dependencies=false
|
||||||
|
auto-install-peers=true
|
@@ -1,27 +0,0 @@
|
|||||||
module.exports = { // https://prettier.io/docs/en/options.html
|
|
||||||
arrowParens: 'always',
|
|
||||||
bracketSameLine: false,
|
|
||||||
bracketSpacing: true,
|
|
||||||
embeddedLanguageFormatting: 'auto',
|
|
||||||
htmlWhitespaceSensitivity: 'css',
|
|
||||||
insertPragma: false,
|
|
||||||
jsxSingleQuote: false,
|
|
||||||
printWidth: 120,
|
|
||||||
proseWrap: 'preserve',
|
|
||||||
quoteProps: 'as-needed',
|
|
||||||
requirePragma: false,
|
|
||||||
semi: true,
|
|
||||||
singleQuote: true,
|
|
||||||
tabWidth: 2,
|
|
||||||
trailingComma: 'es5',
|
|
||||||
useTabs: false,
|
|
||||||
vueIndentScriptAndStyle: false,
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: '*.html',
|
|
||||||
options: {
|
|
||||||
parser: 'html',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
45
.vscode/extensions.json
vendored
@@ -1,36 +1,25 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"formulahendry.auto-close-tag",
|
|
||||||
"formulahendry.auto-complete-tag",
|
|
||||||
"steoates.autoimport",
|
|
||||||
"formulahendry.auto-rename-tag",
|
|
||||||
"coenraads.bracket-pair-colorizer-2",
|
|
||||||
"naumovs.color-highlight",
|
|
||||||
"pranaygp.vscode-css-peek",
|
|
||||||
"mikestead.dotenv",
|
|
||||||
"editorconfig.editorconfig",
|
|
||||||
"dsznajder.es7-react-js-snippets",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"miguelsolorio.fluent-icons",
|
|
||||||
"mhutchie.git-graph",
|
|
||||||
"eamodio.gitlens",
|
|
||||||
"lokalise.i18n-ally",
|
|
||||||
"afzalsayed96.icones",
|
"afzalsayed96.icones",
|
||||||
"antfu.iconify",
|
"antfu.iconify",
|
||||||
"kisstkondoros.vscode-gutter-preview",
|
"antfu.unocss",
|
||||||
"xabikos.javascriptsnippets",
|
|
||||||
"whtouche.vscode-js-console-utils",
|
|
||||||
"ritwickdey.liveserver",
|
|
||||||
"yzhang.markdown-all-in-one",
|
|
||||||
"pkief.material-icon-theme",
|
|
||||||
"zhuangtongfa.material-theme",
|
|
||||||
"jimdong.naive-ui-snippets",
|
|
||||||
"christian-kohler.path-intellisense",
|
"christian-kohler.path-intellisense",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"eamodio.gitlens",
|
||||||
|
"editorconfig.editorconfig",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"johnsoncodehk.volar",
|
"formulahendry.auto-complete-tag",
|
||||||
"johnsoncodehk.vscode-typescript-vue-plugin",
|
"formulahendry.auto-close-tag",
|
||||||
"dariofuzinato.vue-peek",
|
"formulahendry.auto-rename-tag",
|
||||||
"wscats.vue",
|
"kisstkondoros.vscode-gutter-preview",
|
||||||
"voorjaar.windicss-intellisense"
|
"lokalise.i18n-ally",
|
||||||
|
"mhutchie.git-graph",
|
||||||
|
"mikestead.dotenv",
|
||||||
|
"naumovs.color-highlight",
|
||||||
|
"pkief.material-icon-theme",
|
||||||
|
"steoates.autoimport",
|
||||||
|
"vue.volar",
|
||||||
|
"whtouche.vscode-js-console-utils",
|
||||||
|
"zhuangtongfa.material-theme"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
118
.vscode/settings.json
vendored
@@ -1,66 +1,43 @@
|
|||||||
{
|
{
|
||||||
"editor.quickSuggestions": {
|
|
||||||
"strings": true
|
|
||||||
},
|
|
||||||
"workbench.iconTheme": "material-icon-theme",
|
|
||||||
"workbench.colorTheme": "One Dark Pro",
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.fontLigatures": true,
|
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": true
|
"source.fixAll.eslint": true
|
||||||
},
|
},
|
||||||
"editor.bracketPairColorization.enabled": true,
|
"editor.fontLigatures": true,
|
||||||
|
"editor.formatOnSave": false,
|
||||||
"editor.guides.bracketPairs": "active",
|
"editor.guides.bracketPairs": "active",
|
||||||
"git.enableSmartCommit": true,
|
"editor.quickSuggestions": {
|
||||||
"path-intellisense.mappings": {
|
"strings": true
|
||||||
"@": "${workspaceFolder}/src",
|
|
||||||
"~@": "${workspaceFolder}/src",
|
|
||||||
},
|
},
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"eslint.alwaysShowStatus": true,
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact",
|
||||||
|
"vue",
|
||||||
|
"html",
|
||||||
|
"json",
|
||||||
|
"jsonc",
|
||||||
|
"json5",
|
||||||
|
"yaml",
|
||||||
|
"yml",
|
||||||
|
"markdown"
|
||||||
|
],
|
||||||
|
"files.associations": {
|
||||||
|
"*.env.*": "dotenv"
|
||||||
|
},
|
||||||
|
"files.eol": "\n",
|
||||||
|
"git.enableSmartCommit": true,
|
||||||
"gutterpreview.paths": {
|
"gutterpreview.paths": {
|
||||||
"@": "/src",
|
"@": "/src",
|
||||||
"~@": "/src"
|
"~@": "/src"
|
||||||
},
|
},
|
||||||
"terminal.integrated.cursorStyle": "line",
|
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"],
|
||||||
"files.associations": {
|
|
||||||
"*.env.*": "dotenv"
|
|
||||||
},
|
|
||||||
"[jsonc]": {
|
|
||||||
"editor.defaultFormatter": "vscode.json-language-features"
|
|
||||||
},
|
|
||||||
"[json]": {
|
|
||||||
"editor.defaultFormatter": "vscode.json-language-features"
|
|
||||||
},
|
|
||||||
"[javascript]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"javascript.updateImportsOnFileMove.enabled": "always",
|
|
||||||
"[javascriptreact]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"terminal.integrated.fontSize": 14,
|
|
||||||
"terminal.integrated.fontWeight": 500,
|
|
||||||
"i18n-ally.displayLanguage": "zh",
|
|
||||||
"[html]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[typescript]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[vue]": {
|
|
||||||
"editor.defaultFormatter": "johnsoncodehk.volar"
|
|
||||||
},
|
|
||||||
"terminal.integrated.tabs.enabled": true,
|
|
||||||
"[typescriptreact]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[markdown]": {
|
|
||||||
"editor.defaultFormatter": "yzhang.markdown-all-in-one"
|
|
||||||
},
|
|
||||||
"vue3snippets.enable-compile-vue-file-on-did-save-code": false,
|
|
||||||
"editor.formatOnSave": false,
|
|
||||||
"material-icon-theme.activeIconPack": "angular",
|
"material-icon-theme.activeIconPack": "angular",
|
||||||
"material-icon-theme.files.associations": {},
|
"material-icon-theme.files.associations": {},
|
||||||
"material-icon-theme.folders.associations": {
|
"material-icon-theme.folders.associations": {
|
||||||
|
"src-tauri": "src",
|
||||||
"enum": "typescript",
|
"enum": "typescript",
|
||||||
"enums": "typescript",
|
"enums": "typescript",
|
||||||
"store": "context",
|
"store": "context",
|
||||||
@@ -69,6 +46,45 @@
|
|||||||
"composables": "hook",
|
"composables": "hook",
|
||||||
"directive": "tools",
|
"directive": "tools",
|
||||||
"directives": "tools",
|
"directives": "tools",
|
||||||
"business": "core"
|
"business": "core",
|
||||||
|
"request": "api",
|
||||||
|
"adapter": "middleware"
|
||||||
|
},
|
||||||
|
"path-intellisense.mappings": {
|
||||||
|
"@": "${workspaceFolder}/src",
|
||||||
|
"~@": "${workspaceFolder}/src"
|
||||||
|
},
|
||||||
|
"terminal.integrated.cursorStyle": "line",
|
||||||
|
"terminal.integrated.fontSize": 14,
|
||||||
|
"terminal.integrated.fontWeight": 500,
|
||||||
|
"terminal.integrated.tabs.enabled": true,
|
||||||
|
"workbench.iconTheme": "material-icon-theme",
|
||||||
|
"workbench.colorTheme": "One Dark Pro",
|
||||||
|
"[html]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[jsonc]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[markdown]": {
|
||||||
|
"editor.defaultFormatter": "yzhang.markdown-all-in-one"
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[typescriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[vue]": {
|
||||||
|
"editor.defaultFormatter": "Vue.volar"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
111
CHANGELOG.md
@@ -2,6 +2,117 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
### [0.9.7](https://github.com/honghuangdc/soybean-admin/compare/v0.9.6...v0.9.7) (2022-11-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **projects:** 全局搜索菜单及消息通知适配移动端 ([97e2ffd](https://github.com/honghuangdc/soybean-admin/commit/97e2ffddf4ac047133dc016a91ac07556e562d29))
|
||||||
|
* **projects:** 实现用户管理页面 ([472f93b](https://github.com/honghuangdc/soybean-admin/commit/472f93bfc111e8ca94adef823b8cc12e4f8cd2c6))
|
||||||
|
* **projects:** 适配移动端,修复Tab关闭图标的bug ([296b154](https://github.com/honghuangdc/soybean-admin/commit/296b154be5dfe410b3cfca9afaeeaf9c47de3e0c)), closes [#87](https://github.com/honghuangdc/soybean-admin/issues/87) [#106](https://github.com/honghuangdc/soybean-admin/issues/106) [#109](https://github.com/honghuangdc/soybean-admin/issues/109) [#111](https://github.com/honghuangdc/soybean-admin/issues/111)
|
||||||
|
* **projects:** 添加请求适配adapter层应用的示例页面 ([8d11a6a](https://github.com/honghuangdc/soybean-admin/commit/8d11a6affcfa37344011a6aaf3d6e005546f0e61))
|
||||||
|
* **projects:** 添加生产的主题配置缓存 ([718c362](https://github.com/honghuangdc/soybean-admin/commit/718c36263e451a39bca6da6c33657a09515ffbcc))
|
||||||
|
* **projects:** 添加系统管理的页面 ([c33b5eb](https://github.com/honghuangdc/soybean-admin/commit/c33b5ebfefbb3ae507141bd2e9414231fd1512d4))
|
||||||
|
* **projects:** 添加组件名称,调整vue文件里面的类型声明位置 ([f64bc91](https://github.com/honghuangdc/soybean-admin/commit/f64bc91ce285c7a9806ed0f6ae970d9b598fd0cb))
|
||||||
|
* **projects:** 添加provide、inject上下文示例 ([a444731](https://github.com/honghuangdc/soybean-admin/commit/a444731e9eef43022930c3550dcfc058e70a2941))
|
||||||
|
* **projects:** 系统消息组件代码优化 ([9518372](https://github.com/honghuangdc/soybean-admin/commit/9518372fe0431d4e08a5f40d1b2982691fbb4107))
|
||||||
|
* **projects:** 增加返回顶部功能 ([894b0f1](https://github.com/honghuangdc/soybean-admin/commit/894b0f1c182a36ad1774a8144bf50dd4e0b62a46))
|
||||||
|
* **projects:** 增加系统消息组件 ([afa0134](https://github.com/honghuangdc/soybean-admin/commit/afa0134fdd63c253e102bc129e275d16ca25508e))
|
||||||
|
* **projects:** add constant route page without login status[添加未登录可访问的固定路由示例页面] ([78efd77](https://github.com/honghuangdc/soybean-admin/commit/78efd7793a241811065caf56edf7e68aea58bc8c))
|
||||||
|
* **projects:** add pinia setup syntax example: setup-store[添加setup syntax的pinia示例setup-store] ([82c4b09](https://github.com/honghuangdc/soybean-admin/commit/82c4b09b9411390f97c2d10bb211c66ed9656b63))
|
||||||
|
* **projects:** import i18n [引入i18n] ([b632b7f](https://github.com/honghuangdc/soybean-admin/commit/b632b7ffed5c6d6ec15c23c8cce030bf669c554f))
|
||||||
|
* **projects:** new router system [新的路由系统] ([c7b6a3f](https://github.com/honghuangdc/soybean-admin/commit/c7b6a3fbecd1ba051833e4e47b75a06935f212c8))
|
||||||
|
* **projects:** refactor icon system, unify icon usage [重构图标系统,统一图标用法] ([811f820](https://github.com/honghuangdc/soybean-admin/commit/811f820644053606e50624c2f184f9669f3eff7e))
|
||||||
|
* **projects:** support constant route without login status[支持未登录状态下访问自定义的固定路由] ([a539112](https://github.com/honghuangdc/soybean-admin/commit/a539112a0f53183ee073d4eb9034ef48209fe30c))
|
||||||
|
* **projects:** useNaiveTable函数:类型部分 ([02992dc](https://github.com/honghuangdc/soybean-admin/commit/02992dc02d105cbfcebbea397438c68db1fa8177))
|
||||||
|
* **tabs:** 多页签增加关闭所有 ([8237adb](https://github.com/honghuangdc/soybean-admin/commit/8237adb9c0b187911df37d6d99fd84718bc3ea8f))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **deps:** decrease @types/node version to fix TS type error [降低@types/node版本修复TS的类型错误] ([149d22a](https://github.com/honghuangdc/soybean-admin/commit/149d22a4a491ca5fc6c52375046e9f1cb86ee76d))
|
||||||
|
* **projects:** 修复多个后端服务时的本地代理 ([2aba58c](https://github.com/honghuangdc/soybean-admin/commit/2aba58c973e5d0ea975443a8b22c9d94283d4fb9))
|
||||||
|
* **projects:** 修复构建后mockjs对xhr的影响问题 ([7757285](https://github.com/honghuangdc/soybean-admin/commit/77572855c3f7161697f42e6da36771c15707f0ab))
|
||||||
|
* **projects:** 修复图标的TS类型 ([dbd6760](https://github.com/honghuangdc/soybean-admin/commit/dbd676095b42aaebc783d5c89478306a453195a5))
|
||||||
|
* **projects:** 修复eslint规则 ([d7f5bf3](https://github.com/honghuangdc/soybean-admin/commit/d7f5bf3373e7884b8dc2c696a2c36e9cf27ad64b))
|
||||||
|
* **projects:** 修复import.meta.env的TS类型 ([1994262](https://github.com/honghuangdc/soybean-admin/commit/19942625d58e673126db5249488555de71d18457))
|
||||||
|
* **projects:** 修复tab不显示路由首页的问题 ([a792bb5](https://github.com/honghuangdc/soybean-admin/commit/a792bb5cb3c388ba3b93e17bab8f42d23cd5df4a))
|
||||||
|
* **projects:** 修复TS类型问题 ([16dce9a](https://github.com/honghuangdc/soybean-admin/commit/16dce9a4ce4d3aa822d70f6e5199eb9c86e33ad9))
|
||||||
|
* **projects:** add iconify json ([8a1ec93](https://github.com/honghuangdc/soybean-admin/commit/8a1ec938e7a26728919024e9f5b7b0af2b270aba))
|
||||||
|
* **svg-icon:** 自定义图标在Dropdown组件下hover状态无法显示图标 ([0523f08](https://github.com/honghuangdc/soybean-admin/commit/0523f0838246041bfc09130e21369bd777f63682))
|
||||||
|
* **utils:** 修复iconifyRender ([c37d0ac](https://github.com/honghuangdc/soybean-admin/commit/c37d0ac7887a3451b8558fc4aa6c05ed3b0ef74f))
|
||||||
|
|
||||||
|
### [0.9.6](https://github.com/honghuangdc/soybean-admin/compare/v0.9.5...v0.9.6) (2022-06-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **projects:** 本地svg动态渲染图标 ([c3c975e](https://github.com/honghuangdc/soybean-admin/commit/c3c975ee1142987b7ded0107bf91d0080d5651fe)), closes [#61](https://github.com/honghuangdc/soybean-admin/issues/61)
|
||||||
|
* **projects:** 上下结构,菜单支持横向滚动 ([808051b](https://github.com/honghuangdc/soybean-admin/commit/808051b29dd682e1cbcf0e211774efb9cc12713a))
|
||||||
|
* **projects:** 新增Antv G2图表示例 ([2d64a2e](https://github.com/honghuangdc/soybean-admin/commit/2d64a2e57c8d83c8d06f210eeefef8f31b3abeb9))
|
||||||
|
* **projects:** 增加设置当前Tab页签名称功能 ([487213b](https://github.com/honghuangdc/soybean-admin/commit/487213b64853765e2bd186474e4607572624a33e))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **projects:** 设置tab标题导致meta属性丢失 ([efcfa57](https://github.com/honghuangdc/soybean-admin/commit/efcfa576d52a7eab644f3b4c65af153442887fab))
|
||||||
|
* **projects:** 修复顶部菜单的位置失效问题 ([4ee0d94](https://github.com/honghuangdc/soybean-admin/commit/4ee0d94f1bde83c788fc0dcb084402359c04fb1b))
|
||||||
|
|
||||||
|
### [0.9.5](https://github.com/honghuangdc/soybean-admin/compare/v0.9.4...v0.9.5) (2022-06-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **projects:** 支持同一路由根据不同query和hash同时显示不同Tab ([4122685](https://github.com/honghuangdc/soybean-admin/commit/4122685803f8a0a485682d16cec74e27945adc47)), closes [#64](https://github.com/honghuangdc/soybean-admin/issues/64)
|
||||||
|
* **projects:** 动态路由根路由重定向只需取决于后端返回的路由首页 ([434ab1c](https://github.com/honghuangdc/soybean-admin/commit/434ab1c560b260f8a19895405eb1d3c3313052d7))
|
||||||
|
* **projects:** 补充更多的ECharts示例 ([c776249](https://github.com/honghuangdc/soybean-admin/commit/c7762490def77695bedf179ffc63e3e95d15e14d))
|
||||||
|
* **projects:** 添加百度地图、升级依赖 ([39854a4](https://github.com/honghuangdc/soybean-admin/commit/39854a492b9cce71e0c7ed52af9985cb4abd6a97))
|
||||||
|
* **projects:** 添加插件页面:图表 ([0a46ea0](https://github.com/honghuangdc/soybean-admin/commit/0a46ea08443f6b879434e925d440cf07e9494fcb))
|
||||||
|
* **projects:** 添加自动跟随系统主题设置 ([ba07b69](https://github.com/honghuangdc/soybean-admin/commit/ba07b695dd9dc5d3f8ebf57d0f2e69d624994962))
|
||||||
|
* **projects:** 添加antv g2图表示例 ([44b022a](https://github.com/honghuangdc/soybean-admin/commit/44b022aefd7dbb4c34886814cf04767450dec026))
|
||||||
|
* **projects:** 引入echarts替换antvG2plot ([e7ad086](https://github.com/honghuangdc/soybean-admin/commit/e7ad08685e8ac52a8906fc94e656192275f9764c))
|
||||||
|
* **route:** 路由meta新增activeMenu属性 ([ebd16a4](https://github.com/honghuangdc/soybean-admin/commit/ebd16a4d1ab1a95a27838a2d4f20cc1d1e7309ae))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **projects:** 修复@antv/g2生产环境报错 ([4558c24](https://github.com/honghuangdc/soybean-admin/commit/4558c24d1c1e1faa3326650fc16e6baf384509ac))
|
||||||
|
* **projects:** 修复插件不存在的错误提示 ([7165282](https://github.com/honghuangdc/soybean-admin/commit/716528206e9f63e873607d0afd59d83f6984e3fe))
|
||||||
|
* **projects:** 修复权限切换路由数据未更新的问题 ([60f9125](https://github.com/honghuangdc/soybean-admin/commit/60f912508b0e685957fb22ef0ed1f83272847263))
|
||||||
|
* **projects:** 修复页面切换时导致的溢出滚动条 ([e023306](https://github.com/honghuangdc/soybean-admin/commit/e0233061d3bca236b4c4bb462ce00f7ca186b9fa))
|
||||||
|
* **route:** 当为左侧混合菜单时activeMenu无效情况 ([3e4f9e2](https://github.com/honghuangdc/soybean-admin/commit/3e4f9e282442073447c5c24c33d65bc6130978ee))
|
||||||
|
|
||||||
|
### [0.9.4](https://github.com/honghuangdc/soybean-admin/compare/v0.9.3...v0.9.4) (2022-04-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **layouts:** 添加侧边栏/头部的反转模式来增加对比度 ([861c8b9](https://github.com/honghuangdc/soybean-admin/commit/861c8b9852e0097a1f6b79ac2c10d19add123bde))
|
||||||
|
* **layouts:** 添加侧边栏/头部的反转模式来增加对比度 ([3c8dd77](https://github.com/honghuangdc/soybean-admin/commit/3c8dd772f89d2b656a42c4f7164e581acdb2b1a5))
|
||||||
|
* **projects:** 插件方式按需引入naiveUI ([6bed9ea](https://github.com/honghuangdc/soybean-admin/commit/6bed9ead38af6d58f6cd9e520db848ae5cbfa4db))
|
||||||
|
* **projects:** 登录页背景图片位置适配移动端 ([24010d0](https://github.com/honghuangdc/soybean-admin/commit/24010d05fb1ff51cb5e5d94ffe310206a9638711))
|
||||||
|
* **projects:** 登录页面适配移动端 ([ec0776e](https://github.com/honghuangdc/soybean-admin/commit/ec0776e268cd3d1031e9ecd794abce271a675793))
|
||||||
|
* **projects:** 权限完善及权限示例页面 ([807448a](https://github.com/honghuangdc/soybean-admin/commit/807448aec5b041535fe4fbac90eca1138b2f439c))
|
||||||
|
* **projects:** 添加请求适配器的请求示例 ([bed4292](https://github.com/honghuangdc/soybean-admin/commit/bed4292ed380e77ac428ab057abc42eceb72af53))
|
||||||
|
* **projects:** 新增静态路由 ([ca2dfa6](https://github.com/honghuangdc/soybean-admin/commit/ca2dfa6185aa7a4e58184bcfef2a1246a52f88fd))
|
||||||
|
* **projects:** 引入unocss替换windicss ([c9d3e5a](https://github.com/honghuangdc/soybean-admin/commit/c9d3e5a3fdf59179dcfc122ab8369c492ea7832e))
|
||||||
|
* **projects:** HTML lang 修改为 zh-cmn-Hans ([b9c5c34](https://github.com/honghuangdc/soybean-admin/commit/b9c5c349790b1e83a7acd1f2c53a86c9221944ff))
|
||||||
|
* **projects:** HTML lang 修改为 zh-cmn-Hans ([dbeb595](https://github.com/honghuangdc/soybean-admin/commit/dbeb595c0b9fc11e7d166a7684af37cc971f1a11))
|
||||||
|
* **projects:** mock添加权限过滤 ([7f4350a](https://github.com/honghuangdc/soybean-admin/commit/7f4350aeb673dab59192584177a897aacebe4b28))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **projects:** 去除从环境文件引入端口号导致的错误 ([2d6d179](https://github.com/honghuangdc/soybean-admin/commit/2d6d179d669ea71cca3fe97ac840e4856bff4051))
|
||||||
|
* **projects:** 全局搜索弹窗弹出时动画闪屏问题 ([bb1bbf2](https://github.com/honghuangdc/soybean-admin/commit/bb1bbf272438f4ed440735118c6a9ec04c7d109f))
|
||||||
|
* **projects:** 添加.npmrc修复无法获取自动引入的全局组件声明类型 ([e8488e4](https://github.com/honghuangdc/soybean-admin/commit/e8488e4d5237e5e03ec07ff07d03115389d5b1ef))
|
||||||
|
* **projects:** 添加获取路由组件文件未找到时的错误提示 ([219f87f](https://github.com/honghuangdc/soybean-admin/commit/219f87f46758f328f26697f66d8583f49c0d41de))
|
||||||
|
* **projects:** 修复获取vite环境变量的方式 ([46e1ae7](https://github.com/honghuangdc/soybean-admin/commit/46e1ae7825b2b204ce3cdd63b3c64f39bff096d0))
|
||||||
|
* **projects:** 修复路由守卫的动态路由逻辑 ([e6c26fc](https://github.com/honghuangdc/soybean-admin/commit/e6c26fcb4ae085f9fd7d7eb9183ddba020d0b5da))
|
||||||
|
* **projects:** 修复样式 ([e899914](https://github.com/honghuangdc/soybean-admin/commit/e8999144266761b3b701442975c3c00251240d53))
|
||||||
|
* **projects:** 修复在新版vite下环境变量获取不到的问题 ([3fb13ca](https://github.com/honghuangdc/soybean-admin/commit/3fb13ca9e710549d2ddeb774fe08fabd27d5ae11))
|
||||||
|
* **projects:** 修复vite alias ([cd7ca8f](https://github.com/honghuangdc/soybean-admin/commit/cd7ca8f4c77ac8c753b753ba698a9573d6c37bf9))
|
||||||
|
|
||||||
### [0.9.3](https://github.com/honghuangdc/soybean-admin/compare/v0.9.2...v0.9.3) (2022-03-12)
|
### [0.9.3](https://github.com/honghuangdc/soybean-admin/compare/v0.9.2...v0.9.3) (2022-03-12)
|
||||||
|
|
||||||
|
|
||||||
|
16
Makefile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
ImageTag ?=v0.9.6
|
||||||
|
SoybeanAdminImg ?= soybeanjs/soybean-admin:$(ImageTag)
|
||||||
|
|
||||||
|
VERSION=$(shell git rev-parse --short HEAD)
|
||||||
|
|
||||||
|
soybean-admin: soybean-admin-build soybean-admin-push
|
||||||
|
|
||||||
|
soybean-admin-build:
|
||||||
|
docker build --build-arg version=$(VERSION) -t ${SoybeanAdminImg} -f docker/Dockerfile .
|
||||||
|
|
||||||
|
soybean-admin-push:
|
||||||
|
docker push ${SoybeanAdminImg}
|
||||||
|
|
||||||
|
# run tauri app:
|
||||||
|
run:
|
||||||
|
pnpm tauri dev
|
81
README.md
@@ -7,16 +7,16 @@
|
|||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
Soybean Admin 是一个基于 Vue3、Vite、TypeScript、Naive UI 的免费中后台模版,它使用了最新的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于mock实现的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。
|
[Soybean Admin](https://github.com/honghuangdc/soybean-admin) 是一个基于 Vue3、Vite3、TypeScript、NaiveUI、Pinia 和 UnoCSS 的清新优雅的中后台模版,它使用了最新的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于 mock 实现的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
- **最新技术栈**:使用 Vue3/vite2 等前端前沿技术开发, 使用高效率的npm包管理器pnpm
|
- **最新技术栈**:使用 Vue3/Vite3 等前端前沿技术开发, 使用高效率的 npm 包管理器 pnpm
|
||||||
- **TypeScript**: 应用程序级 JavaScript 的语言
|
- **TypeScript**:应用程序级 JavaScript 的语言
|
||||||
- **主题**:丰富可配置的主题、暗黑模式,基于windicss的动态主题颜色
|
- **主题**:丰富可配置的主题、暗黑模式,基于原子 css 框架 - UnoCSS 的动态主题颜色
|
||||||
- **代码规范**:丰富的规范插件及极高的代码规范
|
- **代码规范**:丰富的规范插件及极高的代码规范
|
||||||
- **权限路由**:简易的路由配置、基于 mock 的动态路由能快速实现后端动态路由
|
- **权限路由**:简易的路由配置、基于 mock 的动态路由能快速实现后端动态路由
|
||||||
- **请求函数**:基于axios的完善的请求函数封装,提供Promise和hooks两种请求函数
|
- **请求函数**:基于 axios 的完善的请求函数封装,提供 Promise 和 hooks 两种请求函数,加入请求结果数据转换的适配器
|
||||||
|
|
||||||
## 预览
|
## 预览
|
||||||
|
|
||||||
@@ -24,45 +24,52 @@ Soybean Admin 是一个基于 Vue3、Vite、TypeScript、Naive UI 的免费中
|
|||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
- [项目文档](https://docs.soybean.pro)
|
- [项目文档: docs.soybean.pro](https://docs.soybean.pro)
|
||||||
|
|
||||||
## 代码仓库
|
## 代码仓库
|
||||||
|
|
||||||
- [github](https://github.com/honghuangdc/soybean-admin)
|
- [github](https://github.com/honghuangdc/soybean-admin)
|
||||||
|
|
||||||
- [gitee](https://gitee.com/honghuangdc/soybean-admin)
|
- [gitee](https://gitee.com/honghuangdc/soybean-admin)
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
[CHANGELOG](./CHANGELOG.md)
|
||||||
|
|
||||||
|
## 后端服务
|
||||||
|
|
||||||
|
- [soybean-admin-java(开发中)](https://github.com/honghuangdc/soybean-admin-java)
|
||||||
|
- [soybean-admin-go(开发中)](https://github.com/honghuangdc/soybean-admin-go)
|
||||||
|
- [soybean-admin-nestjs(开发中)](https://github.com/honghuangdc/soybean-admin-nestjs)
|
||||||
|
|
||||||
## 项目示例图
|
## 项目示例图
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 开发计划
|

|
||||||
|
|
||||||
- [ ] 示例页面完善
|

|
||||||
- [ ] 表单、表格示例
|
|
||||||
- [ ] 添加锁屏组件、全局Iframe组件
|

|
||||||
- [ ] 用户角色切换示例、按钮级别权限指令
|
|
||||||
- [ ] 性能优化(优化递归函数)
|

|
||||||
- [ ] element-plus版本
|
|
||||||
- [ ] 其他UI版本
|
|
||||||
- [ ] soybean-admin cli工具(选择不同UI)
|
|
||||||
- [ ] 前端可视化创建路由页面
|
|
||||||
- [ ] soybean-admin 后台nodejs服务
|
|
||||||
|
|
||||||
## 安装使用
|
## 安装使用
|
||||||
|
|
||||||
|
- 环境配置
|
||||||
|
**本地环境需要安装 pnpm 7.x 、Node.js 14.18+ 和 Git**
|
||||||
|
|
||||||
- 克隆代码
|
- 克隆代码
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -87,6 +94,18 @@ pnpm dev
|
|||||||
pnpm build
|
pnpm build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Docker 部署
|
||||||
|
|
||||||
|
- Docker 部署 Soybean
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
|
||||||
|
```
|
||||||
|
|
||||||
|
- 访问 SoybeanAdmin
|
||||||
|
|
||||||
|
打开本地浏览器访问`http://localhost`
|
||||||
|
|
||||||
## 如何贡献
|
## 如何贡献
|
||||||
|
|
||||||
非常欢迎您的加入 或者提交一个 Pull Request。
|
非常欢迎您的加入 或者提交一个 Pull Request。
|
||||||
@@ -108,7 +127,7 @@ pnpm i -g commitizen
|
|||||||
支持现代浏览器, 不支持 IE
|
支持现代浏览器, 不支持 IE
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png" alt="IE" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png" alt="IE" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Safari |
|
||||||
| :-: | :-: | :-: | :-: | :-: |
|
| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||||
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||||
|
|
||||||
## 开源作者
|
## 开源作者
|
||||||
@@ -119,9 +138,9 @@ pnpm i -g commitizen
|
|||||||
|
|
||||||
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群,使用问题欢迎在群内提问。
|
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群,使用问题欢迎在群内提问。
|
||||||
|
|
||||||
- 微信交流群:
|
- 微信交流群(添加本人微信拉进群),欢迎来技术交流,业务咨询。
|
||||||
<div style="text-align:left">
|
<div style="text-align:left">
|
||||||
<img src="https://s2.loli.net/2022/03/06/4wokvQ7R5B62Ei1.jpg" style="width:200px" />
|
<img src="https://s2.loli.net/2022/05/16/3YGBgXnVPJdslk8.jpg" style="width:200px" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
- QQ 交流群 `711301266`
|
- QQ 交流群 `711301266`
|
||||||
@@ -130,7 +149,11 @@ pnpm i -g commitizen
|
|||||||
<img src="https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg" style="width:200px" />
|
<img src="https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg" style="width:200px" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
- 本人微信号:honghuangdc,欢迎来技术交流,业务咨询。
|
## 捐赠
|
||||||
|
|
||||||
|
如果你觉得这个项目对你有帮助,可以请 Soybean 喝杯饮料表示支持,Soybean 开源的动力离不开各位的支持和鼓励。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@@ -3,6 +3,6 @@ import dayjs from 'dayjs';
|
|||||||
/** 项目构建时间 */
|
/** 项目构建时间 */
|
||||||
const PROJECT_BUILD_TIME = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss'));
|
const PROJECT_BUILD_TIME = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss'));
|
||||||
|
|
||||||
export const define = {
|
export const viteDefine = {
|
||||||
PROJECT_BUILD_TIME,
|
PROJECT_BUILD_TIME
|
||||||
};
|
};
|
2
build/config/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './define';
|
||||||
|
export * from './proxy';
|
25
build/config/proxy.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import type { ProxyOptions } from 'vite';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置网络代理
|
||||||
|
* @param isOpenProxy - 是否开启代理
|
||||||
|
* @param envConfig - env环境配置
|
||||||
|
*/
|
||||||
|
export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfig) {
|
||||||
|
if (!isOpenProxy) return undefined;
|
||||||
|
|
||||||
|
const proxy: Record<string, string | ProxyOptions> = {
|
||||||
|
[envConfig.urlPattern]: {
|
||||||
|
target: envConfig.url,
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(new RegExp(`^${envConfig.urlPattern}`), '')
|
||||||
|
},
|
||||||
|
[envConfig.secondUrlPattern]: {
|
||||||
|
target: envConfig.secondUrl,
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(new RegExp(`^${envConfig.secondUrlPattern}`), '')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return proxy;
|
||||||
|
}
|
@@ -1,2 +1,3 @@
|
|||||||
export * from './plugins';
|
export * from './plugins';
|
||||||
export * from './define';
|
export * from './config';
|
||||||
|
export * from './utils';
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
import Icons from 'unplugin-icons/vite';
|
|
||||||
import IconsResolver from 'unplugin-icons/resolver';
|
|
||||||
import Components from 'unplugin-vue-components/vite';
|
|
||||||
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
|
|
||||||
|
|
||||||
export default (srcPath: string) => {
|
|
||||||
return [
|
|
||||||
Icons({
|
|
||||||
compiler: 'vue3',
|
|
||||||
customCollections: {
|
|
||||||
custom: FileSystemIconLoader(`${srcPath}/assets/svg`),
|
|
||||||
},
|
|
||||||
scale: 1,
|
|
||||||
defaultClass: 'inline-block',
|
|
||||||
}),
|
|
||||||
Components({
|
|
||||||
dts: true,
|
|
||||||
resolvers: [IconsResolver({ customCollections: ['custom'], componentPrefix: 'icon' })],
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
};
|
|
6
build/plugins/compress.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import ViteCompression from 'vite-plugin-compression';
|
||||||
|
|
||||||
|
export default (viteEnv: ImportMetaEnv) => {
|
||||||
|
const { VITE_COMPRESS_TYPE = 'gzip' } = viteEnv;
|
||||||
|
return ViteCompression({ algorithm: VITE_COMPRESS_TYPE });
|
||||||
|
};
|
@@ -1,17 +1,14 @@
|
|||||||
import { loadEnv } from 'vite';
|
import type { PluginOption } from 'vite';
|
||||||
import type { ConfigEnv, PluginOption } from 'vite';
|
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||||
import { createHtmlPlugin } from 'vite-plugin-html'; // html插件(使用变量、压缩)
|
|
||||||
|
|
||||||
export default (config: ConfigEnv): PluginOption[] => {
|
|
||||||
const viteEnv = loadEnv(config.mode, `.env.${config.mode}`);
|
|
||||||
|
|
||||||
|
export default (viteEnv: ImportMetaEnv): PluginOption[] => {
|
||||||
return createHtmlPlugin({
|
return createHtmlPlugin({
|
||||||
minify: true,
|
minify: true,
|
||||||
inject: {
|
inject: {
|
||||||
data: {
|
data: {
|
||||||
appName: viteEnv.VITE_APP_NAME,
|
appName: viteEnv.VITE_APP_NAME,
|
||||||
appTitle: viteEnv.VITE_APP_TITLE,
|
appTitle: viteEnv.VITE_APP_TITLE
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@@ -1,26 +1,38 @@
|
|||||||
import type { ConfigEnv, PluginOption } from 'vite';
|
import type { PluginOption } from 'vite';
|
||||||
import vue from './vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
|
import unocss from '@unocss/vite';
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
|
import progress from 'vite-plugin-progress';
|
||||||
import html from './html';
|
import html from './html';
|
||||||
import autoImport from './auto-import';
|
import unplugin from './unplugin';
|
||||||
import windicss from './windicss';
|
|
||||||
import mock from './mock';
|
import mock from './mock';
|
||||||
import visualizer from './visualizer';
|
import visualizer from './visualizer';
|
||||||
|
import compress from './compress';
|
||||||
|
import soybeanjs from './soybeanjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vite插件
|
* vite插件
|
||||||
* @param configEnv - 环境
|
|
||||||
* @param srcPath - src路径
|
|
||||||
* @param viteEnv - 环境变量配置
|
* @param viteEnv - 环境变量配置
|
||||||
*/
|
*/
|
||||||
export function setupVitePlugins(
|
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] {
|
||||||
configEnv: ConfigEnv,
|
const plugins = [
|
||||||
srcPath: string,
|
vue(),
|
||||||
viteEnv: ImportMetaEnv
|
vueJsx(),
|
||||||
): (PluginOption | PluginOption[])[] {
|
VitePWA(),
|
||||||
const plugins = [vue, html(configEnv), ...autoImport(srcPath), windicss, mock];
|
html(viteEnv),
|
||||||
|
...unplugin(viteEnv),
|
||||||
|
unocss(),
|
||||||
|
mock,
|
||||||
|
progress(),
|
||||||
|
soybeanjs()
|
||||||
|
];
|
||||||
|
|
||||||
if (configEnv.command === 'build' && viteEnv.VITE_VISUALIZER === 'true') {
|
if (viteEnv.VITE_VISUALIZER === 'Y') {
|
||||||
plugins.push(visualizer);
|
plugins.push(visualizer as PluginOption);
|
||||||
|
}
|
||||||
|
if (viteEnv.VITE_COMPRESS === 'Y') {
|
||||||
|
plugins.push(compress(viteEnv));
|
||||||
}
|
}
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
|
@@ -5,5 +5,5 @@ export default viteMockServe({
|
|||||||
injectCode: `
|
injectCode: `
|
||||||
import { setupMockServer } from '../mock';
|
import { setupMockServer } from '../mock';
|
||||||
setupMockServer();
|
setupMockServer();
|
||||||
`,
|
`
|
||||||
});
|
});
|
||||||
|
18
build/plugins/soybeanjs.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import routerPage from '@soybeanjs/router-page';
|
||||||
|
|
||||||
|
export default function createSoybeanjsPlugin() {
|
||||||
|
return routerPage({
|
||||||
|
pagesFormatter: names => {
|
||||||
|
/** 系统的内置路由,该文件夹名称不作为RouteKey */
|
||||||
|
const SYSTEM_VIEW = 'system-view';
|
||||||
|
|
||||||
|
const result = names
|
||||||
|
.filter(name => name !== SYSTEM_VIEW)
|
||||||
|
.map(name => {
|
||||||
|
return name.replace(`${SYSTEM_VIEW}_`, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
44
build/plugins/unplugin.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import VueMacros from 'unplugin-vue-macros/vite';
|
||||||
|
import Icons from 'unplugin-icons/vite';
|
||||||
|
import IconsResolver from 'unplugin-icons/resolver';
|
||||||
|
import Components from 'unplugin-vue-components/vite';
|
||||||
|
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers';
|
||||||
|
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
|
||||||
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
|
||||||
|
import { getSrcPath } from '../utils';
|
||||||
|
|
||||||
|
export default function unplugin(viteEnv: ImportMetaEnv) {
|
||||||
|
const { VITE_ICON_PREFFIX, VITE_ICON_LOCAL_PREFFIX } = viteEnv;
|
||||||
|
|
||||||
|
const srcPath = getSrcPath();
|
||||||
|
const localIconPath = `${srcPath}/assets/svg-icon`;
|
||||||
|
|
||||||
|
/** 本地svg图标集合名称 */
|
||||||
|
const collectionName = VITE_ICON_LOCAL_PREFFIX.replace(`${VITE_ICON_PREFFIX}-`, '');
|
||||||
|
|
||||||
|
return [
|
||||||
|
VueMacros(),
|
||||||
|
Icons({
|
||||||
|
compiler: 'vue3',
|
||||||
|
customCollections: {
|
||||||
|
[collectionName]: FileSystemIconLoader(localIconPath)
|
||||||
|
},
|
||||||
|
scale: 1,
|
||||||
|
defaultClass: 'inline-block'
|
||||||
|
}),
|
||||||
|
Components({
|
||||||
|
dts: 'src/typings/components.d.ts',
|
||||||
|
types: [{ from: 'vue-router', names: ['RouterLink', 'RouterView'] }],
|
||||||
|
resolvers: [
|
||||||
|
NaiveUiResolver(),
|
||||||
|
IconsResolver({ customCollections: [collectionName], componentPrefix: VITE_ICON_PREFFIX })
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
createSvgIconsPlugin({
|
||||||
|
iconDirs: [localIconPath],
|
||||||
|
symbolId: `${VITE_ICON_LOCAL_PREFFIX}-[dir]-[name]`,
|
||||||
|
inject: 'body-last',
|
||||||
|
customDomId: '__SVG_ICON_LOCAL__'
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
@@ -3,4 +3,5 @@ import { visualizer } from 'rollup-plugin-visualizer';
|
|||||||
export default visualizer({
|
export default visualizer({
|
||||||
gzipSize: true,
|
gzipSize: true,
|
||||||
brotliSize: true,
|
brotliSize: true,
|
||||||
|
open: true
|
||||||
});
|
});
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
import vue from '@vitejs/plugin-vue';
|
|
||||||
|
|
||||||
export default vue({});
|
|
@@ -1,3 +0,0 @@
|
|||||||
import windiCSS from 'vite-plugin-windicss';
|
|
||||||
|
|
||||||
export default windiCSS();
|
|
20
build/utils/index.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目根路径
|
||||||
|
* @descrition 末尾不带斜杠
|
||||||
|
*/
|
||||||
|
export function getRootPath() {
|
||||||
|
return path.resolve(process.cwd());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目src路径
|
||||||
|
* @param srcName - src目录名称(默认: "src")
|
||||||
|
* @descrition 末尾不带斜杠
|
||||||
|
*/
|
||||||
|
export function getSrcPath(srcName = 'src') {
|
||||||
|
const rootPath = getRootPath();
|
||||||
|
|
||||||
|
return `${rootPath}/${srcName}`;
|
||||||
|
}
|
@@ -1 +0,0 @@
|
|||||||
module.exports = { extends: ['@commitlint/config-conventional'] };
|
|
48
components.d.ts
vendored
@@ -1,48 +0,0 @@
|
|||||||
// generated by unplugin-vue-components
|
|
||||||
// We suggest you to commit this file into source control
|
|
||||||
// Read more: https://github.com/vuejs/vue-next/pull/3399
|
|
||||||
|
|
||||||
declare module 'vue' {
|
|
||||||
export interface GlobalComponents {
|
|
||||||
BetterScroll: typeof import('./src/components/custom/BetterScroll.vue')['default'];
|
|
||||||
CountTo: typeof import('./src/components/custom/CountTo.vue')['default'];
|
|
||||||
DarkModeContainer: typeof import('./src/components/common/DarkModeContainer.vue')['default'];
|
|
||||||
DarkModeSwitch: typeof import('./src/components/common/DarkModeSwitch.vue')['default'];
|
|
||||||
GithubLink: typeof import('./src/components/custom/GithubLink.vue')['default'];
|
|
||||||
HoverContainer: typeof import('./src/components/common/HoverContainer.vue')['default'];
|
|
||||||
IconAntDesignCloseOutlined: typeof import('~icons/ant-design/close-outlined')['default'];
|
|
||||||
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default'];
|
|
||||||
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default'];
|
|
||||||
IconCustomActivity: typeof import('~icons/custom/activity')['default'];
|
|
||||||
IconCustomAvatar: typeof import('~icons/custom/avatar')['default'];
|
|
||||||
IconCustomCast: typeof import('~icons/custom/cast')['default'];
|
|
||||||
IconCustomLogo: typeof import('~icons/custom/logo')['default'];
|
|
||||||
IconCustomLogoFill: typeof import('~icons/custom/logo-fill')['default'];
|
|
||||||
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default'];
|
|
||||||
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default'];
|
|
||||||
IconIcOutlineCheck: typeof import('~icons/ic/outline-check')['default'];
|
|
||||||
IconLineMdMenuFoldLeft: typeof import('~icons/line-md/menu-fold-left')['default'];
|
|
||||||
IconLineMdMenuUnfoldLeft: typeof import('~icons/line-md/menu-unfold-left')['default'];
|
|
||||||
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default'];
|
|
||||||
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default'];
|
|
||||||
IconMdiClose: typeof import('~icons/mdi/close')['default'];
|
|
||||||
IconMdiGithub: typeof import('~icons/mdi/github')['default'];
|
|
||||||
IconMdiMoonWaningCrescent: typeof import('~icons/mdi/moon-waning-crescent')['default'];
|
|
||||||
IconMdiPin: typeof import('~icons/mdi/pin')['default'];
|
|
||||||
IconMdiPinOff: typeof import('~icons/mdi/pin-off')['default'];
|
|
||||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default'];
|
|
||||||
IconMdiWhiteBalanceSunny: typeof import('~icons/mdi/white-balance-sunny')['default'];
|
|
||||||
IconPhCaretDoubleLeftBold: typeof import('~icons/ph/caret-double-left-bold')['default'];
|
|
||||||
IconPhCaretDoubleRightBold: typeof import('~icons/ph/caret-double-right-bold')['default'];
|
|
||||||
IconSelect: typeof import('./src/components/custom/IconSelect.vue')['default'];
|
|
||||||
IconUilSearch: typeof import('~icons/uil/search')['default'];
|
|
||||||
ImageVerify: typeof import('./src/components/custom/ImageVerify.vue')['default'];
|
|
||||||
LoadingEmptyWrapper: typeof import('./src/components/business/LoadingEmptyWrapper.vue')['default'];
|
|
||||||
LoginAgreement: typeof import('./src/components/business/LoginAgreement.vue')['default'];
|
|
||||||
NaiveProvider: typeof import('./src/components/common/NaiveProvider.vue')['default'];
|
|
||||||
SystemLogo: typeof import('./src/components/common/SystemLogo.vue')['default'];
|
|
||||||
WebSiteLink: typeof import('./src/components/custom/WebSiteLink.vue')['default'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {};
|
|
32
docker/.dockerignore
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
.npmrc
|
||||||
|
.cache
|
||||||
|
|
||||||
|
tests/server/static
|
||||||
|
tests/server/static/upload
|
||||||
|
|
||||||
|
.local
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
# .vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
/vite-profile.cpuprofile
|
24
docker/Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
FROM node:16.17.0 as builder
|
||||||
|
|
||||||
|
ENV WORKDIR=/soybean-admin
|
||||||
|
|
||||||
|
WORKDIR $WORKDIR
|
||||||
|
|
||||||
|
COPY ./ $WORKDIR/
|
||||||
|
|
||||||
|
ARG version
|
||||||
|
ENV COMMITID=$version
|
||||||
|
|
||||||
|
RUN npm i -g pnpm
|
||||||
|
|
||||||
|
RUN pnpm install
|
||||||
|
RUN pnpm build
|
||||||
|
|
||||||
|
FROM nginx:alpine as prod
|
||||||
|
|
||||||
|
RUN mkdir /soybean
|
||||||
|
|
||||||
|
COPY --from=builder /soybean-admin/dist /soybean-admin
|
||||||
|
COPY --from=builder /soybean-admin/docker/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
EXPOSE 80
|
54
docker/nginx.conf
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes 1;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# 不缓存html,防止程序更新后缓存继续生效
|
||||||
|
if ($request_filename ~* .*\.(?:htm|html)$) {
|
||||||
|
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
|
||||||
|
access_log on;
|
||||||
|
}
|
||||||
|
root /soybean-admin/;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# location /soybean/soybean-webserver/v1 {
|
||||||
|
# proxy_set_header Host $host;
|
||||||
|
# proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
# proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
|
|
||||||
|
# # 后台接口地址
|
||||||
|
# proxy_pass http://192.168.1.99:30597/v1;
|
||||||
|
# proxy_redirect default;
|
||||||
|
# add_header Access-Control-Allow-Origin *;
|
||||||
|
# add_header Access-Control-Allow-Headers X-Requested-With;
|
||||||
|
# add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
|
||||||
|
# }
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="zh-cmn-Hans">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<div class="right-0 bottom-0 loading-spin-item loading-delay-1500"></div>
|
<div class="right-0 bottom-0 loading-spin-item loading-delay-1500"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="loading-title"><%= appTitle %></h2>
|
<div class="loading-title"><%= appTitle %></div>
|
||||||
</div>
|
</div>
|
||||||
<script src="/resource/loading.js"></script>
|
<script src="/resource/loading.js"></script>
|
||||||
</div>
|
</div>
|
||||||
|
143
mock/api/auth.ts
@@ -1,9 +1,10 @@
|
|||||||
import type { MockMethod } from 'vite-plugin-mock';
|
import type { MockMethod } from 'vite-plugin-mock';
|
||||||
|
import { userModel } from '../model';
|
||||||
|
|
||||||
const token: ApiAuth.Token = {
|
/** 参数错误的状态码 */
|
||||||
token: '__TEMP_TOKEN__',
|
const ERROR_PARAM_CODE = 10000;
|
||||||
refreshToken: '__TEMP_REFRESH_TOKEN__',
|
|
||||||
};
|
const ERROR_PARAM_MSG = '参数校验失败!';
|
||||||
|
|
||||||
const apis: MockMethod[] = [
|
const apis: MockMethod[] = [
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
@@ -14,80 +15,114 @@ const apis: MockMethod[] = [
|
|||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
message: 'ok',
|
message: 'ok',
|
||||||
data: true,
|
data: true
|
||||||
};
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
// 用户+密码 登录
|
||||||
// 密码登录
|
|
||||||
{
|
{
|
||||||
url: '/mock/loginByPwd',
|
url: '/mock/login',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
response: (): Service.MockServiceResult<ApiAuth.Token> => {
|
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
|
||||||
|
const { userName = undefined, password = undefined } = options.body;
|
||||||
|
|
||||||
|
if (!userName || !password) {
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: ERROR_PARAM_CODE,
|
||||||
message: 'ok',
|
message: ERROR_PARAM_MSG,
|
||||||
data: token,
|
data: null
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
},
|
|
||||||
// 验证码登录
|
const findItem = userModel.find(item => item.userName === userName && item.password === password);
|
||||||
{
|
|
||||||
url: '/mock/loginByCode',
|
if (findItem) {
|
||||||
method: 'post',
|
|
||||||
response: (): Service.MockServiceResult<ApiAuth.Token> => {
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
message: 'ok',
|
|
||||||
data: token,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 获取用户信息(请求头携带token)
|
|
||||||
{
|
|
||||||
url: '/mock/getUserInfo',
|
|
||||||
method: 'get',
|
|
||||||
response: (): Service.MockServiceResult<ApiAuth.UserInfo> => {
|
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
message: 'ok',
|
message: 'ok',
|
||||||
data: {
|
data: {
|
||||||
userId: '0',
|
token: findItem.token,
|
||||||
userName: 'Soybean',
|
refreshToken: findItem.refreshToken
|
||||||
userPhone: '15170283876',
|
}
|
||||||
userRole: 'super',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: '/mock/testToken',
|
|
||||||
method: 'post',
|
|
||||||
response: (option: any): Service.MockServiceResult<true | null> => {
|
|
||||||
if (option.headers?.authorization !== token.token) {
|
|
||||||
return {
|
|
||||||
code: 66666,
|
|
||||||
message: 'token 失效',
|
|
||||||
data: null,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
code: 1000,
|
||||||
|
message: '用户名或密码错误!',
|
||||||
|
data: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取用户信息(请求头携带token, 根据token获取用户信息)
|
||||||
|
{
|
||||||
|
url: '/mock/getUserInfo',
|
||||||
|
method: 'get',
|
||||||
|
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.UserInfo | null> => {
|
||||||
|
// 这里的mock插件得到的字段是authorization, 前端传递的是Authorization字段
|
||||||
|
const { authorization = '' } = options.headers;
|
||||||
|
const REFRESH_TOKEN_CODE = 66666;
|
||||||
|
|
||||||
|
if (!authorization) {
|
||||||
|
return {
|
||||||
|
code: REFRESH_TOKEN_CODE,
|
||||||
|
message: '用户已失效或不存在!',
|
||||||
|
data: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const userInfo: Auth.UserInfo = {
|
||||||
|
userId: '',
|
||||||
|
userName: '',
|
||||||
|
userRole: 'user'
|
||||||
|
};
|
||||||
|
const isInUser = userModel.some(item => {
|
||||||
|
const flag = item.token === authorization;
|
||||||
|
if (flag) {
|
||||||
|
const { userId: itemUserId, userName, userRole } = item;
|
||||||
|
Object.assign(userInfo, { userId: itemUserId, userName, userRole });
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isInUser) {
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
message: 'ok',
|
message: 'ok',
|
||||||
data: true,
|
data: userInfo
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: REFRESH_TOKEN_CODE,
|
||||||
|
message: '用户信息异常!',
|
||||||
|
data: null
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: '/mock/updateToken',
|
url: '/mock/updateToken',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
response: (): Service.MockServiceResult<ApiAuth.Token> => {
|
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
|
||||||
|
const { refreshToken = '' } = options.body;
|
||||||
|
|
||||||
|
const findItem = userModel.find(item => item.refreshToken === refreshToken);
|
||||||
|
|
||||||
|
if (findItem) {
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
message: 'ok',
|
message: 'ok',
|
||||||
data: token,
|
data: {
|
||||||
|
token: findItem.token,
|
||||||
|
refreshToken: findItem.refreshToken
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
},
|
return {
|
||||||
|
code: 3000,
|
||||||
|
message: '用户已失效或不存在!',
|
||||||
|
data: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default apis;
|
export default apis;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import auth from './auth';
|
import auth from './auth';
|
||||||
import route from './route';
|
import route from './route';
|
||||||
|
import management from './management';
|
||||||
|
|
||||||
export default [...auth, ...route];
|
export default [...auth, ...route, ...management];
|
||||||
|
33
mock/api/management.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { mock } from 'mockjs';
|
||||||
|
import type { MockMethod } from 'vite-plugin-mock';
|
||||||
|
|
||||||
|
const apis: MockMethod[] = [
|
||||||
|
{
|
||||||
|
url: '/mock/getAllUserList',
|
||||||
|
method: 'post',
|
||||||
|
response: (): Service.MockServiceResult<ApiUserManagement.User[]> => {
|
||||||
|
const data = mock({
|
||||||
|
'list|1000': [
|
||||||
|
{
|
||||||
|
id: '@id',
|
||||||
|
userName: '@cname',
|
||||||
|
'age|18-56': 56,
|
||||||
|
'gender|1': ['0', '1', null],
|
||||||
|
phone:
|
||||||
|
/^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/,
|
||||||
|
'email|1': ['@email("qq.com")', null],
|
||||||
|
'userStatus|1': ['1', '2', '3', '4', null]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
message: 'ok',
|
||||||
|
data: data.list
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default apis;
|
@@ -1,382 +1,29 @@
|
|||||||
import type { MockMethod } from 'vite-plugin-mock';
|
import type { MockMethod } from 'vite-plugin-mock';
|
||||||
|
import { routeModel, userModel } from '../model';
|
||||||
const routes: AuthRoute.Route[] = [
|
|
||||||
{
|
|
||||||
name: 'dashboard',
|
|
||||||
path: '/dashboard',
|
|
||||||
component: 'basic',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'dashboard_analysis',
|
|
||||||
path: '/dashboard/analysis',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '分析页',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'icon-park-outline:analysis',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'dashboard_workbench',
|
|
||||||
path: '/dashboard/workbench',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '工作台',
|
|
||||||
requiresAuth: true,
|
|
||||||
permissions: ['super', 'admin'],
|
|
||||||
icon: 'icon-park-outline:workbench',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '仪表盘',
|
|
||||||
icon: 'carbon:dashboard',
|
|
||||||
order: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'document',
|
|
||||||
path: '/document',
|
|
||||||
component: 'basic',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'document_vue',
|
|
||||||
path: '/document/vue',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: 'vue文档',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:vuejs',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'document_vue-new',
|
|
||||||
path: '/document/vue-new',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: 'vue文档(新版)',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:vuejs',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'document_vite',
|
|
||||||
path: '/document/vite',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: 'vite文档',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'simple-icons:vite',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'document_naive',
|
|
||||||
path: '/document/naive',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: 'naive文档',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:alpha-n-box-outline',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'document_project',
|
|
||||||
path: '/document/project',
|
|
||||||
meta: {
|
|
||||||
title: '项目文档(外链)',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:file-link-outline',
|
|
||||||
href: 'https://docs.soybean.pro/',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '文档',
|
|
||||||
icon: 'carbon:document',
|
|
||||||
order: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'component',
|
|
||||||
path: '/component',
|
|
||||||
component: 'basic',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'component_button',
|
|
||||||
path: '/component/button',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '按钮',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:baseline-radio-button-checked',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'component_card',
|
|
||||||
path: '/component/card',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '卡片',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:card-outline',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'component_table',
|
|
||||||
path: '/component/table',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '表格',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:table-large',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '组件示例',
|
|
||||||
icon: 'fluent:app-store-24-regular',
|
|
||||||
order: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin',
|
|
||||||
path: '/plugin',
|
|
||||||
component: 'basic',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'plugin_map',
|
|
||||||
path: '/plugin/map',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '地图',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:map',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_video',
|
|
||||||
path: '/plugin/video',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '视频',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:video',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_editor',
|
|
||||||
path: '/plugin/editor',
|
|
||||||
component: 'multi',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'plugin_editor_quill',
|
|
||||||
path: '/plugin/editor/quill',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '富文本编辑器',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:file-document-edit-outline',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_editor_markdown',
|
|
||||||
path: '/plugin/editor/markdown',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: 'markdown编辑器',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ri:markdown-line',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '编辑器',
|
|
||||||
icon: 'icon-park-outline:editor',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_swiper',
|
|
||||||
path: '/plugin/swiper',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: 'Swiper插件',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'simple-icons:swiper',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_copy',
|
|
||||||
path: '/plugin/copy',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '剪贴板',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'mdi:clipboard-outline',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_icon',
|
|
||||||
path: '/plugin/icon',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '图标',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:baseline-insert-emoticon',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'plugin_print',
|
|
||||||
path: '/plugin/print',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '打印',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:baseline-local-printshop',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '插件示例',
|
|
||||||
icon: 'clarity:plugin-line',
|
|
||||||
order: 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'exception',
|
|
||||||
path: '/exception',
|
|
||||||
component: 'basic',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'exception_403',
|
|
||||||
path: '/exception/403',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '异常页403',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:baseline-block',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'exception_404',
|
|
||||||
path: '/exception/404',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '异常页404',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:baseline-web-asset-off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'exception_500',
|
|
||||||
path: '/exception/500',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '异常页500',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:baseline-wifi-off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '异常页',
|
|
||||||
icon: 'ant-design:exception-outlined',
|
|
||||||
order: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'multi-menu',
|
|
||||||
path: '/multi-menu',
|
|
||||||
component: 'basic',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'multi-menu_first',
|
|
||||||
path: '/multi-menu/first',
|
|
||||||
component: 'multi',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'multi-menu_first_second',
|
|
||||||
path: '/multi-menu/first/second',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '二级菜单',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:outline-menu',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'multi-menu_first_second-new',
|
|
||||||
path: '/multi-menu/first/second-new',
|
|
||||||
component: 'multi',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'multi-menu_first_second-new_third',
|
|
||||||
path: '/multi-menu/first/second-new/third',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '三级菜单',
|
|
||||||
requiresAuth: true,
|
|
||||||
icon: 'ic:outline-menu',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '二级菜单(有子菜单)',
|
|
||||||
icon: 'ic:outline-menu',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '一级菜单',
|
|
||||||
icon: 'ic:outline-menu',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
meta: {
|
|
||||||
title: '多级菜单',
|
|
||||||
icon: 'carbon:menu',
|
|
||||||
order: 6,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'about',
|
|
||||||
path: '/about',
|
|
||||||
component: 'self',
|
|
||||||
meta: {
|
|
||||||
title: '关于',
|
|
||||||
requiresAuth: true,
|
|
||||||
singleLayout: 'basic',
|
|
||||||
permissions: ['super', 'admin', 'test'],
|
|
||||||
icon: 'fluent:book-information-24-regular',
|
|
||||||
order: 7,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function dataMiddleware(data: AuthRoute.Route[]): ApiRoute.Route {
|
|
||||||
const routeHomeName: AuthRoute.RouteKey = 'dashboard_analysis';
|
|
||||||
|
|
||||||
function sortRoutes(sorts: AuthRoute.Route[]) {
|
|
||||||
return sorts.sort((next, pre) => Number(next.meta?.order) - Number(pre.meta?.order));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
routes: sortRoutes(data),
|
|
||||||
home: routeHomeName,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const apis: MockMethod[] = [
|
const apis: MockMethod[] = [
|
||||||
{
|
{
|
||||||
url: '/mock/getUserRoutes',
|
url: '/mock/getUserRoutes',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
response: (): Service.MockServiceResult => {
|
response: (options: Service.MockOption): Service.MockServiceResult => {
|
||||||
|
const { userId = undefined } = options.body;
|
||||||
|
|
||||||
|
const routeHomeName: AuthRoute.LastDegreeRouteKey = 'dashboard_analysis';
|
||||||
|
|
||||||
|
const role = userModel.find(item => item.userId === userId)?.userRole || 'user';
|
||||||
|
|
||||||
|
const filterRoutes = routeModel[role];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
message: 'ok',
|
message: 'ok',
|
||||||
data: dataMiddleware(routes),
|
data: {
|
||||||
|
routes: filterRoutes,
|
||||||
|
home: routeHomeName
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default apis;
|
export default apis;
|
||||||
|
40
mock/model/auth.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
interface UserModel extends Auth.UserInfo {
|
||||||
|
token: string;
|
||||||
|
refreshToken: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const userModel: UserModel[] = [
|
||||||
|
{
|
||||||
|
token: '__TOKEN_SOYBEAN__',
|
||||||
|
refreshToken: '__REFRESH_TOKEN_SOYBEAN__',
|
||||||
|
userId: '0',
|
||||||
|
userName: 'Soybean',
|
||||||
|
userRole: 'super',
|
||||||
|
password: 'soybean123'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: '__TOKEN_SUPER__',
|
||||||
|
refreshToken: '__REFRESH_TOKEN_SUPER__',
|
||||||
|
userId: '1',
|
||||||
|
userName: 'Super',
|
||||||
|
userRole: 'super',
|
||||||
|
password: 'super123'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: '__TOKEN_ADMIN__',
|
||||||
|
refreshToken: '__REFRESH_TOKEN_ADMIN__',
|
||||||
|
userId: '2',
|
||||||
|
userName: 'Admin',
|
||||||
|
userRole: 'admin',
|
||||||
|
password: 'admin123'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: '__TOKEN_USER01__',
|
||||||
|
refreshToken: '__REFRESH_TOKEN_USER01__',
|
||||||
|
userId: '3',
|
||||||
|
userName: 'User01',
|
||||||
|
userRole: 'user',
|
||||||
|
password: 'user01123'
|
||||||
|
}
|
||||||
|
];
|
2
mock/model/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './auth';
|
||||||
|
export * from './route';
|
1126
mock/model/route.ts
Normal file
190
package.json
@@ -1,99 +1,133 @@
|
|||||||
{
|
{
|
||||||
"name": "soybean-admin",
|
"name": "soybean-admin",
|
||||||
"version": "0.9.3",
|
"version": "0.9.7",
|
||||||
|
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
|
||||||
|
"author": {
|
||||||
|
"name": "Soybean",
|
||||||
|
"email": "honghuangdc@gmail.com",
|
||||||
|
"url": "https://github.com/honghuangdc"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/honghuangdc/soybean-admin",
|
||||||
|
"repository": {
|
||||||
|
"url": "https://github.com/honghuangdc/soybean-admin.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/honghuangdc/soybean-admin/issues"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"Vue",
|
||||||
|
"Vue3",
|
||||||
|
"admin",
|
||||||
|
"admin-template",
|
||||||
|
"vue-admin",
|
||||||
|
"vue-admin-template",
|
||||||
|
"Vite3",
|
||||||
|
"Vite",
|
||||||
|
"vite-admin",
|
||||||
|
"TypeScript",
|
||||||
|
"TS",
|
||||||
|
"NaiveUI",
|
||||||
|
"naive-ui",
|
||||||
|
"naive-admin",
|
||||||
|
"NaiveUI-Admin",
|
||||||
|
"naive-ui-admin",
|
||||||
|
"UnoCSS"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "cross-env VITE_ENV_TYPE=dev vite",
|
"dev": "cross-env VITE_SERVICE_ENV=dev vite",
|
||||||
"dev:test": "cross-env VITE_ENV_TYPE=test vite",
|
"dev:test": "cross-env VITE_SERVICE_ENV=test vite",
|
||||||
"dev:prod": "cross-env VITE_ENV_TYPE=prod vite",
|
"dev:prod": "cross-env VITE_SERVICE_ENV=prod vite",
|
||||||
"build": "npm run typecheck && cross-env VITE_ENV_TYPE=prod vite build",
|
"build": "npm run typecheck && cross-env VITE_SERVICE_ENV=prod vite build",
|
||||||
"build:dev": "npm run typecheck && cross-env VITE_ENV_TYPE=dev vite build",
|
"build:dev": "npm run typecheck && cross-env VITE_SERVICE_ENV=dev vite build",
|
||||||
"build:test": "npm run typecheck && cross-env VITE_ENV_TYPE=test vite build",
|
"build:test": "npm run typecheck && cross-env VITE_SERVICE_ENV=test vite build",
|
||||||
"build:vercel": "cross-env VITE_HASH_ROUTE=true vite build",
|
"build:vercel": "cross-env VITE_HASH_ROUTE=Y VITE_VERCEL=Y vite build",
|
||||||
"preview": "vite preview --port 5050",
|
"preview": "vite preview",
|
||||||
"typecheck": "vue-tsc --noEmit",
|
"typecheck": "vue-tsc --noEmit --skipLibCheck",
|
||||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
"lint": "eslint . --fix",
|
||||||
"prepare": "husky install",
|
"commit": "soybean git-commit",
|
||||||
"postinstall": "patch-package",
|
"esno": "esno",
|
||||||
|
"cleanup": "esno ./scripts/cleanup.ts",
|
||||||
|
"update-pkg": "ncu --deep -u",
|
||||||
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
||||||
"release": "standard-version",
|
"release": "standard-version",
|
||||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"
|
"prepare": "husky install"
|
||||||
},
|
|
||||||
"lint-staged": {
|
|
||||||
"*.{vue,js,jsx,ts,tsx}": "eslint --fix"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"commitizen": {
|
|
||||||
"path": "./node_modules/cz-customizable"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@antv/g2plot": "^2.4.10",
|
"@antv/data-set": "^0.11.8",
|
||||||
"@better-scroll/core": "^2.4.2",
|
"@antv/g2": "^4.2.8",
|
||||||
"@vueuse/core": "^8.0.0",
|
"@better-scroll/core": "^2.5.0",
|
||||||
"axios": "^0.26.1",
|
"@soybeanjs/vue-admin-layout": "^1.1.1",
|
||||||
"clipboard": "^2.0.10",
|
"@soybeanjs/vue-admin-tab": "^1.0.5",
|
||||||
"colord": "^2.9.2",
|
"@vueuse/core": "^9.4.0",
|
||||||
|
"axios": "0.27.2",
|
||||||
|
"clipboard": "^2.0.11",
|
||||||
|
"colord": "^2.9.3",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"dayjs": "^1.10.8",
|
"dayjs": "^1.11.6",
|
||||||
|
"echarts": "^5.4.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"naive-ui": "^2.26.4",
|
"naive-ui": "2.33.5",
|
||||||
"pinia": "^2.0.11",
|
"pinia": "^2.0.23",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"qs": "^6.10.3",
|
"qs": "^6.11.0",
|
||||||
"soybean-admin-layout": "^1.0.4",
|
"swiper": "^8.4.4",
|
||||||
"soybean-admin-tab": "^1.2.3",
|
"ua-parser-js": "^1.0.32",
|
||||||
"swiper": "^8.0.7",
|
"vditor": "^3.8.18",
|
||||||
"ua-parser-js": "^1.0.2",
|
"vue": "3.2.41",
|
||||||
"vditor": "^3.8.12",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue": "^3.2.31",
|
"vue-router": "^4.1.6",
|
||||||
"vue-router": "^4.0.14",
|
"vuedraggable": "^4.1.0",
|
||||||
"wangeditor": "^4.7.12",
|
"wangeditor": "^4.7.15",
|
||||||
"xgplayer": "^2.31.4"
|
"xgplayer": "^2.32.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@amap/amap-jsapi-types": "^0.0.8",
|
"@amap/amap-jsapi-types": "^0.0.10",
|
||||||
"@commitlint/cli": "^16.2.1",
|
"@iconify/json": "^2.1.133",
|
||||||
"@commitlint/config-conventional": "^16.2.1",
|
"@iconify/vue": "^4.0.0",
|
||||||
"@iconify/json": "^2.1.14",
|
"@soybeanjs/cli": "^0.1.2",
|
||||||
"@iconify/vue": "^3.1.4",
|
"@soybeanjs/router-page": "1.0.3",
|
||||||
|
"@tauri-apps/cli": "^1.1.1",
|
||||||
"@types/bmapgl": "^0.0.5",
|
"@types/bmapgl": "^0.0.5",
|
||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.1.1",
|
||||||
"@types/node": "^17.0.21",
|
"@types/node": "18.8.3",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
"@types/ua-parser-js": "^0.7.36",
|
"@types/ua-parser-js": "^0.7.36",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.14.0",
|
"@unocss/preset-uno": "^0.46.3",
|
||||||
"@typescript-eslint/parser": "^5.14.0",
|
"@unocss/vite": "^0.46.3",
|
||||||
"@vitejs/plugin-vue": "^2.2.4",
|
"@vitejs/plugin-vue": "^3.2.0",
|
||||||
"@vue/eslint-config-prettier": "^7.0.0",
|
"@vitejs/plugin-vue-jsx": "^2.1.0",
|
||||||
"@vue/eslint-config-typescript": "^10.0.0",
|
"conventional-changelog": "^3.1.25",
|
||||||
"@vue/tsconfig": "^0.1.3",
|
|
||||||
"commitizen": "^4.2.4",
|
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cz-conventional-changelog": "^3.3.0",
|
"eslint": "^8.27.0",
|
||||||
"cz-customizable": "^6.3.0",
|
"eslint-config-soybeanjs-vue": "^0.1.2",
|
||||||
"eslint": "^8.11.0",
|
"esno": "^0.16.3",
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
"husky": "^8.0.1",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
|
||||||
"eslint-plugin-import": "^2.25.4",
|
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
|
||||||
"eslint-plugin-vue": "^8.5.0",
|
|
||||||
"husky": "^7.0.4",
|
|
||||||
"lint-staged": "^12.3.5",
|
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"patch-package": "^6.4.7",
|
"npm-check-updates": "^16.3.16",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"rimraf": "^3.0.2",
|
||||||
"prettier": "^2.5.1",
|
"rollup-plugin-visualizer": "^5.8.3",
|
||||||
"rollup-plugin-visualizer": "^5.6.0",
|
"sass": "^1.56.0",
|
||||||
"sass": "^1.49.9",
|
"standard-version": "^9.5.0",
|
||||||
"typescript": "~4.6.2",
|
"typescript": "4.8.4",
|
||||||
"unplugin-icons": "^0.13.3",
|
"unplugin-icons": "^0.14.13",
|
||||||
"unplugin-vue-components": "^0.18.0",
|
"unplugin-vue-components": "0.22.8",
|
||||||
"vite": "2.8.6",
|
"unplugin-vue-macros": "^0.16.0",
|
||||||
"vite-plugin-html": "^3.1.0",
|
"utility-types": "^3.10.0",
|
||||||
|
"vite": "^3.2.2",
|
||||||
|
"vite-plugin-compression": "^0.5.1",
|
||||||
|
"vite-plugin-html": "^3.2.0",
|
||||||
"vite-plugin-mock": "^2.9.6",
|
"vite-plugin-mock": "^2.9.6",
|
||||||
"vite-plugin-windicss": "^1.8.3",
|
"vite-plugin-progress": "^0.0.6",
|
||||||
"vue-tsc": "^0.32.1",
|
"vite-plugin-pwa": "^0.13.2",
|
||||||
"vueuc": "^0.4.27",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"windicss": "^3.5.1"
|
"vue-tsc": "^1.0.9",
|
||||||
|
"zx": "^7.1.1"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"patchedDependencies": {
|
||||||
|
"mockjs@1.1.0": "patches/mockjs@1.1.0.patch"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
732
patches/mockjs@1.1.0.patch
Normal file
@@ -0,0 +1,732 @@
|
|||||||
|
diff --git a/dist/mock.js b/dist/mock.js
|
||||||
|
index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecde33320f3 100644
|
||||||
|
--- a/dist/mock.js
|
||||||
|
+++ b/dist/mock.js
|
||||||
|
@@ -126,17 +126,17 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
/* 1 */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
- /*
|
||||||
|
+ /*
|
||||||
|
## Handler
|
||||||
|
|
||||||
|
处理数据模板。
|
||||||
|
-
|
||||||
|
+
|
||||||
|
* Handler.gen( template, name?, context? )
|
||||||
|
|
||||||
|
入口方法。
|
||||||
|
|
||||||
|
* Data Template Definition, DTD
|
||||||
|
-
|
||||||
|
+
|
||||||
|
处理数据模板定义。
|
||||||
|
|
||||||
|
* Handler.array( options )
|
||||||
|
@@ -146,7 +146,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
* Handler.string( options )
|
||||||
|
* Handler.function( options )
|
||||||
|
* Handler.regexp( options )
|
||||||
|
-
|
||||||
|
+
|
||||||
|
处理路径(相对和绝对)。
|
||||||
|
|
||||||
|
* Handler.getValueByKeyPath( key, options )
|
||||||
|
@@ -177,7 +177,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
Handle.gen(template, name, options)
|
||||||
|
context
|
||||||
|
- currentContext, templateCurrentContext,
|
||||||
|
+ currentContext, templateCurrentContext,
|
||||||
|
path, templatePath
|
||||||
|
root, templateRoot
|
||||||
|
*/
|
||||||
|
@@ -456,7 +456,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
phed = Handler.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options)
|
||||||
|
|
||||||
|
// 只有一个占位符,并且没有其他字符
|
||||||
|
- if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { //
|
||||||
|
+ if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { //
|
||||||
|
result = phed
|
||||||
|
break
|
||||||
|
|
||||||
|
@@ -627,7 +627,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
// 引用的值已经计算好
|
||||||
|
if (currentContext && (key in currentContext)) return currentContext[key]
|
||||||
|
-
|
||||||
|
+
|
||||||
|
// 尚未计算,递归引用数据模板中的属性
|
||||||
|
if (templateCurrentContext &&
|
||||||
|
(typeof templateCurrentContext === 'object') &&
|
||||||
|
@@ -816,13 +816,13 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
var tpl = Mock.heredoc(function() {
|
||||||
|
/*!
|
||||||
|
{{email}}{{age}}
|
||||||
|
- <!-- Mock {
|
||||||
|
+ <!-- Mock {
|
||||||
|
email: '@EMAIL',
|
||||||
|
age: '@INT(1,100)'
|
||||||
|
} -->
|
||||||
|
*\/
|
||||||
|
})
|
||||||
|
-
|
||||||
|
+
|
||||||
|
**相关阅读**
|
||||||
|
* [Creating multiline strings in JavaScript](http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript)、
|
||||||
|
*/
|
||||||
|
@@ -850,7 +850,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
解析数据模板(属性名部分)。
|
||||||
|
|
||||||
|
* Parser.parse( name )
|
||||||
|
-
|
||||||
|
+
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
parameters: [ name, inc, range, decimal ],
|
||||||
|
@@ -922,7 +922,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
/*
|
||||||
|
## Mock.Random
|
||||||
|
-
|
||||||
|
+
|
||||||
|
工具类,用于生成各种随机数据。
|
||||||
|
*/
|
||||||
|
|
||||||
|
@@ -1251,7 +1251,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
替代图片源
|
||||||
|
http://fpoimg.com/
|
||||||
|
- 参考自
|
||||||
|
+ 参考自
|
||||||
|
http://rensanning.iteye.com/blog/1933310
|
||||||
|
http://code.tutsplus.com/articles/the-top-8-placeholders-for-web-designers--net-19485
|
||||||
|
*/
|
||||||
|
@@ -1541,7 +1541,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
var bg_colour = Math.floor(Math.random() * 16777215).toString(16);
|
||||||
|
bg_colour = "#" + ("000000" + bg_colour).slice(-6);
|
||||||
|
document.bgColor = bg_colour;
|
||||||
|
-
|
||||||
|
+
|
||||||
|
http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||||
|
Creating random colors is actually more difficult than it seems. The randomness itself is easy, but aesthetically pleasing randomness is more difficult.
|
||||||
|
https://github.com/devongovett/color-generator
|
||||||
|
@@ -1561,7 +1561,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
http://tool.c7sky.com/webcolor
|
||||||
|
网页设计常用色彩搭配表
|
||||||
|
-
|
||||||
|
+
|
||||||
|
https://github.com/One-com/one-color
|
||||||
|
An OO-based JavaScript color parser/computation toolkit with support for RGB, HSV, HSL, CMYK, and alpha channels.
|
||||||
|
API 很赞
|
||||||
|
@@ -1593,7 +1593,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
color += letters[Math.floor(Math.random() * 16)]
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
-
|
||||||
|
+
|
||||||
|
// 随机生成一个无脑的颜色,格式为 '#RRGGBB'。
|
||||||
|
// _brainlessColor()
|
||||||
|
var color = Math.floor(
|
||||||
|
@@ -1959,7 +1959,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
return result.join(' ')
|
||||||
|
},
|
||||||
|
- //
|
||||||
|
+ //
|
||||||
|
cparagraph: function(min, max) {
|
||||||
|
var len = range(3, 7, min, max)
|
||||||
|
var result = []
|
||||||
|
@@ -2282,17 +2282,17 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
随机生成一个 URL。
|
||||||
|
|
||||||
|
[URL 规范](http://www.w3.org/Addressing/URL/url-spec.txt)
|
||||||
|
- http Hypertext Transfer Protocol
|
||||||
|
- ftp File Transfer protocol
|
||||||
|
- gopher The Gopher protocol
|
||||||
|
- mailto Electronic mail address
|
||||||
|
- mid Message identifiers for electronic mail
|
||||||
|
- cid Content identifiers for MIME body part
|
||||||
|
- news Usenet news
|
||||||
|
- nntp Usenet news for local NNTP access only
|
||||||
|
- prospero Access using the prospero protocols
|
||||||
|
+ http Hypertext Transfer Protocol
|
||||||
|
+ ftp File Transfer protocol
|
||||||
|
+ gopher The Gopher protocol
|
||||||
|
+ mailto Electronic mail address
|
||||||
|
+ mid Message identifiers for electronic mail
|
||||||
|
+ cid Content identifiers for MIME body part
|
||||||
|
+ news Usenet news
|
||||||
|
+ nntp Usenet news for local NNTP access only
|
||||||
|
+ prospero Access using the prospero protocols
|
||||||
|
telnet rlogin tn3270 Reference to interactive sessions
|
||||||
|
- wais Wide Area Information Servers
|
||||||
|
+ wais Wide Area Information Servers
|
||||||
|
*/
|
||||||
|
url: function(protocol, host) {
|
||||||
|
return (protocol || this.protocol()) + '://' + // protocol?
|
||||||
|
@@ -2422,9 +2422,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
西南 重庆市 四川省 贵州省 云南省 西藏自治区
|
||||||
|
西北 陕西省 甘肃省 青海省 宁夏回族自治区 新疆维吾尔自治区
|
||||||
|
港澳台 香港特别行政区 澳门特别行政区 台湾省
|
||||||
|
-
|
||||||
|
+
|
||||||
|
**排序**
|
||||||
|
-
|
||||||
|
+
|
||||||
|
```js
|
||||||
|
var map = {}
|
||||||
|
_.each(_.keys(REGIONS),function(id){
|
||||||
|
@@ -6527,7 +6527,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
|
||||||
|
"a" / "b" / "c" / "d" / "e" / "f" /
|
||||||
|
"A" / "B" / "C" / "D" / "E" / "F"
|
||||||
|
-
|
||||||
|
+
|
||||||
|
https://github.com/victorquinn/chancejs/blob/develop/chance.js#L1349
|
||||||
|
*/
|
||||||
|
guid: function() {
|
||||||
|
@@ -6629,7 +6629,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
|
||||||
|
function CaptureGroup(n) {
|
||||||
|
- Group.call(this, "capture-group"), this.index = cgs[this.offset] || (cgs[this.offset] = index++),
|
||||||
|
+ Group.call(this, "capture-group"), this.index = cgs[this.offset] || (cgs[this.offset] = index++),
|
||||||
|
this.body = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6711,7 +6711,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
return r = l ? '"' + u(l) + '"' : "end of input", "Expected " + t + " but " + r + " found.";
|
||||||
|
}
|
||||||
|
- this.expected = n, this.found = l, this.offset = u, this.line = t, this.column = r,
|
||||||
|
+ this.expected = n, this.found = l, this.offset = u, this.line = t, this.column = r,
|
||||||
|
this.name = "SyntaxError", this.message = e(n, l);
|
||||||
|
}
|
||||||
|
function u(n) {
|
||||||
|
@@ -6724,8 +6724,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
function r(l) {
|
||||||
|
function u(l, u, t) {
|
||||||
|
var r, e;
|
||||||
|
- for (r = u; t > r; r++) e = n.charAt(r), "\n" === e ? (l.seenCR || l.line++, l.column = 1,
|
||||||
|
- l.seenCR = !1) : "\r" === e || "\u2028" === e || "\u2029" === e ? (l.line++, l.column = 1,
|
||||||
|
+ for (r = u; t > r; r++) e = n.charAt(r), "\n" === e ? (l.seenCR || l.line++, l.column = 1,
|
||||||
|
+ l.seenCR = !1) : "\r" === e || "\u2028" === e || "\u2029" === e ? (l.line++, l.column = 1,
|
||||||
|
l.seenCR = !0) : (l.column++, l.seenCR = !1);
|
||||||
|
}
|
||||||
|
return Mt !== l && (Mt > l && (Mt = 0, Dt = {
|
||||||
|
@@ -6743,19 +6743,19 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
function c() {
|
||||||
|
var l, u, t, r, o;
|
||||||
|
- return l = qt, u = i(), null !== u ? (t = qt, 124 === n.charCodeAt(qt) ? (r = fl,
|
||||||
|
- qt++) : (r = null, 0 === Wt && e(sl)), null !== r ? (o = c(), null !== o ? (r = [ r, o ],
|
||||||
|
- t = r) : (qt = t, t = il)) : (qt = t, t = il), null === t && (t = al), null !== t ? (Lt = l,
|
||||||
|
- u = hl(u, t), null === u ? (qt = l, l = u) : l = u) : (qt = l, l = il)) : (qt = l,
|
||||||
|
+ return l = qt, u = i(), null !== u ? (t = qt, 124 === n.charCodeAt(qt) ? (r = fl,
|
||||||
|
+ qt++) : (r = null, 0 === Wt && e(sl)), null !== r ? (o = c(), null !== o ? (r = [ r, o ],
|
||||||
|
+ t = r) : (qt = t, t = il)) : (qt = t, t = il), null === t && (t = al), null !== t ? (Lt = l,
|
||||||
|
+ u = hl(u, t), null === u ? (qt = l, l = u) : l = u) : (qt = l, l = il)) : (qt = l,
|
||||||
|
l = il), l;
|
||||||
|
}
|
||||||
|
function i() {
|
||||||
|
var n, l, u, t, r;
|
||||||
|
- if (n = qt, l = f(), null === l && (l = al), null !== l) if (u = qt, Wt++, t = d(),
|
||||||
|
+ if (n = qt, l = f(), null === l && (l = al), null !== l) if (u = qt, Wt++, t = d(),
|
||||||
|
Wt--, null === t ? u = al : (qt = u, u = il), null !== u) {
|
||||||
|
- for (t = [], r = h(), null === r && (r = a()); null !== r; ) t.push(r), r = h(),
|
||||||
|
+ for (t = [], r = h(), null === r && (r = a()); null !== r; ) t.push(r), r = h(),
|
||||||
|
null === r && (r = a());
|
||||||
|
- null !== t ? (r = s(), null === r && (r = al), null !== r ? (Lt = n, l = dl(l, t, r),
|
||||||
|
+ null !== t ? (r = s(), null === r && (r = al), null !== r ? (Lt = n, l = dl(l, t, r),
|
||||||
|
null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n, n = il);
|
||||||
|
} else qt = n, n = il; else qt = n, n = il;
|
||||||
|
return n;
|
||||||
|
@@ -6766,148 +6766,148 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, 94 === n.charCodeAt(qt) ? (u = pl, qt++) : (u = null, 0 === Wt && e(vl)),
|
||||||
|
+ return l = qt, 94 === n.charCodeAt(qt) ? (u = pl, qt++) : (u = null, 0 === Wt && e(vl)),
|
||||||
|
null !== u && (Lt = l, u = wl()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function s() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, 36 === n.charCodeAt(qt) ? (u = Al, qt++) : (u = null, 0 === Wt && e(Cl)),
|
||||||
|
+ return l = qt, 36 === n.charCodeAt(qt) ? (u = Al, qt++) : (u = null, 0 === Wt && e(Cl)),
|
||||||
|
null !== u && (Lt = l, u = gl()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
var n, l, u;
|
||||||
|
- return n = qt, l = a(), null !== l ? (u = d(), null !== u ? (Lt = n, l = bl(l, u),
|
||||||
|
+ return n = qt, l = a(), null !== l ? (u = d(), null !== u ? (Lt = n, l = bl(l, u),
|
||||||
|
null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n, n = il), n;
|
||||||
|
}
|
||||||
|
function d() {
|
||||||
|
var n, l, u;
|
||||||
|
- return Wt++, n = qt, l = p(), null !== l ? (u = k(), null === u && (u = al), null !== u ? (Lt = n,
|
||||||
|
- l = Tl(l, u), null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n,
|
||||||
|
+ return Wt++, n = qt, l = p(), null !== l ? (u = k(), null === u && (u = al), null !== u ? (Lt = n,
|
||||||
|
+ l = Tl(l, u), null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n,
|
||||||
|
n = il), Wt--, null === n && (l = null, 0 === Wt && e(kl)), n;
|
||||||
|
}
|
||||||
|
function p() {
|
||||||
|
var n;
|
||||||
|
- return n = v(), null === n && (n = w(), null === n && (n = A(), null === n && (n = C(),
|
||||||
|
+ return n = v(), null === n && (n = w(), null === n && (n = A(), null === n && (n = C(),
|
||||||
|
null === n && (n = g(), null === n && (n = b()))))), n;
|
||||||
|
}
|
||||||
|
function v() {
|
||||||
|
var l, u, t, r, o, c;
|
||||||
|
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
|
||||||
|
- null !== u ? (t = T(), null !== t ? (44 === n.charCodeAt(qt) ? (r = ml, qt++) : (r = null,
|
||||||
|
- 0 === Wt && e(Rl)), null !== r ? (o = T(), null !== o ? (125 === n.charCodeAt(qt) ? (c = Fl,
|
||||||
|
- qt++) : (c = null, 0 === Wt && e(Ql)), null !== c ? (Lt = l, u = Sl(t, o), null === u ? (qt = l,
|
||||||
|
- l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l,
|
||||||
|
+ return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
|
||||||
|
+ null !== u ? (t = T(), null !== t ? (44 === n.charCodeAt(qt) ? (r = ml, qt++) : (r = null,
|
||||||
|
+ 0 === Wt && e(Rl)), null !== r ? (o = T(), null !== o ? (125 === n.charCodeAt(qt) ? (c = Fl,
|
||||||
|
+ qt++) : (c = null, 0 === Wt && e(Ql)), null !== c ? (Lt = l, u = Sl(t, o), null === u ? (qt = l,
|
||||||
|
+ l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function w() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
|
||||||
|
- null !== u ? (t = T(), null !== t ? (n.substr(qt, 2) === Ul ? (r = Ul, qt += 2) : (r = null,
|
||||||
|
- 0 === Wt && e(El)), null !== r ? (Lt = l, u = Gl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
|
||||||
|
+ null !== u ? (t = T(), null !== t ? (n.substr(qt, 2) === Ul ? (r = Ul, qt += 2) : (r = null,
|
||||||
|
+ 0 === Wt && e(El)), null !== r ? (Lt = l, u = Gl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function A() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
|
||||||
|
- null !== u ? (t = T(), null !== t ? (125 === n.charCodeAt(qt) ? (r = Fl, qt++) : (r = null,
|
||||||
|
- 0 === Wt && e(Ql)), null !== r ? (Lt = l, u = Bl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
|
||||||
|
+ null !== u ? (t = T(), null !== t ? (125 === n.charCodeAt(qt) ? (r = Fl, qt++) : (r = null,
|
||||||
|
+ 0 === Wt && e(Ql)), null !== r ? (Lt = l, u = Bl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function C() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, 43 === n.charCodeAt(qt) ? (u = jl, qt++) : (u = null, 0 === Wt && e($l)),
|
||||||
|
+ return l = qt, 43 === n.charCodeAt(qt) ? (u = jl, qt++) : (u = null, 0 === Wt && e($l)),
|
||||||
|
null !== u && (Lt = l, u = ql()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, 42 === n.charCodeAt(qt) ? (u = Ll, qt++) : (u = null, 0 === Wt && e(Ml)),
|
||||||
|
+ return l = qt, 42 === n.charCodeAt(qt) ? (u = Ll, qt++) : (u = null, 0 === Wt && e(Ml)),
|
||||||
|
null !== u && (Lt = l, u = Dl()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, 63 === n.charCodeAt(qt) ? (u = Hl, qt++) : (u = null, 0 === Wt && e(Ol)),
|
||||||
|
+ return l = qt, 63 === n.charCodeAt(qt) ? (u = Hl, qt++) : (u = null, 0 === Wt && e(Ol)),
|
||||||
|
null !== u && (Lt = l, u = Wl()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function k() {
|
||||||
|
var l;
|
||||||
|
- return 63 === n.charCodeAt(qt) ? (l = Hl, qt++) : (l = null, 0 === Wt && e(Ol)),
|
||||||
|
+ return 63 === n.charCodeAt(qt) ? (l = Hl, qt++) : (l = null, 0 === Wt && e(Ol)),
|
||||||
|
l;
|
||||||
|
}
|
||||||
|
function T() {
|
||||||
|
var l, u, t;
|
||||||
|
- if (l = qt, u = [], zl.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null,
|
||||||
|
- 0 === Wt && e(Il)), null !== t) for (;null !== t; ) u.push(t), zl.test(n.charAt(qt)) ? (t = n.charAt(qt),
|
||||||
|
+ if (l = qt, u = [], zl.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null,
|
||||||
|
+ 0 === Wt && e(Il)), null !== t) for (;null !== t; ) u.push(t), zl.test(n.charAt(qt)) ? (t = n.charAt(qt),
|
||||||
|
qt++) : (t = null, 0 === Wt && e(Il)); else u = il;
|
||||||
|
- return null !== u && (Lt = l, u = Jl(u)), null === u ? (qt = l, l = u) : l = u,
|
||||||
|
+ return null !== u && (Lt = l, u = Jl(u)), null === u ? (qt = l, l = u) : l = u,
|
||||||
|
l;
|
||||||
|
}
|
||||||
|
function x() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- return l = qt, 40 === n.charCodeAt(qt) ? (u = Kl, qt++) : (u = null, 0 === Wt && e(Nl)),
|
||||||
|
- null !== u ? (t = R(), null === t && (t = F(), null === t && (t = m(), null === t && (t = y()))),
|
||||||
|
- null !== t ? (41 === n.charCodeAt(qt) ? (r = Pl, qt++) : (r = null, 0 === Wt && e(Vl)),
|
||||||
|
- null !== r ? (Lt = l, u = Xl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, 40 === n.charCodeAt(qt) ? (u = Kl, qt++) : (u = null, 0 === Wt && e(Nl)),
|
||||||
|
+ null !== u ? (t = R(), null === t && (t = F(), null === t && (t = m(), null === t && (t = y()))),
|
||||||
|
+ null !== t ? (41 === n.charCodeAt(qt) ? (r = Pl, qt++) : (r = null, 0 === Wt && e(Vl)),
|
||||||
|
+ null !== r ? (Lt = l, u = Xl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function y() {
|
||||||
|
var n, l;
|
||||||
|
- return n = qt, l = c(), null !== l && (Lt = n, l = Yl(l)), null === l ? (qt = n,
|
||||||
|
+ return n = qt, l = c(), null !== l && (Lt = n, l = Yl(l)), null === l ? (qt = n,
|
||||||
|
n = l) : n = l, n;
|
||||||
|
}
|
||||||
|
function m() {
|
||||||
|
var l, u, t;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Zl ? (u = Zl, qt += 2) : (u = null, 0 === Wt && e(_l)),
|
||||||
|
- null !== u ? (t = c(), null !== t ? (Lt = l, u = nu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Zl ? (u = Zl, qt += 2) : (u = null, 0 === Wt && e(_l)),
|
||||||
|
+ null !== u ? (t = c(), null !== t ? (Lt = l, u = nu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function R() {
|
||||||
|
var l, u, t;
|
||||||
|
- return l = qt, n.substr(qt, 2) === lu ? (u = lu, qt += 2) : (u = null, 0 === Wt && e(uu)),
|
||||||
|
- null !== u ? (t = c(), null !== t ? (Lt = l, u = tu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, n.substr(qt, 2) === lu ? (u = lu, qt += 2) : (u = null, 0 === Wt && e(uu)),
|
||||||
|
+ null !== u ? (t = c(), null !== t ? (Lt = l, u = tu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function F() {
|
||||||
|
var l, u, t;
|
||||||
|
- return l = qt, n.substr(qt, 2) === ru ? (u = ru, qt += 2) : (u = null, 0 === Wt && e(eu)),
|
||||||
|
- null !== u ? (t = c(), null !== t ? (Lt = l, u = ou(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, n.substr(qt, 2) === ru ? (u = ru, qt += 2) : (u = null, 0 === Wt && e(eu)),
|
||||||
|
+ null !== u ? (t = c(), null !== t ? (Lt = l, u = ou(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function Q() {
|
||||||
|
var l, u, t, r, o;
|
||||||
|
- if (Wt++, l = qt, 91 === n.charCodeAt(qt) ? (u = iu, qt++) : (u = null, 0 === Wt && e(au)),
|
||||||
|
- null !== u) if (94 === n.charCodeAt(qt) ? (t = pl, qt++) : (t = null, 0 === Wt && e(vl)),
|
||||||
|
+ if (Wt++, l = qt, 91 === n.charCodeAt(qt) ? (u = iu, qt++) : (u = null, 0 === Wt && e(au)),
|
||||||
|
+ null !== u) if (94 === n.charCodeAt(qt) ? (t = pl, qt++) : (t = null, 0 === Wt && e(vl)),
|
||||||
|
null === t && (t = al), null !== t) {
|
||||||
|
- for (r = [], o = S(), null === o && (o = U()); null !== o; ) r.push(o), o = S(),
|
||||||
|
+ for (r = [], o = S(), null === o && (o = U()); null !== o; ) r.push(o), o = S(),
|
||||||
|
null === o && (o = U());
|
||||||
|
- null !== r ? (93 === n.charCodeAt(qt) ? (o = fu, qt++) : (o = null, 0 === Wt && e(su)),
|
||||||
|
- null !== o ? (Lt = l, u = hu(t, r), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ null !== r ? (93 === n.charCodeAt(qt) ? (o = fu, qt++) : (o = null, 0 === Wt && e(su)),
|
||||||
|
+ null !== o ? (Lt = l, u = hu(t, r), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il);
|
||||||
|
} else qt = l, l = il; else qt = l, l = il;
|
||||||
|
return Wt--, null === l && (u = null, 0 === Wt && e(cu)), l;
|
||||||
|
}
|
||||||
|
function S() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- return Wt++, l = qt, u = U(), null !== u ? (45 === n.charCodeAt(qt) ? (t = pu, qt++) : (t = null,
|
||||||
|
- 0 === Wt && e(vu)), null !== t ? (r = U(), null !== r ? (Lt = l, u = wu(u, r), null === u ? (qt = l,
|
||||||
|
- l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il), Wt--,
|
||||||
|
+ return Wt++, l = qt, u = U(), null !== u ? (45 === n.charCodeAt(qt) ? (t = pu, qt++) : (t = null,
|
||||||
|
+ 0 === Wt && e(vu)), null !== t ? (r = U(), null !== r ? (Lt = l, u = wu(u, r), null === u ? (qt = l,
|
||||||
|
+ l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il), Wt--,
|
||||||
|
null === l && (u = null, 0 === Wt && e(du)), l;
|
||||||
|
}
|
||||||
|
function U() {
|
||||||
|
var n, l;
|
||||||
|
- return Wt++, n = G(), null === n && (n = E()), Wt--, null === n && (l = null, 0 === Wt && e(Au)),
|
||||||
|
+ return Wt++, n = G(), null === n && (n = E()), Wt--, null === n && (l = null, 0 === Wt && e(Au)),
|
||||||
|
n;
|
||||||
|
}
|
||||||
|
function E() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, Cu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null, 0 === Wt && e(gu)),
|
||||||
|
+ return l = qt, Cu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null, 0 === Wt && e(gu)),
|
||||||
|
null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function G() {
|
||||||
|
var n;
|
||||||
|
- return n = L(), null === n && (n = Y(), null === n && (n = H(), null === n && (n = O(),
|
||||||
|
- null === n && (n = W(), null === n && (n = z(), null === n && (n = I(), null === n && (n = J(),
|
||||||
|
- null === n && (n = K(), null === n && (n = N(), null === n && (n = P(), null === n && (n = V(),
|
||||||
|
- null === n && (n = X(), null === n && (n = _(), null === n && (n = nl(), null === n && (n = ll(),
|
||||||
|
+ return n = L(), null === n && (n = Y(), null === n && (n = H(), null === n && (n = O(),
|
||||||
|
+ null === n && (n = W(), null === n && (n = z(), null === n && (n = I(), null === n && (n = J(),
|
||||||
|
+ null === n && (n = K(), null === n && (n = N(), null === n && (n = P(), null === n && (n = V(),
|
||||||
|
+ null === n && (n = X(), null === n && (n = _(), null === n && (n = nl(), null === n && (n = ll(),
|
||||||
|
null === n && (n = ul(), null === n && (n = tl()))))))))))))))))), n;
|
||||||
|
}
|
||||||
|
function B() {
|
||||||
|
@@ -6916,154 +6916,154 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
}
|
||||||
|
function j() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, 46 === n.charCodeAt(qt) ? (u = ku, qt++) : (u = null, 0 === Wt && e(Tu)),
|
||||||
|
+ return l = qt, 46 === n.charCodeAt(qt) ? (u = ku, qt++) : (u = null, 0 === Wt && e(Tu)),
|
||||||
|
null !== u && (Lt = l, u = xu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function $() {
|
||||||
|
var l, u;
|
||||||
|
- return Wt++, l = qt, mu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null,
|
||||||
|
- 0 === Wt && e(Ru)), null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u,
|
||||||
|
+ return Wt++, l = qt, mu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null,
|
||||||
|
+ 0 === Wt && e(Ru)), null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u,
|
||||||
|
Wt--, null === l && (u = null, 0 === Wt && e(yu)), l;
|
||||||
|
}
|
||||||
|
function q() {
|
||||||
|
var n;
|
||||||
|
- return n = M(), null === n && (n = D(), null === n && (n = Y(), null === n && (n = H(),
|
||||||
|
- null === n && (n = O(), null === n && (n = W(), null === n && (n = z(), null === n && (n = I(),
|
||||||
|
- null === n && (n = J(), null === n && (n = K(), null === n && (n = N(), null === n && (n = P(),
|
||||||
|
- null === n && (n = V(), null === n && (n = X(), null === n && (n = Z(), null === n && (n = _(),
|
||||||
|
- null === n && (n = nl(), null === n && (n = ll(), null === n && (n = ul(), null === n && (n = tl()))))))))))))))))))),
|
||||||
|
+ return n = M(), null === n && (n = D(), null === n && (n = Y(), null === n && (n = H(),
|
||||||
|
+ null === n && (n = O(), null === n && (n = W(), null === n && (n = z(), null === n && (n = I(),
|
||||||
|
+ null === n && (n = J(), null === n && (n = K(), null === n && (n = N(), null === n && (n = P(),
|
||||||
|
+ null === n && (n = V(), null === n && (n = X(), null === n && (n = Z(), null === n && (n = _(),
|
||||||
|
+ null === n && (n = nl(), null === n && (n = ll(), null === n && (n = ul(), null === n && (n = tl()))))))))))))))))))),
|
||||||
|
n;
|
||||||
|
}
|
||||||
|
function L() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
|
||||||
|
null !== u && (Lt = l, u = Su()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function M() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
|
||||||
|
null !== u && (Lt = l, u = Uu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function D() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Eu ? (u = Eu, qt += 2) : (u = null, 0 === Wt && e(Gu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Eu ? (u = Eu, qt += 2) : (u = null, 0 === Wt && e(Gu)),
|
||||||
|
null !== u && (Lt = l, u = Bu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function H() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === ju ? (u = ju, qt += 2) : (u = null, 0 === Wt && e($u)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === ju ? (u = ju, qt += 2) : (u = null, 0 === Wt && e($u)),
|
||||||
|
null !== u && (Lt = l, u = qu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function O() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Lu ? (u = Lu, qt += 2) : (u = null, 0 === Wt && e(Mu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Lu ? (u = Lu, qt += 2) : (u = null, 0 === Wt && e(Mu)),
|
||||||
|
null !== u && (Lt = l, u = Du()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function W() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Hu ? (u = Hu, qt += 2) : (u = null, 0 === Wt && e(Ou)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Hu ? (u = Hu, qt += 2) : (u = null, 0 === Wt && e(Ou)),
|
||||||
|
null !== u && (Lt = l, u = Wu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function z() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === zu ? (u = zu, qt += 2) : (u = null, 0 === Wt && e(Iu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === zu ? (u = zu, qt += 2) : (u = null, 0 === Wt && e(Iu)),
|
||||||
|
null !== u && (Lt = l, u = Ju()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function I() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Ku ? (u = Ku, qt += 2) : (u = null, 0 === Wt && e(Nu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Ku ? (u = Ku, qt += 2) : (u = null, 0 === Wt && e(Nu)),
|
||||||
|
null !== u && (Lt = l, u = Pu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function J() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Vu ? (u = Vu, qt += 2) : (u = null, 0 === Wt && e(Xu)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Vu ? (u = Vu, qt += 2) : (u = null, 0 === Wt && e(Xu)),
|
||||||
|
null !== u && (Lt = l, u = Yu()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function K() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Zu ? (u = Zu, qt += 2) : (u = null, 0 === Wt && e(_u)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Zu ? (u = Zu, qt += 2) : (u = null, 0 === Wt && e(_u)),
|
||||||
|
null !== u && (Lt = l, u = nt()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function N() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === lt ? (u = lt, qt += 2) : (u = null, 0 === Wt && e(ut)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === lt ? (u = lt, qt += 2) : (u = null, 0 === Wt && e(ut)),
|
||||||
|
null !== u && (Lt = l, u = tt()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function P() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === rt ? (u = rt, qt += 2) : (u = null, 0 === Wt && e(et)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === rt ? (u = rt, qt += 2) : (u = null, 0 === Wt && e(et)),
|
||||||
|
null !== u && (Lt = l, u = ot()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function V() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === ct ? (u = ct, qt += 2) : (u = null, 0 === Wt && e(it)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === ct ? (u = ct, qt += 2) : (u = null, 0 === Wt && e(it)),
|
||||||
|
null !== u && (Lt = l, u = at()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function X() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === ft ? (u = ft, qt += 2) : (u = null, 0 === Wt && e(st)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === ft ? (u = ft, qt += 2) : (u = null, 0 === Wt && e(st)),
|
||||||
|
null !== u && (Lt = l, u = ht()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function Y() {
|
||||||
|
var l, u, t;
|
||||||
|
- return l = qt, n.substr(qt, 2) === dt ? (u = dt, qt += 2) : (u = null, 0 === Wt && e(pt)),
|
||||||
|
- null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
|
||||||
|
- null !== t ? (Lt = l, u = wt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, n.substr(qt, 2) === dt ? (u = dt, qt += 2) : (u = null, 0 === Wt && e(pt)),
|
||||||
|
+ null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
|
||||||
|
+ null !== t ? (Lt = l, u = wt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function Z() {
|
||||||
|
var l, u, t;
|
||||||
|
- return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
|
||||||
|
- null !== u ? (gt.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(bt)),
|
||||||
|
- null !== t ? (Lt = l, u = kt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
|
||||||
|
+ null !== u ? (gt.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(bt)),
|
||||||
|
+ null !== t ? (Lt = l, u = kt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
function _() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- if (l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
|
||||||
|
+ if (l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
|
||||||
|
null !== u) {
|
||||||
|
- if (t = [], yt.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(mt)),
|
||||||
|
- null !== r) for (;null !== r; ) t.push(r), yt.test(n.charAt(qt)) ? (r = n.charAt(qt),
|
||||||
|
+ if (t = [], yt.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(mt)),
|
||||||
|
+ null !== r) for (;null !== r; ) t.push(r), yt.test(n.charAt(qt)) ? (r = n.charAt(qt),
|
||||||
|
qt++) : (r = null, 0 === Wt && e(mt)); else t = il;
|
||||||
|
- null !== t ? (Lt = l, u = Rt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ null !== t ? (Lt = l, u = Rt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il);
|
||||||
|
} else qt = l, l = il;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
function nl() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- if (l = qt, n.substr(qt, 2) === Ft ? (u = Ft, qt += 2) : (u = null, 0 === Wt && e(Qt)),
|
||||||
|
+ if (l = qt, n.substr(qt, 2) === Ft ? (u = Ft, qt += 2) : (u = null, 0 === Wt && e(Qt)),
|
||||||
|
null !== u) {
|
||||||
|
- if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
|
||||||
|
- null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
|
||||||
|
+ if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
|
||||||
|
+ null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
|
||||||
|
qt++) : (r = null, 0 === Wt && e(Ut)); else t = il;
|
||||||
|
- null !== t ? (Lt = l, u = Et(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ null !== t ? (Lt = l, u = Et(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il);
|
||||||
|
} else qt = l, l = il;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
function ll() {
|
||||||
|
var l, u, t, r;
|
||||||
|
- if (l = qt, n.substr(qt, 2) === Gt ? (u = Gt, qt += 2) : (u = null, 0 === Wt && e(Bt)),
|
||||||
|
+ if (l = qt, n.substr(qt, 2) === Gt ? (u = Gt, qt += 2) : (u = null, 0 === Wt && e(Bt)),
|
||||||
|
null !== u) {
|
||||||
|
- if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
|
||||||
|
- null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
|
||||||
|
+ if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
|
||||||
|
+ null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
|
||||||
|
qt++) : (r = null, 0 === Wt && e(Ut)); else t = il;
|
||||||
|
- null !== t ? (Lt = l, u = jt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ null !== t ? (Lt = l, u = jt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il);
|
||||||
|
} else qt = l, l = il;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
function ul() {
|
||||||
|
var l, u;
|
||||||
|
- return l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
|
||||||
|
+ return l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
|
||||||
|
null !== u && (Lt = l, u = $t()), null === u ? (qt = l, l = u) : l = u, l;
|
||||||
|
}
|
||||||
|
function tl() {
|
||||||
|
var l, u, t;
|
||||||
|
- return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
|
||||||
|
- null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
|
||||||
|
- null !== t ? (Lt = l, u = bu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
+ return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
|
||||||
|
+ null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
|
||||||
|
+ null !== t ? (Lt = l, u = bu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
|
||||||
|
l = il)) : (qt = l, l = il), l;
|
||||||
|
}
|
||||||
|
var rl, el = arguments.length > 1 ? arguments[1] : {}, ol = {
|
||||||
|
@@ -7234,7 +7234,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
var Util = __webpack_require__(3)
|
||||||
|
var Random = __webpack_require__(5)
|
||||||
|
/*
|
||||||
|
-
|
||||||
|
+
|
||||||
|
*/
|
||||||
|
var Handler = {
|
||||||
|
extend: Util.extend
|
||||||
|
@@ -7481,7 +7481,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
return Random.integer(min, max)
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
-
|
||||||
|
+
|
||||||
|
*/
|
||||||
|
charset: function(node, result, cache) {
|
||||||
|
// node.invert
|
||||||
|
@@ -7642,11 +7642,11 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
## valid(template, data)
|
||||||
|
|
||||||
|
校验真实数据 data 是否与数据模板 template 匹配。
|
||||||
|
-
|
||||||
|
+
|
||||||
|
实现思路:
|
||||||
|
1. 解析规则。
|
||||||
|
先把数据模板 template 解析为更方便机器解析的 JSON-Schame
|
||||||
|
- name 属性名
|
||||||
|
+ name 属性名
|
||||||
|
type 属性值类型
|
||||||
|
template 属性值模板
|
||||||
|
properties 对象属性数组
|
||||||
|
@@ -7655,7 +7655,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
2. 递归验证规则。
|
||||||
|
然后用 JSON-Schema 校验真实数据,校验项包括属性名、值类型、值、值生成规则。
|
||||||
|
|
||||||
|
- 提示信息
|
||||||
|
+ 提示信息
|
||||||
|
https://github.com/fge/json-schema-validator/blob/master/src/main/resources/com/github/fge/jsonschema/validator/validation.properties
|
||||||
|
[JSON-Schama validator](http://json-schema-validator.herokuapp.com/)
|
||||||
|
[Regexp Demo](http://demos.forbeslindesay.co.uk/regexp/)
|
||||||
|
@@ -7693,8 +7693,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
+step
|
||||||
|
整数部分
|
||||||
|
小数部分
|
||||||
|
- boolean
|
||||||
|
- string
|
||||||
|
+ boolean
|
||||||
|
+ string
|
||||||
|
min-max
|
||||||
|
count
|
||||||
|
## properties
|
||||||
|
@@ -7949,9 +7949,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
/*
|
||||||
|
完善、友好的提示信息
|
||||||
|
-
|
||||||
|
+
|
||||||
|
Equal, not equal to, greater than, less than, greater than or equal to, less than or equal to
|
||||||
|
- 路径 验证类型 描述
|
||||||
|
+ 路径 验证类型 描述
|
||||||
|
|
||||||
|
Expect path.name is less than or equal to expected, but path.name is actual.
|
||||||
|
|
||||||
|
@@ -8264,7 +8264,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
Util.extend(MockXMLHttpRequest.prototype, {
|
||||||
|
// https://xhr.spec.whatwg.org/#the-open()-method
|
||||||
|
// Sets the request method, request URL, and synchronous flag.
|
||||||
|
- open: function(method, url, async, username, password) {
|
||||||
|
+ open: function(method, url, async = true, username, password) {
|
||||||
|
var that = this
|
||||||
|
|
||||||
|
Util.extend(this.custom, {
|
||||||
|
@@ -8310,6 +8310,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
var xhr = createNativeXMLHttpRequest()
|
||||||
|
this.custom.xhr = xhr
|
||||||
|
|
||||||
|
+ MockXMLHttpRequest.prototype.upload = xhr.upload
|
||||||
|
+
|
||||||
|
// 初始化所有事件,用于监听原生 XHR 对象的事件
|
||||||
|
for (var i = 0; i < XHR_EVENTS.length; i++) {
|
||||||
|
xhr.addEventListener(XHR_EVENTS[i], handle)
|
||||||
|
@@ -8360,6 +8362,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
// 原生 XHR
|
||||||
|
if (!this.match) {
|
||||||
|
+ this.custom.xhr.responseType = this.responseType || ''
|
||||||
|
this.custom.xhr.send(data)
|
||||||
|
return
|
||||||
|
}
|
14820
pnpm-lock.yaml
generated
@@ -22,8 +22,7 @@ function initSvgLogo(id) {
|
|||||||
<path style="fill:currentColor" d="M77.9,126.6c0,3.9-2.8,7.2-6.7,7.9c-7.8,1.5-14.8,5.9-19.7,12.2c-2.7,3.5-7.6,4.2-11.2,1.6
|
<path style="fill:currentColor" d="M77.9,126.6c0,3.9-2.8,7.2-6.7,7.9c-7.8,1.5-14.8,5.9-19.7,12.2c-2.7,3.5-7.6,4.2-11.2,1.6
|
||||||
c-3.6-2.6-4.3-7.6-1.7-11.2c0.1-0.1,0.2-0.3,0.3-0.4c4.1-5.2,9.3-9.6,15.1-12.8c4.4-2.5,9.1-4.2,14-5.1
|
c-3.6-2.6-4.3-7.6-1.7-11.2c0.1-0.1,0.2-0.3,0.3-0.4c4.1-5.2,9.3-9.6,15.1-12.8c4.4-2.5,9.1-4.2,14-5.1
|
||||||
C73.3,117.7,77.9,121.3,77.9,126.6z" />
|
C73.3,117.7,77.9,121.3,77.9,126.6z" />
|
||||||
</svg>
|
</svg>`;
|
||||||
`;
|
|
||||||
const appEl = document.querySelector(id);
|
const appEl = document.querySelector(id);
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.innerHTML = svgStr;
|
div.innerHTML = svgStr;
|
||||||
@@ -34,11 +33,12 @@ function initSvgLogo(id) {
|
|||||||
|
|
||||||
function addThemeColorCssVars() {
|
function addThemeColorCssVars() {
|
||||||
const key = '__THEME_COLOR__';
|
const key = '__THEME_COLOR__';
|
||||||
const themeColor = window.localStorage.getItem(key) || '#1890ff';
|
const defaultColor = '#1890ff';
|
||||||
|
const themeColor = window.localStorage.getItem(key) || defaultColor;
|
||||||
const cssVars = `--primary-color: ${themeColor}`;
|
const cssVars = `--primary-color: ${themeColor}`;
|
||||||
document.documentElement.style.cssText = cssVars;
|
document.documentElement.style.cssText = cssVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
initSvgLogo('#loadingLogo');
|
|
||||||
|
|
||||||
addThemeColorCssVars();
|
addThemeColorCssVars();
|
||||||
|
|
||||||
|
initSvgLogo('#loadingLogo');
|
||||||
|
4
scripts/cleanup.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env zx
|
||||||
|
import { $ } from 'zx';
|
||||||
|
|
||||||
|
$`pnpm rimraf node_modules dist pnpm-lock.yaml`;
|
@@ -13,11 +13,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { zhCN, dateZhCN } from 'naive-ui';
|
import { dateZhCN, zhCN } from 'naive-ui';
|
||||||
import { useThemeStore, subscribeStore } from '@/store';
|
import { subscribeStore, useThemeStore } from '@/store';
|
||||||
|
import { useGlobalEvents } from '@/composables';
|
||||||
|
|
||||||
const theme = useThemeStore();
|
const theme = useThemeStore();
|
||||||
|
|
||||||
subscribeStore();
|
subscribeStore();
|
||||||
|
useGlobalEvents();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
BIN
src/assets/fonts/aguazyuan-bold.ttf
Normal file
BIN
src/assets/fonts/aguazyuan-light.ttf
Normal file
BIN
src/assets/fonts/aguazyuan-regular.ttf
Normal file
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 351 B |
1
src/assets/svg-icon/custom-icon.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M19 10c0 1.38-2.12 2.5-3.5 2.5s-2.75-1.12-2.75-2.5h-1.5c0 1.38-1.37 2.5-2.75 2.5S5 11.38 5 10h-.75c-.16.64-.25 1.31-.25 2a8 8 0 0 0 8 8a8 8 0 0 0 8-8c0-.69-.09-1.36-.25-2H19m-7-6C9.04 4 6.45 5.61 5.07 8h13.86C17.55 5.61 14.96 4 12 4m10 8a10 10 0 0 1-10 10A10 10 0 0 1 2 12A10 10 0 0 1 12 2a10 10 0 0 1 10 10m-10 5.23c-1.75 0-3.29-.73-4.19-1.81L9.23 14c.45.72 1.52 1.23 2.77 1.23s2.32-.51 2.77-1.23l1.42 1.42c-.9 1.08-2.44 1.81-4.19 1.81Z"></path></svg>
|
After Width: | Height: | Size: 702 B |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 371 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
1
src/assets/svg-icon/no-icon.svg
Normal file
After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
@@ -7,13 +7,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-show="isEmpty" class="absolute-center">
|
<div v-show="isEmpty" class="absolute-center">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<icon-custom-empty-data :class="iconClass" />
|
<icon-local-empty-data :class="iconClass" />
|
||||||
<p class="absolute-lb w-full text-center" :class="descClass">{{ emptyDesc }}</p>
|
<p class="absolute-lb w-full text-center" :class="descClass">{{ emptyDesc }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="!network" class="absolute-center">
|
<div v-show="!network" class="absolute-center">
|
||||||
<div class="relative" :class="{ 'cursor-pointer': showNetworkReload }" @click="handleReload">
|
<div class="relative" :class="{ 'cursor-pointer': showNetworkReload }" @click="handleReload">
|
||||||
<icon-custom-network-error :class="iconClass" />
|
<icon-local-network-error :class="iconClass" />
|
||||||
<p class="absolute-lb w-full text-center" :class="descClass">{{ networkErrorDesc }}</p>
|
<p class="absolute-lb w-full text-center" :class="descClass">{{ networkErrorDesc }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,10 +22,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, watch, nextTick, onUnmounted } from 'vue';
|
import { computed, nextTick, onUnmounted, watch } from 'vue';
|
||||||
import { NETWORK_ERROR_MSG } from '@/config';
|
import { NETWORK_ERROR_MSG } from '@/config';
|
||||||
import { useBoolean } from '@/hooks';
|
import { useBoolean } from '@/hooks';
|
||||||
|
|
||||||
|
defineOptions({ name: 'LoadingEmptyWrapper' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** 是否加载 */
|
/** 是否加载 */
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@@ -53,7 +55,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
emptyDesc: '暂无数据',
|
emptyDesc: '暂无数据',
|
||||||
iconClass: 'text-320px text-primary',
|
iconClass: 'text-320px text-primary',
|
||||||
descClass: 'text-16px text-[#666]',
|
descClass: 'text-16px text-[#666]',
|
||||||
showNetworkReload: false,
|
showNetworkReload: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// 网络状态
|
// 网络状态
|
||||||
@@ -79,7 +81,7 @@ function handleReload() {
|
|||||||
|
|
||||||
const stopHandle = watch(
|
const stopHandle = watch(
|
||||||
() => props.loading,
|
() => props.loading,
|
||||||
(newValue) => {
|
newValue => {
|
||||||
// 结束加载判断一下网络状态
|
// 结束加载判断一下网络状态
|
||||||
if (!newValue) {
|
if (!newValue) {
|
||||||
setNetwork(window.navigator.onLine);
|
setNetwork(window.navigator.onLine);
|
||||||
@@ -91,4 +93,5 @@ onUnmounted(() => {
|
|||||||
stopHandle();
|
stopHandle();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -9,11 +9,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
defineOptions({ name: 'LoginAgreement' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** 是否勾选 */
|
/** 是否勾选 */
|
||||||
value?: boolean;
|
value?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:value', value: boolean): void;
|
(e: 'update:value', value: boolean): void;
|
||||||
/** 点击协议 */
|
/** 点击协议 */
|
||||||
@@ -22,10 +28,6 @@ interface Emits {
|
|||||||
(e: 'click-policy'): void;
|
(e: 'click-policy'): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
value: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const checked = computed({
|
const checked = computed({
|
||||||
@@ -34,7 +36,7 @@ const checked = computed({
|
|||||||
},
|
},
|
||||||
set(newValue: boolean) {
|
set(newValue: boolean) {
|
||||||
emit('update:value', newValue);
|
emit('update:value', newValue);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleClickProtocol() {
|
function handleClickProtocol() {
|
||||||
@@ -44,4 +46,5 @@ function handleClickPolicy() {
|
|||||||
emit('click-policy');
|
emit('click-policy');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -1,10 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="bg-white text-[#333639] dark:(bg-[#18181c] text-white text-opacity-82) transition-all duration-300 ease-in-out"
|
class="dark:bg-[#18181c] dark:text-white dark:text-opacity-82 transition-all duration-300 ease-in-out"
|
||||||
|
:class="inverted ? 'bg-[#001428] text-white' : 'bg-white text-[#333639]'"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
defineOptions({ name: 'DarkModeContainer' });
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
inverted?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
withDefaults(defineProps<Props>(), {
|
||||||
|
inverted: false
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex-center text-18px hover:text-primary cursor-pointer" @click="handleSwitch">
|
<div class="flex-center text-18px cursor-pointer" @click="handleSwitch">
|
||||||
<icon-mdi-moon-waning-crescent v-if="darkMode" />
|
<icon-mdi-moon-waning-crescent v-if="darkMode" />
|
||||||
<icon-mdi-white-balance-sunny v-else />
|
<icon-mdi-white-balance-sunny v-else />
|
||||||
</div>
|
</div>
|
||||||
@@ -8,19 +8,21 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
defineOptions({ name: 'DarkModeSwitch' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** 暗黑模式 */
|
/** 暗黑模式 */
|
||||||
dark?: boolean;
|
dark?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
dark: false
|
||||||
|
});
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:dark', darkMode: boolean): void;
|
(e: 'update:dark', darkMode: boolean): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
dark: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const darkMode = computed({
|
const darkMode = computed({
|
||||||
@@ -29,11 +31,12 @@ const darkMode = computed({
|
|||||||
},
|
},
|
||||||
set(newValue: boolean) {
|
set(newValue: boolean) {
|
||||||
emit('update:dark', newValue);
|
emit('update:dark', newValue);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleSwitch() {
|
function handleSwitch() {
|
||||||
darkMode.value = !darkMode.value;
|
darkMode.value = !darkMode.value;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex-col-center wh-full">
|
<div class="flex-col-center wh-full">
|
||||||
<div class="text-400px text-primary">
|
<div class="text-400px text-primary">
|
||||||
<icon-custom-no-permission v-if="type === '403'" />
|
<icon-local-no-permission v-if="type === '403'" />
|
||||||
<icon-custom-not-found v-if="type === '404'" />
|
<icon-local-not-found v-if="type === '404'" />
|
||||||
<icon-custom-service-error v-if="type === '500'" />
|
<icon-local-service-error v-if="type === '500'" />
|
||||||
</div>
|
</div>
|
||||||
<router-link :to="{ name: routeHomePath }">
|
<router-link :to="{ name: routeHomePath }">
|
||||||
<n-button type="primary">回到首页</n-button>
|
<n-button type="primary">回到首页</n-button>
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { routeName } from '@/router';
|
import { routeName } from '@/router';
|
||||||
|
|
||||||
|
defineOptions({ name: 'ExceptionBase' });
|
||||||
|
|
||||||
type ExceptionType = '403' | '404' | '500';
|
type ExceptionType = '403' | '404' | '500';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -25,4 +27,5 @@ defineProps<Props>();
|
|||||||
|
|
||||||
const routeHomePath = routeName('root');
|
const routeHomePath = routeName('root');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
@@ -2,36 +2,47 @@
|
|||||||
<div v-if="showTooltip">
|
<div v-if="showTooltip">
|
||||||
<n-tooltip :placement="placement" trigger="hover">
|
<n-tooltip :placement="placement" trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div class="flex-center h-full cursor-pointer hover:bg-[#f6f6f6] dark:hover:bg-[#333]" :class="contentClass">
|
<div class="flex-center h-full cursor-pointer dark:hover:bg-[#333]" :class="contentClassName">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
{{ tooltipContent }}
|
{{ tooltipContent }}
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex-center cursor-pointer hover:bg-[#f6f6f6] dark:hover:bg-[#333]" :class="contentClass">
|
<div v-else class="flex-center cursor-pointer dark:hover:bg-[#333]" :class="contentClassName">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import type { FollowerPlacement } from 'vueuc';
|
import type { PopoverPlacement } from 'naive-ui';
|
||||||
|
|
||||||
|
defineOptions({ name: 'HoverContainer' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** tooltip显示文本 */
|
/** tooltip显示文本 */
|
||||||
tooltipContent?: string;
|
tooltipContent?: string;
|
||||||
/** tooltip的位置 */
|
/** tooltip的位置 */
|
||||||
placement?: FollowerPlacement;
|
placement?: PopoverPlacement;
|
||||||
/** class类 */
|
/** class类 */
|
||||||
contentClass?: string;
|
contentClass?: string;
|
||||||
|
/** 反转模式下 */
|
||||||
|
inverted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
tooltipContent: '',
|
tooltipContent: '',
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
contentClass: '',
|
contentClass: '',
|
||||||
|
inverted: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const showTooltip = computed(() => Boolean(props.tooltipContent));
|
const showTooltip = computed(() => Boolean(props.tooltipContent));
|
||||||
|
|
||||||
|
const contentClassName = computed(
|
||||||
|
() => `${props.contentClass} ${props.inverted ? 'hover:bg-primary' : 'hover:bg-[#f6f6f6]'}`
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, h } from 'vue';
|
import { defineComponent, h } from 'vue';
|
||||||
import { useLoadingBar, useDialog, useMessage, useNotification } from 'naive-ui';
|
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui';
|
||||||
|
|
||||||
|
defineOptions({ name: 'NaiveProvider' });
|
||||||
|
|
||||||
// 挂载naive组件的方法至window, 以便在路由钩子函数和请求函数里面调用
|
// 挂载naive组件的方法至window, 以便在路由钩子函数和请求函数里面调用
|
||||||
function registerNaiveTools() {
|
function registerNaiveTools() {
|
||||||
@@ -24,12 +26,13 @@ function registerNaiveTools() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const NaiveProviderContent = defineComponent({
|
const NaiveProviderContent = defineComponent({
|
||||||
|
name: 'NaiveProviderContent',
|
||||||
setup() {
|
setup() {
|
||||||
registerNaiveTools();
|
registerNaiveTools();
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
return h('div');
|
return h('div');
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<icon-custom-logo-fill v-if="fill" />
|
<icon-local-logo-fill v-if="fill" />
|
||||||
<icon-custom-logo v-else />
|
<icon-local-logo v-else />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
defineOptions({ name: 'SystemLogo' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** logo是否填充 */
|
/** logo是否填充 */
|
||||||
fill?: boolean;
|
fill?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
withDefaults(defineProps<Props>(), {
|
withDefaults(defineProps<Props>(), {
|
||||||
fill: false,
|
fill: false
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -7,11 +7,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, onMounted } from 'vue';
|
import { computed, onMounted, ref, watch } from 'vue';
|
||||||
import { useElementSize } from '@vueuse/core';
|
import { useElementSize } from '@vueuse/core';
|
||||||
import BScroll from '@better-scroll/core';
|
import BScroll from '@better-scroll/core';
|
||||||
import type { Options } from '@better-scroll/core';
|
import type { Options } from '@better-scroll/core';
|
||||||
|
|
||||||
|
defineOptions({ name: 'BetterScroll' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** better-scroll的配置: https://better-scroll.github.io/docs/zh-CN/guide/base-scroll-options.html */
|
/** better-scroll的配置: https://better-scroll.github.io/docs/zh-CN/guide/base-scroll-options.html */
|
||||||
options: Options;
|
options: Options;
|
||||||
@@ -44,4 +46,5 @@ onMounted(() => {
|
|||||||
|
|
||||||
defineExpose({ instance });
|
defineExpose({ instance });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -2,10 +2,14 @@
|
|||||||
<span>{{ value }}</span>
|
<span>{{ value }}</span>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted, watch, watchEffect } from 'vue';
|
import { computed, onMounted, ref, watch, watchEffect } from 'vue';
|
||||||
import { useTransition, TransitionPresets } from '@vueuse/core';
|
import { TransitionPresets, useTransition } from '@vueuse/core';
|
||||||
import { isNumber } from '@/utils';
|
import { isNumber } from '@/utils';
|
||||||
|
|
||||||
|
defineOptions({ name: 'CountTo' });
|
||||||
|
|
||||||
|
type TansitionKey = keyof typeof TransitionPresets;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** 初始值 */
|
/** 初始值 */
|
||||||
startValue?: number;
|
startValue?: number;
|
||||||
@@ -28,7 +32,7 @@ interface Props {
|
|||||||
/** 使用缓冲动画函数 */
|
/** 使用缓冲动画函数 */
|
||||||
useEasing?: boolean;
|
useEasing?: boolean;
|
||||||
/** 缓冲动画函数类型 */
|
/** 缓冲动画函数类型 */
|
||||||
transition?: string;
|
transition?: TansitionKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -42,13 +46,15 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
separator: ',',
|
separator: ',',
|
||||||
decimal: '.',
|
decimal: '.',
|
||||||
useEasing: true,
|
useEasing: true,
|
||||||
transition: 'linear',
|
transition: 'linear'
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
interface Emits {
|
||||||
(e: 'on-started'): void;
|
(e: 'on-started'): void;
|
||||||
(e: 'on-finished'): void;
|
(e: 'on-finished'): void;
|
||||||
}>();
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const source = ref(props.startValue);
|
const source = ref(props.startValue);
|
||||||
let outputValue = useTransition(source);
|
let outputValue = useTransition(source);
|
||||||
@@ -61,7 +67,7 @@ function run() {
|
|||||||
duration: props.duration,
|
duration: props.duration,
|
||||||
onStarted: () => emit('on-started'),
|
onStarted: () => emit('on-started'),
|
||||||
onFinished: () => emit('on-finished'),
|
onFinished: () => emit('on-finished'),
|
||||||
...(props.useEasing ? { transition: TransitionPresets[props.transition] } : {}),
|
...(props.useEasing ? { transition: TransitionPresets[props.transition] } : {})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +82,7 @@ function formatNumber(num: number | string) {
|
|||||||
}
|
}
|
||||||
const { decimals, decimal, separator, suffix, prefix } = props;
|
const { decimals, decimal, separator, suffix, prefix } = props;
|
||||||
let number = Number(num).toFixed(decimals);
|
let number = Number(num).toFixed(decimals);
|
||||||
number += '';
|
number = String(number);
|
||||||
|
|
||||||
const x = number.split('.');
|
const x = number.split('.');
|
||||||
let x1 = x[0];
|
let x1 = x[0];
|
||||||
@@ -106,3 +112,5 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
@@ -5,6 +5,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import WebSiteLink from './WebSiteLink.vue';
|
import WebSiteLink from './WebSiteLink.vue';
|
||||||
|
|
||||||
|
defineOptions({ name: 'GithubLink' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** github链接 */
|
/** github链接 */
|
||||||
link: string;
|
link: string;
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-input v-model:value="modelValue" readonly placeholder="点击选择图标">
|
<n-input v-model:value="modelValue" readonly placeholder="点击选择图标">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<Icon :icon="modelValue ? modelValue : emptyIcon" class="text-30px p-5px" />
|
<svg-icon :icon="selectedIcon" class="text-30px p-5px" />
|
||||||
</template>
|
</template>
|
||||||
</n-input>
|
</n-input>
|
||||||
</template>
|
</template>
|
||||||
@@ -12,10 +12,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<div v-if="iconsList.length > 0" class="grid grid-cols-9 h-auto overflow-auto">
|
<div v-if="iconsList.length > 0" class="grid grid-cols-9 h-auto overflow-auto">
|
||||||
<template v-for="iconItem in iconsList" :key="iconItem">
|
<template v-for="iconItem in iconsList" :key="iconItem">
|
||||||
<Icon
|
<svg-icon
|
||||||
:icon="iconItem"
|
:icon="iconItem"
|
||||||
class="border-1px border-[#d9d9d9] text-30px m-2px p-5px"
|
class="border-1px border-[#d9d9d9] text-30px m-2px p-5px"
|
||||||
:style="{ 'border-color': modelValue === iconItem ? theme.themeColor : '' }"
|
:class="{ 'border-primary': modelValue === iconItem }"
|
||||||
@click="handleChange(iconItem)"
|
@click="handleChange(iconItem)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -25,9 +25,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { Icon } from '@iconify/vue';
|
|
||||||
import { useThemeStore } from '@/store';
|
defineOptions({ name: 'IconSelect' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** 选中的图标 */
|
/** 选中的图标 */
|
||||||
@@ -38,34 +38,36 @@ interface Props {
|
|||||||
emptyIcon?: string;
|
emptyIcon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
emptyIcon: 'mdi:apps'
|
||||||
|
});
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:value', val: string): void;
|
(e: 'update:value', val: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
emptyIcon: 'mdi:apps',
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const theme = useThemeStore();
|
|
||||||
|
|
||||||
const searchValue = ref('');
|
|
||||||
const iconsList = computed(() => props.icons.filter((v) => v.includes(searchValue.value)));
|
|
||||||
|
|
||||||
const modelValue = computed({
|
const modelValue = computed({
|
||||||
get() {
|
get() {
|
||||||
return props.value;
|
return props.value;
|
||||||
},
|
},
|
||||||
set(val: string) {
|
set(val: string) {
|
||||||
emit('update:value', val);
|
emit('update:value', val);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectedIcon = computed(() => modelValue.value || props.emptyIcon);
|
||||||
|
|
||||||
|
const searchValue = ref('');
|
||||||
|
|
||||||
|
const iconsList = computed(() => props.icons.filter(v => v.includes(searchValue.value)));
|
||||||
|
|
||||||
function handleChange(iconItem: string) {
|
function handleChange(iconItem: string) {
|
||||||
modelValue.value = iconItem;
|
modelValue.value = iconItem;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.n-input-wrapper) {
|
:deep(.n-input-wrapper) {
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
|
@@ -8,32 +8,35 @@
|
|||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
import { useImageVerify } from '@/hooks';
|
import { useImageVerify } from '@/hooks';
|
||||||
|
|
||||||
|
defineOptions({ name: 'ImageVerify' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
code?: string;
|
code?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
code: ''
|
||||||
|
});
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:code', code: string): void;
|
(e: 'update:code', code: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
code: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify();
|
const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify();
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.code,
|
() => props.code,
|
||||||
(newValue) => {
|
newValue => {
|
||||||
setImgCode(newValue);
|
setImgCode(newValue);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
watch(imgCode, (newValue) => {
|
watch(imgCode, newValue => {
|
||||||
emit('update:code', newValue);
|
emit('update:code', newValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({ getImgCode });
|
defineExpose({ getImgCode });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
53
src/components/custom/SvgIcon.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<template v-if="renderLocalIcon">
|
||||||
|
<svg aria-hidden="true" width="1em" height="1em" v-bind="bindAttrs">
|
||||||
|
<use :xlink:href="symbolId" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<Icon :icon="icon" v-bind="bindAttrs" />
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, useAttrs } from 'vue';
|
||||||
|
import { Icon } from '@iconify/vue';
|
||||||
|
|
||||||
|
defineOptions({ name: 'SvgIcon' });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标组件
|
||||||
|
* - 支持iconify和本地svg图标
|
||||||
|
* - 同时传递了icon和localIcon,localIcon会优先渲染
|
||||||
|
*/
|
||||||
|
interface Props {
|
||||||
|
/** 图标名称 */
|
||||||
|
icon?: string;
|
||||||
|
/** 本地svg的文件名 */
|
||||||
|
localIcon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
const attrs = useAttrs();
|
||||||
|
|
||||||
|
const bindAttrs = computed<{ class: string; style: string }>(() => ({
|
||||||
|
class: (attrs.class as string) || '',
|
||||||
|
style: (attrs.style as string) || ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
const symbolId = computed(() => {
|
||||||
|
const { VITE_ICON_LOCAL_PREFFIX: preffix } = import.meta.env;
|
||||||
|
|
||||||
|
const defaultLocalIcon = 'no-icon';
|
||||||
|
|
||||||
|
const icon = props.localIcon || defaultLocalIcon;
|
||||||
|
|
||||||
|
return `#${preffix}-${icon}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 渲染本地icon */
|
||||||
|
const renderLocalIcon = computed(() => props.localIcon || !props.icon);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@@ -8,6 +8,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
defineOptions({ name: 'WebSiteLink' });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** 网址名称 */
|
/** 网址名称 */
|
||||||
label: string;
|
label: string;
|
||||||
@@ -17,4 +19,5 @@ interface Props {
|
|||||||
|
|
||||||
defineProps<Props>();
|
defineProps<Props>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
167
src/composables/echarts.ts
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
import { nextTick, onUnmounted, ref, watch } from 'vue';
|
||||||
|
import type { ComputedRef, Ref } from 'vue';
|
||||||
|
import * as echarts from 'echarts/core';
|
||||||
|
import { BarChart, GaugeChart, LineChart, PictorialBarChart, PieChart, RadarChart, ScatterChart } from 'echarts/charts';
|
||||||
|
import type {
|
||||||
|
BarSeriesOption,
|
||||||
|
GaugeSeriesOption,
|
||||||
|
LineSeriesOption,
|
||||||
|
PictorialBarSeriesOption,
|
||||||
|
PieSeriesOption,
|
||||||
|
RadarSeriesOption,
|
||||||
|
ScatterSeriesOption
|
||||||
|
} from 'echarts/charts';
|
||||||
|
import {
|
||||||
|
DatasetComponent,
|
||||||
|
GridComponent,
|
||||||
|
LegendComponent,
|
||||||
|
TitleComponent,
|
||||||
|
ToolboxComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
TransformComponent
|
||||||
|
} from 'echarts/components';
|
||||||
|
import type {
|
||||||
|
DatasetComponentOption,
|
||||||
|
GridComponentOption,
|
||||||
|
LegendComponentOption,
|
||||||
|
TitleComponentOption,
|
||||||
|
ToolboxComponentOption,
|
||||||
|
TooltipComponentOption
|
||||||
|
} from 'echarts/components';
|
||||||
|
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
import { useElementSize } from '@vueuse/core';
|
||||||
|
import { useThemeStore } from '@/store';
|
||||||
|
|
||||||
|
export type ECOption = echarts.ComposeOption<
|
||||||
|
| BarSeriesOption
|
||||||
|
| LineSeriesOption
|
||||||
|
| PieSeriesOption
|
||||||
|
| ScatterSeriesOption
|
||||||
|
| PictorialBarSeriesOption
|
||||||
|
| RadarSeriesOption
|
||||||
|
| GaugeSeriesOption
|
||||||
|
| TitleComponentOption
|
||||||
|
| LegendComponentOption
|
||||||
|
| TooltipComponentOption
|
||||||
|
| GridComponentOption
|
||||||
|
| ToolboxComponentOption
|
||||||
|
| DatasetComponentOption
|
||||||
|
>;
|
||||||
|
|
||||||
|
echarts.use([
|
||||||
|
TitleComponent,
|
||||||
|
LegendComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
GridComponent,
|
||||||
|
DatasetComponent,
|
||||||
|
TransformComponent,
|
||||||
|
ToolboxComponent,
|
||||||
|
BarChart,
|
||||||
|
LineChart,
|
||||||
|
PieChart,
|
||||||
|
ScatterChart,
|
||||||
|
PictorialBarChart,
|
||||||
|
RadarChart,
|
||||||
|
GaugeChart,
|
||||||
|
LabelLayout,
|
||||||
|
UniversalTransition,
|
||||||
|
CanvasRenderer
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echarts hooks函数
|
||||||
|
* @param options - 图表配置
|
||||||
|
* @param renderFun - 图表渲染函数(例如:图表监听函数)
|
||||||
|
* @description 按需引入图表组件,没注册的组件需要先引入
|
||||||
|
*/
|
||||||
|
export function useEcharts(
|
||||||
|
options: Ref<ECOption> | ComputedRef<ECOption>,
|
||||||
|
renderFun?: (chartInstance: echarts.ECharts) => void
|
||||||
|
) {
|
||||||
|
const theme = useThemeStore();
|
||||||
|
|
||||||
|
const domRef = ref<HTMLElement>();
|
||||||
|
|
||||||
|
const initialSize = { width: 0, height: 0 };
|
||||||
|
const { width, height } = useElementSize(domRef, initialSize);
|
||||||
|
|
||||||
|
let chart: echarts.ECharts | null = null;
|
||||||
|
|
||||||
|
function canRender() {
|
||||||
|
return initialSize.width > 0 && initialSize.height > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRendered() {
|
||||||
|
return Boolean(domRef.value && chart);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(updateOptions: ECOption) {
|
||||||
|
if (isRendered()) {
|
||||||
|
chart!.setOption({ ...updateOptions, backgroundColor: 'transparent' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function render() {
|
||||||
|
if (domRef.value) {
|
||||||
|
const chartTheme = theme.darkMode ? 'dark' : 'light';
|
||||||
|
await nextTick();
|
||||||
|
chart = echarts.init(domRef.value, chartTheme);
|
||||||
|
if (renderFun) {
|
||||||
|
renderFun(chart);
|
||||||
|
}
|
||||||
|
update(options.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
chart?.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy() {
|
||||||
|
chart?.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTheme() {
|
||||||
|
destroy();
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopSizeWatch = watch([width, height], ([newWidth, newHeight]) => {
|
||||||
|
initialSize.width = newWidth;
|
||||||
|
initialSize.height = newHeight;
|
||||||
|
if (newWidth === 0 && newHeight === 0) {
|
||||||
|
// 节点被删除 将chart置为空
|
||||||
|
chart = null;
|
||||||
|
}
|
||||||
|
if (canRender()) {
|
||||||
|
if (!isRendered()) {
|
||||||
|
render();
|
||||||
|
} else {
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const stopOptionWatch = watch(options, newValue => {
|
||||||
|
update(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
const stopDarkModeWatch = watch(
|
||||||
|
() => theme.darkMode,
|
||||||
|
() => {
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
destroy();
|
||||||
|
stopSizeWatch();
|
||||||
|
stopOptionWatch();
|
||||||
|
stopDarkModeWatch();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
domRef
|
||||||
|
};
|
||||||
|
}
|
14
src/composables/events.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { useEventListener } from '@vueuse/core';
|
||||||
|
import { useTabStore, useThemeStore } from '@/store';
|
||||||
|
|
||||||
|
/** 全局事件 */
|
||||||
|
export function useGlobalEvents() {
|
||||||
|
const theme = useThemeStore();
|
||||||
|
const tab = useTabStore();
|
||||||
|
|
||||||
|
/** 页面离开时缓存多页签数据 */
|
||||||
|
useEventListener(window, 'beforeunload', () => {
|
||||||
|
theme.cacheThemeSettings();
|
||||||
|
tab.cacheTabRoutes();
|
||||||
|
});
|
||||||
|
}
|
60
src/composables/icon.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { h } from 'vue';
|
||||||
|
import SvgIcon from '@/components/custom/SvgIcon.vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标渲染
|
||||||
|
* - 用于vue的render函数
|
||||||
|
*/
|
||||||
|
export const useIconRender = () => {
|
||||||
|
interface IconConfig {
|
||||||
|
/**
|
||||||
|
* 图标名称(iconify图标的名称)
|
||||||
|
* - 例如:mdi-account 或者 mdi:account
|
||||||
|
*/
|
||||||
|
icon?: string;
|
||||||
|
/**
|
||||||
|
* 本地svg图标文件名(assets/svg-icon文件夹下)
|
||||||
|
*/
|
||||||
|
localIcon?: string;
|
||||||
|
/** 图标颜色 */
|
||||||
|
color?: string;
|
||||||
|
/** 图标大小 */
|
||||||
|
fontSize?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IconStyle {
|
||||||
|
color?: string;
|
||||||
|
fontSize?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标渲染
|
||||||
|
* @param config
|
||||||
|
* @property icon - 图标名称(iconify图标的名称), 例如:mdi-account 或者 mdi:account
|
||||||
|
* @property localIcon - 本地svg图标文件名(assets/svg-icon文件夹下)
|
||||||
|
* @property color - 图标颜色
|
||||||
|
* @property fontSize - 图标大小
|
||||||
|
*/
|
||||||
|
const iconRender = (config: IconConfig) => {
|
||||||
|
const { color, fontSize, icon, localIcon } = config;
|
||||||
|
|
||||||
|
const style: IconStyle = {};
|
||||||
|
|
||||||
|
if (color) {
|
||||||
|
style.color = color;
|
||||||
|
}
|
||||||
|
if (fontSize) {
|
||||||
|
style.fontSize = `${fontSize}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!icon && !localIcon) {
|
||||||
|
window.console.warn('没有传递图标名称,请确保给icon或localIcon传递有效值!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => h(SvgIcon, { icon, localIcon, style });
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
iconRender
|
||||||
|
};
|
||||||
|
};
|
@@ -1,3 +1,6 @@
|
|||||||
export * from './system';
|
export * from './system';
|
||||||
export * from './router';
|
export * from './router';
|
||||||
export * from './layout';
|
export * from './layout';
|
||||||
|
export * from './events';
|
||||||
|
export * from './echarts';
|
||||||
|
export * from './icon';
|
||||||
|
@@ -1,40 +1,44 @@
|
|||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core';
|
||||||
import { useAppStore, useThemeStore } from '@/store';
|
import { useAppStore, useThemeStore } from '@/store';
|
||||||
|
|
||||||
type LayoutHeaderProps = Record<EnumType.ThemeLayoutMode, GlobalHeaderProps>;
|
type LayoutMode = 'vertical' | 'horizontal';
|
||||||
|
type LayoutHeaderProps = Record<EnumType.ThemeLayoutMode, App.GlobalHeaderProps>;
|
||||||
|
|
||||||
export function useBasicLayout() {
|
export function useBasicLayout() {
|
||||||
const app = useAppStore();
|
const app = useAppStore();
|
||||||
const theme = useThemeStore();
|
const theme = useThemeStore();
|
||||||
|
const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||||
|
|
||||||
type LayoutMode = 'vertical' | 'horizontal';
|
|
||||||
const mode = computed(() => {
|
const mode = computed(() => {
|
||||||
const vertical: LayoutMode = 'vertical';
|
const vertical: LayoutMode = 'vertical';
|
||||||
const horizontal: LayoutMode = 'horizontal';
|
const horizontal: LayoutMode = 'horizontal';
|
||||||
return theme.layout.mode.includes(vertical) ? vertical : horizontal;
|
return theme.layout.mode.includes(vertical) ? vertical : horizontal;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isMobile = breakpoints.smaller('sm');
|
||||||
|
|
||||||
const layoutHeaderProps: LayoutHeaderProps = {
|
const layoutHeaderProps: LayoutHeaderProps = {
|
||||||
vertical: {
|
vertical: {
|
||||||
showLogo: false,
|
showLogo: false,
|
||||||
showHeaderMenu: false,
|
showHeaderMenu: false,
|
||||||
showMenuCollape: true,
|
showMenuCollapse: true
|
||||||
},
|
},
|
||||||
'vertical-mix': {
|
'vertical-mix': {
|
||||||
showLogo: false,
|
showLogo: false,
|
||||||
showHeaderMenu: false,
|
showHeaderMenu: false,
|
||||||
showMenuCollape: false,
|
showMenuCollapse: false
|
||||||
},
|
},
|
||||||
horizontal: {
|
horizontal: {
|
||||||
showLogo: true,
|
showLogo: true,
|
||||||
showHeaderMenu: true,
|
showHeaderMenu: true,
|
||||||
showMenuCollape: false,
|
showMenuCollapse: false
|
||||||
},
|
},
|
||||||
'horizontal-mix': {
|
'horizontal-mix': {
|
||||||
showLogo: true,
|
showLogo: true,
|
||||||
showHeaderMenu: false,
|
showHeaderMenu: false,
|
||||||
showMenuCollape: true,
|
showMenuCollapse: true
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerProps = computed(() => layoutHeaderProps[theme.layout.mode]);
|
const headerProps = computed(() => layoutHeaderProps[theme.layout.mode]);
|
||||||
@@ -61,9 +65,10 @@ export function useBasicLayout() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
mode,
|
mode,
|
||||||
|
isMobile,
|
||||||
headerProps,
|
headerProps,
|
||||||
siderVisible,
|
siderVisible,
|
||||||
siderWidth,
|
siderWidth,
|
||||||
siderCollapsedWidth,
|
siderCollapsedWidth
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ export function useRouterPush(inSetup = true) {
|
|||||||
const module: EnumType.LoginModuleKey = loginModule || 'pwd-login';
|
const module: EnumType.LoginModuleKey = loginModule || 'pwd-login';
|
||||||
const routeLocation: RouteLocationRaw = {
|
const routeLocation: RouteLocationRaw = {
|
||||||
name: routeName('login'),
|
name: routeName('login'),
|
||||||
params: { module },
|
params: { module }
|
||||||
};
|
};
|
||||||
const redirect = redirectUrl || route.value.fullPath;
|
const redirect = redirectUrl || route.value.fullPath;
|
||||||
Object.assign(routeLocation, { query: { redirect } });
|
Object.assign(routeLocation, { query: { redirect } });
|
||||||
@@ -80,6 +80,6 @@ export function useRouterPush(inSetup = true) {
|
|||||||
toHome,
|
toHome,
|
||||||
toLogin,
|
toLogin,
|
||||||
toLoginModule,
|
toLoginModule,
|
||||||
toLoginRedirect,
|
toLoginRedirect
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import UAParser from 'ua-parser-js';
|
import UAParser from 'ua-parser-js';
|
||||||
|
import { useAuthStore } from '@/store';
|
||||||
|
import { isArray, isString } from '@/utils';
|
||||||
|
|
||||||
interface AppInfo {
|
interface AppInfo {
|
||||||
/** 项目名称 */
|
/** 项目名称 */
|
||||||
@@ -16,7 +18,7 @@ export function useAppInfo(): AppInfo {
|
|||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
title,
|
title,
|
||||||
desc,
|
desc
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,3 +28,27 @@ export function useDeviceInfo() {
|
|||||||
const result = parser.getResult();
|
const result = parser.getResult();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 权限判断 */
|
||||||
|
export function usePermission() {
|
||||||
|
const auth = useAuthStore();
|
||||||
|
|
||||||
|
function hasPermission(permission: Auth.RoleType | Auth.RoleType[]) {
|
||||||
|
const { userRole } = auth.userInfo;
|
||||||
|
|
||||||
|
let has = userRole === 'super';
|
||||||
|
if (!has) {
|
||||||
|
if (isArray(permission)) {
|
||||||
|
has = (permission as Auth.RoleType[]).includes(userRole);
|
||||||
|
}
|
||||||
|
if (isString(permission)) {
|
||||||
|
has = (permission as Auth.RoleType) === userRole;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return has;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasPermission
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
/** 百度地图sdk地址 */
|
/** 百度地图sdk地址 */
|
||||||
export const BAIDU_MAP_SDK_URL =
|
export const BAIDU_MAP_SDK_URL = `https://api.map.baidu.com/getscript?v=3.0&ak=KSezYymXPth1DIGILRX3oYN9PxbOQQmU&services=&t=20210201100830&s=1`;
|
||||||
'https://api.map.baidu.com/getscript?v=3.0&ak=KSezYymXPth1DIGILRX3oYN9PxbOQQmU&services=&t=20210201100830&s=1';
|
|
||||||
|
|
||||||
/** 高德地图sdk地址 */
|
/** 高德地图sdk地址 */
|
||||||
export const GAODE_MAP_SDK_URL = 'https://webapi.amap.com/maps?v=2.0&key=e7bd02bd504062087e6563daf4d6721d';
|
export const GAODE_MAP_SDK_URL = 'https://webapi.amap.com/maps?v=2.0&key=e7bd02bd504062087e6563daf4d6721d';
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
/** 手机号码正则 */
|
/** 手机号码正则 */
|
||||||
export const REGEXP_PHONE =
|
export const REGEXP_PHONE =
|
||||||
/^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/;
|
/^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/;
|
||||||
|
|
||||||
/** 邮箱正则 */
|
/** 邮箱正则 */
|
||||||
export const REGEXP_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
|
export const REGEXP_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
|
||||||
|
|
||||||
/** 密码正则(密码为8-18位数字/字符/符号的组合) */
|
/** 密码正则(密码为6-18位数字/字符/符号的组合) */
|
||||||
export const REGEXP_PWD =
|
export const REGEXP_PWD =
|
||||||
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
|
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){6,18}$/;
|
||||||
|
|
||||||
/** 6位数字验证码正则 */
|
/** 6位数字验证码正则 */
|
||||||
export const REGEXP_CODE_SIX = /^\d{6}$/;
|
export const REGEXP_CODE_SIX = /^\d{6}$/;
|
||||||
|
@@ -36,11 +36,11 @@ export const ERROR_STATUS = {
|
|||||||
503: '503: 服务不可用~',
|
503: '503: 服务不可用~',
|
||||||
504: '504: 网关超时~',
|
504: '504: 网关超时~',
|
||||||
505: '505: http版本不支持该请求~',
|
505: '505: http版本不支持该请求~',
|
||||||
[DEFAULT_REQUEST_ERROR_CODE]: DEFAULT_REQUEST_ERROR_MSG,
|
[DEFAULT_REQUEST_ERROR_CODE]: DEFAULT_REQUEST_ERROR_MSG
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 不弹出错误信息的code */
|
/** 不弹出错误信息的code */
|
||||||
export const NO_ERROR_MSG_CODE: (string | number)[] = [];
|
export const NO_ERROR_MSG_CODE: (string | number)[] = [];
|
||||||
|
|
||||||
/** token失效需要刷新token的code */
|
/** token失效需要刷新token的code(这里的66666只是个例子,需要将后端表示token过期的code填进来) */
|
||||||
export const REFRESH_TOKEN_CODE: (string | number)[] = [66666];
|
export const REFRESH_TOKEN_CODE: (string | number)[] = [66666];
|
||||||
|
25
src/constants/business.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/** 用户性别 */
|
||||||
|
export const genderLabels: Record<UserManagement.GenderKey, string> = {
|
||||||
|
0: '女',
|
||||||
|
1: '男'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const genderOptions: { value: UserManagement.GenderKey; label: string }[] = [
|
||||||
|
{ value: '0', label: genderLabels['0'] },
|
||||||
|
{ value: '1', label: genderLabels['1'] }
|
||||||
|
];
|
||||||
|
|
||||||
|
/** 用户状态 */
|
||||||
|
export const userStatusLabels: Record<UserManagement.UserStatusKey, string> = {
|
||||||
|
1: '启用',
|
||||||
|
2: '禁用',
|
||||||
|
3: '冻结',
|
||||||
|
4: '软删除'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const userStatusOptions: { value: UserManagement.UserStatusKey; label: string }[] = [
|
||||||
|
{ value: '1', label: userStatusLabels['1'] },
|
||||||
|
{ value: '2', label: userStatusLabels['2'] },
|
||||||
|
{ value: '3', label: userStatusLabels['3'] },
|
||||||
|
{ value: '4', label: userStatusLabels['4'] }
|
||||||
|
];
|
1
src/constants/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './business';
|