Compare commits
153 Commits
tauri-v1.1
...
v1.3.8
Author | SHA1 | Date | |
---|---|---|---|
|
0c1741096b | ||
|
71e6307db2 | ||
|
b667eab76a | ||
|
4b3ac11bd5 | ||
|
24bb6d95cb | ||
|
4726498faa | ||
|
75cbfbbfe6 | ||
|
8dcda38560 | ||
|
2072f5850e | ||
|
cfaab8527a | ||
|
83ba798781 | ||
|
9669ca2041 | ||
|
baefdfd8c4 | ||
|
24e9e57a31 | ||
|
4da588c6ba | ||
|
3e72c3b45a | ||
|
ce66bca1a1 | ||
|
f35627e169 | ||
|
0ac95bdcf5 | ||
|
04d056479f | ||
|
60bbd2d145 | ||
|
38eeb678f3 | ||
|
207d6eb6ec | ||
|
6561f0b5f9 | ||
|
20f8ed311c | ||
|
5baf19d204 | ||
|
75997c1655 | ||
|
c4e16102cb | ||
|
be8556cd2b | ||
|
27b5222cfb | ||
|
79b2a28b5a | ||
|
531bfaf1b9 | ||
|
c3f1f69833 | ||
|
a44ea624f1 | ||
|
7cb43fc3c2 | ||
|
4c9f4e09b1 | ||
|
9c012c7d13 | ||
|
878d9c395c | ||
|
3830ec7a69 | ||
|
ef6cf93d96 | ||
|
7fa55905fc | ||
|
2fa400b113 | ||
|
73e917ad59 | ||
|
e9a2ee4a23 | ||
|
a1c14a1570 | ||
|
b16a96323a | ||
|
26c93dff9a | ||
|
5094f0eea8 | ||
|
a8f923eb38 | ||
|
e6aa25e9f8 | ||
|
968370b1aa | ||
|
cb1d44525d | ||
|
939c512f02 | ||
|
3f23993a83 | ||
|
ebc838c3e0 | ||
|
5646a50ddf | ||
|
217a3bb259 | ||
|
d37591dd7a | ||
|
cf67d55cbf | ||
|
98b75c22c3 | ||
|
993e9caf79 | ||
|
f26d0a61eb | ||
|
eed617f9eb | ||
|
ea8aa6c4e6 | ||
|
4dde4c22b1 | ||
|
59f07d8ac4 | ||
|
e8378318c6 | ||
|
840273474f | ||
|
4e55b0e9bd | ||
|
5377002932 | ||
|
c469512bd4 | ||
|
613c836e0f | ||
|
f73f70c51b | ||
|
a0b76daeff | ||
|
f6bd6b8603 | ||
|
087e532613 | ||
|
00f41dd25e | ||
|
1d1b148c8f | ||
|
958d0baf3f | ||
|
0206969e98 | ||
|
527fd79df2 | ||
|
06971f3935 | ||
|
f4eeb2ed63 | ||
|
793b16e9ba | ||
|
cf9fc7d31f | ||
|
58fc09623c | ||
|
276ea7fa2f | ||
|
96c1044ffb | ||
|
a91335d74b | ||
|
3e2a993db8 | ||
|
cf0192ad71 | ||
|
a454b620f1 | ||
|
752ec1e9e7 | ||
|
e035eab223 | ||
|
be13ca274b | ||
|
72ede8bf9c | ||
|
0d20e4c915 | ||
|
c791adc6bc | ||
|
693f704690 | ||
|
49f60b2d50 | ||
|
425c69acc2 | ||
|
f7de3fd0f1 | ||
|
c7f6f2a537 | ||
|
531432d5ff | ||
|
ff1d50461f | ||
|
b5027c8f3e | ||
|
1e67ae8c49 | ||
|
5c67d0650e | ||
|
af735e87b8 | ||
|
b336841567 | ||
|
b094d6882b | ||
|
b94baa18c1 | ||
|
3eeace94dd | ||
|
ad2f24707a | ||
|
cd9d58d4de | ||
|
2198b982f0 | ||
|
376e2f7d84 | ||
|
069fa8a817 | ||
|
b5a723cb5f | ||
|
79e85bc6b5 | ||
|
bf7183747b | ||
|
aabb2a49c4 | ||
|
7026126a57 | ||
|
c212565248 | ||
|
813d8ce4c7 | ||
|
20a8127434 | ||
|
ec8cadd183 | ||
|
4470cb4e8c | ||
|
8f9a70505c | ||
|
9094b21cbb | ||
|
6259287240 | ||
|
22004ff4dc | ||
|
08827a42a3 | ||
|
6a6eb9afd6 | ||
|
ff51b72dac | ||
|
fe06b8c499 | ||
|
4b63bbcf67 | ||
|
5531a68641 | ||
|
584cd54d6d | ||
|
2bec899031 | ||
|
83862ba76e | ||
|
060c0a91c7 | ||
|
76649e2a08 | ||
|
ddf3823a55 | ||
|
e75fd73f34 | ||
|
1f4647b995 | ||
|
910dfca8bb | ||
|
ffb48b15bc | ||
|
e6086f0f35 | ||
|
9b05d73e6d | ||
|
bd69c00e74 | ||
|
d08a3817d1 | ||
|
d0380ce5cb |
5
.env
@@ -36,7 +36,7 @@ VITE_SERVICE_LOGOUT_CODES=8888,8889
|
||||
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
|
||||
VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998,3333
|
||||
|
||||
# when the route mode is static, the defined super role
|
||||
VITE_STATIC_SUPER_ROLE=R_SUPER
|
||||
@@ -46,3 +46,6 @@ VITE_SOURCE_MAP=N
|
||||
|
||||
# Used to differentiate storage across different domains
|
||||
VITE_STORAGE_PREFIX=SOY_
|
||||
|
||||
# used to control whether the program automatically detects updates
|
||||
VITE_AUTOMATICALLY_DETECT_UPDATE=Y
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# backend service base url, prod environment
|
||||
VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default
|
||||
VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default
|
||||
|
||||
# other backend service base url, prod environment
|
||||
VITE_OTHER_SERVICE_BASE_URL= `{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# backend service base url, test environment
|
||||
VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default
|
||||
VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default
|
||||
|
||||
# other backend service base url, test environment
|
||||
VITE_OTHER_SERVICE_BASE_URL= `{
|
||||
|
2
.github/ISSUE_TEMPLATE/bug-report_cn.yaml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Bug提交
|
||||
name: 🐞 Bug提交
|
||||
description: 在使用软件或功能的过程中遇到了错误
|
||||
title: '[Bug]: '
|
||||
labels: [ "bug?" ]
|
||||
|
2
.github/ISSUE_TEMPLATE/bug-report_en.yaml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Bug Report
|
||||
name: 🐞 Bug Report
|
||||
description: Encountered an error while using the software or feature
|
||||
title: '[Bug]: '
|
||||
labels: [ "bug?" ]
|
||||
|
48
.github/ISSUE_TEMPLATE/feature_request_cn.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: 🚀 功能请求
|
||||
description: 提出一个想法以帮助我们改进W&B
|
||||
title: "[功能]: "
|
||||
labels:
|
||||
- "功能请求"
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**感谢 :heart: 您花时间填写此功能请求报告!**
|
||||
我们恳请您搜索看看您的功能是否[已经存在](https://github.com/soybeanjs/soybean-admin/issues?q=is%3Aissue+sort%3Acreated-desc+)。
|
||||
|
||||
我们也很乐意接受用户的贡献。有关更多详细信息,请参阅[此处](https://github.com/soybeanjs/soybean-admin/blob/main/README.zh_CN.md#%E5%A6%82%E4%BD%95%E8%B4%A1%E7%8C%AE)。
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 描述
|
||||
description: |
|
||||
对您感兴趣的功能的清晰简洁的描述。
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 建议的解决方案
|
||||
description: |
|
||||
描述您想要的解决方案。对您希望发生的事情的清晰简洁的描述。
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 替代方案
|
||||
description: |
|
||||
描述您考虑过的替代方案。
|
||||
对您考虑过的任何替代解决方案或功能的清晰简洁的描述。
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 额外的上下文
|
||||
description: |
|
||||
在此处添加有关问题的其他上下文。
|
||||
validations:
|
||||
required: false
|
48
.github/ISSUE_TEMPLATE/feature_request_en.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: 🚀 Feature Request
|
||||
description: Suggest an idea to help us improve W&B
|
||||
title: "[Feature]: "
|
||||
labels:
|
||||
- "feature_request"
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Thanks :heart: for taking the time to fill out this feature request report!**
|
||||
We kindly ask that you search to see if an issue [already exists](https://github.com/soybeanjs/soybean-admin/issues?q=is%3Aissue+sort%3Acreated-desc+) for your feature.
|
||||
|
||||
We are also happy to accept contributions from our users. For more details see [here](https://github.com/soybeanjs/soybean-admin/blob/main/README.md#how-to-contribute).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
A clear and concise description of the feature you're interested in.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Suggested Solution
|
||||
description: |
|
||||
Describe the solution you'd like. A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives
|
||||
description: |
|
||||
Describe alternatives you've considered.
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: |
|
||||
Add any other context about the problem here.
|
||||
validations:
|
||||
required: false
|
3
.vscode/extensions.json
vendored
@@ -6,9 +6,6 @@
|
||||
"dbaeumer.vscode-eslint",
|
||||
"editorconfig.editorconfig",
|
||||
"esbenp.prettier-vscode",
|
||||
"formulahendry.auto-close-tag",
|
||||
"formulahendry.auto-complete-tag",
|
||||
"formulahendry.auto-rename-tag",
|
||||
"lokalise.i18n-ally",
|
||||
"mhutchie.git-graph",
|
||||
"mikestead.dotenv",
|
||||
|
5
.vscode/settings.json
vendored
@@ -3,7 +3,7 @@
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never"
|
||||
},
|
||||
"eslint.experimental.useFlatConfig": true,
|
||||
"eslint.useFlatConfig": true,
|
||||
"editor.formatOnSave": false,
|
||||
"eslint.validate": ["html", "css", "scss", "json", "jsonc"],
|
||||
"i18n-ally.displayLanguage": "zh-cn",
|
||||
@@ -14,5 +14,6 @@
|
||||
"i18n-ally.localesPaths": ["src/locales/langs"],
|
||||
"prettier.enable": false,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"unocss.root": ["./"]
|
||||
"unocss.root": ["./"],
|
||||
"vue.server.hybridMode": true
|
||||
}
|
||||
|
518
CHANGELOG.md
@@ -1,6 +1,524 @@
|
||||
# Changelog
|
||||
|
||||
|
||||
## [v1.3.8](https://github.com/soybeanjs/soybean-admin/compare/v1.3.7...v1.3.8) (2024-10-25)
|
||||
|
||||
### 🚨 Breaking Changes
|
||||
|
||||
- **projects**: refactor route cache & support reset route cache strategy - by @soybeanjs [<samp>(b667e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b667eab)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **packages**:
|
||||
- add subpackage `@sa/alova` - by @JOU-amjs in https://github.com/soybeanjs/soybean-admin/issues/640 [<samp>(2072f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2072f58)
|
||||
- optimistic subpackage `@sa/alova` - by @JOU-amjs in https://github.com/soybeanjs/soybean-admin/issues/646 [<samp>(4b3ac)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4b3ac11)
|
||||
- **projects**:
|
||||
- login supports accessible operation. - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/637 [<samp>(cfaab)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cfaab85)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **utils**: fix `isPC`. fixed #644 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/644 [<samp>(47264)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4726498)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps - by @soybeanjs [<samp>(8dcda)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8dcda38)
|
||||
- **projects**:
|
||||
- update vscode extensions - by @soybeanjs [<samp>(24bb6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/24bb6d9)
|
||||
- update deps & fix sass usage - by @soybeanjs [<samp>(71e63)</samp>](https://github.com/soybeanjs/soybean-admin/commit/71e6307)
|
||||
- **types**:
|
||||
- remove type declaration for document.startViewTransition (TypeScript 5.6 includes it) - by @NHZEX in https://github.com/soybeanjs/soybean-admin/issues/633 [<samp>(83ba7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/83ba798)
|
||||
|
||||
### 🎨 Styles
|
||||
|
||||
- **projects**: reduce ambiguity in theme configuration instructions. - by @Azir-11 [<samp>(75cbf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/75cbfbb)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/JOU-amjs) [](https://github.com/Azir-11) [](https://github.com/NHZEX)
|
||||
|
||||
## [v1.3.7](https://github.com/soybeanjs/soybean-admin/compare/v1.3.6...v1.3.7) (2024-09-21)
|
||||
|
||||
### 🚨 Breaking Changes
|
||||
|
||||
- **projects**: update scss config - by @soybeanjs [<samp>(24e9e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/24e9e57)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**: fix global-tab click conflict with contextmenu - by @soybeanjs [<samp>(3e72c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3e72c3b)
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- **packages**: @sa/materials: remove tab close shortcut by mouse - by @soybeanjs [<samp>(4da58)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4da588c)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @soybeanjs [<samp>(baefd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/baefdfd)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
## [v1.3.6](https://github.com/soybeanjs/soybean-admin/compare/v1.3.5...v1.3.6) (2024-09-20)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **components**:
|
||||
- fix VerticalMixMenu name - by @soybeanjs [<samp>(20f8e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/20f8ed3)
|
||||
- **projects**:
|
||||
- fix click global-tab in iPad. fixed #624 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/624 [<samp>(04d05)</samp>](https://github.com/soybeanjs/soybean-admin/commit/04d0564)
|
||||
- when the roles filter submenu is empty, the parent menu is not excluded. fixed #621. - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/626 and https://github.com/soybeanjs/soybean-admin/issues/621 [<samp>(0ac95)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0ac95bd)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**:
|
||||
- optimize code - by @soybeanjs [<samp>(6561f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/6561f0b)
|
||||
- optimize code - by @soybeanjs [<samp>(38eeb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/38eeb67)
|
||||
- remove defineModel setting,enabled by default - by @yanbowe in https://github.com/soybeanjs/soybean-admin/issues/620 [<samp>(60bbd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/60bbd2d)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @soybeanjs [<samp>(5baf1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5baf19d)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps - by @soybeanjs [<samp>(207d6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/207d6eb)
|
||||
- update deps - by @soybeanjs [<samp>(f3562)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f35627e)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/Azir-11) [](https://github.com/yanbowe)
|
||||
|
||||
## [v1.3.5](https://github.com/soybeanjs/soybean-admin/compare/v1.3.4...v1.3.5) (2024-09-07)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **packages**:
|
||||
- @sa/axios: add response to flatRequest when success - by @soybeanjs [<samp>(c4e16)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c4e1610)
|
||||
- **projects**:
|
||||
- README.zh_CN.md 添加合作推广 - by @PZ-18664918826 in https://github.com/soybeanjs/soybean-admin/issues/601 [<samp>(2fa40)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2fa400b)
|
||||
- Add more commit types according to Apache specifications - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/610 [<samp>(878d9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/878d9c3)
|
||||
- does the configuration support automatic updates. close#612 - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/617 and https://github.com/soybeanjs/soybean-admin/issues/612 [<samp>(4c9f4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4c9f4e0)
|
||||
- add app error handler. close #587 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/587 [<samp>(be855)</samp>](https://github.com/soybeanjs/soybean-admin/commit/be8556c)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **deps**:
|
||||
- move json5 from devDependencies to dependencies to support production usage - by @mufeng889 in https://github.com/soybeanjs/soybean-admin/issues/618 [<samp>(7cb43)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7cb43fc)
|
||||
- **projects**:
|
||||
- avoid retrieving cached HTML - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/605 [<samp>(ef6cf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ef6cf93)
|
||||
- fix login redirect - by @soybeanjs [<samp>(3830e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3830ec7)
|
||||
- fix vertical-mix-menu when sider collapse. fixed #608 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/608 [<samp>(c3f1f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c3f1f69)
|
||||
- fix breadcrumb when activeMenu is parent menu. fixed #589 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/589 [<samp>(79b2a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/79b2a28)
|
||||
- fix refresh token when meet multi requests. fixed #581 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/581 [<samp>(27b52)</samp>](https://github.com/soybeanjs/soybean-admin/commit/27b5222)
|
||||
- **types**:
|
||||
- fix the type of TableApiFn - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/599 [<samp>(26c93)</samp>](https://github.com/soybeanjs/soybean-admin/commit/26c93df)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**: optimize menu selectedKey - by @soybeanjs [<samp>(531bf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/531bfaf)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**:
|
||||
- update README - by @mufeng889 in https://github.com/soybeanjs/soybean-admin/issues/594 [<samp>(a8f92)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a8f923e)
|
||||
- update README - by @soybeanjs [<samp>(e9a2e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e9a2ee4)
|
||||
- update README - by @soybeanjs [<samp>(73e91)</samp>](https://github.com/soybeanjs/soybean-admin/commit/73e917a)
|
||||
- update the location of important information in the document - by **Azir** [<samp>(9c012)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9c012c7)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps - by @soybeanjs [<samp>(a1c14)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a1c14a1)
|
||||
- update deps - by @soybeanjs [<samp>(7fa55)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7fa5590)
|
||||
- update deps - by @soybeanjs [<samp>(a44ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a44ea62)
|
||||
- **projects**:
|
||||
- use json5 resolve env `VITE_OTHER_SERVICE_BASE_URL` & fix proxy enable - by @soybeanjs [<samp>(b16a9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b16a963)
|
||||
|
||||
### 🎨 Styles
|
||||
|
||||
- **projects**: rename script czh to commit:zh - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/597 [<samp>(5094f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5094f0e)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/mufeng889) [](https://github.com/Azir-11) [](https://github.com/PZ-18664918826)
|
||||
[Azir](mailto:2075125282@qq.com),
|
||||
|
||||
## [v1.3.4](https://github.com/honghuangdc/soybean-admin/compare/v1.3.3...v1.3.4) (2024-08-01)
|
||||
|
||||
### 🚨 Breaking Changes
|
||||
|
||||
- **projects**: don't reset active menu of vertical-mix layout when it is mixSiderFixed - by @honghuangdc [<samp>(939c5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/939c512)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**: optimize code - by @honghuangdc [<samp>(cb1d4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cb1d445)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **projects**: update deps & fix vue-router type - by @honghuangdc [<samp>(96837)</samp>](https://github.com/honghuangdc/soybean-admin/commit/968370b)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
|
||||
## [v1.3.3](https://github.com/honghuangdc/soybean-admin/compare/v1.3.2...v1.3.3) (2024-07-30)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**: fix watermark settings - by @honghuangdc [<samp>(5646a)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5646a50)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @honghuangdc [<samp>(ebc83)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ebc838c)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
|
||||
## [v1.3.2](https://github.com/honghuangdc/soybean-admin/compare/v1.3.1...v1.3.2) (2024-07-30)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **projects**:
|
||||
- add color fading mode.close #567 - by @Azir-11 in https://github.com/honghuangdc/soybean-admin/issues/569 and https://github.com/honghuangdc/soybean-admin/issues/567 [<samp>(4dde4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4dde4c2)
|
||||
- add full screen watermark. close#571 - by @paynezhuang in https://github.com/honghuangdc/soybean-admin/issues/573 and https://github.com/honghuangdc/soybean-admin/issues/571 [<samp>(ea8aa)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ea8aa6c)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**: fix vertical-mix menu selected - by @honghuangdc [<samp>(59f07)</samp>](https://github.com/honghuangdc/soybean-admin/commit/59f07d8)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**:
|
||||
- add type WatermarkProps - by @honghuangdc [<samp>(f26d0)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f26d0a6)
|
||||
- remove home NAlert closable - by @honghuangdc [<samp>(98b75)</samp>](https://github.com/honghuangdc/soybean-admin/commit/98b75c2)
|
||||
- optimize response code comparison - by @honghuangdc [<samp>(cf67d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cf67d55)
|
||||
- **types**:
|
||||
- remove useless types. - by **Azir** [<samp>(eed61)</samp>](https://github.com/honghuangdc/soybean-admin/commit/eed617f)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @honghuangdc [<samp>(d3759)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d37591d)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @honghuangdc [<samp>(993e9)</samp>](https://github.com/honghuangdc/soybean-admin/commit/993e9ca)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/paynezhuang) [](https://github.com/Azir-11)
|
||||
[Azir](mailto:2075125282@qq.com),
|
||||
|
||||
## [v1.3.1](https://github.com/honghuangdc/soybean-admin/compare/v1.3.0...v1.3.1) (2024-07-22)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**:
|
||||
- fix the issue of abnormal width of the sidebar in the top menu mix and reverse mode - by @Azir-11 in https://github.com/honghuangdc/soybean-admin/issues/562 [<samp>(c4695)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c469512)
|
||||
- fix HorizontalMixMenu inverted. fixed #563 - by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/563 [<samp>(4e55b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4e55b0e)
|
||||
- fix vertical-menu will not render when the layout is from mobile - by @honghuangdc [<samp>(84027)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8402734)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @honghuangdc [<samp>(613c8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/613c836)
|
||||
|
||||
### 🎨 Styles
|
||||
|
||||
- **other**: modify the Chinese name of the grayscale mode - by **Azir** [<samp>(53770)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5377002)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/Azir-11)
|
||||
[Azir](mailto:2075125282@qq.com),
|
||||
|
||||
## [v1.3.0](https://github.com/soybeanjs/soybean-admin/compare/v1.2.8...v1.3.0) (2024-07-22)
|
||||
|
||||
### 🚨 Breaking Changes
|
||||
|
||||
- **projects**: refactor global menu & support `reversed-horizontal-mix-menu`. close #365 - by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/365 [<samp>(087e5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/087e532)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **packages**:
|
||||
- `@sa/scripts`: command `gitCommit` support chinese - by @mmdapl in https://github.com/soybeanjs/soybean-admin/issues/548 [<samp>(06971)</samp>](https://github.com/soybeanjs/soybean-admin/commit/06971f3)
|
||||
- @sa/axios: replace CancelTokenSource by AbortController. close #530, close #532 - by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/530 and https://github.com/soybeanjs/soybean-admin/issues/532 [<samp>(527fd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/527fd79)
|
||||
- @sa/scripts: add ignore pattern list for command `gitCommitVerify`. close #504 - by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/504 [<samp>(958d0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/958d0ba)
|
||||
- **projects**:
|
||||
- make branch `main` tiny & modify request retry times to 0 - by @Azir-11 [<samp>(793b1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/793b16e)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **hooks**: prevent program freezing when pagesize returns 0 - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/545 [<samp>(f4eeb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f4eeb2e)
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- **projects**:
|
||||
- combine `theme tokens` and `theme settings`. close #379 - by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/379 [<samp>(1d1b1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1d1b148)
|
||||
- change css vars mount to root - by @honghuangdc [<samp>(00f41)</samp>](https://github.com/soybeanjs/soybean-admin/commit/00f41dd)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @honghuangdc [<samp>(a0b76)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a0b76da)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @honghuangdc [<samp>(f6bd6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f6bd6b8)
|
||||
- **projects**: add script `czh` - by @honghuangdc [<samp>(02069)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0206969)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/mmdapl) [](https://github.com/Azir-11)
|
||||
|
||||
## [v1.2.8](https://github.com/soybeanjs/soybean-admin/compare/v1.2.7...v1.2.8) (2024-07-20)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **packages**:
|
||||
- @sa/hooks: fix searchParams of useHookTable. fixed #552 - by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/552 [<samp>(96c10)</samp>](https://github.com/soybeanjs/soybean-admin/commit/96c1044)
|
||||
- **types**:
|
||||
- Fixed the reference type error - by **dodu2014** in https://github.com/soybeanjs/soybean-admin/issues/551 [<samp>(3e2a9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3e2a993)
|
||||
- fix data type of useHookTable - by @honghuangdc [<samp>(276ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/276ea7f)
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- **projects**: replace `cloneDeep` of `lodash-es` with `klona` - by @honghuangdc [<samp>(a9133)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a91335d)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @honghuangdc [<samp>(58fc0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/58fc096)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @honghuangdc [<samp>(cf019)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cf0192a)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
[dodu2014](mailto:dodu@live.cn)
|
||||
|
||||
## [v1.2.7](https://github.com/honghuangdc/soybean-admin/compare/v1.2.6...v1.2.7) (2024-07-12)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**: supports custom menu icon sizes - by @wynn-w in https://github.com/honghuangdc/soybean-admin/issues/534 [<samp>(e035e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e035eab)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps - by @honghuangdc [<samp>(72ede)</samp>](https://github.com/honghuangdc/soybean-admin/commit/72ede8b)
|
||||
- update deps - by @honghuangdc [<samp>(be13c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/be13ca2)
|
||||
- update deps - by @honghuangdc [<samp>(752ec)</samp>](https://github.com/honghuangdc/soybean-admin/commit/752ec1e)
|
||||
- **projects**:
|
||||
- Fix deprecated configuration config - by @paynezhuang in https://github.com/honghuangdc/soybean-admin/issues/524 [<samp>(0d20e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/0d20e4c)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/wynn-w) [](https://github.com/paynezhuang)
|
||||
|
||||
## [v1.2.6](https://github.com/honghuangdc/soybean-admin/compare/v1.2.5...v1.2.6) (2024-06-21)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**:
|
||||
- request modal title use i18n. fixed #507 - by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/507 [<samp>(f7de3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f7de3fd)
|
||||
- add `getDataByPage` for `useTable`. fixed #499 - by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/499 [<samp>(425c6)</samp>](https://github.com/honghuangdc/soybean-admin/commit/425c69a)
|
||||
- fix login redirect to routeHome when routeHome of dynamic route is not same as static route. fixed #511 - by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/511 [<samp>(49f60)</samp>](https://github.com/honghuangdc/soybean-admin/commit/49f60b2)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**: optimize `getRouteQueryOfLoginRoute` - by @honghuangdc [<samp>(693f7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/693f704)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**:
|
||||
- update CHANGELOG - by @honghuangdc [<samp>(5c67d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5c67d06)
|
||||
- update README - by @honghuangdc [<samp>(1e67a)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1e67ae8)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps. close #510 - by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/510 [<samp>(53143)</samp>](https://github.com/honghuangdc/soybean-admin/commit/531432d)
|
||||
- update deps - by @honghuangdc [<samp>(c7f6f)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c7f6f2a)
|
||||
|
||||
### 🤖 CI
|
||||
|
||||
- **projects**:
|
||||
- add github issues template - by @honghuangdc [<samp>(b5027)</samp>](https://github.com/honghuangdc/soybean-admin/commit/b5027c8)
|
||||
- update github issues template - by @honghuangdc [<samp>(ff1d5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff1d504)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
|
||||
## [v1.2.5](https://github.com/soybeanjs/soybean-admin/compare/v1.2.4...v1.2.5) (2024-06-15)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**: Fix the issue of abnormal tab caching after logout. fixed #495 - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/495 [<samp>(3eeac)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3eeace9)
|
||||
|
||||
### 🔥 Performance
|
||||
|
||||
- **project**: Initializing the static routing function does not require asynchronization - by **CHENZL** in https://github.com/soybeanjs/soybean-admin/issues/493 [<samp>(2198b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2198b98)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**: optimize code - by @soybeanjs [<samp>(b94ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b94baa1)
|
||||
- **types**: Enhance compatibility of global types - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/494 [<samp>(cd9d5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cd9d58d)
|
||||
- **utils**: Reduce code indentation and improve readability - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/496 [<samp>(ad2f2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ad2f247)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @soybeanjs [<samp>(b3368)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b336841)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @soybeanjs [<samp>(b094d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b094d68)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/Azir-11)
|
||||
[CHENZL](mailto:zlong5568863@qq.com)
|
||||
|
||||
## [v1.2.4](https://github.com/soybeanjs/soybean-admin/compare/v1.2.3...v1.2.4) (2024-06-14)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**:
|
||||
- optimize `setupAppVersionNotification` - by @soybeanjs [<samp>(b5a72)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5a723c)
|
||||
- get buildTime with timezone 'Asia/Shanghai' - by @soybeanjs [<samp>(069fa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/069fa8a)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
## [v1.2.3](https://github.com/soybeanjs/soybean-admin/compare/v1.2.2...v1.2.3) (2024-06-13)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**:
|
||||
- fix mobile browser theme issue by adding color-scheme meta tag to index.html - by @KickCashew in https://github.com/soybeanjs/soybean-admin/issues/488 [<samp>(c2125)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c212565)
|
||||
- Fix secondary directory components is empty - by @paynezhuang in https://github.com/soybeanjs/soybean-admin/issues/491 [<samp>(aabb2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/aabb2a4)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**:
|
||||
- Fixed the hyperlink pointing error - by **Azir** [<samp>(20a81)</samp>](https://github.com/soybeanjs/soybean-admin/commit/20a8127)
|
||||
- update README - by @soybeanjs [<samp>(70261)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7026126)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps - by @soybeanjs [<samp>(813d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/813d8ce)
|
||||
- update deps - by @soybeanjs [<samp>(bf718)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bf71837)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/paynezhuang) [](https://github.com/KickCashew)
|
||||
[Azir](mailto:2075125282@qq.com)
|
||||
|
||||
## [v1.2.2](https://github.com/honghuangdc/soybean-admin/compare/v1.2.1...v1.2.2) (2024-06-12)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **projects**: reset scroll position when tab change - by @soybeanjs [<samp>(9094b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9094b21)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**:
|
||||
- hide AppVersionNotification in DEV mode - by @sigma-plus in https://github.com/honghuangdc/soybean-admin/issues/482 [<samp>(62592)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6259287)
|
||||
- fix menu-toggler hidden in mobile layout. fixed #483 - by @soybeanjs in https://github.com/honghuangdc/soybean-admin/issues/483 [<samp>(4470c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4470cb4)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update README - by @soybeanjs [<samp>(8f9a7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8f9a705)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/sigma-plus)
|
||||
|
||||
## [v1.2.1](https://github.com/honghuangdc/soybean-admin/compare/v1.2.0...v1.2.1) (2024-06-07)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**:
|
||||
- fix get user info when page reload - by @soybeanjs [<samp>(ff51b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff51b72)
|
||||
- fix setupAppVersionNotification render - by @soybeanjs [<samp>(6a6eb)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6a6eb9a)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @soybeanjs [<samp>(fe06b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/fe06b8c)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @soybeanjs [<samp>(08827)</samp>](https://github.com/honghuangdc/soybean-admin/commit/08827a4)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
## [v1.2.0](https://github.com/soybeanjs/soybean-admin/compare/v1.1.5...v1.2.0) (2024-06-06)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **projects**:
|
||||
- support system new version update notification. close #420 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/420 [<samp>(584cd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/584cd54)
|
||||
- get user info in router guard and remove in localStorage. close #459 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/459 [<samp>(5531a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5531a68)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**: update CHANGELOG - by @soybeanjs [<samp>(2bec8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2bec899)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
## [v1.1.5](https://github.com/soybeanjs/soybean-admin/compare/v1.1.4...v1.1.5) (2024-06-06)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **projects**: fix register name, CodeLogin => Register - by @m-xlsea in https://github.com/soybeanjs/soybean-admin/issues/478 [<samp>(ddf38)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ddf3823)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**: update deps - by @soybeanjs [<samp>(060c0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/060c0a9)
|
||||
- **projects**: update vscode settings: vue official - by @soybeanjs [<samp>(76649)</samp>](https://github.com/soybeanjs/soybean-admin/commit/76649e2)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/m-xlsea)
|
||||
|
||||
## [v1.1.4](https://github.com/honghuangdc/soybean-admin/compare/v1.1.3...v1.1.4) (2024-06-06)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
||||
- **utils**: modalLogout bug when esc is pressed - by @sigma-plus in https://github.com/honghuangdc/soybean-admin/issues/470 [<samp>(bd69c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/bd69c00)
|
||||
|
||||
### 🛠 Optimizations
|
||||
|
||||
- **projects**: optimize RouteMeta remarks - by @soybeanjs [<samp>(ffb48)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ffb48b1)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **projects**:
|
||||
- update CHANGELOG - by @soybeanjs [<samp>(756f8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/756f84a)
|
||||
- update Node&pnpm version - by @Azir-11 in https://github.com/honghuangdc/soybean-admin/issues/472 [<samp>(9b05d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9b05d73)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps**:
|
||||
- update deps - by @soybeanjs [<samp>(d0380)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d0380ce)
|
||||
- update deps - by @soybeanjs [<samp>(1f464)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1f4647b)
|
||||
- **projects**:
|
||||
- close http proxy - by @soybeanjs [<samp>(d08a3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d08a381)
|
||||
- update mock url - by @soybeanjs [<samp>(e6086)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e6086f0)
|
||||
- update vscode settings - by @soybeanjs [<samp>(910df)</samp>](https://github.com/honghuangdc/soybean-admin/commit/910dfca)
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/Azir-11) [](https://github.com/sigma-plus)
|
||||
|
||||
## [v1.1.3](https://github.com/soybeanjs/soybean-admin/compare/v1.1.2...v1.1.3) (2024-06-02)
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
|
@@ -1,5 +1,439 @@
|
||||
# 更新日志
|
||||
|
||||
## [v1.3.5](https://github.com/soybeanjs/soybean-admin/compare/v1.3.4...v1.3.5) (2024-09-07)
|
||||
|
||||
### 🚀 新功能
|
||||
|
||||
- **packages**:
|
||||
- @sa/axios: 成功时将响应添加到 flatRequest - by @soybeanjs [<samp>(c4e16)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c4e1610)
|
||||
- **projects**:
|
||||
- README.zh_CN.md 添加合作推广 - by @PZ-18664918826 in https://github.com/soybeanjs/soybean-admin/issues/601 [<samp>(2fa40)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2fa400b)
|
||||
- 根据 Apache 规范添加更多提交类型 - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/610 [<samp>(878d9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/878d9c3)
|
||||
- 配置是否支持自动更新。关闭#612 - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/617 和 https://github.com/soybeanjs/soybean-admin/issues/612 [<samp>(4c9f4)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4c9f4e0)
|
||||
- 添加应用错误处理程序。关闭 #587 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/587 [<samp>(be855)</samp>](https://github.com/soybeanjs/soybean-admin/commit/be8556c)
|
||||
|
||||
### 🐞 Bug 修复
|
||||
|
||||
- **deps**:
|
||||
- 将 json5 从 devDependencies 移到 dependencies 以支持生产环境使用 - by @mufeng889 in https://github.com/soybeanjs/soybean-admin/issues/618 [<samp>(7cb43)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7cb43fc)
|
||||
- **projects**:
|
||||
- 避免检索缓存的 HTML - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/605 [<samp>(ef6cf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ef6cf93)
|
||||
- 修复登录重定向 - by @soybeanjs [<samp>(3830e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3830ec7)
|
||||
- 修复侧边栏折叠时的 vertical-mix-menu。修复 #608 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/608 [<samp>(c3f1f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c3f1f69)
|
||||
- 修复 activeMenu 为父菜单时的面包屑。修复 #589 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/589 [<samp>(79b2a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/79b2a28)
|
||||
- 修复遇到多请求时的刷新令牌。修复 #581 - by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/581 [<samp>(27b52)</samp>](https://github.com/soybeanjs/soybean-admin/commit/27b5222)
|
||||
- **types**:
|
||||
- 修复 TableApiFn 的类型 - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/599 [<samp>(26c93)</samp>](https://github.com/soybeanjs/soybean-admin/commit/26c93df)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **projects**: 优化菜单 selectedKey - by @soybeanjs [<samp>(531bf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/531bfaf)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **projects**:
|
||||
- 更新 README - by @mufeng889 in https://github.com/soybeanjs/soybean-admin/issues/594 [<samp>(a8f92)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a8f923e)
|
||||
- 更新 README - by @soybeanjs [<samp>(e9a2e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e9a2ee4)
|
||||
- 更新 README - by @soybeanjs [<samp>(73e91)</samp>](https://github.com/soybeanjs/soybean-admin/commit/73e917a)
|
||||
- 更新文档中重要信息的位置 - by **Azir** [<samp>(9c012)</samp>](https://github.com/soybeanjs/soybean-admin/commit/9c012c7)
|
||||
|
||||
### 🏡 杂项
|
||||
|
||||
- **deps**:
|
||||
- 更新依赖 - by @soybeanjs [<samp>(a1c14)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a1c14a1)
|
||||
- 更新依赖 - by @soybeanjs [<samp>(7fa55)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7fa5590)
|
||||
- 更新依赖 - by @soybeanjs [<samp>(a44ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a44ea62)
|
||||
- **projects**:
|
||||
- 使用 json5 解析环境变量 `VITE_OTHER_SERVICE_BASE_URL` 并修复代理启用 - by @soybeanjs [<samp>(b16a9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b16a963)
|
||||
|
||||
### 🎨 样式
|
||||
|
||||
- **projects**: 将脚本 czh 重命名为 commit:zh - by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/597 [<samp>(5094f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5094f0e)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/mufeng889) [](https://github.com/Azir-11) [](https://github.com/PZ-18664918826)
|
||||
[Azir](mailto:2075125282@qq.com),
|
||||
|
||||
## [v1.3.4](https://github.com/honghuangdc/soybean-admin/compare/v1.3.3...v1.3.4) (2024-08-01)
|
||||
|
||||
### 🚨 重大变更
|
||||
|
||||
- **projects**: 当 vertical-mix 布局为 mixSiderFixed 时,不重置活动菜单 - by @honghuangdc [<samp>(939c5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/939c512)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **projects**: 优化代码 - by @honghuangdc [<samp>(cb1d4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cb1d445)
|
||||
|
||||
### 🏡 杂项
|
||||
|
||||
- **projects**: 更新依赖并修复 vue-router 类型 - by @honghuangdc [<samp>(96837)</samp>](https://github.com/honghuangdc/soybean-admin/commit/968370b)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
|
||||
## [v1.3.3](https://github.com/honghuangdc/soybean-admin/compare/v1.3.2...v1.3.3) (2024-07-30)
|
||||
|
||||
### 🐞 Bug 修复
|
||||
|
||||
- **projects**: 修复水印设置 - by @honghuangdc [<samp>(5646a)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5646a50)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **projects**: 更新 CHANGELOG - by @honghuangdc [<samp>(ebc83)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ebc838c)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
|
||||
## [v1.3.2](https://github.com/honghuangdc/soybean-admin/compare/v1.3.1...v1.3.2) (2024-07-30)
|
||||
|
||||
### 🚀 新功能
|
||||
|
||||
- **项目**:
|
||||
- 添加颜色渐变模式。关闭 #567 - 由 @Azir-11 在 https://github.com/honghuangdc/soybean-admin/issues/569 和 https://github.com/honghuangdc/soybean-admin/issues/567 [<samp>(4dde4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4dde4c2)
|
||||
- 添加全屏水印。关闭 #571 - 由 @paynezhuang 在 https://github.com/honghuangdc/soybean-admin/issues/573 和 https://github.com/honghuangdc/soybean-admin/issues/571 [<samp>(ea8aa)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ea8aa6c)
|
||||
|
||||
### 🐞 Bug 修复
|
||||
|
||||
- **项目**: 修复 vertical-mix 菜单选中问题 - 由 @honghuangdc [<samp>(59f07)</samp>](https://github.com/honghuangdc/soybean-admin/commit/59f07d8)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **项目**:
|
||||
- 添加类型 WatermarkProps - 由 @honghuangdc [<samp>(f26d0)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f26d0a6)
|
||||
- 移除 home NAlert 可关闭 - 由 @honghuangdc [<samp>(98b75)</samp>](https://github.com/honghuangdc/soybean-admin/commit/98b75c2)
|
||||
- 优化响应代码比较 - 由 @honghuangdc [<samp>(cf67d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cf67d55)
|
||||
- **类型**:
|
||||
- 移除无用类型。 - 由 **Azir** [<samp>(eed61)</samp>](https://github.com/honghuangdc/soybean-admin/commit/eed617f)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新更新日志 - 由 @honghuangdc [<samp>(d3759)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d37591d)
|
||||
|
||||
### 🏡 杂项
|
||||
|
||||
- **依赖**: 更新依赖 - 由 @honghuangdc [<samp>(993e9)</samp>](https://github.com/honghuangdc/soybean-admin/commit/993e9ca)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/paynezhuang) [](https://github.com/Azir-11)
|
||||
[Azir](mailto:2075125282@qq.com),
|
||||
|
||||
## [v1.3.1](https://github.com/honghuangdc/soybean-admin/compare/v1.3.0...v1.3.1) (2024-07-22)
|
||||
|
||||
### 🐞 Bug 修复
|
||||
|
||||
- **项目**:
|
||||
- 修复顶部菜单混合和反向模式下侧边栏宽度异常的问题 - 由 @Azir-11 在 https://github.com/honghuangdc/soybean-admin/issues/562 修复 [<samp>(c4695)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c469512)
|
||||
- 修复水平混合菜单反转问题。修复 #563 - 由 @honghuangdc 在 https://github.com/honghuangdc/soybean-admin/issues/563 修复 [<samp>(4e55b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4e55b0e)
|
||||
- 修复当布局来自移动端时垂直菜单不渲染的问题 - 由 @honghuangdc 修复 [<samp>(84027)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8402734)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新更新日志 - 由 @honghuangdc 更新 [<samp>(613c8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/613c836)
|
||||
|
||||
### 🎨 样式
|
||||
|
||||
- **其他**: 修改灰度模式的中文名称 - 由 **Azir** 修改 [<samp>(53770)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5377002)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/Azir-11)
|
||||
[Azir](mailto:2075125282@qq.com),
|
||||
|
||||
|
||||
## [v1.3.0](https://github.com/soybeanjs/soybean-admin/compare/v1.2.8...v1.3.0) (2024-07-22)
|
||||
|
||||
### 🚨 破坏性变更
|
||||
|
||||
- **项目**: 重构全局菜单 & 支持 `reversed-horizontal-mix-menu`。关闭 #365 - 由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/365 提出 [<samp>(087e5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/087e532)
|
||||
|
||||
### 🚀 功能
|
||||
|
||||
- **包**:
|
||||
- `@sa/scripts`: 命令 `gitCommit` 支持中文 - 由 @mmdapl 在 https://github.com/soybeanjs/soybean-admin/issues/548 提出 [<samp>(06971)</samp>](https://github.com/soybeanjs/soybean-admin/commit/06971f3)
|
||||
- @sa/axios: 用 AbortController 替换 CancelTokenSource。关闭 #530, 关闭 #532 - 由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/530 和 https://github.com/soybeanjs/soybean-admin/issues/532 提出 [<samp>(527fd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/527fd79)
|
||||
- @sa/scripts: 为命令 `gitCommitVerify` 添加忽略模式列表。关闭 #504 - 由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/504 提出 [<samp>(958d0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/958d0ba)
|
||||
- **项目**:
|
||||
- 使分支 `main` 更精简 & 修改请求重试次数为 0 - 由 @Azir-11 提出 [<samp>(793b1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/793b16e)
|
||||
|
||||
### 🐞 修复
|
||||
|
||||
- **钩子**: 当 pagesize 返回 0 时防止程序冻结 - 由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/545 提出 [<samp>(f4eeb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f4eeb2e)
|
||||
|
||||
### 💅 重构
|
||||
|
||||
- **项目**:
|
||||
- 合并 `theme tokens` 和 `theme settings`。关闭 #379 - 由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/379 提出 [<samp>(1d1b1)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1d1b148)
|
||||
- 将 css 变量挂载到 root - 由 @honghuangdc 提出 [<samp>(00f41)</samp>](https://github.com/soybeanjs/soybean-admin/commit/00f41dd)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新更新日志 - 由 @honghuangdc 提出 [<samp>(a0b76)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a0b76da)
|
||||
|
||||
### 🏡 杂务
|
||||
|
||||
- **依赖**: 更新依赖 - 由 @honghuangdc 提出 [<samp>(f6bd6)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f6bd6b8)
|
||||
- **项目**: 添加脚本 `czh` - 由 @honghuangdc 提出 [<samp>(02069)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0206969)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/mmdapl) [](https://github.com/Azir-11)
|
||||
|
||||
|
||||
## [v1.2.8](https://github.com/soybeanjs/soybean-admin/compare/v1.2.7...v1.2.8) (2024-07-20)
|
||||
|
||||
### 🐞 修复
|
||||
|
||||
- **包**:
|
||||
- @sa/hooks: 修复 useHookTable 的 searchParams。修复了 #552 - 由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/552 提出 [<samp>(96c10)</samp>](https://github.com/soybeanjs/soybean-admin/commit/96c1044)
|
||||
- **类型**:
|
||||
- 修复了引用类型错误 - 由 **dodu2014** 在 https://github.com/soybeanjs/soybean-admin/issues/551 提出 [<samp>(3e2a9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3e2a993)
|
||||
- 修复 useHookTable 的数据类型 - 由 @honghuangdc 提出 [<samp>(276ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/276ea7f)
|
||||
|
||||
### 💅 重构
|
||||
|
||||
- **项目**: 用 `klona` 替换 `lodash-es` 的 `cloneDeep` - 由 @honghuangdc 提出 [<samp>(a9133)</samp>](https://github.com/soybeanjs/soybean-admin/commit/a91335d)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新更新日志 - 由 @honghuangdc 提出 [<samp>(58fc0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/58fc096)
|
||||
|
||||
### 🏡 杂务
|
||||
|
||||
- **依赖**: 更新依赖 - 由 @honghuangdc 提出 [<samp>(cf019)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cf0192a)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
[dodu2014](mailto:dodu@live.cn)
|
||||
|
||||
|
||||
## [v1.2.7](https://github.com/honghuangdc/soybean-admin/compare/v1.2.6...v1.2.7) (2024-07-12)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **项目**: 支持自定义菜单图标大小 - 由 @wynn-w 在 https://github.com/honghuangdc/soybean-admin/issues/534 提出 [<samp>(e035e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e035eab)
|
||||
|
||||
### 🏡 杂务
|
||||
|
||||
- **依赖**:
|
||||
- 更新依赖 - 由 @honghuangdc [<samp>(72ede)</samp>](https://github.com/honghuangdc/soybean-admin/commit/72ede8b)
|
||||
- 更新依赖 - 由 @honghuangdc [<samp>(be13c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/be13ca2)
|
||||
- 更新依赖 - 由 @honghuangdc [<samp>(752ec)</samp>](https://github.com/honghuangdc/soybean-admin/commit/752ec1e)
|
||||
- **项目**:
|
||||
- 修复已弃用的配置配置 - 由 @paynezhuang 在 https://github.com/honghuangdc/soybean-admin/issues/524 提出 [<samp>(0d20e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/0d20e4c)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc) [](https://github.com/wynn-w) [](https://github.com/paynezhuang)
|
||||
|
||||
## [v1.2.6](https://github.com/honghuangdc/soybean-admin/compare/v1.2.5...v1.2.6) (2024-06-21)
|
||||
|
||||
### 🐞 修复
|
||||
|
||||
- **项目**:
|
||||
- 请求模态标题使用 i18n。修复 #507 - 由 @honghuangdc 在 https://github.com/honghuangdc/soybean-admin/issues/507 提出 [<samp>(f7de3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f7de3fd)
|
||||
- 为 `useTable` 添加 `getDataByPage`。修复 #499 - 由 @honghuangdc 在 https://github.com/honghuangdc/soybean-admin/issues/499 提出 [<samp>(425c6)</samp>](https://github.com/honghuangdc/soybean-admin/commit/425c69a)
|
||||
- 修复登录重定向到 routeHome 时,动态路由的 routeHome 与静态路由不同的问题。修复 #511 - 由 @honghuangdc 在 https://github.com/honghuangdc/soybean-admin/issues/511 提出 [<samp>(49f60)</samp>](https://github.com/honghuangdc/soybean-admin/commit/49f60b2)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **项目**: 优化 `getRouteQueryOfLoginRoute` - 由 @honghuangdc [<samp>(693f7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/693f704)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**:
|
||||
- 更新更新日志 - 由 @honghuangdc [<samp>(5c67d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5c67d06)
|
||||
- 更新自述文件 - 由 @honghuangdc [<samp>(1e67a)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1e67ae8)
|
||||
|
||||
### 🏡 杂务
|
||||
|
||||
- **依赖**:
|
||||
- 更新依赖。关闭 #510 - 由 @honghuangdc 在 https://github.com/honghuangdc/soybean-admin/issues/510 提出 [<samp>(53143)</samp>](https://github.com/honghuangdc/soybean-admin/commit/531432d)
|
||||
- 更新依赖 - 由 @honghuangdc [<samp>(c7f6f)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c7f6f2a)
|
||||
|
||||
### 🤖 CI
|
||||
|
||||
- **项目**:
|
||||
- 添加 github 问题模板 - 由 @honghuangdc [<samp>(b5027)</samp>](https://github.com/honghuangdc/soybean-admin/commit/b5027c8)
|
||||
- 更新 github 问题模板 - 由 @honghuangdc [<samp>(ff1d5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff1d504)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/honghuangdc)
|
||||
|
||||
## [v1.2.5](https://github.com/soybeanjs/soybean-admin/compare/v1.2.4...v1.2.5) (2024-06-15)
|
||||
|
||||
### 🐞 错误修复
|
||||
|
||||
- **项目**: 修复登出后标签页异常缓存的问题。已修复 #495 - 由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/495 [<samp>(3eeac)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3eeace9)
|
||||
|
||||
### 🔥 性能
|
||||
|
||||
- **项目**: 初始化静态路由功能不需要异步 - 由 **CHENZL** 在 https://github.com/soybeanjs/soybean-admin/issues/493 [<samp>(2198b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2198b98)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **项目**: 优化代码 - 由 @soybeanjs [<samp>(b94ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b94baa1)
|
||||
- **类型**: 提高全局类型的兼容性 - 由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/494 [<samp>(cd9d5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cd9d58d)
|
||||
- **工具**: 减少代码缩进,提高可读性 - 由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/496 [<samp>(ad2f2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ad2f247)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新CHANGELOG - 由 @soybeanjs [<samp>(f70d2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f70d29b)
|
||||
|
||||
### 🏡 杂项
|
||||
|
||||
- **依赖**: 更新依赖 - 由 @soybeanjs [<samp>(b094d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b094d68)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/Azir-11)
|
||||
[CHENZL](mailto:zlong5568863@qq.com)
|
||||
|
||||
|
||||
## [v1.2.4](https://github.com/soybeanjs/soybean-admin/compare/v1.2.3...v1.2.4) (2024-06-14)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **项目**:
|
||||
- 优化 `setupAppVersionNotification` - 由 @soybeanjs 提交 [<samp>(b5a72)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5a723c)
|
||||
- 获取 'Asia/Shanghai' 时区的构建时间 - 由 @soybeanjs 提交 [<samp>(069fa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/069fa8a)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
## [v1.2.3](https://github.com/soybeanjs/soybean-admin/compare/v1.2.2...v1.2.3) (2024-06-13)
|
||||
|
||||
### 🐞 修复错误
|
||||
|
||||
- **项目**:
|
||||
- 通过在index.html中添加color-scheme元标签修复移动浏览器主题问题 - 由 @KickCashew 在 https://github.com/soybeanjs/soybean-admin/issues/488 中提交 [<samp>(c2125)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c212565)
|
||||
- 修复二级目录组件为空 - 由 @paynezhuang 在 https://github.com/soybeanjs/soybean-admin/issues/491 中提交 [<samp>(aabb2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/aabb2a4)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**:
|
||||
- 修复超链接指向错误 - 由 **Azir** 提交 [<samp>(20a81)</samp>](https://github.com/soybeanjs/soybean-admin/commit/20a8127)
|
||||
- 更新 README - 由 @soybeanjs 提交 [<samp>(70261)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7026126)
|
||||
|
||||
### 🏡 杂项
|
||||
|
||||
- **依赖**:
|
||||
- 更新依赖 - 由 @soybeanjs 提交 [<samp>(813d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/813d8ce)
|
||||
- 更新依赖 - 由 @soybeanjs 提交 [<samp>(bf718)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bf71837)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/paynezhuang) [](https://github.com/KickCashew)
|
||||
[Azir](mailto:2075125282@qq.com)
|
||||
|
||||
## [v1.2.2](https://github.com/honghuangdc/soybean-admin/compare/v1.2.1...v1.2.2) (2024-06-12)
|
||||
|
||||
### 🚀 特性
|
||||
|
||||
- **项目**: 切换标签时重置滚动位置 - 由 @soybeanjs 提交 [<samp>(9094b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9094b21)
|
||||
|
||||
### 🐞 修复错误
|
||||
|
||||
- **项目**:
|
||||
- 在DEV模式下隐藏AppVersionNotification - 由 @sigma-plus 在 https://github.com/honghuangdc/soybean-admin/issues/482 中提交 [<samp>(62592)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6259287)
|
||||
- 修复在移动布局中隐藏menu-toggler。fixed #483 - 由 @soybeanjs 在 https://github.com/honghuangdc/soybean-admin/issues/483 中提交 [<samp>(4470c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4470cb4)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新 README - 由 @soybeanjs 提交 [<samp>(8f9a7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8f9a705)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/sigma-plus)
|
||||
|
||||
## [v1.2.1](https://github.com/honghuangdc/soybean-admin/compare/v1.2.0...v1.2.1) (2024-06-07)
|
||||
|
||||
### 🐞 修复错误
|
||||
|
||||
- **项目**:
|
||||
- 修复页面重新加载时获取用户信息 - 由 @soybeanjs 提交 [<samp>(ff51b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff51b72)
|
||||
- 修复setupAppVersionNotification渲染 - 由 @soybeanjs 提交 [<samp>(6a6eb)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6a6eb9a)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新CHANGELOG - 由 @soybeanjs [<samp>(fe06b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/fe06b8c)完成
|
||||
|
||||
### 🏡 日常任务
|
||||
|
||||
- **依赖**: 更新依赖 - 由 @soybeanjs [<samp>(08827)</samp>](https://github.com/honghuangdc/soybean-admin/commit/08827a4)完成
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
|
||||
## [v1.2.0](https://github.com/soybeanjs/soybean-admin/compare/v1.1.5...v1.2.0) (2024-06-06)
|
||||
|
||||
### 🚀 功能
|
||||
|
||||
- **项目**:
|
||||
- 支持系统新版本更新通知。关闭 #420 - 由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/420 [<samp>(584cd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/584cd54)
|
||||
- 在路由守卫中获取用户信息并从localStorage中移除。关闭 #459 - 由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/459 [<samp>(5531a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5531a68)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **项目**: 更新CHANGELOG - 由 @soybeanjs [<samp>(2bec8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2bec899)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs)
|
||||
|
||||
## [v1.1.5](https://github.com/soybeanjs/soybean-admin/compare/v1.1.4...v1.1.5) (2024-06-06)
|
||||
|
||||
### 🐞 错误修复
|
||||
|
||||
- **项目**: 修复注册组件名,CodeLogin => Register - 由 @m-xlsea 在 https://github.com/soybeanjs/soybean-admin/issues/478 [<samp>(ddf38)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ddf3823)
|
||||
|
||||
### 🏡 杂务
|
||||
|
||||
- **依赖**: 更新依赖 - 由 @soybeanjs [<samp>(060c0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/060c0a9)
|
||||
- **项目**: 更新 vscode 设置: vue 官方 - 由 @soybeanjs [<samp>(76649)</samp>](https://github.com/soybeanjs/soybean-admin/commit/76649e2)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/m-xlsea)
|
||||
|
||||
## [v1.1.4](https://github.com/honghuangdc/soybean-admin/compare/v1.1.3...v1.1.4) (2024-06-06)
|
||||
|
||||
### 🐞 错误修复
|
||||
|
||||
- **utils**: 修复了按esc键时modalLogout的错误 - 由 @sigma-plus 在 https://github.com/honghuangdc/soybean-admin/issues/470 中提出 [<samp>(bd69c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/bd69c00)
|
||||
|
||||
### 🛠 优化
|
||||
|
||||
- **projects**: 优化了RouteMeta的备注 - 由 @soybeanjs 提出 [<samp>(ffb48)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ffb48b1)
|
||||
|
||||
### 📖 文档
|
||||
|
||||
- **projects**:
|
||||
- 更新了CHANGELOG - 由 @soybeanjs 提出 [<samp>(756f8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/756f84a)
|
||||
- 更新了Node&pnpm版本 - 由 @Azir-11 在 https://github.com/honghuangdc/soybean-admin/issues/472 中提出 [<samp>(9b05d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9b05d73)
|
||||
|
||||
### 🏡 杂项
|
||||
|
||||
- **deps**:
|
||||
- 更新了依赖 - 由 @soybeanjs 提出 [<samp>(d0380)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d0380ce)
|
||||
- 更新了依赖 - 由 @soybeanjs 提出 [<samp>(1f464)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1f4647b)
|
||||
- **projects**:
|
||||
- 关闭了http代理 - 由 @soybeanjs 提出 [<samp>(d08a3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d08a381)
|
||||
- 更新了mock url - 由 @soybeanjs 提出 [<samp>(e6086)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e6086f0)
|
||||
- 更新了vscode设置 - 由 @soybeanjs 提出 [<samp>(910df)</samp>](https://github.com/honghuangdc/soybean-admin/commit/910dfca)
|
||||
|
||||
### ❤️ 贡献者
|
||||
|
||||
[](https://github.com/soybeanjs) [](https://github.com/Azir-11) [](https://github.com/sigma-plus)
|
||||
|
||||
## [v1.1.3](https://github.com/soybeanjs/soybean-admin/compare/v1.1.2...v1.1.3) (2024-06-02)
|
||||
|
||||
### 🐞 错误修复
|
||||
|
16
README.md
@@ -11,6 +11,9 @@
|
||||
[](https://github.com/soybeanjs/soybean-admin)
|
||||
[](https://gitee.com/honghuangdc/soybean-admin)
|
||||
|
||||
<a href="https://hellogithub.com/repository/1298f27d5fe54959a16cf9686516ddb3" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=1298f27d5fe54959a16cf9686516ddb3&claim_uid=IiDXWmP4TEntjbV" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> If you think `SoybeanAdmin` 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!
|
||||
|
||||
@@ -78,8 +81,8 @@
|
||||
Make sure your environment meets the following requirements:
|
||||
|
||||
- **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.
|
||||
- **NodeJS**: >=18.12.0, recommended 18.19.0 or higher.
|
||||
- **pnpm**: >= 8.7.0, recommended 8.14.0 or higher.
|
||||
|
||||
**Clone Project**
|
||||
|
||||
@@ -108,6 +111,7 @@ pnpm build
|
||||
|
||||
## Ecosystem
|
||||
|
||||
- [react-soybean-admin](https://github.com/mufeng889/react-soybean-admin): SoybeanAdmin based version of React.
|
||||
- [electron-mock-admin](https://github.com/lixin59/electron-mock-api): A Mock Api management system that helps front-end developers quickly implement interface mocks.
|
||||
- [T-Shell](https://github.com/TheBlindM/T-Shell): A terminal emulator and SSH client with configurable command prompts.
|
||||
- [pea](https://github.com/haitang1894/pea) : Adopting SpringBoot3.2 + JDK21, MyBatis-Plus, SpringSecurity security framework, etc., suitable for the simple permission system developed by [soybean-admin](https://gitee.com/honghuangdc/soybean-admin).
|
||||
@@ -152,20 +156,16 @@ Thanks the following people for their contributions. If you want to contribute t
|
||||
|
||||
<div>
|
||||
<p>QQ Group</p>
|
||||
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/qq-soybean-admin-2.jpg" style="width:200px" />
|
||||
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/qq-soybean-admin-3.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" />
|
||||
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/picgo/soybean-admin-wechat-0620.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
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
<img src="./public/favicon.svg" width="160" />
|
||||
<h1>SoybeanAdmin</h1>
|
||||
<span><a href="./README.zh_CN.md">English</a> | 中文</span>
|
||||
<span><a href="./README.md">English</a> | 中文</span>
|
||||
</div>
|
||||
|
||||
---
|
||||
@@ -11,6 +11,8 @@
|
||||
[](https://github.com/soybeanjs/soybean-admin)
|
||||
[](https://gitee.com/honghuangdc/soybean-admin)
|
||||
|
||||
<a href="https://hellogithub.com/repository/1298f27d5fe54959a16cf9686516ddb3" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=1298f27d5fe54959a16cf9686516ddb3&claim_uid=IiDXWmP4TEntjbV" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
|
||||
> [!NOTE]
|
||||
> 如果您觉得 `SoybeanAdmin`对您有所帮助,或者您喜欢我们的项目,请在 GitHub 上给我们一个 ⭐️。您的支持是我们持续改进和增加新功能的动力!感谢您的支持!
|
||||
|
||||
@@ -55,6 +57,36 @@
|
||||
- [地址](https://docs.soybeanjs.cn)
|
||||
- [旧版文档](https://legacy-docs.soybeanjs.cn)
|
||||
|
||||
|
||||
## 合作事项
|
||||
|
||||
我们非常感谢大家对 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 的支持!为了进一步回馈社区,并助力企业和开发者实现个性化需求,我们现提供多种合作服务,期待与您携手共赢。
|
||||
|
||||
##### 1、定制化管理后台开发
|
||||
|
||||
针对企业和开发者的特定业务需求,我们提供基于 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 的定制化管理后台开发服务。我们的团队具备丰富的行业经验,能够迅速理解并实现您的需求,打造高效、灵活且安全的定制化解决方案。
|
||||
|
||||
- **定制开发**:我们将根据您的具体需求,提供从需求分析、UI设计到功能实现的全方位服务,确保项目高效交付。
|
||||
- **功能扩展**:在 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 基础上,扩展您所需的特定功能模块,提升管理后台的功能和用户体验。
|
||||
|
||||
##### 2、企业外包服务
|
||||
|
||||
我们承接各类企业级外包项目,特别是在管理后台系统的开发、集成与运维方面。我们以精益求精的态度,确保项目的质量和进度,为您的业务提供强有力的技术支持。
|
||||
|
||||
- **项目开发**:无论是全新的项目,还是现有系统的优化与集成,我们都将为您量身打造高效可靠的解决方案。
|
||||
- **系统集成与维护**:我们也提供基于 [`SoybeanAdmin`](https://github.com/soybeanjs/soybean-admin) 的系统集成与长期维护服务,确保您的系统稳定、安全地运行。
|
||||
|
||||
##### 3、联系方式
|
||||
|
||||
如有合作意向或项目咨询,请通过以下方式与我们联系:
|
||||
|
||||
- **Email**: [soybeanjs@outlook.com](mailto:soybeanjs@outlook.com)
|
||||
- **GitHub Issues**: 欢迎通过 [GitHub Issues](https://github.com/soybeanjs/soybean-admin/issues/new) 联系我们,进行初步的合作洽谈。
|
||||
- **商务合作微信**: honghuangdc
|
||||
|
||||
期待与您开展深入合作,共同推动 SoybeanAdmin 项目及其在更多领域的成功应用!
|
||||
|
||||
|
||||
## 示例图片
|
||||
|
||||

|
||||
@@ -77,8 +109,8 @@
|
||||
确保你的环境满足以下要求:
|
||||
|
||||
- **git**: 你需要git来克隆和管理项目版本。
|
||||
- **NodeJS**: >=18.0.0,推荐 18.19.0 或更高。
|
||||
- **pnpm**: >= 8.0.0,推荐 8.14.0 或更高。
|
||||
- **NodeJS**: >=18.12.0,推荐 18.19.0 或更高。
|
||||
- **pnpm**: >= 8.7.0,推荐 8.14.0 或更高。
|
||||
|
||||
**克隆项目**
|
||||
|
||||
@@ -107,6 +139,7 @@ pnpm build
|
||||
|
||||
## 周边生态
|
||||
|
||||
- [react-soybean-admin](https://github.com/mufeng889/react-soybean-admin): 基于SoybeanAdmin的React版本.
|
||||
- [electron-mock-admin](https://github.com/lixin59/electron-mock-api): 一个 Mock Api 管理系统,帮助前端开发伙伴快速实现接口的 mock。
|
||||
- [T-Shell](https://github.com/TheBlindM/T-Shell): 是一个可配置命令提示的终端模拟器和 SSH 客户端。
|
||||
- [pea](https://github.com/haitang1894/pea) : 采用SpringBoot3.2 + JDK21、MyBatis-Plus、SpringSecurity安全框架等,适配 [soybean-admin](https://gitee.com/honghuangdc/soybean-admin) 开发的简单权限系统。
|
||||
@@ -153,20 +186,16 @@ pnpm build
|
||||
|
||||
<div>
|
||||
<p>QQ交流群</p>
|
||||
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/qq-soybean-admin-2.jpg" style="width:200px" />
|
||||
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/qq-soybean-admin-3.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" />
|
||||
<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/picgo/soybean-admin-wechat-0620.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 趋势
|
||||
|
||||
|
@@ -1 +1,2 @@
|
||||
export * from './proxy';
|
||||
export * from './time';
|
||||
|
@@ -5,10 +5,10 @@ import { createServiceConfig } from '../../src/utils/service';
|
||||
* Set http proxy
|
||||
*
|
||||
* @param env - The current env
|
||||
* @param isDev - Is development environment
|
||||
* @param enable - If enable http proxy
|
||||
*/
|
||||
export function createViteProxy(env: Env.ImportMeta, isDev: boolean) {
|
||||
const isEnableHttpProxy = isDev && env.VITE_HTTP_PROXY === 'Y';
|
||||
export function createViteProxy(env: Env.ImportMeta, enable: boolean) {
|
||||
const isEnableHttpProxy = enable && env.VITE_HTTP_PROXY === 'Y';
|
||||
|
||||
if (!isEnableHttpProxy) return undefined;
|
||||
|
||||
|
12
build/config/time.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import timezone from 'dayjs/plugin/timezone';
|
||||
|
||||
export function getBuildTime() {
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
||||
const buildTime = dayjs.tz(Date.now(), 'Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss');
|
||||
|
||||
return buildTime;
|
||||
}
|
13
build/plugins/html.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
export function setupHtmlPlugin(buildTime: string) {
|
||||
const plugin: Plugin = {
|
||||
name: 'html-plugin',
|
||||
apply: 'build',
|
||||
transformIndexHtml(html) {
|
||||
return html.replace('<head>', `<head>\n <meta name="buildTime" content="${buildTime}">`);
|
||||
}
|
||||
};
|
||||
|
||||
return plugin;
|
||||
}
|
@@ -6,20 +6,18 @@ import progress from 'vite-plugin-progress';
|
||||
import { setupElegantRouter } from './router';
|
||||
import { setupUnocss } from './unocss';
|
||||
import { setupUnplugin } from './unplugin';
|
||||
import { setupHtmlPlugin } from './html';
|
||||
|
||||
export function setupVitePlugins(viteEnv: Env.ImportMeta) {
|
||||
export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) {
|
||||
const plugins: PluginOption = [
|
||||
vue({
|
||||
script: {
|
||||
defineModel: true
|
||||
}
|
||||
}),
|
||||
vue(),
|
||||
vueJsx(),
|
||||
VueDevtools(),
|
||||
setupElegantRouter(),
|
||||
setupUnocss(viteEnv),
|
||||
...setupUnplugin(viteEnv),
|
||||
progress()
|
||||
progress(),
|
||||
setupHtmlPlugin(buildTime)
|
||||
];
|
||||
|
||||
return plugins;
|
||||
|
@@ -8,20 +8,6 @@ export function setupElegantRouter() {
|
||||
base: 'src/layouts/base-layout/index.vue',
|
||||
blank: 'src/layouts/blank-layout/index.vue'
|
||||
},
|
||||
customRoutes: {
|
||||
names: [
|
||||
'exception_403',
|
||||
'exception_404',
|
||||
'exception_500',
|
||||
'document_project',
|
||||
'document_project-link',
|
||||
'document_vue',
|
||||
'document_vite',
|
||||
'document_unocss',
|
||||
'document_naive',
|
||||
'document_antd'
|
||||
]
|
||||
},
|
||||
routePathTransformer(routeName, routePath) {
|
||||
const key = routeName as RouteKey;
|
||||
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import { defineConfig } from '@soybeanjs/eslint-config';
|
||||
|
||||
export default defineConfig(
|
||||
{ vue: true, unocss: true, ignores: ['src-tauri/target'] },
|
||||
{ vue: true, unocss: true },
|
||||
{
|
||||
rules: {
|
||||
'vue/multi-word-component-names': [
|
||||
'warn',
|
||||
{
|
||||
ignores: ['index', 'App', '[id]', '[url]']
|
||||
ignores: ['index', 'App', 'Register', '[id]', '[url]']
|
||||
}
|
||||
],
|
||||
'vue/component-name-in-template-casing': [
|
||||
|
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<title>%VITE_APP_TITLE%</title>
|
||||
</head>
|
||||
<body>
|
||||
|
78
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "soybean-admin",
|
||||
"type": "module",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
|
||||
"author": {
|
||||
"name": "Soybean",
|
||||
@@ -32,19 +32,17 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vite build --mode prod",
|
||||
"build:tauri": "pnpm tauri build",
|
||||
"build:test": "vite build --mode test",
|
||||
"cleanup": "sa cleanup",
|
||||
"commit": "sa git-commit",
|
||||
"commit:zh": "sa git-commit -l=zh-cn",
|
||||
"dev": "vite --mode test",
|
||||
"dev:prod": "vite --mode prod",
|
||||
"dev:tauri": "pnpm tauri dev",
|
||||
"gen-route": "sa gen-route",
|
||||
"lint": "eslint . --fix",
|
||||
"prepare": "simple-git-hooks",
|
||||
"preview": "vite preview",
|
||||
"release": "sa release",
|
||||
"tauri-icon": "pnpm tauri icon ./public/logo.png",
|
||||
"typecheck": "vue-tsc --noEmit --skipLibCheck",
|
||||
"update-pkg": "sa update-pkg"
|
||||
},
|
||||
@@ -56,53 +54,51 @@
|
||||
"@sa/hooks": "workspace:*",
|
||||
"@sa/materials": "workspace:*",
|
||||
"@sa/utils": "workspace:*",
|
||||
"@vueuse/core": "10.9.0",
|
||||
"@vueuse/core": "11.1.0",
|
||||
"clipboard": "2.0.11",
|
||||
"dayjs": "1.11.11",
|
||||
"echarts": "5.5.0",
|
||||
"lodash-es": "4.17.21",
|
||||
"naive-ui": "2.38.2",
|
||||
"dayjs": "1.11.13",
|
||||
"echarts": "5.5.1",
|
||||
"json5": "2.2.3",
|
||||
"naive-ui": "2.40.1",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "2.1.7",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"vue": "3.4.27",
|
||||
"vue-draggable-plus": "0.4.1",
|
||||
"vue-i18n": "9.13.1",
|
||||
"vue-router": "4.3.2"
|
||||
"pinia": "2.2.4",
|
||||
"tailwind-merge": "2.5.4",
|
||||
"vue": "3.5.12",
|
||||
"vue-draggable-plus": "0.5.4",
|
||||
"vue-i18n": "10.0.4",
|
||||
"vue-router": "4.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@elegant-router/vue": "0.3.7",
|
||||
"@iconify/json": "2.2.211",
|
||||
"@elegant-router/vue": "0.3.8",
|
||||
"@iconify/json": "2.2.263",
|
||||
"@sa/scripts": "workspace:*",
|
||||
"@sa/uno-preset": "workspace:*",
|
||||
"@soybeanjs/eslint-config": "1.3.5",
|
||||
"@tauri-apps/cli": "1.5.11",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/node": "20.12.12",
|
||||
"@soybeanjs/eslint-config": "1.4.2",
|
||||
"@types/node": "22.7.9",
|
||||
"@types/nprogress": "0.2.3",
|
||||
"@unocss/eslint-config": "0.60.2",
|
||||
"@unocss/preset-icons": "0.60.2",
|
||||
"@unocss/preset-uno": "0.60.2",
|
||||
"@unocss/transformer-directives": "0.60.2",
|
||||
"@unocss/transformer-variant-group": "0.60.2",
|
||||
"@unocss/vite": "0.60.2",
|
||||
"@vitejs/plugin-vue": "5.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "3.1.0",
|
||||
"eslint": "9.3.0",
|
||||
"eslint-plugin-vue": "9.26.0",
|
||||
"lint-staged": "15.2.2",
|
||||
"sass": "1.77.2",
|
||||
"@unocss/eslint-config": "0.63.6",
|
||||
"@unocss/preset-icons": "0.63.6",
|
||||
"@unocss/preset-uno": "0.63.6",
|
||||
"@unocss/transformer-directives": "0.63.6",
|
||||
"@unocss/transformer-variant-group": "0.63.6",
|
||||
"@unocss/vite": "0.63.6",
|
||||
"@vitejs/plugin-vue": "5.1.4",
|
||||
"@vitejs/plugin-vue-jsx": "4.0.1",
|
||||
"eslint": "9.13.0",
|
||||
"eslint-plugin-vue": "9.29.1",
|
||||
"lint-staged": "15.2.10",
|
||||
"sass": "1.80.4",
|
||||
"simple-git-hooks": "2.11.1",
|
||||
"tsx": "4.10.5",
|
||||
"typescript": "5.4.5",
|
||||
"unplugin-icons": "0.19.0",
|
||||
"unplugin-vue-components": "0.27.0",
|
||||
"vite": "5.2.11",
|
||||
"tsx": "4.19.1",
|
||||
"typescript": "5.6.3",
|
||||
"unplugin-icons": "0.19.3",
|
||||
"unplugin-vue-components": "0.27.4",
|
||||
"vite": "5.4.10",
|
||||
"vite-plugin-progress": "0.0.7",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-devtools": "7.2.0",
|
||||
"vue-eslint-parser": "9.4.2",
|
||||
"vue-tsc": "2.0.19"
|
||||
"vite-plugin-vue-devtools": "7.5.4",
|
||||
"vue-eslint-parser": "9.4.3",
|
||||
"vue-tsc": "2.1.6"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"commit-msg": "pnpm sa git-commit-verify",
|
||||
|
20
packages/alova/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@sa/alova",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./fetch": "./src/fetch.ts",
|
||||
"./client": "./src/client.ts",
|
||||
"./mock": "./src/mock.ts"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@alova/mock": "2.0.8",
|
||||
"@sa/utils": "workspace:*",
|
||||
"alova": "3.1.1"
|
||||
}
|
||||
}
|
1
packages/alova/src/client.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from 'alova/client';
|
2
packages/alova/src/constant.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/** the backend error code key */
|
||||
export const BACKEND_ERROR_CODE = 'BACKEND_ERROR';
|
2
packages/alova/src/fetch.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import adapterFetch from 'alova/fetch';
|
||||
export default adapterFetch;
|
77
packages/alova/src/index.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { createAlova } from 'alova';
|
||||
import type { AlovaDefaultCacheAdapter, AlovaGenerics, AlovaGlobalCacheAdapter, AlovaRequestAdapter } from 'alova';
|
||||
import VueHook from 'alova/vue';
|
||||
import type { VueHookType } from 'alova/vue';
|
||||
import adapterFetch from 'alova/fetch';
|
||||
import { createServerTokenAuthentication } from 'alova/client';
|
||||
import type { FetchRequestInit } from 'alova/fetch';
|
||||
import { BACKEND_ERROR_CODE } from './constant';
|
||||
import type { CustomAlovaConfig, RequestOptions } from './type';
|
||||
|
||||
export const createAlovaRequest = <
|
||||
RequestConfig = FetchRequestInit,
|
||||
ResponseType = Response,
|
||||
ResponseHeader = Headers,
|
||||
L1Cache extends AlovaGlobalCacheAdapter = AlovaDefaultCacheAdapter,
|
||||
L2Cache extends AlovaGlobalCacheAdapter = AlovaDefaultCacheAdapter
|
||||
>(
|
||||
customConfig: CustomAlovaConfig<
|
||||
AlovaGenerics<any, any, RequestConfig, ResponseType, ResponseHeader, L1Cache, L2Cache, any>
|
||||
>,
|
||||
options: RequestOptions<AlovaGenerics<any, any, RequestConfig, ResponseType, ResponseHeader, L1Cache, L2Cache, any>>
|
||||
) => {
|
||||
const { tokenRefresher } = options;
|
||||
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<
|
||||
VueHookType,
|
||||
AlovaRequestAdapter<RequestConfig, ResponseType, ResponseHeader>
|
||||
>({
|
||||
refreshTokenOnSuccess: {
|
||||
isExpired: (response, method) => tokenRefresher?.isExpired(response, method) || false,
|
||||
handler: async (response, method) => tokenRefresher?.handler(response, method)
|
||||
},
|
||||
refreshTokenOnError: {
|
||||
isExpired: (response, method) => tokenRefresher?.isExpired(response, method) || false,
|
||||
handler: async (response, method) => tokenRefresher?.handler(response, method)
|
||||
}
|
||||
});
|
||||
|
||||
const instance = createAlova({
|
||||
...customConfig,
|
||||
timeout: customConfig.timeout ?? 10 * 1000,
|
||||
requestAdapter: (customConfig.requestAdapter as any) ?? adapterFetch(),
|
||||
statesHook: VueHook,
|
||||
beforeRequest: onAuthRequired(options.onRequest as any),
|
||||
responded: onResponseRefreshToken({
|
||||
onSuccess: async (response, method) => {
|
||||
// check if http status is success
|
||||
let error: any = null;
|
||||
let transformedData: any = null;
|
||||
try {
|
||||
if (await options.isBackendSuccess(response)) {
|
||||
transformedData = await options.transformBackendResponse(response);
|
||||
} else {
|
||||
error = new Error('the backend request error');
|
||||
error.code = BACKEND_ERROR_CODE;
|
||||
}
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
await options.onError?.(error, response, method);
|
||||
throw error;
|
||||
}
|
||||
|
||||
return transformedData;
|
||||
},
|
||||
onComplete: options.onComplete,
|
||||
onError: (error, method) => options.onError?.(error, null, method)
|
||||
})
|
||||
});
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export { BACKEND_ERROR_CODE };
|
||||
export type * from './type';
|
||||
export type * from 'alova';
|
1
packages/alova/src/mock.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@alova/mock';
|
52
packages/alova/src/type.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { AlovaGenerics, AlovaOptions, AlovaRequestAdapter, Method, ResponseCompleteHandler } from 'alova';
|
||||
|
||||
export type CustomAlovaConfig<AG extends AlovaGenerics> = Omit<
|
||||
AlovaOptions<AG>,
|
||||
'statesHook' | 'beforeRequest' | 'responded' | 'requestAdapter'
|
||||
> & {
|
||||
/** request adapter. all request of alova will be sent by it. */
|
||||
requestAdapter?: AlovaRequestAdapter<AG['RequestConfig'], AG['Response'], AG['ResponseHeader']>;
|
||||
};
|
||||
|
||||
export interface RequestOptions<AG extends AlovaGenerics> {
|
||||
/**
|
||||
* The hook before request
|
||||
*
|
||||
* For example: You can add header token in this hook
|
||||
*
|
||||
* @param method alova Method Instance
|
||||
*/
|
||||
onRequest?: AlovaOptions<AG>['beforeRequest'];
|
||||
/**
|
||||
* The hook to check backend response is success or not
|
||||
*
|
||||
* @param response alova response
|
||||
*/
|
||||
isBackendSuccess: (response: AG['Response']) => Promise<boolean>;
|
||||
|
||||
/** The config to refresh token */
|
||||
tokenRefresher?: {
|
||||
/** detect the token is expired */
|
||||
isExpired(response: AG['Response'], Method: Method<AG>): Promise<boolean> | boolean;
|
||||
/** refresh token handler */
|
||||
handler(response: AG['Response'], Method: Method<AG>): Promise<void>;
|
||||
};
|
||||
|
||||
/** The hook after backend request complete */
|
||||
onComplete?: ResponseCompleteHandler<AG>;
|
||||
|
||||
/**
|
||||
* The hook to handle error
|
||||
*
|
||||
* For example: You can show error message in this hook
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
onError?: (error: any, response: AG['Response'] | null, methodInstance: Method<AG>) => any | Promise<any>;
|
||||
/**
|
||||
* transform backend response when the responseType is json
|
||||
*
|
||||
* @param response alova response
|
||||
*/
|
||||
transformBackendResponse: (response: AG['Response']) => any;
|
||||
}
|
20
packages/alova/tsconfig.json
Normal 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"]
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/axios",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
@@ -11,11 +11,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sa/utils": "workspace:*",
|
||||
"axios": "1.6.8",
|
||||
"axios-retry": "4.2.0",
|
||||
"qs": "6.12.1"
|
||||
"axios": "1.7.7",
|
||||
"axios-retry": "4.5.0",
|
||||
"qs": "6.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/qs": "6.9.15"
|
||||
"@types/qs": "6.9.16"
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import axios, { AxiosError } from 'axios';
|
||||
import type { AxiosResponse, CancelTokenSource, CreateAxiosDefaults, InternalAxiosRequestConfig } from 'axios';
|
||||
import type { AxiosResponse, CreateAxiosDefaults, InternalAxiosRequestConfig } from 'axios';
|
||||
import axiosRetry from 'axios-retry';
|
||||
import { nanoid } from '@sa/utils';
|
||||
import { createAxiosConfig, createDefaultOptions, createRetryOptions } from './options';
|
||||
@@ -22,7 +22,7 @@ function createCommonRequest<ResponseData = any>(
|
||||
const axiosConf = createAxiosConfig(axiosConfig);
|
||||
const instance = axios.create(axiosConf);
|
||||
|
||||
const cancelTokenSourceMap = new Map<string, CancelTokenSource>();
|
||||
const abortControllerMap = new Map<string, AbortController>();
|
||||
|
||||
// config axios retry
|
||||
const retryOptions = createRetryOptions(axiosConf);
|
||||
@@ -35,10 +35,12 @@ function createCommonRequest<ResponseData = any>(
|
||||
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);
|
||||
// config abort controller
|
||||
if (!config.signal) {
|
||||
const abortController = new AbortController();
|
||||
config.signal = abortController.signal;
|
||||
abortControllerMap.set(requestId, abortController);
|
||||
}
|
||||
|
||||
// handle config by hook
|
||||
const handledConfig = opts.onRequest?.(config) || config;
|
||||
@@ -79,18 +81,18 @@ function createCommonRequest<ResponseData = any>(
|
||||
);
|
||||
|
||||
function cancelRequest(requestId: string) {
|
||||
const cancelTokenSource = cancelTokenSourceMap.get(requestId);
|
||||
if (cancelTokenSource) {
|
||||
cancelTokenSource.cancel();
|
||||
cancelTokenSourceMap.delete(requestId);
|
||||
const abortController = abortControllerMap.get(requestId);
|
||||
if (abortController) {
|
||||
abortController.abort();
|
||||
abortControllerMap.delete(requestId);
|
||||
}
|
||||
}
|
||||
|
||||
function cancelAllRequest() {
|
||||
cancelTokenSourceMap.forEach(cancelTokenSource => {
|
||||
cancelTokenSource.cancel();
|
||||
abortControllerMap.forEach(abortController => {
|
||||
abortController.abort();
|
||||
});
|
||||
cancelTokenSourceMap.clear();
|
||||
abortControllerMap.clear();
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -160,12 +162,12 @@ export function createFlatRequest<ResponseData = any, State = Record<string, unk
|
||||
if (responseType === 'json') {
|
||||
const data = opts.transformBackendResponse(response);
|
||||
|
||||
return { data, error: null };
|
||||
return { data, error: null, response };
|
||||
}
|
||||
|
||||
return { data: response.data as MappedType<R, T>, error: null };
|
||||
} catch (error) {
|
||||
return { data: null, error };
|
||||
return { data: null, error, response: (error as AxiosError<ResponseData>).response };
|
||||
}
|
||||
} as FlatRequestInstance<State, ResponseData>;
|
||||
|
||||
|
@@ -20,7 +20,7 @@ export function createDefaultOptions<ResponseData = any>(options?: Partial<Reque
|
||||
|
||||
export function createRetryOptions(config?: Partial<CreateAxiosDefaults>) {
|
||||
const retryConfig: IAxiosRetryConfig = {
|
||||
retries: 3
|
||||
retries: 0
|
||||
};
|
||||
|
||||
Object.assign(retryConfig, config);
|
||||
|
@@ -69,7 +69,19 @@ export type CustomAxiosRequestConfig<R extends ResponseType = 'json'> = Omit<Axi
|
||||
};
|
||||
|
||||
export interface RequestInstanceCommon<T> {
|
||||
/**
|
||||
* cancel the request by request id
|
||||
*
|
||||
* if the request provide abort controller sign from config, it will not collect in the abort controller map
|
||||
*
|
||||
* @param requestId
|
||||
*/
|
||||
cancelRequest: (requestId: string) => void;
|
||||
/**
|
||||
* cancel all request
|
||||
*
|
||||
* if the request provide abort controller sign from config, it will not collect in the abort controller map
|
||||
*/
|
||||
cancelAllRequest: () => void;
|
||||
/** you can set custom state in the request instance */
|
||||
state: T;
|
||||
@@ -80,18 +92,20 @@ export interface RequestInstance<S = Record<string, unknown>> extends RequestIns
|
||||
<T = any, R extends ResponseType = 'json'>(config: CustomAxiosRequestConfig<R>): Promise<MappedType<R, T>>;
|
||||
}
|
||||
|
||||
export type FlatResponseSuccessData<T = any> = {
|
||||
export type FlatResponseSuccessData<T = any, ResponseData = any> = {
|
||||
data: T;
|
||||
error: null;
|
||||
response: AxiosResponse<ResponseData>;
|
||||
};
|
||||
|
||||
export type FlatResponseFailData<ResponseData = any> = {
|
||||
data: null;
|
||||
error: AxiosError<ResponseData>;
|
||||
response: AxiosResponse<ResponseData>;
|
||||
};
|
||||
|
||||
export type FlatResponseData<T = any, ResponseData = any> =
|
||||
| FlatResponseSuccessData<T>
|
||||
| FlatResponseSuccessData<T, ResponseData>
|
||||
| FlatResponseFailData<ResponseData>;
|
||||
|
||||
export interface FlatRequestInstance<S = Record<string, unknown>, ResponseData = any> extends RequestInstanceCommon<S> {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/color",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/hooks",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
@@ -10,6 +10,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@sa/axios": "workspace:*"
|
||||
"@sa/axios": "workspace:*",
|
||||
"@sa/utils": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { jsonClone } from '@sa/utils';
|
||||
import useBoolean from './use-boolean';
|
||||
import useLoading from './use-loading';
|
||||
|
||||
@@ -65,11 +66,11 @@ export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<
|
||||
|
||||
const { apiFn, apiParams, transformer, immediate = true, getColumnChecks, getColumns } = config;
|
||||
|
||||
const searchParams: NonNullable<Parameters<A>[0]> = reactive({ ...apiParams });
|
||||
const searchParams: NonNullable<Parameters<A>[0]> = reactive(jsonClone({ ...apiParams }));
|
||||
|
||||
const allColumns = ref(config.columns()) as Ref<C[]>;
|
||||
|
||||
const data: Ref<T[]> = ref([]);
|
||||
const data: Ref<TableDataWithIndex<T>[]> = ref([]);
|
||||
|
||||
const columnChecks: Ref<TableColumnCheck[]> = ref(getColumnChecks(config.columns()));
|
||||
|
||||
@@ -129,7 +130,7 @@ export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<
|
||||
|
||||
/** reset search params */
|
||||
function resetSearchParams() {
|
||||
Object.assign(searchParams, apiParams);
|
||||
Object.assign(searchParams, jsonClone(apiParams));
|
||||
}
|
||||
|
||||
if (immediate) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/materials",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sa/utils": "workspace:*",
|
||||
"simplebar-vue": "2.3.4"
|
||||
"simplebar-vue": "2.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typed-css-modules": "0.9.1"
|
||||
|
@@ -53,23 +53,10 @@ const bindProps = computed(() => {
|
||||
function handleClose() {
|
||||
emit('close');
|
||||
}
|
||||
|
||||
function handleMouseup(e: MouseEvent) {
|
||||
// close tab by mouse wheel button click
|
||||
if (e.button === 1) {
|
||||
handleClose();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="activeTabComponent.component"
|
||||
:class="activeTabComponent.class"
|
||||
:style="cssVars"
|
||||
v-bind="bindProps"
|
||||
@mouseup="handleMouseup"
|
||||
>
|
||||
<component :is="activeTabComponent.component" :class="activeTabComponent.class" :style="cssVars" v-bind="bindProps">
|
||||
<template #prefix>
|
||||
<slot name="prefix"></slot>
|
||||
</template>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/fetch",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
@@ -10,6 +10,6 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"ofetch": "1.3.4"
|
||||
"ofetch": "1.4.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/scripts",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"bin": {
|
||||
"sa": "./bin.ts"
|
||||
},
|
||||
@@ -13,15 +13,15 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@soybeanjs/changelog": "0.3.23",
|
||||
"bumpp": "9.4.1",
|
||||
"c12": "1.10.0",
|
||||
"@soybeanjs/changelog": "0.3.24",
|
||||
"bumpp": "9.7.1",
|
||||
"c12": "2.0.1",
|
||||
"cac": "6.7.14",
|
||||
"consola": "3.2.3",
|
||||
"enquirer": "2.4.1",
|
||||
"execa": "9.1.0",
|
||||
"execa": "9.4.1",
|
||||
"kolorist": "1.8.0",
|
||||
"npm-check-updates": "16.14.20",
|
||||
"rimraf": "5.0.7"
|
||||
"npm-check-updates": "17.1.4",
|
||||
"rimraf": "6.0.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import path from 'node:path';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { prompt } from 'enquirer';
|
||||
import { bgRed, green, red, yellow } from 'kolorist';
|
||||
import { execCommand } from '../shared';
|
||||
import type { CliOption } from '../types';
|
||||
import { locales } from '../locales';
|
||||
import type { Lang } from '../locales';
|
||||
|
||||
interface PromptObject {
|
||||
types: string;
|
||||
@@ -14,13 +14,11 @@ interface PromptObject {
|
||||
/**
|
||||
* Git commit with Conventional Commits standard
|
||||
*
|
||||
* @param gitCommitTypes
|
||||
* @param gitCommitScopes
|
||||
* @param lang
|
||||
*/
|
||||
export async function gitCommit(
|
||||
gitCommitTypes: CliOption['gitCommitTypes'],
|
||||
gitCommitScopes: CliOption['gitCommitScopes']
|
||||
) {
|
||||
export async function gitCommit(lang: Lang = 'en-us') {
|
||||
const { gitCommitMessages, gitCommitTypes, gitCommitScopes } = locales[lang];
|
||||
|
||||
const typesChoices = gitCommitTypes.map(([value, msg]) => {
|
||||
const nameWithSuffix = `${value}:`;
|
||||
|
||||
@@ -41,19 +39,19 @@ export async function gitCommit(
|
||||
{
|
||||
name: 'types',
|
||||
type: 'select',
|
||||
message: 'Please select a type',
|
||||
message: gitCommitMessages.types,
|
||||
choices: typesChoices
|
||||
},
|
||||
{
|
||||
name: 'scopes',
|
||||
type: 'select',
|
||||
message: 'Please select a scope',
|
||||
message: gitCommitMessages.scopes,
|
||||
choices: scopesChoices
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
message: `Please enter a description (add prefix ${yellow('!')} to indicate breaking change)`
|
||||
message: gitCommitMessages.description
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -67,20 +65,20 @@ export async function gitCommit(
|
||||
}
|
||||
|
||||
/** Git commit message verify */
|
||||
export async function gitCommitVerify() {
|
||||
export async function gitCommitVerify(lang: Lang = 'en-us', ignores: RegExp[] = []) {
|
||||
const gitPath = await execCommand('git', ['rev-parse', '--show-toplevel']);
|
||||
|
||||
const gitMsgPath = path.join(gitPath, '.git', 'COMMIT_EDITMSG');
|
||||
|
||||
const commitMsg = readFileSync(gitMsgPath, 'utf8').trim();
|
||||
|
||||
if (ignores.some(regExp => regExp.test(commitMsg))) return;
|
||||
|
||||
const REG_EXP = /(?<type>[a-z]+)(?:\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i;
|
||||
|
||||
if (!REG_EXP.test(commitMsg)) {
|
||||
throw new Error(
|
||||
`${bgRed(' ERROR ')} ${red('git commit message must match the Conventional Commits standard!')}\n\n${green(
|
||||
'Recommended to use the command `pnpm commit` to generate Conventional Commits compliant commit information.\nGet more info about Conventional Commits, follow this link: https://conventionalcommits.org'
|
||||
)}`
|
||||
);
|
||||
const errorMsg = locales[lang].gitCommitVerify;
|
||||
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
}
|
||||
|
@@ -12,34 +12,18 @@ const defaultOptions: CliOption = {
|
||||
'**/node_modules',
|
||||
'!node_modules/**'
|
||||
],
|
||||
gitCommitTypes: [
|
||||
['feat', 'A new feature'],
|
||||
['fix', 'A bug fix'],
|
||||
['docs', 'Documentation only changes'],
|
||||
['style', 'Changes that do not affect the meaning of the code'],
|
||||
['refactor', 'A code change that neither fixes a bug nor adds a feature'],
|
||||
['perf', 'A code change that improves performance'],
|
||||
['optimize', 'A code change that optimizes code quality'],
|
||||
['test', 'Adding missing tests or correcting existing tests'],
|
||||
['build', 'Changes that affect the build system or external dependencies'],
|
||||
['ci', 'Changes to our CI configuration files and scripts'],
|
||||
['chore', "Other changes that don't modify src or test files"],
|
||||
['revert', 'Reverts a previous commit']
|
||||
],
|
||||
gitCommitScopes: [
|
||||
['projects', 'project'],
|
||||
['packages', 'packages'],
|
||||
['components', 'components'],
|
||||
['hooks', 'hook functions'],
|
||||
['utils', 'utils functions'],
|
||||
['types', 'TS declaration'],
|
||||
['styles', 'style'],
|
||||
['deps', 'project dependencies'],
|
||||
['release', 'release project'],
|
||||
['other', 'other changes']
|
||||
],
|
||||
ncuCommandArgs: ['--deep', '-u'],
|
||||
changelogOptions: {}
|
||||
changelogOptions: {},
|
||||
gitCommitVerifyIgnores: [
|
||||
/^((Merge pull request)|(Merge (.*?) into (.*?)|(Merge branch (.*?)))(?:\r?\n)*$)/m,
|
||||
/^(Merge tag (.*?))(?:\r?\n)*$/m,
|
||||
/^(R|r)evert (.*)/,
|
||||
/^(amend|fixup|squash)!/,
|
||||
/^(Merged (.*?)(in|into) (.*)|Merged PR (.*): (.*))/,
|
||||
/^Merge remote-tracking branch(\s*)(.*)/,
|
||||
/^Automatic merge(.*)/,
|
||||
/^Auto-merged (.*?) into (.*)/
|
||||
]
|
||||
};
|
||||
|
||||
export async function loadCliOptions(overrides?: Partial<CliOption>, cwd = process.cwd()) {
|
||||
|
@@ -3,6 +3,7 @@ import { blue, lightGreen } from 'kolorist';
|
||||
import { version } from '../package.json';
|
||||
import { cleanup, genChangelog, generateRoute, gitCommit, gitCommitVerify, release, updatePkg } from './commands';
|
||||
import { loadCliOptions } from './config';
|
||||
import type { Lang } from './locales';
|
||||
|
||||
type Command = 'cleanup' | 'update-pkg' | 'git-commit' | 'git-commit-verify' | 'changelog' | 'release' | 'gen-route';
|
||||
|
||||
@@ -18,13 +19,19 @@ interface CommandArg {
|
||||
/** Generate changelog by total tags */
|
||||
total?: boolean;
|
||||
/**
|
||||
* The glob pattern of dirs to cleanup
|
||||
* The glob pattern of dirs to clean up
|
||||
*
|
||||
* If not set, it will use the default value
|
||||
*
|
||||
* Multiple values use "," to separate them
|
||||
*/
|
||||
cleanupDir?: string;
|
||||
/**
|
||||
* display lang of cli
|
||||
*
|
||||
* @default 'en-us'
|
||||
*/
|
||||
lang?: Lang;
|
||||
}
|
||||
|
||||
export async function setupCli() {
|
||||
@@ -44,6 +51,7 @@ export async function setupCli() {
|
||||
'-c, --cleanupDir <dir>',
|
||||
'The glob pattern of dirs to cleanup, If not set, it will use the default value, Multiple values use "," to separate them'
|
||||
)
|
||||
.option('-l, --lang <lang>', 'display lang of cli', { default: 'en-us', type: [String] })
|
||||
.help();
|
||||
|
||||
const commands: CommandWithAction<CommandArg> = {
|
||||
@@ -61,14 +69,14 @@ export async function setupCli() {
|
||||
},
|
||||
'git-commit': {
|
||||
desc: 'git commit, generate commit message which match Conventional Commits standard',
|
||||
action: async () => {
|
||||
await gitCommit(cliOptions.gitCommitTypes, cliOptions.gitCommitScopes);
|
||||
action: async args => {
|
||||
await gitCommit(args?.lang);
|
||||
}
|
||||
},
|
||||
'git-commit-verify': {
|
||||
desc: 'verify git commit message, make sure it match Conventional Commits standard',
|
||||
action: async () => {
|
||||
await gitCommitVerify();
|
||||
action: async args => {
|
||||
await gitCommitVerify(args?.lang, cliOptions.gitCommitVerifyIgnores);
|
||||
}
|
||||
},
|
||||
changelog: {
|
||||
|
82
packages/scripts/src/locales/index.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { bgRed, green, red, yellow } from 'kolorist';
|
||||
|
||||
export type Lang = 'zh-cn' | 'en-us';
|
||||
|
||||
export const locales = {
|
||||
'zh-cn': {
|
||||
gitCommitMessages: {
|
||||
types: '请选择提交类型',
|
||||
scopes: '请选择提交范围',
|
||||
description: `请输入描述信息(${yellow('!')}开头表示破坏性改动`
|
||||
},
|
||||
gitCommitTypes: [
|
||||
['feat', '新功能'],
|
||||
['feat-wip', '开发中的功能,比如某功能的部分代码'],
|
||||
['fix', '修复Bug'],
|
||||
['docs', '只涉及文档更新'],
|
||||
['typo', '代码或文档勘误,比如错误拼写'],
|
||||
['style', '修改代码风格,不影响代码含义的变更'],
|
||||
['refactor', '代码重构,既不修复 bug 也不添加功能的代码变更'],
|
||||
['perf', '可提高性能的代码更改'],
|
||||
['optimize', '优化代码质量的代码更改'],
|
||||
['test', '添加缺失的测试或更正现有测试'],
|
||||
['build', '影响构建系统或外部依赖项的更改'],
|
||||
['ci', '对 CI 配置文件和脚本的更改'],
|
||||
['chore', '没有修改src或测试文件的其他变更'],
|
||||
['revert', '还原先前的提交']
|
||||
] as [string, string][],
|
||||
gitCommitScopes: [
|
||||
['projects', '项目'],
|
||||
['packages', '包'],
|
||||
['components', '组件'],
|
||||
['hooks', '钩子函数'],
|
||||
['utils', '工具函数'],
|
||||
['types', 'TS类型声明'],
|
||||
['styles', '代码风格'],
|
||||
['deps', '项目依赖'],
|
||||
['release', '发布项目新版本'],
|
||||
['other', '其他的变更']
|
||||
] as [string, string][],
|
||||
gitCommitVerify: `${bgRed(' 错误 ')} ${red('git 提交信息必须符合 Conventional Commits 标准!')}\n\n${green(
|
||||
'推荐使用命令 `pnpm commit` 生成符合 Conventional Commits 标准的提交信息。\n获取有关 Conventional Commits 的更多信息,请访问此链接: https://conventionalcommits.org'
|
||||
)}`
|
||||
},
|
||||
'en-us': {
|
||||
gitCommitMessages: {
|
||||
types: 'Please select a type',
|
||||
scopes: 'Please select a scope',
|
||||
description: `Please enter a description (add prefix ${yellow('!')} to indicate breaking change)`
|
||||
},
|
||||
gitCommitTypes: [
|
||||
['feat', 'A new feature'],
|
||||
['feat-wip', 'Features in development, such as partial code for a certain feature'],
|
||||
['fix', 'A bug fix'],
|
||||
['docs', 'Documentation only changes'],
|
||||
['typo', 'Code or document corrections, such as spelling errors'],
|
||||
['style', 'Changes that do not affect the meaning of the code'],
|
||||
['refactor', 'A code change that neither fixes a bug nor adds a feature'],
|
||||
['perf', 'A code change that improves performance'],
|
||||
['optimize', 'A code change that optimizes code quality'],
|
||||
['test', 'Adding missing tests or correcting existing tests'],
|
||||
['build', 'Changes that affect the build system or external dependencies'],
|
||||
['ci', 'Changes to our CI configuration files and scripts'],
|
||||
['chore', "Other changes that don't modify src or test files"],
|
||||
['revert', 'Reverts a previous commit']
|
||||
] as [string, string][],
|
||||
gitCommitScopes: [
|
||||
['projects', 'project'],
|
||||
['packages', 'packages'],
|
||||
['components', 'components'],
|
||||
['hooks', 'hook functions'],
|
||||
['utils', 'utils functions'],
|
||||
['types', 'TS declaration'],
|
||||
['styles', 'style'],
|
||||
['deps', 'project dependencies'],
|
||||
['release', 'release project'],
|
||||
['other', 'other changes']
|
||||
] as [string, string][],
|
||||
gitCommitVerify: `${bgRed(' ERROR ')} ${red('git commit message must match the Conventional Commits standard!')}\n\n${green(
|
||||
'Recommended to use the command `pnpm commit` to generate Conventional Commits compliant commit information.\nGet more info about Conventional Commits, follow this link: https://conventionalcommits.org'
|
||||
)}`
|
||||
}
|
||||
} satisfies Record<Lang, Record<string, unknown>>;
|
@@ -14,10 +14,6 @@ export interface CliOption {
|
||||
* ```
|
||||
*/
|
||||
cleanupDirs: string[];
|
||||
/** Git commit types */
|
||||
gitCommitTypes: [string, string][];
|
||||
/** Git commit scopes */
|
||||
gitCommitScopes: [string, string][];
|
||||
/**
|
||||
* Npm-check-updates command args
|
||||
*
|
||||
@@ -30,4 +26,6 @@ export interface CliOption {
|
||||
* @link https://github.com/soybeanjs/changelog
|
||||
*/
|
||||
changelogOptions: Partial<ChangelogOption>;
|
||||
/** The ignore pattern list of git commit verify */
|
||||
gitCommitVerifyIgnores: RegExp[];
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/uno-preset",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/utils",
|
||||
"version": "1.1.3",
|
||||
"version": "1.3.8",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"colord": "2.9.3",
|
||||
"crypto-js": "4.2.0",
|
||||
"klona": "2.0.6",
|
||||
"localforage": "1.10.0",
|
||||
"nanoid": "5.0.7"
|
||||
},
|
||||
|
@@ -1,3 +1,4 @@
|
||||
export * from './crypto';
|
||||
export * from './storage';
|
||||
export * from './nanoid';
|
||||
export * from './klona';
|
||||
|
3
packages/utils/src/klona.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { klona as jsonClone } from 'klona/json';
|
||||
|
||||
export { jsonClone };
|
5918
pnpm-lock.yaml
generated
BIN
public/logo.png
Before Width: | Height: | Size: 20 KiB |
3
src-tauri/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
3664
src-tauri/Cargo.lock
generated
@@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
license = ""
|
||||
repository = ""
|
||||
default-run = "app"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.5.1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.6.1", features = [] }
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
|
||||
# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
|
||||
# DO NOT REMOVE!!
|
||||
custom-protocol = [ "tauri/custom-protocol" ]
|
@@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
Before Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 39 KiB |
@@ -1,8 +0,0 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"build": {
|
||||
"beforeBuildCommand": "npm run build",
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"devPath": "http://localhost:9527",
|
||||
"distDir": "../dist"
|
||||
},
|
||||
"package": {
|
||||
"productName": "soybean-admin",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": false
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"category": "DeveloperTool",
|
||||
"copyright": "",
|
||||
"deb": {
|
||||
"depends": []
|
||||
},
|
||||
"externalBin": [],
|
||||
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
|
||||
"identifier": "cn.soybeanjs.admin",
|
||||
"longDescription": "",
|
||||
"macOS": {
|
||||
"entitlements": null,
|
||||
"exceptionDomain": "",
|
||||
"frameworks": [],
|
||||
"providerShortName": null,
|
||||
"signingIdentity": null
|
||||
},
|
||||
"resources": [],
|
||||
"shortDescription": "",
|
||||
"targets": "all",
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"csp": null
|
||||
},
|
||||
"updater": {
|
||||
"active": false
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"fullscreen": false,
|
||||
"height": 768,
|
||||
"resizable": true,
|
||||
"title": "SoybeanAdmin",
|
||||
"width": 1366
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
18
src/App.vue
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { NConfigProvider, darkTheme } from 'naive-ui';
|
||||
import type { WatermarkProps } from 'naive-ui';
|
||||
import { useAppStore } from './store/modules/app';
|
||||
import { useThemeStore } from './store/modules/theme';
|
||||
import { naiveDateLocales, naiveLocales } from './locales/naive';
|
||||
@@ -21,6 +22,22 @@ const naiveLocale = computed(() => {
|
||||
const naiveDateLocale = computed(() => {
|
||||
return naiveDateLocales[appStore.locale];
|
||||
});
|
||||
|
||||
const watermarkProps = computed<WatermarkProps>(() => {
|
||||
return {
|
||||
content: themeStore.watermark?.text || 'SoybeanAdmin',
|
||||
cross: true,
|
||||
fullscreen: true,
|
||||
fontSize: 16,
|
||||
lineHeight: 16,
|
||||
width: 384,
|
||||
height: 384,
|
||||
xOffset: 12,
|
||||
yOffset: 60,
|
||||
rotate: -15,
|
||||
zIndex: 9999
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -33,6 +50,7 @@ const naiveDateLocale = computed(() => {
|
||||
>
|
||||
<AppProvider>
|
||||
<RouterView class="bg-layout" />
|
||||
<NWatermark v-if="themeStore.watermark?.visible" v-bind="watermarkProps" />
|
||||
</AppProvider>
|
||||
</NConfigProvider>
|
||||
</template>
|
||||
|
@@ -9,7 +9,7 @@ defineProps<Props>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-container text-base_text transition-300" :class="{ 'bg-inverted text-#1f1f1f': inverted }">
|
||||
<div class="bg-container text-base-text transition-300" :class="{ 'bg-inverted text-#1f1f1f': inverted }">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -41,6 +41,7 @@ const icon = computed(() => {
|
||||
|
||||
<template>
|
||||
<ButtonIcon
|
||||
:key="String(collapsed)"
|
||||
:tooltip-content="collapsed ? $t('icon.expand') : $t('icon.collapse')"
|
||||
tooltip-placement="bottom-start"
|
||||
:z-index="zIndex"
|
||||
|
@@ -1,5 +1,9 @@
|
||||
import { transformRecordToOption } from '@/utils/common';
|
||||
|
||||
export const GLOBAL_HEADER_MENU_ID = '__GLOBAL_HEADER_MENU__';
|
||||
|
||||
export const GLOBAL_SIDER_MENU_ID = '__GLOBAL_SIDER_MENU__';
|
||||
|
||||
export const themeSchemaRecord: Record<UnionKey.ThemeScheme, App.I18n.I18nKey> = {
|
||||
light: 'theme.themeSchema.light',
|
||||
dark: 'theme.themeSchema.dark',
|
||||
@@ -50,3 +54,10 @@ export const themePageAnimationModeRecord: Record<UnionKey.ThemePageAnimateMode,
|
||||
};
|
||||
|
||||
export const themePageAnimationModeOptions = transformRecordToOption(themePageAnimationModeRecord);
|
||||
|
||||
export const resetCacheStrategyRecord: Record<UnionKey.ResetCacheStrategy, App.I18n.I18nKey> = {
|
||||
close: 'theme.resetCacheStrategy.close',
|
||||
refresh: 'theme.resetCacheStrategy.refresh'
|
||||
};
|
||||
|
||||
export const resetCacheStrategyOptions = transformRecordToOption(resetCacheStrategyRecord);
|
||||
|
@@ -1,29 +0,0 @@
|
||||
import { transformRecordToOption } from '@/utils/common';
|
||||
|
||||
export const enableStatusRecord: Record<Api.Common.EnableStatus, App.I18n.I18nKey> = {
|
||||
'1': 'page.manage.common.status.enable',
|
||||
'2': 'page.manage.common.status.disable'
|
||||
};
|
||||
|
||||
export const enableStatusOptions = transformRecordToOption(enableStatusRecord);
|
||||
|
||||
export const userGenderRecord: Record<Api.SystemManage.UserGender, App.I18n.I18nKey> = {
|
||||
'1': 'page.manage.user.gender.male',
|
||||
'2': 'page.manage.user.gender.female'
|
||||
};
|
||||
|
||||
export const userGenderOptions = transformRecordToOption(userGenderRecord);
|
||||
|
||||
export const menuTypeRecord: Record<Api.SystemManage.MenuType, App.I18n.I18nKey> = {
|
||||
'1': 'page.manage.menu.type.directory',
|
||||
'2': 'page.manage.menu.type.menu'
|
||||
};
|
||||
|
||||
export const menuTypeOptions = transformRecordToOption(menuTypeRecord);
|
||||
|
||||
export const menuIconTypeRecord: Record<Api.SystemManage.IconType, App.I18n.I18nKey> = {
|
||||
'1': 'page.manage.menu.iconType.iconify',
|
||||
'2': 'page.manage.menu.iconType.local'
|
||||
};
|
||||
|
||||
export const menuIconTypeOptions = transformRecordToOption(menuIconTypeRecord);
|
@@ -30,17 +30,30 @@ export function useRouterPush(inSetup = true) {
|
||||
name: key
|
||||
};
|
||||
|
||||
if (query) {
|
||||
if (Object.keys(query || {}).length) {
|
||||
routeLocation.query = query;
|
||||
}
|
||||
|
||||
if (params) {
|
||||
if (Object.keys(params || {}).length) {
|
||||
routeLocation.params = params;
|
||||
}
|
||||
|
||||
return routerPush(routeLocation);
|
||||
}
|
||||
|
||||
function routerPushByKeyWithMetaQuery(key: RouteKey) {
|
||||
const allRoutes = router.getRoutes();
|
||||
const meta = allRoutes.find(item => item.name === key)?.meta || null;
|
||||
|
||||
const query: Record<string, string> = {};
|
||||
|
||||
meta?.query?.forEach(item => {
|
||||
query[item.key] = item.value;
|
||||
});
|
||||
|
||||
return routerPushByKey(key, { query });
|
||||
}
|
||||
|
||||
async function toHome() {
|
||||
return routerPushByKey('root');
|
||||
}
|
||||
@@ -80,11 +93,15 @@ export function useRouterPush(inSetup = true) {
|
||||
return routerPushByKey('login', { query, params: { module } });
|
||||
}
|
||||
|
||||
/** Redirect from login */
|
||||
async function redirectFromLogin() {
|
||||
/**
|
||||
* Redirect from login
|
||||
*
|
||||
* @param [needRedirect=true] Whether to redirect after login. Default is `true`
|
||||
*/
|
||||
async function redirectFromLogin(needRedirect = true) {
|
||||
const redirect = route.value.query?.redirect as string;
|
||||
|
||||
if (redirect) {
|
||||
if (needRedirect && redirect) {
|
||||
routerPush(redirect);
|
||||
} else {
|
||||
toHome();
|
||||
@@ -95,6 +112,7 @@ export function useRouterPush(inSetup = true) {
|
||||
routerPush,
|
||||
routerBack,
|
||||
routerPushByKey,
|
||||
routerPushByKeyWithMetaQuery,
|
||||
toLogin,
|
||||
toggleLoginModule,
|
||||
redirectFromLogin
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { computed, effectScope, onScopeDispose, reactive, ref, watch } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import type { PaginationProps } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { jsonClone } from '@sa/utils';
|
||||
import { useBoolean, useHookTable } from '@sa/hooks';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { $t } from '@/locales';
|
||||
@@ -40,17 +40,20 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
|
||||
transformer: res => {
|
||||
const { records = [], current = 1, size = 10, total = 0 } = res.data || {};
|
||||
|
||||
// Ensure that the size is greater than 0, If it is less than 0, it will cause paging calculation errors.
|
||||
const pageSize = size <= 0 ? 10 : size;
|
||||
|
||||
const recordsWithIndex = records.map((item, index) => {
|
||||
return {
|
||||
...item,
|
||||
index: (current - 1) * size + index + 1
|
||||
index: (current - 1) * pageSize + index + 1
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
data: recordsWithIndex,
|
||||
pageNum: current,
|
||||
pageSize: size,
|
||||
pageSize,
|
||||
total
|
||||
};
|
||||
},
|
||||
@@ -160,6 +163,24 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
|
||||
Object.assign(pagination, update);
|
||||
}
|
||||
|
||||
/**
|
||||
* get data by page number
|
||||
*
|
||||
* @param pageNum the page number. default is 1
|
||||
*/
|
||||
async function getDataByPage(pageNum: number = 1) {
|
||||
updatePagination({
|
||||
page: pageNum
|
||||
});
|
||||
|
||||
updateSearchParams({
|
||||
current: pageNum,
|
||||
size: pagination.pageSize!
|
||||
});
|
||||
|
||||
await getData();
|
||||
}
|
||||
|
||||
scope.run(() => {
|
||||
watch(
|
||||
() => appStore.locale,
|
||||
@@ -184,6 +205,7 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
|
||||
mobilePagination,
|
||||
updatePagination,
|
||||
getData,
|
||||
getDataByPage,
|
||||
searchParams,
|
||||
updateSearchParams,
|
||||
resetSearchParams
|
||||
@@ -206,7 +228,7 @@ export function useTableOperate<T extends TableData = TableData>(data: Ref<T[]>,
|
||||
function handleEdit(id: T['id']) {
|
||||
operateType.value = 'edit';
|
||||
const findItem = data.value.find(item => item.id === id) || null;
|
||||
editingData.value = cloneDeep(findItem);
|
||||
editingData.value = jsonClone(findItem);
|
||||
|
||||
openDrawer();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { computed, defineAsyncComponent } from 'vue';
|
||||
import { AdminLayout, LAYOUT_SCROLL_EL_ID } from '@sa/materials';
|
||||
import type { LayoutMode } from '@sa/materials';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
@@ -18,7 +18,9 @@ defineOptions({
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const { menus } = setupMixMenuContext();
|
||||
const { childLevelMenus, isActiveFirstLevelMenuHasChildren } = setupMixMenuContext();
|
||||
|
||||
const GlobalMenu = defineAsyncComponent(() => import('../modules/global-menu/index.vue'));
|
||||
|
||||
const layoutMode = computed(() => {
|
||||
const vertical: LayoutMode = 'vertical';
|
||||
@@ -26,30 +28,34 @@ const layoutMode = computed(() => {
|
||||
return themeStore.layout.mode.includes(vertical) ? vertical : horizontal;
|
||||
});
|
||||
|
||||
const headerPropsConfig: Record<UnionKey.ThemeLayoutMode, App.Global.HeaderProps> = {
|
||||
vertical: {
|
||||
showLogo: false,
|
||||
showMenu: false,
|
||||
showMenuToggler: true
|
||||
},
|
||||
'vertical-mix': {
|
||||
showLogo: false,
|
||||
showMenu: false,
|
||||
showMenuToggler: false
|
||||
},
|
||||
horizontal: {
|
||||
showLogo: true,
|
||||
showMenu: true,
|
||||
showMenuToggler: false
|
||||
},
|
||||
'horizontal-mix': {
|
||||
showLogo: true,
|
||||
showMenu: true,
|
||||
showMenuToggler: false
|
||||
}
|
||||
};
|
||||
const headerProps = computed(() => {
|
||||
const { mode, reverseHorizontalMix } = themeStore.layout;
|
||||
|
||||
const headerProps = computed(() => headerPropsConfig[themeStore.layout.mode]);
|
||||
const headerPropsConfig: Record<UnionKey.ThemeLayoutMode, App.Global.HeaderProps> = {
|
||||
vertical: {
|
||||
showLogo: false,
|
||||
showMenu: false,
|
||||
showMenuToggler: true
|
||||
},
|
||||
'vertical-mix': {
|
||||
showLogo: false,
|
||||
showMenu: false,
|
||||
showMenuToggler: false
|
||||
},
|
||||
horizontal: {
|
||||
showLogo: true,
|
||||
showMenu: true,
|
||||
showMenuToggler: false
|
||||
},
|
||||
'horizontal-mix': {
|
||||
showLogo: true,
|
||||
showMenu: true,
|
||||
showMenuToggler: reverseHorizontalMix && isActiveFirstLevelMenuHasChildren.value
|
||||
}
|
||||
};
|
||||
|
||||
return headerPropsConfig[mode];
|
||||
});
|
||||
|
||||
const siderVisible = computed(() => themeStore.layout.mode !== 'horizontal');
|
||||
|
||||
@@ -62,11 +68,16 @@ const siderWidth = computed(() => getSiderWidth());
|
||||
const siderCollapsedWidth = computed(() => getSiderCollapsedWidth());
|
||||
|
||||
function getSiderWidth() {
|
||||
const { reverseHorizontalMix } = themeStore.layout;
|
||||
const { width, mixWidth, mixChildMenuWidth } = themeStore.sider;
|
||||
|
||||
if (isHorizontalMix.value && reverseHorizontalMix) {
|
||||
return isActiveFirstLevelMenuHasChildren.value ? width : 0;
|
||||
}
|
||||
|
||||
let w = isVerticalMix.value || isHorizontalMix.value ? mixWidth : width;
|
||||
|
||||
if (isVerticalMix.value && appStore.mixSiderFixed && menus.value.length) {
|
||||
if (isVerticalMix.value && appStore.mixSiderFixed && childLevelMenus.value.length) {
|
||||
w += mixChildMenuWidth;
|
||||
}
|
||||
|
||||
@@ -74,11 +85,16 @@ function getSiderWidth() {
|
||||
}
|
||||
|
||||
function getSiderCollapsedWidth() {
|
||||
const { reverseHorizontalMix } = themeStore.layout;
|
||||
const { collapsedWidth, mixCollapsedWidth, mixChildMenuWidth } = themeStore.sider;
|
||||
|
||||
if (isHorizontalMix.value && reverseHorizontalMix) {
|
||||
return isActiveFirstLevelMenuHasChildren.value ? collapsedWidth : 0;
|
||||
}
|
||||
|
||||
let w = isVerticalMix.value || isHorizontalMix.value ? mixCollapsedWidth : collapsedWidth;
|
||||
|
||||
if (isVerticalMix.value && appStore.mixSiderFixed && menus.value.length) {
|
||||
if (isVerticalMix.value && appStore.mixSiderFixed && childLevelMenus.value.length) {
|
||||
w += mixChildMenuWidth;
|
||||
}
|
||||
|
||||
@@ -116,6 +132,7 @@ function getSiderCollapsedWidth() {
|
||||
<template #sider>
|
||||
<GlobalSider />
|
||||
</template>
|
||||
<GlobalMenu />
|
||||
<GlobalContent />
|
||||
<ThemeDrawer />
|
||||
<template #footer>
|
||||
|
@@ -8,6 +8,7 @@ export const { setupStore: setupMixMenuContext, useStore: useMixMenuContext } =
|
||||
function useMixMenu() {
|
||||
const route = useRoute();
|
||||
const routeStore = useRouteStore();
|
||||
const { selectedKey } = useMenu();
|
||||
|
||||
const activeFirstLevelMenuKey = ref('');
|
||||
|
||||
@@ -16,20 +17,35 @@ function useMixMenu() {
|
||||
}
|
||||
|
||||
function getActiveFirstLevelMenuKey() {
|
||||
const { hideInMenu, activeMenu } = route.meta;
|
||||
const name = route.name as string;
|
||||
|
||||
const routeName = (hideInMenu ? activeMenu : name) || name;
|
||||
|
||||
const [firstLevelRouteName] = routeName.split('_');
|
||||
const [firstLevelRouteName] = selectedKey.value.split('_');
|
||||
|
||||
setActiveFirstLevelMenuKey(firstLevelRouteName);
|
||||
}
|
||||
|
||||
const menus = computed(
|
||||
const allMenus = computed<App.Global.Menu[]>(() => routeStore.menus);
|
||||
|
||||
const firstLevelMenus = computed<App.Global.Menu[]>(() =>
|
||||
routeStore.menus.map(menu => {
|
||||
const { children: _, ...rest } = menu;
|
||||
|
||||
return rest;
|
||||
})
|
||||
);
|
||||
|
||||
const childLevelMenus = computed<App.Global.Menu[]>(
|
||||
() => routeStore.menus.find(menu => menu.key === activeFirstLevelMenuKey.value)?.children || []
|
||||
);
|
||||
|
||||
const isActiveFirstLevelMenuHasChildren = computed(() => {
|
||||
if (!activeFirstLevelMenuKey.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const findItem = allMenus.value.find(item => item.key === activeFirstLevelMenuKey.value);
|
||||
|
||||
return Boolean(findItem?.children?.length);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
() => {
|
||||
@@ -39,9 +55,29 @@ function useMixMenu() {
|
||||
);
|
||||
|
||||
return {
|
||||
allMenus,
|
||||
firstLevelMenus,
|
||||
childLevelMenus,
|
||||
isActiveFirstLevelMenuHasChildren,
|
||||
activeFirstLevelMenuKey,
|
||||
setActiveFirstLevelMenuKey,
|
||||
getActiveFirstLevelMenuKey,
|
||||
menus
|
||||
getActiveFirstLevelMenuKey
|
||||
};
|
||||
}
|
||||
|
||||
export function useMenu() {
|
||||
const route = useRoute();
|
||||
|
||||
const selectedKey = computed(() => {
|
||||
const { hideInMenu, activeMenu } = route.meta;
|
||||
const name = route.name as string;
|
||||
|
||||
const routeName = (hideInMenu ? activeMenu : name) || name;
|
||||
|
||||
return routeName;
|
||||
});
|
||||
|
||||
return {
|
||||
selectedKey
|
||||
};
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { LAYOUT_SCROLL_EL_ID } from '@sa/materials';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
@@ -24,6 +25,12 @@ const routeStore = useRouteStore();
|
||||
const tabStore = useTabStore();
|
||||
|
||||
const transitionName = computed(() => (themeStore.page.animate ? themeStore.page.animateMode : ''));
|
||||
|
||||
function resetScroll() {
|
||||
const el = document.querySelector(`#${LAYOUT_SCROLL_EL_ID}`);
|
||||
|
||||
el?.scrollTo({ left: 0, top: 0 });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -32,9 +39,10 @@ const transitionName = computed(() => (themeStore.page.animate ? themeStore.page
|
||||
:name="transitionName"
|
||||
mode="out-in"
|
||||
@before-leave="appStore.setContentXScrollable(true)"
|
||||
@after-leave="resetScroll"
|
||||
@after-enter="appStore.setContentXScrollable(false)"
|
||||
>
|
||||
<KeepAlive :include="routeStore.cacheRoutes">
|
||||
<KeepAlive :include="routeStore.cacheRoutes" :exclude="routeStore.excludeCacheRoutes">
|
||||
<component
|
||||
:is="Component"
|
||||
v-if="appStore.reloadFlag"
|
||||
|
@@ -18,7 +18,7 @@ function loginOrRegister() {
|
||||
toLogin();
|
||||
}
|
||||
|
||||
type DropdownKey = 'user-center' | 'logout';
|
||||
type DropdownKey = 'logout';
|
||||
|
||||
type DropdownOption =
|
||||
| {
|
||||
@@ -33,15 +33,6 @@ type DropdownOption =
|
||||
|
||||
const options = computed(() => {
|
||||
const opts: DropdownOption[] = [
|
||||
{
|
||||
label: $t('common.userCenter'),
|
||||
key: 'user-center',
|
||||
icon: SvgIconVNode({ icon: 'ph:user-circle', fontSize: 18 })
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
key: 'divider'
|
||||
},
|
||||
{
|
||||
label: $t('common.logout'),
|
||||
key: 'logout',
|
||||
@@ -68,6 +59,7 @@ function handleDropdown(key: DropdownKey) {
|
||||
if (key === 'logout') {
|
||||
logout();
|
||||
} else {
|
||||
// If your other options are jumps from other routes, they will be directly supported here
|
||||
routerPushByKey(key);
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useFullscreen } from '@vueuse/core';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import HorizontalMenu from '../global-menu/base-menu.vue';
|
||||
import { GLOBAL_HEADER_MENU_ID } from '@/constants/app';
|
||||
import GlobalLogo from '../global-logo/index.vue';
|
||||
import GlobalBreadcrumb from '../global-breadcrumb/index.vue';
|
||||
import GlobalSearch from '../global-search/index.vue';
|
||||
import { useMixMenuContext } from '../../context';
|
||||
import ThemeButton from './components/theme-button.vue';
|
||||
import UserAvatar from './components/user-avatar.vue';
|
||||
|
||||
@@ -29,29 +26,15 @@ defineProps<Props>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
const { isFullscreen, toggle } = useFullscreen();
|
||||
const { menus } = useMixMenuContext();
|
||||
|
||||
const headerMenus = computed(() => {
|
||||
if (themeStore.layout.mode === 'horizontal') {
|
||||
return routeStore.menus;
|
||||
}
|
||||
|
||||
if (themeStore.layout.mode === 'horizontal-mix') {
|
||||
return menus.value;
|
||||
}
|
||||
|
||||
return [];
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DarkModeContainer class="h-full flex-y-center px-12px shadow-header">
|
||||
<GlobalLogo v-if="showLogo" class="h-full" :style="{ width: themeStore.sider.width + 'px' }" />
|
||||
<HorizontalMenu v-if="showMenu" mode="horizontal" :menus="headerMenus" class="px-12px" />
|
||||
<MenuToggler v-if="showMenuToggler" :collapsed="appStore.siderCollapse" @click="appStore.toggleSiderCollapse" />
|
||||
<div v-if="showMenu" :id="GLOBAL_HEADER_MENU_ID" class="h-full flex-y-center flex-1-hidden"></div>
|
||||
<div v-else class="h-full flex-y-center flex-1-hidden">
|
||||
<MenuToggler v-if="showMenuToggler" :collapsed="appStore.siderCollapse" @click="appStore.toggleSiderCollapse" />
|
||||
<GlobalBreadcrumb v-if="!appStore.isMobile" class="ml-12px" />
|
||||
</div>
|
||||
<div class="h-full flex-y-center justify-end">
|
||||
|
@@ -1,96 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import type { MentionOption, MenuProps } from 'naive-ui';
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import type { RouteKey } from '@elegant-router/types';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
|
||||
defineOptions({
|
||||
name: 'BaseMenu'
|
||||
});
|
||||
|
||||
interface Props {
|
||||
darkTheme?: boolean;
|
||||
mode?: MenuProps['mode'];
|
||||
menus: App.Global.Menu[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
mode: 'vertical'
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
const naiveMenus = computed(() => props.menus as unknown as MentionOption[]);
|
||||
|
||||
const isHorizontal = computed(() => props.mode === 'horizontal');
|
||||
|
||||
const siderCollapse = computed(() => themeStore.layout.mode === 'vertical' && appStore.siderCollapse);
|
||||
|
||||
const headerHeight = computed(() => `${themeStore.header.height}px`);
|
||||
|
||||
const selectedKey = computed(() => {
|
||||
const { hideInMenu, activeMenu } = route.meta;
|
||||
const name = route.name as string;
|
||||
|
||||
const routeName = (hideInMenu ? activeMenu : name) || name;
|
||||
|
||||
return routeName;
|
||||
});
|
||||
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
|
||||
function updateExpandedKeys() {
|
||||
if (isHorizontal.value || siderCollapse.value || !selectedKey.value) {
|
||||
expandedKeys.value = [];
|
||||
return;
|
||||
}
|
||||
expandedKeys.value = routeStore.getSelectedMenuKeyPath(selectedKey.value);
|
||||
}
|
||||
|
||||
function handleClickMenu(key: RouteKey) {
|
||||
const query = routeStore.getRouteQueryOfMetaByKey(key);
|
||||
|
||||
routerPushByKey(key, { query });
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
() => {
|
||||
updateExpandedKeys();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SimpleScrollbar>
|
||||
<NMenu
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
:mode="mode"
|
||||
:value="selectedKey"
|
||||
:collapsed="siderCollapse"
|
||||
:collapsed-width="themeStore.sider.collapsedWidth"
|
||||
:collapsed-icon-size="22"
|
||||
:options="naiveMenus"
|
||||
:inverted="darkTheme"
|
||||
:indent="18"
|
||||
responsive
|
||||
@update:value="handleClickMenu"
|
||||
/>
|
||||
</SimpleScrollbar>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.n-menu--horizontal) {
|
||||
--n-item-height: v-bind(headerHeight) !important;
|
||||
}
|
||||
</style>
|
@@ -3,31 +3,29 @@ import { computed } from 'vue';
|
||||
import { createReusableTemplate } from '@vueuse/core';
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import { transformColorWithOpacity } from '@sa/color';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
|
||||
defineOptions({
|
||||
name: 'FirstLevelMenu'
|
||||
});
|
||||
|
||||
interface Props {
|
||||
menus: App.Global.Menu[];
|
||||
activeMenuKey?: string;
|
||||
inverted?: boolean;
|
||||
siderCollapse?: boolean;
|
||||
darkMode?: boolean;
|
||||
themeColor: string;
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
const props = defineProps<Props>();
|
||||
|
||||
interface Emits {
|
||||
(e: 'select', menu: App.Global.Menu): boolean;
|
||||
(e: 'toggleSiderCollapse'): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
|
||||
interface MixMenuItemProps {
|
||||
/** Menu item label */
|
||||
label: App.Global.Menu['label'];
|
||||
@@ -36,12 +34,12 @@ interface MixMenuItemProps {
|
||||
/** Active menu item */
|
||||
active: boolean;
|
||||
/** Mini size */
|
||||
isMini: boolean;
|
||||
isMini?: boolean;
|
||||
}
|
||||
const [DefineMixMenuItem, MixMenuItem] = createReusableTemplate<MixMenuItemProps>();
|
||||
|
||||
const selectedBgColor = computed(() => {
|
||||
const { darkMode, themeColor } = themeStore;
|
||||
const { darkMode, themeColor } = props;
|
||||
|
||||
const light = transformColorWithOpacity(themeColor, 0.1, '#ffffff');
|
||||
const dark = transformColorWithOpacity(themeColor, 0.3, '#000000');
|
||||
@@ -52,6 +50,10 @@ const selectedBgColor = computed(() => {
|
||||
function handleClickMixMenu(menu: App.Global.Menu) {
|
||||
emit('select', menu);
|
||||
}
|
||||
|
||||
function toggleSiderCollapse() {
|
||||
emit('toggleSiderCollapse');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -80,21 +82,21 @@ function handleClickMixMenu(menu: App.Global.Menu) {
|
||||
<slot></slot>
|
||||
<SimpleScrollbar>
|
||||
<MixMenuItem
|
||||
v-for="menu in routeStore.menus"
|
||||
v-for="menu in menus"
|
||||
:key="menu.key"
|
||||
:label="menu.label"
|
||||
:icon="menu.icon"
|
||||
:active="menu.key === activeMenuKey"
|
||||
:is-mini="appStore.siderCollapse"
|
||||
:is-mini="siderCollapse"
|
||||
@click="handleClickMixMenu(menu)"
|
||||
/>
|
||||
</SimpleScrollbar>
|
||||
<MenuToggler
|
||||
arrow-icon
|
||||
:collapsed="appStore.siderCollapse"
|
||||
:collapsed="siderCollapse"
|
||||
:z-index="99"
|
||||
:class="{ 'text-white:88 !hover:text-white': inverted }"
|
||||
@click="appStore.toggleSiderCollapse"
|
||||
@click="toggleSiderCollapse"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
@@ -1,28 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useMixMenuContext } from '../../context';
|
||||
import FirstLevelMenu from './first-level-menu.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'HorizontalMixMenu'
|
||||
});
|
||||
|
||||
const { activeFirstLevelMenuKey, setActiveFirstLevelMenuKey } = useMixMenuContext();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
function handleSelectMixMenu(menu: App.Global.Menu) {
|
||||
setActiveFirstLevelMenuKey(menu.key);
|
||||
|
||||
if (!menu.children?.length) {
|
||||
routerPushByKey(menu.routeKey);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FirstLevelMenu :active-menu-key="activeFirstLevelMenuKey" @select="handleSelectMixMenu">
|
||||
<slot></slot>
|
||||
</FirstLevelMenu>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
37
src/layouts/modules/global-menu/index.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { Component } from 'vue';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import VerticalMenu from './modules/vertical-menu.vue';
|
||||
import VerticalMixMenu from './modules/vertical-mix-menu.vue';
|
||||
import HorizontalMenu from './modules/horizontal-menu.vue';
|
||||
import HorizontalMixMenu from './modules/horizontal-mix-menu.vue';
|
||||
import ReversedHorizontalMixMenu from './modules/reversed-horizontal-mix-menu.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'GlobalMenu'
|
||||
});
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
const activeMenu = computed(() => {
|
||||
const menuMap: Record<UnionKey.ThemeLayoutMode, Component> = {
|
||||
vertical: VerticalMenu,
|
||||
'vertical-mix': VerticalMixMenu,
|
||||
horizontal: HorizontalMenu,
|
||||
'horizontal-mix': themeStore.layout.reverseHorizontalMix ? ReversedHorizontalMixMenu : HorizontalMixMenu
|
||||
};
|
||||
|
||||
return menuMap[themeStore.layout.mode];
|
||||
});
|
||||
|
||||
const reRenderVertical = computed(() => themeStore.layout.mode === 'vertical' && appStore.isMobile);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component :is="activeMenu" :key="reRenderVertical" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
29
src/layouts/modules/global-menu/modules/horizontal-menu.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { GLOBAL_HEADER_MENU_ID } from '@/constants/app';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useMenu } from '../../../context';
|
||||
|
||||
defineOptions({
|
||||
name: 'HorizontalMenu'
|
||||
});
|
||||
|
||||
const routeStore = useRouteStore();
|
||||
const { routerPushByKeyWithMetaQuery } = useRouterPush();
|
||||
const { selectedKey } = useMenu();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport :to="`#${GLOBAL_HEADER_MENU_ID}`">
|
||||
<NMenu
|
||||
mode="horizontal"
|
||||
:value="selectedKey"
|
||||
:options="routeStore.menus"
|
||||
:indent="18"
|
||||
responsive
|
||||
@update:value="routerPushByKeyWithMetaQuery"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { GLOBAL_HEADER_MENU_ID, GLOBAL_SIDER_MENU_ID } from '@/constants/app';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import FirstLevelMenu from '../components/first-level-menu.vue';
|
||||
import { useMenu, useMixMenuContext } from '../../../context';
|
||||
|
||||
defineOptions({
|
||||
name: 'HorizontalMixMenu'
|
||||
});
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const { routerPushByKeyWithMetaQuery } = useRouterPush();
|
||||
const { allMenus, childLevelMenus, activeFirstLevelMenuKey, setActiveFirstLevelMenuKey } = useMixMenuContext();
|
||||
const { selectedKey } = useMenu();
|
||||
|
||||
function handleSelectMixMenu(menu: App.Global.Menu) {
|
||||
setActiveFirstLevelMenuKey(menu.key);
|
||||
|
||||
if (!menu.children?.length) {
|
||||
routerPushByKeyWithMetaQuery(menu.routeKey);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport :to="`#${GLOBAL_HEADER_MENU_ID}`">
|
||||
<NMenu
|
||||
mode="horizontal"
|
||||
:value="selectedKey"
|
||||
:options="childLevelMenus"
|
||||
:indent="18"
|
||||
responsive
|
||||
@update:value="routerPushByKeyWithMetaQuery"
|
||||
/>
|
||||
</Teleport>
|
||||
<Teleport :to="`#${GLOBAL_SIDER_MENU_ID}`">
|
||||
<FirstLevelMenu
|
||||
:menus="allMenus"
|
||||
:active-menu-key="activeFirstLevelMenuKey"
|
||||
:sider-collapse="appStore.siderCollapse"
|
||||
:dark-mode="themeStore.darkMode"
|
||||
:theme-color="themeStore.themeColor"
|
||||
@select="handleSelectMixMenu"
|
||||
@toggle-sider-collapse="appStore.toggleSiderCollapse"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import type { RouteKey } from '@elegant-router/types';
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import { GLOBAL_HEADER_MENU_ID, GLOBAL_SIDER_MENU_ID } from '@/constants/app';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useMenu, useMixMenuContext } from '../../../context';
|
||||
|
||||
defineOptions({
|
||||
name: 'ReversedHorizontalMixMenu'
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
const { routerPushByKeyWithMetaQuery } = useRouterPush();
|
||||
const {
|
||||
firstLevelMenus,
|
||||
childLevelMenus,
|
||||
activeFirstLevelMenuKey,
|
||||
setActiveFirstLevelMenuKey,
|
||||
isActiveFirstLevelMenuHasChildren
|
||||
} = useMixMenuContext();
|
||||
const { selectedKey } = useMenu();
|
||||
|
||||
function handleSelectMixMenu(key: RouteKey) {
|
||||
setActiveFirstLevelMenuKey(key);
|
||||
|
||||
if (!isActiveFirstLevelMenuHasChildren.value) {
|
||||
routerPushByKeyWithMetaQuery(key);
|
||||
}
|
||||
}
|
||||
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
|
||||
function updateExpandedKeys() {
|
||||
if (appStore.siderCollapse || !selectedKey.value) {
|
||||
expandedKeys.value = [];
|
||||
return;
|
||||
}
|
||||
expandedKeys.value = routeStore.getSelectedMenuKeyPath(selectedKey.value);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
() => {
|
||||
updateExpandedKeys();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport :to="`#${GLOBAL_HEADER_MENU_ID}`">
|
||||
<NMenu
|
||||
mode="horizontal"
|
||||
:value="activeFirstLevelMenuKey"
|
||||
:options="firstLevelMenus"
|
||||
:indent="18"
|
||||
responsive
|
||||
@update:value="handleSelectMixMenu"
|
||||
/>
|
||||
</Teleport>
|
||||
<Teleport :to="`#${GLOBAL_SIDER_MENU_ID}`">
|
||||
<SimpleScrollbar>
|
||||
<NMenu
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
mode="vertical"
|
||||
:value="selectedKey"
|
||||
:collapsed="appStore.siderCollapse"
|
||||
:collapsed-width="themeStore.sider.collapsedWidth"
|
||||
:collapsed-icon-size="22"
|
||||
:options="childLevelMenus"
|
||||
:indent="18"
|
||||
@update:value="routerPushByKeyWithMetaQuery"
|
||||
/>
|
||||
</SimpleScrollbar>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
63
src/layouts/modules/global-menu/modules/vertical-menu.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { GLOBAL_SIDER_MENU_ID } from '@/constants/app';
|
||||
import { useMenu } from '../../../context';
|
||||
|
||||
defineOptions({
|
||||
name: 'VerticalMenu'
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
const { routerPushByKeyWithMetaQuery } = useRouterPush();
|
||||
const { selectedKey } = useMenu();
|
||||
|
||||
const inverted = computed(() => !themeStore.darkMode && themeStore.sider.inverted);
|
||||
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
|
||||
function updateExpandedKeys() {
|
||||
if (appStore.siderCollapse || !selectedKey.value) {
|
||||
expandedKeys.value = [];
|
||||
return;
|
||||
}
|
||||
expandedKeys.value = routeStore.getSelectedMenuKeyPath(selectedKey.value);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
() => {
|
||||
updateExpandedKeys();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport :to="`#${GLOBAL_SIDER_MENU_ID}`">
|
||||
<SimpleScrollbar>
|
||||
<NMenu
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
mode="vertical"
|
||||
:value="selectedKey"
|
||||
:collapsed="appStore.siderCollapse"
|
||||
:collapsed-width="themeStore.sider.collapsedWidth"
|
||||
:collapsed-icon-size="22"
|
||||
:options="routeStore.menus"
|
||||
:inverted="inverted"
|
||||
:indent="18"
|
||||
@update:value="routerPushByKeyWithMetaQuery"
|
||||
/>
|
||||
</SimpleScrollbar>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
128
src/layouts/modules/global-menu/modules/vertical-mix-menu.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { $t } from '@/locales';
|
||||
import { GLOBAL_SIDER_MENU_ID } from '@/constants/app';
|
||||
import { useMenu, useMixMenuContext } from '../../../context';
|
||||
import FirstLevelMenu from '../components/first-level-menu.vue';
|
||||
import GlobalLogo from '../../global-logo/index.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'VerticalMixMenu'
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
const { routerPushByKeyWithMetaQuery } = useRouterPush();
|
||||
const { bool: drawerVisible, setBool: setDrawerVisible } = useBoolean();
|
||||
const {
|
||||
allMenus,
|
||||
childLevelMenus,
|
||||
activeFirstLevelMenuKey,
|
||||
setActiveFirstLevelMenuKey,
|
||||
getActiveFirstLevelMenuKey
|
||||
//
|
||||
} = useMixMenuContext();
|
||||
const { selectedKey } = useMenu();
|
||||
|
||||
const inverted = computed(() => !themeStore.darkMode && themeStore.sider.inverted);
|
||||
|
||||
const hasChildMenus = computed(() => childLevelMenus.value.length > 0);
|
||||
|
||||
const showDrawer = computed(() => hasChildMenus.value && (drawerVisible.value || appStore.mixSiderFixed));
|
||||
|
||||
function handleSelectMixMenu(menu: App.Global.Menu) {
|
||||
setActiveFirstLevelMenuKey(menu.key);
|
||||
|
||||
if (menu.children?.length) {
|
||||
setDrawerVisible(true);
|
||||
} else {
|
||||
routerPushByKeyWithMetaQuery(menu.routeKey);
|
||||
}
|
||||
}
|
||||
|
||||
function handleResetActiveMenu() {
|
||||
setDrawerVisible(false);
|
||||
|
||||
if (!appStore.mixSiderFixed) {
|
||||
getActiveFirstLevelMenuKey();
|
||||
}
|
||||
}
|
||||
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
|
||||
function updateExpandedKeys() {
|
||||
if (appStore.siderCollapse || !selectedKey.value) {
|
||||
expandedKeys.value = [];
|
||||
return;
|
||||
}
|
||||
expandedKeys.value = routeStore.getSelectedMenuKeyPath(selectedKey.value);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
() => {
|
||||
updateExpandedKeys();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport :to="`#${GLOBAL_SIDER_MENU_ID}`">
|
||||
<div class="h-full flex" @mouseleave="handleResetActiveMenu">
|
||||
<FirstLevelMenu
|
||||
:menus="allMenus"
|
||||
:active-menu-key="activeFirstLevelMenuKey"
|
||||
:inverted="inverted"
|
||||
:sider-collapse="appStore.siderCollapse"
|
||||
:dark-mode="themeStore.darkMode"
|
||||
:theme-color="themeStore.themeColor"
|
||||
@select="handleSelectMixMenu"
|
||||
@toggle-sider-collapse="appStore.toggleSiderCollapse"
|
||||
>
|
||||
<GlobalLogo :show-title="false" :style="{ height: themeStore.header.height + 'px' }" />
|
||||
</FirstLevelMenu>
|
||||
<div
|
||||
class="relative h-full transition-width-300"
|
||||
:style="{ width: appStore.mixSiderFixed && hasChildMenus ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||
>
|
||||
<DarkModeContainer
|
||||
class="absolute-lt h-full flex-col-stretch nowrap-hidden shadow-sm transition-all-300"
|
||||
:inverted="inverted"
|
||||
:style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||
>
|
||||
<header class="flex-y-center justify-between px-12px" :style="{ height: themeStore.header.height + 'px' }">
|
||||
<h2 class="text-16px text-primary font-bold">{{ $t('system.title') }}</h2>
|
||||
<PinToggler
|
||||
:pin="appStore.mixSiderFixed"
|
||||
:class="{ 'text-white:88 !hover:text-white': inverted }"
|
||||
@click="appStore.toggleMixSiderFixed"
|
||||
/>
|
||||
</header>
|
||||
<SimpleScrollbar>
|
||||
<NMenu
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
mode="vertical"
|
||||
:value="selectedKey"
|
||||
:options="childLevelMenus"
|
||||
:inverted="inverted"
|
||||
:indent="18"
|
||||
@update:value="routerPushByKeyWithMetaQuery"
|
||||
/>
|
||||
</SimpleScrollbar>
|
||||
</DarkModeContainer>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@@ -1,72 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { $t } from '@/locales';
|
||||
import { useMixMenuContext } from '../../context';
|
||||
import FirstLevelMenu from './first-level-menu.vue';
|
||||
import BaseMenu from './base-menu.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'VerticalMixMenu'
|
||||
});
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
const { bool: drawerVisible, setBool: setDrawerVisible } = useBoolean();
|
||||
const { menus, activeFirstLevelMenuKey, setActiveFirstLevelMenuKey, getActiveFirstLevelMenuKey } = useMixMenuContext();
|
||||
|
||||
const siderInverted = computed(() => !themeStore.darkMode && themeStore.sider.inverted);
|
||||
|
||||
const hasMenus = computed(() => menus.value.length > 0);
|
||||
|
||||
const showDrawer = computed(() => hasMenus.value && (drawerVisible.value || appStore.mixSiderFixed));
|
||||
|
||||
function handleSelectMixMenu(menu: App.Global.Menu) {
|
||||
setActiveFirstLevelMenuKey(menu.key);
|
||||
|
||||
if (menu.children?.length) {
|
||||
setDrawerVisible(true);
|
||||
} else {
|
||||
routerPushByKey(menu.routeKey);
|
||||
}
|
||||
}
|
||||
|
||||
function handleResetActiveMenu() {
|
||||
getActiveFirstLevelMenuKey();
|
||||
setDrawerVisible(false);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full flex" @mouseleave="handleResetActiveMenu">
|
||||
<FirstLevelMenu :active-menu-key="activeFirstLevelMenuKey" :inverted="siderInverted" @select="handleSelectMixMenu">
|
||||
<slot></slot>
|
||||
</FirstLevelMenu>
|
||||
<div
|
||||
class="relative h-full transition-width-300"
|
||||
:style="{ width: appStore.mixSiderFixed && hasMenus ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||
>
|
||||
<DarkModeContainer
|
||||
class="absolute-lt h-full flex-col-stretch nowrap-hidden shadow-sm transition-all-300"
|
||||
:inverted="siderInverted"
|
||||
:style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
|
||||
>
|
||||
<header class="flex-y-center justify-between px-12px" :style="{ height: themeStore.header.height + 'px' }">
|
||||
<h2 class="text-16px text-primary font-bold">{{ $t('system.title') }}</h2>
|
||||
<PinToggler
|
||||
:pin="appStore.mixSiderFixed"
|
||||
:class="{ 'text-white:88 !hover:text-white': siderInverted }"
|
||||
@click="appStore.toggleMixSiderFixed"
|
||||
/>
|
||||
</header>
|
||||
<BaseMenu :dark-theme="siderInverted" :menus="menus" />
|
||||
</DarkModeContainer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@@ -2,11 +2,8 @@
|
||||
import { computed } from 'vue';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { GLOBAL_SIDER_MENU_ID } from '@/constants/app';
|
||||
import GlobalLogo from '../global-logo/index.vue';
|
||||
import VerticalMenu from '../global-menu/base-menu.vue';
|
||||
import VerticalMixMenu from '../global-menu/vertical-mix-menu.vue';
|
||||
import HorizontalMixMenu from '../global-menu/horizontal-mix-menu.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'GlobalSider'
|
||||
@@ -14,12 +11,12 @@ defineOptions({
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
const routeStore = useRouteStore();
|
||||
|
||||
const isVerticalMix = computed(() => themeStore.layout.mode === 'vertical-mix');
|
||||
const isHorizontalMix = computed(() => themeStore.layout.mode === 'horizontal-mix');
|
||||
const darkMenu = computed(() => !themeStore.darkMode && !isHorizontalMix.value && themeStore.sider.inverted);
|
||||
const showLogo = computed(() => !isVerticalMix.value && !isHorizontalMix.value);
|
||||
const menuWrapperClass = computed(() => (showLogo.value ? 'flex-1-hidden' : 'h-full'));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -29,11 +26,7 @@ const showLogo = computed(() => !isVerticalMix.value && !isHorizontalMix.value);
|
||||
:show-title="!appStore.siderCollapse"
|
||||
:style="{ height: themeStore.header.height + 'px' }"
|
||||
/>
|
||||
<VerticalMixMenu v-if="isVerticalMix">
|
||||
<GlobalLogo :show-title="false" :style="{ height: themeStore.header.height + 'px' }" />
|
||||
</VerticalMixMenu>
|
||||
<HorizontalMixMenu v-else-if="isHorizontalMix" />
|
||||
<VerticalMenu v-else :dark-theme="darkMenu" :menus="routeStore.menus" />
|
||||
<div :id="GLOBAL_SIDER_MENU_ID" :class="menuWrapperClass"></div>
|
||||
</DarkModeContainer>
|
||||
</template>
|
||||
|
||||
|
@@ -8,6 +8,7 @@ import { useAppStore } from '@/store/modules/app';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useTabStore } from '@/store/modules/tab';
|
||||
import { isPC } from '@/utils/agent';
|
||||
import ContextMenu from './context-menu.vue';
|
||||
|
||||
defineOptions({
|
||||
@@ -24,6 +25,7 @@ const bsWrapper = ref<HTMLElement>();
|
||||
const { width: bsWrapperWidth, left: bsWrapperLeft } = useElementBounding(bsWrapper);
|
||||
const bsScroll = ref<InstanceType<typeof BetterScroll>>();
|
||||
const tabRef = ref<HTMLElement>();
|
||||
const isPCFlag = isPC();
|
||||
|
||||
const TAB_DATA_ID = 'data-tab-id';
|
||||
|
||||
@@ -82,7 +84,10 @@ function getContextMenuDisabledKeys(tabId: string) {
|
||||
|
||||
async function handleCloseTab(tab: App.Global.Tab) {
|
||||
await tabStore.removeTab(tab.id);
|
||||
await routeStore.reCacheRoutesByKey(tab.routeKey);
|
||||
|
||||
if (themeStore.resetCacheStrategy === 'close') {
|
||||
routeStore.resetRouteCache(tab.routeKey);
|
||||
}
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
@@ -166,11 +171,7 @@ init();
|
||||
<template>
|
||||
<DarkModeContainer class="size-full flex-y-center px-16px shadow-tab">
|
||||
<div ref="bsWrapper" class="h-full flex-1-hidden">
|
||||
<BetterScroll
|
||||
ref="bsScroll"
|
||||
:options="{ scrollX: true, scrollY: false, click: appStore.isMobile }"
|
||||
@click="removeFocus"
|
||||
>
|
||||
<BetterScroll ref="bsScroll" :options="{ scrollX: true, scrollY: false, click: !isPCFlag }" @click="removeFocus">
|
||||
<div
|
||||
ref="tabRef"
|
||||
class="h-full flex pr-18px"
|
||||
|
@@ -14,7 +14,7 @@ defineProps<Props>();
|
||||
<template>
|
||||
<div class="w-full flex-y-center justify-between">
|
||||
<div>
|
||||
<span class="pr-8px text-base_text">{{ label }}</span>
|
||||
<span class="pr-8px text-base-text">{{ label }}</span>
|
||||
<slot name="suffix"></slot>
|
||||
</div>
|
||||
<slot></slot>
|
||||
|
@@ -25,6 +25,10 @@ function handleGrayscaleChange(value: boolean) {
|
||||
themeStore.setGrayscale(value);
|
||||
}
|
||||
|
||||
function handleColourWeaknessChange(value: boolean) {
|
||||
themeStore.setColourWeakness(value);
|
||||
}
|
||||
|
||||
const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layout.mode.includes('vertical'));
|
||||
</script>
|
||||
|
||||
@@ -53,6 +57,9 @@ const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layo
|
||||
<SettingItem :label="$t('theme.grayscale')">
|
||||
<NSwitch :value="themeStore.grayscale" @update:value="handleGrayscaleChange" />
|
||||
</SettingItem>
|
||||
<SettingItem :label="$t('theme.colourWeakness')">
|
||||
<NSwitch :value="themeStore.colourWeakness" @update:value="handleColourWeaknessChange" />
|
||||
</SettingItem>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|