Compare commits

..

316 Commits

Author SHA1 Message Date
Soybean
1c3b4734fa chore(projects): release v1.0.6 2024-04-25 22:09:59 +08:00
Soybean
93c7ff7122 fix(projects): fix mix-menu blank. fixed #389 & cache mixMenuFixed 2024-04-25 22:07:23 +08:00
Soybean
1e14293d67 refactor(projects): useMixMenuContext replace useMixMenu 2024-04-25 21:49:14 +08:00
Soybean
19e65c1a9f chore(projects): update pnpm version requirement 2024-04-25 21:27:59 +08:00
Soybean
e57bf0b076 chore(deps): update deps 2024-04-25 15:01:23 +08:00
Soybean
5d45cef1f0 perf(hooks): perf useSignal 2024-04-25 15:00:47 +08:00
Soybean
d460e5cc6d perf(projects): add tsconfig.json for @sa/color-palette 2024-04-25 13:09:26 +08:00
Soybean
3b5e4b3405 refactor(hooks): refactor useSignal, useComputed 2024-04-25 13:08:38 +08:00
Soybean
dcd51f4cda chore(projects): use engines replace packageManager 2024-04-25 10:24:48 +08:00
Soybean
09f6464678 feat(hooks): add state hooks: useRef, useState, useSignal 2024-04-25 01:39:59 +08:00
Soybean
fdde679c70 perf(projects): remove useless prop title of NDrawer 2024-04-25 00:23:07 +08:00
Soybean
b266035800 fix(projects): supply $t import statement 2024-04-25 00:20:26 +08:00
Soybean
a1e432f81e Merge pull request #399 from alleycharming/main
fix(projects): added responseType judgment. #396
2024-04-24 18:41:24 +08:00
alleycharming
82eabab753 fix(projects): added responseType judgment. #396 2024-04-24 17:58:46 +08:00
Soybean
0d45b86cde chore(projects): release v1.0.5 2024-04-24 10:22:59 +08:00
Soybean
516f46a47e chore(projects): update pnpm-lock.yaml 2024-04-24 10:19:34 +08:00
Soybean
b52432a792 chore(projects): lower vue version to 3.4.23 2024-04-24 10:09:21 +08:00
Soybean
cf5bc88a75 docs(projects): update CHANGELOG.md 2024-04-24 01:52:03 +08:00
Soybean
03b1fbacc4 chore(projects): release v1.0.4 2024-04-24 01:42:40 +08:00
Soybean
9a66979f09 chore(deps): update deps 2024-04-24 01:39:42 +08:00
Soybean
c695208f62 fix(projects): recovery pnpm-lock.yaml 2024-04-24 01:38:19 +08:00
Soybean
3ceeb6f942 chore(deps): update deps 2024-04-24 01:04:50 +08:00
Soybean
04aa0972f9 fix(projects): fix tabs data when role is change. fixed #392 2024-04-24 01:01:52 +08:00
Soybean
cb83d6d90d fix(projects): fix routes data when role is change. fixed #391 2024-04-24 00:47:58 +08:00
Soybean
79d9c5143a docs(projects): update README.md 2024-04-23 17:31:15 +08:00
Soybean
5a5232bdf4 docs(projects): update README.md 2024-04-23 11:25:51 +08:00
Soybean
7392bebff9 chore(projects): update deps & update pnpm version & update eslint config 2024-04-23 11:20:55 +08:00
Soybean
23f283aa31 fix(projects): fix disabled page animate 2024-04-16 01:15:45 +08:00
Soybean
42e16a0165 chore(projects): update pnpm version 2024-04-16 01:02:51 +08:00
Soybean
ac92817343 chore(deps): update deps 2024-04-16 01:01:46 +08:00
Soybean
93191737dd refactor(hooks): refactor @sa/color-palette 2024-04-16 00:57:24 +08:00
Soybean
d9af5aa2d3 fix(projects): fix CHANGELOG versions 2024-04-16 00:17:10 +08:00
Soybean
d984f75b80 chore(projects): release v1.0.3 2024-04-16 00:15:37 +08:00
Soybean
27c53cd688 fix(projects): fix update theme color 2024-04-16 00:14:32 +08:00
Soybean
b7f0749170 perf(projects): perf code 2024-04-16 00:03:00 +08:00
Soybean
cb8ea2531d Merge pull request #386 from paynezhuang/main 2024-04-15 16:27:08 +08:00
paynezhuang
c6648b6c8b feat(hooks): deleting the route export of useRoutePush, use vue-router 2024-04-15 16:20:30 +08:00
Soybean
bb74d9949b refactor(projects): update naive-ui.d.ts 2024-04-14 15:44:48 +08:00
Soybean
60beff7e63 fix(projects): update union-key.d.ts 2024-04-14 12:48:02 +08:00
Soybean
d6eda8f9ed fix(projects): fix axios createRequest: add default state 2024-04-09 17:44:05 +08:00
Soybean
f4a9cf8339 docs(projects): update README.md 2024-04-09 15:37:23 +08:00
Soybean
efc0e25c7f fix(projects): fix SvgIcon inheritAttrs warning 2024-04-09 07:27:48 +08:00
Soybean
35310ed73c Merge pull request #381 from paynezhuang/main 2024-04-08 19:04:13 +08:00
paynezhuang
001059cca0 fix(projects): fix menu edit rules 2024-04-08 11:44:12 +08:00
Soybean
4af884c08b chore(projects): release v1.0.2 2024-04-08 08:00:41 +08:00
Soybean
41e470ed6e refactor(projects): refactor addThemeVarsToHtml 2024-04-08 07:59:50 +08:00
Soybean
2f15a2ac6a fix(projects): unify border-radius of Tag. fixed #378 2024-04-08 07:50:26 +08:00
Soybean
1c72dc76ee chore(projects): disabled unocss eslint rule: order-attributify 2024-04-08 07:46:02 +08:00
Soybean
a1b484a8eb chore(deps): update deps 2024-04-08 07:42:46 +08:00
Soybean
d9410e416e Merge pull request #377 from yanbowe/main
fix(styles): fix css var is inserted repeatedly
2024-04-07 17:41:08 +08:00
燕博文
769d84a7f4 fix(styles): fix css var is inserted repeatedly 2024-04-07 17:34:33 +08:00
Soybean
0fbb00cee1 chore(projects): release v1.0.1 2024-04-03 00:21:42 +08:00
Soybean
cc539974b2 fix(projects): add maxWidth for GlobalTab to fix bg with gap. fixed #350 2024-04-03 00:20:55 +08:00
Soybean
1ec5ea0ff1 fix(projects): fix flatRequest error type. fixed #376 2024-04-03 00:02:09 +08:00
Soybean
9125cc9b60 chore(projects): update pnpm version 2024-04-02 23:14:34 +08:00
Soybean
76011af8a9 docs(projects): update README.md 2024-04-02 23:13:31 +08:00
Soybean
4babbe19a3 chore(projects): update deps 2024-04-02 23:00:17 +08:00
Soybean
ae508bc572 chore(projects): release v1.0.0 2024-03-31 17:07:09 +08:00
Soybean
c8260221dd chore(projects): release v1.0.0-beta.3 2024-03-31 17:06:35 +08:00
Soybean
82b53d7e98 chore(deps): update deps 2024-03-31 17:05:33 +08:00
Soybean
f69e1523c0 docs(projects): update README.md 2024-03-29 10:03:00 +08:00
Soybean
c0009203c6 chore(projects): add .gitattributes 2024-03-28 00:37:58 +08:00
Soybean
f23e1f7ea4 chore(projects): release v1.0.0-beta.2 2024-03-27 22:49:51 +08:00
Soybean
f89e6c0361 fix(projects): fix pin-toggler toolTip zIndex 2024-03-27 22:32:56 +08:00
Soybean
6b5132c169 chore(deps): update deps 2024-03-27 22:27:20 +08:00
Soybean
1a7070f02b docs(projects): update README.md 2024-03-26 14:14:44 +08:00
Soybean
07d8d25dbf docs(projects): update README.md 2024-03-26 14:13:56 +08:00
Soybean
a0bad57a4e perf(projects): perf code 2024-03-25 23:20:49 +08:00
Soybean
8c7ea235d9 docs(projects): add communication 2024-03-25 11:47:00 +08:00
Soybean
06e204a7fe ci(projects): add issue template 2024-03-25 10:48:22 +08:00
Soybean
7b298c679e ci(projects): update release.yml 2024-03-25 10:37:38 +08:00
Soybean
25fc24c746 chore(projects): release v1.0.0-beta.1 2024-03-25 10:32:03 +08:00
Soybean
4cb17c7440 ci(projects): add github actions config 2024-03-25 10:26:58 +08:00
Soybean
46b6156620 docs(projects): add CHANGELOG.md 2024-03-25 10:18:04 +08:00
Soybean
23a4098bba fix(projects): fix route init 2024-03-25 09:55:16 +08:00
Soybean
000c68ad60 Merge commit '2c543f19ec100af4d6224787956550910e5fb7c8' 2024-03-25 03:14:28 +08:00
Soybean
2c543f19ec fix(projects): fix repeat routes 2024-03-25 03:13:53 +08:00
Soybean
37d20b8e0d refactor(projects): new route guard 2024-03-25 02:42:50 +08:00
Soybean
c11d56da29 feat(projects): add auth example 2024-03-24 15:39:41 +08:00
Soybean
41e8bc44f8 feat(projects): add request exception example page 2024-03-24 06:23:56 +08:00
Soybean
11a6a3bd80 feat(projects): add request refresh token & logout 2024-03-24 05:11:30 +08:00
Soybean
1ed33dc47a feat(projects): login page: register 2024-03-24 04:10:55 +08:00
Soybean
c91dd282a6 feat(projects): login page: code-login 2024-03-24 04:03:49 +08:00
Soybean
f91ef30bd5 refactor(projects): perf code 2024-03-24 03:02:08 +08:00
Soybean
187098136e feat(projects): pef manage role 2024-03-23 15:51:04 +08:00
Soybean
0abbfa5d0c perf(projects): manage menu: add transform to component 2024-03-22 01:31:38 +08:00
Soybean
71f2c5535b perf(projects): perf manage menu 2024-03-22 01:23:24 +08:00
Soybean
49558ca048 feat(projects): change borderRadius to 6px of naiveUI 2024-03-21 19:49:00 +08:00
Soybean
c0a65a165a chore(deps): update deps 2024-03-21 19:44:22 +08:00
Soybean
3fd15e5649 refactor(projects): finish refactor useTable and apply 2024-03-21 19:40:48 +08:00
Soybean
4158a72bd8 feat(projects): update 2024-03-21 08:29:15 +08:00
Soybean
8630175a3f refactor(projects): finish refactor useTable 2024-03-19 02:46:53 +08:00
Soybean
c3efa1b6e0 refactor(projects): refactor useTable 2024-03-19 02:44:03 +08:00
Soybean
51d7758903 Merge pull request #352 from Li-0221/main
fix(components): fix homeTab closeRight and disable colseLeft
2024-03-18 14:56:57 +08:00
~li
d28bf52683 fix(components): fix homeTab closeRight and disable colseLeft 2024-03-18 13:58:22 +08:00
Soybean
455e48f792 fix(projects): fix class name conflict with unocss icon 2024-03-18 07:38:21 +08:00
Soybean
6ad51e9431 chore(projects): update pnpm version 2024-03-18 07:34:43 +08:00
Soybean
0fee104bf9 chore(deps): update deps 2024-03-18 07:32:39 +08:00
Soybean
0cc8f05a26 fix(projects): fix table row-key ts type 2024-03-16 16:18:44 +08:00
Soybean
03c2f3aaf0 Merge pull request #349 from vastsa/main
fix(projects):fix invalid footer-height for theme configuration
2024-03-13 14:56:44 +08:00
lan
6c5404610b fix(projects):fix invalid footer-height for theme configuration 2024-03-13 14:46:12 +08:00
Soybean
8143b0063c chore(projects): update deps & fix eslint vue rule 2024-03-13 14:28:12 +08:00
Soybean
72745229d6 perf(components): perf global-search 2024-03-11 22:57:37 +08:00
Soybean
779ba4e415 perf(projects): perf manage page style 2024-03-11 22:42:22 +08:00
Soybean
b2ee9eef8c chore(deps): update deps 2024-03-11 21:38:10 +08:00
Soybean
7065f6f073 chore(projects): update pnpm version 2024-03-10 14:37:31 +08:00
Soybean
dc24a36739 perf(projects): perf code 2024-03-10 14:36:05 +08:00
Soybean
c05e7ff360 Merge branch 'main' into example 2024-03-10 14:24:46 +08:00
Soybean
2b7e3c237d Merge pull request #347 from Azir-11/main
feat(projects): Add route meta parameter:fixedQuery
2024-03-10 13:50:46 +08:00
Azir-11
874aaca5bb feat(projects): Add route meta parameter:fixedQuery 2024-03-10 05:19:21 +08:00
Soybean
7a2f54be8b Merge pull request #345 from Azir-11/main
style(components): Uniform icon size for header
2024-03-07 22:27:23 +08:00
青菜白玉汤
b37c1e94a0 style(components): Uniform icon size for header 2024-03-07 22:19:06 +08:00
Soybean
cb35a94baf Merge branch 'main' into example 2024-03-07 21:52:49 +08:00
Soybean
02d4b0a574 chore(deps): update deps 2024-03-07 21:51:08 +08:00
Soybean
4e29acaae3 chore(projects): update vscode extensions.json 2024-03-07 21:46:26 +08:00
Soybean
7898d08174 Merge pull request #343 from soybeanjs/main
merge: main to example
2024-03-06 17:34:20 +08:00
Soybean
ed1c585a6b Merge pull request #342 from yanbowe/main 2024-03-06 12:03:21 +08:00
燕博文
0126da4778 feat(projects): globalSearch add i18n 2024-03-06 11:43:27 +08:00
燕博文
04aa10b477 perf(components): components name is converted to uppercase 2024-03-06 11:05:54 +08:00
燕博文
9ea878915e feat(components): add GlobalSearch components 2024-03-06 10:59:40 +08:00
Soybean
05db8c08d5 perf(projects): perf code 2024-03-04 14:01:27 +08:00
Soybean
ffc95d2b7b fix(projects): fix proxy config 2024-03-04 13:57:47 +08:00
Soybean
c8019c4ff7 fix(projects): fix proxy config 2024-03-04 10:23:25 +08:00
Soybean
b546ff8625 refactor(projects): use enquirer replace prompts 2024-03-03 20:43:21 +08:00
Soybean
14aa856a0f chore(deps): update deps 2024-03-03 19:48:00 +08:00
Soybean
3db82acb02 chore(projects): update launch.json 2024-03-03 13:25:18 +08:00
Soybean
4063529a25 chore(projects): add unocss eslint config 2024-03-03 03:53:53 +08:00
Soybean
b4c00ce199 refactor(projects): refactor unocss shortcuts: wh-full => size-full 2024-03-03 03:51:04 +08:00
Soybean
fb3b94b1e3 chore(deps): update deps 2024-03-03 03:48:01 +08:00
Soybean
43193e2808 refactor(projects): refactor service env config 2024-03-02 12:31:19 +08:00
Soybean
bccd6cb3c3 fix(projects): fix repeat home tab 2024-03-02 11:13:09 +08:00
Soybean
a17d68eb11 Merge pull request #337 from Azir-11/main
Fix home mount issue for static and dynamic routes
2024-03-01 13:32:18 +08:00
恕瑞玛的皇帝
9cf2a513f7 fix(projects): Fix homepage mount error under dynamic routing 2024-03-01 13:12:28 +08:00
恕瑞玛的皇帝
0123c37de2 fix(projects): Fix the logic of root route redirection to home 2024-03-01 11:35:25 +08:00
Soybean
418302a34b docs(projects): update README.md 2024-03-01 02:52:15 +08:00
Soybean
7fa87f53d1 perf(projects): perf code 2024-03-01 02:44:09 +08:00
Soybean
b235ef3bc0 Merge pull request #335 from dodu2014/main
fix(hooks): Fix Naive Pagination's outdated API
2024-02-29 22:28:32 +08:00
tnt group
3743612d62 fix(hooks): Fix Naive Pagination's outdated API 2024-02-29 22:22:15 +08:00
Soybean
c3e8ef2ed2 Merge pull request #333 from dodu2014/main
feat(components): enhance the custom strength of the 'TableHeaderOper…
2024-02-26 10:44:31 +08:00
tnt group
ccc2b674db fix(components): supplement the NaiveUI type 2024-02-26 10:40:44 +08:00
tnt group
fdf64f71f4 feat(components): enhance the custom strength of the 'TableHeaderOperation' component 2024-02-26 06:40:32 +08:00
Soybean
9c4ba6650d chore(deps): update deps 2024-02-26 02:11:37 +08:00
Soybean
1a6be003e2 feat(projects): mock manage list data with pagination 2024-02-26 01:59:06 +08:00
Soybean
c7e2c55996 fix(projects): fix table x-scroll. fixed #324 2024-02-23 22:17:31 +08:00
Soybean
0a3efe3442 fix(projects): add route icon: fucntion_hide-child 2024-02-23 21:59:21 +08:00
Soybean
7256ad4ee3 feat(projects): support directory menu hide all child menus. fixed #325 2024-02-23 21:51:20 +08:00
Soybean
8ee2acc1fc Merge pull request #327 from Azir-11/main
fix(projects): Missing default value for tab icon
2024-02-23 21:16:21 +08:00
Azir
72a4679c0a fix(projects): Missing default value for tab icon 2024-02-23 15:27:50 +08:00
Soybean
3bdcbc71eb fix(projects): fix resolve alias 2024-02-20 22:21:46 +08:00
Soybean
9772aec2bd chore(projects): update deps & update pnpm version 2024-02-20 22:01:23 +08:00
Soybean
c18d82f9f8 fix(projects): fix build [unocss]: build failed to load icon "close", fixed #319 2024-02-20 21:57:17 +08:00
Soybean
114c835921 Merge pull request #316 from Azir-11/main
fix(projects): The matched value of TabRoute should be optional
2024-02-17 18:42:16 +08:00
Azir
e6fed1fdb5 fix(projects): The matched value of TabRoute should be optional 2024-02-11 13:52:03 +08:00
Soybean
5d75ca924e Merge pull request #315 from Azir-11/main 2024-02-06 18:03:35 +08:00
Azir
2d102a054a feat(projects): Add type to TabRoute: matched 2024-02-06 17:51:40 +08:00
Azir
a9c98d9655 fix(projects): Fix the issue of tab error displaying parent localIcon
Fix the issue of abnormal tab display when the parent menu has a localIcon and the child menu does not have one
2024-02-06 17:42:51 +08:00
Soybean
ef4af79a11 docs(projects): update README.md 2024-02-04 01:09:48 +08:00
Soybean
806a1cba5f chore(projects): update repository url 2024-02-04 01:04:31 +08:00
Soybean
147f60d17e chore(projects): update pnpm-lock.yaml 2024-02-04 00:48:04 +08:00
Soybean
579636b0b4 chore(projects): update deps & remove packages docs 2024-02-04 00:28:38 +08:00
Soybean
ebb154840a chore(projects): add dev and build command with service env 2024-02-04 00:26:15 +08:00
Soybean
ae6b6134f3 fix(projects): fix request msg 2024-02-04 00:14:17 +08:00
Soybean
6ea9b85ff1 docs(projects): update README.md 2024-02-03 04:54:18 +08:00
Soybean
0b56e44c0e chore(projects): update @elegant-router/vue, fix inject name in windows 2024-02-02 00:52:29 +08:00
Soybean
13001bc83e chore(projects): update deps & fix keep-alive 2024-02-01 22:46:34 +08:00
Soybean
adec0d7501 chore(projects): update pnpm version 2024-02-01 22:08:17 +08:00
Soybean
db17c916ef feat(projects): page manage_menu operateDrawer 2024-01-30 00:33:26 +08:00
Soybean
e2085e058d docs(projects): update README.md 2024-01-29 22:25:19 +08:00
Soybean
b8f85692d6 Merge pull request #306 from smileluck/main 2024-01-29 16:38:11 +08:00
smileluck
da24642783 fix(projects): default proxy prefix 2024-01-29 16:31:24 +08:00
Soybean
86b445c26a docs(projects): update README.md 2024-01-29 01:50:29 +08:00
Soybean
4e4d2de54a docs(projects): update README.md 2024-01-29 01:40:37 +08:00
Soybean
7770b378f3 fix(projects): fix manage_user title 2024-01-29 01:19:29 +08:00
Soybean
0aa75c0422 perf(projects): perf page manage_menu style 2024-01-28 23:49:01 +08:00
Soybean
87d65d3b1c feat(projects): page manage_menu 2024-01-28 23:38:44 +08:00
Soybean
f8467ceb17 refactor(projects): manage_route => manage_menu 2024-01-28 17:14:46 +08:00
Soybean
babdb5d5cc perf(projects): perf table columns style 2024-01-28 16:37:52 +08:00
Soybean
8a170eeebd feat(projects): page manage_user 2024-01-28 16:24:43 +08:00
Soybean
a19f895cd9 refactor(projects): perf page manage_role 2024-01-28 14:27:07 +08:00
Soybean
39aa7aa2de perf(projects): perf page manage_role, useTable 2024-01-28 01:35:01 +08:00
Soybean
0e9e2e1dc0 refactor(projects): page manage_role: extract module 2024-01-28 01:25:04 +08:00
Soybean
237c6d227e feat(projects): page manage_role 2024-01-28 00:44:21 +08:00
Soybean
2724169eb6 refactor(projects): update mock api 2024-01-26 21:26:26 +08:00
Soybean
4031fafc1f chore(projects): remove soybean.svg 2024-01-26 21:11:10 +08:00
Soybean
456c318ac6 perf(projects): echarts loading style 2024-01-26 02:27:10 +08:00
Soybean
b5477e8996 refactor(projects): perf page function_tab 2024-01-26 02:00:34 +08:00
Soybean
59bec2d923 refactor(projects): login components => modules 2024-01-26 01:52:24 +08:00
Soybean
4c61c6ff3c refactor(projects): perf page home 2024-01-26 01:51:06 +08:00
Soybean
123fd4f96c style(projects): sort defineProps, defineEmits with TS type 2024-01-25 23:24:35 +08:00
Soybean
b2c61f0306 perf(components): perf count-to 2024-01-25 23:16:12 +08:00
Soybean
9cc7ee5c94 chore(deps): update deps 2024-01-25 23:15:01 +08:00
Soybean
502a4d2b85 chore(projects): remove @simonwep/pickr 2024-01-25 21:30:00 +08:00
Soybean
c1afb9dc50 fix(projects): perf card style 2024-01-25 16:01:23 +08:00
Soybean
d886e50fd3 fix(projects): fix horizontal menu 2024-01-25 15:26:46 +08:00
Soybean
4aae6a5297 fix(projects): remove space in tab content 2024-01-25 14:38:16 +08:00
Soybean
b5551d674a refactor(projects): use naive-ui color-picker 2024-01-25 14:35:49 +08:00
Soybean
6114b9f9bd chore(deps): update deps 2024-01-25 12:00:45 +08:00
Soybean
ea02b23721 chore(projects): update pnpm version 2024-01-25 11:59:11 +08:00
Soybean
6ff86e7777 feat(projects): add page function_tab 2024-01-25 02:35:37 +08:00
Soybean
7bd1e47af9 feat(projects): finish page home 2024-01-25 01:12:33 +08:00
Soybean
62e4da053d feat(projects): page home & perf useEcharts 2024-01-24 01:48:23 +08:00
Soybean
0fae9932ac docs(projects): update README.md 2024-01-23 17:43:41 +08:00
Soybean
2400c02655 feat(projects): @sa/axios: add qs stringify for params 2024-01-23 00:30:43 +08:00
Soybean
b3779a6313 fix(projects): fix themeDrawer copy 2024-01-22 00:35:13 +08:00
Soybean
99097b4632 fix(components): fix tooltip zIndex of ButtonIcon 2024-01-22 00:20:00 +08:00
Soybean
1b5caa08be fix(projects): fix themeDrawer darkMode segement 2024-01-22 00:01:35 +08:00
Soybean
db747c4a03 style(projects): fix tooltip zIndex of ButtonIcon 2024-01-21 23:55:00 +08:00
Soybean
8b6de484b8 fix(projects): fix page about style in mobile 2024-01-21 23:48:44 +08:00
Soybean
697c1b6106 feat(projects): add script: gen-route 2024-01-21 23:21:27 +08:00
Soybean
41349555bf perf(projects): remove @soybeanjs/cli 2024-01-21 22:41:01 +08:00
Soybean
dafb6fa06f feat(projects): packages/scripts: add command changelog,release 2024-01-21 18:17:11 +08:00
Soybean
840e7f99fc chore(deps): update deps 2024-01-20 20:34:00 +08:00
Soybean
a24f963121 chore(projects): lock deps versions 2024-01-20 20:32:58 +08:00
Soybean
f59f34884c feat(projects): filter tabs which are not in routes 2024-01-20 19:58:58 +08:00
Soybean
b4f3dd2f7a refactor(projects): refactor app-loading 2024-01-20 19:16:34 +08:00
Soybean
726abe4208 feat(hooks): add use-echarts 2024-01-19 02:17:17 +08:00
Soybean
b43c925696 feat(projects): add custom route exception 2024-01-19 01:28:46 +08:00
Soybean
4955f1af89 feat(projects): add page: about 2024-01-18 23:51:04 +08:00
Soybean
f1b86ccb1d chore(deps): update deps 2024-01-18 23:49:06 +08:00
Soybean
affcc26b3d feat(projects): add copyright, unocss shortcut: card-wrapper, update package.json 2024-01-18 23:43:33 +08:00
Soybean
03c42aa8cc docs(projects): update README.md 2024-01-18 22:46:16 +08:00
Soybean
c260fe26ae docs(projects): update README.md 2024-01-18 22:10:22 +08:00
Soybean
0ba19d5479 fix(projects): fix app loading theme color 2024-01-18 02:44:10 +08:00
Soybean
b30c0359f6 docs(projects): update README.md 2024-01-18 02:17:07 +08:00
Soybean
57b6d8a058 docs(projects): update README.md 2024-01-18 02:09:48 +08:00
Soybean
6a771eae42 docs(projects): update README.md 2024-01-18 01:57:20 +08:00
Soybean
c624f325c7 perf(projects): remove useless file 2024-01-18 01:08:31 +08:00
Soybean
c65451b34c feat(projects): add app loading 2024-01-17 22:48:36 +08:00
Soybean
2372dc9bb7 fix(projects): fix theme mode segment 2024-01-17 22:09:22 +08:00
Soybean
d16a9d58a8 docs(projects): update README 2024-01-17 02:16:47 +08:00
Soybean
2371ba8448 docs(projects): add README 2024-01-17 02:06:19 +08:00
Soybean
4d8469e2d1 style(projects): update theme mode segment height 2024-01-16 23:43:18 +08:00
Soybean
5023f37125 chore(projects): update eslint config 2024-01-16 23:32:22 +08:00
Soybean
5534294163 chore(deps): update deps 2024-01-16 23:31:45 +08:00
Soybean
5c49d24504 perf(projects): perf code 2024-01-16 02:07:31 +08:00
Soybean
87143172e8 fix(projects): fix menu indent 2024-01-16 01:56:05 +08:00
Soybean
f6bab0cc9d perf(projects): add detailed annotations for route role 2024-01-16 01:54:19 +08:00
Soybean
1335d47ae8 fix(projects): add duration of login success notification 2024-01-16 01:52:32 +08:00
Soybean
bac1632457 feat(projects): @sa/axios: createRequest, createFlatRequest, createHookRequest 2024-01-16 01:50:12 +08:00
Soybean
fbf4cc430d fix(projects): fix i18n vscode settings 2024-01-16 01:37:58 +08:00
Soybean
55f7638531 chore(projects): update pnpm version 2024-01-16 01:36:54 +08:00
Soybean
36fe1dad0b chore(deps): update deps 2024-01-16 01:34:52 +08:00
Soybean
ff4c8cc21c Merge pull request #295 from Azir-11/v1.0-beta
feat(router): add sortRoutesByOrder function
2024-01-16 01:24:29 +08:00
Azir-11
0cf09baef8 feat(router): add sortRoutesByOrder function 2024-01-12 02:51:39 +08:00
Soybean
257bbfc527 Merge pull request #294 from Azir-11/v1.0-beta
fix(projects): Fix welcome notification not closing
2024-01-11 12:53:15 +08:00
Azir
748cfa2c62 fix(projects): Fix welcome notification not closing 2024-01-11 12:17:41 +08:00
Soybean
d778560dbd chore(projects): update @sa/scripts 2023-12-14 21:54:10 +08:00
Soybean
a748166399 style(projects): format code 2023-12-14 21:45:29 +08:00
Soybean
a176dc443e chore(projects): use eslint flat config & update config 2023-12-14 21:00:53 +08:00
Soybean
3346bcdfad refactor(projects): fix conflict with locale file 2023-11-21 16:54:35 +08:00
Soybean
1bac3b78d7 perf(projects): env config 2023-11-20 21:32:55 +08:00
Soybean
8081e19ebc perf(projects): perf code 2023-11-18 00:36:10 +08:00
Soybean
96e4aff5c8 feat(projects): support Vite5 2023-11-18 00:34:14 +08:00
Soybean
377db8298b chore(project): delete src/locales/lang/zh-CN.ts 2023-11-17 12:00:20 +08:00
Soybean
a8a77ea5d7 fix(projects): rename zh-ch 2023-11-17 11:39:13 +08:00
Soybean
e918a2c0f5 feat(projects): 1.0 beta 2023-11-17 10:25:32 +08:00
Soybean
1ea4817f6a docs(projects): update README.md 2023-11-14 12:35:02 +08:00
Soybean
ecbb96f3a5 Merge pull request #286 from yanbowe/main
perf(components): Optimize internationalized menu search code
2023-10-18 22:42:35 +08:00
燕博文
296a2d2f0e perf(components): Optimize menu search code 2023-10-18 21:13:05 +08:00
燕博文
8c1ef4b0fd perf(components): Optimize internationalized menu search code 2023-10-18 20:58:04 +08:00
Soybean
04d3330463 Merge pull request #285 from Kori000/main
feat: internationalized menu search
2023-10-18 00:01:11 +08:00
Kori
9e115daeb9 feat: internationalized menu search 2023-10-16 22:53:01 +08:00
Soybean
3eaf05bd4d chore(deps): update deps 2023-10-12 22:26:11 +08:00
Soybean
a195980547 Merge pull request #280 from Particaly/main
fix(projects): 修复路由命名为包含关系时导致导航数据出错的问题
2023-09-27 23:08:18 +08:00
J.S.Patrick
f04a929856 Update menu.ts 2023-09-27 08:43:12 +08:00
J.S.Patrick
5b8af29496 Update breadcrumb.ts
防止找不到顶级路由时报错
2023-09-26 13:50:04 +08:00
pantao
766369f911 fix(projects): 修复路由命名为包含关系时导致导航数据出错的问题 2023-09-25 17:16:25 +08:00
Soybean
f6c6dbd312 refactor(projects): remove plugin-web-update-notification 2023-09-21 01:08:28 +08:00
Soybean
783648f516 docs(projects): update README.md 2023-09-21 00:55:19 +08:00
Soybean
ead48f4502 chore(projects): release v0.10.4 2023-09-20 23:42:22 +08:00
Soybean
305d95672a chore(deps): update deps 2023-09-20 23:40:51 +08:00
Soybean
8a792c7d63 Merge pull request #278 from eltociear/patch-1
docs(projects): update README.md
2023-09-20 23:31:05 +08:00
Ikko Eltociear Ashimine
93ed5ad085 docs(projects): update README.md
github -> GitHub
2023-09-20 14:35:47 +09:00
Soybean
41f23386b2 fix(projects): fix reload button animate 2023-09-07 23:25:30 +08:00
Soybean
c91644b829 feat(projects): add plugin-web-update-notification 2023-09-06 01:27:39 +08:00
Soybean
073fd16bd7 refactor(projects): update soybean domain 2023-09-06 01:07:29 +08:00
Soybean
f92ee770e0 refactor(projects): add reCacheRoute method 2023-09-06 00:34:48 +08:00
Soybean
1e6d52357e Merge pull request #272 from linjiangl/main
chore(projects): When tab is switched, keep the page without refreshing
2023-09-06 00:18:04 +08:00
Soybean
751ded44f3 chore(deps): update deps 2023-09-06 00:14:35 +08:00
Soybean
8567f3e34e Merge pull request #271 from lapislazulisch/dynamicRoute
Dynamic route
2023-08-31 00:31:40 +08:00
linjiangl
83f2514403 chore(projects): When tab is switched, keep the page without refreshing 2023-08-24 16:26:49 +08:00
lapislazulisch
ad6ac7222c fix(components): 修复动态路由home页404 2023-08-23 16:03:19 +08:00
lapislazulisch
3ae1952624 fix(components): 修复动态路由主页404 2023-08-23 16:00:17 +08:00
lapislazulisch
3db549af40 fix:动态路由首页404 2023-08-23 15:41:40 +08:00
Soybean
94179ae552 Merge pull request #269 from snowords/main
Update Docker deployment method and git hooks init command
2023-08-11 16:49:32 +08:00
muzzyh
7f35e87ed8 docs(projects): update git hooks init command 2023-08-11 14:47:47 +08:00
muzzyh
00da0009ef docs(projects): update Docker deployment method 2023-08-11 11:08:05 +08:00
Soybean
cffc30afa3 chore(projects): correct word spell & eslint fix code 2023-08-04 01:55:00 +08:00
Soybean
24cf1d9284 style(projects): prettier format code 2023-08-04 01:39:12 +08:00
Soybean
9296e6987d chore(deps): update deps 2023-08-04 01:37:21 +08:00
Soybean
809fa85706 perf(hooks): perf useHookTable 2023-07-26 00:50:21 +08:00
Soybean
b3ae7605d3 feat(hooks): add useHookTable 2023-07-24 00:59:45 +08:00
Soybean
864ec4737d fix(projects): correct the lang file name & add recommend vscode plugin i18n-ally 2023-07-23 20:31:59 +08:00
Soybean
854d0bcf20 feat(projects): new i18n function $t & login page and setting drawer config i18n 2023-07-23 20:29:39 +08:00
Soybean
458e387b68 chore(projects): correct the word spell 2023-07-19 23:44:18 +08:00
Soybean
56c770c49d chore(projects): update VSCode setting 2023-07-19 23:28:32 +08:00
Soybean
946447394d chore(projects): update pnpm-lock.yaml 2023-07-19 23:25:29 +08:00
Soybean
44ba3273cb chore(deps): update deps 2023-07-19 23:15:27 +08:00
Soybean
0f7b9d5e2b fix(styles): 用户管理页面布局自适应屏幕高度 (fixed #253) 2023-07-19 23:14:33 +08:00
Soybean
8a3f66db7b Merge pull request #260 from eAliwei/issues/255
feat(auth): 防止多次刷新token
2023-07-15 01:06:43 +08:00
liwei
0eaa327d47 feat(auth): 防止多次刷新token 2023-07-13 21:34:34 +08:00
Soybean
08e0cf5ad5 chore(projects): update deps & fix eslint code 2023-07-09 13:40:33 +08:00
Soybean
d7aea9d11c chore(projects): update package.json 2023-07-07 01:50:05 +08:00
Soybean
135ce77288 chore(deps): update deps 2023-07-07 01:49:02 +08:00
Soybean
19141a73d2 docs(projects): update README.md logo 2023-07-07 01:33:34 +08:00
Soybean
9d1051b0bd chore(projects): update deps and fix swiper 2023-07-05 01:54:30 +08:00
Soybean
c46a5920e5 refactor(projects): 生产环境缓存主题变更为sessionStorage 2023-07-05 01:41:57 +08:00
Soybean
43ac23f113 style(projects): update default theme color 2023-07-05 01:37:29 +08:00
Soybean
13f6cd8ef4 fix(projects): fix set tab title (fixed #256) 2023-06-27 22:48:04 +08:00
Soybean
0e6d289128 chore(deps): update deps 2023-06-27 22:24:08 +08:00
Soybean
bba68bff29 chore(deps): update deps 2023-06-25 07:55:39 +08:00
Soybean
6e0cce4d49 feat(projects): add switch for customize darkmode transition 2023-06-20 22:33:22 +08:00
Soybean
d3ebe95076 perf(projects): add type declaration for document startViewTransition 2023-06-20 22:07:21 +08:00
Soybean
cbda4a38a3 style(projects): unify card border radius, 16px to 8px 2023-06-20 00:17:18 +08:00
Soybean
3318041b92 perf(hooks): perf use-table 2023-06-19 23:43:16 +08:00
Soybean
af53ec7625 feat(projects): add websocket demo 2023-06-18 22:24:21 +08:00
566 changed files with 27071 additions and 32086 deletions

View File

@@ -4,7 +4,7 @@ root = true
[*]
charset = utf-8
indent_style = tab
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true

47
.env
View File

@@ -1,20 +1,45 @@
VITE_BASE_URL=/
VITE_APP_NAME=SoybeanAdmin
VITE_APP_TITLE=SoybeanAdmin
VITE_APP_TITLE=Soybean管理系统
VITE_APP_DESC=SoybeanAdmin is a fresh and elegant admin template
VITE_APP_DESC=SoybeanAdmin是一个中后台管理系统模版
# the prefix of the icon name
VITE_ICON_PREFIX=icon
# 权限路由模式: static dynamic
# the prefix of the local svg icon component, must include VITE_ICON_PREFIX
# format {VITE_ICON_PREFIX}-{local icon name}
VITE_ICON_LOCAL_PREFIX=icon-local
# auth route mode: static dynamic
VITE_AUTH_ROUTE_MODE=static
# 路由首页(根路由重定向), 用于static模式的权限路由dynamic模式取决于后端返回的路由首页
VITE_ROUTE_HOME_PATH=/dashboard/analysis
# static auth route home
VITE_ROUTE_HOME=home
# iconify图标作为组件的前缀
VITE_ICON_PREFFIX=icon
# default menu icon
VITE_MENU_ICON=mdi:menu
# 本地SVG图标作为组件的前缀, 请注意一定要包含 VITE_ICON_PREFFIX
# 格式 {VITE_ICON_PREFFIX}-{本地图标集合名称}
VITE_ICON_LOCAL_PREFFIX=icon-local
# whether to enable http proxy when is dev mode
VITE_HTTP_PROXY=Y
# vue-router mode: hash | history | memory
VITE_ROUTER_HISTORY_MODE=history
# success code of backend service, when the code is received, the request is successful
VITE_SERVICE_SUCCESS_CODE=0000
# logout codes of backend service, when the code is received, the user will be logged out and redirected to login page
VITE_SERVICE_LOGOUT_CODES=8888,8889
# modal logout codes of backend service, when the code is received, the user will be logged out by displaying a modal
VITE_SERVICE_MODAL_LOGOUT_CODES=7777,7778
# token expired codes of backend service, when the code is received, it will refresh the token and resend the request
VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998
# when the route mode is static, the defined super role
VITE_STATIC_SUPER_ROLE=R_SUPER
# sourcemap
VITE_SOURCE_MAP=N

View File

@@ -1,30 +0,0 @@
/** 请求服务的环境配置 */
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>;
/** 不同请求服务的环境配置 */
const serviceEnv: ServiceEnv = {
dev: {
url: 'http://localhost:8080'
},
test: {
url: 'http://localhost:8080'
},
prod: {
url: 'http://localhost:8080'
}
};
/**
* 获取当前环境模式下的请求服务的配置
* @param env 环境
*/
export function getServiceEnvConfig(env: ImportMetaEnv): ServiceEnvConfigWithProxyPattern {
const { VITE_SERVICE_ENV = 'dev' } = env;
const config = serviceEnv[VITE_SERVICE_ENV];
return {
...config,
proxyPattern: '/proxy-pattern'
};
}

View File

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

7
.env.prod Normal file
View File

@@ -0,0 +1,7 @@
# backend service base url, prod environment
VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default
# other backend service base url, prod environment
VITE_OTHER_SERVICE_BASE_URL= `{
"demo": "http://localhost:9529"
}`

View File

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

7
.env.test Normal file
View File

@@ -0,0 +1,7 @@
# backend service base url, test environment
VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default
# other backend service base url, test environment
VITE_OTHER_SERVICE_BASE_URL= `{
"demo": "http://localhost:9528"
}`

View File

@@ -1,5 +0,0 @@
!.env-config.ts
components.d.ts
router-page.d.ts
*.svg
src-tauri/target

View File

@@ -1,132 +0,0 @@
module.exports = {
extends: ['soybeanjs/vue'],
overrides: [
{
files: ['./scripts/*.ts'],
rules: {
'no-unused-expressions': 'off'
}
},
{
files: ['*.vue'],
rules: {
'no-undef': 'off' // use tsc to check the ts code of the vue
}
}
],
settings: {
'import/core-modules': ['uno.css', '~icons/*', 'virtual:svg-icons-register']
},
rules: {
'import/order': [
'error',
{
'newlines-between': 'never',
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
pathGroups: [
{
pattern: 'vue',
group: 'external',
position: 'before'
},
{
pattern: 'vue-router',
group: 'external',
position: 'before'
},
{
pattern: 'pinia',
group: 'external',
position: 'before'
},
{
pattern: 'naive-ui',
group: 'external',
position: 'before'
},
{
pattern: '@/constants',
group: 'internal',
position: 'before'
},
{
pattern: '@/config',
group: 'internal',
position: 'before'
},
{
pattern: '@/settings',
group: 'internal',
position: 'before'
},
{
pattern: '@/plugins',
group: 'internal',
position: 'before'
},
{
pattern: '@/layouts',
group: 'internal',
position: 'before'
},
{
pattern: '@/views',
group: 'internal',
position: 'before'
},
{
pattern: '@/components',
group: 'internal',
position: 'before'
},
{
pattern: '@/router',
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',
position: 'before'
},
{
pattern: '@/hooks',
group: 'internal',
position: 'before'
},
{
pattern: '@/utils',
group: 'internal',
position: 'before'
},
{
pattern: '@/assets',
group: 'internal',
position: 'before'
},
{
pattern: '@/**',
group: 'internal',
position: 'before'
}
],
pathGroupsExcludedImportTypes: ['vue', 'vue-router', 'pinia', 'naive-ui']
}
]
}
};

10
.gitattributes vendored
View File

@@ -3,15 +3,11 @@
"*.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
"*.md" eol=lf
"*.md" eol=lf
"*.yaml" eol=lf
"*.yml" eol=lf

View File

@@ -0,0 +1,90 @@
name: Bug Report
description: Encountered an error while using the software or feature
title: '[Bug]: '
labels: [ "bug?" ]
body:
- type: markdown
attributes:
value: |
## Please submit according to the following requirements
### 1. After submission, you need to specify the label and deadline.
---
- type: markdown
attributes:
value: |
## Environment Information
Please modify the following information according to the actual usage environment.
- type: input
id: env-program-ver
attributes:
label: Software Version
validations:
required: true
- type: dropdown
id: env-vm-ver
attributes:
label: Operating Environment
description: Select the system version on which the software is running
options:
- Windows (64)
- Windows (32/x84)
- MacOS
- Linux
- Ubuntu
- CentOS
- ArchLinux
- UNIX (Android)
- Other (please specify below)
validations:
required: true
- type: dropdown
id: env-vm-arch
attributes:
label: Operating Architecture
description: (Optional) Select the system architecture on which the software is running
options:
- AMD64
- x86
- ARM [32] (AliasAArch32 / ARMv7
- ARM [64] (AliasAArch64 / ARMv8
- Other
- type: textarea
id: reproduce-steps
attributes:
label: Reproduce Steps
description: |
What operations do we need to perform to make the bug appear?
The concise and clear reproduction steps can help us locate the problem more quickly.
validations:
required: true
- type: textarea
id: expected
attributes:
label: What is the expected result?
validations:
required: true
- type: textarea
id: actual
attributes:
label: What is the actual result?
validations:
required: true
- type: textarea
id: logging
attributes:
label: Logging (Optional)
render: golang
- type: textarea
id: extra-desc
attributes:
label: Additional Description (Optional)

View File

@@ -1,11 +0,0 @@
## Pull Request 详情
请根据实际使用情况修改以下信息。
## 版本信息
## 解决了哪些问题
## 是否关闭了某个 Issue
Closes #

50
.github/PULL_REQUEST_TEMPLATE/pr_cn.md vendored Normal file
View File

@@ -0,0 +1,50 @@
首先,感谢你的贡献! 😄
新特性请提交至 feature 分支,其余可提交至 main 分支。在一个维护者审核通过后合并。请确保填写以下 pull request 的信息,谢谢!~
[[English Template / 英文模板](./pr_en.md)]
### 这个变动的性质是
- [ ] 新特性提交
- [ ] 日常 bug 修复
- [ ] 站点、文档改进
- [ ] 组件样式改进
- [ ] TypeScript 定义更新
- [ ] 重构
- [ ] 代码风格优化
- [ ] 分支合并
- [ ] 其他改动(是关于什么的改动?)
### 需求背景
> 1. 描述相关需求的来源。
> 2. 要解决的问题。
> 3. 相关的 issue 讨论链接。
### 实现方案和 API非新功能可选
> 1. 基本的解决思路和其他可选方案。
> 2. 列出最终的 API 实现和用法。
> 3. 涉及 UI/交互变动需要有截图或 GIF。
### 对用户的影响和可能的风险(非新功能可选)
> 1. 这个改动对用户端是否有影响?影响的方面有哪些?
> 2. 是否有可能隐含的 break change 和其他风险?
### Changelog 描述(非新功能可选)
> 1. 英文描述
> 2. 中文描述(可选)
### 请求合并前的自查清单
- [ ] 文档已补充或无须补充
- [ ] 代码演示已提供或无须提供
- [ ] TypeScript 定义已补充或无须补充
- [ ] Changelog 已提供或无须提供
### 后续计划(非新功能可选)
> 如果这个提交后面还有相关的其他提交和跟进信息,可以写在这里。

51
.github/PULL_REQUEST_TEMPLATE/pr_en.md vendored Normal file
View File

@@ -0,0 +1,51 @@
First of all, thank you for your contribution! 😄
New feature please send pull request to feature branch, and rest to main branch. Pull request will be merged after one of collaborators approve. Please makes sure that these form are filled before submitting your pull request, thank you!
[[中文版模板 / Chinese template](./pr_cn.md)]
### This is a ...
- [ ] New feature
- [ ] Bug fix
- [ ] Site / document update
- [ ] Component style update
- [ ] TypeScript definition update
- [ ] Refactoring
- [ ] Code style optimization
- [ ] Branch merge
- [ ] Other (about what?)
### What's the background?
> 1. Describe the source of requirement.
> 2. Resolve what problem.
> 3. Related issue link.
### API Realization (Optional if not new feature)
> 1. Basic thought of solution and other optional proposal.
> 2. List final API realization and usage sample.
> 3. GIF or snapshot should be provided if includes UI/interactive modification.
### What's the effect? (Optional if not new feature)
> 1. Does this PR affect user? Which part will be affected?
> 2. What will say in changelog?
> 3. Does this PR contains potential break change or other risk?
### Changelog description (Optional if not new feature)
> 1. English description
> 2. Chinese description (optional)
### Self Check before Merge
- [ ] Doc is updated/provided or not needed
- [ ] Demo is updated/provided or not needed
- [ ] TypeScript definition is updated/provided or not needed
- [ ] Changelog is provided or not needed
### Additional Plan? (Optional if not new feature)
> If this PR related with other PR or following info. You can type here.

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 18.x
- run: npx githublogen
env:

7
.gitignore vendored
View File

@@ -11,10 +11,8 @@ node_modules
.DS_Store
dist
dist-ssr
dist.zip
coverage
*.local
stats.html
/cypress/videos/
/cypress/screenshots/
@@ -22,8 +20,8 @@ stats.html
# Editor directories and files
.vscode/*
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/settings.json
!.vscode/launch.json
.idea
*.suo
*.ntvs*
@@ -31,6 +29,7 @@ stats.html
*.sln
*.sw?
/src/typings/components.d.ts
package-lock.json
yarn.lock
.VSCodeCounter

1
.npmrc
View File

@@ -1,2 +1,3 @@
registry=https://registry.npmmirror.com/
shamefully-hoist=true
ignore-workspace-root-check=true

View File

@@ -3,24 +3,19 @@
"afzalsayed96.icones",
"antfu.iconify",
"antfu.unocss",
"christian-kohler.path-intellisense",
"dbaeumer.vscode-eslint",
"eamodio.gitlens",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"formulahendry.auto-close-tag",
"formulahendry.auto-complete-tag",
"formulahendry.auto-rename-tag",
"kisstkondoros.vscode-gutter-preview",
"lokalise.i18n-ally",
"mariusalchimavicius.json-to-ts",
"mhutchie.git-graph",
"mikestead.dotenv",
"naumovs.color-highlight",
"pkief.material-icon-theme",
"sdras.vue-vscode-snippets",
"vue.volar",
"vue.vscode-typescript-vue-plugin",
"whtouche.vscode-js-console-utils",
"zhuangtongfa.material-theme"
]

12
.vscode/launch.json vendored
View File

@@ -4,17 +4,17 @@
{
"type": "chrome",
"request": "launch",
"name": "Vue debugger",
"url": "http://localhost:3200",
"name": "Vue Debugger",
"url": "http://localhost:9527",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "TS debugger",
"skipFiles": ["<node_internals>/**"],
"runtimeArgs": ["--loader", "tsx"],
"program": "${relativeFile}"
"name": "TS Debugger",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/tsx",
"skipFiles": ["<node_internals>/**", "${workspaceFolder}/node_modules/**"],
"program": "${file}"
}
]
}

84
.vscode/settings.json vendored
View File

@@ -1,75 +1,19 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
"editor.fontLigatures": true,
"eslint.experimental.useFlatConfig": true,
"editor.formatOnSave": false,
"editor.guides.bracketPairs": "active",
"editor.quickSuggestions": {
"strings": true
},
"editor.tabSize": 2,
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue", "json"],
"files.associations": {
"*.env.*": "dotenv"
},
"files.eol": "\n",
"git.enableSmartCommit": true,
"gutterpreview.paths": {
"@": "/src",
"~@": "/src"
},
"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.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"
},
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"]
"eslint.validate": ["html", "css", "scss", "json", "jsonc"],
"i18n-ally.displayLanguage": "zh-cn",
"i18n-ally.enabledParsers": ["ts"],
"i18n-ally.enabledFrameworks": ["vue"],
"i18n-ally.editor.preferEditor": true,
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": ["src/locales/langs"],
"prettier.enable": false,
"unocss.root": ["./"],
"typescript.tsdk": "node_modules/typescript/lib",
"vue.server.hybridMode": true
}

View File

@@ -1,6 +1,749 @@
# Changelog
## [v1.0.6](https://github.com/soybeanjs/soybean-admin/compare/v1.0.5...v1.0.6) (2024-04-25)
### &nbsp;&nbsp;&nbsp;🚀 Features
- **hooks**: add state hooks: useRef, useState, useSignal &nbsp;-&nbsp; by @honghuangdc [<samp>(09f64)</samp>](https://github.com/soybeanjs/soybean-admin/commit/09f6464)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**:
- added responseType judgment. #396 &nbsp;-&nbsp; by **alleycharming** in https://github.com/soybeanjs/soybean-admin/issues/396 [<samp>(82eab)</samp>](https://github.com/soybeanjs/soybean-admin/commit/82eabab)
- supply $t import statement &nbsp;-&nbsp; by @honghuangdc [<samp>(b2660)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b266035)
- fix mix-menu blank. fixed #389 & cache mixMenuFixed &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/389 [<samp>(93c7f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/93c7ff7)
### &nbsp;&nbsp;&nbsp;🔥 Performance
- **hooks**:
- perf useSignal &nbsp;-&nbsp; by @honghuangdc [<samp>(5d45c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5d45cef)
- **projects**:
- remove useless prop `title` of `NDrawer` &nbsp;-&nbsp; by @honghuangdc [<samp>(fdde6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fdde679)
- add tsconfig.json for @sa/color-palette &nbsp;-&nbsp; by @honghuangdc [<samp>(d460e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d460e5c)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **hooks**: refactor useSignal, useComputed &nbsp;-&nbsp; by @honghuangdc [<samp>(3b5e4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3b5e4b3)
- **projects**: useMixMenuContext replace useMixMenu &nbsp;-&nbsp; by @honghuangdc [<samp>(1e142)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1e14293)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**:
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(e57bf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e57bf0b)
- **projects**:
- use `engines` replace `packageManager` &nbsp;-&nbsp; by @honghuangdc [<samp>(dcd51)</samp>](https://github.com/soybeanjs/soybean-admin/commit/dcd51f4)
- update pnpm version requirement &nbsp;-&nbsp; by @honghuangdc [<samp>(19e65)</samp>](https://github.com/soybeanjs/soybean-admin/commit/19e65c1)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
[alleycharming](mailto:alleycharming@gmail.com)
## [v1.0.5](https://github.com/honghuangdc/soybean-admin/compare/v1.0.4...v1.0.5) (2024-04-24)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**: update CHANGELOG.md &nbsp;-&nbsp; by @honghuangdc [<samp>(cf5bc)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cf5bc88)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **projects**:
- lower vue version to 3.4.23 &nbsp;-&nbsp; by @honghuangdc [<samp>(b5243)</samp>](https://github.com/honghuangdc/soybean-admin/commit/b52432a)
- update pnpm-lock.yaml &nbsp;-&nbsp; by @honghuangdc [<samp>(516f4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/516f46a)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.0.4](https://github.com/soybeanjs/soybean-admin/compare/v1.0.3...v1.0.4) (2024-04-24)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**:
- fix CHANGELOG versions &nbsp;-&nbsp; by @honghuangdc [<samp>(d9af5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d9af5aa)
- fix disabled page animate &nbsp;-&nbsp; by @honghuangdc [<samp>(23f28)</samp>](https://github.com/soybeanjs/soybean-admin/commit/23f283a)
- fix routes data when role is change. fixed #391 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/391 [<samp>(cb83d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cb83d6d)
- fix tabs data when role is change. fixed #392 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/392 [<samp>(04aa0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/04aa097)
- recovery pnpm-lock.yaml &nbsp;-&nbsp; by @honghuangdc [<samp>(c6952)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c695208)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **hooks**: refactor @sa/color-palette &nbsp;-&nbsp; by @honghuangdc [<samp>(93191)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9319173)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**:
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(5a523)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5a5232b)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(79d9c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/79d9c51)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**:
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(ac928)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ac92817)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(3ceeb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3ceeb6f)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(9a669)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9a66979)
- **projects**:
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(42e16)</samp>](https://github.com/soybeanjs/soybean-admin/commit/42e16a0)
- update deps & update pnpm version & update eslint config &nbsp;-&nbsp; by @honghuangdc [<samp>(7392b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7392beb)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.0.3](https://github.com/soybeanjs/soybean-admin/compare/v1.0.2...v1.0.3) (2024-04-16)
### &nbsp;&nbsp;&nbsp;🚀 Features
- **hooks**: deleting the route export of useRoutePush, use vue-router &nbsp;-&nbsp; by **paynezhuang** [<samp>(c6648)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c6648b6)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**:
- fix menu edit rules &nbsp;-&nbsp; by **paynezhuang** [<samp>(00105)</samp>](https://github.com/soybeanjs/soybean-admin/commit/001059c)
- fix SvgIcon inheritAttrs warning &nbsp;-&nbsp; by @honghuangdc [<samp>(efc0e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/efc0e25)
- fix axios createRequest: add default state &nbsp;-&nbsp; by @honghuangdc [<samp>(d6eda)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d6eda8f)
- update union-key.d.ts &nbsp;-&nbsp; by @honghuangdc [<samp>(60bef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/60beff7)
- fix update theme color &nbsp;-&nbsp; by @honghuangdc [<samp>(27c53)</samp>](https://github.com/soybeanjs/soybean-admin/commit/27c53cd)
### &nbsp;&nbsp;&nbsp;🔥 Performance
- **projects**: perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(b7f07)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b7f0749)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **projects**: update naive-ui.d.ts &nbsp;-&nbsp; by @honghuangdc [<samp>(bb74d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bb74d99)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**: update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(f4a9c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f4a9cf8)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
[paynezhuang](mailto:paynezhuang@gmail.com)
## [v1.0.2](https://github.com/soybeanjs/soybean-admin/compare/v1.0.1...v1.0.2) (2024-04-08)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**: unify border-radius of Tag. fixed #378 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/378 [<samp>(2f15a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2f15a2a)
- **styles**: fix css var is inserted repeatedly &nbsp;-&nbsp; by **燕博文** [<samp>(769d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/769d84a)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **projects**: refactor addThemeVarsToHtml &nbsp;-&nbsp; by @honghuangdc [<samp>(41e47)</samp>](https://github.com/soybeanjs/soybean-admin/commit/41e470e)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**: update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(a1b48)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a1b484a)
- **projects**: disabled unocss eslint rule: order-attributify &nbsp;-&nbsp; by @honghuangdc [<samp>(1c72d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1c72dc7)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
[燕博文](mailto:349952469@qq.com)
## [v1.0.1](https://github.com/soybeanjs/soybean-admin/compare/v1.0.0...v1.0.1) (2024-04-03)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**:
- fix flatRequest error type. fixed #376 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/376 [<samp>(1ec5e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1ec5ea0)
- add maxWidth for GlobalTab to fix bg with gap. fixed #350 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/350 [<samp>(cc539)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cc53997)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**: update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(76011)</samp>](https://github.com/soybeanjs/soybean-admin/commit/76011af)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **projects**:
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(4babb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4babbe1)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(9125c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9125cc9)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.0.0](https://github.com/soybeanjs/soybean-admin/compare/v0.10.4...v1.0.0) (2024-03-31)
### &nbsp;&nbsp;&nbsp;🚀 Features
- internationalized menu search &nbsp;-&nbsp; by **Kori** [<samp>(9e115)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9e115da)
- **components**:
- enhance the custom strength of the 'TableHeaderOperation' component &nbsp;-&nbsp; by **tnt group** [<samp>(fdf64)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fdf64f7)
- add GlobalSearch components &nbsp;-&nbsp; by **燕博文** [<samp>(9ea87)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9ea8789)
- **hooks**:
- add use-echarts &nbsp;-&nbsp; by @honghuangdc [<samp>(726ab)</samp>](https://github.com/soybeanjs/soybean-admin/commit/726abe4)
- **projects**:
- 1.0 beta &nbsp;-&nbsp; by @honghuangdc [<samp>(e918a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e918a2c)
- support Vite5 &nbsp;-&nbsp; by @honghuangdc [<samp>(96e4a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/96e4aff)
- @sa/axios: createRequest, createFlatRequest, createHookRequest &nbsp;-&nbsp; by @honghuangdc [<samp>(bac16)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bac1632)
- add app loading &nbsp;-&nbsp; by @honghuangdc [<samp>(c6545)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c65451b)
- add copyright, unocss shortcut: card-wrapper, update package.json &nbsp;-&nbsp; by @honghuangdc [<samp>(affcc)</samp>](https://github.com/soybeanjs/soybean-admin/commit/affcc26)
- add page: about &nbsp;-&nbsp; by @honghuangdc [<samp>(4955f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4955f1a)
- add custom route exception &nbsp;-&nbsp; by @honghuangdc [<samp>(b43c9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b43c925)
- filter tabs which are not in routes &nbsp;-&nbsp; by @honghuangdc [<samp>(f59f3)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f59f348)
- packages/scripts: add command changelog,release &nbsp;-&nbsp; by @honghuangdc [<samp>(dafb6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/dafb6fa)
- add script: gen-route &nbsp;-&nbsp; by @honghuangdc [<samp>(697c1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/697c1b6)
- @sa/axios: add qs stringify for params &nbsp;-&nbsp; by @honghuangdc [<samp>(2400c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2400c02)
- page home & perf useEcharts &nbsp;-&nbsp; by @honghuangdc [<samp>(62e4d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/62e4da0)
- finish page home &nbsp;-&nbsp; by @honghuangdc [<samp>(7bd1e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7bd1e47)
- add page function_tab &nbsp;-&nbsp; by @honghuangdc [<samp>(6ff86)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6ff86e7)
- page manage_role &nbsp;-&nbsp; by @honghuangdc [<samp>(237c6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/237c6d2)
- page manage_user &nbsp;-&nbsp; by @honghuangdc [<samp>(8a170)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8a170ee)
- page manage_menu &nbsp;-&nbsp; by @honghuangdc [<samp>(87d65)</samp>](https://github.com/soybeanjs/soybean-admin/commit/87d65d3)
- page manage_menu operateDrawer &nbsp;-&nbsp; by @honghuangdc [<samp>(db17c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/db17c91)
- Add type to TabRoute: matched &nbsp;-&nbsp; by @Azir-11 [<samp>(2d102)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2d102a0)
- support directory menu hide all child menus. fixed #325 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/325 [<samp>(7256a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7256ad4)
- mock manage list data with pagination &nbsp;-&nbsp; by @honghuangdc [<samp>(1a6be)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1a6be00)
- globalSearch add i18n &nbsp;-&nbsp; by **燕博文** [<samp>(0126d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0126da4)
- Add route meta parameter:fixedQuery &nbsp;-&nbsp; by @Azir-11 [<samp>(874aa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/874aaca)
- update &nbsp;-&nbsp; by @honghuangdc [<samp>(4158a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4158a72)
- change borderRadius to 6px of naiveUI &nbsp;-&nbsp; by @honghuangdc [<samp>(49558)</samp>](https://github.com/soybeanjs/soybean-admin/commit/49558ca)
- pef manage role &nbsp;-&nbsp; by @honghuangdc [<samp>(18709)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1870981)
- login page: code-login &nbsp;-&nbsp; by @honghuangdc [<samp>(c91dd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c91dd28)
- login page: register &nbsp;-&nbsp; by @honghuangdc [<samp>(1ed33)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1ed33dc)
- add request refresh token & logout &nbsp;-&nbsp; by @honghuangdc [<samp>(11a6a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/11a6a3b)
- add request exception example page &nbsp;-&nbsp; by @honghuangdc [<samp>(41e8b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/41e8bc4)
- add auth example &nbsp;-&nbsp; by @honghuangdc [<samp>(c11d5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c11d56d)
- **router**:
- add sortRoutesByOrder function &nbsp;-&nbsp; by @Azir-11 [<samp>(0cf09)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0cf09ba)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **components**:
- fix tooltip zIndex of ButtonIcon &nbsp;-&nbsp; by @honghuangdc [<samp>(99097)</samp>](https://github.com/soybeanjs/soybean-admin/commit/99097b4)
- supplement the `NaiveUI` type &nbsp;-&nbsp; by **tnt group** [<samp>(ccc2b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ccc2b67)
- fix homeTab closeRight and disable colseLeft &nbsp;-&nbsp; by **~li** [<samp>(d28bf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d28bf52)
- **hooks**:
- Fix Naive Pagination's outdated API &nbsp;-&nbsp; by **tnt group** [<samp>(37436)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3743612)
- **projects**:
- 修复路由命名为包含关系时导致导航数据出错的问题 &nbsp;-&nbsp; by @Particaly [<samp>(76636)</samp>](https://github.com/soybeanjs/soybean-admin/commit/766369f)
- rename zh-ch &nbsp;-&nbsp; by @honghuangdc [<samp>(a8a77)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a8a77ea)
- Fix welcome notification not closing &nbsp;-&nbsp; by @Azir-11 [<samp>(748cf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/748cfa2)
- fix i18n vscode settings &nbsp;-&nbsp; by @honghuangdc [<samp>(fbf4c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fbf4cc4)
- add duration of login success notification &nbsp;-&nbsp; by @honghuangdc [<samp>(1335d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1335d47)
- fix menu indent &nbsp;-&nbsp; by @honghuangdc [<samp>(87143)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8714317)
- fix theme mode segment &nbsp;-&nbsp; by @honghuangdc [<samp>(2372d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2372dc9)
- fix app loading theme color &nbsp;-&nbsp; by @honghuangdc [<samp>(0ba19)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0ba19d5)
- fix page about style in mobile &nbsp;-&nbsp; by @honghuangdc [<samp>(8b6de)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8b6de48)
- fix themeDrawer darkMode segement &nbsp;-&nbsp; by @honghuangdc [<samp>(1b5ca)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1b5caa0)
- fix themeDrawer copy &nbsp;-&nbsp; by @honghuangdc [<samp>(b3779)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b3779a6)
- remove space in tab content &nbsp;-&nbsp; by @honghuangdc [<samp>(4aae6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4aae6a5)
- fix horizontal menu &nbsp;-&nbsp; by @honghuangdc [<samp>(d886e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d886e50)
- perf card style &nbsp;-&nbsp; by @honghuangdc [<samp>(c1afb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c1afb9d)
- fix manage_user title &nbsp;-&nbsp; by @honghuangdc [<samp>(7770b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7770b37)
- default proxy prefix &nbsp;-&nbsp; by @smileluck [<samp>(da246)</samp>](https://github.com/soybeanjs/soybean-admin/commit/da24642)
- fix request msg &nbsp;-&nbsp; by @honghuangdc [<samp>(ae6b6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ae6b613)
- Fix the issue of tab error displaying parent localIcon &nbsp;-&nbsp; by @Azir-11 [<samp>(a9c98)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a9c98d9)
- The matched value of TabRoute should be optional &nbsp;-&nbsp; by @Azir-11 [<samp>(e6fed)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e6fed1f)
- fix build [unocss]: build failed to load icon "close", fixed #319 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/319 [<samp>(c18d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c18d82f)
- fix resolve alias &nbsp;-&nbsp; by @honghuangdc [<samp>(3bdcb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3bdcbc7)
- Missing default value for tab icon &nbsp;-&nbsp; by @Azir-11 [<samp>(72a46)</samp>](https://github.com/soybeanjs/soybean-admin/commit/72a4679)
- add route icon: fucntion_hide-child &nbsp;-&nbsp; by @honghuangdc [<samp>(0a3ef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0a3efe3)
- fix table x-scroll. fixed #324 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/324 [<samp>(c7e2c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c7e2c55)
- Fix the logic of root route redirection to home &nbsp;-&nbsp; by **恕瑞玛的皇帝** [<samp>(0123c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0123c37)
- Fix homepage mount error under dynamic routing &nbsp;-&nbsp; by **恕瑞玛的皇帝** [<samp>(9cf2a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9cf2a51)
- fix repeat home tab &nbsp;-&nbsp; by @honghuangdc [<samp>(bccd6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bccd6cb)
- fix proxy config &nbsp;-&nbsp; by @honghuangdc [<samp>(c8019)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c8019c4)
- fix proxy config &nbsp;-&nbsp; by @honghuangdc [<samp>(ffc95)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ffc95d2)
- fix table row-key ts type &nbsp;-&nbsp; by @honghuangdc [<samp>(0cc8f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0cc8f05)
- fix class name conflict with unocss icon &nbsp;-&nbsp; by @honghuangdc [<samp>(455e4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/455e48f)
- fix repeat routes &nbsp;-&nbsp; by @honghuangdc [<samp>(2c543)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2c543f1)
- fix route init &nbsp;-&nbsp; by @honghuangdc [<samp>(23a40)</samp>](https://github.com/soybeanjs/soybean-admin/commit/23a4098)
- fix pin-toggler toolTip zIndex &nbsp;-&nbsp; by @honghuangdc [<samp>(f89e6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f89e6c0)
### &nbsp;&nbsp;&nbsp;🔥 Performance
- **components**:
- Optimize internationalized menu search code &nbsp;-&nbsp; by **燕博文** [<samp>(8c1ef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8c1ef4b)
- Optimize menu search code &nbsp;-&nbsp; by **燕博文** [<samp>(296a2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/296a2d2)
- perf count-to &nbsp;-&nbsp; by @honghuangdc [<samp>(b2c61)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b2c61f0)
- components name is converted to uppercase &nbsp;-&nbsp; by **燕博文** [<samp>(04aa1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/04aa10b)
- perf global-search &nbsp;-&nbsp; by @honghuangdc [<samp>(72745)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7274522)
- **projects**:
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(8081e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8081e19)
- env config &nbsp;-&nbsp; by @honghuangdc [<samp>(1bac3)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1bac3b7)
- add detailed annotations for route role &nbsp;-&nbsp; by @honghuangdc [<samp>(f6bab)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f6bab0c)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(5c49d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5c49d24)
- remove useless file &nbsp;-&nbsp; by @honghuangdc [<samp>(c624f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c624f32)
- remove @soybeanjs/cli &nbsp;-&nbsp; by @honghuangdc [<samp>(41349)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4134955)
- echarts loading style &nbsp;-&nbsp; by @honghuangdc [<samp>(456c3)</samp>](https://github.com/soybeanjs/soybean-admin/commit/456c318)
- perf page manage_role, useTable &nbsp;-&nbsp; by @honghuangdc [<samp>(39aa7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/39aa7aa)
- perf table columns style &nbsp;-&nbsp; by @honghuangdc [<samp>(babdb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/babdb5d)
- perf page manage_menu style &nbsp;-&nbsp; by @honghuangdc [<samp>(0aa75)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0aa75c0)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(7fa87)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7fa87f5)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(05db8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/05db8c0)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(dc24a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/dc24a36)
- perf manage page style &nbsp;-&nbsp; by @honghuangdc [<samp>(779ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/779ba4e)
- perf manage menu &nbsp;-&nbsp; by @honghuangdc [<samp>(71f2c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/71f2c55)
- manage menu: add transform to component &nbsp;-&nbsp; by @honghuangdc [<samp>(0abbf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0abbfa5)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(a0bad)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a0bad57)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **projects**:
- remove plugin-web-update-notification &nbsp;-&nbsp; by @honghuangdc [<samp>(f6c6d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f6c6dbd)
- fix conflict with locale file &nbsp;-&nbsp; by @honghuangdc [<samp>(3346b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3346bcd)
- refactor app-loading &nbsp;-&nbsp; by @honghuangdc [<samp>(b4f3d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b4f3dd2)
- use naive-ui color-picker &nbsp;-&nbsp; by @honghuangdc [<samp>(b5551)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5551d6)
- perf page home &nbsp;-&nbsp; by @honghuangdc [<samp>(4c61c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4c61c6f)
- login components => modules &nbsp;-&nbsp; by @honghuangdc [<samp>(59bec)</samp>](https://github.com/soybeanjs/soybean-admin/commit/59bec2d)
- perf page function_tab &nbsp;-&nbsp; by @honghuangdc [<samp>(b5477)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5477e8)
- update mock api &nbsp;-&nbsp; by @honghuangdc [<samp>(27241)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2724169)
- page manage_role: extract module &nbsp;-&nbsp; by @honghuangdc [<samp>(0e9e2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0e9e2e1)
- perf page manage_role &nbsp;-&nbsp; by @honghuangdc [<samp>(a19f8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a19f895)
- manage_route => manage_menu &nbsp;-&nbsp; by @honghuangdc [<samp>(f8467)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f8467ce)
- refactor service env config &nbsp;-&nbsp; by @honghuangdc [<samp>(43193)</samp>](https://github.com/soybeanjs/soybean-admin/commit/43193e2)
- refactor unocss shortcuts: wh-full => size-full &nbsp;-&nbsp; by @honghuangdc [<samp>(b4c00)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b4c00ce)
- use enquirer replace prompts &nbsp;-&nbsp; by @honghuangdc [<samp>(b546f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b546ff8)
- refactor useTable &nbsp;-&nbsp; by @honghuangdc [<samp>(c3efa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c3efa1b)
- finish refactor useTable &nbsp;-&nbsp; by @honghuangdc [<samp>(86301)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8630175)
- finish refactor useTable and apply &nbsp;-&nbsp; by @honghuangdc [<samp>(3fd15)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3fd15e5)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(f91ef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f91ef30)
- new route guard &nbsp;-&nbsp; by @honghuangdc [<samp>(37d20)</samp>](https://github.com/soybeanjs/soybean-admin/commit/37d20b8)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**:
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(78364)</samp>](https://github.com/soybeanjs/soybean-admin/commit/783648f)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(1ea48)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1ea4817)
- add README &nbsp;-&nbsp; by @honghuangdc [<samp>(2371b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2371ba8)
- update README &nbsp;-&nbsp; by @honghuangdc [<samp>(d16a9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d16a9d5)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(6a771)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6a771ea)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(57b6d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/57b6d8a)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(b30c0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b30c035)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(c260f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c260fe2)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(03c42)</samp>](https://github.com/soybeanjs/soybean-admin/commit/03c42aa)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(0fae9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0fae993)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(4e4d2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4e4d2de)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(86b44)</samp>](https://github.com/soybeanjs/soybean-admin/commit/86b445c)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(e2085)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e2085e0)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(6ea9b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6ea9b85)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(ef4af)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ef4af79)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(41830)</samp>](https://github.com/soybeanjs/soybean-admin/commit/418302a)
- add CHANGELOG.md &nbsp;-&nbsp; by @honghuangdc [<samp>(46b61)</samp>](https://github.com/soybeanjs/soybean-admin/commit/46b6156)
- add communication &nbsp;-&nbsp; by @honghuangdc [<samp>(8c7ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8c7ea23)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(07d8d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/07d8d25)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(1a707)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1a7070f)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(f69e1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f69e152)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**:
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(3eaf0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3eaf05b)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(36fe1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/36fe1da)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(55342)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5534294)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(f1b86)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f1b86cc)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(840e7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/840e7f9)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(6114b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6114b9f)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(9cc7e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9cc7ee5)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(9c4ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9c4ba66)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(fb3b9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fb3b94b)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(14aa8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/14aa856)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(02d4b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/02d4b0a)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(b2ee9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b2ee9ee)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(0fee1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0fee104)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(c0a65)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c0a65a1)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(6b513)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6b5132c)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(82b53)</samp>](https://github.com/soybeanjs/soybean-admin/commit/82b53d7)
- **project**:
- delete src/locales/lang/zh-CN.ts &nbsp;-&nbsp; by @honghuangdc [<samp>(377db)</samp>](https://github.com/soybeanjs/soybean-admin/commit/377db82)
- **projects**:
- use eslint flat config & update config &nbsp;-&nbsp; by @honghuangdc [<samp>(a176d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a176dc4)
- update @sa/scripts &nbsp;-&nbsp; by @honghuangdc [<samp>(d7785)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d778560)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(55f76)</samp>](https://github.com/soybeanjs/soybean-admin/commit/55f7638)
- update eslint config &nbsp;-&nbsp; by @honghuangdc [<samp>(5023f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5023f37)
- lock deps versions &nbsp;-&nbsp; by @honghuangdc [<samp>(a24f9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a24f963)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(ea02b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ea02b23)
- remove @simonwep/pickr &nbsp;-&nbsp; by @honghuangdc [<samp>(502a4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/502a4d2)
- remove soybean.svg &nbsp;-&nbsp; by @honghuangdc [<samp>(4031f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4031faf)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(adec0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/adec0d7)
- update deps & fix keep-alive &nbsp;-&nbsp; by @honghuangdc [<samp>(13001)</samp>](https://github.com/soybeanjs/soybean-admin/commit/13001bc)
- update @elegant-router/vue, fix inject name in windows &nbsp;-&nbsp; by @honghuangdc [<samp>(0b56e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0b56e44)
- add dev and build command with service env &nbsp;-&nbsp; by @honghuangdc [<samp>(ebb15)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ebb1548)
- update deps & remove packages docs &nbsp;-&nbsp; by @honghuangdc [<samp>(57963)</samp>](https://github.com/soybeanjs/soybean-admin/commit/579636b)
- update pnpm-lock.yaml &nbsp;-&nbsp; by @honghuangdc [<samp>(147f6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/147f60d)
- update repository url &nbsp;-&nbsp; by @honghuangdc [<samp>(806a1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/806a1cb)
- update deps & update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(9772a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9772aec)
- add unocss eslint config &nbsp;-&nbsp; by @honghuangdc [<samp>(40635)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4063529)
- update launch.json &nbsp;-&nbsp; by @honghuangdc [<samp>(3db82)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3db82ac)
- update vscode extensions.json &nbsp;-&nbsp; by @honghuangdc [<samp>(4e29a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4e29aca)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(7065f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7065f6f)
- update deps & fix eslint vue rule &nbsp;-&nbsp; by @honghuangdc [<samp>(8143b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8143b00)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(6ad51)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6ad51e9)
- add .gitattributes &nbsp;-&nbsp; by @honghuangdc [<samp>(c0009)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c000920)
### &nbsp;&nbsp;&nbsp;🎨 Styles
- **components**:
- Uniform icon size for header &nbsp;-&nbsp; by @Azir-11 [<samp>(b37c1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b37c1e9)
- **projects**:
- format code &nbsp;-&nbsp; by @honghuangdc [<samp>(a7481)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a748166)
- update theme mode segment height &nbsp;-&nbsp; by @honghuangdc [<samp>(4d846)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4d8469e)
- fix tooltip zIndex of ButtonIcon &nbsp;-&nbsp; by @honghuangdc [<samp>(db747)</samp>](https://github.com/soybeanjs/soybean-admin/commit/db747c4)
- sort defineProps, defineEmits with TS type &nbsp;-&nbsp; by @honghuangdc [<samp>(123fd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/123fd4f)
### &nbsp;&nbsp;&nbsp;🤖 CI
- **projects**:
- add github actions config &nbsp;-&nbsp; by @honghuangdc [<samp>(4cb17)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4cb17c7)
- update release.yml &nbsp;-&nbsp; by @honghuangdc [<samp>(7b298)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7b298c6)
- add issue template &nbsp;-&nbsp; by @honghuangdc [<samp>(06e20)</samp>](https://github.com/soybeanjs/soybean-admin/commit/06e204a)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;[![Azir-11](https://github.com/Azir-11.png?size=48)](https://github.com/Azir-11)&nbsp;&nbsp;[![smileluck](https://github.com/smileluck.png?size=48)](https://github.com/smileluck)&nbsp;&nbsp;[![Particaly](https://github.com/Particaly.png?size=48)](https://github.com/Particaly)&nbsp;&nbsp;
[~li](mailto:miciili-02@outlook.com),&nbsp;[Azir-11](mailto:2075125282@qq.com),&nbsp;[燕博文](mailto:349952469@qq.com),&nbsp;[tnt group](mailto:dodu@live.cn),&nbsp;[Kori](mailto:kexin@korix.top),&nbsp;
## [v1.0.0-beta.3](https://github.com/soybeanjs/soybean-admin/compare/v1.0.0-beta.2...v1.0.0-beta.3) (2024-03-31)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**: update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(f69e1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f69e152)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**: update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(82b53)</samp>](https://github.com/soybeanjs/soybean-admin/commit/82b53d7)
- **projects**: add .gitattributes &nbsp;-&nbsp; by @honghuangdc [<samp>(c0009)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c000920)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.0.0-beta.2](https://github.com/soybeanjs/soybean-admin/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2024-03-27)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**: fix pin-toggler toolTip zIndex &nbsp;-&nbsp; by @honghuangdc [<samp>(f89e6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f89e6c0)
### &nbsp;&nbsp;&nbsp;🔥 Performance
- **projects**: perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(a0bad)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a0bad57)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**:
- add communication &nbsp;-&nbsp; by @honghuangdc [<samp>(8c7ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8c7ea23)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(07d8d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/07d8d25)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(1a707)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1a7070f)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**: update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(6b513)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6b5132c)
### &nbsp;&nbsp;&nbsp;🤖 CI
- **projects**:
- update release.yml &nbsp;-&nbsp; by @honghuangdc [<samp>(7b298)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7b298c6)
- add issue template &nbsp;-&nbsp; by @honghuangdc [<samp>(06e20)</samp>](https://github.com/soybeanjs/soybean-admin/commit/06e204a)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.0.0-beta.1](https://github.com/soybeanjs/soybean-admin/compare/v0.10.4...v1.0.0-beta.1) (2024-03-25)
### &nbsp;&nbsp;&nbsp;🚀 Features
- internationalized menu search &nbsp;-&nbsp; by **Kori** [<samp>(9e115)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9e115da)
- **components**:
- enhance the custom strength of the 'TableHeaderOperation' component &nbsp;-&nbsp; by **tnt group** [<samp>(fdf64)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fdf64f7)
- add GlobalSearch components &nbsp;-&nbsp; by **燕博文** [<samp>(9ea87)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9ea8789)
- **hooks**:
- add use-echarts &nbsp;-&nbsp; by @honghuangdc [<samp>(726ab)</samp>](https://github.com/soybeanjs/soybean-admin/commit/726abe4)
- **projects**:
- 1.0 beta &nbsp;-&nbsp; by @honghuangdc [<samp>(e918a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e918a2c)
- support Vite5 &nbsp;-&nbsp; by @honghuangdc [<samp>(96e4a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/96e4aff)
- @sa/axios: createRequest, createFlatRequest, createHookRequest &nbsp;-&nbsp; by @honghuangdc [<samp>(bac16)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bac1632)
- add app loading &nbsp;-&nbsp; by @honghuangdc [<samp>(c6545)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c65451b)
- add copyright, unocss shortcut: card-wrapper, update package.json &nbsp;-&nbsp; by @honghuangdc [<samp>(affcc)</samp>](https://github.com/soybeanjs/soybean-admin/commit/affcc26)
- add page: about &nbsp;-&nbsp; by @honghuangdc [<samp>(4955f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4955f1a)
- add custom route exception &nbsp;-&nbsp; by @honghuangdc [<samp>(b43c9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b43c925)
- filter tabs which are not in routes &nbsp;-&nbsp; by @honghuangdc [<samp>(f59f3)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f59f348)
- packages/scripts: add command changelog,release &nbsp;-&nbsp; by @honghuangdc [<samp>(dafb6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/dafb6fa)
- add script: gen-route &nbsp;-&nbsp; by @honghuangdc [<samp>(697c1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/697c1b6)
- @sa/axios: add qs stringify for params &nbsp;-&nbsp; by @honghuangdc [<samp>(2400c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2400c02)
- page home & perf useEcharts &nbsp;-&nbsp; by @honghuangdc [<samp>(62e4d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/62e4da0)
- finish page home &nbsp;-&nbsp; by @honghuangdc [<samp>(7bd1e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7bd1e47)
- add page function_tab &nbsp;-&nbsp; by @honghuangdc [<samp>(6ff86)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6ff86e7)
- page manage_role &nbsp;-&nbsp; by @honghuangdc [<samp>(237c6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/237c6d2)
- page manage_user &nbsp;-&nbsp; by @honghuangdc [<samp>(8a170)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8a170ee)
- page manage_menu &nbsp;-&nbsp; by @honghuangdc [<samp>(87d65)</samp>](https://github.com/soybeanjs/soybean-admin/commit/87d65d3)
- page manage_menu operateDrawer &nbsp;-&nbsp; by @honghuangdc [<samp>(db17c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/db17c91)
- Add type to TabRoute: matched &nbsp;-&nbsp; by @Azir-11 [<samp>(2d102)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2d102a0)
- support directory menu hide all child menus. fixed #325 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/325 [<samp>(7256a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7256ad4)
- mock manage list data with pagination &nbsp;-&nbsp; by @honghuangdc [<samp>(1a6be)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1a6be00)
- globalSearch add i18n &nbsp;-&nbsp; by **燕博文** [<samp>(0126d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0126da4)
- Add route meta parameter:fixedQuery &nbsp;-&nbsp; by @Azir-11 [<samp>(874aa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/874aaca)
- update &nbsp;-&nbsp; by @honghuangdc [<samp>(4158a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4158a72)
- change borderRadius to 6px of naiveUI &nbsp;-&nbsp; by @honghuangdc [<samp>(49558)</samp>](https://github.com/soybeanjs/soybean-admin/commit/49558ca)
- pef manage role &nbsp;-&nbsp; by @honghuangdc [<samp>(18709)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1870981)
- login page: code-login &nbsp;-&nbsp; by @honghuangdc [<samp>(c91dd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c91dd28)
- login page: register &nbsp;-&nbsp; by @honghuangdc [<samp>(1ed33)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1ed33dc)
- add request refresh token & logout &nbsp;-&nbsp; by @honghuangdc [<samp>(11a6a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/11a6a3b)
- add request exception example page &nbsp;-&nbsp; by @honghuangdc [<samp>(41e8b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/41e8bc4)
- add auth example &nbsp;-&nbsp; by @honghuangdc [<samp>(c11d5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c11d56d)
- **router**:
- add sortRoutesByOrder function &nbsp;-&nbsp; by @Azir-11 [<samp>(0cf09)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0cf09ba)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **components**:
- fix tooltip zIndex of ButtonIcon &nbsp;-&nbsp; by @honghuangdc [<samp>(99097)</samp>](https://github.com/soybeanjs/soybean-admin/commit/99097b4)
- supplement the `NaiveUI` type &nbsp;-&nbsp; by **tnt group** [<samp>(ccc2b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ccc2b67)
- fix homeTab closeRight and disable colseLeft &nbsp;-&nbsp; by **~li** [<samp>(d28bf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d28bf52)
- **hooks**:
- Fix Naive Pagination's outdated API &nbsp;-&nbsp; by **tnt group** [<samp>(37436)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3743612)
- **projects**:
- 修复路由命名为包含关系时导致导航数据出错的问题 &nbsp;-&nbsp; by **pantao** [<samp>(76636)</samp>](https://github.com/soybeanjs/soybean-admin/commit/766369f)
- rename zh-ch &nbsp;-&nbsp; by @honghuangdc [<samp>(a8a77)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a8a77ea)
- Fix welcome notification not closing &nbsp;-&nbsp; by @Azir-11 [<samp>(748cf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/748cfa2)
- fix i18n vscode settings &nbsp;-&nbsp; by @honghuangdc [<samp>(fbf4c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fbf4cc4)
- add duration of login success notification &nbsp;-&nbsp; by @honghuangdc [<samp>(1335d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1335d47)
- fix menu indent &nbsp;-&nbsp; by @honghuangdc [<samp>(87143)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8714317)
- fix theme mode segment &nbsp;-&nbsp; by @honghuangdc [<samp>(2372d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2372dc9)
- fix app loading theme color &nbsp;-&nbsp; by @honghuangdc [<samp>(0ba19)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0ba19d5)
- fix page about style in mobile &nbsp;-&nbsp; by @honghuangdc [<samp>(8b6de)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8b6de48)
- fix themeDrawer darkMode segement &nbsp;-&nbsp; by @honghuangdc [<samp>(1b5ca)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1b5caa0)
- fix themeDrawer copy &nbsp;-&nbsp; by @honghuangdc [<samp>(b3779)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b3779a6)
- remove space in tab content &nbsp;-&nbsp; by @honghuangdc [<samp>(4aae6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4aae6a5)
- fix horizontal menu &nbsp;-&nbsp; by @honghuangdc [<samp>(d886e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d886e50)
- perf card style &nbsp;-&nbsp; by @honghuangdc [<samp>(c1afb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c1afb9d)
- fix manage_user title &nbsp;-&nbsp; by @honghuangdc [<samp>(7770b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7770b37)
- default proxy prefix &nbsp;-&nbsp; by @smileluck [<samp>(da246)</samp>](https://github.com/soybeanjs/soybean-admin/commit/da24642)
- fix request msg &nbsp;-&nbsp; by @honghuangdc [<samp>(ae6b6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ae6b613)
- Fix the issue of tab error displaying parent localIcon &nbsp;-&nbsp; by @Azir-11 [<samp>(a9c98)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a9c98d9)
- The matched value of TabRoute should be optional &nbsp;-&nbsp; by @Azir-11 [<samp>(e6fed)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e6fed1f)
- fix build [unocss]: build failed to load icon "close", fixed #319 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/319 [<samp>(c18d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c18d82f)
- fix resolve alias &nbsp;-&nbsp; by @honghuangdc [<samp>(3bdcb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3bdcbc7)
- Missing default value for tab icon &nbsp;-&nbsp; by @Azir-11 [<samp>(72a46)</samp>](https://github.com/soybeanjs/soybean-admin/commit/72a4679)
- add route icon: fucntion_hide-child &nbsp;-&nbsp; by @honghuangdc [<samp>(0a3ef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0a3efe3)
- fix table x-scroll. fixed #324 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/324 [<samp>(c7e2c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c7e2c55)
- Fix the logic of root route redirection to home &nbsp;-&nbsp; by **恕瑞玛的皇帝** [<samp>(0123c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0123c37)
- Fix homepage mount error under dynamic routing &nbsp;-&nbsp; by **恕瑞玛的皇帝** [<samp>(9cf2a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9cf2a51)
- fix repeat home tab &nbsp;-&nbsp; by @honghuangdc [<samp>(bccd6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bccd6cb)
- fix proxy config &nbsp;-&nbsp; by @honghuangdc [<samp>(c8019)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c8019c4)
- fix proxy config &nbsp;-&nbsp; by @honghuangdc [<samp>(ffc95)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ffc95d2)
- fix table row-key ts type &nbsp;-&nbsp; by @honghuangdc [<samp>(0cc8f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0cc8f05)
- fix class name conflict with unocss icon &nbsp;-&nbsp; by @honghuangdc [<samp>(455e4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/455e48f)
- fix repeat routes &nbsp;-&nbsp; by @honghuangdc [<samp>(2c543)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2c543f1)
- fix route init &nbsp;-&nbsp; by @honghuangdc [<samp>(23a40)</samp>](https://github.com/soybeanjs/soybean-admin/commit/23a4098)
### &nbsp;&nbsp;&nbsp;🔥 Performance
- **components**:
- Optimize internationalized menu search code &nbsp;-&nbsp; by **燕博文** [<samp>(8c1ef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8c1ef4b)
- Optimize menu search code &nbsp;-&nbsp; by **燕博文** [<samp>(296a2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/296a2d2)
- perf count-to &nbsp;-&nbsp; by @honghuangdc [<samp>(b2c61)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b2c61f0)
- components name is converted to uppercase &nbsp;-&nbsp; by **燕博文** [<samp>(04aa1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/04aa10b)
- perf global-search &nbsp;-&nbsp; by @honghuangdc [<samp>(72745)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7274522)
- **projects**:
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(8081e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8081e19)
- env config &nbsp;-&nbsp; by @honghuangdc [<samp>(1bac3)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1bac3b7)
- add detailed annotations for route role &nbsp;-&nbsp; by @honghuangdc [<samp>(f6bab)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f6bab0c)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(5c49d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5c49d24)
- remove useless file &nbsp;-&nbsp; by @honghuangdc [<samp>(c624f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c624f32)
- remove @soybeanjs/cli &nbsp;-&nbsp; by @honghuangdc [<samp>(41349)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4134955)
- echarts loading style &nbsp;-&nbsp; by @honghuangdc [<samp>(456c3)</samp>](https://github.com/soybeanjs/soybean-admin/commit/456c318)
- perf page manage_role, useTable &nbsp;-&nbsp; by @honghuangdc [<samp>(39aa7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/39aa7aa)
- perf table columns style &nbsp;-&nbsp; by @honghuangdc [<samp>(babdb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/babdb5d)
- perf page manage_menu style &nbsp;-&nbsp; by @honghuangdc [<samp>(0aa75)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0aa75c0)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(7fa87)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7fa87f5)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(05db8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/05db8c0)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(dc24a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/dc24a36)
- perf manage page style &nbsp;-&nbsp; by @honghuangdc [<samp>(779ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/779ba4e)
- perf manage menu &nbsp;-&nbsp; by @honghuangdc [<samp>(71f2c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/71f2c55)
- manage menu: add transform to component &nbsp;-&nbsp; by @honghuangdc [<samp>(0abbf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0abbfa5)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **projects**:
- remove plugin-web-update-notification &nbsp;-&nbsp; by @honghuangdc [<samp>(f6c6d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f6c6dbd)
- fix conflict with locale file &nbsp;-&nbsp; by @honghuangdc [<samp>(3346b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3346bcd)
- refactor app-loading &nbsp;-&nbsp; by @honghuangdc [<samp>(b4f3d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b4f3dd2)
- use naive-ui color-picker &nbsp;-&nbsp; by @honghuangdc [<samp>(b5551)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5551d6)
- perf page home &nbsp;-&nbsp; by @honghuangdc [<samp>(4c61c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4c61c6f)
- login components => modules &nbsp;-&nbsp; by @honghuangdc [<samp>(59bec)</samp>](https://github.com/soybeanjs/soybean-admin/commit/59bec2d)
- perf page function_tab &nbsp;-&nbsp; by @honghuangdc [<samp>(b5477)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5477e8)
- update mock api &nbsp;-&nbsp; by @honghuangdc [<samp>(27241)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2724169)
- page manage_role: extract module &nbsp;-&nbsp; by @honghuangdc [<samp>(0e9e2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0e9e2e1)
- perf page manage_role &nbsp;-&nbsp; by @honghuangdc [<samp>(a19f8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a19f895)
- manage_route => manage_menu &nbsp;-&nbsp; by @honghuangdc [<samp>(f8467)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f8467ce)
- refactor service env config &nbsp;-&nbsp; by @honghuangdc [<samp>(43193)</samp>](https://github.com/soybeanjs/soybean-admin/commit/43193e2)
- refactor unocss shortcuts: wh-full => size-full &nbsp;-&nbsp; by @honghuangdc [<samp>(b4c00)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b4c00ce)
- use enquirer replace prompts &nbsp;-&nbsp; by @honghuangdc [<samp>(b546f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b546ff8)
- refactor useTable &nbsp;-&nbsp; by @honghuangdc [<samp>(c3efa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c3efa1b)
- finish refactor useTable &nbsp;-&nbsp; by @honghuangdc [<samp>(86301)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8630175)
- finish refactor useTable and apply &nbsp;-&nbsp; by @honghuangdc [<samp>(3fd15)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3fd15e5)
- perf code &nbsp;-&nbsp; by @honghuangdc [<samp>(f91ef)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f91ef30)
- new route guard &nbsp;-&nbsp; by @honghuangdc [<samp>(37d20)</samp>](https://github.com/soybeanjs/soybean-admin/commit/37d20b8)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**:
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(78364)</samp>](https://github.com/soybeanjs/soybean-admin/commit/783648f)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(1ea48)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1ea4817)
- add README &nbsp;-&nbsp; by @honghuangdc [<samp>(2371b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2371ba8)
- update README &nbsp;-&nbsp; by @honghuangdc [<samp>(d16a9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d16a9d5)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(6a771)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6a771ea)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(57b6d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/57b6d8a)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(b30c0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b30c035)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(c260f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c260fe2)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(03c42)</samp>](https://github.com/soybeanjs/soybean-admin/commit/03c42aa)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(0fae9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0fae993)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(4e4d2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4e4d2de)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(86b44)</samp>](https://github.com/soybeanjs/soybean-admin/commit/86b445c)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(e2085)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e2085e0)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(6ea9b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6ea9b85)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(ef4af)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ef4af79)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(41830)</samp>](https://github.com/soybeanjs/soybean-admin/commit/418302a)
- add CHANGELOG.md &nbsp;-&nbsp; by @honghuangdc [<samp>(46b61)</samp>](https://github.com/soybeanjs/soybean-admin/commit/46b6156)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**:
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(3eaf0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3eaf05b)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(36fe1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/36fe1da)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(55342)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5534294)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(f1b86)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f1b86cc)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(840e7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/840e7f9)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(6114b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6114b9f)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(9cc7e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9cc7ee5)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(9c4ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9c4ba66)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(fb3b9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fb3b94b)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(14aa8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/14aa856)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(02d4b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/02d4b0a)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(b2ee9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b2ee9ee)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(0fee1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0fee104)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(c0a65)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c0a65a1)
- **project**:
- delete src/locales/lang/zh-CN.ts &nbsp;-&nbsp; by @honghuangdc [<samp>(377db)</samp>](https://github.com/soybeanjs/soybean-admin/commit/377db82)
- **projects**:
- use eslint flat config & update config &nbsp;-&nbsp; by @honghuangdc [<samp>(a176d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a176dc4)
- update @sa/scripts &nbsp;-&nbsp; by @honghuangdc [<samp>(d7785)</samp>](https://github.com/soybeanjs/soybean-admin/commit/d778560)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(55f76)</samp>](https://github.com/soybeanjs/soybean-admin/commit/55f7638)
- update eslint config &nbsp;-&nbsp; by @honghuangdc [<samp>(5023f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5023f37)
- lock deps versions &nbsp;-&nbsp; by @honghuangdc [<samp>(a24f9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a24f963)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(ea02b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ea02b23)
- remove @simonwep/pickr &nbsp;-&nbsp; by @honghuangdc [<samp>(502a4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/502a4d2)
- remove soybean.svg &nbsp;-&nbsp; by @honghuangdc [<samp>(4031f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4031faf)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(adec0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/adec0d7)
- update deps & fix keep-alive &nbsp;-&nbsp; by @honghuangdc [<samp>(13001)</samp>](https://github.com/soybeanjs/soybean-admin/commit/13001bc)
- update @elegant-router/vue, fix inject name in windows &nbsp;-&nbsp; by @honghuangdc [<samp>(0b56e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0b56e44)
- add dev and build command with service env &nbsp;-&nbsp; by @honghuangdc [<samp>(ebb15)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ebb1548)
- update deps & remove packages docs &nbsp;-&nbsp; by @honghuangdc [<samp>(57963)</samp>](https://github.com/soybeanjs/soybean-admin/commit/579636b)
- update pnpm-lock.yaml &nbsp;-&nbsp; by @honghuangdc [<samp>(147f6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/147f60d)
- update repository url &nbsp;-&nbsp; by @honghuangdc [<samp>(806a1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/806a1cb)
- update deps & update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(9772a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9772aec)
- add unocss eslint config &nbsp;-&nbsp; by @honghuangdc [<samp>(40635)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4063529)
- update launch.json &nbsp;-&nbsp; by @honghuangdc [<samp>(3db82)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3db82ac)
- update vscode extensions.json &nbsp;-&nbsp; by @honghuangdc [<samp>(4e29a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4e29aca)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(7065f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7065f6f)
- update deps & fix eslint vue rule &nbsp;-&nbsp; by @honghuangdc [<samp>(8143b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8143b00)
- update pnpm version &nbsp;-&nbsp; by @honghuangdc [<samp>(6ad51)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6ad51e9)
### &nbsp;&nbsp;&nbsp;🎨 Styles
- **components**:
- Uniform icon size for header &nbsp;-&nbsp; by @Azir-11 [<samp>(b37c1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b37c1e9)
- **projects**:
- format code &nbsp;-&nbsp; by @honghuangdc [<samp>(a7481)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a748166)
- update theme mode segment height &nbsp;-&nbsp; by @honghuangdc [<samp>(4d846)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4d8469e)
- fix tooltip zIndex of ButtonIcon &nbsp;-&nbsp; by @honghuangdc [<samp>(db747)</samp>](https://github.com/soybeanjs/soybean-admin/commit/db747c4)
- sort defineProps, defineEmits with TS type &nbsp;-&nbsp; by @honghuangdc [<samp>(123fd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/123fd4f)
### &nbsp;&nbsp;&nbsp;🤖 CI
- **projects**: add github actions config &nbsp;-&nbsp; by @honghuangdc [<samp>(4cb17)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4cb17c7)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;[![Azir-11](https://github.com/Azir-11.png?size=48)](https://github.com/Azir-11)&nbsp;&nbsp;[![smileluck](https://github.com/smileluck.png?size=48)](https://github.com/smileluck)&nbsp;&nbsp;[![Particaly](https://github.com/Particaly.png?size=48)](https://github.com/Particaly)&nbsp;&nbsp;
[~li](mailto:miciili-02@outlook.com),&nbsp;[Azir-11](mailto:2075125282@qq.com),&nbsp;[燕博文](mailto:349952469@qq.com),&nbsp;[tnt group](mailto:dodu@live.cn),&nbsp;[Kori](mailto:kexin@korix.top),&nbsp;
## [v0.10.4](https://github.com/honghuangdc/soybean-admin/compare/v0.10.3...v0.10.4) (23-09-20)
### &nbsp;&nbsp;&nbsp;🚀 Features
- **auth**:
- 防止多次刷新token &nbsp;-&nbsp; by @eAliwei [<samp>(0eaa3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/0eaa327)
- **hooks**:
- add useHookTable &nbsp;-&nbsp; by @honghuangdc [<samp>(b3ae7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/b3ae760)
- **projects**:
- add websocket demo &nbsp;-&nbsp; by @honghuangdc [<samp>(af53e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/af53ec7)
- add switch for customize darkmode transition &nbsp;-&nbsp; by @honghuangdc [<samp>(6e0cc)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6e0cce4)
- new i18n function $t & login page and setting drawer config i18n &nbsp;-&nbsp; by @honghuangdc [<samp>(854d0)</samp>](https://github.com/honghuangdc/soybean-admin/commit/854d0bc)
- add plugin-web-update-notification &nbsp;-&nbsp; by @honghuangdc [<samp>(c9164)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c91644b)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **components**:
- 修复动态路由主页404 &nbsp;-&nbsp; by @lapislazulisch [<samp>(3ae19)</samp>](https://github.com/honghuangdc/soybean-admin/commit/3ae1952)
- 修复动态路由home页404 &nbsp;-&nbsp; by @lapislazulisch [<samp>(ad6ac)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ad6ac72)
- **projects**:
- fix set tab title (fixed #256) &nbsp;-&nbsp; by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/256 [<samp>(13f6c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/13f6cd8)
- correct the lang file name & add recommend vscode plugin i18n-ally &nbsp;-&nbsp; by @honghuangdc [<samp>(864ec)</samp>](https://github.com/honghuangdc/soybean-admin/commit/864ec47)
- fix reload button animate &nbsp;-&nbsp; by @honghuangdc [<samp>(41f23)</samp>](https://github.com/honghuangdc/soybean-admin/commit/41f2338)
- **styles**:
- 用户管理页面布局自适应屏幕高度 (fixed #253) &nbsp;-&nbsp; by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/253 [<samp>(0f7b9)</samp>](https://github.com/honghuangdc/soybean-admin/commit/0f7b9d5)
### &nbsp;&nbsp;&nbsp;🔥 Performance
- **hooks**:
- perf use-table &nbsp;-&nbsp; by @honghuangdc [<samp>(33180)</samp>](https://github.com/honghuangdc/soybean-admin/commit/3318041)
- perf useHookTable &nbsp;-&nbsp; by @honghuangdc [<samp>(809fa)</samp>](https://github.com/honghuangdc/soybean-admin/commit/809fa85)
- **projects**:
- add type declaration for document startViewTransition &nbsp;-&nbsp; by @honghuangdc [<samp>(d3ebe)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d3ebe95)
### &nbsp;&nbsp;&nbsp;💅 Refactors
- **projects**:
- 生产环境缓存主题变更为sessionStorage &nbsp;-&nbsp; by @honghuangdc [<samp>(c46a5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c46a592)
- add reCacheRoute method &nbsp;-&nbsp; by @honghuangdc [<samp>(f92ee)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f92ee77)
- update soybean domain &nbsp;-&nbsp; by @honghuangdc [<samp>(073fd)</samp>](https://github.com/honghuangdc/soybean-admin/commit/073fd16)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**:
- update README.md logo &nbsp;-&nbsp; by @honghuangdc [<samp>(19141)</samp>](https://github.com/honghuangdc/soybean-admin/commit/19141a7)
- update Docker deployment method &nbsp;-&nbsp; by @snowords [<samp>(00da0)</samp>](https://github.com/honghuangdc/soybean-admin/commit/00da000)
- update git hooks init command &nbsp;-&nbsp; by @snowords [<samp>(7f35e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/7f35e87)
- update README.md &nbsp;-&nbsp; by @eltociear [<samp>(93ed5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/93ed5ad)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**:
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(bba68)</samp>](https://github.com/honghuangdc/soybean-admin/commit/bba68bf)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(0e6d2)</samp>](https://github.com/honghuangdc/soybean-admin/commit/0e6d289)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(135ce)</samp>](https://github.com/honghuangdc/soybean-admin/commit/135ce77)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(44ba3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/44ba327)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(9296e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9296e69)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(751de)</samp>](https://github.com/honghuangdc/soybean-admin/commit/751ded4)
- update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(305d9)</samp>](https://github.com/honghuangdc/soybean-admin/commit/305d956)
- **projects**:
- update deps and fix swiper &nbsp;-&nbsp; by @honghuangdc [<samp>(9d105)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9d1051b)
- update package.json &nbsp;-&nbsp; by @honghuangdc [<samp>(d7aea)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d7aea9d)
- update deps & fix eslint code &nbsp;-&nbsp; by @honghuangdc [<samp>(08e0c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/08e0cf5)
- update pnpm-lock.yaml &nbsp;-&nbsp; by @honghuangdc [<samp>(94644)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9464473)
- update VSCode setting &nbsp;-&nbsp; by @honghuangdc [<samp>(56c77)</samp>](https://github.com/honghuangdc/soybean-admin/commit/56c770c)
- correct the word spell &nbsp;-&nbsp; by @honghuangdc [<samp>(458e3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/458e387)
- correct word spell & eslint fix code &nbsp;-&nbsp; by @honghuangdc [<samp>(cffc3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cffc30a)
- When tab is switched, keep the page without refreshing &nbsp;-&nbsp; by @linjiangl [<samp>(83f25)</samp>](https://github.com/honghuangdc/soybean-admin/commit/83f2514)
### &nbsp;&nbsp;&nbsp;🎨 Styles
- **projects**:
- unify card border radius, 16px to 8px &nbsp;-&nbsp; by @honghuangdc [<samp>(cbda4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cbda4a3)
- update default theme color &nbsp;-&nbsp; by @honghuangdc [<samp>(43ac2)</samp>](https://github.com/honghuangdc/soybean-admin/commit/43ac23f)
- prettier format code &nbsp;-&nbsp; by @honghuangdc [<samp>(24cf1)</samp>](https://github.com/honghuangdc/soybean-admin/commit/24cf1d9)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;[![eltociear](https://github.com/eltociear.png?size=48)](https://github.com/eltociear)&nbsp;&nbsp;[![linjiangl](https://github.com/linjiangl.png?size=48)](https://github.com/linjiangl)&nbsp;&nbsp;[![lapislazulisch](https://github.com/lapislazulisch.png?size=48)](https://github.com/lapislazulisch)&nbsp;&nbsp;[![snowords](https://github.com/snowords.png?size=48)](https://github.com/snowords)&nbsp;&nbsp;[![eAliwei](https://github.com/eAliwei.png?size=48)](https://github.com/eAliwei)&nbsp;&nbsp;[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v0.10.3](https://github.com/honghuangdc/soybean-admin/compare/v0.10.2...v0.10.3) (23-06-15)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes

View File

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

212
README.md
View File

@@ -1,180 +1,164 @@
<div align="center">
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean.svg" style="width: 160px;"/>
<img src="./public/favicon.svg" width="160" />
<h1>Soybean Admin</h1>
<span>English | <a href="./README.zh_CN.md">中文</a></span>
</div>
[![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/honghuangdc/soybean-admin) ![](https://img.shields.io/github/forks/honghuangdc/soybean-admin)
---
## 简介
[![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
[![github stars](https://img.shields.io/github/stars/soybeanjs/soybean-admin)](https://github.com/soybeanjs/soybean-admin)
[![github forks](https://img.shields.io/github/forks/soybeanjs/soybean-admin)](https://github.com/soybeanjs/soybean-admin)
[![gitee stars](https://gitee.com/honghuangdc/soybean-admin/badge/star.svg)](https://gitee.com/honghuangdc/soybean-admin)
[Soybean Admin](https://github.com/honghuangdc/soybean-admin) 是一个基于 Vue3、Vite3、TypeScript、NaiveUI、Pinia 和 UnoCSS 的清新优雅的中后台模版,它使用了最新流行的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于文件的路由系统以及基于 Mock 的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。
> [!NOTE]
> If you think `Soybean Admin` is helpful to you, or you like our project, please give us a ⭐️ on GitHub. Your support is the driving force for us to continue to improve and add new features! Thank you for your support!
## 特性
## Introduction
- **最新流行技术栈**:使用 Vue3/Vite 等前端前沿技术开发, 使用高效率的 npm 包管理器 pnpm
- **TypeScript**: 应用程序级 JavaScript 的语言
- **主题**:丰富可配置的主题、暗黑模式,基于原子 css 框架 - UnoCss 的动态主题颜色
- **代码规范**:丰富的规范插件及极高的代码规范
- **文件路由系统**:基于文件的路由系统,根据页面文件自动生成路由声明、路由导入和路由模块
- **权限路由**:提供前端静态和后端动态两种路由模式,基于 mock 的动态路由能快速实现后端动态路由
- **请求函数**:基于 axios 的完善的请求函数封装,提供 Promise 和 hooks 两种请求函数,加入请求结果数据转换的适配器
[`Soybean Admin`](https://github.com/soybeanjs/soybean-admin) is a clean, elegant, beautiful and powerful admin template, based on the latest front-end technology stack, including Vue3, Vite5, TypeScript, Pinia and UnoCSS. It has built-in rich theme configuration and components, strict code specifications, and an automated file routing system. In addition, it also uses the online mock data solution based on ApiFox. `Soybean Admin` provides you with a one-stop admin solution, no additional configuration, and out of the box. It is also a best practice for learning cutting-edge technologies quickly.
## SoybeanJS 工具库
- [@soybeanjs/cli](https://github.com/soybeanjs/cli): SoybeanJS 命令行工具包含发布、git 和依赖等相关的实用命令
- [@soybeanjs/changelog](https://github.com/soybeanjs/changelog): 根据 git tags 和 commits 生成 changelog [示例](./CHANGELOG.md)
- [eslint-config-soybeanjs](https://github.com/soybeanjs/eslint-config): SoybeanJS 的 eslint 预设配置
- [@soybeanjs/materials](https://github.com/soybeanjs/materials): SoybeanJS 的物料仓库
- [@soybeanjs/vite-plugin-vue-page-route](https://github.com/soybeanjs/vite-plugin-vue-page-route): SoybeanAdmin 的路由插件
## Features
## 基于 SoybeanAdmin 二次开发的项目
- **Cutting-edge technology application**: using the latest popular technology stack such as Vue3, Vite5, TypeScript, Pinia and UnoCSS.
- **Clear project architecture**: using pnpm monorepo architecture, clear structure, elegant and easy to understand.
- **Strict code specifications**: follow the [SoybeanJS specification](https://docs.soybeanjs.cn/standard), integrate eslint, prettier and simple-git-hooks to ensure the code is standardized.
- **TypeScript**: support strict type checking to improve code maintainability.
- **Rich theme configuration**: built-in a variety of theme configurations, perfectly integrated with UnoCSS.
- **Built-in internationalization solution**: easily realize multi-language support.
- **Automated file routing system**: automatically generate route import, declaration and type. For more details, please refer to [Elegant Router](https://github.com/soybeanjs/elegant-router).
- **Flexible permission routing**: support both front-end static routing and back-end dynamic routing.
- **Rich page components**: built-in a variety of pages and components, including 403, 404, 500 pages, as well as layout components, tag components, theme configuration components, etc.
- **Command line tool**: built-in efficient command line tool, git commit, delete file, release, etc.
- **Mobile adaptation**: perfectly support mobile terminal to realize adaptive layout.
- [electron-mock-admin](https://github.com/lixin59/electron-mock-api): 一个 Mock Api 管理系统,帮助前端开发伙伴快速实现接口的 mock。
- [T-Shell](https://github.com/TheBlindM/T-Shell): 是一个可配置命令提示的终端模拟器和 SSH 客户端。
## 在线预览
## Version
- [Soybean Admin 预览地址](https://soybean.pro/)
- **NaiveUI Version:**
- [Preview Link](https://naive.soybeanjs.cn/)
- [Github Repository](https://github.com/soybeanjs/soybean-admin)
- [Gitee Repository](https://gitee.com/honghuangdc/soybean-admin)
## 文档
- **AntDesignVue Version:**
- [Preview Link](https://antd.soybeanjs.cn/)
- [Github Repository](https://github.com/soybeanjs/soybean-admin-antd)
- [Gitee Repository](https://gitee.com/honghuangdc/soybean-admin-antd)
- [项目文档预览地址](https://docs.soybean.pro)
- **Legacy Version:**
- [Preview Link](https://legacy.soybeanjs.cn/)
- [Github Repository](https://github.com/soybeanjs/soybean-admin/tree/legacy)
## 代码仓库
| 仓库 | github 地址 | gitee 镜像 | 预览 |
| -------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
| soybean-admin | [github](https://github.com/honghuangdc/soybean-admin) | [gitee](https://gitee.com/honghuangdc/soybean-admin) | [预览](https://soybean.pro/) |
| tauri 版 | [tauri 版](https://github.com/honghuangdc/soybean-admin/tree/tauri) | [tauri 版](https://gitee.com/honghuangdc/soybean-admin/tree/tauri) | |
| 精简版 | [精简版](https://github.com/honghuangdc/soybean-admin/tree/thin) | [精简版](https://gitee.com/honghuangdc/soybean-admin/tree/thin) | |
| 集成 fast-crud | [集成 fast-crud](https://github.com/honghuangdc/soybean-admin/tree/fast-crud) | [集成 fast-crud](https://gitee.com/honghuangdc/soybean-admin/tree/fast-crud) | [预览](http://fast-crud.docmirror.cn/soybean/#/crud/demo) |
## Documentation
## 更新日志
- [Link](https://docs.soybeanjs.cn)
- [Legacy Docs](https://legacy-docs.soybeanjs.cn)
[CHANGELOG](./CHANGELOG.md)
## Example Images
## 后端服务
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-01.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-02.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-03.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-04.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-05.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-06.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-07.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-08.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-09.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-10.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-mobile.png)
- [soybean-admin-java](https://github.com/honghuangdc/soybean-admin-java)
## 项目示例图
## Usage
![](https://s2.loli.net/2022/05/16/keOtgFH27r9nqYS.png)
**Environment Preparation**
![](https://s2.loli.net/2022/05/18/bW7mftiQexkvSTG.png)
Make sure your environment meets the following requirements:
![](https://s2.loli.net/2022/05/16/uV5nzjb3gYptAEl.png)
- **git**: you need git to clone and manage project versions.
- **NodeJS**: >=18.0.0, recommended 18.19.0 or higher.
- **pnpm**: >= 8.0.0, recommended 8.14.0 or higher.
![](https://s2.loli.net/2022/05/16/rSnNHLdpuvkKxWq.png)
![](https://s2.loli.net/2023/06/07/O39EKNa675FZIuS.png)
![](https://s2.loli.net/2022/05/18/Mt6YZqmDxO8v4uR.png)
![](https://s2.loli.net/2023/06/07/zhmWnFlPTfDpot8.png)
![](https://s2.loli.net/2022/05/16/VPl6Ru1iCAhLcS4.png)
![](https://s2.loli.net/2023/06/07/n6Dy1HXBvuPc9oT.png)
![](https://s2.loli.net/2022/06/07/rY8TyAftM5dxspv.png)
![](https://s2.loli.net/2022/06/07/5GNBAd31IzQVjLP.png)
![](https://s2.loli.net/2022/06/07/rRSG6mEZpujOACT.png)
<div align="center">
<img style="width:380px;margin-right:18px;border:1px solid #dedede;" src="https://s2.loli.net/2023/06/07/A5Nonc9vI6pB1lr.png" />
&nbsp;
<img style="width:380px;border:1px solid #dedede;" src="https://s2.loli.net/2023/06/07/VwBjqEhTke3OxXF.png" />
</div>
## 安装使用
- 环境配置
**本地环境需要安装 pnpm 7.x 、Node.js 14.18+ 和 Git**
- 克隆代码
**Clone Project**
```bash
git clone https://github.com/honghuangdc/soybean-admin.git
git clone https://github.com/soybeanjs/soybean-admin.git
```
- 安装依赖
**Install Dependencies**
```bash
pnpm i
```
> Since this project uses the pnpm monorepo management method, please do not use npm or yarn to install dependencies.
- 运行
**Start Project**
```bash
pnpm dev
```
- 打包
**Build Project**
```bash
pnpm build
```
## Docker 部署
## How to Contribute
- Docker 部署 Soybean
We warmly welcome and appreciate all forms of contributions. If you have any ideas or suggestions, please feel free to share them by submitting [pull requests](https://github.com/soybeanjs/soybean-admin/pulls) or creating GitHub [issue](https://github.com/soybeanjs/soybean-admin/issues/new).
```bash
docker run --name soybean -p 80:80 -d soybeanjs/soybean-admin:v0.9.6
```
## Git Commit Guidelines
- 访问 SoybeanAdmin
This project has built-in `commit` command, you can execute `pnpm commit` to generate commit information that conforms to [Conventional Commits](https://www.conventionalcommits.org/) specification. When submitting PR, please be sure to use `commit` command to create commit information to ensure the standardization of information.
打开本地浏览器访问`http://localhost`
## Browser Support
## 如何贡献
It is recommended to use the latest version of Chrome in development for a better experience.
非常欢迎您的加入![提一个 Issue](https://github.com/honghuangdc/soybean-admin/issues/new) 或者提交一个 Pull Request。
| [<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/) | [<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/) | [<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/) | [<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/) | [<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/) |
| --- | --- | --- | --- | --- |
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## Git 贡献提交规范
## OpenSource Author
项目已经内置 Angular 提交规范,直接执行 commit 命令即可生成符合 Angular 提交规范的 commit。
[Soybean](https://github.com/honghuangdc)
项目已用 simple-git-hooks 代替了 husky, 旧版本用了 husky执行 pnpm soy init-git-hooks 进行初始化配置
## Contributors
## 浏览器支持
Thanks the following people for their contributions. If you want to contribute to this project, please refer to [How to Contribute](#how-to-contribute).
本地开发推荐使用`Chrome 90+` 浏览器
<a href="https://github.com/soybeanjs/soybean-admin/graphs/contributors">
<img src="https://contrib.rocks/image?repo=soybeanjs/soybean-admin" />
</a>
支持现代浏览器, 不支持 IE
## Communication
| [<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 |
`Soybean Admin` is a completely open source and free project, helping developers to develop medium and large-scale management systems more conveniently. It also provides WeChat and QQ communication groups. If you have any questions, please feel free to ask in the group.
## 开源作者
[@Soybean](https://github.com/honghuangdc)
## 交流
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群,使用问题欢迎在群内提问。
<div style="display:flex;">
<div style="padding-right:24px;">
<p>QQ交流群</p>
<img src="https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg" style="width:200px" />
</div>
<div>
<p>添加本人微信,欢迎来技术交流,业务咨询</p>
<img src="https://s2.loli.net/2023/06/07/sVyCUFBvzQ9f5b7.jpg" style="width:200px" />
</div>
<div>
<p>QQ Group</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/qq-soybean-admin-2.jpg" style="width:200px" />
</div>
<!-- <div>
<p>WeChat Group</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-0402.jpg" style="width:200px" />
</div> -->
<div>
<p>Add the following WeChat to invite to the WeChat group</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-soybeanjs.jpg" style="width:200px" />
</div>
<div>
<p>Add Soybean's WeChat for business consultation, cooperation, project architecture, one-on-one guidance, etc.</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-soybean.jpg" style="width:200px" />
</div>
## 捐赠
## Star Trend
如果你觉得这个项目对你有帮助,可以请 Soybean 喝杯饮料表示支持Soybean 开源的动力离不开各位的支持和鼓励。
![赞助](https://s2.loli.net/2022/01/24/i9cpq7lTCrKUoFf.png)
[![Star History Chart](https://api.star-history.com/svg?repos=soybeanjs/soybean-admin&type=Date)](https://star-history.com/#soybeanjs/soybean-admin&Date)
## License
本项目基于[MIT © Soybean-2021](./LICENSE) 协议,仅供参考学习,商用时请保留作者的版权信息,作者不对软件做担保和负责。
This project is based on the [MIT © 2021 Soybean](./LICENSE) protocol, for learning purposes only, please retain the author's copyright information for commercial use, the author does not guarantee and is not responsible for the software.

164
README.zh_CN.md Normal file
View File

@@ -0,0 +1,164 @@
<div align="center">
<img src="./public/favicon.svg" width="160" />
<h1>Soybean Admin</h1>
<span><a href="./README.zh_CN.md">English</a> | 中文</span>
</div>
---
[![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
[![github stars](https://img.shields.io/github/stars/honghuangdc/soybean-admin)](https://github.com/soybeanjs/soybean-admin)
[![github forks](https://img.shields.io/github/forks/honghuangdc/soybean-admin)](https://github.com/soybeanjs/soybean-admin)
[![gitee stars](https://gitee.com/honghuangdc/soybean-admin/badge/star.svg)](https://gitee.com/honghuangdc/soybean-admin)
> [!NOTE]
> 如果您觉得 `Soybean Admin`对您有所帮助,或者您喜欢我们的项目,请在 GitHub 上给我们一个 ⭐️。您的支持是我们持续改进和增加新功能的动力!感谢您的支持!
## 简介
[`Soybean Admin`](https://github.com/soybeanjs/soybean-admin) 是一个清新优雅、高颜值且功能强大的后台管理模板,基于最新的前端技术栈,包括 Vue3, Vite5, TypeScript, Pinia 和 UnoCSS。它内置了丰富的主题配置和组件代码规范严谨实现了自动化的文件路由系统。此外它还采用了基于 ApiFox 的在线Mock数据方案。`Soybean Admin` 为您提供了一站式的后台管理解决方案,无需额外配置,开箱即用。同样是一个快速学习前沿技术的最佳实践。
## 特性
- **前沿技术应用**:采用 Vue3, Vite5, TypeScript, Pinia 和 UnoCSS 等最新流行的技术栈。
- **清晰的项目架构**:采用 pnpm monorepo 架构,结构清晰,优雅易懂。
- **严格的代码规范**:遵循 [SoybeanJS 规范](https://docs.soybeanjs.cn/zh/standard)集成了eslint, prettier 和 simple-git-hooks保证代码的规范性。
- **TypeScript** 支持严格的类型检查,提高代码的可维护性。
- **丰富的主题配置**:内置多样的主题配置,与 UnoCSS 完美结合。
- **内置国际化方案**:轻松实现多语言支持。
- **自动化文件路由系统**:自动生成路由导入、声明和类型。更多细节请查看 [Elegant Router](https://github.com/soybeanjs/elegant-router)。
- **灵活的权限路由**:同时支持前端静态路由和后端动态路由。
- **丰富的页面组件**内置多样页面和组件包括403、404、500页面以及布局组件、标签组件、主题配置组件等。
- **命令行工具**内置高效的命令行工具git提交、删除文件、发布等。
- **移动端适配**:完美支持移动端,实现自适应布局。
## 版本
- **NaiveUI 版本:**
- [预览地址](https://naive.soybeanjs.cn/)
- [Github 仓库](https://github.com/soybeanjs/soybean-admin)
- [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin)
- **AntDesignVue 版本:**
- [预览地址](https://antd.soybeanjs.cn/)
- [Github 仓库](https://github.com/soybeanjs/soybean-admin-antd)
- [Gitee 仓库](https://gitee.com/honghuangdc/soybean-admin-antd)
- **旧版:**
- [预览地址](https://legacy.soybeanjs.cn/)
- [Github 仓库](https://github.com/soybeanjs/soybean-admin/tree/legacy)
## 文档
- [地址](https://docs.soybeanjs.cn)
- [旧版文档](https://legacy-docs.soybeanjs.cn)
## 示例图片
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-01.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-02.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-03.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-04.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-05.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-06.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-07.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-08.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-09.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-10.png)
![](https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/soybean-admin-v1-mobile.png)
## 使用
**环境准备**
确保你的环境满足以下要求:
- **git**: 你需要git来克隆和管理项目版本。
- **NodeJS**: >=18.0.0,推荐 18.19.0 或更高。
- **pnpm**: >= 8.0.0,推荐 8.14.0 或更高。
**克隆项目**
```bash
git clone https://github.com/soybeanjs/soybean-admin.git
```
**安装依赖**
```bash
pnpm i
```
> 由于本项目采用了 pnpm monorepo 的管理方式,因此请不要使用 npm 或 yarn 来安装依赖。
**启动项目**
```bash
pnpm dev
```
**构建项目**
```bash
pnpm build
```
## 如何贡献
我们热烈欢迎并感谢所有形式的贡献。如果您有任何想法或建议,欢迎通过提交 [pull requests](https://github.com/soybeanjs/soybean-admin/pulls) 或创建 GitHub [issue](https://github.com/soybeanjs/soybean-admin/issues/new) 来分享。
## Git 提交规范
本项目已内置 `commit` 命令,您可以通过执行 `pnpm commit` 来生成符合 [Conventional Commits]([conventionalcommits](https://www.conventionalcommits.org/)) 规范的提交信息。在提交PR时请务必使用 `commit` 命令来创建提交信息,以确保信息的规范性。
## 浏览器支持
推荐使用最新版的 Chrome 浏览器进行开发,以获得更好的体验。
| [<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/) | [<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/) | [<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/) | [<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/) | [<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/) |
| --- | --- | --- | --- | --- |
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## 开源作者
[Soybean](https://github.com/honghuangdc)
## 贡献者
感谢以下贡献者的贡献。如果您想为本项目做出贡献,请参考 [如何贡献](#如何贡献)。
<a href="https://github.com/soybeanjs/soybean-admin/graphs/contributors">
<img src="https://contrib.rocks/image?repo=soybeanjs/soybean-admin" />
</a>
## 交流
`Soybean Admin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供微信和 QQ 交流群,使用问题欢迎在群内提问。
<div>
<p>QQ交流群</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/qq-soybean-admin-2.jpg" style="width:200px" />
</div>
<!-- <div>
<p>微信群</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-0402.jpg" style="width:200px" />
</div> -->
<div>
<p>添加下面微信邀请进微信群</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-soybeanjs.jpg" style="width:200px" />
</div>
<div>
<p>添加 Soybean 的微信,业务咨询、合作、项目架构、一对一指导等</p>
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-soybean.jpg" style="width:200px" />
</div>
## Star 趋势
[![Star History Chart](https://api.star-history.com/svg?repos=soybeanjs/soybean-admin&type=Date)](https://star-history.com/#soybeanjs/soybean-admin&Date)
## 开源协议
项目基于 [MIT © 2021 Soybean](./LICENSE) 协议,仅供学习参考,商业使用请保留作者版权信息,作者不保证也不承担任何软件的使用风险。

View File

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

View File

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

View File

@@ -1,19 +1,35 @@
import type { ProxyOptions } from 'vite';
import { createServiceConfig } from '../../src/utils/service';
/**
* 设置网络代理
* @param isOpenProxy - 是否开启代理
* @param envConfig - env环境配置
* Set http proxy
*
* @param env - The current env
* @param isDev - Is development environment
*/
export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfigWithProxyPattern) {
if (!isOpenProxy) return undefined;
export function createViteProxy(env: Env.ImportMeta, isDev: boolean) {
const isEnableHttpProxy = isDev && env.VITE_HTTP_PROXY === 'Y';
const proxy: Record<string, string | ProxyOptions> = {
[envConfig.proxyPattern]: {
target: envConfig.url,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${envConfig.proxyPattern}`), '')
}
if (!isEnableHttpProxy) return undefined;
const { baseURL, proxyPattern, other } = createServiceConfig(env);
const proxy: Record<string, ProxyOptions> = createProxyItem({ baseURL, proxyPattern });
other.forEach(item => {
Object.assign(proxy, createProxyItem(item));
});
return proxy;
}
function createProxyItem(item: App.Service.ServiceConfigItem) {
const proxy: Record<string, ProxyOptions> = {};
proxy[item.proxyPattern] = {
target: item.baseURL,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${item.proxyPattern}`), '')
};
return proxy;

View File

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

View File

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

View File

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

View File

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

View File

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

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

@@ -0,0 +1,44 @@
import type { RouteMeta } from 'vue-router';
import ElegantVueRouter from '@elegant-router/vue/vite';
import type { RouteKey } from '@elegant-router/types';
export function setupElegantRouter() {
return ElegantVueRouter({
layouts: {
base: 'src/layouts/base-layout/index.vue',
blank: 'src/layouts/blank-layout/index.vue'
},
customRoutes: {
names: ['exception_403', 'exception_404', 'exception_500']
},
routePathTransformer(routeName, routePath) {
const key = routeName as RouteKey;
if (key === 'login') {
const modules: UnionKey.LoginModule[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat'];
const moduleReg = modules.join('|');
return `/login/:module(${moduleReg})?`;
}
return routePath;
},
onRouteMetaGen(routeName) {
const key = routeName as RouteKey;
const constantRoutes: RouteKey[] = ['login', '403', '404', '500'];
const meta: Partial<RouteMeta> = {
title: key,
i18nKey: `route.${key}` as App.I18n.I18nKey
};
if (constantRoutes.includes(key)) {
meta.constant = true;
}
return meta;
}
});
}

32
build/plugins/unocss.ts Normal file
View File

@@ -0,0 +1,32 @@
import process from 'node:process';
import path from 'node:path';
import unocss from '@unocss/vite';
import presetIcons from '@unocss/preset-icons';
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders';
export function setupUnocss(viteEnv: Env.ImportMeta) {
const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv;
const localIconPath = path.join(process.cwd(), 'src/assets/svg-icon');
/** The name of the local icon collection */
const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, '');
return unocss({
presets: [
presetIcons({
prefix: `${VITE_ICON_PREFIX}-`,
scale: 1,
extraProperties: {
display: 'inline-block'
},
collections: {
[collectionName]: FileSystemIconLoader(localIconPath, svg =>
svg.replace(/^<svg\s/, '<svg width="1em" height="1em" ')
)
},
warn: true
})
]
});
}

View File

@@ -1,21 +1,22 @@
import process from 'node:process';
import path from 'node:path';
import type { PluginOption } from '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 { AntDesignVueResolver, 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;
export function setupUnplugin(viteEnv: Env.ImportMeta) {
const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv;
const srcPath = getSrcPath();
const localIconPath = `${srcPath}/assets/svg-icon`;
const localIconPath = path.join(process.cwd(), 'src/assets/svg-icon');
/** 本地svg图标集合名称 */
const collectionName = VITE_ICON_LOCAL_PREFFIX.replace(`${VITE_ICON_PREFFIX}-`, '');
/** The name of the local icon collection */
const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, '');
return [
const plugins: PluginOption[] = [
Icons({
compiler: 'vue3',
customCollections: {
@@ -30,15 +31,20 @@ export default function unplugin(viteEnv: ImportMetaEnv) {
dts: 'src/typings/components.d.ts',
types: [{ from: 'vue-router', names: ['RouterLink', 'RouterView'] }],
resolvers: [
AntDesignVueResolver({
importStyle: false
}),
NaiveUiResolver(),
IconsResolver({ customCollections: [collectionName], componentPrefix: VITE_ICON_PREFFIX })
IconsResolver({ customCollections: [collectionName], componentPrefix: VITE_ICON_PREFIX })
]
}),
createSvgIconsPlugin({
iconDirs: [localIconPath],
symbolId: `${VITE_ICON_LOCAL_PREFFIX}-[dir]-[name]`,
symbolId: `${VITE_ICON_LOCAL_PREFIX}-[dir]-[name]`,
inject: 'body-last',
customDomId: '__SVG_ICON_LOCAL__'
})
];
return plugins;
}

View File

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

View File

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

View File

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

View File

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

24
eslint.config.js Normal file
View File

@@ -0,0 +1,24 @@
import { defineConfig } from '@soybeanjs/eslint-config';
export default defineConfig(
{ vue: true, unocss: true },
{
rules: {
'vue/multi-word-component-names': [
'warn',
{
ignores: ['index', 'App', '[id]']
}
],
'vue/component-name-in-template-casing': [
'warn',
'PascalCase',
{
registeredComponentsOnly: false,
ignores: ['/^icon-/']
}
],
'unocss/order-attributify': 'off'
}
}
);

View File

@@ -1,15 +1,13 @@
<!DOCTYPE html>
<!doctype html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>%VITE_APP_NAME%</title>
</head>
<body>
<div id="app">
<div id="appLoading"></div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>%VITE_APP_TITLE%</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@@ -1,128 +0,0 @@
import type { MockMethod } from 'vite-plugin-mock';
import { userModel } from '../model';
/** 参数错误的状态码 */
const ERROR_PARAM_CODE = 10000;
const ERROR_PARAM_MSG = '参数校验失败!';
const apis: MockMethod[] = [
// 获取验证码
{
url: '/mock/getSmsCode',
method: 'post',
response: (): Service.MockServiceResult<boolean> => {
return {
code: 200,
message: 'ok',
data: true
};
}
},
// 用户+密码 登录
{
url: '/mock/login',
method: 'post',
response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
const { userName = undefined, password = undefined } = options.body;
if (!userName || !password) {
return {
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: 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: (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: 3000,
message: '用户已失效或不存在!',
data: null
};
}
}
];
export default apis;

View File

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

View File

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

View File

@@ -1,29 +0,0 @@
import type { MockMethod } from 'vite-plugin-mock';
import { routeModel, userModel } from '../model';
const apis: MockMethod[] = [
{
url: '/mock/getUserRoutes',
method: 'post',
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: {
routes: filterRoutes,
home: routeHomeName
}
};
}
}
];
export default apis;

View File

@@ -1,6 +0,0 @@
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
import api from './api';
export function setupMockServer() {
createProdMockServer(api);
}

View File

@@ -1,40 +0,0 @@
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'
}
];

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +1,110 @@
{
"name": "soybean-admin",
"version": "0.10.3",
"type": "module",
"version": "1.0.6",
"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"
"email": "soybeanjs@outlook.com",
"url": "https://github.com/soybeanjs"
},
"license": "MIT",
"homepage": "https://github.com/honghuangdc/soybean-admin",
"homepage": "https://github.com/soybeanjs/soybean-admin",
"repository": {
"url": "https://github.com/honghuangdc/soybean-admin.git"
"url": "https://github.com/soybeanjs/soybean-admin.git"
},
"bugs": {
"url": "https://github.com/honghuangdc/soybean-admin/issues"
"url": "https://github.com/soybeanjs/soybean-admin/issues"
},
"keywords": [
"Vue",
"Vue3",
"admin",
"admin-template",
"vue-admin",
"Vue3 admin ",
"vue-admin-template",
"Vite3",
"Vite",
"vite-admin",
"Vite5",
"TypeScript",
"TS",
"NaiveUI",
"naive-ui",
"naive-admin",
"NaiveUI-Admin",
"naive-ui-admin",
"ant-design-vue v4",
"UnoCSS"
],
"engines": {
"node": ">=18.12.0",
"pnpm": ">=8.7.0"
},
"scripts": {
"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",
"dev:tauri": "pnpm tauri dev",
"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",
"build:tauri": "pnpm tauri build",
"tauri-icon": "pnpm tauri icon ./public/logo.png",
"preview": "vite preview",
"typecheck": "vue-tsc --noEmit --skipLibCheck",
"build": "vite build --mode prod",
"build:test": "vite build --mode test",
"cleanup": "sa cleanup",
"commit": "sa git-commit",
"dev": "vite --mode test",
"dev:prod": "vite --mode prod",
"gen-route": "sa gen-route",
"lint": "eslint . --fix",
"format": "soy prettier-write",
"commit": "soy git-commit",
"cleanup": "soy cleanup",
"update-pkg": "soy ncu",
"release": "soy release",
"tsx": "tsx",
"logo": "tsx ./scripts/logo.ts",
"prepare": "soy init-simple-git-hooks"
"prepare": "simple-git-hooks",
"preview": "vite preview",
"release": "sa release",
"typecheck": "vue-tsc --noEmit --skipLibCheck",
"update-pkg": "sa update-pkg"
},
"dependencies": {
"@antv/data-set": "0.11.8",
"@antv/g2": "4.2.10",
"@better-scroll/core": "2.5.1",
"@soybeanjs/vue-materials": "0.2.0",
"@vueuse/core": "10.1.2",
"axios": "1.4.0",
"@iconify/vue": "4.1.2",
"@sa/axios": "workspace:*",
"@sa/color-palette": "workspace:*",
"@sa/hooks": "workspace:*",
"@sa/materials": "workspace:*",
"@sa/utils": "workspace:*",
"@vueuse/core": "10.9.0",
"clipboard": "2.0.11",
"colord": "2.9.3",
"crypto-js": "4.1.1",
"dayjs": "1.11.8",
"echarts": "5.4.2",
"form-data": "4.0.0",
"dayjs": "1.11.10",
"echarts": "5.5.0",
"lodash-es": "4.17.21",
"naive-ui": "2.34.4",
"pinia": "2.1.4",
"print-js": "1.6.0",
"qs": "6.11.2",
"swiper": "9.4.1",
"ua-parser-js": "1.0.35",
"vditor": "3.9.3",
"vue": "3.3.4",
"vue-i18n": "9.2.2",
"vue-router": "4.2.2",
"vuedraggable": "4.1.0",
"wangeditor": "4.7.15",
"xgplayer": "3.0.4"
"naive-ui": "2.38.1",
"nprogress": "0.2.0",
"pinia": "2.1.7",
"vue": "3.4.25",
"vue-draggable-plus": "0.4.0",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2"
},
"devDependencies": {
"@amap/amap-jsapi-types": "0.0.13",
"@iconify/json": "2.2.78",
"@iconify/vue": "4.1.1",
"@soybeanjs/cli": "0.6.2",
"@soybeanjs/vite-plugin-vue-page-route": "0.0.5",
"@tauri-apps/cli": "^1.3.1",
"@types/bmapgl": "0.0.7",
"@types/crypto-js": "4.1.1",
"@types/node": "20.3.1",
"@types/qs": "6.9.7",
"@types/ua-parser-js": "0.7.36",
"@unocss/preset-uno": "0.53.1",
"@unocss/transformer-directives": "0.53.1",
"@unocss/vite": "0.53.1",
"@vitejs/plugin-vue": "4.2.3",
"@vitejs/plugin-vue-jsx": "3.0.1",
"cross-env": "7.0.3",
"eslint": "8.42.0",
"eslint-config-soybeanjs": "0.4.9",
"mockjs": "1.1.0",
"rollup-plugin-visualizer": "5.9.2",
"sass": "1.63.4",
"simple-git-hooks": "2.8.1",
"tsx": "3.12.7",
"typescript": "5.1.3",
"unplugin-icons": "0.16.3",
"unplugin-vue-components": "0.25.1",
"vite": "4.3.9",
"vite-plugin-compression": "0.5.1",
"vite-plugin-mock": "2.9.8",
"@elegant-router/vue": "0.3.6",
"@iconify/json": "2.2.204",
"@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.2",
"@types/lodash-es": "4.17.12",
"@types/node": "20.12.7",
"@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.59.4",
"@unocss/preset-icons": "0.59.4",
"@unocss/preset-uno": "0.59.4",
"@unocss/transformer-directives": "0.59.4",
"@unocss/transformer-variant-group": "0.59.4",
"@unocss/vite": "0.59.4",
"@vitejs/plugin-vue": "5.0.4",
"@vitejs/plugin-vue-jsx": "3.1.0",
"eslint": "9.1.1",
"eslint-plugin-vue": "9.25.0",
"lint-staged": "15.2.2",
"sass": "1.75.0",
"simple-git-hooks": "2.11.1",
"tsx": "4.7.2",
"typescript": "5.4.5",
"unplugin-icons": "0.18.5",
"unplugin-vue-components": "0.26.0",
"vite": "5.2.10",
"vite-plugin-progress": "0.0.7",
"vite-plugin-pwa": "0.16.4",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "0.2.0",
"vue-tsc": "1.6.5"
},
"pnpm": {
"patchedDependencies": {
"mockjs@1.1.0": "patches/mockjs@1.1.0.patch"
}
"vite-plugin-vue-devtools": "7.1.2",
"vue-eslint-parser": "9.4.2",
"vue-tsc": "2.0.14"
},
"simple-git-hooks": {
"commit-msg": "pnpm soy git-commit-verify",
"pre-commit": "pnpm typecheck && pnpm lint"
"commit-msg": "pnpm sa git-commit-verify",
"pre-commit": "pnpm typecheck && pnpm lint-staged"
},
"soybean": {
"useSoybeanToken": true
}
"lint-staged": {
"*": "eslint --fix"
},
"website": "https://admin.soybeanjs.cn"
}

View File

@@ -0,0 +1,21 @@
{
"name": "@sa/axios",
"version": "1.0.6",
"exports": {
".": "./src/index.ts"
},
"typesVersions": {
"*": {
"*": ["./src/*"]
}
},
"dependencies": {
"@sa/utils": "workspace:*",
"axios": "1.6.8",
"axios-retry": "4.1.0",
"qs": "6.12.1"
},
"devDependencies": {
"@types/qs": "6.9.15"
}
}

View File

@@ -0,0 +1,5 @@
/** request id key */
export const REQUEST_ID_KEY = 'X-Request-Id';
/** the backend error code key */
export const BACKEND_ERROR_CODE = 'BACKEND_ERROR';

181
packages/axios/src/index.ts Normal file
View File

@@ -0,0 +1,181 @@
import axios, { AxiosError } from 'axios';
import type { AxiosResponse, CancelTokenSource, CreateAxiosDefaults, InternalAxiosRequestConfig } from 'axios';
import axiosRetry from 'axios-retry';
import { nanoid } from '@sa/utils';
import { createAxiosConfig, createDefaultOptions, createRetryOptions } from './options';
import { BACKEND_ERROR_CODE, REQUEST_ID_KEY } from './constant';
import type {
CustomAxiosRequestConfig,
FlatRequestInstance,
MappedType,
RequestInstance,
RequestOption,
ResponseType
} from './type';
function createCommonRequest<ResponseData = any>(
axiosConfig?: CreateAxiosDefaults,
options?: Partial<RequestOption<ResponseData>>
) {
const opts = createDefaultOptions<ResponseData>(options);
const axiosConf = createAxiosConfig(axiosConfig);
const instance = axios.create(axiosConf);
const cancelTokenSourceMap = new Map<string, CancelTokenSource>();
// config axios retry
const retryOptions = createRetryOptions(axiosConf);
axiosRetry(instance, retryOptions);
instance.interceptors.request.use(conf => {
const config: InternalAxiosRequestConfig = { ...conf };
// set request id
const requestId = nanoid();
config.headers.set(REQUEST_ID_KEY, requestId);
// config cancel token
const cancelTokenSource = axios.CancelToken.source();
config.cancelToken = cancelTokenSource.token;
cancelTokenSourceMap.set(requestId, cancelTokenSource);
// handle config by hook
const handledConfig = opts.onRequest?.(config) || config;
return handledConfig;
});
instance.interceptors.response.use(
async response => {
const responseType: ResponseType = (response.config?.responseType as ResponseType) || 'json';
if (responseType !== 'json' || opts.isBackendSuccess(response)) {
return Promise.resolve(response);
}
const fail = await opts.onBackendFail(response, instance);
if (fail) {
return fail;
}
const backendError = new AxiosError<ResponseData>(
'the backend request error',
BACKEND_ERROR_CODE,
response.config,
response.request,
response
);
await opts.onError(backendError);
return Promise.reject(backendError);
},
async (error: AxiosError<ResponseData>) => {
await opts.onError(error);
return Promise.reject(error);
}
);
function cancelRequest(requestId: string) {
const cancelTokenSource = cancelTokenSourceMap.get(requestId);
if (cancelTokenSource) {
cancelTokenSource.cancel();
cancelTokenSourceMap.delete(requestId);
}
}
function cancelAllRequest() {
cancelTokenSourceMap.forEach(cancelTokenSource => {
cancelTokenSource.cancel();
});
cancelTokenSourceMap.clear();
}
return {
instance,
opts,
cancelRequest,
cancelAllRequest
};
}
/**
* create a request instance
*
* @param axiosConfig axios config
* @param options request options
*/
export function createRequest<ResponseData = any, State = Record<string, unknown>>(
axiosConfig?: CreateAxiosDefaults,
options?: Partial<RequestOption<ResponseData>>
) {
const { instance, opts, cancelRequest, cancelAllRequest } = createCommonRequest<ResponseData>(axiosConfig, options);
const request: RequestInstance<State> = async function request<T = any, R extends ResponseType = 'json'>(
config: CustomAxiosRequestConfig
) {
const response: AxiosResponse<ResponseData> = await instance(config);
const responseType = response.config?.responseType || 'json';
if (responseType === 'json') {
return opts.transformBackendResponse(response);
}
return response.data as MappedType<R, T>;
} as RequestInstance<State>;
request.cancelRequest = cancelRequest;
request.cancelAllRequest = cancelAllRequest;
request.state = {} as State;
return request;
}
/**
* create a flat request instance
*
* The response data is a flat object: { data: any, error: AxiosError }
*
* @param axiosConfig axios config
* @param options request options
*/
export function createFlatRequest<ResponseData = any, State = Record<string, unknown>>(
axiosConfig?: CreateAxiosDefaults,
options?: Partial<RequestOption<ResponseData>>
) {
const { instance, opts, cancelRequest, cancelAllRequest } = createCommonRequest<ResponseData>(axiosConfig, options);
const flatRequest: FlatRequestInstance<State, ResponseData> = async function flatRequest<
T = any,
R extends ResponseType = 'json'
>(config: CustomAxiosRequestConfig) {
try {
const response: AxiosResponse<ResponseData> = await instance(config);
const responseType = response.config?.responseType || 'json';
if (responseType === 'json') {
const data = opts.transformBackendResponse(response);
return { data, error: null };
}
return { data: response.data as MappedType<R, T>, error: null };
} catch (error) {
return { data: null, error };
}
} as FlatRequestInstance<State, ResponseData>;
flatRequest.cancelRequest = cancelRequest;
flatRequest.cancelAllRequest = cancelAllRequest;
flatRequest.state = {} as State;
return flatRequest;
}
export { BACKEND_ERROR_CODE, REQUEST_ID_KEY };
export type * from './type';
export type { CreateAxiosDefaults, AxiosError };

View File

@@ -0,0 +1,48 @@
import type { CreateAxiosDefaults } from 'axios';
import type { IAxiosRetryConfig } from 'axios-retry';
import { stringify } from 'qs';
import { isHttpSuccess } from './shared';
import type { RequestOption } from './type';
export function createDefaultOptions<ResponseData = any>(options?: Partial<RequestOption<ResponseData>>) {
const opts: RequestOption<ResponseData> = {
onRequest: async config => config,
isBackendSuccess: _response => true,
onBackendFail: async () => {},
transformBackendResponse: async response => response.data,
onError: async () => {}
};
Object.assign(opts, options);
return opts;
}
export function createRetryOptions(config?: Partial<CreateAxiosDefaults>) {
const retryConfig: IAxiosRetryConfig = {
retries: 3
};
Object.assign(retryConfig, config);
return retryConfig;
}
export function createAxiosConfig(config?: Partial<CreateAxiosDefaults>) {
const TEN_SECONDS = 10 * 1000;
const axiosConfig: CreateAxiosDefaults = {
timeout: TEN_SECONDS,
headers: {
'Content-Type': 'application/json'
},
validateStatus: isHttpSuccess,
paramsSerializer: params => {
return stringify(params);
}
};
Object.assign(axiosConfig, config);
return axiosConfig;
}

View File

@@ -0,0 +1,28 @@
import type { AxiosHeaderValue, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
export function getContentType(config: InternalAxiosRequestConfig) {
const contentType: AxiosHeaderValue = config.headers?.['Content-Type'] || 'application/json';
return contentType;
}
/**
* check if http status is success
*
* @param status
*/
export function isHttpSuccess(status: number) {
const isSuccessCode = status >= 200 && status < 300;
return isSuccessCode || status === 304;
}
/**
* is response json
*
* @param response axios response
*/
export function isResponseJson(response: AxiosResponse) {
const { responseType } = response.config;
return responseType === 'json' || responseType === undefined;
}

101
packages/axios/src/type.ts Normal file
View File

@@ -0,0 +1,101 @@
import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
export type ContentType =
| 'text/html'
| 'text/plain'
| 'multipart/form-data'
| 'application/json'
| 'application/x-www-form-urlencoded'
| 'application/octet-stream';
export interface RequestOption<ResponseData = any> {
/**
* The hook before request
*
* For example: You can add header token in this hook
*
* @param config Axios config
*/
onRequest: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>;
/**
* The hook to check backend response is success or not
*
* @param response Axios response
*/
isBackendSuccess: (response: AxiosResponse<ResponseData>) => boolean;
/**
* The hook after backend request fail
*
* For example: You can handle the expired token in this hook
*
* @param response Axios response
* @param instance Axios instance
*/
onBackendFail: (
response: AxiosResponse<ResponseData>,
instance: AxiosInstance
) => Promise<AxiosResponse | null> | Promise<void>;
/**
* transform backend response when the responseType is json
*
* @param response Axios response
*/
transformBackendResponse(response: AxiosResponse<ResponseData>): any | Promise<any>;
/**
* The hook to handle error
*
* For example: You can show error message in this hook
*
* @param error
*/
onError: (error: AxiosError<ResponseData>) => void | Promise<void>;
}
interface ResponseMap {
blob: Blob;
text: string;
arrayBuffer: ArrayBuffer;
stream: ReadableStream<Uint8Array>;
document: Document;
}
export type ResponseType = keyof ResponseMap | 'json';
export type MappedType<R extends ResponseType, JsonType = any> = R extends keyof ResponseMap
? ResponseMap[R]
: JsonType;
export type CustomAxiosRequestConfig<R extends ResponseType = 'json'> = Omit<AxiosRequestConfig, 'responseType'> & {
responseType?: R;
};
export interface RequestInstanceCommon<T> {
cancelRequest: (requestId: string) => void;
cancelAllRequest: () => void;
/** you can set custom state in the request instance */
state: T;
}
/** The request instance */
export interface RequestInstance<S = Record<string, unknown>> extends RequestInstanceCommon<S> {
<T = any, R extends ResponseType = 'json'>(config: CustomAxiosRequestConfig<R>): Promise<MappedType<R, T>>;
}
export type FlatResponseSuccessData<T = any> = {
data: T;
error: null;
};
export type FlatResponseFailData<ResponseData = any> = {
data: null;
error: AxiosError<ResponseData>;
};
export type FlatResponseData<T = any, ResponseData = any> =
| FlatResponseSuccessData<T>
| FlatResponseFailData<ResponseData>;
export interface FlatRequestInstance<S = Record<string, unknown>, ResponseData = any> extends RequestInstanceCommon<S> {
<T = any, R extends ResponseType = 'json'>(
config: CustomAxiosRequestConfig<R>
): Promise<FlatResponseData<MappedType<R, T>, ResponseData>>;
}

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"lib": ["DOM", "ESNext"],
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"types": ["node"],
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,15 @@
{
"name": "@sa/color-palette",
"version": "1.0.6",
"exports": {
".": "./src/index.ts"
},
"typesVersions": {
"*": {
"*": ["./src/*"]
}
},
"dependencies": {
"colord": "2.9.3"
}
}

View File

@@ -0,0 +1,2 @@
export * from './name';
export * from './palette';

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,356 @@
import type { ColorPaletteFamily } from '../types';
export const colorPalettes: ColorPaletteFamily[] = [
{
name: 'Slate',
palettes: [
{ hex: '#f8fafc', number: 50 },
{ hex: '#f1f5f9', number: 100 },
{ hex: '#e2e8f0', number: 200 },
{ hex: '#cbd5e1', number: 300 },
{ hex: '#94a3b8', number: 400 },
{ hex: '#64748b', number: 500 },
{ hex: '#475569', number: 600 },
{ hex: '#334155', number: 700 },
{ hex: '#1e293b', number: 800 },
{ hex: '#0f172a', number: 900 },
{ hex: '#020617', number: 950 }
]
},
{
name: 'Gray',
palettes: [
{ hex: '#f9fafb', number: 50 },
{ hex: '#f3f4f6', number: 100 },
{ hex: '#e5e7eb', number: 200 },
{ hex: '#d1d5db', number: 300 },
{ hex: '#9ca3af', number: 400 },
{ hex: '#6b7280', number: 500 },
{ hex: '#4b5563', number: 600 },
{ hex: '#374151', number: 700 },
{ hex: '#1f2937', number: 800 },
{ hex: '#111827', number: 900 },
{ hex: '#030712', number: 950 }
]
},
{
name: 'Zinc',
palettes: [
{ hex: '#fafafa', number: 50 },
{ hex: '#f4f4f5', number: 100 },
{ hex: '#e4e4e7', number: 200 },
{ hex: '#d4d4d8', number: 300 },
{ hex: '#a1a1aa', number: 400 },
{ hex: '#71717a', number: 500 },
{ hex: '#52525b', number: 600 },
{ hex: '#3f3f46', number: 700 },
{ hex: '#27272a', number: 800 },
{ hex: '#18181b', number: 900 },
{ hex: '#09090b', number: 950 }
]
},
{
name: 'Neutral',
palettes: [
{ hex: '#fafafa', number: 50 },
{ hex: '#f5f5f5', number: 100 },
{ hex: '#e5e5e5', number: 200 },
{ hex: '#d4d4d4', number: 300 },
{ hex: '#a3a3a3', number: 400 },
{ hex: '#737373', number: 500 },
{ hex: '#525252', number: 600 },
{ hex: '#404040', number: 700 },
{ hex: '#262626', number: 800 },
{ hex: '#171717', number: 900 },
{ hex: '#0a0a0a', number: 950 }
]
},
{
name: 'Stone',
palettes: [
{ hex: '#fafaf9', number: 50 },
{ hex: '#f5f5f4', number: 100 },
{ hex: '#e7e5e4', number: 200 },
{ hex: '#d6d3d1', number: 300 },
{ hex: '#a8a29e', number: 400 },
{ hex: '#78716c', number: 500 },
{ hex: '#57534e', number: 600 },
{ hex: '#44403c', number: 700 },
{ hex: '#292524', number: 800 },
{ hex: '#1c1917', number: 900 },
{ hex: '#0c0a09', number: 950 }
]
},
{
name: 'Red',
palettes: [
{ hex: '#fef2f2', number: 50 },
{ hex: '#fee2e2', number: 100 },
{ hex: '#fecaca', number: 200 },
{ hex: '#fca5a5', number: 300 },
{ hex: '#f87171', number: 400 },
{ hex: '#ef4444', number: 500 },
{ hex: '#dc2626', number: 600 },
{ hex: '#b91c1c', number: 700 },
{ hex: '#991b1b', number: 800 },
{ hex: '#7f1d1d', number: 900 },
{ hex: '#450a0a', number: 950 }
]
},
{
name: 'Orange',
palettes: [
{ hex: '#fff7ed', number: 50 },
{ hex: '#ffedd5', number: 100 },
{ hex: '#fed7aa', number: 200 },
{ hex: '#fdba74', number: 300 },
{ hex: '#fb923c', number: 400 },
{ hex: '#f97316', number: 500 },
{ hex: '#ea580c', number: 600 },
{ hex: '#c2410c', number: 700 },
{ hex: '#9a3412', number: 800 },
{ hex: '#7c2d12', number: 900 },
{ hex: '#431407', number: 950 }
]
},
{
name: 'Amber',
palettes: [
{ hex: '#fffbeb', number: 50 },
{ hex: '#fef3c7', number: 100 },
{ hex: '#fde68a', number: 200 },
{ hex: '#fcd34d', number: 300 },
{ hex: '#fbbf24', number: 400 },
{ hex: '#f59e0b', number: 500 },
{ hex: '#d97706', number: 600 },
{ hex: '#b45309', number: 700 },
{ hex: '#92400e', number: 800 },
{ hex: '#78350f', number: 900 },
{ hex: '#451a03', number: 950 }
]
},
{
name: 'Yellow',
palettes: [
{ hex: '#fefce8', number: 50 },
{ hex: '#fef9c3', number: 100 },
{ hex: '#fef08a', number: 200 },
{ hex: '#fde047', number: 300 },
{ hex: '#facc15', number: 400 },
{ hex: '#eab308', number: 500 },
{ hex: '#ca8a04', number: 600 },
{ hex: '#a16207', number: 700 },
{ hex: '#854d0e', number: 800 },
{ hex: '#713f12', number: 900 },
{ hex: '#422006', number: 950 }
]
},
{
name: 'Lime',
palettes: [
{ hex: '#f7fee7', number: 50 },
{ hex: '#ecfccb', number: 100 },
{ hex: '#d9f99d', number: 200 },
{ hex: '#bef264', number: 300 },
{ hex: '#a3e635', number: 400 },
{ hex: '#84cc16', number: 500 },
{ hex: '#65a30d', number: 600 },
{ hex: '#4d7c0f', number: 700 },
{ hex: '#3f6212', number: 800 },
{ hex: '#365314', number: 900 },
{ hex: '#1a2e05', number: 950 }
]
},
{
name: 'Green',
palettes: [
{ hex: '#f0fdf4', number: 50 },
{ hex: '#dcfce7', number: 100 },
{ hex: '#bbf7d0', number: 200 },
{ hex: '#86efac', number: 300 },
{ hex: '#4ade80', number: 400 },
{ hex: '#22c55e', number: 500 },
{ hex: '#16a34a', number: 600 },
{ hex: '#15803d', number: 700 },
{ hex: '#166534', number: 800 },
{ hex: '#14532d', number: 900 },
{ hex: '#052e16', number: 950 }
]
},
{
name: 'Emerald',
palettes: [
{ hex: '#ecfdf5', number: 50 },
{ hex: '#d1fae5', number: 100 },
{ hex: '#a7f3d0', number: 200 },
{ hex: '#6ee7b7', number: 300 },
{ hex: '#34d399', number: 400 },
{ hex: '#10b981', number: 500 },
{ hex: '#059669', number: 600 },
{ hex: '#047857', number: 700 },
{ hex: '#065f46', number: 800 },
{ hex: '#064e3b', number: 900 },
{ hex: '#022c22', number: 950 }
]
},
{
name: 'Teal',
palettes: [
{ hex: '#f0fdfa', number: 50 },
{ hex: '#ccfbf1', number: 100 },
{ hex: '#99f6e4', number: 200 },
{ hex: '#5eead4', number: 300 },
{ hex: '#2dd4bf', number: 400 },
{ hex: '#14b8a6', number: 500 },
{ hex: '#0d9488', number: 600 },
{ hex: '#0f766e', number: 700 },
{ hex: '#115e59', number: 800 },
{ hex: '#134e4a', number: 900 },
{ hex: '#042f2e', number: 950 }
]
},
{
name: 'Cyan',
palettes: [
{ hex: '#ecfeff', number: 50 },
{ hex: '#cffafe', number: 100 },
{ hex: '#a5f3fc', number: 200 },
{ hex: '#67e8f9', number: 300 },
{ hex: '#22d3ee', number: 400 },
{ hex: '#06b6d4', number: 500 },
{ hex: '#0891b2', number: 600 },
{ hex: '#0e7490', number: 700 },
{ hex: '#155e75', number: 800 },
{ hex: '#164e63', number: 900 },
{ hex: '#083344', number: 950 }
]
},
{
name: 'Sky',
palettes: [
{ hex: '#f0f9ff', number: 50 },
{ hex: '#e0f2fe', number: 100 },
{ hex: '#bae6fd', number: 200 },
{ hex: '#7dd3fc', number: 300 },
{ hex: '#38bdf8', number: 400 },
{ hex: '#0ea5e9', number: 500 },
{ hex: '#0284c7', number: 600 },
{ hex: '#0369a1', number: 700 },
{ hex: '#075985', number: 800 },
{ hex: '#0c4a6e', number: 900 },
{ hex: '#082f49', number: 950 }
]
},
{
name: 'Blue',
palettes: [
{ hex: '#eff6ff', number: 50 },
{ hex: '#dbeafe', number: 100 },
{ hex: '#bfdbfe', number: 200 },
{ hex: '#93c5fd', number: 300 },
{ hex: '#60a5fa', number: 400 },
{ hex: '#3b82f6', number: 500 },
{ hex: '#2563eb', number: 600 },
{ hex: '#1d4ed8', number: 700 },
{ hex: '#1e40af', number: 800 },
{ hex: '#1e3a8a', number: 900 },
{ hex: '#172554', number: 950 }
]
},
{
name: 'Indigo',
palettes: [
{ hex: '#eef2ff', number: 50 },
{ hex: '#e0e7ff', number: 100 },
{ hex: '#c7d2fe', number: 200 },
{ hex: '#a5b4fc', number: 300 },
{ hex: '#818cf8', number: 400 },
{ hex: '#6366f1', number: 500 },
{ hex: '#4f46e5', number: 600 },
{ hex: '#4338ca', number: 700 },
{ hex: '#3730a3', number: 800 },
{ hex: '#312e81', number: 900 },
{ hex: '#1e1b4b', number: 950 }
]
},
{
name: 'Violet',
palettes: [
{ hex: '#f5f3ff', number: 50 },
{ hex: '#ede9fe', number: 100 },
{ hex: '#ddd6fe', number: 200 },
{ hex: '#c4b5fd', number: 300 },
{ hex: '#a78bfa', number: 400 },
{ hex: '#8b5cf6', number: 500 },
{ hex: '#7c3aed', number: 600 },
{ hex: '#6d28d9', number: 700 },
{ hex: '#5b21b6', number: 800 },
{ hex: '#4c1d95', number: 900 },
{ hex: '#2e1065', number: 950 }
]
},
{
name: 'Purple',
palettes: [
{ hex: '#faf5ff', number: 50 },
{ hex: '#f3e8ff', number: 100 },
{ hex: '#e9d5ff', number: 200 },
{ hex: '#d8b4fe', number: 300 },
{ hex: '#c084fc', number: 400 },
{ hex: '#a855f7', number: 500 },
{ hex: '#9333ea', number: 600 },
{ hex: '#7e22ce', number: 700 },
{ hex: '#6b21a8', number: 800 },
{ hex: '#581c87', number: 900 },
{ hex: '#3b0764', number: 950 }
]
},
{
name: 'Fuchsia',
palettes: [
{ hex: '#fdf4ff', number: 50 },
{ hex: '#fae8ff', number: 100 },
{ hex: '#f5d0fe', number: 200 },
{ hex: '#f0abfc', number: 300 },
{ hex: '#e879f9', number: 400 },
{ hex: '#d946ef', number: 500 },
{ hex: '#c026d3', number: 600 },
{ hex: '#a21caf', number: 700 },
{ hex: '#86198f', number: 800 },
{ hex: '#701a75', number: 900 },
{ hex: '#4a044e', number: 950 }
]
},
{
name: 'Pink',
palettes: [
{ hex: '#fdf2f8', number: 50 },
{ hex: '#fce7f3', number: 100 },
{ hex: '#fbcfe8', number: 200 },
{ hex: '#f9a8d4', number: 300 },
{ hex: '#f472b6', number: 400 },
{ hex: '#ec4899', number: 500 },
{ hex: '#db2777', number: 600 },
{ hex: '#be185d', number: 700 },
{ hex: '#9d174d', number: 800 },
{ hex: '#831843', number: 900 },
{ hex: '#500724', number: 950 }
]
},
{
name: 'Rose',
palettes: [
{ hex: '#fff1f2', number: 50 },
{ hex: '#ffe4e6', number: 100 },
{ hex: '#fecdd3', number: 200 },
{ hex: '#fda4af', number: 300 },
{ hex: '#fb7185', number: 400 },
{ hex: '#f43f5e', number: 500 },
{ hex: '#e11d48', number: 600 },
{ hex: '#be123c', number: 700 },
{ hex: '#9f1239', number: 800 },
{ hex: '#881337', number: 900 },
{ hex: '#4c0519', number: 950 }
]
}
];

View File

@@ -0,0 +1,6 @@
import { colorPalettes } from './constant';
import { getColorName, getHex, getHsl, getRgb } from './shared';
export * from './palette';
export { getColorName, getHex, getHsl, getRgb, colorPalettes };
export * from './types';

View File

@@ -0,0 +1,152 @@
import { getColorName, getDeltaE, getHsl, isValidColor, transformHslToHex } from '../shared';
import { colorPalettes } from '../constant';
import type {
ColorPalette,
ColorPaletteFamily,
ColorPaletteFamilyWithNearestPalette,
ColorPaletteMatch,
ColorPaletteNumber
} from '../types';
/**
* get color palette by provided color and color name
*
* @param color the provided color
*/
export function getColorPalette(color: string) {
const colorPaletteFamily = getColorPaletteFamily(color);
const colorMap = new Map<ColorPaletteNumber, ColorPalette>();
colorPaletteFamily.palettes.forEach(palette => {
colorMap.set(palette.number, palette);
});
const mainColor = colorMap.get(500)!;
const matchColor = colorPaletteFamily.palettes.find(palette => palette.hex === color)!;
const colorPalette: ColorPaletteMatch = {
...colorPaletteFamily,
colorMap,
main: mainColor,
match: matchColor
};
return colorPalette;
}
/**
* get color by number
*
* @param color the provided color
* @param number the color palette number
*/
export function getColorByPaletteNumber(color: string, number: ColorPaletteNumber) {
const colorPalette = getColorPalette(color);
const { hex } = colorPalette.colorMap.get(number)!;
return hex;
}
/**
* get color palette family by provided color and color name
*
* @param color the provided color
*/
export function getColorPaletteFamily(color: string) {
if (!isValidColor(color)) {
throw new Error('Invalid color, please check color value!');
}
let colorName = getColorName(color);
colorName = colorName.toLowerCase().replace(/\s/g, '-');
const { h: h1, s: s1 } = getHsl(color);
const { nearestLightnessPalette, palettes } = getNearestColorPaletteFamily(color, colorPalettes);
const { number, hex } = nearestLightnessPalette;
const { h: h2, s: s2 } = getHsl(hex);
const deltaH = h1 - h2;
const sRatio = s1 / s2;
const colorPaletteFamily: ColorPaletteFamily = {
name: colorName,
palettes: palettes.map(palette => {
let hexValue = color;
const isSame = number === palette.number;
if (!isSame) {
const { h: h3, s: s3, l } = getHsl(palette.hex);
const newH = deltaH < 0 ? h3 + deltaH : h3 - deltaH;
const newS = s3 * sRatio;
hexValue = transformHslToHex({
h: newH,
s: newS,
l
});
}
return {
hex: hexValue,
number: palette.number
};
})
};
return colorPaletteFamily;
}
/**
* get nearest color palette family
*
* @param color color
* @param families color palette families
*/
function getNearestColorPaletteFamily(color: string, families: ColorPaletteFamily[]) {
const familyWithConfig = families.map(family => {
const palettes = family.palettes.map(palette => {
return {
...palette,
delta: getDeltaE(color, palette.hex)
};
});
const nearestPalette = palettes.reduce((prev, curr) => (prev.delta < curr.delta ? prev : curr));
return {
...family,
palettes,
nearestPalette
};
});
const nearestPaletteFamily = familyWithConfig.reduce((prev, curr) =>
prev.nearestPalette.delta < curr.nearestPalette.delta ? prev : curr
);
const { l } = getHsl(color);
const paletteFamily: ColorPaletteFamilyWithNearestPalette = {
...nearestPaletteFamily,
nearestLightnessPalette: nearestPaletteFamily.palettes.reduce((prev, curr) => {
const { l: prevLightness } = getHsl(prev.hex);
const { l: currLightness } = getHsl(curr.hex);
const deltaPrev = Math.abs(prevLightness - l);
const deltaCurr = Math.abs(currLightness - l);
return deltaPrev < deltaCurr ? prev : curr;
})
};
return paletteFamily;
}

View File

@@ -0,0 +1,29 @@
import { colord, extend } from 'colord';
import type { HslColor } from 'colord';
import labPlugin from 'colord/plugins/lab';
extend([labPlugin]);
export function isValidColor(color: string) {
return colord(color).isValid();
}
export function getHex(color: string) {
return colord(color).toHex();
}
export function getRgb(color: string) {
return colord(color).toRgb();
}
export function getHsl(color: string) {
return colord(color).toHsl();
}
export function getDeltaE(color1: string, color2: string) {
return colord(color1).delta(color2);
}
export function transformHslToHex(color: HslColor) {
return colord(color).toHex();
}

View File

@@ -0,0 +1,2 @@
export * from './colord';
export * from './name';

View File

@@ -0,0 +1,49 @@
import { colorNames } from '../constant';
import { getHex, getHsl, getRgb } from './colord';
/**
* Get color name
*
* @param color
*/
export function getColorName(color: string) {
const hex = getHex(color);
const rgb = getRgb(color);
const hsl = getHsl(color);
let ndf = 0;
let ndf1 = 0;
let ndf2 = 0;
let cl = -1;
let df = -1;
let name = '';
colorNames.some((item, index) => {
const [hexValue, colorName] = item;
const match = hex === hexValue;
if (match) {
name = colorName;
} else {
const { r, g, b } = getRgb(hexValue);
const { h, s, l } = getHsl(hexValue);
ndf1 = (rgb.r - r) ** 2 + (rgb.g - g) ** 2 + (rgb.b - b) ** 2;
ndf2 = (hsl.h - h) ** 2 + (hsl.s - s) ** 2 + (hsl.l - l) ** 2;
ndf = ndf1 + ndf2 * 2;
if (df < 0 || df > ndf) {
df = ndf;
cl = index;
}
}
return match;
});
name = colorNames[cl][1];
return name;
}

View File

@@ -0,0 +1,47 @@
/** the color palette number */
export type ColorPaletteNumber = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950;
/** the color palette */
export type ColorPalette = {
/** the color hex value */
hex: string;
/**
* the color number
*
* - 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950
*/
number: ColorPaletteNumber;
};
/** the color palette family */
export type ColorPaletteFamily = {
/** the color palette family name */
name: string;
/** the color palettes */
palettes: ColorPalette[];
};
/** the color palette with delta */
export type ColorPaletteWithDelta = ColorPalette & {
delta: number;
};
/** the color palette family with nearest palette */
export type ColorPaletteFamilyWithNearestPalette = ColorPaletteFamily & {
nearestPalette: ColorPaletteWithDelta;
nearestLightnessPalette: ColorPaletteWithDelta;
};
/** the color palette match */
export type ColorPaletteMatch = ColorPaletteFamily & {
/** the color map of the palette */
colorMap: Map<ColorPaletteNumber, ColorPalette>;
/**
* the main color of the palette
*
* which number is 500
*/
main: ColorPalette;
/** the match color of the palette */
match: ColorPalette;
};

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"lib": ["DOM", "ESNext"],
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"types": ["node"],
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,15 @@
{
"name": "@sa/hooks",
"version": "1.0.6",
"exports": {
".": "./src/index.ts"
},
"typesVersions": {
"*": {
"*": ["./src/*"]
}
},
"dependencies": {
"@sa/axios": "workspace:*"
}
}

View File

@@ -0,0 +1,11 @@
import useBoolean from './use-boolean';
import useLoading from './use-loading';
import useCountDown from './use-count-down';
import useContext from './use-context';
import useSvgIconRender from './use-svg-icon-render';
import useHookTable from './use-table';
export { useBoolean, useLoading, useCountDown, useContext, useSvgIconRender, useHookTable };
export * from './use-signal';
export * from './use-table';

View File

@@ -1,8 +1,9 @@
import { ref } from 'vue';
/**
* boolean组合式函数
* @param initValue
* Boolean
*
* @param initValue Init value
*/
export default function useBoolean(initValue = false) {
const bool = ref(initValue);

View File

@@ -0,0 +1,96 @@
import { inject, provide } from 'vue';
import type { InjectionKey } from 'vue';
/**
* Use context
*
* @example
* ```ts
* // there are three vue files: A.vue, B.vue, C.vue, and A.vue is the parent component of B.vue and C.vue
*
* // context.ts
* import { ref } from 'vue';
* import { useContext } from '@sa/hooks';
*
* export const { setupStore, useStore } = useContext('demo', () => {
* const count = ref(0);
*
* function increment() {
* count.value++;
* }
*
* function decrement() {
* count.value--;
* }
*
* return {
* count,
* increment,
* decrement
* };
* })
* ``` // A.vue
* ```vue
* <template>
* <div>A</div>
* </template>
* <script setup lang="ts">
* import { setupStore } from './context';
*
* setupStore();
* // const { increment } = setupStore(); // also can control the store in the parent component
* </script>
* ``` // B.vue
* ```vue
* <template>
* <div>B</div>
* </template>
* <script setup lang="ts">
* import { useStore } from './context';
*
* const { count, increment } = useStore();
* </script>
* ```;
*
* // C.vue is same as B.vue
*
* @param contextName Context name
* @param fn Context function
*/
export default function useContext<T extends (...args: any[]) => any>(contextName: string, fn: T) {
type Context = ReturnType<T>;
const { useProvide, useInject: useStore } = createContext<Context>(contextName);
function setupStore(...args: Parameters<T>) {
const context: Context = fn(...args);
return useProvide(context);
}
return {
/** Setup store in the parent component */
setupStore,
/** Use store in the child component */
useStore
};
}
/** Create context */
function createContext<T>(contextName: string) {
const injectKey: InjectionKey<T> = Symbol(contextName);
function useProvide(context: T) {
provide(injectKey, context);
return context;
}
function useInject() {
return inject(injectKey) as T;
}
return {
useProvide,
useInject
};
}

View File

@@ -0,0 +1,49 @@
import { computed, onScopeDispose, ref } from 'vue';
import { useRafFn } from '@vueuse/core';
/**
* count down
*
* @param seconds - count down seconds
*/
export default function useCountDown(seconds: number) {
const FPS_PER_SECOND = 60;
const fps = ref(0);
const count = computed(() => Math.ceil(fps.value / FPS_PER_SECOND));
const isCounting = computed(() => fps.value > 0);
const { pause, resume } = useRafFn(
() => {
if (fps.value > 0) {
fps.value -= 1;
} else {
pause();
}
},
{ immediate: false }
);
function start(updateSeconds: number = seconds) {
fps.value = FPS_PER_SECOND * updateSeconds;
resume();
}
function stop() {
fps.value = 0;
pause();
}
onScopeDispose(() => {
pause();
});
return {
count,
isCounting,
start,
stop
};
}

View File

@@ -1,5 +1,10 @@
import useBoolean from './use-boolean';
/**
* Loading
*
* @param initValue Init value
*/
export default function useLoading(initValue = false) {
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(initValue);

View File

@@ -0,0 +1,79 @@
import { ref } from 'vue';
import type { Ref } from 'vue';
import { createFlatRequest } from '@sa/axios';
import type {
AxiosError,
CreateAxiosDefaults,
CustomAxiosRequestConfig,
MappedType,
RequestOption,
ResponseType
} from '@sa/axios';
import useLoading from './use-loading';
export type HookRequestInstanceResponseSuccessData<T = any> = {
data: Ref<T>;
error: Ref<null>;
};
export type HookRequestInstanceResponseFailData<ResponseData = any> = {
data: Ref<null>;
error: Ref<AxiosError<ResponseData>>;
};
export type HookRequestInstanceResponseData<T = any, ResponseData = any> = {
loading: Ref<boolean>;
} & (HookRequestInstanceResponseSuccessData<T> | HookRequestInstanceResponseFailData<ResponseData>);
export interface HookRequestInstance<ResponseData = any> {
<T = any, R extends ResponseType = 'json'>(
config: CustomAxiosRequestConfig
): HookRequestInstanceResponseData<MappedType<R, T>, ResponseData>;
cancelRequest: (requestId: string) => void;
cancelAllRequest: () => void;
}
/**
* create a hook request instance
*
* @param axiosConfig
* @param options
*/
export default function createHookRequest<ResponseData = any>(
axiosConfig?: CreateAxiosDefaults,
options?: Partial<RequestOption<ResponseData>>
) {
const request = createFlatRequest<ResponseData>(axiosConfig, options);
const hookRequest: HookRequestInstance<ResponseData> = function hookRequest<T = any, R extends ResponseType = 'json'>(
config: CustomAxiosRequestConfig
) {
const { loading, startLoading, endLoading } = useLoading();
const data = ref<MappedType<R, T> | null>(null) as Ref<MappedType<R, T>>;
const error = ref<AxiosError<ResponseData> | null>(null) as Ref<AxiosError<ResponseData> | null>;
startLoading();
request(config).then(res => {
if (res.data) {
data.value = res.data;
} else {
error.value = res.error;
}
endLoading();
});
return {
loading,
data,
error
};
} as HookRequestInstance<ResponseData>;
hookRequest.cancelRequest = request.cancelRequest;
hookRequest.cancelAllRequest = request.cancelAllRequest;
return hookRequest;
}

View File

@@ -0,0 +1,144 @@
import { computed, ref, shallowRef, triggerRef } from 'vue';
import type {
ComputedGetter,
DebuggerOptions,
Ref,
ShallowRef,
WritableComputedOptions,
WritableComputedRef
} from 'vue';
type Updater<T> = (value: T) => T;
type Mutator<T> = (value: T) => void;
/**
* Signal is a reactive value that can be set, updated or mutated
*
* @example
* ```ts
* const count = useSignal(0);
*
* // `watchEffect`
* watchEffect(() => {
* console.log(count());
* });
*
* // watch
* watch(count, value => {
* console.log(value);
* });
*
* // useComputed
* const double = useComputed(() => count() * 2);
* const writeableDouble = useComputed({
* get: () => count() * 2,
* set: value => count.set(value / 2)
* });
* ```
*/
export interface Signal<T> {
(): Readonly<T>;
/**
* Set the value of the signal
*
* It recommend use `set` for primitive values
*
* @param value
*/
set(value: T): void;
/**
* Update the value of the signal using an updater function
*
* It recommend use `update` for non-primitive values, only the first level of the object will be reactive.
*
* @param updater
*/
update(updater: Updater<T>): void;
/**
* Mutate the value of the signal using a mutator function
*
* this action will call `triggerRef`, so the value will be tracked on `watchEffect`.
*
* It recommend use `mutate` for non-primitive values, all levels of the object will be reactive.
*
* @param mutator
*/
mutate(mutator: Mutator<T>): void;
/**
* Get the reference of the signal
*
* Sometimes it can be useful to make `v-model` work with the signal
*
* ```vue
* <template>
* <input v-model="model.count" />
* </template>;
*
* <script setup lang="ts">
* const state = useSignal({ count: 0 }, { useRef: true });
*
* const model = state.getRef();
* </script>
* ```
*/
getRef(): Readonly<ShallowRef<Readonly<T>>>;
}
export interface ReadonlySignal<T> {
(): Readonly<T>;
}
export interface SignalOptions {
/**
* Whether to use `ref` to store the value
*
* @default false use `sharedRef` to store the value
*/
useRef?: boolean;
}
export function useSignal<T>(initialValue: T, options?: SignalOptions): Signal<T> {
const { useRef } = options || {};
const state = useRef ? (ref(initialValue) as Ref<T>) : shallowRef(initialValue);
return createSignal(state);
}
export function useComputed<T>(getter: ComputedGetter<T>, debugOptions?: DebuggerOptions): ReadonlySignal<T>;
export function useComputed<T>(options: WritableComputedOptions<T>, debugOptions?: DebuggerOptions): Signal<T>;
export function useComputed<T>(
getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>,
debugOptions?: DebuggerOptions
) {
const isGetter = typeof getterOrOptions === 'function';
const computedValue = computed(getterOrOptions as any, debugOptions);
if (isGetter) {
return () => computedValue.value as ReadonlySignal<T>;
}
return createSignal(computedValue);
}
function createSignal<T>(state: ShallowRef<T> | WritableComputedRef<T>): Signal<T> {
const signal = () => state.value;
signal.set = (value: T) => {
state.value = value;
};
signal.update = (updater: Updater<T>) => {
state.value = updater(state.value);
};
signal.mutate = (mutator: Mutator<T>) => {
mutator(state.value);
triggerRef(state);
};
signal.getRef = () => state as Readonly<ShallowRef<Readonly<T>>>;
return signal;
}

View File

@@ -0,0 +1,50 @@
import { h } from 'vue';
import type { Component } from 'vue';
/**
* Svg icon render hook
*
* @param SvgIcon Svg icon component
*/
export default function useSvgIconRender(SvgIcon: Component) {
interface IconConfig {
/** Iconify icon name */
icon?: string;
/** Local icon name */
localIcon?: string;
/** Icon color */
color?: string;
/** Icon size */
fontSize?: number;
}
type IconStyle = Partial<Pick<CSSStyleDeclaration, 'color' | 'fontSize'>>;
/**
* Svg icon VNode
*
* @param config
*/
const SvgIconVNode = (config: IconConfig) => {
const { color, fontSize, icon, localIcon } = config;
const style: IconStyle = {};
if (color) {
style.color = color;
}
if (fontSize) {
style.fontSize = `${fontSize}px`;
}
if (!icon && !localIcon) {
return undefined;
}
return () => h(SvgIcon, { icon, localIcon, style });
};
return {
SvgIconVNode
};
}

View File

@@ -0,0 +1,151 @@
import { computed, reactive, ref } from 'vue';
import type { Ref } from 'vue';
import useBoolean from './use-boolean';
import useLoading from './use-loading';
export type MaybePromise<T> = T | Promise<T>;
export type ApiFn = (args: any) => Promise<unknown>;
export type TableColumnCheck = {
key: string;
title: string;
checked: boolean;
};
export type TableDataWithIndex<T> = T & { index: number };
export type TransformedData<T> = {
data: TableDataWithIndex<T>[];
pageNum: number;
pageSize: number;
total: number;
};
export type Transformer<T, Response> = (response: Response) => TransformedData<T>;
export type TableConfig<A extends ApiFn, T, C> = {
/** api function to get table data */
apiFn: A;
/** api params */
apiParams?: Parameters<A>[0];
/** transform api response to table data */
transformer: Transformer<T, Awaited<ReturnType<A>>>;
/** columns factory */
columns: () => C[];
/**
* get column checks
*
* @param columns
*/
getColumnChecks: (columns: C[]) => TableColumnCheck[];
/**
* get columns
*
* @param columns
*/
getColumns: (columns: C[], checks: TableColumnCheck[]) => C[];
/**
* callback when response fetched
*
* @param transformed transformed data
*/
onFetched?: (transformed: TransformedData<T>) => MaybePromise<void>;
/**
* whether to get data immediately
*
* @default true
*/
immediate?: boolean;
};
export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<A, T, C>) {
const { loading, startLoading, endLoading } = useLoading();
const { bool: empty, setBool: setEmpty } = useBoolean();
const { apiFn, apiParams, transformer, immediate = true, getColumnChecks, getColumns } = config;
const searchParams: NonNullable<Parameters<A>[0]> = reactive({ ...apiParams });
const allColumns = ref(config.columns()) as Ref<C[]>;
const data: Ref<T[]> = ref([]);
const columnChecks: Ref<TableColumnCheck[]> = ref(getColumnChecks(config.columns()));
const columns = computed(() => getColumns(allColumns.value, columnChecks.value));
function reloadColumns() {
allColumns.value = config.columns();
const checkMap = new Map(columnChecks.value.map(col => [col.key, col.checked]));
const defaultChecks = getColumnChecks(allColumns.value);
columnChecks.value = defaultChecks.map(col => ({
...col,
checked: checkMap.get(col.key) ?? col.checked
}));
}
async function getData() {
startLoading();
const formattedParams = formatSearchParams(searchParams);
const response = await apiFn(formattedParams);
const transformed = transformer(response as Awaited<ReturnType<A>>);
data.value = transformed.data;
setEmpty(transformed.data.length === 0);
await config.onFetched?.(transformed);
endLoading();
}
function formatSearchParams(params: Record<string, unknown>) {
const formattedParams: Record<string, unknown> = {};
Object.entries(params).forEach(([key, value]) => {
if (value !== null && value !== undefined) {
formattedParams[key] = value;
}
});
return formattedParams;
}
/**
* update search params
*
* @param params
*/
function updateSearchParams(params: Partial<Parameters<A>[0]>) {
Object.assign(searchParams, params);
}
/** reset search params */
function resetSearchParams() {
Object.assign(searchParams, apiParams);
}
if (immediate) {
getData();
}
return {
loading,
empty,
data,
columns,
columnChecks,
reloadColumns,
getData,
searchParams,
updateSearchParams,
resetSearchParams
};
}

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"lib": ["DOM", "ESNext"],
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"types": ["node"],
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,19 @@
{
"name": "@sa/materials",
"version": "1.0.6",
"exports": {
".": "./src/index.ts"
},
"typesVersions": {
"*": {
"*": ["./src/*"]
}
},
"dependencies": {
"@sa/utils": "workspace:*",
"simplebar-vue": "2.3.3"
},
"devDependencies": {
"typed-css-modules": "0.9.1"
}
}

View File

@@ -0,0 +1,6 @@
import AdminLayout, { LAYOUT_MAX_Z_INDEX, LAYOUT_SCROLL_EL_ID } from './libs/admin-layout';
import PageTab from './libs/page-tab';
import SimpleScrollbar from './libs/simple-scrollbar';
export { AdminLayout, LAYOUT_SCROLL_EL_ID, LAYOUT_MAX_Z_INDEX, PageTab, SimpleScrollbar };
export * from './types';

View File

@@ -0,0 +1,63 @@
/* @type */
.layout-header,
.layout-header-placement {
height: var(--soy-header-height);
}
.layout-header {
z-index: var(--soy-header-z-index);
}
.layout-tab {
top: var(--soy-header-height);
height: var(--soy-tab-height);
z-index: var(--soy-tab-z-index);
}
.layout-tab-placement {
height: var(--soy-tab-height);
}
.layout-sider {
width: var(--soy-sider-width);
z-index: var(--soy-sider-z-index);
}
.layout-mobile-sider {
z-index: var(--soy-sider-z-index);
}
.layout-mobile-sider-mask {
z-index: var(--soy-mobile-sider-z-index);
}
.layout-sider_collapsed {
width: var(--soy-sider-collapsed-width);
z-index: var(--soy-sider-z-index);
}
.layout-footer,
.layout-footer-placement {
height: var(--soy-footer-height);
}
.layout-footer {
z-index: var(--soy-footer-z-index);
}
.left-gap {
padding-left: var(--soy-sider-width);
}
.left-gap_collapsed {
padding-left: var(--soy-sider-collapsed-width);
}
.sider-padding-top {
padding-top: var(--soy-header-height);
}
.sider-padding-bottom {
padding-bottom: var(--soy-footer-height);
}

View File

@@ -0,0 +1,18 @@
declare const styles: {
readonly 'layout-header': string;
readonly 'layout-header-placement': string;
readonly 'layout-tab': string;
readonly 'layout-tab-placement': string;
readonly 'layout-sider': string;
readonly 'layout-mobile-sider': string;
readonly 'layout-mobile-sider-mask': string;
readonly 'layout-sider_collapsed': string;
readonly 'layout-footer': string;
readonly 'layout-footer-placement': string;
readonly 'left-gap': string;
readonly 'left-gap_collapsed': string;
readonly 'sider-padding-top': string;
readonly 'sider-padding-bottom': string;
};
export default styles;

View File

@@ -0,0 +1,5 @@
import AdminLayout from './index.vue';
import { LAYOUT_MAX_Z_INDEX, LAYOUT_SCROLL_EL_ID } from './shared';
export default AdminLayout;
export { LAYOUT_SCROLL_EL_ID, LAYOUT_MAX_Z_INDEX };

View File

@@ -0,0 +1,237 @@
<script setup lang="ts">
import { computed } from 'vue';
import type { AdminLayoutProps } from '../../types';
import { LAYOUT_MAX_Z_INDEX, LAYOUT_SCROLL_EL_ID, createLayoutCssVars } from './shared';
import style from './index.module.css';
defineOptions({
name: 'AdminLayout'
});
const props = withDefaults(defineProps<AdminLayoutProps>(), {
mode: 'vertical',
scrollMode: 'content',
scrollElId: LAYOUT_SCROLL_EL_ID,
commonClass: 'transition-all-300',
fixedTop: true,
maxZIndex: LAYOUT_MAX_Z_INDEX,
headerVisible: true,
headerHeight: 56,
tabVisible: true,
tabHeight: 48,
siderVisible: true,
siderCollapse: false,
siderWidth: 220,
siderCollapsedWidth: 64,
footerVisible: true,
footerHeight: 48,
rightFooter: false
});
interface Emits {
/** Update siderCollapse */
(e: 'update:siderCollapse', collapse: boolean): void;
}
const emit = defineEmits<Emits>();
type SlotFn = (props?: Record<string, unknown>) => any;
type Slots = {
/** Main */
default?: SlotFn;
/** Header */
header?: SlotFn;
/** Tab */
tab?: SlotFn;
/** Sider */
sider?: SlotFn;
/** Footer */
footer?: SlotFn;
};
const slots = defineSlots<Slots>();
const cssVars = computed(() => createLayoutCssVars(props));
// config visible
const showHeader = computed(() => Boolean(slots.header) && props.headerVisible);
const showTab = computed(() => Boolean(slots.tab) && props.tabVisible);
const showSider = computed(() => !props.isMobile && Boolean(slots.sider) && props.siderVisible);
const showMobileSider = computed(() => props.isMobile && Boolean(slots.sider) && props.siderVisible);
const showFooter = computed(() => Boolean(slots.footer) && props.footerVisible);
// scroll mode
const isWrapperScroll = computed(() => props.scrollMode === 'wrapper');
const isContentScroll = computed(() => props.scrollMode === 'content');
// layout direction
const isVertical = computed(() => props.mode === 'vertical');
const isHorizontal = computed(() => props.mode === 'horizontal');
const fixedHeaderAndTab = computed(() => props.fixedTop || (isHorizontal.value && isWrapperScroll.value));
// css
const leftGapClass = computed(() => {
if (!props.fullContent && showSider.value) {
return props.siderCollapse ? style['left-gap_collapsed'] : style['left-gap'];
}
return '';
});
const headerLeftGapClass = computed(() => (isVertical.value ? leftGapClass.value : ''));
const footerLeftGapClass = computed(() => {
const condition1 = isVertical.value;
const condition2 = isHorizontal.value && isWrapperScroll.value && !props.fixedFooter;
const condition3 = Boolean(isHorizontal.value && props.rightFooter);
if (condition1 || condition2 || condition3) {
return leftGapClass.value;
}
return '';
});
const siderPaddingClass = computed(() => {
let cls = '';
if (showHeader.value && !headerLeftGapClass.value) {
cls += style['sider-padding-top'];
}
if (showFooter.value && !footerLeftGapClass.value) {
cls += ` ${style['sider-padding-bottom']}`;
}
return cls;
});
function handleClickMask() {
emit('update:siderCollapse', true);
}
</script>
<template>
<div class="relative h-full" :class="[commonClass]" :style="cssVars">
<div
:id="isWrapperScroll ? scrollElId : undefined"
class="h-full flex flex-col"
:class="[commonClass, scrollWrapperClass, { 'overflow-y-auto': isWrapperScroll }]"
>
<!-- Header -->
<template v-if="showHeader">
<header
v-show="!fullContent"
class="flex-shrink-0"
:class="[
style['layout-header'],
commonClass,
headerClass,
headerLeftGapClass,
{ 'absolute top-0 left-0 w-full': fixedHeaderAndTab }
]"
>
<slot name="header"></slot>
</header>
<div
v-show="!fullContent && fixedHeaderAndTab"
class="flex-shrink-0 overflow-hidden"
:class="[style['layout-header-placement']]"
></div>
</template>
<!-- Tab -->
<template v-if="showTab">
<div
class="flex-shrink-0"
:class="[
style['layout-tab'],
commonClass,
tabClass,
{ 'top-0!': fullContent || !showHeader },
leftGapClass,
{ 'absolute left-0 w-full': fixedHeaderAndTab }
]"
>
<slot name="tab"></slot>
</div>
<div
v-show="fullContent || fixedHeaderAndTab"
class="flex-shrink-0 overflow-hidden"
:class="[style['layout-tab-placement']]"
></div>
</template>
<!-- Sider -->
<template v-if="showSider">
<aside
v-show="!fullContent"
class="absolute left-0 top-0 h-full"
:class="[
commonClass,
siderClass,
siderPaddingClass,
siderCollapse ? style['layout-sider_collapsed'] : style['layout-sider']
]"
>
<slot name="sider"></slot>
</aside>
</template>
<!-- Mobile Sider -->
<template v-if="showMobileSider">
<aside
class="absolute left-0 top-0 h-full w-0 bg-white"
:class="[
commonClass,
mobileSiderClass,
style['layout-mobile-sider'],
siderCollapse ? 'overflow-hidden' : style['layout-sider']
]"
>
<slot name="sider"></slot>
</aside>
<div
v-show="!siderCollapse"
class="absolute left-0 top-0 h-full w-full bg-[rgba(0,0,0,0.2)]"
:class="[style['layout-mobile-sider-mask']]"
@click="handleClickMask"
></div>
</template>
<!-- Main Content -->
<main
:id="isContentScroll ? scrollElId : undefined"
class="flex flex-col flex-grow"
:class="[commonClass, contentClass, leftGapClass, { 'overflow-y-auto': isContentScroll }]"
>
<slot></slot>
</main>
<!-- Footer -->
<template v-if="showFooter">
<footer
v-show="!fullContent"
class="flex-shrink-0"
:class="[
style['layout-footer'],
commonClass,
footerClass,
footerLeftGapClass,
{ 'absolute left-0 bottom-0 w-full': fixedFooter }
]"
>
<slot name="footer"></slot>
</footer>
<div
v-show="!fullContent && fixedFooter"
class="flex-shrink-0 overflow-hidden"
:class="[style['layout-footer-placement']]"
></div>
</template>
</div>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,68 @@
import type { AdminLayoutProps, LayoutCssVars, LayoutCssVarsProps } from '../../types';
/** The id of the scroll element of the layout */
export const LAYOUT_SCROLL_EL_ID = '__SCROLL_EL_ID__';
/** The max z-index of the layout */
export const LAYOUT_MAX_Z_INDEX = 100;
/**
* Create layout css vars by css vars props
*
* @param props Css vars props
*/
function createLayoutCssVarsByCssVarsProps(props: LayoutCssVarsProps) {
const cssVars: LayoutCssVars = {
'--soy-header-height': `${props.headerHeight}px`,
'--soy-header-z-index': props.headerZIndex,
'--soy-tab-height': `${props.tabHeight}px`,
'--soy-tab-z-index': props.tabZIndex,
'--soy-sider-width': `${props.siderWidth}px`,
'--soy-sider-collapsed-width': `${props.siderCollapsedWidth}px`,
'--soy-sider-z-index': props.siderZIndex,
'--soy-mobile-sider-z-index': props.mobileSiderZIndex,
'--soy-footer-height': `${props.footerHeight}px`,
'--soy-footer-z-index': props.footerZIndex
};
return cssVars;
}
/**
* Create layout css vars
*
* @param props
*/
export function createLayoutCssVars(props: AdminLayoutProps) {
const {
mode,
isMobile,
maxZIndex = LAYOUT_MAX_Z_INDEX,
headerHeight,
tabHeight,
siderWidth,
siderCollapsedWidth,
footerHeight
} = props;
const headerZIndex = maxZIndex - 3;
const tabZIndex = maxZIndex - 5;
const siderZIndex = mode === 'vertical' || isMobile ? maxZIndex - 1 : maxZIndex - 4;
const mobileSiderZIndex = isMobile ? maxZIndex - 2 : 0;
const footerZIndex = maxZIndex - 5;
const cssProps: LayoutCssVarsProps = {
headerHeight,
headerZIndex,
tabHeight,
tabZIndex,
siderWidth,
siderZIndex,
mobileSiderZIndex,
siderCollapsedWidth,
footerHeight,
footerZIndex
};
return createLayoutCssVarsByCssVarsProps(cssProps);
}

View File

@@ -0,0 +1,53 @@
<script setup lang="ts">
import type { PageTabProps } from '../../types';
import style from './index.module.css';
defineOptions({
name: 'ButtonTab'
});
defineProps<PageTabProps>();
type SlotFn = (props?: Record<string, unknown>) => any;
type Slots = {
/**
* Slot
*
* The center content of the tab
*/
default?: SlotFn;
/**
* Slot
*
* The left content of the tab
*/
prefix?: SlotFn;
/**
* Slot
*
* The right content of the tab
*/
suffix?: SlotFn;
};
defineSlots<Slots>();
</script>
<template>
<div
class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-12px whitespace-nowrap border-1px rounded-4px border-solid px-12px py-4px"
:class="[
style['button-tab'],
{ [style['button-tab_dark']]: darkMode },
{ [style['button-tab_active']]: active },
{ [style['button-tab_active_dark']]: active && darkMode }
]"
>
<slot name="prefix"></slot>
<slot></slot>
<slot name="suffix"></slot>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
defineOptions({
name: 'ChromeTabBg'
});
</script>
<template>
<svg class="size-full">
<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" />
</symbol>
<symbol id="geometry-right" viewBox="0 0 214 36">
<use xlink:href="#geometry-left" />
</symbol>
<clipPath>
<rect width="100%" height="100%" x="0" />
</clipPath>
</defs>
<svg width="51%" height="100%">
<use xlink:href="#geometry-left" width="214" height="36" fill="currentColor" />
</svg>
<g transform="scale(-1, 1)">
<svg width="51%" height="100%" x="-100%" y="0">
<use xlink:href="#geometry-right" width="214" height="36" fill="currentColor" />
</svg>
</g>
</svg>
</template>
<style scoped></style>

View File

@@ -0,0 +1,58 @@
<script setup lang="ts">
import type { PageTabProps } from '../../types';
import ChromeTabBg from './chrome-tab-bg.vue';
import style from './index.module.css';
defineOptions({
name: 'ChromeTab'
});
defineProps<PageTabProps>();
type SlotFn = (props?: Record<string, unknown>) => any;
type Slots = {
/**
* Slot
*
* The center content of the tab
*/
default?: SlotFn;
/**
* Slot
*
* The left content of the tab
*/
prefix?: SlotFn;
/**
* Slot
*
* The right content of the tab
*/
suffix?: SlotFn;
};
defineSlots<Slots>();
</script>
<template>
<div
class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-16px whitespace-nowrap px-24px py-6px -mr-18px"
:class="[
style['chrome-tab'],
{ [style['chrome-tab_dark']]: darkMode },
{ [style['chrome-tab_active']]: active },
{ [style['chrome-tab_active_dark']]: active && darkMode }
]"
>
<div class=":soy: pointer-events-none absolute left-0 top-0 h-full w-full -z-1" :class="[style['chrome-tab__bg']]">
<ChromeTabBg />
</div>
<slot name="prefix"></slot>
<slot></slot>
<slot name="suffix"></slot>
<div class=":soy: absolute right-7px h-16px w-1px bg-#1f2225" :class="[style['chrome-tab-divider']]"></div>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,97 @@
/* @type */
.button-tab {
border-color: #e5e7eb;
}
.button-tab_dark {
border-color: #ffffff3d;
}
.button-tab:hover {
color: var(--soy-primary-color);
border-color: var(--soy-primary-color-opacity3);
}
.button-tab_active {
color: var(--soy-primary-color);
border-color: var(--soy-primary-color-opacity3);
background-color: var(--soy-primary-color-opacity1);
}
.button-tab_active_dark {
background-color: var(--soy-primary-color-opacity2);
}
.button-tab .svg-close:hover {
font-size: 12px;
color: #ffffff;
background-color: var(--soy-primary-color);
}
.button-tab_dark .svg-close:hover {
color: #000000;
}
.chrome-tab:hover {
z-index: 9;
}
.chrome-tab_active {
z-index: 10;
color: var(--soy-primary-color);
}
.chrome-tab__bg {
color: transparent;
}
.chrome-tab_active .chrome-tab__bg {
color: var(--soy-primary-color1);
}
.chrome-tab_active_dark .chrome-tab__bg {
color: var(--soy-primary-color2);
}
.chrome-tab:hover .chrome-tab__bg {
color: #dee1e6;
}
.chrome-tab_active:hover .chrome-tab__bg {
color: var(--soy-primary-color1);
}
.chrome-tab_dark:hover .chrome-tab__bg {
color: #333333;
}
.chrome-tab_active_dark:hover .chrome-tab__bg {
color: var(--soy-primary-color2);
}
.chrome-tab .svg-close:hover {
font-size: 12px;
color: #ffffff;
background-color: #9ca3af;
}
.chrome-tab_active .svg-close:hover {
background-color: var(--soy-primary-color);
}
.chrome-tab_dark .svg-close:hover {
color: #000000;
}
.chrome-tab_active .chrome-tab-divider {
opacity: 0;
}
.chrome-tab:hover .chrome-tab-divider {
opacity: 0;
}
.chrome-tab_dark .chrome-tab-divider {
background-color: rgba(255, 255, 255, 0.9);
}

View File

@@ -0,0 +1,15 @@
declare const styles: {
readonly 'button-tab': string;
readonly 'button-tab_dark': string;
readonly 'button-tab_active': string;
readonly 'button-tab_active_dark': string;
readonly 'chrome-tab': string;
readonly 'chrome-tab_active': string;
readonly 'chrome-tab__bg': string;
readonly 'chrome-tab_active_dark': string;
readonly 'chrome-tab_dark': string;
readonly 'chrome-tab-divider': string;
readonly 'svg-close': string;
};
export default styles;

View File

@@ -0,0 +1,3 @@
import PageTab from './index.vue';
export default PageTab;

View File

@@ -0,0 +1,72 @@
<script setup lang="ts">
import { computed } from 'vue';
import type { Component } from 'vue';
import type { PageTabMode, PageTabProps } from '../../types';
import { ACTIVE_COLOR, createTabCssVars } from './shared';
import ChromeTab from './chrome-tab.vue';
import ButtonTab from './button-tab.vue';
import SvgClose from './svg-close.vue';
import style from './index.module.css';
defineOptions({
name: 'PageTab'
});
const props = withDefaults(defineProps<PageTabProps>(), {
mode: 'chrome',
commonClass: 'transition-all-300',
activeColor: ACTIVE_COLOR,
closable: true
});
interface Emits {
(e: 'close'): void;
}
const emit = defineEmits<Emits>();
const activeTabComponent = computed(() => {
const { mode, chromeClass, buttonClass } = props;
const tabComponentMap = {
chrome: {
component: ChromeTab,
class: chromeClass
},
button: {
component: ButtonTab,
class: buttonClass
}
} satisfies Record<PageTabMode, { component: Component; class?: string }>;
return tabComponentMap[mode];
});
const cssVars = computed(() => createTabCssVars(props.activeColor));
const bindProps = computed(() => {
const { chromeClass: _chromeCls, buttonClass: _btnCls, ...rest } = props;
return rest;
});
function handleClose() {
emit('close');
}
</script>
<template>
<component :is="activeTabComponent.component" :class="activeTabComponent.class" :style="cssVars" v-bind="bindProps">
<template #prefix>
<slot name="prefix"></slot>
</template>
<slot></slot>
<template #suffix>
<slot name="suffix">
<SvgClose v-if="closable" :class="[style['svg-close']]" @click.stop="handleClose" />
</slot>
</template>
</component>
</template>
<style scoped></style>

View File

@@ -0,0 +1,31 @@
import { addColorAlpha, transformColorWithOpacity } from '@sa/utils';
import type { PageTabCssVars, PageTabCssVarsProps } from '../../types';
/** The active color of the tab */
export const ACTIVE_COLOR = '#1890ff';
function createCssVars(props: PageTabCssVarsProps) {
const cssVars: PageTabCssVars = {
'--soy-primary-color': props.primaryColor,
'--soy-primary-color1': props.primaryColor1,
'--soy-primary-color2': props.primaryColor2,
'--soy-primary-color-opacity1': props.primaryColorOpacity1,
'--soy-primary-color-opacity2': props.primaryColorOpacity2,
'--soy-primary-color-opacity3': props.primaryColorOpacity3
};
return cssVars;
}
export function createTabCssVars(primaryColor: string) {
const cssProps: PageTabCssVarsProps = {
primaryColor,
primaryColor1: transformColorWithOpacity(primaryColor, 0.1, '#ffffff'),
primaryColor2: transformColorWithOpacity(primaryColor, 0.3, '#000000'),
primaryColorOpacity1: addColorAlpha(primaryColor, 0.1),
primaryColorOpacity2: addColorAlpha(primaryColor, 0.15),
primaryColorOpacity3: addColorAlpha(primaryColor, 0.3)
};
return createCssVars(cssProps);
}

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
defineOptions({
name: 'SvgClose'
});
</script>
<template>
<div class=":soy: relative h-16px w-16px inline-flex items-center justify-center rd-50% text-14px">
<svg width="1em" height="1em" viewBox="0 0 1024 1024">
<path
fill="currentColor"
d="m563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8L295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512L196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1l216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,3 @@
import SimpleScrollbar from './index.vue';
export default SimpleScrollbar;

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
import Simplebar from 'simplebar-vue';
import 'simplebar-vue/dist/simplebar.min.css';
defineOptions({
name: 'SimpleScrollbar'
});
</script>
<template>
<div class="h-full flex-1-hidden">
<Simplebar class="h-full">
<slot />
</Simplebar>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,294 @@
/** Header config */
interface AdminLayoutHeaderConfig {
/**
* Whether header is visible
*
* @default true
*/
headerVisible?: boolean;
/**
* Header class
*
* @default ''
*/
headerClass?: string;
/**
* Header height
*
* @default 56px
*/
headerHeight?: number;
}
/** Tab config */
interface AdminLayoutTabConfig {
/**
* Whether tab is visible
*
* @default true
*/
tabVisible?: boolean;
/**
* Tab class
*
* @default ''
*/
tabClass?: string;
/**
* Tab height
*
* @default 48px
*/
tabHeight?: number;
}
/** Sider config */
interface AdminLayoutSiderConfig {
/**
* Whether sider is visible
*
* @default true
*/
siderVisible?: boolean;
/**
* Sider class
*
* @default ''
*/
siderClass?: string;
/**
* Mobile sider class
*
* @default ''
*/
mobileSiderClass?: string;
/**
* Sider collapse status
*
* @default false
*/
siderCollapse?: boolean;
/**
* Sider width when collapse is false
*
* @default '220px'
*/
siderWidth?: number;
/**
* Sider width when collapse is true
*
* @default '64px'
*/
siderCollapsedWidth?: number;
}
/** Content config */
export interface AdminLayoutContentConfig {
/**
* Content class
*
* @default ''
*/
contentClass?: string;
/**
* Whether content is full the page
*
* If true, other elements will be hidden by `display: none`
*/
fullContent?: boolean;
}
/** Footer config */
export interface AdminLayoutFooterConfig {
/**
* Whether footer is visible
*
* @default true
*/
footerVisible?: boolean;
/**
* Whether footer is fixed
*
* @default true
*/
fixedFooter?: boolean;
/**
* Footer class
*
* @default ''
*/
footerClass?: string;
/**
* Footer height
*
* @default 48px
*/
footerHeight?: number;
/**
* Whether footer is on the right side
*
* When the layout is vertical, the footer is on the right side
*/
rightFooter?: boolean;
}
/**
* Layout mode
*
* - Horizontal
* - Vertical
*/
export type LayoutMode = 'horizontal' | 'vertical';
/**
* The scroll mode when content overflow
*
* - Wrapper: the layout component's wrapper element has a scrollbar
* - Content: the layout component's content element has a scrollbar
*
* @default 'wrapper'
*/
export type LayoutScrollMode = 'wrapper' | 'content';
/** Admin layout props */
export interface AdminLayoutProps
extends AdminLayoutHeaderConfig,
AdminLayoutTabConfig,
AdminLayoutSiderConfig,
AdminLayoutContentConfig,
AdminLayoutFooterConfig {
/**
* Layout mode
*
* - {@link LayoutMode}
*/
mode?: LayoutMode;
/** Is mobile layout */
isMobile?: boolean;
/**
* Scroll mode
*
* - {@link ScrollMode}
*/
scrollMode?: LayoutScrollMode;
/**
* The id of the scroll element of the layout
*
* It can be used to get the corresponding Dom and scroll it
*
* @example
* use the default id by import
* ```ts
* import { adminLayoutScrollElId } from '@sa/vue-materials';
* ```
*
* @default
* ```ts
* const adminLayoutScrollElId = '__ADMIN_LAYOUT_SCROLL_EL_ID__'
* ```
*/
scrollElId?: string;
/** The class of the scroll element */
scrollElClass?: string;
/** The class of the scroll wrapper element */
scrollWrapperClass?: string;
/**
* The common class of the layout
*
* Is can be used to configure the transition animation
*
* @default 'transition-all-300'
*/
commonClass?: string;
/**
* Whether fix the header and tab
*
* @default true
*/
fixedTop?: boolean;
/**
* The max z-index of the layout
*
* The z-index of Header,Tab,Sider and Footer will not exceed this value
*/
maxZIndex?: number;
}
type Kebab<S extends string> = S extends Uncapitalize<S> ? S : `-${Uncapitalize<S>}`;
type KebabCase<S extends string> = S extends `${infer Start}${infer End}`
? `${Uncapitalize<Start>}${KebabCase<Kebab<End>>}`
: S;
type Prefix = '--soy-';
export type LayoutCssVarsProps = Pick<
AdminLayoutProps,
'headerHeight' | 'tabHeight' | 'siderWidth' | 'siderCollapsedWidth' | 'footerHeight'
> & {
headerZIndex?: number;
tabZIndex?: number;
siderZIndex?: number;
mobileSiderZIndex?: number;
footerZIndex?: number;
};
export type LayoutCssVars = {
[K in keyof LayoutCssVarsProps as `${Prefix}${KebabCase<K>}`]: string | number;
};
/**
* The mode of the tab
*
* - Button: button style
* - Chrome: chrome style
*
* @default chrome
*/
export type PageTabMode = 'button' | 'chrome';
export interface PageTabProps {
/** Whether is dark mode */
darkMode?: boolean;
/**
* The mode of the tab
*
* - {@link TabMode}
*/
mode?: PageTabMode;
/**
* The common class of the layout
*
* Is can be used to configure the transition animation
*
* @default 'transition-all-300'
*/
commonClass?: string;
/** The class of the button tab */
buttonClass?: string;
/** The class of the chrome tab */
chromeClass?: string;
/** Whether the tab is active */
active?: boolean;
/** The color of the active tab */
activeColor?: string;
/**
* Whether the tab is closable
*
* Show the close icon when true
*/
closable?: boolean;
}
export type PageTabCssVarsProps = {
primaryColor: string;
primaryColor1: string;
primaryColor2: string;
primaryColorOpacity1: string;
primaryColorOpacity2: string;
primaryColorOpacity3: string;
};
export type PageTabCssVars = {
[K in keyof PageTabCssVarsProps as `${Prefix}${KebabCase<K>}`]: string | number;
};

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