mirror of
https://github.com/BgaSol/sol-cloud
synced 2026-04-21 09:07:17 +00:00
init
This commit is contained in:
commit
5f627eef67
337 changed files with 15967 additions and 0 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/mvnw text eol=lf
|
||||
*.cmd text eol=crlf
|
||||
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
docker/data
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 BgaSol
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
17
client/.gitignore
vendored
Normal file
17
client/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
.vite-ssg-temp
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
/common
|
||||
*.local
|
||||
|
||||
# lock
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
|
||||
*.log
|
||||
|
||||
.vite
|
||||
2
client/.npmrc
Normal file
2
client/.npmrc
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
shamefully-hoist=true
|
||||
strict-peer-dependencies=false
|
||||
19
client/Dockerfile
Normal file
19
client/Dockerfile
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# 第一阶段:构建
|
||||
FROM node:20-alpine AS builder
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
77
client/index.html
Normal file
77
client/index.html
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang='zh'>
|
||||
<head>
|
||||
<meta charset='UTF-8'/>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'/>
|
||||
<!-- 字体 -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* 定义css颜色变量 */
|
||||
html {
|
||||
--loading-clolor: #1890ff;
|
||||
}
|
||||
|
||||
.init-loading {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
perspective: 200px;
|
||||
}
|
||||
|
||||
.init-loading:before,
|
||||
.init-loading:after {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
content: "";
|
||||
animation: jumping 0.5s infinite alternate;
|
||||
background: var(--loading-clolor)
|
||||
}
|
||||
|
||||
.init-loading:before {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.init-loading:after {
|
||||
right: 0;
|
||||
animation-delay: 0.15s;
|
||||
}
|
||||
|
||||
@keyframes jumping {
|
||||
0% {
|
||||
transform: scale(1) translateY(0px) rotateX(0deg);
|
||||
box-shadow: 0 0 0 var(--loading-clolor);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1.2) translateY(-25px) rotateX(45deg);
|
||||
background: var(--loading-clolor);
|
||||
box-shadow: 0 25px 40px var(--loading-clolor);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id='app'>
|
||||
<div class="init-loading"></div>
|
||||
</div>
|
||||
<script type='module' src='/src/main.ts'></script>
|
||||
</body>
|
||||
</html>
|
||||
40
client/nginx.conf
Normal file
40
client/nginx.conf
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# 全局配置
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
# 事件模块配置
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
# HTTP 模块配置
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 3600;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
server {
|
||||
listen 3000;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
client/package.json
Normal file
46
client/package.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "element-plus-vite-starter",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"generate": "vite-ssg build",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@icon-park/vue-next": "^1.4.2",
|
||||
"@rollup/plugin-dynamic-import-vars": "^2.1.5",
|
||||
"@types/chroma-js": "^2.4.4",
|
||||
"@vueuse/core": "^11.2.0",
|
||||
"@vueuse/integrations": "^11.2.0",
|
||||
"@vueuse/motion": "^2.2.6",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.7.7",
|
||||
"chroma-js": "^3.1.2",
|
||||
"element-plus": "^2.8.8",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.2.6",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"unplugin-element-plus": "^0.8.0",
|
||||
"vue": "^3.5.12",
|
||||
"vue-router": "^4.4.5",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/ep": "^1.2.1",
|
||||
"@types/node": "^22.9.0",
|
||||
"@vitejs/plugin-vue": "^5.1.5",
|
||||
"openapi-typescript-codegen": "^0.29.0",
|
||||
"sass": "^1.80.7",
|
||||
"sharp": "^0.33.5",
|
||||
"svgo": "^3.3.2",
|
||||
"typescript": "^5.6.3",
|
||||
"unocss": "^0.64.0",
|
||||
"vite": "^5.4.10",
|
||||
"vite-plugin-image-optimizer": "^1.1.8",
|
||||
"vue-tsc": "^2.1.10"
|
||||
}
|
||||
}
|
||||
93
client/public/Open_Sans/OFL.txt
Normal file
93
client/public/Open_Sans/OFL.txt
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
BIN
client/public/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf
Normal file
BIN
client/public/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf
Normal file
Binary file not shown.
100
client/public/Open_Sans/README.txt
Normal file
100
client/public/Open_Sans/README.txt
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
Open Sans Variable Font
|
||||
=======================
|
||||
|
||||
This download contains Open Sans as both variable fonts and static fonts.
|
||||
|
||||
Open Sans is a variable font with these axes:
|
||||
wdth
|
||||
wght
|
||||
|
||||
This means all the styles are contained in these files:
|
||||
Open_Sans/OpenSans-VariableFont_wdth,wght.ttf
|
||||
Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf
|
||||
|
||||
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||
in those cases you can use the static font files for Open Sans:
|
||||
Open_Sans/static/OpenSans_Condensed-Light.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-Regular.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-Medium.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-SemiBold.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-Bold.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-ExtraBold.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-Light.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-Regular.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-Medium.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-SemiBold.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-Bold.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-ExtraBold.ttf
|
||||
Open_Sans/static/OpenSans-Light.ttf
|
||||
Open_Sans/static/OpenSans-Regular.ttf
|
||||
Open_Sans/static/OpenSans-Medium.ttf
|
||||
Open_Sans/static/OpenSans-SemiBold.ttf
|
||||
Open_Sans/static/OpenSans-Bold.ttf
|
||||
Open_Sans/static/OpenSans-ExtraBold.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-LightItalic.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-Italic.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-MediumItalic.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-SemiBoldItalic.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-BoldItalic.ttf
|
||||
Open_Sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-LightItalic.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-Italic.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-MediumItalic.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-BoldItalic.ttf
|
||||
Open_Sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf
|
||||
Open_Sans/static/OpenSans-LightItalic.ttf
|
||||
Open_Sans/static/OpenSans-Italic.ttf
|
||||
Open_Sans/static/OpenSans-MediumItalic.ttf
|
||||
Open_Sans/static/OpenSans-SemiBoldItalic.ttf
|
||||
Open_Sans/static/OpenSans-BoldItalic.ttf
|
||||
Open_Sans/static/OpenSans-ExtraBoldItalic.ttf
|
||||
|
||||
Get started
|
||||
-----------
|
||||
|
||||
1. Install the font files you want to use
|
||||
|
||||
2. Use your app's font picker to view the font family and all the
|
||||
available styles
|
||||
|
||||
Learn more about variable fonts
|
||||
-------------------------------
|
||||
|
||||
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||
https://variablefonts.typenetwork.com
|
||||
https://medium.com/variable-fonts
|
||||
|
||||
In desktop apps
|
||||
|
||||
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||
|
||||
Online
|
||||
|
||||
https://developers.google.com/fonts/docs/getting_started
|
||||
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||
|
||||
Installing fonts
|
||||
|
||||
MacOS: https://support.apple.com/en-us/HT201749
|
||||
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||
|
||||
Android Apps
|
||||
|
||||
https://developers.google.com/fonts/docs/android
|
||||
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||
|
||||
License
|
||||
-------
|
||||
Please read the full license text (OFL.txt) to understand the permissions,
|
||||
restrictions and requirements for usage, redistribution, and modification.
|
||||
|
||||
You can use them in your products & projects – print or digital,
|
||||
commercial or otherwise.
|
||||
|
||||
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||
license for all details.
|
||||
BIN
client/public/Open_Sans/static/OpenSans-Bold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-Bold.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-BoldItalic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-ExtraBold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-ExtraBoldItalic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-Italic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-Italic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-Light.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-Light.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-LightItalic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-LightItalic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-Medium.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-Medium.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-MediumItalic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-MediumItalic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-Regular.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-Regular.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-SemiBold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans-SemiBoldItalic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans-SemiBoldItalic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Bold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Bold.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-BoldItalic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-ExtraBold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-ExtraBold.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Italic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Italic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Light.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Light.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Medium.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Medium.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Regular.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-Regular.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_Condensed-SemiBold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_Condensed-SemiBold.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Bold.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Bold.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Italic.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Italic.ttf
Normal file
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Light.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Light.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Medium.ttf
Normal file
BIN
client/public/Open_Sans/static/OpenSans_SemiCondensed-Medium.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
116
client/src/api/HttpRequest.ts
Normal file
116
client/src/api/HttpRequest.ts
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
import axios, {AxiosRequestHeaders} from "axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
export const BaseUrl = '/api'
|
||||
/**
|
||||
* 请求头的key
|
||||
*/
|
||||
export const authorization = "Authorization"
|
||||
/**
|
||||
* 获取请求头对象
|
||||
*/
|
||||
export const getHeaders = () => {
|
||||
return {
|
||||
[authorization]: localStorage.getItem(authorization)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 上传文件的路径
|
||||
*/
|
||||
export const uploadFilePath = `${BaseUrl}/file/file`
|
||||
/**
|
||||
* 获取请求头字符串
|
||||
*/
|
||||
export const getHeadersString = () => {
|
||||
return `${authorization}=${localStorage.getItem(authorization)}`
|
||||
}
|
||||
/**
|
||||
* 获取文件的url
|
||||
* @param id 文件id
|
||||
*/
|
||||
export const getFileUrl = (id: string) => {
|
||||
return `${BaseUrl}/file/file/download/${id}?${getHeadersString()}`
|
||||
}
|
||||
/**
|
||||
* 获取图片的url
|
||||
* @param id 图片id
|
||||
*/
|
||||
export const getImageUrl = (id: string) => {
|
||||
return `${BaseUrl}/file/image/download/${id}?${getHeadersString()}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 dto 中的 undefined 和 null 值去掉 替换为默认值 默认值一般为空字符串空数组等
|
||||
* 后端默认不更新 undefined 和 null 的值
|
||||
* @param defaultDto 默认的dto对象
|
||||
* @param dto 提交的dto对象
|
||||
*/
|
||||
export const buildDto = <DTO>(defaultDto: DTO, dto: DTO) => {
|
||||
const data = {...defaultDto}
|
||||
for (const key in dto) {
|
||||
if ((dto[key] !== undefined) && (dto[key] !== null)) {
|
||||
// 判断其是否是代理对象
|
||||
data[key] = dto[key]
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
/**
|
||||
* 响应拦截器
|
||||
*/
|
||||
axios.interceptors.response.use(
|
||||
response => {
|
||||
const data = response.data
|
||||
if (data.code === 500) {
|
||||
if (data.message) {
|
||||
ElMessage({
|
||||
message: data.message,
|
||||
type: data.type || "error"
|
||||
})
|
||||
}
|
||||
throw new Error(data.message);
|
||||
} else if (data.code === 401) {
|
||||
localStorage.removeItem(authorization);
|
||||
// 获取当前页面的url
|
||||
const url = window.location.href;
|
||||
// 跳转到登录页面
|
||||
window.location.href = `/login?redirect=${encodeURIComponent(url)}&error=401`;
|
||||
} else if (data.code === 403) {
|
||||
ElMessage.error('没有权限')
|
||||
} else if (data.code === 400) {
|
||||
ElMessage.warning('请求参数错误')
|
||||
}
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
ElMessage.error("服务器发生错误")
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
/**
|
||||
* 请求拦截器
|
||||
*/
|
||||
axios.interceptors.request.use(
|
||||
config => {
|
||||
config.url = BaseUrl + urlFilter(config.url as string)
|
||||
// 处理请求头 添加token
|
||||
config.headers = {
|
||||
...config.headers,
|
||||
...getHeaders()
|
||||
} as unknown as AxiosRequestHeaders;
|
||||
return config;
|
||||
}
|
||||
);
|
||||
|
||||
const urlFilter = (url: string) => {
|
||||
// 判断url中是否包含/api (因为API调用根据OPENAPI生成)
|
||||
const agreement = url.indexOf("://")
|
||||
if (agreement > 0) {
|
||||
url = url.substring(agreement + 3)
|
||||
}
|
||||
const host = url.indexOf("/")
|
||||
if (host > 0) {
|
||||
url = url.substring(host)
|
||||
}
|
||||
return url;
|
||||
}
|
||||
BIN
client/src/assets/logo.png
Normal file
BIN
client/src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
37
client/src/components/BaseBatchDelete.vue
Normal file
37
client/src/components/BaseBatchDelete.vue
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<script lang="ts" setup>
|
||||
import {ref} from 'vue';
|
||||
import {ElTable as ElTableRefType} from 'element-plus/es/components/table';
|
||||
import {ElButton, ElMessage, ElPopconfirm} from 'element-plus';
|
||||
|
||||
const props = defineProps<{ table: InstanceType<typeof ElTableRefType>, api: (ids: string) => Promise<any> }>();
|
||||
|
||||
const emit = defineEmits<{ success: [] }>();
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const deleteByIds = () => {
|
||||
const ids = (props.table.getSelectionRows()).map((entity: any) => entity.id);
|
||||
if (ids.length) {
|
||||
loading.value = true;
|
||||
props.api(ids.join(",")).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
emit('success');
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
} else {
|
||||
ElMessage.warning('请选择删除项');
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-popconfirm :title='`确定删除所选项目吗`' cancel-button-text='取消'
|
||||
confirm-button-text='删除'
|
||||
confirm-button-type='danger' @confirm='deleteByIds'>
|
||||
<template #reference>
|
||||
<el-button :loading='loading' type='danger'>批量删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
30
client/src/components/BaseDelete.vue
Normal file
30
client/src/components/BaseDelete.vue
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<script lang='ts' setup>
|
||||
import {ref} from 'vue';
|
||||
import {ElButton, ElMessage, ElPopconfirm} from 'element-plus';
|
||||
|
||||
const props = defineProps<{ id: string; api: (id: string) => Promise<any> }>();
|
||||
|
||||
const emit = defineEmits<{ success: [] }>();
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const deleteById = () => {
|
||||
loading.value = true;
|
||||
props.api(props.id).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
emit('success');
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-popconfirm cancel-button-text='取消' confirm-button-text='删除'
|
||||
confirm-button-type='danger'
|
||||
title='确定删除吗' @confirm='deleteById'>
|
||||
<template #reference>
|
||||
<el-button :loading='loading' size='small' type='danger'>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
86
client/src/components/DownloadFile.vue
Normal file
86
client/src/components/DownloadFile.vue
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<script setup lang="ts">
|
||||
import {ref} from "vue";
|
||||
import axios from "axios";
|
||||
import {BaseUrl} from "~/api/HttpRequest";
|
||||
import {useCssVar} from "@vueuse/core";
|
||||
import {ElButton, ElMessage} from "element-plus";
|
||||
|
||||
const percent = ref(0);
|
||||
|
||||
const state = ref<"loading" | "success" | "error">("success");
|
||||
|
||||
const notificationVisible = ref(false);
|
||||
const downloadFileById = async (id: string) => {
|
||||
state.value = "loading"
|
||||
notificationVisible.value = true
|
||||
percent.value = 0;
|
||||
axios.get(`${BaseUrl}/file/download/${id}`, {
|
||||
responseType: 'blob',
|
||||
// 获取文件下载进度
|
||||
onDownloadProgress: (progressEvent) => {
|
||||
let progressNum = (progressEvent.loaded / (progressEvent.total as number)) * 100
|
||||
if (progressNum >= 99) {
|
||||
progressNum = 99
|
||||
}
|
||||
percent.value = progressNum
|
||||
}
|
||||
}).then(res => {
|
||||
ElMessage.success("下载成功")
|
||||
percent.value = 100
|
||||
state.value = "success"
|
||||
const link = document.createElement('a')
|
||||
link.style.display = 'none'
|
||||
link.href = URL.createObjectURL(res.data)
|
||||
link.setAttribute('download', decodeURI(res.headers['content-disposition'].split('filename=')[1]))
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}).catch(() => {
|
||||
state.value = "error"
|
||||
ElMessage.error("下载失败")
|
||||
}).finally(() => {
|
||||
setTimeout(() => notificationVisible.value = false, 3000);
|
||||
})
|
||||
}
|
||||
const props = withDefaults(defineProps<{
|
||||
name: string
|
||||
id: string
|
||||
}>(), {
|
||||
name: "下载"
|
||||
});
|
||||
|
||||
const successColor = useCssVar("--el-color-success")
|
||||
const errorColor = useCssVar("--el-color-danger")
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-button @click="downloadFileById(props.id)" :loading="state==='loading'">{{ props.name }}</el-button>
|
||||
<!-- <el-dialog class="downLoad-dialog important-mt-20px" v-model="notificationVisible" append-to-body :close-on-click-modal="false" width="200px"-->
|
||||
<!-- :modal="false" :show-close="false">-->
|
||||
<!-- <template #header>-->
|
||||
<!-- <div class="flex items-center">-->
|
||||
<!-- <template v-if="state==='loading'">-->
|
||||
<!-- <el-icon class="is-loading">-->
|
||||
<!-- <Loading/>-->
|
||||
<!-- </el-icon>-->
|
||||
<!-- <span class="ml-2">文件下载中</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-else-if="state==='success'">-->
|
||||
<!-- <el-icon :color="success">-->
|
||||
<!-- <CircleCheck/>-->
|
||||
<!-- </el-icon>-->
|
||||
<!-- <span class="ml-2">文件下载完成</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-else-if="state==='error'">-->
|
||||
<!-- <el-icon :color="error">-->
|
||||
<!-- <WarningFilled/>-->
|
||||
<!-- </el-icon>-->
|
||||
<!-- <span class="ml-2">文件下载失败</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </div>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template>-->
|
||||
<!-- <el-progress :text-inside="true" :stroke-width="26" :percentage="percent"/>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-dialog>-->
|
||||
</template>
|
||||
84
client/src/components/ElFromTreeHelper.vue
Normal file
84
client/src/components/ElFromTreeHelper.vue
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<script lang="ts" setup>
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {ElTree as ElTreeRefType} from "element-plus/es/components/tree";
|
||||
import {TreeOptionProps} from "element-plus/es/components/tree/src/tree.type";
|
||||
import {CheckboxValueType, ElCheckbox, ElFormItem, ElTree} from "element-plus";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
label: string
|
||||
error: string
|
||||
treeData: any[]
|
||||
props: TreeOptionProps;
|
||||
nodeKey: string;
|
||||
modelValue: string[];
|
||||
defaultExpandAll?: boolean;
|
||||
}>(), {
|
||||
defaultExpandAll: true
|
||||
});
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [string[]]
|
||||
}>();
|
||||
|
||||
const modelValue = computed({
|
||||
get: () => {
|
||||
return props.modelValue;
|
||||
},
|
||||
set: (val: string[]) => {
|
||||
treeRef.value?.setCheckedKeys(val);
|
||||
emit('update:modelValue', val);
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
treeRef.value?.setCheckedKeys(modelValue.value);
|
||||
});
|
||||
|
||||
const treeRef = ref<InstanceType<typeof ElTreeRefType>>();
|
||||
|
||||
// 选中事件
|
||||
const treeSelectChange = () => {
|
||||
modelValue.value = treeRef.value?.getCheckedKeys() as string[];
|
||||
};
|
||||
// 父子联动
|
||||
const checkStrictly = ref(false);
|
||||
|
||||
// 全选/全不选
|
||||
const selectAll = (checked: CheckboxValueType) => {
|
||||
modelValue.value = checked ? getTreeAllKeys(props.treeData, props.nodeKey) : [];
|
||||
};
|
||||
|
||||
const getTreeAllKeys = (treeData: any[], nodeKey: string) => {
|
||||
const keys: string[] = [];
|
||||
treeData.forEach((item) => {
|
||||
keys.push(item[nodeKey]);
|
||||
if (item.children) {
|
||||
keys.push(...getTreeAllKeys(item.children, nodeKey));
|
||||
}
|
||||
});
|
||||
return keys;
|
||||
};
|
||||
|
||||
const expandTree = (checked: CheckboxValueType) => {
|
||||
if (checked) {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form-item :label='props.label' class="label-form">
|
||||
<el-checkbox v-model="checkStrictly">父子联动</el-checkbox>
|
||||
<el-checkbox @change="selectAll">全选/全不选</el-checkbox>
|
||||
<!--todo <el-checkbox @change="expandTree">展开/收回</el-checkbox>-->
|
||||
</el-form-item>
|
||||
<el-form-item :error='props.error'>
|
||||
<el-tree ref='treeRef'
|
||||
:check-strictly="!checkStrictly"
|
||||
:data='props.treeData'
|
||||
:default-expand-all="props.defaultExpandAll" :node-key='props.nodeKey'
|
||||
:props='props.props' class='form-item-tree'
|
||||
show-checkbox
|
||||
@check-change='treeSelectChange'>
|
||||
</el-tree>
|
||||
</el-form-item>
|
||||
</template>
|
||||
57
client/src/components/IconSelector.vue
Normal file
57
client/src/components/IconSelector.vue
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<script lang='ts' setup>
|
||||
import {computed} from 'vue';
|
||||
import {useIcons} from '~/pinia/modules/icons';
|
||||
import {ElOption, ElSelect} from "element-plus";
|
||||
|
||||
const props = defineProps<{ modelValue: string, placeholder: string }>();
|
||||
const emit = defineEmits<{ 'update:modelValue': [modelValue: string] }>();
|
||||
const icons = useIcons();
|
||||
|
||||
const updateValue = (value: string) => {
|
||||
emit('update:modelValue', value);
|
||||
};
|
||||
|
||||
const icon = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => updateValue(value),
|
||||
});
|
||||
</script>
|
||||
|
||||
<template class='icon-selector'>
|
||||
<el-select v-model='icon' :placeholder='props.placeholder' class='w-100 icon-selector'
|
||||
popper-class='icon-selector'>
|
||||
<el-option
|
||||
v-for='name in icons.icons'
|
||||
:key='name'
|
||||
:label='name'
|
||||
:value='name'>
|
||||
<component :is='name' class='icon-item'/>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.icon-selector {
|
||||
//.el-select-dropdown__list {
|
||||
// display: flex;
|
||||
// flex-wrap: wrap;
|
||||
// flex-direction: row;
|
||||
// max-width: 500px;
|
||||
//}
|
||||
|
||||
.icon-item {
|
||||
width: 1.3em;
|
||||
height: 1.3em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang='scss'>
|
||||
.icon-selector {
|
||||
.el-select-dropdown__list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
max-width: 500px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
46
client/src/components/UploadFile.vue
Normal file
46
client/src/components/UploadFile.vue
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<script lang="ts" setup>
|
||||
// 外部v-model绑定的值
|
||||
import {BaseUrl, getHeaders, uploadFilePath} from "~/api/HttpRequest";
|
||||
import {ref, watch} from "vue";
|
||||
import {ElIcon, ElUpload} from "element-plus";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
modelValue: string;
|
||||
accept: string;
|
||||
tip: string;
|
||||
limit: number;
|
||||
}>(), {
|
||||
accept: '*',
|
||||
tip: '只能上传jpg/png文件',
|
||||
limit: 1
|
||||
});
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [string];
|
||||
}>();
|
||||
const uploadSuccess = async (response: any) => {
|
||||
if (response.code === 200) {
|
||||
emit('update:modelValue', response.data?.id as string);
|
||||
}
|
||||
}
|
||||
const fileList = ref([]);
|
||||
watch(() => props.modelValue, (value) => {
|
||||
if (!value) {
|
||||
fileList.value = [];
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-upload :action="uploadFilePath" :headers="getHeaders()" :on-success="uploadSuccess"
|
||||
:accept="props.accept" class="w-full" method="POST" name="uploadFile" drag
|
||||
:file-list="fileList" :limit="props.limit">
|
||||
<el-icon class="el-icon--upload">
|
||||
<upload-filled/>
|
||||
</el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处或 <em>单击上传</em>
|
||||
<br>
|
||||
<em>{{ props.tip }}</em>
|
||||
</div>
|
||||
</el-upload>
|
||||
</template>
|
||||
43
client/src/components/UploadImage.vue
Normal file
43
client/src/components/UploadImage.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<script lang="ts" setup>
|
||||
// 外部v-model绑定的值
|
||||
import {Service} from "~/generated/file";
|
||||
import {BaseUrl, getHeaders, getImageUrl, uploadFilePath} from "~/api/HttpRequest";
|
||||
import {ElIcon, ElUpload} from "element-plus";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [string];
|
||||
}>();
|
||||
const uploadSuccess = async (response: any) => {
|
||||
if (response.code === 200) {
|
||||
return Service.saveImage({
|
||||
fileId: response.data.id,
|
||||
name: response.data.name,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
emit('update:modelValue', res.data?.id as string);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-upload :action="uploadFilePath"
|
||||
:headers="getHeaders()"
|
||||
:on-success="uploadSuccess"
|
||||
:show-file-list="false"
|
||||
accept="image/*"
|
||||
class="dialog-form-img-upload w-full"
|
||||
method="POST"
|
||||
name="uploadFile">
|
||||
<template v-if="props.modelValue">
|
||||
<img :src="getImageUrl(props.modelValue)" alt="加载失败" class="up-img"/>
|
||||
</template>
|
||||
<el-icon v-else class="dialog-form-img-uploader-icon">
|
||||
<component is="Plus"></component>
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</template>
|
||||
15
client/src/composables/ElementPlusIcons.ts
Normal file
15
client/src/composables/ElementPlusIcons.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
|
||||
import {useIcons} from '~/pinia/modules/icons';
|
||||
import {Plugin} from '@vue/runtime-core';
|
||||
|
||||
const ElementPlusIcons: Plugin = {
|
||||
install(app) {
|
||||
const icons = useIcons();
|
||||
const entries = Object.entries(ElementPlusIconsVue);
|
||||
icons.addIcon(...entries.map(([key]) => key))
|
||||
for (const [key, component] of entries) {
|
||||
app.component(key, component);
|
||||
}
|
||||
},
|
||||
};
|
||||
export default ElementPlusIcons;
|
||||
19
client/src/composables/FormValidationHook.ts
Normal file
19
client/src/composables/FormValidationHook.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import {ref} from "vue";
|
||||
import type {VerificationResult} from "~/generated/system";
|
||||
|
||||
export const useFormValidation = () => {
|
||||
const errData = ref<any>({});
|
||||
const validate = (data: VerificationResult[]) => {
|
||||
data.forEach((item: any) => {
|
||||
errData.value[item.field] = item.message
|
||||
})
|
||||
}
|
||||
const resetValidate = () => {
|
||||
errData.value = {}
|
||||
}
|
||||
return {
|
||||
errData,
|
||||
validate,
|
||||
resetValidate,
|
||||
}
|
||||
}
|
||||
19
client/src/composables/IconParkIcons.ts
Normal file
19
client/src/composables/IconParkIcons.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import * as IconParkIcons from '@icon-park/vue-next/es/map'
|
||||
import '@icon-park/vue-next/styles/index.css';
|
||||
import {useIcons} from "~/pinia/modules/icons";
|
||||
import {Plugin} from "@vue/runtime-core";
|
||||
|
||||
const iconParkName = (icon: string) => {
|
||||
return "IconPark" + icon
|
||||
}
|
||||
const IconParkIconsPlugin: Plugin = {
|
||||
install(app) {
|
||||
const icons = useIcons();
|
||||
const entries = Object.entries(IconParkIcons);
|
||||
icons.addIcon(...entries.map(([key]) => iconParkName(key)))
|
||||
for (const [key, component] of entries) {
|
||||
app.component(iconParkName(key), component);
|
||||
}
|
||||
},
|
||||
}
|
||||
export default IconParkIconsPlugin;
|
||||
55
client/src/composables/PageHook.ts
Normal file
55
client/src/composables/PageHook.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import {Ref} from "vue";
|
||||
|
||||
export interface PageDto {
|
||||
page: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export const usePage = <T extends PageDto>(pageData: Ref<T>, getTable: () => Promise<unknown>) => {
|
||||
/**
|
||||
* 页码变化
|
||||
* @param val
|
||||
*/
|
||||
const handleCurrentChange = async (val: number) => {
|
||||
pageData.value.page = val;
|
||||
await getTable();
|
||||
// 滚动页面到顶部
|
||||
window.scrollTo(0, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* 每页条数变化
|
||||
* @param val
|
||||
*/
|
||||
const handleSizeChange = async (val: number) => {
|
||||
pageData.value.size = val;
|
||||
pageData.value.page = 1;
|
||||
await getTable();
|
||||
// 滚动页面到顶部
|
||||
window.scrollTo(0, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*/
|
||||
const search = async () => {
|
||||
pageData.value.page = 1;
|
||||
await getTable();
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置分页数据
|
||||
* @param defaultRequestData
|
||||
*/
|
||||
const resetPageData = async (defaultRequestData: T) => {
|
||||
pageData.value = defaultRequestData;
|
||||
await getTable();
|
||||
};
|
||||
|
||||
return {
|
||||
handleCurrentChange,
|
||||
handleSizeChange,
|
||||
search,
|
||||
resetPageData
|
||||
}
|
||||
}
|
||||
6
client/src/composables/VueUseMotion.ts
Normal file
6
client/src/composables/VueUseMotion.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import {MotionPlugin} from "@vueuse/motion";
|
||||
import {App} from "vue";
|
||||
|
||||
export const initVueUseMotion = (app: App) => {
|
||||
app.use(MotionPlugin)
|
||||
}
|
||||
7
client/src/env.d.ts
vendored
Normal file
7
client/src/env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import {DefineComponent} from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
25
client/src/generated/file/core/ApiError.ts
Normal file
25
client/src/generated/file/core/ApiError.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
|
||||
export class ApiError extends Error {
|
||||
public readonly url: string;
|
||||
public readonly status: number;
|
||||
public readonly statusText: string;
|
||||
public readonly body: any;
|
||||
public readonly request: ApiRequestOptions;
|
||||
|
||||
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
|
||||
super(message);
|
||||
|
||||
this.name = 'ApiError';
|
||||
this.url = response.url;
|
||||
this.status = response.status;
|
||||
this.statusText = response.statusText;
|
||||
this.body = response.body;
|
||||
this.request = request;
|
||||
}
|
||||
}
|
||||
17
client/src/generated/file/core/ApiRequestOptions.ts
Normal file
17
client/src/generated/file/core/ApiRequestOptions.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type ApiRequestOptions = {
|
||||
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
|
||||
readonly url: string;
|
||||
readonly path?: Record<string, any>;
|
||||
readonly cookies?: Record<string, any>;
|
||||
readonly headers?: Record<string, any>;
|
||||
readonly query?: Record<string, any>;
|
||||
readonly formData?: Record<string, any>;
|
||||
readonly body?: any;
|
||||
readonly mediaType?: string;
|
||||
readonly responseHeader?: string;
|
||||
readonly errors?: Record<number, string>;
|
||||
};
|
||||
11
client/src/generated/file/core/ApiResult.ts
Normal file
11
client/src/generated/file/core/ApiResult.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type ApiResult = {
|
||||
readonly url: string;
|
||||
readonly ok: boolean;
|
||||
readonly status: number;
|
||||
readonly statusText: string;
|
||||
readonly body: any;
|
||||
};
|
||||
131
client/src/generated/file/core/CancelablePromise.ts
Normal file
131
client/src/generated/file/core/CancelablePromise.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export class CancelError extends Error {
|
||||
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'CancelError';
|
||||
}
|
||||
|
||||
public get isCancelled(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export interface OnCancel {
|
||||
readonly isResolved: boolean;
|
||||
readonly isRejected: boolean;
|
||||
readonly isCancelled: boolean;
|
||||
|
||||
(cancelHandler: () => void): void;
|
||||
}
|
||||
|
||||
export class CancelablePromise<T> implements Promise<T> {
|
||||
#isResolved: boolean;
|
||||
#isRejected: boolean;
|
||||
#isCancelled: boolean;
|
||||
readonly #cancelHandlers: (() => void)[];
|
||||
readonly #promise: Promise<T>;
|
||||
#resolve?: (value: T | PromiseLike<T>) => void;
|
||||
#reject?: (reason?: any) => void;
|
||||
|
||||
constructor(
|
||||
executor: (
|
||||
resolve: (value: T | PromiseLike<T>) => void,
|
||||
reject: (reason?: any) => void,
|
||||
onCancel: OnCancel
|
||||
) => void
|
||||
) {
|
||||
this.#isResolved = false;
|
||||
this.#isRejected = false;
|
||||
this.#isCancelled = false;
|
||||
this.#cancelHandlers = [];
|
||||
this.#promise = new Promise<T>((resolve, reject) => {
|
||||
this.#resolve = resolve;
|
||||
this.#reject = reject;
|
||||
|
||||
const onResolve = (value: T | PromiseLike<T>): void => {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#isResolved = true;
|
||||
if (this.#resolve) this.#resolve(value);
|
||||
};
|
||||
|
||||
const onReject = (reason?: any): void => {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#isRejected = true;
|
||||
if (this.#reject) this.#reject(reason);
|
||||
};
|
||||
|
||||
const onCancel = (cancelHandler: () => void): void => {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#cancelHandlers.push(cancelHandler);
|
||||
};
|
||||
|
||||
Object.defineProperty(onCancel, 'isResolved', {
|
||||
get: (): boolean => this.#isResolved,
|
||||
});
|
||||
|
||||
Object.defineProperty(onCancel, 'isRejected', {
|
||||
get: (): boolean => this.#isRejected,
|
||||
});
|
||||
|
||||
Object.defineProperty(onCancel, 'isCancelled', {
|
||||
get: (): boolean => this.#isCancelled,
|
||||
});
|
||||
|
||||
return executor(onResolve, onReject, onCancel as OnCancel);
|
||||
});
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return "Cancellable Promise";
|
||||
}
|
||||
|
||||
public then<TResult1 = T, TResult2 = never>(
|
||||
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
||||
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
||||
): Promise<TResult1 | TResult2> {
|
||||
return this.#promise.then(onFulfilled, onRejected);
|
||||
}
|
||||
|
||||
public catch<TResult = never>(
|
||||
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
|
||||
): Promise<T | TResult> {
|
||||
return this.#promise.catch(onRejected);
|
||||
}
|
||||
|
||||
public finally(onFinally?: (() => void) | null): Promise<T> {
|
||||
return this.#promise.finally(onFinally);
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#isCancelled = true;
|
||||
if (this.#cancelHandlers.length) {
|
||||
try {
|
||||
for (const cancelHandler of this.#cancelHandlers) {
|
||||
cancelHandler();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Cancellation threw an error', error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.#cancelHandlers.length = 0;
|
||||
if (this.#reject) this.#reject(new CancelError('Request aborted'));
|
||||
}
|
||||
|
||||
public get isCancelled(): boolean {
|
||||
return this.#isCancelled;
|
||||
}
|
||||
}
|
||||
32
client/src/generated/file/core/OpenAPI.ts
Normal file
32
client/src/generated/file/core/OpenAPI.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
|
||||
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||
type Headers = Record<string, string>;
|
||||
|
||||
export type OpenAPIConfig = {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
WITH_CREDENTIALS: boolean;
|
||||
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
||||
TOKEN?: string | Resolver<string> | undefined;
|
||||
USERNAME?: string | Resolver<string> | undefined;
|
||||
PASSWORD?: string | Resolver<string> | undefined;
|
||||
HEADERS?: Headers | Resolver<Headers> | undefined;
|
||||
ENCODE_PATH?: ((path: string) => string) | undefined;
|
||||
};
|
||||
|
||||
export const OpenAPI: OpenAPIConfig = {
|
||||
BASE: 'http://localhost:9527/file',
|
||||
VERSION: '1.0.0',
|
||||
WITH_CREDENTIALS: false,
|
||||
CREDENTIALS: 'include',
|
||||
TOKEN: undefined,
|
||||
USERNAME: undefined,
|
||||
PASSWORD: undefined,
|
||||
HEADERS: undefined,
|
||||
ENCODE_PATH: undefined,
|
||||
};
|
||||
323
client/src/generated/file/core/request.ts
Normal file
323
client/src/generated/file/core/request.ts
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import axios from 'axios';
|
||||
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import { ApiError } from './ApiError';
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
import { CancelablePromise } from './CancelablePromise';
|
||||
import type { OnCancel } from './CancelablePromise';
|
||||
import type { OpenAPIConfig } from './OpenAPI';
|
||||
|
||||
export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
|
||||
return value !== undefined && value !== null;
|
||||
};
|
||||
|
||||
export const isString = (value: any): value is string => {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
|
||||
export const isStringWithValue = (value: any): value is string => {
|
||||
return isString(value) && value !== '';
|
||||
};
|
||||
|
||||
export const isBlob = (value: any): value is Blob => {
|
||||
return (
|
||||
typeof value === 'object' &&
|
||||
typeof value.type === 'string' &&
|
||||
typeof value.stream === 'function' &&
|
||||
typeof value.arrayBuffer === 'function' &&
|
||||
typeof value.constructor === 'function' &&
|
||||
typeof value.constructor.name === 'string' &&
|
||||
/^(Blob|File)$/.test(value.constructor.name) &&
|
||||
/^(Blob|File)$/.test(value[Symbol.toStringTag])
|
||||
);
|
||||
};
|
||||
|
||||
export const isFormData = (value: any): value is FormData => {
|
||||
return value instanceof FormData;
|
||||
};
|
||||
|
||||
export const isSuccess = (status: number): boolean => {
|
||||
return status >= 200 && status < 300;
|
||||
};
|
||||
|
||||
export const base64 = (str: string): string => {
|
||||
try {
|
||||
return btoa(str);
|
||||
} catch (err) {
|
||||
// @ts-ignore
|
||||
return Buffer.from(str).toString('base64');
|
||||
}
|
||||
};
|
||||
|
||||
export const getQueryString = (params: Record<string, any>): string => {
|
||||
const qs: string[] = [];
|
||||
|
||||
const append = (key: string, value: any) => {
|
||||
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
||||
};
|
||||
|
||||
const process = (key: string, value: any) => {
|
||||
if (isDefined(value)) {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => {
|
||||
process(key, v);
|
||||
});
|
||||
} else if (typeof value === 'object') {
|
||||
Object.entries(value).forEach(([k, v]) => {
|
||||
process(`${key}[${k}]`, v);
|
||||
});
|
||||
} else {
|
||||
append(key, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
process(key, value);
|
||||
});
|
||||
|
||||
if (qs.length > 0) {
|
||||
return `?${qs.join('&')}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
||||
const encoder = config.ENCODE_PATH || encodeURI;
|
||||
|
||||
const path = options.url
|
||||
.replace('{api-version}', config.VERSION)
|
||||
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
||||
if (options.path?.hasOwnProperty(group)) {
|
||||
return encoder(String(options.path[group]));
|
||||
}
|
||||
return substring;
|
||||
});
|
||||
|
||||
const url = `${config.BASE}${path}`;
|
||||
if (options.query) {
|
||||
return `${url}${getQueryString(options.query)}`;
|
||||
}
|
||||
return url;
|
||||
};
|
||||
|
||||
export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
|
||||
if (options.formData) {
|
||||
const formData = new FormData();
|
||||
|
||||
const process = (key: string, value: any) => {
|
||||
if (isString(value) || isBlob(value)) {
|
||||
formData.append(key, value);
|
||||
} else {
|
||||
formData.append(key, JSON.stringify(value));
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(options.formData)
|
||||
.filter(([_, value]) => isDefined(value))
|
||||
.forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => process(key, v));
|
||||
} else {
|
||||
process(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
return formData;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||
|
||||
export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
|
||||
if (typeof resolver === 'function') {
|
||||
return (resolver as Resolver<T>)(options);
|
||||
}
|
||||
return resolver;
|
||||
};
|
||||
|
||||
export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
|
||||
const [token, username, password, additionalHeaders] = await Promise.all([
|
||||
resolve(options, config.TOKEN),
|
||||
resolve(options, config.USERNAME),
|
||||
resolve(options, config.PASSWORD),
|
||||
resolve(options, config.HEADERS),
|
||||
]);
|
||||
|
||||
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
|
||||
|
||||
const headers = Object.entries({
|
||||
Accept: 'application/json',
|
||||
...additionalHeaders,
|
||||
...options.headers,
|
||||
...formHeaders,
|
||||
})
|
||||
.filter(([_, value]) => isDefined(value))
|
||||
.reduce((headers, [key, value]) => ({
|
||||
...headers,
|
||||
[key]: String(value),
|
||||
}), {} as Record<string, string>);
|
||||
|
||||
if (isStringWithValue(token)) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
if (isStringWithValue(username) && isStringWithValue(password)) {
|
||||
const credentials = base64(`${username}:${password}`);
|
||||
headers['Authorization'] = `Basic ${credentials}`;
|
||||
}
|
||||
|
||||
if (options.body !== undefined) {
|
||||
if (options.mediaType) {
|
||||
headers['Content-Type'] = options.mediaType;
|
||||
} else if (isBlob(options.body)) {
|
||||
headers['Content-Type'] = options.body.type || 'application/octet-stream';
|
||||
} else if (isString(options.body)) {
|
||||
headers['Content-Type'] = 'text/plain';
|
||||
} else if (!isFormData(options.body)) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
export const getRequestBody = (options: ApiRequestOptions): any => {
|
||||
if (options.body) {
|
||||
return options.body;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const sendRequest = async <T>(
|
||||
config: OpenAPIConfig,
|
||||
options: ApiRequestOptions,
|
||||
url: string,
|
||||
body: any,
|
||||
formData: FormData | undefined,
|
||||
headers: Record<string, string>,
|
||||
onCancel: OnCancel,
|
||||
axiosClient: AxiosInstance
|
||||
): Promise<AxiosResponse<T>> => {
|
||||
const source = axios.CancelToken.source();
|
||||
|
||||
const requestConfig: AxiosRequestConfig = {
|
||||
url,
|
||||
headers,
|
||||
data: body ?? formData,
|
||||
method: options.method,
|
||||
withCredentials: config.WITH_CREDENTIALS,
|
||||
withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
|
||||
cancelToken: source.token,
|
||||
};
|
||||
|
||||
onCancel(() => source.cancel('The user aborted a request.'));
|
||||
|
||||
try {
|
||||
return await axiosClient.request(requestConfig);
|
||||
} catch (error) {
|
||||
const axiosError = error as AxiosError<T>;
|
||||
if (axiosError.response) {
|
||||
return axiosError.response;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
|
||||
if (responseHeader) {
|
||||
const content = response.headers[responseHeader];
|
||||
if (isString(content)) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const getResponseBody = (response: AxiosResponse<any>): any => {
|
||||
if (response.status !== 204) {
|
||||
return response.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
|
||||
const errors: Record<number, string> = {
|
||||
400: 'Bad Request',
|
||||
401: 'Unauthorized',
|
||||
403: 'Forbidden',
|
||||
404: 'Not Found',
|
||||
500: 'Internal Server Error',
|
||||
502: 'Bad Gateway',
|
||||
503: 'Service Unavailable',
|
||||
...options.errors,
|
||||
}
|
||||
|
||||
const error = errors[result.status];
|
||||
if (error) {
|
||||
throw new ApiError(options, result, error);
|
||||
}
|
||||
|
||||
if (!result.ok) {
|
||||
const errorStatus = result.status ?? 'unknown';
|
||||
const errorStatusText = result.statusText ?? 'unknown';
|
||||
const errorBody = (() => {
|
||||
try {
|
||||
return JSON.stringify(result.body, null, 2);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
})();
|
||||
|
||||
throw new ApiError(options, result,
|
||||
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Request method
|
||||
* @param config The OpenAPI configuration object
|
||||
* @param options The request options from the service
|
||||
* @param axiosClient The axios client instance to use
|
||||
* @returns CancelablePromise<T>
|
||||
* @throws ApiError
|
||||
*/
|
||||
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
|
||||
return new CancelablePromise(async (resolve, reject, onCancel) => {
|
||||
try {
|
||||
const url = getUrl(config, options);
|
||||
const formData = getFormData(options);
|
||||
const body = getRequestBody(options);
|
||||
const headers = await getHeaders(config, options, formData);
|
||||
|
||||
if (!onCancel.isCancelled) {
|
||||
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
|
||||
const responseBody = getResponseBody(response);
|
||||
const responseHeader = getResponseHeader(response, options.responseHeader);
|
||||
|
||||
const result: ApiResult = {
|
||||
url,
|
||||
ok: isSuccess(response.status),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
body: responseHeader ?? responseBody,
|
||||
};
|
||||
|
||||
catchErrorCodes(options, result);
|
||||
|
||||
resolve(result.body);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
28
client/src/generated/file/index.ts
Normal file
28
client/src/generated/file/index.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export { ApiError } from './core/ApiError';
|
||||
export { CancelablePromise, CancelError } from './core/CancelablePromise';
|
||||
export { OpenAPI } from './core/OpenAPI';
|
||||
export type { OpenAPIConfig } from './core/OpenAPI';
|
||||
|
||||
export { BaseVoFileEntity } from './models/BaseVoFileEntity';
|
||||
export { BaseVoImageEntity } from './models/BaseVoImageEntity';
|
||||
export { BaseVoInteger } from './models/BaseVoInteger';
|
||||
export { BaseVoListVerificationResult } from './models/BaseVoListVerificationResult';
|
||||
export { BaseVoObject } from './models/BaseVoObject';
|
||||
export { BaseVoPageVoFileEntity } from './models/BaseVoPageVoFileEntity';
|
||||
export { BaseVoPageVoImageEntity } from './models/BaseVoPageVoImageEntity';
|
||||
export type { FileCreateDto } from './models/FileCreateDto';
|
||||
export type { FileEntity } from './models/FileEntity';
|
||||
export type { FilePageDto } from './models/FilePageDto';
|
||||
export type { ImageCreateDto } from './models/ImageCreateDto';
|
||||
export type { ImageEntity } from './models/ImageEntity';
|
||||
export type { ImagePageDto } from './models/ImagePageDto';
|
||||
export type { ImageUpdateDto } from './models/ImageUpdateDto';
|
||||
export type { PageVoFileEntity } from './models/PageVoFileEntity';
|
||||
export type { PageVoImageEntity } from './models/PageVoImageEntity';
|
||||
export type { VerificationResult } from './models/VerificationResult';
|
||||
|
||||
export { Service } from './services/Service';
|
||||
39
client/src/generated/file/models/BaseVoFileEntity.ts
Normal file
39
client/src/generated/file/models/BaseVoFileEntity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { FileEntity } from './FileEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoFileEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
data?: FileEntity;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoFileEntity.type;
|
||||
};
|
||||
export namespace BaseVoFileEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
39
client/src/generated/file/models/BaseVoImageEntity.ts
Normal file
39
client/src/generated/file/models/BaseVoImageEntity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ImageEntity } from './ImageEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoImageEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
data?: ImageEntity;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoImageEntity.type;
|
||||
};
|
||||
export namespace BaseVoImageEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
41
client/src/generated/file/models/BaseVoInteger.ts
Normal file
41
client/src/generated/file/models/BaseVoInteger.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoInteger = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
data?: Array<number>;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoInteger.type;
|
||||
};
|
||||
export namespace BaseVoInteger {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { VerificationResult } from './VerificationResult';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoListVerificationResult = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
data?: Array<VerificationResult>;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoListVerificationResult.type;
|
||||
};
|
||||
export namespace BaseVoListVerificationResult {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
41
client/src/generated/file/models/BaseVoObject.ts
Normal file
41
client/src/generated/file/models/BaseVoObject.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoObject = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
data?: Record<string, any>;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoObject.type;
|
||||
};
|
||||
export namespace BaseVoObject {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
39
client/src/generated/file/models/BaseVoPageVoFileEntity.ts
Normal file
39
client/src/generated/file/models/BaseVoPageVoFileEntity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { PageVoFileEntity } from './PageVoFileEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoPageVoFileEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
data?: PageVoFileEntity;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoPageVoFileEntity.type;
|
||||
};
|
||||
export namespace BaseVoPageVoFileEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
39
client/src/generated/file/models/BaseVoPageVoImageEntity.ts
Normal file
39
client/src/generated/file/models/BaseVoPageVoImageEntity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { PageVoImageEntity } from './PageVoImageEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoPageVoImageEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
data?: PageVoImageEntity;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoPageVoImageEntity.type;
|
||||
};
|
||||
export namespace BaseVoPageVoImageEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
19
client/src/generated/file/models/FileCreateDto.ts
Normal file
19
client/src/generated/file/models/FileCreateDto.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 创建文件
|
||||
*/
|
||||
export type FileCreateDto = {
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
sort?: number;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
description?: string;
|
||||
uploadFile: Blob;
|
||||
};
|
||||
|
||||
67
client/src/generated/file/models/FileEntity.ts
Normal file
67
client/src/generated/file/models/FileEntity.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 文件实体类
|
||||
*/
|
||||
export type FileEntity = {
|
||||
id?: string;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
sort?: number;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime?: string;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
updateTime?: string;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
deleted?: number;
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 文件HASH
|
||||
*/
|
||||
hash?: string;
|
||||
/**
|
||||
* 文件状态
|
||||
*/
|
||||
status?: string;
|
||||
/**
|
||||
* 文件后缀
|
||||
*/
|
||||
suffix?: string;
|
||||
/**
|
||||
* 文件来源
|
||||
*/
|
||||
source?: string;
|
||||
/**
|
||||
* 文件所在桶
|
||||
*/
|
||||
bucket?: string;
|
||||
};
|
||||
|
||||
54
client/src/generated/file/models/FilePageDto.ts
Normal file
54
client/src/generated/file/models/FilePageDto.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 文件分页查询参数
|
||||
*/
|
||||
export type FilePageDto = {
|
||||
/**
|
||||
* 页码
|
||||
*/
|
||||
page: number;
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* 文件大小范围-最大值
|
||||
*/
|
||||
maxLen?: number;
|
||||
/**
|
||||
* 文件大小范围-最小值
|
||||
*/
|
||||
minLen?: number;
|
||||
/**
|
||||
* 文件HASH
|
||||
*/
|
||||
hash?: string;
|
||||
/**
|
||||
* 文件状态
|
||||
*/
|
||||
status?: string;
|
||||
/**
|
||||
* 文件后缀
|
||||
*/
|
||||
suffix?: string;
|
||||
/**
|
||||
* 文件来源
|
||||
*/
|
||||
source?: string;
|
||||
/**
|
||||
* 文件所在桶
|
||||
*/
|
||||
bucket?: string;
|
||||
};
|
||||
|
||||
26
client/src/generated/file/models/ImageCreateDto.ts
Normal file
26
client/src/generated/file/models/ImageCreateDto.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 创建图片实体类
|
||||
*/
|
||||
export type ImageCreateDto = {
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
sort?: number;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 图片名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 图片文件id
|
||||
*/
|
||||
fileId: string;
|
||||
};
|
||||
|
||||
53
client/src/generated/file/models/ImageEntity.ts
Normal file
53
client/src/generated/file/models/ImageEntity.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { FileEntity } from './FileEntity';
|
||||
/**
|
||||
* 图片实体类
|
||||
*/
|
||||
export type ImageEntity = {
|
||||
id?: string;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
sort?: number;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime?: string;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
updateTime?: string;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
deleted?: number;
|
||||
/**
|
||||
* 图片名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 图片宽度
|
||||
*/
|
||||
width?: number;
|
||||
/**
|
||||
* 图片高度
|
||||
*/
|
||||
height?: number;
|
||||
/**
|
||||
* 图片文件id
|
||||
*/
|
||||
fileId?: string;
|
||||
file?: FileEntity;
|
||||
};
|
||||
|
||||
22
client/src/generated/file/models/ImagePageDto.ts
Normal file
22
client/src/generated/file/models/ImagePageDto.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 图片分页查询参数
|
||||
*/
|
||||
export type ImagePageDto = {
|
||||
/**
|
||||
* 页码
|
||||
*/
|
||||
page: number;
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* 图片名称
|
||||
*/
|
||||
name?: string;
|
||||
};
|
||||
|
||||
30
client/src/generated/file/models/ImageUpdateDto.ts
Normal file
30
client/src/generated/file/models/ImageUpdateDto.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 更新图片实体类
|
||||
*/
|
||||
export type ImageUpdateDto = {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
sort?: number;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 图片名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 图片文件id
|
||||
*/
|
||||
fileId: string;
|
||||
};
|
||||
|
||||
27
client/src/generated/file/models/PageVoFileEntity.ts
Normal file
27
client/src/generated/file/models/PageVoFileEntity.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { FileEntity } from './FileEntity';
|
||||
/**
|
||||
* 分页响应数据
|
||||
*/
|
||||
export type PageVoFileEntity = {
|
||||
/**
|
||||
* 总条数
|
||||
*/
|
||||
total?: number;
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
result?: Array<FileEntity>;
|
||||
};
|
||||
|
||||
27
client/src/generated/file/models/PageVoImageEntity.ts
Normal file
27
client/src/generated/file/models/PageVoImageEntity.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ImageEntity } from './ImageEntity';
|
||||
/**
|
||||
* 分页响应数据
|
||||
*/
|
||||
export type PageVoImageEntity = {
|
||||
/**
|
||||
* 总条数
|
||||
*/
|
||||
total?: number;
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
result?: Array<ImageEntity>;
|
||||
};
|
||||
|
||||
22
client/src/generated/file/models/VerificationResult.ts
Normal file
22
client/src/generated/file/models/VerificationResult.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 参数校验结果
|
||||
*/
|
||||
export type VerificationResult = {
|
||||
/**
|
||||
* 校验结果
|
||||
*/
|
||||
result?: boolean;
|
||||
/**
|
||||
* 校验字段
|
||||
*/
|
||||
field?: string;
|
||||
/**
|
||||
* 校验消息
|
||||
*/
|
||||
message?: string;
|
||||
};
|
||||
|
||||
246
client/src/generated/file/services/Service.ts
Normal file
246
client/src/generated/file/services/Service.ts
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { BaseVoFileEntity } from '../models/BaseVoFileEntity';
|
||||
import type { BaseVoImageEntity } from '../models/BaseVoImageEntity';
|
||||
import type { BaseVoInteger } from '../models/BaseVoInteger';
|
||||
import type { BaseVoPageVoFileEntity } from '../models/BaseVoPageVoFileEntity';
|
||||
import type { BaseVoPageVoImageEntity } from '../models/BaseVoPageVoImageEntity';
|
||||
import type { FileCreateDto } from '../models/FileCreateDto';
|
||||
import type { FilePageDto } from '../models/FilePageDto';
|
||||
import type { ImageCreateDto } from '../models/ImageCreateDto';
|
||||
import type { ImagePageDto } from '../models/ImagePageDto';
|
||||
import type { ImageUpdateDto } from '../models/ImageUpdateDto';
|
||||
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||
import { OpenAPI } from '../core/OpenAPI';
|
||||
import { request as __request } from '../core/request';
|
||||
export class Service {
|
||||
/**
|
||||
* 更新图片
|
||||
* @param requestBody
|
||||
* @returns BaseVoImageEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static updateImage(
|
||||
requestBody: ImageUpdateDto,
|
||||
): CancelablePromise<BaseVoImageEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'PUT',
|
||||
url: '/image',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 新增图片
|
||||
* @param requestBody
|
||||
* @returns BaseVoImageEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static saveImage(
|
||||
requestBody: ImageCreateDto,
|
||||
): CancelablePromise<BaseVoImageEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/image',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 分页查询图片
|
||||
* @param requestBody
|
||||
* @returns BaseVoPageVoImageEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static findPageImage(
|
||||
requestBody: ImagePageDto,
|
||||
): CancelablePromise<BaseVoPageVoImageEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/image/page',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 保存|上传文件
|
||||
* @param fileCreateDto
|
||||
* @returns BaseVoFileEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static saveFile(
|
||||
fileCreateDto: FileCreateDto,
|
||||
): CancelablePromise<BaseVoFileEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/file',
|
||||
query: {
|
||||
'fileCreateDto': fileCreateDto,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 分页查询文件
|
||||
* @param requestBody
|
||||
* @returns BaseVoPageVoFileEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static findPageFile(
|
||||
requestBody: FilePageDto,
|
||||
): CancelablePromise<BaseVoPageVoFileEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/file/page',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 查询图片
|
||||
* @param id
|
||||
* @returns BaseVoImageEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static findImageById(
|
||||
id: string,
|
||||
): CancelablePromise<BaseVoImageEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/image/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 下载图片
|
||||
* @param id
|
||||
* @returns binary OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static downloadFile(
|
||||
id: string,
|
||||
): CancelablePromise<Blob> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/image/download/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 根据id查询文件
|
||||
* @param id
|
||||
* @returns BaseVoFileEntity OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static findFileById(
|
||||
id: string,
|
||||
): CancelablePromise<BaseVoFileEntity> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/file/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 下载文件
|
||||
* @param id
|
||||
* @returns binary OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static downloadFile1(
|
||||
id: string,
|
||||
): CancelablePromise<Blob> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/file/download/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除图片
|
||||
* @param ids
|
||||
* @returns BaseVoInteger<any> OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static deleteImage(
|
||||
ids: string,
|
||||
): CancelablePromise<BaseVoInteger> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'DELETE',
|
||||
url: '/image/{ids}',
|
||||
path: {
|
||||
'ids': ids,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除文件
|
||||
* @param ids
|
||||
* @returns BaseVoInteger<any> OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static deleteFile(
|
||||
ids: string,
|
||||
): CancelablePromise<BaseVoInteger> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'DELETE',
|
||||
url: '/file/{ids}',
|
||||
path: {
|
||||
'ids': ids,
|
||||
},
|
||||
errors: {
|
||||
400: `参数校验异常`,
|
||||
500: `业务异常`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
25
client/src/generated/system/core/ApiError.ts
Normal file
25
client/src/generated/system/core/ApiError.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
|
||||
export class ApiError extends Error {
|
||||
public readonly url: string;
|
||||
public readonly status: number;
|
||||
public readonly statusText: string;
|
||||
public readonly body: any;
|
||||
public readonly request: ApiRequestOptions;
|
||||
|
||||
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
|
||||
super(message);
|
||||
|
||||
this.name = 'ApiError';
|
||||
this.url = response.url;
|
||||
this.status = response.status;
|
||||
this.statusText = response.statusText;
|
||||
this.body = response.body;
|
||||
this.request = request;
|
||||
}
|
||||
}
|
||||
17
client/src/generated/system/core/ApiRequestOptions.ts
Normal file
17
client/src/generated/system/core/ApiRequestOptions.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type ApiRequestOptions = {
|
||||
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
|
||||
readonly url: string;
|
||||
readonly path?: Record<string, any>;
|
||||
readonly cookies?: Record<string, any>;
|
||||
readonly headers?: Record<string, any>;
|
||||
readonly query?: Record<string, any>;
|
||||
readonly formData?: Record<string, any>;
|
||||
readonly body?: any;
|
||||
readonly mediaType?: string;
|
||||
readonly responseHeader?: string;
|
||||
readonly errors?: Record<number, string>;
|
||||
};
|
||||
11
client/src/generated/system/core/ApiResult.ts
Normal file
11
client/src/generated/system/core/ApiResult.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type ApiResult = {
|
||||
readonly url: string;
|
||||
readonly ok: boolean;
|
||||
readonly status: number;
|
||||
readonly statusText: string;
|
||||
readonly body: any;
|
||||
};
|
||||
131
client/src/generated/system/core/CancelablePromise.ts
Normal file
131
client/src/generated/system/core/CancelablePromise.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export class CancelError extends Error {
|
||||
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'CancelError';
|
||||
}
|
||||
|
||||
public get isCancelled(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export interface OnCancel {
|
||||
readonly isResolved: boolean;
|
||||
readonly isRejected: boolean;
|
||||
readonly isCancelled: boolean;
|
||||
|
||||
(cancelHandler: () => void): void;
|
||||
}
|
||||
|
||||
export class CancelablePromise<T> implements Promise<T> {
|
||||
#isResolved: boolean;
|
||||
#isRejected: boolean;
|
||||
#isCancelled: boolean;
|
||||
readonly #cancelHandlers: (() => void)[];
|
||||
readonly #promise: Promise<T>;
|
||||
#resolve?: (value: T | PromiseLike<T>) => void;
|
||||
#reject?: (reason?: any) => void;
|
||||
|
||||
constructor(
|
||||
executor: (
|
||||
resolve: (value: T | PromiseLike<T>) => void,
|
||||
reject: (reason?: any) => void,
|
||||
onCancel: OnCancel
|
||||
) => void
|
||||
) {
|
||||
this.#isResolved = false;
|
||||
this.#isRejected = false;
|
||||
this.#isCancelled = false;
|
||||
this.#cancelHandlers = [];
|
||||
this.#promise = new Promise<T>((resolve, reject) => {
|
||||
this.#resolve = resolve;
|
||||
this.#reject = reject;
|
||||
|
||||
const onResolve = (value: T | PromiseLike<T>): void => {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#isResolved = true;
|
||||
if (this.#resolve) this.#resolve(value);
|
||||
};
|
||||
|
||||
const onReject = (reason?: any): void => {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#isRejected = true;
|
||||
if (this.#reject) this.#reject(reason);
|
||||
};
|
||||
|
||||
const onCancel = (cancelHandler: () => void): void => {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#cancelHandlers.push(cancelHandler);
|
||||
};
|
||||
|
||||
Object.defineProperty(onCancel, 'isResolved', {
|
||||
get: (): boolean => this.#isResolved,
|
||||
});
|
||||
|
||||
Object.defineProperty(onCancel, 'isRejected', {
|
||||
get: (): boolean => this.#isRejected,
|
||||
});
|
||||
|
||||
Object.defineProperty(onCancel, 'isCancelled', {
|
||||
get: (): boolean => this.#isCancelled,
|
||||
});
|
||||
|
||||
return executor(onResolve, onReject, onCancel as OnCancel);
|
||||
});
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return "Cancellable Promise";
|
||||
}
|
||||
|
||||
public then<TResult1 = T, TResult2 = never>(
|
||||
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
||||
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
||||
): Promise<TResult1 | TResult2> {
|
||||
return this.#promise.then(onFulfilled, onRejected);
|
||||
}
|
||||
|
||||
public catch<TResult = never>(
|
||||
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
|
||||
): Promise<T | TResult> {
|
||||
return this.#promise.catch(onRejected);
|
||||
}
|
||||
|
||||
public finally(onFinally?: (() => void) | null): Promise<T> {
|
||||
return this.#promise.finally(onFinally);
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||
return;
|
||||
}
|
||||
this.#isCancelled = true;
|
||||
if (this.#cancelHandlers.length) {
|
||||
try {
|
||||
for (const cancelHandler of this.#cancelHandlers) {
|
||||
cancelHandler();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Cancellation threw an error', error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.#cancelHandlers.length = 0;
|
||||
if (this.#reject) this.#reject(new CancelError('Request aborted'));
|
||||
}
|
||||
|
||||
public get isCancelled(): boolean {
|
||||
return this.#isCancelled;
|
||||
}
|
||||
}
|
||||
32
client/src/generated/system/core/OpenAPI.ts
Normal file
32
client/src/generated/system/core/OpenAPI.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
|
||||
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||
type Headers = Record<string, string>;
|
||||
|
||||
export type OpenAPIConfig = {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
WITH_CREDENTIALS: boolean;
|
||||
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
||||
TOKEN?: string | Resolver<string> | undefined;
|
||||
USERNAME?: string | Resolver<string> | undefined;
|
||||
PASSWORD?: string | Resolver<string> | undefined;
|
||||
HEADERS?: Headers | Resolver<Headers> | undefined;
|
||||
ENCODE_PATH?: ((path: string) => string) | undefined;
|
||||
};
|
||||
|
||||
export const OpenAPI: OpenAPIConfig = {
|
||||
BASE: 'http://localhost:9527/system',
|
||||
VERSION: '1.0.0',
|
||||
WITH_CREDENTIALS: false,
|
||||
CREDENTIALS: 'include',
|
||||
TOKEN: undefined,
|
||||
USERNAME: undefined,
|
||||
PASSWORD: undefined,
|
||||
HEADERS: undefined,
|
||||
ENCODE_PATH: undefined,
|
||||
};
|
||||
323
client/src/generated/system/core/request.ts
Normal file
323
client/src/generated/system/core/request.ts
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import axios from 'axios';
|
||||
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import { ApiError } from './ApiError';
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
import { CancelablePromise } from './CancelablePromise';
|
||||
import type { OnCancel } from './CancelablePromise';
|
||||
import type { OpenAPIConfig } from './OpenAPI';
|
||||
|
||||
export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
|
||||
return value !== undefined && value !== null;
|
||||
};
|
||||
|
||||
export const isString = (value: any): value is string => {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
|
||||
export const isStringWithValue = (value: any): value is string => {
|
||||
return isString(value) && value !== '';
|
||||
};
|
||||
|
||||
export const isBlob = (value: any): value is Blob => {
|
||||
return (
|
||||
typeof value === 'object' &&
|
||||
typeof value.type === 'string' &&
|
||||
typeof value.stream === 'function' &&
|
||||
typeof value.arrayBuffer === 'function' &&
|
||||
typeof value.constructor === 'function' &&
|
||||
typeof value.constructor.name === 'string' &&
|
||||
/^(Blob|File)$/.test(value.constructor.name) &&
|
||||
/^(Blob|File)$/.test(value[Symbol.toStringTag])
|
||||
);
|
||||
};
|
||||
|
||||
export const isFormData = (value: any): value is FormData => {
|
||||
return value instanceof FormData;
|
||||
};
|
||||
|
||||
export const isSuccess = (status: number): boolean => {
|
||||
return status >= 200 && status < 300;
|
||||
};
|
||||
|
||||
export const base64 = (str: string): string => {
|
||||
try {
|
||||
return btoa(str);
|
||||
} catch (err) {
|
||||
// @ts-ignore
|
||||
return Buffer.from(str).toString('base64');
|
||||
}
|
||||
};
|
||||
|
||||
export const getQueryString = (params: Record<string, any>): string => {
|
||||
const qs: string[] = [];
|
||||
|
||||
const append = (key: string, value: any) => {
|
||||
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
||||
};
|
||||
|
||||
const process = (key: string, value: any) => {
|
||||
if (isDefined(value)) {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => {
|
||||
process(key, v);
|
||||
});
|
||||
} else if (typeof value === 'object') {
|
||||
Object.entries(value).forEach(([k, v]) => {
|
||||
process(`${key}[${k}]`, v);
|
||||
});
|
||||
} else {
|
||||
append(key, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
process(key, value);
|
||||
});
|
||||
|
||||
if (qs.length > 0) {
|
||||
return `?${qs.join('&')}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
||||
const encoder = config.ENCODE_PATH || encodeURI;
|
||||
|
||||
const path = options.url
|
||||
.replace('{api-version}', config.VERSION)
|
||||
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
||||
if (options.path?.hasOwnProperty(group)) {
|
||||
return encoder(String(options.path[group]));
|
||||
}
|
||||
return substring;
|
||||
});
|
||||
|
||||
const url = `${config.BASE}${path}`;
|
||||
if (options.query) {
|
||||
return `${url}${getQueryString(options.query)}`;
|
||||
}
|
||||
return url;
|
||||
};
|
||||
|
||||
export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
|
||||
if (options.formData) {
|
||||
const formData = new FormData();
|
||||
|
||||
const process = (key: string, value: any) => {
|
||||
if (isString(value) || isBlob(value)) {
|
||||
formData.append(key, value);
|
||||
} else {
|
||||
formData.append(key, JSON.stringify(value));
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(options.formData)
|
||||
.filter(([_, value]) => isDefined(value))
|
||||
.forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => process(key, v));
|
||||
} else {
|
||||
process(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
return formData;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||
|
||||
export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
|
||||
if (typeof resolver === 'function') {
|
||||
return (resolver as Resolver<T>)(options);
|
||||
}
|
||||
return resolver;
|
||||
};
|
||||
|
||||
export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
|
||||
const [token, username, password, additionalHeaders] = await Promise.all([
|
||||
resolve(options, config.TOKEN),
|
||||
resolve(options, config.USERNAME),
|
||||
resolve(options, config.PASSWORD),
|
||||
resolve(options, config.HEADERS),
|
||||
]);
|
||||
|
||||
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
|
||||
|
||||
const headers = Object.entries({
|
||||
Accept: 'application/json',
|
||||
...additionalHeaders,
|
||||
...options.headers,
|
||||
...formHeaders,
|
||||
})
|
||||
.filter(([_, value]) => isDefined(value))
|
||||
.reduce((headers, [key, value]) => ({
|
||||
...headers,
|
||||
[key]: String(value),
|
||||
}), {} as Record<string, string>);
|
||||
|
||||
if (isStringWithValue(token)) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
if (isStringWithValue(username) && isStringWithValue(password)) {
|
||||
const credentials = base64(`${username}:${password}`);
|
||||
headers['Authorization'] = `Basic ${credentials}`;
|
||||
}
|
||||
|
||||
if (options.body !== undefined) {
|
||||
if (options.mediaType) {
|
||||
headers['Content-Type'] = options.mediaType;
|
||||
} else if (isBlob(options.body)) {
|
||||
headers['Content-Type'] = options.body.type || 'application/octet-stream';
|
||||
} else if (isString(options.body)) {
|
||||
headers['Content-Type'] = 'text/plain';
|
||||
} else if (!isFormData(options.body)) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
export const getRequestBody = (options: ApiRequestOptions): any => {
|
||||
if (options.body) {
|
||||
return options.body;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const sendRequest = async <T>(
|
||||
config: OpenAPIConfig,
|
||||
options: ApiRequestOptions,
|
||||
url: string,
|
||||
body: any,
|
||||
formData: FormData | undefined,
|
||||
headers: Record<string, string>,
|
||||
onCancel: OnCancel,
|
||||
axiosClient: AxiosInstance
|
||||
): Promise<AxiosResponse<T>> => {
|
||||
const source = axios.CancelToken.source();
|
||||
|
||||
const requestConfig: AxiosRequestConfig = {
|
||||
url,
|
||||
headers,
|
||||
data: body ?? formData,
|
||||
method: options.method,
|
||||
withCredentials: config.WITH_CREDENTIALS,
|
||||
withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
|
||||
cancelToken: source.token,
|
||||
};
|
||||
|
||||
onCancel(() => source.cancel('The user aborted a request.'));
|
||||
|
||||
try {
|
||||
return await axiosClient.request(requestConfig);
|
||||
} catch (error) {
|
||||
const axiosError = error as AxiosError<T>;
|
||||
if (axiosError.response) {
|
||||
return axiosError.response;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
|
||||
if (responseHeader) {
|
||||
const content = response.headers[responseHeader];
|
||||
if (isString(content)) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const getResponseBody = (response: AxiosResponse<any>): any => {
|
||||
if (response.status !== 204) {
|
||||
return response.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
|
||||
const errors: Record<number, string> = {
|
||||
400: 'Bad Request',
|
||||
401: 'Unauthorized',
|
||||
403: 'Forbidden',
|
||||
404: 'Not Found',
|
||||
500: 'Internal Server Error',
|
||||
502: 'Bad Gateway',
|
||||
503: 'Service Unavailable',
|
||||
...options.errors,
|
||||
}
|
||||
|
||||
const error = errors[result.status];
|
||||
if (error) {
|
||||
throw new ApiError(options, result, error);
|
||||
}
|
||||
|
||||
if (!result.ok) {
|
||||
const errorStatus = result.status ?? 'unknown';
|
||||
const errorStatusText = result.statusText ?? 'unknown';
|
||||
const errorBody = (() => {
|
||||
try {
|
||||
return JSON.stringify(result.body, null, 2);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
})();
|
||||
|
||||
throw new ApiError(options, result,
|
||||
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Request method
|
||||
* @param config The OpenAPI configuration object
|
||||
* @param options The request options from the service
|
||||
* @param axiosClient The axios client instance to use
|
||||
* @returns CancelablePromise<T>
|
||||
* @throws ApiError
|
||||
*/
|
||||
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
|
||||
return new CancelablePromise(async (resolve, reject, onCancel) => {
|
||||
try {
|
||||
const url = getUrl(config, options);
|
||||
const formData = getFormData(options);
|
||||
const body = getRequestBody(options);
|
||||
const headers = await getHeaders(config, options, formData);
|
||||
|
||||
if (!onCancel.isCancelled) {
|
||||
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
|
||||
const responseBody = getResponseBody(response);
|
||||
const responseHeader = getResponseHeader(response, options.responseHeader);
|
||||
|
||||
const result: ApiResult = {
|
||||
url,
|
||||
ok: isSuccess(response.status),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
body: responseHeader ?? responseBody,
|
||||
};
|
||||
|
||||
catchErrorCodes(options, result);
|
||||
|
||||
resolve(result.body);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
46
client/src/generated/system/index.ts
Normal file
46
client/src/generated/system/index.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export { ApiError } from './core/ApiError';
|
||||
export { CancelablePromise, CancelError } from './core/CancelablePromise';
|
||||
export { OpenAPI } from './core/OpenAPI';
|
||||
export type { OpenAPIConfig } from './core/OpenAPI';
|
||||
|
||||
export { BaseVoDepartmentEntity } from './models/BaseVoDepartmentEntity';
|
||||
export { BaseVoInteger } from './models/BaseVoInteger';
|
||||
export { BaseVoListDepartmentEntity } from './models/BaseVoListDepartmentEntity';
|
||||
export { BaseVoListMenuEntity } from './models/BaseVoListMenuEntity';
|
||||
export { BaseVoListPermissionEntity } from './models/BaseVoListPermissionEntity';
|
||||
export { BaseVoListRoleEntity } from './models/BaseVoListRoleEntity';
|
||||
export { BaseVoListUserEntity } from './models/BaseVoListUserEntity';
|
||||
export { BaseVoListVerificationResult } from './models/BaseVoListVerificationResult';
|
||||
export { BaseVoMenuEntity } from './models/BaseVoMenuEntity';
|
||||
export { BaseVoObject } from './models/BaseVoObject';
|
||||
export { BaseVoPageVoUserEntity } from './models/BaseVoPageVoUserEntity';
|
||||
export { BaseVoPermissionEntity } from './models/BaseVoPermissionEntity';
|
||||
export { BaseVoRoleEntity } from './models/BaseVoRoleEntity';
|
||||
export { BaseVoSaTokenInfo } from './models/BaseVoSaTokenInfo';
|
||||
export { BaseVoUserEntity } from './models/BaseVoUserEntity';
|
||||
export { BaseVoVerificationVo } from './models/BaseVoVerificationVo';
|
||||
export type { DepartmentCreateDto } from './models/DepartmentCreateDto';
|
||||
export type { DepartmentEntity } from './models/DepartmentEntity';
|
||||
export type { DepartmentUpdateDto } from './models/DepartmentUpdateDto';
|
||||
export { MenuEntity } from './models/MenuEntity';
|
||||
export type { PageVoUserEntity } from './models/PageVoUserEntity';
|
||||
export type { PermissionEntity } from './models/PermissionEntity';
|
||||
export type { RoleCreateDto } from './models/RoleCreateDto';
|
||||
export type { RoleEntity } from './models/RoleEntity';
|
||||
export type { RoleUpdateDto } from './models/RoleUpdateDto';
|
||||
export type { SaTokenInfo } from './models/SaTokenInfo';
|
||||
export type { UserCreateDto } from './models/UserCreateDto';
|
||||
export type { UserEntity } from './models/UserEntity';
|
||||
export type { UserLoginDto } from './models/UserLoginDto';
|
||||
export type { UserPageDto } from './models/UserPageDto';
|
||||
export type { UserPasswordResetDto } from './models/UserPasswordResetDto';
|
||||
export type { UserPasswordUpdateDto } from './models/UserPasswordUpdateDto';
|
||||
export type { UserUpdateDto } from './models/UserUpdateDto';
|
||||
export type { VerificationResult } from './models/VerificationResult';
|
||||
export type { VerificationVo } from './models/VerificationVo';
|
||||
|
||||
export { Service } from './services/Service';
|
||||
39
client/src/generated/system/models/BaseVoDepartmentEntity.ts
Normal file
39
client/src/generated/system/models/BaseVoDepartmentEntity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { DepartmentEntity } from './DepartmentEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoDepartmentEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
data?: DepartmentEntity;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoDepartmentEntity.type;
|
||||
};
|
||||
export namespace BaseVoDepartmentEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
41
client/src/generated/system/models/BaseVoInteger.ts
Normal file
41
client/src/generated/system/models/BaseVoInteger.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoInteger = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
data?: Array<number>;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoInteger.type;
|
||||
};
|
||||
export namespace BaseVoInteger {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { DepartmentEntity } from './DepartmentEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoListDepartmentEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
data?: Array<DepartmentEntity>;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoListDepartmentEntity.type;
|
||||
};
|
||||
export namespace BaseVoListDepartmentEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
42
client/src/generated/system/models/BaseVoListMenuEntity.ts
Normal file
42
client/src/generated/system/models/BaseVoListMenuEntity.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { MenuEntity } from './MenuEntity';
|
||||
/**
|
||||
* 基础响应数据
|
||||
*/
|
||||
export type BaseVoListMenuEntity = {
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
code?: number;
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
data?: Array<MenuEntity>;
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
type?: BaseVoListMenuEntity.type;
|
||||
};
|
||||
export namespace BaseVoListMenuEntity {
|
||||
/**
|
||||
* 响应类型
|
||||
*/
|
||||
export enum type {
|
||||
SUCCESS = 'SUCCESS',
|
||||
WARNING = 'WARNING',
|
||||
INFO = 'INFO',
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue