chore: vendor FBA UI 工程源码(fastapi-best-architecture-ui master,Epic #163 受控源码基础)
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { miniRequestClient, requestClient } from '#/api/request';
|
||||
|
||||
export interface CaptchaResult {
|
||||
is_enabled: boolean;
|
||||
expire_seconds: number;
|
||||
uuid: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
export interface LoginParams {
|
||||
username: string;
|
||||
password: string;
|
||||
uuid: string;
|
||||
captcha: string;
|
||||
}
|
||||
|
||||
export interface LoginResult {
|
||||
access_token: string;
|
||||
session_uuid: string;
|
||||
}
|
||||
|
||||
export type RefreshTokenResult = LoginResult;
|
||||
|
||||
/**
|
||||
* 登录验证码
|
||||
*/
|
||||
export async function getCaptchaApi() {
|
||||
return requestClient.get<CaptchaResult>('/api/v1/auth/captcha');
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
export async function loginApi(data: LoginParams) {
|
||||
return requestClient.post<LoginResult>('/api/v1/auth/login', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新accessToken
|
||||
*/
|
||||
export async function refreshTokenApi() {
|
||||
return miniRequestClient.post<RefreshTokenResult>(
|
||||
'/api/v1/auth/refresh',
|
||||
undefined,
|
||||
{
|
||||
withCredentials: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
export async function logoutApi() {
|
||||
return requestClient.post('/api/v1/auth/logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户权限码
|
||||
*/
|
||||
export async function getAccessCodesApi() {
|
||||
return requestClient.get<string[]>('/api/v1/auth/codes');
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './auth';
|
||||
export * from './menu';
|
||||
export * from './upload';
|
||||
export * from './user';
|
||||
@@ -0,0 +1,125 @@
|
||||
import type { RouteRecordStringComponent } from '@vben/types';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export interface SysMenuResult {
|
||||
id: number;
|
||||
title: string;
|
||||
name: string;
|
||||
path: string;
|
||||
sort: number;
|
||||
icon?: string;
|
||||
type: number;
|
||||
component?: string;
|
||||
perms?: string;
|
||||
status: number;
|
||||
display: number;
|
||||
cache: number;
|
||||
remark?: string;
|
||||
parent_id?: number;
|
||||
created_time: string;
|
||||
}
|
||||
|
||||
export interface SysMenuTreeResult extends SysMenuResult {
|
||||
children?: SysMenuTreeResult[];
|
||||
}
|
||||
|
||||
export interface SysMenuParams {
|
||||
title: string;
|
||||
name: string;
|
||||
path?: string;
|
||||
parent_id?: number;
|
||||
sort?: number;
|
||||
icon?: string;
|
||||
type?: number;
|
||||
component?: string;
|
||||
perms?: string;
|
||||
status?: number;
|
||||
display?: number;
|
||||
cache?: number;
|
||||
link?: string;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface SysMenuTreeParams {
|
||||
title?: string;
|
||||
status: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户所有菜单
|
||||
*/
|
||||
export async function getAllMenusApi() {
|
||||
return requestClient.get<RouteRecordStringComponent[]>(
|
||||
'/api/v1/sys/menus/sidebar',
|
||||
);
|
||||
}
|
||||
|
||||
export async function getSysMenuTreeApi(params: SysMenuTreeParams) {
|
||||
const transformMenuTitles = (menuData: SysMenuTreeResult[]) => {
|
||||
return menuData.map((item) => {
|
||||
const transformedItem = {
|
||||
...item,
|
||||
title: $t(item.title),
|
||||
};
|
||||
|
||||
if (item.children && item.children.length > 0) {
|
||||
transformedItem.children = transformMenuTitles(item.children);
|
||||
}
|
||||
|
||||
return transformedItem;
|
||||
});
|
||||
};
|
||||
|
||||
const filterMenuTree = (
|
||||
menuData: SysMenuTreeResult[],
|
||||
keyword: string,
|
||||
): SysMenuTreeResult[] => {
|
||||
const lowerKeyword = keyword.toLowerCase();
|
||||
const result: SysMenuTreeResult[] = [];
|
||||
for (const item of menuData) {
|
||||
const filteredChildren = item.children?.length
|
||||
? filterMenuTree(item.children, keyword)
|
||||
: [];
|
||||
const isMatch = item.title.toLowerCase().includes(lowerKeyword);
|
||||
if (isMatch || filteredChildren.length > 0) {
|
||||
result.push({
|
||||
...item,
|
||||
children: isMatch ? item.children : filteredChildren,
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const { title, ...restParams } = params;
|
||||
|
||||
const data = await requestClient.get<SysMenuTreeResult[]>(
|
||||
'/api/v1/sys/menus',
|
||||
{
|
||||
params: restParams,
|
||||
},
|
||||
);
|
||||
|
||||
const translatedData = transformMenuTitles(data);
|
||||
|
||||
if (title) {
|
||||
return filterMenuTree(translatedData, title);
|
||||
}
|
||||
|
||||
return translatedData;
|
||||
}
|
||||
|
||||
export async function createSysMenuApi(data: SysMenuParams) {
|
||||
return requestClient.post('/api/v1/sys/menus', data);
|
||||
}
|
||||
|
||||
export async function updateSysMenuApi(pk: number, data: SysMenuParams) {
|
||||
return requestClient.put(`/api/v1/sys/menus/${pk}`, data);
|
||||
}
|
||||
|
||||
export async function deleteSysMenuApi(pk: number) {
|
||||
return requestClient.delete(`/api/v1/sys/menus/${pk}`);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
interface UploadFileParams {
|
||||
file: File;
|
||||
onError?: (error: Error) => void;
|
||||
onProgress?: (progress: { percent: number }) => void;
|
||||
onSuccess?: (data: any, file: File) => void;
|
||||
}
|
||||
export async function upload_file({
|
||||
file,
|
||||
onError,
|
||||
onProgress,
|
||||
onSuccess,
|
||||
}: UploadFileParams) {
|
||||
try {
|
||||
onProgress?.({ percent: 0 });
|
||||
|
||||
const data = await requestClient.upload('/api/v1/sys/files/upload', {
|
||||
file,
|
||||
});
|
||||
|
||||
onProgress?.({ percent: 100 });
|
||||
onSuccess?.(data, file);
|
||||
} catch (error) {
|
||||
onError?.(error instanceof Error ? error : new Error(String(error)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
import type { UserInfo } from '@vben/types';
|
||||
|
||||
import type { SysDeptResult, SysRoleResult } from '#/api';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export interface MyUserInfo extends UserInfo {
|
||||
id: number;
|
||||
nickname: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
dept?: string;
|
||||
last_login_time: string;
|
||||
}
|
||||
|
||||
export interface SysUserResult {
|
||||
id: number;
|
||||
uuid: string;
|
||||
dept_id?: number;
|
||||
username: string;
|
||||
nickname: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
avatar?: string;
|
||||
status: number;
|
||||
is_superuser: boolean;
|
||||
is_staff: boolean;
|
||||
is_multi_login: boolean;
|
||||
join_time: string;
|
||||
last_login_time: string;
|
||||
dept?: SysDeptResult;
|
||||
roles: SysRoleResult[];
|
||||
}
|
||||
|
||||
export interface SysUserParams {
|
||||
dept?: number;
|
||||
username?: string;
|
||||
phone?: string;
|
||||
status?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface SysUpdateUserParams {
|
||||
dept_id?: number;
|
||||
username: string;
|
||||
nickname: string;
|
||||
avatar?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
roles: number[];
|
||||
}
|
||||
|
||||
export interface SysAddUserParams extends SysUpdateUserParams {
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface SysUpdatePasswordParams {
|
||||
old_password: string;
|
||||
new_password: string;
|
||||
confirm_password: string;
|
||||
}
|
||||
|
||||
export interface SysUpdateUserPhoneParams {
|
||||
phone: string;
|
||||
captcha: string;
|
||||
}
|
||||
|
||||
export interface SysUpdateUserEmailParams {
|
||||
email: string;
|
||||
captcha: string;
|
||||
}
|
||||
|
||||
export interface SysUpdateUserNicknameParams {
|
||||
nickname: string;
|
||||
}
|
||||
|
||||
export interface SysUpdateUserAvatarParams {
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
export interface SysResetPasswordParams {
|
||||
password: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
export async function getUserInfoApi() {
|
||||
return requestClient.get<MyUserInfo>('/api/v1/sys/users/me');
|
||||
}
|
||||
|
||||
export async function getSysUserListApi(params: SysUserParams) {
|
||||
return requestClient.get<SysUserResult>('/api/v1/sys/users', { params });
|
||||
}
|
||||
|
||||
export async function createSysUserApi(data: SysAddUserParams) {
|
||||
return requestClient.post('/api/v1/sys/users', data);
|
||||
}
|
||||
|
||||
export async function updateSysUserApi(pk: number, data: SysUpdateUserParams) {
|
||||
return requestClient.put(`/api/v1/sys/users/${pk}`, data);
|
||||
}
|
||||
|
||||
export async function updateSysUserPermissionApi(pk: number, type: string) {
|
||||
return requestClient.put(`/api/v1/sys/users/${pk}/permissions`, undefined, {
|
||||
params: { type },
|
||||
paramsSerializer: 'repeat',
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateSysUserAvatarApi(data: SysUpdateUserAvatarParams) {
|
||||
return requestClient.put(`/api/v1/sys/users/me/avatar`, data);
|
||||
}
|
||||
|
||||
export async function updateSysUserNicknameApi(
|
||||
data: SysUpdateUserNicknameParams,
|
||||
) {
|
||||
return requestClient.put(`/api/v1/sys/users/me/nickname`, data);
|
||||
}
|
||||
export async function updateSysUserPhoneApi(data: SysUpdateUserPhoneParams) {
|
||||
return requestClient.put(`/api/v1/sys/users/me/phone`, data);
|
||||
}
|
||||
|
||||
export async function updateSysUserEmailApi(data: SysUpdateUserEmailParams) {
|
||||
return requestClient.put(`/api/v1/sys/users/me/email`, data);
|
||||
}
|
||||
|
||||
export async function updateSysUserPasswordApi(data: SysUpdatePasswordParams) {
|
||||
return requestClient.put(`/api/v1/sys/users/me/password`, data);
|
||||
}
|
||||
|
||||
export async function resetSysUserPasswordApi(
|
||||
pk: number,
|
||||
data: SysResetPasswordParams,
|
||||
) {
|
||||
return requestClient.put(`/api/v1/sys/users/${pk}/password`, data);
|
||||
}
|
||||
|
||||
export async function deleteSysUserApi(pk: number) {
|
||||
return requestClient.delete(`/api/v1/sys/users/${pk}`);
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export interface SysDataScopeResult {
|
||||
id: number;
|
||||
name: string;
|
||||
status: number;
|
||||
created_time: string;
|
||||
updated_time: string;
|
||||
}
|
||||
|
||||
export interface SysDataRuleResult {
|
||||
id: number;
|
||||
name: string;
|
||||
model: string;
|
||||
column: string;
|
||||
operator: string;
|
||||
expression: string;
|
||||
value: string;
|
||||
created_time: string;
|
||||
updated_time: string;
|
||||
}
|
||||
|
||||
export interface SysDataScopeParams {
|
||||
name?: string;
|
||||
status?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface CreateSysDataScopeParams {
|
||||
name: string;
|
||||
status: number;
|
||||
}
|
||||
|
||||
export interface SysDataScopeRulesResult extends SysDataScopeResult {
|
||||
rules: SysDataRuleResult[];
|
||||
}
|
||||
|
||||
export interface SysDataRuleParams {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface SysDataRuleModelColumnsResult {
|
||||
key: string;
|
||||
comment: string;
|
||||
}
|
||||
|
||||
export interface SysDataRuleTemplateVariableResult {
|
||||
key: string;
|
||||
comment: string;
|
||||
}
|
||||
|
||||
export interface CreateSysDataRuleParams {
|
||||
name: string;
|
||||
model: string;
|
||||
column: string;
|
||||
operator: string;
|
||||
expression: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export async function getSysDataScopeListApi(params: SysDataScopeParams) {
|
||||
return requestClient.get<SysDataScopeResult[]>('/api/v1/sys/data-scopes', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSysDataScopesApi() {
|
||||
return requestClient.get<SysDataScopeResult[]>('/api/v1/sys/data-scopes/all');
|
||||
}
|
||||
|
||||
export async function getSysDataScopeRulesApi(pk: number) {
|
||||
return requestClient.get<SysDataScopeRulesResult>(
|
||||
`/api/v1/sys/data-scopes/${pk}/rules`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function createSysDataScope(data: CreateSysDataScopeParams) {
|
||||
return requestClient.post('/api/v1/sys/data-scopes', data);
|
||||
}
|
||||
|
||||
export async function updateSysDataScope(
|
||||
pk: number,
|
||||
data: CreateSysDataScopeParams,
|
||||
) {
|
||||
return requestClient.put(`/api/v1/sys/data-scopes/${pk}`, data);
|
||||
}
|
||||
|
||||
export async function updateSysDataScopeRulesApi(pk: number, rules: number[]) {
|
||||
return requestClient.put(`/api/v1/sys/data-scopes/${pk}/rules`, { rules });
|
||||
}
|
||||
|
||||
export async function deleteSysDataScopeApi(pks: number[]) {
|
||||
return requestClient.delete(`/api/v1/sys/data-scopes`, { data: { pks } });
|
||||
}
|
||||
|
||||
export async function getSysDataRuleListApi(params: SysDataRuleParams) {
|
||||
return requestClient.get<SysDataRuleResult[]>('/api/v1/sys/data-rules', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSysDataRulesApi() {
|
||||
return requestClient.get<SysDataRuleResult[]>('/api/v1/sys/data-rules/all');
|
||||
}
|
||||
|
||||
export async function getSysDataRuleModelsApi() {
|
||||
return requestClient.get<string[]>('/api/v1/sys/data-rules/models');
|
||||
}
|
||||
|
||||
export async function getSysDataRuleModelColumnsApi(model: string) {
|
||||
return requestClient.get<SysDataRuleModelColumnsResult[]>(
|
||||
`/api/v1/sys/data-rules/models/${model}/columns`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getSysDataRuleTemplateVariablesApi() {
|
||||
return requestClient.get<SysDataRuleTemplateVariableResult[]>(
|
||||
'/api/v1/sys/data-rules/value-template-variables',
|
||||
);
|
||||
}
|
||||
|
||||
export async function createSysDataRuleApi(data: CreateSysDataRuleParams) {
|
||||
return requestClient.post('/api/v1/sys/data-rules', data);
|
||||
}
|
||||
|
||||
export async function updateSysDataRuleApi(
|
||||
pk: number,
|
||||
data: CreateSysDataRuleParams,
|
||||
) {
|
||||
return requestClient.put(`/api/v1/sys/data-rules/${pk}`, data);
|
||||
}
|
||||
|
||||
export async function deleteSysDataRuleApi(pks: number[]) {
|
||||
return requestClient.delete(`/api/v1/sys/data-rules`, { data: { pks } });
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import { requestClient } from './request';
|
||||
|
||||
export interface SysDeptResult {
|
||||
id: number;
|
||||
name: string;
|
||||
parent_id: number;
|
||||
sort: number;
|
||||
leader?: string;
|
||||
phone?: string;
|
||||
email?: string;
|
||||
status: number;
|
||||
created_time: string;
|
||||
}
|
||||
|
||||
export interface SysDeptTreeResult extends SysDeptResult {
|
||||
children?: SysDeptTreeResult[];
|
||||
}
|
||||
|
||||
export interface SysDeptParams {
|
||||
name: string;
|
||||
parent_id?: number;
|
||||
sort?: number;
|
||||
leader?: string;
|
||||
phone?: string;
|
||||
email?: string;
|
||||
status: number;
|
||||
}
|
||||
|
||||
export interface SysDeptTreeParams {
|
||||
name?: string;
|
||||
leader?: string;
|
||||
phone?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门树
|
||||
*/
|
||||
export async function getSysDeptTreeApi(params: SysDeptTreeParams) {
|
||||
return requestClient.get<SysDeptTreeResult[]>('/api/v1/sys/depts', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门详情
|
||||
*/
|
||||
export async function getSysDeptDetailApi(pk: number) {
|
||||
return requestClient.get<SysDeptTreeResult>(`/api/v1/sys/depts/${pk}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建部门
|
||||
*/
|
||||
export async function createSysDeptApi(data: SysDeptParams) {
|
||||
return requestClient.post('/api/v1/sys/depts', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新部门
|
||||
*/
|
||||
export async function updateSysDeptApi(pk: number, data: SysDeptParams) {
|
||||
return requestClient.put(`/api/v1/sys/depts/${pk}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除部门
|
||||
*/
|
||||
export async function deleteSysDeptApi(pk: number) {
|
||||
return requestClient.delete(`/api/v1/sys/depts/${pk}`);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export * from './core';
|
||||
export * from './data-permission';
|
||||
export * from './dept';
|
||||
export * from './log';
|
||||
export * from './monitor';
|
||||
export * from './plugin';
|
||||
export * from './role';
|
||||
export * from './scheduler';
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { PaginationResult } from '#/types';
|
||||
|
||||
import { requestClient } from './request';
|
||||
|
||||
export interface LoginLogParams {
|
||||
username?: string;
|
||||
status?: number;
|
||||
ip?: string;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface LoginLogResult {
|
||||
id: number;
|
||||
username: string;
|
||||
status: number;
|
||||
ip: string;
|
||||
country?: string;
|
||||
region?: string;
|
||||
os?: string;
|
||||
browser?: string;
|
||||
device?: string;
|
||||
msg: string;
|
||||
login_time: string;
|
||||
}
|
||||
|
||||
export type OperaLogParams = LoginLogParams;
|
||||
|
||||
export interface OperaLogResult {
|
||||
id: number;
|
||||
trace_id: string;
|
||||
username?: string;
|
||||
method: string;
|
||||
title: string;
|
||||
path: string;
|
||||
ip: string;
|
||||
country?: string;
|
||||
region?: string;
|
||||
city?: string;
|
||||
user_agent: string;
|
||||
os?: string;
|
||||
browser?: string;
|
||||
device?: string;
|
||||
args?: JSON;
|
||||
status: number;
|
||||
code: string;
|
||||
msg: string;
|
||||
cost_time: number;
|
||||
opera_time: string;
|
||||
}
|
||||
|
||||
export async function getLoginLogListApi(params: LoginLogParams) {
|
||||
return requestClient.get<PaginationResult<LoginLogResult>>(
|
||||
'/api/v1/logs/login',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteLoginLogApi(pks: number[]) {
|
||||
return requestClient.delete('/api/v1/logs/login', { data: { pks } });
|
||||
}
|
||||
|
||||
export async function getOperaLogListApi(params: OperaLogParams) {
|
||||
return requestClient.get<PaginationResult<OperaLogResult>>(
|
||||
'/api/v1/logs/opera',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteOperaLogApi(pks: number[]) {
|
||||
return requestClient.delete('/api/v1/logs/opera', { data: { pks } });
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { requestClient } from './request';
|
||||
|
||||
export interface ServerMonitorResult {
|
||||
cpu: Record<string, any>;
|
||||
mem: Record<string, any>;
|
||||
sys: Record<string, any>;
|
||||
disk: Record<string, any>[];
|
||||
service: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface RedisMonitorResult {
|
||||
info: Record<string, any>;
|
||||
stats: Record<string, any>[];
|
||||
}
|
||||
|
||||
export interface OnlineMonitorResult {
|
||||
id: number;
|
||||
session_uuid: string;
|
||||
username: string;
|
||||
nickname: string;
|
||||
ip: string;
|
||||
os: string;
|
||||
browser: string;
|
||||
device: string;
|
||||
status: number;
|
||||
last_login_time: string;
|
||||
expires_time: number;
|
||||
}
|
||||
|
||||
export interface MonitorOnlineParams {
|
||||
username: string;
|
||||
}
|
||||
|
||||
export interface KickOutOnlineParams {
|
||||
session_uuid: string;
|
||||
}
|
||||
|
||||
export async function getServerMonitorApi() {
|
||||
return requestClient.get<ServerMonitorResult>('/api/v1/monitors/server');
|
||||
}
|
||||
|
||||
export async function getRedisMonitorApi() {
|
||||
return requestClient.get<RedisMonitorResult>('/api/v1/monitors/redis');
|
||||
}
|
||||
|
||||
export async function getOnlineMonitorApi(params: MonitorOnlineParams) {
|
||||
return requestClient.get<OnlineMonitorResult[]>('/api/v1/monitors/sessions', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
export async function kickOutOnlineApi(
|
||||
pk: number,
|
||||
params: KickOutOnlineParams,
|
||||
) {
|
||||
return requestClient.delete(`/api/v1/monitors/sessions/${pk}`, { params });
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export interface PluginResult {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export async function getPluginListApi() {
|
||||
return requestClient.get<PluginResult[]>('/api/v1/sys/plugins');
|
||||
}
|
||||
|
||||
export async function getPluginChangedApi() {
|
||||
return requestClient.get<boolean>('/api/v1/sys/plugins/changed');
|
||||
}
|
||||
|
||||
export async function installZipPluginApi(file: File) {
|
||||
return await requestClient.upload(
|
||||
'/api/v1/sys/plugins',
|
||||
{ file },
|
||||
{ params: { type: 'zip' }, timeout: 60_000 },
|
||||
);
|
||||
}
|
||||
|
||||
export async function installGitPluginApi(repo_url: string) {
|
||||
return await requestClient.post('/api/v1/sys/plugins', undefined, {
|
||||
params: { type: 'git', repo_url },
|
||||
});
|
||||
}
|
||||
|
||||
export async function updatePluginStatus(plugin: string) {
|
||||
return await requestClient.put(`/api/v1/sys/plugins/${plugin}/status`);
|
||||
}
|
||||
|
||||
export async function downloadPluginApi(plugin: string) {
|
||||
return await requestClient.download<Blob>(`/api/v1/sys/plugins/${plugin}`);
|
||||
}
|
||||
|
||||
export async function uninstallPluginApi(plugin: string) {
|
||||
return await requestClient.delete(`/api/v1/sys/plugins/${plugin}`);
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* 该文件可自行根据业务逻辑进行调整
|
||||
*/
|
||||
import type { RequestClientOptions } from '@vben/request';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import {
|
||||
authenticateResponseInterceptor,
|
||||
defaultResponseInterceptor,
|
||||
errorMessageResponseInterceptor,
|
||||
RequestClient,
|
||||
} from '@vben/request';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { message } from 'antdv-next';
|
||||
|
||||
import { useAuthStore } from '#/store';
|
||||
|
||||
import { refreshTokenApi } from './core';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
|
||||
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
||||
const client = new RequestClient({
|
||||
...options,
|
||||
baseURL,
|
||||
});
|
||||
|
||||
/**
|
||||
* 重新认证逻辑
|
||||
*/
|
||||
async function doReAuthenticate() {
|
||||
console.warn('Access token or refresh token is invalid or expired. ');
|
||||
const accessStore = useAccessStore();
|
||||
const authStore = useAuthStore();
|
||||
accessStore.setAccessToken(null);
|
||||
accessStore.setAccessSessionUuid(null);
|
||||
if (
|
||||
preferences.app.loginExpiredMode === 'modal' &&
|
||||
accessStore.isAccessChecked
|
||||
) {
|
||||
accessStore.setLoginExpired(true);
|
||||
} else {
|
||||
await authStore.logout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token逻辑
|
||||
*/
|
||||
async function doRefreshToken() {
|
||||
const accessStore = useAccessStore();
|
||||
const resp = await refreshTokenApi();
|
||||
const newToken = resp.access_token;
|
||||
accessStore.setAccessToken(newToken);
|
||||
accessStore.setAccessSessionUuid(resp.session_uuid);
|
||||
return newToken;
|
||||
}
|
||||
|
||||
function formatToken(token: null | string) {
|
||||
return token ? `Bearer ${token}` : null;
|
||||
}
|
||||
|
||||
// 请求头处理
|
||||
client.addRequestInterceptor({
|
||||
fulfilled: async (config) => {
|
||||
const accessStore = useAccessStore();
|
||||
|
||||
config.headers.Authorization = formatToken(accessStore.accessToken);
|
||||
config.headers['Accept-Language'] = preferences.app.locale;
|
||||
return config;
|
||||
},
|
||||
});
|
||||
|
||||
// 处理返回的响应数据格式
|
||||
client.addResponseInterceptor(
|
||||
defaultResponseInterceptor({
|
||||
codeField: 'code',
|
||||
dataField: 'data',
|
||||
successCode: 200,
|
||||
}),
|
||||
);
|
||||
|
||||
// token过期的处理
|
||||
client.addResponseInterceptor(
|
||||
authenticateResponseInterceptor({
|
||||
client,
|
||||
doReAuthenticate,
|
||||
doRefreshToken,
|
||||
enableRefreshToken: preferences.app.enableRefreshToken,
|
||||
formatToken,
|
||||
}),
|
||||
);
|
||||
|
||||
// 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里
|
||||
client.addResponseInterceptor(
|
||||
errorMessageResponseInterceptor((msg: string, error) => {
|
||||
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
|
||||
// 当前mock接口返回的错误字段是 error 或者 message
|
||||
const responseData = error?.response?.data ?? {};
|
||||
const errorMessage =
|
||||
responseData?.error ?? responseData?.msg ?? error?.msg ?? '';
|
||||
// 如果没有错误信息,则会根据状态码进行提示
|
||||
message.error(errorMessage || msg);
|
||||
}),
|
||||
);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
function createMiniRequestClient(
|
||||
baseURL: string,
|
||||
options?: RequestClientOptions,
|
||||
) {
|
||||
const client = new RequestClient({
|
||||
...options,
|
||||
baseURL,
|
||||
});
|
||||
|
||||
// 处理返回的响应数据格式
|
||||
client.addResponseInterceptor(
|
||||
defaultResponseInterceptor({
|
||||
codeField: 'code',
|
||||
dataField: 'data',
|
||||
successCode: 200,
|
||||
}),
|
||||
);
|
||||
|
||||
// 通用的错误处理
|
||||
client.addResponseInterceptor(
|
||||
errorMessageResponseInterceptor((msg: string, error) => {
|
||||
const responseData = error?.response?.data ?? {};
|
||||
const errorMessage =
|
||||
responseData?.error ?? responseData?.msg ?? error?.msg ?? '';
|
||||
message.error(errorMessage || msg);
|
||||
}),
|
||||
);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
export const requestClient = createRequestClient(apiURL, {
|
||||
responseReturn: 'data',
|
||||
});
|
||||
|
||||
export const miniRequestClient = createMiniRequestClient(apiURL, {
|
||||
responseReturn: 'data',
|
||||
});
|
||||
|
||||
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { RouteRecordStringComponent } from '@vben/types';
|
||||
|
||||
import { requestClient } from './request';
|
||||
|
||||
export interface SysRoleParams {
|
||||
name?: string;
|
||||
status?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface SysRoleResult {
|
||||
id: number;
|
||||
name: string;
|
||||
status: number;
|
||||
is_filter_scopes: boolean;
|
||||
remark?: string;
|
||||
created_time: string;
|
||||
updated_time: string;
|
||||
}
|
||||
|
||||
export interface CreateSysRoleParams {
|
||||
name: string;
|
||||
status: number;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统角色列表
|
||||
*/
|
||||
export async function getSysRoleListApi(params: SysRoleParams) {
|
||||
return requestClient.get<SysRoleResult[]>('/api/v1/sys/roles', { params });
|
||||
}
|
||||
|
||||
export async function getAllSysRoleApi() {
|
||||
return requestClient.get<SysRoleResult[]>('/api/v1/sys/roles/all');
|
||||
}
|
||||
|
||||
export async function getSysRoleMenuApi(pk: number) {
|
||||
return requestClient.get<RouteRecordStringComponent[]>(
|
||||
`/api/v1/sys/roles/${pk}/menus`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getSysRoleDataScopesApi(pk: number) {
|
||||
return requestClient.get<number[]>(`/api/v1/sys/roles/${pk}/scopes`);
|
||||
}
|
||||
|
||||
export async function createSysRoleApi(data: CreateSysRoleParams) {
|
||||
return requestClient.post('/api/v1/sys/roles', data);
|
||||
}
|
||||
|
||||
export async function updateSysRoleApi(pk: number, data: CreateSysRoleParams) {
|
||||
return requestClient.put(`/api/v1/sys/roles/${pk}`, data);
|
||||
}
|
||||
|
||||
export async function updateSysRoleMenuApi(pk: number, menus: number[]) {
|
||||
return requestClient.put(`/api/v1/sys/roles/${pk}/menus`, { menus });
|
||||
}
|
||||
|
||||
export async function updateSysRoleDataScopesApi(pk: number, scopes: number[]) {
|
||||
return requestClient.put(`/api/v1/sys/roles/${pk}/scopes`, { scopes });
|
||||
}
|
||||
|
||||
export async function deleteSysRoleApi(pks: number[]) {
|
||||
return requestClient.delete(`/api/v1/sys/roles`, { data: { pks } });
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
import type { PaginationResult } from '#/types';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export interface TaskResultParams {
|
||||
name?: string;
|
||||
task_id?: string;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface TaskSchedulerParams {
|
||||
name?: string;
|
||||
type?: number;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface TaskResult {
|
||||
id: number;
|
||||
task_id: string;
|
||||
status: string;
|
||||
result?: string;
|
||||
date_done?: string;
|
||||
traceback?: string;
|
||||
name?: string;
|
||||
args?: string;
|
||||
kwargs?: string;
|
||||
worker?: string;
|
||||
retries?: number;
|
||||
queue?: string;
|
||||
}
|
||||
|
||||
export interface CreateTaskSchedulerParams {
|
||||
name: string;
|
||||
task: string;
|
||||
args?: string;
|
||||
kwargs?: string;
|
||||
queue?: string;
|
||||
exchange?: string;
|
||||
routing_key?: string;
|
||||
start_time?: Dayjs;
|
||||
expire_time?: Dayjs;
|
||||
expire_seconds?: number;
|
||||
type: number;
|
||||
interval_every?: number;
|
||||
interval_period?: string;
|
||||
crontab: string;
|
||||
one_off: boolean;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface TaskSchedulerResult extends CreateTaskSchedulerParams {
|
||||
id: number;
|
||||
enabled: boolean;
|
||||
total_run_count: number;
|
||||
last_run_time: string;
|
||||
created_time: string;
|
||||
updated_time?: string;
|
||||
}
|
||||
|
||||
export async function getTaskResultApi(pk: number) {
|
||||
return requestClient.get<TaskResult>(`/api/v1/task-results/${pk}`);
|
||||
}
|
||||
|
||||
export async function getTaskResultListApi(params?: TaskResultParams) {
|
||||
return requestClient.get<PaginationResult<TaskSchedulerResult>>(
|
||||
'/api/v1/task-results',
|
||||
{
|
||||
params,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteTaskResultApi(pks: number[]) {
|
||||
return requestClient.delete('/api/v1/task-results', { data: { pks } });
|
||||
}
|
||||
|
||||
export async function getAllTaskSchedulerApi() {
|
||||
return requestClient.get<TaskSchedulerResult[]>('/api/v1/schedulers/all');
|
||||
}
|
||||
|
||||
export async function getTaskSchedulerListApi(params?: TaskSchedulerParams) {
|
||||
return requestClient.get<PaginationResult<TaskSchedulerResult>>(
|
||||
'/api/v1/schedulers',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
export async function getTaskSchedulerApi(pk: number) {
|
||||
return requestClient.get<TaskSchedulerResult>(`/api/v1/schedulers/${pk}`);
|
||||
}
|
||||
|
||||
export async function createTaskSchedulerApi(data: CreateTaskSchedulerParams) {
|
||||
return requestClient.post('/api/v1/schedulers', data);
|
||||
}
|
||||
|
||||
export async function updateTaskSchedulerApi(
|
||||
pk: number,
|
||||
data: CreateTaskSchedulerParams,
|
||||
) {
|
||||
return requestClient.put(`/api/v1/schedulers/${pk}`, data);
|
||||
}
|
||||
|
||||
export async function updateTaskSchedulerStatusApi(pk: number) {
|
||||
return requestClient.put(`/api/v1/schedulers/${pk}/status`);
|
||||
}
|
||||
|
||||
export async function deleteTaskSchedulerApi(pk: number) {
|
||||
return requestClient.delete(`/api/v1/schedulers/${pk}`);
|
||||
}
|
||||
|
||||
export async function executeTaskSchedulerApi(pk: number) {
|
||||
return requestClient.post(`/api/v1/schedulers/${pk}/execute`);
|
||||
}
|
||||
|
||||
export async function getTaskRegisteredApi() {
|
||||
return requestClient.get<any[]>('/api/v1/tasks/registered');
|
||||
}
|
||||
|
||||
export async function revokeTaskSchedulerApi(task_id: string) {
|
||||
return requestClient.delete(`/api/v1/tasks/${task_id}/cancel`);
|
||||
}
|
||||
Reference in New Issue
Block a user