Compare commits

...

90 Commits

Author SHA1 Message Date
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
99 changed files with 7554 additions and 5504 deletions

View File

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

View File

@@ -6,3 +6,5 @@ VITE_COMPRESS=N
VITE_COMPRESS_TYPE=gzip VITE_COMPRESS_TYPE=gzip
VITE_PWA=N VITE_PWA=N
VITE_PROD_MOCK=Y

View File

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

2
.npmrc
View File

@@ -1,4 +1,2 @@
registry=https://registry.npmmirror.com/ registry=https://registry.npmmirror.com/
shamefully-hoist=true 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", "name": "Vue debugger",
"url": "http://localhost:3200", "url": "http://localhost:3200",
"webRoot": "${workspaceFolder}" "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",
"~@": "${workspaceFolder}/src" "~@": "${workspaceFolder}/src"
}, },
"terminal.integrated.cursorStyle": "line",
"terminal.integrated.fontSize": 14, "terminal.integrated.fontSize": 14,
"terminal.integrated.fontWeight": 500, "terminal.integrated.fontWeight": 500,
"terminal.integrated.tabs.enabled": true, "terminal.integrated.tabs.enabled": true,
@@ -71,5 +70,6 @@
}, },
"[vue]": { "[vue]": {
"editor.defaultFormatter": "Vue.volar" "editor.defaultFormatter": "Vue.volar"
} },
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"]
} }

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,19 @@
- **权限路由**:提供前端静态和后端动态两种路由模式,基于 mock 的动态路由能快速实现后端动态路由 - **权限路由**:提供前端静态和后端动态两种路由模式,基于 mock 的动态路由能快速实现后端动态路由
- **请求函数**:基于 axios 的完善的请求函数封装,提供 Promise 和 hooks 两种请求函数,加入请求结果数据转换的适配器 - **请求函数**:基于 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/) - [Soybean Admin 预览地址](https://soybean.pro/)
@@ -29,12 +42,12 @@
## 代码仓库 ## 代码仓库
- [github](https://github.com/honghuangdc/soybean-admin) | 仓库 | github 地址 | gitee 镜像 | 预览 |
- [tauri 版](https://github.com/honghuangdc/soybean-admin/tree/tauri) | -------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
- [精简版](https://github.com/honghuangdc/soybean-admin/tree/thin) | soybean-admin | [github](https://github.com/honghuangdc/soybean-admin) | [gitee](https://gitee.com/honghuangdc/soybean-admin) | [预览](https://soybean.pro/) |
- [gitee](https://gitee.com/honghuangdc/soybean-admin) | tauri 版 | [tauri 版](https://github.com/honghuangdc/soybean-admin/tree/tauri) | [tauri 版](https://gitee.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) | |
- [精简版](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/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/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/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) ![](https://s2.loli.net/2022/06/07/rY8TyAftM5dxspv.png)
@@ -68,6 +83,12 @@
![](https://s2.loli.net/2022/06/07/rRSG6mEZpujOACT.png) ![](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 进行初始化配置 项目已用 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+` 浏览器 本地开发推荐使用`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="display:flex;">
<div style="padding-right:24px;"> <div style="padding-right:24px;">
<p>微信交流群</p> <p>QQ交流群</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybeanjs-wechat2.jpeg" style="width:200px" /> <img src="https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg" style="width:200px" />
</div> </div>
<div> <div>
<p>添加本人微信,欢迎来技术交流,业务咨询</p> <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>
</div> </div>
@@ -159,4 +177,4 @@ docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
## License ## License
[MIT © Soybean-2021](./LICENSE) 本项目基于[MIT © Soybean-2021](./LICENSE) 协议,仅供参考学习,商用时请保留作者的版权信息,作者不对软件做担保和负责。

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

@@ -3,8 +3,8 @@ import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx'; import vueJsx from '@vitejs/plugin-vue-jsx';
import unocss from '@unocss/vite'; import unocss from '@unocss/vite';
import progress from 'vite-plugin-progress'; import progress from 'vite-plugin-progress';
import VueDevtools from 'vite-plugin-vue-devtools';
import pageRoute from '@soybeanjs/vite-plugin-vue-page-route'; import pageRoute from '@soybeanjs/vite-plugin-vue-page-route';
import html from './html';
import unplugin from './unplugin'; import unplugin from './unplugin';
import mock from './mock'; import mock from './mock';
import visualizer from './visualizer'; import visualizer from './visualizer';
@@ -16,7 +16,19 @@ import pwa from './pwa';
* @param viteEnv - 环境变量配置 * @param viteEnv - 环境变量配置
*/ */
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] { 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),
progress()
];
if (viteEnv.VITE_VISUALIZER === 'Y') { if (viteEnv.VITE_VISUALIZER === 'Y') {
plugins.push(visualizer as PluginOption); plugins.push(visualizer as PluginOption);
@@ -27,6 +39,9 @@ export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | Plugin
if (viteEnv.VITE_PWA === 'Y' || viteEnv.VITE_VERCEL === 'Y') { if (viteEnv.VITE_PWA === 'Y' || viteEnv.VITE_VERCEL === 'Y') {
plugins.push(pwa()); plugins.push(pwa());
} }
if (viteEnv.VITE_SOYBEAN_ROUTE_PLUGIN === 'Y') {
plugins.push(pageRoute());
}
return plugins; return plugins;
} }

View File

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

View File

@@ -1,4 +1,3 @@
import VueMacros from 'unplugin-vue-macros/vite';
import Icons from 'unplugin-icons/vite'; import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver'; import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite'; 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}-`, ''); const collectionName = VITE_ICON_LOCAL_PREFFIX.replace(`${VITE_ICON_PREFFIX}-`, '');
return [ return [
VueMacros({}),
Icons({ Icons({
compiler: 'vue3', compiler: 'vue3',
customCollections: { customCollections: {

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

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

View File

@@ -12,7 +12,8 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
meta: { meta: {
title: '分析页', title: '分析页',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:analysis' icon: 'icon-park-outline:analysis',
i18nTitle: 'message.routes.dashboard.analysis'
} }
}, },
{ {
@@ -22,14 +23,16 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
meta: { meta: {
title: '工作台', title: '工作台',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:workbench' icon: 'icon-park-outline:workbench',
i18nTitle: 'message.routes.dashboard.workbench'
} }
} }
], ],
meta: { meta: {
title: '仪表盘', title: '仪表盘',
icon: 'mdi:monitor-dashboard', icon: 'mdi:monitor-dashboard',
order: 1 order: 1,
i18nTitle: 'message.routes.dashboard._value'
} }
}, },
{ {
@@ -43,6 +46,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'vue文档', title: 'vue文档',
i18nTitle: 'message.routes.document.vue',
requiresAuth: true, requiresAuth: true,
icon: 'logos:vue' icon: 'logos:vue'
} }
@@ -53,6 +57,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'vite文档', title: 'vite文档',
i18nTitle: 'message.routes.document.vite',
requiresAuth: true, requiresAuth: true,
icon: 'logos:vitejs' icon: 'logos:vitejs'
} }
@@ -63,6 +68,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'naive文档', title: 'naive文档',
i18nTitle: 'message.routes.document.naive',
requiresAuth: true, requiresAuth: true,
icon: 'logos:naiveui' icon: 'logos:naiveui'
} }
@@ -73,6 +79,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '项目文档', title: '项目文档',
i18nTitle: 'message.routes.document.project',
requiresAuth: true, requiresAuth: true,
localIcon: 'logo' localIcon: 'logo'
} }
@@ -82,6 +89,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
path: '/document/project-link', path: '/document/project-link',
meta: { meta: {
title: '项目文档(外链)', title: '项目文档(外链)',
i18nTitle: 'message.routes.document.project-link',
requiresAuth: true, requiresAuth: true,
localIcon: 'logo', localIcon: 'logo',
href: 'https://docs.soybean.pro/' href: 'https://docs.soybean.pro/'
@@ -90,6 +98,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '文档', title: '文档',
i18nTitle: 'message.routes.document._value',
icon: 'mdi:file-document-multiple-outline', icon: 'mdi:file-document-multiple-outline',
order: 2 order: 2
} }
@@ -105,6 +114,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '按钮', title: '按钮',
i18nTitle: 'message.routes.component.button',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:button-cursor' icon: 'mdi:button-cursor'
} }
@@ -115,6 +125,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '卡片', title: '卡片',
i18nTitle: 'message.routes.component.card',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:card-outline' icon: 'mdi:card-outline'
} }
@@ -125,6 +136,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '表格', title: '表格',
i18nTitle: 'message.routes.component.table',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:table-large' icon: 'mdi:table-large'
} }
@@ -132,6 +144,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '组件示例', title: '组件示例',
i18nTitle: 'message.routes.component._value',
icon: 'cib:app-store', icon: 'cib:app-store',
order: 3 order: 3
} }
@@ -152,6 +165,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'ECharts', title: 'ECharts',
i18nTitle: 'message.routes.plugin.charts.echarts',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:apacheecharts' icon: 'simple-icons:apacheecharts'
} }
@@ -162,6 +176,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'AntV', title: 'AntV',
i18nTitle: 'message.routes.plugin.charts.antv',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:antdesign' icon: 'simple-icons:antdesign'
} }
@@ -169,6 +184,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '图表', title: '图表',
i18nTitle: 'message.routes.plugin.charts._value',
icon: 'mdi:chart-areaspline' icon: 'mdi:chart-areaspline'
} }
}, },
@@ -178,6 +194,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '地图', title: '地图',
i18nTitle: 'message.routes.plugin.map',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:map' icon: 'mdi:map'
} }
@@ -188,6 +205,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '视频', title: '视频',
i18nTitle: 'message.routes.plugin.video',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:video' icon: 'mdi:video'
} }
@@ -203,6 +221,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '富文本编辑器', title: '富文本编辑器',
i18nTitle: 'message.routes.plugin.editor.quill',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:file-document-edit-outline' icon: 'mdi:file-document-edit-outline'
} }
@@ -213,6 +232,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'markdown编辑器', title: 'markdown编辑器',
i18nTitle: 'message.routes.plugin.editor.markdown',
requiresAuth: true, requiresAuth: true,
icon: 'ri:markdown-line' icon: 'ri:markdown-line'
} }
@@ -220,6 +240,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '编辑器', title: '编辑器',
i18nTitle: 'message.routes.plugin.editor._value',
icon: 'icon-park-outline:editor' icon: 'icon-park-outline:editor'
} }
}, },
@@ -229,6 +250,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'Swiper插件', title: 'Swiper插件',
i18nTitle: 'message.routes.plugin.swiper',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:swiper' icon: 'simple-icons:swiper'
} }
@@ -239,6 +261,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '剪贴板', title: '剪贴板',
i18nTitle: 'message.routes.plugin.copy',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:clipboard-outline' icon: 'mdi:clipboard-outline'
} }
@@ -249,6 +272,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '图标', title: '图标',
i18nTitle: 'message.routes.plugin.icon',
requiresAuth: true, requiresAuth: true,
localIcon: 'custom-icon' localIcon: 'custom-icon'
} }
@@ -259,6 +283,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '打印', title: '打印',
i18nTitle: 'message.routes.plugin.print',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:printer' icon: 'mdi:printer'
} }
@@ -266,6 +291,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '插件示例', title: '插件示例',
i18nTitle: 'message.routes.plugin._value',
icon: 'clarity:plugin-line', icon: 'clarity:plugin-line',
order: 4 order: 4
} }
@@ -281,6 +307,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限切换', title: '权限切换',
i18nTitle: 'message.routes.auth-demo.permission',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-construction' icon: 'ic:round-construction'
} }
@@ -291,6 +318,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '超级管理员可见', title: '超级管理员可见',
i18nTitle: 'message.routes.auth-demo.super',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-supervisor-account' icon: 'ic:round-supervisor-account'
} }
@@ -298,6 +326,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '权限示例', title: '权限示例',
i18nTitle: 'message.routes.auth-demo._value',
icon: 'ic:baseline-security', icon: 'ic:baseline-security',
order: 5 order: 5
} }
@@ -313,6 +342,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'Tab', title: 'Tab',
i18nTitle: 'message.routes.function.tab',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-tab' icon: 'ic:round-tab'
} }
@@ -345,6 +375,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '功能', title: '功能',
i18nTitle: 'message.routes.function._value',
icon: 'icon-park-outline:all-application', icon: 'icon-park-outline:all-application',
order: 6 order: 6
} }
@@ -360,6 +391,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页403', title: '异常页403',
i18nTitle: 'message.routes.exception.403',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-block' icon: 'ic:baseline-block'
} }
@@ -370,6 +402,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页404', title: '异常页404',
i18nTitle: 'message.routes.exception.404',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-web-asset-off' icon: 'ic:baseline-web-asset-off'
} }
@@ -380,12 +413,14 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页500', title: '异常页500',
i18nTitle: 'message.routes.exception.500',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-wifi-off' icon: 'ic:baseline-wifi-off'
} }
} }
], ],
meta: { meta: {
i18nTitle: 'message.routes.exception._value',
title: '异常页', title: '异常页',
icon: 'ant-design:exception-outlined', icon: 'ant-design:exception-outlined',
order: 7 order: 7
@@ -407,6 +442,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '二级菜单', title: '二级菜单',
i18nTitle: 'message.routes.multi-menu.first.second',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:menu' icon: 'mdi:menu'
} }
@@ -422,6 +458,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '三级菜单', title: '三级菜单',
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:menu' icon: 'mdi:menu'
} }
@@ -429,18 +466,21 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '二级菜单(有子菜单)', title: '二级菜单(有子菜单)',
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
icon: 'mdi:menu' icon: 'mdi:menu'
} }
} }
], ],
meta: { meta: {
title: '一级菜单', title: '一级菜单',
i18nTitle: 'message.routes.multi-menu.first._value',
icon: 'mdi:menu' icon: 'mdi:menu'
} }
} }
], ],
meta: { meta: {
title: '多级菜单', title: '多级菜单',
i18nTitle: 'message.routes.multi-menu._value',
icon: 'carbon:menu', icon: 'carbon:menu',
order: 8 order: 8
} }
@@ -456,6 +496,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限管理', title: '权限管理',
i18nTitle: 'message.routes.management.auth',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-security' icon: 'ic:baseline-security'
} }
@@ -466,6 +507,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '角色管理', title: '角色管理',
i18nTitle: 'message.routes.management.role',
requiresAuth: true, requiresAuth: true,
icon: 'carbon:user-role' icon: 'carbon:user-role'
} }
@@ -476,6 +518,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '用户管理', title: '用户管理',
i18nTitle: 'message.routes.management.user',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-manage-accounts' icon: 'ic:round-manage-accounts'
} }
@@ -486,6 +529,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '路由管理', title: '路由管理',
i18nTitle: 'message.routes.management.route',
requiresAuth: true, requiresAuth: true,
icon: 'material-symbols:route' icon: 'material-symbols:route'
} }
@@ -493,6 +537,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '系统管理', title: '系统管理',
i18nTitle: 'message.routes.management._value',
icon: 'carbon:cloud-service-management', icon: 'carbon:cloud-service-management',
order: 9 order: 9
} }
@@ -503,7 +548,9 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '关于', title: '关于',
i18nTitle: 'message.routes.about',
requiresAuth: true, requiresAuth: true,
keepAlive: true,
singleLayout: 'basic', singleLayout: 'basic',
icon: 'fluent:book-information-24-regular', icon: 'fluent:book-information-24-regular',
order: 10 order: 10
@@ -523,7 +570,8 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
meta: { meta: {
title: '分析页', title: '分析页',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:analysis' icon: 'icon-park-outline:analysis',
i18nTitle: 'message.routes.dashboard.analysis'
} }
}, },
{ {
@@ -533,14 +581,16 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
meta: { meta: {
title: '工作台', title: '工作台',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:workbench' icon: 'icon-park-outline:workbench',
i18nTitle: 'message.routes.dashboard.workbench'
} }
} }
], ],
meta: { meta: {
title: '仪表盘', title: '仪表盘',
icon: 'mdi:monitor-dashboard', icon: 'mdi:monitor-dashboard',
order: 1 order: 1,
i18nTitle: 'message.routes.dashboard._value'
} }
}, },
{ {
@@ -554,6 +604,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'vue文档', title: 'vue文档',
i18nTitle: 'message.routes.document.vue',
requiresAuth: true, requiresAuth: true,
icon: 'logos:vue' icon: 'logos:vue'
} }
@@ -564,6 +615,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'vite文档', title: 'vite文档',
i18nTitle: 'message.routes.document.vite',
requiresAuth: true, requiresAuth: true,
icon: 'logos:vitejs' icon: 'logos:vitejs'
} }
@@ -574,6 +626,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'naive文档', title: 'naive文档',
i18nTitle: 'message.routes.document.naive',
requiresAuth: true, requiresAuth: true,
icon: 'logos:naiveui' icon: 'logos:naiveui'
} }
@@ -584,6 +637,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '项目文档', title: '项目文档',
i18nTitle: 'message.routes.document.project',
requiresAuth: true, requiresAuth: true,
localIcon: 'logo' localIcon: 'logo'
} }
@@ -593,6 +647,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
path: '/document/project-link', path: '/document/project-link',
meta: { meta: {
title: '项目文档(外链)', title: '项目文档(外链)',
i18nTitle: 'message.routes.document.project-link',
requiresAuth: true, requiresAuth: true,
localIcon: 'logo', localIcon: 'logo',
href: 'https://docs.soybean.pro/' href: 'https://docs.soybean.pro/'
@@ -601,6 +656,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '文档', title: '文档',
i18nTitle: 'message.routes.document._value',
icon: 'mdi:file-document-multiple-outline', icon: 'mdi:file-document-multiple-outline',
order: 2 order: 2
} }
@@ -616,6 +672,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '按钮', title: '按钮',
i18nTitle: 'message.routes.component.button',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:button-cursor' icon: 'mdi:button-cursor'
} }
@@ -626,6 +683,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '卡片', title: '卡片',
i18nTitle: 'message.routes.component.card',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:card-outline' icon: 'mdi:card-outline'
} }
@@ -636,6 +694,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '表格', title: '表格',
i18nTitle: 'message.routes.component.table',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:table-large' icon: 'mdi:table-large'
} }
@@ -643,6 +702,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '组件示例', title: '组件示例',
i18nTitle: 'message.routes.component._value',
icon: 'cib:app-store', icon: 'cib:app-store',
order: 3 order: 3
} }
@@ -663,6 +723,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'ECharts', title: 'ECharts',
i18nTitle: 'message.routes.plugin.charts.echarts',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:apacheecharts' icon: 'simple-icons:apacheecharts'
} }
@@ -673,6 +734,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'AntV', title: 'AntV',
i18nTitle: 'message.routes.plugin.charts.antv',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:antdesign' icon: 'simple-icons:antdesign'
} }
@@ -680,6 +742,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '图表', title: '图表',
i18nTitle: 'message.routes.plugin.charts._value',
icon: 'mdi:chart-areaspline' icon: 'mdi:chart-areaspline'
} }
}, },
@@ -689,6 +752,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '地图', title: '地图',
i18nTitle: 'message.routes.plugin.map',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:map' icon: 'mdi:map'
} }
@@ -699,6 +763,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '视频', title: '视频',
i18nTitle: 'message.routes.plugin.video',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:video' icon: 'mdi:video'
} }
@@ -714,6 +779,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '富文本编辑器', title: '富文本编辑器',
i18nTitle: 'message.routes.plugin.editor.quill',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:file-document-edit-outline' icon: 'mdi:file-document-edit-outline'
} }
@@ -724,6 +790,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'markdown编辑器', title: 'markdown编辑器',
i18nTitle: 'message.routes.plugin.editor.markdown',
requiresAuth: true, requiresAuth: true,
icon: 'ri:markdown-line' icon: 'ri:markdown-line'
} }
@@ -731,6 +798,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '编辑器', title: '编辑器',
i18nTitle: 'message.routes.plugin.editor._value',
icon: 'icon-park-outline:editor' icon: 'icon-park-outline:editor'
} }
}, },
@@ -740,6 +808,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'Swiper插件', title: 'Swiper插件',
i18nTitle: 'message.routes.plugin.swiper',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:swiper' icon: 'simple-icons:swiper'
} }
@@ -750,6 +819,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '剪贴板', title: '剪贴板',
i18nTitle: 'message.routes.plugin.copy',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:clipboard-outline' icon: 'mdi:clipboard-outline'
} }
@@ -760,6 +830,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '图标', title: '图标',
i18nTitle: 'message.routes.plugin.icon',
requiresAuth: true, requiresAuth: true,
localIcon: 'custom-icon' localIcon: 'custom-icon'
} }
@@ -770,6 +841,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '打印', title: '打印',
i18nTitle: 'message.routes.plugin.print',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:printer' icon: 'mdi:printer'
} }
@@ -777,6 +849,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '插件示例', title: '插件示例',
i18nTitle: 'message.routes.plugin._value',
icon: 'clarity:plugin-line', icon: 'clarity:plugin-line',
order: 4 order: 4
} }
@@ -792,13 +865,26 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限切换', title: '权限切换',
i18nTitle: 'message.routes.auth-demo.permission',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-construction' icon: 'ic:round-construction'
} }
},
{
name: 'auth-demo_super',
path: '/auth-demo/super',
component: 'self',
meta: {
title: '超级管理员可见',
i18nTitle: 'message.routes.auth-demo.super',
requiresAuth: true,
icon: 'ic:round-supervisor-account'
}
} }
], ],
meta: { meta: {
title: '权限示例', title: '权限示例',
i18nTitle: 'message.routes.auth-demo._value',
icon: 'ic:baseline-security', icon: 'ic:baseline-security',
order: 5 order: 5
} }
@@ -814,6 +900,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: 'Tab', title: 'Tab',
i18nTitle: 'message.routes.function.tab',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-tab' icon: 'ic:round-tab'
} }
@@ -846,6 +933,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '功能', title: '功能',
i18nTitle: 'message.routes.function._value',
icon: 'icon-park-outline:all-application', icon: 'icon-park-outline:all-application',
order: 6 order: 6
} }
@@ -861,6 +949,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页403', title: '异常页403',
i18nTitle: 'message.routes.exception.403',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-block' icon: 'ic:baseline-block'
} }
@@ -871,6 +960,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页404', title: '异常页404',
i18nTitle: 'message.routes.exception.404',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-web-asset-off' icon: 'ic:baseline-web-asset-off'
} }
@@ -881,12 +971,14 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页500', title: '异常页500',
i18nTitle: 'message.routes.exception.500',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-wifi-off' icon: 'ic:baseline-wifi-off'
} }
} }
], ],
meta: { meta: {
i18nTitle: 'message.routes.exception._value',
title: '异常页', title: '异常页',
icon: 'ant-design:exception-outlined', icon: 'ant-design:exception-outlined',
order: 7 order: 7
@@ -908,6 +1000,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '二级菜单', title: '二级菜单',
i18nTitle: 'message.routes.multi-menu.first.second',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:menu' icon: 'mdi:menu'
} }
@@ -923,6 +1016,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '三级菜单', title: '三级菜单',
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:menu' icon: 'mdi:menu'
} }
@@ -930,18 +1024,21 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '二级菜单(有子菜单)', title: '二级菜单(有子菜单)',
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
icon: 'mdi:menu' icon: 'mdi:menu'
} }
} }
], ],
meta: { meta: {
title: '一级菜单', title: '一级菜单',
i18nTitle: 'message.routes.multi-menu.first._value',
icon: 'mdi:menu' icon: 'mdi:menu'
} }
} }
], ],
meta: { meta: {
title: '多级菜单', title: '多级菜单',
i18nTitle: 'message.routes.multi-menu._value',
icon: 'carbon:menu', icon: 'carbon:menu',
order: 8 order: 8
} }
@@ -957,6 +1054,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限管理', title: '权限管理',
i18nTitle: 'message.routes.management.auth',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-security' icon: 'ic:baseline-security'
} }
@@ -967,6 +1065,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '角色管理', title: '角色管理',
i18nTitle: 'message.routes.management.role',
requiresAuth: true, requiresAuth: true,
icon: 'carbon:user-role' icon: 'carbon:user-role'
} }
@@ -977,6 +1076,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '用户管理', title: '用户管理',
i18nTitle: 'message.routes.management.user',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-manage-accounts' icon: 'ic:round-manage-accounts'
} }
@@ -987,6 +1087,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '路由管理', title: '路由管理',
i18nTitle: 'message.routes.management.route',
requiresAuth: true, requiresAuth: true,
icon: 'material-symbols:route' icon: 'material-symbols:route'
} }
@@ -994,6 +1095,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '系统管理', title: '系统管理',
i18nTitle: 'message.routes.management._value',
icon: 'carbon:cloud-service-management', icon: 'carbon:cloud-service-management',
order: 9 order: 9
} }
@@ -1004,7 +1106,9 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '关于', title: '关于',
i18nTitle: 'message.routes.about',
requiresAuth: true, requiresAuth: true,
keepAlive: true,
singleLayout: 'basic', singleLayout: 'basic',
icon: 'fluent:book-information-24-regular', icon: 'fluent:book-information-24-regular',
order: 10 order: 10
@@ -1024,14 +1128,27 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
meta: { meta: {
title: '分析页', title: '分析页',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:analysis' icon: 'icon-park-outline:analysis',
i18nTitle: 'message.routes.dashboard.analysis'
}
},
{
name: 'dashboard_workbench',
path: '/dashboard/workbench',
component: 'self',
meta: {
title: '工作台',
requiresAuth: true,
icon: 'icon-park-outline:workbench',
i18nTitle: 'message.routes.dashboard.workbench'
} }
} }
], ],
meta: { meta: {
title: '仪表盘', title: '仪表盘',
icon: 'mdi:monitor-dashboard', icon: 'mdi:monitor-dashboard',
order: 1 order: 1,
i18nTitle: 'message.routes.dashboard._value'
} }
}, },
{ {
@@ -1045,13 +1162,26 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限切换', title: '权限切换',
i18nTitle: 'message.routes.auth-demo.permission',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-construction' icon: 'ic:round-construction'
} }
},
{
name: 'auth-demo_super',
path: '/auth-demo/super',
component: 'self',
meta: {
title: '超级管理员可见',
i18nTitle: 'message.routes.auth-demo.super',
requiresAuth: true,
icon: 'ic:round-supervisor-account'
}
} }
], ],
meta: { meta: {
title: '权限示例', title: '权限示例',
i18nTitle: 'message.routes.auth-demo._value',
icon: 'ic:baseline-security', icon: 'ic:baseline-security',
order: 5 order: 5
} }
@@ -1072,6 +1202,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '二级菜单', title: '二级菜单',
i18nTitle: 'message.routes.multi-menu.first.second',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:menu' icon: 'mdi:menu'
} }
@@ -1087,6 +1218,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '三级菜单', title: '三级菜单',
i18nTitle: 'message.routes.multi-menu.first.second-new.third',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:menu' icon: 'mdi:menu'
} }
@@ -1094,20 +1226,23 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
], ],
meta: { meta: {
title: '二级菜单(有子菜单)', title: '二级菜单(有子菜单)',
i18nTitle: 'message.routes.multi-menu.first.second-new._value',
icon: 'mdi:menu' icon: 'mdi:menu'
} }
} }
], ],
meta: { meta: {
title: '一级菜单', title: '一级菜单',
i18nTitle: 'message.routes.multi-menu.first._value',
icon: 'mdi:menu' icon: 'mdi:menu'
} }
} }
], ],
meta: { meta: {
title: '多级菜单', title: '多级菜单',
i18nTitle: 'message.routes.multi-menu._value',
icon: 'carbon:menu', icon: 'carbon:menu',
order: 7 order: 8
} }
}, },
{ {
@@ -1116,10 +1251,12 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
component: 'self', component: 'self',
meta: { meta: {
title: '关于', title: '关于',
i18nTitle: 'message.routes.about',
requiresAuth: true, requiresAuth: true,
keepAlive: true,
singleLayout: 'basic', singleLayout: 'basic',
icon: 'fluent:book-information-24-regular', icon: 'fluent:book-information-24-regular',
order: 8 order: 10
} }
} }
] ]

View File

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

View File

@@ -5,56 +5,56 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
@@ -126,17 +126,17 @@ return /******/ (function(modules) { // webpackBootstrap @@ -126,17 +126,17 @@ return /******/ (function(modules) { // webpackBootstrap
/* 1 */ /* 1 */
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
- /* - /*
+ /* + /*
## Handler ## Handler
处理数据模板。 处理数据模板。
- -
+ +
* Handler.gen( template, name?, context? ) * Handler.gen( template, name?, context? )
入口方法。 入口方法。
* Data Template Definition, DTD * Data Template Definition, DTD
- -
+ +
处理数据模板定义。 处理数据模板定义。
* Handler.array( options ) * Handler.array( options )
@@ -146,7 +146,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -146,7 +146,7 @@ return /******/ (function(modules) { // webpackBootstrap
* Handler.string( options ) * Handler.string( options )
* Handler.function( options ) * Handler.function( options )
* Handler.regexp( options ) * Handler.regexp( options )
- -
+ +
处理路径(相对和绝对)。 处理路径(相对和绝对)。
* Handler.getValueByKeyPath( key, options ) * Handler.getValueByKeyPath( key, options )
@@ -177,7 +177,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -177,7 +177,7 @@ return /******/ (function(modules) { // webpackBootstrap
Handle.gen(template, name, options) Handle.gen(template, name, options)
context context
- currentContext, templateCurrentContext, - currentContext, templateCurrentContext,
+ currentContext, templateCurrentContext, + currentContext, templateCurrentContext,
path, templatePath path, templatePath
root, templateRoot root, templateRoot
*/ */
@@ -456,7 +456,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -456,7 +456,7 @@ return /******/ (function(modules) { // webpackBootstrap
phed = Handler.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options) 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) { // + if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { //
result = phed result = phed
break break
@@ -627,7 +627,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -627,7 +627,7 @@ return /******/ (function(modules) { // webpackBootstrap
} }
// 引用的值已经计算好 // 引用的值已经计算好
if (currentContext && (key in currentContext)) return currentContext[key] if (currentContext && (key in currentContext)) return currentContext[key]
- -
+ +
// 尚未计算,递归引用数据模板中的属性 // 尚未计算,递归引用数据模板中的属性
if (templateCurrentContext && if (templateCurrentContext &&
@@ -63,41 +63,41 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
var tpl = Mock.heredoc(function() { var tpl = Mock.heredoc(function() {
/*! /*!
{{email}}{{age}} {{email}}{{age}}
- <!-- Mock { - <!-- Mock {
+ <!-- Mock { + <!-- Mock {
email: '@EMAIL', email: '@EMAIL',
age: '@INT(1,100)' age: '@INT(1,100)'
} --> } -->
*\/ *\/
}) })
- -
+ +
**相关阅读** **相关阅读**
* [Creating multiline strings in JavaScript](http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript)、 * [Creating multiline strings in JavaScript](http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript)、
*/ */
@@ -850,7 +850,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -850,7 +850,7 @@ return /******/ (function(modules) { // webpackBootstrap
解析数据模板(属性名部分)。 解析数据模板(属性名部分)。
* Parser.parse( name ) * Parser.parse( name )
- -
+ +
```json ```json
{ {
parameters: [ name, inc, range, decimal ], parameters: [ name, inc, range, decimal ],
@@ -922,7 +922,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -922,7 +922,7 @@ return /******/ (function(modules) { // webpackBootstrap
/* /*
## Mock.Random ## Mock.Random
- -
+ +
工具类,用于生成各种随机数据。 工具类,用于生成各种随机数据。
*/ */
@@ -1251,7 +1251,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -1251,7 +1251,7 @@ return /******/ (function(modules) { // webpackBootstrap
替代图片源 替代图片源
http://fpoimg.com/ http://fpoimg.com/
- 参考自 - 参考自
+ 参考自 + 参考自
http://rensanning.iteye.com/blog/1933310 http://rensanning.iteye.com/blog/1933310
http://code.tutsplus.com/articles/the-top-8-placeholders-for-web-designers--net-19485 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); var bg_colour = Math.floor(Math.random() * 16777215).toString(16);
bg_colour = "#" + ("000000" + bg_colour).slice(-6); bg_colour = "#" + ("000000" + bg_colour).slice(-6);
document.bgColor = bg_colour; document.bgColor = bg_colour;
- -
+ +
http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ 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. 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 https://github.com/devongovett/color-generator
@@ -1561,7 +1561,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -1561,7 +1561,7 @@ return /******/ (function(modules) { // webpackBootstrap
http://tool.c7sky.com/webcolor http://tool.c7sky.com/webcolor
网页设计常用色彩搭配表 网页设计常用色彩搭配表
- -
+ +
https://github.com/One-com/one-color 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. 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)] color += letters[Math.floor(Math.random() * 16)]
} }
return color return color
- -
+ +
// 随机生成一个无脑的颜色,格式为 '#RRGGBB'。 // 随机生成一个无脑的颜色,格式为 '#RRGGBB'。
// _brainlessColor() // _brainlessColor()
@@ -133,24 +133,24 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
return result.join(' ') return result.join(' ')
}, },
- // - //
+ // + //
cparagraph: function(min, max) { cparagraph: function(min, max) {
var len = range(3, 7, min, max) var len = range(3, 7, min, max)
var result = [] var result = []
@@ -2282,17 +2282,17 @@ return /******/ (function(modules) { // webpackBootstrap @@ -2282,17 +2282,17 @@ return /******/ (function(modules) { // webpackBootstrap
随机生成一个 URL。 随机生成一个 URL。
[URL 规范](http://www.w3.org/Addressing/URL/url-spec.txt) [URL 规范](http://www.w3.org/Addressing/URL/url-spec.txt)
- http Hypertext Transfer Protocol - http Hypertext Transfer Protocol
- ftp File Transfer protocol - ftp File Transfer protocol
- gopher The Gopher protocol - gopher The Gopher protocol
- mailto Electronic mail address - mailto Electronic mail address
- mid Message identifiers for electronic mail - mid Message identifiers for electronic mail
- cid Content identifiers for MIME body part - cid Content identifiers for MIME body part
- news Usenet news - news Usenet news
- nntp Usenet news for local NNTP access only - nntp Usenet news for local NNTP access only
- prospero Access using the prospero protocols - prospero Access using the prospero protocols
+ http Hypertext Transfer Protocol + http Hypertext Transfer Protocol
+ ftp File Transfer protocol + ftp File Transfer protocol
+ gopher The Gopher protocol + gopher The Gopher protocol
@@ -161,7 +161,7 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
+ nntp Usenet news for local NNTP access only + nntp Usenet news for local NNTP access only
+ prospero Access using the prospero protocols + prospero Access using the prospero protocols
telnet rlogin tn3270 Reference to interactive sessions telnet rlogin tn3270 Reference to interactive sessions
- wais Wide Area Information Servers - wais Wide Area Information Servers
+ wais Wide Area Information Servers + wais Wide Area Information Servers
*/ */
url: function(protocol, host) { url: function(protocol, host) {
@@ -170,10 +170,10 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
西南 重庆市 四川省 贵州省 云南省 西藏自治区 西南 重庆市 四川省 贵州省 云南省 西藏自治区
西北 陕西省 甘肃省 青海省 宁夏回族自治区 新疆维吾尔自治区 西北 陕西省 甘肃省 青海省 宁夏回族自治区 新疆维吾尔自治区
港澳台 香港特别行政区 澳门特别行政区 台湾省 港澳台 香港特别行政区 澳门特别行政区 台湾省
- -
+ +
**排序** **排序**
- -
+ +
```js ```js
var map = {} var map = {}
@@ -182,25 +182,25 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" / "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
"a" / "b" / "c" / "d" / "e" / "f" / "a" / "b" / "c" / "d" / "e" / "f" /
"A" / "B" / "C" / "D" / "E" / "F" "A" / "B" / "C" / "D" / "E" / "F"
- -
+ +
https://github.com/victorquinn/chancejs/blob/develop/chance.js#L1349 https://github.com/victorquinn/chancejs/blob/develop/chance.js#L1349
*/ */
guid: function() { guid: function() {
@@ -6629,7 +6629,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -6629,7 +6629,7 @@ return /******/ (function(modules) { // webpackBootstrap
} }
function CaptureGroup(n) { 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++), + Group.call(this, "capture-group"), this.index = cgs[this.offset] || (cgs[this.offset] = index++),
this.body = n; this.body = n;
} }
@@ -6711,7 +6711,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -6711,7 +6711,7 @@ return /******/ (function(modules) { // webpackBootstrap
} }
return r = l ? '"' + u(l) + '"' : "end of input", "Expected " + t + " but " + r + " found."; 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.expected = n, this.found = l, this.offset = u, this.line = t, this.column = r,
this.name = "SyntaxError", this.message = e(n, l); this.name = "SyntaxError", this.message = e(n, l);
} }
@@ -209,8 +209,8 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
function r(l) { function r(l) {
function u(l, u, t) { function u(l, u, t) {
var r, e; var r, e;
- for (r = u; t > r; r++) e = n.charAt(r), "\n" === e ? (l.seenCR || 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 = !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, + 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 = !1) : "\r" === e || "\u2028" === e || "\u2029" === e ? (l.line++, l.column = 1,
l.seenCR = !0) : (l.column++, l.seenCR = !1); l.seenCR = !0) : (l.column++, l.seenCR = !1);
@@ -220,10 +220,10 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function c() { function c() {
var l, u, t, r, o; var l, u, t, r, o;
- return l = qt, u = i(), null !== u ? (t = qt, 124 === n.charCodeAt(qt) ? (r = fl, - 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 ], - 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, - 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, - 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, + 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 ], + 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, + 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() { function i() {
var n, l, u, t, r; 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(), + 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) { 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(), + for (t = [], r = h(), null === r && (r = a()); null !== r; ) t.push(r), r = h(),
null === r && (r = a()); 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 !== 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); 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; } else qt = n, n = il; else qt = n, n = il;
@@ -247,43 +247,43 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function f() { function f() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = wl()), null === u ? (qt = l, l = u) : l = u, l;
} }
function s() { function s() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = gl()), null === u ? (qt = l, l = u) : l = u, l;
} }
function h() { function h() {
var n, l, u; 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), + 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; null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n, n = il), n;
} }
function d() { function d() {
var n, l, u; var n, l, u;
- return Wt++, n = qt, l = p(), null !== l ? (u = k(), null === u && (u = al), null !== u ? (Lt = 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, - 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, + 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, + 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; n = il), Wt--, null === n && (l = null, 0 === Wt && e(kl)), n;
} }
function p() { function p() {
var n; 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(), + return n = v(), null === n && (n = w(), null === n && (n = A(), null === n && (n = C(),
null === n && (n = g(), null === n && (n = b()))))), n; null === n && (n = g(), null === n && (n = b()))))), n;
} }
function v() { function v() {
var l, u, t, r, o, c; var l, u, t, r, o, c;
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)), - 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, - 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, - 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, - qt++) : (c = null, 0 === Wt && e(Ql)), null !== c ? (Lt = l, u = Sl(t, o), null === u ? (qt = l,
- l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, - l = 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)), + 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, + 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, + 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() { function w() {
var l, u, t, r; var l, u, t, r;
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)), - 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, - 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, - 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)), + 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, + 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, + 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() { function A() {
var l, u, t, r; var l, u, t, r;
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)), - 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, - 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, - 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)), + 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, + 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, + 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() { function C() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = ql()), null === u ? (qt = l, l = u) : l = u, l;
} }
function g() { function g() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Dl()), null === u ? (qt = l, l = u) : l = u, l;
} }
function b() { function b() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Wl()), null === u ? (qt = l, l = u) : l = u, l;
} }
function k() { function k() {
var l; 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)), + return 63 === n.charCodeAt(qt) ? (l = Hl, qt++) : (l = null, 0 === Wt && e(Ol)),
l; l;
} }
function T() { function T() {
var l, u, t; var l, u, t;
- if (l = qt, u = [], zl.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null, - 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), - 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, + 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), + 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; 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, + return null !== u && (Lt = l, u = Jl(u)), null === u ? (qt = l, l = u) : l = u,
l; l;
} }
function x() { function x() {
var l, u, t, r; var l, u, t, r;
- return l = qt, 40 === n.charCodeAt(qt) ? (u = Kl, qt++) : (u = null, 0 === Wt && e(Nl)), - 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 !== 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 !== 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, - 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)), + 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 !== 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 !== t ? (41 === n.charCodeAt(qt) ? (r = Pl, qt++) : (r = null, 0 === Wt && e(Vl)),
@@ -360,46 +360,46 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function y() { function y() {
var n, l; 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, + return n = qt, l = c(), null !== l && (Lt = n, l = Yl(l)), null === l ? (qt = n,
n = l) : n = l, n; n = l) : n = l, n;
} }
function m() { function m() {
var l, u, t; var l, u, t;
- return l = qt, n.substr(qt, 2) === Zl ? (u = Zl, qt += 2) : (u = null, 0 === Wt && e(_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, - 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)), + 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, + 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; l = il)) : (qt = l, l = il), l;
} }
function R() { function R() {
var l, u, t; var l, u, t;
- return l = qt, n.substr(qt, 2) === lu ? (u = lu, qt += 2) : (u = null, 0 === Wt && e(uu)), - 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, - 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)), + 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, + 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; l = il)) : (qt = l, l = il), l;
} }
function F() { function F() {
var l, u, t; var l, u, t;
- return l = qt, n.substr(qt, 2) === ru ? (u = ru, qt += 2) : (u = null, 0 === Wt && e(eu)), - 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, - 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)), + 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, + 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; l = il)) : (qt = l, l = il), l;
} }
function Q() { function Q() {
var l, u, t, r, o; var l, u, t, r, o;
- if (Wt++, l = qt, 91 === n.charCodeAt(qt) ? (u = iu, qt++) : (u = null, 0 === Wt && e(au)), - 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 !== 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)), + 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 !== u) if (94 === n.charCodeAt(qt) ? (t = pl, qt++) : (t = null, 0 === Wt && e(vl)),
null === t && (t = al), null !== t) { 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(), + for (r = [], o = S(), null === o && (o = U()); null !== o; ) r.push(o), o = S(),
null === o && (o = U()); null === o && (o = U());
- null !== r ? (93 === n.charCodeAt(qt) ? (o = fu, qt++) : (o = null, 0 === Wt && e(su)), - 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 !== 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 !== 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 !== o ? (Lt = l, u = hu(t, r), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il); l = il)) : (qt = l, l = il);
@@ -408,9 +408,9 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function S() { function S() {
var l, u, t, r; var l, u, t, r;
- return Wt++, l = qt, u = U(), null !== u ? (45 === n.charCodeAt(qt) ? (t = pu, qt++) : (t = null, - 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, - 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--, - 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, + 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, + 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--, + 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() { function U() {
var n, l; 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)), + return Wt++, n = G(), null === n && (n = E()), Wt--, null === n && (l = null, 0 === Wt && e(Au)),
n; n;
} }
function E() { function E() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u, l;
} }
function G() { function G() {
var n; var n;
- return n = L(), null === n && (n = Y(), null === n && (n = H(), null === n && (n = O(), - 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 = 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 = K(), null === n && (n = N(), null === n && (n = P(), null === n && (n = V(),
- null === n && (n = X(), null === n && (n = _(), null === n && (n = nl(), null === n && (n = ll(), - null === n && (n = 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(), + 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 = 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 = K(), null === n && (n = N(), null === n && (n = P(), null === n && (n = V(),
@@ -445,25 +445,25 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function j() { function j() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = xu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function $() { function $() {
var l, u; var l, u;
- return Wt++, l = qt, mu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null, - 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, - 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, + 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, + 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; Wt--, null === l && (u = null, 0 === Wt && e(yu)), l;
} }
function q() { function q() {
var n; var n;
- return n = M(), null === n && (n = D(), null === n && (n = Y(), null === n && (n = H(), - 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 = 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 = 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 = 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()))))))))))))))))))), - 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(), + 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 = 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 = J(), null === n && (n = K(), null === n && (n = N(), null === n && (n = P(),
@@ -473,93 +473,93 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function L() { function L() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Su()), null === u ? (qt = l, l = u) : l = u, l;
} }
function M() { function M() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Uu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function D() { function D() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Bu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function H() { function H() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = qu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function O() { function O() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Du()), null === u ? (qt = l, l = u) : l = u, l;
} }
function W() { function W() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Wu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function z() { function z() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Ju()), null === u ? (qt = l, l = u) : l = u, l;
} }
function I() { function I() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Pu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function J() { function J() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = Yu()), null === u ? (qt = l, l = u) : l = u, l;
} }
function K() { function K() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = nt()), null === u ? (qt = l, l = u) : l = u, l;
} }
function N() { function N() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = tt()), null === u ? (qt = l, l = u) : l = u, l;
} }
function P() { function P() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = ot()), null === u ? (qt = l, l = u) : l = u, l;
} }
function V() { function V() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = at()), null === u ? (qt = l, l = u) : l = u, l;
} }
function X() { function X() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = ht()), null === u ? (qt = l, l = u) : l = u, l;
} }
function Y() { function Y() {
var l, u, t; var l, u, t;
- return l = qt, n.substr(qt, 2) === dt ? (u = dt, qt += 2) : (u = null, 0 === Wt && e(pt)), - 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 !== 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, - 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)), + 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 !== 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, + 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() { function Z() {
var l, u, t; var l, u, t;
- return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)), - 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 !== 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, - 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)), + 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 !== 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, + 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 _() { function _() {
var l, u, t, r; 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)), + if (l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
null !== u) { null !== u) {
- if (t = [], yt.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(mt)), - 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), - 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)), + 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), + 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; 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, + null !== t ? (Lt = l, u = Rt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il); l = il);
} else qt = l, l = il; } else qt = l, l = il;
@@ -593,15 +593,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function nl() { function nl() {
var l, u, t, r; 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)), + if (l = qt, n.substr(qt, 2) === Ft ? (u = Ft, qt += 2) : (u = null, 0 === Wt && e(Qt)),
null !== u) { null !== u) {
- if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)), - 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), - 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)), + 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), + 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; 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, + null !== t ? (Lt = l, u = Et(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il); l = il);
} else qt = l, l = il; } else qt = l, l = il;
@@ -609,15 +609,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function ll() { function ll() {
var l, u, t, r; 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)), + if (l = qt, n.substr(qt, 2) === Gt ? (u = Gt, qt += 2) : (u = null, 0 === Wt && e(Bt)),
null !== u) { null !== u) {
- if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)), - 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), - 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)), + 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), + 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; 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, + null !== t ? (Lt = l, u = jt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il); l = il);
} else qt = l, l = il; } else qt = l, l = il;
@@ -625,15 +625,15 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
} }
function ul() { function ul() {
var l, u; 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)), + 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; null !== u && (Lt = l, u = $t()), null === u ? (qt = l, l = u) : l = u, l;
} }
function tl() { function tl() {
var l, u, t; var l, u, t;
- return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)), - 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 !== 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, - 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)), + 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 !== 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, + 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 Util = __webpack_require__(3)
var Random = __webpack_require__(5) var Random = __webpack_require__(5)
/* /*
- -
+ +
*/ */
var Handler = { var Handler = {
@@ -653,21 +653,21 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
return Random.integer(min, max) return Random.integer(min, max)
}, },
/* /*
- -
+ +
*/ */
charset: function(node, result, cache) { charset: function(node, result, cache) {
// node.invert // node.invert
@@ -7642,11 +7642,11 @@ return /******/ (function(modules) { // webpackBootstrap @@ -7642,11 +7642,11 @@ return /******/ (function(modules) { // webpackBootstrap
## valid(template, data) ## valid(template, data)
校验真实数据 data 是否与数据模板 template 匹配。 校验真实数据 data 是否与数据模板 template 匹配。
- -
+ +
实现思路: 实现思路:
1. 解析规则。 1. 解析规则。
先把数据模板 template 解析为更方便机器解析的 JSON-Schame 先把数据模板 template 解析为更方便机器解析的 JSON-Schame
- name 属性名 - name 属性名
+ name 属性名 + name 属性名
type 属性值类型 type 属性值类型
template 属性值模板 template 属性值模板
@@ -675,8 +675,8 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
@@ -7655,7 +7655,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -7655,7 +7655,7 @@ return /******/ (function(modules) { // webpackBootstrap
2. 递归验证规则。 2. 递归验证规则。
然后用 JSON-Schema 校验真实数据,校验项包括属性名、值类型、值、值生成规则。 然后用 JSON-Schema 校验真实数据,校验项包括属性名、值类型、值、值生成规则。
- 提示信息 - 提示信息
+ 提示信息 + 提示信息
https://github.com/fge/json-schema-validator/blob/master/src/main/resources/com/github/fge/jsonschema/validator/validation.properties 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/) [JSON-Schama validator](http://json-schema-validator.herokuapp.com/)
@@ -685,25 +685,25 @@ index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecd
+step +step
整数部分 整数部分
小数部分 小数部分
- boolean - boolean
- string - string
+ boolean + boolean
+ string + string
min-max min-max
count count
## properties ## properties
@@ -7949,9 +7949,9 @@ return /******/ (function(modules) { // webpackBootstrap @@ -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 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. Expect path.name is less than or equal to expected, but path.name is actual.
@@ -8264,7 +8264,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -8264,7 +8264,7 @@ return /******/ (function(modules) { // webpackBootstrap
Util.extend(MockXMLHttpRequest.prototype, { Util.extend(MockXMLHttpRequest.prototype, {
// https://xhr.spec.whatwg.org/#the-open()-method // 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, username, password) {
+ open: function(method, url, async = true, username, password) { + open: function(method, url, async = true, username, password) {
var that = this var that = this
Util.extend(this.custom, { Util.extend(this.custom, {
@@ -8310,6 +8310,8 @@ return /******/ (function(modules) { // webpackBootstrap @@ -8310,6 +8310,8 @@ return /******/ (function(modules) { // webpackBootstrap
var xhr = createNativeXMLHttpRequest() var xhr = createNativeXMLHttpRequest()
this.custom.xhr = xhr this.custom.xhr = xhr
+ MockXMLHttpRequest.prototype.upload = xhr.upload + MockXMLHttpRequest.prototype.upload = xhr.upload
+ +
// 初始化所有事件,用于监听原生 XHR 对象的事件 // 初始化所有事件,用于监听原生 XHR 对象的事件
for (var i = 0; i < XHR_EVENTS.length; i++) { for (var i = 0; i < XHR_EVENTS.length; i++) {
xhr.addEventListener(XHR_EVENTS[i], handle) xhr.addEventListener(XHR_EVENTS[i], handle)
@@ -8360,6 +8362,7 @@ return /******/ (function(modules) { // webpackBootstrap @@ -8360,6 +8362,7 @@ return /******/ (function(modules) { // webpackBootstrap
// 原生 XHR // 原生 XHR
if (!this.match) { if (!this.match) {
+ this.custom.xhr.responseType = this.responseType || '' + this.custom.xhr.responseType = this.responseType || ''
this.custom.xhr.send(data) this.custom.xhr.send(data)
return return
} }

9761
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', placeholderClass: 'bg-white dark:bg-dark transition-background-color duration-300 ease-in-out',
emptyDesc: '暂无数据', emptyDesc: '暂无数据',
iconClass: 'text-320px text-primary', iconClass: 'text-320px text-primary',
descClass: 'text-16px text-[#666]', descClass: 'text-16px text-#666',
showNetworkReload: false showNetworkReload: false
}); });

View File

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

View File

@@ -34,9 +34,51 @@ const darkMode = computed({
} }
}); });
function handleSwitch() { function handleSwitch(event: MouseEvent) {
darkMode.value = !darkMode.value; 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> </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> <template>
<div class="flex-col-center wh-full"> <div class="flex-col-center gap-24px min-h-520px wh-full overflow-hidden">
<div class="text-400px text-primary"> <div class="flex text-400px text-primary">
<icon-local-no-permission v-if="type === '403'" /> <icon-local-no-permission v-if="type === '403'" />
<icon-local-not-found v-if="type === '404'" /> <icon-local-not-found v-if="type === '404'" />
<icon-local-service-error v-if="type === '500'" /> <icon-local-service-error v-if="type === '500'" />

View File

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

View File

@@ -14,7 +14,7 @@
<span v-for="iconItem in iconsList" :key="iconItem" @click="handleChange(iconItem)"> <span v-for="iconItem in iconsList" :key="iconItem" @click="handleChange(iconItem)">
<svg-icon <svg-icon
:icon="iconItem" :icon="iconItem"
class="border-1px border-[#d9d9d9] text-30px m-2px p-5px cursor-pointer" class="border-1px border-#d9d9d9 text-30px m-2px p-5px cursor-pointer"
:class="{ 'border-primary': modelValue === iconItem }" :class="{ 'border-primary': modelValue === iconItem }"
/> />
</span> </span>

View File

@@ -1,14 +1,34 @@
import { effectScope, onScopeDispose, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useEventListener } from '@vueuse/core'; import { useEventListener } from '@vueuse/core';
import { useI18n } from 'vue-i18n';
import { useTabStore, useThemeStore } from '@/store'; import { useTabStore, useThemeStore } from '@/store';
/** 全局事件 */ /** 全局事件 */
export function useGlobalEvents() { export function useGlobalEvents() {
const theme = useThemeStore(); const theme = useThemeStore();
const tab = useTabStore(); const tab = useTabStore();
const route = useRoute();
const { locale, t } = useI18n();
const scope = effectScope();
/** 页面离开时缓存多页签数据 */ /** 页面离开时缓存多页签数据 */
useEventListener(window, 'beforeunload', () => { useEventListener(window, 'beforeunload', () => {
theme.cacheThemeSettings(); theme.cacheThemeSettings();
tab.cacheTabRoutes(); 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 { h } from 'vue';
import SvgIcon from '~/src/components/custom/svg-icon.vue'; import SvgIcon from '@/components/custom/svg-icon.vue';
/** /**
* 图标渲染 * 图标渲染

View File

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

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> = { export const loginModuleLabels: Record<UnionKey.LoginModule, string> = {
'pwd-login': '账密登录', 'pwd-login': '账密登录',
'code-login': '手机验证码登录', 'code-login': '手机验证码登录',
@@ -11,23 +13,14 @@ export const userRoleLabels: Record<Auth.RoleType, string> = {
admin: '管理员', admin: '管理员',
user: '普通用户' user: '普通用户'
}; };
export const userRoleOptions = transformObjectToOption(userRoleLabels);
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> = { export const genderLabels: Record<UserManagement.GenderKey, string> = {
0: '女', 0: '女',
1: '男' 1: '男'
}; };
export const genderOptions = transformObjectToOption(genderLabels);
export const genderOptions: Common.OptionWithKey<UserManagement.GenderKey>[] = [
{ value: '0', label: genderLabels['0'] },
{ value: '1', label: genderLabels['1'] }
];
/** 用户状态 */ /** 用户状态 */
export const userStatusLabels: Record<UserManagement.UserStatusKey, string> = { export const userStatusLabels: Record<UserManagement.UserStatusKey, string> = {
@@ -36,10 +29,4 @@ export const userStatusLabels: Record<UserManagement.UserStatusKey, string> = {
3: '冻结', 3: '冻结',
4: '软删除' 4: '软删除'
}; };
export const userStatusOptions = transformObjectToOption(userStatusLabels);
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'] }
];

View File

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

View File

@@ -1,10 +1,42 @@
import { ref, reactive } from 'vue'; import { ref, reactive } from 'vue';
import type { Ref } from 'vue'; import type { Ref } from 'vue';
import type { DataTableBaseColumn, DataTableSelectionColumn, DataTableExpandColumn, PaginationProps } from 'naive-ui'; 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 type { TableColumnGroup, InternalRowData } from 'naive-ui/es/data-table/src/interface';
import { useLoadingEmpty } from '../common'; import { useLoadingEmpty } from '../common';
/**
* 表格分页参数
*/
type PaginationParams = Pick<PaginationProps, 'page' | 'pageSize'>;
/**
* 表格请求接口的参数
*/
type ApiParams = Record<string, unknown> & PaginationParams;
/**
* 表格请求接口的结果
* @description 这里用属性list来表示后端接口返回的表格数据
*/
type ApiData<TableData = Record<string, unknown>> = Record<string, unknown> & { list: TableData[] };
/**
* 表格接口的请求函数
*/
type ApiFn<Params = ApiParams, TableData = Record<string, unknown>> = (
params: Params
) => Promise<Service.RequestResult<ApiData<TableData>>>;
/**
* 表格接口请求后转换后的数据
*/
type TransformedTableData<TableData = Record<string, unknown>> = {
data: TableData[];
pageNum: number;
pageSize: number;
total: number;
};
/** /**
* 表格的列 * 表格的列
*/ */
@@ -15,60 +47,45 @@ type DataTableColumn<T = InternalRowData> =
| DataTableExpandColumn<T>; | DataTableExpandColumn<T>;
/** /**
* 表格分页参 * 表格数据转换器
* @description 将不同接口的表格数据转换成统一的类型
*/ */
type TablePaginationParams = Pick<PaginationProps, 'page' | 'pageSize'>; type Transformer<TableData = Record<string, unknown>> = (
apiData: ApiData<TableData>
) => TransformedTableData<TableData>;
/** type TableParams<TableData = Record<string, unknown>, Params = ApiParams> = {
* 表格接口的请求参数 apiFn: ApiFn<Params, TableData>;
*/ apiParams: Params;
type TableApiParams = Record<string, unknown> & TablePaginationParams; transformer: Transformer<TableData>;
columns: DataTableColumn<TableData>[];
/** pagination?: PaginationProps;
* 表格接口的请求数据
*/
type TableApiData<T = InternalRowData> = {
data: T[];
pageNum: number;
pageSize: number;
total: number;
}; };
/** export function useTable<TableData extends Record<string, unknown>, Params extends ApiParams>(
* 表格接口的请求函数 params: TableParams<TableData, Params>,
*/ immediate = true
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 { loading, startLoading, endLoading, empty, setEmpty } = useLoadingEmpty();
const data: Ref<TableData[]> = ref([]);
const tableData: Ref<TableData[]> = ref([]); function updateData(update: TableData[]) {
data.value = update;
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({ let dataSource: TableData[] = [];
page: 1, function setDataSource(source: TableData[]) {
pageSize: 10, dataSource = source;
showSizePicker: true, }
pageSizes: [10, 15, 20, 25, 30],
function resetData() {
data.value = dataSource;
}
const columns = ref(params.columns) as Ref<DataTableColumn<TableData>[]>;
const pagination = reactive({
...getPagination(params.pagination),
onChange: (page: number) => { onChange: (page: number) => {
pagination.page = page; pagination.page = page;
}, },
@@ -76,14 +93,59 @@ export function useNaiveTable<TableData extends InternalRowData, P extends Table
pagination.pageSize = pageSize; pagination.pageSize = pageSize;
pagination.page = 1; pagination.page = 1;
} }
}); }) as PaginationProps;
function updatePagination(update: Partial<PaginationProps>) {
Object.assign(pagination, update);
}
async function getData() {
const apiParams: Params = { ...params.apiParams };
apiParams.page = apiParams.page || pagination.page;
apiParams.pageSize = apiParams.pageSize || pagination.pageSize;
startLoading();
const { data: apiData } = await params.apiFn(apiParams);
if (apiData) {
const transformedData = params.transformer(apiData);
updateData(transformedData.data);
setDataSource(transformedData.data);
setEmpty(transformedData.data.length === 0);
updatePagination({ page: transformedData.pageNum, pageSize: transformedData.pageSize });
}
endLoading();
}
if (immediate) {
getData();
}
return { return {
tableData, data,
columns, columns,
loading, loading,
empty, empty,
pagination, pagination,
start: getTableData getData,
updateData,
resetData
}; };
} }
function getPagination(pagination?: Partial<PaginationProps>) {
const defaultPagination: Partial<PaginationProps> = {
page: 1,
pageSize: 10,
showSizePicker: true,
pageSizes: [10, 15, 20, 25, 30]
};
Object.assign(defaultPagination, pagination);
return defaultPagination;
}

View File

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

View File

@@ -1,11 +1,15 @@
<template> <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> <span>Copyright ©2021 Soybean Admin</span>
</dark-mode-container> </dark-mode-container>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useThemeStore } from '@/store';
defineOptions({ name: 'GlobalFooter' }); defineOptions({ name: 'GlobalFooter' });
const theme = useThemeStore();
</script> </script>
<style scoped></style> <style scoped></style>

View File

@@ -2,7 +2,7 @@
<n-breadcrumb class="px-12px"> <n-breadcrumb class="px-12px">
<template v-for="breadcrumb in breadcrumbs" :key="breadcrumb.key"> <template v-for="breadcrumb in breadcrumbs" :key="breadcrumb.key">
<n-breadcrumb-item> <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> <span>
<component <component
:is="breadcrumb.icon" :is="breadcrumb.icon"
@@ -19,7 +19,9 @@
class="inline-block align-text-bottom mr-4px text-16px" class="inline-block align-text-bottom mr-4px text-16px"
:class="{ 'text-#BBBBBB': theme.header.inverted }" :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> </template>
</n-breadcrumb-item> </n-breadcrumb-item>
</template> </template>
@@ -33,6 +35,7 @@ import { routePath } from '@/router';
import { useRouteStore, useThemeStore } from '@/store'; import { useRouteStore, useThemeStore } from '@/store';
import { useRouterPush } from '@/composables'; import { useRouterPush } from '@/composables';
import { getBreadcrumbByRouteKey } from '@/utils'; import { getBreadcrumbByRouteKey } from '@/utils';
import { t } from '@/locales';
defineOptions({ name: 'GlobalBreadcrumb' }); defineOptions({ name: 'GlobalBreadcrumb' });
@@ -42,7 +45,13 @@ const routeStore = useRouteStore();
const { routerPush } = useRouterPush(); const { routerPush } = useRouterPush();
const breadcrumbs = computed(() => 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) { function dropdownSelect(key: string) {

View File

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

View File

@@ -7,6 +7,7 @@ import ThemeMode from './theme-mode.vue';
import UserAvatar from './user-avatar.vue'; import UserAvatar from './user-avatar.vue';
import SystemMessage from './system-message.vue'; import SystemMessage from './system-message.vue';
import SettingButton from './setting-button.vue'; import SettingButton from './setting-button.vue';
import ToggleLang from './toggle-lang.vue';
export { export {
MenuCollapse, MenuCollapse,
@@ -17,5 +18,6 @@ export {
ThemeMode, ThemeMode,
UserAvatar, UserAvatar,
SystemMessage, SystemMessage,
SettingButton SettingButton,
ToggleLang
}; };

View File

@@ -4,7 +4,7 @@
<n-list-item <n-list-item
v-for="(item, index) in list" v-for="(item, index) in list"
:key="item.id" :key="item.id"
class="hover:bg-[#f6f6f6] dark:hover:bg-dark cursor-pointer" class="hover:bg-#f6f6f6 dark:hover:bg-dark cursor-pointer"
@click="handleRead(index)" @click="handleRead(index)"
> >
<n-thing class="px-15px" :class="{ 'opacity-30': item.isRead }"> <n-thing class="px-15px" :class="{ 'opacity-30': item.isRead }">

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

@@ -11,6 +11,7 @@
<github-site /> <github-site />
<full-screen /> <full-screen />
<theme-mode /> <theme-mode />
<toggle-lang />
<system-message /> <system-message />
<setting-button v-if="showButton" /> <setting-button v-if="showButton" />
<user-avatar /> <user-avatar />
@@ -32,7 +33,8 @@ import {
SettingButton, SettingButton,
SystemMessage, SystemMessage,
ThemeMode, ThemeMode,
UserAvatar UserAvatar,
ToggleLang
} from './components'; } from './components';
defineOptions({ name: 'GlobalHeader' }); defineOptions({ name: 'GlobalHeader' });

View File

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

View File

@@ -12,7 +12,7 @@
<n-input-group> <n-input-group>
<n-input ref="inputRef" v-model:value="keyword" clearable placeholder="请输入关键词搜索" @input="handleSearch"> <n-input ref="inputRef" v-model:value="keyword" clearable placeholder="请输入关键词搜索" @input="handleSearch">
<template #prefix> <template #prefix>
<icon-uil-search class="text-15px text-[#c2c2c2]" /> <icon-uil-search class="text-15px text-#c2c2c2" />
</template> </template>
</n-input> </n-input>
<n-button v-if="isMobile" type="primary" ghost @click="handleClose">取消</n-button> <n-button v-if="isMobile" type="primary" ghost @click="handleClose">取消</n-button>

View File

@@ -3,7 +3,7 @@
<div class="pb-12px"> <div class="pb-12px">
<template v-for="item in options" :key="item.path"> <template v-for="item in options" :key="item.path">
<div <div
class="bg-[#e5e7eb] dark:bg-dark h-56px mt-8px px-14px rounded-4px cursor-pointer flex-y-center justify-between" class="bg-#e5e7eb dark:bg-dark h-56px mt-8px px-14px rounded-4px cursor-pointer flex-y-center justify-between"
:style="{ :style="{
background: item.path === active ? theme.themeColor : '', background: item.path === active ? theme.themeColor : '',
color: item.path === active ? '#fff' : '' color: item.path === active ? '#fff' : ''

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,6 +5,5 @@ import GlobalSider from './global-sider/index.vue';
import GlobalContent from './global-content/index.vue'; import GlobalContent from './global-content/index.vue';
import GlobalFooter from './global-footer/index.vue'; import GlobalFooter from './global-footer/index.vue';
import GlobalLogo from './global-logo/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> </template>
</n-switch> </n-switch>
</setting-menu> </setting-menu>
<setting-menu label="侧边栏深色主题"> <setting-menu label="侧边栏深色">
<n-switch :value="theme.sider.inverted" @update:value="theme.setSiderInverted" /> <n-switch :value="theme.sider.inverted" @update:value="theme.setSiderInverted" />
</setting-menu> </setting-menu>
<setting-menu label="头部深色主题"> <setting-menu label="头部深色">
<n-switch :value="theme.header.inverted" @update:value="theme.setHeaderInverted" /> <n-switch :value="theme.header.inverted" @update:value="theme.setHeaderInverted" />
</setting-menu> </setting-menu>
<setting-menu label="底部深色">
<n-switch :value="theme.footer.inverted" @update:value="theme.setFooterInverted" />
</setting-menu>
</n-space> </n-space>
</template> </template>

View File

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

View File

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

View File

@@ -1,12 +1,14 @@
import type { App } from 'vue'; import type { App } from 'vue';
import { createI18n } from 'vue-i18n'; import { createI18n } from 'vue-i18n';
import { localStg } from '@/utils';
import messages from './lang'; import messages from './lang';
import type { LocaleKey } from './lang'; import type { LocaleKey } from './lang';
const i18n = createI18n({ const i18n = createI18n({
locale: 'zh-CN', locale: localStg.get('lang') || 'zh-CN',
fallbackLocale: 'en', fallbackLocale: 'en',
messages messages,
legacy: false
}); });
export function setupI18n(app: App) { export function setupI18n(app: App) {
@@ -18,5 +20,5 @@ export function t(key: string) {
} }
export function setLocale(locale: LocaleKey) { 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: { routes: {
dashboard: { dashboard: {
dashboard: 'Dashboard', _value: 'Dashboard',
analysis: 'Analysis', analysis: 'Analysis',
workbench: 'Workbench' workbench: 'Workbench'
}, },
about: { document: {
about: 'About' _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 zhCN from './zh-cn';
import en from './en'; import en from './en';
import kmKH from './km-KH';
const locales = { const locales = {
'zh-CN': zhCN, 'zh-CN': zhCN,
en en,
'km-KH': kmKH
}; };
export type LocaleKey = keyof typeof locales; 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: { routes: {
dashboard: { dashboard: {
dashboard: '仪表盘', _value: '仪表盘',
analysis: '分析页', analysis: '分析页',
workbench: '工作台' workbench: '工作台'
}, },
about: { document: {
about: '关于' _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); setupI18n(app);
appLoading.unmount();
// mount app // mount app
app.mount('#app'); app.mount('#app');
} }

View File

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

View File

@@ -4,6 +4,7 @@ const about1: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '关于', title: '关于',
i18nTitle: 'message.routes.about',
requiresAuth: true, requiresAuth: true,
keepAlive: true, keepAlive: true,
singleLayout: 'basic', singleLayout: 'basic',

View File

@@ -9,6 +9,7 @@ const authDemo: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限切换', title: '权限切换',
i18nTitle: 'message.routes.auth-demo.permission',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-construction' icon: 'ic:round-construction'
} }
@@ -19,6 +20,7 @@ const authDemo: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '超级管理员可见', title: '超级管理员可见',
i18nTitle: 'message.routes.auth-demo.super',
requiresAuth: true, requiresAuth: true,
permissions: ['super'], permissions: ['super'],
icon: 'ic:round-supervisor-account' icon: 'ic:round-supervisor-account'
@@ -27,6 +29,7 @@ const authDemo: AuthRoute.Route = {
], ],
meta: { meta: {
title: '权限示例', title: '权限示例',
i18nTitle: 'message.routes.auth-demo._value',
icon: 'ic:baseline-security', icon: 'ic:baseline-security',
order: 5 order: 5
} }

View File

@@ -9,6 +9,7 @@ const component: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '按钮', title: '按钮',
i18nTitle: 'message.routes.component.button',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:button-cursor' icon: 'mdi:button-cursor'
} }
@@ -19,6 +20,7 @@ const component: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '卡片', title: '卡片',
i18nTitle: 'message.routes.component.card',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:card-outline' icon: 'mdi:card-outline'
} }
@@ -29,6 +31,7 @@ const component: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '表格', title: '表格',
i18nTitle: 'message.routes.component.table',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:table-large' icon: 'mdi:table-large'
} }
@@ -36,6 +39,7 @@ const component: AuthRoute.Route = {
], ],
meta: { meta: {
title: '组件示例', title: '组件示例',
i18nTitle: 'message.routes.component._value',
icon: 'cib:app-store', icon: 'cib:app-store',
order: 3 order: 3
} }

View File

@@ -10,7 +10,8 @@ const dashboard: AuthRoute.Route = {
meta: { meta: {
title: '分析页', title: '分析页',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:analysis' icon: 'icon-park-outline:analysis',
i18nTitle: 'message.routes.dashboard.analysis'
} }
}, },
{ {
@@ -20,14 +21,16 @@ const dashboard: AuthRoute.Route = {
meta: { meta: {
title: '工作台', title: '工作台',
requiresAuth: true, requiresAuth: true,
icon: 'icon-park-outline:workbench' icon: 'icon-park-outline:workbench',
i18nTitle: 'message.routes.dashboard.workbench'
} }
} }
], ],
meta: { meta: {
title: '仪表盘', title: '仪表盘',
icon: 'mdi:monitor-dashboard', icon: 'mdi:monitor-dashboard',
order: 1 order: 1,
i18nTitle: 'message.routes.dashboard._value'
} }
}; };

View File

@@ -9,6 +9,7 @@ const document: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'vue文档', title: 'vue文档',
i18nTitle: 'message.routes.document.vue',
requiresAuth: true, requiresAuth: true,
icon: 'logos:vue' icon: 'logos:vue'
} }
@@ -19,6 +20,7 @@ const document: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'vite文档', title: 'vite文档',
i18nTitle: 'message.routes.document.vite',
requiresAuth: true, requiresAuth: true,
icon: 'logos:vitejs' icon: 'logos:vitejs'
} }
@@ -29,6 +31,7 @@ const document: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'naive文档', title: 'naive文档',
i18nTitle: 'message.routes.document.naive',
requiresAuth: true, requiresAuth: true,
icon: 'logos:naiveui' icon: 'logos:naiveui'
} }
@@ -39,6 +42,7 @@ const document: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '项目文档', title: '项目文档',
i18nTitle: 'message.routes.document.project',
requiresAuth: true, requiresAuth: true,
localIcon: 'logo' localIcon: 'logo'
} }
@@ -48,6 +52,7 @@ const document: AuthRoute.Route = {
path: '/document/project-link', path: '/document/project-link',
meta: { meta: {
title: '项目文档(外链)', title: '项目文档(外链)',
i18nTitle: 'message.routes.document.project-link',
requiresAuth: true, requiresAuth: true,
localIcon: 'logo', localIcon: 'logo',
href: 'https://docs.soybean.pro/' href: 'https://docs.soybean.pro/'
@@ -56,6 +61,7 @@ const document: AuthRoute.Route = {
], ],
meta: { meta: {
title: '文档', title: '文档',
i18nTitle: 'message.routes.document._value',
icon: 'mdi:file-document-multiple-outline', icon: 'mdi:file-document-multiple-outline',
order: 2 order: 2
} }

View File

@@ -9,6 +9,7 @@ const exception: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页403', title: '异常页403',
i18nTitle: 'message.routes.exception.403',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-block' icon: 'ic:baseline-block'
} }
@@ -19,6 +20,7 @@ const exception: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页404', title: '异常页404',
i18nTitle: 'message.routes.exception.404',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-web-asset-off' icon: 'ic:baseline-web-asset-off'
} }
@@ -29,12 +31,14 @@ const exception: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '异常页500', title: '异常页500',
i18nTitle: 'message.routes.exception.500',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-wifi-off' icon: 'ic:baseline-wifi-off'
} }
} }
], ],
meta: { meta: {
i18nTitle: 'message.routes.exception._value',
title: '异常页', title: '异常页',
icon: 'ant-design:exception-outlined', icon: 'ant-design:exception-outlined',
order: 7 order: 7

View File

@@ -9,6 +9,7 @@ const functionRoute: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'Tab', title: 'Tab',
i18nTitle: 'message.routes.function.tab',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-tab' icon: 'ic:round-tab'
} }
@@ -41,6 +42,7 @@ const functionRoute: AuthRoute.Route = {
], ],
meta: { meta: {
title: '功能', title: '功能',
i18nTitle: 'message.routes.function._value',
icon: 'icon-park-outline:all-application', icon: 'icon-park-outline:all-application',
order: 6 order: 6
} }

View File

@@ -9,6 +9,7 @@ const management: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '权限管理', title: '权限管理',
i18nTitle: 'message.routes.management.auth',
requiresAuth: true, requiresAuth: true,
icon: 'ic:baseline-security' icon: 'ic:baseline-security'
} }
@@ -19,6 +20,7 @@ const management: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '角色管理', title: '角色管理',
i18nTitle: 'message.routes.management.role',
requiresAuth: true, requiresAuth: true,
icon: 'carbon:user-role' icon: 'carbon:user-role'
} }
@@ -29,6 +31,7 @@ const management: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '用户管理', title: '用户管理',
i18nTitle: 'message.routes.management.user',
requiresAuth: true, requiresAuth: true,
icon: 'ic:round-manage-accounts' icon: 'ic:round-manage-accounts'
} }
@@ -39,6 +42,7 @@ const management: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '路由管理', title: '路由管理',
i18nTitle: 'message.routes.management.route',
requiresAuth: true, requiresAuth: true,
icon: 'material-symbols:route' icon: 'material-symbols:route'
} }
@@ -46,6 +50,7 @@ const management: AuthRoute.Route = {
], ],
meta: { meta: {
title: '系统管理', title: '系统管理',
i18nTitle: 'message.routes.management._value',
icon: 'carbon:cloud-service-management', icon: 'carbon:cloud-service-management',
order: 9 order: 9
} }

View File

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

View File

@@ -14,6 +14,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'ECharts', title: 'ECharts',
i18nTitle: 'message.routes.plugin.charts.echarts',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:apacheecharts' icon: 'simple-icons:apacheecharts'
} }
@@ -24,6 +25,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'AntV', title: 'AntV',
i18nTitle: 'message.routes.plugin.charts.antv',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:antdesign' icon: 'simple-icons:antdesign'
} }
@@ -31,6 +33,7 @@ const plugin: AuthRoute.Route = {
], ],
meta: { meta: {
title: '图表', title: '图表',
i18nTitle: 'message.routes.plugin.charts._value',
icon: 'mdi:chart-areaspline' icon: 'mdi:chart-areaspline'
} }
}, },
@@ -40,6 +43,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '地图', title: '地图',
i18nTitle: 'message.routes.plugin.map',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:map' icon: 'mdi:map'
} }
@@ -50,6 +54,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '视频', title: '视频',
i18nTitle: 'message.routes.plugin.video',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:video' icon: 'mdi:video'
} }
@@ -65,6 +70,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '富文本编辑器', title: '富文本编辑器',
i18nTitle: 'message.routes.plugin.editor.quill',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:file-document-edit-outline' icon: 'mdi:file-document-edit-outline'
} }
@@ -75,6 +81,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'markdown编辑器', title: 'markdown编辑器',
i18nTitle: 'message.routes.plugin.editor.markdown',
requiresAuth: true, requiresAuth: true,
icon: 'ri:markdown-line' icon: 'ri:markdown-line'
} }
@@ -82,6 +89,7 @@ const plugin: AuthRoute.Route = {
], ],
meta: { meta: {
title: '编辑器', title: '编辑器',
i18nTitle: 'message.routes.plugin.editor._value',
icon: 'icon-park-outline:editor' icon: 'icon-park-outline:editor'
} }
}, },
@@ -91,6 +99,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: 'Swiper插件', title: 'Swiper插件',
i18nTitle: 'message.routes.plugin.swiper',
requiresAuth: true, requiresAuth: true,
icon: 'simple-icons:swiper' icon: 'simple-icons:swiper'
} }
@@ -101,6 +110,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '剪贴板', title: '剪贴板',
i18nTitle: 'message.routes.plugin.copy',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:clipboard-outline' icon: 'mdi:clipboard-outline'
} }
@@ -111,6 +121,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '图标', title: '图标',
i18nTitle: 'message.routes.plugin.icon',
requiresAuth: true, requiresAuth: true,
localIcon: 'custom-icon' localIcon: 'custom-icon'
} }
@@ -121,6 +132,7 @@ const plugin: AuthRoute.Route = {
component: 'self', component: 'self',
meta: { meta: {
title: '打印', title: '打印',
i18nTitle: 'message.routes.plugin.print',
requiresAuth: true, requiresAuth: true,
icon: 'mdi:printer' icon: 'mdi:printer'
} }
@@ -128,6 +140,7 @@ const plugin: AuthRoute.Route = {
], ],
meta: { meta: {
title: '插件示例', title: '插件示例',
i18nTitle: 'message.routes.plugin._value',
icon: 'clarity:plugin-line', icon: 'clarity:plugin-line',
order: 4 order: 4
} }

View File

@@ -1,5 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'; import type { AxiosResponse, AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
import { REFRESH_TOKEN_CODE } from '@/config'; import { REFRESH_TOKEN_CODE } from '@/config';
import { import {
localStg, localStg,
@@ -59,7 +59,7 @@ export default class CustomAxiosInstance {
} }
); );
this.instance.interceptors.response.use( this.instance.interceptors.response.use(
async response => { (async response => {
const { status } = response; const { status } = response;
if (status === 200 || status < 300 || status === 304) { if (status === 200 || status < 300 || status === 304) {
const backend = response.data; const backend = response.data;
@@ -82,7 +82,7 @@ export default class CustomAxiosInstance {
} }
const error = handleResponseError(response); const error = handleResponseError(response);
return handleServiceResult(error, null); return handleServiceResult(error, null);
}, }) as (response: AxiosResponse<any, any>) => Promise<AxiosResponse<any, any>>,
(axiosError: AxiosError) => { (axiosError: AxiosError) => {
const error = handleAxiosError(axiosError); const error = handleAxiosError(axiosError);
return handleServiceResult(error, null); return handleServiceResult(error, null);

View File

@@ -120,9 +120,11 @@
] ]
}, },
"footer": { "footer": {
"visible": true,
"fixed": false, "fixed": false,
"right": true,
"height": 48, "height": 48,
"visible": true "inverted": false
}, },
"page": { "page": {
"animate": true, "animate": true,

View File

@@ -83,9 +83,11 @@ const defaultThemeSetting: Theme.Setting = {
horizontalPositionList: themeHorizontalMenuPositionOptions horizontalPositionList: themeHorizontalMenuPositionOptions
}, },
footer: { footer: {
visible: true,
fixed: false, fixed: false,
right: true,
height: 48, height: 48,
visible: true inverted: false
}, },
page: { page: {
animate: true, animate: true,

View File

@@ -1,6 +1,6 @@
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { SCROLL_EL_ID } from '@soybeanjs/vue-materials'; import { LAYOUT_SCROLL_EL_ID } from '@soybeanjs/vue-materials';
interface AppState { interface AppState {
/** 滚动元素的id */ /** 滚动元素的id */
@@ -21,7 +21,7 @@ interface AppState {
export const useAppStore = defineStore('app-store', { export const useAppStore = defineStore('app-store', {
state: (): AppState => ({ state: (): AppState => ({
scrollElId: SCROLL_EL_ID, scrollElId: LAYOUT_SCROLL_EL_ID,
contentFull: false, contentFull: false,
disableMainXScroll: false, disableMainXScroll: false,
reloadFlag: true, reloadFlag: true,

View File

@@ -107,6 +107,7 @@ export const useRouteStore = defineStore('route-store', {
}, },
/** 初始化动态路由 */ /** 初始化动态路由 */
async initDynamicRoute() { async initDynamicRoute() {
const { resetAuthStore } = useAuthStore();
const { initHomeTab } = useTabStore(); const { initHomeTab } = useTabStore();
const { userId } = localStg.get('userInfo') || {}; const { userId } = localStg.get('userInfo') || {};
@@ -125,6 +126,8 @@ export const useRouteStore = defineStore('route-store', {
initHomeTab(data.home, router); initHomeTab(data.home, router);
this.isInitAuthRoute = true; this.isInitAuthRoute = true;
} else {
resetAuthStore();
} }
}, },
/** 初始化静态路由 */ /** 初始化静态路由 */

View File

@@ -7,7 +7,6 @@ import { localStg } from '@/utils';
*/ */
export function getTabRouteByVueRoute(route: RouteRecordNormalized | RouteLocationNormalizedLoaded) { export function getTabRouteByVueRoute(route: RouteRecordNormalized | RouteLocationNormalizedLoaded) {
const fullPath = hasFullPath(route) ? route.fullPath : route.path; const fullPath = hasFullPath(route) ? route.fullPath : route.path;
const tabRoute: App.GlobalTabRoute = { const tabRoute: App.GlobalTabRoute = {
name: route.name, name: route.name,
fullPath, fullPath,

View File

@@ -145,17 +145,25 @@ export const useThemeStore = defineStore('theme-store', {
setHorizontalMenuPosition(position: UnionKey.ThemeHorizontalMenuPosition) { setHorizontalMenuPosition(position: UnionKey.ThemeHorizontalMenuPosition) {
this.menu.horizontalPosition = position; this.menu.horizontalPosition = position;
}, },
/** 设置底部是否显示 */
setFooterVisible(isVisible: boolean) {
this.footer.visible = isVisible;
},
/** 设置底部是否固定 */ /** 设置底部是否固定 */
setFooterIsFixed(isFixed: boolean) { setFooterIsFixed(isFixed: boolean) {
this.footer.fixed = isFixed; this.footer.fixed = isFixed;
}, },
/** 设置底部是否固定 */
setFooterIsRight(right: boolean) {
this.footer.right = right;
},
/** 设置底部高度 */ /** 设置底部高度 */
setFooterHeight(height: number) { setFooterHeight(height: number) {
this.footer.height = height; this.footer.height = height;
}, },
/** 设置底部是否显示 */ /** 设置底部高度 */
setFooterVisible(isVisible: boolean) { setFooterInverted(inverted: boolean) {
this.footer.visible = isVisible; this.footer.inverted = inverted;
}, },
/** 设置切换页面时是否过渡动画 */ /** 设置切换页面时是否过渡动画 */
setPageIsAnimate(animate: boolean) { setPageIsAnimate(animate: boolean) {

View File

@@ -1,6 +1,5 @@
@import "./transition.css"; @import "./transition.css";
@import "./reset.css"; @import "./reset.css";
@import "./scrollbar.css";
html, html,
body, body,

View File

@@ -1,52 +0,0 @@
html {
scrollbar-width: thin;
scrollbar-color: #e1e1e1 transparent;
}
/*---滚动条默认显示样式--*/
html::-webkit-scrollbar-thumb {
background-color: #e1e1e1;
border-radius: 8px;
}
/*---鼠标点击滚动条显示样式--*/
html::-webkit-scrollbar-thumb:hover {
background-color: #e1e1e1;
border-radius: 8px;
}
/*---滚动条大小--*/
html::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/*---滚动框背景样式--*/
html::-webkit-scrollbar-track-piece {
background-color: rgba(0, 0, 0, 0);
border-radius: 0;
}
html.dark {
scrollbar-width: thin;
scrollbar-color: #555 transparent;
}
/*---滚动条默认显示样式--*/
html.dark::-webkit-scrollbar-thumb {
background-color: #555;
border-radius: 8px;
}
/*---鼠标点击滚动条显示样式--*/
html.dark::-webkit-scrollbar-thumb:hover {
background-color: #555;
border-radius: 8px;
}
/*---滚动条大小--*/
html.dark::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/*---滚动框背景样式--*/
html.dark::-webkit-scrollbar-track-piece {
background-color: rgba(0, 0, 0, 0);
border-radius: 0;
}

View File

@@ -1,4 +1,7 @@
@mixin scrollbar($size: 8px, $color: #d9d9d9) { @mixin scrollbar($size: 8px, $color: #d9d9d9) {
scrollbar-width: thin;
scrollbar-color: $color transparent;
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: $color; background-color: $color;
border-radius: $size; border-radius: $size;

View File

@@ -59,8 +59,15 @@ interface ImportMetaEnv {
readonly VITE_COMPRESS_TYPE?: 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw'; readonly VITE_COMPRESS_TYPE?: 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw';
/** 是否应用pwa */ /** 是否应用pwa */
readonly VITE_PWA?: 'Y' | 'N'; readonly VITE_PWA?: 'Y' | 'N';
/**
* 是否开启生产模式下的mock
* @description 生产模式下会拦截XHR导致无法获取response不使用mock请求时设置为N
*/
readonly VITE_PROD_MOCK?: 'Y' | 'N';
/** hash路由模式 */ /** hash路由模式 */
readonly VITE_HASH_ROUTE?: 'Y' | 'N'; readonly VITE_HASH_ROUTE?: 'Y' | 'N';
/** 是否应用自动生成路由的插件 */
readonly VITE_SOYBEAN_ROUTE_PLUGIN?: 'Y' | 'N';
/** 是否是部署的vercel */ /** 是否是部署的vercel */
readonly VITE_VERCEL?: 'Y' | 'N'; readonly VITE_VERCEL?: 'Y' | 'N';
} }

View File

@@ -31,6 +31,8 @@ declare namespace AuthRoute {
interface RouteMeta<K extends AuthRoute.RoutePath> { interface RouteMeta<K extends AuthRoute.RoutePath> {
/** 路由标题(可用来作document.title或者菜单的名称) */ /** 路由标题(可用来作document.title或者菜单的名称) */
title: string; title: string;
/** 用来支持多国语言 如果i18nTitle和title同时存在优先使用i18nTitle */
i18nTitle?: string;
/** 路由的动态路径(需要动态路径的页面需要将path添加进范型参数) */ /** 路由的动态路径(需要动态路径的页面需要将path添加进范型参数) */
dynamicPath?: AuthRouteUtils.GetDynamicPath<K>; dynamicPath?: AuthRouteUtils.GetDynamicPath<K>;
/** 作为单级路由的父级路由布局组件 */ /** 作为单级路由的父级路由布局组件 */

View File

@@ -18,5 +18,7 @@ declare namespace StorageInterface {
themeSettings: Theme.Setting; themeSettings: Theme.Setting;
/** 多页签路由信息 */ /** 多页签路由信息 */
multiTabRoutes: App.GlobalTabRoute[]; multiTabRoutes: App.GlobalTabRoute[];
/** 本地语言缓存 */
lang: I18nType.langType;
} }
} }

View File

@@ -200,12 +200,16 @@ declare namespace Theme {
/** 底部样式 */ /** 底部样式 */
interface Footer { interface Footer {
/** 是否固定底部 */
fixed: boolean;
/** 底部高度 */
height: number;
/* 底部是否可见 */ /* 底部是否可见 */
visible: boolean; visible: boolean;
/** 是否固定底部 */
fixed: boolean;
/** 底部是否居右(顶部混合菜单模式有效) */
right: boolean;
/** 底部高度 */
height: number;
/** 底部反转色 */
inverted: boolean;
} }
/** 页面样式 */ /** 页面样式 */
@@ -238,16 +242,19 @@ declare namespace App {
routePath: string; routePath: string;
icon?: () => import('vue').VNodeChild; icon?: () => import('vue').VNodeChild;
children?: GlobalMenuOption[]; children?: GlobalMenuOption[];
i18nTitle?: string;
}; };
/** 面包屑 */ /** 面包屑 */
type GlobalBreadcrumb = import('naive-ui').DropdownOption & { type GlobalBreadcrumb = Omit<import('naive-ui').DropdownOption, 'icon'> & {
key: string; key: string;
label: string; label: string;
disabled: boolean; disabled: boolean;
routeName: string; routeName: string;
hasChildren: boolean; hasChildren: boolean;
children?: GlobalBreadcrumb[]; icon?: import('vue').Component;
i18nTitle?: string;
options?: (import('naive-ui/es/dropdown/src/interface').DropdownMixedOption & { i18nTitle?: string })[];
}; };
/** 多页签Tab的路由 */ /** 多页签Tab的路由 */
@@ -295,19 +302,85 @@ declare namespace App {
} }
declare namespace I18nType { declare namespace I18nType {
type langType = 'en' | 'zh-CN' | 'km-KH';
interface Schema { interface Schema {
system: { system: {
title: string; title: string;
}; };
routes: { routes: {
dashboard: { dashboard: {
dashboard: string; _value: string;
analysis: string; analysis: string;
workbench: string; workbench: string;
}; };
about: { document: {
about: string; _value: string;
vue: string;
vite: string;
naive: string;
project: string;
'project-link': string;
}; };
component: {
_value: string;
button: string;
card: string;
table: string;
};
plugin: {
_value: string;
charts: {
_value: string;
antv: string;
echarts: string;
};
copy: string;
editor: {
_value: string;
markdown: string;
quill: string;
};
icon: string;
map: string;
print: string;
swiper: string;
video: string;
};
'auth-demo': {
_value: string;
permission: string;
super: string;
};
function: {
_value: string;
tab: string;
};
exception: {
_value: string;
403: string;
404: string;
500: string;
};
'multi-menu': {
_value: string;
first: {
_value: string;
second: string;
'second-new': {
_value: string;
third: string;
};
};
};
management: {
_value: string;
auth: string;
role: string;
route: string;
user: string;
};
about: string;
}; };
} }
} }

View File

@@ -59,15 +59,16 @@ function transformBreadcrumbMenuToBreadcrumb(menu: App.GlobalMenuOption, rootPat
label: menu.label as string, label: menu.label as string,
routeName: menu.routeName, routeName: menu.routeName,
disabled: menu.routePath === rootPath, disabled: menu.routePath === rootPath,
hasChildren hasChildren,
i18nTitle: menu.i18nTitle
}; };
if (menu.icon) { if (menu.icon) {
breadcrumb.icon = menu.icon; breadcrumb.icon = menu.icon;
} }
if (hasChildren) { if (hasChildren) {
breadcrumb.children = menu.children?.map(item => breadcrumb.options = menu.children?.map(item =>
transformBreadcrumbMenuToBreadcrumb(item as App.GlobalMenuOption, rootPath) transformBreadcrumbMenuToBreadcrumb(item as App.GlobalMenuOption, rootPath)
); ) as NonNullable<App.GlobalBreadcrumb['options']>;
} }
return breadcrumb; return breadcrumb;
} }

View File

@@ -1,4 +1,5 @@
import { useIconRender } from '@/composables'; import { useIconRender } from '@/composables';
import { t } from '@/locales';
/** /**
* 将权限路由转换成菜单 * 将权限路由转换成菜单
@@ -18,7 +19,8 @@ export function transformAuthRouteToMenu(routes: AuthRoute.Route[]): App.GlobalM
key: routeName, key: routeName,
label: meta.title, label: meta.title,
routeName, routeName,
routePath: path routePath: path,
i18nTitle: meta.i18nTitle
}, },
icon: meta.icon, icon: meta.icon,
localIcon: meta.localIcon, localIcon: meta.localIcon,
@@ -33,6 +35,28 @@ export function transformAuthRouteToMenu(routes: AuthRoute.Route[]): App.GlobalM
return globalMenu; return globalMenu;
} }
/**
* 翻译菜单
* @param menus
* @returns
*/
export function translateMenuLabel(menus: App.GlobalMenuOption[]): App.GlobalMenuOption[] {
const globalMenu: App.GlobalMenuOption[] = [];
menus.forEach(menu => {
let menuChildren: App.GlobalMenuOption[] | undefined;
if (menu.children && menu.children.length > 0) {
menuChildren = translateMenuLabel(menu.children);
}
const menuItem: App.GlobalMenuOption = {
...menu,
children: menuChildren,
label: menu.i18nTitle ? t(menu.i18nTitle) : menu.label
};
globalMenu.push(menuItem);
});
return globalMenu;
}
/** /**
* 获取当前路由所在菜单数据的paths * 获取当前路由所在菜单数据的paths
* @param activeKey - 当前路由的key * @param activeKey - 当前路由的key

View File

@@ -1,6 +1,6 @@
<template> <template>
<n-space :vertical="true"> <n-space :vertical="true">
<n-divider class="!mb-0 text-14px text-[#666]">其他账户登录</n-divider> <n-divider class="!mb-0 text-14px text-#666">其他账户登录</n-divider>
<n-space justify="center"> <n-space justify="center">
<n-button <n-button
v-for="item in accounts" v-for="item in accounts"

View File

@@ -1,9 +1,9 @@
<template> <template>
<n-space :vertical="true"> <n-space :vertical="true">
<n-divider class="!mb-0 text-14px text-[#666]">其他登录方式</n-divider> <n-divider class="!mb-0 text-14px text-#666">其他登录方式</n-divider>
<div class="flex-center"> <div class="flex-center">
<n-button :text="true"> <n-button :text="true">
<icon-mdi-wechat class="text-22px text-[#888] hover:text-[#52BF5E]" /> <icon-mdi-wechat class="text-22px text-#888 hover:text-#52BF5E" />
</n-button> </n-button>
</div> </div>
</n-space> </n-space>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="h-full"> <div class="h-full">
<n-card title="当前页面只有super才能看到" class="h-full shadow-sm rounded-16px"> </n-card> <n-card title="当前页面只有super才能看到" class="h-full shadow-sm rounded-16px"></n-card>
</div> </div>
</template> </template>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div> <div class="h-full overflow-hidden">
<n-card title="表格" class="h-full shadow-sm rounded-16px"> <n-card title="表格" class="h-full shadow-sm rounded-16px">
<n-space :vertical="true"> <n-space :vertical="true">
<n-space> <n-space>

View File

@@ -1,14 +1,14 @@
<template> <template>
<n-grid :x-gap="16" :y-gap="16" :item-responsive="true"> <n-grid :x-gap="16" :y-gap="16" :item-responsive="true">
<n-grid-item span="0:24 640:24 1024:8"> <n-grid-item span="0:24 640:24 1024:8">
<n-card title="时间线" :bordered="false" class="rounded-16px shadow-sm"> <n-card title="时间线" :bordered="false" class="h-full rounded-16px shadow-sm">
<n-timeline> <n-timeline>
<n-timeline-item v-for="item in timelines" :key="item.type" v-bind="item" /> <n-timeline-item v-for="item in timelines" :key="item.type" v-bind="item" />
</n-timeline> </n-timeline>
</n-card> </n-card>
</n-grid-item> </n-grid-item>
<n-grid-item span="0:24 640:24 1024:16"> <n-grid-item span="0:24 640:24 1024:16">
<n-card title="表格" :bordered="false" class="rounded-16px shadow-sm"> <n-card title="表格" :bordered="false" class="h-full rounded-16px shadow-sm">
<n-data-table size="small" :columns="columns" :data="tableData" /> <n-data-table size="small" :columns="columns" :data="tableData" />
</n-card> </n-card>
</n-grid-item> </n-grid-item>

View File

@@ -4,15 +4,15 @@
<n-card :bordered="false" class="rounded-16px shadow-sm"> <n-card :bordered="false" class="rounded-16px shadow-sm">
<div class="w-full h-360px py-12px"> <div class="w-full h-360px py-12px">
<h3 class="text-16px font-bold">Dashboard</h3> <h3 class="text-16px font-bold">Dashboard</h3>
<p class="text-[#aaa]">Overview Of Lasted Month</p> <p class="text-#aaa">Overview Of Lasted Month</p>
<h3 class="pt-32px text-24px font-bold"> <h3 class="pt-32px text-24px font-bold">
<count-to prefix="$" :start-value="0" :end-value="7754" /> <count-to prefix="$" :start-value="0" :end-value="7754" />
</h3> </h3>
<p class="text-[#aaa]">Current Month Earnings</p> <p class="text-#aaa">Current Month Earnings</p>
<h3 class="pt-32px text-24px font-bold"> <h3 class="pt-32px text-24px font-bold">
<count-to :start-value="0" :end-value="1234" /> <count-to :start-value="0" :end-value="1234" />
</h3> </h3>
<p class="text-[#aaa]">Current Month Sales</p> <p class="text-#aaa">Current Month Sales</p>
<n-button class="mt-24px whitespace-pre-wrap" type="primary">Last Month Summary</n-button> <n-button class="mt-24px whitespace-pre-wrap" type="primary">Last Month Summary</n-button>
</div> </div>
</n-card> </n-card>

View File

@@ -5,7 +5,7 @@
<icon-local-avatar class="text-70px" /> <icon-local-avatar class="text-70px" />
<div class="pl-12px"> <div class="pl-12px">
<h3 class="text-18px font-semibold">早安{{ auth.userInfo.userName }}, 今天又是充满活力的一天</h3> <h3 class="text-18px font-semibold">早安{{ auth.userInfo.userName }}, 今天又是充满活力的一天</h3>
<p class="leading-30px text-[#999]">今日多云转晴20 - 25</p> <p class="leading-30px text-#999">今日多云转晴20 - 25</p>
</div> </div>
</div> </div>
<n-space :size="24" :wrap="false"> <n-space :size="24" :wrap="false">

View File

@@ -1,6 +1,6 @@
<template> <template>
<div <div
class="flex-col-center h-120px p-12px border-1px border-[#efeff5] dark:border-[#ffffff17] rounded-4px hover:shadow-sm cursor-pointer" class="flex-col-center h-120px p-12px border-1px border-#efeff5 dark:border-#ffffff17 rounded-4px hover:shadow-sm cursor-pointer"
> >
<svg-icon :icon="icon" :style="{ color: iconColor }" class="text-30px" /> <svg-icon :icon="icon" :style="{ color: iconColor }" class="text-30px" />
<p class="py-8px text-16px">{{ label }}</p> <p class="py-8px text-16px">{{ label }}</p>

View File

@@ -1,13 +1,13 @@
<template> <template>
<div <div
class="h-120px p-4px border-1px border-[#efeff5] dark:border-[#ffffff17] rounded-4px hover:shadow-sm cursor-pointer" class="h-120px p-4px border-1px border-#efeff5 dark:border-#ffffff17 rounded-4px hover:shadow-sm cursor-pointer"
@click="handleOpenSite" @click="handleOpenSite"
> >
<header class="flex-y-center"> <header class="flex-y-center">
<svg-icon :icon="icon" :style="{ color: iconColor }" class="text-30px" /> <svg-icon :icon="icon" :style="{ color: iconColor }" class="text-30px" />
<h3 class="pl-12px text-18px font-semibold">{{ name }}</h3> <h3 class="pl-12px text-18px font-semibold">{{ name }}</h3>
</header> </header>
<p class="py-8px h-56px text-[#999]">{{ description }}</p> <p class="py-8px h-56px text-#999">{{ description }}</p>
<div class="flex justify-end"> <div class="flex justify-end">
<span>{{ author }}</span> <span>{{ author }}</span>
</div> </div>

View File

@@ -1,31 +1,33 @@
<template> <template>
<n-card title="用户管理" :bordered="false" class="rounded-16px shadow-sm"> <div class="h-full overflow-hidden">
<n-space class="pb-12px" justify="space-between"> <n-card title="用户管理" :bordered="false" class="rounded-16px shadow-sm">
<n-space> <n-space class="pb-12px" justify="space-between">
<n-button type="primary" @click="handleAddTable"> <n-space>
<icon-ic-round-plus class="mr-4px text-20px" /> <n-button type="primary" @click="handleAddTable">
新增 <icon-ic-round-plus class="mr-4px text-20px" />
</n-button> 新增
<n-button type="error"> </n-button>
<icon-ic-round-delete class="mr-4px text-20px" /> <n-button type="error">
删除 <icon-ic-round-delete class="mr-4px text-20px" />
</n-button> 删除
<n-button type="success"> </n-button>
<icon-uil:export class="mr-4px text-20px" /> <n-button type="success">
导出Excel <icon-uil:export class="mr-4px text-20px" />
</n-button> 导出Excel
</n-button>
</n-space>
<n-space align="center" :size="18">
<n-button size="small" type="primary" @click="getTableData">
<icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" />
刷新表格
</n-button>
<column-setting v-model:columns="columns" />
</n-space>
</n-space> </n-space>
<n-space align="center" :size="18"> <n-data-table :columns="columns" :data="tableData" :loading="loading" :pagination="pagination" />
<n-button size="small" type="primary" @click="getTableData"> <table-action-modal v-model:visible="visible" :type="modalType" :edit-data="editData" />
<icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" /> </n-card>
刷新表格 </div>
</n-button>
<column-setting v-model:columns="columns" />
</n-space>
</n-space>
<n-data-table :columns="columns" :data="tableData" :loading="loading" :pagination="pagination" />
<table-action-modal v-model:visible="visible" :type="modalType" :edit-data="editData" />
</n-card>
</template> </template>
<script setup lang="tsx"> <script setup lang="tsx">

View File

@@ -11,7 +11,7 @@
<h3 class="py-24px text-24px font-bold">{{ item.label }}</h3> <h3 class="py-24px text-24px font-bold">{{ item.label }}</h3>
<swiper v-bind="item.options"> <swiper v-bind="item.options">
<swiper-slide v-for="i in 5" :key="i"> <swiper-slide v-for="i in 5" :key="i">
<div class="flex-center h-240px border-1px border-[#999] text-18px font-bold">Slide{{ i }}</div> <div class="flex-center h-240px border-1px border-#999 text-18px font-bold">Slide{{ i }}</div>
</swiper-slide> </swiper-slide>
</swiper> </swiper>
</div> </div>

View File

@@ -9,6 +9,7 @@
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"jsx": "preserve", "jsx": "preserve",
"moduleResolution": "node", "moduleResolution": "node",
"isolatedModules": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"strictNullChecks": true, "strictNullChecks": true,
@@ -17,7 +18,7 @@
"~/*": ["./*"], "~/*": ["./*"],
"@/*": ["./src/*"] "@/*": ["./src/*"]
}, },
"types": ["vite/client", "node", "unplugin-icons/types/vue", "naive-ui/volar", "unplugin-vue-macros/macros-global"] "types": ["vite/client", "node", "unplugin-icons/types/vue", "naive-ui/volar"]
}, },
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist"]
} }

View File

@@ -3,7 +3,11 @@ import presetUno from '@unocss/preset-uno';
import transformerDirectives from '@unocss/transformer-directives'; import transformerDirectives from '@unocss/transformer-directives';
export default defineConfig({ export default defineConfig({
exclude: ['node_modules', 'dist', '.git', '.husky', '.vscode', 'public', 'build', 'mock', './stats.html'], content: {
pipeline: {
exclude: ['node_modules', 'dist', '.git', '.husky', '.vscode', 'public', 'build', 'mock', './stats.html']
}
},
presets: [presetUno({ dark: 'class' })], presets: [presetUno({ dark: 'class' })],
transformers: [transformerDirectives()], transformers: [transformerDirectives()],
shortcuts: { shortcuts: {