mirror of
https://gitee.com/dapppp/ruoyi-plus-vben5.git
synced 2026-04-02 16:13:23 +08:00
Compare commits
315 Commits
vite8-prev
...
antdv-next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3f8cd8f96 | ||
|
|
486ce6a567 | ||
|
|
1b63469c40 | ||
|
|
a9241aef84 | ||
|
|
6c6fb316f0 | ||
|
|
2a86404ba5 | ||
|
|
b8a0199cde | ||
|
|
a46ed55a86 | ||
|
|
1a9fbddef4 | ||
|
|
1209aaafb4 | ||
|
|
8e71261d49 | ||
|
|
55b9d5cdb7 | ||
|
|
4f9caec9d5 | ||
|
|
49e45eab54 | ||
|
|
bd22793ceb | ||
|
|
b2013436c5 | ||
|
|
cc808cb8c5 | ||
|
|
afffc4b3f0 | ||
|
|
a272c54561 | ||
|
|
7f5758b89c | ||
|
|
ba6c450298 | ||
|
|
99710ef9dc | ||
|
|
3d4ae04d9b | ||
|
|
707b391449 | ||
|
|
45b843f344 | ||
|
|
191fd90f06 | ||
|
|
05920cd66d | ||
|
|
01508d5e42 | ||
|
|
57cf6cbc9e | ||
|
|
03ebbea46a | ||
|
|
8e7a5d1ec3 | ||
|
|
aa74a2535b | ||
|
|
32379ba4b7 | ||
|
|
5177f5c98d | ||
|
|
e9d3200c38 | ||
|
|
27c78cb888 | ||
|
|
7fe8d7b4be | ||
|
|
aace726a91 | ||
|
|
e6f6e5464a | ||
|
|
7d04b600fb | ||
|
|
05b32dd249 | ||
|
|
ed42d9de65 | ||
|
|
463bfde2ac | ||
|
|
b788a7d860 | ||
|
|
f3942edece | ||
|
|
4a6745a8ea | ||
|
|
88b311202d | ||
|
|
7d1a51bfe3 | ||
|
|
893f74dc3e | ||
|
|
7092cd59d3 | ||
|
|
2189f22bbd | ||
|
|
8a215fbcc7 | ||
|
|
ac5e4c4722 | ||
|
|
04d01b0bab | ||
|
|
cb1d7565a3 | ||
|
|
1d9b6407a4 | ||
|
|
22ed522711 | ||
|
|
a3598ef859 | ||
|
|
6fe09ec2dd | ||
|
|
57911d9e09 | ||
|
|
3aee283495 | ||
|
|
54b24c2677 | ||
|
|
8cadad0a1e | ||
|
|
633c5f3cda | ||
|
|
a8431e2040 | ||
|
|
7a2b916387 | ||
|
|
f4dfb68b7b | ||
|
|
8f4f27d860 | ||
|
|
e9eab29953 | ||
|
|
4f1eeb7da5 | ||
|
|
1b3eb65280 | ||
|
|
d1461f3fa4 | ||
|
|
6fd426d719 | ||
|
|
331da3c8c7 | ||
|
|
4c0dc60ce6 | ||
|
|
cba346b0fc | ||
|
|
f53c7b48c0 | ||
|
|
543162986f | ||
|
|
1276559728 | ||
|
|
3c8d613623 | ||
|
|
2a126c9ca2 | ||
|
|
70acbdd7c5 | ||
|
|
d7552b0faf | ||
|
|
fb33137790 | ||
|
|
f2bd1cc378 | ||
|
|
6bf71681c4 | ||
|
|
a5f66bce57 | ||
|
|
949b81e630 | ||
|
|
17aefd5568 | ||
|
|
41f0e043e9 | ||
|
|
f276b0f062 | ||
|
|
6d42a6d1bd | ||
|
|
3c2acf9ca1 | ||
|
|
9b38389040 | ||
|
|
c48943bc67 | ||
|
|
1f4592e6fb | ||
|
|
3dd1a07ae3 | ||
|
|
1666a65ba0 | ||
|
|
4085b05dae | ||
|
|
8e2901775e | ||
|
|
0049c76f78 | ||
|
|
48f979497e | ||
|
|
cd908a967c | ||
|
|
487dd67d76 | ||
|
|
2a8e712e6d | ||
|
|
16544228b7 | ||
|
|
330f2d81ed | ||
|
|
585a543c8f | ||
|
|
25994bd3bb | ||
|
|
72a62fa77f | ||
|
|
dab5f8ed72 | ||
|
|
9129026bcb | ||
|
|
7b4d68a164 | ||
|
|
35d67ad71c | ||
|
|
1ff118c2e0 | ||
|
|
abb386f49d | ||
|
|
d28d80295c | ||
|
|
e2f063907e | ||
|
|
9454121963 | ||
|
|
189b86f5b7 | ||
|
|
bfb2287b2e | ||
|
|
048ee5833e | ||
|
|
7680b33b99 | ||
|
|
3cb93fd67c | ||
|
|
cb2a58425f | ||
|
|
1f6de0ec29 | ||
|
|
703cdf4125 | ||
|
|
157fb22820 | ||
|
|
2d1545106e | ||
|
|
dfbab164ec | ||
|
|
32344ed038 | ||
|
|
f01093af6d | ||
|
|
3abf3333ec | ||
|
|
0934d7b785 | ||
|
|
6baecb5199 | ||
|
|
6b613aacb9 | ||
|
|
ecd2bdb5fc | ||
|
|
59fc7b66ad | ||
|
|
2746c7bdf0 | ||
|
|
ba577dda14 | ||
|
|
afb7222955 | ||
|
|
be5af9e991 | ||
|
|
a8576d2c05 | ||
|
|
188ef3a66e | ||
|
|
0636c5f4a6 | ||
|
|
154c8b664b | ||
|
|
8fea830f9d | ||
|
|
3907f206d9 | ||
|
|
dc2de11f57 | ||
|
|
c2b1d880c1 | ||
|
|
bb5d75bc7e | ||
|
|
cf1ed14c00 | ||
|
|
e4d882b4bc | ||
|
|
0b3ab4de63 | ||
|
|
1082ea90cf | ||
|
|
edb887a7ed | ||
|
|
1ec73473cf | ||
|
|
29028d7237 | ||
|
|
09b147195a | ||
|
|
528395e2c3 | ||
|
|
6a9012e5e4 | ||
|
|
6e8315ab40 | ||
|
|
7cb2699f19 | ||
|
|
4b5da81ba6 | ||
|
|
6aca9a9c99 | ||
|
|
fa195fde8e | ||
|
|
1057f2932b | ||
|
|
682dc9a5d6 | ||
|
|
b9224fc379 | ||
|
|
57dd818170 | ||
|
|
49256ec1b7 | ||
|
|
f6f92e5403 | ||
|
|
613c311076 | ||
|
|
9ee7a7d9ff | ||
|
|
44f8aed06d | ||
|
|
1539932556 | ||
|
|
d2e80b3ae0 | ||
|
|
657842336d | ||
|
|
f9c85bca3f | ||
|
|
fa4d16c542 | ||
|
|
87706ad425 | ||
|
|
d475b29e9f | ||
|
|
d5d4a5c591 | ||
|
|
052d7d5cdd | ||
|
|
948dc9b520 | ||
|
|
46fa96f556 | ||
|
|
82c6674e7c | ||
|
|
49736f49a4 | ||
|
|
74381aa8c1 | ||
|
|
203ee9b623 | ||
|
|
6c8c49966a | ||
|
|
3862942e9f | ||
|
|
919f166c16 | ||
|
|
f0253f6971 | ||
|
|
c1b886e77f | ||
|
|
31b332a87f | ||
|
|
b6afd5fbb8 | ||
|
|
7b74975819 | ||
|
|
1246f8f77b | ||
|
|
7bb7e8b636 | ||
|
|
efbd8e9bd1 | ||
|
|
3582807910 | ||
|
|
fcc3daf904 | ||
|
|
736fa21410 | ||
|
|
8b0cf671b5 | ||
|
|
c713828037 | ||
|
|
8571fc43b0 | ||
|
|
59aabd956d | ||
|
|
9b09ba4483 | ||
|
|
946b148cfa | ||
|
|
62abaedbdb | ||
|
|
1f859c45fa | ||
|
|
2a5c45e15c | ||
|
|
1f643874a9 | ||
|
|
20f9a8a497 | ||
|
|
e5bbaf5f9a | ||
|
|
29e0d0437e | ||
|
|
fbd5b64345 | ||
|
|
884c4f39fd | ||
|
|
448856e547 | ||
|
|
07fa5626fd | ||
|
|
3c8aac0203 | ||
|
|
b84eabf1c9 | ||
|
|
35c96b3a9e | ||
|
|
ee1b37c787 | ||
|
|
2312f438ac | ||
|
|
63349395cf | ||
|
|
64ecf47310 | ||
|
|
686c3f9208 | ||
|
|
32d395fbab | ||
|
|
0ef6eb2502 | ||
|
|
56c8c3db9a | ||
|
|
f47ff98160 | ||
|
|
910dc5f3fb | ||
|
|
7c8e962a01 | ||
|
|
76d698f670 | ||
|
|
ba65f750d4 | ||
|
|
5776672901 | ||
|
|
8a7e2bd8e4 | ||
|
|
174c4ae749 | ||
|
|
67da9417a8 | ||
|
|
35e8549dcc | ||
|
|
bc8ee604fb | ||
|
|
2f6fd30fa7 | ||
|
|
e73f90bb05 | ||
|
|
9428b44e30 | ||
|
|
5c30bcdefa | ||
|
|
b427a77fc1 | ||
|
|
58071810d9 | ||
|
|
2ca75d7bf0 | ||
|
|
1cee71e18f | ||
|
|
935e86cdeb | ||
|
|
5fc59de0e9 | ||
|
|
2d68ff0d61 | ||
|
|
0ab5c46812 | ||
|
|
ff39e65d81 | ||
|
|
cc2f96b691 | ||
|
|
e4ab0bc359 | ||
|
|
cb94bc5eca | ||
|
|
efe744cfdd | ||
|
|
0626b65c74 | ||
|
|
f4a4ced88d | ||
|
|
296bcbd857 | ||
|
|
19b2d7af41 | ||
|
|
343d8a1c1e | ||
|
|
9480f8272a | ||
|
|
0d9e260a6a | ||
|
|
51bca25345 | ||
|
|
694396dcfb | ||
|
|
1cb53e943e | ||
|
|
13c8318adc | ||
|
|
48ed797055 | ||
|
|
a208034539 | ||
|
|
1383f63361 | ||
|
|
dbe8beb7f9 | ||
|
|
3c2285141c | ||
|
|
49b884c0b1 | ||
|
|
24d20ca9ee | ||
|
|
6f02181024 | ||
|
|
3566191cd1 | ||
|
|
ed3353a271 | ||
|
|
965f5f96b7 | ||
|
|
61d9df7f58 | ||
|
|
231a5169ec | ||
|
|
ce7b7b910a | ||
|
|
81a61558cb | ||
|
|
7d2bc2e885 | ||
|
|
89b237f6b4 | ||
|
|
a1bb132233 | ||
|
|
022d538940 | ||
|
|
ccf70a1b76 | ||
|
|
af3fe53ec8 | ||
|
|
e981fb159f | ||
|
|
79b9d55854 | ||
|
|
b2055a4457 | ||
|
|
1479f159aa | ||
|
|
7bf7e09002 | ||
|
|
de8d39ffed | ||
|
|
543a7e3962 | ||
|
|
9dfe3f5af8 | ||
|
|
f11b08d8cb | ||
|
|
45b6f08984 | ||
|
|
92a4676f8d | ||
|
|
7bf7c0bb06 | ||
|
|
8f8cf5b704 | ||
|
|
6be238430d | ||
|
|
f77216d8f4 | ||
|
|
d42a9b2409 | ||
|
|
6753834054 | ||
|
|
77a4a64eb4 | ||
|
|
49db40d557 | ||
|
|
0032c608f1 | ||
|
|
fa603b32b1 | ||
|
|
9105d4d14a | ||
|
|
c76db7d8d1 |
@@ -1,5 +0,0 @@
|
||||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
||||
|
||||
We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
||||
"changelog": [
|
||||
"@changesets/changelog-github",
|
||||
{ "repo": "vbenjs/vue-vben-admin" }
|
||||
],
|
||||
"commit": false,
|
||||
"fixed": [["@vben-core/*", "@vben/*"]],
|
||||
"snapshot": {
|
||||
"prereleaseTemplate": "{tag}-{datetime}"
|
||||
},
|
||||
"privatePackages": { "version": true, "tag": true },
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
14
.github/CODEOWNERS
vendored
14
.github/CODEOWNERS
vendored
@@ -1,14 +0,0 @@
|
||||
# default onwer
|
||||
* anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
|
||||
# vben core onwer
|
||||
/.github/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
/.vscode/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
/packages/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
/packages/@core/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
/internal/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
/scripts/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
|
||||
|
||||
# vben team onwer
|
||||
apps/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com @vbenjs/team-v5 jinmao88@qq.com
|
||||
docs/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com @vbenjs/team-v5 jinmao88@qq.com
|
||||
74
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
74
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,74 +0,0 @@
|
||||
name: 🐞 Bug Report
|
||||
description: Report an issue with Vben Admin to help us make it better.
|
||||
title: 'Bug: '
|
||||
labels: ['bug: pending triage']
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running?
|
||||
options:
|
||||
- Vben Admin V5
|
||||
- Vben Admin V2
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: bug-desc
|
||||
attributes:
|
||||
label: Describe the bug?
|
||||
description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
|
||||
placeholder: Bug Description
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproduction
|
||||
description: Please provide a link to [StackBlitz](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/basic?initialPath=__vitest__/) (you can also use [examples](https://github.com/vitest-dev/vitest/tree/main/examples)) or a github repo that can reproduce the problem you ran into. A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is required unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "needs reproduction" label. If no reproduction is provided after 3 days, it will be auto-closed.
|
||||
placeholder: Reproduction
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: System Info
|
||||
description: Output of `npx envinfo --system --npmPackages '{vue}' --binaries --browsers`
|
||||
render: shell
|
||||
placeholder: System, Binaries, Browsers
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Validations
|
||||
description: Before submitting the issue, please make sure you do the following
|
||||
# description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com).
|
||||
options:
|
||||
- label: Read the [docs](https://doc.vben.pro/)
|
||||
required: true
|
||||
- label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
|
||||
required: true
|
||||
- label: I have searched the [existing issues](https://github.com/vbenjs/vue-vben-admin/issues) and checked that my issue does not duplicate any existing issues.
|
||||
required: true
|
||||
- label: Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/vbenjs/vue-vben-admin/discussions) or join our [Discord Chat Server](https://discord.gg/8GuAdwDhj6).
|
||||
required: true
|
||||
- label: The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
|
||||
required: true
|
||||
38
.github/ISSUE_TEMPLATE/docs.yml
vendored
38
.github/ISSUE_TEMPLATE/docs.yml
vendored
@@ -1,38 +0,0 @@
|
||||
name: 📚 Documentation
|
||||
description: Report an issue with Vben Admin Website to help us make it better.
|
||||
title: 'Docs: '
|
||||
labels: [documentation]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this issue!
|
||||
- type: checkboxes
|
||||
id: documentation_is
|
||||
attributes:
|
||||
label: Documentation is
|
||||
options:
|
||||
- label: Missing
|
||||
- label: Outdated
|
||||
- label: Confusing
|
||||
- label: Not sure?
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Explain in Detail
|
||||
description: A clear and concise description of your suggestion. If you intend to submit a PR for this issue, tell us in the description. Thanks!
|
||||
placeholder: The description of ... page is not clear. I thought it meant ... but it wasn't.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: suggestion
|
||||
attributes:
|
||||
label: Your Suggestion for Changes
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please provide any reproduction steps that may need to be described. E.g. if it happens only when running the dev or build script make sure it's clear which one to use.
|
||||
placeholder: Run `pnpm install` followed by `pnpm run docs:dev`
|
||||
70
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
70
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -1,70 +0,0 @@
|
||||
name: ✨ New Feature Proposal
|
||||
description: Propose a new feature to be added to Vben Admin
|
||||
title: 'FEATURE: '
|
||||
labels: ['enhancement: pending triage']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for suggesting a feature for our project! Please fill out the information below to help us understand and implement your request!
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running?
|
||||
options:
|
||||
- Vben Admin V5
|
||||
- Vben Admin V2
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: A detailed description of the feature request.
|
||||
placeholder: Please describe the feature you would like to see, and why it would be useful.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
attributes:
|
||||
label: Proposed Solution
|
||||
description: A clear and concise description of what you want to happen.
|
||||
placeholder: Describe the solution you'd like to see
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Alternatives Considered
|
||||
description: |
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
placeholder: Describe any alternative solutions or features you've considered
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
placeholder: Any additional information
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
id: checkboxes
|
||||
attributes:
|
||||
label: Validations
|
||||
description: Before submitting the issue, please make sure you do the following
|
||||
options:
|
||||
- label: Read the [docs](https://doc.vben.pro/)
|
||||
required: true
|
||||
- label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
|
||||
required: true
|
||||
- label: I have searched the [existing issues](https://github.com/vbenjs/vue-vben-admin/issues) and checked that my issue does not duplicate any existing issues.
|
||||
required: true
|
||||
40
.github/actions/setup-node/action.yml
vendored
40
.github/actions/setup-node/action.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: 'Setup Node'
|
||||
|
||||
description: 'Setup node and pnpm'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v4
|
||||
name: Setup pnpm cache
|
||||
if: ${{ github.ref_name == 'main' }}
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- uses: actions/cache/restore@v4
|
||||
if: ${{ github.ref_name != 'main' }}
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pnpm install --frozen-lockfile
|
||||
89
.github/commit-convention.md
vendored
89
.github/commit-convention.md
vendored
@@ -1,89 +0,0 @@
|
||||
## Git Commit Message Convention
|
||||
|
||||
> This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular).
|
||||
|
||||
#### TL;DR:
|
||||
|
||||
Messages must be matched by the following regex:
|
||||
|
||||
```js
|
||||
/^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|build|ci|chore|types|wip): .{1,50}/;
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
Appears under "Features" header, `dev` subheader:
|
||||
|
||||
```
|
||||
feat(dev): add 'comments' option
|
||||
```
|
||||
|
||||
Appears under "Bug Fixes" header, `dev` subheader, with a link to issue #28:
|
||||
|
||||
```
|
||||
fix(dev): fix dev error
|
||||
|
||||
close #28
|
||||
```
|
||||
|
||||
Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:
|
||||
|
||||
```
|
||||
perf(build): remove 'foo' option
|
||||
|
||||
BREAKING CHANGE: The 'foo' option has been removed.
|
||||
```
|
||||
|
||||
The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.
|
||||
|
||||
```
|
||||
revert: feat(compiler): add 'comments' option
|
||||
|
||||
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
|
||||
```
|
||||
|
||||
### Full Message Format
|
||||
|
||||
A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The **header** is mandatory and the **scope** of the header is optional.
|
||||
|
||||
### Revert
|
||||
|
||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body, it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
|
||||
|
||||
### Type
|
||||
|
||||
If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However, if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.
|
||||
|
||||
Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.
|
||||
|
||||
### Scope
|
||||
|
||||
The scope could be anything specifying the place of the commit change. For example `dev`, `build`, `workflow`, `cli` etc...
|
||||
|
||||
### Subject
|
||||
|
||||
The subject contains a succinct description of the change:
|
||||
|
||||
- use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
- don't capitalize the first letter
|
||||
- no dot (.) at the end
|
||||
|
||||
### Body
|
||||
|
||||
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
### Footer
|
||||
|
||||
The footer should contain any information about **Breaking Changes** and is also the place to reference GitHub issues that this commit **Closes**.
|
||||
|
||||
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
|
||||
39
.github/config.yml
vendored
39
.github/config.yml
vendored
@@ -1,39 +0,0 @@
|
||||
# Prevent issues being created without using the template
|
||||
blank_issues_enabled: false
|
||||
checkIssueTemplate: true
|
||||
checkPullRequestTemplate: true
|
||||
|
||||
contact_links:
|
||||
- name: 💬 Discord Chat
|
||||
url: https://discord.gg/8GuAdwDhj6
|
||||
about: Ask questions and discuss with other Vben users in real time.
|
||||
|
||||
- name: ❓ Questions & Discussions
|
||||
url: https://github.com/@vbenjs/vue-vben-admin/discussions
|
||||
about: Use GitHub discussions for message-board style questions and discussions.
|
||||
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for opening this pull request! 💖
|
||||
Please be patient and we will get back to you as soon as we can.
|
||||
|
||||
# Comment to be posted to on pull requests merged by a first time user
|
||||
firstPRMergeComment: >
|
||||
Thanks for your contribution! 🎉🎉🎉
|
||||
|
||||
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: >
|
||||
Thanks for opening your first issue! Be sure to follow the issue template and provide every bit of information to help the developers!
|
||||
|
||||
|
||||
# *OPTIONAL* default titles to check against for lack of descriptiveness
|
||||
# MUST BE ALL LOWERCASE
|
||||
requestInfoDefaultTitles:
|
||||
- update readme.md
|
||||
- updates
|
||||
|
||||
# *Required* Comment to reply with
|
||||
requestInfoReplyComment: >
|
||||
Thanks for filing this issue/PR! It would be much appreciated if you could provide us with more information so we can effectively analyze the situation in context.
|
||||
|
||||
40
.github/contributing.md
vendored
40
.github/contributing.md
vendored
@@ -1,40 +0,0 @@
|
||||
# Vben Admin Contributing Guide
|
||||
|
||||
Hi! We're really excited that you are interested in contributing to Vben Admin. Before submitting your contribution, please make sure to take a moment and read through the following guidelines:
|
||||
|
||||
- [Pull Request Guidelines](#pull-request-guidelines)
|
||||
|
||||
## Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
||||
|
||||
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
- Checkout a topic branch from the relevant branch, e.g. main, and merge back against that branch.
|
||||
|
||||
- If adding a new feature:
|
||||
- Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it.
|
||||
|
||||
- If fixing bug:
|
||||
- Provide a detailed description of the bug in the PR. Live demo preferred.
|
||||
|
||||
- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging.
|
||||
|
||||
## Development Setup
|
||||
|
||||
You will need [pnpm](https://pnpm.io/)
|
||||
|
||||
After cloning the repo, run:
|
||||
|
||||
```bash
|
||||
# install the dependencies of the project
|
||||
$ pnpm install
|
||||
# start the project
|
||||
$ pnpm run dev
|
||||
```
|
||||
17
.github/dependabot.yml
vendored
17
.github/dependabot.yml
vendored
@@ -1,17 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: daily
|
||||
groups:
|
||||
non-breaking-changes:
|
||||
update-types: [minor, patch]
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
non-breaking-changes:
|
||||
update-types: [minor, patch]
|
||||
33
.github/pull_request_template.md
vendored
33
.github/pull_request_template.md
vendored
@@ -1,33 +0,0 @@
|
||||
## Description
|
||||
|
||||
<!-- Please describe the change as necessary. If it's a feature or enhancement please be as detailed as possible. If it's a bug fix, please link the issue that it fixes or describe the bug in as much detail.
|
||||
|
||||
-->
|
||||
|
||||
<!-- You can also add additional context here -->
|
||||
|
||||
## Type of change
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
- [ ] Please, don't make changes to `pnpm-lock.yaml` unless you introduce a new test example.
|
||||
|
||||
## Checklist
|
||||
|
||||
> ℹ️ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in [CONTRIBUTING](contributing.md).
|
||||
|
||||
- [ ] If you introduce new functionality, document it. You can run documentation with `pnpm run docs:dev` command.
|
||||
- [ ] Run the tests with `pnpm test`.
|
||||
- [ ] Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with `feat:`, `fix:`, `perf:`, `docs:`, or `chore:`.
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] New and existing unit tests pass locally with my changes
|
||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
||||
61
.github/release-drafter.yml
vendored
61
.github/release-drafter.yml
vendored
@@ -1,61 +0,0 @@
|
||||
name-template: 'v$RESOLVED_VERSION'
|
||||
tag-template: 'v$RESOLVED_VERSION'
|
||||
version-template: $MAJOR.$MINOR.$PATCH
|
||||
change-template: '* $TITLE (#$NUMBER) @$AUTHOR'
|
||||
template: |
|
||||
# What's Changed
|
||||
|
||||
$CHANGES
|
||||
|
||||
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
|
||||
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'feature'
|
||||
- title: '🐞 Bug Fixes'
|
||||
labels:
|
||||
- 'bug'
|
||||
- title: '📈 Performance & Enhancement'
|
||||
labels:
|
||||
- 'perf'
|
||||
- 'enhancement'
|
||||
- title: 📝 Documentation
|
||||
labels:
|
||||
- 'documentation'
|
||||
- title: 👻 Maintenance
|
||||
labels:
|
||||
- 'chore'
|
||||
- 'dependencies'
|
||||
# collapse-after: 12
|
||||
- title: 🚦 Tests
|
||||
labels:
|
||||
- 'tests'
|
||||
- title: 'Breaking'
|
||||
label: 'breaking'
|
||||
|
||||
version-resolver:
|
||||
major:
|
||||
labels:
|
||||
- 'major'
|
||||
- 'breaking'
|
||||
minor:
|
||||
labels:
|
||||
- 'minor'
|
||||
patch:
|
||||
labels:
|
||||
- 'feature'
|
||||
- 'patch'
|
||||
- 'bug'
|
||||
- 'maintenance'
|
||||
- 'docs'
|
||||
- 'dependencies'
|
||||
- 'security'
|
||||
|
||||
exclude-labels:
|
||||
- 'skip-changelog'
|
||||
- 'no-changelog'
|
||||
- 'changelog'
|
||||
- 'bump versions'
|
||||
- 'reverted'
|
||||
- 'invalid'
|
||||
13
.github/semantic.yml
vendored
13
.github/semantic.yml
vendored
@@ -1,13 +0,0 @@
|
||||
titleAndCommits: true
|
||||
types:
|
||||
- feat
|
||||
- fix
|
||||
- docs
|
||||
- chore
|
||||
- style
|
||||
- refactor
|
||||
- perf
|
||||
- test
|
||||
- build
|
||||
- ci
|
||||
- revert
|
||||
48
.github/workflows/build.yml
vendored
48
.github/workflows/build.yml
vendored
@@ -1,48 +0,0 @@
|
||||
# name: Dependabot post-update
|
||||
name: Build detection
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
HUSKY: '0'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
post-update:
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
# if: ${{ github.actor == 'dependabot[bot]' }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
# - macos-latest
|
||||
- windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Checkout out pull request
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr checkout ${{ github.event.pull_request.number }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
pnpm run build
|
||||
42
.github/workflows/changeset-version.yml
vendored
42
.github/workflows/changeset-version.yml
vendored
@@ -1,42 +0,0 @@
|
||||
# https://github.com/changesets/action
|
||||
name: Changeset version
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
|
||||
env:
|
||||
CI: true
|
||||
|
||||
jobs:
|
||||
version:
|
||||
if: (github.event.pull_request.merged || github.event_name == 'workflow_dispatch') && github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
|
||||
# if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Create Release Pull Request
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
version: pnpm run version
|
||||
commit: 'chore: bump versions'
|
||||
title: 'chore: bump versions'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
125
.github/workflows/ci.yml
vendored
125
.github/workflows/ci.yml
vendored
@@ -1,125 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- 'releases/*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
TZ: Asia/Shanghai
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
# - macos-latest
|
||||
- windows-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
# - name: Check Git version
|
||||
# run: git --version
|
||||
|
||||
# - name: Setup mock Git user
|
||||
# run: git config --global user.email "you@example.com" && git config --global user.name "Your Name"
|
||||
|
||||
- name: Vitest tests
|
||||
run: pnpm run test:unit
|
||||
|
||||
# - name: Upload coverage
|
||||
# uses: codecov/codecov-action@v4
|
||||
# with:
|
||||
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
# - macos-latest
|
||||
- windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Lint
|
||||
run: pnpm run lint
|
||||
|
||||
check:
|
||||
name: Check
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
# - macos-latest
|
||||
- windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm check:type
|
||||
|
||||
# From https://github.com/rhysd/actionlint/blob/main/docs/usage.md#use-actionlint-on-github-actions
|
||||
- name: Check workflow files
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
|
||||
./actionlint -color -shellcheck=""
|
||||
|
||||
ci-ok:
|
||||
name: CI OK
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test, check, lint]
|
||||
env:
|
||||
FAILURE: ${{ contains(join(needs.*.result, ','), 'failure') }}
|
||||
steps:
|
||||
- name: Check for failure
|
||||
run: |
|
||||
echo $FAILURE
|
||||
if [ "$FAILURE" = "false" ]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
94
.github/workflows/codeql.yml
vendored
94
.github/workflows/codeql.yml
vendored
@@ -1,94 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
schedule:
|
||||
- cron: '35 0 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: '/language:${{matrix.language}}'
|
||||
172
.github/workflows/deploy.yml
vendored
172
.github/workflows/deploy.yml
vendored
@@ -1,172 +0,0 @@
|
||||
name: Deploy Website on push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
deploy-playground-ftp:
|
||||
name: Deploy Push Playground Ftp
|
||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Sed Config Base
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./playground/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./playground/.env.production
|
||||
cat ./playground/.env.production
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Build
|
||||
run: pnpm build:play
|
||||
|
||||
- name: Sync Playground files
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
|
||||
with:
|
||||
server: ${{ secrets.PRO_FTP_HOST }}
|
||||
username: ${{ secrets.WEB_PLAYGROUND_FTP_ACCOUNT }}
|
||||
password: ${{ secrets.WEB_PLAYGROUND_FTP_PWSSWORD }}
|
||||
local-dir: ./playground/dist/
|
||||
|
||||
deploy-docs-ftp:
|
||||
name: Deploy Push Docs Ftp
|
||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Build
|
||||
run: pnpm build:docs
|
||||
|
||||
- name: Sync Docs files
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
|
||||
with:
|
||||
server: ${{ secrets.PRO_FTP_HOST }}
|
||||
username: ${{ secrets.WEBSITE_FTP_ACCOUNT }}
|
||||
password: ${{ secrets.WEBSITE_FTP_PASSWORD }}
|
||||
local-dir: ./docs/.vitepress/dist/
|
||||
|
||||
deploy-antd-ftp:
|
||||
name: Deploy Push Antd Ftp
|
||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Sed Config Base
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-antd/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-antd/.env.production
|
||||
cat ./apps/web-antd/.env.production
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build:antd
|
||||
|
||||
- name: Sync files
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
|
||||
with:
|
||||
server: ${{ secrets.PRO_FTP_HOST }}
|
||||
username: ${{ secrets.WEB_ANTD_FTP_ACCOUNT }}
|
||||
password: ${{ secrets.WEB_ANTD_FTP_PASSWORD }}
|
||||
local-dir: ./apps/web-antd/dist/
|
||||
|
||||
deploy-ele-ftp:
|
||||
name: Deploy Push Element Ftp
|
||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Sed Config Base
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-ele/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-ele/.env.production
|
||||
cat ./apps/web-ele/.env.production
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build:ele
|
||||
|
||||
- name: Sync files
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
|
||||
with:
|
||||
server: ${{ secrets.PRO_FTP_HOST }}
|
||||
username: ${{ secrets.WEB_ELE_FTP_ACCOUNT }}
|
||||
password: ${{ secrets.WEB_ELE_FTP_PASSWORD }}
|
||||
local-dir: ./apps/web-ele/dist/
|
||||
|
||||
deploy-naive-ftp:
|
||||
name: Deploy Push Naive Ftp
|
||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Sed Config Base
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-naive/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-naive/.env.production
|
||||
cat ./apps/web-naive/.env.production
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build:naive
|
||||
|
||||
- name: Sync files
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
|
||||
with:
|
||||
server: ${{ secrets.PRO_FTP_HOST }}
|
||||
username: ${{ secrets.WEB_NAIVE_FTP_ACCOUNT }}
|
||||
password: ${{ secrets.WEB_NAIVE_FTP_PASSWORD }}
|
||||
local-dir: ./apps/web-naive/dist/
|
||||
|
||||
rerun-on-failure:
|
||||
name: Rerun on failure
|
||||
needs:
|
||||
- deploy-playground-ftp
|
||||
- deploy-docs-ftp
|
||||
- deploy-antd-ftp
|
||||
- deploy-ele-ftp
|
||||
- deploy-naive-ftp
|
||||
if: failure() && fromJSON(github.run_attempt) < 10
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Retry ${{ fromJSON(github.run_attempt) }} of 10
|
||||
env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: gh workflow run rerun.yml -F run_id=${{ github.run_id }}
|
||||
25
.github/workflows/draft.yml
vendored
25
.github/workflows/draft.yml
vendored
@@ -1,25 +0,0 @@
|
||||
name: Release Drafter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
permissions:
|
||||
# write permission is required to create a github release
|
||||
contents: write
|
||||
# write permission is required for autolabeler
|
||||
# otherwise, read permission is required at least
|
||||
pull-requests: write
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: release-drafter/release-drafter@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
31
.github/workflows/issue-close-require.yml
vendored
31
.github/workflows/issue-close-require.yml
vendored
@@ -1,31 +0,0 @@
|
||||
# 每天零点运行一次,它会检查所有带有 "need reproduction" 标签的 Issues。如果这些 Issues 在过去的 3 天内没有任何活动,它们将会被自动关闭。这有助于保持 Issue 列表的整洁,并且提醒用户在必要时提供更多的信息。
|
||||
name: Issue Close Require
|
||||
|
||||
# 触发条件:每天零点
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# 关闭未活动的 Issues
|
||||
- name: Close Inactive Issues
|
||||
uses: actions/stale@v9
|
||||
with:
|
||||
days-before-stale: -1 # Issues and PR will never be flagged stale automatically.
|
||||
stale-issue-label: needs-reproduction # Label that flags an issue as stale.
|
||||
only-labels: needs-reproduction # Only process these issues
|
||||
days-before-issue-close: 3
|
||||
ignore-updates: true
|
||||
remove-stale-when-updated: false
|
||||
close-issue-message: This issue was closed because it was open for 3 days without a valid reproduction.
|
||||
close-issue-label: closed-by-action
|
||||
46
.github/workflows/issue-labeled.yml
vendored
46
.github/workflows/issue-labeled.yml
vendored
@@ -1,46 +0,0 @@
|
||||
name: Label Based Actions
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
# pull_request:
|
||||
# types: [labeled]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
reply-labeled:
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: remove enhancement pending
|
||||
if: github.event.label.name == 'enhancement'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: 'enhancement: pending triage'
|
||||
|
||||
- name: remove bug pending
|
||||
if: github.event.label.name == 'bug'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: 'bug: pending triage'
|
||||
|
||||
- name: needs reproduction
|
||||
if: github.event.label.name == 'needs reproduction'
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: 'create-comment, remove-labels'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hello @${{ github.event.issue.user.login }}. Please provide the complete reproduction steps and code. Issues labeled by `needs reproduction` will be closed if no activities in 3 days.
|
||||
labels: 'bug: pending triage'
|
||||
24
.github/workflows/lock.yml
vendored
24
.github/workflows/lock.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Lock Threads
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
action:
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-inactive-days: '14'
|
||||
issue-lock-reason: ''
|
||||
pr-inactive-days: '30'
|
||||
pr-lock-reason: ''
|
||||
process-only: 'issues, prs'
|
||||
80
.github/workflows/release-tag.yml
vendored
80
.github/workflows/release-tag.yml
vendored
@@ -1,80 +0,0 @@
|
||||
name: Create Release Tag
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
env:
|
||||
HUSKY: '0'
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Create Release
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
|
||||
# - name: Install pnpm
|
||||
# uses: pnpm/action-setup@v4
|
||||
|
||||
# - name: Use Node.js ${{ matrix.node-version }}
|
||||
# uses: actions/setup-node@v4
|
||||
# with:
|
||||
# node-version: ${{ matrix.node-version }}
|
||||
# cache: "pnpm"
|
||||
|
||||
# - name: Install dependencies
|
||||
# run: pnpm install --frozen-lockfile
|
||||
|
||||
# - name: Test and Build
|
||||
# run: |
|
||||
# pnpm run test
|
||||
# pnpm run build
|
||||
|
||||
- name: version
|
||||
id: version
|
||||
run: |
|
||||
tag=${GITHUB_REF/refs\/tags\//}
|
||||
version=${tag#v}
|
||||
major=${version%%.*}
|
||||
echo "tag=${tag}" >> $GITHUB_OUTPUT
|
||||
echo "version=${version}" >> $GITHUB_OUTPUT
|
||||
echo "major=${major}" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: release-drafter/release-drafter@v6
|
||||
with:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
publish: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# - name: force update major tag
|
||||
# run: |
|
||||
# git tag v${{ steps.version.outputs.major }} ${{ steps.version.outputs.tag }} -f
|
||||
# git push origin refs/tags/v${{ steps.version.outputs.major }} -f
|
||||
|
||||
# - name: Create Release for Tag
|
||||
# id: release_tag
|
||||
# uses: ncipollo/release-action@v1
|
||||
# with:
|
||||
# token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# generateReleaseNotes: "true"
|
||||
# body: |
|
||||
# > Please refer to [CHANGELOG.md](https://github.com/vbenjs/vue-vben-admin/blob/main/CHANGELOG.md) for details.
|
||||
19
.github/workflows/rerun.yml
vendored
19
.github/workflows/rerun.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: Rerun workflow
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_id:
|
||||
description: The workflow id to relanch
|
||||
required: true
|
||||
jobs:
|
||||
rerun:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: rerun ${{ inputs.run_id }}
|
||||
env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh run watch ${{ inputs.run_id }} > /dev/null 2>&1
|
||||
gh run rerun ${{ inputs.run_id }} --failed
|
||||
41
.github/workflows/semantic-pull-request.yml
vendored
41
.github/workflows/semantic-pull-request.yml
vendored
@@ -1,41 +0,0 @@
|
||||
name: Semantic Pull Request
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Semantic Pull Request
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate PR title
|
||||
uses: amannn/action-semantic-pull-request@v5
|
||||
with:
|
||||
wip: true
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
subjectPatternError: |
|
||||
The subject "{subject}" found in the pull request title "{title}"
|
||||
didn't match the configured pattern. Please ensure that the subject
|
||||
doesn't start with an uppercase character.
|
||||
requireScope: false
|
||||
types: |
|
||||
fix
|
||||
feat
|
||||
docs
|
||||
style
|
||||
refactor
|
||||
perf
|
||||
test
|
||||
build
|
||||
ci
|
||||
chore
|
||||
revert
|
||||
types
|
||||
release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
19
.github/workflows/stale.yml
vendored
19
.github/workflows/stale.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: 'Close stale issues'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||
exempt-issue-labels: 'bug,enhancement'
|
||||
days-before-stale: 60
|
||||
days-before-close: 7
|
||||
@@ -1 +1 @@
|
||||
22.1.0
|
||||
22.22.0
|
||||
|
||||
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@@ -2,15 +2,6 @@
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"name": "vben admin playground dev",
|
||||
"request": "launch",
|
||||
"url": "http://localhost:5555",
|
||||
"env": { "NODE_ENV": "development" },
|
||||
"sourceMaps": true,
|
||||
"webRoot": "${workspaceFolder}/playground"
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
"name": "vben admin antd dev",
|
||||
|
||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[html]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"editor.defaultFormatter": "vscode.html-language-features"
|
||||
},
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
@@ -181,7 +181,8 @@
|
||||
"markdown",
|
||||
"json",
|
||||
"jsonc",
|
||||
"json5"
|
||||
"json5",
|
||||
"yaml"
|
||||
],
|
||||
|
||||
"tailwindCSS.experimental.classRegex": [
|
||||
@@ -199,7 +200,6 @@
|
||||
|
||||
"i18n-ally.localesPaths": [
|
||||
"packages/locales/src/langs",
|
||||
"playground/src/locales/langs",
|
||||
"apps/*/src/locales/langs"
|
||||
],
|
||||
"i18n-ally.pathMatcher": "{locale}/{namespace}.{ext}",
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
dev中 未发布
|
||||
|
||||
**REFACTOR**
|
||||
|
||||
- 使用antd组件替换密码登录表单
|
||||
|
||||
**FEATURES**
|
||||
|
||||
- 合并官方更新 将Radix(v1)替换为Reka UI(v2)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
## 提示
|
||||
|
||||
该分支使用[antdv-next](https://github.com/antdv-next/antdv-next)替代已经不维护的antd-design-vue
|
||||
|
||||
该仓库使用vben最新版本v5开发
|
||||
|
||||
v5版本采用分仓(包)目录结构, 具体开发路径为: `根目录/apps/web-antd`
|
||||
@@ -14,13 +16,13 @@ V1.2.0版本对接warmflow工作流
|
||||
|
||||
## 简介
|
||||
|
||||
基于 [vben5 & ant-design-vue](https://github.com/vbenjs/vue-vben-admin) 的 RuoYi-Vue-Plus 前端项目
|
||||
基于 [vben5 & antdv-next](https://github.com/vbenjs/vue-vben-admin) 的 RuoYi-Vue-Plus 前端项目
|
||||
|
||||
| 组件/框架 | 版本 |
|
||||
| :------------- | :----- |
|
||||
| vben | 5.5.9 |
|
||||
| ant-design-vue | 4.2.6 |
|
||||
| vue | 3.5.13 |
|
||||
| 组件/框架 | 版本 |
|
||||
| :--------- | :----- |
|
||||
| vben | 5.5.9 |
|
||||
| antdv-next | 4.2.6 |
|
||||
| vue | 3.5.13 |
|
||||
|
||||
对应后端项目: **(分布式 5.X 分支 微服务 2.分支)**
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
PORT=5320
|
||||
ACCESS_TOKEN_SECRET=access_token_secret
|
||||
REFRESH_TOKEN_SECRET=refresh_token_secret
|
||||
@@ -1,15 +0,0 @@
|
||||
# @vben/backend-mock
|
||||
|
||||
## Description
|
||||
|
||||
Vben Admin 数据 mock 服务,没有对接任何的数据库,所有数据都是模拟的,用于前端开发时提供数据支持。线上环境不再提供 mock 集成,可自行部署服务或者对接真实数据,由于 `mock.js` 等工具有一些限制,比如上传文件不行、无法模拟复杂的逻辑等,所以这里使用了真实的后端服务来实现。唯一麻烦的是本地需要同时启动后端服务和前端服务,但是这样可以更好的模拟真实环境。该服务不需要手动启动,已经集成在 vite 插件内,随应用一起启用。
|
||||
|
||||
## Running the app
|
||||
|
||||
```bash
|
||||
# development
|
||||
$ pnpm run start
|
||||
|
||||
# production mode
|
||||
$ pnpm run build
|
||||
```
|
||||
@@ -1,16 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_CODES } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
|
||||
const codes =
|
||||
MOCK_CODES.find((item) => item.username === userinfo.username)?.codes ?? [];
|
||||
|
||||
return useResponseSuccess(codes);
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
import { defineEventHandler, readBody, setResponseStatus } from 'h3';
|
||||
import {
|
||||
clearRefreshTokenCookie,
|
||||
setRefreshTokenCookie,
|
||||
} from '~/utils/cookie-utils';
|
||||
import { generateAccessToken, generateRefreshToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_USERS } from '~/utils/mock-data';
|
||||
import {
|
||||
forbiddenResponse,
|
||||
useResponseError,
|
||||
useResponseSuccess,
|
||||
} from '~/utils/response';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { password, username } = await readBody(event);
|
||||
if (!password || !username) {
|
||||
setResponseStatus(event, 400);
|
||||
return useResponseError(
|
||||
'BadRequestException',
|
||||
'Username and password are required',
|
||||
);
|
||||
}
|
||||
|
||||
const findUser = MOCK_USERS.find(
|
||||
(item) => item.username === username && item.password === password,
|
||||
);
|
||||
|
||||
if (!findUser) {
|
||||
clearRefreshTokenCookie(event);
|
||||
return forbiddenResponse(event, 'Username or password is incorrect.');
|
||||
}
|
||||
|
||||
const accessToken = generateAccessToken(findUser);
|
||||
const refreshToken = generateRefreshToken(findUser);
|
||||
|
||||
setRefreshTokenCookie(event, refreshToken);
|
||||
|
||||
return useResponseSuccess({
|
||||
...findUser,
|
||||
accessToken,
|
||||
});
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
import { defineEventHandler } from 'h3';
|
||||
import {
|
||||
clearRefreshTokenCookie,
|
||||
getRefreshTokenFromCookie,
|
||||
} from '~/utils/cookie-utils';
|
||||
import { useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const refreshToken = getRefreshTokenFromCookie(event);
|
||||
if (!refreshToken) {
|
||||
return useResponseSuccess('');
|
||||
}
|
||||
|
||||
clearRefreshTokenCookie(event);
|
||||
|
||||
return useResponseSuccess('');
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
import { defineEventHandler } from 'h3';
|
||||
import {
|
||||
clearRefreshTokenCookie,
|
||||
getRefreshTokenFromCookie,
|
||||
setRefreshTokenCookie,
|
||||
} from '~/utils/cookie-utils';
|
||||
import { generateAccessToken, verifyRefreshToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_USERS } from '~/utils/mock-data';
|
||||
import { forbiddenResponse } from '~/utils/response';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const refreshToken = getRefreshTokenFromCookie(event);
|
||||
if (!refreshToken) {
|
||||
return forbiddenResponse(event);
|
||||
}
|
||||
|
||||
clearRefreshTokenCookie(event);
|
||||
|
||||
const userinfo = verifyRefreshToken(refreshToken);
|
||||
if (!userinfo) {
|
||||
return forbiddenResponse(event);
|
||||
}
|
||||
|
||||
const findUser = MOCK_USERS.find(
|
||||
(item) => item.username === userinfo.username,
|
||||
);
|
||||
if (!findUser) {
|
||||
return forbiddenResponse(event);
|
||||
}
|
||||
const accessToken = generateAccessToken(findUser);
|
||||
|
||||
setRefreshTokenCookie(event, refreshToken);
|
||||
|
||||
return accessToken;
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
import { eventHandler, setHeader } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { unAuthorizedResponse } from '~/utils/response';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
const data = `
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": [
|
||||
{
|
||||
"id": 123456789012345678901234567890123456789012345678901234567890,
|
||||
"name": "John Doe",
|
||||
"age": 30,
|
||||
"email": "john-doe@demo.com"
|
||||
},
|
||||
{
|
||||
"id": 987654321098765432109876543210987654321098765432109876543210,
|
||||
"name": "Jane Smith",
|
||||
"age": 25,
|
||||
"email": "jane@demo.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
`;
|
||||
setHeader(event, 'Content-Type', 'application/json');
|
||||
return data;
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_MENUS } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
|
||||
const menus =
|
||||
MOCK_MENUS.find((item) => item.username === userinfo.username)?.menus ?? [];
|
||||
return useResponseSuccess(menus);
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import { eventHandler, getQuery, setResponseStatus } from 'h3';
|
||||
import { useResponseError } from '~/utils/response';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const { status } = getQuery(event);
|
||||
setResponseStatus(event, Number(status));
|
||||
return useResponseError(`${status}`);
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import {
|
||||
sleep,
|
||||
unAuthorizedResponse,
|
||||
useResponseSuccess,
|
||||
} from '~/utils/response';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
await sleep(600);
|
||||
return useResponseSuccess(null);
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import {
|
||||
sleep,
|
||||
unAuthorizedResponse,
|
||||
useResponseSuccess,
|
||||
} from '~/utils/response';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
await sleep(1000);
|
||||
return useResponseSuccess(null);
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import {
|
||||
sleep,
|
||||
unAuthorizedResponse,
|
||||
useResponseSuccess,
|
||||
} from '~/utils/response';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
await sleep(2000);
|
||||
return useResponseSuccess(null);
|
||||
});
|
||||
@@ -1,62 +0,0 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
const formatterCN = new Intl.DateTimeFormat('zh-CN', {
|
||||
timeZone: 'Asia/Shanghai',
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
});
|
||||
|
||||
function generateMockDataList(count: number) {
|
||||
const dataList = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const dataItem: Record<string, any> = {
|
||||
id: faker.string.uuid(),
|
||||
pid: 0,
|
||||
name: faker.commerce.department(),
|
||||
status: faker.helpers.arrayElement([0, 1]),
|
||||
createTime: formatterCN.format(
|
||||
faker.date.between({ from: '2021-01-01', to: '2022-12-31' }),
|
||||
),
|
||||
remark: faker.lorem.sentence(),
|
||||
};
|
||||
if (faker.datatype.boolean()) {
|
||||
dataItem.children = Array.from(
|
||||
{ length: faker.number.int({ min: 1, max: 5 }) },
|
||||
() => ({
|
||||
id: faker.string.uuid(),
|
||||
pid: dataItem.id,
|
||||
name: faker.commerce.department(),
|
||||
status: faker.helpers.arrayElement([0, 1]),
|
||||
createTime: formatterCN.format(
|
||||
faker.date.between({ from: '2023-01-01', to: '2023-12-31' }),
|
||||
),
|
||||
remark: faker.lorem.sentence(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
dataList.push(dataItem);
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
const mockData = generateMockDataList(10);
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
|
||||
const listData = structuredClone(mockData);
|
||||
|
||||
return useResponseSuccess(listData);
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_MENU_LIST } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
|
||||
return useResponseSuccess(MOCK_MENU_LIST);
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import { eventHandler, getQuery } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_MENU_LIST } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
const namesMap: Record<string, any> = {};
|
||||
|
||||
function getNames(menus: any[]) {
|
||||
menus.forEach((menu) => {
|
||||
namesMap[menu.name] = String(menu.id);
|
||||
if (menu.children) {
|
||||
getNames(menu.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
getNames(MOCK_MENU_LIST);
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
const { id, name } = getQuery(event);
|
||||
|
||||
return (name as string) in namesMap &&
|
||||
(!id || namesMap[name as string] !== String(id))
|
||||
? useResponseSuccess(true)
|
||||
: useResponseSuccess(false);
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import { eventHandler, getQuery } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { MOCK_MENU_LIST } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
const pathMap: Record<string, any> = { '/': 0 };
|
||||
|
||||
function getPaths(menus: any[]) {
|
||||
menus.forEach((menu) => {
|
||||
pathMap[menu.path] = String(menu.id);
|
||||
if (menu.children) {
|
||||
getPaths(menu.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
getPaths(MOCK_MENU_LIST);
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
const { id, path } = getQuery(event);
|
||||
|
||||
return (path as string) in pathMap &&
|
||||
(!id || pathMap[path as string] !== String(id))
|
||||
? useResponseSuccess(true)
|
||||
: useResponseSuccess(false);
|
||||
});
|
||||
@@ -1,84 +0,0 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { eventHandler, getQuery } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { getMenuIds, MOCK_MENU_LIST } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response';
|
||||
|
||||
const formatterCN = new Intl.DateTimeFormat('zh-CN', {
|
||||
timeZone: 'Asia/Shanghai',
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
});
|
||||
|
||||
const menuIds = getMenuIds(MOCK_MENU_LIST);
|
||||
|
||||
function generateMockDataList(count: number) {
|
||||
const dataList = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const dataItem: Record<string, any> = {
|
||||
id: faker.string.uuid(),
|
||||
name: faker.commerce.product(),
|
||||
status: faker.helpers.arrayElement([0, 1]),
|
||||
createTime: formatterCN.format(
|
||||
faker.date.between({ from: '2022-01-01', to: '2025-01-01' }),
|
||||
),
|
||||
permissions: faker.helpers.arrayElements(menuIds),
|
||||
remark: faker.lorem.sentence(),
|
||||
};
|
||||
|
||||
dataList.push(dataItem);
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
const mockData = generateMockDataList(100);
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
|
||||
const {
|
||||
page = 1,
|
||||
pageSize = 20,
|
||||
name,
|
||||
id,
|
||||
remark,
|
||||
startTime,
|
||||
endTime,
|
||||
status,
|
||||
} = getQuery(event);
|
||||
let listData = structuredClone(mockData);
|
||||
if (name) {
|
||||
listData = listData.filter((item) =>
|
||||
item.name.toLowerCase().includes(String(name).toLowerCase()),
|
||||
);
|
||||
}
|
||||
if (id) {
|
||||
listData = listData.filter((item) =>
|
||||
item.id.toLowerCase().includes(String(id).toLowerCase()),
|
||||
);
|
||||
}
|
||||
if (remark) {
|
||||
listData = listData.filter((item) =>
|
||||
item.remark?.toLowerCase()?.includes(String(remark).toLowerCase()),
|
||||
);
|
||||
}
|
||||
if (startTime) {
|
||||
listData = listData.filter((item) => item.createTime >= startTime);
|
||||
}
|
||||
if (endTime) {
|
||||
listData = listData.filter((item) => item.createTime <= endTime);
|
||||
}
|
||||
if (['0', '1'].includes(status as string)) {
|
||||
listData = listData.filter((item) => item.status === Number(status));
|
||||
}
|
||||
return usePageResponseSuccess(page as string, pageSize as string, listData);
|
||||
});
|
||||
@@ -1,117 +0,0 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { eventHandler, getQuery } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import {
|
||||
sleep,
|
||||
unAuthorizedResponse,
|
||||
usePageResponseSuccess,
|
||||
} from '~/utils/response';
|
||||
|
||||
function generateMockDataList(count: number) {
|
||||
const dataList = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const dataItem = {
|
||||
id: faker.string.uuid(),
|
||||
imageUrl: faker.image.avatar(),
|
||||
imageUrl2: faker.image.avatar(),
|
||||
open: faker.datatype.boolean(),
|
||||
status: faker.helpers.arrayElement(['success', 'error', 'warning']),
|
||||
productName: faker.commerce.productName(),
|
||||
price: faker.commerce.price(),
|
||||
currency: faker.finance.currencyCode(),
|
||||
quantity: faker.number.int({ min: 1, max: 100 }),
|
||||
available: faker.datatype.boolean(),
|
||||
category: faker.commerce.department(),
|
||||
releaseDate: faker.date.past(),
|
||||
rating: faker.number.float({ min: 1, max: 5 }),
|
||||
description: faker.commerce.productDescription(),
|
||||
weight: faker.number.float({ min: 0.1, max: 10 }),
|
||||
color: faker.color.human(),
|
||||
inProduction: faker.datatype.boolean(),
|
||||
tags: Array.from({ length: 3 }, () => faker.commerce.productAdjective()),
|
||||
};
|
||||
|
||||
dataList.push(dataItem);
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
const mockData = generateMockDataList(100);
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
|
||||
await sleep(600);
|
||||
|
||||
const { page, pageSize, sortBy, sortOrder } = getQuery(event);
|
||||
// 规范化分页参数,处理 string[]
|
||||
const pageRaw = Array.isArray(page) ? page[0] : page;
|
||||
const pageSizeRaw = Array.isArray(pageSize) ? pageSize[0] : pageSize;
|
||||
const pageNumber = Math.max(
|
||||
1,
|
||||
Number.parseInt(String(pageRaw ?? '1'), 10) || 1,
|
||||
);
|
||||
const pageSizeNumber = Math.min(
|
||||
100,
|
||||
Math.max(1, Number.parseInt(String(pageSizeRaw ?? '10'), 10) || 10),
|
||||
);
|
||||
const listData = structuredClone(mockData);
|
||||
|
||||
// 规范化 query 入参,兼容 string[]
|
||||
const sortKeyRaw = Array.isArray(sortBy) ? sortBy[0] : sortBy;
|
||||
const sortOrderRaw = Array.isArray(sortOrder) ? sortOrder[0] : sortOrder;
|
||||
// 检查 sortBy 是否是 listData 元素的合法属性键
|
||||
if (
|
||||
typeof sortKeyRaw === 'string' &&
|
||||
listData[0] &&
|
||||
Object.prototype.hasOwnProperty.call(listData[0], sortKeyRaw)
|
||||
) {
|
||||
// 定义数组元素的类型
|
||||
type ItemType = (typeof listData)[0];
|
||||
const sortKey = sortKeyRaw as keyof ItemType; // 将 sortBy 断言为合法键
|
||||
const isDesc = sortOrderRaw === 'desc';
|
||||
listData.sort((a, b) => {
|
||||
const aValue = a[sortKey] as unknown;
|
||||
const bValue = b[sortKey] as unknown;
|
||||
|
||||
let result = 0;
|
||||
|
||||
if (typeof aValue === 'number' && typeof bValue === 'number') {
|
||||
result = aValue - bValue;
|
||||
} else if (aValue instanceof Date && bValue instanceof Date) {
|
||||
result = aValue.getTime() - bValue.getTime();
|
||||
} else if (typeof aValue === 'boolean' && typeof bValue === 'boolean') {
|
||||
if (aValue === bValue) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = aValue ? 1 : -1;
|
||||
}
|
||||
} else {
|
||||
const aStr = String(aValue);
|
||||
const bStr = String(bValue);
|
||||
const aNum = Number(aStr);
|
||||
const bNum = Number(bStr);
|
||||
result =
|
||||
Number.isFinite(aNum) && Number.isFinite(bNum)
|
||||
? aNum - bNum
|
||||
: aStr.localeCompare(bStr, undefined, {
|
||||
numeric: true,
|
||||
sensitivity: 'base',
|
||||
});
|
||||
}
|
||||
|
||||
return isDesc ? -result : result;
|
||||
});
|
||||
}
|
||||
|
||||
return usePageResponseSuccess(
|
||||
String(pageNumber),
|
||||
String(pageSizeNumber),
|
||||
listData,
|
||||
);
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
import { defineEventHandler } from 'h3';
|
||||
|
||||
export default defineEventHandler(() => 'Test get handler');
|
||||
@@ -1,3 +0,0 @@
|
||||
import { defineEventHandler } from 'h3';
|
||||
|
||||
export default defineEventHandler(() => 'Test post handler');
|
||||
@@ -1,12 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
import { getTimezone } from '~/utils/timezone-utils';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
return useResponseSuccess(getTimezone());
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { TIME_ZONE_OPTIONS } from '~/utils/mock-data';
|
||||
import { useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default eventHandler(() => {
|
||||
const data = TIME_ZONE_OPTIONS.map((o) => ({
|
||||
label: `${o.timezone} (GMT${o.offset >= 0 ? `+${o.offset}` : o.offset})`,
|
||||
value: o.timezone,
|
||||
}));
|
||||
return useResponseSuccess(data);
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import { eventHandler, readBody } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { TIME_ZONE_OPTIONS } from '~/utils/mock-data';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
import { setTimezone } from '~/utils/timezone-utils';
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
const body = await readBody<{ timezone?: unknown }>(event);
|
||||
const timezone =
|
||||
typeof body?.timezone === 'string' ? body.timezone : undefined;
|
||||
const allowed = TIME_ZONE_OPTIONS.some((o) => o.timezone === timezone);
|
||||
if (!timezone || !allowed) {
|
||||
setResponseStatus(event, 400);
|
||||
return useResponseError('Bad Request', 'Invalid timezone');
|
||||
}
|
||||
setTimezone(timezone);
|
||||
return useResponseSuccess({});
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
return useResponseSuccess({
|
||||
url: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
|
||||
});
|
||||
// return useResponseError("test")
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { eventHandler } from 'h3';
|
||||
import { verifyAccessToken } from '~/utils/jwt-utils';
|
||||
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const userinfo = verifyAccessToken(event);
|
||||
if (!userinfo) {
|
||||
return unAuthorizedResponse(event);
|
||||
}
|
||||
return useResponseSuccess(userinfo);
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
import type { NitroErrorHandler } from 'nitropack';
|
||||
|
||||
const errorHandler: NitroErrorHandler = function (error, event) {
|
||||
event.node.res.end(`[Error Handler] ${error.stack}`);
|
||||
};
|
||||
|
||||
export default errorHandler;
|
||||
@@ -1,20 +0,0 @@
|
||||
import { defineEventHandler } from 'h3';
|
||||
import { forbiddenResponse, sleep } from '~/utils/response';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
event.node.res.setHeader(
|
||||
'Access-Control-Allow-Origin',
|
||||
event.headers.get('Origin') ?? '*',
|
||||
);
|
||||
if (event.method === 'OPTIONS') {
|
||||
event.node.res.statusCode = 204;
|
||||
event.node.res.statusMessage = 'No Content.';
|
||||
return 'OK';
|
||||
} else if (
|
||||
['DELETE', 'PATCH', 'POST', 'PUT'].includes(event.method) &&
|
||||
event.path.startsWith('/api/system/')
|
||||
) {
|
||||
await sleep(Math.floor(Math.random() * 2000));
|
||||
return forbiddenResponse(event, '演示环境,禁止修改');
|
||||
}
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import errorHandler from './error';
|
||||
|
||||
process.env.COMPATIBILITY_DATE = new Date().toISOString();
|
||||
export default defineNitroConfig({
|
||||
devErrorHandler: errorHandler,
|
||||
errorHandler: '~/error',
|
||||
routeRules: {
|
||||
'/api/**': {
|
||||
cors: true,
|
||||
headers: {
|
||||
'Access-Control-Allow-Credentials': 'true',
|
||||
'Access-Control-Allow-Headers':
|
||||
'Accept, Authorization, Content-Length, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With',
|
||||
'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Expose-Headers': '*',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "@vben/backend-mock",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"author": "",
|
||||
"scripts": {
|
||||
"build": "nitro build",
|
||||
"start": "nitro dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@faker-js/faker": "catalog:",
|
||||
"jsonwebtoken": "catalog:",
|
||||
"nitropack": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "catalog:",
|
||||
"h3": "catalog:"
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { defineEventHandler } from 'h3';
|
||||
|
||||
export default defineEventHandler(() => {
|
||||
return `
|
||||
<h1>Hello Vben Admin</h1>
|
||||
<h2>Mock service is starting</h2>
|
||||
<ul>
|
||||
<li><a href="/api/user">/api/user/info</a></li>
|
||||
<li><a href="/api/menu">/api/menu/all</a></li>
|
||||
<li><a href="/api/auth/codes">/api/auth/codes</a></li>
|
||||
<li><a href="/api/auth/login">/api/auth/login</a></li>
|
||||
<li><a href="/api/upload">/api/upload</a></li>
|
||||
</ul>
|
||||
`;
|
||||
});
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "./.nitro/types/tsconfig.json"
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import type { EventHandlerRequest, H3Event } from 'h3';
|
||||
|
||||
import { deleteCookie, getCookie, setCookie } from 'h3';
|
||||
|
||||
export function clearRefreshTokenCookie(event: H3Event<EventHandlerRequest>) {
|
||||
deleteCookie(event, 'jwt', {
|
||||
httpOnly: true,
|
||||
sameSite: 'none',
|
||||
secure: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function setRefreshTokenCookie(
|
||||
event: H3Event<EventHandlerRequest>,
|
||||
refreshToken: string,
|
||||
) {
|
||||
setCookie(event, 'jwt', refreshToken, {
|
||||
httpOnly: true,
|
||||
maxAge: 24 * 60 * 60, // unit: seconds
|
||||
sameSite: 'none',
|
||||
secure: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function getRefreshTokenFromCookie(event: H3Event<EventHandlerRequest>) {
|
||||
const refreshToken = getCookie(event, 'jwt');
|
||||
return refreshToken;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
import type { EventHandlerRequest, H3Event } from 'h3';
|
||||
|
||||
import type { UserInfo } from './mock-data';
|
||||
|
||||
import { getHeader } from 'h3';
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
import { MOCK_USERS } from './mock-data';
|
||||
|
||||
// TODO: Replace with your own secret key
|
||||
const ACCESS_TOKEN_SECRET = 'access_token_secret';
|
||||
const REFRESH_TOKEN_SECRET = 'refresh_token_secret';
|
||||
|
||||
export interface UserPayload extends UserInfo {
|
||||
iat: number;
|
||||
exp: number;
|
||||
}
|
||||
|
||||
export function generateAccessToken(user: UserInfo) {
|
||||
return jwt.sign(user, ACCESS_TOKEN_SECRET, { expiresIn: '7d' });
|
||||
}
|
||||
|
||||
export function generateRefreshToken(user: UserInfo) {
|
||||
return jwt.sign(user, REFRESH_TOKEN_SECRET, {
|
||||
expiresIn: '30d',
|
||||
});
|
||||
}
|
||||
|
||||
export function verifyAccessToken(
|
||||
event: H3Event<EventHandlerRequest>,
|
||||
): null | Omit<UserInfo, 'password'> {
|
||||
const authHeader = getHeader(event, 'Authorization');
|
||||
if (!authHeader?.startsWith('Bearer')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tokenParts = authHeader.split(' ');
|
||||
if (tokenParts.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
const token = tokenParts[1] as string;
|
||||
try {
|
||||
const decoded = jwt.verify(
|
||||
token,
|
||||
ACCESS_TOKEN_SECRET,
|
||||
) as unknown as UserPayload;
|
||||
|
||||
const username = decoded.username;
|
||||
const user = MOCK_USERS.find((item) => item.username === username);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
const { password: _pwd, ...userinfo } = user;
|
||||
return userinfo;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function verifyRefreshToken(
|
||||
token: string,
|
||||
): null | Omit<UserInfo, 'password'> {
|
||||
try {
|
||||
const decoded = jwt.verify(token, REFRESH_TOKEN_SECRET) as UserPayload;
|
||||
const username = decoded.username;
|
||||
const user = MOCK_USERS.find(
|
||||
(item) => item.username === username,
|
||||
) as UserInfo;
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
const { password: _pwd, ...userinfo } = user;
|
||||
return userinfo;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,421 +0,0 @@
|
||||
export interface UserInfo {
|
||||
id: number;
|
||||
password: string;
|
||||
realName: string;
|
||||
roles: string[];
|
||||
username: string;
|
||||
homePath?: string;
|
||||
}
|
||||
|
||||
export interface TimezoneOption {
|
||||
offset: number;
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
export const MOCK_USERS: UserInfo[] = [
|
||||
{
|
||||
id: 0,
|
||||
password: '123456',
|
||||
realName: 'Vben',
|
||||
roles: ['super'],
|
||||
username: 'vben',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
password: '123456',
|
||||
realName: 'Admin',
|
||||
roles: ['admin'],
|
||||
username: 'admin',
|
||||
homePath: '/workspace',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
password: '123456',
|
||||
realName: 'Jack',
|
||||
roles: ['user'],
|
||||
username: 'jack',
|
||||
homePath: '/analytics',
|
||||
},
|
||||
];
|
||||
|
||||
export const MOCK_CODES = [
|
||||
// super
|
||||
{
|
||||
codes: ['AC_100100', 'AC_100110', 'AC_100120', 'AC_100010'],
|
||||
username: 'vben',
|
||||
},
|
||||
{
|
||||
// admin
|
||||
codes: ['AC_100010', 'AC_100020', 'AC_100030'],
|
||||
username: 'admin',
|
||||
},
|
||||
{
|
||||
// user
|
||||
codes: ['AC_1000001', 'AC_1000002'],
|
||||
username: 'jack',
|
||||
},
|
||||
];
|
||||
|
||||
const dashboardMenus = [
|
||||
{
|
||||
meta: {
|
||||
order: -1,
|
||||
title: 'page.dashboard.title',
|
||||
},
|
||||
name: 'Dashboard',
|
||||
path: '/dashboard',
|
||||
redirect: '/analytics',
|
||||
children: [
|
||||
{
|
||||
name: 'Analytics',
|
||||
path: '/analytics',
|
||||
component: '/dashboard/analytics/index',
|
||||
meta: {
|
||||
affixTab: true,
|
||||
title: 'page.dashboard.analytics',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Workspace',
|
||||
path: '/workspace',
|
||||
component: '/dashboard/workspace/index',
|
||||
meta: {
|
||||
title: 'page.dashboard.workspace',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const createDemosMenus = (role: 'admin' | 'super' | 'user') => {
|
||||
const roleWithMenus = {
|
||||
admin: {
|
||||
component: '/demos/access/admin-visible',
|
||||
meta: {
|
||||
icon: 'mdi:button-cursor',
|
||||
title: 'demos.access.adminVisible',
|
||||
},
|
||||
name: 'AccessAdminVisibleDemo',
|
||||
path: '/demos/access/admin-visible',
|
||||
},
|
||||
super: {
|
||||
component: '/demos/access/super-visible',
|
||||
meta: {
|
||||
icon: 'mdi:button-cursor',
|
||||
title: 'demos.access.superVisible',
|
||||
},
|
||||
name: 'AccessSuperVisibleDemo',
|
||||
path: '/demos/access/super-visible',
|
||||
},
|
||||
user: {
|
||||
component: '/demos/access/user-visible',
|
||||
meta: {
|
||||
icon: 'mdi:button-cursor',
|
||||
title: 'demos.access.userVisible',
|
||||
},
|
||||
name: 'AccessUserVisibleDemo',
|
||||
path: '/demos/access/user-visible',
|
||||
},
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
meta: {
|
||||
icon: 'ic:baseline-view-in-ar',
|
||||
keepAlive: true,
|
||||
order: 1000,
|
||||
title: 'demos.title',
|
||||
},
|
||||
name: 'Demos',
|
||||
path: '/demos',
|
||||
redirect: '/demos/access',
|
||||
children: [
|
||||
{
|
||||
name: 'AccessDemos',
|
||||
path: '/demosaccess',
|
||||
meta: {
|
||||
icon: 'mdi:cloud-key-outline',
|
||||
title: 'demos.access.backendPermissions',
|
||||
},
|
||||
redirect: '/demos/access/page-control',
|
||||
children: [
|
||||
{
|
||||
name: 'AccessPageControlDemo',
|
||||
path: '/demos/access/page-control',
|
||||
component: '/demos/access/index',
|
||||
meta: {
|
||||
icon: 'mdi:page-previous-outline',
|
||||
title: 'demos.access.pageAccess',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'AccessButtonControlDemo',
|
||||
path: '/demos/access/button-control',
|
||||
component: '/demos/access/button-control',
|
||||
meta: {
|
||||
icon: 'mdi:button-cursor',
|
||||
title: 'demos.access.buttonControl',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'AccessMenuVisible403Demo',
|
||||
path: '/demos/access/menu-visible-403',
|
||||
component: '/demos/access/menu-visible-403',
|
||||
meta: {
|
||||
authority: ['no-body'],
|
||||
icon: 'mdi:button-cursor',
|
||||
menuVisibleWithForbidden: true,
|
||||
title: 'demos.access.menuVisible403',
|
||||
},
|
||||
},
|
||||
roleWithMenus[role],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const MOCK_MENUS = [
|
||||
{
|
||||
menus: [...dashboardMenus, ...createDemosMenus('super')],
|
||||
username: 'vben',
|
||||
},
|
||||
{
|
||||
menus: [...dashboardMenus, ...createDemosMenus('admin')],
|
||||
username: 'admin',
|
||||
},
|
||||
{
|
||||
menus: [...dashboardMenus, ...createDemosMenus('user')],
|
||||
username: 'jack',
|
||||
},
|
||||
];
|
||||
|
||||
export const MOCK_MENU_LIST = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Workspace',
|
||||
status: 1,
|
||||
type: 'menu',
|
||||
icon: 'mdi:dashboard',
|
||||
path: '/workspace',
|
||||
component: '/dashboard/workspace/index',
|
||||
meta: {
|
||||
icon: 'carbon:workspace',
|
||||
title: 'page.dashboard.workspace',
|
||||
affixTab: true,
|
||||
order: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
meta: {
|
||||
icon: 'carbon:settings',
|
||||
order: 9997,
|
||||
title: 'system.title',
|
||||
badge: 'new',
|
||||
badgeType: 'normal',
|
||||
badgeVariants: 'primary',
|
||||
},
|
||||
status: 1,
|
||||
type: 'catalog',
|
||||
name: 'System',
|
||||
path: '/system',
|
||||
children: [
|
||||
{
|
||||
id: 201,
|
||||
pid: 2,
|
||||
path: '/system/menu',
|
||||
name: 'SystemMenu',
|
||||
authCode: 'System:Menu:List',
|
||||
status: 1,
|
||||
type: 'menu',
|
||||
meta: {
|
||||
icon: 'carbon:menu',
|
||||
title: 'system.menu.title',
|
||||
},
|
||||
component: '/system/menu/list',
|
||||
children: [
|
||||
{
|
||||
id: 20_101,
|
||||
pid: 201,
|
||||
name: 'SystemMenuCreate',
|
||||
status: 1,
|
||||
type: 'button',
|
||||
authCode: 'System:Menu:Create',
|
||||
meta: { title: 'common.create' },
|
||||
},
|
||||
{
|
||||
id: 20_102,
|
||||
pid: 201,
|
||||
name: 'SystemMenuEdit',
|
||||
status: 1,
|
||||
type: 'button',
|
||||
authCode: 'System:Menu:Edit',
|
||||
meta: { title: 'common.edit' },
|
||||
},
|
||||
{
|
||||
id: 20_103,
|
||||
pid: 201,
|
||||
name: 'SystemMenuDelete',
|
||||
status: 1,
|
||||
type: 'button',
|
||||
authCode: 'System:Menu:Delete',
|
||||
meta: { title: 'common.delete' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 202,
|
||||
pid: 2,
|
||||
path: '/system/dept',
|
||||
name: 'SystemDept',
|
||||
status: 1,
|
||||
type: 'menu',
|
||||
authCode: 'System:Dept:List',
|
||||
meta: {
|
||||
icon: 'carbon:container-services',
|
||||
title: 'system.dept.title',
|
||||
},
|
||||
component: '/system/dept/list',
|
||||
children: [
|
||||
{
|
||||
id: 20_401,
|
||||
pid: 202,
|
||||
name: 'SystemDeptCreate',
|
||||
status: 1,
|
||||
type: 'button',
|
||||
authCode: 'System:Dept:Create',
|
||||
meta: { title: 'common.create' },
|
||||
},
|
||||
{
|
||||
id: 20_402,
|
||||
pid: 202,
|
||||
name: 'SystemDeptEdit',
|
||||
status: 1,
|
||||
type: 'button',
|
||||
authCode: 'System:Dept:Edit',
|
||||
meta: { title: 'common.edit' },
|
||||
},
|
||||
{
|
||||
id: 20_403,
|
||||
pid: 202,
|
||||
name: 'SystemDeptDelete',
|
||||
status: 1,
|
||||
type: 'button',
|
||||
authCode: 'System:Dept:Delete',
|
||||
meta: { title: 'common.delete' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
meta: {
|
||||
badgeType: 'dot',
|
||||
order: 9998,
|
||||
title: 'demos.vben.title',
|
||||
icon: 'carbon:data-center',
|
||||
},
|
||||
name: 'Project',
|
||||
path: '/vben-admin',
|
||||
type: 'catalog',
|
||||
status: 1,
|
||||
children: [
|
||||
{
|
||||
id: 901,
|
||||
pid: 9,
|
||||
name: 'VbenDocument',
|
||||
path: '/vben-admin/document',
|
||||
component: 'IFrameView',
|
||||
type: 'embedded',
|
||||
status: 1,
|
||||
meta: {
|
||||
icon: 'carbon:book',
|
||||
iframeSrc: 'https://doc.vben.pro',
|
||||
title: 'demos.vben.document',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 902,
|
||||
pid: 9,
|
||||
name: 'VbenGithub',
|
||||
path: '/vben-admin/github',
|
||||
component: 'IFrameView',
|
||||
type: 'link',
|
||||
status: 1,
|
||||
meta: {
|
||||
icon: 'carbon:logo-github',
|
||||
link: 'https://github.com/vbenjs/vue-vben-admin',
|
||||
title: 'Github',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 903,
|
||||
pid: 9,
|
||||
name: 'VbenAntdv',
|
||||
path: '/vben-admin/antdv',
|
||||
component: 'IFrameView',
|
||||
type: 'link',
|
||||
status: 0,
|
||||
meta: {
|
||||
icon: 'carbon:hexagon-vertical-solid',
|
||||
badgeType: 'dot',
|
||||
link: 'https://ant.vben.pro',
|
||||
title: 'demos.vben.antdv',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
component: '_core/about/index',
|
||||
type: 'menu',
|
||||
status: 1,
|
||||
meta: {
|
||||
icon: 'lucide:copyright',
|
||||
order: 9999,
|
||||
title: 'demos.vben.about',
|
||||
},
|
||||
name: 'About',
|
||||
path: '/about',
|
||||
},
|
||||
];
|
||||
|
||||
export function getMenuIds(menus: any[]) {
|
||||
const ids: number[] = [];
|
||||
menus.forEach((item) => {
|
||||
ids.push(item.id);
|
||||
if (item.children && item.children.length > 0) {
|
||||
ids.push(...getMenuIds(item.children));
|
||||
}
|
||||
});
|
||||
return ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时区选项
|
||||
*/
|
||||
export const TIME_ZONE_OPTIONS: TimezoneOption[] = [
|
||||
{
|
||||
offset: -5,
|
||||
timezone: 'America/New_York',
|
||||
},
|
||||
{
|
||||
offset: 0,
|
||||
timezone: 'Europe/London',
|
||||
},
|
||||
{
|
||||
offset: 8,
|
||||
timezone: 'Asia/Shanghai',
|
||||
},
|
||||
{
|
||||
offset: 9,
|
||||
timezone: 'Asia/Tokyo',
|
||||
},
|
||||
{
|
||||
offset: 9,
|
||||
timezone: 'Asia/Seoul',
|
||||
},
|
||||
];
|
||||
@@ -1,70 +0,0 @@
|
||||
import type { EventHandlerRequest, H3Event } from 'h3';
|
||||
|
||||
import { setResponseStatus } from 'h3';
|
||||
|
||||
export function useResponseSuccess<T = any>(data: T) {
|
||||
return {
|
||||
code: 0,
|
||||
data,
|
||||
error: null,
|
||||
message: 'ok',
|
||||
};
|
||||
}
|
||||
|
||||
export function usePageResponseSuccess<T = any>(
|
||||
page: number | string,
|
||||
pageSize: number | string,
|
||||
list: T[],
|
||||
{ message = 'ok' } = {},
|
||||
) {
|
||||
const pageData = pagination(
|
||||
Number.parseInt(`${page}`),
|
||||
Number.parseInt(`${pageSize}`),
|
||||
list,
|
||||
);
|
||||
|
||||
return {
|
||||
...useResponseSuccess({
|
||||
items: pageData,
|
||||
total: list.length,
|
||||
}),
|
||||
message,
|
||||
};
|
||||
}
|
||||
|
||||
export function useResponseError(message: string, error: any = null) {
|
||||
return {
|
||||
code: -1,
|
||||
data: null,
|
||||
error,
|
||||
message,
|
||||
};
|
||||
}
|
||||
|
||||
export function forbiddenResponse(
|
||||
event: H3Event<EventHandlerRequest>,
|
||||
message = 'Forbidden Exception',
|
||||
) {
|
||||
setResponseStatus(event, 403);
|
||||
return useResponseError(message, message);
|
||||
}
|
||||
|
||||
export function unAuthorizedResponse(event: H3Event<EventHandlerRequest>) {
|
||||
setResponseStatus(event, 401);
|
||||
return useResponseError('Unauthorized Exception', 'Unauthorized Exception');
|
||||
}
|
||||
|
||||
export function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function pagination<T = any>(
|
||||
pageNo: number,
|
||||
pageSize: number,
|
||||
array: T[],
|
||||
): T[] {
|
||||
const offset = (pageNo - 1) * Number(pageSize);
|
||||
return offset + Number(pageSize) >= array.length
|
||||
? array.slice(offset)
|
||||
: array.slice(offset, offset + Number(pageSize));
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
let mockTimeZone: null | string = null;
|
||||
|
||||
export const setTimezone = (timeZone: string) => {
|
||||
mockTimeZone = timeZone;
|
||||
};
|
||||
|
||||
export const getTimezone = () => {
|
||||
return mockTimeZone;
|
||||
};
|
||||
@@ -1,7 +1,35 @@
|
||||
# public path
|
||||
VITE_BASE=/
|
||||
|
||||
# Basic interface address SPA
|
||||
VITE_GLOB_API_URL=/api
|
||||
# 是否开启压缩,可以设置为 none, brotli, gzip
|
||||
VITE_COMPRESS=gzip
|
||||
|
||||
# 是否开启 PWA
|
||||
VITE_PWA=false
|
||||
|
||||
# vue-router 的模式
|
||||
VITE_ROUTER_HISTORY=history
|
||||
|
||||
# 是否注入全局loading
|
||||
VITE_INJECT_APP_LOADING=true
|
||||
|
||||
# 打包后是否生成dist.zip
|
||||
VITE_ARCHIVER=true
|
||||
|
||||
# 后端接口地址
|
||||
VITE_GLOB_API_URL=/prod-api
|
||||
|
||||
# 全局加密开关(即开启了加解密功能才会生效 不是全部接口加密 需要和后端对应)
|
||||
VITE_GLOB_ENABLE_ENCRYPT=true
|
||||
# RSA公钥 请求加密使用 注意这两个是两对RSA公私钥 请求加密-后端解密是一对 响应解密-后端加密是一对
|
||||
VITE_GLOB_RSA_PUBLIC_KEY=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
|
||||
# RSA私钥 响应解密使用 注意这两个是两对RSA公私钥 请求加密-后端解密是一对 响应解密-后端加密是一对
|
||||
VITE_GLOB_RSA_PRIVATE_KEY=MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=
|
||||
# 客户端id
|
||||
# VITE_GLOB_APP_CLIENT_ID=e5cd7e4891bf95d1d19206ce24a7b32e
|
||||
VITE_GLOB_APP_CLIENT_ID=3fd880a0e6476add885c95bd5afd630f
|
||||
|
||||
# 开启SSE 具体消息逻辑: apps/web-antd/src/store/notify.ts
|
||||
VITE_GLOB_SSE_ENABLE=true
|
||||
# 开启websocket 具体消息逻辑: apps/web-antd/src/store/notify.ts
|
||||
VITE_GLOB_WEBSOCKET_ENABLE=false
|
||||
|
||||
VITE_VISUALIZER=true
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
VITE_PORT=5666
|
||||
|
||||
VITE_BASE=/
|
||||
# 是否开启 Nitro Mock服务,true 为开启,false 为关闭
|
||||
VITE_NITRO_MOCK=false
|
||||
# 是否打开 devtools,true 为打开,false 为关闭
|
||||
VITE_DEVTOOLS=false
|
||||
# 是否注入全局loading
|
||||
|
||||
@@ -25,7 +25,8 @@ VITE_GLOB_RSA_PUBLIC_KEY=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj6
|
||||
# RSA私钥 响应解密使用 注意这两个是两对RSA公私钥 请求加密-后端解密是一对 响应解密-后端加密是一对
|
||||
VITE_GLOB_RSA_PRIVATE_KEY=MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=
|
||||
# 客户端id
|
||||
VITE_GLOB_APP_CLIENT_ID=e5cd7e4891bf95d1d19206ce24a7b32e
|
||||
# VITE_GLOB_APP_CLIENT_ID=e5cd7e4891bf95d1d19206ce24a7b32e
|
||||
VITE_GLOB_APP_CLIENT_ID=3fd880a0e6476add885c95bd5afd630f
|
||||
|
||||
# 开启SSE 具体消息逻辑: apps/web-antd/src/store/notify.ts
|
||||
VITE_GLOB_SSE_ENABLE=true
|
||||
|
||||
290
apps/web-antd/loading.html
Normal file
290
apps/web-antd/loading.html
Normal file
@@ -0,0 +1,290 @@
|
||||
<style data-app-loading="inject-css">
|
||||
html {
|
||||
/* same as antdv-next/dist/reset.css setting, avoid the title line-height changed */
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.dark .loading {
|
||||
background-color: #0d0d10;
|
||||
}
|
||||
|
||||
.dark .loading .title {
|
||||
color: rgb(255 255 255 / 85%);
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
background-color: #f4f7f9;
|
||||
}
|
||||
|
||||
/* .loading.hidden {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.6s ease-out;
|
||||
} */
|
||||
|
||||
.loading .title {
|
||||
margin-top: 36px;
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
color: rgb(0 0 0 / 85%);
|
||||
}
|
||||
|
||||
#__app-loading__.hidden {
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.6s ease-out;
|
||||
}
|
||||
|
||||
/** 下面是自定义 **/
|
||||
/* From Uiverse.io by Admin12121 */
|
||||
.content {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content .planet {
|
||||
width: 65%;
|
||||
height: 65%;
|
||||
background-color: #546c8c;
|
||||
border-radius: 100%;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transform-origin: center center;
|
||||
box-shadow: inset 2px -10px 0px rgba(0, 0, 0, 0.1);
|
||||
animation: planet 5s ease infinite alternate;
|
||||
/* planet ring */
|
||||
/* to cover the back of the ring */
|
||||
/* planet spots */
|
||||
}
|
||||
|
||||
@keyframes planet {
|
||||
0% {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(-10deg);
|
||||
}
|
||||
}
|
||||
|
||||
.content .planet .ring {
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
border-radius: 100%;
|
||||
background-color: #bacbd9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform-origin: 33% center;
|
||||
box-shadow: 2px -10px 0px rgba(0, 0, 0, 0.1), inset -5px -10px 0px rgba(0, 0, 0, 0.1);
|
||||
animation: ring 3s ease infinite;
|
||||
/* small ball */
|
||||
/* inner ring */
|
||||
}
|
||||
|
||||
@keyframes ring {
|
||||
0% {
|
||||
transform: rotateX(110deg) rotateZ(0deg) translate(-50px, 5px);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotateX(110deg) rotateZ(360deg) translate(-50px, 5px);
|
||||
}
|
||||
}
|
||||
|
||||
.content .planet .ring:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 30px;
|
||||
border-radius: 100%;
|
||||
background-color: #7ea1bf;
|
||||
z-index: 2;
|
||||
left: calc(0px - 5px);
|
||||
box-shadow: inset -3px 3px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.content .planet .ring:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
border-radius: 100%;
|
||||
background-color: #7ea1bf;
|
||||
box-shadow: inset 2px -10px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.content .planet .cover-ring {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
border-bottom-left-radius: 80%;
|
||||
border-bottom-right-radius: 80%;
|
||||
border-top-left-radius: 100px;
|
||||
border-top-right-radius: 100px;
|
||||
transform: translate(0px, -17px);
|
||||
background-color: #546c8c;
|
||||
z-index: 2;
|
||||
box-shadow: inset 0px -2px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.content .planet .spots {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.content .planet .spots span {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #3c4359;
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
box-shadow: inset -2px 3px 0px rgba(0, 0, 0, 0.3);
|
||||
animation: dots 5s ease infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes dots {
|
||||
0% {
|
||||
box-shadow: inset -3px 3px 0px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: inset 3px 3px 0px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(1) {
|
||||
top: 20px;
|
||||
right: 50px;
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(2) {
|
||||
top: 40px;
|
||||
left: 50px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(3) {
|
||||
top: 80px;
|
||||
left: 20px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(4) {
|
||||
top: 80px;
|
||||
left: 90px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(5) {
|
||||
top: 160px;
|
||||
left: 70px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(6) {
|
||||
top: 165px;
|
||||
left: 125px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.content .planet .spots span:nth-child(7) {
|
||||
top: 90px;
|
||||
left: 150px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.content p {
|
||||
color: #bacbd9;
|
||||
font-size: 14px;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
animation: text 4s ease infinite;
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@keyframes text {
|
||||
0% {
|
||||
transform: translateX(-30px);
|
||||
letter-spacing: 0px;
|
||||
color: #bacbd9;
|
||||
}
|
||||
|
||||
25% {
|
||||
letter-spacing: 3px;
|
||||
color: #7ea1bf;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(30px);
|
||||
letter-spacing: 0px;
|
||||
color: #bacbd9;
|
||||
}
|
||||
|
||||
75% {
|
||||
letter-spacing: 3px;
|
||||
color: #7ea1bf;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(-30px);
|
||||
letter-spacing: 0px;
|
||||
color: #bacbd9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="loading" id="__app-loading__">
|
||||
<div class="content">
|
||||
<div class="planet">
|
||||
<div class="ring"></div>
|
||||
<div class="cover-ring"></div>
|
||||
<div class="spots">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<%= VITE_APP_TITLE %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-antd",
|
||||
"version": "1.5.2",
|
||||
"version": "2.0.0-alpha.3",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -27,8 +27,11 @@
|
||||
"#/*": "./src/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@tinymce/tinymce-vue": "^6.0.1",
|
||||
"@alova/adapter-axios": "catalog:",
|
||||
"@antdv-next/auto-import-resolver": "catalog:",
|
||||
"@antdv-next/happy-work-theme": "catalog:",
|
||||
"@antdv-next/icons": "catalog:",
|
||||
"@tinymce/tinymce-vue": "catalog:",
|
||||
"@vben/access": "workspace:*",
|
||||
"@vben/common-ui": "workspace:*",
|
||||
"@vben/constants": "workspace:*",
|
||||
@@ -44,19 +47,22 @@
|
||||
"@vben/types": "workspace:*",
|
||||
"@vben/utils": "workspace:*",
|
||||
"@vueuse/core": "catalog:",
|
||||
"ant-design-vue": "catalog:",
|
||||
"cropperjs": "^1.6.2",
|
||||
"alova": "catalog:",
|
||||
"antdv-next": "catalog:",
|
||||
"axios": "catalog:",
|
||||
"cropperjs": "catalog:",
|
||||
"dayjs": "catalog:",
|
||||
"echarts": "^5.5.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"echarts": "catalog:conflicts_echarts_h5_5_1",
|
||||
"lodash-es": "catalog:",
|
||||
"motion-v": "catalog:",
|
||||
"pinia": "catalog:",
|
||||
"tinymce": "7.9.1",
|
||||
"unplugin-vue-components": "^0.27.3",
|
||||
"tinymce": "catalog:",
|
||||
"unplugin-vue-components": "catalog:",
|
||||
"version-polling": "catalog:",
|
||||
"vue": "catalog:",
|
||||
"vue-router": "catalog:",
|
||||
"vue3-colorpicker": "^2.3.0"
|
||||
"vue-router": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "^4.17.12"
|
||||
"@types/lodash-es": "catalog:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,6 @@ import { computed, defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { notification } from 'ant-design-vue';
|
||||
|
||||
import { FileUploadOld, ImageUploadOld } from '#/components/upload-old';
|
||||
|
||||
const RichTextarea = defineAsyncComponent(() =>
|
||||
import('#/components/tinymce/index').then((res) => res.Tinymce),
|
||||
);
|
||||
@@ -29,57 +25,68 @@ const ImageUpload = defineAsyncComponent(() =>
|
||||
import('#/components/upload').then((res) => res.ImageUpload),
|
||||
);
|
||||
|
||||
const AutoComplete = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/auto-complete'),
|
||||
const Button = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/button/index'),
|
||||
);
|
||||
const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
|
||||
const Cascader = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/cascader'),
|
||||
() => import('antdv-next/dist/cascader/index'),
|
||||
);
|
||||
const Checkbox = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/checkbox'),
|
||||
() => import('antdv-next/dist/checkbox/index'),
|
||||
);
|
||||
const CheckboxGroup = defineAsyncComponent(() =>
|
||||
import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup),
|
||||
const CheckboxGroup = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/checkbox/Group'),
|
||||
);
|
||||
const DatePicker = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/date-picker'),
|
||||
() => import('antdv-next/dist/date-picker/index'),
|
||||
);
|
||||
const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider'));
|
||||
const Input = defineAsyncComponent(() => import('ant-design-vue/es/input'));
|
||||
const Divider = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/divider/index'),
|
||||
);
|
||||
const Input = defineAsyncComponent(() => import('antdv-next/dist/input/index'));
|
||||
const InputNumber = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/input-number'),
|
||||
() => import('antdv-next/dist/input-number/index'),
|
||||
);
|
||||
const InputPassword = defineAsyncComponent(() =>
|
||||
import('ant-design-vue/es/input').then((res) => res.InputPassword),
|
||||
const InputPassword = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/input/Password'),
|
||||
);
|
||||
const Mentions = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/mentions'),
|
||||
() => import('antdv-next/dist/mentions/index'),
|
||||
);
|
||||
const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio'));
|
||||
const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index'));
|
||||
const RadioGroup = defineAsyncComponent(() =>
|
||||
import('ant-design-vue/es/radio').then((res) => res.RadioGroup),
|
||||
import('antdv-next/dist/radio/index').then((res) => res.RadioGroup),
|
||||
);
|
||||
const RangePicker = defineAsyncComponent(() =>
|
||||
import('ant-design-vue/es/date-picker').then((res) => res.RangePicker),
|
||||
import('antdv-next/dist/date-picker/index').then(
|
||||
(res) => res.DateRangePicker,
|
||||
),
|
||||
);
|
||||
const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate'));
|
||||
const Select = defineAsyncComponent(() => import('ant-design-vue/es/select'));
|
||||
const Space = defineAsyncComponent(() => import('ant-design-vue/es/space'));
|
||||
const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch'));
|
||||
const Textarea = defineAsyncComponent(() =>
|
||||
import('ant-design-vue/es/input').then((res) => res.Textarea),
|
||||
const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index'));
|
||||
const Select = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/select/index'),
|
||||
);
|
||||
const Space = defineAsyncComponent(() => import('antdv-next/dist/space/index'));
|
||||
const Switch = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/switch/index'),
|
||||
);
|
||||
const Textarea = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/input/TextArea'),
|
||||
);
|
||||
const TimePicker = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/time-picker'),
|
||||
() => import('antdv-next/dist/time-picker/index'),
|
||||
);
|
||||
const TimeRangePicker = defineAsyncComponent(() =>
|
||||
import('ant-design-vue/es/time-picker').then((res) => res.TimeRangePicker),
|
||||
import('antdv-next/dist/time-picker/index').then(
|
||||
(res) => res.TimeRangePicker,
|
||||
),
|
||||
);
|
||||
const TreeSelect = defineAsyncComponent(
|
||||
() => import('ant-design-vue/es/tree-select'),
|
||||
() => import('antdv-next/dist/tree-select/index'),
|
||||
);
|
||||
const Upload = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/upload/Upload'),
|
||||
);
|
||||
const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload'));
|
||||
|
||||
const withDefaultPlaceholder = <T extends Component>(
|
||||
component: T,
|
||||
@@ -127,6 +134,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||
|
||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||
export type ComponentType =
|
||||
| 'ApiCascader'
|
||||
| 'ApiSelect'
|
||||
| 'ApiTreeSelect'
|
||||
| 'AutoComplete'
|
||||
@@ -137,10 +145,8 @@ export type ComponentType =
|
||||
| 'DefaultButton'
|
||||
| 'Divider'
|
||||
| 'FileUpload'
|
||||
| 'FileUploadOld'
|
||||
| 'IconPicker'
|
||||
| 'ImageUpload'
|
||||
| 'ImageUploadOld'
|
||||
| 'Input'
|
||||
| 'InputNumber'
|
||||
| 'InputPassword'
|
||||
@@ -166,6 +172,14 @@ async function initComponentAdapter() {
|
||||
// 如果你的组件体积比较大,可以使用异步加载
|
||||
// Button: () =>
|
||||
// import('xxx').then((res) => res.Button),
|
||||
|
||||
ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||
component: Cascader,
|
||||
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
||||
loadingSlot: 'suffixIcon',
|
||||
modelPropName: 'value',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
}),
|
||||
ApiSelect: withDefaultPlaceholder(
|
||||
{
|
||||
...ApiComponent,
|
||||
@@ -194,7 +208,6 @@ async function initComponentAdapter() {
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
),
|
||||
AutoComplete,
|
||||
Cascader: withDefaultPlaceholder(Cascader, 'select'),
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
@@ -232,8 +245,6 @@ async function initComponentAdapter() {
|
||||
ImageUpload,
|
||||
FileUpload,
|
||||
RichTextarea,
|
||||
ImageUploadOld,
|
||||
FileUploadOld,
|
||||
};
|
||||
|
||||
// 将组件注册到全局共享状态中
|
||||
@@ -243,9 +254,9 @@ async function initComponentAdapter() {
|
||||
globalShareState.defineMessage({
|
||||
// 复制成功消息提示
|
||||
copyPreferencesSuccess: (title, content) => {
|
||||
notification.success({
|
||||
window.notification.success({
|
||||
description: content,
|
||||
message: title,
|
||||
title,
|
||||
placement: 'bottomRight',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ import { h } from 'vue';
|
||||
|
||||
import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
|
||||
|
||||
import { Button, Image } from 'ant-design-vue';
|
||||
import { Button, Image } from 'antdv-next';
|
||||
|
||||
import { useVbenForm } from './form';
|
||||
|
||||
@@ -78,9 +78,10 @@ setupVbenVxeTable({
|
||||
|
||||
// 表格配置项可以用 cellRender: { name: 'CellImage' },
|
||||
vxeUI.renderer.add('CellImage', {
|
||||
renderTableDefault(_renderOpts, params) {
|
||||
renderTableDefault(renderOpts, params) {
|
||||
const { props } = renderOpts;
|
||||
const { column, row } = params;
|
||||
return h(Image, { src: row[column.field] });
|
||||
return h(Image, { src: row[column.field], ...props });
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { HttpResponse } from '@vben/request';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
const { clientId, sseEnable } = useAppConfig(
|
||||
import.meta.env,
|
||||
@@ -78,7 +78,7 @@ export namespace AuthApi {
|
||||
* 登录
|
||||
*/
|
||||
export async function loginApi(data: AuthApi.LoginParams) {
|
||||
return requestClient.post<AuthApi.LoginResult>(
|
||||
return alovaInstance.post<AuthApi.LoginResult>(
|
||||
'/auth/login',
|
||||
{ ...data, clientId },
|
||||
{
|
||||
@@ -92,7 +92,7 @@ export async function loginApi(data: AuthApi.LoginParams) {
|
||||
* @returns void
|
||||
*/
|
||||
export function doLogout() {
|
||||
return requestClient.post<HttpResponse<void>>('/auth/logout');
|
||||
return alovaInstance.post<HttpResponse<void>>('/auth/logout');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +106,7 @@ export function seeConnectionClose() {
|
||||
if (!sseEnable) {
|
||||
return;
|
||||
}
|
||||
return requestClient.get<void>('/resource/sse/close');
|
||||
return alovaInstance.get<void>('/resource/sse/close');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +133,7 @@ export interface TenantResp {
|
||||
* 获取租户列表 下拉框使用
|
||||
*/
|
||||
export function tenantList() {
|
||||
return requestClient.get<TenantResp>('/auth/tenant/list');
|
||||
return alovaInstance.get<TenantResp>('/auth/tenant/list');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +141,7 @@ export function tenantList() {
|
||||
* @returns string[]
|
||||
*/
|
||||
export async function getAccessCodesApi() {
|
||||
return requestClient.get<string[]>('/auth/codes');
|
||||
return alovaInstance.get<string[]>('/auth/codes');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +150,7 @@ export async function getAccessCodesApi() {
|
||||
* @returns 跳转url
|
||||
*/
|
||||
export function authBinding(source: string, tenantId: string) {
|
||||
return requestClient.get<string>(`/auth/binding/${source}`, {
|
||||
return alovaInstance.get<string>(`/auth/binding/${source}`, {
|
||||
params: {
|
||||
domain: window.location.host,
|
||||
tenantId,
|
||||
@@ -163,7 +163,7 @@ export function authBinding(source: string, tenantId: string) {
|
||||
* @param id id
|
||||
*/
|
||||
export function authUnbinding(id: string) {
|
||||
return requestClient.deleteWithMsg<void>(`/auth/unlock/${id}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`/auth/unlock/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,5 +172,5 @@ export function authUnbinding(id: string) {
|
||||
* @returns void
|
||||
*/
|
||||
export function authCallback(data: AuthApi.OAuthLoginParams) {
|
||||
return requestClient.post<void>('/auth/social/callback', data);
|
||||
return alovaInstance.post<void>('/auth/social/callback', data);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
@@ -6,7 +6,7 @@ import { requestClient } from '#/api/request';
|
||||
* @returns void
|
||||
*/
|
||||
export function sendSmsCode(phonenumber: string) {
|
||||
return requestClient.get<void>('/resource/sms/code', {
|
||||
return alovaInstance.get<void>('/resource/sms/code', {
|
||||
params: { phonenumber },
|
||||
});
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export function sendSmsCode(phonenumber: string) {
|
||||
* @returns void
|
||||
*/
|
||||
export function sendEmailCode(email: string) {
|
||||
return requestClient.get<void>('/resource/email/code', {
|
||||
return alovaInstance.get<void>('/resource/email/code', {
|
||||
params: { email },
|
||||
});
|
||||
}
|
||||
@@ -38,5 +38,5 @@ export interface CaptchaResponse {
|
||||
* @returns resp
|
||||
*/
|
||||
export function captchaImage() {
|
||||
return requestClient.get<CaptchaResponse>('/auth/code');
|
||||
return alovaInstance.get<CaptchaResponse>('/auth/code');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
/**
|
||||
* @description: 菜单meta
|
||||
@@ -41,5 +41,5 @@ export interface Menu {
|
||||
* 获取用户所有菜单
|
||||
*/
|
||||
export async function getAllMenusApi() {
|
||||
return requestClient.get<Menu[]>('/system/menu/getRouters');
|
||||
return alovaInstance.get<Menu[]>('/system/menu/getRouters');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { AxiosRequestConfig } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
import { ContentTypeEnum } from '#/utils/http/helper';
|
||||
|
||||
/**
|
||||
* Axios上传进度事件
|
||||
@@ -20,24 +21,25 @@ export interface UploadResult {
|
||||
* 通过单文件上传接口
|
||||
* @param file 上传的文件
|
||||
* @param options 一些配置项
|
||||
* @param options.onUploadProgress 上传进度事件
|
||||
* @param options.signal 上传取消信号
|
||||
* @param options.otherData 其他请求参数 后端拓展可能会用到
|
||||
* @returns 上传结果
|
||||
*/
|
||||
export function uploadApi(
|
||||
file: Blob | File,
|
||||
options?: {
|
||||
onUploadProgress?: AxiosProgressEvent;
|
||||
otherData?: Record<string, any>;
|
||||
signal?: AbortSignal;
|
||||
},
|
||||
) {
|
||||
const { onUploadProgress, signal, otherData = {} } = options ?? {};
|
||||
return requestClient.upload<UploadResult>(
|
||||
const { otherData = {} } = options ?? {};
|
||||
return alovaInstance.post<UploadResult>(
|
||||
'/resource/oss/upload',
|
||||
{ file, ...otherData },
|
||||
{ onUploadProgress, signal, timeout: 60_000 },
|
||||
{
|
||||
timeout: 60_000,
|
||||
headers: {
|
||||
'Content-Type': ContentTypeEnum.FORM_DATA,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
export interface Role {
|
||||
dataScope: string;
|
||||
@@ -42,5 +42,5 @@ export interface UserInfoResp {
|
||||
* 存在返回null的情况(401) 不会抛出异常 需要手动抛异常
|
||||
*/
|
||||
export async function getUserInfoApi() {
|
||||
return requestClient.get<null | UserInfoResp>('/system/user/getInfo');
|
||||
return alovaInstance.get<null | UserInfoResp>('/system/user/getInfo');
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
|
||||
import { useAuthStore } from '#/store';
|
||||
|
||||
import { requestClient } from './request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
/**
|
||||
* @description: contentType
|
||||
@@ -25,8 +22,7 @@ export const ContentTypeEnum = {
|
||||
* @returns blob二进制
|
||||
*/
|
||||
export function commonExport(url: string, data: Record<string, any>) {
|
||||
return requestClient.post<Blob>(url, data, {
|
||||
data,
|
||||
return alovaInstance.post<Blob>(url, data, {
|
||||
headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
|
||||
isTransformResponse: false,
|
||||
responseType: 'blob',
|
||||
@@ -83,7 +79,7 @@ export function handleUnauthorizedLogout() {
|
||||
if (error instanceof ImpossibleReturn401Exception) {
|
||||
lockLogoutRequest = true;
|
||||
if (import.meta.env.DEV) {
|
||||
Modal.error({
|
||||
window.modal.error({
|
||||
title: '提示',
|
||||
centered: true,
|
||||
content:
|
||||
@@ -93,7 +89,7 @@ export function handleUnauthorizedLogout() {
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
message.error(timeoutMsg);
|
||||
window.message.error(timeoutMsg);
|
||||
isLogoutProcessing = false;
|
||||
});
|
||||
// 不再执行下面逻辑
|
||||
|
||||
4
apps/web-antd/src/api/monitor/cache/index.ts
vendored
4
apps/web-antd/src/api/monitor/cache/index.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
export interface CommandStats {
|
||||
name: string;
|
||||
@@ -20,5 +20,5 @@ export interface CacheInfo {
|
||||
* @returns redis信息
|
||||
*/
|
||||
export function redisCacheInfo() {
|
||||
return requestClient.get<CacheInfo>('/monitor/cache');
|
||||
return alovaInstance.get<CacheInfo>('/monitor/cache');
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { LoginLog } from './model';
|
||||
import type { IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
loginInfoClean = '/monitor/logininfor/clean',
|
||||
@@ -19,7 +19,7 @@ enum Api {
|
||||
* @returns list[]
|
||||
*/
|
||||
export function loginInfoList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<LoginLog>>(Api.loginInfoList, { params });
|
||||
return alovaInstance.get<PageResult<LoginLog>>(Api.loginInfoList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function loginInfoExport(data: any) {
|
||||
* @returns void
|
||||
*/
|
||||
export function loginInfoRemove(infoIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${infoIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${infoIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ export function loginInfoRemove(infoIds: IDS) {
|
||||
* @returns void
|
||||
*/
|
||||
export function userUnlock(username: string) {
|
||||
return requestClient.get<void>(`${Api.userUnlock}/${username}`, {
|
||||
return alovaInstance.get<void>(`${Api.userUnlock}/${username}`, {
|
||||
successMessageMode: 'message',
|
||||
});
|
||||
}
|
||||
@@ -56,5 +56,5 @@ export function userUnlock(username: string) {
|
||||
* @returns void
|
||||
*/
|
||||
export function loginInfoClean() {
|
||||
return requestClient.deleteWithMsg<void>(Api.loginInfoClean);
|
||||
return alovaInstance.deleteWithMsg<void>(Api.loginInfoClean);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { OnlineUser } from './model';
|
||||
|
||||
import type { PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
onlineList = '/monitor/online/list',
|
||||
@@ -14,7 +14,7 @@ enum Api {
|
||||
* @returns OnlineUser[]
|
||||
*/
|
||||
export function onlineDeviceList() {
|
||||
return requestClient.get<PageResult<OnlineUser>>(Api.root);
|
||||
return alovaInstance.get<PageResult<OnlineUser>>(Api.root);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,7 +23,7 @@ export function onlineDeviceList() {
|
||||
* @returns 结果
|
||||
*/
|
||||
export function onlineList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<OnlineUser>>(Api.onlineList, { params });
|
||||
return alovaInstance.get<PageResult<OnlineUser>>(Api.onlineList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,7 +32,7 @@ export function onlineList(params?: PageQuery) {
|
||||
* @returns void
|
||||
*/
|
||||
export function forceLogout(tokenId: string) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${tokenId}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${tokenId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,5 +41,5 @@ export function forceLogout(tokenId: string) {
|
||||
* @returns void
|
||||
*/
|
||||
export function forceLogout2(tokenId: string) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/myself/${tokenId}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/myself/${tokenId}`);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { OperationLog } from './model';
|
||||
import type { IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
operLogClean = '/monitor/operlog/clean',
|
||||
@@ -18,7 +18,7 @@ enum Api {
|
||||
* @returns 分页结果
|
||||
*/
|
||||
export function operLogList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<OperationLog>>(Api.operLogList, {
|
||||
return alovaInstance.get<PageResult<OperationLog>>(Api.operLogList, {
|
||||
params,
|
||||
});
|
||||
}
|
||||
@@ -28,14 +28,14 @@ export function operLogList(params?: PageQuery) {
|
||||
* @param operIds id/ids
|
||||
*/
|
||||
export function operLogDelete(operIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${operIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${operIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空全部分页日志
|
||||
*/
|
||||
export function operLogClean() {
|
||||
return requestClient.deleteWithMsg<void>(Api.operLogClean);
|
||||
return alovaInstance.deleteWithMsg<void>(Api.operLogClean);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
/**
|
||||
* 该文件可自行根据业务逻辑进行调整
|
||||
*/
|
||||
|
||||
import type { HttpResponse } from '@vben/request';
|
||||
import type {
|
||||
BaseAsymmetricEncryption,
|
||||
BaseSymmetricEncryption,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { BUSINESS_SUCCESS_CODE, UNAUTHORIZED_CODE } from '@vben/constants';
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { $t } from '@vben/locales';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import {
|
||||
authenticateResponseInterceptor,
|
||||
errorMessageResponseInterceptor,
|
||||
RequestClient,
|
||||
stringify,
|
||||
} from '@vben/request';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
import {
|
||||
AesEncryption,
|
||||
decodeBase64,
|
||||
encodeBase64,
|
||||
randomStr,
|
||||
RsaEncryption,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { isEmpty, isNull } from 'lodash-es';
|
||||
|
||||
import { useAuthStore } from '#/store';
|
||||
|
||||
import { handleUnauthorizedLogout } from './helper';
|
||||
|
||||
const { apiURL, clientId, enableEncrypt, rsaPublicKey, rsaPrivateKey } =
|
||||
useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
|
||||
/**
|
||||
* 使用非对称加密的实现 前端已经实现RSA/SM2
|
||||
*
|
||||
* 你可以使用Sm2Encryption来替换 后端也需要同步替换公私钥对
|
||||
*
|
||||
* 后端文件位置: ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java
|
||||
*
|
||||
* 注意前端sm-crypto库只能支持04开头的公钥! 否则加密会有问题 你可以使用前端的import { logSm2KeyPair } from '@vben/utils';方法来生成
|
||||
* 如果你生成的公钥开头不是04 那么不能正常加密
|
||||
* 或者使用这个网站来生成: https://tool.hiofd.com/sm2-key-gen/
|
||||
*/
|
||||
const asymmetricEncryption: BaseAsymmetricEncryption = new RsaEncryption({
|
||||
publicKey: rsaPublicKey,
|
||||
privateKey: rsaPrivateKey,
|
||||
});
|
||||
|
||||
/**
|
||||
* 对称加密的实现 AES/SM4
|
||||
*/
|
||||
const symmetricEncryption: BaseSymmetricEncryption = new AesEncryption();
|
||||
|
||||
function createRequestClient(baseURL: string) {
|
||||
const client = new RequestClient({
|
||||
// 后端地址
|
||||
baseURL,
|
||||
// 消息提示类型
|
||||
errorMessageMode: 'message',
|
||||
// 是否返回原生响应 比如:需要获取响应头时使用该属性
|
||||
isReturnNativeResponse: false,
|
||||
// 需要对返回数据进行处理
|
||||
isTransformResponse: true,
|
||||
});
|
||||
|
||||
/**
|
||||
* 重新认证逻辑
|
||||
*/
|
||||
async function doReAuthenticate() {
|
||||
console.warn('Access token or refresh token is invalid or expired. ');
|
||||
const accessStore = useAccessStore();
|
||||
const authStore = useAuthStore();
|
||||
accessStore.setAccessToken(null);
|
||||
if (
|
||||
preferences.app.loginExpiredMode === 'modal' &&
|
||||
accessStore.isAccessChecked
|
||||
) {
|
||||
accessStore.setLoginExpired(true);
|
||||
} else {
|
||||
await authStore.logout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token逻辑
|
||||
*/
|
||||
async function doRefreshToken() {
|
||||
// 不需要
|
||||
// 保留此方法只是为了合并方便
|
||||
return '';
|
||||
}
|
||||
|
||||
function formatToken(token: null | string) {
|
||||
return token ? `Bearer ${token}` : null;
|
||||
}
|
||||
|
||||
client.addRequestInterceptor({
|
||||
fulfilled: (config) => {
|
||||
const accessStore = useAccessStore();
|
||||
// 添加token
|
||||
config.headers.Authorization = formatToken(accessStore.accessToken);
|
||||
/**
|
||||
* locale跟后台不一致 需要转换
|
||||
*/
|
||||
const language = preferences.app.locale.replace('-', '_');
|
||||
config.headers['Accept-Language'] = language;
|
||||
config.headers['Content-Language'] = language;
|
||||
/**
|
||||
* 添加全局clientId
|
||||
* 关于header的clientId被错误绑定到实体类
|
||||
* https://gitee.com/dapppp/ruoyi-plus-vben5/issues/IC0BDS
|
||||
*/
|
||||
config.headers.ClientID = clientId;
|
||||
/**
|
||||
* 格式化get/delete参数
|
||||
* 如果包含自定义的paramsSerializer则不走此逻辑
|
||||
*/
|
||||
if (
|
||||
['DELETE', 'GET'].includes(config.method?.toUpperCase() || '') &&
|
||||
config.params &&
|
||||
!config.paramsSerializer
|
||||
) {
|
||||
/**
|
||||
* 1. 格式化参数 微服务在传递区间时间选择(后端的params Map类型参数)需要格式化key 否则接收不到
|
||||
* 2. 数组参数需要格式化 后端才能正常接收 会变成arr=1&arr=2&arr=3的格式来接收
|
||||
*/
|
||||
config.paramsSerializer = (params) =>
|
||||
stringify(params, { arrayFormat: 'repeat' });
|
||||
}
|
||||
|
||||
const { encrypt } = config;
|
||||
// 全局开启请求加密功能 && 该请求开启 && 是post/put请求
|
||||
if (
|
||||
enableEncrypt &&
|
||||
encrypt &&
|
||||
['POST', 'PUT'].includes(config.method?.toUpperCase() || '')
|
||||
) {
|
||||
// sm4这里改为randomStr(16)
|
||||
const key = randomStr(32);
|
||||
const keyWithBase64 = encodeBase64(key);
|
||||
config.headers['encrypt-key'] =
|
||||
asymmetricEncryption.encrypt(keyWithBase64);
|
||||
/**
|
||||
* axios会默认给字符串前后加上引号 RSA可以正常解密(加不加都能解密) 但是SM2不行(大坑!!!)
|
||||
* 这里通过transformRequest强制返回原始内容
|
||||
*/
|
||||
config.transformRequest = (data) => data;
|
||||
|
||||
config.data =
|
||||
typeof config.data === 'object'
|
||||
? symmetricEncryption.encrypt(JSON.stringify(config.data), key)
|
||||
: symmetricEncryption.encrypt(config.data, key);
|
||||
}
|
||||
return config;
|
||||
},
|
||||
});
|
||||
|
||||
// 通用的错误处理, 如果没有进入上面的错误处理逻辑,就会进入这里
|
||||
// 主要处理http状态码不为200(如网络异常/离线)的情况 必须放在在下面的响应拦截器之前
|
||||
client.addResponseInterceptor(
|
||||
errorMessageResponseInterceptor((msg: string) => message.error(msg)),
|
||||
);
|
||||
|
||||
client.addResponseInterceptor<HttpResponse>({
|
||||
fulfilled: async (response) => {
|
||||
const encryptKey = (response.headers ?? {})['encrypt-key'];
|
||||
if (encryptKey) {
|
||||
/** RSA私钥解密 拿到解密秘钥的base64 */
|
||||
const base64Str = asymmetricEncryption.decrypt(encryptKey);
|
||||
/** base64 解码 得到请求头的 AES 秘钥 */
|
||||
const secret = decodeBase64(base64Str);
|
||||
/** 使用aesKey解密 responseData */
|
||||
const decryptData = symmetricEncryption.decrypt(
|
||||
response.data as unknown as string,
|
||||
secret,
|
||||
);
|
||||
/** 赋值 需要转为对象 */
|
||||
response.data = JSON.parse(decryptData);
|
||||
}
|
||||
|
||||
const { isReturnNativeResponse, isTransformResponse } = response.config;
|
||||
// 是否返回原生响应 比如:需要获取响应时使用该属性
|
||||
if (isReturnNativeResponse) {
|
||||
return response;
|
||||
}
|
||||
// 不进行任何处理,直接返回
|
||||
// 用于页面代码可能需要直接获取code,data,message这些信息时开启
|
||||
if (!isTransformResponse) {
|
||||
/**
|
||||
* @warning 注意 微服务版本在401(网关)会返回text/plain的头 所以这里代码会无效
|
||||
* 我建议你改后端而不是前端来做兼容
|
||||
*/
|
||||
// json数据的判断
|
||||
if (response.headers['content-type']?.includes?.('application/json')) {
|
||||
/**
|
||||
* 需要判断是否登录超时/401
|
||||
* 执行登出操作
|
||||
*/
|
||||
const resp = response.data as unknown as HttpResponse;
|
||||
// 抛出异常 不再执行
|
||||
if (
|
||||
typeof resp === 'object' &&
|
||||
Reflect.has(resp, 'code') &&
|
||||
resp.code === UNAUTHORIZED_CODE
|
||||
) {
|
||||
handleUnauthorizedLogout();
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要判断下载二进制的情况 正常是返回二进制 报错会返回json
|
||||
* 当type为blob且content-type为application/json时 则判断已经下载出错
|
||||
*/
|
||||
if (response.config.responseType === 'blob') {
|
||||
// 这时候的data为blob类型
|
||||
const blob = response.data as unknown as Blob;
|
||||
// 拿到字符串转json对象
|
||||
response.data = JSON.parse(await blob.text());
|
||||
// 然后按正常逻辑执行下面的代码(判断业务状态码)
|
||||
} else {
|
||||
// 其他类型数据 直接返回
|
||||
return response.data;
|
||||
}
|
||||
} else {
|
||||
// 非json数据 直接返回 不做校验
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
const axiosResponseData = response.data;
|
||||
if (!axiosResponseData) {
|
||||
throw new Error($t('http.apiRequestFailed'));
|
||||
}
|
||||
|
||||
// 后端并没有采用严格的{code, msg, data}模式
|
||||
const { code, data, msg, ...other } = axiosResponseData;
|
||||
|
||||
// 业务状态码为200 则请求成功
|
||||
const hasSuccess =
|
||||
Reflect.has(axiosResponseData, 'code') &&
|
||||
code === BUSINESS_SUCCESS_CODE;
|
||||
if (hasSuccess) {
|
||||
let successMsg = msg;
|
||||
|
||||
if (isNull(successMsg) || isEmpty(successMsg)) {
|
||||
successMsg = $t(`http.operationSuccess`);
|
||||
}
|
||||
|
||||
if (response.config.successMessageMode === 'modal') {
|
||||
Modal.success({
|
||||
content: successMsg,
|
||||
title: $t('http.successTip'),
|
||||
});
|
||||
} else if (response.config.successMessageMode === 'message') {
|
||||
message.success(successMsg);
|
||||
}
|
||||
// 分页情况下为code msg rows total 并没有data字段
|
||||
// 如果有data 直接返回data 没有data将剩余参数(...other)封装为data返回
|
||||
// 需要考虑data为null的情况(比如查询为空) 所以这里直接判断undefined
|
||||
if (data !== undefined) {
|
||||
return data;
|
||||
}
|
||||
// 没有data 将其他参数包装为data
|
||||
return other;
|
||||
}
|
||||
// 在此处根据自己项目的实际情况对不同的code执行不同的操作
|
||||
// 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
|
||||
let timeoutMsg = '';
|
||||
switch (code) {
|
||||
// 登录超时
|
||||
case UNAUTHORIZED_CODE: {
|
||||
handleUnauthorizedLogout();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (msg) {
|
||||
timeoutMsg = msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// errorMessageMode='modal'的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
|
||||
// errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
|
||||
if (response.config.errorMessageMode === 'modal') {
|
||||
Modal.error({
|
||||
content: timeoutMsg,
|
||||
title: $t('http.errorTip'),
|
||||
});
|
||||
} else if (response.config.errorMessageMode === 'message') {
|
||||
message.error(timeoutMsg);
|
||||
}
|
||||
|
||||
throw new Error(timeoutMsg || $t('http.apiRequestFailed'));
|
||||
},
|
||||
});
|
||||
|
||||
// token过期的处理
|
||||
client.addResponseInterceptor(
|
||||
authenticateResponseInterceptor({
|
||||
client,
|
||||
doReAuthenticate,
|
||||
doRefreshToken,
|
||||
enableRefreshToken: preferences.app.enableRefreshToken,
|
||||
formatToken,
|
||||
}),
|
||||
);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
export const requestClient = createRequestClient(apiURL);
|
||||
|
||||
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
|
||||
@@ -3,7 +3,7 @@ import type { Client } from './model';
|
||||
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
clientChangeStatus = '/system/client/changeStatus',
|
||||
@@ -18,7 +18,7 @@ enum Api {
|
||||
* @returns 列表
|
||||
*/
|
||||
export function clientList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<Client>>(Api.clientList, { params });
|
||||
return alovaInstance.get<PageResult<Client>>(Api.clientList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,7 +35,7 @@ export function clientExport(data: Partial<Client>) {
|
||||
* @returns 详情
|
||||
*/
|
||||
export function clientInfo(id: ID) {
|
||||
return requestClient.get<Client>(`${Api.root}/${id}`);
|
||||
return alovaInstance.get<Client>(`${Api.root}/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ export function clientInfo(id: ID) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function clientAdd(data: Partial<Client>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ export function clientAdd(data: Partial<Client>) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function clientUpdate(data: Partial<Client>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ export function clientChangeStatus(data: any) {
|
||||
clientId: data.clientId,
|
||||
status: data.status,
|
||||
};
|
||||
return requestClient.putWithMsg<void>(Api.clientChangeStatus, requestData);
|
||||
return alovaInstance.putWithMsg<void>(Api.clientChangeStatus, requestData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,5 +71,5 @@ export function clientChangeStatus(data: any) {
|
||||
* @param ids id集合
|
||||
*/
|
||||
export function clientRemove(ids: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${ids}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${ids}`);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { SysConfig } from './model';
|
||||
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
configExport = '/system/config/export',
|
||||
@@ -19,11 +19,11 @@ enum Api {
|
||||
* @returns 列表
|
||||
*/
|
||||
export function configList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<SysConfig>>(Api.configList, { params });
|
||||
return alovaInstance.get<PageResult<SysConfig>>(Api.configList, { params });
|
||||
}
|
||||
|
||||
export function configInfo(configId: ID) {
|
||||
return requestClient.get<SysConfig>(`${Api.root}/${configId}`);
|
||||
return alovaInstance.get<SysConfig>(`${Api.root}/${configId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ export function configExport(data: Partial<SysConfig>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function configRefreshCache() {
|
||||
return requestClient.deleteWithMsg<void>(Api.configRefreshCache);
|
||||
return alovaInstance.deleteWithMsg<void>(Api.configRefreshCache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ export function configRefreshCache() {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function configUpdate(data: Partial<SysConfig>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@ export function configUpdate(data: Partial<SysConfig>) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function configAdd(data: Partial<SysConfig>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ export function configAdd(data: Partial<SysConfig>) {
|
||||
* @param configIds ids
|
||||
*/
|
||||
export function configRemove(configIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${configIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${configIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,5 +72,5 @@ export function configRemove(configIds: IDS) {
|
||||
* @returns value
|
||||
*/
|
||||
export function configInfoByKey(configKey: string) {
|
||||
return requestClient.get<string>(`${Api.configInfoByKey}/${configKey}`);
|
||||
return alovaInstance.get<string>(`${Api.configInfoByKey}/${configKey}`);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Dept } from './model';
|
||||
|
||||
import type { ID } from '#/api/common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
deptList = '/system/dept/list',
|
||||
@@ -15,7 +15,7 @@ enum Api {
|
||||
* @returns list
|
||||
*/
|
||||
export function deptList(params?: { deptName?: string; status?: string }) {
|
||||
return requestClient.get<Dept[]>(Api.deptList, { params });
|
||||
return alovaInstance.get<Dept[]>(Api.deptList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ export function deptList(params?: { deptName?: string; status?: string }) {
|
||||
* @returns void
|
||||
*/
|
||||
export function deptNodeList(deptId: ID) {
|
||||
return requestClient.get<Dept[]>(`${Api.deptNodeInfo}/${deptId}`);
|
||||
return alovaInstance.get<Dept[]>(`${Api.deptNodeInfo}/${deptId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ export function deptNodeList(deptId: ID) {
|
||||
* @returns 部门信息
|
||||
*/
|
||||
export function deptInfo(deptId: ID) {
|
||||
return requestClient.get<Dept>(`${Api.root}/${deptId}`);
|
||||
return alovaInstance.get<Dept>(`${Api.root}/${deptId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +41,7 @@ export function deptInfo(deptId: ID) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function deptAdd(data: Partial<Dept>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ export function deptAdd(data: Partial<Dept>) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function deptUpdate(data: Partial<Dept>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,5 +58,5 @@ export function deptUpdate(data: Partial<Dept>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function deptRemove(deptId: ID) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${deptId}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${deptId}`);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { DictData } from './dict-data-model';
|
||||
import type { ID, IDS, PageQuery } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
dictDataExport = '/system/dict/data/export',
|
||||
@@ -17,7 +17,7 @@ enum Api {
|
||||
* @returns 字典数据
|
||||
*/
|
||||
export function dictDataInfo(dictType: string) {
|
||||
return requestClient.get<DictData[]>(`${Api.root}/type/${dictType}`);
|
||||
return alovaInstance.get<DictData[]>(`${Api.root}/type/${dictType}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,7 +26,7 @@ export function dictDataInfo(dictType: string) {
|
||||
* @returns 字典数据列表
|
||||
*/
|
||||
export function dictDataList(params?: PageQuery) {
|
||||
return requestClient.get<DictData[]>(Api.dictDataList, { params });
|
||||
return alovaInstance.get<DictData[]>(Api.dictDataList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +44,7 @@ export function dictDataExport(data: Partial<DictData>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function dictDataRemove(dictIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${dictIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${dictIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,7 @@ export function dictDataRemove(dictIds: IDS) {
|
||||
* @returns void
|
||||
*/
|
||||
export function dictDataAdd(data: Partial<DictData>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ export function dictDataAdd(data: Partial<DictData>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function dictDataUpdate(data: Partial<DictData>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,5 +71,5 @@ export function dictDataUpdate(data: Partial<DictData>) {
|
||||
* @returns 字典数据
|
||||
*/
|
||||
export function dictDetailInfo(dictCode: ID) {
|
||||
return requestClient.get<DictData>(`${Api.root}/${dictCode}`);
|
||||
return alovaInstance.get<DictData>(`${Api.root}/${dictCode}`);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { DictType } from './dict-type-model';
|
||||
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
dictOptionSelectList = '/system/dict/type/optionselect',
|
||||
@@ -19,7 +19,7 @@ enum Api {
|
||||
* @returns list
|
||||
*/
|
||||
export function dictTypeList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<DictType>>(Api.dictTypeList, { params });
|
||||
return alovaInstance.get<PageResult<DictType>>(Api.dictTypeList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function dictTypeExport(data: Partial<DictType>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function dictTypeRemove(dictIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${dictIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${dictIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,7 @@ export function dictTypeRemove(dictIds: IDS) {
|
||||
* @returns void
|
||||
*/
|
||||
export function refreshDictTypeCache() {
|
||||
return requestClient.deleteWithMsg<void>(Api.dictTypeRefreshCache);
|
||||
return alovaInstance.deleteWithMsg<void>(Api.dictTypeRefreshCache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ export function refreshDictTypeCache() {
|
||||
* @returns void
|
||||
*/
|
||||
export function dictTypeAdd(data: Partial<DictType>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ export function dictTypeAdd(data: Partial<DictType>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function dictTypeUpdate(data: Partial<DictType>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ export function dictTypeUpdate(data: Partial<DictType>) {
|
||||
* @returns 信息
|
||||
*/
|
||||
export function dictTypeInfo(dictId: ID) {
|
||||
return requestClient.get<DictType>(`${Api.root}/${dictId}`);
|
||||
return alovaInstance.get<DictType>(`${Api.root}/${dictId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,5 +81,5 @@ export function dictTypeInfo(dictId: ID) {
|
||||
* @returns options
|
||||
*/
|
||||
export function dictOptionSelectList() {
|
||||
return requestClient.get<DictType[]>(Api.dictOptionSelectList);
|
||||
return alovaInstance.get<DictType[]>(Api.dictOptionSelectList);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Menu, MenuOption, MenuQuery, MenuResp } from './model';
|
||||
|
||||
import type { ID, IDS } from '#/api/common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
menuList = '/system/menu/list',
|
||||
@@ -18,7 +18,7 @@ enum Api {
|
||||
* @returns 列表
|
||||
*/
|
||||
export function menuList(params?: MenuQuery) {
|
||||
return requestClient.get<Menu[]>(Api.menuList, { params });
|
||||
return alovaInstance.get<Menu[]>(Api.menuList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,7 +27,7 @@ export function menuList(params?: MenuQuery) {
|
||||
* @returns 菜单详情
|
||||
*/
|
||||
export function menuInfo(menuId: ID) {
|
||||
return requestClient.get<Menu>(`${Api.root}/${menuId}`);
|
||||
return alovaInstance.get<Menu>(`${Api.root}/${menuId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,7 +35,7 @@ export function menuInfo(menuId: ID) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function menuAdd(data: Partial<Menu>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ export function menuAdd(data: Partial<Menu>) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function menuUpdate(data: Partial<Menu>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ export function menuUpdate(data: Partial<Menu>) {
|
||||
* @param menuIds ids
|
||||
*/
|
||||
export function menuRemove(menuIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${menuIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${menuIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ export function menuRemove(menuIds: IDS) {
|
||||
* @returns resp
|
||||
*/
|
||||
export function roleMenuTreeSelect(roleId: ID) {
|
||||
return requestClient.get<MenuResp>(`${Api.roleMenuTree}/${roleId}`);
|
||||
return alovaInstance.get<MenuResp>(`${Api.roleMenuTree}/${roleId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ export function roleMenuTreeSelect(roleId: ID) {
|
||||
* @returns []
|
||||
*/
|
||||
export function menuTreeSelect() {
|
||||
return requestClient.get<MenuOption[]>(Api.menuTreeSelect);
|
||||
return alovaInstance.get<MenuOption[]>(Api.menuTreeSelect);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ export function menuTreeSelect() {
|
||||
* @returns resp
|
||||
*/
|
||||
export function tenantPackageMenuTreeSelect(packageId: ID) {
|
||||
return requestClient.get<MenuResp>(
|
||||
return alovaInstance.get<MenuResp>(
|
||||
`${Api.tenantPackageMenuTreeselect}/${packageId}`,
|
||||
);
|
||||
}
|
||||
@@ -88,5 +88,5 @@ export function tenantPackageMenuTreeSelect(packageId: ID) {
|
||||
* @returns void
|
||||
*/
|
||||
export function menuCascadeRemove(menuIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/cascade/${menuIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/cascade/${menuIds}`);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Notice } from './model';
|
||||
|
||||
import type { ID, IDS, PageQuery } from '#/api/common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
noticeList = '/system/notice/list',
|
||||
@@ -15,7 +15,7 @@ enum Api {
|
||||
* @returns 分页结果
|
||||
*/
|
||||
export function noticeList(params?: PageQuery) {
|
||||
return requestClient.get<Notice[]>(Api.noticeList, { params });
|
||||
return alovaInstance.get<Notice[]>(Api.noticeList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ export function noticeList(params?: PageQuery) {
|
||||
* @returns 详情
|
||||
*/
|
||||
export function noticeInfo(noticeId: ID) {
|
||||
return requestClient.get<Notice>(`${Api.root}/${noticeId}`);
|
||||
return alovaInstance.get<Notice>(`${Api.root}/${noticeId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,7 +32,7 @@ export function noticeInfo(noticeId: ID) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function noticeAdd(data: Partial<Notice>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +40,7 @@ export function noticeAdd(data: Partial<Notice>) {
|
||||
* @param data 参数
|
||||
*/
|
||||
export function noticeUpdate(data: any) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,5 +48,5 @@ export function noticeUpdate(data: any) {
|
||||
* @param noticeIds ids
|
||||
*/
|
||||
export function noticeRemove(noticeIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${noticeIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${noticeIds}`);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { OssConfig } from './model';
|
||||
|
||||
import type { ID, IDS, PageQuery } from '#/api/common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
ossConfigChangeStatus = '/resource/oss/config/changeStatus',
|
||||
@@ -12,27 +12,27 @@ enum Api {
|
||||
|
||||
// 获取OSS配置列表
|
||||
export function ossConfigList(params?: PageQuery) {
|
||||
return requestClient.get<OssConfig[]>(Api.ossConfigList, { params });
|
||||
return alovaInstance.get<OssConfig[]>(Api.ossConfigList, { params });
|
||||
}
|
||||
|
||||
// 获取OSS配置的信息
|
||||
export function ossConfigInfo(ossConfigId: ID) {
|
||||
return requestClient.get<OssConfig>(`${Api.root}/${ossConfigId}`);
|
||||
return alovaInstance.get<OssConfig>(`${Api.root}/${ossConfigId}`);
|
||||
}
|
||||
|
||||
// 添加新的OSS配置
|
||||
export function ossConfigAdd(data: Partial<OssConfig>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
// 更新现有的OSS配置
|
||||
export function ossConfigUpdate(data: Partial<OssConfig>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
// 删除OSS配置
|
||||
export function ossConfigRemove(ossConfigIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${ossConfigIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${ossConfigIds}`);
|
||||
}
|
||||
|
||||
// 更改OSS配置的状态
|
||||
@@ -42,5 +42,5 @@ export function ossConfigChangeStatus(data: any) {
|
||||
status: data.status,
|
||||
configKey: data.configKey,
|
||||
};
|
||||
return requestClient.putWithMsg(Api.ossConfigChangeStatus, requestData);
|
||||
return alovaInstance.putWithMsg(Api.ossConfigChangeStatus, requestData);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import type { AxiosRequestConfig } from '@vben/request';
|
||||
|
||||
import type { OssFile } from './model';
|
||||
|
||||
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { ContentTypeEnum } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
ossDownload = '/resource/oss/download',
|
||||
@@ -21,7 +19,7 @@ enum Api {
|
||||
* @returns 分页
|
||||
*/
|
||||
export function ossList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<OssFile>>(Api.ossList, { params });
|
||||
return alovaInstance.get<PageResult<OssFile>>(Api.ossList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,7 +28,7 @@ export function ossList(params?: PageQuery) {
|
||||
* @returns 信息数组
|
||||
*/
|
||||
export function ossInfo(ossIds: ID | IDS) {
|
||||
return requestClient.get<OssFile[]>(`${Api.ossInfo}/${ossIds}`);
|
||||
return alovaInstance.get<OssFile[]>(`${Api.ossInfo}/${ossIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +39,7 @@ export function ossInfo(ossIds: ID | IDS) {
|
||||
export function ossUpload(file: Blob | File) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return requestClient.postWithMsg(Api.ossUpload, formData, {
|
||||
return alovaInstance.postWithMsg(Api.ossUpload, formData, {
|
||||
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||
timeout: 30 * 1000,
|
||||
});
|
||||
@@ -50,18 +48,13 @@ export function ossUpload(file: Blob | File) {
|
||||
/**
|
||||
* 下载文件 返回为二进制
|
||||
* @param ossId ossId
|
||||
* @param onDownloadProgress 下载进度(可选)
|
||||
* @returns blob
|
||||
*/
|
||||
export function ossDownload(
|
||||
ossId: ID,
|
||||
onDownloadProgress?: AxiosRequestConfig['onDownloadProgress'],
|
||||
) {
|
||||
return requestClient.get<Blob>(`${Api.ossDownload}/${ossId}`, {
|
||||
export function ossDownload(ossId: ID) {
|
||||
return alovaInstance.get<Blob>(`${Api.ossDownload}/${ossId}`, {
|
||||
responseType: 'blob',
|
||||
timeout: 30 * 1000,
|
||||
isTransformResponse: false,
|
||||
onDownloadProgress,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,7 +67,7 @@ export function ossDownload(
|
||||
* @returns void
|
||||
*/
|
||||
export function checkLoginBeforeDownload() {
|
||||
return requestClient.get<OssFile[]>(`${Api.ossInfo}/1`, {
|
||||
return alovaInstance.get<OssFile[]>(`${Api.ossInfo}/1`, {
|
||||
errorMessageMode: 'none',
|
||||
});
|
||||
}
|
||||
@@ -85,5 +78,5 @@ export function checkLoginBeforeDownload() {
|
||||
* @returns void
|
||||
*/
|
||||
export function ossRemove(ossIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${ossIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${ossIds}`);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Post } from './model';
|
||||
import type { ID, IDS, PageQuery } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
postExport = '/system/post/export',
|
||||
@@ -19,7 +19,7 @@ enum Api {
|
||||
* @returns Post[]
|
||||
*/
|
||||
export function postList(params?: PageQuery) {
|
||||
return requestClient.get<Post[]>(Api.postList, { params });
|
||||
return alovaInstance.get<Post[]>(Api.postList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function postExport(data: Partial<Post>) {
|
||||
* @returns 岗位信息
|
||||
*/
|
||||
export function postInfo(postId: ID) {
|
||||
return requestClient.get<Post>(`${Api.root}/${postId}`);
|
||||
return alovaInstance.get<Post>(`${Api.root}/${postId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ export function postInfo(postId: ID) {
|
||||
* @returns void
|
||||
*/
|
||||
export function postAdd(data: Partial<Post>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@ export function postAdd(data: Partial<Post>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function postUpdate(data: Partial<Post>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +64,7 @@ export function postUpdate(data: Partial<Post>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function postRemove(postIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${postIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${postIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ export function postRemove(postIds: IDS) {
|
||||
* @returns 岗位
|
||||
*/
|
||||
export function postOptionSelect(deptId: ID) {
|
||||
return requestClient.get<Post[]>(Api.postSelect, { params: { deptId } });
|
||||
return alovaInstance.get<Post[]>(Api.postSelect, { params: { deptId } });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,5 +81,5 @@ export function postOptionSelect(deptId: ID) {
|
||||
* @returns 部门树
|
||||
*/
|
||||
export function postDeptTreeSelect() {
|
||||
return requestClient.get<DeptTree[]>('/system/post/deptTree');
|
||||
return alovaInstance.get<DeptTree[]>('/system/post/deptTree');
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { FileCallBack, UpdatePasswordParam, UserProfile } from './model';
|
||||
|
||||
import { buildUUID } from '@vben/utils';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
root = '/system/user/profile',
|
||||
@@ -15,7 +15,7 @@ enum Api {
|
||||
* @returns userInformation
|
||||
*/
|
||||
export function userProfile() {
|
||||
return requestClient.get<UserProfile>(Api.root);
|
||||
return alovaInstance.get<UserProfile>(Api.root);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ export function userProfile() {
|
||||
* @returns void
|
||||
*/
|
||||
export function userProfileUpdate(data: any) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ export function userProfileUpdate(data: any) {
|
||||
* @returns void
|
||||
*/
|
||||
export function userUpdatePassword(data: UpdatePasswordParam) {
|
||||
return requestClient.putWithMsg<void>(Api.updatePassword, data, {
|
||||
return alovaInstance.putWithMsg<void>(Api.updatePassword, data, {
|
||||
encrypt: true,
|
||||
});
|
||||
}
|
||||
@@ -55,7 +55,7 @@ export function userUpdateAvatar(fileCallback: FileCallBack) {
|
||||
file = filename
|
||||
? new File([file], filename)
|
||||
: new File([file], `${buildUUID()}.png`);
|
||||
return requestClient.post(
|
||||
return alovaInstance.post(
|
||||
Api.updateAvatar,
|
||||
{
|
||||
avatarfile: file,
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { DeptResp, Role } from './model';
|
||||
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
|
||||
|
||||
import { commonExport } from '#/api/helper';
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
roleAllocatedList = '/system/role/authUser/allocatedList',
|
||||
@@ -27,7 +27,7 @@ enum Api {
|
||||
* @returns 分页列表
|
||||
*/
|
||||
export function roleList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<Role>>(Api.roleList, { params });
|
||||
return alovaInstance.get<PageResult<Role>>(Api.roleList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,7 @@ export function roleExport(data: Partial<Role>) {
|
||||
* @returns 角色信息
|
||||
*/
|
||||
export function roleInfo(roleId: ID) {
|
||||
return requestClient.get<Role>(`${Api.root}/${roleId}`);
|
||||
return alovaInstance.get<Role>(`${Api.root}/${roleId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ export function roleInfo(roleId: ID) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleAdd(data: Partial<Role>) {
|
||||
return requestClient.postWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.postWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ export function roleAdd(data: Partial<Role>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleUpdate(data: Partial<Role>) {
|
||||
return requestClient.putWithMsg<void>(Api.root, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ export function roleChangeStatus(data: Partial<Role>) {
|
||||
roleId: data.roleId,
|
||||
status: data.status,
|
||||
};
|
||||
return requestClient.putWithMsg<void>(Api.roleChangeStatus, requestData);
|
||||
return alovaInstance.putWithMsg<void>(Api.roleChangeStatus, requestData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ export function roleChangeStatus(data: Partial<Role>) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleRemove(roleIds: IDS) {
|
||||
return requestClient.deleteWithMsg<void>(`${Api.root}/${roleIds}`);
|
||||
return alovaInstance.deleteWithMsg<void>(`${Api.root}/${roleIds}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,14 +94,14 @@ export function roleRemove(roleIds: IDS) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleDataScope(data: any) {
|
||||
return requestClient.putWithMsg<void>(Api.roleDataScope, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.roleDataScope, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 全局并没有用到这个方法
|
||||
*/
|
||||
export function roleOptionSelect(params?: any) {
|
||||
return requestClient.get(Api.roleOptionSelect, { params });
|
||||
return alovaInstance.get(Api.roleOptionSelect, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +110,7 @@ export function roleOptionSelect(params?: any) {
|
||||
* @returns 分页
|
||||
*/
|
||||
export function roleAllocatedList(params?: PageQuery) {
|
||||
return requestClient.get<PageResult<User>>(Api.roleAllocatedList, { params });
|
||||
return alovaInstance.get<PageResult<User>>(Api.roleAllocatedList, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,7 +119,7 @@ export function roleAllocatedList(params?: PageQuery) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleUnallocatedList(params: any) {
|
||||
return requestClient.get<PageResult<User>>(Api.roleUnallocatedList, {
|
||||
return alovaInstance.get<PageResult<User>>(Api.roleUnallocatedList, {
|
||||
params,
|
||||
});
|
||||
}
|
||||
@@ -129,7 +129,7 @@ export function roleUnallocatedList(params: any) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleAuthCancel(data: { roleId: ID; userId: ID }) {
|
||||
return requestClient.putWithMsg<void>(Api.roleAuthCancel, data);
|
||||
return alovaInstance.putWithMsg<void>(Api.roleAuthCancel, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +139,7 @@ export function roleAuthCancel(data: { roleId: ID; userId: ID }) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleAuthCancelAll(roleId: ID, userIds: IDS) {
|
||||
return requestClient.putWithMsg<void>(
|
||||
return alovaInstance.putWithMsg<void>(
|
||||
`${Api.roleAuthCancelAll}?roleId=${roleId}&userIds=${userIds.join(',')}`,
|
||||
);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ export function roleAuthCancelAll(roleId: ID, userIds: IDS) {
|
||||
* @returns void
|
||||
*/
|
||||
export function roleSelectAll(roleId: ID, userIds: IDS) {
|
||||
return requestClient.putWithMsg<void>(
|
||||
return alovaInstance.putWithMsg<void>(
|
||||
`${Api.roleAuthSelectAll}?roleId=${roleId}&userIds=${userIds.join(',')}`,
|
||||
);
|
||||
}
|
||||
@@ -162,5 +162,5 @@ export function roleSelectAll(roleId: ID, userIds: IDS) {
|
||||
* @returns DeptResp
|
||||
*/
|
||||
export function roleDeptTree(roleId: ID) {
|
||||
return requestClient.get<DeptResp>(`${Api.roleDeptTree}/${roleId}`);
|
||||
return alovaInstance.get<DeptResp>(`${Api.roleDeptTree}/${roleId}`);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { SocialInfo } from './model';
|
||||
|
||||
import type { ID } from '#/api/common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
import { alovaInstance } from '#/utils/http';
|
||||
|
||||
enum Api {
|
||||
root = '/system/social',
|
||||
@@ -14,12 +14,12 @@ enum Api {
|
||||
* @returns info
|
||||
*/
|
||||
export function socialList() {
|
||||
return requestClient.get<SocialInfo[]>(Api.socialList);
|
||||
return alovaInstance.get<SocialInfo[]>(Api.socialList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 并没有用到这个方法
|
||||
*/
|
||||
export function socialInfo(id: ID) {
|
||||
return requestClient.get(`${Api.root}/${id}`);
|
||||
return alovaInstance.get(`${Api.root}/${id}`);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user