refactor: vue3 axios api ...

This commit is contained in:
xingyu
2022-07-19 22:33:54 +08:00
parent ba96eef51a
commit 9e2e220b69
121 changed files with 1022 additions and 9700 deletions

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),
// 是否所有的超出隐藏优先级低于schema中的showOverflowTooltip,
showOverflowTooltip: propTypes.bool.def(true),
// 表头
@ -294,9 +294,3 @@ export default defineComponent({
}
})
</script>
<style lang="less" scoped>
:deep(.el-button.is-text) {
margin-left: 0;
padding: 8px 10px;
}
</style>

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,280 +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 芋艿:文件下载,需要特殊处理
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,7 +26,6 @@ const router = createRouter({
history: createWebHashHistory(),
strict: true,
routes: remainingRouter as RouteRecordRaw[],
// routes: constantRoutes.concat(...remainingRouter),
scrollBehavior: () => ({ left: 0, top: 0 })
})

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,16 +27,15 @@ export const useUserStore = defineStore({
}
}),
actions: {
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,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'
@ -98,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)
@ -120,7 +114,8 @@ const signIn = async () => {
await smsLoginApi(smsVO.loginSms)
.then(async (res) => {
setToken(res?.token)
await userStore.getUserInfoAction()
const userInfo = await getInfoApi()
await userStore.getUserInfoAction(userInfo)
getRoutes()
})
.catch(() => {})
@ -141,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

@ -2,4 +2,4 @@ import LoginForm from './LoginForm.vue'
import MobileForm from './MobileForm.vue'
import LoginFormTitle from './LoginFormTitle.vue'
export {LoginForm, MobileForm, LoginFormTitle}
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,72 +39,3 @@ export function useFormValid<T extends Object = any>(formRef: Ref<any>) {
validForm
}
}
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

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

@ -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"

View File

@ -12,7 +12,7 @@ import * as MerchantApi from '@/api/pay/merchant'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<MerchantVO>, MerchantVO>({
const { register, tableObject, methods } = useTable<MerchantVO>({
getListApi: MerchantApi.getMerchantPageApi,
delListApi: MerchantApi.deleteMerchantApi,
exportListApi: MerchantApi.exportMerchantApi
@ -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"

View File

@ -11,7 +11,7 @@ import { rules, allSchemas } from './order.data'
import * as OrderApi from '@/api/pay/order'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<OrderVO>, OrderVO>({
const { register, tableObject, methods } = useTable<OrderVO>({
getListApi: OrderApi.getOrderPageApi,
delListApi: OrderApi.deleteOrderApi,
exportListApi: OrderApi.exportOrderApi
@ -99,7 +99,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['pay:order: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

@ -10,7 +10,7 @@ import * as RefundApi from '@/api/pay/refund'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<RefundVO>, RefundVO>({
const { register, tableObject, methods } = useTable<RefundVO>({
getListApi: RefundApi.getRefundPageApi,
delListApi: RefundApi.deleteRefundApi,
exportListApi: RefundApi.exportRefundApi

View File

@ -16,7 +16,7 @@ const {
register: typeRegister,
tableObject: typeTableObject,
methods: typeMethods
} = useTable<PageResult<DictTypeVO>, DictTypeVO>({
} = useTable<DictTypeVO>({
getListApi: DictTypeApi.getDictTypePageApi,
delListApi: DictTypeApi.deleteDictTypeApi
})
@ -49,7 +49,7 @@ const {
register: dataRegister,
tableObject: dataTableObject,
methods: dataMethods
} = useTable<PageResult<DictDataVO>, DictDataVO>({
} = useTable<DictDataVO>({
getListApi: DictDataApi.getDictDataPageApi,
delListApi: DictDataApi.deleteDictDataApi
})
@ -79,7 +79,7 @@ const handleDataDelete = async (row: DictTypeVO) => {
const parentType = ref('')
const onClickType = async (data: { [key: string]: any }) => {
tableTypeSelect.value = true
dataTableObject.paramsObj.params = {
dataTableObject.params = {
dictType: data.type
}
getDataList()
@ -161,7 +161,7 @@ onMounted(async () => {
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['system:dict:create']" @click="handleTypeCreate">
<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>
<!-- 列表 -->
@ -221,7 +221,7 @@ onMounted(async () => {
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['system:dict:create']" @click="handleDataCreate">
<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

View File

@ -12,7 +12,7 @@ import * as ErrorCodeApi from '@/api/system/errorCode'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<ErrorCodeVO>, ErrorCodeVO>({
const { register, tableObject, methods } = useTable<ErrorCodeVO>({
getListApi: ErrorCodeApi.getErrorCodePageApi,
delListApi: ErrorCodeApi.deleteErrorCodeApi
})
@ -96,7 +96,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button v-hasPermi="['system:error-code:create']" 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>
<!-- 列表 -->

View File

@ -10,7 +10,7 @@ import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<LoginLogVO>, LoginLogVO>({
const { register, tableObject, methods } = useTable<LoginLogVO>({
getListApi: getLoginLogPageApi,
exportListApi: exportLoginLogApi
})

View File

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

View File

@ -195,7 +195,7 @@ onMounted(async () => {
<ContentWrap>
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['system:notice: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>
<el-table

View File

@ -1,166 +0,0 @@
import { reactive } from 'vue'
import { required } from '@/utils/formRules'
import { useI18n } from '@/hooks/web/useI18n'
// 国际化
const { t } = useI18n()
// 修改
export const modelSchema = reactive<FormSchema[]>([
{
label: '上级菜单',
field: 'parentId',
component: 'Input',
formItemProps: {
rules: [required]
}
},
{
label: '菜单类型',
field: 'type',
component: 'RadioButton',
formItemProps: {
rules: [required]
},
componentProps: {
options: [
{
label: '目录',
value: 1
},
{
label: '菜单',
value: 2
},
{
label: '按钮',
value: 3
}
]
}
},
{
label: '菜单图标',
field: 'icon',
component: 'Input',
formItemProps: {
rules: [required]
}
},
{
label: '菜单名称',
field: 'name',
component: 'Input',
formItemProps: {
rules: [required]
}
},
{
label: '显示排序',
field: 'sort',
component: 'Input'
},
{
label: '路由地址',
field: 'path',
component: 'Input',
labelMessage: '访问的路由地址,如:`user`。如需外网地址时,则以 `http(s)://` 开头'
},
{
label: '组件路径',
field: 'component',
component: 'Input'
},
{
label: '权限标识',
field: 'permission',
component: 'Input',
labelMessage:
'Controller 方法上的权限字符,如:@PreAuthorize(`@ss.hasPermission(`system:user:list`)`)'
},
{
label: t('common.status'),
field: 'status',
component: 'RadioButton',
value: 0,
formItemProps: {
rules: [required]
},
componentProps: {
options: [
{
label: '开启',
value: 0
},
{
label: '关闭',
value: 1
}
]
},
labelMessage: '选择停用时,路由将不会出现在侧边栏,也不能被访问'
},
{
label: '是否显示',
field: 'visible',
component: 'RadioButton',
value: 0,
formItemProps: {
rules: [required]
},
componentProps: {
options: [
{
label: '显示',
value: 0
},
{
label: '隐藏',
value: 1
}
]
},
labelMessage: '选择隐藏时,路由将不会出现在侧边栏,但仍然可以访问'
},
{
label: '是否缓存',
field: 'keepAlive',
component: 'RadioButton',
value: 0,
componentProps: {
options: [
{
label: '缓存',
value: 0
},
{
label: '不缓存',
value: 1
}
]
},
labelMessage: '选择缓存时,则会被 `keep-alive` 缓存,需要匹配组件的 `name` 和路由地址保持一致'
}
])
// 列表
export const columns = reactive<TableColumn[]>([
{
label: '菜单名称',
field: 'name'
},
{
label: '权限标识',
field: 'permission',
component: 'Input',
formItemProps: {
rules: [required]
}
},
{
label: '排序',
field: 'sort'
},
{
label: t('table.action'),
field: 'action',
width: '180px'
}
])

View File

@ -1,226 +0,0 @@
<script setup lang="ts">
import { onMounted, ref, unref } from 'vue'
import { handleTree } from '@/utils/tree'
import { useI18n } from '@/hooks/web/useI18n'
import { IconSelect } from '@/components/Icon'
import { ElCard, ElMessage, ElMessageBox, ElTree, ElTreeSelect } from 'element-plus'
import { columns, modelSchema } from './menu.data'
import { Form, FormExpose } from '@/components/Form'
import * as MenuApi from '@/api/system/menu'
import { MenuVO } from '@/api/system/menu/types'
const { t } = useI18n() // 国际化
interface Tree {
id: number
name: string
children?: Tree[]
}
const defaultProps = {
children: 'children',
label: 'name',
value: 'id'
}
// ========== 创建菜单树结构 ==========
const menuOptions = ref([]) // 树形结构
const treeRef = ref<InstanceType<typeof ElTree>>()
const getTree = async () => {
const res = await MenuApi.listSimpleMenusApi()
menuOptions.value = handleTree(res)
}
const filterNode = (value: string, data: Tree) => {
if (!value) return true
return data.name.includes(value)
}
// ========== 菜单信息form表单 ==========
const loading = ref(false) // 遮罩层
const formRef = ref<FormExpose>()
const iconModel = ref('ep:user')
const menuParentId = ref()
const menuStatus = ref('add')
const menuTitle = ref('菜单信息')
const showEdit = ref(false)
// 提交按钮
const submitForm = async () => {
loading.value = true
// 提交请求
try {
const data = unref(formRef)?.formModel as MenuVO
data.parentId = menuParentId.value
// TODO: 表单提交待完善
if (menuStatus.value === 'add') {
await MenuApi.createMenuApi(data)
} else if (menuStatus.value === 'edit') {
await MenuApi.updateMenuApi(data)
}
} finally {
loading.value = false
}
}
// ========== 按钮列表相关 ==========
const tableData = ref([])
const tableLoading = ref(false)
const onDisabled = ref(true)
const tableTitle = ref('按钮信息')
// 树点击事件
const handleMenuNodeClick = async (data: { [key: string]: any }) => {
showEdit.value = true
const res = await MenuApi.getMenuApi(data.id)
menuTitle.value = res.name + '-菜单信息'
tableTitle.value = res.name + '-按钮列表'
menuParentId.value = data.id
tableData.value = await MenuApi.getMenuListApi({ name: res.name })
unref(formRef)?.setValues(res)
onDisabled.value = true
changeDisabled()
}
const handleCreate = () => {
// 重置表单
unref(formRef)?.getElFormRef()?.resetFields()
menuParentId.value = 0
onDisabled.value = false
changeDisabled()
}
const handleEdit = () => {
onDisabled.value = false
changeDisabled()
}
const changeDisabled = () => {
unref(formRef)?.setProps({
disabled: onDisabled
})
}
// 修改操作
const handleUpdate = async (row: MenuVO) => {
// 设置数据
const res = await MenuApi.getMenuApi(row.id)
unref(formRef)?.setValues(res)
}
// 删除操作
const handleDelete = (row: MenuVO) => {
ElMessageBox.confirm(t('common.delDataMessage'), t('common.confirmTitle'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
type: 'warning'
})
.then(async () => {
await MenuApi.deleteMenuApi(row.id)
ElMessage.success(t('common.delSuccess'))
})
.catch(() => {})
}
onMounted(async () => {
await getTree()
})
</script>
<template>
<div class="flex">
<el-card class="w-1/4 menu" :gutter="12" shadow="always">
<template #header>
<div class="card-header">
<span>菜单列表</span>
<el-button type="primary" v-hasPermi="['system:menu:create']" @click="handleCreate">
新增根节点
</el-button>
</div>
</template>
<!-- <p>菜单列表</p> -->
<el-tree
ref="treeRef"
node-key="id"
:accordion="true"
:data="menuOptions"
:props="defaultProps"
:highlight-current="true"
:filter-method="filterNode"
@node-click="handleMenuNodeClick"
/>
</el-card>
<el-card class="w-1/2 menu" style="margin-left: 10px" :gutter="12" shadow="hover">
<template #header>
<div class="card-header">
<span>{{ menuTitle }}</span>
</div>
</template>
<div v-if="!showEdit">
<span>请从左侧选择菜单</span>
</div>
<div v-if="showEdit">
<Form :loading="loading" :schema="modelSchema" ref="formRef">
<template #parentId>
<el-tree-select
node-key="id"
v-model="menuParentId"
:props="defaultProps"
:data="menuOptions"
check-strictly
/>
</template>
<template #icon>
<IconSelect v-model="iconModel" />
</template>
</Form>
<el-button
v-if="!onDisabled"
type="primary"
v-hasPermi="['system:menu:update']"
:loading="loading"
@click="submitForm"
>
{{ t('action.save') }}
</el-button>
<el-button v-if="!onDisabled" :loading="loading" @click="showEdit = false">
{{ t('common.cancel') }}
</el-button>
<el-button
v-if="onDisabled"
v-hasPermi="['system:menu:update']"
type="primary"
:loading="loading"
@click="handleEdit"
>
{{ t('action.edit') }}
</el-button>
</div>
</el-card>
<el-card class="w-1/2 menu" style="margin-left: 10px" :gutter="12" shadow="hover">
<template #header>
<div class="card-header">
<span>{{ tableTitle }}</span>
<!-- <el-button type="primary">新增根节点</el-button> -->
</div>
</template>
<!-- 列表 -->
<Table :loading="tableLoading" :columns="columns" :data="tableData">
<template #action="{ row }">
<el-button
link
type="primary"
v-hasPermi="['system:menu:update']"
@click="handleUpdate(row)"
>
<Icon icon="ep:edit" class="mr-5px" /> {{ t('action.edit') }}
</el-button>
<el-button
link
type="primary"
v-hasPermi="['system:menu:delete']"
@click="handleDelete(row)"
>
<Icon icon="ep:delete" class="mr-5px" /> {{ t('action.del') }}
</el-button>
</template>
</Table>
</el-card>
</div>
</template>
<style scoped>
.menu {
height: 1000px;
max-height: 1800px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View File

@ -11,7 +11,7 @@ import { rules, allSchemas } from './notice.data'
import * as NoticeApi from '@/api/system/notice'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<NoticeVO>, NoticeVO>({
const { register, tableObject, methods } = useTable<NoticeVO>({
getListApi: NoticeApi.getNoticePageApi,
delListApi: NoticeApi.deleteNoticeApi
})
@ -95,7 +95,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['system:notice: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

@ -12,7 +12,7 @@ import * as ClientApi from '@/api/system/oauth2/client'
const { t } = useI18n() // 国际化
// ========== 列表相关 ==========
const { register, tableObject, methods } = useTable<PageResult<OAuth2ClientVo>, OAuth2ClientVo>({
const { register, tableObject, methods } = useTable<OAuth2ClientVo>({
getListApi: ClientApi.getOAuth2ClientPageApi,
delListApi: ClientApi.deleteOAuth2ClientApi
})
@ -96,7 +96,7 @@ getList()
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['system:oauth2-client: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>
<!-- 列表 -->

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