This commit is contained in:
Bga Sol 2025-02-12 17:22:25 +08:00
commit 5f627eef67
337 changed files with 15967 additions and 0 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf

35
.gitignore vendored Normal file
View 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
View 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
View 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
View file

@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false

19
client/Dockerfile Normal file
View 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
View 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
View 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
View 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"
}
}

View 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.

View 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 arent 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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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;

View 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,
}
}

View 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;

View 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
}
}

View 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
View file

@ -0,0 +1,7 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import {DefineComponent} from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

View 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;
}
}

View 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>;
};

View 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;
};

View 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;
}
}

View 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,
};

View 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);
}
});
};

View 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';

View 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',
}
}

View 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',
}
}

View 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',
}
}

View file

@ -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',
}
}

View 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',
}
}

View 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',
}
}

View 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',
}
}

View 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;
};

View 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;
};

View 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;
};

View 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;
};

View 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;
};

View 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;
};

View 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;
};

View 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>;
};

View 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>;
};

View 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;
};

View 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: `业务异常`,
},
});
}
}

View 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;
}
}

View 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>;
};

View 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;
};

View 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;
}
}

View 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,
};

View 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);
}
});
};

View 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';

View 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',
}
}

View 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',
}
}

View file

@ -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',
}
}

View 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