Compare commits

..

283 Commits

Author SHA1 Message Date
Soybean
cc00c8f03a chore(other): release v0.9.7 2022-11-08 01:26:24 +08:00
Soybean
c7b6a3fbec feat(projects): new router system [新的路由系统] 2022-11-08 01:23:41 +08:00
Soybean
40c1e13b50 build(projects): add vite plugin @soybeanjs/router-page 2022-11-07 18:47:44 +08:00
Soybean
288d586dbc build(projects): new router branch 2022-11-07 00:47:08 +08:00
Soybean
7d69992694 build(projects): update deps and update config 2022-11-07 00:45:48 +08:00
Soybean
6c14bfe6a9 build(projects): move tauri to branch tauri 2022-10-31 19:11:36 +08:00
Soybean
6773659e89 build(projects): remove useless file: commitlint.config.js 2022-10-31 19:09:13 +08:00
Soybean
9455ad9a4f build(projects): use pnpm patch replace @milahu/patch-package 2022-10-31 16:56:29 +08:00
Soybean
428d41b485 build(projects): use @soybeanjs/cli replace commitizen 2022-10-31 00:29:52 +08:00
Soybean
74772a1f03 build(deps): update deps 2022-10-31 00:21:23 +08:00
Soybean
1f3e6e4fac build(deps): update deps 2022-10-24 19:39:13 +08:00
Soybean
41b3bcb445 build(deps): update deps 2022-10-23 23:02:53 +08:00
Soybean
8e801dd790 build(deps): update deps 2022-10-19 17:02:54 +08:00
Soybean
d6b1530720 build(deps): update deps 2022-10-15 16:44:50 +08:00
Soybean
b632b7ffed feat(projects): import i18n [引入i18n] 2022-10-12 01:03:14 +08:00
Soybean
1b45b71f20 build(projects): add tauri scripts, change tauri icon, fix mockjs [添加tauri相关的命令,变更tauri图标,修复mockjs] 2022-10-11 23:20:31 +08:00
Soybean
149d22a4a4 fix(deps): decrease @types/node version to fix TS type error [降低@types/node版本修复TS的类型错误] 2022-10-11 22:39:37 +08:00
Soybean
83a2e01070 Merge pull request #140 from better-rs/dev/tauri-support
使用 rust + tauri 支持打包成 Windows/Mac/Linux 应用
2022-10-11 15:37:45 +08:00
Henry.Huang
11d615f807 update: change tauri window size 2022-10-11 15:23:01 +08:00
Henry.Huang
853745587d update: tauri support 2022-10-11 15:18:49 +08:00
Henry.Huang
f29108aa14 update: add tauri cli 2022-10-11 15:18:11 +08:00
Soybean
abd02d1990 build(deps): update deps 2022-10-10 00:37:47 +08:00
Soybean
65ac69ef71 build(deps): update deps 2022-10-03 21:58:37 +08:00
Soybean
8998581b99 build(deps): update deps 2022-10-01 03:31:52 +08:00
Soybean
468b4bb0e1 refactor(projects): refactor page: user-management [重构用户管理页面] 2022-09-29 02:02:28 +08:00
Soybean
88e535f63c build(deps): update deps 2022-09-28 21:35:41 +08:00
Soybean
13d0c4153a build(projects): add constant page content 2022-09-28 09:35:38 +08:00
Soybean
331b14e74d build(deps): update deps [升级依赖]
ISSUES CLOSED: #133
2022-09-27 15:55:00 +08:00
Soybean
c29b887eb2 refactor(projects): cancel autoinstall @iconify-json [取消@iconify-json自动安装] 2022-09-24 17:22:08 +08:00
Soybean
8a1ec938e7 fix(projects): add iconify json 2022-09-24 16:19:38 +08:00
Soybean
c045e3fe4e build(deps): unplugin-icon autoinstall @iconify-json [unplugin-icon自动安装@iconify-json] 2022-09-23 12:42:06 +08:00
Soybean
811f820644 feat(projects): refactor icon system, unify icon usage [重构图标系统,统一图标用法] 2022-09-23 03:18:53 +08:00
Soybean
fe8cab3d1c build(deps): update deps 2022-09-22 23:31:01 +08:00
Soybean
78efd7793a feat(projects): add constant route page without login status[添加未登录可访问的固定路由示例页面] 2022-09-21 18:45:28 +08:00
Soybean
82c4b09b94 feat(projects): add pinia setup syntax example: setup-store[添加setup syntax的pinia示例setup-store] 2022-09-21 18:17:33 +08:00
Soybean
a539112a0f feat(projects): support constant route without login status[支持未登录状态下访问自定义的固定路由] 2022-09-21 15:30:35 +08:00
Soybean
22c05674f8 build(projects): update deps, update logos 2022-09-20 12:09:15 +08:00
Soybean
7dd7c71d01 build(deps): update deps 2022-09-15 06:37:36 +08:00
Soybean
22c90257de build(deps): unplugin-vue-define-options替换为unplugin-vue-macros 2022-09-15 06:33:48 +08:00
Soybean
3d03d6ddb5 Merge pull request #132 from zqxu1993/main
ci: change docker image name
2022-09-14 12:35:03 +08:00
徐志强
6fbde1eb57 ci: change docker image name 2022-09-14 06:28:14 +02:00
Soybean
0ee16e0228 Merge pull request #130 from zqxu1993/main
ci: add docker build
2022-09-13 21:11:19 +08:00
徐志强
af74046124 ci: add docker build 2022-09-13 14:56:59 +02:00
Soybean
d823ee5684 build(deps): update deps 2022-09-12 23:52:47 +08:00
Soybean
f7ca2782b0 Merge pull request #129 from shy1118999/patch-1
fix:cannot re-render if dom is deleted <Update echarts.ts>
2022-09-09 22:32:15 +08:00
Yan Shaohang
af8c133914 Update echarts.ts
fix:cannot re-render if dom is deleted

If the chart is opened in the pop-up window, opening the chart again will not display properly.
2022-09-09 18:06:30 +08:00
Soybean
21b6fb697e build(deps): update deps 2022-09-05 00:37:45 +08:00
Soybean
3e0cc8c2c1 build(deps): update deps 2022-09-03 01:48:10 +08:00
Soybean
3540b75557 build(projects): 引入@unocss/vite替换unocss,精简体积 2022-08-31 23:29:37 +08:00
Soybean
73ce53a388 build(projects): 升级依赖,修复TS类型 2022-08-31 22:57:53 +08:00
Soybean
f408ea017c build(projects): 升级依赖,降低naive-ui版本修复打包问题 2022-08-29 22:01:40 +08:00
Soybean
c5ba63182e build(deps): update deps 2022-08-29 02:39:46 +08:00
Soybean
07325a4236 build(projects): 更换eslint依赖为eslint-config-soybeanjs-vue 2022-08-28 04:46:44 +08:00
Soybean
7240be8495 build(deps): 升级依赖 2022-08-24 19:22:34 +08:00
Soybean
71a753f323 build(projects): 引入TS高级类型库 2022-08-24 19:21:22 +08:00
Soybean
639c4458be build(projects): 升级依赖、修复T标签右键菜单连续显示问题
ISSUES CLOSED: #125
2022-08-24 00:15:46 +08:00
Soybean
1ad92a2d1b build(deps): update deps 2022-08-22 23:36:15 +08:00
Soybean
49f95c4e45 refactor(projects): 代码优化 2022-08-22 23:34:14 +08:00
Soybean
44ab07779e build(projects): 引入vite-plugin-progress 2022-08-22 12:05:17 +08:00
Soybean
40ecc320a5 build(projects): 更新依赖、调整页面 2022-08-22 12:01:57 +08:00
Soybean
695ec7e50d build(projects): 引入pwa插件,更新配置 2022-08-19 12:32:33 +08:00
Soybean
85901d2d5e Merge pull request #121 from yanbowe/main
feat(projects): 全局搜索菜单及消息通知适配移动端
2022-08-18 19:43:25 +08:00
燕博文
97e2ffddf4 feat(projects): 全局搜索菜单及消息通知适配移动端 2022-08-18 10:02:15 +08:00
Soybean
907cf44cc1 build(projects): update eslint 2022-08-15 18:40:24 +08:00
Soybean
d9324f07b5 build(deps): update deps 2022-08-15 12:23:30 +08:00
Soybean
d7f5bf3373 fix(projects): 修复eslint规则 2022-08-15 12:14:20 +08:00
Soybean
36f06bc899 build(deps): 更新@soybeanjs/eslint-config 2022-08-11 14:37:22 +08:00
Soybean
182dac0d2e build(projects): 去除prettier,已集成进@soybeanjs/eslint-config 2022-08-10 21:49:22 +08:00
Soybean
f4d37cf7f0 refactor(projects): 抽离格式化相关依赖配置 2022-08-10 21:31:59 +08:00
Soybean
16dce9a4ce fix(projects): 修复TS类型问题 2022-08-08 13:37:32 +08:00
Soybean
0f0cd0b759 build(deps): update deps 2022-08-08 01:08:54 +08:00
Soybean
472f93bfc1 feat(projects): 实现用户管理页面 2022-08-07 04:59:05 +08:00
Soybean
77572855c3 fix(projects): 修复构建后mockjs对xhr的影响问题 2022-08-07 00:49:30 +08:00
Soybean
19942625d5 fix(projects): 修复import.meta.env的TS类型 2022-08-03 23:19:25 +08:00
Soybean
dbd676095b fix(projects): 修复图标的TS类型 2022-08-03 22:39:08 +08:00
Soybean
ed9cd6ce39 refactor(projects): 更新搜索弹窗的图标 2022-08-03 22:34:59 +08:00
Soybean
ee434b465a build(projects): 升级依赖、vite配置optimizeDeps 2022-08-03 22:25:04 +08:00
Soybean
2aba58c973 fix(projects): 修复多个后端服务时的本地代理 2022-08-03 22:14:42 +08:00
Soybean
2c56233155 docs(projects): revert docs 2022-07-31 23:18:26 +08:00
Soybean
8d11a6affc feat(projects): 添加请求适配adapter层应用的示例页面 2022-07-30 22:16:42 +08:00
Soybean
f6b61418e5 build(deps): update deps 2022-07-30 05:22:32 +08:00
Soybean
7f9c98ab8d refactor(projects): 请求适配器函数范型重构、优化请求相关的命名 2022-07-28 15:16:37 +08:00
Soybean
02992dc02d feat(projects): useNaiveTable函数:类型部分 2022-07-28 00:34:29 +08:00
Soybean
b32bca4984 build(deps): update deps 2022-07-26 22:39:51 +08:00
Soybean
c37d0ac788 fix(utils): 修复iconifyRender 2022-07-26 20:55:37 +08:00
Soybean
35aeedf320 build(projects): update deps and README.md 2022-07-20 00:41:31 +08:00
Soybean
94ff787053 build(deps): update deps 2022-07-19 00:03:25 +08:00
Soybean
d0823b030b build(deps): update deps 2022-07-17 13:04:57 +08:00
Soybean
2d722db243 Merge pull request #114 from xiaotao2018/main
fix(components): 添加更多主题颜色模态窗的层级覆盖设置按钮
2022-07-16 02:06:34 +08:00
Soybean
6143605297 refactor(projects): 代码优化 2022-07-16 02:04:59 +08:00
xiaotao2018
e2d6554313 perf(components): 添加更多主题颜色设置模态窗的层级,z-index为int
z-index为int类型,修复在小屏幕下,系统设置按钮悬浮至模态窗之上的缺陷,提升用户体验
2022-07-15 23:58:54 +08:00
Soybean
872bb84502 chore(projects): 更新eslint配置 2022-07-15 10:09:47 +08:00
xiaotao2018
ee7eb3ac0d perf(components): 添加更多主题颜色设置模态窗的层级
修复在小屏幕下,系统设置按钮悬浮至模态窗之上的缺陷,提升用户体验
2022-07-15 10:08:21 +08:00
Soybean
dd1132482e build(deps): update deps 2022-07-14 23:34:05 +08:00
Soybean
c33b5ebfef feat(projects): 添加系统管理的页面 2022-07-14 23:32:19 +08:00
Soybean
711a4ae34f build(projects): 升级依赖,添加对json的eslint检测及格式化 2022-07-14 02:16:38 +08:00
Soybean
d9cfeabb47 build(deps): update deps
ISSUES CLOSED: #87,#106,#109,#111
2022-07-12 23:26:23 +08:00
Soybean
296b154be5 feat(projects): 适配移动端,修复Tab关闭图标的bug
ISSUES CLOSED: #87,#106,#109,#111
2022-07-12 01:49:46 +08:00
Soybean
cec0f25c6b build(deps): update deps 2022-07-11 20:53:13 +08:00
Soybean
b18c49e9d2 chore(projects): 更新.cz-config 2022-07-10 16:55:26 +08:00
Soybean
f64bc91ce2 feat(projects): 添加组件名称,调整vue文件里面的类型声明位置 2022-07-10 16:47:56 +08:00
Soybean
b60db89801 refactor(projects): 代码优化 2022-07-10 03:06:02 +08:00
Soybean
da407b6653 build(deps): update deps 2022-07-09 16:13:02 +08:00
Soybean
6a9a362caa build(projects): 代码优化 2022-07-07 23:46:07 +08:00
Soybean
aa2f78a86f refactor(projects): 添加subscribeAppStore 2022-07-07 23:33:52 +08:00
Soybean
a444731e9e feat(projects): 添加provide、inject上下文示例 2022-07-07 23:27:58 +08:00
Soybean
1523c7b075 build(deps): update deps 2022-07-07 21:56:30 +08:00
Soybean
896e6f2eac build(projects): 添加.gitattributes 2022-07-07 21:15:49 +08:00
Soybean
8dcfbb29f9 build(deps): update deps 2022-07-01 00:47:41 +08:00
Soybean
750000ec66 build(deps): update deps 2022-06-30 00:28:04 +08:00
Soybean
a792bb5cb3 fix(projects): 修复tab不显示路由首页的问题 2022-06-28 07:49:26 +08:00
Soybean
973ab14442 build(deps): update deps 2022-06-28 07:35:05 +08:00
Soybean
3fe4e92f4a build(projects): update vscode settings 2022-06-28 07:31:16 +08:00
Soybean
9ce58073dd build(projects): update tsconfig 2022-06-26 00:42:42 +08:00
Soybean
e2727e6fa1 docs(projects): update README.md 2022-06-26 00:30:48 +08:00
Soybean
73fa3d14c5 build(deps): update deps 2022-06-25 01:07:26 +08:00
Soybean
ea1a336535 build(deps): update deps 2022-06-24 00:19:13 +08:00
Soybean
69e39c142e build(deps): update deps 2022-06-20 23:41:58 +08:00
Soybean
718c36263e feat(projects): 添加生产的主题配置缓存 2022-06-20 23:29:58 +08:00
Soybean
5c1b086cb4 build(projects): 代码优化 2022-06-19 15:34:18 +08:00
Soybean
414ccbe360 Merge pull request #105 from yanbowe/main
feat(projects): 增加返回顶部功能
2022-06-17 17:54:31 +08:00
燕博文
41147b34fa refactor(projects): 代码优化 2022-06-17 16:29:06 +08:00
燕博文
894b0f1c18 feat(projects): 增加返回顶部功能 2022-06-17 15:59:56 +08:00
Soybean
d214bb2f2a Merge pull request #104 from yanbowe/main
feat(projects): 增加系统消息组件
2022-06-17 13:48:14 +08:00
燕博文
9518372fe0 feat(projects): 系统消息组件代码优化 2022-06-17 12:49:53 +08:00
燕博文
afa0134fdd feat(projects): 增加系统消息组件 2022-06-17 11:39:38 +08:00
Soybean
c6ed9b1558 Merge pull request #103 from yanbowe/main
feat(tabs): 多页签增加关闭所有
2022-06-16 12:06:28 +08:00
燕博文
0523f08382 fix(svg-icon): 自定义图标在Dropdown组件下hover状态无法显示图标 2022-06-16 11:07:43 +08:00
燕博文
8237adb9c0 feat(tabs): 多页签增加关闭所有 2022-06-16 10:00:23 +08:00
Soybean
65c21812bb chore(release): 0.9.6 2022-06-16 01:18:18 +08:00
Soybean
c3c975ee11 feat(projects): 本地svg动态渲染图标
ISSUES CLOSED: #61
2022-06-16 01:17:31 +08:00
Soybean
833018a831 build(deps): update deps 2022-06-15 23:44:46 +08:00
Soybean
3eb7f6f593 Merge pull request #102 from yanbowe/main
feat(projects): 增加设置当前Tab页签名称功能
2022-06-14 16:54:03 +08:00
燕博文
efcfa576d5 fix(projects): 设置tab标题导致meta属性丢失 2022-06-14 16:09:33 +08:00
燕博文
487213b648 feat(projects): 增加设置当前Tab页签名称功能 2022-06-14 15:42:59 +08:00
Soybean
4ee0d94f1b fix(projects): 修复顶部菜单的位置失效问题 2022-06-11 15:27:19 +08:00
Soybean
5fa822f4d4 refactor(projects): 代码优化 2022-06-11 13:37:52 +08:00
Soybean
8e6e787543 build(projects): update deps, update config 2022-06-11 13:30:25 +08:00
Soybean
9917b5e53c build(deps): update deps 2022-06-10 01:02:50 +08:00
Soybean
8f3e855f41 refactor(projects): 优化菜单支持横向滚动
ISSUES CLOSED: #76
2022-06-10 01:02:50 +08:00
tanminglin
808051b29d feat(projects): 上下结构,菜单支持横向滚动 2022-06-10 01:02:24 +08:00
Soybean
906aed5e75 build(deps): update deps 2022-06-08 00:08:16 +08:00
Soybean
2d64a2e57c feat(projects): 新增Antv G2图表示例 2022-06-07 23:58:47 +08:00
Soybean
0c70a9e083 docs(projects): update README.md 2022-06-07 23:49:02 +08:00
Soybean
08d83ecbea chore(release): 0.9.5 2022-06-07 01:55:57 +08:00
Soybean
4122685803 feat(projects): 支持同一路由根据不同query和hash同时显示不同Tab
ISSUES CLOSED: #64
2022-06-07 01:51:40 +08:00
Soybean
434ab1c560 feat(projects): 动态路由根路由重定向只需取决于后端返回的路由首页
ISSUES CLOSED: \
2022-06-06 22:47:46 +08:00
Soybean
ae99e57c52 docs(projects): update README.md 2022-06-06 18:37:27 +08:00
Soybean
e3c4a6ece6 build(deps): 依赖升级 2022-06-06 12:14:19 +08:00
Soybean
c8717c25b8 build(projects): 配置更改 2022-06-06 12:11:01 +08:00
Soybean
e9656c6e76 docs(projects): update docs 2022-06-04 12:04:44 +08:00
Soybean
fd78791229 build(projects): 配置优化 2022-06-04 11:48:24 +08:00
Soybean
de09f82586 build(projects): 代码优化
ISSUES CLOSED: \
2022-06-02 02:39:26 +08:00
Soybean
c7762490de feat(projects): 补充更多的ECharts示例
ISSUES CLOSED: \
2022-06-01 00:27:28 +08:00
Soybean
4558c24d1c fix(projects): 修复@antv/g2生产环境报错
ISSUES CLOSED: \
2022-05-31 23:02:24 +08:00
Soybean
d9ac7e4de0 refactor(projects): 代码优化
ISSUES CLOSED: \
2022-05-31 00:26:52 +08:00
Soybean
6a5a357f50 build(deps): update deps
ISSUES CLOSED: \
2022-05-30 22:53:44 +08:00
Soybean
44b022aefd feat(projects): 添加antv g2图表示例
ISSUES CLOSED: \
2022-05-30 22:39:44 +08:00
Soybean
0a46ea0844 feat(projects): 添加插件页面:图表
ISSUES CLOSED: \
2022-05-29 23:44:47 +08:00
Soybean
39854a492b feat(projects): 添加百度地图、升级依赖
ISSUES CLOSED: \
2022-05-29 22:39:07 +08:00
Soybean
4c2f535a9b refactor(projects): 代码优化
ISSUES CLOSED: \
2022-05-28 20:26:29 +08:00
Soybean
be45d83766 build(deps): update deps
ISSUES CLOSED: \
2022-05-28 17:06:55 +08:00
Soybean
d28b9039bb refactor(projects): 代码优化
ISSUES CLOSED: \
2022-05-28 13:33:09 +08:00
Soybean
8f6d6ce3cb refactor(styles): 代码格式
ISSUES CLOSED: \
2022-05-28 12:30:17 +08:00
Soybean
07baac7cf8 build(other): update cz config 2022-05-27 09:53:40 +08:00
Soybean
7487ab79b3 chore(deps): update deps
ISSUES CLOSED: \
2022-05-27 00:54:13 +08:00
Soybean
a70e4161be chore(deps): update deps
ISSUES CLOSED: \
2022-05-19 23:51:28 +08:00
Soybean
095c432363 refactor(projects): 代码优化
ISSUES CLOSED: \
2022-05-19 00:15:37 +08:00
Soybean
028096e53f build(deps): update deps
ISSUES CLOSED: \
2022-05-19 00:00:47 +08:00
Soybean
44ab55d594 refactor(projects): 代码优化
ISSUES CLOSED: \
2022-05-18 23:43:41 +08:00
Soybean
4b80a66114 docs(projects): update README.md
ISSUES CLOSED: \
2022-05-18 23:23:04 +08:00
Soybean
cc0bb088ec Merge pull request #91 from yanbowe/main
路由meta新增activeMenu属性
2022-05-17 19:09:05 +08:00
燕博文
3e4f9e2824 fix(route): 当为左侧混合菜单时activeMenu无效情况 2022-05-17 14:06:20 +08:00
燕博文
ebd16a4d1a feat(route): 路由meta新增activeMenu属性 2022-05-17 13:54:48 +08:00
Soybean
84cb07baec docs(projects): update README.md
ISSUES CLOSED: \
2022-05-16 22:17:01 +08:00
Soybean
0811ffa5ae docs(projects): update README.md 2022-05-16 20:09:07 +08:00
Soybean
3f822a7d76 build(deps): update deps
ISSUES CLOSED: \
2022-05-14 00:57:23 +08:00
Soybean
a1c7e10574 refactor(projects): 代码优化 2022-05-11 00:18:36 +08:00
Soybean
50d7ccd82d build(deps): update deps 2022-05-10 23:53:56 +08:00
Soybean
e0233061d3 fix(projects): 修复页面切换时导致的溢出滚动条 2022-05-10 23:22:24 +08:00
Soybean
a0c405dadd build(projects): update config 2022-05-10 22:07:53 +08:00
Soybean
60f912508b fix(projects): 修复权限切换路由数据未更新的问题 2022-05-09 23:53:09 +08:00
Soybean
3590b65e22 refactor(projects): 代码优化 2022-05-09 20:52:43 +08:00
Soybean
92b8406444 build(deps): update deps 2022-05-07 01:01:46 +08:00
Soybean
e7ad08685e feat(projects): 引入echarts替换antvG2plot 2022-05-07 00:58:24 +08:00
Soybean
14c145eef1 refactor(projects): 代码优化 2022-05-05 18:42:29 +08:00
Soybean
518f7eed28 build(deps): update deps 2022-05-05 13:11:16 +08:00
Soybean
21e63998d0 docs(projects): update README.md 2022-05-05 12:50:14 +08:00
Soybean
38ee2a62cd Merge pull request #86 from dxxzst/patch-1
fix(projects): 修复插件不存在的错误提示
2022-05-04 21:14:17 +08:00
Grazing Wind
716528206e fix(projects): 修复插件不存在的错误提示
已经改成小写
2022-05-04 09:35:19 +08:00
Soybean
b81143e55e Merge pull request #84 from tclyjy/main
refactor(layouts): layout/header 反转色样式补充
2022-04-29 20:59:59 +08:00
Eric_Yuan
0243b27505 style(GlobalBreadcrumb): 代码格式fix 2022-04-29 19:19:10 +08:00
Soybean
909c12d3c6 Merge pull request #83 from toolvcn/相思
feat(projects): 添加自动跟随系统主题设置
2022-04-29 17:56:27 +08:00
元家怿
01d0bcbfd0 refactor(layouts): layout/header 反转色样式补充 2022-04-29 15:53:12 +08:00
相思
ba07b695dd feat(projects): 添加自动跟随系统主题设置 2022-04-29 15:02:51 +08:00
Soybean
3d8befa376 docs(projects): update README.md 2022-04-29 02:05:00 +08:00
Soybean
97c92626cc chore(release): 0.9.4 2022-04-29 02:02:52 +08:00
Soybean
55ddc9cab0 refactor(projects): 动态路由权限完善 2022-04-29 02:00:51 +08:00
Soybean
401f0c748d build(projects): 细节调整 2022-04-28 01:02:41 +08:00
Soybean
d5c751153c docs(projects): update README.md 2022-04-28 00:54:40 +08:00
Soybean
69d51318ff refactor(projects): merge branch unocss to main 2022-04-28 00:50:22 +08:00
Soybean
de5fb84215 refactor(projects): layout和tab组件依赖名称变更、样式修复 2022-04-27 22:51:28 +08:00
Soybean
c275f2632c refactor(projects): 细节优化 2022-04-27 22:27:46 +08:00
Soybean
e899914426 fix(projects): 修复样式 2022-04-27 19:31:40 +08:00
元家怿
861c8b9852 feat(layouts): 添加侧边栏/头部的反转模式来增加对比度 2022-04-27 19:15:23 +08:00
Soybean
a782461453 refactor(projects): 代码优化 2022-04-27 19:05:58 +08:00
Soybean
e8488e4d52 fix(projects): 添加.npmrc修复无法获取自动引入的全局组件声明类型 2022-04-27 18:08:39 +08:00
Soybean
889c859865 Merge pull request #82 from tclyjy/main
feat(layouts): 添加侧边栏/头部的反转模式来增加对比度
2022-04-27 16:46:09 +08:00
元家怿
3c8dd772f8 feat(layouts): 添加侧边栏/头部的反转模式来增加对比度 2022-04-27 16:39:20 +08:00
Soybean
251b5b9664 refactor(projects): 代码优化 2022-04-27 07:47:26 +08:00
Soybean
41e46a5d80 refactor(projects): mock权限相关数据优化 2022-04-26 00:12:20 +08:00
Soybean
5c75e9d958 build(deps): update deps 2022-04-24 00:23:45 +08:00
Soybean
7f4350aeb6 feat(projects): mock添加权限过滤 2022-04-23 12:31:06 +08:00
Soybean
807448aec5 feat(projects): 权限完善及权限示例页面 2022-04-23 02:21:02 +08:00
相思
b9c5c34979 feat(projects): HTML lang 修改为 zh-cmn-Hans 2022-04-22 13:35:22 +08:00
Soybean
20347b7d65 Merge pull request #79 from toolvcn/相思
feat(projects): HTML lang 修改为 zh-cmn-Hans
2022-04-22 13:31:11 +08:00
相思
dbeb595c0b feat(projects): HTML lang 修改为 zh-cmn-Hans 2022-04-22 13:00:50 +08:00
Soybean
c9d3e5a3fd feat(projects): 引入unocss替换windicss 2022-04-22 12:29:22 +08:00
Soybean
5e276421ad refactor(projects): 代码优化 2022-04-22 09:07:53 +08:00
Soybean
219f87f467 fix(projects): 添加获取路由组件文件未找到时的错误提示 2022-04-21 09:04:18 +08:00
Soybean
b35ed8960d refactor(projects): 去除在pinia的getters的函数调用副作用,用watch代替 2022-04-21 00:46:03 +08:00
Soybean
24010d05fb feat(projects): 登录页背景图片位置适配移动端 2022-04-21 00:26:21 +08:00
Soybean
ec0776e268 feat(projects): 登录页面适配移动端 2022-04-21 00:15:34 +08:00
Soybean
cecce83bc3 build(deps): update deps 2022-04-18 23:47:38 +08:00
Soybean
4eb46ea3dd chore(deps): update deps 2022-04-14 00:02:19 +08:00
Soybean
e8b534b84e refactor(projects): 代码优化 2022-04-13 23:45:15 +08:00
Soybean
46e1ae7825 fix(projects): 修复获取vite环境变量的方式 2022-04-07 22:48:52 +08:00
Soybean
60a55a776e docs(projects): update README.md 2022-04-06 14:34:52 +08:00
Soybean
bed4292ed3 feat(projects): 添加请求适配器的请求示例 2022-04-04 19:13:15 +08:00
Soybean
6bed9ead38 feat(projects): 插件方式按需引入naiveUI 2022-04-04 17:41:55 +08:00
Soybean
3fb13ca9e7 fix(projects): 修复在新版vite下环境变量获取不到的问题 2022-04-04 17:30:26 +08:00
Soybean
2d6d179d66 fix(projects): 去除从环境文件引入端口号导致的错误 2022-04-03 01:07:25 +08:00
Soybean
eebb753884 Merge pull request #70 from yanbowe/main
fix(projects): 全局搜索弹窗弹出时动画闪屏问题
2022-04-02 14:13:39 +08:00
yanbowen
bb1bbf2724 fix(projects): 全局搜索弹窗弹出时动画闪屏问题 2022-04-02 10:35:21 +08:00
Soybean
df56abe18d style(projects): update prettier config 2022-04-01 14:47:57 +08:00
Soybean
ca2dfa6185 feat(projects): 新增静态路由 2022-03-30 01:30:12 +08:00
Soybean
bbfdcc8276 Merge pull request #67 from Southliu/main
perf: refresh-koken命名
2022-03-24 15:59:00 +08:00
“Southliu”
1715504789 perf: refresh-koken命名 2022-03-24 11:49:07 +08:00
Soybean
9a90f18e77 docs(projects): update README.md 2022-03-23 15:21:09 +08:00
Soybean
21645537d5 docs(projects): update README.md 2022-03-15 01:34:31 +08:00
Soybean
e6c26fcb4a fix(projects): 修复路由守卫的动态路由逻辑 2022-03-14 15:16:28 +08:00
Soybean
20911dd882 refactor(projects): lint命令修改 2022-03-13 19:42:01 +08:00
Soybean
cd7ca8f4c7 fix(projects): 修复vite alias 2022-03-13 18:37:44 +08:00
Soybean
ca707a456b build(projects): vite.config代码优化 2022-03-13 18:14:27 +08:00
Soybean
d0522ce514 chore(release): 0.9.3 2022-03-12 21:22:49 +08:00
Soybean
f83c7b59b8 feat(projects): 新增自定义svg图标动态渲染 2022-03-12 21:22:01 +08:00
Soybean
f5a043b11a feat(projects): 添加全局组件自动引入注册 2022-03-12 19:56:58 +08:00
Soybean
094dca961f feat(projects): 添加网络代理 2022-03-12 19:35:49 +08:00
Soybean
8191490f39 feat(projects): 重构项目的TS类型架构,去除interface文件夹 2022-03-12 17:45:37 +08:00
Soybean
75de2b0604 build(projects): update tsconfig、eslintrc 2022-03-12 16:21:40 +08:00
Soybean
4093dcd6dc Merge pull request #62 from Imgodmaoyouknow/main
docs(other): 注释文案修改
2022-03-10 17:40:52 +08:00
毛博文
d00643c9f5 docs(other): 注释文案修改 2022-03-10 17:07:06 +08:00
Soybean
b8db2116df docs(projects): update README.md 2022-03-06 21:23:00 +08:00
Soybean
a0dfa3d30d docs(projects): update README.md 2022-03-06 03:33:37 +08:00
Soybean
4e31abd446 refactor(projects): 代码优化 2022-03-06 00:00:51 +08:00
Soybean
f42ee9dbe5 build(projects): 更新tsconfig.json 2022-03-05 23:20:00 +08:00
Soybean
f5c56c355c feat(projects): 新增子菜单图标和多页签图标 2022-03-05 05:37:40 +08:00
Soybean
a1a57a185c feat(projects): 引入soybean-admin-tab、去除vite-plugin-svg-icons,用unplugin-icons实现自定义svg的iconify写法、代码优化 2022-03-05 05:00:26 +08:00
Soybean
b298af1ddb build(deps): upgrade deps 2022-03-04 04:20:35 +08:00
Soybean
43d685ccd3 Merge pull request #54 from pany-ang/main
fix(projects): 修复 BASE_URL 没有生效的问题
2022-03-03 16:26:44 +08:00
pany
72d7dcfa5e fix(projects): 修复 BASE_URL 没有生效的问题 2022-03-03 12:01:14 +08:00
Soybean
1e2fdda090 style(components): 代码优化 2022-03-03 00:35:44 +08:00
Soybean
8d00b238f7 build(deps): upgrade deps 2022-03-03 00:11:04 +08:00
Soybean
8cdad54236 docs(projects): update README.md 2022-03-01 12:07:13 +08:00
Soybean
6298e61328 Merge pull request #52 from bundlejs/main
fix(projects): 修复页面切换动画开关不生效
2022-02-28 14:57:29 +08:00
bundle
9d4ed617fb fix(projects): 修复页面切换动画开关不生效 2022-02-28 13:50:52 +08:00
Soybean
f92d7ecfbe Merge pull request #51 from Lsq128/main
feat(components): svgIcon,添加type,调整size方案
2022-02-27 08:45:59 +08:00
Lsq128
ce4e039f48 feat(components): svgIcon,添加type,调整size方案 2022-02-26 23:47:34 +08:00
Soybean
1a9efee591 Merge pull request #48 from Lsq128/main
feat(projects): 添加SvgIcon,配置vite plugin
2022-02-25 21:58:03 +08:00
Liushengqun
378d55ac0e feat(projects): 添加SvgIcon,配置vite plugin 2022-02-25 17:56:00 +08:00
Soybean
50c8b9daa1 build(deps): upgrade deps 2022-02-25 11:06:48 +08:00
Soybean
c4546bdfa3 fix(projects): 修复页面切换动画无变化 2022-02-25 10:57:05 +08:00
Soybean
5b401a79ba docs(projects): update README.md 2022-02-24 17:30:48 +08:00
Soybean
7add5c2edf fix(components): 组件LoadingEmptyWrapper添加背景颜色动画过渡 2022-02-23 21:44:32 +08:00
Soybean
811b15e672 fix(components): 修复组件LoadingEmptyWrapper适应暗黑模式 2022-02-23 21:38:04 +08:00
Soybean
c1182fef0a refactor(components): 去除packages的soybean-layout,通过npm的方式引入 2022-02-23 02:29:10 +08:00
Soybean
7ba332cd6a build(deps): 升级依赖 2022-02-20 22:57:08 +08:00
Soybean
a810ef85b1 feat(projects): 添加naiveUI按需引入 2022-02-17 01:01:17 +08:00
Soybean
225e7128b6 docs(projects): update README.md 2022-02-16 19:28:49 +08:00
Soybean
3aded40461 docs(projects): update README.md 2022-02-16 19:17:21 +08:00
Soybean
57c692be74 build(deps): 升级依赖 2022-02-16 13:14:59 +08:00
Soybean
284af63cfe build(deps): 升级依赖 2022-02-12 23:39:42 +08:00
Soybean
e856cdb7b2 docs(projects): update README.md 2022-02-11 16:55:14 +08:00
398 changed files with 20556 additions and 16488 deletions

View File

@@ -1,45 +0,0 @@
module.exports = {
types: [
{ value: 'feat', name: 'feat: 新增功能' },
{ value: 'fix', name: 'fix: 修复bug' },
{ value: 'docs', name: 'docs: 文档变更' },
{ value: 'style', name: 'style: 代码格式(不影响功能,例如空格、分号等格式修正)' },
{ value: 'refactor', name: 'refactor: 代码重构(不包括 bug 修复、功能新增)' },
{ value: 'perf', name: 'perf: 性能优化' },
{ value: 'test', name: 'test: 添加、修改测试用例' },
{ value: 'build', name: 'build: 构建流程、外部依赖变更(如升级 npm 包、修改 脚手架 配置等)' },
{ value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
{ value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)' },
{ value: 'revert', name: 'revert: 回滚 commit' }
],
scopes: [
['projects', '项目搭建'],
['components', '组件相关'],
['hooks', 'hook 相关'],
['utils', 'utils 相关'],
['types', 'ts类型相关'],
['styles', '样式相关'],
['deps', '项目依赖'],
['auth', '对 auth 修改'],
['other', '其他修改'],
['custom', '以上都不是?我要自定义']
].map(([value, description]) => {
return {
value,
name: `${value.padEnd(30)} (${description})`
}
}),
messages: {
type: '确保本次提交遵循 Angular 规范!\n选择你要提交的类型',
scope: '\n选择一个 scope可选',
customScope: '请输入自定义的 scope',
subject: '填写简短精炼的变更描述:\n',
body: '填写更加详细的变更描述(可选)。使用 "|" 换行:\n',
breaking: '列举非兼容性重大的变更(可选):\n',
footer: '列举出所有变更的 ISSUES CLOSED可选。 例如: #31, #34\n',
confirmCommit: '确认提交?'
},
allowBreakingChanges: ['feat', 'fix'],
subjectLimit: 100,
breaklineChar: '|'
}

View File

@@ -1,12 +1,11 @@
# Editor configuration, see http://editorconfig.org
# 表示是最顶层的 EditorConfig 配置文件
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = tab # 缩进风格tab | space
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*]
charset = utf-8
indent_style = tab
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

15
.env
View File

@@ -1,7 +1,20 @@
BASE_URL=/
VITE_BASE_URL=/
VITE_APP_NAME=SoybeanAdmin
VITE_APP_TITLE=Soybean管理系统
VITE_APP_DESC=SoybeanAdmin是一个中后台管理系统模版
# 权限路由模式: static dynamic
VITE_AUTH_ROUTE_MODE=dynamic
# 路由首页(根路由重定向), 用于static模式的权限路由dynamic模式取决于后端返回的路由首页
VITE_ROUTE_HOME_PATH=/dashboard/analysis
# iconify图标作为组件的前缀
VITE_ICON_PREFFIX=icon
# 本地SVG图标作为组件的前缀, 请注意一定要包含 VITE_ICON_PREFFIX
# 格式 {VITE_ICON_PREFFIX}-{本地图标集合名称}
VITE_ICON_LOCAL_PREFFIX=icon-local

View File

@@ -1,22 +1,36 @@
/** 请求环境配置 */
type ServiceEnv = Record<
Service.HttpEnv,
{
/** 请求环境 */
env: Service.HttpEnv;
/** 请求地址 */
url: string;
}
>;
/** 请求服务的环境配置 */
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>;
/** 请求的环境 */
export const serviceEnv: ServiceEnv = {
/** 不同请求服务的环境配置 */
const serviceEnv: ServiceEnv = {
dev: {
url: 'http://localhost:8080',
urlPattern: '/url-pattern',
secondUrl: 'http://localhost:8081',
secondUrlPattern: '/second-url-pattern'
},
test: {
env: 'test',
url: 'http://120.76.42.91:18888'
url: 'http://localhost:8080',
urlPattern: '/url-pattern',
secondUrl: 'http://localhost:8081',
secondUrlPattern: '/second-url-pattern'
},
prod: {
env: 'prod',
url: 'http://120.76.42.91:18888'
url: 'http://localhost:8080',
urlPattern: '/url-pattern',
secondUrl: 'http://localhost:8081',
secondUrlPattern: '/second-url-pattern'
}
};
/**
* 获取当前环境模式下的请求服务的配置
* @param env 环境
*/
export function getServiceEnvConfig(env: ImportMetaEnv) {
const { VITE_SERVICE_ENV = 'dev' } = env;
const config = serviceEnv[VITE_SERVICE_ENV];
return config;
}

1
.env.development Normal file
View File

@@ -0,0 +1 @@
VITE_HTTP_PROXY=Y

6
.env.production Normal file
View File

@@ -0,0 +1,6 @@
VITE_VISUALIZER=N
VITE_COMPRESS=N
# gzip | brotliCompress | deflate | deflateRaw
VITE_COMPRESS_TYPE=gzip

View File

@@ -1,15 +1,3 @@
*.sh
node_modules
lib
*.md
*.woff
*.ttf
.vscode
.idea
/dist/
/public
/docs
.vscode
.local
!.env-config.ts
package.json
components.d.ts
router-page.d.ts

View File

@@ -1,30 +1,17 @@
module.exports = {
env: {
browser: true,
es2021: true
extends: ['soybeanjs-vue'],
overrides: [
{
files: ['./scripts/*.ts'],
rules: {
'no-unused-expressions': 'off'
}
}
],
settings: {
'import/core-modules': ['uno.css', '~icons/*', 'virtual:svg-icons-register']
},
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly',
PROJECT_BUILD_TIME: 'readonly',
AMap: 'readonly',
BMap: 'readonly',
TMap: 'readonly'
},
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['vue', '@typescript-eslint'],
extends: ['plugin:vue/vue3-recommended', 'airbnb-base', '@vue/typescript/recommended', 'plugin:prettier/recommended'],
rules: {
'import/extensions': 'off',
'import/no-extraneous-dependencies': 'off',
'import/no-unresolved': 0,
'import/order': [
'error',
{
@@ -76,11 +63,6 @@ module.exports = {
group: 'internal',
position: 'before'
},
{
pattern: '@/layouts',
group: 'internal',
position: 'before'
},
{
pattern: '@/views',
group: 'internal',
@@ -96,11 +78,21 @@ module.exports = {
group: 'internal',
position: 'before'
},
{
pattern: '@/service',
group: 'internal',
position: 'before'
},
{
pattern: '@/store',
group: 'internal',
position: 'before'
},
{
pattern: '@/context',
group: 'internal',
position: 'before'
},
{
pattern: '@/composables',
group: 'internal',
@@ -111,11 +103,6 @@ module.exports = {
group: 'internal',
position: 'before'
},
{
pattern: '@/service',
group: 'internal',
position: 'before'
},
{
pattern: '@/utils',
group: 'internal',
@@ -130,33 +117,10 @@ module.exports = {
pattern: '@/**',
group: 'internal',
position: 'before'
},
{
pattern: '@/interface',
group: 'internal',
position: 'before'
}
],
pathGroupsExcludedImportTypes: ['vue', 'vue-router', 'pinia', 'naive-ui']
}
],
'import/prefer-default-export': 0,
'max-classes-per-file': 0,
'no-shadow': 0,
'no-unused-vars': 'off',
'no-use-before-define': 'off',
'vue/comment-directive': 0,
'vue/multi-word-component-names': 0,
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-inferrable-types': 0,
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { ignoreRestSiblings: true, varsIgnorePattern: 'Ignored' }],
'@typescript-eslint/no-use-before-define': ['error', { classes: true, functions: false, typedefs: false }],
'@typescript-eslint/no-var-requires': 'off'
]
}
};

16
.gitattributes vendored Normal file
View File

@@ -0,0 +1,16 @@
"*.vue" eol=lf
"*.js" eol=lf
"*.ts" eol=lf
"*.jsx" eol=lf
"*.tsx" eol=lf
"*.cjs" eol=lf
"*.cts" eol=lf
"*.mjs" eol=lf
"*.mts" eol=lf
"*.json" eol=lf
"*.html" eol=lf
"*.css" eol=lf
"*.less" eol=lf
"*.scss" eol=lf
"*.sass" eol=lf
"*.styl" eol=lf

10
.gitignore vendored
View File

@@ -11,12 +11,17 @@ node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
stats.html
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea
*.suo
*.ntvs*
@@ -24,4 +29,7 @@ dist-ssr
*.sln
*.sw?
stats.html
/src/typings/components.d.ts
/src/typings/router-page.d.ts
package-lock.json
yarn.lock

View File

@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit
pnpm soybean git-commit-verify

4
.npmrc Normal file
View File

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

View File

@@ -1,27 +0,0 @@
module.exports = {
printWidth: 120, // 超过最大值换行
tabWidth: 2, // 缩进字节数
useTabs: false, // 缩进使用tab不使用空格
semi: true, // 句尾添加分号
singleQuote: true, // 使用单引号代替双引号
proseWrap: 'preserve', // 默认值。因为使用了一些折行敏感型的渲染器如GitHub comment而按照markdown文本样式进行折行
arrowParens: 'avoid', // (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid省略括号
bracketSpacing: true, // 在对象,数组括号与文字之间加空格 "{ foo: bar }"
endOfLine: 'auto', // 结尾是 \n \r \n\r auto
eslintIntegration: false, //不让prettier使用eslint的代码格式进行校验
htmlWhitespaceSensitivity: 'ignore', // 指定HTML文件的全局空白区域敏感度 有效选项:"css"- 遵守CSS display属性的默认值。"strict" - 空格被认为是敏感的。"ignore" - 空格被认为是不敏感的。html 中空格也会占位影响布局prettier 格式化的时候可能会将文本换行,造成布局错乱
ignorePath: '.prettierignore', // 不使用prettier格式化的文件填写在项目的.prettierignore文件中
jsxSingleQuote: false, // 在jsx中使用单引号代替双引号
requireConfig: false, // Require a 'prettierconfig' to format prettier
stylelintIntegration: false, //不让prettier使用stylelint的代码格式进行校验
trailingComma: 'none', // 在对象或数组最后一个元素后面是否加逗号在ES5中加尾逗号
tslintIntegration: false, // 不让prettier使用tslint的代码格式进行校验
overrides: [
{
files: '*.html',
options: {
parser: 'html'
}
}
]
};

View File

@@ -1,35 +1,25 @@
{
"recommendations": [
"formulahendry.auto-close-tag",
"formulahendry.auto-complete-tag",
"steoates.autoimport",
"formulahendry.auto-rename-tag",
"coenraads.bracket-pair-colorizer-2",
"naumovs.color-highlight",
"pranaygp.vscode-css-peek",
"mikestead.dotenv",
"editorconfig.editorconfig",
"dsznajder.es7-react-js-snippets",
"dbaeumer.vscode-eslint",
"miguelsolorio.fluent-icons",
"mhutchie.git-graph",
"eamodio.gitlens",
"lokalise.i18n-ally",
"afzalsayed96.icones",
"antfu.iconify",
"kisstkondoros.vscode-gutter-preview",
"xabikos.javascriptsnippets",
"whtouche.vscode-js-console-utils",
"ritwickdey.liveserver",
"yzhang.markdown-all-in-one",
"pkief.material-icon-theme",
"zhuangtongfa.material-theme",
"christian-kohler.path-intellisense",
"esbenp.prettier-vscode",
"johnsoncodehk.volar",
"johnsoncodehk.vscode-typescript-vue-plugin",
"dariofuzinato.vue-peek",
"wscats.vue",
"voorjaar.windicss-intellisense"
]
"recommendations": [
"afzalsayed96.icones",
"antfu.iconify",
"antfu.unocss",
"christian-kohler.path-intellisense",
"dbaeumer.vscode-eslint",
"eamodio.gitlens",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"formulahendry.auto-complete-tag",
"formulahendry.auto-close-tag",
"formulahendry.auto-rename-tag",
"kisstkondoros.vscode-gutter-preview",
"lokalise.i18n-ally",
"mhutchie.git-graph",
"mikestead.dotenv",
"naumovs.color-highlight",
"pkief.material-icon-theme",
"steoates.autoimport",
"vue.volar",
"whtouche.vscode-js-console-utils",
"zhuangtongfa.material-theme"
]
}

160
.vscode/settings.json vendored
View File

@@ -1,74 +1,90 @@
{
"editor.quickSuggestions": {
"strings": true
},
"workbench.iconTheme": "material-icon-theme",
"workbench.colorTheme": "One Dark Pro",
"editor.tabSize": 2,
"editor.fontLigatures": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": "active",
"git.enableSmartCommit": true,
"path-intellisense.mappings": {
"@": "${workspaceFolder}/src",
"~@": "${workspaceFolder}/src",
},
"gutterpreview.paths": {
"@": "/src",
"~@": "/src"
},
"terminal.integrated.cursorStyle": "line",
"files.associations": {
"*.env.*": "dotenv"
},
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"javascript.updateImportsOnFileMove.enabled": "always",
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"terminal.integrated.fontSize": 14,
"terminal.integrated.fontWeight": 500,
"i18n-ally.displayLanguage": "zh",
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "johnsoncodehk.volar"
},
"terminal.integrated.tabs.enabled": true,
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "yzhang.markdown-all-in-one"
},
"vue3snippets.enable-compile-vue-file-on-did-save-code": false,
"editor.formatOnSave": false,
"material-icon-theme.activeIconPack": "angular",
"material-icon-theme.files.associations": {},
"material-icon-theme.folders.associations": {
"enum": "typescript",
"enums": "typescript",
"store": "context",
"stores": "context",
"composable": "hook",
"composables": "hook",
"directive": "tools",
"directives": "tools",
"business": "core"
}
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.fontLigatures": true,
"editor.formatOnSave": false,
"editor.guides.bracketPairs": "active",
"editor.quickSuggestions": {
"strings": true
},
"editor.tabSize": 2,
"eslint.alwaysShowStatus": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"json",
"jsonc",
"json5",
"yaml",
"yml",
"markdown"
],
"files.associations": {
"*.env.*": "dotenv"
},
"files.eol": "\n",
"git.enableSmartCommit": true,
"gutterpreview.paths": {
"@": "/src",
"~@": "/src"
},
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"],
"material-icon-theme.activeIconPack": "angular",
"material-icon-theme.files.associations": {},
"material-icon-theme.folders.associations": {
"src-tauri": "src",
"enum": "typescript",
"enums": "typescript",
"store": "context",
"stores": "context",
"composable": "hook",
"composables": "hook",
"directive": "tools",
"directives": "tools",
"business": "core",
"request": "api",
"adapter": "middleware"
},
"path-intellisense.mappings": {
"@": "${workspaceFolder}/src",
"~@": "${workspaceFolder}/src"
},
"terminal.integrated.cursorStyle": "line",
"terminal.integrated.fontSize": 14,
"terminal.integrated.fontWeight": 500,
"terminal.integrated.tabs.enabled": true,
"workbench.iconTheme": "material-icon-theme",
"workbench.colorTheme": "One Dark Pro",
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "yzhang.markdown-all-in-one"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
}
}

View File

@@ -2,6 +2,141 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.9.7](https://github.com/honghuangdc/soybean-admin/compare/v0.9.6...v0.9.7) (2022-11-07)
### Features
* **projects:** 全局搜索菜单及消息通知适配移动端 ([97e2ffd](https://github.com/honghuangdc/soybean-admin/commit/97e2ffddf4ac047133dc016a91ac07556e562d29))
* **projects:** 实现用户管理页面 ([472f93b](https://github.com/honghuangdc/soybean-admin/commit/472f93bfc111e8ca94adef823b8cc12e4f8cd2c6))
* **projects:** 适配移动端修复Tab关闭图标的bug ([296b154](https://github.com/honghuangdc/soybean-admin/commit/296b154be5dfe410b3cfca9afaeeaf9c47de3e0c)), closes [#87](https://github.com/honghuangdc/soybean-admin/issues/87) [#106](https://github.com/honghuangdc/soybean-admin/issues/106) [#109](https://github.com/honghuangdc/soybean-admin/issues/109) [#111](https://github.com/honghuangdc/soybean-admin/issues/111)
* **projects:** 添加请求适配adapter层应用的示例页面 ([8d11a6a](https://github.com/honghuangdc/soybean-admin/commit/8d11a6affcfa37344011a6aaf3d6e005546f0e61))
* **projects:** 添加生产的主题配置缓存 ([718c362](https://github.com/honghuangdc/soybean-admin/commit/718c36263e451a39bca6da6c33657a09515ffbcc))
* **projects:** 添加系统管理的页面 ([c33b5eb](https://github.com/honghuangdc/soybean-admin/commit/c33b5ebfefbb3ae507141bd2e9414231fd1512d4))
* **projects:** 添加组件名称调整vue文件里面的类型声明位置 ([f64bc91](https://github.com/honghuangdc/soybean-admin/commit/f64bc91ce285c7a9806ed0f6ae970d9b598fd0cb))
* **projects:** 添加provide、inject上下文示例 ([a444731](https://github.com/honghuangdc/soybean-admin/commit/a444731e9eef43022930c3550dcfc058e70a2941))
* **projects:** 系统消息组件代码优化 ([9518372](https://github.com/honghuangdc/soybean-admin/commit/9518372fe0431d4e08a5f40d1b2982691fbb4107))
* **projects:** 增加返回顶部功能 ([894b0f1](https://github.com/honghuangdc/soybean-admin/commit/894b0f1c182a36ad1774a8144bf50dd4e0b62a46))
* **projects:** 增加系统消息组件 ([afa0134](https://github.com/honghuangdc/soybean-admin/commit/afa0134fdd63c253e102bc129e275d16ca25508e))
* **projects:** add constant route page without login status[添加未登录可访问的固定路由示例页面] ([78efd77](https://github.com/honghuangdc/soybean-admin/commit/78efd7793a241811065caf56edf7e68aea58bc8c))
* **projects:** add pinia setup syntax example: setup-store[添加setup syntax的pinia示例setup-store] ([82c4b09](https://github.com/honghuangdc/soybean-admin/commit/82c4b09b9411390f97c2d10bb211c66ed9656b63))
* **projects:** import i18n [引入i18n] ([b632b7f](https://github.com/honghuangdc/soybean-admin/commit/b632b7ffed5c6d6ec15c23c8cce030bf669c554f))
* **projects:** new router system [新的路由系统] ([c7b6a3f](https://github.com/honghuangdc/soybean-admin/commit/c7b6a3fbecd1ba051833e4e47b75a06935f212c8))
* **projects:** refactor icon system, unify icon usage [重构图标系统,统一图标用法] ([811f820](https://github.com/honghuangdc/soybean-admin/commit/811f820644053606e50624c2f184f9669f3eff7e))
* **projects:** support constant route without login status[支持未登录状态下访问自定义的固定路由] ([a539112](https://github.com/honghuangdc/soybean-admin/commit/a539112a0f53183ee073d4eb9034ef48209fe30c))
* **projects:** useNaiveTable函数类型部分 ([02992dc](https://github.com/honghuangdc/soybean-admin/commit/02992dc02d105cbfcebbea397438c68db1fa8177))
* **tabs:** 多页签增加关闭所有 ([8237adb](https://github.com/honghuangdc/soybean-admin/commit/8237adb9c0b187911df37d6d99fd84718bc3ea8f))
### Bug Fixes
* **deps:** decrease @types/node version to fix TS type error [降低@types/node版本修复TS的类型错误] ([149d22a](https://github.com/honghuangdc/soybean-admin/commit/149d22a4a491ca5fc6c52375046e9f1cb86ee76d))
* **projects:** 修复多个后端服务时的本地代理 ([2aba58c](https://github.com/honghuangdc/soybean-admin/commit/2aba58c973e5d0ea975443a8b22c9d94283d4fb9))
* **projects:** 修复构建后mockjs对xhr的影响问题 ([7757285](https://github.com/honghuangdc/soybean-admin/commit/77572855c3f7161697f42e6da36771c15707f0ab))
* **projects:** 修复图标的TS类型 ([dbd6760](https://github.com/honghuangdc/soybean-admin/commit/dbd676095b42aaebc783d5c89478306a453195a5))
* **projects:** 修复eslint规则 ([d7f5bf3](https://github.com/honghuangdc/soybean-admin/commit/d7f5bf3373e7884b8dc2c696a2c36e9cf27ad64b))
* **projects:** 修复import.meta.env的TS类型 ([1994262](https://github.com/honghuangdc/soybean-admin/commit/19942625d58e673126db5249488555de71d18457))
* **projects:** 修复tab不显示路由首页的问题 ([a792bb5](https://github.com/honghuangdc/soybean-admin/commit/a792bb5cb3c388ba3b93e17bab8f42d23cd5df4a))
* **projects:** 修复TS类型问题 ([16dce9a](https://github.com/honghuangdc/soybean-admin/commit/16dce9a4ce4d3aa822d70f6e5199eb9c86e33ad9))
* **projects:** add iconify json ([8a1ec93](https://github.com/honghuangdc/soybean-admin/commit/8a1ec938e7a26728919024e9f5b7b0af2b270aba))
* **svg-icon:** 自定义图标在Dropdown组件下hover状态无法显示图标 ([0523f08](https://github.com/honghuangdc/soybean-admin/commit/0523f0838246041bfc09130e21369bd777f63682))
* **utils:** 修复iconifyRender ([c37d0ac](https://github.com/honghuangdc/soybean-admin/commit/c37d0ac7887a3451b8558fc4aa6c05ed3b0ef74f))
### [0.9.6](https://github.com/honghuangdc/soybean-admin/compare/v0.9.5...v0.9.6) (2022-06-15)
### Features
* **projects:** 本地svg动态渲染图标 ([c3c975e](https://github.com/honghuangdc/soybean-admin/commit/c3c975ee1142987b7ded0107bf91d0080d5651fe)), closes [#61](https://github.com/honghuangdc/soybean-admin/issues/61)
* **projects:** 上下结构,菜单支持横向滚动 ([808051b](https://github.com/honghuangdc/soybean-admin/commit/808051b29dd682e1cbcf0e211774efb9cc12713a))
* **projects:** 新增Antv G2图表示例 ([2d64a2e](https://github.com/honghuangdc/soybean-admin/commit/2d64a2e57c8d83c8d06f210eeefef8f31b3abeb9))
* **projects:** 增加设置当前Tab页签名称功能 ([487213b](https://github.com/honghuangdc/soybean-admin/commit/487213b64853765e2bd186474e4607572624a33e))
### Bug Fixes
* **projects:** 设置tab标题导致meta属性丢失 ([efcfa57](https://github.com/honghuangdc/soybean-admin/commit/efcfa576d52a7eab644f3b4c65af153442887fab))
* **projects:** 修复顶部菜单的位置失效问题 ([4ee0d94](https://github.com/honghuangdc/soybean-admin/commit/4ee0d94f1bde83c788fc0dcb084402359c04fb1b))
### [0.9.5](https://github.com/honghuangdc/soybean-admin/compare/v0.9.4...v0.9.5) (2022-06-06)
### Features
* **projects:** 支持同一路由根据不同query和hash同时显示不同Tab ([4122685](https://github.com/honghuangdc/soybean-admin/commit/4122685803f8a0a485682d16cec74e27945adc47)), closes [#64](https://github.com/honghuangdc/soybean-admin/issues/64)
* **projects:** 动态路由根路由重定向只需取决于后端返回的路由首页 ([434ab1c](https://github.com/honghuangdc/soybean-admin/commit/434ab1c560b260f8a19895405eb1d3c3313052d7))
* **projects:** 补充更多的ECharts示例 ([c776249](https://github.com/honghuangdc/soybean-admin/commit/c7762490def77695bedf179ffc63e3e95d15e14d))
* **projects:** 添加百度地图、升级依赖 ([39854a4](https://github.com/honghuangdc/soybean-admin/commit/39854a492b9cce71e0c7ed52af9985cb4abd6a97))
* **projects:** 添加插件页面:图表 ([0a46ea0](https://github.com/honghuangdc/soybean-admin/commit/0a46ea08443f6b879434e925d440cf07e9494fcb))
* **projects:** 添加自动跟随系统主题设置 ([ba07b69](https://github.com/honghuangdc/soybean-admin/commit/ba07b695dd9dc5d3f8ebf57d0f2e69d624994962))
* **projects:** 添加antv g2图表示例 ([44b022a](https://github.com/honghuangdc/soybean-admin/commit/44b022aefd7dbb4c34886814cf04767450dec026))
* **projects:** 引入echarts替换antvG2plot ([e7ad086](https://github.com/honghuangdc/soybean-admin/commit/e7ad08685e8ac52a8906fc94e656192275f9764c))
* **route:** 路由meta新增activeMenu属性 ([ebd16a4](https://github.com/honghuangdc/soybean-admin/commit/ebd16a4d1ab1a95a27838a2d4f20cc1d1e7309ae))
### Bug Fixes
* **projects:** 修复@antv/g2生产环境报错 ([4558c24](https://github.com/honghuangdc/soybean-admin/commit/4558c24d1c1e1faa3326650fc16e6baf384509ac))
* **projects:** 修复插件不存在的错误提示 ([7165282](https://github.com/honghuangdc/soybean-admin/commit/716528206e9f63e873607d0afd59d83f6984e3fe))
* **projects:** 修复权限切换路由数据未更新的问题 ([60f9125](https://github.com/honghuangdc/soybean-admin/commit/60f912508b0e685957fb22ef0ed1f83272847263))
* **projects:** 修复页面切换时导致的溢出滚动条 ([e023306](https://github.com/honghuangdc/soybean-admin/commit/e0233061d3bca236b4c4bb462ce00f7ca186b9fa))
* **route:** 当为左侧混合菜单时activeMenu无效情况 ([3e4f9e2](https://github.com/honghuangdc/soybean-admin/commit/3e4f9e282442073447c5c24c33d65bc6130978ee))
### [0.9.4](https://github.com/honghuangdc/soybean-admin/compare/v0.9.3...v0.9.4) (2022-04-28)
### Features
* **layouts:** 添加侧边栏/头部的反转模式来增加对比度 ([861c8b9](https://github.com/honghuangdc/soybean-admin/commit/861c8b9852e0097a1f6b79ac2c10d19add123bde))
* **layouts:** 添加侧边栏/头部的反转模式来增加对比度 ([3c8dd77](https://github.com/honghuangdc/soybean-admin/commit/3c8dd772f89d2b656a42c4f7164e581acdb2b1a5))
* **projects:** 插件方式按需引入naiveUI ([6bed9ea](https://github.com/honghuangdc/soybean-admin/commit/6bed9ead38af6d58f6cd9e520db848ae5cbfa4db))
* **projects:** 登录页背景图片位置适配移动端 ([24010d0](https://github.com/honghuangdc/soybean-admin/commit/24010d05fb1ff51cb5e5d94ffe310206a9638711))
* **projects:** 登录页面适配移动端 ([ec0776e](https://github.com/honghuangdc/soybean-admin/commit/ec0776e268cd3d1031e9ecd794abce271a675793))
* **projects:** 权限完善及权限示例页面 ([807448a](https://github.com/honghuangdc/soybean-admin/commit/807448aec5b041535fe4fbac90eca1138b2f439c))
* **projects:** 添加请求适配器的请求示例 ([bed4292](https://github.com/honghuangdc/soybean-admin/commit/bed4292ed380e77ac428ab057abc42eceb72af53))
* **projects:** 新增静态路由 ([ca2dfa6](https://github.com/honghuangdc/soybean-admin/commit/ca2dfa6185aa7a4e58184bcfef2a1246a52f88fd))
* **projects:** 引入unocss替换windicss ([c9d3e5a](https://github.com/honghuangdc/soybean-admin/commit/c9d3e5a3fdf59179dcfc122ab8369c492ea7832e))
* **projects:** HTML lang 修改为 zh-cmn-Hans ([b9c5c34](https://github.com/honghuangdc/soybean-admin/commit/b9c5c349790b1e83a7acd1f2c53a86c9221944ff))
* **projects:** HTML lang 修改为 zh-cmn-Hans ([dbeb595](https://github.com/honghuangdc/soybean-admin/commit/dbeb595c0b9fc11e7d166a7684af37cc971f1a11))
* **projects:** mock添加权限过滤 ([7f4350a](https://github.com/honghuangdc/soybean-admin/commit/7f4350aeb673dab59192584177a897aacebe4b28))
### Bug Fixes
* **projects:** 去除从环境文件引入端口号导致的错误 ([2d6d179](https://github.com/honghuangdc/soybean-admin/commit/2d6d179d669ea71cca3fe97ac840e4856bff4051))
* **projects:** 全局搜索弹窗弹出时动画闪屏问题 ([bb1bbf2](https://github.com/honghuangdc/soybean-admin/commit/bb1bbf272438f4ed440735118c6a9ec04c7d109f))
* **projects:** 添加.npmrc修复无法获取自动引入的全局组件声明类型 ([e8488e4](https://github.com/honghuangdc/soybean-admin/commit/e8488e4d5237e5e03ec07ff07d03115389d5b1ef))
* **projects:** 添加获取路由组件文件未找到时的错误提示 ([219f87f](https://github.com/honghuangdc/soybean-admin/commit/219f87f46758f328f26697f66d8583f49c0d41de))
* **projects:** 修复获取vite环境变量的方式 ([46e1ae7](https://github.com/honghuangdc/soybean-admin/commit/46e1ae7825b2b204ce3cdd63b3c64f39bff096d0))
* **projects:** 修复路由守卫的动态路由逻辑 ([e6c26fc](https://github.com/honghuangdc/soybean-admin/commit/e6c26fcb4ae085f9fd7d7eb9183ddba020d0b5da))
* **projects:** 修复样式 ([e899914](https://github.com/honghuangdc/soybean-admin/commit/e8999144266761b3b701442975c3c00251240d53))
* **projects:** 修复在新版vite下环境变量获取不到的问题 ([3fb13ca](https://github.com/honghuangdc/soybean-admin/commit/3fb13ca9e710549d2ddeb774fe08fabd27d5ae11))
* **projects:** 修复vite alias ([cd7ca8f](https://github.com/honghuangdc/soybean-admin/commit/cd7ca8f4c77ac8c753b753ba698a9573d6c37bf9))
### [0.9.3](https://github.com/honghuangdc/soybean-admin/compare/v0.9.2...v0.9.3) (2022-03-12)
### Features
* **components:** svgIcon,添加type,调整size方案 ([ce4e039](https://github.com/honghuangdc/soybean-admin/commit/ce4e039f48001b47a2933e807f5410a9573781b9))
* **projects:** 引入soybean-admin-tab、去除vite-plugin-svg-icons用unplugin-icons实现自定义svg的iconify写法、代码优化 ([a1a57a1](https://github.com/honghuangdc/soybean-admin/commit/a1a57a185ce5004888ca4e1611973665ee46980b))
* **projects:** 新增子菜单图标和多页签图标 ([f5c56c3](https://github.com/honghuangdc/soybean-admin/commit/f5c56c355ce41157b20ed0a10272a28e6d8b2b49))
* **projects:** 新增自定义svg图标动态渲染 ([f83c7b5](https://github.com/honghuangdc/soybean-admin/commit/f83c7b59b893ab6e210188e92c4177b3d01392ce))
* **projects:** 添加naiveUI按需引入 ([a810ef8](https://github.com/honghuangdc/soybean-admin/commit/a810ef85b19e4b74f3ddb3c69d17c050e556ee90))
* **projects:** 添加SvgIcon,配置vite plugin ([378d55a](https://github.com/honghuangdc/soybean-admin/commit/378d55ac0e11cdf115ce3cb8e281d60f7fc4ff7a))
* **projects:** 添加全局组件自动引入注册 ([f5a043b](https://github.com/honghuangdc/soybean-admin/commit/f5a043b11a403927828ae922bdae411a4e5ae3c6))
* **projects:** 添加网络代理 ([094dca9](https://github.com/honghuangdc/soybean-admin/commit/094dca961f608404352ac360f44496423d88dae8))
* **projects:** 重构项目的TS类型架构去除interface文件夹 ([8191490](https://github.com/honghuangdc/soybean-admin/commit/8191490f39fc011096edd77c3156eb4fe33d4e1c))
### Bug Fixes
* **components:** 修复组件LoadingEmptyWrapper适应暗黑模式 ([811b15e](https://github.com/honghuangdc/soybean-admin/commit/811b15e672c9d69e9c5789eb11ab2db7bd729f37))
* **components:** 组件LoadingEmptyWrapper添加背景颜色动画过渡 ([7add5c2](https://github.com/honghuangdc/soybean-admin/commit/7add5c2edfcabadb77084179d464b849d880d5e6))
* **projects:** 修复 BASE_URL 没有生效的问题 ([72d7dcf](https://github.com/honghuangdc/soybean-admin/commit/72d7dcfa5ee8dc6f3601f4d65c6aca9ad2cc5d5c))
* **projects:** 修复页面切换动画开关不生效 ([9d4ed61](https://github.com/honghuangdc/soybean-admin/commit/9d4ed617fb80095e521d8063718283459711118f))
* **projects:** 修复页面切换动画无变化 ([c4546bd](https://github.com/honghuangdc/soybean-admin/commit/c4546bdfa303f1e89c0d7ddd46b54e4ec5170096))
### [0.9.2](https://github.com/honghuangdc/soybean-admin/compare/v0.9.1...v0.9.2) (2022-02-11)

16
Makefile Normal file
View File

@@ -0,0 +1,16 @@
ImageTag ?=v0.9.6
SoybeanAdminImg ?= soybeanjs/soybean-admin:$(ImageTag)
VERSION=$(shell git rev-parse --short HEAD)
soybean-admin: soybean-admin-build soybean-admin-push
soybean-admin-build:
docker build --build-arg version=$(VERSION) -t ${SoybeanAdminImg} -f docker/Dockerfile .
soybean-admin-push:
docker push ${SoybeanAdminImg}
# run tauri app:
run:
pnpm tauri dev

View File

@@ -7,16 +7,16 @@
## 简介
Soybean Admin 是一个基于 Vue3、Vite、TypeScript、Naive UI 的免费中后台模版它使用了最新的前端技术栈内置丰富的主题配置有着极高的代码规范基于mock实现的动态权限路由开箱即用的中后台前端解决方案也可用于学习参考。
[Soybean Admin](https://github.com/honghuangdc/soybean-admin) 是一个基于 Vue3、Vite3、TypeScript、NaiveUI、Pinia 和 UnoCSS 的清新优雅的中后台模版,它使用了最新的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于 mock 实现的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。
## 特性
- **最新技术栈**:使用 Vue3/vite2 等前端前沿技术开发, 使用高效率的npm包管理器pnpm
- **TypeScript**: 应用程序级 JavaScript 的语言
- **主题**:丰富可配置的主题、暗黑模式,基于windicss的动态主题颜色
- **最新技术栈**:使用 Vue3/Vite3 等前端前沿技术开发, 使用高效率的 npm 包管理器 pnpm
- **TypeScript**应用程序级 JavaScript 的语言
- **主题**:丰富可配置的主题、暗黑模式,基于原子 css 框架 - UnoCSS 的动态主题颜色
- **代码规范**:丰富的规范插件及极高的代码规范
- **权限路由**简易的路由配置、基于mock的动态路由能快速实现后端动态路由
- **请求函数**完善的请求函数封装提供Promisehooks两种请求函数
- **权限路由**:简易的路由配置、基于 mock 的动态路由能快速实现后端动态路由
- **请求函数**基于 axios 的完善的请求函数封装,提供 Promisehooks 两种请求函数,加入请求结果数据转换的适配器
## 预览
@@ -24,42 +24,52 @@ Soybean Admin 是一个基于 Vue3、Vite、TypeScript、Naive UI 的免费中
## 文档
- [项目文档](https://docs.soybean.pro)
- [项目文档: docs.soybean.pro](https://docs.soybean.pro)
### 代码仓库
## 代码仓库
- [github](https://github.com/honghuangdc/soybean-admin)
- [gitee](https://gitee.com/honghuangdc/soybean-admin)
### 温馨提示(老用户)
## 更新日志
旧版代码在old分支等main分支稳定下来再删除old分支。
[CHANGELOG](./CHANGELOG.md)
如果不是第一次进预览地址 soybean.pro新版的发布会导致有缓存退出用户重新登录即可。
## 后端服务
thin分支相对于main分支少了插件示例其他都一样后面会适当精简一些代码。
- [soybean-admin-java(开发中)](https://github.com/honghuangdc/soybean-admin-java)
- [soybean-admin-go(开发中)](https://github.com/honghuangdc/soybean-admin-go)
- [soybean-admin-nestjs(开发中)](https://github.com/honghuangdc/soybean-admin-nestjs)
## 项目示例图
![](https://s2.loli.net/2022/01/24/ovK6Oyqr7gIMu2n.png)
![](https://s2.loli.net/2022/05/16/keOtgFH27r9nqYS.png)
![](https://s2.loli.net/2022/01/24/O8loxYhMySHwGfJ.png)
![](https://s2.loli.net/2022/05/18/bW7mftiQexkvSTG.png)
![](https://s2.loli.net/2022/01/24/HKwpJ7Ab6j8fVvk.png)
![](https://s2.loli.net/2022/05/16/uV5nzjb3gYptAEl.png)
![](https://s2.loli.net/2022/01/24/bqJRSDZHBv3jsif.png)
![](https://s2.loli.net/2022/05/16/rSnNHLdpuvkKxWq.png)
![](https://s2.loli.net/2022/01/24/wXpHeau6UrSTWdF.png)
![](https://s2.loli.net/2022/05/18/Mt6YZqmDxO8v4uR.png)
### 使用 Gitpod
![](https://s2.loli.net/2022/05/16/ktH5dcG3fuFOoKA.png)
在 Gitpod适用于 GitHub 的免费在线开发环境)中打开项目,并立即开始编码.
![](https://s2.loli.net/2022/05/16/VPl6Ru1iCAhLcS4.png)
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/honghuangdc/soybean-admin)
![](https://s2.loli.net/2022/05/16/bRlAKuHW7ZVh9DT.png)
![](https://s2.loli.net/2022/06/07/rY8TyAftM5dxspv.png)
![](https://s2.loli.net/2022/06/07/5GNBAd31IzQVjLP.png)
![](https://s2.loli.net/2022/06/07/rRSG6mEZpujOACT.png)
## 安装使用
- 环境配置
**本地环境需要安装 pnpm 7.x 、Node.js 14.18+ 和 Git**
- 克隆代码
```bash
@@ -84,15 +94,27 @@ pnpm dev
pnpm build
```
## Docker 部署
- Docker 部署 Soybean
```bash
docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
```
- 访问 SoybeanAdmin
打开本地浏览器访问`http://localhost`
## 如何贡献
非常欢迎您的加入![提一个 Issue](https://github.com/honghuangdc/soybean-admin/issues/new) 或者提交一个 Pull Request。
## Git 贡献提交规范
项目已经内置angular提交规范通过git cz 代替git commit 命令即可。
项目已经内置 angular 提交规范,通过 git cz 代替 git commit 命令即可。
git cz命令需要全局安装 commitizen
git cz 命令需要全局安装 commitizen
```bash
pnpm i -g commitizen
@@ -105,8 +127,8 @@ pnpm i -g commitizen
支持现代浏览器, 不支持 IE
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png" alt="IE" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)Safari |
| :-: | :-: | :-: | :-: | :-: |
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## 开源作者
@@ -114,20 +136,24 @@ pnpm i -g commitizen
## 交流
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供 QQ 交流群使用问题欢迎在群内提问。
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群使用问题欢迎在群内提问。
- 微信交流群
- 微信交流群(添加本人微信拉进群),欢迎来技术交流,业务咨询。
<div style="text-align:left">
<img src="https://s2.loli.net/2022/02/07/hJWkOUAjpCQNwdf.jpg" style="width:200px" />
<img src="https://s2.loli.net/2022/05/16/3YGBgXnVPJdslk8.jpg" style="width:200px" />
</div>
- QQ 群 `711301266`
- QQ 交流`711301266`
<div style="text-align:left">
<img src="https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg" style="width:200px" />
</div>
- 本人微信号honghuangdc欢迎来技术交流业务咨询。
## 捐赠
如果你觉得这个项目对你有帮助,可以请 Soybean 喝杯饮料表示支持Soybean 开源的动力离不开各位的支持和鼓励。
![赞助](https://s2.loli.net/2022/01/24/i9cpq7lTCrKUoFf.png)
## License

View File

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

2
build/config/index.ts Normal file
View File

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

25
build/config/proxy.ts Normal file
View File

@@ -0,0 +1,25 @@
import type { ProxyOptions } from 'vite';
/**
* 设置网络代理
* @param isOpenProxy - 是否开启代理
* @param envConfig - env环境配置
*/
export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfig) {
if (!isOpenProxy) return undefined;
const proxy: Record<string, string | ProxyOptions> = {
[envConfig.urlPattern]: {
target: envConfig.url,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${envConfig.urlPattern}`), '')
},
[envConfig.secondUrlPattern]: {
target: envConfig.secondUrl,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${envConfig.secondUrlPattern}`), '')
}
};
return proxy;
}

View File

@@ -1,2 +1,3 @@
export * from './plugins';
export * from './define';
export * from './config';
export * from './utils';

View File

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

View File

@@ -1,17 +1,14 @@
import { loadEnv } from 'vite';
import type { ConfigEnv, PluginOption } from 'vite';
import { minifyHtml, injectHtml } from 'vite-plugin-html'; // html插件(使用变量、压缩)
import type { PluginOption } from 'vite';
import { createHtmlPlugin } from 'vite-plugin-html';
export default (config: ConfigEnv): PluginOption[] => {
const viteEnv = loadEnv(config.mode, `.env.${config.mode}`);
return [
minifyHtml(),
injectHtml({
injectData: {
export default (viteEnv: ImportMetaEnv): PluginOption[] => {
return createHtmlPlugin({
minify: true,
inject: {
data: {
appName: viteEnv.VITE_APP_NAME,
appTitle: viteEnv.VITE_APP_TITLE
}
})
];
}
});
};

View File

@@ -1,11 +0,0 @@
import Icons from 'unplugin-icons/vite'; // iconify图标
import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite'; // 从指定目录自动导入组件
export default [
Components({
dts: false,
resolvers: [IconsResolver({ componentPrefix: 'icon' })]
}),
Icons({ scale: 1, defaultClass: 'inline-block' })
];

View File

@@ -1,16 +1,38 @@
import type { ConfigEnv, PluginOption } from 'vite';
import vue from './vue';
import type { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import unocss from '@unocss/vite';
import { VitePWA } from 'vite-plugin-pwa';
import progress from 'vite-plugin-progress';
import html from './html';
import iconify from './iconify';
import windicss from './windicss';
import unplugin from './unplugin';
import mock from './mock';
import visualizer from './visualizer';
import compress from './compress';
import soybeanjs from './soybeanjs';
export function setupVitePlugins(configEnv: ConfigEnv): (PluginOption | PluginOption[])[] {
const plugins = [vue, ...html(configEnv), ...iconify, windicss, mock];
/**
* vite插件
* @param viteEnv - 环境变量配置
*/
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] {
const plugins = [
vue(),
vueJsx(),
VitePWA(),
html(viteEnv),
...unplugin(viteEnv),
unocss(),
mock,
progress(),
soybeanjs()
];
if (configEnv.command === 'build') {
plugins.push(visualizer);
if (viteEnv.VITE_VISUALIZER === 'Y') {
plugins.push(visualizer as PluginOption);
}
if (viteEnv.VITE_COMPRESS === 'Y') {
plugins.push(compress(viteEnv));
}
return plugins;

View File

@@ -0,0 +1,18 @@
import routerPage from '@soybeanjs/router-page';
export default function createSoybeanjsPlugin() {
return routerPage({
pagesFormatter: names => {
/** 系统的内置路由该文件夹名称不作为RouteKey */
const SYSTEM_VIEW = 'system-view';
const result = names
.filter(name => name !== SYSTEM_VIEW)
.map(name => {
return name.replace(`${SYSTEM_VIEW}_`, '');
});
return result;
}
});
}

44
build/plugins/unplugin.ts Normal file
View File

@@ -0,0 +1,44 @@
import VueMacros from 'unplugin-vue-macros/vite';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite';
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers';
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import { getSrcPath } from '../utils';
export default function unplugin(viteEnv: ImportMetaEnv) {
const { VITE_ICON_PREFFIX, VITE_ICON_LOCAL_PREFFIX } = viteEnv;
const srcPath = getSrcPath();
const localIconPath = `${srcPath}/assets/svg-icon`;
/** 本地svg图标集合名称 */
const collectionName = VITE_ICON_LOCAL_PREFFIX.replace(`${VITE_ICON_PREFFIX}-`, '');
return [
VueMacros(),
Icons({
compiler: 'vue3',
customCollections: {
[collectionName]: FileSystemIconLoader(localIconPath)
},
scale: 1,
defaultClass: 'inline-block'
}),
Components({
dts: 'src/typings/components.d.ts',
types: [{ from: 'vue-router', names: ['RouterLink', 'RouterView'] }],
resolvers: [
NaiveUiResolver(),
IconsResolver({ customCollections: [collectionName], componentPrefix: VITE_ICON_PREFFIX })
]
}),
createSvgIconsPlugin({
iconDirs: [localIconPath],
symbolId: `${VITE_ICON_LOCAL_PREFFIX}-[dir]-[name]`,
inject: 'body-last',
customDomId: '__SVG_ICON_LOCAL__'
})
];
}

View File

@@ -2,5 +2,6 @@ import { visualizer } from 'rollup-plugin-visualizer';
export default visualizer({
gzipSize: true,
brotliSize: true
brotliSize: true,
open: true
});

View File

@@ -1,3 +0,0 @@
import vue from '@vitejs/plugin-vue';
export default vue({});

View File

@@ -1,3 +0,0 @@
import windiCSS from 'vite-plugin-windicss';
export default windiCSS();

20
build/utils/index.ts Normal file
View File

@@ -0,0 +1,20 @@
import path from 'path';
/**
* 获取项目根路径
* @descrition 末尾不带斜杠
*/
export function getRootPath() {
return path.resolve(process.cwd());
}
/**
* 获取项目src路径
* @param srcName - src目录名称(默认: "src")
* @descrition 末尾不带斜杠
*/
export function getSrcPath(srcName = 'src') {
const rootPath = getRootPath();
return `${rootPath}/${srcName}`;
}

View File

@@ -1 +0,0 @@
module.exports = { extends: ['@commitlint/config-conventional'] };

32
docker/.dockerignore Normal file
View File

@@ -0,0 +1,32 @@
node_modules
.DS_Store
dist
.npmrc
.cache
tests/server/static
tests/server/static/upload
.local
# local env files
.env.local
.env.*.local
.eslintcache
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
# .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
yarn.lock
pnpm-lock.yaml
/vite-profile.cpuprofile

24
docker/Dockerfile Normal file
View File

@@ -0,0 +1,24 @@
FROM node:16.17.0 as builder
ENV WORKDIR=/soybean-admin
WORKDIR $WORKDIR
COPY ./ $WORKDIR/
ARG version
ENV COMMITID=$version
RUN npm i -g pnpm
RUN pnpm install
RUN pnpm build
FROM nginx:alpine as prod
RUN mkdir /soybean
COPY --from=builder /soybean-admin/dist /soybean-admin
COPY --from=builder /soybean-admin/docker/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

54
docker/nginx.conf Normal file
View File

@@ -0,0 +1,54 @@
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
# 不缓存html防止程序更新后缓存继续生效
if ($request_filename ~* .*\.(?:htm|html)$) {
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
access_log on;
}
root /soybean-admin/;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# location /soybean/soybean-webserver/v1 {
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header REMOTE-HOST $remote_addr;
# # 后台接口地址
# proxy_pass http://192.168.1.99:30597/v1;
# proxy_redirect default;
# add_header Access-Control-Allow-Origin *;
# add_header Access-Control-Allow-Headers X-Requested-With;
# add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
# }
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}

View File

@@ -1,8 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/resource/loading.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= appName %></title>
</head>
@@ -18,11 +19,8 @@
<div class="right-0 bottom-0 loading-spin-item loading-delay-1500"></div>
</div>
</div>
<h2 class="loading-title"><%= appTitle %></h2>
<div class="loading-title"><%= appTitle %></div>
</div>
<style>
@import '/resource/loading.css';
</style>
<script src="/resource/loading.js"></script>
</div>
<script type="module" src="/src/main.ts"></script>

View File

@@ -1,9 +1,10 @@
import type { MockMethod } from 'vite-plugin-mock';
import { userModel } from '../model';
const token: ApiAuth.Token = {
token: '__TEMP_TOKEN__',
refreshToken: '__TEMP_REFRESH_TOKEN__'
};
/** 参数错误的状态码 */
const ERROR_PARAM_CODE = 10000;
const ERROR_PARAM_MSG = '参数校验失败!';
const apis: MockMethod[] = [
// 获取验证码
@@ -18,73 +19,107 @@ const apis: MockMethod[] = [
};
}
},
// 密码登录
// 用户+密码 登录
{
url: '/mock/loginByPwd',
url: '/mock/login',
method: 'post',
response: (): Service.MockServiceResult<ApiAuth.Token> => {
return {
code: 200,
message: 'ok',
data: token
};
}
},
// 验证码登录
{
url: '/mock/loginByCode',
method: 'post',
response: (): Service.MockServiceResult<ApiAuth.Token> => {
return {
code: 200,
message: 'ok',
data: token
};
}
},
// 获取用户信息(请求头携带token)
{
url: '/mock/getUserInfo',
method: 'get',
response: (): Service.MockServiceResult<ApiAuth.UserInfo> => {
return {
code: 200,
message: 'ok',
data: {
userId: '0',
userName: 'Soybean',
userPhone: '15170283876',
userRole: 'super'
}
};
}
},
{
url: '/mock/testToken',
method: 'post',
response: (option: any): Service.MockServiceResult<true | null> => {
if (option.headers?.authorization !== token.token) {
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
const { userName = undefined, password = undefined } = options.body;
if (!userName || !password) {
return {
code: 66666,
message: 'token 失效',
code: ERROR_PARAM_CODE,
message: ERROR_PARAM_MSG,
data: null
};
}
const findItem = userModel.find(item => item.userName === userName && item.password === password);
if (findItem) {
return {
code: 200,
message: 'ok',
data: {
token: findItem.token,
refreshToken: findItem.refreshToken
}
};
}
return {
code: 200,
message: 'ok',
data: true
code: 1000,
message: '用户名或密码错误!',
data: null
};
}
},
// 获取用户信息(请求头携带token, 根据token获取用户信息)
{
url: '/mock/getUserInfo',
method: 'get',
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.UserInfo | null> => {
// 这里的mock插件得到的字段是authorization, 前端传递的是Authorization字段
const { authorization = '' } = options.headers;
const REFRESH_TOKEN_CODE = 66666;
if (!authorization) {
return {
code: REFRESH_TOKEN_CODE,
message: '用户已失效或不存在!',
data: null
};
}
const userInfo: Auth.UserInfo = {
userId: '',
userName: '',
userRole: 'user'
};
const isInUser = userModel.some(item => {
const flag = item.token === authorization;
if (flag) {
const { userId: itemUserId, userName, userRole } = item;
Object.assign(userInfo, { userId: itemUserId, userName, userRole });
}
return flag;
});
if (isInUser) {
return {
code: 200,
message: 'ok',
data: userInfo
};
}
return {
code: REFRESH_TOKEN_CODE,
message: '用户信息异常!',
data: null
};
}
},
{
url: '/mock/updateToken',
method: 'post',
response: (): Service.MockServiceResult<string> => {
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
const { refreshToken = '' } = options.body;
const findItem = userModel.find(item => item.refreshToken === refreshToken);
if (findItem) {
return {
code: 200,
message: 'ok',
data: {
token: findItem.token,
refreshToken: findItem.refreshToken
}
};
}
return {
code: 200,
message: 'ok',
data: token.token
code: 3000,
message: '用户已失效或不存在!',
data: null
};
}
}

View File

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

33
mock/api/management.ts Normal file
View File

@@ -0,0 +1,33 @@
import { mock } from 'mockjs';
import type { MockMethod } from 'vite-plugin-mock';
const apis: MockMethod[] = [
{
url: '/mock/getAllUserList',
method: 'post',
response: (): Service.MockServiceResult<ApiUserManagement.User[]> => {
const data = mock({
'list|1000': [
{
id: '@id',
userName: '@cname',
'age|18-56': 56,
'gender|1': ['0', '1', null],
phone:
/^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/,
'email|1': ['@email("qq.com")', null],
'userStatus|1': ['1', '2', '3', '4', null]
}
]
});
return {
code: 200,
message: 'ok',
data: data.list
};
}
}
];
export default apis;

View File

@@ -1,352 +1,26 @@
import type { MockMethod } from 'vite-plugin-mock';
const routes: AuthRoute.Route[] = [
{
name: 'dashboard',
path: '/dashboard',
component: 'basic',
children: [
{
name: 'dashboard_analysis',
path: '/dashboard/analysis',
component: 'self',
meta: {
title: '分析页',
requiresAuth: true
}
},
{
name: 'dashboard_workbench',
path: '/dashboard/workbench',
component: 'self',
meta: {
title: '工作台',
requiresAuth: true,
permissions: ['super', 'admin']
}
}
],
meta: {
title: '仪表盘',
icon: 'carbon:dashboard',
order: 1
}
},
{
name: 'document',
path: '/document',
component: 'basic',
children: [
{
name: 'document_vue',
path: '/document/vue',
component: 'self',
meta: {
title: 'vue文档',
requiresAuth: true
}
},
{
name: 'document_vue-new',
path: '/document/vue-new',
component: 'self',
meta: {
title: 'vue文档(新版)',
requiresAuth: true
}
},
{
name: 'document_vite',
path: '/document/vite',
component: 'self',
meta: {
title: 'vite文档',
requiresAuth: true
}
},
{
name: 'document_naive',
path: '/document/naive',
component: 'self',
meta: {
title: 'naive文档',
requiresAuth: true
}
},
{
name: 'document_project',
path: '/document/project',
meta: {
title: '项目文档(外链)',
requiresAuth: true,
href: 'https://docs.soybean.pro/'
}
}
],
meta: {
title: '文档',
icon: 'carbon:document',
order: 2
}
},
{
name: 'component',
path: '/component',
component: 'basic',
children: [
{
name: 'component_button',
path: '/component/button',
component: 'self',
meta: {
title: '按钮',
requiresAuth: true
}
},
{
name: 'component_card',
path: '/component/card',
component: 'self',
meta: {
title: '卡片',
requiresAuth: true
}
},
{
name: 'component_table',
path: '/component/table',
component: 'self',
meta: {
title: '表格',
requiresAuth: true
}
}
],
meta: {
title: '组件示例',
icon: 'fluent:app-store-24-regular',
order: 3
}
},
{
name: 'plugin',
path: '/plugin',
component: 'basic',
children: [
{
name: 'plugin_map',
path: '/plugin/map',
component: 'self',
meta: {
title: '地图',
requiresAuth: true
}
},
{
name: 'plugin_video',
path: '/plugin/video',
component: 'self',
meta: {
title: '视频',
requiresAuth: true
}
},
{
name: 'plugin_editor',
path: '/plugin/editor',
component: 'multi',
children: [
{
name: 'plugin_editor_quill',
path: '/plugin/editor/quill',
component: 'self',
meta: {
title: '富文本编辑器'
}
},
{
name: 'plugin_editor_markdown',
path: '/plugin/editor/markdown',
component: 'self',
meta: {
title: 'markdown编辑器'
}
}
],
meta: {
title: '编辑器',
requiresAuth: true
}
},
{
name: 'plugin_swiper',
path: '/plugin/swiper',
component: 'self',
meta: {
title: 'Swiper插件',
requiresAuth: true
}
},
{
name: 'plugin_copy',
path: '/plugin/copy',
component: 'self',
meta: {
title: '剪贴板',
requiresAuth: true
}
},
{
name: 'plugin_icon',
path: '/plugin/icon',
component: 'self',
meta: {
title: '图标',
requiresAuth: true
}
},
{
name: 'plugin_print',
path: '/plugin/print',
component: 'self',
meta: {
title: '打印',
requiresAuth: true
}
}
],
meta: {
title: '插件示例',
icon: 'clarity:plugin-line',
order: 4
}
},
{
name: 'exception',
path: '/exception',
component: 'basic',
children: [
{
name: 'exception_403',
path: '/exception/403',
component: 'self',
meta: {
title: '异常页403',
requiresAuth: true
}
},
{
name: 'exception_404',
path: '/exception/404',
component: 'self',
meta: {
title: '异常页404',
requiresAuth: true
}
},
{
name: 'exception_500',
path: '/exception/500',
component: 'self',
meta: {
title: '异常页500',
requiresAuth: true
}
}
],
meta: {
title: '异常页',
icon: 'ant-design:exception-outlined',
order: 5
}
},
{
name: 'multi-menu',
path: '/multi-menu',
component: 'basic',
children: [
{
name: 'multi-menu_first',
path: '/multi-menu/first',
component: 'multi',
children: [
{
name: 'multi-menu_first_second',
path: '/multi-menu/first/second',
component: 'self',
meta: {
title: '二级菜单',
requiresAuth: true
}
},
{
name: 'multi-menu_first_second-new',
path: '/multi-menu/first/second-new',
component: 'multi',
children: [
{
name: 'multi-menu_first_second-new_third',
path: '/multi-menu/first/second-new/third',
component: 'self',
meta: {
title: '三级菜单',
requiresAuth: true
}
}
],
meta: {
title: '二级菜单(有子菜单)'
}
}
],
meta: {
title: '一级菜单'
}
}
],
meta: {
title: '多级菜单',
icon: 'carbon:menu',
order: 6
}
},
{
name: 'about',
path: '/about',
component: 'self',
meta: {
title: '关于',
requiresAuth: true,
singleLayout: 'basic',
permissions: ['super', 'admin', 'test'],
icon: 'fluent:book-information-24-regular',
order: 7
}
}
];
function dataMiddleware(data: AuthRoute.Route[]): ApiRoute.Route {
const routeHomeName: AuthRoute.RouteKey = 'dashboard_analysis';
function sortRoutes(sorts: AuthRoute.Route[]) {
return sorts.sort((next, pre) => Number(next.meta?.order) - Number(pre.meta?.order));
}
return {
routes: sortRoutes(data),
home: routeHomeName
};
}
import { routeModel, userModel } from '../model';
const apis: MockMethod[] = [
{
url: '/mock/getUserRoutes',
method: 'post',
response: (): Service.MockServiceResult => {
response: (options: Service.MockOption): Service.MockServiceResult => {
const { userId = undefined } = options.body;
const routeHomeName: AuthRoute.LastDegreeRouteKey = 'dashboard_analysis';
const role = userModel.find(item => item.userId === userId)?.userRole || 'user';
const filterRoutes = routeModel[role];
return {
code: 200,
message: 'ok',
data: dataMiddleware(routes)
data: {
routes: filterRoutes,
home: routeHomeName
}
};
}
}

40
mock/model/auth.ts Normal file
View File

@@ -0,0 +1,40 @@
interface UserModel extends Auth.UserInfo {
token: string;
refreshToken: string;
password: string;
}
export const userModel: UserModel[] = [
{
token: '__TOKEN_SOYBEAN__',
refreshToken: '__REFRESH_TOKEN_SOYBEAN__',
userId: '0',
userName: 'Soybean',
userRole: 'super',
password: 'soybean123'
},
{
token: '__TOKEN_SUPER__',
refreshToken: '__REFRESH_TOKEN_SUPER__',
userId: '1',
userName: 'Super',
userRole: 'super',
password: 'super123'
},
{
token: '__TOKEN_ADMIN__',
refreshToken: '__REFRESH_TOKEN_ADMIN__',
userId: '2',
userName: 'Admin',
userRole: 'admin',
password: 'admin123'
},
{
token: '__TOKEN_USER01__',
refreshToken: '__REFRESH_TOKEN_USER01__',
userId: '3',
userName: 'User01',
userRole: 'user',
password: 'user01123'
}
];

2
mock/model/index.ts Normal file
View File

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

1126
mock/model/route.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,94 +1,133 @@
{
"name": "soybean-admin",
"version": "0.9.2",
"version": "0.9.7",
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
"author": {
"name": "Soybean",
"email": "honghuangdc@gmail.com",
"url": "https://github.com/honghuangdc"
},
"license": "MIT",
"homepage": "https://github.com/honghuangdc/soybean-admin",
"repository": {
"url": "https://github.com/honghuangdc/soybean-admin.git"
},
"bugs": {
"url": "https://github.com/honghuangdc/soybean-admin/issues"
},
"keywords": [
"Vue",
"Vue3",
"admin",
"admin-template",
"vue-admin",
"vue-admin-template",
"Vite3",
"Vite",
"vite-admin",
"TypeScript",
"TS",
"NaiveUI",
"naive-ui",
"naive-admin",
"NaiveUI-Admin",
"naive-ui-admin",
"UnoCSS"
],
"scripts": {
"dev": "cross-env VITE_HTTP_ENV=test vite",
"dev:prod": "cross-env VITE_HTTP_ENV=prod vite",
"typecheck": "vue-tsc",
"build": "npm run typecheck && cross-env VITE_HTTP_ENV=prod vite build",
"build:test": "npm run typecheck && cross-env VITE_HTTP_ENV=test vite build",
"build:vercel": "npm run typecheck && cross-env VITE_HTTP_ENV=prod VITE_IS_VERCEL=1 vite build",
"preview": "vite preview --port 5050",
"dev": "cross-env VITE_SERVICE_ENV=dev vite",
"dev:test": "cross-env VITE_SERVICE_ENV=test vite",
"dev:prod": "cross-env VITE_SERVICE_ENV=prod vite",
"build": "npm run typecheck && cross-env VITE_SERVICE_ENV=prod vite build",
"build:dev": "npm run typecheck && cross-env VITE_SERVICE_ENV=dev vite build",
"build:test": "npm run typecheck && cross-env VITE_SERVICE_ENV=test vite build",
"build:vercel": "cross-env VITE_HASH_ROUTE=Y VITE_VERCEL=Y vite build",
"preview": "vite preview",
"typecheck": "vue-tsc --noEmit --skipLibCheck",
"lint": "eslint . --fix",
"commit": "soybean git-commit",
"esno": "esno",
"cleanup": "esno ./scripts/cleanup.ts",
"update-pkg": "ncu --deep -u",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"release": "standard-version",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",
"lint": "eslint --fix ./ --ext .vue,.js,jsx,.ts,tsx",
"prepare": "husky install",
"postinstall": "patch-package"
},
"lint-staged": {
"*.{vue,js,jsx,ts,tsx}": "eslint --fix"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-customizable"
}
"prepare": "husky install"
},
"dependencies": {
"@antv/g2plot": "^2.4.7",
"@better-scroll/core": "^2.4.2",
"@vueuse/core": "^7.5.5",
"axios": "^0.25.0",
"clipboard": "^2.0.10",
"colord": "^2.9.2",
"@antv/data-set": "^0.11.8",
"@antv/g2": "^4.2.8",
"@better-scroll/core": "^2.5.0",
"@soybeanjs/vue-admin-layout": "^1.1.1",
"@soybeanjs/vue-admin-tab": "^1.0.5",
"@vueuse/core": "^9.4.0",
"axios": "0.27.2",
"clipboard": "^2.0.11",
"colord": "^2.9.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.10.7",
"dayjs": "^1.11.6",
"echarts": "^5.4.0",
"form-data": "^4.0.0",
"lodash-es": "^4.17.21",
"naive-ui": "^2.25.1",
"pinia": "^2.0.11",
"naive-ui": "2.33.5",
"pinia": "^2.0.23",
"print-js": "^1.6.0",
"qs": "^6.10.3",
"swiper": "^8.0.3",
"ua-parser-js": "^1.0.2",
"vditor": "^3.8.11",
"vue": "^3.2.29",
"vue-router": "^4.0.12",
"wangeditor": "^4.7.11",
"xgplayer": "^2.31.4"
"qs": "^6.11.0",
"swiper": "^8.4.4",
"ua-parser-js": "^1.0.32",
"vditor": "^3.8.18",
"vue": "3.2.41",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.6",
"vuedraggable": "^4.1.0",
"wangeditor": "^4.7.15",
"xgplayer": "^2.32.1"
},
"devDependencies": {
"@amap/amap-jsapi-types": "^0.0.8",
"@commitlint/cli": "^16.1.0",
"@commitlint/config-conventional": "^16.0.0",
"@iconify/json": "^2.0.33",
"@iconify/vue": "^3.1.3",
"@amap/amap-jsapi-types": "^0.0.10",
"@iconify/json": "^2.1.133",
"@iconify/vue": "^4.0.0",
"@soybeanjs/cli": "^0.1.2",
"@soybeanjs/router-page": "1.0.3",
"@tauri-apps/cli": "^1.1.1",
"@types/bmapgl": "^0.0.5",
"@types/crypto-js": "^4.1.0",
"@types/node": "^17.0.15",
"@types/crypto-js": "^4.1.1",
"@types/node": "18.8.3",
"@types/qs": "^6.9.7",
"@types/ua-parser-js": "^0.7.36",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"@vitejs/plugin-vue": "^2.1.0",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"commitizen": "^4.2.4",
"@unocss/preset-uno": "^0.46.3",
"@unocss/vite": "^0.46.3",
"@vitejs/plugin-vue": "^3.2.0",
"@vitejs/plugin-vue-jsx": "^2.1.0",
"conventional-changelog": "^3.1.25",
"cross-env": "^7.0.3",
"cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^6.3.0",
"eslint": "^8.8.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.4.1",
"husky": "^7.0.4",
"lint-staged": "^12.3.3",
"eslint": "^8.27.0",
"eslint-config-soybeanjs-vue": "^0.1.2",
"esno": "^0.16.3",
"husky": "^8.0.1",
"mockjs": "^1.1.0",
"patch-package": "^6.4.7",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.5.1",
"rollup-plugin-visualizer": "^5.5.4",
"sass": "^1.49.7",
"typescript": "^4.5.5",
"unplugin-icons": "^0.13.0",
"unplugin-vue-components": "^0.17.17",
"vite": "^2.7.13",
"vite-plugin-html": "^2.1.2",
"npm-check-updates": "^16.3.16",
"rimraf": "^3.0.2",
"rollup-plugin-visualizer": "^5.8.3",
"sass": "^1.56.0",
"standard-version": "^9.5.0",
"typescript": "4.8.4",
"unplugin-icons": "^0.14.13",
"unplugin-vue-components": "0.22.8",
"unplugin-vue-macros": "^0.16.0",
"utility-types": "^3.10.0",
"vite": "^3.2.2",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.0",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-windicss": "^1.6.3",
"vue-tsc": "^0.31.2",
"vueuc": "^0.4.25",
"windicss": "^3.4.3"
"vite-plugin-progress": "^0.0.6",
"vite-plugin-pwa": "^0.13.2",
"vite-plugin-svg-icons": "^2.0.1",
"vue-tsc": "^1.0.9",
"zx": "^7.1.1"
},
"pnpm": {
"patchedDependencies": {
"mockjs@1.1.0": "patches/mockjs@1.1.0.patch"
}
}
}

732
patches/mockjs@1.1.0.patch Normal file
View File

@@ -0,0 +1,732 @@
diff --git a/dist/mock.js b/dist/mock.js
index 35d5b9af3eff34324656879705dcb81470fc9697..3e6a52e0fbfdd39d3aaf1592ffd19ecde33320f3 100644
--- a/dist/mock.js
+++ b/dist/mock.js
@@ -126,17 +126,17 @@ return /******/ (function(modules) { // webpackBootstrap
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
- /*
+ /*
## Handler
处理数据模板。
-
+
* Handler.gen( template, name?, context? )
入口方法。
* Data Template Definition, DTD
-
+
处理数据模板定义。
* Handler.array( options )
@@ -146,7 +146,7 @@ return /******/ (function(modules) { // webpackBootstrap
* Handler.string( options )
* Handler.function( options )
* Handler.regexp( options )
-
+
处理路径(相对和绝对)。
* Handler.getValueByKeyPath( key, options )
@@ -177,7 +177,7 @@ return /******/ (function(modules) { // webpackBootstrap
Handle.gen(template, name, options)
context
- currentContext, templateCurrentContext,
+ currentContext, templateCurrentContext,
path, templatePath
root, templateRoot
*/
@@ -456,7 +456,7 @@ return /******/ (function(modules) { // webpackBootstrap
phed = Handler.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext, options)
// 只有一个占位符,并且没有其他字符
- if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { //
+ if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) { //
result = phed
break
@@ -627,7 +627,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
// 引用的值已经计算好
if (currentContext && (key in currentContext)) return currentContext[key]
-
+
// 尚未计算,递归引用数据模板中的属性
if (templateCurrentContext &&
(typeof templateCurrentContext === 'object') &&
@@ -816,13 +816,13 @@ return /******/ (function(modules) { // webpackBootstrap
var tpl = Mock.heredoc(function() {
/*!
{{email}}{{age}}
- <!-- Mock {
+ <!-- Mock {
email: '@EMAIL',
age: '@INT(1,100)'
} -->
*\/
})
-
+
**相关阅读**
* [Creating multiline strings in JavaScript](http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript)、
*/
@@ -850,7 +850,7 @@ return /******/ (function(modules) { // webpackBootstrap
解析数据模板(属性名部分)。
* Parser.parse( name )
-
+
```json
{
parameters: [ name, inc, range, decimal ],
@@ -922,7 +922,7 @@ return /******/ (function(modules) { // webpackBootstrap
/*
## Mock.Random
-
+
工具类,用于生成各种随机数据。
*/
@@ -1251,7 +1251,7 @@ return /******/ (function(modules) { // webpackBootstrap
替代图片源
http://fpoimg.com/
- 参考自
+ 参考自
http://rensanning.iteye.com/blog/1933310
http://code.tutsplus.com/articles/the-top-8-placeholders-for-web-designers--net-19485
*/
@@ -1541,7 +1541,7 @@ return /******/ (function(modules) { // webpackBootstrap
var bg_colour = Math.floor(Math.random() * 16777215).toString(16);
bg_colour = "#" + ("000000" + bg_colour).slice(-6);
document.bgColor = bg_colour;
-
+
http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
Creating random colors is actually more difficult than it seems. The randomness itself is easy, but aesthetically pleasing randomness is more difficult.
https://github.com/devongovett/color-generator
@@ -1561,7 +1561,7 @@ return /******/ (function(modules) { // webpackBootstrap
http://tool.c7sky.com/webcolor
网页设计常用色彩搭配表
-
+
https://github.com/One-com/one-color
An OO-based JavaScript color parser/computation toolkit with support for RGB, HSV, HSL, CMYK, and alpha channels.
API 很赞
@@ -1593,7 +1593,7 @@ return /******/ (function(modules) { // webpackBootstrap
color += letters[Math.floor(Math.random() * 16)]
}
return color
-
+
// 随机生成一个无脑的颜色,格式为 '#RRGGBB'。
// _brainlessColor()
var color = Math.floor(
@@ -1959,7 +1959,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
return result.join(' ')
},
- //
+ //
cparagraph: function(min, max) {
var len = range(3, 7, min, max)
var result = []
@@ -2282,17 +2282,17 @@ return /******/ (function(modules) { // webpackBootstrap
随机生成一个 URL。
[URL 规范](http://www.w3.org/Addressing/URL/url-spec.txt)
- http Hypertext Transfer Protocol
- ftp File Transfer protocol
- gopher The Gopher protocol
- mailto Electronic mail address
- mid Message identifiers for electronic mail
- cid Content identifiers for MIME body part
- news Usenet news
- nntp Usenet news for local NNTP access only
- prospero Access using the prospero protocols
+ http Hypertext Transfer Protocol
+ ftp File Transfer protocol
+ gopher The Gopher protocol
+ mailto Electronic mail address
+ mid Message identifiers for electronic mail
+ cid Content identifiers for MIME body part
+ news Usenet news
+ nntp Usenet news for local NNTP access only
+ prospero Access using the prospero protocols
telnet rlogin tn3270 Reference to interactive sessions
- wais Wide Area Information Servers
+ wais Wide Area Information Servers
*/
url: function(protocol, host) {
return (protocol || this.protocol()) + '://' + // protocol?
@@ -2422,9 +2422,9 @@ return /******/ (function(modules) { // webpackBootstrap
西南 重庆市 四川省 贵州省 云南省 西藏自治区
西北 陕西省 甘肃省 青海省 宁夏回族自治区 新疆维吾尔自治区
港澳台 香港特别行政区 澳门特别行政区 台湾省
-
+
**排序**
-
+
```js
var map = {}
_.each(_.keys(REGIONS),function(id){
@@ -6527,7 +6527,7 @@ return /******/ (function(modules) { // webpackBootstrap
"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
"a" / "b" / "c" / "d" / "e" / "f" /
"A" / "B" / "C" / "D" / "E" / "F"
-
+
https://github.com/victorquinn/chancejs/blob/develop/chance.js#L1349
*/
guid: function() {
@@ -6629,7 +6629,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
function CaptureGroup(n) {
- Group.call(this, "capture-group"), this.index = cgs[this.offset] || (cgs[this.offset] = index++),
+ Group.call(this, "capture-group"), this.index = cgs[this.offset] || (cgs[this.offset] = index++),
this.body = n;
}
@@ -6711,7 +6711,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
return r = l ? '"' + u(l) + '"' : "end of input", "Expected " + t + " but " + r + " found.";
}
- this.expected = n, this.found = l, this.offset = u, this.line = t, this.column = r,
+ this.expected = n, this.found = l, this.offset = u, this.line = t, this.column = r,
this.name = "SyntaxError", this.message = e(n, l);
}
function u(n) {
@@ -6724,8 +6724,8 @@ return /******/ (function(modules) { // webpackBootstrap
function r(l) {
function u(l, u, t) {
var r, e;
- for (r = u; t > r; r++) e = n.charAt(r), "\n" === e ? (l.seenCR || l.line++, l.column = 1,
- l.seenCR = !1) : "\r" === e || "\u2028" === e || "\u2029" === e ? (l.line++, l.column = 1,
+ for (r = u; t > r; r++) e = n.charAt(r), "\n" === e ? (l.seenCR || l.line++, l.column = 1,
+ l.seenCR = !1) : "\r" === e || "\u2028" === e || "\u2029" === e ? (l.line++, l.column = 1,
l.seenCR = !0) : (l.column++, l.seenCR = !1);
}
return Mt !== l && (Mt > l && (Mt = 0, Dt = {
@@ -6743,19 +6743,19 @@ return /******/ (function(modules) { // webpackBootstrap
}
function c() {
var l, u, t, r, o;
- return l = qt, u = i(), null !== u ? (t = qt, 124 === n.charCodeAt(qt) ? (r = fl,
- qt++) : (r = null, 0 === Wt && e(sl)), null !== r ? (o = c(), null !== o ? (r = [ r, o ],
- t = r) : (qt = t, t = il)) : (qt = t, t = il), null === t && (t = al), null !== t ? (Lt = l,
- u = hl(u, t), null === u ? (qt = l, l = u) : l = u) : (qt = l, l = il)) : (qt = l,
+ return l = qt, u = i(), null !== u ? (t = qt, 124 === n.charCodeAt(qt) ? (r = fl,
+ qt++) : (r = null, 0 === Wt && e(sl)), null !== r ? (o = c(), null !== o ? (r = [ r, o ],
+ t = r) : (qt = t, t = il)) : (qt = t, t = il), null === t && (t = al), null !== t ? (Lt = l,
+ u = hl(u, t), null === u ? (qt = l, l = u) : l = u) : (qt = l, l = il)) : (qt = l,
l = il), l;
}
function i() {
var n, l, u, t, r;
- if (n = qt, l = f(), null === l && (l = al), null !== l) if (u = qt, Wt++, t = d(),
+ if (n = qt, l = f(), null === l && (l = al), null !== l) if (u = qt, Wt++, t = d(),
Wt--, null === t ? u = al : (qt = u, u = il), null !== u) {
- for (t = [], r = h(), null === r && (r = a()); null !== r; ) t.push(r), r = h(),
+ for (t = [], r = h(), null === r && (r = a()); null !== r; ) t.push(r), r = h(),
null === r && (r = a());
- null !== t ? (r = s(), null === r && (r = al), null !== r ? (Lt = n, l = dl(l, t, r),
+ null !== t ? (r = s(), null === r && (r = al), null !== r ? (Lt = n, l = dl(l, t, r),
null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n, n = il);
} else qt = n, n = il; else qt = n, n = il;
return n;
@@ -6766,148 +6766,148 @@ return /******/ (function(modules) { // webpackBootstrap
}
function f() {
var l, u;
- return l = qt, 94 === n.charCodeAt(qt) ? (u = pl, qt++) : (u = null, 0 === Wt && e(vl)),
+ return l = qt, 94 === n.charCodeAt(qt) ? (u = pl, qt++) : (u = null, 0 === Wt && e(vl)),
null !== u && (Lt = l, u = wl()), null === u ? (qt = l, l = u) : l = u, l;
}
function s() {
var l, u;
- return l = qt, 36 === n.charCodeAt(qt) ? (u = Al, qt++) : (u = null, 0 === Wt && e(Cl)),
+ return l = qt, 36 === n.charCodeAt(qt) ? (u = Al, qt++) : (u = null, 0 === Wt && e(Cl)),
null !== u && (Lt = l, u = gl()), null === u ? (qt = l, l = u) : l = u, l;
}
function h() {
var n, l, u;
- return n = qt, l = a(), null !== l ? (u = d(), null !== u ? (Lt = n, l = bl(l, u),
+ return n = qt, l = a(), null !== l ? (u = d(), null !== u ? (Lt = n, l = bl(l, u),
null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n, n = il), n;
}
function d() {
var n, l, u;
- return Wt++, n = qt, l = p(), null !== l ? (u = k(), null === u && (u = al), null !== u ? (Lt = n,
- l = Tl(l, u), null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n,
+ return Wt++, n = qt, l = p(), null !== l ? (u = k(), null === u && (u = al), null !== u ? (Lt = n,
+ l = Tl(l, u), null === l ? (qt = n, n = l) : n = l) : (qt = n, n = il)) : (qt = n,
n = il), Wt--, null === n && (l = null, 0 === Wt && e(kl)), n;
}
function p() {
var n;
- return n = v(), null === n && (n = w(), null === n && (n = A(), null === n && (n = C(),
+ return n = v(), null === n && (n = w(), null === n && (n = A(), null === n && (n = C(),
null === n && (n = g(), null === n && (n = b()))))), n;
}
function v() {
var l, u, t, r, o, c;
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
- null !== u ? (t = T(), null !== t ? (44 === n.charCodeAt(qt) ? (r = ml, qt++) : (r = null,
- 0 === Wt && e(Rl)), null !== r ? (o = T(), null !== o ? (125 === n.charCodeAt(qt) ? (c = Fl,
- qt++) : (c = null, 0 === Wt && e(Ql)), null !== c ? (Lt = l, u = Sl(t, o), null === u ? (qt = l,
- l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l,
+ return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
+ null !== u ? (t = T(), null !== t ? (44 === n.charCodeAt(qt) ? (r = ml, qt++) : (r = null,
+ 0 === Wt && e(Rl)), null !== r ? (o = T(), null !== o ? (125 === n.charCodeAt(qt) ? (c = Fl,
+ qt++) : (c = null, 0 === Wt && e(Ql)), null !== c ? (Lt = l, u = Sl(t, o), null === u ? (qt = l,
+ l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
function w() {
var l, u, t, r;
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
- null !== u ? (t = T(), null !== t ? (n.substr(qt, 2) === Ul ? (r = Ul, qt += 2) : (r = null,
- 0 === Wt && e(El)), null !== r ? (Lt = l, u = Gl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
+ null !== u ? (t = T(), null !== t ? (n.substr(qt, 2) === Ul ? (r = Ul, qt += 2) : (r = null,
+ 0 === Wt && e(El)), null !== r ? (Lt = l, u = Gl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il)) : (qt = l, l = il), l;
}
function A() {
var l, u, t, r;
- return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
- null !== u ? (t = T(), null !== t ? (125 === n.charCodeAt(qt) ? (r = Fl, qt++) : (r = null,
- 0 === Wt && e(Ql)), null !== r ? (Lt = l, u = Bl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, 123 === n.charCodeAt(qt) ? (u = xl, qt++) : (u = null, 0 === Wt && e(yl)),
+ null !== u ? (t = T(), null !== t ? (125 === n.charCodeAt(qt) ? (r = Fl, qt++) : (r = null,
+ 0 === Wt && e(Ql)), null !== r ? (Lt = l, u = Bl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il)) : (qt = l, l = il), l;
}
function C() {
var l, u;
- return l = qt, 43 === n.charCodeAt(qt) ? (u = jl, qt++) : (u = null, 0 === Wt && e($l)),
+ return l = qt, 43 === n.charCodeAt(qt) ? (u = jl, qt++) : (u = null, 0 === Wt && e($l)),
null !== u && (Lt = l, u = ql()), null === u ? (qt = l, l = u) : l = u, l;
}
function g() {
var l, u;
- return l = qt, 42 === n.charCodeAt(qt) ? (u = Ll, qt++) : (u = null, 0 === Wt && e(Ml)),
+ return l = qt, 42 === n.charCodeAt(qt) ? (u = Ll, qt++) : (u = null, 0 === Wt && e(Ml)),
null !== u && (Lt = l, u = Dl()), null === u ? (qt = l, l = u) : l = u, l;
}
function b() {
var l, u;
- return l = qt, 63 === n.charCodeAt(qt) ? (u = Hl, qt++) : (u = null, 0 === Wt && e(Ol)),
+ return l = qt, 63 === n.charCodeAt(qt) ? (u = Hl, qt++) : (u = null, 0 === Wt && e(Ol)),
null !== u && (Lt = l, u = Wl()), null === u ? (qt = l, l = u) : l = u, l;
}
function k() {
var l;
- return 63 === n.charCodeAt(qt) ? (l = Hl, qt++) : (l = null, 0 === Wt && e(Ol)),
+ return 63 === n.charCodeAt(qt) ? (l = Hl, qt++) : (l = null, 0 === Wt && e(Ol)),
l;
}
function T() {
var l, u, t;
- if (l = qt, u = [], zl.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null,
- 0 === Wt && e(Il)), null !== t) for (;null !== t; ) u.push(t), zl.test(n.charAt(qt)) ? (t = n.charAt(qt),
+ if (l = qt, u = [], zl.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null,
+ 0 === Wt && e(Il)), null !== t) for (;null !== t; ) u.push(t), zl.test(n.charAt(qt)) ? (t = n.charAt(qt),
qt++) : (t = null, 0 === Wt && e(Il)); else u = il;
- return null !== u && (Lt = l, u = Jl(u)), null === u ? (qt = l, l = u) : l = u,
+ return null !== u && (Lt = l, u = Jl(u)), null === u ? (qt = l, l = u) : l = u,
l;
}
function x() {
var l, u, t, r;
- return l = qt, 40 === n.charCodeAt(qt) ? (u = Kl, qt++) : (u = null, 0 === Wt && e(Nl)),
- null !== u ? (t = R(), null === t && (t = F(), null === t && (t = m(), null === t && (t = y()))),
- null !== t ? (41 === n.charCodeAt(qt) ? (r = Pl, qt++) : (r = null, 0 === Wt && e(Vl)),
- null !== r ? (Lt = l, u = Xl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, 40 === n.charCodeAt(qt) ? (u = Kl, qt++) : (u = null, 0 === Wt && e(Nl)),
+ null !== u ? (t = R(), null === t && (t = F(), null === t && (t = m(), null === t && (t = y()))),
+ null !== t ? (41 === n.charCodeAt(qt) ? (r = Pl, qt++) : (r = null, 0 === Wt && e(Vl)),
+ null !== r ? (Lt = l, u = Xl(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il)) : (qt = l, l = il), l;
}
function y() {
var n, l;
- return n = qt, l = c(), null !== l && (Lt = n, l = Yl(l)), null === l ? (qt = n,
+ return n = qt, l = c(), null !== l && (Lt = n, l = Yl(l)), null === l ? (qt = n,
n = l) : n = l, n;
}
function m() {
var l, u, t;
- return l = qt, n.substr(qt, 2) === Zl ? (u = Zl, qt += 2) : (u = null, 0 === Wt && e(_l)),
- null !== u ? (t = c(), null !== t ? (Lt = l, u = nu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, n.substr(qt, 2) === Zl ? (u = Zl, qt += 2) : (u = null, 0 === Wt && e(_l)),
+ null !== u ? (t = c(), null !== t ? (Lt = l, u = nu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
function R() {
var l, u, t;
- return l = qt, n.substr(qt, 2) === lu ? (u = lu, qt += 2) : (u = null, 0 === Wt && e(uu)),
- null !== u ? (t = c(), null !== t ? (Lt = l, u = tu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, n.substr(qt, 2) === lu ? (u = lu, qt += 2) : (u = null, 0 === Wt && e(uu)),
+ null !== u ? (t = c(), null !== t ? (Lt = l, u = tu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
function F() {
var l, u, t;
- return l = qt, n.substr(qt, 2) === ru ? (u = ru, qt += 2) : (u = null, 0 === Wt && e(eu)),
- null !== u ? (t = c(), null !== t ? (Lt = l, u = ou(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, n.substr(qt, 2) === ru ? (u = ru, qt += 2) : (u = null, 0 === Wt && e(eu)),
+ null !== u ? (t = c(), null !== t ? (Lt = l, u = ou(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
function Q() {
var l, u, t, r, o;
- if (Wt++, l = qt, 91 === n.charCodeAt(qt) ? (u = iu, qt++) : (u = null, 0 === Wt && e(au)),
- null !== u) if (94 === n.charCodeAt(qt) ? (t = pl, qt++) : (t = null, 0 === Wt && e(vl)),
+ if (Wt++, l = qt, 91 === n.charCodeAt(qt) ? (u = iu, qt++) : (u = null, 0 === Wt && e(au)),
+ null !== u) if (94 === n.charCodeAt(qt) ? (t = pl, qt++) : (t = null, 0 === Wt && e(vl)),
null === t && (t = al), null !== t) {
- for (r = [], o = S(), null === o && (o = U()); null !== o; ) r.push(o), o = S(),
+ for (r = [], o = S(), null === o && (o = U()); null !== o; ) r.push(o), o = S(),
null === o && (o = U());
- null !== r ? (93 === n.charCodeAt(qt) ? (o = fu, qt++) : (o = null, 0 === Wt && e(su)),
- null !== o ? (Lt = l, u = hu(t, r), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ null !== r ? (93 === n.charCodeAt(qt) ? (o = fu, qt++) : (o = null, 0 === Wt && e(su)),
+ null !== o ? (Lt = l, u = hu(t, r), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il);
} else qt = l, l = il; else qt = l, l = il;
return Wt--, null === l && (u = null, 0 === Wt && e(cu)), l;
}
function S() {
var l, u, t, r;
- return Wt++, l = qt, u = U(), null !== u ? (45 === n.charCodeAt(qt) ? (t = pu, qt++) : (t = null,
- 0 === Wt && e(vu)), null !== t ? (r = U(), null !== r ? (Lt = l, u = wu(u, r), null === u ? (qt = l,
- l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il), Wt--,
+ return Wt++, l = qt, u = U(), null !== u ? (45 === n.charCodeAt(qt) ? (t = pu, qt++) : (t = null,
+ 0 === Wt && e(vu)), null !== t ? (r = U(), null !== r ? (Lt = l, u = wu(u, r), null === u ? (qt = l,
+ l = u) : l = u) : (qt = l, l = il)) : (qt = l, l = il)) : (qt = l, l = il), Wt--,
null === l && (u = null, 0 === Wt && e(du)), l;
}
function U() {
var n, l;
- return Wt++, n = G(), null === n && (n = E()), Wt--, null === n && (l = null, 0 === Wt && e(Au)),
+ return Wt++, n = G(), null === n && (n = E()), Wt--, null === n && (l = null, 0 === Wt && e(Au)),
n;
}
function E() {
var l, u;
- return l = qt, Cu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null, 0 === Wt && e(gu)),
+ return l = qt, Cu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null, 0 === Wt && e(gu)),
null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u, l;
}
function G() {
var n;
- return n = L(), null === n && (n = Y(), null === n && (n = H(), null === n && (n = O(),
- null === n && (n = W(), null === n && (n = z(), null === n && (n = I(), null === n && (n = J(),
- null === n && (n = K(), null === n && (n = N(), null === n && (n = P(), null === n && (n = V(),
- null === n && (n = X(), null === n && (n = _(), null === n && (n = nl(), null === n && (n = ll(),
+ return n = L(), null === n && (n = Y(), null === n && (n = H(), null === n && (n = O(),
+ null === n && (n = W(), null === n && (n = z(), null === n && (n = I(), null === n && (n = J(),
+ null === n && (n = K(), null === n && (n = N(), null === n && (n = P(), null === n && (n = V(),
+ null === n && (n = X(), null === n && (n = _(), null === n && (n = nl(), null === n && (n = ll(),
null === n && (n = ul(), null === n && (n = tl()))))))))))))))))), n;
}
function B() {
@@ -6916,154 +6916,154 @@ return /******/ (function(modules) { // webpackBootstrap
}
function j() {
var l, u;
- return l = qt, 46 === n.charCodeAt(qt) ? (u = ku, qt++) : (u = null, 0 === Wt && e(Tu)),
+ return l = qt, 46 === n.charCodeAt(qt) ? (u = ku, qt++) : (u = null, 0 === Wt && e(Tu)),
null !== u && (Lt = l, u = xu()), null === u ? (qt = l, l = u) : l = u, l;
}
function $() {
var l, u;
- return Wt++, l = qt, mu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null,
- 0 === Wt && e(Ru)), null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u,
+ return Wt++, l = qt, mu.test(n.charAt(qt)) ? (u = n.charAt(qt), qt++) : (u = null,
+ 0 === Wt && e(Ru)), null !== u && (Lt = l, u = bu(u)), null === u ? (qt = l, l = u) : l = u,
Wt--, null === l && (u = null, 0 === Wt && e(yu)), l;
}
function q() {
var n;
- return n = M(), null === n && (n = D(), null === n && (n = Y(), null === n && (n = H(),
- null === n && (n = O(), null === n && (n = W(), null === n && (n = z(), null === n && (n = I(),
- null === n && (n = J(), null === n && (n = K(), null === n && (n = N(), null === n && (n = P(),
- null === n && (n = V(), null === n && (n = X(), null === n && (n = Z(), null === n && (n = _(),
- null === n && (n = nl(), null === n && (n = ll(), null === n && (n = ul(), null === n && (n = tl()))))))))))))))))))),
+ return n = M(), null === n && (n = D(), null === n && (n = Y(), null === n && (n = H(),
+ null === n && (n = O(), null === n && (n = W(), null === n && (n = z(), null === n && (n = I(),
+ null === n && (n = J(), null === n && (n = K(), null === n && (n = N(), null === n && (n = P(),
+ null === n && (n = V(), null === n && (n = X(), null === n && (n = Z(), null === n && (n = _(),
+ null === n && (n = nl(), null === n && (n = ll(), null === n && (n = ul(), null === n && (n = tl()))))))))))))))))))),
n;
}
function L() {
var l, u;
- return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
+ return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
null !== u && (Lt = l, u = Su()), null === u ? (qt = l, l = u) : l = u, l;
}
function M() {
var l, u;
- return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
+ return l = qt, n.substr(qt, 2) === Fu ? (u = Fu, qt += 2) : (u = null, 0 === Wt && e(Qu)),
null !== u && (Lt = l, u = Uu()), null === u ? (qt = l, l = u) : l = u, l;
}
function D() {
var l, u;
- return l = qt, n.substr(qt, 2) === Eu ? (u = Eu, qt += 2) : (u = null, 0 === Wt && e(Gu)),
+ return l = qt, n.substr(qt, 2) === Eu ? (u = Eu, qt += 2) : (u = null, 0 === Wt && e(Gu)),
null !== u && (Lt = l, u = Bu()), null === u ? (qt = l, l = u) : l = u, l;
}
function H() {
var l, u;
- return l = qt, n.substr(qt, 2) === ju ? (u = ju, qt += 2) : (u = null, 0 === Wt && e($u)),
+ return l = qt, n.substr(qt, 2) === ju ? (u = ju, qt += 2) : (u = null, 0 === Wt && e($u)),
null !== u && (Lt = l, u = qu()), null === u ? (qt = l, l = u) : l = u, l;
}
function O() {
var l, u;
- return l = qt, n.substr(qt, 2) === Lu ? (u = Lu, qt += 2) : (u = null, 0 === Wt && e(Mu)),
+ return l = qt, n.substr(qt, 2) === Lu ? (u = Lu, qt += 2) : (u = null, 0 === Wt && e(Mu)),
null !== u && (Lt = l, u = Du()), null === u ? (qt = l, l = u) : l = u, l;
}
function W() {
var l, u;
- return l = qt, n.substr(qt, 2) === Hu ? (u = Hu, qt += 2) : (u = null, 0 === Wt && e(Ou)),
+ return l = qt, n.substr(qt, 2) === Hu ? (u = Hu, qt += 2) : (u = null, 0 === Wt && e(Ou)),
null !== u && (Lt = l, u = Wu()), null === u ? (qt = l, l = u) : l = u, l;
}
function z() {
var l, u;
- return l = qt, n.substr(qt, 2) === zu ? (u = zu, qt += 2) : (u = null, 0 === Wt && e(Iu)),
+ return l = qt, n.substr(qt, 2) === zu ? (u = zu, qt += 2) : (u = null, 0 === Wt && e(Iu)),
null !== u && (Lt = l, u = Ju()), null === u ? (qt = l, l = u) : l = u, l;
}
function I() {
var l, u;
- return l = qt, n.substr(qt, 2) === Ku ? (u = Ku, qt += 2) : (u = null, 0 === Wt && e(Nu)),
+ return l = qt, n.substr(qt, 2) === Ku ? (u = Ku, qt += 2) : (u = null, 0 === Wt && e(Nu)),
null !== u && (Lt = l, u = Pu()), null === u ? (qt = l, l = u) : l = u, l;
}
function J() {
var l, u;
- return l = qt, n.substr(qt, 2) === Vu ? (u = Vu, qt += 2) : (u = null, 0 === Wt && e(Xu)),
+ return l = qt, n.substr(qt, 2) === Vu ? (u = Vu, qt += 2) : (u = null, 0 === Wt && e(Xu)),
null !== u && (Lt = l, u = Yu()), null === u ? (qt = l, l = u) : l = u, l;
}
function K() {
var l, u;
- return l = qt, n.substr(qt, 2) === Zu ? (u = Zu, qt += 2) : (u = null, 0 === Wt && e(_u)),
+ return l = qt, n.substr(qt, 2) === Zu ? (u = Zu, qt += 2) : (u = null, 0 === Wt && e(_u)),
null !== u && (Lt = l, u = nt()), null === u ? (qt = l, l = u) : l = u, l;
}
function N() {
var l, u;
- return l = qt, n.substr(qt, 2) === lt ? (u = lt, qt += 2) : (u = null, 0 === Wt && e(ut)),
+ return l = qt, n.substr(qt, 2) === lt ? (u = lt, qt += 2) : (u = null, 0 === Wt && e(ut)),
null !== u && (Lt = l, u = tt()), null === u ? (qt = l, l = u) : l = u, l;
}
function P() {
var l, u;
- return l = qt, n.substr(qt, 2) === rt ? (u = rt, qt += 2) : (u = null, 0 === Wt && e(et)),
+ return l = qt, n.substr(qt, 2) === rt ? (u = rt, qt += 2) : (u = null, 0 === Wt && e(et)),
null !== u && (Lt = l, u = ot()), null === u ? (qt = l, l = u) : l = u, l;
}
function V() {
var l, u;
- return l = qt, n.substr(qt, 2) === ct ? (u = ct, qt += 2) : (u = null, 0 === Wt && e(it)),
+ return l = qt, n.substr(qt, 2) === ct ? (u = ct, qt += 2) : (u = null, 0 === Wt && e(it)),
null !== u && (Lt = l, u = at()), null === u ? (qt = l, l = u) : l = u, l;
}
function X() {
var l, u;
- return l = qt, n.substr(qt, 2) === ft ? (u = ft, qt += 2) : (u = null, 0 === Wt && e(st)),
+ return l = qt, n.substr(qt, 2) === ft ? (u = ft, qt += 2) : (u = null, 0 === Wt && e(st)),
null !== u && (Lt = l, u = ht()), null === u ? (qt = l, l = u) : l = u, l;
}
function Y() {
var l, u, t;
- return l = qt, n.substr(qt, 2) === dt ? (u = dt, qt += 2) : (u = null, 0 === Wt && e(pt)),
- null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
- null !== t ? (Lt = l, u = wt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, n.substr(qt, 2) === dt ? (u = dt, qt += 2) : (u = null, 0 === Wt && e(pt)),
+ null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
+ null !== t ? (Lt = l, u = wt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
function Z() {
var l, u, t;
- return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
- null !== u ? (gt.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(bt)),
- null !== t ? (Lt = l, u = kt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
+ null !== u ? (gt.test(n.charAt(qt)) ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(bt)),
+ null !== t ? (Lt = l, u = kt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
function _() {
var l, u, t, r;
- if (l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
+ if (l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
null !== u) {
- if (t = [], yt.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(mt)),
- null !== r) for (;null !== r; ) t.push(r), yt.test(n.charAt(qt)) ? (r = n.charAt(qt),
+ if (t = [], yt.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(mt)),
+ null !== r) for (;null !== r; ) t.push(r), yt.test(n.charAt(qt)) ? (r = n.charAt(qt),
qt++) : (r = null, 0 === Wt && e(mt)); else t = il;
- null !== t ? (Lt = l, u = Rt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ null !== t ? (Lt = l, u = Rt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il);
} else qt = l, l = il;
return l;
}
function nl() {
var l, u, t, r;
- if (l = qt, n.substr(qt, 2) === Ft ? (u = Ft, qt += 2) : (u = null, 0 === Wt && e(Qt)),
+ if (l = qt, n.substr(qt, 2) === Ft ? (u = Ft, qt += 2) : (u = null, 0 === Wt && e(Qt)),
null !== u) {
- if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
- null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
+ if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
+ null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
qt++) : (r = null, 0 === Wt && e(Ut)); else t = il;
- null !== t ? (Lt = l, u = Et(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ null !== t ? (Lt = l, u = Et(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il);
} else qt = l, l = il;
return l;
}
function ll() {
var l, u, t, r;
- if (l = qt, n.substr(qt, 2) === Gt ? (u = Gt, qt += 2) : (u = null, 0 === Wt && e(Bt)),
+ if (l = qt, n.substr(qt, 2) === Gt ? (u = Gt, qt += 2) : (u = null, 0 === Wt && e(Bt)),
null !== u) {
- if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
- null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
+ if (t = [], St.test(n.charAt(qt)) ? (r = n.charAt(qt), qt++) : (r = null, 0 === Wt && e(Ut)),
+ null !== r) for (;null !== r; ) t.push(r), St.test(n.charAt(qt)) ? (r = n.charAt(qt),
qt++) : (r = null, 0 === Wt && e(Ut)); else t = il;
- null !== t ? (Lt = l, u = jt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ null !== t ? (Lt = l, u = jt(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il);
} else qt = l, l = il;
return l;
}
function ul() {
var l, u;
- return l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
+ return l = qt, n.substr(qt, 2) === Tt ? (u = Tt, qt += 2) : (u = null, 0 === Wt && e(xt)),
null !== u && (Lt = l, u = $t()), null === u ? (qt = l, l = u) : l = u, l;
}
function tl() {
var l, u, t;
- return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
- null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
- null !== t ? (Lt = l, u = bu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
+ return l = qt, 92 === n.charCodeAt(qt) ? (u = At, qt++) : (u = null, 0 === Wt && e(Ct)),
+ null !== u ? (n.length > qt ? (t = n.charAt(qt), qt++) : (t = null, 0 === Wt && e(vt)),
+ null !== t ? (Lt = l, u = bu(t), null === u ? (qt = l, l = u) : l = u) : (qt = l,
l = il)) : (qt = l, l = il), l;
}
var rl, el = arguments.length > 1 ? arguments[1] : {}, ol = {
@@ -7234,7 +7234,7 @@ return /******/ (function(modules) { // webpackBootstrap
var Util = __webpack_require__(3)
var Random = __webpack_require__(5)
/*
-
+
*/
var Handler = {
extend: Util.extend
@@ -7481,7 +7481,7 @@ return /******/ (function(modules) { // webpackBootstrap
return Random.integer(min, max)
},
/*
-
+
*/
charset: function(node, result, cache) {
// node.invert
@@ -7642,11 +7642,11 @@ return /******/ (function(modules) { // webpackBootstrap
## valid(template, data)
校验真实数据 data 是否与数据模板 template 匹配。
-
+
实现思路:
1. 解析规则。
先把数据模板 template 解析为更方便机器解析的 JSON-Schame
- name 属性名
+ name 属性名
type 属性值类型
template 属性值模板
properties 对象属性数组
@@ -7655,7 +7655,7 @@ return /******/ (function(modules) { // webpackBootstrap
2. 递归验证规则。
然后用 JSON-Schema 校验真实数据,校验项包括属性名、值类型、值、值生成规则。
- 提示信息
+ 提示信息
https://github.com/fge/json-schema-validator/blob/master/src/main/resources/com/github/fge/jsonschema/validator/validation.properties
[JSON-Schama validator](http://json-schema-validator.herokuapp.com/)
[Regexp Demo](http://demos.forbeslindesay.co.uk/regexp/)
@@ -7693,8 +7693,8 @@ return /******/ (function(modules) { // webpackBootstrap
+step
整数部分
小数部分
- boolean
- string
+ boolean
+ string
min-max
count
## properties
@@ -7949,9 +7949,9 @@ return /******/ (function(modules) { // webpackBootstrap
/*
完善、友好的提示信息
-
+
Equal, not equal to, greater than, less than, greater than or equal to, less than or equal to
- 路径 验证类型 描述
+ 路径 验证类型 描述
Expect path.name is less than or equal to expected, but path.name is actual.
@@ -8264,7 +8264,7 @@ return /******/ (function(modules) { // webpackBootstrap
Util.extend(MockXMLHttpRequest.prototype, {
// https://xhr.spec.whatwg.org/#the-open()-method
// Sets the request method, request URL, and synchronous flag.
- open: function(method, url, async, username, password) {
+ open: function(method, url, async = true, username, password) {
var that = this
Util.extend(this.custom, {
@@ -8310,6 +8310,8 @@ return /******/ (function(modules) { // webpackBootstrap
var xhr = createNativeXMLHttpRequest()
this.custom.xhr = xhr
+ MockXMLHttpRequest.prototype.upload = xhr.upload
+
// 初始化所有事件,用于监听原生 XHR 对象的事件
for (var i = 0; i < XHR_EVENTS.length; i++) {
xhr.addEventListener(XHR_EVENTS[i], handle)
@@ -8360,6 +8362,7 @@ return /******/ (function(modules) { // webpackBootstrap
// 原生 XHR
if (!this.match) {
+ this.custom.xhr.responseType = this.responseType || ''
this.custom.xhr.send(data)
return
}

16123
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/**
* 初始化加载效果的svg格式logo
* @param { string }id - 元素id
* @param {string} id - 元素id
*/
function initSvgLogo(id) {
const svgStr = `<svg width="128px" height="128px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
@@ -22,8 +22,7 @@ function initSvgLogo(id) {
<path style="fill:currentColor" d="M77.9,126.6c0,3.9-2.8,7.2-6.7,7.9c-7.8,1.5-14.8,5.9-19.7,12.2c-2.7,3.5-7.6,4.2-11.2,1.6
c-3.6-2.6-4.3-7.6-1.7-11.2c0.1-0.1,0.2-0.3,0.3-0.4c4.1-5.2,9.3-9.6,15.1-12.8c4.4-2.5,9.1-4.2,14-5.1
C73.3,117.7,77.9,121.3,77.9,126.6z" />
</svg>
`;
</svg>`;
const appEl = document.querySelector(id);
const div = document.createElement('div');
div.innerHTML = svgStr;
@@ -34,11 +33,12 @@ function initSvgLogo(id) {
function addThemeColorCssVars() {
const key = '__THEME_COLOR__';
const themeColor = window.localStorage.getItem(key) || '#1890ff';
const defaultColor = '#1890ff';
const themeColor = window.localStorage.getItem(key) || defaultColor;
const cssVars = `--primary-color: ${themeColor}`;
document.documentElement.style.cssText = cssVars;
}
initSvgLogo('#loadingLogo');
addThemeColorCssVars();
initSvgLogo('#loadingLogo');

4
scripts/cleanup.ts Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env zx
import { $ } from 'zx';
$`pnpm rimraf node_modules dist pnpm-lock.yaml`;

View File

@@ -13,12 +13,14 @@
</template>
<script setup lang="ts">
import { NConfigProvider, zhCN, dateZhCN } from 'naive-ui';
import { NaiveProvider } from '@/components';
import { useThemeStore, subscribeStore } from '@/store';
import { dateZhCN, zhCN } from 'naive-ui';
import { subscribeStore, useThemeStore } from '@/store';
import { useGlobalEvents } from '@/composables';
const theme = useThemeStore();
subscribeStore();
useGlobalEvents();
</script>
<style scoped></style>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-activity"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline></svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-at-sign"><circle cx="12" cy="12" r="4"></circle><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94"></path></svg>

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-cast"><path d="M2 16.1A5 5 0 0 1 5.9 20M2 12.05A9 9 0 0 1 9.95 20M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6"></path><line x1="2" y1="20" x2="2.01" y2="20"></line></svg>

After

Width:  |  Height:  |  Size: 387 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chrome"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4"></circle><line x1="21.17" y1="8" x2="12" y2="8"></line><line x1="3.95" y1="6.06" x2="8.54" y2="14"></line><line x1="10.88" y1="21.94" x2="15.46" y2="14"></line></svg>

After

Width:  |  Height:  |  Size: 448 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-copy"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>

After

Width:  |  Height:  |  Size: 351 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M19 10c0 1.38-2.12 2.5-3.5 2.5s-2.75-1.12-2.75-2.5h-1.5c0 1.38-1.37 2.5-2.75 2.5S5 11.38 5 10h-.75c-.16.64-.25 1.31-.25 2a8 8 0 0 0 8 8a8 8 0 0 0 8-8c0-.69-.09-1.36-.25-2H19m-7-6C9.04 4 6.45 5.61 5.07 8h13.86C17.55 5.61 14.96 4 12 4m10 8a10 10 0 0 1-10 10A10 10 0 0 1 2 12A10 10 0 0 1 12 2a10 10 0 0 1 10 10m-10 5.23c-1.75 0-3.29-.73-4.19-1.81L9.23 14c.45.72 1.52 1.23 2.77 1.23s2.32-.51 2.77-1.23l1.42 1.42c-.9 1.08-2.44 1.81-4.19 1.81Z"></path></svg>

After

Width:  |  Height:  |  Size: 702 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 77 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>

After

Width:  |  Height:  |  Size: 371 B

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 158.88 158.88"><path d="M158.86.3v157.48c0 .9-.2 1.1-1.1 1.1H.24a2.61 2.61 0 01-.11-1.3V1.67C.14 0 0 .18 1.61.18h156a2.62 2.62 0 011.25.12z" fill="currentColor"/><path d="M158.86.3H2C0 .31.27 0 .27 2v156.85c-.07-.05-.25.12-.24-.12s0-.64 0-1Q0 79.46 0 1.14C0 .24.2 0 1.1 0h156.68c.35.08.81-.2 1.08.3z" fill="#fff"/><path d="M93.65 51.52a68.65 68.65 0 01-6.47 28.81 1.72 1.72 0 00.19 2c6.08 8.28 13.58 14.79 23.19 18.69a46.22 46.22 0 0017.15 3.39 28.87 28.87 0 003.34-.25 6.2 6.2 0 017 5.12 6.07 6.07 0 01-5.15 7.14 50.39 50.39 0 01-18.06-1c-15.85-3.66-28-12.75-37.44-25.7a2.15 2.15 0 00-2.23-1.09c-14 1.37-26.17 6.43-35.5 17.21a38.47 38.47 0 00-6.23 9.74 6.21 6.21 0 01-8.17 3.42 6.14 6.14 0 01-3.27-8.2 49.31 49.31 0 019.63-14.62c10.56-11.44 23.8-17.54 39.09-19.54a13.93 13.93 0 012.84-.34c1.61.14 2.18-.73 2.73-2A54.38 54.38 0 0081.12 51a44 44 0 00-8-25 6.11 6.11 0 01-.65-6.46A6 6 0 0177.75 16a6.34 6.34 0 015.66 3 53.61 53.61 0 017.17 14.28 59.33 59.33 0 013.07 18.24z" fill="#fff"/><path d="M46.92 118.63a6 6 0 011.35-3.88 37.89 37.89 0 0122.5-14 6.08 6.08 0 016.65 2.47 6.18 6.18 0 01-3.84 9.63 26.09 26.09 0 00-15.71 9.77 6.2 6.2 0 01-10.95-4zM124.3 92.8a34.66 34.66 0 01-9.82-2.48 35.46 35.46 0 01-14.65-10.45 6.19 6.19 0 012.84-9.93 5.79 5.79 0 016.44 1.73 26.79 26.79 0 0016.51 8.85 6 6 0 015 5.54 6.21 6.21 0 01-4.29 6.46 6.55 6.55 0 01-2.03.28zM69.32 53.27a33.46 33.46 0 01-2.27 12.52 6.21 6.21 0 01-10.94 1 6.09 6.09 0 01-.65-5.4 26 26 0 00-.53-18.25 6.21 6.21 0 0111.49-4.72 40.24 40.24 0 012.9 14.85z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 158.88 158.88"><path d="M0 158.86V1.1C0 .2.2 0 1.1 0h156.68c.9 0 1.1.2 1.1 1.1v156.68c0 .9-.2 1.1-1.1 1.1Q78.9 158.83 0 158.86z" fill="#ffffff00"/><path d="M81.28 55.9c-.1-11.67-2.93-22.55-9.37-32.38-1-1.5-2.14-2.86-2.5-4.71a8.1 8.1 0 014-8.61 7.89 7.89 0 019.3 1.23 36 36 0 015.9 8.83 75.18 75.18 0 018.44 28.58 83.21 83.21 0 01-5.23 36.74 103 103 0 01-3 7.28 1.2 1.2 0 000 1.41c9.58 13.3 21.76 23 37.85 27.24a54.35 54.35 0 0019.68 1.57 7.72 7.72 0 018.36 6.9 7.9 7.9 0 01-6.7 9 64.74 64.74 0 01-23-1.33 77.68 77.68 0 01-36.93-19.88 93.64 93.64 0 01-11.91-13.71 2.18 2.18 0 00-2.3-1.06 72.75 72.75 0 00-27.38 7.55c-11.6 6-20.67 14.58-26.4 26.45a10.13 10.13 0 01-3.7 4.7 8 8 0 01-9.19-.7 7.86 7.86 0 01-2.36-9.28 60.32 60.32 0 018.72-14.52c12.2-15.43 28.21-24.59 47.32-28.57A85.08 85.08 0 0173.07 87a1.22 1.22 0 001.18-.8 76.06 76.06 0 006.53-22.3 57.87 57.87 0 00.5-8z" fill="currentColor"/><path d="M136.26 108.34a44.72 44.72 0 01-11.13-2.87 46.11 46.11 0 01-19.66-13.76 8 8 0 015.72-13.22 7.93 7.93 0 016.54 2.93 33.27 33.27 0 0018.87 10.75 14.76 14.76 0 014.48 1.18 8.08 8.08 0 013.84 9.21c-.92 3.52-4.13 5.81-8.66 5.78zM55.66 33.32a7.61 7.61 0 016.64 5 49.14 49.14 0 013.64 17 46.33 46.33 0 01-2.46 17.28c-2 5.77-8.24 7.79-12.89 4.15a8.1 8.1 0 01-2.39-9 31.68 31.68 0 001.68-12.36 35.77 35.77 0 00-2.43-11c-2.1-5.45 1.75-11.07 8.21-11.07zM77.92 126.57a8 8 0 01-6.68 7.86 32.88 32.88 0 00-19.7 12.19 8.13 8.13 0 01-11.21 1.62 8 8 0 01-1.41-11.58A51.05 51.05 0 0154 123.81a45.85 45.85 0 0114-5.1c5.35-1.04 9.91 2.56 9.92 7.86z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 50 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-wind"><path d="M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2"></path></svg>

After

Width:  |  Height:  |  Size: 326 B

View File

@@ -6,19 +6,15 @@
<n-spin :show="true" :size="loadingSize" />
</div>
<div v-show="isEmpty" class="absolute-center">
<div class="relative" :class="emptyNetworkClass">
<svg-empty-data class="text-primary" />
<p class="absolute-lb w-full text-center">{{ emptyDesc }}</p>
<div class="relative">
<icon-local-empty-data :class="iconClass" />
<p class="absolute-lb w-full text-center" :class="descClass">{{ emptyDesc }}</p>
</div>
</div>
<div v-show="!network" class="absolute-center">
<div
class="relative"
:class="[{ 'cursor-pointer': showNetworkReload }, emptyNetworkClass]"
@click="handleReload"
>
<svg-network-error class="text-primary" />
<p class="absolute-lb w-full text-center">{{ networkErrorDesc }}</p>
<div class="relative" :class="{ 'cursor-pointer': showNetworkReload }" @click="handleReload">
<icon-local-network-error :class="iconClass" />
<p class="absolute-lb w-full text-center" :class="descClass">{{ networkErrorDesc }}</p>
</div>
</div>
</div>
@@ -26,12 +22,12 @@
</template>
<script setup lang="ts">
import { computed, watch, nextTick, onUnmounted } from 'vue';
import { NSpin } from 'naive-ui';
import { computed, nextTick, onUnmounted, watch } from 'vue';
import { NETWORK_ERROR_MSG } from '@/config';
import { SvgEmptyData, SvgNetworkError } from '@/components';
import { useBoolean } from '@/hooks';
defineOptions({ name: 'LoadingEmptyWrapper' });
interface Props {
/** 是否加载 */
loading: boolean;
@@ -43,8 +39,10 @@ interface Props {
placeholderClass?: string;
/** 空数据描述文本 */
emptyDesc?: string;
/** 空数据和网络异常占位class */
emptyNetworkClass?: string;
/** 图标的class */
iconClass?: string;
/** 描述文本的class */
descClass?: string;
/** 显示网络异常的重试点击按钮 */
showNetworkReload?: boolean;
}
@@ -53,9 +51,10 @@ const props = withDefaults(defineProps<Props>(), {
loading: false,
empty: false,
loadingSize: 'medium',
placeholderClass: 'bg-white',
placeholderClass: 'bg-white dark:bg-dark transition-background-color duration-300 ease-in-out',
emptyDesc: '暂无数据',
emptyNetworkClass: 'w-320px h-320px text-16px text-[#666]',
iconClass: 'text-320px text-primary',
descClass: 'text-16px text-[#666]',
showNetworkReload: false
});
@@ -94,4 +93,5 @@ onUnmounted(() => {
stopHandle();
});
</script>
<style scoped></style>

View File

@@ -8,13 +8,18 @@
<script setup lang="ts">
import { computed } from 'vue';
import { NCheckbox, NButton } from 'naive-ui';
defineOptions({ name: 'LoginAgreement' });
interface Props {
/** 是否勾选 */
value?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
value: true
});
interface Emits {
(e: 'update:value', value: boolean): void;
/** 点击协议 */
@@ -23,10 +28,6 @@ interface Emits {
(e: 'click-policy'): void;
}
const props = withDefaults(defineProps<Props>(), {
value: true
});
const emit = defineEmits<Emits>();
const checked = computed({
@@ -45,4 +46,5 @@ function handleClickPolicy() {
emit('click-policy');
}
</script>
<style scoped></style>

View File

@@ -1,4 +0,0 @@
import LoadingEmptyWrapper from './LoadingEmptyWrapper/index.vue';
import LoginAgreement from './LoginAgreement/index.vue';
export { LoadingEmptyWrapper, LoginAgreement };

View File

@@ -0,0 +1,22 @@
<template>
<div
class="dark:bg-[#18181c] dark:text-white dark:text-opacity-82 transition-all duration-300 ease-in-out"
:class="inverted ? 'bg-[#001428] text-white' : 'bg-white text-[#333639]'"
>
<slot></slot>
</div>
</template>
<script setup lang="ts">
defineOptions({ name: 'DarkModeContainer' });
interface Props {
inverted?: boolean;
}
withDefaults(defineProps<Props>(), {
inverted: false
});
</script>
<style scoped></style>

View File

@@ -1,10 +0,0 @@
<template>
<div
class="bg-white text-[#333639] dark:(bg-[#18181c] text-white text-opacity-82) transition-all duration-300 ease-in-out"
>
<slot></slot>
</div>
</template>
<script setup lang="ts"></script>
<style scoped></style>

View File

@@ -1,5 +1,5 @@
<template>
<div class="flex-center text-18px hover:text-primary cursor-pointer" @click="handleSwitch">
<div class="flex-center text-18px cursor-pointer" @click="handleSwitch">
<icon-mdi-moon-waning-crescent v-if="darkMode" />
<icon-mdi-white-balance-sunny v-else />
</div>
@@ -8,19 +8,21 @@
<script setup lang="ts">
import { computed } from 'vue';
defineOptions({ name: 'DarkModeSwitch' });
interface Props {
/** 暗黑模式 */
dark?: boolean;
}
interface Emits {
(e: 'update:dark', darkMode: boolean): void;
}
const props = withDefaults(defineProps<Props>(), {
dark: false
});
interface Emits {
(e: 'update:dark', darkMode: boolean): void;
}
const emit = defineEmits<Emits>();
const darkMode = computed({
@@ -36,4 +38,5 @@ function handleSwitch() {
darkMode.value = !darkMode.value;
}
</script>
<style scoped></style>

View File

@@ -0,0 +1,31 @@
<template>
<div class="flex-col-center wh-full">
<div class="text-400px text-primary">
<icon-local-no-permission v-if="type === '403'" />
<icon-local-not-found v-if="type === '404'" />
<icon-local-service-error v-if="type === '500'" />
</div>
<router-link :to="{ name: routeHomePath }">
<n-button type="primary">回到首页</n-button>
</router-link>
</div>
</template>
<script lang="ts" setup>
import { routeName } from '@/router';
defineOptions({ name: 'ExceptionBase' });
type ExceptionType = '403' | '404' | '500';
interface Props {
/** 异常类型 403 404 500 */
type: ExceptionType;
}
defineProps<Props>();
const routeHomePath = routeName('root');
</script>
<style scoped></style>

View File

@@ -2,37 +2,47 @@
<div v-if="showTooltip">
<n-tooltip :placement="placement" trigger="hover">
<template #trigger>
<div class="flex-center h-full cursor-pointer hover:bg-[#f6f6f6] dark:hover:bg-[#333]" :class="contentClass">
<div class="flex-center h-full cursor-pointer dark:hover:bg-[#333]" :class="contentClassName">
<slot></slot>
</div>
</template>
{{ tooltipContent }}
</n-tooltip>
</div>
<div v-else class="flex-center cursor-pointer hover:bg-[#f6f6f6] dark:hover:bg-[#333]" :class="contentClass">
<div v-else class="flex-center cursor-pointer dark:hover:bg-[#333]" :class="contentClassName">
<slot></slot>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { NTooltip } from 'naive-ui';
import type { FollowerPlacement } from 'vueuc';
import type { PopoverPlacement } from 'naive-ui';
defineOptions({ name: 'HoverContainer' });
interface Props {
/** tooltip显示文本 */
tooltipContent?: string;
/** tooltip的位置 */
placement?: FollowerPlacement;
placement?: PopoverPlacement;
/** class类 */
contentClass?: string;
/** 反转模式下 */
inverted?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
tooltipContent: '',
placement: 'bottom',
contentClass: ''
contentClass: '',
inverted: false
});
const showTooltip = computed(() => Boolean(props.tooltipContent));
const contentClassName = computed(
() => `${props.contentClass} ${props.inverted ? 'hover:bg-primary' : 'hover:bg-[#f6f6f6]'}`
);
</script>
<style scoped></style>

View File

@@ -0,0 +1,38 @@
<template>
<n-loading-bar-provider>
<n-dialog-provider>
<n-notification-provider>
<n-message-provider>
<slot></slot>
<naive-provider-content />
</n-message-provider>
</n-notification-provider>
</n-dialog-provider>
</n-loading-bar-provider>
</template>
<script setup lang="ts">
import { defineComponent, h } from 'vue';
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui';
defineOptions({ name: 'NaiveProvider' });
// 挂载naive组件的方法至window, 以便在路由钩子函数和请求函数里面调用
function registerNaiveTools() {
window.$loadingBar = useLoadingBar();
window.$dialog = useDialog();
window.$message = useMessage();
window.$notification = useNotification();
}
const NaiveProviderContent = defineComponent({
name: 'NaiveProviderContent',
setup() {
registerNaiveTools();
},
render() {
return h('div');
}
});
</script>
<style scoped></style>

View File

@@ -1,18 +0,0 @@
<template>
<div></div>
</template>
<script lang="ts" setup>
import { useLoadingBar, useDialog, useMessage, useNotification } from 'naive-ui';
// 挂载naive组件的方法至window, 以便在路由钩子函数和请求函数里面调用
function registerNaiveTools() {
window.$loadingBar = useLoadingBar();
window.$dialog = useDialog();
window.$message = useMessage();
window.$notification = useNotification();
}
registerNaiveTools();
</script>
<style scoped></style>

View File

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

View File

@@ -1,18 +0,0 @@
<template>
<n-loading-bar-provider>
<n-dialog-provider>
<n-notification-provider>
<n-message-provider>
<slot></slot>
<naive-provider-content />
</n-message-provider>
</n-notification-provider>
</n-dialog-provider>
</n-loading-bar-provider>
</template>
<script setup lang="ts">
import { NLoadingBarProvider, NDialogProvider, NNotificationProvider, NMessageProvider } from 'naive-ui';
import { NaiveProviderContent } from './components';
</script>
<style scoped></style>

View File

@@ -1,12 +1,10 @@
<template>
<div>
<svg-fill-logo v-if="fill" />
<svg-logo v-else />
</div>
<icon-local-logo-fill v-if="fill" />
<icon-local-logo v-else />
</template>
<script lang="ts" setup>
import { SvgLogo, SvgFillLogo } from './components';
defineOptions({ name: 'SystemLogo' });
interface Props {
/** logo是否填充 */
@@ -17,4 +15,5 @@ withDefaults(defineProps<Props>(), {
fill: false
});
</script>
<style scoped></style>

View File

@@ -1,31 +0,0 @@
<template>
<svg viewBox="0 0 158.88 158.88">
<path
d="M158.86.3q0,78.74,0,157.48c0,.9-.2,1.1-1.1,1.1q-78.77,0-157.52,0a2.61,2.61,0,0,1-.11-1.3q0-78,0-155.91C.14,0,0,.18,1.61.18h156A2.62,2.62,0,0,1,158.86.3Z"
style="fill: currentColor"
/>
<path
d="M158.86.3H2C0,.31.27,0,.27,2q0,78.42,0,156.85c-.07-.05-.25.12-.24-.12s0-.64,0-1Q0,79.46,0,1.14C0,.24.2,0,1.1,0l156.68,0C158.13.08,158.59-.2,158.86.3Z"
style="fill: #ffffff"
/>
<path
d="M93.65,51.52a68.65,68.65,0,0,1-6.47,28.81,1.72,1.72,0,0,0,.19,2c6.08,8.28,13.58,14.79,23.19,18.69a46.22,46.22,0,0,0,17.15,3.39,28.87,28.87,0,0,0,3.34-.25,6.2,6.2,0,0,1,7,5.12,6.07,6.07,0,0,1-5.15,7.14,50.39,50.39,0,0,1-18.06-1c-15.85-3.66-28-12.75-37.44-25.7a2.15,2.15,0,0,0-2.23-1.09C61.17,90,49,95.06,39.67,105.84a38.47,38.47,0,0,0-6.23,9.74A6.21,6.21,0,0,1,25.27,119,6.14,6.14,0,0,1,22,110.8a49.31,49.31,0,0,1,9.63-14.62c10.56-11.44,23.8-17.54,39.09-19.54a13.93,13.93,0,0,1,2.84-.34c1.61.14,2.18-.73,2.73-2A54.38,54.38,0,0,0,81.12,51a44,44,0,0,0-8-25,6.11,6.11,0,0,1-.65-6.46A6,6,0,0,1,77.75,16a6.34,6.34,0,0,1,5.66,3,53.61,53.61,0,0,1,7.17,14.28A59.33,59.33,0,0,1,93.65,51.52Z"
style="fill: #ffffff"
/>
<path
d="M46.92,118.63a6,6,0,0,1,1.35-3.88,37.89,37.89,0,0,1,22.5-14,6.08,6.08,0,0,1,6.65,2.47,6.18,6.18,0,0,1-3.84,9.63,26.09,26.09,0,0,0-15.71,9.77,6.2,6.2,0,0,1-10.95-4Z"
style="fill: #ffffff"
/>
<path
d="M124.3,92.8a34.66,34.66,0,0,1-9.82-2.48A35.46,35.46,0,0,1,99.83,79.87a6.19,6.19,0,0,1,2.84-9.93,5.79,5.79,0,0,1,6.44,1.73,26.79,26.79,0,0,0,16.51,8.85,6,6,0,0,1,5,5.54,6.21,6.21,0,0,1-4.29,6.46A6.55,6.55,0,0,1,124.3,92.8Z"
style="fill: #ffffff"
/>
<path
d="M69.32,53.27a33.46,33.46,0,0,1-2.27,12.52,6.21,6.21,0,0,1-10.94,1,6.09,6.09,0,0,1-.65-5.4,26,26,0,0,0-.53-18.25,6.21,6.21,0,0,1,11.49-4.72A40.24,40.24,0,0,1,69.32,53.27Z"
style="fill: #ffffff"
/>
</svg>
</template>
<script setup lang="ts"></script>
<style scoped></style>

View File

@@ -1,32 +0,0 @@
<template>
<svg viewBox="0 0 158.88 158.88">
<path
d="M0,158.86Q0,80,0,1.1C0,.2.2,0,1.1,0Q79.44,0,157.78,0c.9,0,1.1.2,1.1,1.1q0,78.35,0,156.68c0,.9-.2,1.1-1.1,1.1Q78.9,158.83,0,158.86Z"
transform="translate(0)"
style="fill: #ffffff00"
/>
<path
d="M81.28,55.9c-.1-11.67-2.93-22.55-9.37-32.38-1-1.5-2.14-2.86-2.5-4.71a8.1,8.1,0,0,1,4-8.61,7.89,7.89,0,0,1,9.3,1.23,36,36,0,0,1,5.9,8.83,75.18,75.18,0,0,1,8.44,28.58,83.21,83.21,0,0,1-5.23,36.74c-.91,2.47-1.91,4.9-3,7.28a1.2,1.2,0,0,0,0,1.41c9.58,13.3,21.76,23,37.85,27.24a54.35,54.35,0,0,0,19.68,1.57,7.72,7.72,0,0,1,8.36,6.9,7.9,7.9,0,0,1-6.7,9,64.74,64.74,0,0,1-23-1.33,77.68,77.68,0,0,1-36.93-19.88,93.64,93.64,0,0,1-11.91-13.71A2.18,2.18,0,0,0,73.87,103a72.75,72.75,0,0,0-27.38,7.55c-11.6,6-20.67,14.58-26.4,26.45a10.13,10.13,0,0,1-3.7,4.7A8,8,0,0,1,7.2,141a7.86,7.86,0,0,1-2.36-9.28,60.32,60.32,0,0,1,8.72-14.52c12.2-15.43,28.21-24.59,47.32-28.57A85.08,85.08,0,0,1,73.07,87a1.22,1.22,0,0,0,1.18-.8A76.06,76.06,0,0,0,80.78,63.9,57.87,57.87,0,0,0,81.28,55.9Z"
transform="translate(0)"
style="fill: currentColor"
/>
<path
d="M136.26,108.34a44.72,44.72,0,0,1-11.13-2.87,46.11,46.11,0,0,1-19.66-13.76,8,8,0,0,1,5.72-13.22,7.93,7.93,0,0,1,6.54,2.93A33.27,33.27,0,0,0,136.6,92.17a14.76,14.76,0,0,1,4.48,1.18,8.08,8.08,0,0,1,3.84,9.21C144,106.08,140.79,108.37,136.26,108.34Z"
transform="translate(0)"
style="fill: currentColor"
/>
<path
d="M55.66,33.32a7.61,7.61,0,0,1,6.64,5,49.14,49.14,0,0,1,3.64,17,46.33,46.33,0,0,1-2.46,17.28c-2,5.77-8.24,7.79-12.89,4.15a8.1,8.1,0,0,1-2.39-9,31.68,31.68,0,0,0,1.68-12.36,35.77,35.77,0,0,0-2.43-11C45.35,38.94,49.2,33.32,55.66,33.32Z"
transform="translate(0)"
style="fill: currentColor"
/>
<path
d="M77.92,126.57a8,8,0,0,1-6.68,7.86,32.88,32.88,0,0,0-19.7,12.19,8.13,8.13,0,0,1-11.21,1.62,8,8,0,0,1-1.41-11.58A51.05,51.05,0,0,1,54,123.81a45.85,45.85,0,0,1,14-5.1C73.35,117.67,77.91,121.27,77.92,126.57Z"
transform="translate(0)"
style="fill: currentColor"
/>
</svg>
</template>
<script setup lang="ts"></script>
<style scoped></style>

View File

@@ -1,4 +0,0 @@
import SvgLogo from './SvgLogo.vue';
import SvgFillLogo from './SvgFillLogo.vue';
export { SvgLogo, SvgFillLogo };

View File

@@ -1,7 +0,0 @@
import NaiveProvider from './NaiveProvider/index.vue';
import SystemLogo from './SystemLogo/index.vue';
import DarkModeSwitch from './DarkModeSwitch/index.vue';
import DarkModeContainer from './DarkModeContainer/index.vue';
import HoverContainer from './HoverContainer/index.vue';
export { NaiveProvider, SystemLogo, DarkModeSwitch, DarkModeContainer, HoverContainer };

View File

@@ -7,11 +7,13 @@
</template>
<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
import { computed, onMounted, ref, watch } from 'vue';
import { useElementSize } from '@vueuse/core';
import BScroll from '@better-scroll/core';
import type { Options } from '@better-scroll/core';
defineOptions({ name: 'BetterScroll' });
interface Props {
/** better-scroll的配置: https://better-scroll.github.io/docs/zh-CN/guide/base-scroll-options.html */
options: Options;
@@ -44,4 +46,5 @@ onMounted(() => {
defineExpose({ instance });
</script>
<style scoped></style>

View File

@@ -1,71 +0,0 @@
<template>
<div
class="relative flex-center h-30px pl-14px border-1px border-[#e5e7eb] dark:border-[#ffffff3d] rounded-2px cursor-pointer transition-colors duration-300 ease-in-out"
:class="[closable ? 'pr-6px' : 'pr-14px']"
:style="buttonStyle"
@mouseenter="setTrue"
@mouseleave="setFalse"
>
<span class="whitespace-nowrap">
<slot></slot>
</span>
<div v-if="closable" class="pl-10px">
<icon-close :is-active="isIconActive" :primary-color="primaryColor" @click="handleClose" />
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useBoolean } from '@/hooks';
import { addColorAlpha } from '@/utils';
import IconClose from '../IconClose/index.vue';
interface Props {
/** 激活状态 */
isActive?: boolean;
/** 主题颜色 */
primaryColor?: string;
/** 是否显示关闭图标 */
closable?: boolean;
/** 暗黑模式 */
darkMode?: boolean;
}
interface Emits {
/** 点击关闭图标 */
(e: 'close'): void;
}
const props = withDefaults(defineProps<Props>(), {
isActive: false,
primaryColor: '#1890ff',
closable: true,
darkMode: false
});
const emit = defineEmits<Emits>();
const { bool: isHover, setTrue, setFalse } = useBoolean();
const isIconActive = computed(() => props.isActive || isHover.value);
const buttonStyle = computed(() => {
const style: Record<string, string> = {};
if (isIconActive.value) {
style.color = props.primaryColor;
style.borderColor = addColorAlpha(props.primaryColor, 0.3);
if (props.isActive) {
const alpha = props.darkMode ? 0.15 : 0.1;
style.backgroundColor = addColorAlpha(props.primaryColor, alpha);
}
}
return style;
});
function handleClose(e: MouseEvent) {
e.stopPropagation();
emit('close');
}
</script>
<style scoped></style>

View File

@@ -1,79 +0,0 @@
<template>
<svg>
<defs>
<symbol id="geometry-left" viewBox="0 0 214 36">
<path d="M17 0h197v36H0v-2c4.5 0 9-3.5 9-8V8c0-4.5 3.5-8 8-8z"></path>
</symbol>
<symbol id="geometry-right" viewBox="0 0 214 36">
<use xlink:href="#geometry-left"></use>
</symbol>
<clipPath>
<rect width="100%" height="100%" x="0"></rect>
</clipPath>
</defs>
<svg width="52%" height="100%">
<use
xlink:href="#geometry-left"
width="214"
height="36"
:fill="fill"
class="transition-fill duration-300 ease-in-out"
></use>
</svg>
<g transform="scale(-1, 1)">
<svg width="52%" height="100%" x="-100%" y="0">
<use
xlink:href="#geometry-right"
width="214"
height="36"
:fill="fill"
class="transition-fill duration-300 ease-in-out"
></use>
</svg>
</g>
</svg>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { mixColor } from '@/utils';
interface Props {
/** 激活状态 */
isActive?: boolean;
/** 鼠标悬浮状态 */
isHover?: boolean;
/** 主题颜色 */
primaryColor?: string;
/** 暗黑模式 */
darkMode?: boolean;
}
/** 填充的背景颜色: [默认颜色, 暗黑主题颜色] */
type FillColor = [string, string];
const props = withDefaults(defineProps<Props>(), {
isActive: false,
isHover: false,
primaryColor: '#409EFF',
darkMode: false
});
const defaultColor: FillColor = ['#fff', '#18181c'];
const hoverColor: FillColor = ['#dee1e6', '#3f3c37'];
const mixColors: FillColor = ['#ffffff', '#000000'];
const fill = computed(() => {
const index = Number(props.darkMode);
let color = defaultColor[index];
if (props.isHover) {
color = hoverColor[index];
}
if (props.isActive) {
const alpha = props.darkMode ? 0.1 : 0.15;
color = mixColor(mixColors[index], props.primaryColor, alpha);
}
return color;
});
</script>
<style scoped></style>

View File

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

View File

@@ -1,66 +0,0 @@
<template>
<div
class="relative flex-y-center h-34px px-24px -mr-18px cursor-pointer"
:class="{ 'z-10': isActive, 'z-9': isHover }"
@mouseenter="setTrue"
@mouseleave="setFalse"
>
<div class="absolute-lb wh-full overflow-hidden">
<svg-radius-bg
class="wh-full"
:is-active="isActive"
:is-hover="isHover"
:dark-mode="darkMode"
:primary-color="primaryColor"
/>
</div>
<span class="relative whitespace-nowrap z-2">
<slot></slot>
</span>
<div v-if="closable" class="pl-18px">
<icon-close :is-active="isActive" :primary-color="primaryColor" @click="handleClose" />
</div>
<n-divider v-if="!isHover && !isActive" :vertical="true" class="absolute right-0 !bg-[#a4abb8] z-2" />
</div>
</template>
<script setup lang="ts">
import { NDivider } from 'naive-ui';
import { useBoolean } from '@/hooks';
import IconClose from '../IconClose/index.vue';
import { SvgRadiusBg } from './components';
interface Props {
/** 激活状态 */
isActive?: boolean;
/** 主题颜色 */
primaryColor?: string;
/** 是否显示关闭图标 */
closable?: boolean;
/** 暗黑模式 */
darkMode?: boolean;
}
interface Emits {
/** 点击关闭图标 */
(e: 'close'): void;
}
withDefaults(defineProps<Props>(), {
isActive: false,
primaryColor: '#409EFF',
closable: true,
darkMode: false,
isLast: false
});
const emit = defineEmits<Emits>();
const { bool: isHover, setTrue, setFalse } = useBoolean();
function handleClose(e: MouseEvent) {
e.stopPropagation();
emit('close');
}
</script>
<style scoped></style>

View File

@@ -2,10 +2,14 @@
<span>{{ value }}</span>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, watch, watchEffect } from 'vue';
import { useTransition, TransitionPresets } from '@vueuse/core';
import { computed, onMounted, ref, watch, watchEffect } from 'vue';
import { TransitionPresets, useTransition } from '@vueuse/core';
import { isNumber } from '@/utils';
defineOptions({ name: 'CountTo' });
type TansitionKey = keyof typeof TransitionPresets;
interface Props {
/** 初始值 */
startValue?: number;
@@ -28,7 +32,7 @@ interface Props {
/** 使用缓冲动画函数 */
useEasing?: boolean;
/** 缓冲动画函数类型 */
transition?: string;
transition?: TansitionKey;
}
const props = withDefaults(defineProps<Props>(), {
@@ -45,10 +49,12 @@ const props = withDefaults(defineProps<Props>(), {
transition: 'linear'
});
const emit = defineEmits<{
interface Emits {
(e: 'on-started'): void;
(e: 'on-finished'): void;
}>();
}
const emit = defineEmits<Emits>();
const source = ref(props.startValue);
let outputValue = useTransition(source);
@@ -76,7 +82,7 @@ function formatNumber(num: number | string) {
}
const { decimals, decimal, separator, suffix, prefix } = props;
let number = Number(num).toFixed(decimals);
number += '';
number = String(number);
const x = number.split('.');
let x1 = x[0];
@@ -106,3 +112,5 @@ onMounted(() => {
}
});
</script>
<style scoped></style>

View File

@@ -3,7 +3,9 @@
</template>
<script setup lang="ts">
import WebSiteLink from '../WebSiteLink/index.vue';
import WebSiteLink from './WebSiteLink.vue';
defineOptions({ name: 'GithubLink' });
interface Props {
/** github链接 */

View File

@@ -1,35 +0,0 @@
<template>
<div
class="relative flex-center w-18px h-18px text-14px"
:style="{ color: isActive ? primaryColor : defaultColor }"
@mouseenter="setTrue"
@mouseleave="setFalse"
>
<transition name="fade">
<icon-mdi:close-circle v-if="isHover" key="hover" class="absolute" />
<icon-mdi:close v-else key="unhover" class="absolute" />
</transition>
</div>
</template>
<script lang="ts" setup>
import { useBoolean } from '@/hooks';
interface Props {
/** 激活状态 */
isActive?: boolean;
/** 主题颜色 */
primaryColor?: string;
/** 默认颜色 */
defaultColor?: string;
}
withDefaults(defineProps<Props>(), {
isPrimary: false,
primaryColor: '#1890ff',
defaultColor: '#9ca3af'
});
const { bool: isHover, setTrue, setFalse } = useBoolean();
</script>
<style scoped></style>

View File

@@ -3,7 +3,7 @@
<template #trigger>
<n-input v-model:value="modelValue" readonly placeholder="点击选择图标">
<template #suffix>
<Icon :icon="modelValue ? modelValue : emptyIcon" class="text-30px p-5px" />
<svg-icon :icon="selectedIcon" class="text-30px p-5px" />
</template>
</n-input>
</template>
@@ -12,10 +12,10 @@
</template>
<div v-if="iconsList.length > 0" class="grid grid-cols-9 h-auto overflow-auto">
<template v-for="iconItem in iconsList" :key="iconItem">
<Icon
<svg-icon
:icon="iconItem"
class="border-1px border-[#d9d9d9] text-30px m-2px p-5px"
:style="{ 'border-color': modelValue === iconItem ? theme.themeColor : '' }"
:class="{ 'border-primary': modelValue === iconItem }"
@click="handleChange(iconItem)"
/>
</template>
@@ -25,10 +25,9 @@
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { NPopover, NInput, NEmpty } from 'naive-ui';
import { Icon } from '@iconify/vue';
import { useThemeStore } from '@/store';
import { computed, ref } from 'vue';
defineOptions({ name: 'IconSelect' });
interface Props {
/** 选中的图标 */
@@ -39,21 +38,16 @@ interface Props {
emptyIcon?: string;
}
interface Emits {
(e: 'update:value', val: string): void;
}
const props = withDefaults(defineProps<Props>(), {
emptyIcon: 'mdi:apps'
});
interface Emits {
(e: 'update:value', val: string): void;
}
const emit = defineEmits<Emits>();
const theme = useThemeStore();
const searchValue = ref('');
const iconsList = computed(() => props.icons.filter(v => v.includes(searchValue.value)));
const modelValue = computed({
get() {
return props.value;
@@ -63,10 +57,17 @@ const modelValue = computed({
}
});
const selectedIcon = computed(() => modelValue.value || props.emptyIcon);
const searchValue = ref('');
const iconsList = computed(() => props.icons.filter(v => v.includes(searchValue.value)));
function handleChange(iconItem: string) {
modelValue.value = iconItem;
}
</script>
<style lang="scss" scoped>
:deep(.n-input-wrapper) {
padding-right: 0;

View File

@@ -8,18 +8,20 @@
import { watch } from 'vue';
import { useImageVerify } from '@/hooks';
defineOptions({ name: 'ImageVerify' });
interface Props {
code?: string;
}
interface Emits {
(e: 'update:code', code: string): void;
}
const props = withDefaults(defineProps<Props>(), {
code: ''
});
interface Emits {
(e: 'update:code', code: string): void;
}
const emit = defineEmits<Emits>();
const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify();
@@ -36,4 +38,5 @@ watch(imgCode, newValue => {
defineExpose({ getImgCode });
</script>
<style scoped></style>

View File

@@ -0,0 +1,53 @@
<template>
<template v-if="renderLocalIcon">
<svg aria-hidden="true" width="1em" height="1em" v-bind="bindAttrs">
<use :xlink:href="symbolId" fill="currentColor" />
</svg>
</template>
<template v-else>
<Icon :icon="icon" v-bind="bindAttrs" />
</template>
</template>
<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { Icon } from '@iconify/vue';
defineOptions({ name: 'SvgIcon' });
/**
* 图标组件
* - 支持iconify和本地svg图标
* - 同时传递了icon和localIconlocalIcon会优先渲染
*/
interface Props {
/** 图标名称 */
icon?: string;
/** 本地svg的文件名 */
localIcon?: string;
}
const props = defineProps<Props>();
const attrs = useAttrs();
const bindAttrs = computed<{ class: string; style: string }>(() => ({
class: (attrs.class as string) || '',
style: (attrs.style as string) || ''
}));
const symbolId = computed(() => {
const { VITE_ICON_LOCAL_PREFFIX: preffix } = import.meta.env;
const defaultLocalIcon = 'no-icon';
const icon = props.localIcon || defaultLocalIcon;
return `#${preffix}-${icon}`;
});
/** 渲染本地icon */
const renderLocalIcon = computed(() => props.localIcon || !props.icon);
</script>
<style scoped></style>

View File

@@ -8,6 +8,8 @@
</template>
<script setup lang="ts">
defineOptions({ name: 'WebSiteLink' });
interface Props {
/** 网址名称 */
label: string;
@@ -17,4 +19,5 @@ interface Props {
defineProps<Props>();
</script>
<style scoped></style>

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