Merge pull request !219 from xingyu/master
This commit is contained in:
芋道源码 2022-07-19 15:06:48 +00:00 committed by Gitee
commit 8dadc51920
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
129 changed files with 1076 additions and 10034 deletions

View File

@ -23,7 +23,8 @@
>
> 😜 给项目点点 Star 吧,这对我们真的很重要!
* 前端采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) ,正在支持 Vue 3 + ElementUI Plus 最新方案。
* 前端 vue2 版本采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
* 前端 vue3 版本采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin)
* 后端采用 Spring Boot、MySQL + MyBatis Plus、Redis + Redisson。
* 数据库可使用 MySQL、Oracle、PostgreSQL、SQL Server、MariaDB、国产达梦 DM、TiDB 等
* 权限认证使用 Spring Security & Token & Redis支持多终端、多种用户的认证系统。
@ -176,13 +177,29 @@ ps核心功能已经实现正在对接微信小程序中...
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - |
| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.0.0 | - |
### 前端
### vue2 前端
| 框架 | 说明 | 版本 |
|------------------------------------------------------------------------------|---------------|--------|
| [Vue](https://cn.vuejs.org/index.html) | JavaScript 框架 | 2.6.12 |
| [Vue Element Admin](https://panjiachen.github.io/vue-element-admin-site/zh/) | 后台前端解决方案 | - |
### vue3 前端
| 框架 | 说明 | 版本 |
|------------------------------------------------------------------------------|---------------|--------|
| [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.37 |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 3.0.1 |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.9 |
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.7.4 |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.16 |
| [vueuse](https://vueuse.org//) | 常用工具集 | 8.9.4 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.1.10 |
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.2 |
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.11 |
## 🐷 演示图
### 系统功能

View File

@ -418,7 +418,7 @@
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-basic</artifactId>
<artifactId>flowable-spring-boot-starter-process</artifactId>
<version>${flowable.version}</version>
</dependency>
<dependency>

View File

@ -26,7 +26,7 @@
<!-- flowable 工作流相关 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-basic</artifactId>
<artifactId>flowable-spring-boot-starter-process</artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>

View File

@ -4,5 +4,5 @@ dist
dist-ssr
*.local
/dist*
*-lock.*
pnpm-debug
/frank*

View File

@ -1,16 +0,0 @@
{
"types": [
{"type": "chore", "section":"Others", "hidden": false},
{"type": "revert", "section":"Reverts", "hidden": false},
{"type": "feat", "section": "Features", "hidden": false},
{"type": "fix", "section": "Bug Fixes", "hidden": false},
{"type": "improvement", "section": "Feature Improvements", "hidden": false},
{"type": "docs", "section":"Docs", "hidden": false},
{"type": "style", "section":"Styling", "hidden": false},
{"type": "refactor", "section":"Code Refactoring", "hidden": false},
{"type": "perf", "section":"Performance Improvements", "hidden": false},
{"type": "test", "section":"Tests", "hidden": false},
{"type": "build", "section":"Build System", "hidden": false},
{"type": "ci", "section":"CI", "hidden":false}
]
}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-present Archer
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.

View File

@ -7,7 +7,7 @@
## 注意事项
- 项目路径请不要使用中文命名!!!会造成解析乱码!!!请使用全英文路径!!!
- node >=14.18.0 ,pnpm >=7
- node >=14.18.0(建议使用16版本) ,pnpm >=7
- 开发建议使用 [谷歌浏览器-开发者版](https://www.google.cn/intl/zh-CN/chrome/dev/) 不支持 IE\QQ 等浏览器
### 前端依赖
@ -65,6 +65,10 @@ pnpm install
pnpm run dev
# 打包
pnpm run build:pro
# 安装一个包
pnpm add 包名
@ -72,6 +76,8 @@ pnpm add 包名
# 卸载一个包
pnpm remove 包名
# 其他命令请看package.json
```
## 浏览器支持

View File

@ -1,7 +1,7 @@
{
"name": "ruoyi-vue-pro-vue3",
"version": "0.0.154",
"description": "基于vue3、element-plus、typesScript、vite3",
"version": "1.0.160",
"description": "基于vue3、element-plus、typesScript、vite3",
"author": "xingyu",
"private": false,
"scripts": {
@ -10,7 +10,7 @@
"ts:check": "vue-tsc --noEmit",
"build:pro": "vite build --mode pro",
"build:dev": "vite build --mode dev",
"build:test": "npm run ts:check && vite build --mode test",
"build:test": "pnpm run ts:check && vite build --mode test",
"serve:pro": "vite preview --mode pro",
"serve:dev": "vite preview --mode dev",
"serve:test": "vite preview --mode test",
@ -27,7 +27,7 @@
"dependencies": {
"@iconify/iconify": "^2.2.1",
"@vueuse/core": "^8.9.4",
"@wangeditor/editor": "^5.1.11",
"@wangeditor/editor": "^5.1.10",
"@wangeditor/editor-for-vue": "^5.1.10",
"@zxcvbn-ts/core": "^2.0.3",
"animate.css": "^4.1.1",
@ -37,6 +37,7 @@
"echarts-wordcloud": "^2.0.0",
"element-plus": "2.2.9",
"intro.js": "^6.0.0",
"jsencrypt": "^3.2.1",
"lodash-es": "^4.17.21",
"mitt": "^3.0.0",
"nprogress": "^0.2.0",
@ -44,6 +45,7 @@
"pinia-plugin-persist": "^1.0.0",
"qrcode": "^1.5.1",
"qs": "^6.11.0",
"url": "^0.11.0",
"vue": "3.2.37",
"vue-cropper": "^1.0.3",
"vue-i18n": "9.1.10",
@ -63,8 +65,8 @@
"@types/nprogress": "^0.2.0",
"@types/qrcode": "^1.4.2",
"@types/qs": "^6.9.7",
"@typescript-eslint/eslint-plugin": "^5.30.6",
"@typescript-eslint/parser": "^5.30.6",
"@typescript-eslint/eslint-plugin": "^5.30.7",
"@typescript-eslint/parser": "^5.30.7",
"@vitejs/plugin-vue": "^3.0.1",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"autoprefixer": "^10.4.7",
@ -80,7 +82,6 @@
"postcss-html": "^1.5.0",
"postcss-less": "^6.0.0",
"prettier": "^2.7.1",
"pretty-quick": "^3.1.3",
"rimraf": "^3.0.2",
"rollup": "^2.77.0",
"stylelint": "^14.9.1",
@ -91,8 +92,8 @@
"stylelint-order": "^5.0.0",
"typescript": "4.7.4",
"unplugin-vue-define-options": "^0.6.2",
"vite": "3.0.1",
"vite-plugin-eslint": "^1.6.1",
"vite": "3.0.2",
"vite-plugin-eslint": "^1.7.0",
"vite-plugin-html": "^3.2.0",
"vite-plugin-purge-icons": "^0.8.1",
"vite-plugin-style-import": "^1.4.1",

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,13 @@
import { defHttp } from '@/config/axios'
import { ApiAccessLogVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询列表API 访问日志
export const getApiAccessLogPageApi = ({ params }) => {
return defHttp.get<PageResult<ApiAccessLogVO>>({ url: '/infra/api-access-log/page', params })
export const getApiAccessLogPageApi = (params) => {
return request.get({ url: '/infra/api-access-log/page', params })
}
// 导出API 访问日志
export const exportApiAccessLogApi = (params) => {
return defHttp.get({ url: '/infra/api-access-log/export-excel', params, responseType: 'blob' })
return request.get({ url: '/infra/api-access-log/export-excel', params, responseType: 'blob' })
}

View File

@ -1,19 +1,20 @@
import { defHttp } from '@/config/axios'
import { ApiErrorLogVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询列表API 访问日志
export const getApiErrorLogPageApi = ({ params }) => {
return defHttp.get<PageResult<ApiErrorLogVO>>({ url: '/infra/api-error-log/page', params })
export const getApiErrorLogPageApi = (params) => {
return request.get({ url: '/infra/api-error-log/page', params })
}
// 更新 API 错误日志的处理状态
export const updateApiErrorLogPageApi = (id: number, processStatus: number) => {
return defHttp.put({
return request.put({
url: '/infra/api-error-log/update-status?id=' + id + '&processStatus=' + processStatus
})
}
// 导出API 访问日志
export const exportApiErrorLogApi = ({ params }) => {
return defHttp.get({ url: '/infra/api-error-log/export-excel', params, responseType: 'blob' })
export const exportApiErrorLogApi = (params) => {
return request.get({ url: '/infra/api-error-log/export-excel', params, responseType: 'blob' })
}

View File

@ -1,62 +1,59 @@
import { defHttp } from '@/config/axios'
import type { CodegenDetailVO, CodegenPreviewVO, CodegenTableVO, DatabaseTableVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
import type { CodegenTableVO } from './types'
const request = useAxios()
// 查询列表代码生成表定义
export const getCodegenTablePageApi = ({ params }) => {
return defHttp.get<PageResult<CodegenTableVO>>({ url: '/infra/codegen/table/page', params })
export const getCodegenTablePageApi = (params) => {
return request.get({ url: '/infra/codegen/table/page', params })
}
// 查询详情代码生成表定义
export const getCodegenTableApi = (id: number) => {
return defHttp.get<CodegenDetailVO>({ url: '/infra/codegen/detail?tableId=' + id })
return request.get({ url: '/infra/codegen/detail?tableId=' + id })
}
// 新增代码生成表定义
export const createCodegenTableApi = (params: CodegenTableVO) => {
return defHttp.post({ url: '/infra/codegen/create', params })
export const createCodegenTableApi = (data: CodegenTableVO) => {
return request.post({ url: '/infra/codegen/create', data })
}
// 修改代码生成表定义
export const updateCodegenTableApi = (params: CodegenTableVO) => {
return defHttp.put({ url: '/infra/codegen/update', params })
export const updateCodegenTableApi = (data: CodegenTableVO) => {
return request.put({ url: '/infra/codegen/update', data })
}
// 基于数据库的表结构,同步数据库的表和字段定义
export const syncCodegenFromDBApi = (id: number) => {
return defHttp.put({ url: '/infra/codegen/sync-from-db?tableId=' + id })
return request.put({ url: '/infra/codegen/sync-from-db?tableId=' + id })
}
// 基于 SQL 建表语句,同步数据库的表和字段定义
export const syncCodegenFromSQLApi = (id: number, sql: string) => {
return defHttp.put({
url: '/infra/codegen/sync-from-sql?tableId=' + id + '&sql=' + sql,
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
})
return request.put({ url: '/infra/codegen/sync-from-sql?tableId=' + id + '&sql=' + sql })
}
// 预览生成代码
export const previewCodegenApi = (id: number) => {
return defHttp.get<CodegenPreviewVO[]>({ url: '/infra/codegen/preview?tableId=' + id })
return request.get({ url: '/infra/codegen/preview?tableId=' + id })
}
// 下载生成代码
export const downloadCodegenApi = (id: number) => {
return defHttp.get({ url: '/infra/codegen/download?tableId=' + id, responseType: 'blob' })
return request.get({ url: '/infra/codegen/download?tableId=' + id, responseType: 'blob' })
}
// 获得表定义
export const getSchemaTableListApi = (params) => {
return defHttp.get<DatabaseTableVO[]>({ url: '/infra/codegen/db/table/list', params })
return request.get({ url: '/infra/codegen/db/table/list', params })
}
// 基于数据库的表结构,创建代码生成器的表定义
export const createCodegenListApi = (params) => {
return defHttp.post({ url: '/infra/codegen/create-list', params })
export const createCodegenListApi = (data) => {
return request.post({ url: '/infra/codegen/create-list', data })
}
// 删除代码生成表定义
export const deleteCodegenTableApi = (id: number) => {
return defHttp.delete({ url: '/infra/codegen/delete?tableId=' + id })
return request.delete({ url: '/infra/codegen/delete?tableId=' + id })
}

View File

@ -1,37 +1,39 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { ConfigVO } from './types'
const request = useAxios()
// 查询参数列表
export const getConfigPageApi = ({ params }) => {
return defHttp.get<PageResult<ConfigVO>>({ url: '/infra/config/page', params })
export const getConfigPageApi = (params) => {
return request.get({ url: '/infra/config/page', params })
}
// 查询参数详情
export const getConfigApi = (id: number) => {
return defHttp.get<ConfigVO>({ url: '/infra/config/get?id=' + id })
return request.get({ url: '/infra/config/get?id=' + id })
}
// 根据参数键名查询参数值
export const getConfigKeyApi = (configKey: string) => {
return defHttp.get<ConfigVO>({ url: '/infra/config/get-value-by-key?key=' + configKey })
return request.get({ url: '/infra/config/get-value-by-key?key=' + configKey })
}
// 新增参数
export const createConfigApi = (params: ConfigVO) => {
return defHttp.post({ url: '/infra/config/create', params })
export const createConfigApi = (data: ConfigVO) => {
return request.post({ url: '/infra/config/create', data })
}
// 修改参数
export const updateConfigApi = (params: ConfigVO) => {
return defHttp.put({ url: '/infra/config/update', params })
export const updateConfigApi = (data: ConfigVO) => {
return request.put({ url: '/infra/config/update', data })
}
// 删除参数
export const deleteConfigApi = (id: number) => {
return defHttp.delete({ url: '/infra/config/delete?id=' + id })
return request.delete({ url: '/infra/config/delete?id=' + id })
}
// 导出参数
export const exportConfigApi = ({ params }) => {
return defHttp.get({ url: '/infra/config/export', params, responseType: 'blob' })
export const exportConfigApi = (params) => {
return request.get({ url: '/infra/config/export', params, responseType: 'blob' })
}

View File

@ -1,27 +1,29 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { DataSourceConfigVO } from './types'
const request = useAxios()
// 查询数据源配置列表
export const getDataSourceConfigListApi = () => {
return defHttp.get<DataSourceConfigVO[]>({ url: '/infra/data-source-config/list' })
return request.get({ url: '/infra/data-source-config/list' })
}
// 查询数据源配置详情
export const getDataSourceConfigApi = (id: number) => {
return defHttp.get<DataSourceConfigVO>({ url: '/infra/data-source-config/get?id=' + id })
return request.get({ url: '/infra/data-source-config/get?id=' + id })
}
// 新增数据源配置
export const createDataSourceConfigApi = (params: DataSourceConfigVO) => {
return defHttp.post({ url: '/infra/data-source-config/create', params })
export const createDataSourceConfigApi = (data: DataSourceConfigVO) => {
return request.post({ url: '/infra/data-source-config/create', data })
}
// 修改数据源配置
export const updateDataSourceConfigApi = (params: DataSourceConfigVO) => {
return defHttp.put({ url: '/infra/data-source-config/update', params })
export const updateDataSourceConfigApi = (data: DataSourceConfigVO) => {
return request.put({ url: '/infra/data-source-config/update', data })
}
// 删除数据源配置
export const deleteDataSourceConfigApi = (id: number) => {
return defHttp.delete({ url: '/infra/data-source-config/delete?id=' + id })
return request.delete({ url: '/infra/data-source-config/delete?id=' + id })
}

View File

@ -1,16 +1,18 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 导出Html
export const exportHtmlApi = () => {
return defHttp.get({ url: '/infra/db-doc/export-html', responseType: 'blob' })
return request.get({ url: '/infra/db-doc/export-html', responseType: 'blob' })
}
// 导出Word
export const exportWordApi = () => {
return defHttp.get({ url: '/infra/db-doc/export-word', responseType: 'blob' })
return request.get({ url: '/infra/db-doc/export-word', responseType: 'blob' })
}
// 导出Markdown
export const exportMarkdownApi = () => {
return defHttp.get({ url: '/infra/db-doc/export-markdown', responseType: 'blob' })
return request.get({ url: '/infra/db-doc/export-markdown', responseType: 'blob' })
}

View File

@ -1,12 +1,13 @@
import { defHttp } from '@/config/axios'
import type { FileVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询文件列表
export const getFilePageApi = ({ params }) => {
return defHttp.get<PageResult<FileVO>>({ url: '/infra/file/page', params })
export const getFilePageApi = (params) => {
return request.get({ url: '/infra/file/page', params })
}
// 删除文件
export const deleteFileApi = (id: number) => {
return defHttp.delete({ url: '/infra/file/delete?id=' + id })
return request.delete({ url: '/infra/file/delete?id=' + id })
}

View File

@ -1,37 +1,39 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { FileConfigVO } from './types'
const request = useAxios()
// 查询文件配置列表
export const getFileConfigPageApi = ({ params }) => {
return defHttp.get<PageResult<FileConfigVO>>({ url: '/infra/file-config/page', params })
export const getFileConfigPageApi = (params) => {
return request.get({ url: '/infra/file-config/page', params })
}
// 查询文件配置详情
export const getFileConfigApi = (id: number) => {
return defHttp.get<FileConfigVO>({ url: '/infra/file-config/get?id=' + id })
return request.get({ url: '/infra/file-config/get?id=' + id })
}
// 更新文件配置为主配置
export const updateFileConfigMasterApi = (id: number) => {
return defHttp.get<FileConfigVO>({ url: '/infra/file-config/update-master?id=' + id })
return request.get({ url: '/infra/file-config/update-master?id=' + id })
}
// 新增文件配置
export const createFileConfigApi = (params: FileConfigVO) => {
return defHttp.post({ url: '/infra/file-config/create', params })
export const createFileConfigApi = (data: FileConfigVO) => {
return request.post({ url: '/infra/file-config/create', data })
}
// 修改文件配置
export const updateFileConfigApi = (params: FileConfigVO) => {
return defHttp.put({ url: '/infra/file-config/update', params })
export const updateFileConfigApi = (data: FileConfigVO) => {
return request.put({ url: '/infra/file-config/update', data })
}
// 删除文件配置
export const deleteFileConfigApi = (id: number) => {
return defHttp.delete({ url: '/infra/file-config/delete?id=' + id })
return request.delete({ url: '/infra/file-config/delete?id=' + id })
}
// 测试文件配置
export const testFileConfigApi = (id: number) => {
return defHttp.get({ url: '/infra/file-config/test?id=' + id })
return request.get({ url: '/infra/file-config/test?id=' + id })
}

View File

@ -1,38 +1,36 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { JobVO } from './types'
const request = useAxios()
// 任务列表
export const getJobPageApi = ({ params }) => {
return defHttp.get<PageResult<JobVO>>({ url: '/infra/job/page', params })
export const getJobPageApi = (params) => {
return request.get({ url: '/infra/job/page', params })
}
// 任务详情
export const getJobApi = (id: number) => {
return defHttp.get<JobVO>({ url: '/infra/job/get?id=' + id })
return request.get({ url: '/infra/job/get?id=' + id })
}
// 新增任务
export const createJobApi = (params: JobVO) => {
return defHttp.post({ url: '/infra/job/create', params })
export const createJobApi = (data: JobVO) => {
return request.post({ url: '/infra/job/create', data })
}
// 修改定时任务调度
export const updateJobApi = (params: JobVO) => {
return defHttp.put({ url: '/infra/job/update', params })
return request.put({ url: '/infra/job/update', params })
}
// 删除定时任务调度
export const deleteJobApi = (id: number) => {
return defHttp.delete({ url: '/infra/job/delete?id=' + id })
return request.delete({ url: '/infra/job/delete?id=' + id })
}
// 导出定时任务调度
export const exportJobApi = (params) => {
return defHttp.get({
url: '/infra/job/export-excel',
params,
responseType: 'blob'
})
return request.get({ url: '/infra/job/export-excel', params, responseType: 'blob' })
}
// 任务状态修改
@ -41,15 +39,15 @@ export const updateJobStatusApi = (id: number, status: number) => {
id,
status
}
return defHttp.put({ url: '/infra/job/update-status', data: data })
return request.put({ url: '/infra/job/update-status', data: data })
}
// 定时任务立即执行一次
export const runJobApi = (id: number) => {
return defHttp.put({ url: '/infra/job/trigger?id=' + id })
return request.put({ url: '/infra/job/trigger?id=' + id })
}
// 获得定时任务的下 n 次执行时间
export const getJobNextTimesApi = (id: number) => {
return defHttp.get({ url: '/infra/job/get_next_times?id=' + id })
return request.get({ url: '/infra/job/get_next_times?id=' + id })
}

View File

@ -1,19 +1,20 @@
import { defHttp } from '@/config/axios'
import type { JobLogVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 任务日志列表
export const getJobLogPageApi = ({ params }) => {
return defHttp.get<PageResult<JobLogVO>>({ url: '/infra/job-log/page', params })
export const getJobLogPageApi = (params) => {
return request.get({ url: '/infra/job-log/page', params })
}
// 任务日志详情
export const getJobLogApi = (id: number) => {
return defHttp.get<JobLogVO>({ url: '/infra/job-log/get?id=' + id })
return request.get({ url: '/infra/job-log/get?id=' + id })
}
// 导出定时任务日志
export const exportJobLogApi = (params) => {
return defHttp.get({
return request.get({
url: '/infra/job-log/export-excel',
params,
responseType: 'blob'

View File

@ -1,16 +1,25 @@
import { defHttp } from '@/config/axios'
import { RedisKeyInfo, RedisMonitorInfoVO } from '@/api/infra/redis/types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
/**
* redis
*/
export const redisMonitorInfo = () => {
return defHttp.get<RedisMonitorInfoVO>({ url: '/infra/redis/get-monitor-info' })
export const getCacheApi = () => {
return request.get({ url: '/infra/redis/get-monitor-info' })
}
// 获取模块
export const getKeyDefineListApi = () => {
return request.get({ url: '/infra/redis/get-key-define-list' })
}
/**
* redis key列表
*/
export const redisKeysInfo = () => {
return defHttp.get<RedisKeyInfo[]>({ url: '/infra/redis/get-key-list' })
export const getKeyListApi = (keyTemplate: string) => {
return request.get({
url: '/infra/redis/get-key-list',
params: {
keyTemplate
}
})
}

View File

@ -1,6 +1,8 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import { getRefreshToken } from '@/utils/auth'
import type { UserLoginVO, TokenType, UserInfoVO } from './types'
import type { UserLoginVO } from './types'
const request = useAxios()
export interface CodeImgResult {
captchaOnOff: boolean
@ -18,45 +20,45 @@ export interface SmsLoginVO {
// 获取验证码
export const getCodeImgApi = () => {
return defHttp.get<CodeImgResult>({ url: '/system/captcha/get-image' })
return request.get({ url: '/system/captcha/get-image' })
}
// 登录
export const loginApi = (params: UserLoginVO) => {
return defHttp.post<TokenType>({ url: '/system/auth/login', params })
export const loginApi = (data: UserLoginVO) => {
return request.post({ url: '/system/auth/login', data })
}
// 刷新访问令牌
export const refreshToken = () => {
return defHttp.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() })
return request.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() })
}
// 使用租户名,获得租户编号
export const getTenantIdByNameApi = (name: string) => {
return defHttp.get({ url: '/system/tenant/get-id-by-name?name=' + name })
return request.get({ url: '/system/tenant/get-id-by-name?name=' + name })
}
// 登出
export const loginOutApi = () => {
return defHttp.delete({ url: '/system/auth/logout' })
return request.delete({ url: '/system/auth/logout' })
}
// 获取用户权限信息
export const getInfoApi = () => {
return defHttp.get<UserInfoVO>({ url: '/system/auth/get-permission-info' })
return request.get({ url: '/system/auth/get-permission-info' })
}
// 路由
export const getAsyncRoutesApi = () => {
return defHttp.get({ url: '/system/auth/list-menus' })
return request.get({ url: '/system/auth/list-menus' })
}
//获取登录验证码
export const sendSmsCodeApi = (params: SmsCodeVO) => {
return defHttp.post({ url: '/system/auth/send-sms-code', params })
export const sendSmsCodeApi = (data: SmsCodeVO) => {
return request.post({ url: '/system/auth/send-sms-code', data })
}
// 短信验证码登录
export const smsLoginApi = (params: SmsLoginVO) => {
return defHttp.post({ url: '/system/auth/sms-login', params })
export const smsLoginApi = (data: SmsLoginVO) => {
return request.post({ url: '/system/auth/sms-login', data })
}

View File

@ -1,24 +1,26 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { AppVO } from './types'
const request = useAxios()
// 查询列表支付应用
export const getAppPageApi = ({ params }) => {
return defHttp.get<PageResult<AppVO>>({ url: '/pay/app/page', params })
export const getAppPageApi = (params) => {
return request.get({ url: '/pay/app/page', params })
}
// 查询详情支付应用
export const getAppApi = (id: number) => {
return defHttp.get<AppVO>({ url: '/pay/app/get?id=' + id })
return request.get({ url: '/pay/app/get?id=' + id })
}
// 新增支付应用
export const createAppApi = (params: AppVO) => {
return defHttp.post({ url: '/pay/app/create', params })
export const createAppApi = (data: AppVO) => {
return request.post({ url: '/pay/app/create', data })
}
// 修改支付应用
export const updateAppApi = (params: AppVO) => {
return defHttp.put({ url: '/pay/app/update', params })
export const updateAppApi = (data: AppVO) => {
return request.put({ url: '/pay/app/update', data })
}
// 支付应用信息状态修改
@ -27,20 +29,20 @@ export const changeAppStatusApi = (id: number, status: number) => {
id,
status
}
return defHttp.put({ url: '/pay/app/update-status', data: data })
return request.put({ url: '/pay/app/update-status', data: data })
}
// 删除支付应用
export const deleteAppApi = (id: number) => {
return defHttp.delete({ url: '/pay/app/delete?id=' + id })
return request.delete({ url: '/pay/app/delete?id=' + id })
}
// 导出支付应用
export const exportAppApi = (params) => {
return defHttp.get({ url: '/pay/app/export-excel', params, responseType: 'blob' })
return request.get({ url: '/pay/app/export-excel', params, responseType: 'blob' })
}
// 根据商ID称搜索应用列表
export const getAppListByMerchantIdApi = (merchantId: number) => {
return defHttp.get({ url: '/pay/app/list-merchant-id', params: { merchantId: merchantId } })
return request.get({ url: '/pay/app/list-merchant-id', params: { merchantId: merchantId } })
}

View File

@ -1,9 +1,11 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { ChannelVO } from './types'
const request = useAxios()
// 查询列表支付渠道
export const getChannelPageApi = ({ params }) => {
return defHttp.get<PageResult<ChannelVO>>({ url: '/pay/channel/page', params })
export const getChannelPageApi = (params) => {
return request.get({ url: '/pay/channel/page', params })
}
// 查询详情支付渠道
@ -13,25 +15,25 @@ export const getChannelApi = (merchantId: number, appId: string, code: string) =
appId: appId,
code: code
}
return defHttp.get<ChannelVO>({ url: '/pay/channel/get-channel', params: params })
return request.get({ url: '/pay/channel/get-channel', params: params })
}
// 新增支付渠道
export const createChannelApi = (params: ChannelVO) => {
return defHttp.post({ url: '/pay/channel/create', params })
export const createChannelApi = (data: ChannelVO) => {
return request.post({ url: '/pay/channel/create', data })
}
// 修改支付渠道
export const updateChannelApi = (params: ChannelVO) => {
return defHttp.put({ url: '/pay/channel/update', params })
export const updateChannelApi = (data: ChannelVO) => {
return request.put({ url: '/pay/channel/update', data })
}
// 删除支付渠道
export const deleteChannelApi = (id: number) => {
return defHttp.delete({ url: '/pay/channel/delete?id=' + id })
return request.delete({ url: '/pay/channel/delete?id=' + id })
}
// 导出支付渠道
export const exportChannelApi = (params) => {
return defHttp.get({ url: '/pay/channel/export-excel', params, responseType: 'blob' })
return request.get({ url: '/pay/channel/export-excel', params, responseType: 'blob' })
}

View File

@ -1,19 +1,21 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { MerchantVO } from './types'
const request = useAxios()
// 查询列表支付商户
export const getMerchantPageApi = ({ params }) => {
return defHttp.get<PageResult<MerchantVO>>({ url: '/pay/merchant/page', params })
export const getMerchantPageApi = (params) => {
return request.get({ url: '/pay/merchant/page', params })
}
// 查询详情支付商户
export const getMerchantApi = (id: number) => {
return defHttp.get<MerchantVO>({ url: '/pay/merchant/get?id=' + id })
return request.get({ url: '/pay/merchant/get?id=' + id })
}
// 根据商户名称搜索商户列表
export const getMerchantListByNameApi = (name: string) => {
return defHttp.get<MerchantVO>({
return request.get({
url: '/pay/merchant/list-by-name?id=',
params: {
name: name
@ -22,23 +24,23 @@ export const getMerchantListByNameApi = (name: string) => {
}
// 新增支付商户
export const createMerchantApi = (params: MerchantVO) => {
return defHttp.post({ url: '/pay/merchant/create', params })
export const createMerchantApi = (data: MerchantVO) => {
return request.post({ url: '/pay/merchant/create', data })
}
// 修改支付商户
export const updateMerchantApi = (params: MerchantVO) => {
return defHttp.put({ url: '/pay/merchant/update', params })
export const updateMerchantApi = (data: MerchantVO) => {
return request.put({ url: '/pay/merchant/update', data })
}
// 删除支付商户
export const deleteMerchantApi = (id: number) => {
return defHttp.delete({ url: '/pay/merchant/delete?id=' + id })
return request.delete({ url: '/pay/merchant/delete?id=' + id })
}
// 导出支付商户
export const exportMerchantApi = (params) => {
return defHttp.get({ url: '/pay/merchant/export-excel', params, responseType: 'blob' })
return request.get({ url: '/pay/merchant/export-excel', params, responseType: 'blob' })
}
// 支付商户状态修改
export const changeMerchantStatusApi = (id: number, status: number) => {
@ -46,5 +48,5 @@ export const changeMerchantStatusApi = (id: number, status: number) => {
id,
status
}
return defHttp.put({ url: '/pay/merchant/update-status', data: data })
return request.put({ url: '/pay/merchant/update-status', data: data })
}

View File

@ -1,32 +1,34 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { OrderVO } from './types'
const request = useAxios()
// 查询列表支付订单
export const getOrderPageApi = ({ params }) => {
return defHttp.get<PageResult<OrderVO>>({ url: '/pay/order/page', params })
export const getOrderPageApi = async (params) => {
return await request.get({ url: '/pay/order/page', params })
}
// 查询详情支付订单
export const getOrderApi = (id: number) => {
return defHttp.get<OrderVO>({ url: '/pay/order/get?id=' + id })
export const getOrderApi = async (id: number) => {
return await request.get({ url: '/pay/order/get?id=' + id })
}
// 新增支付订单
export const createOrderApi = (params: OrderVO) => {
return defHttp.post({ url: '/pay/order/create', params })
export const createOrderApi = async (data: OrderVO) => {
return await request.post({ url: '/pay/order/create', data })
}
// 修改支付订单
export const updateOrderApi = (params: OrderVO) => {
return defHttp.put({ url: '/pay/order/update', params })
export const updateOrderApi = async (data: OrderVO) => {
return await request.put({ url: '/pay/order/update', data })
}
// 删除支付订单
export const deleteOrderApi = (id: number) => {
return defHttp.delete({ url: '/pay/order/delete?id=' + id })
export const deleteOrderApi = async (id: number) => {
return await request.delete({ url: '/pay/order/delete?id=' + id })
}
// 导出支付订单
export const exportOrderApi = (params) => {
return defHttp.get({ url: '/pay/order/export-excel', params, responseType: 'blob' })
export const exportOrderApi = async (params) => {
return await request.get({ url: '/pay/order/export-excel', params, responseType: 'blob' })
}

View File

@ -1,32 +1,34 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { RefundVO } from './types'
const request = useAxios()
// 查询列表退款订单
export const getRefundPageApi = ({ params }) => {
return defHttp.get<PageResult<RefundVO>>({ url: '/pay/refund/page', params })
export const getRefundPageApi = (params) => {
return request.get({ url: '/pay/refund/page', params })
}
// 查询详情退款订单
export const getRefundApi = (id: number) => {
return defHttp.get<RefundVO>({ url: '/pay/refund/get?id=' + id })
return request.get({ url: '/pay/refund/get?id=' + id })
}
// 新增退款订单
export const createRefundApi = (params: RefundVO) => {
return defHttp.post({ url: '/pay/refund/create', params })
export const createRefundApi = (data: RefundVO) => {
return request.post({ url: '/pay/refund/create', data })
}
// 修改退款订单
export const updateRefundApi = (params: RefundVO) => {
return defHttp.put({ url: '/pay/refund/update', params })
export const updateRefundApi = (data: RefundVO) => {
return request.put({ url: '/pay/refund/update', data })
}
// 删除退款订单
export const deleteRefundApi = (id: number) => {
return defHttp.delete({ url: '/pay/refund/delete?id=' + id })
return request.delete({ url: '/pay/refund/delete?id=' + id })
}
// 导出退款订单
export const exportRefundApi = (params) => {
return defHttp.get({ url: '/pay/refund/export-excel', params, responseType: 'blob' })
return request.get({ url: '/pay/refund/export-excel', params, responseType: 'blob' })
}

View File

@ -1,32 +1,34 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { DeptVO } from './types'
const request = useAxios()
// 查询部门(精简)列表
export const listSimpleDeptApi = () => {
return defHttp.get({ url: '/system/dept/list-all-simple' })
return request.get({ url: '/system/dept/list-all-simple' })
}
// 查询部门列表
export const getDeptPageApi = ({ params }) => {
return defHttp.get<PageResult<DeptVO>>({ url: '/system/dept/list', params })
export const getDeptPageApi = (params) => {
return request.get({ url: '/system/dept/list', params })
}
// 查询部门详情
export const getDeptApi = (id: number) => {
return defHttp.get<DeptVO>({ url: '/system/dept/get?id=' + id })
return request.get({ url: '/system/dept/get?id=' + id })
}
// 新增部门
export const createDeptApi = (params: DeptVO) => {
return defHttp.post({ url: '/system/dept/create', data: params })
export const createDeptApi = (data: DeptVO) => {
return request.post({ url: '/system/dept/create', data: data })
}
// 修改部门
export const updateDeptApi = (params: DeptVO) => {
return defHttp.put({ url: '/system/dept/update', data: params })
return request.put({ url: '/system/dept/update', data: params })
}
// 删除部门
export const deleteDeptApi = (id: number) => {
return defHttp.delete({ url: '/system/dept/delete?id=' + id })
return request.delete({ url: '/system/dept/delete?id=' + id })
}

View File

@ -1,36 +1,38 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { DictDataVO } from './types'
const request = useAxios()
// 查询字典数据(精简)列表
export const listSimpleDictDataApi = () => {
return defHttp.get({ url: '/system/dict-data/list-all-simple' })
return request.get({ url: '/system/dict-data/list-all-simple' })
}
// 查询字典数据列表
export const getDictDataPageApi = ({ params }) => {
return defHttp.get<PageResult<DictDataVO>>({ url: '/system/dict-data/page', params })
export const getDictDataPageApi = (params) => {
return request.get({ url: '/system/dict-data/page', params })
}
// 查询字典数据详情
export const getDictDataApi = (id: number) => {
return defHttp.get({ url: '/system/dict-data/get?id=' + id })
return request.get({ url: '/system/dict-data/get?id=' + id })
}
// 新增字典数据
export const createDictDataApi = (params: DictDataVO) => {
return defHttp.post({ url: '/system/dict-data/create', params })
export const createDictDataApi = (data: DictDataVO) => {
return request.post({ url: '/system/dict-data/create', data })
}
// 修改字典数据
export const updateDictDataApi = (params: DictDataVO) => {
return defHttp.put({ url: '/system/dict-data/update', params })
export const updateDictDataApi = (data: DictDataVO) => {
return request.put({ url: '/system/dict-data/update', data })
}
// 删除字典数据
export const deleteDictDataApi = (id: number) => {
return defHttp.delete({ url: '/system/dict-data/delete?id=' + id })
return request.delete({ url: '/system/dict-data/delete?id=' + id })
}
// 导出字典类型数据
export const exportDictDataApi = (params: DictDataVO) => {
return defHttp.get({ url: '/system/dict-data/export', params })
return request.get({ url: '/system/dict-data/export', params })
}

View File

@ -1,36 +1,38 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { DictTypeVO } from './types'
const request = useAxios()
// 查询字典(精简)列表
export const listSimpleDictTypeApi = () => {
return defHttp.get({ url: '/system/dict-type/list-all-simple' })
return request.get({ url: '/system/dict-type/list-all-simple' })
}
// 查询字典列表
export const getDictTypePageApi = ({ params }) => {
return defHttp.get<PageResult<DictTypeVO>>({ url: '/system/dict-type/page', params })
export const getDictTypePageApi = (params) => {
return request.get({ url: '/system/dict-type/page', params })
}
// 查询字典详情
export const getDictTypeApi = (id: number) => {
return defHttp.get({ url: '/system/dict-type/get?id=' + id })
return request.get({ url: '/system/dict-type/get?id=' + id })
}
// 新增字典
export const createDictTypeApi = (params: DictTypeVO) => {
return defHttp.post({ url: '/system/dict-type/create', params })
export const createDictTypeApi = (data: DictTypeVO) => {
return request.post({ url: '/system/dict-type/create', data })
}
// 修改字典
export const updateDictTypeApi = (params: DictTypeVO) => {
return defHttp.put({ url: '/system/dict-type/update', params })
export const updateDictTypeApi = (data: DictTypeVO) => {
return request.put({ url: '/system/dict-type/update', data })
}
// 删除字典
export const deleteDictTypeApi = (id: number) => {
return defHttp.delete({ url: '/system/dict-type/delete?id=' + id })
return request.delete({ url: '/system/dict-type/delete?id=' + id })
}
// 导出字典类型
export const exportDictTypeApi = (params: DictTypeVO) => {
return defHttp.get({ url: '/system/dict-type/export', params })
return request.get({ url: '/system/dict-type/export', params })
}

View File

@ -1,31 +1,33 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { ErrorCodeVO } from './types'
const request = useAxios()
// 查询错误码列表
export const getErrorCodePageApi = ({ params }) => {
return defHttp.get<PageResult<ErrorCodeVO>>({ url: '/system/error-code/page', params })
export const getErrorCodePageApi = (params) => {
return request.get({ url: '/system/error-code/page', params })
}
// 查询错误码详情
export const getErrorCodeApi = (id: number) => {
return defHttp.get<ErrorCodeVO>({ url: '/system/error-code/get?id=' + id })
return request.get({ url: '/system/error-code/get?id=' + id })
}
// 新增错误码
export const createErrorCodeApi = (params: ErrorCodeVO) => {
return defHttp.post({ url: '/system/error-code/create', params })
export const createErrorCodeApi = (data: ErrorCodeVO) => {
return request.post({ url: '/system/error-code/create', data })
}
// 修改错误码
export const updateErrorCodeApi = (params: ErrorCodeVO) => {
return defHttp.put({ url: '/system/error-code/update', params })
export const updateErrorCodeApi = (data: ErrorCodeVO) => {
return request.put({ url: '/system/error-code/update', data })
}
// 删除错误码
export const deleteErrorCodeApi = (id: number) => {
return defHttp.delete({ url: '/system/error-code/delete?id=' + id })
return request.delete({ url: '/system/error-code/delete?id=' + id })
}
// 导出错误码
export const excelErrorCodeApi = (params) => {
return defHttp.get({ url: '/system/error-code/export-excel', params, responseType: 'blob' })
return request.get({ url: '/system/error-code/export-excel', params, responseType: 'blob' })
}

View File

@ -1,11 +1,12 @@
import { defHttp } from '@/config/axios'
import type { LoginLogVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询登录日志列表
export const getLoginLogPageApi = ({ params }) => {
return defHttp.get<PageResult<LoginLogVO>>({ url: '/system/login-log/page', params })
export const getLoginLogPageApi = (params) => {
return request.get({ url: '/system/login-log/page', params })
}
// 导出登录日志
export const exportLoginLogApi = (params) => {
return defHttp.get({ url: '/system/login-log/export', params, responseType: 'blob' })
return request.get({ url: '/system/login-log/export', params, responseType: 'blob' })
}

View File

@ -1,31 +1,33 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { MenuVO } from './types'
const request = useAxios()
// 查询菜单(精简)列表
export const listSimpleMenusApi = () => {
return defHttp.get({ url: '/system/menu/list-all-simple' })
return request.get({ url: '/system/menu/list-all-simple' })
}
// 查询菜单列表
export const getMenuListApi = (params) => {
return defHttp.get({ url: '/system/menu/list', params })
return request.get({ url: '/system/menu/list', params })
}
// 获取菜单详情
export const getMenuApi = (id: number) => {
return defHttp.get<MenuVO>({ url: '/system/menu/get?id=' + id })
return request.get({ url: '/system/menu/get?id=' + id })
}
// 新增菜单
export const createMenuApi = (params: MenuVO) => {
return defHttp.post({ url: '/system/menu/create', params })
export const createMenuApi = (data: MenuVO) => {
return request.post({ url: '/system/menu/create', data })
}
// 修改菜单
export const updateMenuApi = (params: MenuVO) => {
return defHttp.put({ url: '/system/menu/update', params })
export const updateMenuApi = (data: MenuVO) => {
return request.put({ url: '/system/menu/update', data })
}
// 删除菜单
export const deleteMenuApi = (id: number) => {
return defHttp.delete({ url: '/system/menu/delete?id=' + id })
return request.delete({ url: '/system/menu/delete?id=' + id })
}

View File

@ -1,27 +1,29 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { NoticeVO } from './types'
const request = useAxios()
// 查询公告列表
export const getNoticePageApi = ({ params }) => {
return defHttp.get<PageResult<NoticeVO>>({ url: '/system/notice/page', params })
export const getNoticePageApi = (params) => {
return request.get({ url: '/system/notice/page', params })
}
// 查询公告详情
export const getNoticeApi = (id: number) => {
return defHttp.get<NoticeVO>({ url: '/system/notice/get?id=' + id })
return request.get({ url: '/system/notice/get?id=' + id })
}
// 新增公告
export const createNoticeApi = (params: NoticeVO) => {
return defHttp.post({ url: '/system/notice/create', params })
export const createNoticeApi = (data: NoticeVO) => {
return request.post({ url: '/system/notice/create', data })
}
// 修改公告
export const updateNoticeApi = (params: NoticeVO) => {
return defHttp.put({ url: '/system/notice/update', params })
export const updateNoticeApi = (data: NoticeVO) => {
return request.put({ url: '/system/notice/update', data })
}
// 删除公告
export const deleteNoticeApi = (id: number) => {
return defHttp.delete({ url: '/system/notice/delete?id=' + id })
return request.delete({ url: '/system/notice/delete?id=' + id })
}

View File

@ -1,27 +1,29 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import { OAuth2ClientVo } from './client.types'
const request = useAxios()
// 查询 OAuth2列表
export const getOAuth2ClientPageApi = ({ params }) => {
return defHttp.get<PageResult<OAuth2ClientVo>>({ url: '/system/oauth2-client/page', params })
export const getOAuth2ClientPageApi = (params) => {
return request.get({ url: '/system/oauth2-client/page', params })
}
// 查询 OAuth2详情
export const getOAuth2ClientApi = (id: number) => {
return defHttp.get<OAuth2ClientVo>({ url: '/system/oauth2-client/get?id=' + id })
return request.get({ url: '/system/oauth2-client/get?id=' + id })
}
// 新增 OAuth2
export const createOAuth2ClientApi = (params: OAuth2ClientVo) => {
return defHttp.post({ url: '/system/oauth2-client/create', params })
export const createOAuth2ClientApi = (data: OAuth2ClientVo) => {
return request.post({ url: '/system/oauth2-client/create', data })
}
// 修改 OAuth2
export const updateOAuth2ClientApi = (params: OAuth2ClientVo) => {
return defHttp.put({ url: '/system/oauth2-client/update', params })
export const updateOAuth2ClientApi = (data: OAuth2ClientVo) => {
return request.put({ url: '/system/oauth2-client/update', data })
}
// 删除 OAuth2
export const deleteOAuth2ClientApi = (id: number) => {
return defHttp.delete({ url: '/system/oauth2-client/delete?id=' + id })
return request.delete({ url: '/system/oauth2-client/delete?id=' + id })
}

View File

@ -1,12 +1,13 @@
import { defHttp } from '@/config/axios'
import { OAuth2TokenVo } from './token.types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询 token列表
export const getAccessTokenPageApi = ({ params }) => {
return defHttp.get<PageResult<OAuth2TokenVo>>({ url: '/system/oauth2-token/page', params })
export const getAccessTokenPageApi = (params) => {
return request.get({ url: '/system/oauth2-token/page', params })
}
// 删除 token
export const deleteAccessTokenApi = (accessToken: number) => {
return defHttp.delete({ url: '/system/oauth2-token/delete?accessToken=' + accessToken })
return request.delete({ url: '/system/oauth2-token/delete?accessToken=' + accessToken })
}

View File

@ -1,11 +1,12 @@
import { defHttp } from '@/config/axios'
import type { OperateLogVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询操作日志列表
export const getOperateLogPageApi = ({ params }) => {
return defHttp.get<PageResult<OperateLogVO>>({ url: '/system/operate-log/page', params })
export const getOperateLogPageApi = (params) => {
return request.get({ url: '/system/operate-log/page', params })
}
// 导出操作日志
export const exportOperateLogApi = (params) => {
return defHttp.get({ url: '/system/operate-log/export', params, responseType: 'blob' })
return request.get({ url: '/system/operate-log/export', params, responseType: 'blob' })
}

View File

@ -1,36 +1,38 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { PostVO } from './types'
const request = useAxios()
// 查询岗位列表
export const getPostPageApi = ({ params }) => {
return defHttp.get<PageResult<PostVO>>({ url: '/system/post/page', params })
export const getPostPageApi = async (params) => {
return await request.get({ url: '/system/post/page', params })
}
// 获取岗位精简信息列表
export const listSimplePostsApi = () => {
return defHttp.get<PostVO[]>({ url: '/system/post/list-all-simple' })
export const listSimplePostsApi = async () => {
return await request.get({ url: '/system/post/list-all-simple' })
}
// 查询岗位详情
export const getPostApi = (id: number) => {
return defHttp.get<PostVO>({ url: '/system/post/get?id=' + id })
export const getPostApi = async (id: number) => {
return await request.get({ url: '/system/post/get?id=' + id })
}
// 新增岗位
export const createPostApi = (params: PostVO) => {
return defHttp.post({ url: '/system/post/create', params })
export const createPostApi = async (data: PostVO) => {
return await request.post({ url: '/system/post/create', data })
}
// 修改岗位
export const updatePostApi = (params: PostVO) => {
return defHttp.put({ url: '/system/post/update', params })
export const updatePostApi = async (data: PostVO) => {
return await request.put({ url: '/system/post/update', data })
}
// 删除岗位
export const deletePostApi = (id: number) => {
return defHttp.delete({ url: '/system/post/delete?id=' + id })
export const deletePostApi = async (id: number) => {
return await request.delete({ url: '/system/post/delete?id=' + id })
}
// 导出岗位
export const exportPostApi = (params) => {
return defHttp.get({ url: '/system/post/export', params, responseType: 'blob' })
export const exportPostApi = async (params) => {
return await request.get({ url: '/system/post/export', params, responseType: 'blob' })
}

View File

@ -1,32 +1,34 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { RoleVO } from './types'
const request = useAxios()
// 查询角色列表
export const getRolePageApi = ({ params }) => {
return defHttp.get<PageResult<RoleVO>>({ url: '/system/role/page', params })
export const getRolePageApi = (params) => {
return request.get({ url: '/system/role/page', params })
}
// 查询角色详情
export const getRoleApi = (id: number) => {
return defHttp.get<RoleVO>({ url: '/system/role/get?id=' + id })
return request.get({ url: '/system/role/get?id=' + id })
}
// 新增角色
export const createRoleApi = (params: RoleVO) => {
return defHttp.post({ url: '/system/role/create', params })
export const createRoleApi = (data: RoleVO) => {
return request.post({ url: '/system/role/create', data })
}
// 修改角色
export const updateRoleApi = (params: RoleVO) => {
return defHttp.put({ url: '/system/role/update', params })
export const updateRoleApi = (data: RoleVO) => {
return request.put({ url: '/system/role/update', data })
}
// 修改角色状态
export const updateRoleStatusApi = (params: RoleVO) => {
return defHttp.put({ url: '/system/role/update-status', params })
export const updateRoleStatusApi = (data: RoleVO) => {
return request.put({ url: '/system/role/update-status', data })
}
// 删除角色
export const deleteRoleApi = (id: number) => {
return defHttp.delete({ url: '/system/role/delete?id=' + id })
return request.delete({ url: '/system/role/delete?id=' + id })
}

View File

@ -1,42 +1,44 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { SensitiveWordVO } from './types'
const request = useAxios()
// 查询敏感词列表
export const getSensitiveWordPageApi = ({ params }) => {
return defHttp.get<PageResult<SensitiveWordVO>>({ url: '/system/sensitive-word/page', params })
export const getSensitiveWordPageApi = (params) => {
return request.get({ url: '/system/sensitive-word/page', params })
}
// 查询敏感词详情
export const getSensitiveWordApi = (id: number) => {
return defHttp.get<SensitiveWordVO>({ url: '/system/sensitive-word/get?id=' + id })
return request.get({ url: '/system/sensitive-word/get?id=' + id })
}
// 新增敏感词
export const createSensitiveWordApi = (params: SensitiveWordVO) => {
return defHttp.post({ url: '/system/sensitive-word/create', params })
export const createSensitiveWordApi = (data: SensitiveWordVO) => {
return request.post({ url: '/system/sensitive-word/create', data })
}
// 修改敏感词
export const updateSensitiveWordApi = (params: SensitiveWordVO) => {
return defHttp.put({ url: '/system/sensitive-word/update', params })
export const updateSensitiveWordApi = (data: SensitiveWordVO) => {
return request.put({ url: '/system/sensitive-word/update', data })
}
// 删除敏感词
export const deleteSensitiveWordApi = (id: number) => {
return defHttp.delete({ url: '/system/sensitive-word/delete?id=' + id })
return request.delete({ url: '/system/sensitive-word/delete?id=' + id })
}
// 导出敏感词
export const exportSensitiveWordApi = (params) => {
return defHttp.get({ url: '/system/sensitive-word/export', params, responseType: 'blob' })
return request.get({ url: '/system/sensitive-word/export', params, responseType: 'blob' })
}
// 获取所有敏感词的标签数组
export const getSensitiveWordTagsApi = () => {
return defHttp.get<SensitiveWordVO>({ url: '/system/sensitive-word/get-tags' })
return request.get({ url: '/system/sensitive-word/get-tags' })
}
// 获得文本所包含的不合法的敏感词数组
export const validateTextApi = (id: number) => {
return defHttp.get<SensitiveWordVO>({ url: '/system/sensitive-word/validate-text?' + id })
return request.get({ url: '/system/sensitive-word/validate-text?' + id })
}

View File

@ -1,32 +1,34 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { SmsChannelVO } from './types'
const request = useAxios()
// 查询短信渠道列表
export const getSmsChannelPageApi = ({ params }) => {
return defHttp.get<PageResult<SmsChannelVO>>({ url: '/system/sms-channel/page', params })
export const getSmsChannelPageApi = (params) => {
return request.get({ url: '/system/sms-channel/page', params })
}
// 获得短信渠道精简列表
export function getSimpleSmsChannels() {
return defHttp.get({ url: '/system/sms-channel/list-all-simple' })
return request.get({ url: '/system/sms-channel/list-all-simple' })
}
// 查询短信渠道详情
export const getSmsChannelApi = (id: number) => {
return defHttp.get<SmsChannelVO>({ url: '/system/sms-channel/get?id=' + id })
return request.get({ url: '/system/sms-channel/get?id=' + id })
}
// 新增短信渠道
export const createSmsChannelApi = (params: SmsChannelVO) => {
return defHttp.post({ url: '/system/sms-channel/create', params })
export const createSmsChannelApi = (data: SmsChannelVO) => {
return request.post({ url: '/system/sms-channel/create', data })
}
// 修改短信渠道
export const updateSmsChannelApi = (params: SmsChannelVO) => {
return defHttp.put({ url: '/system/sms-channel/update', params })
export const updateSmsChannelApi = (data: SmsChannelVO) => {
return request.put({ url: '/system/sms-channel/update', data })
}
// 删除短信渠道
export const deleteSmsChannelApi = (id: number) => {
return defHttp.delete({ url: '/system/sms-channel/delete?id=' + id })
return request.delete({ url: '/system/sms-channel/delete?id=' + id })
}

View File

@ -1,12 +1,13 @@
import { defHttp } from '@/config/axios'
import type { SmsLogVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询短信日志列表
export const getSmsLogPageApi = ({ params }) => {
return defHttp.get<PageResult<SmsLogVO>>({ url: '/system/sms-log/page', params })
export const getSmsLogPageApi = (params) => {
return request.get({ url: '/system/sms-log/page', params })
}
// 导出短信日志
export const exportSmsLogApi = (params) => {
return defHttp.get({ url: '/system/sms-log/export', params, responseType: 'blob' })
return request.get({ url: '/system/sms-log/export', params, responseType: 'blob' })
}

View File

@ -1,37 +1,39 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { SmsTemplateVO, SmsSendVO } from './types'
const request = useAxios()
// 查询短信模板列表
export const getSmsTemplatePageApi = ({ params }) => {
return defHttp.get<PageResult<SmsTemplateVO>>({ url: '/system/sms-template/page', params })
export const getSmsTemplatePageApi = (params) => {
return request.get({ url: '/system/sms-template/page', params })
}
// 查询短信模板详情
export const getSmsTemplateApi = (id: number) => {
return defHttp.get<SmsTemplateVO>({ url: '/system/sms-template/get?id=' + id })
return request.get({ url: '/system/sms-template/get?id=' + id })
}
// 新增短信模板
export const createSmsTemplateApi = (params: SmsTemplateVO) => {
return defHttp.post({ url: '/system/sms-template/create', params })
export const createSmsTemplateApi = (data: SmsTemplateVO) => {
return request.post({ url: '/system/sms-template/create', data })
}
// 修改短信模板
export const updateSmsTemplateApi = (params: SmsTemplateVO) => {
return defHttp.put({ url: '/system/sms-template/update', params })
export const updateSmsTemplateApi = (data: SmsTemplateVO) => {
return request.put({ url: '/system/sms-template/update', data })
}
// 删除短信模板
export const deleteSmsTemplateApi = (id: number) => {
return defHttp.delete({ url: '/system/sms-template/delete?id=' + id })
return request.delete({ url: '/system/sms-template/delete?id=' + id })
}
// 发送短信
export function sendSms(params: SmsSendVO) {
return defHttp.post({ url: '/system/sms-template/send-sms', params })
export function sendSms(data: SmsSendVO) {
return request.post({ url: '/system/sms-template/send-sms', data })
}
// 导出短信模板
export const exportPostApi = (params) => {
return defHttp.get({ url: '/system/sms-template/export-excel', params, responseType: 'blob' })
return request.get({ url: '/system/sms-template/export-excel', params, responseType: 'blob' })
}

View File

@ -1,32 +1,34 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { TenantVO } from './types'
const request = useAxios()
// 查询租户列表
export const getTenantPageApi = ({ params }) => {
return defHttp.get<PageResult<TenantVO>>({ url: '/system/tenant/page', params })
export const getTenantPageApi = (params) => {
return request.get({ url: '/system/tenant/page', params })
}
// 查询租户详情
export const getTenantApi = (id: number) => {
return defHttp.get<TenantVO>({ url: '/system/tenant/get?id=' + id })
return request.get({ url: '/system/tenant/get?id=' + id })
}
// 新增租户
export const createTenantApi = (params: TenantVO) => {
return defHttp.post({ url: '/system/tenant/create', params })
export const createTenantApi = (data: TenantVO) => {
return request.post({ url: '/system/tenant/create', data })
}
// 修改租户
export const updateTenantApi = (params: TenantVO) => {
return defHttp.put({ url: '/system/tenant/update', params })
export const updateTenantApi = (data: TenantVO) => {
return request.put({ url: '/system/tenant/update', data })
}
// 删除租户
export const deleteTenantApi = (id: number) => {
return defHttp.delete({ url: '/system/tenant/delete?id=' + id })
return request.delete({ url: '/system/tenant/delete?id=' + id })
}
// 导出租户
export const exportTenantApi = (params) => {
return defHttp.get({ url: '/system/tenant/export-excel', params, responseType: 'blob' })
return request.get({ url: '/system/tenant/export-excel', params, responseType: 'blob' })
}

View File

@ -1,33 +1,33 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { TenantPackageVO } from './types'
const request = useAxios()
// 查询租户套餐列表
export const getTenantPackageTypePageApi = ({ params }) => {
return defHttp.get<PageResult<TenantPackageVO>>({ url: '/system/tenant-package/page', params })
export const getTenantPackageTypePageApi = (params) => {
return request.get({ url: '/system/tenant-package/page', params })
}
// 获得租户
export const getTenantPackageApi = (id: number) => {
return defHttp.get<TenantPackageVO>({ url: '/system/tenant-package/get?id=' + id })
return request.get({ url: '/system/tenant-package/get?id=' + id })
}
// 新增租户套餐
export const createTenantPackageTypeApi = (params: TenantPackageVO) => {
return defHttp.post({ url: '/system/tenant-package/create', params })
export const createTenantPackageTypeApi = (data: TenantPackageVO) => {
return request.post({ url: '/system/tenant-package/create', data })
}
// 修改租户套餐
export const updateTenantPackageTypeApi = (params: TenantPackageVO) => {
return defHttp.put({ url: '/system/tenant-package/update', params })
export const updateTenantPackageTypeApi = (data: TenantPackageVO) => {
return request.put({ url: '/system/tenant-package/update', data })
}
// 删除租户套餐
export const deleteTenantPackageTypeApi = (id: number) => {
return defHttp.delete({ url: '/system/tenant-package/delete?id=' + id })
return request.delete({ url: '/system/tenant-package/delete?id=' + id })
}
// // 获取租户套餐精简信息列表
export const getTenantPackageList = () => {
return defHttp.get({
url: '/system/tenant-package/get-simple-list'
})
return request.get({ url: '/system/tenant-package/get-simple-list' })
}

View File

@ -1,51 +1,50 @@
import { defHttp } from '@/config/axios'
import { useAxios } from '@/hooks/web/useAxios'
import type { UserVO } from './types'
const request = useAxios()
// 查询用户管理列表
export const getUserPageApi = ({ params }) => {
return defHttp.get<PageResult<UserVO>>({ url: '/system/user/page', params })
export const getUserPageApi = (params) => {
return request.get({ url: '/system/user/page', params })
}
// 查询用户详情
export const getUserApi = (id: number) => {
return defHttp.get<UserVO>({ url: '/system/user/get?id=' + id })
return request.get({ url: '/system/user/get?id=' + id })
}
// 新增用户
export const createUserApi = (params: UserVO) => {
return defHttp.post({ url: '/system/user/create', params })
export const createUserApi = (data: UserVO) => {
return request.post({ url: '/system/user/create', data })
}
// 修改用户
export const updateUserApi = (params: UserVO) => {
return defHttp.put({ url: '/system/user/update', params })
export const updateUserApi = (data: UserVO) => {
return request.put({ url: '/system/user/update', data })
}
// 删除用户
export const deleteUserApi = (id: number) => {
return defHttp.delete({ url: '/system/user/delete?id=' + id })
return request.delete({ url: '/system/user/delete?id=' + id })
}
// 导出用户
export const exportUserApi = (params) => {
return defHttp.get({ url: '/system/user/export', params, responseType: 'blob' })
return request.get({ url: '/system/user/export', params, responseType: 'blob' })
}
// 下载用户导入模板
export const importUserTemplateApi = () => {
return defHttp.get({ url: '/system/user/get-import-template', responseType: 'blob' })
return request.get({ url: '/system/user/get-import-template', responseType: 'blob' })
}
// 用户密码重置
export const resetUserPwdApi = (userId: number, password: number) => {
export const resetUserPwdApi = (id: number, password: string) => {
const data = {
userId,
id,
password
}
return defHttp.put({
url: '/system/user/resetPwd',
data: data
})
return request.put({ url: '/system/user/update-password', data: data })
}
// 用户状态修改
@ -54,15 +53,5 @@ export const updateUserStatusApi = (id: number, status: number) => {
id,
status
}
return defHttp.put({ url: '/system/user/update-status', data: data })
}
// 查询授权角色
export const getAuthRoleApi = (userId: string) => {
return defHttp.get({ url: '/system/user/authRole/' + userId })
}
// 保存授权角色
export const updateAuthRoleApi = (data: any) => {
return defHttp.put({ url: '/system/user/authRole', params: data })
return request.put({ url: '/system/user/update-status', data: data })
}

View File

@ -1,19 +1,20 @@
import { defHttp } from '@/config/axios'
import { ProfileVO } from './types'
import { useAxios } from '@/hooks/web/useAxios'
const request = useAxios()
// 查询用户个人信息
export const getUserProfileApi = () => {
return defHttp.get<ProfileVO>({ url: '/system/user/profile/get' })
return request.get({ url: '/system/user/profile/get' })
}
// 修改用户个人信息
export const updateUserProfileApi = ({ params }) => {
return defHttp.put({ url: '/system/user/profile/update', params })
export const updateUserProfileApi = (params) => {
return request.put({ url: '/system/user/profile/update', params })
}
// 用户密码重置
export const updateUserPwdApi = (oldPassword: string, newPassword: string) => {
return defHttp.put({
return request.put({
url: '/system/user/profile/update-password',
params: {
oldPassword: oldPassword,
@ -24,5 +25,5 @@ export const updateUserPwdApi = (oldPassword: string, newPassword: string) => {
// 用户头像上传
export const uploadAvatarApi = (data) => {
return defHttp.put({ url: '/system/user/profile/update-avatar', data: data })
return request.put({ url: '/system/user/profile/update-avatar', data: data })
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -1 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 0 1 4.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 0 1 2.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg>
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 014.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 012.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg>
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 013.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 01-3.889 2.843 10.582 10.582 0 01-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 01-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 01-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 013.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 013.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 01-3.89 2.843 11 11 0 01-4.732 1.066 10.58 10.58 0 01-4.667-1.066 12.478 12.478 0 01-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 01-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 013.824-2.772 11.212 11.212 0 014.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 01.778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 01-2.788 8.743 1236.373 1236.373 0 00-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 01-1.88-4.478 44.128 44.128 0 01-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 01-2.14-2.558 10.416 10.416 0 01-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 011.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -94,8 +94,8 @@ const dialogStyle = computed(() => {
<style lang="less">
.@{elNamespace}-dialog__header {
border-bottom: 1px solid var(--tags-view-border-color);
margin-right: 0 !important;
border-bottom: 1px solid var(--tags-view-border-color);
}
.@{elNamespace}-dialog__footer {

View File

@ -293,7 +293,7 @@ export default defineComponent({
<style lang="less" scoped>
.@{elNamespace}-form.@{namespace}-form .@{elNamespace}-row {
margin-left: 0 !important;
margin-right: 0 !important;
margin-left: 0 !important;
}
</style>

View File

@ -55,34 +55,31 @@ watch(
</script>
<template>
<div>
<router-link
<router-link
:class="[
prefixCls,
layout !== 'classic' ? `${prefixCls}__Top` : '',
'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative',
'dark:bg-[var(--el-bg-color)]'
]"
to="/"
>
<img
src="@/assets/imgs/logo.png"
class="w-[calc(var(--logo-height)-10px)] h-[calc(var(--logo-height)-10px)]"
/>
<div
v-if="show"
:class="[
prefixCls,
layout !== 'classic' ? `${prefixCls}__Top` : '',
'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative',
'dark:bg-[var(--el-bg-color)]'
'ml-10px text-16px font-700',
{
'text-[var(--logo-title-text-color)]': layout === 'classic',
'text-[var(--top-header-text-color)]':
layout === 'topLeft' || layout === 'top' || layout === 'cutMenu'
}
]"
to="/"
>
<img
src="@/assets/imgs/logo.png"
class="w-[calc(var(--logo-height)-10px)] h-[calc(var(--logo-height)-10px)]"
alt=""
/>
<div
v-if="show"
:class="[
'ml-10px text-16px font-700',
{
'text-[var(--logo-title-text-color)]': layout === 'classic',
'text-[var(--top-header-text-color)]':
layout === 'topLeft' || layout === 'top' || layout === 'cutMenu'
}
]"
>
{{ title }}
</div>
</router-link>
</div>
{{ title }}
</div>
</router-link>
</template>

View File

@ -13,7 +13,7 @@ export default defineComponent({
pageSize: propTypes.number.def(10),
currentPage: propTypes.number.def(1),
//
selection: propTypes.bool.def(true),
selection: propTypes.bool.def(false),
// schemashowOverflowTooltip,
showOverflowTooltip: propTypes.bool.def(true),
//

View File

@ -84,7 +84,7 @@ const refreshSelectedTag = async (view?: RouteLocationNormalizedLoaded) => {
tagsViewStore.delCachedView()
const { path, query } = view
await nextTick()
await replace({
replace({
path: '/redirect' + path,
query: query
})
@ -107,7 +107,15 @@ const toLastView = () => {
if (latestView) {
push(latestView)
} else {
push('/')
if (
unref(currentRoute).path === permissionStore.getAddRouters[0].path ||
unref(currentRoute).path === permissionStore.getAddRouters[0].redirect
) {
addTags()
return
}
// You can set another route
push(permissionStore.getAddRouters[0].path)
}
}

View File

@ -22,9 +22,9 @@ const { push, replace } = useRouter()
const user = wsCache.get('user')
const avatar = user ? user.user.avatar : '@/assets/imgs/avatar.gif'
const avatar = user?.user?.avatar ? user.user.avatar : '@/assets/imgs/avatar.gif'
const userName = user ? user.user.nickname : 'Admin'
const userName = user?.user?.nickname ? user.user.nickname : 'Admin'
const loginOut = () => {
ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), {
@ -38,7 +38,6 @@ const loginOut = () => {
removeToken()
tagsViewStore.delAllViews()
replace('/login')
// }
})
.catch(() => {})
}

View File

@ -1,287 +0,0 @@
import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, AxiosError } from 'axios'
import type { RequestOptions, RequestResult, UploadFileParams } from 'types/axios'
import type { CreateAxiosOptions } from './axiosTransform'
import axios from 'axios'
import qs from 'qs'
import { AxiosCanceler } from './axiosCancel'
import { isFunction } from '@/utils/is'
import { cloneDeep } from 'lodash-es'
import { ContentTypeEnum } from '@/enums/http.enum'
import { RequestEnum } from '@/enums/http.enum'
import { downloadByData } from '@/utils/filt'
export * from './axiosTransform'
/**
* @description: axios module
*/
export class VAxios {
private axiosInstance: AxiosInstance
private readonly options: CreateAxiosOptions
constructor(options: CreateAxiosOptions) {
this.options = options
this.axiosInstance = axios.create(options)
this.setupInterceptors()
}
/**
* @description: Create axios instance
*/
private createAxios(config: CreateAxiosOptions): void {
this.axiosInstance = axios.create(config)
}
private getTransform() {
const { transform } = this.options
return transform
}
getAxios(): AxiosInstance {
return this.axiosInstance
}
/**
* @description: Reconfigure axios
*/
configAxios(config: CreateAxiosOptions) {
if (!this.axiosInstance) {
return
}
this.createAxios(config)
}
/**
* @description: Set general header
*/
setHeader(headers: any): void {
if (!this.axiosInstance) {
return
}
Object.assign(this.axiosInstance.defaults.headers, headers)
}
/**
* @description: Interceptor configuration
*/
private setupInterceptors() {
const transform = this.getTransform()
if (!transform) {
return
}
const {
requestInterceptors,
requestInterceptorsCatch,
responseInterceptors,
responseInterceptorsCatch
} = transform
const axiosCanceler = new AxiosCanceler()
// Request interceptor configuration processing
this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
// If cancel repeat request is turned on, then cancel repeat request is prohibited
const {
// @ts-ignore
headers: { ignoreCancelToken }
} = config
const ignoreCancel =
ignoreCancelToken !== undefined
? ignoreCancelToken
: this.options.requestOptions?.ignoreCancelToken
!ignoreCancel && axiosCanceler.addPending(config)
if (requestInterceptors && isFunction(requestInterceptors)) {
config = requestInterceptors(config, this.options)
}
return config
}, undefined)
// Request interceptor error capture
requestInterceptorsCatch &&
isFunction(requestInterceptorsCatch) &&
this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch)
// Response result interceptor processing
this.axiosInstance.interceptors.response.use((res: AxiosResponse<any>) => {
res && axiosCanceler.removePending(res.config)
if (responseInterceptors && isFunction(responseInterceptors)) {
res = responseInterceptors(res)
}
return res
}, undefined)
// Response result interceptor error capture
responseInterceptorsCatch &&
isFunction(responseInterceptorsCatch) &&
this.axiosInstance.interceptors.response.use(undefined, responseInterceptorsCatch)
}
/**
* @description: File Upload
*/
uploadFile<T = any>(config: AxiosRequestConfig, params: UploadFileParams) {
const formData = new window.FormData()
const customFilename = params.name || 'file'
if (params.filename) {
formData.append(customFilename, params.file, params.filename)
} else {
formData.append(customFilename, params.file)
}
if (params.data) {
Object.keys(params.data).forEach((key) => {
const value = params.data![key]
if (Array.isArray(value)) {
value.forEach((item) => {
formData.append(`${key}[]`, item)
})
return
}
formData.append(key, params.data![key])
})
}
return this.axiosInstance.request<T>({
...config,
method: 'POST',
data: {
file: formData
},
headers: {
'Content-type': ContentTypeEnum.FORM_DATA,
// @ts-ignore
ignoreCancelToken: true
}
})
}
// support form-data
supportFormData(config: AxiosRequestConfig) {
const headers = config.headers || this.options.headers
const contentType = headers?.['Content-Type'] || headers?.['content-type']
if (
contentType !== ContentTypeEnum.FORM_URLENCODED ||
!Reflect.has(config, 'data') ||
config.method?.toUpperCase() === RequestEnum.GET
) {
return config
}
return {
...config,
data: qs.stringify(config.data, { arrayFormat: 'brackets' })
}
}
get<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'GET' }, options)
}
post<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'POST' }, options)
}
put<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'PUT' }, options)
}
delete<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'DELETE' }, options)
}
download<T = any>(
config: AxiosRequestConfig,
title: string,
options?: RequestOptions
): Promise<T> {
let conf: CreateAxiosOptions = cloneDeep({
...config,
method: 'GET',
responseType: 'blob'
})
const transform = this.getTransform()
const { requestOptions } = this.options
const opt: RequestOptions = Object.assign({}, requestOptions, options)
const { beforeRequestHook, requestCatchHook } = transform || {}
if (beforeRequestHook && isFunction(beforeRequestHook)) {
conf = beforeRequestHook(conf, opt)
}
conf.requestOptions = opt
conf = this.supportFormData(conf)
return new Promise((resolve, reject) => {
this.axiosInstance
.request<any, AxiosResponse<RequestResult>>(conf)
.then((res: AxiosResponse<RequestResult>) => {
resolve(res as unknown as Promise<T>)
// download file
if (typeof res != undefined) {
downloadByData(res?.data as unknown as BlobPart, title)
}
})
.catch((e: Error | AxiosError) => {
if (requestCatchHook && isFunction(requestCatchHook)) {
reject(requestCatchHook(e, opt))
return
}
if (axios.isAxiosError(e)) {
// rewrite error message from axios in here
}
reject(e)
})
})
}
request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
let conf: CreateAxiosOptions = cloneDeep(config)
const transform = this.getTransform()
const { requestOptions } = this.options
const opt: RequestOptions = Object.assign({}, requestOptions, options)
const { beforeRequestHook, requestCatchHook, transformRequestHook } = transform || {}
if (beforeRequestHook && isFunction(beforeRequestHook)) {
conf = beforeRequestHook(conf, opt)
}
conf.requestOptions = opt
conf = this.supportFormData(conf)
return new Promise((resolve, reject) => {
this.axiosInstance
.request<any, AxiosResponse<RequestResult>>(conf)
.then((res: AxiosResponse<RequestResult>) => {
if (transformRequestHook && isFunction(transformRequestHook)) {
try {
const ret = transformRequestHook(res, opt)
resolve(ret)
} catch (err) {
reject(err || new Error('request error!'))
}
return
}
resolve(res as unknown as Promise<T>)
})
.catch((e: Error | AxiosError) => {
if (requestCatchHook && isFunction(requestCatchHook)) {
reject(requestCatchHook(e, opt))
return
}
if (axios.isAxiosError(e)) {
// rewrite error message from axios in here
}
reject(e)
})
})
}
}

View File

@ -1,57 +0,0 @@
import type { AxiosRequestConfig, Canceler } from 'axios'
import axios from 'axios'
import { isFunction } from '@/utils/is'
// 用于存储每个请求的标识和取消功能
let pendingMap = new Map<string, Canceler>()
export const getPendingUrl = (config: AxiosRequestConfig) => [config.method, config.url].join('&')
export class AxiosCanceler {
/**
*
* @param {Object} config
*/
addPending(config: AxiosRequestConfig) {
this.removePending(config)
const url = getPendingUrl(config)
config.cancelToken =
config.cancelToken ||
new axios.CancelToken((cancel) => {
if (!pendingMap.has(url)) {
// If there is no current request in pending, add it
pendingMap.set(url, cancel)
}
})
}
/**
* @description:
*/
removeAllPending() {
pendingMap.forEach((cancel) => {
cancel && isFunction(cancel) && cancel()
})
pendingMap.clear()
}
/**
*
* @param {Object} config
*/
removePending(config: AxiosRequestConfig) {
const url = getPendingUrl(config)
if (pendingMap.has(url)) {
// 如果挂起中有当前请求标识符,则需要取消并删除当前请求
const cancel = pendingMap.get(url)
cancel && cancel(url)
pendingMap.delete(url)
}
}
/** 重置 */
reset(): void {
pendingMap = new Map<string, Canceler>()
}
}

View File

@ -1,35 +0,0 @@
/** 数据处理类,可根据项目配置 */
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
import type { RequestOptions, RequestResult } from 'types/axios'
export interface CreateAxiosOptions extends AxiosRequestConfig {
authenticationScheme?: string
transform?: AxiosTransform
requestOptions?: RequestOptions
}
export abstract class AxiosTransform {
/** 请求前的流程配置 */
beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig
/** 请求成功处理 */
transformRequestHook?: (res: AxiosResponse<RequestResult>, options: RequestOptions) => any
/** 请求失败处理 */
requestCatchHook?: (e: Error, options: RequestOptions) => Promise<any>
/** 请求之前的拦截器 */
requestInterceptors?: (
config: AxiosRequestConfig,
options: CreateAxiosOptions
) => AxiosRequestConfig
/** 请求之后的拦截器 */
responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>
/** 请求之前的拦截器错误处理 */
requestInterceptorsCatch?: (error: Error) => void
/** 请求之后的拦截器错误处理 */
responseInterceptorsCatch?: (error: Error) => void
}

View File

@ -1,74 +0,0 @@
import type { ErrorMessageMode } from 'types/axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
export function checkStatus(
status: number,
msg: string,
errorMessageMode: ErrorMessageMode = 'message'
): void {
const { t } = useI18n()
let errMessage = ''
switch (status) {
case 400:
errMessage = `${msg}`
break
// 401: Not logged in
// 如果未登录,跳转到登录页面,并携带当前页面的路径
// 成功登录后返回当前页面。此步骤需要在登录页面上操作。
case 401:
wsCache.clear()
errMessage = msg || t('sys.api.errMsg401')
break
case 403:
errMessage = t('sys.api.errMsg403')
break
// 404请求不存在
case 404:
errMessage = t('sys.api.errMsg404')
break
case 405:
errMessage = t('sys.api.errMsg405')
break
case 408:
errMessage = t('sys.api.errMsg408')
break
case 500:
errMessage = t('sys.api.errMsg500')
break
case 501:
errMessage = t('sys.api.errMsg501')
break
case 502:
errMessage = t('sys.api.errMsg502')
break
case 503:
errMessage = t('sys.api.errMsg503')
break
case 504:
errMessage = t('sys.api.errMsg504')
break
case 505:
errMessage = t('sys.api.errMsg505')
break
case 901:
errMessage = t('sys.api.errMsg505')
break
default:
}
if (errMessage) {
if (errorMessageMode === 'modal') {
ElMessageBox.confirm(errMessage, {
cancelButtonText: t('common.cancel'),
type: 'warning'
})
} else if (errorMessageMode === 'message') {
ElMessage.error(errMessage)
}
}
}

View File

@ -0,0 +1,46 @@
const config: {
base_url: {
base: string
dev: string
pro: string
test: string
}
result_code: number | string
default_headers: AxiosHeaders
request_timeout: number
} = {
/**
* api请求基础路径
*/
base_url: {
// 开发环境接口前缀
base: '',
// 打包开发环境接口前缀
dev: '',
// 打包生产环境接口前缀
pro: '',
// 打包测试环境接口前缀
test: ''
},
/**
*
*/
result_code: 200,
/**
*
*/
request_timeout: 30000,
/**
*
* application/x-www-form-urlencoded multipart/form-data
*/
default_headers: 'application/json'
}
export { config }

View File

@ -0,0 +1,6 @@
export default {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
default: '系统未知错误,请反馈给管理员'
}

View File

@ -1,45 +0,0 @@
import { isObject, isString } from '@/utils/is'
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'
export function joinTimestamp<T extends boolean>(
join: boolean,
restful: T
): T extends true ? string : object
export function joinTimestamp(join: boolean, restful = false): string | object {
if (!join) {
return restful ? '' : {}
}
const now = new Date().getTime()
if (restful) {
return `?_t=${now}`
}
return { _t: now }
}
/** 格式化请求参数中的时间 */
export function formatRequestDate(params: Recordable) {
if (Object.prototype.toString.call(params) !== '[object Object]') {
return
}
for (const key in params) {
if (params[key] && params[key]._isAMomentObject) {
params[key] = params[key].format(DATE_TIME_FORMAT)
}
if (isString(key)) {
const value = params[key]
if (value) {
try {
params[key] = isString(value) ? value.trim() : value
} catch (error: any) {
throw new Error(error)
}
}
}
if (isObject(params[key])) {
formatRequestDate(params[key])
}
}
}

View File

@ -1,285 +1,148 @@
// axios配置 可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动
// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import qs from 'qs'
import { config } from '@/config/axios/config'
import { getAccessToken, getRefreshToken, getTenantId } from '@/utils/auth'
import errorCode from './errorCode'
import type { AxiosResponse } from 'axios'
import type { RequestOptions, RequestResult } from 'types/axios'
import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform'
import { VAxios } from './Axios'
import { checkStatus } from './checkStatus'
import { RequestEnum, ResultEnum, ContentTypeEnum } from '@/enums/http.enum'
import { useCache } from '@/hooks/web/useCache'
import { isString } from '@/utils/is'
import { getAccessToken, setToken } from '@/utils/auth'
import { setObjToUrlParams, deepMerge } from './utils'
import { useI18n } from '@/hooks/web/useI18n'
import { joinTimestamp, formatRequestDate } from './helper'
import { ElMessage, ElMessageBox } from 'element-plus'
import { refreshToken } from '@/api/login'
const { t } = useI18n()
const { wsCache } = useCache()
const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
const BASE_URL = import.meta.env.VITE_BASE_URL
const BASE_API = import.meta.env.VITE_API_URL
const apiUrl = BASE_URL + BASE_API
const { result_code, base_url } = config
// 需要忽略的提示。忽略后,自动 Promise.reject('error')
const ignoreMsgs = [
'无效的刷新令牌', // 刷新令牌被删除时,不用提示
'刷新令牌已过期' // 使用刷新令牌,刷新获取新的访问令牌时,结果因为过期失败,此时需要忽略。否则,会导致继续 401无法跳转到登出界面
]
// 是否显示重新登录
// export let isRelogin = { show: false }
// TODO 请求队列
// let requestList = []
export const isRelogin = { show: false }
// Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现
// 是否正在刷新中
let isRefreshToken = false
/**
* @description: 便
*/
const transform: AxiosTransform = {
/**
* @description:
*/
transformRequestHook: async (res: AxiosResponse<RequestResult>, options: RequestOptions) => {
const { isTransformResponse, isReturnNativeResponse } = options
// 是否返回原生响应头 比如:需要获取响应头时使用该属性
if (isReturnNativeResponse) {
return res
}
// 不进行任何处理,直接返回
// 用于页面代码可能需要直接获取codedatamessage这些信息时开启
if (!isTransformResponse) {
return res.data
}
// 错误的时候返回
export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH]
const { data } = res
if (!data) {
// 返回“[HTTP]请求没有返回值”;
throw new Error(t('sys.api.apiRequestFailed'))
}
// 这里 coderesultmessage为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
const { code, msg } = data
const result = data.data
// TODO 输出res 方便调试,完成后删除
// console.info('data')
// console.info(data)
// console.info('result')
// console.info(result)
// TODO 芋艿:文件下载,需要特殊处理
if (code === undefined) {
console.log(res)
return res.data
}
// 创建axios实例
const service: AxiosInstance = axios.create({
baseURL: BASE_URL + BASE_API, // api 的 base_url
timeout: config.request_timeout // 请求超时时间
})
// 这里逻辑可以根据项目进行修改
const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS
if (hasSuccess) {
return result
}
// 在此处根据自己项目的实际情况对不同的code执行不同的操作
// 如果不希望中断当前请求请return数据否则直接抛出异常即可
let timeoutMsg = ''
switch (code) {
case ResultEnum.TIMEOUT:
// TODO 未完成
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
if (!isRefreshToken) {
isRefreshToken = true
const refreshTokenRes = await refreshToken()
// 1. 如果获取不到刷新令牌,则只能执行登出操作
if (!refreshTokenRes) {
timeoutMsg = t('sys.api.timeoutMessage')
wsCache.clear() // 清除浏览器全部临时缓存
ElMessageBox.confirm(timeoutMsg, {
confirmButtonText: t('login.relogin'),
cancelButtonText: t('common.cancel'),
type: 'warning'
})
.then(() => {})
.catch(() => {})
break
} else {
// 2. 进行刷新访问令牌
// 2.1 刷新成功,则回放队列的请求 + 当前请求
setToken(refreshTokenRes.data)
}
}
default:
if (msg) {
timeoutMsg = msg
}
}
// errorMessageMode=modal的时候会显示modal错误弹窗而不是消息提示用于一些比较重要的错误
// errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
if (options.errorMessageMode === 'modal') {
await ElMessageBox.confirm(timeoutMsg, {
type: 'error'
})
} else if (options.errorMessageMode === 'message') {
ElMessage.error(timeoutMsg)
}
throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'))
},
// 请求之前处理config
beforeRequestHook: (config, options) => {
const { apiUrl, joinParamsToUrl, formatDate, joinTime = true } = options
if (apiUrl && isString(apiUrl)) {
config.url = `${apiUrl}${config.url}`
}
const params = config.params || {}
const data = config.data || false
formatDate && data && !isString(data) && formatRequestDate(data)
if (config.method?.toUpperCase() === RequestEnum.GET) {
if (!isString(params)) {
// 给 get 请求加上时间戳参数,避免从缓存中拿数据。
config.params = Object.assign(params || {}, joinTimestamp(joinTime, false))
} else {
// 兼容restful风格
config.url = config.url + params + `${joinTimestamp(joinTime, true)}`
config.params = undefined
}
} else {
if (!isString(params)) {
formatDate && formatRequestDate(params)
if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
config.data = data
config.params = params
} else {
// 非GET请求如果没有提供data则将params视为data
config.data = params
config.params = undefined
}
if (joinParamsToUrl) {
config.url = setObjToUrlParams(
config.url as string,
Object.assign({}, config.params, config.data)
)
}
} else {
// 兼容restful风格
config.url = config.url + params
config.params = undefined
}
}
return config
},
/**
* @description:
*/
requestInterceptors: (config, options) => {
// 请求之前处理config
const token = getAccessToken()
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
// jwt token
;(config as Recordable).headers.Authorization = options.authenticationScheme
? `${options.authenticationScheme} ${token}`
: token
// request拦截器
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 是否需要设置 token
const isToken = (config!.headers || {}).isToken === false
if (getAccessToken() && !isToken) {
;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
}
// 设置租户
if (tenantEnable) {
const tenantId = wsCache.get('tenantId')
const tenantId = getTenantId()
if (tenantId) (config as Recordable).headers.common['tenant-id'] = tenantId
}
if (
config.method === 'post' &&
config!.headers!['Content-Type'] === 'application/x-www-form-urlencoded'
) {
config.data = qs.stringify(config.data)
}
// get参数编码
if (config.method === 'get' && config.params) {
let url = config.url as string
url += '?'
const keys = Object.keys(config.params)
for (const key of keys) {
if (config.params[key] !== void 0 && config.params[key] !== null) {
url += `${key}=${encodeURIComponent(config.params[key])}&`
}
}
// 给 get 请求加上时间戳参数,避免从缓存中拿数据
// const now = new Date().getTime()
// url = url.substring(0, url.length - 1) + `?_t=${now}`
config.params = {}
config.url = url
}
return config
},
(error: AxiosError) => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
/**
* @description:
*/
responseInterceptors: (res: AxiosResponse<any>) => {
return res
},
/**
* @description:
*/
responseInterceptorsCatch: (error: any) => {
const { response, code, message, config } = error || {}
const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'
const msg: string = response?.data?.msg ?? ''
const err: string = error?.toString?.() ?? ''
let errMessage = ''
try {
if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
errMessage = t('sys.api.apiTimeoutMessage')
}
if (err?.includes('Network Error')) {
errMessage = t('sys.api.networkExceptionMsg')
}
if (errMessage) {
if (errorMessageMode === 'modal') {
ElMessageBox.confirm(errMessage, {
type: 'error'
})
} else if (errorMessageMode === 'message') {
ElMessage.error(errMessage)
}
return Promise.reject(error)
}
} catch (error) {
throw new Error(error as unknown as string)
// response 拦截器
service.interceptors.response.use(
async (response: AxiosResponse<Recordable>) => {
const { data } = response
if (!data) {
// 返回“[HTTP]请求没有返回值”;
throw new Error()
}
checkStatus(error?.response?.status, msg, errorMessageMode)
// 未设置状态码则默认成功状态
const code = data.code || result_code
// 获取错误信息
const msg = data.msg || errorCode[code] || errorCode['default']
if (ignoreMsgs.indexOf(msg) !== -1) {
// 如果是忽略的错误码,直接返回 msg 异常
return Promise.reject(msg)
} else if (code === 401) {
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
if (!isRefreshToken) {
isRefreshToken = true
// 1. 如果获取不到刷新令牌,则只能执行登出操作
if (!getRefreshToken()) {
return handleAuthorized()
}
}
} else if (code === 500) {
ElMessage.error(msg)
return Promise.reject(new Error(msg))
} else if (code === 901) {
ElMessage.error(
'<div>演示模式,无法进行写操作</div>' +
'<div> &nbsp; </div>' +
'<div>参考 https://doc.iocoder.cn/ 教程</div>' +
'<div> &nbsp; </div>' +
'<div>5 分钟搭建本地环境</div>'
)
return Promise.reject(new Error(msg))
} else if (code !== 200) {
if (msg === '无效的刷新令牌') {
// hard coding忽略这个提示直接登出
console.log(msg)
} else {
ElNotification.error({
title: msg
})
}
return Promise.reject('error')
} else {
return data
}
},
(error: AxiosError) => {
console.log('err' + error) // for debug
ElMessage.error(error.message)
return Promise.reject(error)
}
)
function handleAuthorized() {
if (!isRelogin.show) {
isRelogin.show = true
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
isRelogin.show = false
})
.catch(() => {
isRelogin.show = false
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
}
function createAxios(opt?: Partial<CreateAxiosOptions>) {
return new VAxios(
deepMerge(
{
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
// authentication schemese.g: Bearer
// authenticationScheme: 'Bearer',
authenticationScheme: 'Bearer',
timeout: 10 * 1000,
// 基础接口地址
// baseURL: globSetting.apiUrl,
headers: { 'Content-Type': ContentTypeEnum.JSON },
// 如果是form-data格式
// headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
// 数据处理方式
transform,
// 配置项,下面的选项都可以在独立的接口请求中覆盖
requestOptions: {
// 默认将prefix 添加到url
joinPrefix: true,
// 是否返回原生响应头 比如:需要获取响应头时使用该属性
isReturnNativeResponse: false,
// 需要对返回数据进行处理
isTransformResponse: true,
// post请求的时候添加参数到url
joinParamsToUrl: false,
// 格式化提交参数时间
formatDate: true,
// 消息提示类型
errorMessageMode: 'message',
// 接口地址
apiUrl: apiUrl,
// 是否加入时间戳
joinTime: true,
// 忽略重复请求
ignoreCancelToken: true,
// 是否携带token
withToken: true
}
},
opt || {}
)
)
}
export const defHttp = createAxios()
// other api url
// export const otherHttp = createAxios({
// requestOptions: {
// apiUrl: 'xxx',
// urlPrefix: 'xxx',
// },
// });
export { service }

View File

@ -1,63 +0,0 @@
import { unref } from 'vue'
import { isObject } from '@/utils/is'
// dynamic use hook props
export const getDynamicProps = <T, U>(props: T): Partial<U> => {
const ret: Recordable = {}
Object.keys(props).map((key) => {
ret[key] = unref((props as Recordable)[key])
})
return ret as Partial<U>
}
export const openWindow = (
url: string,
opt?: {
target?: '_self' | '_blank' | string
noopener?: boolean
noreferrer?: boolean
}
) => {
const { target = '__blank', noopener = true, noreferrer = true } = opt || {}
const feature: string[] = []
noopener && feature.push('noopener=yes')
noreferrer && feature.push('noreferrer=yes')
window.open(url, target, feature.join(','))
}
/**
* Add the object as a parameter to the URL
* @param baseUrl url
* @param obj
* @returns {string}
* eg:
* let obj = {a: '3', b: '4'}
* setObjToUrlParams('www.baidu.com', obj)
* ==>www.baidu.com?a=3&b=4
*/
export const setObjToUrlParams = (baseUrl: string, obj: any): string => {
let parameters = ''
for (const key in obj) {
parameters += key + '=' + encodeURIComponent(obj[key]) + '&'
}
parameters = parameters.replace(/&$/, '')
return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters
}
/**
* @description: Set ui mount node
*/
export const getPopupContainer = (node?: HTMLElement): HTMLElement => {
return (node?.parentNode as HTMLElement) ?? document.body
}
export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
let key: string
for (key in target) {
src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key])
}
return src
}

View File

@ -1,51 +0,0 @@
/**
* @description: Request result set
*/
export enum ResultEnum {
SUCCESS = 0,
ERROR = 500,
TIMEOUT = 401,
TYPE = 'success'
}
/**
* @description: request method
*/
export enum RequestEnum {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
DELETE = 'DELETE'
}
/**
* @description: contentType
*/
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',
// form-data qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data upload
FORM_DATA = 'multipart/form-data;charset=UTF-8'
}
/**
* Exception related enumeration
*/
export enum ExceptionEnum {
// page not access
PAGE_NOT_ACCESS = 403,
// page not found
PAGE_NOT_FOUND = 404,
// error
ERROR = 500,
// net work error
NET_WORK_ERROR = 10000,
// No data on the page. In fact, it is not an exception page
PAGE_NOT_DATA = 10100
}

View File

@ -1,46 +1,48 @@
// import { service } from '@/config/axios'
import { service } from '@/config/axios'
// import { AxiosPromise } from 'axios'
import { config } from '@/config/axios/config'
// import { config } from '@/config/axios/config'
const { default_headers } = config
// const { default_headers } = config
const request = (option: AxiosConfig) => {
const { url, method, params, data, headersType, responseType } = option
return service({
url: url,
method,
params,
data,
responseType: responseType,
headers: {
'Content-Type': headersType || default_headers
}
})
}
// const request = <T>(option: AxiosConfig): AxiosPromise<T> => {
// const { url, method, params, data, headersType, responseType } = option
// return service({
// url: url,
// method,
// params,
// data,
// responseType: responseType,
// headers: {
// 'Content-Type': headersType || default_headers
// }
// })
// }
async function getFn<T = any>(option: AxiosConfig): Promise<T> {
const res = await request({ method: 'GET', ...option })
return res.data
}
// function getFn<T = any>(option: AxiosConfig): AxiosPromise<T> {
// return request<T>({ method: 'get', ...option })
// }
async function postFn<T = any>(option: AxiosConfig): Promise<T> {
const res = await request({ method: 'POST', ...option })
return res.data
}
// function postFn<T = any>(option: AxiosConfig): AxiosPromise<T> {
// return request<T>({ method: 'post', ...option })
// }
async function deleteFn<T = any>(option: AxiosConfig): Promise<T> {
const res = await request({ method: 'DELETE', ...option })
return res.data
}
// function deleteFn<T = any>(option: AxiosConfig): AxiosPromise<T> {
// return request<T>({ method: 'delete', ...option })
// }
async function putFn<T = any>(option: AxiosConfig): Promise<T> {
const res = await request({ method: 'PUT', ...option })
return res.data
}
// function putFn<T = any>(option: AxiosConfig): AxiosPromise<T> {
// return request<T>({ method: 'put', ...option })
// }
// export const useAxios = () => {
// return {
// get: getFn,
// post: postFn,
// delete: deleteFn,
// put: putFn
// }
// }
export const useAxios = () => {
return {
get: getFn,
post: postFn,
delete: deleteFn,
put: putFn
}
}

View File

@ -1,33 +1,38 @@
import download from '@/utils/download'
import { useI18n } from '@/hooks/web/useI18n'
import { Table, TableExpose } from '@/components/Table'
import { ElMessage, ElMessageBox, ElTable } from 'element-plus'
import { computed, nextTick, reactive, ref, unref, watch } from 'vue'
import { ElTable, ElMessageBox, ElMessage } from 'element-plus'
import { ref, reactive, watch, computed, unref, nextTick } from 'vue'
import type { TableProps } from '@/components/Table/src/types'
const { t } = useI18n()
import { useI18n } from '@/hooks/web/useI18n'
interface UseTableConfig<T, L> {
getListApi: (option: L) => Promise<T>
delListApi?: (ids: string | number) => Promise<unknown>
exportListApi?: (option: L) => Promise<T>
const { t } = useI18n()
interface ResponseType<T = any> {
list: T[]
total?: string
}
interface UseTableConfig<T = any> {
getListApi: (option: any) => Promise<T>
delListApi?: (option: any) => Promise<T>
exportListApi?: (option: any) => Promise<T>
// 返回数据格式配置
response?: ResponseType
props?: TableProps
}
interface TableObject<K, L> {
interface TableObject<T = any> {
pageSize: number
currentPage: number
total: number
tableList: K[]
paramsObj: L
tableList: T[]
params: any
loading: boolean
exportLoading: boolean
currentRow: Nullable<K>
currentRow: Nullable<T>
}
export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
config?: UseTableConfig<T, L>
) => {
const tableObject = reactive<TableObject<K, L>>({
export const useTable = <T = any>(config?: UseTableConfig<T>) => {
const tableObject = reactive<TableObject<T>>({
// 页数
pageSize: 10,
// 当前页
@ -37,7 +42,7 @@ export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
// 表格数据
tableList: [],
// AxiosConfig 配置
paramsObj: {} as L,
params: {},
// 加载中
loading: true,
// 导出加载中
@ -48,11 +53,9 @@ export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
const paramsObj = computed(() => {
return {
params: {
...tableObject.paramsObj.params,
pageSize: tableObject.pageSize,
pageNo: tableObject.currentPage
}
...tableObject.params,
pageSize: tableObject.pageSize,
pageNo: tableObject.currentPage
}
})
@ -109,33 +112,25 @@ export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
await (config?.delListApi && config?.delListApi(ids))
}
ElMessage.success(t('common.delSuccess'))
// 计算出临界点
tableObject.currentPage =
const currentPage =
tableObject.total % tableObject.pageSize === idsLength || tableObject.pageSize === 1
? tableObject.currentPage > 1
? tableObject.currentPage - 1
: tableObject.currentPage
: tableObject.currentPage
tableObject.currentPage = currentPage
methods.getList()
}
const methods: {
setProps: (props: Recordable) => void
getList: () => Promise<void>
setColumn: (columnProps: TableSetPropsType[]) => void
setSearchParams: (data: Recordable) => void
getSelections: () => Promise<K[]>
delList: (ids: string | number | string[] | number[], multiple: boolean) => Promise<void>
exportList: (fileName: string) => Promise<void>
} = {
const methods = {
getList: async () => {
tableObject.loading = true
const res = await config
?.getListApi(unref(paramsObj) as unknown as L)
.catch(() => {})
.finally(() => {
tableObject.loading = false
})
const res = await config?.getListApi(unref(paramsObj)).finally(() => {
tableObject.loading = false
})
if (res) {
tableObject.tableList = res?.list
tableObject.total = res?.total
@ -151,41 +146,42 @@ export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
},
getSelections: async () => {
const table = await getTable()
return (table?.selections || []) as K[]
return (table?.selections || []) as T[]
},
// 与Search组件结合
setSearchParams: (data: Recordable) => {
tableObject.currentPage = 1
tableObject.paramsObj = Object.assign(tableObject.paramsObj, {
params: {
pageSize: tableObject.pageSize,
pageNo: tableObject.currentPage,
...data
}
tableObject.params = Object.assign(tableObject.params, {
pageSize: tableObject.pageSize,
pageNo: tableObject.currentPage,
...data
})
methods.getList()
},
// 删除数据
delList: async (ids: string | number | string[] | number[], multiple: boolean) => {
delList: async (
ids: string | number | string[] | number[],
multiple: boolean,
message = true
) => {
const tableRef = await getTable()
let message = 'common.delDataMessage'
if (multiple) {
if (!tableRef?.selections.length) {
ElMessage.warning(t('common.delNoData'))
return
} else {
message = 'common.delMessage'
}
}
ElMessageBox.confirm(t(message), t('common.confirmTitle'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
type: 'warning'
})
.then(async () => {
if (message) {
ElMessageBox.confirm(t('common.delMessage'), t('common.confirmTitle'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
type: 'warning'
}).then(async () => {
await delData(ids)
})
.catch(() => {})
} else {
await delData(ids)
}
},
// 导出列表
exportList: async (fileName: string) => {
@ -196,14 +192,11 @@ export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
type: 'warning'
})
.then(async () => {
const res = await config
?.exportListApi?.(unref(paramsObj) as unknown as L)
.catch(() => {})
const res = await config?.exportListApi?.(unref(paramsObj) as unknown as T)
if (res) {
download.excel(res, fileName)
}
})
.catch(() => {})
.finally(() => {
tableObject.exportLoading = false
})

View File

@ -27,8 +27,8 @@ export const useValidator = () => {
}
}
// 不能有空格
const notSpace = (val: any, callback: Callback, message: string) => {
// 用户名不能有空格
if (val.indexOf(' ') !== -1) {
callback(new Error(message))
} else {
@ -36,8 +36,8 @@ export const useValidator = () => {
}
}
// 不能是特殊字符
const notSpecialCharacters = (val: any, callback: Callback, message: string) => {
// 密码不能是特殊字符
if (/[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/gi.test(val)) {
callback(new Error(message))
} else {

View File

@ -1,25 +1,37 @@
// 引入windi css
import '@/plugins/windi.css'
// 导入全局的svg图标
import '@/plugins/svgIcon'
// 初始化多语言
import { setupI18n } from '@/plugins/vueI18n'
// 引入状态管理
import { setupStore } from '@/store'
// 全局组件
import { setupGlobCom } from '@/components'
// 引入element-plus
import { setupElementPlus } from '@/plugins/elementPlus'
// 引入全局样式
import '@/styles/index.less'
// 引入动画
import '@/plugins/animate.css'
// 路由
import { setupRouter } from './router'
// 权限
import { setupAuth } from './directive'
import { setupAuth } from './directives'
import { createApp } from 'vue'
import App from './App.vue'
// 创建实例
const setupAll = async () => {
const app = createApp(App)

View File

@ -1,72 +0,0 @@
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n() // 国际化
const message = {
// 消息提示
msg(content: string) {
ElMessage.info(content)
},
// 错误消息
msgError(content: string) {
ElMessage.error(content)
},
// 成功消息
msgSuccess(content: string) {
ElMessage.success(content)
},
// 警告消息
msgWarning(content: string) {
ElMessage.warning(content)
},
// 弹出提示
alert(content: string) {
ElMessageBox.alert(content, t('common.confirmTitle'))
},
// 错误提示
alertError(content: string) {
ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'error' })
},
// 成功提示
alertSuccess(content: string) {
ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'success' })
},
// 警告提示
alertWarning(content: string) {
ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'warning' })
},
// 通知提示
notify(content: string) {
ElNotification.info(content)
},
// 错误通知
notifyError(content: string) {
ElNotification.error(content)
},
// 成功通知
notifySuccess(content: string) {
ElNotification.success(content)
},
// 警告通知
notifyWarning(content: string) {
ElNotification.warning(content)
},
// 确认窗体
confirm(content: string) {
return ElMessageBox.confirm(content, t('common.confirmTitle'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
type: 'warning'
})
},
// 提交内容
prompt(content: string) {
return ElMessageBox.prompt(content, t('common.confirmTitle'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
type: 'warning'
})
}
}
export default message

View File

@ -26,11 +26,10 @@ const router = createRouter({
history: createWebHashHistory(),
strict: true,
routes: remainingRouter as RouteRecordRaw[],
// routes: constantRoutes.concat(...remainingRouter),
scrollBehavior: () => ({ left: 0, top: 0 })
})
// 路由白名单
// 路由不重定向白名单
const whiteList = [
'/login',
'/social-login',
@ -97,7 +96,6 @@ export const resetRouter = (): void => {
router.hasRoute(name) && router.removeRoute(name)
}
})
routes: remainingRouter as RouteRecordRaw[]
}
export const setupRouter = (app: App<Element>) => {

View File

@ -1,9 +1,10 @@
import { store } from '../index'
import { defineStore } from 'pinia'
import { getInfoApi } from '@/api/login'
import { getAccessToken } from '@/utils/auth'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
interface UserInfoVO {
permissions: []
roles: []
@ -13,7 +14,6 @@ interface UserInfoVO {
nickname: string
}
}
const { wsCache } = useCache()
export const useUserStore = defineStore({
id: 'admin-user',
@ -27,17 +27,15 @@ export const useUserStore = defineStore({
}
}),
actions: {
// TODO 设置store刷新页面就消失
async getUserInfoAction() {
async getUserInfoAction(userInfo: UserInfoVO) {
if (!getAccessToken()) {
this.resetState()
return null
}
const res = await getInfoApi()
this.permissions = res.permissions
this.roles = res.roles
this.user = res.user
wsCache.set('user', res)
this.permissions = userInfo.permissions
this.roles = userInfo.roles
this.user = userInfo.user
wsCache.set('user', userInfo)
},
resetState() {
this.permissions = []

View File

@ -1,2 +1,2 @@
@import './var.css';
@import 'element-plus/theme-chalk/dark/css-vars.css';
@import 'element-plus/theme-chalk/dark/css-vars.css';

View File

@ -1,29 +1,101 @@
import { useCache } from '@/hooks/web/useCache'
import { TokenType } from '@/api/login/types'
import { decrypt, encrypt } from '@/utils/jsencrypt'
const { wsCache } = useCache()
const AccessTokenKey = 'ACCESS_TOKEN'
const RefreshTokenKey = 'REFRESH_TOKEN'
// 获取token
export function getAccessToken() {
export const getAccessToken = () => {
// 此处与TokenKey相同此写法解决初始化时Cookies中不存在TokenKey报错
return wsCache.get('ACCESS_TOKEN')
}
// 刷新token
export function getRefreshToken() {
export const getRefreshToken = () => {
return wsCache.get(RefreshTokenKey)
}
// 设置token
export function setToken(token: TokenType) {
export const setToken = (token: TokenType) => {
wsCache.set(RefreshTokenKey, token.refreshToken, { exp: token.expiresTime })
wsCache.set(AccessTokenKey, token.accessToken)
}
// 删除token
export function removeToken() {
export const removeToken = () => {
wsCache.delete(AccessTokenKey)
wsCache.delete(RefreshTokenKey)
}
// ========== 账号相关 ==========
const UsernameKey = 'USERNAME'
const PasswordKey = 'PASSWORD'
const RememberMeKey = 'REMEMBER_ME'
export const getUsername = () => {
return wsCache.get(UsernameKey)
}
export const setUsername = (username: string) => {
wsCache.set(UsernameKey, username)
}
export const removeUsername = () => {
wsCache.delete(UsernameKey)
}
export const getPassword = () => {
const password = wsCache.get(PasswordKey)
return password ? decrypt(password) : undefined
}
export const setPassword = (password: string) => {
wsCache.set(PasswordKey, encrypt(password))
}
export const removePassword = () => {
wsCache.delete(PasswordKey)
}
export const getRememberMe = () => {
return wsCache.get(RememberMeKey) === 'true'
}
export const setRememberMe = (rememberMe: string) => {
wsCache.set(RememberMeKey, rememberMe)
}
export const removeRememberMe = () => {
wsCache.delete(RememberMeKey)
}
// ========== 租户相关 ==========
const TenantIdKey = 'TENANT_ID'
const TenantNameKey = 'TENANT_NAME'
export const getTenantName = () => {
return wsCache.get(TenantNameKey)
}
export const setTenantName = (username: string) => {
wsCache.set(TenantNameKey, username)
}
export const removeTenantName = () => {
wsCache.delete(TenantNameKey)
}
export const getTenantId = () => {
return wsCache.get(TenantIdKey)
}
export const setTenantId = (username: string) => {
wsCache.set(TenantIdKey, username)
}
export const removeTenantId = () => {
wsCache.delete(TenantIdKey)
}

View File

@ -1,130 +0,0 @@
import { required as requiredRule } from '@/utils/formRules'
import dayjs from 'dayjs'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n() // 国际化
export class FormSchemaBuilder {
static input(label: string, field: string, required: Boolean = false): FormSchema {
return {
label,
field,
component: 'Input',
formItemProps: {
rules: required ? [requiredRule] : []
}
}
}
static inputNumber(
label: string,
field: string,
value: number,
required: Boolean = false
): FormSchema {
return {
label,
field,
value,
component: 'InputNumber',
formItemProps: {
rules: required ? [requiredRule] : []
}
}
}
static radioButton(
label: string,
field: string,
value: number,
options: ComponentOptions[],
required: Boolean = false
): FormSchema {
return {
label,
field,
component: 'RadioButton',
value,
formItemProps: {
rules: required ? [requiredRule] : []
},
componentProps: {
options
}
}
}
static select(
label: string,
field: string,
value: number | null,
options: ComponentOptions[],
required: Boolean = false
): FormSchema {
return {
label,
field,
component: 'Select',
value,
formItemProps: {
rules: required ? [requiredRule] : []
},
componentProps: {
options
}
}
}
static textarea(
label: string,
field: string,
rows: number,
span: number,
required: Boolean = false
): FormSchema {
return {
label,
field,
component: 'Input',
componentProps: {
type: 'textarea',
rows: rows
},
formItemProps: {
rules: required ? [requiredRule] : []
},
colProps: {
span: span
}
}
}
}
export class TableColumnBuilder {
static column(label: string, field: string): TableColumn {
return {
label,
field
}
}
static date(label: string, field: string, template?: string): TableColumn {
return {
label,
field,
formatter: (_: Recordable, __: TableColumn, cellValue: string) => {
return dayjs(cellValue).format(template || 'YYYY-MM-DD HH:mm:ss')
}
}
}
static action(width: number): TableColumn {
return {
label: t('table.action'),
field: 'action',
width: width + 'px'
}
}
}
export class ComponentOptionsBuilder {
static option(label: string, value: number): ComponentOptions {
return {
label,
value
}
}
}

View File

@ -0,0 +1,31 @@
import { JSEncrypt } from 'jsencrypt/bin/jsencrypt.min'
// 密钥对生成 http://web.chacuo.net/netrsakeypair
const publicKey =
'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
const privateKey =
'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
'UP8iWi1Qw0Y='
// 加密
export const encrypt = (txt: string) => {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对数据进行加密
}
// 解密
export const decrypt = (txt: string) => {
const encryptor = new JSEncrypt()
encryptor.setPrivateKey(privateKey) // 设置私钥
return encryptor.decrypt(txt) // 对数据进行解密
}

View File

@ -94,13 +94,13 @@ export const generateRoutes = (routes: AppCustomRouteRecordRaw[]): AppRouteRecor
}
return res
}
export const getRedirect = (parentPath: string, children: Array<Object>) => {
export const getRedirect = (parentPath: string, children: AppCustomRouteRecordRaw[]) => {
if (!children || children.length == 0) {
return parentPath
}
const path = generateRoutePath(parentPath, children[0]?.path)
const path = generateRoutePath(parentPath, children[0].path)
// 递归子节点
return getRedirect(path, children[0]?.children)
if (children[0].children) return getRedirect(path, children[0].children)
}
const generateRoutePath = (parentPath: string, path: string) => {
if (parentPath.endsWith('/')) {

View File

@ -12,8 +12,8 @@ import {
ElDivider
} from 'element-plus'
import { reactive, ref, unref, onMounted, computed, watch } from 'vue'
import { getCodeImgApi, getTenantIdByNameApi, loginApi, getAsyncRoutesApi } from '@/api/login'
import { setToken } from '@/utils/auth'
import * as LoginApi from '@/api/login'
import { setToken, setTenantId } from '@/utils/auth'
import { useUserStoreWithOut } from '@/store/modules/user'
import { useCache } from '@/hooks/web/useCache'
import { usePermissionStore } from '@/store/modules/permission'
@ -68,14 +68,14 @@ const loginData = reactive({
//
const getCode = async () => {
const res = await getCodeImgApi()
const res = await LoginApi.getCodeImgApi()
loginData.codeImg = 'data:image/gif;base64,' + res.img
loginData.loginForm.uuid = res.uuid
}
//ID
const getTenantId = async () => {
const res = await getTenantIdByNameApi(loginData.loginForm.tenantName)
wsCache.set('tenantId', res)
const res = await LoginApi.getTenantIdByNameApi(loginData.loginForm.tenantName)
setTenantId(res)
}
//
const handleLogin = async () => {
@ -83,10 +83,11 @@ const handleLogin = async () => {
const data = await validForm()
if (!data) return
loginLoading.value = true
await loginApi(loginData.loginForm)
await LoginApi.loginApi(loginData.loginForm)
.then(async (res) => {
setToken(res)
await userStore.getUserInfoAction()
const userInfo = await LoginApi.getInfoApi()
await userStore.getUserInfoAction(userInfo)
await getRoutes()
})
.catch(() => {
@ -100,9 +101,9 @@ const handleLogin = async () => {
//
const getRoutes = async () => {
//
const routers = await getAsyncRoutesApi()
wsCache.set('roleRouters', routers)
await permissionStore.generateRoutes(routers).catch(() => {})
const res = await LoginApi.getAsyncRoutesApi()
wsCache.set('roleRouters', res)
await permissionStore.generateRoutes(res).catch(() => {})
permissionStore.getAddRouters.forEach((route) => {
addRoute(route as RouteRecordRaw) // 访
})

View File

@ -1,279 +0,0 @@
<script setup lang="ts">
import { reactive, ref, unref, watch, onMounted } from 'vue'
import { Form } from '@/components/Form'
import { useI18n } from '@/hooks/web/useI18n'
import { ElCheckbox, ElLink } from 'element-plus'
import { required } from '@/utils/formRules'
import { useForm } from '@/hooks/web/useForm'
import { getTenantIdByNameApi, getCodeImgApi, loginApi, getAsyncRoutesApi } from '@/api/login'
import { useCache } from '@/hooks/web/useCache'
import { usePermissionStore } from '@/store/modules/permission'
import { useRouter } from 'vue-router'
import { setToken } from '@/utils/auth'
import { useUserStoreWithOut } from '@/store/modules/user'
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
import { UserLoginVO } from '@/api/login/types'
const { wsCache } = useCache()
const userStore = useUserStoreWithOut()
const permissionStore = usePermissionStore()
const { currentRoute, addRoute, push } = useRouter()
const { t } = useI18n()
const rules = {
tenantName: [required],
username: [required],
password: [required],
code: [required]
}
const loginData = reactive({
codeImg: '',
isShowPassword: false,
captchaEnable: true,
tenantEnable: true,
token: '',
loading: {
signIn: false
},
loginForm: {
tenantName: '芋道源码',
username: 'admin',
password: 'admin123',
code: '',
uuid: ''
}
})
const schema = reactive<FormSchema[]>([
{
field: 'title',
colProps: {
span: 24
}
},
{
field: 'tenantName',
label: t('login.tenantname'),
value: loginData.loginForm.tenantName,
component: 'Input',
colProps: {
span: 24
},
componentProps: {
placeholder: t('login.tenantNamePlaceholder')
}
},
{
field: 'username',
label: t('login.username'),
value: loginData.loginForm.username,
component: 'Input',
colProps: {
span: 24
},
componentProps: {
placeholder: t('login.usernamePlaceholder')
}
},
{
field: 'password',
label: t('login.password'),
value: loginData.loginForm.password,
component: 'InputPassword',
colProps: {
span: 24
},
componentProps: {
style: {
width: '100%'
},
placeholder: t('login.passwordPlaceholder')
}
},
{
field: 'code',
label: t('login.code'),
value: loginData.loginForm.code,
component: 'Input',
colProps: {
span: 12
},
componentProps: {
style: {
width: '100%'
},
placeholder: t('login.codePlaceholder')
}
},
{
field: 'codeImg',
colProps: {
span: 12
}
},
{
field: 'tool',
colProps: {
span: 24
}
},
{
field: 'login',
colProps: {
span: 24
}
},
{
field: 'other',
component: 'Divider',
label: t('login.otherLogin'),
componentProps: {
contentPosition: 'center'
}
},
{
field: 'otherIcon',
colProps: {
span: 24
}
}
])
const iconSize = 30
const remember = ref(false)
const { register, elFormRef, methods } = useForm()
const loading = ref(false)
const iconColor = '#999'
const redirect = ref<string>('')
watch(
() => currentRoute.value,
(route: RouteLocationNormalizedLoaded) => {
redirect.value = route?.query?.redirect as string
},
{
immediate: true
}
)
//
const getCode = async () => {
const res = await getCodeImgApi()
loginData.codeImg = 'data:image/gif;base64,' + res.img
loginData.loginForm.uuid = res.uuid
}
//ID
const getTenantId = async () => {
const res = await getTenantIdByNameApi(loginData.loginForm.tenantName)
wsCache.set('tenantId', res)
}
//
const signIn = async () => {
await getTenantId()
const formRef = unref(elFormRef)
await formRef?.validate(async (isValid) => {
if (isValid) {
loading.value = true
const { getFormData } = methods
const formData = await getFormData<UserLoginVO>()
formData.uuid = loginData.loginForm.uuid
await loginApi(formData)
.then(async (res) => {
setToken(res)
getRoutes()
await userStore.getUserInfoAction()
})
.catch(() => {
getCode()
})
.finally(() => (loading.value = false))
}
})
}
//
const getRoutes = async () => {
//
const routers = await getAsyncRoutesApi()
wsCache.set('roleRouters', routers)
await permissionStore.generateRoutes(routers).catch(() => {})
permissionStore.getAddRouters.forEach((route) => {
addRoute(route as RouteRecordRaw) // 访
})
permissionStore.setIsAddRouters(true)
push({ path: redirect.value || permissionStore.addRouters[0].path })
}
onMounted(() => {
getCode()
})
</script>
<template>
<Form
:schema="schema"
:rules="rules"
label-position="top"
hide-required-asterisk
size="large"
@register="register"
v-show="false"
>
<template #header>
<h2 class="text-2xl font-bold text-center w-[100%]">{{ t('login.login') }}</h2>
</template>
<template #codeImg>
<img :src="loginData.codeImg" @click="getCode" alt="" />
</template>
<template #tool>
<div class="flex justify-between items-center w-[100%]">
<ElCheckbox v-model="remember" :label="t('login.remember')" size="small" />
<ElLink type="primary" :underline="false">{{ t('login.forgetPassword') }}</ElLink>
</div>
</template>
<template #login>
<ElButton :loading="loading" type="primary" class="w-[100%]" @click="signIn">
{{ t('login.login') }}
</ElButton>
</template>
<template #otherIcon>
<div class="flex justify-between w-[100%]">
<Icon
icon="ant-design:github-filled"
:size="iconSize"
class="cursor-pointer anticon"
:color="iconColor"
/>
<Icon
icon="ant-design:wechat-filled"
:size="iconSize"
class="cursor-pointer anticon"
:color="iconColor"
/>
<Icon
icon="ant-design:alipay-circle-filled"
:size="iconSize"
:color="iconColor"
class="cursor-pointer anticon"
/>
<Icon
icon="ant-design:weibo-circle-filled"
:size="iconSize"
:color="iconColor"
class="cursor-pointer anticon"
/>
</div>
</template>
</Form>
</template>
<style lang="less" scoped>
:deep(.anticon) {
&:hover {
color: var(--el-color-primary) !important;
}
}
</style>

View File

@ -1,16 +1,16 @@
<script setup lang="ts">
import { useIcon } from '@/hooks/web/useIcon'
import { reactive, ref, unref, watch, onMounted, computed } from 'vue'
import { reactive, ref, unref, watch, computed } from 'vue'
import LoginFormTitle from './LoginFormTitle.vue'
import { ElForm, ElFormItem, ElInput, ElRow, ElCol, ElMessage } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { required } from '@/utils/formRules'
import {
getTenantIdByNameApi,
getCodeImgApi,
getAsyncRoutesApi,
sendSmsCodeApi,
smsLoginApi
smsLoginApi,
getInfoApi
} from '@/api/login'
import { useCache } from '@/hooks/web/useCache'
import { usePermissionStore } from '@/store/modules/permission'
@ -40,9 +40,6 @@ const rules = {
}
const loginData = reactive({
codeImg: '',
// TODO @jinz isShowPasswordcaptchaEnable
isShowPassword: false,
captchaEnable: true,
tenantEnable: true,
token: '',
loading: {
@ -55,8 +52,7 @@ const loginData = reactive({
code: ''
}
})
// TODO @jinzsmsVO
const SmsVO = reactive({
const smsVO = reactive({
smsCode: {
mobile: '',
scene: 21
@ -70,9 +66,9 @@ const mobileCodeTimer = ref(0)
const redirect = ref<string>('')
const getSmsCode = async () => {
await getTenantId()
SmsVO.smsCode.mobile = loginData.loginForm.mobileNumber
console.log('getSmsCode begin:', SmsVO.smsCode)
await sendSmsCodeApi(SmsVO.smsCode)
smsVO.smsCode.mobile = loginData.loginForm.mobileNumber
console.log('getSmsCode begin:', smsVO.smsCode)
await sendSmsCodeApi(smsVO.smsCode)
.then(async (res) => {
//
ElMessage({
@ -102,12 +98,6 @@ watch(
immediate: true
}
)
// TODO @jinz
const getCode = async () => {
const res = await getCodeImgApi()
loginData.codeImg = 'data:image/gif;base64,' + res.img
loginData.loginForm.uuid = res.uuid
}
// ID
const getTenantId = async () => {
const res = await getTenantIdByNameApi(loginData.loginForm.tenantName)
@ -119,12 +109,13 @@ const signIn = async () => {
const data = await validForm()
if (!data) return
loginLoading.value = true
SmsVO.loginSms.mobile = loginData.loginForm.mobileNumber
SmsVO.loginSms.code = loginData.loginForm.code
await smsLoginApi(SmsVO.loginSms)
smsVO.loginSms.mobile = loginData.loginForm.mobileNumber
smsVO.loginSms.code = loginData.loginForm.code
await smsLoginApi(smsVO.loginSms)
.then(async (res) => {
setToken(res?.token)
await userStore.getUserInfoAction()
const userInfo = await getInfoApi()
await userStore.getUserInfoAction(userInfo)
getRoutes()
})
.catch(() => {})
@ -145,9 +136,6 @@ const getRoutes = async () => {
permissionStore.setIsAddRouters(true)
push({ path: redirect.value || permissionStore.addRouters[0].path })
}
onMounted(() => {
getCode()
})
</script>
<template>
<el-form

View File

@ -1,4 +1,5 @@
export { default as LoginForm } from './LoginForm.vue'
export { default as MobileForm } from './MobileForm.vue'
export { default as LoginFormOld } from './LoginFormOld.vue' // TODO jinzold 是不是可以删除哈git 可以管理的
export { default as LoginFormTitle } from './LoginFormTitle.vue'
import LoginForm from './LoginForm.vue'
import MobileForm from './MobileForm.vue'
import LoginFormTitle from './LoginFormTitle.vue'
export { LoginForm, MobileForm, LoginFormTitle }

View File

@ -1,5 +1,4 @@
import { ref, computed, unref, Ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
export enum LoginStateEnum {
LOGIN,
@ -40,97 +39,3 @@ export function useFormValid<T extends Object = any>(formRef: Ref<any>) {
validForm
}
}
// TODO @jinz多余的是不是可以删除哈
export function useFormRules(formData?: Recordable) {
const { t } = useI18n()
const getAccountFormRule = computed(() => createRule(t('sys.login.accountPlaceholder')))
const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder')))
const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder')))
const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder')))
const validatePolicy = async (_: RuleObject, value: boolean) => {
return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve()
}
const validateConfirmPassword = (password: string) => {
return async (_: RuleObject, value: string) => {
if (!value) {
return Promise.reject(t('sys.login.passwordPlaceholder'))
}
if (value !== password) {
return Promise.reject(t('sys.login.diffPwd'))
}
return Promise.resolve()
}
}
const getFormRules = computed(
(): {
[k: string]: ValidationRule | ValidationRule[]
} => {
const accountFormRule = unref(getAccountFormRule)
const passwordFormRule = unref(getPasswordFormRule)
const smsFormRule = unref(getSmsFormRule)
const mobileFormRule = unref(getMobileFormRule)
const mobileRule = {
sms: smsFormRule,
mobile: mobileFormRule
}
switch (unref(currentState)) {
// register form rules
case LoginStateEnum.REGISTER:
return {
account: accountFormRule,
password: passwordFormRule,
confirmPassword: [
{
validator: validateConfirmPassword(formData?.password),
trigger: 'change'
}
],
policy: [
{
validator: validatePolicy,
trigger: 'change'
}
],
...mobileRule
}
// reset password form rules
case LoginStateEnum.RESET_PASSWORD:
return {
account: accountFormRule,
...mobileRule
}
// mobile form rules
case LoginStateEnum.MOBILE:
return mobileRule
// login form rules
default:
return {
account: accountFormRule,
password: passwordFormRule
}
}
}
)
return {
getFormRules
}
}
function createRule(message: string) {
return [
{
required: true,
message,
trigger: 'change'
}
]
}

View File

@ -53,7 +53,9 @@ const beforeUpload = (file: Blob) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
state.options.img = reader.result
if (reader.result) {
state.options.img = reader.result as string
}
}
}
}

View File

@ -10,7 +10,7 @@ import * as ApiAccessLogApi from '@/api/infra/apiAccessLog'
const { t } = useI18n() //
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<ApiAccessLogVO>, ApiAccessLogVO>({
const { register, tableObject, methods } = useTable<ApiAccessLogVO>({
getListApi: ApiAccessLogApi.getApiAccessLogPageApi
})
const { getList, setSearchParams } = methods

View File

@ -12,7 +12,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
const { t } = useI18n() //
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<ApiErrorLogVO>, ApiErrorLogVO>({
const { register, tableObject, methods } = useTable<ApiErrorLogVO>({
getListApi: ApiErrorLogApi.getApiErrorLogPageApi,
exportListApi: ApiErrorLogApi.exportApiErrorLogApi
})

View File

@ -27,7 +27,6 @@ const loading = ref(false)
const activeName = ref('cloum')
const basicInfoRef = ref<ComponentRef<typeof BasicInfoForm>>()
const genInfoRef = ref<ComponentRef<typeof GenInfoFormVue>>()
// TODO:
const submitForm = async () => {
const basicInfo = unref(basicInfoRef)
const genInfo = unref(genInfoRef)

View File

@ -14,7 +14,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
const { t } = useI18n() //
const { push } = useRouter()
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<CodegenTableVO>, CodegenTableVO>({
const { register, tableObject, methods } = useTable<CodegenTableVO>({
getListApi: CodegenApi.getCodegenTablePageApi,
delListApi: CodegenApi.deleteCodegenTableApi
})
@ -71,7 +71,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['infra:codegen:create']" @click="openImportTable">
<Icon icon="el:zoom-in" class="mr-5px" /> {{ t('action.import') }}
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.import') }}
</el-button>
</div>
<!-- 列表 -->

View File

@ -12,7 +12,7 @@ import * as ConfigApi from '@/api/infra/config'
const { t } = useI18n() //
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<ConfigVO>, ConfigVO>({
const { register, tableObject, methods } = useTable<ConfigVO>({
getListApi: ConfigApi.getConfigPageApi,
delListApi: ConfigApi.deleteConfigApi,
exportListApi: ConfigApi.exportConfigApi
@ -102,7 +102,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['infra:config:create']" @click="handleCreate">
<Icon icon="el:zoom-in" class="mr-5px" /> {{ t('action.add') }}
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
</el-button>
<el-button
type="warning"

View File

@ -92,7 +92,7 @@ onMounted(async () => {
type="primary"
@click="handleCreate"
>
<Icon icon="el:zoom-in" class="mr-5px" /> {{ t('action.add') }}
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</div>
<Table :columns="allSchemas.tableColumns" :data="tableData">

View File

@ -12,7 +12,7 @@ const { wsCache } = useCache()
const { t } = useI18n() //
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<FileVO>, FileVO>({
const { register, tableObject, methods } = useTable<FileVO>({
getListApi: FileApi.getFilePageApi,
delListApi: FileApi.deleteFileApi
})

View File

@ -12,7 +12,7 @@ import * as FileConfigApi from '@/api/infra/fileConfig'
const { t } = useI18n() //
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<FileConfigVO>, FileConfigVO>({
const { register, tableObject, methods } = useTable<FileConfigVO>({
getListApi: FileConfigApi.getFileConfigPageApi,
delListApi: FileConfigApi.deleteFileConfigApi
})
@ -110,7 +110,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['infra:file-config:create']" @click="handleCreate">
<Icon icon="el:zoom-in" class="mr-5px" /> {{ t('action.add') }}
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</div>
<!-- 列表 -->

View File

@ -13,14 +13,14 @@ import { allSchemas } from './jobLog.data'
const { t } = useI18n() //
const { query } = useRoute()
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<JobLogVO>, JobLogVO>({
const { register, tableObject, methods } = useTable<JobLogVO>({
getListApi: JobLogApi.getJobLogPageApi,
exportListApi: JobLogApi.exportJobLogApi
})
const { getList, setSearchParams, exportList } = methods
const getTableList = async () => {
const id = (query.id as unknown as number) && (query.jobId as unknown as number)
tableObject.paramsObj.params = {
tableObject.params = {
jobId: id
}
await getList()

View File

@ -14,7 +14,7 @@ import { useRouter } from 'vue-router'
const { t } = useI18n() //
const { push } = useRouter()
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<JobVO>, JobVO>({
const { register, tableObject, methods } = useTable<JobVO>({
getListApi: JobApi.getJobPageApi,
delListApi: JobApi.deleteJobApi,
exportListApi: JobApi.exportJobApi
@ -126,7 +126,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['infra:job:create']" @click="handleCreate">
<Icon icon="el:zoom-in" class="mr-5px" /> {{ t('action.add') }}
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
</el-button>
<el-button
type="warning"
@ -137,7 +137,7 @@ getList()
<Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
</el-button>
<el-button type="info" v-hasPermi="['infra:job:query']" @click="handleJobLog">
<Icon icon="el:zoom-in" class="mr-5px" /> 执行日志
<Icon icon="ep:zoom-in" class="mr-5px" /> 执行日志
</el-button>
</div>
<!-- 列表 -->

View File

@ -79,7 +79,7 @@ const crudSchemas = reactive<CrudSchema[]>([
},
{
field: 'action',
width: '400px',
width: '500px',
label: t('table.action'),
form: {
show: false

View File

@ -20,10 +20,10 @@ const keyListLoad = ref(true)
const keyList = ref<RedisKeyInfo[]>([])
//
const readRedisInfo = async () => {
const data = await RedisApi.redisMonitorInfo()
const data = await RedisApi.getCacheApi()
cache.value = data
loadEchartOptions(cache.value.commandStats)
const redisKeysInfo = await RedisApi.redisKeysInfo()
loadEchartOptions(data.commandStats)
const redisKeysInfo = await RedisApi.getKeyDefineListApi()
keyList.value = redisKeysInfo
keyListLoad.value = false //
}

View File

@ -12,7 +12,7 @@ import * as AppApi from '@/api/pay/app'
const { t } = useI18n() //
// ========== ==========
const { register, tableObject, methods } = useTable<PageResult<AppVO>, AppVO>({
const { register, tableObject, methods } = useTable<AppVO>({
getListApi: AppApi.getAppPageApi,
delListApi: AppApi.deleteAppApi,
exportListApi: AppApi.exportAppApi
@ -102,7 +102,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">
<Icon icon="el:zoom-in" class="mr-5px" /> {{ t('action.add') }}
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
</el-button>
<el-button
type="warning"

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