Compare commits

..

91 Commits

Author SHA1 Message Date
Soybean
d32e296473 chore(projects): release v0.10.3 thin branch 2023-06-15 19:35:35 +08:00
Soybean
de2829fde7 chore(projects): release v0.10.3 2023-06-15 19:26:12 +08:00
Soybean
c1bee4046c chore(projects): add vite-plugin-vue-devtools 2023-06-15 19:25:32 +08:00
Soybean
473095b01b fix(styles): fix toggle-lang bg 2023-06-15 01:00:14 +08:00
Soybean
e6abf93457 chore(deps): update deps 2023-06-14 23:59:43 +08:00
Soybean
882f281482 chore(deps): decrease vite-plugin-page-route 2023-06-12 13:35:05 +08:00
Soybean
0b2f68ac04 chore(projects): update deps & update package.json 2023-06-12 01:30:50 +08:00
Soybean
2ca2b766f8 fix(projects): fix userRoleOptions 2023-06-10 12:05:57 +08:00
Soybean
da611fb10b perf(projects): use transformObjectToOption to generate option of object labels 2023-06-08 23:56:27 +08:00
Soybean
eb8e49e23c perf(projects): remove useless code 2023-06-08 23:38:14 +08:00
Soybean
0907d38c06 chore(projects): update deps & update unocss deprecated api exclude 2023-06-08 23:05:08 +08:00
Soybean
2a9b725c6a docs(projects): update CHANGELOG.md by regenerate changelog 2023-06-07 22:50:59 +08:00
Soybean
8f24a94ed3 docs(projects): update README.md 2023-06-07 02:22:13 +08:00
Soybean
4eefc95baa docs(projects): update README.md picture url 2023-06-07 02:16:18 +08:00
Soybean
1681c34a52 docs(projects): update README.md 2023-06-07 02:06:40 +08:00
Soybean
47ab0184b7 chore(deps): update deps 2023-06-07 01:48:55 +08:00
Soybean
58591f660a chore(projects): update @soybeanjs/cli and generate total changelog 2023-06-07 01:46:09 +08:00
Soybean
3c7e1cf442 docs(projects): update README.md 2023-06-05 02:13:15 +08:00
Soybean
055d4cce33 docs(projects): generate full CHANGELOG.md 2023-06-05 02:00:59 +08:00
Soybean
a3dfe61a7b chore(projects): remove bumpp & add release script 2023-06-05 01:57:23 +08:00
Soybean
f9d47c081f chore(deps): update deps 2023-06-05 01:55:09 +08:00
Soybean
ff5bf62989 docs(projects): CHANGELOG.md 2023-05-31 18:25:40 +00:00
Soybean
1f6d079644 chore: release v0.10.2 2023-06-01 02:24:57 +08:00
Soybean
5c085a1986 fix(components): fix mix-menu layout when the locale is English (fixed 241) 2023-06-01 02:24:26 +08:00
Soybean
9a23817473 chore(projects): update deps and use soy lint-staged replace lint-staged 2023-06-01 02:10:07 +08:00
Soybean
56ea8937f6 docs(projects): fix README.md: example image link 2023-05-31 09:28:34 +08:00
Soybean
4f51263501 docs(projects): update README.md: update example image url [更新示例图片的链接] 2023-05-31 02:32:06 +08:00
Soybean
bb2eab60f4 docs(projects): CHANGELOG.md 2023-05-30 18:20:40 +00:00
Soybean
44e4c04811 chore: release v0.10.1 2023-05-31 02:19:56 +08:00
Soybean
b5839eab26 docs(projects): update README.md 2023-05-31 02:18:19 +08:00
Soybean
780ac75bf6 chore(projects): add switch for pageRoute plugin [添加自动生成路由的插件的开关] 2023-05-31 01:52:57 +08:00
Soybean
a252138594 docs(projects): CHANGELOG.md 2023-05-30 17:47:56 +00:00
Soybean
270a055072 chore: release v0.10.0 2023-05-31 01:47:13 +08:00
Soybean
08e194efe9 perf(projects): move changing document title by locale to global event of composables & add appLoading unmount 2023-05-31 01:44:49 +08:00
Soybean
5f6caab338 docs(projects): update CHANGELOG.md 2023-05-31 01:35:04 +08:00
Soybean
5aaa318142 chore(projects): remove useless packages, update lint-staged config, add githublogen 2023-05-31 01:33:46 +08:00
Soybean
cebbef680f chore(deps): update deps 2023-05-31 01:08:31 +08:00
Soybean
0abde46ef4 fix(projects): hide the drawer when it is initial mobile mode [初始化时为移动端布局则隐藏侧边栏] fixed #238 2023-05-26 13:08:35 +08:00
Soybean
f2b518ed26 feat(projects): support mobile layout [支持移动端布局] 2023-05-26 03:27:41 +08:00
Soybean
c6207f35e1 Merge pull request #237 from abstain23/fix-i18n
fix(projects): 修复面包屑导航下拉菜单语言显示问题
2023-05-25 21:13:45 +08:00
cc
ee8fa04814 fix(projects): 修复面包屑导航下拉菜单语言显示问题 2023-05-25 21:11:42 +08:00
Soybean
7b746fa053 perf(projects): complete dynamic route translate [补充动态路由的翻译] 2023-05-24 23:17:29 +08:00
Soybean
b7fea53107 Merge pull request #234 from chhinsras/main
Add Khmer Translation
2023-05-24 23:03:23 +08:00
Chhin Sras
f89f3e6a38 Added Khmer Translation 2023-05-24 21:07:35 +07:00
Chhin Sras
a0da2f6e16 Delete actions-template-sync.yml 2023-05-24 15:52:05 +07:00
Chhin Sras
3b5380e0d1 Update Sras.md 2023-05-24 15:38:43 +07:00
Chhin Sras
35276bfe41 Update and rename .github/workflows/actions-template-sync.yml to actions-template-sync.yml 2023-05-24 15:30:10 +07:00
Chhin Sras
215c1ecbd9 Update and rename sync-from-template.yml to actions-template-sync.yml 2023-05-24 15:24:51 +07:00
Chhin Sras
1698b21d7a Create Sras.md 2023-05-24 15:18:35 +07:00
Chhin Sras
ca1e66be47 Rename sync-from-template to sync-from-template.yml 2023-05-24 15:13:58 +07:00
Chhin Sras
22bf2823e8 Update and rename actions-template-sync to sync-from-template 2023-05-24 15:12:03 +07:00
Chhin Sras
32e98f1b3a Create actions-template-sync 2023-05-24 15:06:44 +07:00
Soybean
c1c4335ce7 build(projects): update deps and fix style [升级依赖&修复代码格式] 2023-05-24 00:17:00 +08:00
Soybean
6c50662280 Merge pull request #233 from fast-crud/优化README.md
优化readme.md
2023-05-24 00:12:44 +08:00
xiaojunnuo
f3a1707b94 docs(projects): readme.md 二次开发的项目内容换行 2023-05-23 17:52:06 +08:00
xiaojunnuo
6ea755f2a8 docs(projects): 优化README.md 2023-05-23 17:43:00 +08:00
Soybean
a989b44a15 docs(projects): update README.md [更新README.md] 2023-05-22 23:04:57 +08:00
Soybean
40f8587fd6 build(deps): update deps [升级依赖] 2023-05-21 22:35:30 +08:00
Soybean
9f5638f16d fix(projects): add prod mockjs switch [添加生产模式的mockjs的开关] 2023-05-17 07:55:12 +08:00
Soybean
9b19f96ff6 fix(projects): fix mockjs [修复mockjs] 2023-05-16 22:29:35 +08:00
Soybean
15da557892 Merge pull request #230 from kirklin/fix_tsconfig
fix(projects): tsconfig missing isolatedModules
2023-05-16 19:36:04 +08:00
Soybean
2d23c9a2e6 Merge pull request #229 from kirklin/vue3.3
refactor(projects): upgrade vue3.3, official support defineOptions
2023-05-16 19:34:16 +08:00
Kirk Lin
ab49afd3db fix(projects): tsconfig missing isolatedModules 2023-05-16 17:39:05 +08:00
Kirk Lin
86a370fd69 refactor(projects): upgrade vue3.3, official support defineOptions 2023-05-16 17:32:38 +08:00
Soybean
36fc74ce07 Merge pull request #226 from abstain23/feat/theme-transtion
feat(projects): 增加主题切换过渡效果
2023-05-14 16:49:26 +08:00
cc
8da8843fd0 feat(projects): 增加主题切换过渡效果 2023-05-14 16:35:38 +08:00
Soybean
f68285fbe5 feat(projects): add menu translate [翻译菜单] 2023-05-13 14:20:06 +08:00
Soybean
85b8ef8f88 Merge pull request #225 from abstain23/feat-i18n
feat(projects): 增加i18n支持翻译菜单,tab,title
2023-05-13 13:12:28 +08:00
cc
3d48aa8bbe feat(projects): 增加i18n支持翻译菜单,tab,title 2023-05-13 12:58:35 +08:00
Soybean
a765da6e28 docs(projects): update README.md [更新README.md] 2023-05-10 22:23:18 +08:00
Soybean
c57640acd0 fix(projects): fix better-mock usage [修复better-mock用法] 2023-05-06 19:41:55 +08:00
Soybean
c264216053 build(deps): update deps [升级依赖] 2023-05-06 19:35:54 +08:00
Soybean
9d3c732993 refactor(projects): use better-mock replace mockjs [用better-mock替换mockjs] 2023-05-06 19:34:31 +08:00
Soybean
34f023c4b1 build(projects): update deps and fix type error [升级依赖并修复类型问题] 2023-05-04 19:02:20 +08:00
Soybean
5a4f842774 docs(projects): update README.md [更新README.md] 2023-04-26 08:40:07 +08:00
Soybean
bae1767141 build(deps): update deps [升级依赖] 2023-04-26 08:32:54 +08:00
Soybean
5957833a4f fix(projects): fix router guide [修复路由跳转异常] fixed #216 2023-04-21 00:46:03 +08:00
Soybean
397092c21f docs(projects): update README.md [更新README.md] 2023-04-20 01:41:07 +08:00
Soybean
f309003e67 refactor(projects): remove page examples: tree [去除tree相关示例页面] 2023-04-20 01:37:52 +08:00
Soybean
eaf3678758 build(deps): update deps and remove vite-plugin-html [升级依赖,去除vite-plugin-html] 2023-04-20 01:32:53 +08:00
Soybean
f2e82da7c8 build(deps): update deps [升级依赖] 2023-04-19 09:10:36 +08:00
Soybean
211ae1f905 refactor(projects): update useTable 2023-04-04 19:19:13 +08:00
Soybean
db629593c6 build(deps): update deps 2023-04-02 12:57:36 +08:00
Soybean
80d58cce2b Merge pull request #210 from SonyLeo/feature/tree
Feature/tree
2023-04-02 12:56:00 +08:00
small_happy
a0f55aca69 feat(components): Add routing data related to tree components and page display optimization 2023-04-02 10:45:51 +08:00
small_happy
d203a3586c feat(components): Add tree related component instances 2023-04-02 10:07:50 +08:00
Soybean
f74a6424d0 docs(projects): add qq to README.md [文档添加QQ群] 2023-03-15 18:14:25 +08:00
Soybean
209ef3d890 style(projects): per style [完善样式] 2023-03-15 09:01:06 +08:00
Soybean
b549b32cbb Merge pull request #205 from yanbowe/main
feat(projects): fix to top [返回顶部功能适配新布局]
2023-03-14 22:31:41 +08:00
燕博文
54e2cb51cf feat(projects): 返回顶部功能适配新布局 2023-03-14 13:50:23 +08:00
Soybean
42e6de395f build(projects): remove old layout,tab package [去除旧的布局和页签依赖] 2023-03-14 00:34:47 +08:00
188 changed files with 5051 additions and 13852 deletions

2
.env
View File

@@ -10,7 +10,7 @@ VITE_APP_DESC=SoybeanAdmin是一个中后台管理系统模版
VITE_AUTH_ROUTE_MODE=static
# 路由首页(根路由重定向), 用于static模式的权限路由dynamic模式取决于后端返回的路由首页
VITE_ROUTE_HOME_PATH=/dashboard/analysis
VITE_ROUTE_HOME_PATH=/multi-menu/first/second
# iconify图标作为组件的前缀
VITE_ICON_PREFFIX=icon

View File

@@ -1 +1,2 @@
VITE_HTTP_PROXY=Y
VITE_SOYBEAN_ROUTE_PLUGIN=Y

View File

@@ -1,8 +1 @@
VITE_VISUALIZER=N
VITE_COMPRESS=N
# gzip | brotliCompress | deflate | deflateRaw
VITE_COMPRESS_TYPE=gzip
VITE_PWA=N
VITE_PROD_MOCK=Y

View File

@@ -1,27 +1,25 @@
name: Release
on:
push:
tags:
- "v*.**"
permissions:
contents: write
on:
push:
tags:
- "v*"
jobs:
release:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
- uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Create github releases
run: npx changelogithub
- run: npx githublogen
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

2
.npmrc
View File

@@ -1,4 +1,2 @@
registry=https://registry.npmmirror.com/
shamefully-hoist=true
strict-peer-dependencies=false
auto-install-peers=true

8
.vscode/launch.json vendored
View File

@@ -7,6 +7,14 @@
"name": "Vue debugger",
"url": "http://localhost:3200",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "TS debugger",
"skipFiles": ["<node_internals>/**"],
"runtimeArgs": ["--loader", "tsx"],
"program": "${relativeFile}"
}
]
}

View File

@@ -39,7 +39,6 @@
"@": "${workspaceFolder}/src",
"~@": "${workspaceFolder}/src"
},
"terminal.integrated.cursorStyle": "line",
"terminal.integrated.fontSize": 14,
"terminal.integrated.fontWeight": 500,
"terminal.integrated.tabs.enabled": true,
@@ -71,5 +70,6 @@
},
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
}
},
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"]
}

View File

@@ -1,272 +0,0 @@
# Changelog
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.9](https://github.com/honghuangdc/soybean-admin/compare/v0.9.8...v0.9.9) (2023-03-13)
### Features
* **hooks:** add useNaiveTable ([cc13fcc](https://github.com/honghuangdc/soybean-admin/commit/cc13fcc8aaaf667902d69350ad0de3cc16c261ab))
* **projects:** custom unocss colors support opacity ([488e6e3](https://github.com/honghuangdc/soybean-admin/commit/488e6e32045d995361b898ef3d384dafcb069008))
* **projects:** new layout,tab and add update theme settings ([912c353](https://github.com/honghuangdc/soybean-admin/commit/912c3531c5d7a3ab30e15d39bed98ca9b20131ab))
### Bug Fixes
* **components:** 修复iconSelect选择器点击事件失效 ([7e505f9](https://github.com/honghuangdc/soybean-admin/commit/7e505f9b96f5380b6c27b4c2ee2ab0698c4eedc4))
* **components:** 页面跳转被拦截, 则会出现 tab 页签与页面不一致的问题 ([bd5dd2c](https://github.com/honghuangdc/soybean-admin/commit/bd5dd2cf28a0943721c397d70c53fe3988a4f81a))
* **components:** refresh cached routes ([b0f98e4](https://github.com/honghuangdc/soybean-admin/commit/b0f98e4bfac31751dd39a7dec203277db813694b))
* **projects:** fix eslint svg cause incorrect icon render ([0b5afda](https://github.com/honghuangdc/soybean-admin/commit/0b5afda287a0eea57daa8d35409297e2cbf6d578))
* **projects:** fix github bug-report ([f73e3f6](https://github.com/honghuangdc/soybean-admin/commit/f73e3f648decf5632fe5193e825b1f912c5f6153))
* **projects:** fix pwa logo ([bf2f617](https://github.com/honghuangdc/soybean-admin/commit/bf2f6172554337450c4a300b8bdb580d3e25ad45))
* **projects:** not only `/login` claim dynamic path scenario , but also others , eg:/user/1 ([6059891](https://github.com/honghuangdc/soybean-admin/commit/60598915561f1bad6ffba0dc102f0a776be52f0d))
* **projects:** sortRoutes recursively ([9188941](https://github.com/honghuangdc/soybean-admin/commit/918894147ab739b4592e8c76378246e28c46491a))
* **projects:** the length of routes children list should greater than 0 ([e1afc10](https://github.com/honghuangdc/soybean-admin/commit/e1afc10b80243a5d8d270a351a37a0a2d159f167))
* **utils:** make AxiosRequestConfig optional for request.handleDelete() ([4a6fec8](https://github.com/honghuangdc/soybean-admin/commit/4a6fec8af0b44b546f81ec41d7a5947371e189b2))
### [0.9.8](https://github.com/honghuangdc/soybean-admin/compare/v0.9.7...v0.9.8) (2023-01-15)
### Features
* 新增 affix 属性用于将其固定在tab卡 ([e772ff0](https://github.com/honghuangdc/soybean-admin/commit/e772ff05fb6ef513bd37cd9b1e245ea72f0ad6d2))
* **projects:** add compress script [添加压缩命令] ([be6d431](https://github.com/honghuangdc/soybean-admin/commit/be6d431485a5688bd1ed567e11c1ca35ab9259b0))
* **projects:** add generate logo script ([25daa23](https://github.com/honghuangdc/soybean-admin/commit/25daa236064c9a76677dbf16bc6d9717b1e0040f))
* **projects:** add new route plugin @soybeanjs/vite-plugin-vue-page-route [集成新的路由插件] ([3131e00](https://github.com/honghuangdc/soybean-admin/commit/3131e00f0f4a66756f547892a8d312cde3aaf868))
* **projects:** add script about generating png logo from [添加根据svg生成png图标的命令] ([70aeefe](https://github.com/honghuangdc/soybean-admin/commit/70aeefea02fcc13c152ee9d7a1197381bac724b9))
* setting 页面新增 是否显示footer的开关 ([d064f62](https://github.com/honghuangdc/soybean-admin/commit/d064f6285a6d1616d7606f1390d5f01819b258bb))
### Bug Fixes
* **components:** 修复路由在path中包含重复路单词径菜单时被激活会错误展开 ([264da00](https://github.com/honghuangdc/soybean-admin/commit/264da00e5d2cd8139907c2ac11a046649d942f4b))
* count can't display when endValue is 0. ([0282feb](https://github.com/honghuangdc/soybean-admin/commit/0282feb1730724ba66c2e57ab354099afa074e81))
* **projects:** 修复动态路由模式下路由不排序的问题 ([58b27c9](https://github.com/honghuangdc/soybean-admin/commit/58b27c96932ba89b362138a6056a82c25a7be282))
* **projects:** 修复tabs在static路由模式下可以关闭首页 ([7211a17](https://github.com/honghuangdc/soybean-admin/commit/7211a17a8158b01a1f6dd6c83591f86d76633de0))
* **projects:** add router-page.d.ts to git [将router-page.d.ts添加git提交] ([7a58035](https://github.com/honghuangdc/soybean-admin/commit/7a5803551419f65ca55ba797b49273b3a0dc6067))
* **projects:** fix login success message [修复登录成功的消息提示] ([810398a](https://github.com/honghuangdc/soybean-admin/commit/810398abb882613f82ba385e8a7666cf8b86d92d))
* **projects:** fix router when the dynamic routes api was failed [修复当动态路由接口失败后路由异常问题] ([f2b580f](https://github.com/honghuangdc/soybean-admin/commit/f2b580fc067e81202238bf8079a13ff014b0b329))
* **projects:** fix vite-pwa plugin config ([94098d0](https://github.com/honghuangdc/soybean-admin/commit/94098d02e8cec12e3c9f9331ece154b65d1c9150))
* remove height limit h-360px ([b5c570a](https://github.com/honghuangdc/soybean-admin/commit/b5c570adf55fd235dcec49bc20837623b1d5d3c4))
* set password attributes ([a9a3703](https://github.com/honghuangdc/soybean-admin/commit/a9a37036d58274385a779e6460f7be281dafdcaf))
### [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)
### Features
* **components:** svgIcon,添加type,调整size方案 ([ce4e039](https://github.com/honghuangdc/soybean-admin/commit/ce4e039f48001b47a2933e807f5410a9573781b9))
* **projects:** 引入soybean-admin-tab、去除vite-plugin-svg-icons用unplugin-icons实现自定义svg的iconify写法、代码优化 ([a1a57a1](https://github.com/honghuangdc/soybean-admin/commit/a1a57a185ce5004888ca4e1611973665ee46980b))
* **projects:** 新增子菜单图标和多页签图标 ([f5c56c3](https://github.com/honghuangdc/soybean-admin/commit/f5c56c355ce41157b20ed0a10272a28e6d8b2b49))
* **projects:** 新增自定义svg图标动态渲染 ([f83c7b5](https://github.com/honghuangdc/soybean-admin/commit/f83c7b59b893ab6e210188e92c4177b3d01392ce))
* **projects:** 添加naiveUI按需引入 ([a810ef8](https://github.com/honghuangdc/soybean-admin/commit/a810ef85b19e4b74f3ddb3c69d17c050e556ee90))
* **projects:** 添加SvgIcon,配置vite plugin ([378d55a](https://github.com/honghuangdc/soybean-admin/commit/378d55ac0e11cdf115ce3cb8e281d60f7fc4ff7a))
* **projects:** 添加全局组件自动引入注册 ([f5a043b](https://github.com/honghuangdc/soybean-admin/commit/f5a043b11a403927828ae922bdae411a4e5ae3c6))
* **projects:** 添加网络代理 ([094dca9](https://github.com/honghuangdc/soybean-admin/commit/094dca961f608404352ac360f44496423d88dae8))
* **projects:** 重构项目的TS类型架构去除interface文件夹 ([8191490](https://github.com/honghuangdc/soybean-admin/commit/8191490f39fc011096edd77c3156eb4fe33d4e1c))
### Bug Fixes
* **components:** 修复组件LoadingEmptyWrapper适应暗黑模式 ([811b15e](https://github.com/honghuangdc/soybean-admin/commit/811b15e672c9d69e9c5789eb11ab2db7bd729f37))
* **components:** 组件LoadingEmptyWrapper添加背景颜色动画过渡 ([7add5c2](https://github.com/honghuangdc/soybean-admin/commit/7add5c2edfcabadb77084179d464b849d880d5e6))
* **projects:** 修复 BASE_URL 没有生效的问题 ([72d7dcf](https://github.com/honghuangdc/soybean-admin/commit/72d7dcfa5ee8dc6f3601f4d65c6aca9ad2cc5d5c))
* **projects:** 修复页面切换动画开关不生效 ([9d4ed61](https://github.com/honghuangdc/soybean-admin/commit/9d4ed617fb80095e521d8063718283459711118f))
* **projects:** 修复页面切换动画无变化 ([c4546bd](https://github.com/honghuangdc/soybean-admin/commit/c4546bdfa303f1e89c0d7ddd46b54e4ec5170096))
### [0.9.2](https://github.com/honghuangdc/soybean-admin/compare/v0.9.1...v0.9.2) (2022-02-11)
### Features
* **projects:** 迁移全局搜索菜单功能 ([554d7fd](https://github.com/honghuangdc/soybean-admin/commit/554d7fd6114b9cf6df571c3cb02f4cb0cc6dcfd4))
### Bug Fixes
* **components:** 修复Tab在移动端设备无法点击的问题 ([2c9660f](https://github.com/honghuangdc/soybean-admin/commit/2c9660fdbf9a84e980db0aff5cd0aed0f75963ca))
* **projects:** 修复分析页和工作台的布局问题 ([e93b94c](https://github.com/honghuangdc/soybean-admin/commit/e93b94cb2435a130bb1d94a703328af342cd24c9))
* **projects:** 修复项目配置拷贝功能 ([a7a269d](https://github.com/honghuangdc/soybean-admin/commit/a7a269d6a61ccd25883e6bb69639d39e0260587d))
* **projects:** vite配置修复 ([facc00e](https://github.com/honghuangdc/soybean-admin/commit/facc00e8b4998dc8bd338e3b63a652b4bfe2ed3e))
### [0.9.1](https://github.com/honghuangdc/soybean-admin/compare/v0.1.3...v0.9.1) (2022-01-23)
### Features
* **projects:** 新版重构完成 ([68b4230](https://github.com/honghuangdc/soybean-admin/commit/68b42304d5964246775c7a82dcc1406c5db7a4e4))
### [0.1.3](https://github.com/honghuangdc/soybean-admin/compare/v0.1.2...v0.1.3) (2022-01-23)
### Bug Fixes
* **projects:** 修复未登录时会调用获取用户路由的接口 ([21bab1f](https://github.com/honghuangdc/soybean-admin/commit/21bab1f7c30611fe59dc91c7a73050ccb49a4658))
* **projects:** 修复路由守卫的动态路由逻辑 ([b61b0ce](https://github.com/honghuangdc/soybean-admin/commit/b61b0ce25fdcbaf29ca64cbcc467e12faa947625))
### [0.1.2](https://github.com/honghuangdc/soybean-admin/compare/v0.1.1...v0.1.2) (2022-01-21)
### Features
* **projects:** 添加缓存主题色 ([3709297](https://github.com/honghuangdc/soybean-admin/commit/37092974d37b2e661d4cbf9d27c89b5e99119cd7))
* **projects:** 添加页面缓存、记录在tab中的缓存页面的滚动条位置 ([1d63a83](https://github.com/honghuangdc/soybean-admin/commit/1d63a838226df4f48e7f2a15b5a05d4b496d3c69))
### [0.1.1](https://github.com/honghuangdc/soybean-admin/compare/v0.0.5...v0.1.1) (2022-01-20)
### Features
* **projects:** theme store完成 ([bf020a8](https://github.com/honghuangdc/soybean-admin/commit/bf020a82580e6b1fbda1cc1e0bd6176770434884))
* **projects:** 主题配置抽屉: 迁移其他功能 ([6d132c5](https://github.com/honghuangdc/soybean-admin/commit/6d132c59770e925cfc61217dcefa5b4d937604df))
* **projects:** 主题配置抽屉:迁移暗黑模式、布局模式、添加颜色选择面板 ([912bfdf](https://github.com/honghuangdc/soybean-admin/commit/912bfdf4390ab624d3f8e343be88e8c1cf7ab5b6))
* **projects:** 创建自定义布局组件SoybeanLayout ([0653fb1](https://github.com/honghuangdc/soybean-admin/commit/0653fb144fe9d49f24ef4fe6e4a58de6de342b78))
* **projects:** 初始化加载效果:应用主题颜色 ([035fa11](https://github.com/honghuangdc/soybean-admin/commit/035fa114c9fd638cf467e6a73a8e4c558f503deb))
* **projects:** 图标选择器增加扩展树形 ([041012b](https://github.com/honghuangdc/soybean-admin/commit/041012b3ee04d960c1e38895839225613f7af377))
* **projects:** 增加Icon选择器组件 ([9472b51](https://github.com/honghuangdc/soybean-admin/commit/9472b51811f419e9139de81c73f2c71d170700c2))
* **projects:** 增加全局搜索菜单功能 ([b9ce691](https://github.com/honghuangdc/soybean-admin/commit/b9ce69130b12712013228326f883e2d973e4e46a))
* **projects:** 增加项目文档外链 ([1901a0b](https://github.com/honghuangdc/soybean-admin/commit/1901a0bfb7bfa516dfda552675397ddec96b8d4b))
* **projects:** 多级路由的所有子路由转换成二级路由 ([85b55bb](https://github.com/honghuangdc/soybean-admin/commit/85b55bb37a0a06e2645b96ed81aefe463127121a))
* **projects:** 引入mockjs ([9bc682d](https://github.com/honghuangdc/soybean-admin/commit/9bc682dae878c084e38a0e2c9a4a2de171023c48))
* **projects:** 新增BasicLayout布局 ([006467a](https://github.com/honghuangdc/soybean-admin/commit/006467a0626f427da3f516d90c15bf1e1eef0e55))
* **projects:** 添加cryptojs对本地缓存数据进行加密 ([7a0648d](https://github.com/honghuangdc/soybean-admin/commit/7a0648dba55a98f61f4d81696307d86c82a1d34d))
* **projects:** 添加NaiveProvider组件 ([c804b21](https://github.com/honghuangdc/soybean-admin/commit/c804b21ceb92133c6ea7cc64c87521cc164e40ce))
* **projects:** 添加侧边菜单 ([e25afe2](https://github.com/honghuangdc/soybean-admin/commit/e25afe2fadfe86b9330ee02190a4e40b8321714c))
* **projects:** 添加头部折叠按钮 ([a090d39](https://github.com/honghuangdc/soybean-admin/commit/a090d398fc071e246b92d0da80883cf5cbedba0e))
* **projects:** 添加常用组件、composables函数 ([230a50a](https://github.com/honghuangdc/soybean-admin/commit/230a50a4cf4d2ebb62b19d6324234243cf6b2f0d))
* **projects:** 添加抽屉 ([10e4d81](https://github.com/honghuangdc/soybean-admin/commit/10e4d81bd6a0b35d8cfb4f7a1e981f8ef6ab87cc))
* **projects:** 添加表格页面示例 ([51c744c](https://github.com/honghuangdc/soybean-admin/commit/51c744c8e2c8ed9691e92e35b6a88582f22c30d8))
* **projects:** 添加路由跳转浏览器新标签 ([987cef3](https://github.com/honghuangdc/soybean-admin/commit/987cef336338987f2e6f0d5aba8f6d4602b297ca))
* **projects:** 登录页面开始迁移 ([f5a36a0](https://github.com/honghuangdc/soybean-admin/commit/f5a36a05cb626ec62115283f1d2c534b2a787bdd))
* **projects:** 细节完善 ([cc290ac](https://github.com/honghuangdc/soybean-admin/commit/cc290accc29282e9ba655356e2695b6ca4b23605))
* **projects:** 细节完善、迁移页面 ([ce531ce](https://github.com/honghuangdc/soybean-admin/commit/ce531ce5dda0b4a1024aa6bd3d68835b59760d57))
* **projects:** 菜单搜索增加大小写转换 ([2907868](https://github.com/honghuangdc/soybean-admin/commit/29078689b0652cf4ae852c93d8601a157579adcc))
* **projects:** 请求拦截器添加刷新token ([839b82b](https://github.com/honghuangdc/soybean-admin/commit/839b82ba8b052b02e24bcfe6da54160609a4fd4b))
* **projects:** 路由页面跳转权限完成 ([0d2a562](https://github.com/honghuangdc/soybean-admin/commit/0d2a5629e89c73a32d6c79f04b51543e1513e006))
* **projects:** 迁移多页签 ([28efbdb](https://github.com/honghuangdc/soybean-admin/commit/28efbdbc70733d22011a0eee084d35711429d188))
* **projects:** 迁移登录完成 ([b93b80c](https://github.com/honghuangdc/soybean-admin/commit/b93b80cb4b35268dfb6a09517a2494af24748dac))
* **projects:** 集成naiveUI主题配置将css vars添加至html ([2c19684](https://github.com/honghuangdc/soybean-admin/commit/2c196841bd8527d7acccefe6a7545e0a49d532f7))
* **projects:** 面包屑 ([09c7658](https://github.com/honghuangdc/soybean-admin/commit/09c7658c21c7dda461dbb528e85b638b5a7dfacd))
### Bug Fixes
* **deps:** 降低vite版本 ([c9c5ca9](https://github.com/honghuangdc/soybean-admin/commit/c9c5ca9989eddb084f2706155473123c5dcfc334))
* **projects:** 修复redirect-not-found子路由 ([5bfb819](https://github.com/honghuangdc/soybean-admin/commit/5bfb8199b463d9ca6430577b5c493c0b78967aa9))
* **projects:** 修复vertical-mix布局、重构初始化的loading ([579e074](https://github.com/honghuangdc/soybean-admin/commit/579e07400e1b9a52934ed808a37c8579a41e8e74))
* **projects:** 修复网络请求错误空信息的提示 ([ff9216b](https://github.com/honghuangdc/soybean-admin/commit/ff9216b621aaef0a8203386fa1c3ca5477a2edea))
* **projects:** 修复面包屑数据 ([28b5d22](https://github.com/honghuangdc/soybean-admin/commit/28b5d224010a28669ad3a1919fc49f6e2dc808cd))
* **projects:** 去除Layout组件冗余代码 ([0e783bc](https://github.com/honghuangdc/soybean-admin/commit/0e783bcf7be0b3a083fe950adfb0afc72b510f97))
* **projects:** 请求相关细节修复 ([2ad1ad3](https://github.com/honghuangdc/soybean-admin/commit/2ad1ad32b8410d84902a33d825032c282ca6df86))

View File

@@ -1,16 +0,0 @@
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

View File

@@ -19,6 +19,19 @@
- **权限路由**:提供前端静态和后端动态两种路由模式,基于 mock 的动态路由能快速实现后端动态路由
- **请求函数**:基于 axios 的完善的请求函数封装,提供 Promise 和 hooks 两种请求函数,加入请求结果数据转换的适配器
## SoybeanJS 工具库
- [@soybeanjs/cli](https://github.com/soybeanjs/cli): SoybeanJS 命令行工具包含发布、git 和依赖等相关的实用命令
- [@soybeanjs/changelog](https://github.com/soybeanjs/changelog): 根据 git tags 和 commits 生成 changelog [示例](./CHANGELOG.md)
- [eslint-config-soybeanjs](https://github.com/soybeanjs/eslint-config): SoybeanJS 的 eslint 预设配置
- [@soybeanjs/materials](https://github.com/soybeanjs/materials): SoybeanJS 的物料仓库
- [@soybeanjs/vite-plugin-vue-page-route](https://github.com/soybeanjs/vite-plugin-vue-page-route): SoybeanAdmin 的路由插件
## 基于 SoybeanAdmin 二次开发的项目
- [electron-mock-admin](https://github.com/lixin59/electron-mock-api): 一个 Mock Api 管理系统,帮助前端开发伙伴快速实现接口的 mock。
- [T-Shell](https://github.com/TheBlindM/T-Shell): 是一个可配置命令提示的终端模拟器和 SSH 客户端。
## 在线预览
- [Soybean Admin 预览地址](https://soybean.pro/)
@@ -29,12 +42,12 @@
## 代码仓库
- [github](https://github.com/honghuangdc/soybean-admin)
- [tauri 版](https://github.com/honghuangdc/soybean-admin/tree/tauri)
- [精简版](https://github.com/honghuangdc/soybean-admin/tree/thin)
- [gitee](https://gitee.com/honghuangdc/soybean-admin)
- [tauri 版](https://gitee.com/honghuangdc/soybean-admin/tree/tauri)
- [精简版](https://gitee.com/honghuangdc/soybean-admin/tree/thin)
| 仓库 | github 地址 | gitee 镜像 | 预览 |
| -------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
| soybean-admin | [github](https://github.com/honghuangdc/soybean-admin) | [gitee](https://gitee.com/honghuangdc/soybean-admin) | [预览](https://soybean.pro/) |
| tauri 版 | [tauri 版](https://github.com/honghuangdc/soybean-admin/tree/tauri) | [tauri 版](https://gitee.com/honghuangdc/soybean-admin/tree/tauri) | |
| 精简版 | [精简版](https://github.com/honghuangdc/soybean-admin/tree/thin) | [精简版](https://gitee.com/honghuangdc/soybean-admin/tree/thin) | |
| 集成 fast-crud | [集成 fast-crud](https://github.com/honghuangdc/soybean-admin/tree/fast-crud) | [集成 fast-crud](https://gitee.com/honghuangdc/soybean-admin/tree/fast-crud) | [预览](http://fast-crud.docmirror.cn/soybean/#/crud/demo) |
## 更新日志
@@ -54,13 +67,15 @@
![](https://s2.loli.net/2022/05/16/rSnNHLdpuvkKxWq.png)
![](https://s2.loli.net/2023/06/07/O39EKNa675FZIuS.png)
![](https://s2.loli.net/2022/05/18/Mt6YZqmDxO8v4uR.png)
![](https://s2.loli.net/2022/05/16/ktH5dcG3fuFOoKA.png)
![](https://s2.loli.net/2023/06/07/zhmWnFlPTfDpot8.png)
![](https://s2.loli.net/2022/05/16/VPl6Ru1iCAhLcS4.png)
![](https://s2.loli.net/2022/05/16/bRlAKuHW7ZVh9DT.png)
![](https://s2.loli.net/2023/06/07/n6Dy1HXBvuPc9oT.png)
![](https://s2.loli.net/2022/06/07/rY8TyAftM5dxspv.png)
@@ -68,6 +83,12 @@
![](https://s2.loli.net/2022/06/07/rRSG6mEZpujOACT.png)
<div align="center">
<img style="width:380px;margin-right:18px;border:1px solid #dedede;" src="https://s2.loli.net/2023/06/07/A5Nonc9vI6pB1lr.png" />
&nbsp;
<img style="width:380px;border:1px solid #dedede;" src="https://s2.loli.net/2023/06/07/VwBjqEhTke3OxXF.png" />
</div>
## 安装使用
- 环境配置
@@ -119,9 +140,6 @@ docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
项目已用 simple-git-hooks 代替了 husky, 旧版本用了 husky执行 pnpm soy init-git-hooks 进行初始化配置
## 基于 SoybeanAdmin 二次开发的项目
[electron-mock-admin](https://github.com/lixin59/electron-mock-api): 一个 Mock Api 管理系统帮助前端开发伙伴快速实现接口的mock。
## 浏览器支持
本地开发推荐使用`Chrome 90+` 浏览器
@@ -138,16 +156,16 @@ docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
## 交流
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群(人员已满),使用问题欢迎在群内提问。
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群,使用问题欢迎在群内提问。
<div style="display:flex;">
<div style="padding-right:24px;">
<p>微信交流群</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybeanjs-wechat2.jpeg" style="width:200px" />
<p>QQ交流群</p>
<img src="https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg" style="width:200px" />
</div>
<div>
<p>添加本人微信,欢迎来技术交流,业务咨询</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybeanjs.jpeg" style="width:180px" />
<img src="https://s2.loli.net/2023/06/07/sVyCUFBvzQ9f5b7.jpg" style="width:200px" />
</div>
</div>
@@ -159,4 +177,4 @@ docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
## License
[MIT © Soybean-2021](./LICENSE)
本项目基于[MIT © Soybean-2021](./LICENSE) 协议,仅供参考学习,商用时请保留作者的版权信息,作者不对软件做担保和负责。

View File

@@ -1,8 +0,0 @@
import dayjs from 'dayjs';
/** 项目构建时间 */
const PROJECT_BUILD_TIME = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss'));
export const viteDefine = {
PROJECT_BUILD_TIME
};

View File

@@ -1,2 +1 @@
export * from './define';
export * from './proxy';

View File

@@ -1,6 +0,0 @@
import ViteCompression from 'vite-plugin-compression';
export default (viteEnv: ImportMetaEnv) => {
const { VITE_COMPRESS_TYPE = 'gzip' } = viteEnv;
return ViteCompression({ algorithm: VITE_COMPRESS_TYPE });
};

View File

@@ -1,14 +0,0 @@
import type { PluginOption } from 'vite';
import { createHtmlPlugin } from 'vite-plugin-html';
export default (viteEnv: ImportMetaEnv): PluginOption[] => {
return createHtmlPlugin({
minify: true,
inject: {
data: {
appName: viteEnv.VITE_APP_NAME,
appTitle: viteEnv.VITE_APP_TITLE
}
}
});
};

View File

@@ -2,30 +2,31 @@ import type { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import unocss from '@unocss/vite';
import progress from 'vite-plugin-progress';
import VueDevtools from 'vite-plugin-vue-devtools';
import pageRoute from '@soybeanjs/vite-plugin-vue-page-route';
import html from './html';
import unplugin from './unplugin';
import mock from './mock';
import visualizer from './visualizer';
import compress from './compress';
import pwa from './pwa';
/**
* vite插件
* @param viteEnv - 环境变量配置
*/
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] {
const plugins = [vue(), vueJsx(), html(viteEnv), ...unplugin(viteEnv), unocss(), mock, progress(), pageRoute()];
const plugins = [
vue({
script: {
defineModel: true
}
}),
vueJsx(),
VueDevtools(),
...unplugin(viteEnv),
unocss(),
mock(viteEnv)
];
if (viteEnv.VITE_VISUALIZER === 'Y') {
plugins.push(visualizer as PluginOption);
}
if (viteEnv.VITE_COMPRESS === 'Y') {
plugins.push(compress(viteEnv));
}
if (viteEnv.VITE_PWA === 'Y' || viteEnv.VITE_VERCEL === 'Y') {
plugins.push(pwa());
if (viteEnv.VITE_SOYBEAN_ROUTE_PLUGIN === 'Y') {
plugins.push(pageRoute());
}
return plugins;

View File

@@ -1,9 +1,14 @@
import { viteMockServe } from 'vite-plugin-mock';
export default viteMockServe({
mockPath: 'mock',
injectCode: `
import { setupMockServer } from '../mock';
setupMockServer();
`
});
export default (viteEnv: ImportMetaEnv) => {
const prodMock = viteEnv.VITE_PROD_MOCK === 'Y';
return viteMockServe({
mockPath: 'mock',
prodEnabled: prodMock,
injectCode: `
import { setupMockServer } from '../mock';
setupMockServer();
`
});
};

View File

@@ -1,31 +0,0 @@
import { VitePWA } from 'vite-plugin-pwa';
export default function setupVitePwa() {
return VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico'],
manifest: {
name: 'SoybeanAdmin',
short_name: 'SoybeanAdmin',
theme_color: '#fff',
icons: [
{
src: '/logo.png',
sizes: '192x192',
type: 'image/png'
},
{
src: '/logo.png',
sizes: '512x512',
type: 'image/png'
},
{
src: '/logo.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable'
}
]
}
});
}

View File

@@ -1,4 +1,3 @@
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';
@@ -17,7 +16,6 @@ export default function unplugin(viteEnv: ImportMetaEnv) {
const collectionName = VITE_ICON_LOCAL_PREFFIX.replace(`${VITE_ICON_PREFFIX}-`, '');
return [
VueMacros({}),
Icons({
compiler: 'vue3',
customCollections: {

View File

@@ -1,7 +0,0 @@
import { visualizer } from 'rollup-plugin-visualizer';
export default visualizer({
gzipSize: true,
brotliSize: true,
open: true
});

View File

@@ -1,21 +0,0 @@
{
"types": {
"feat": { "title": "🚀 Features" },
"perf": { "title": "🔥 Performance" },
"fix": { "title": "🩹 Fixes" },
"refactor": { "title": "💅 Refactors" },
"docs": { "title": "📖 Documentation" },
"types": { "title": "🌊 Types" },
"chore": { "title": "🏡 Chore" },
"test": { "title": "🧪 Tests" },
"style": { "title": "🎨 Styles" },
"ci": { "title": "🤖 CI" }
},
"scopeMap": {},
"titles": {
"breakingChanges": "🚨 Breaking Changes"
},
"contributors": true,
"capitalize": true,
"group": true
}

View File

@@ -1,32 +0,0 @@
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

View File

@@ -1,24 +0,0 @@
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

View File

@@ -1,54 +0,0 @@
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;
}
}
}

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= appName %></title>
<title>%VITE_APP_NAME%</title>
</head>
<body>
<div id="app">

View File

@@ -1,5 +1,4 @@
import auth from './auth';
import route from './route';
import management from './management';
export default [...auth, ...route, ...management];
export default [...auth, ...route];

View File

@@ -1,33 +0,0 @@
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;

View File

@@ -8,7 +8,7 @@ const apis: MockMethod[] = [
response: (options: Service.MockOption): Service.MockServiceResult => {
const { userId = undefined } = options.body;
const routeHomeName: AuthRoute.LastDegreeRouteKey = 'dashboard_analysis';
const routeHomeName: AuthRoute.LastDegreeRouteKey = 'multi-menu_first_second';
const role = userModel.find(item => item.userId === userId)?.userRole || 'user';

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "soybean-admin",
"version": "0.9.9",
"version": "0.10.3",
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
"author": {
"name": "Soybean",
@@ -44,97 +44,65 @@
"build:vercel": "cross-env VITE_HASH_ROUTE=Y VITE_VERCEL=Y vite build",
"preview": "vite preview",
"typecheck": "vue-tsc --noEmit --skipLibCheck",
"lint": "eslint . --fix --ext .js,.jsx,.mjs,.json,.ts,.tsx,.vue",
"format": "soy prettier-format",
"lint": "eslint . --fix",
"format": "soy prettier-write",
"commit": "soy git-commit",
"cleanup": "soy cleanup",
"update-pkg": "soy update-pkg",
"update-pkg": "soy ncu",
"tsx": "tsx",
"logo": "tsx ./scripts/logo.ts",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"release": "standard-version",
"prepare": "soy init-git-hooks"
"logo": "tsx ./scripts/logo.ts"
},
"dependencies": {
"@antv/data-set": "^0.11.8",
"@antv/g2": "^4.2.9",
"@better-scroll/core": "^2.5.0",
"@soybeanjs/vue-admin-layout": "^1.1.1",
"@soybeanjs/vue-admin-tab": "^1.0.5",
"@soybeanjs/vue-materials": "^0.1.8",
"@vueuse/core": "^9.13.0",
"axios": "0.27.2",
"clipboard": "^2.0.11",
"colord": "^2.9.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.7",
"echarts": "^5.4.1",
"form-data": "^4.0.0",
"lodash-es": "^4.17.21",
"naive-ui": "2.34.3",
"pinia": "^2.0.33",
"print-js": "^1.6.0",
"qs": "^6.11.1",
"swiper": "^9.1.0",
"ua-parser-js": "^1.0.34",
"vditor": "^3.9.0",
"vue": "3.2.47",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.6",
"vuedraggable": "^4.1.0",
"wangeditor": "^4.7.15",
"xgplayer": "^2.32.2"
"@better-scroll/core": "2.5.1",
"@soybeanjs/vue-materials": "0.2.0",
"@vueuse/core": "10.1.2",
"axios": "1.4.0",
"clipboard": "2.0.11",
"colord": "2.9.3",
"crypto-js": "4.1.1",
"dayjs": "1.11.8",
"form-data": "4.0.0",
"lodash-es": "4.17.21",
"naive-ui": "2.34.4",
"pinia": "2.1.4",
"qs": "6.11.2",
"ua-parser-js": "1.0.35",
"vue": "3.3.4",
"vue-i18n": "9.2.2",
"vue-router": "4.2.2"
},
"devDependencies": {
"@amap/amap-jsapi-types": "^0.0.13",
"@iconify/json": "^2.2.33",
"@iconify/vue": "^4.1.0",
"@soybeanjs/cli": "^0.1.7",
"@soybeanjs/vite-plugin-vue-page-route": "^0.0.5",
"@types/bmapgl": "^0.0.5",
"@types/crypto-js": "^4.1.1",
"@types/node": "18.15.0",
"@types/qs": "^6.9.7",
"@types/ua-parser-js": "^0.7.36",
"@unocss/preset-uno": "^0.50.4",
"@unocss/transformer-directives": "^0.50.4",
"@unocss/vite": "^0.50.4",
"@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
"conventional-changelog": "^3.1.25",
"cross-env": "^7.0.3",
"eslint": "^8.36.0",
"eslint-config-soybeanjs": "^0.3.1",
"lint-staged": "12.5.0",
"mockjs": "^1.1.0",
"rollup-plugin-visualizer": "^5.9.0",
"sass": "^1.59.2",
"simple-git-hooks": "^2.8.1",
"standard-version": "^9.5.0",
"tsx": "^3.12.4",
"typescript": "4.9.5",
"unplugin-icons": "^0.15.3",
"unplugin-vue-components": "0.24.1",
"unplugin-vue-macros": "1.6.4",
"vite": "^4.1.4",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.0",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-progress": "^0.0.6",
"vite-plugin-pwa": "^0.14.4",
"vite-plugin-svg-icons": "^2.0.1",
"vue-tsc": "^1.2.0"
"@iconify/json": "2.2.78",
"@iconify/vue": "4.1.1",
"@soybeanjs/cli": "0.6.2",
"@soybeanjs/vite-plugin-vue-page-route": "0.0.5",
"@types/crypto-js": "4.1.1",
"@types/node": "20.3.1",
"@types/qs": "6.9.7",
"@types/ua-parser-js": "0.7.36",
"@unocss/preset-uno": "0.53.1",
"@unocss/transformer-directives": "0.53.1",
"@unocss/vite": "0.53.1",
"@vitejs/plugin-vue": "4.2.3",
"@vitejs/plugin-vue-jsx": "3.0.1",
"cross-env": "7.0.3",
"eslint": "8.42.0",
"eslint-config-soybeanjs": "0.4.9",
"mockjs": "1.1.0",
"sass": "1.63.4",
"tsx": "3.12.7",
"typescript": "5.1.3",
"unplugin-icons": "0.16.3",
"unplugin-vue-components": "0.25.1",
"vite": "4.3.9",
"vite-plugin-mock": "2.9.8",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "0.2.0",
"vue-tsc": "1.6.5"
},
"pnpm": {
"patchedDependencies": {
"mockjs@1.1.0": "patches/mockjs@1.1.0.patch"
}
},
"simple-git-hooks": {
"commit-msg": "pnpm soy git-commit-verify",
"pre-commit": "pnpm typecheck && pnpm lint-staged"
},
"lint-staged": {
"*.{js,jsx,mjs,json,ts,tsx,vue}": "eslint . --fix"
}
}

View File

@@ -5,56 +5,56 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
@@ -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,
+ 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) { //
+ 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 &&
@@ -63,41 +63,41 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
var tpl = Mock.heredoc(function() {
/*!
{{email}}{{age}}
- <!-- Mock {
- <!-- 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
@@ -106,16 +106,16 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
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.
@@ -124,7 +124,7 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
color += letters[Math.floor(Math.random() * 16)]
}
return color
-
-
+
// 随机生成一个无脑的颜色,格式为 '#RRGGBB'。
// _brainlessColor()
@@ -133,24 +133,24 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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
+ http Hypertext Transfer Protocol
+ ftp File Transfer protocol
+ gopher The Gopher protocol
@@ -161,7 +161,7 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
+ 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
+ wais Wide Area Information Servers
*/
url: function(protocol, host) {
@@ -170,10 +170,10 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
西南 重庆市 四川省 贵州省 云南省 西藏自治区
西北 陕西省 甘肃省 青海省 宁夏回族自治区 新疆维吾尔自治区
港澳台 香港特别行政区 澳门特别行政区 台湾省
-
-
+
**排序**
-
-
+
```js
var map = {}
@@ -182,25 +182,25 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
"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++),
+ 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.expected = n, this.found = l, this.offset = u, this.line = t, this.column = r,
this.name = "SyntaxError", this.message = e(n, l);
}
@@ -209,8 +209,8 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
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,
+ 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);
@@ -220,10 +220,10 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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,
+ 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,
@@ -232,13 +232,13 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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(),
+ 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(),
+ 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 !== 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;
@@ -247,43 +247,43 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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)),
+ 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),
+ 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,
+ 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(),
+ 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,
+ 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,
@@ -293,9 +293,9 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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,
+ 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,
@@ -303,9 +303,9 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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,
+ 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,
@@ -313,45 +313,45 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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)),
+ 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)),
+ 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)),
+ 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),
+ 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,
+ 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,
+ 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)),
@@ -360,46 +360,46 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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,
+ 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,
+ 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,
+ 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,
+ 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)),
+ 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(),
+ 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,
+ 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);
@@ -408,9 +408,9 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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--,
+ 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--,
@@ -418,22 +418,22 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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)),
+ 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(),
+ 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(),
@@ -445,25 +445,25 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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,
+ 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()))))))))))))))))))),
+ 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(),
@@ -473,93 +473,93 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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)),
+ 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,
+ 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,
@@ -567,9 +567,9 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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,
+ 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,
@@ -577,15 +577,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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),
+ 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,
+ null !== t ? (Lt = l, u = Rt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il);
} else qt = l, l = il;
@@ -593,15 +593,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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),
+ 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,
+ null !== t ? (Lt = l, u = Et(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il);
} else qt = l, l = il;
@@ -609,15 +609,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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),
+ 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,
+ null !== t ? (Lt = l, u = jt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il);
} else qt = l, l = il;
@@ -625,15 +625,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
}
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)),
+ 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,
+ 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,
@@ -644,7 +644,7 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
var Util = __webpack_require__(3)
var Random = __webpack_require__(5)
/*
-
-
+
*/
var Handler = {
@@ -653,21 +653,21 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
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 属性名
+ name 属性名
type 属性值类型
template 属性值模板
@@ -675,8 +675,8 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
@@ -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/)
@@ -685,25 +685,25 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
+step
整数部分
小数部分
- boolean
- string
- 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
@@ -711,22 +711,22 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
- 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
}
}

9904
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -54,7 +54,7 @@ const props = withDefaults(defineProps<Props>(), {
placeholderClass: 'bg-white dark:bg-dark transition-background-color duration-300 ease-in-out',
emptyDesc: '暂无数据',
iconClass: 'text-320px text-primary',
descClass: 'text-16px text-[#666]',
descClass: 'text-16px text-#666',
showNetworkReload: false
});

View File

@@ -1,7 +1,7 @@
<template>
<div
class="dark:bg-[#18181c] dark:text-white dark:text-opacity-82 transition-all"
:class="inverted ? 'bg-[#001428] text-white' : 'bg-white text-[#333639]'"
class="dark:bg-dark dark:text-white dark:text-opacity-82 transition-all"
:class="inverted ? 'bg-#001428 text-white' : 'bg-white text-#333639'"
>
<slot></slot>
</div>

View File

@@ -34,9 +34,51 @@ const darkMode = computed({
}
});
function handleSwitch() {
darkMode.value = !darkMode.value;
function handleSwitch(event: MouseEvent) {
const x = event.clientX;
const y = event.clientY;
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
// @ts-expect-error: Transition API
if (!document.startViewTransition) {
darkMode.value = !darkMode.value;
return;
}
// @ts-expect-error: Transition API
const transition = document.startViewTransition(() => {
darkMode.value = !darkMode.value;
});
transition.ready.then(() => {
const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];
document.documentElement.animate(
{
clipPath: darkMode.value ? clipPath : [...clipPath].reverse()
},
{
duration: 300,
easing: 'ease-in',
pseudoElement: darkMode.value ? '::view-transition-new(root)' : '::view-transition-old(root)'
}
);
});
}
</script>
<style scoped></style>
<style>
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-old(root) {
z-index: 9999;
}
::view-transition-new(root) {
z-index: 1;
}
.dark::view-transition-old(root) {
z-index: 1;
}
.dark::view-transition-new(root) {
z-index: 9999;
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="flex-col-center wh-full">
<div class="text-400px text-primary">
<div class="flex-col-center gap-24px min-h-520px wh-full overflow-hidden">
<div class="flex text-400px text-primary">
<icon-local-no-permission v-if="type === '403'" />
<icon-local-not-found v-if="type === '404'" />
<icon-local-service-error v-if="type === '500'" />

View File

@@ -2,14 +2,14 @@
<div v-if="showTooltip">
<n-tooltip :placement="placement" trigger="hover">
<template #trigger>
<div class="flex-center h-full cursor-pointer dark:hover:bg-[#333]" :class="contentClassName">
<div class="flex-center h-full cursor-pointer dark:hover:bg-#333" :class="contentClassName">
<slot></slot>
</div>
</template>
{{ tooltipContent }}
</n-tooltip>
</div>
<div v-else class="flex-center cursor-pointer dark:hover:bg-[#333]" :class="contentClassName">
<div v-else class="flex-center cursor-pointer dark:hover:bg-#333" :class="contentClassName">
<slot></slot>
</div>
</template>
@@ -41,7 +41,7 @@ const props = withDefaults(defineProps<Props>(), {
const showTooltip = computed(() => Boolean(props.tooltipContent));
const contentClassName = computed(
() => `${props.contentClass} ${props.inverted ? 'hover:bg-primary' : 'hover:bg-[#f6f6f6]'}`
() => `${props.contentClass} ${props.inverted ? 'hover:bg-primary' : 'hover:bg-#f6f6f6'}`
);
</script>

View File

@@ -1,116 +0,0 @@
<template>
<span>{{ value }}</span>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, watch, watchEffect } from 'vue';
import { TransitionPresets, useTransition } from '@vueuse/core';
import { isNumber } from '@/utils';
defineOptions({ name: 'CountTo' });
type TansitionKey = keyof typeof TransitionPresets;
interface Props {
/** 初始值 */
startValue?: number;
/** 结束值 */
endValue?: number;
/** 动画时长 */
duration?: number;
/** 自动动画 */
autoplay?: boolean;
/** 进制 */
decimals?: number;
/** 前缀 */
prefix?: string;
/** 后缀 */
suffix?: string;
/** 分割符号 */
separator?: string;
/** 小数点 */
decimal?: string;
/** 使用缓冲动画函数 */
useEasing?: boolean;
/** 缓冲动画函数类型 */
transition?: TansitionKey;
}
const props = withDefaults(defineProps<Props>(), {
startValue: 0,
endValue: 2021,
duration: 1500,
autoplay: true,
decimals: 0,
prefix: '',
suffix: '',
separator: ',',
decimal: '.',
useEasing: true,
transition: 'linear'
});
interface Emits {
(e: 'on-started'): void;
(e: 'on-finished'): void;
}
const emit = defineEmits<Emits>();
const source = ref(props.startValue);
let outputValue = useTransition(source);
const value = computed(() => formatNumber(outputValue.value));
const disabled = ref(false);
function run() {
outputValue = useTransition(source, {
disabled,
duration: props.duration,
onStarted: () => emit('on-started'),
onFinished: () => emit('on-finished'),
...(props.useEasing ? { transition: TransitionPresets[props.transition] } : {})
});
}
function start() {
run();
source.value = props.endValue;
}
function formatNumber(num: number | string) {
if (num !== 0 && !num) {
return '';
}
const { decimals, decimal, separator, suffix, prefix } = props;
let number = Number(num).toFixed(decimals);
number = String(number);
const x = number.split('.');
let x1 = x[0];
const x2 = x.length > 1 ? decimal + x[1] : '';
const rgx = /(\d+)(\d{3})/;
if (separator && !isNumber(separator)) {
while (rgx.test(x1)) {
x1 = x1.replace(rgx, `$1${separator}$2`);
}
}
return prefix + x1 + x2 + suffix;
}
watch([() => props.startValue, () => props.endValue], () => {
if (props.autoplay) {
start();
}
});
watchEffect(() => {
source.value = props.startValue;
});
onMounted(() => {
if (props.autoplay) {
start();
}
});
</script>
<style scoped></style>

View File

@@ -1,17 +0,0 @@
<template>
<web-site-link label="github地址" :link="link" />
</template>
<script setup lang="ts">
import WebSiteLink from './web-site-link.vue';
defineOptions({ name: 'GithubLink' });
interface Props {
/** github链接 */
link: string;
}
defineProps<Props>();
</script>
<style scoped></style>

View File

@@ -1,77 +0,0 @@
<template>
<n-popover placement="bottom-end" trigger="click">
<template #trigger>
<n-input v-model:value="modelValue" readonly placeholder="点击选择图标">
<template #suffix>
<svg-icon :icon="selectedIcon" class="text-30px p-5px" />
</template>
</n-input>
</template>
<template #header>
<n-input v-model:value="searchValue" placeholder="搜索图标"></n-input>
</template>
<div v-if="iconsList.length > 0" class="grid grid-cols-9 h-auto overflow-auto">
<span v-for="iconItem in iconsList" :key="iconItem" @click="handleChange(iconItem)">
<svg-icon
:icon="iconItem"
class="border-1px border-[#d9d9d9] text-30px m-2px p-5px cursor-pointer"
:class="{ 'border-primary': modelValue === iconItem }"
/>
</span>
</div>
<n-empty v-else class="w-306px" description="你什么也找不到" />
</n-popover>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
defineOptions({ name: 'IconSelect' });
interface Props {
/** 选中的图标 */
value: string;
/** 图标列表 */
icons: string[];
/** 未选中图标 */
emptyIcon?: string;
}
const props = withDefaults(defineProps<Props>(), {
emptyIcon: 'mdi:apps'
});
interface Emits {
(e: 'update:value', val: string): void;
}
const emit = defineEmits<Emits>();
const modelValue = computed({
get() {
return props.value;
},
set(val: string) {
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) {
modelValue.value = iconItem;
}
</script>
<style lang="scss" scoped>
:deep(.n-input-wrapper) {
padding-right: 0;
}
:deep(.n-input__suffix) {
border: 1px solid #d9d9d9;
}
</style>

View File

@@ -1,42 +0,0 @@
<template>
<div>
<canvas ref="domRef" width="152" height="40" class="cursor-pointer" @click="getImgCode"></canvas>
</div>
</template>
<script setup lang="ts">
import { watch } from 'vue';
import { useImageVerify } from '@/hooks';
defineOptions({ name: 'ImageVerify' });
interface Props {
code?: string;
}
const props = withDefaults(defineProps<Props>(), {
code: ''
});
interface Emits {
(e: 'update:code', code: string): void;
}
const emit = defineEmits<Emits>();
const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify();
watch(
() => props.code,
newValue => {
setImgCode(newValue);
}
);
watch(imgCode, newValue => {
emit('update:code', newValue);
});
defineExpose({ getImgCode });
</script>
<style scoped></style>

View File

@@ -1,23 +0,0 @@
<template>
<p>
<span>{{ label }}</span>
<a class="text-blue-500" :href="link" target="_blank">
{{ link }}
</a>
</p>
</template>
<script setup lang="ts">
defineOptions({ name: 'WebSiteLink' });
interface Props {
/** 网址名称 */
label: string;
/** 网址链接 */
link: string;
}
defineProps<Props>();
</script>
<style scoped></style>

View File

@@ -1,174 +0,0 @@
import { nextTick, effectScope, onScopeDispose, 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?.clear();
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 scope = effectScope();
scope.run(() => {
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();
}
}
});
watch(
options,
newValue => {
update(newValue);
},
{ deep: true }
);
watch(
() => theme.darkMode,
() => {
updateTheme();
}
);
});
onScopeDispose(() => {
destroy();
scope.stop();
});
return {
domRef
};
}

View File

@@ -1,14 +1,34 @@
import { effectScope, onScopeDispose, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useEventListener } from '@vueuse/core';
import { useI18n } from 'vue-i18n';
import { useTabStore, useThemeStore } from '@/store';
/** 全局事件 */
export function useGlobalEvents() {
const theme = useThemeStore();
const tab = useTabStore();
const route = useRoute();
const { locale, t } = useI18n();
const scope = effectScope();
/** 页面离开时缓存多页签数据 */
useEventListener(window, 'beforeunload', () => {
theme.cacheThemeSettings();
tab.cacheTabRoutes();
});
scope.run(() => {
// 国际化切换时更新浏览器标签文本
watch(
() => locale.value,
() => {
document.title = route.meta.i18nTitle ? t(route.meta.i18nTitle) : route.meta.title;
}
);
});
onScopeDispose(() => {
scope.stop();
});
}

View File

@@ -1,5 +1,5 @@
import { h } from 'vue';
import SvgIcon from '~/src/components/custom/svg-icon.vue';
import SvgIcon from '@/components/custom/svg-icon.vue';
/**
* 图标渲染
@@ -48,7 +48,7 @@ export const useIconRender = () => {
}
if (!icon && !localIcon) {
window.console.warn('没有传递图标名称请确保给icon或localIcon传递有效值!');
throw Error('没有传递图标名称请确保给icon或localIcon传递有效值!');
}
return () => h(SvgIcon, { icon, localIcon, style });

View File

@@ -2,5 +2,4 @@ export * from './system';
export * from './router';
export * from './layout';
export * from './events';
export * from './echarts';
export * from './icon';

View File

@@ -1,4 +1,4 @@
import { computed } from 'vue';
import { computed, watch } from 'vue';
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core';
import { useAppStore, useThemeStore } from '@/store';
@@ -63,6 +63,16 @@ export function useBasicLayout() {
return w;
});
watch(
isMobile,
newValue => {
if (newValue) {
app.setSiderCollapse(true);
}
},
{ immediate: true }
);
return {
mode,
isMobile,

View File

@@ -1,3 +1,2 @@
export * from './service';
export * from './regexp';
export * from './map-sdk';

View File

@@ -1,8 +0,0 @@
/** 百度地图sdk地址 */
export const BAIDU_MAP_SDK_URL = `https://api.map.baidu.com/getscript?v=3.0&ak=KSezYymXPth1DIGILRX3oYN9PxbOQQmU&services=&t=20210201100830&s=1`;
/** 高德地图sdk地址 */
export const GAODE_MAP_SDK_URL = 'https://webapi.amap.com/maps?v=2.0&key=e7bd02bd504062087e6563daf4d6721d';
/** 腾讯地图sdk地址 */
export const TENCENT_MAP_SDK_URL = 'https://map.qq.com/api/gljs?v=1.exp&key=A6DBZ-KXPLW-JKSRY-ONZF4-CPHY3-K6BL7';

6
src/constants/_shared.ts Normal file
View File

@@ -0,0 +1,6 @@
export function transformObjectToOption<T extends object>(obj: T) {
return Object.entries(obj).map(([value, label]) => ({
value,
label
})) as Common.OptionWithKey<keyof T>[];
}

View File

@@ -1,3 +1,5 @@
import { transformObjectToOption } from './_shared';
export const loginModuleLabels: Record<UnionKey.LoginModule, string> = {
'pwd-login': '账密登录',
'code-login': '手机验证码登录',
@@ -11,35 +13,4 @@ export const userRoleLabels: Record<Auth.RoleType, string> = {
admin: '管理员',
user: '普通用户'
};
export const userRoleOptions: Common.OptionWithKey<Auth.RoleType>[] = [
{ value: 'super', label: userRoleLabels.super },
{ value: 'admin', label: userRoleLabels.admin },
{ value: 'user', label: userRoleLabels.user }
];
/** 用户性别 */
export const genderLabels: Record<UserManagement.GenderKey, string> = {
0: '女',
1: '男'
};
export const genderOptions: Common.OptionWithKey<UserManagement.GenderKey>[] = [
{ value: '0', label: genderLabels['0'] },
{ value: '1', label: genderLabels['1'] }
];
/** 用户状态 */
export const userStatusLabels: Record<UserManagement.UserStatusKey, string> = {
1: '启用',
2: '禁用',
3: '冻结',
4: '软删除'
};
export const userStatusOptions: Common.OptionWithKey<UserManagement.UserStatusKey>[] = [
{ value: '1', label: userStatusLabels['1'] },
{ value: '2', label: userStatusLabels['2'] },
{ value: '3', label: userStatusLabels['3'] },
{ value: '4', label: userStatusLabels['4'] }
];
export const userRoleOptions = transformObjectToOption(userRoleLabels);

View File

@@ -1,81 +1,31 @@
import { transformObjectToOption } from './_shared';
export const themeLayoutModeLabels: Record<UnionKey.ThemeLayoutMode, string> = {
vertical: '左侧菜单模式',
horizontal: '顶部菜单模式',
'vertical-mix': '左侧菜单混合模式',
'horizontal-mix': '顶部菜单混合模式'
};
export const themeLayoutModeOptions: Common.OptionWithKey<UnionKey.ThemeLayoutMode>[] = [
{
value: 'vertical',
label: themeLayoutModeLabels.vertical
},
{
value: 'horizontal',
label: themeLayoutModeLabels.horizontal
},
{
value: 'vertical-mix',
label: themeLayoutModeLabels['vertical-mix']
},
{
value: 'horizontal-mix',
label: themeLayoutModeLabels['horizontal-mix']
}
];
export const themeLayoutModeOptions = transformObjectToOption(themeLayoutModeLabels);
export const themeScrollModeLabels: Record<UnionKey.ThemeScrollMode, string> = {
wrapper: '外层滚动',
content: '主体滚动'
};
export const themeScrollModeOptions: Common.OptionWithKey<UnionKey.ThemeScrollMode>[] = [
{
value: 'wrapper',
label: themeScrollModeLabels.wrapper
},
{
value: 'content',
label: themeScrollModeLabels.content
}
];
export const themeScrollModeOptions = transformObjectToOption(themeScrollModeLabels);
export const themeTabModeLabels: Record<UnionKey.ThemeTabMode, string> = {
chrome: '谷歌风格',
button: '按钮风格'
};
export const themeTabModeOptions: Common.OptionWithKey<UnionKey.ThemeTabMode>[] = [
{
value: 'chrome',
label: themeTabModeLabels.chrome
},
{
value: 'button',
label: themeTabModeLabels.button
}
];
export const themeTabModeOptions = transformObjectToOption(themeTabModeLabels);
export const themeHorizontalMenuPositionLabels: Record<UnionKey.ThemeHorizontalMenuPosition, string> = {
'flex-start': '居左',
center: '居中',
'flex-end': '居右'
};
export const themeHorizontalMenuPositionOptions: Common.OptionWithKey<UnionKey.ThemeHorizontalMenuPosition>[] = [
{
value: 'flex-start',
label: themeHorizontalMenuPositionLabels['flex-start']
},
{
value: 'center',
label: themeHorizontalMenuPositionLabels.center
},
{
value: 'flex-end',
label: themeHorizontalMenuPositionLabels['flex-end']
}
];
export const themeHorizontalMenuPositionOptions = transformObjectToOption(themeHorizontalMenuPositionLabels);
export const themeAnimateModeLabels: Record<UnionKey.ThemeAnimateMode, string> = {
'zoom-fade': '渐变',
@@ -85,30 +35,4 @@ export const themeAnimateModeLabels: Record<UnionKey.ThemeAnimateMode, string> =
'fade-bottom': '底部消退',
'fade-scale': '缩放消退'
};
export const themeAnimateModeOptions: Common.OptionWithKey<UnionKey.ThemeAnimateMode>[] = [
{
value: 'zoom-fade',
label: themeAnimateModeLabels['zoom-fade']
},
{
value: 'zoom-out',
label: themeAnimateModeLabels['zoom-out']
},
{
value: 'fade-slide',
label: themeAnimateModeLabels['fade-slide']
},
{
value: 'fade',
label: themeAnimateModeLabels.fade
},
{
value: 'fade-bottom',
label: themeAnimateModeLabels['fade-bottom']
},
{
value: 'fade-scale',
label: themeAnimateModeLabels['fade-scale']
}
];
export const themeAnimateModeOptions = transformObjectToOption(themeAnimateModeLabels);

View File

@@ -1,5 +1,4 @@
import useCountDown from './use-count-down';
import useSmsCode from './use-sms-code';
import useImageVerify from './use-image-verify';
export { useCountDown, useSmsCode, useImageVerify };
export { useCountDown, useSmsCode };

View File

@@ -1,87 +0,0 @@
import { onMounted, ref } from 'vue';
/**
* 绘制图形验证码
* @param width - 图形宽度
* @param height - 图形高度
*/
export default function useImageVerify(width = 152, height = 40) {
const domRef = ref<HTMLCanvasElement>();
const imgCode = ref('');
function setImgCode(code: string) {
imgCode.value = code;
}
function getImgCode() {
if (!domRef.value) return;
imgCode.value = draw(domRef.value, width, height);
}
onMounted(() => {
getImgCode();
});
return {
domRef,
imgCode,
setImgCode,
getImgCode
};
}
function randomNum(min: number, max: number) {
const num = Math.floor(Math.random() * (max - min) + min);
return num;
}
function randomColor(min: number, max: number) {
const r = randomNum(min, max);
const g = randomNum(min, max);
const b = randomNum(min, max);
return `rgb(${r},${g},${b})`;
}
function draw(dom: HTMLCanvasElement, width: number, height: number) {
let imgCode = '';
const NUMBER_STRING = '0123456789';
const ctx = dom.getContext('2d');
if (!ctx) return imgCode;
ctx.fillStyle = randomColor(180, 230);
ctx.fillRect(0, 0, width, height);
for (let i = 0; i < 4; i += 1) {
const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)];
imgCode += text;
const fontSize = randomNum(18, 41);
const deg = randomNum(-30, 30);
ctx.font = `${fontSize}px Simhei`;
ctx.textBaseline = 'top';
ctx.fillStyle = randomColor(80, 150);
ctx.save();
ctx.translate(30 * i + 23, 15);
ctx.rotate((deg * Math.PI) / 180);
ctx.fillText(text, -15 + 5, -15);
ctx.restore();
}
for (let i = 0; i < 5; i += 1) {
ctx.beginPath();
ctx.moveTo(randomNum(0, width), randomNum(0, height));
ctx.lineTo(randomNum(0, width), randomNum(0, height));
ctx.strokeStyle = randomColor(180, 230);
ctx.closePath();
ctx.stroke();
}
for (let i = 0; i < 41; i += 1) {
ctx.beginPath();
ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI);
ctx.closePath();
ctx.fillStyle = randomColor(150, 200);
ctx.fill();
}
return imgCode;
}

View File

@@ -1,89 +0,0 @@
import { ref, reactive } from 'vue';
import type { Ref } from 'vue';
import type { DataTableBaseColumn, DataTableSelectionColumn, DataTableExpandColumn, PaginationProps } from 'naive-ui';
import type { MaybeComputedRef } from '@vueuse/core';
import type { TableColumnGroup, InternalRowData } from 'naive-ui/es/data-table/src/interface';
import { useLoadingEmpty } from '../common';
/**
* 表格的列
*/
type DataTableColumn<T = InternalRowData> =
| (Omit<TableColumnGroup<T>, 'key'> & { key: keyof T })
| (Omit<DataTableBaseColumn<T>, 'key'> & { key: keyof T })
| DataTableSelectionColumn<T>
| DataTableExpandColumn<T>;
/**
* 表格分页参数
*/
type TablePaginationParams = Pick<PaginationProps, 'page' | 'pageSize'>;
/**
* 表格接口的请求参数
*/
type TableApiParams = Record<string, unknown> & TablePaginationParams;
/**
* 表格接口的请求数据
*/
type TableApiData<T = InternalRowData> = {
data: T[];
pageNum: number;
pageSize: number;
total: number;
};
/**
* 表格接口的请求函数
*/
type TableApiFn<P extends TableApiParams, T extends InternalRowData> = (
params: P
) => Promise<Service.SuccessResult<TableApiData<T>>>;
export function useNaiveTable<TableData extends InternalRowData, P extends TableApiParams>(
apiFn: TableApiFn<P, TableData>,
apiParams: P,
columns: MaybeComputedRef<DataTableColumn<TableData>[]>
) {
const { loading, startLoading, endLoading, empty, setEmpty } = useLoadingEmpty();
const tableData: Ref<TableData[]> = ref([]);
async function getTableData(paginationParams?: TablePaginationParams) {
startLoading();
const params = { ...apiParams, ...paginationParams };
const { data } = await apiFn(params);
if (data) {
tableData.value = data.data;
setEmpty(data.data.length === 0);
}
endLoading();
}
const pagination: PaginationProps = reactive({
page: 1,
pageSize: 10,
showSizePicker: true,
pageSizes: [10, 15, 20, 25, 30],
onChange: (page: number) => {
pagination.page = page;
},
onUpdatePageSize: (pageSize: number) => {
pagination.pageSize = pageSize;
pagination.page = 1;
}
});
return {
tableData,
columns,
loading,
empty,
pagination,
start: getTableData
};
}

View File

@@ -1,6 +1,7 @@
<template>
<admin-layout
:mode="mode"
:is-mobile="isMobile"
:scroll-mode="theme.scrollMode"
:scroll-el-id="app.scrollElId"
:full-content="app.contentFull"
@@ -15,6 +16,8 @@
:sider-collapsed-width="siderCollapsedWidth"
:footer-visible="theme.footer.visible"
:fixed-footer="theme.footer.fixed"
:right-footer="theme.footer.right"
@click-mobile-sider-mask="app.setSiderCollapse(true)"
>
<template #header>
<global-header v-bind="headerProps" />
@@ -30,7 +33,7 @@
<global-footer />
</template>
</admin-layout>
<global-back-top />
<n-back-top :key="theme.scrollMode" :listen-to="`#${app.scrollElId}`" class="z-100" />
<setting-drawer />
</template>
@@ -38,22 +41,22 @@
import { AdminLayout } from '@soybeanjs/vue-materials';
import { useAppStore, useThemeStore } from '@/store';
import { useBasicLayout } from '@/composables';
import {
GlobalBackTop,
GlobalContent,
GlobalFooter,
GlobalHeader,
GlobalSider,
GlobalTab,
SettingDrawer
} from '../common';
import { GlobalContent, GlobalFooter, GlobalHeader, GlobalSider, GlobalTab, SettingDrawer } from '../common';
defineOptions({ name: 'BasicLayout' });
const app = useAppStore();
const theme = useThemeStore();
const { mode, headerProps, siderVisible, siderWidth, siderCollapsedWidth } = useBasicLayout();
const { mode, isMobile, headerProps, siderVisible, siderWidth, siderCollapsedWidth } = useBasicLayout();
</script>
<style scoped></style>
<style lang="scss">
#__SCROLL_EL_ID__ {
@include scrollbar(8px, #e1e1e1);
}
.dark #__SCROLL_EL_ID__ {
@include scrollbar(8px, #555);
}
</style>

View File

@@ -1,15 +0,0 @@
<template>
<n-back-top :show="show" class="z-1000" />
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useWindowScroll } from '@vueuse/core';
defineOptions({ name: 'GlobalBackTop' });
const { y: scrollY } = useWindowScroll();
const show = computed(() => scrollY.value > 180);
</script>
<style scoped></style>

View File

@@ -13,7 +13,7 @@
v-if="app.reloadFlag"
:key="route.fullPath"
:class="{ 'p-16px': showPadding }"
class="flex-grow bg-[#f6f9f8] dark:bg-[#101014] transition duration-300 ease-in-out"
class="flex-grow bg-#f6f9f8 dark:bg-#101014 transition duration-300 ease-in-out"
/>
</keep-alive>
</transition>

View File

@@ -1,11 +1,15 @@
<template>
<dark-mode-container class="flex-center h-full">
<dark-mode-container class="flex-center h-full" :inverted="theme.footer.inverted">
<span>Copyright ©2021 Soybean Admin</span>
</dark-mode-container>
</template>
<script setup lang="ts">
import { useThemeStore } from '@/store';
defineOptions({ name: 'GlobalFooter' });
const theme = useThemeStore();
</script>
<style scoped></style>

View File

@@ -1,23 +0,0 @@
<template>
<hover-container
tooltip-content="github"
class="w-40px h-full"
:inverted="theme.header.inverted"
@click="handleClickLink"
>
<icon-mdi-github class="text-20px" />
</hover-container>
</template>
<script lang="ts" setup>
import { useThemeStore } from '@/store';
defineOptions({ name: 'GithubSite' });
const theme = useThemeStore();
function handleClickLink() {
window.open('https://github.com/honghuangdc/soybean-admin', '_blank');
}
</script>
<style scoped></style>

View File

@@ -2,7 +2,7 @@
<n-breadcrumb class="px-12px">
<template v-for="breadcrumb in breadcrumbs" :key="breadcrumb.key">
<n-breadcrumb-item>
<n-dropdown v-if="breadcrumb.hasChildren" :options="breadcrumb.children" @select="dropdownSelect">
<n-dropdown v-if="breadcrumb.hasChildren" :options="breadcrumb.options" @select="dropdownSelect">
<span>
<component
:is="breadcrumb.icon"
@@ -19,7 +19,9 @@
class="inline-block align-text-bottom mr-4px text-16px"
:class="{ 'text-#BBBBBB': theme.header.inverted }"
/>
<span :class="{ 'text-#BBBBBB': theme.header.inverted }">{{ breadcrumb.label }}</span>
<span :class="{ 'text-#BBBBBB': theme.header.inverted }">
{{ breadcrumb.label }}
</span>
</template>
</n-breadcrumb-item>
</template>
@@ -33,6 +35,7 @@ import { routePath } from '@/router';
import { useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables';
import { getBreadcrumbByRouteKey } from '@/utils';
import { t } from '@/locales';
defineOptions({ name: 'GlobalBreadcrumb' });
@@ -42,7 +45,13 @@ const routeStore = useRouteStore();
const { routerPush } = useRouterPush();
const breadcrumbs = computed(() =>
getBreadcrumbByRouteKey(route.name as string, routeStore.menus as App.GlobalMenuOption[], routePath('root'))
getBreadcrumbByRouteKey(route.name as string, routeStore.menus as App.GlobalMenuOption[], routePath('root')).map(
item => ({
...item,
label: item.i18nTitle ? t(item.i18nTitle) : item.label,
options: item.options?.map(oItem => ({ ...oItem, label: oItem.i18nTitle ? t(oItem.i18nTitle) : oItem.label }))
})
)
);
function dropdownSelect(key: string) {

View File

@@ -20,6 +20,7 @@ import { useRoute } from 'vue-router';
import type { MenuOption } from 'naive-ui';
import { useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables';
import { translateMenuLabel } from '@/utils';
defineOptions({ name: 'HeaderMenu' });
@@ -28,7 +29,7 @@ const routeStore = useRouteStore();
const theme = useThemeStore();
const { routerPush } = useRouterPush();
const menus = computed(() => routeStore.menus as App.GlobalMenuOption[]);
const menus = computed(() => translateMenuLabel(routeStore.menus as App.GlobalMenuOption[]));
const activeKey = computed(() => (route.meta?.activeMenu ? route.meta.activeMenu : route.name) as string);
function handleUpdateMenu(_key: string, item: MenuOption) {

View File

@@ -1,21 +1,10 @@
import MenuCollapse from './menu-collapse.vue';
import GlobalBreadcrumb from './global-breadcrumb.vue';
import HeaderMenu from './header-menu.vue';
import GithubSite from './github-site.vue';
import FullScreen from './full-screen.vue';
import ThemeMode from './theme-mode.vue';
import UserAvatar from './user-avatar.vue';
import SystemMessage from './system-message.vue';
import SettingButton from './setting-button.vue';
import ToggleLang from './toggle-lang.vue';
export {
MenuCollapse,
GlobalBreadcrumb,
HeaderMenu,
GithubSite,
FullScreen,
ThemeMode,
UserAvatar,
SystemMessage,
SettingButton
};
export { MenuCollapse, GlobalBreadcrumb, HeaderMenu, FullScreen, ThemeMode, UserAvatar, SettingButton, ToggleLang };

View File

@@ -1,57 +0,0 @@
<template>
<n-scrollbar class="max-h-360px">
<n-list>
<n-list-item
v-for="(item, index) in list"
:key="item.id"
class="hover:bg-[#f6f6f6] dark:hover:bg-dark cursor-pointer"
@click="handleRead(index)"
>
<n-thing class="px-15px" :class="{ 'opacity-30': item.isRead }">
<template #avatar>
<n-avatar v-if="item.avatar" :src="item.avatar" />
<svg-icon v-else class="text-34px text-primary" :icon="item.icon" :local-icon="item.svgIcon" />
</template>
<template #header>
<n-ellipsis :line-clamp="1">
{{ item.title }}
<template #tooltip>
{{ item.title }}
</template>
</n-ellipsis>
</template>
<template v-if="item.tagTitle" #header-extra>
<n-tag v-bind="item.tagProps" size="small">{{ item.tagTitle }}</n-tag>
</template>
<template #description>
<n-ellipsis v-if="item.description" :line-clamp="2">
{{ item.description }}
</n-ellipsis>
<p>{{ item.date }}</p>
</template>
</n-thing>
</n-list-item>
</n-list>
</n-scrollbar>
</template>
<script lang="ts" setup>
defineOptions({ name: 'MessageList' });
interface Props {
list?: App.MessageList[];
}
withDefaults(defineProps<Props>(), {
list: () => []
});
interface Emits {
(e: 'read', val: number): void;
}
const emit = defineEmits<Emits>();
function handleRead(index: number) {
emit('read', index);
}
</script>

View File

@@ -1,217 +0,0 @@
<template>
<n-popover class="!p-0" trigger="click" placement="bottom">
<template #trigger>
<hover-container tooltip-content="消息通知" :inverted="theme.header.inverted" class="relative w-40px h-full">
<icon-clarity:notification-line class="text-18px" />
<n-badge
:value="count"
:max="99"
:class="[count < 10 ? '-right-2px' : '-right-10px']"
class="absolute top-10px"
/>
</hover-container>
</template>
<n-tabs
v-model:value="currentTab"
:class="[isMobile ? 'w-276px' : 'w-360px']"
type="line"
justify-content="space-evenly"
>
<n-tab-pane v-for="(item, index) in tabData" :key="item.key" :name="index">
<template #tab>
<div class="flex-x-center items-center" :class="[isMobile ? 'w-92px' : 'w-120px']">
<span class="mr-5px">{{ item.name }}</span>
<n-badge
v-bind="item.badgeProps"
:value="item.list.filter(message => !message.isRead).length"
:max="99"
show-zero
/>
</div>
</template>
<loading-empty-wrapper
class="h-360px"
:loading="loading"
:empty="item.list.length === 0"
placeholder-class="bg-$n-color transition-background-color duration-300 ease-in-out"
>
<message-list :list="item.list" @read="handleRead" />
</loading-empty-wrapper>
</n-tab-pane>
</n-tabs>
<div v-if="showAction" class="flex border-t border-$n-divider-color cursor-pointer">
<div class="flex-1 text-center py-10px" @click="handleClear">清空</div>
<div class="flex-1 text-center py-10px border-l border-$n-divider-color" @click="handleAllRead">全部已读</div>
<div class="flex-1 text-center py-10px border-l border-$n-divider-color" @click="handleLoadMore">查看更多</div>
</div>
</n-popover>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { useThemeStore } from '@/store';
import { useBasicLayout } from '@/composables';
import { useBoolean } from '@/hooks';
import MessageList from './message-list.vue';
defineOptions({ name: 'SystemMessage' });
const theme = useThemeStore();
const { isMobile } = useBasicLayout();
const { bool: loading, setBool: setLoading } = useBoolean();
const currentTab = ref(0);
const tabData = ref<App.MessageTab[]>([
{
key: 1,
name: '通知',
badgeProps: { type: 'warning' },
list: [
{ id: 1, icon: 'ri:message-3-line', title: '你收到了5条新消息', date: '2022-06-17' },
{ id: 4, icon: 'ri:message-3-line', title: 'Soybean Admin 1.0.0 版本正在筹备中', date: '2022-06-17' },
{ id: 2, icon: 'ri:message-3-line', title: 'Soybean Admin 0.9.6 版本发布了', date: '2022-06-16' },
{ id: 3, icon: 'ri:message-3-line', title: 'Soybean Admin 0.9.5 版本发布了', date: '2022-06-07' },
{
id: 5,
icon: 'ri:message-3-line',
title: '测试超长标题测试超长标题测试超长标题测试超长标题测试超长标题测试超长标题测试超长标题测试超长标题',
date: '2022-06-17'
}
]
},
{
key: 2,
name: '消息',
badgeProps: { type: 'error' },
list: [
{
id: 1,
title: '项目动态',
svgIcon: 'avatar',
description: 'Soybean 刚才把工作台页面随便写了一些,凑合能看了!',
date: '2021-11-07 22:45:32'
},
{
id: 2,
title: '项目动态',
svgIcon: 'avatar',
description: 'Soybean 正在忙于为soybean-admin写项目说明文档',
date: '2021-11-03 20:33:31'
},
{
id: 3,
title: '项目动态',
svgIcon: 'avatar',
description: 'Soybean 准备为soybean-admin 1.0的发布做充分的准备工作!',
date: '2021-10-31 22:43:12'
},
{
id: 4,
title: '项目动态',
svgIcon: 'avatar',
description: '@yanbowe 向soybean-admin提交了一个bug多标签栏不会自适应。',
date: '2021-10-27 10:24:54'
},
{
id: 5,
title: '项目动态',
svgIcon: 'avatar',
description: 'Soybean 在2021年5月28日创建了开源项目soybean-admin',
date: '2021-05-28 22:22:22'
}
]
},
{
key: 3,
name: '待办',
badgeProps: { type: 'info' },
list: [
{
id: 1,
icon: 'ri:calendar-todo-line',
title: '缓存主题配置',
description: '任务正在计划中',
date: '2022-06-17',
tagTitle: '未开始',
tagProps: { type: 'default' }
},
{
id: 2,
icon: 'ri:calendar-todo-line',
title: '添加锁屏组件、全局Iframe组件',
description: '任务正在计划中',
date: '2022-06-17',
tagTitle: '未开始',
tagProps: { type: 'default' }
},
{
id: 3,
icon: 'ri:calendar-todo-line',
title: '示例页面完善',
description: '任务正在计划中',
date: '2022-06-17',
tagTitle: '未开始',
tagProps: { type: 'default' }
},
{
id: 4,
icon: 'ri:calendar-todo-line',
title: '表单、表格示例',
description: '任务正在计划中',
date: '2022-06-17',
tagTitle: '未开始',
tagProps: { type: 'default' }
},
{
id: 5,
icon: 'ri:calendar-todo-line',
title: '性能优化(优化递归函数)',
description: '任务正在计划中',
date: '2022-06-17',
tagTitle: '未开始',
tagProps: { type: 'default' }
},
{
id: 6,
icon: 'ri:calendar-todo-line',
title: '精简版(新分支thin)',
description: '任务正在计划中',
date: '2022-06-17',
tagTitle: '未开始',
tagProps: { type: 'default' }
}
]
}
]);
const count = computed(() => {
return tabData.value.reduce((acc, cur) => {
return acc + cur.list.filter(item => !item.isRead).length;
}, 0);
});
const showAction = computed(() => tabData.value[currentTab.value].list.length > 0);
function handleRead(index: number) {
tabData.value[currentTab.value].list[index].isRead = true;
}
function handleAllRead() {
tabData.value[currentTab.value].list.forEach(item => Object.assign(item, { isRead: true }));
}
function handleClear() {
tabData.value[currentTab.value].list = [];
}
function handleLoadMore() {
const { list } = tabData.value[currentTab.value];
setLoading(true);
setTimeout(() => {
list.push(...tabData.value[currentTab.value].list);
setLoading(false);
}, 1000);
}
</script>
<style scoped></style>

View File

@@ -0,0 +1,39 @@
<template>
<hover-container class="w-40px h-full" :inverted="theme.header.inverted">
<n-dropdown :options="options" trigger="hover" :value="language" @select="handleSelect">
<icon-cil:language class="text-18px outline-transparent" />
</n-dropdown>
</hover-container>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useThemeStore } from '@/store';
import { localStg } from '@/utils';
const theme = useThemeStore();
const { locale } = useI18n();
const language = ref<I18nType.langType>(localStg.get('lang') || 'zh-CN');
const options = [
{
label: '中文',
key: 'zh-CN'
},
{
label: 'English',
key: 'en'
},
{
label: 'ភាសាខ្មែរ',
key: 'km-KH'
}
];
const handleSelect = (key: string) => {
language.value = key as I18nType.langType;
locale.value = key;
localStg.set('lang', key as I18nType.langType);
};
</script>
<style scoped></style>

View File

@@ -7,11 +7,9 @@
</div>
<header-menu v-else />
<div class="flex justify-end h-full">
<global-search />
<github-site />
<full-screen />
<theme-mode />
<system-message />
<toggle-lang />
<setting-button v-if="showButton" />
<user-avatar />
</div>
@@ -22,17 +20,15 @@
import { useThemeStore } from '@/store';
import { useBasicLayout } from '@/composables';
import GlobalLogo from '../global-logo/index.vue';
import GlobalSearch from '../global-search/index.vue';
import {
FullScreen,
GithubSite,
GlobalBreadcrumb,
HeaderMenu,
MenuCollapse,
SettingButton,
SystemMessage,
ThemeMode,
UserAvatar
UserAvatar,
ToggleLang
} from './components';
defineOptions({ name: 'GlobalHeader' });

View File

@@ -1,11 +1,7 @@
<template>
<router-link :to="routeHomePath" class="flex-center w-full nowrap-hidden">
<system-logo class="text-32px text-primary" />
<h2
v-show="showTitle"
class="pl-8px text-16px font-bold text-primary transition duration-300 ease-in-out"
@click="toggleLocal"
>
<h2 v-show="showTitle" class="pl-8px text-16px font-bold text-primary transition duration-300 ease-in-out">
{{ t('message.system.title') }}
</h2>
</router-link>
@@ -13,7 +9,7 @@
<script setup lang="ts">
import { routePath } from '@/router';
import { t, setLocale } from '@/locales';
import { t } from '@/locales';
defineOptions({ name: 'GlobalLogo' });
@@ -25,12 +21,6 @@ interface Props {
defineProps<Props>();
const routeHomePath = routePath('root');
let flag = true;
function toggleLocal() {
flag = !flag;
setLocale(flag ? 'en' : 'zh-CN');
}
</script>
<style scoped></style>

View File

@@ -1,3 +0,0 @@
import SearchModal from './search-modal.vue';
export { SearchModal };

View File

@@ -1,27 +0,0 @@
<template>
<div class="px-24px h-44px flex-y-center">
<span class="mr-14px flex-y-center">
<icon-mdi-keyboard-return class="icon text-20px p-2px mr-6px" />
<span>确认</span>
</span>
<span class="mr-14px flex-y-center">
<icon-mdi-arrow-up-thin class="icon text-20px p-2px mr-5px" />
<icon-mdi-arrow-down-thin class="icon text-20px p-2px mr-6px" />
<span>切换</span>
</span>
<span class="flex-y-center">
<icon-mdi-keyboard-esc class="icon text-20px p-2px mr-6px" />
<span>关闭</span>
</span>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'SearchFooter' });
</script>
<style lang="scss" scoped>
.icon {
box-shadow: inset 0 -2px #cdcde6, inset 0 0 1px 1px #fff, 0 1px 2px 1px #1e235a66;
}
</style>

View File

@@ -1,147 +0,0 @@
<template>
<n-modal
v-model:show="show"
:segmented="{ footer: 'soft' }"
:closable="false"
preset="card"
footer-style="padding: 0; margin: 0"
class="fixed left-0 right-0"
:class="[isMobile ? 'wh-full top-0px rounded-0' : 'w-630px top-50px']"
@after-leave="handleClose"
>
<n-input-group>
<n-input ref="inputRef" v-model:value="keyword" clearable placeholder="请输入关键词搜索" @input="handleSearch">
<template #prefix>
<icon-uil-search class="text-15px text-[#c2c2c2]" />
</template>
</n-input>
<n-button v-if="isMobile" type="primary" ghost @click="handleClose">取消</n-button>
</n-input-group>
<div class="mt-20px">
<n-empty v-if="resultOptions.length === 0" description="暂无搜索结果" />
<search-result v-else v-model:value="activePath" :options="resultOptions" @enter="handleEnter" />
</div>
<template #footer>
<search-footer v-if="!isMobile" />
</template>
</n-modal>
</template>
<script lang="ts" setup>
import { computed, nextTick, ref, shallowRef, watch } from 'vue';
import { useRouter } from 'vue-router';
import { onKeyStroke, useDebounceFn } from '@vueuse/core';
import { useRouteStore } from '@/store';
import { useBasicLayout } from '@/composables';
import SearchResult from './search-result.vue';
import SearchFooter from './search-footer.vue';
defineOptions({ name: 'SearchModal' });
interface Props {
/** 弹窗显隐 */
value: boolean;
}
const props = defineProps<Props>();
interface Emits {
(e: 'update:value', val: boolean): void;
}
const emit = defineEmits<Emits>();
const { isMobile } = useBasicLayout();
const router = useRouter();
const routeStore = useRouteStore();
const keyword = ref('');
const activePath = ref('');
const resultOptions = shallowRef<AuthRoute.Route[]>([]);
const inputRef = ref<HTMLInputElement>();
const handleSearch = useDebounceFn(search, 300);
const show = computed({
get() {
return props.value;
},
set(val: boolean) {
emit('update:value', val);
}
});
watch(show, async val => {
if (val) {
/** 自动聚焦 */
await nextTick();
inputRef.value?.focus();
}
});
/** 查询 */
function search() {
resultOptions.value = routeStore.searchMenus.filter(
menu => keyword.value && menu.meta?.title.toLocaleLowerCase().includes(keyword.value.toLocaleLowerCase().trim())
);
if (resultOptions.value?.length > 0) {
activePath.value = resultOptions.value[0].path;
} else {
activePath.value = '';
}
}
function handleClose() {
show.value = false;
/** 延时处理防止用户看到某些操作 */
setTimeout(() => {
resultOptions.value = [];
keyword.value = '';
}, 200);
}
/** key up */
function handleUp() {
const { length } = resultOptions.value;
if (length === 0) return;
const index = resultOptions.value.findIndex(item => item.path === activePath.value);
if (index === 0) {
activePath.value = resultOptions.value[length - 1].path;
} else {
activePath.value = resultOptions.value[index - 1].path;
}
}
/** key down */
function handleDown() {
const { length } = resultOptions.value;
if (length === 0) return;
const index = resultOptions.value.findIndex(item => item.path === activePath.value);
if (index + 1 === length) {
activePath.value = resultOptions.value[0].path;
} else {
activePath.value = resultOptions.value[index + 1].path;
}
}
/** key enter */
function handleEnter() {
const { length } = resultOptions.value;
if (length === 0 || activePath.value === '') return;
const routeItem = resultOptions.value.find(item => item.path === activePath.value);
if (routeItem?.meta?.href) {
window.open(activePath.value, '__blank');
} else {
router.push(activePath.value);
handleClose();
}
}
onKeyStroke('Escape', handleClose);
onKeyStroke('Enter', handleEnter);
onKeyStroke('ArrowUp', handleUp);
onKeyStroke('ArrowDown', handleDown);
</script>
<style lang="scss" scoped></style>

View File

@@ -1,64 +0,0 @@
<template>
<n-scrollbar>
<div class="pb-12px">
<template v-for="item in options" :key="item.path">
<div
class="bg-[#e5e7eb] dark:bg-dark h-56px mt-8px px-14px rounded-4px cursor-pointer flex-y-center justify-between"
:style="{
background: item.path === active ? theme.themeColor : '',
color: item.path === active ? '#fff' : ''
}"
@click="handleTo"
@mouseenter="handleMouse(item)"
>
<svg-icon :icon="item.meta.icon" :local-icon="item.meta.localIcon" />
<span class="flex-1 ml-5px">{{ item.meta?.title }}</span>
<icon-ant-design-enter-outlined class="icon text-20px p-2px mr-3px" />
</div>
</template>
</div>
</n-scrollbar>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useThemeStore } from '@/store';
defineOptions({ name: 'SearchResult' });
interface Props {
value: string;
options: AuthRoute.Route[];
}
const props = defineProps<Props>();
interface Emits {
(e: 'update:value', val: string): void;
(e: 'enter'): void;
}
const emit = defineEmits<Emits>();
const theme = useThemeStore();
const active = computed({
get() {
return props.value;
},
set(val: string) {
emit('update:value', val);
}
});
/** 鼠标移入 */
async function handleMouse(item: AuthRoute.Route) {
active.value = item.path;
}
function handleTo() {
emit('enter');
}
</script>
<style lang="scss" scoped></style>

View File

@@ -1,30 +0,0 @@
<template>
<div>
<hover-container
class="w-40px h-full"
tooltip-content="搜索"
:inverted="theme.header.inverted"
@click="handleSearch"
>
<icon-uil-search class="text-20px" />
</hover-container>
<search-modal v-model:value="show" />
</div>
</template>
<script lang="ts" setup>
import { useThemeStore } from '@/store';
import { useBoolean } from '@/hooks';
import { SearchModal } from './components';
defineOptions({ name: 'GlobalSearch' });
const { bool: show, toggle } = useBoolean();
const theme = useThemeStore();
function handleSearch() {
toggle();
}
</script>
<style lang="scss" scoped></style>

View File

@@ -6,7 +6,7 @@
>
<component :is="icon" :class="[isMini ? 'text-16px' : 'text-20px']" />
<p
class="text-12px overflow-hidden transition-height duration-300 ease-in-out"
class="w-full text-center ellipsis-text text-12px transition-height duration-300 ease-in-out"
:class="[isMini ? 'h-0 pt-0' : 'h-24px pt-4px']"
>
{{ label }}
@@ -17,7 +17,7 @@
<script setup lang="ts">
import { computed } from 'vue';
import type { VNodeChild } from 'vue';
import type { Component } from 'vue';
import { useBoolean } from '@/hooks';
defineOptions({ name: 'MixMenuDetail' });
@@ -30,7 +30,7 @@ interface Props {
/** 当前激活状态的理由名称 */
activeRouteName: string;
/** 路由图标 */
icon?: () => VNodeChild;
icon?: Component;
/** mini尺寸的路由 */
isMini?: boolean;
}

View File

@@ -5,6 +5,7 @@
>
<dark-mode-container
class="drawer-shadow absolute-lt flex-col-stretch h-full nowrap-hidden"
:inverted="theme.sider.inverted"
:style="{ width: showDrawer ? theme.sider.mixChildMenuWidth + 'px' : '0px' }"
>
<header class="header-height flex-y-center justify-between" :style="{ height: theme.header.height + 'px' }">
@@ -20,6 +21,7 @@
:options="menus"
:expanded-keys="expandedKeys"
:indent="18"
:inverted="!theme.darkMode && theme.sider.inverted"
@update:value="handleUpdateMenu"
@update:expanded-keys="handleUpdateExpandedKeys"
/>

View File

@@ -1,6 +1,6 @@
<template>
<dark-mode-container class="flex h-full" :inverted="theme.sider.inverted" @mouseleave="resetFirstDegreeMenus">
<div class="flex-1 flex-col-stretch h-full">
<div class="flex-1-hidden flex-col-stretch h-full">
<global-logo :show-title="false" :style="{ height: theme.header.height + 'px' }" />
<n-scrollbar class="flex-1-hidden">
<mix-menu-detail
@@ -26,7 +26,9 @@ import { useRoute } from 'vue-router';
import { useAppStore, useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables';
import { useBoolean } from '@/hooks';
import { translateMenuLabel } from '@/utils';
import { GlobalLogo } from '@/layouts/common';
import { t } from '@/locales';
import { MixMenuCollapse, MixMenuDetail, MixMenuDrawer } from './components';
defineOptions({ name: 'VerticalMixSider' });
@@ -45,13 +47,13 @@ function setActiveParentRouteName(routeName: string) {
const firstDegreeMenus = computed(() =>
routeStore.menus.map(item => {
const { routeName, label } = item;
const { routeName, label, i18nTitle } = item;
const icon = item?.icon;
const hasChildren = Boolean(item.children && item.children.length);
return {
routeName,
label,
label: i18nTitle ? t(i18nTitle) : label,
icon,
hasChildren
};
@@ -88,7 +90,7 @@ const activeChildMenus = computed(() => {
routeStore.menus.some(item => {
const flag = item.routeName === activeParentRouteName.value && Boolean(item.children?.length);
if (flag) {
menus.push(...(item.children || []));
menus.push(...translateMenuLabel((item.children || []) as App.GlobalMenuOption[]));
}
return flag;
});

View File

@@ -8,7 +8,7 @@
:options="menus"
:expanded-keys="expandedKeys"
:indent="18"
:inverted="theme.sider.inverted"
:inverted="!theme.darkMode && theme.sider.inverted"
@update:value="handleUpdateMenu"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
@@ -21,7 +21,7 @@ import { useRoute } from 'vue-router';
import type { MenuOption } from 'naive-ui';
import { useAppStore, useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables';
import { getActiveKeyPathsOfMenus } from '@/utils';
import { getActiveKeyPathsOfMenus, translateMenuLabel } from '@/utils';
defineOptions({ name: 'VerticalMenu' });
@@ -31,7 +31,7 @@ const theme = useThemeStore();
const routeStore = useRouteStore();
const { routerPush } = useRouterPush();
const menus = computed(() => routeStore.menus as App.GlobalMenuOption[]);
const menus = computed(() => translateMenuLabel(routeStore.menus as App.GlobalMenuOption[]));
const activeKey = computed(() => (route.meta?.activeMenu ? route.meta.activeMenu : route.name) as string);
const expandedKeys = ref<string[]>([]);

View File

@@ -1,6 +1,6 @@
<template>
<div ref="tabRef" class="flex h-full pr-18px" :class="[isChromeMode ? 'items-end' : 'items-center gap-12px']">
<AdminTab
<PageTab
v-for="item in tab.tabs"
:key="item.fullPath"
:mode="theme.tab.mode"
@@ -19,8 +19,8 @@
class="inline-block align-text-bottom text-16px"
/>
</template>
{{ item.meta.title }}
</AdminTab>
{{ item.meta.i18nTitle ? t(item.meta.i18nTitle) : item.meta.title }}
</PageTab>
</div>
<context-menu
:visible="dropdown.visible"
@@ -34,8 +34,9 @@
<script setup lang="ts">
import { computed, nextTick, reactive, ref, watch } from 'vue';
import { AdminTab } from '@soybeanjs/vue-materials';
import { PageTab } from '@soybeanjs/vue-materials';
import { useTabStore, useThemeStore } from '@/store';
import { t } from '@/locales';
import { ContextMenu } from './components';
defineOptions({ name: 'TabDetail' });

View File

@@ -5,6 +5,5 @@ import GlobalSider from './global-sider/index.vue';
import GlobalContent from './global-content/index.vue';
import GlobalFooter from './global-footer/index.vue';
import GlobalLogo from './global-logo/index.vue';
import GlobalBackTop from './global-back-top/index.vue';
export { SettingDrawer, GlobalHeader, GlobalTab, GlobalSider, GlobalContent, GlobalFooter, GlobalLogo, GlobalBackTop };
export { SettingDrawer, GlobalHeader, GlobalTab, GlobalSider, GlobalContent, GlobalFooter, GlobalLogo };

View File

@@ -21,12 +21,15 @@
</template>
</n-switch>
</setting-menu>
<setting-menu label="侧边栏深色主题">
<setting-menu label="侧边栏深色">
<n-switch :value="theme.sider.inverted" @update:value="theme.setSiderInverted" />
</setting-menu>
<setting-menu label="头部深色主题">
<setting-menu label="头部深色">
<n-switch :value="theme.header.inverted" @update:value="theme.setHeaderInverted" />
</setting-menu>
<setting-menu label="底部深色">
<n-switch :value="theme.footer.inverted" @update:value="theme.setFooterInverted" />
</setting-menu>
</n-space>
</template>

View File

@@ -6,8 +6,8 @@
<n-tooltip :placement="activeConfig.placement" trigger="hover">
<template #trigger>
<div class="layout-checkbox__shadow relative w-56px h-48px bg-white rounded-4px overflow-hidden">
<div class="absolute-lt bg-[#273352]" :class="activeConfig.menuClass"></div>
<div class="absolute-rb bg-[#f0f2f5]" :class="activeConfig.mainClass"></div>
<div class="absolute-lt bg-#273352" :class="activeConfig.menuClass"></div>
<div class="absolute-rb bg-#f0f2f5" :class="activeConfig.mainClass"></div>
</div>
</template>
<span>{{ label }}</span>

View File

@@ -61,11 +61,14 @@
@update:value="theme.setMixSiderWidth"
/>
</setting-menu>
<setting-menu label="显示底部">
<n-switch :value="theme.footer.visible" @update:value="theme.setFooterVisible" />
</setting-menu>
<setting-menu label="固定底部">
<n-switch :value="theme.footer.fixed" @update:value="theme.setFooterIsFixed" />
</setting-menu>
<setting-menu label="显示底部">
<n-switch :value="theme.footer.visible" @update:value="theme.setFooterVisible" />
<setting-menu label="底部居右">
<n-switch :value="theme.footer.right" @update:value="theme.setFooterIsRight" />
</setting-menu>
</n-space>
</template>

View File

@@ -1,12 +1,14 @@
import type { App } from 'vue';
import { createI18n } from 'vue-i18n';
import { localStg } from '@/utils';
import messages from './lang';
import type { LocaleKey } from './lang';
const i18n = createI18n({
locale: 'zh-CN',
locale: localStg.get('lang') || 'zh-CN',
fallbackLocale: 'en',
messages
messages,
legacy: false
});
export function setupI18n(app: App) {
@@ -18,5 +20,5 @@ export function t(key: string) {
}
export function setLocale(locale: LocaleKey) {
i18n.global.locale = locale;
i18n.global.locale.value = locale;
}

View File

@@ -7,13 +7,77 @@ const locale: LocaleMessages<I18nType.Schema> = {
},
routes: {
dashboard: {
dashboard: 'Dashboard',
_value: 'Dashboard',
analysis: 'Analysis',
workbench: 'Workbench'
},
about: {
about: 'About'
}
document: {
_value: 'Document',
vue: 'Vue Document',
vite: 'Vite Document',
naive: 'NaiveUI Document',
project: 'Project Document',
'project-link': 'Project Document(href)'
},
component: {
_value: 'Component',
button: 'Button',
card: 'Card',
table: 'Table'
},
plugin: {
_value: 'Plugin',
charts: {
_value: 'Chart',
echarts: 'ECharts',
antv: 'AntV'
},
copy: 'Copy',
editor: {
_value: 'Editor',
quill: 'Quill',
markdown: 'Markdown'
},
icon: 'Icon',
map: 'Map',
print: 'Print',
swiper: 'Swiper',
video: 'Video'
},
'auth-demo': {
_value: 'Auth Demo',
permission: 'Toggle Permission',
super: 'Super Auth'
},
function: {
_value: 'Function',
tab: 'System Tab'
},
exception: {
_value: 'Exception',
403: '403',
404: '404',
500: '500'
},
'multi-menu': {
_value: 'Multi Degree Menu',
first: {
_value: 'First Degree',
second: 'Second Degree',
'second-new': {
_value: 'Second Degree With Children',
third: 'Third Degree'
}
}
},
management: {
_value: 'System Management',
auth: 'Auth',
role: 'Role',
route: 'Route',
user: 'User'
},
about: 'About'
}
}
};

View File

@@ -1,9 +1,11 @@
import zhCN from './zh-cn';
import en from './en';
import kmKH from './km-KH';
const locales = {
'zh-CN': zhCN,
en
en,
'km-KH': kmKH
};
export type LocaleKey = keyof typeof locales;

85
src/locales/lang/km-KH.ts Normal file
View File

@@ -0,0 +1,85 @@
import type { LocaleMessages } from 'vue-i18n';
const locale: LocaleMessages<I18nType.Schema> = {
message: {
system: {
title: 'ប្រព័ន្ធគ្រប់គ្រង'
},
routes: {
dashboard: {
_value: 'ផ្ទាំងទិន្នន័យ',
analysis: 'ផ្ទាំងវិភាគ',
workbench: 'ផ្ទាំងការងារ'
},
document: {
_value: 'ឯកសារ',
vue: 'ឯកសារ​ Vue',
vite: 'ឯកសារ​ Vite',
naive: 'ឯកសារ NaiveUI',
project: 'ឯកសារគម្រោង',
'project-link': 'ឯកសារគម្រោង(href)'
},
component: {
_value: 'សមាស​ភាគ',
button: 'ប៊ូតុង',
card: 'កាត',
table: 'តារាង'
},
plugin: {
_value: 'មុខងារជំនួយ',
charts: {
_value: 'តារាង​ Chart',
echarts: 'តារាង ECharts',
antv: 'AntV'
},
copy: 'ចម្លង',
editor: {
_value: 'កែប្រែ',
quill: 'Quill',
markdown: 'Markdown'
},
icon: 'អាយខន',
map: 'ផែនទី',
print: 'បោះពុម្ភ',
swiper: 'Swiper',
video: 'វីដេអូ'
},
'auth-demo': {
_value: 'ឌីមូ Auth',
permission: 'បិទ/បើកការអនុញ្ញាត',
super: 'Super Auth'
},
function: {
_value: 'មុខងារ',
tab: 'ថេបប្រព័ន្ធ'
},
exception: {
_value: 'ករណីពិេសស',
403: '403',
404: '404',
500: '500'
},
'multi-menu': {
_value: 'ម៉ឺនុយពហុដឺក្រេ',
first: {
_value: 'ដឺក្រេទី១',
second: 'ដែក្រេទី២',
'second-new': {
_value: 'ដឺក្រេទី២មានអនុក្រោម',
third: 'ដឺក្រេទី៣'
}
}
},
management: {
_value: 'ការគ្រប់គ្រងប្រព័ន្ធ',
auth: 'Auth',
role: 'សិទ្ធី',
route: 'ផ្លូវប្រព័ន្ធ',
user: 'អ្នកប្រើប្រាស់'
},
about: 'អំពីប្រព័ន្ធ'
}
}
};
export default locale;

View File

@@ -7,13 +7,77 @@ const locale: LocaleMessages<I18nType.Schema> = {
},
routes: {
dashboard: {
dashboard: '仪表盘',
_value: '仪表盘',
analysis: '分析页',
workbench: '工作台'
},
about: {
about: '关于'
}
document: {
_value: '文档',
vue: 'Vue文档',
vite: 'Vite文档',
naive: 'NaiveUI文档',
project: '项目文档',
'project-link': '项目文档(外链)'
},
component: {
_value: '组件示例',
button: '按钮',
card: '卡片',
table: '表格'
},
plugin: {
_value: '插件示例',
charts: {
_value: '图表',
echarts: 'ECharts',
antv: 'AntV'
},
copy: '剪贴板',
editor: {
_value: '编辑器',
quill: '富文本',
markdown: 'Markdown'
},
icon: '图标',
map: '地图',
print: '打印',
swiper: 'Swiper',
video: '视频'
},
'auth-demo': {
_value: '权限示例',
permission: '切换权限',
super: '超级管理员可见'
},
function: {
_value: '功能',
tab: 'Tab页签'
},
exception: {
_value: '异常页',
403: '403',
404: '404',
500: '500'
},
'multi-menu': {
_value: '多级菜单',
first: {
_value: '一级菜单',
second: '二级菜单',
'second-new': {
_value: '二级菜单(有子菜单)',
third: '三级菜单'
}
}
},
management: {
_value: '系统管理',
auth: '权限管理',
role: '角色管理',
route: '路由管理',
user: '用户管理'
},
about: '关于'
}
}
};

View File

@@ -29,6 +29,8 @@ async function setupApp() {
setupI18n(app);
appLoading.unmount();
// mount app
app.mount('#app');
}

View File

@@ -1,8 +1,5 @@
import 'uno.css';
import '@soybeanjs/vue-materials/dist/style.css';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'virtual:svg-icons-register';
import '../styles/css/global.css';

View File

@@ -1,5 +1,6 @@
import type { Router } from 'vue-router';
import { useTitle } from '@vueuse/core';
import { t } from '@/locales';
import { createPermissionGuard } from './permission';
/**
@@ -15,7 +16,7 @@ export function createRouterGuard(router: Router) {
});
router.afterEach(to => {
// 设置document title
useTitle(to.meta.title);
useTitle(to.meta.i18nTitle ? t(to.meta.i18nTitle) : to.meta.title);
// 结束 loadingBar
window.$loadingBar?.finish();
});

View File

@@ -1,16 +0,0 @@
const about1: AuthRoute.Route = {
name: 'about',
path: '/about',
component: 'self',
meta: {
title: '关于',
requiresAuth: true,
keepAlive: true,
singleLayout: 'basic',
permissions: ['super', 'admin', 'user'],
icon: 'fluent:book-information-24-regular',
order: 10
}
};
export default about1;

View File

@@ -1,35 +0,0 @@
const authDemo: AuthRoute.Route = {
name: 'auth-demo',
path: '/auth-demo',
component: 'basic',
children: [
{
name: 'auth-demo_permission',
path: '/auth-demo/permission',
component: 'self',
meta: {
title: '权限切换',
requiresAuth: true,
icon: 'ic:round-construction'
}
},
{
name: 'auth-demo_super',
path: '/auth-demo/super',
component: 'self',
meta: {
title: '超级管理员可见',
requiresAuth: true,
permissions: ['super'],
icon: 'ic:round-supervisor-account'
}
}
],
meta: {
title: '权限示例',
icon: 'ic:baseline-security',
order: 5
}
};
export default authDemo;

View File

@@ -1,44 +0,0 @@
const component: AuthRoute.Route = {
name: 'component',
path: '/component',
component: 'basic',
children: [
{
name: 'component_button',
path: '/component/button',
component: 'self',
meta: {
title: '按钮',
requiresAuth: true,
icon: 'mdi:button-cursor'
}
},
{
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: 'cib:app-store',
order: 3
}
};
export default component;

View File

@@ -1,34 +0,0 @@
const dashboard: 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,
icon: 'icon-park-outline:workbench'
}
}
],
meta: {
title: '仪表盘',
icon: 'mdi:monitor-dashboard',
order: 1
}
};
export default dashboard;

View File

@@ -1,64 +0,0 @@
const document: AuthRoute.Route = {
name: 'document',
path: '/document',
component: 'basic',
children: [
{
name: 'document_vue',
path: '/document/vue',
component: 'self',
meta: {
title: 'vue文档',
requiresAuth: true,
icon: 'logos:vue'
}
},
{
name: 'document_vite',
path: '/document/vite',
component: 'self',
meta: {
title: 'vite文档',
requiresAuth: true,
icon: 'logos:vitejs'
}
},
{
name: 'document_naive',
path: '/document/naive',
component: 'self',
meta: {
title: 'naive文档',
requiresAuth: true,
icon: 'logos:naiveui'
}
},
{
name: 'document_project',
path: '/document/project',
component: 'self',
meta: {
title: '项目文档',
requiresAuth: true,
localIcon: 'logo'
}
},
{
name: 'document_project-link',
path: '/document/project-link',
meta: {
title: '项目文档(外链)',
requiresAuth: true,
localIcon: 'logo',
href: 'https://docs.soybean.pro/'
}
}
],
meta: {
title: '文档',
icon: 'mdi:file-document-multiple-outline',
order: 2
}
};
export default document;

View File

@@ -1,44 +0,0 @@
const exception: AuthRoute.Route = {
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: 7
}
};
export default exception;

View File

@@ -1,49 +0,0 @@
const functionRoute: AuthRoute.Route = {
name: 'function',
path: '/function',
component: 'basic',
children: [
{
name: 'function_tab',
path: '/function/tab',
component: 'self',
meta: {
title: 'Tab',
requiresAuth: true,
icon: 'ic:round-tab'
}
},
{
name: 'function_tab-detail',
path: '/function/tab-detail',
component: 'self',
meta: {
title: 'Tab Detail',
requiresAuth: true,
hide: true,
activeMenu: 'function_tab',
icon: 'ic:round-tab'
}
},
{
name: 'function_tab-multi-detail',
path: '/function/tab-multi-detail',
component: 'self',
meta: {
title: 'Tab Multi Detail',
requiresAuth: true,
hide: true,
multiTab: true,
activeMenu: 'function_tab',
icon: 'ic:round-tab'
}
}
],
meta: {
title: '功能',
icon: 'icon-park-outline:all-application',
order: 6
}
};
export default functionRoute;

View File

@@ -1,54 +0,0 @@
const management: AuthRoute.Route = {
name: 'management',
path: '/management',
component: 'basic',
children: [
{
name: 'management_auth',
path: '/management/auth',
component: 'self',
meta: {
title: '权限管理',
requiresAuth: true,
icon: 'ic:baseline-security'
}
},
{
name: 'management_role',
path: '/management/role',
component: 'self',
meta: {
title: '角色管理',
requiresAuth: true,
icon: 'carbon:user-role'
}
},
{
name: 'management_user',
path: '/management/user',
component: 'self',
meta: {
title: '用户管理',
requiresAuth: true,
icon: 'ic:round-manage-accounts'
}
},
{
name: 'management_route',
path: '/management/route',
component: 'self',
meta: {
title: '路由管理',
requiresAuth: true,
icon: 'material-symbols:route'
}
}
],
meta: {
title: '系统管理',
icon: 'carbon:cloud-service-management',
order: 9
}
};
export default management;

View File

@@ -14,6 +14,7 @@ const multiMenu: AuthRoute.Route = {
component: 'self',
meta: {
title: '二级菜单',
i18nTitle: 'message.routes.multi-menu.first.second',
requiresAuth: true,
icon: 'mdi:menu'
}
@@ -29,6 +30,7 @@ const multiMenu: AuthRoute.Route = {
component: 'self',
meta: {
title: '三级菜单',
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
requiresAuth: true,
icon: 'mdi:menu'
}
@@ -36,18 +38,21 @@ const multiMenu: AuthRoute.Route = {
],
meta: {
title: '二级菜单(有子菜单)',
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
icon: 'mdi:menu'
}
}
],
meta: {
title: '一级菜单',
i18nTitle: 'message.routes.multi-menu.first._value',
icon: 'mdi:menu'
}
}
],
meta: {
title: '多级菜单',
i18nTitle: 'message.routes.multi-menu._value',
icon: 'carbon:menu',
order: 8
}

View File

@@ -1,136 +0,0 @@
const plugin: AuthRoute.Route = {
name: 'plugin',
path: '/plugin',
component: 'basic',
children: [
{
name: 'plugin_charts',
path: '/plugin/charts',
component: 'multi',
children: [
{
name: 'plugin_charts_echarts',
path: '/plugin/charts/echarts',
component: 'self',
meta: {
title: 'ECharts',
requiresAuth: true,
icon: 'simple-icons:apacheecharts'
}
},
{
name: 'plugin_charts_antv',
path: '/plugin/charts/antv',
component: 'self',
meta: {
title: 'AntV',
requiresAuth: true,
icon: 'simple-icons:antdesign'
}
}
],
meta: {
title: '图表',
icon: 'mdi:chart-areaspline'
}
},
{
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,
localIcon: 'custom-icon'
}
},
{
name: 'plugin_print',
path: '/plugin/print',
component: 'self',
meta: {
title: '打印',
requiresAuth: true,
icon: 'mdi:printer'
}
}
],
meta: {
title: '插件示例',
icon: 'clarity:plugin-line',
order: 4
}
};
export default plugin;

View File

@@ -1,2 +1 @@
export * from './auth';
export * from './management';

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