初始化本地仓库
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<ElConfigProvider size="default" :locale="locales[language]" :z-index="3000">
|
||||
<RouterView></RouterView>
|
||||
</ElConfigProvider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUserStore } from "./store/modules/user";
|
||||
import zh from "element-plus/es/locale/lang/zh-cn";
|
||||
import en from "element-plus/es/locale/lang/en";
|
||||
import { systemUpgrade } from "./utils/sys";
|
||||
import { toggleTransition } from "./utils/ui/animation";
|
||||
import { checkStorageCompatibility } from "./utils/storage";
|
||||
import { initializeTheme } from "./hooks/core/useTheme";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { language } = storeToRefs(userStore);
|
||||
|
||||
const locales = {
|
||||
zh: zh,
|
||||
en: en,
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
toggleTransition(true);
|
||||
initializeTheme();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
checkStorageCompatibility();
|
||||
toggleTransition(false);
|
||||
systemUpgrade();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,136 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
type Method = 'list' | 'get' | 'create' | 'update' | 'patch' | 'remove' | 'delete' | 'export' | 'changStatus'
|
||||
|
||||
interface BaseApiOptions {
|
||||
baseUrl: string
|
||||
forbiddenMethods?: Method[]
|
||||
allowedMethods?: Method[]
|
||||
}
|
||||
|
||||
function BaseService<T = any>(options: BaseApiOptions) {
|
||||
const { baseUrl, forbiddenMethods = [], allowedMethods = [] } = options
|
||||
|
||||
function checkMethod(method: Method) {
|
||||
if (forbiddenMethods.includes(method)) {
|
||||
throw new Error(`${method} method is forbidden.`)
|
||||
}
|
||||
if (allowedMethods.length > 0 && !allowedMethods.includes(method)) {
|
||||
throw new Error(`${method} method is not allowed.`)
|
||||
}
|
||||
}
|
||||
|
||||
const list = async (params?: Record<string, any>): Promise<T[]> => {
|
||||
checkMethod('list')
|
||||
return request.get<T[]>({
|
||||
url: baseUrl,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
const get = (id: string | number): Promise<T> => {
|
||||
checkMethod('get')
|
||||
return request.get<T>({
|
||||
url: `${baseUrl}/${id}`,
|
||||
})
|
||||
}
|
||||
|
||||
const create = (params: Omit<T, 'id'>): Promise<T> => {
|
||||
checkMethod('create')
|
||||
return request.post<T>({
|
||||
url: baseUrl,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
// update(params: Partial<T>): Promise<T> {
|
||||
// checkMethod('update')
|
||||
// return request.put<T>({
|
||||
// url: baseUrl,
|
||||
// params,
|
||||
// })
|
||||
// },
|
||||
const update = (id: string | number | Partial<T>, params?: Partial<T>): Promise<T> => {
|
||||
checkMethod('update');
|
||||
if (typeof id === 'object' && id !== null) {
|
||||
//@ts-expect-error
|
||||
const { id: extractedId, ...extractedParams } = id;
|
||||
if (extractedId !== undefined) {
|
||||
return request.put<T>({
|
||||
url: `${baseUrl}/${extractedId}`,
|
||||
params: extractedParams,
|
||||
});
|
||||
} else {
|
||||
return request.put<T>({
|
||||
url: baseUrl,
|
||||
params: id,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return request.put<T>({
|
||||
url: `${baseUrl}/${id}`,
|
||||
params,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const patch = (id: string | number, params: Partial<T>): Promise<T> => {
|
||||
checkMethod('patch')
|
||||
return request.patch<T>({
|
||||
url: `${baseUrl}/${id}`,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
const remove = (params?: Record<string, any>): Promise<T> => {
|
||||
checkMethod('remove')
|
||||
return request.del({
|
||||
url: `${baseUrl}`,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
const del = (id: string | number, params?: Record<string, any>): Promise<T> => {
|
||||
checkMethod('delete')
|
||||
return request.del({
|
||||
url: `${baseUrl}/${id}`,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
const exportData = (params: any) => {
|
||||
checkMethod('export')
|
||||
return request.post({
|
||||
url: `${baseUrl}/export`,
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
const changStatus = (id: string | number, params: Partial<T>): Promise<T> => {
|
||||
checkMethod('changStatus')
|
||||
return request.put<T>({
|
||||
url: `${baseUrl}/${id}/change-status`,
|
||||
params,
|
||||
})
|
||||
}
|
||||
const detail = (params: any): Promise<T> => {
|
||||
checkMethod('get')
|
||||
const { id } = params;
|
||||
return request.get<T>({
|
||||
url: `${baseUrl}/${id}`,
|
||||
})
|
||||
}
|
||||
|
||||
const methods = { list, get, create, update, patch, remove, delete: del, export: exportData, changStatus, detail }
|
||||
Object.values(methods).forEach((method) => {
|
||||
Object.defineProperty(method, '__baseUrl', {
|
||||
value: baseUrl,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
})
|
||||
})
|
||||
|
||||
return methods
|
||||
}
|
||||
|
||||
export default BaseService
|
||||
@@ -0,0 +1,11 @@
|
||||
import request from "@/utils/http";
|
||||
|
||||
export class DictService {
|
||||
// 获取所有字典
|
||||
static getAllDict() {
|
||||
return request.get<any>({
|
||||
url: "/dict/dict/enum-dict-list",
|
||||
showErrorMessage: false, // 不显示错误消息
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import BaseService from "./base"; // 导入基础服务类
|
||||
import request from '@/utils/http'; // 导入HTTP请求工具
|
||||
|
||||
|
||||
const baseUrl = '/export';
|
||||
|
||||
const DownloadService = {
|
||||
...BaseService<any>({ baseUrl }),
|
||||
/**
|
||||
* 导出Excel文件
|
||||
* @param params 导出参数(需与后端约定,如`reportType`报表类型、`dateRange`日期范围)
|
||||
* @returns 返回包含文件URL的响应对象(前端可通过URL触发文件下载)
|
||||
* @example
|
||||
* // 调用示例:导出用户数据Excel
|
||||
* downloadApi.excelDownload({
|
||||
* reportType: 'user',
|
||||
* dateRange: ['2024-01-01', '2024-03-31']
|
||||
* })
|
||||
*/
|
||||
excelDownload(params: any) {
|
||||
return request.get({
|
||||
url: `${baseUrl}/download`, // 对接后端`/export/download`接口
|
||||
params // 传递导出参数
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default DownloadService
|
||||
@@ -0,0 +1,46 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/member/auth';
|
||||
|
||||
export const AuthService = {
|
||||
...BaseService<any>({ baseUrl }),
|
||||
tagMenuIds(params: any) {
|
||||
return request.get({ url: `${baseUrl}/tag-menu-ids`, params });
|
||||
},
|
||||
|
||||
tagScopeIds(params: any) {
|
||||
return request.get({ url: `${baseUrl}/tag-scope-ids`, params });
|
||||
},
|
||||
|
||||
userListByTagId(params: any) {
|
||||
return request.get({ url: `${baseUrl}/user-list-by-tag-id`, params });
|
||||
},
|
||||
|
||||
userListExcludeTagId(params: any) {
|
||||
return request.get({ url: `${baseUrl}/user-list-exclude-tag-id`, params });
|
||||
},
|
||||
|
||||
removeUserTag(data: any) {
|
||||
return request.post({ url: `${baseUrl}/remove-user-tag`, data });
|
||||
},
|
||||
|
||||
saveTagMenu(data: any) {
|
||||
return request.post({ url: `${baseUrl}/save-tag-menu`, data });
|
||||
},
|
||||
|
||||
saveUserTag(data: any) {
|
||||
return request.post({ url: `${baseUrl}/save-user-tag`, data });
|
||||
},
|
||||
|
||||
getMemberAllPermission() {
|
||||
return request.get({ url: `${baseUrl}/permissions`, params: {} });
|
||||
},
|
||||
|
||||
getMemberPermissionByTagId(id: number | string, params: any) {
|
||||
return request.get({ url: `${baseUrl}/${id}/tag-permissions`, params: { format: 'tree' } });
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default AuthService;
|
||||
@@ -0,0 +1 @@
|
||||
export * from './auth';
|
||||
@@ -0,0 +1,6 @@
|
||||
import { MemberService } from './user';
|
||||
import { MemberTagService } from './tag';
|
||||
import { MemberLevelService } from './level';
|
||||
import { MemberPointsService } from './points';
|
||||
|
||||
export { MemberService, MemberTagService, MemberLevelService, MemberPointsService };
|
||||
@@ -0,0 +1,29 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { MemberLevel } from './types'
|
||||
|
||||
const baseUrl = '/member/level'
|
||||
|
||||
export const MemberLevelService = {
|
||||
...BaseService<MemberLevel>({
|
||||
baseUrl,
|
||||
allowedMethods: [],
|
||||
forbiddenMethods: [],
|
||||
}),
|
||||
|
||||
getLevelMembers(levelId: number, params?: Record<string, any>): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/${levelId}/members`, params })
|
||||
},
|
||||
|
||||
getEnabledLevels(): Promise<MemberLevel[]> {
|
||||
return request.get({ url: `${baseUrl}/enabled` })
|
||||
},
|
||||
|
||||
updateSort(data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/update-sort`, data })
|
||||
},
|
||||
|
||||
checkDelete(levelId: number): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/check-delete/${levelId}` })
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 会员等级模型
|
||||
*/
|
||||
export interface MemberLevel {
|
||||
id?: number;
|
||||
name?: string;
|
||||
icon?: string;
|
||||
min_points?: number;
|
||||
discount?: number;
|
||||
description?: string;
|
||||
member_count?: number;
|
||||
sort?: number;
|
||||
status?: number;
|
||||
create_time?: string;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { MemberPointsLog } from './types'
|
||||
|
||||
const baseUrl = '/member/points'
|
||||
|
||||
export const MemberPointsService = {
|
||||
...BaseService<MemberPointsLog>({
|
||||
baseUrl,
|
||||
allowedMethods: [],
|
||||
forbiddenMethods: ['remove', 'update'],
|
||||
}),
|
||||
|
||||
operate(data: Record<string, any>): Promise<any> {
|
||||
return request.post({ url: `${baseUrl}/operate`, data });
|
||||
},
|
||||
|
||||
batchOperate(data: Record<string, any>): Promise<any> {
|
||||
return request.post({ url: `${baseUrl}/batch-operate`, data })
|
||||
},
|
||||
|
||||
getStatistics(params?: Record<string, any>): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/statistics`, params })
|
||||
},
|
||||
|
||||
exportLogs(params?: Record<string, any>): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/export`, params, responseType: 'blob' })
|
||||
},
|
||||
|
||||
setRules(data: Record<string, any>): Promise<any> {
|
||||
return request.post({ url: `${baseUrl}/rules`, data })
|
||||
},
|
||||
|
||||
getRules(): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/rules` })
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 会员积分记录模型
|
||||
*/
|
||||
export interface MemberPointsLog {
|
||||
id?: number;
|
||||
member_id?: number;
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
type?: number;
|
||||
points?: number;
|
||||
points_before?: number;
|
||||
points_after?: number;
|
||||
source?: string;
|
||||
remark?: string;
|
||||
operator?: string;
|
||||
create_time?: string;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { MemberTag } from './types'
|
||||
|
||||
const baseUrl = '/member/tag'
|
||||
|
||||
export const MemberTagService = {
|
||||
...BaseService<MemberTag>({
|
||||
baseUrl,
|
||||
allowedMethods: [],
|
||||
forbiddenMethods: [],
|
||||
}),
|
||||
|
||||
getTagMembers(tagId: number, params?: Record<string, any>): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/${tagId}/members`, params })
|
||||
},
|
||||
|
||||
batchAssignTags(data: Record<string, any>): Promise<any> {
|
||||
return request.post({ url: `${baseUrl}/batch-assign`, data })
|
||||
},
|
||||
|
||||
getEnabledTags(): Promise<MemberTag[]> {
|
||||
return request.get({ url: `${baseUrl}/enabled` })
|
||||
},
|
||||
|
||||
updateSort(data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/update-sort`, data })
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 会员标签模型
|
||||
*/
|
||||
export interface MemberTag {
|
||||
id?: number;
|
||||
name?: string;
|
||||
color?: string;
|
||||
description?: string;
|
||||
member_count?: number;
|
||||
sort?: number;
|
||||
status?: number;
|
||||
create_time?: string;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { Member } from './types'
|
||||
|
||||
const baseUrl = '/member/user'
|
||||
|
||||
export const MemberService = {
|
||||
...BaseService<Member>({
|
||||
baseUrl,
|
||||
allowedMethods: [],
|
||||
forbiddenMethods: [],
|
||||
}),
|
||||
|
||||
resetPassword(id: number, data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/${id}/reset-password`, data })
|
||||
},
|
||||
|
||||
enable(data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/enable`, data })
|
||||
},
|
||||
|
||||
disable(data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/disable`, data })
|
||||
},
|
||||
|
||||
assignTags(id: number | string, data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/${id}/assign-tags`, data })
|
||||
},
|
||||
|
||||
getDetail(id: number): Promise<Member> {
|
||||
return request.get({ url: `${baseUrl}/${id}` })
|
||||
},
|
||||
|
||||
batchOperation(data: Record<string, any>): Promise<any> {
|
||||
return request.post({ url: `${baseUrl}/batch`, data })
|
||||
},
|
||||
|
||||
statistics(params?: Record<string, any>): Promise<any> {
|
||||
return request.get({ url: `${baseUrl}/statistics`, params })
|
||||
},
|
||||
|
||||
adjustPoints(id: number, data: Record<string, any>): Promise<any> {
|
||||
return request.put({ url: `${baseUrl}/${id}/adjust-points`, data })
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 会员模型
|
||||
*/
|
||||
export interface Member {
|
||||
id?: number;
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
phone?: string;
|
||||
email?: string;
|
||||
avatar?: string;
|
||||
level_id?: number;
|
||||
level_name?: string;
|
||||
balance?: number;
|
||||
points?: number;
|
||||
status?: number;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./logs";
|
||||
export type * from "./types";
|
||||
@@ -0,0 +1,29 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import type { LoginRecordRow, OnlineUserRow, OperateRecordRow } from './types';
|
||||
|
||||
const loginBaseUrl = '/logs/login';
|
||||
const operateBaseUrl = '/logs/operate';
|
||||
const onlineUserBaseUrl = '/monitor/online-user';
|
||||
|
||||
export const LoginLogService = {
|
||||
...BaseService<LoginRecordRow>({ baseUrl: loginBaseUrl, allowedMethods: ['list', 'get', 'remove'] }),
|
||||
};
|
||||
|
||||
export const OperateLogService = {
|
||||
...BaseService<OperateRecordRow>({ baseUrl: operateBaseUrl, allowedMethods: ['list', 'get', 'remove'] }),
|
||||
};
|
||||
|
||||
export const OnlineUserService = {
|
||||
...BaseService<OnlineUserRow>({ baseUrl: onlineUserBaseUrl, allowedMethods: ['list', 'delete'] }),
|
||||
|
||||
revoke(jti: string) {
|
||||
return request.post({ url: `${onlineUserBaseUrl}/${jti}/revoke` });
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
loginLogApi: LoginLogService,
|
||||
operateLogApi: OperateLogService,
|
||||
onlineUserApi: OnlineUserService,
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
type Timestamp = number; // Unix 时间戳
|
||||
type DateTime = string; // ISO 8601 格式字符串
|
||||
|
||||
/**
|
||||
* 登录日志
|
||||
*/
|
||||
export interface LoginRecordRow {
|
||||
id: string;
|
||||
user_name: string;
|
||||
ip: string;
|
||||
ip_location: string;
|
||||
os: string;
|
||||
browser: string;
|
||||
status: number;
|
||||
message: string | null;
|
||||
login_time: Timestamp;
|
||||
key: string;
|
||||
remark: string | null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 操作日志
|
||||
*/
|
||||
export interface OperateRecordRow {
|
||||
id: string;
|
||||
name: string;
|
||||
app: string;
|
||||
ip: string;
|
||||
ip_location: string;
|
||||
browser: string;
|
||||
os: string;
|
||||
url: string;
|
||||
class_name: string;
|
||||
action: string;
|
||||
method: string;
|
||||
param: string;
|
||||
result: string;
|
||||
user_name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在线用户
|
||||
*/
|
||||
export interface OnlineUserRow {
|
||||
jti: string;
|
||||
user_id: string;
|
||||
account: string;
|
||||
real_name: string;
|
||||
dept_names: string;
|
||||
post_names: string;
|
||||
role_names: string;
|
||||
ip: string;
|
||||
ip_location: string;
|
||||
device: string;
|
||||
browser: string;
|
||||
status: string;
|
||||
client_type: string;
|
||||
login_time: Timestamp;
|
||||
last_active_at: Timestamp;
|
||||
offline_at: Timestamp | null;
|
||||
online_seconds: number;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './redis';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,20 @@
|
||||
import request from '@/utils/http'
|
||||
import { RedisMonitorData } from './types'
|
||||
|
||||
const baseUrl = '/monitor/redis'
|
||||
|
||||
|
||||
/**
|
||||
* Redis监控
|
||||
*/
|
||||
export const RedisService = {
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
list(params?: Record<string, any>): Promise<RedisMonitorData> {
|
||||
return request.get({ url: baseUrl, params })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
export interface RedisProps {
|
||||
description?: string;
|
||||
name?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface DescriptionItem {
|
||||
content: Component | string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
|
||||
// 主数据类型
|
||||
export interface RedisMonitorData {
|
||||
uptime_in_seconds: number;
|
||||
connected_clients: number;
|
||||
used_memory: string; // 保持原始格式(如:"686.79 KB")
|
||||
memory_fragmentation_ratio: number;
|
||||
total_commands_processed: number;
|
||||
total_connections_received: number;
|
||||
keyspace_hits: number;
|
||||
keyspace_misses: number;
|
||||
hit_rate: number;
|
||||
variable: RedisVariableInfo;
|
||||
data: RedisDataEntries;
|
||||
}
|
||||
|
||||
// 变量信息类型(嵌套对象)
|
||||
export interface RedisVariableInfo {
|
||||
redis_version: string;
|
||||
redis_git_sha1: number | string; // 原始数据中包含数字0和字符串类型
|
||||
redis_git_dirty: number;
|
||||
redis_build_id: string;
|
||||
redis_mode: "standalone" | "cluster"; // 根据实际值限定
|
||||
os: string;
|
||||
arch_bits: 64 | 32; // 根据实际值限定
|
||||
multiplexing_api: "WinSock_IOCP" | string; // 根据实际值扩展
|
||||
process_id: number;
|
||||
run_id: string;
|
||||
tcp_port: number;
|
||||
uptime_in_seconds: number;
|
||||
uptime_in_days: number;
|
||||
hz: number;
|
||||
lru_clock: number;
|
||||
config_file: string;
|
||||
// 以下字段根据实际数据补充完整类型
|
||||
client_longest_output_list: number;
|
||||
client_biggest_input_buf: number;
|
||||
blocked_clients: number;
|
||||
used_memory: number; // 原始数值(与顶层used_memory格式不同)
|
||||
used_memory_human: string;
|
||||
used_memory_rss: number;
|
||||
used_memory_peak: number;
|
||||
used_memory_peak_human: string;
|
||||
used_memory_lua: number;
|
||||
mem_fragmentation_ratio: number;
|
||||
mem_allocator: string;
|
||||
|
||||
}
|
||||
|
||||
// 数据存储类型(键值对集合)
|
||||
interface RedisDataEntries {
|
||||
[key: string]: string; // 所有值保持原始序列化字符串格式
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './server';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,18 @@
|
||||
import request from '@/utils/http'
|
||||
import { type ServerInfo } from './types'
|
||||
|
||||
const baseUrl = '/monitor/server'
|
||||
|
||||
/**
|
||||
* 性能监控
|
||||
*/
|
||||
export const ServerService = {
|
||||
/**
|
||||
* 列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
list(params?: Record<string, any>): Promise<ServerInfo> {
|
||||
return request.get({ url: baseUrl, params })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 系统监控数据类型
|
||||
export interface ServerInfo {
|
||||
cpu: CpuInfo;
|
||||
memory: MemoryInfo;
|
||||
disk: DiskInfo[];
|
||||
php: PhpInfo;
|
||||
}
|
||||
|
||||
// CPU 信息类型
|
||||
export interface CpuInfo {
|
||||
cpu_name: string;
|
||||
physical_cores: string; // 物理核心数(字符串类型)
|
||||
logical_cores: string; // 逻辑核心数(字符串类型)
|
||||
cache_size_mb: number; // 缓存大小(MB,数值类型)
|
||||
cpu_usage_percentage: number; // CPU 使用率(百分比)
|
||||
free_cpu_percentage: number; // 空闲 CPU 百分比
|
||||
}
|
||||
|
||||
// 内存信息类型
|
||||
export interface MemoryInfo {
|
||||
total_memory: number; // 总内存(GB,数值类型)
|
||||
available_memory: number; // 可用内存(GB,数值类型)
|
||||
used_memory: number; // 已用内存(GB,数值类型)
|
||||
php_memory_usage: number; // PHP 内存使用率(百分比)
|
||||
memory_usage_rate: string; // 内存使用率(原始字符串格式)
|
||||
}
|
||||
|
||||
// 磁盘信息类型(数组项)
|
||||
export interface DiskInfo {
|
||||
filesystem: string; // 文件系统标识
|
||||
size: string; // 磁盘总大小(含单位)
|
||||
available: string; // 剩余空间(含单位)
|
||||
used: string; // 已用空间(含单位)
|
||||
use_percentage: string; // 使用率百分比(含%符号)
|
||||
mounted_on: string; // 挂载点
|
||||
}
|
||||
|
||||
// PHP 配置信息类型
|
||||
export interface PhpInfo {
|
||||
php_version: string; // PHP 版本
|
||||
os: string; // 操作系统类型
|
||||
project_path: string; // 项目路径
|
||||
memory_limit: string; // 内存限制
|
||||
max_execution_time: string; // 最大执行时间
|
||||
error_reporting: string; // 错误报告级别
|
||||
display_errors: "on" | "off"; // 错误显示开关(严格类型)
|
||||
upload_max_filesize: string; // 最大上传文件大小
|
||||
post_max_size: string; // POST 数据最大大小
|
||||
extension_dir: string; // 扩展目录
|
||||
loaded_extensions: string; // 已加载扩展(逗号分隔)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
export * from '@/utils/http';
|
||||
|
||||
|
||||
|
||||
export const getApiBaseUrl = (customValue?: string | null): string => {
|
||||
const getBaseUrl = (value: string): string => {
|
||||
// 如果是 useCurrentDomain,返回当前域名并添加 /adminapi
|
||||
if (value === 'useCurrentDomain') {
|
||||
const currentDomain = window.location.protocol + '//' + window.location.host;
|
||||
return currentDomain + '/adminapi';
|
||||
}
|
||||
|
||||
// 如果是完整 URL,直接返回
|
||||
if (/^https?:\/\//i.test(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// 如果是相对路径,确保以 / 开头
|
||||
const normalizedPath = value.replace(/^\/+/, '');
|
||||
|
||||
// 如果是当前域名,添加 /adminapi
|
||||
if (normalizedPath === '') {
|
||||
return window.location.protocol + '//' + window.location.host + '/adminapi';
|
||||
}
|
||||
|
||||
// 如果已经是 /adminapi 开头,直接返回
|
||||
if (normalizedPath.startsWith('adminapi')) {
|
||||
return window.location.protocol + '//' + window.location.host + '/' + normalizedPath;
|
||||
}
|
||||
|
||||
// 其他相对路径,添加当前域名
|
||||
return window.location.protocol + '//' + window.location.host + '/' + normalizedPath;
|
||||
};
|
||||
|
||||
if (customValue) {
|
||||
return getBaseUrl(customValue);
|
||||
}
|
||||
|
||||
const envValue = import.meta.env.VITE_API_URL;
|
||||
if (envValue) {
|
||||
return getBaseUrl(envValue);
|
||||
}
|
||||
|
||||
// 默认返回当前域名 + /adminapi
|
||||
return window.location.protocol + '//' + window.location.host + '/adminapi';
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const baseUrl = '/system/config'
|
||||
|
||||
export const ConfigService = {
|
||||
getByCode($code: string, params?: Record<string, any>) {
|
||||
return request.get({ url: `${baseUrl}/code/${$code}`, params })
|
||||
},
|
||||
getApiEncryptDetail() {
|
||||
return request.get({ url: '/system/api-encrypt' })
|
||||
},
|
||||
generateApiEncryptKeypair() {
|
||||
return request.post({ url: '/system/api-encrypt/generate-keypair' })
|
||||
},
|
||||
getByGroup(groupCode: string, params?: Record<string, any>) {
|
||||
return request.get({ url: `${baseUrl}/group/${groupCode}`, params })
|
||||
},
|
||||
getItems(params: Record<string, any>) {
|
||||
return request.get({ url: `${baseUrl}/items`, params })
|
||||
},
|
||||
update(code: string, data: Record<string, any>) {
|
||||
return request.put({ url: `${baseUrl}/${code}`, data })
|
||||
},
|
||||
save(data: Record<string, any>) {
|
||||
return request.post({ url: baseUrl, data })
|
||||
},
|
||||
delete(code: string) {
|
||||
return request.del({ url: `${baseUrl}/${code}` })
|
||||
}
|
||||
}
|
||||
|
||||
export default ConfigService
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './config';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,557 @@
|
||||
|
||||
/**
|
||||
* 网站核心配置接口
|
||||
* @desc 包含站点基础信息、备案数据及安全认证配置
|
||||
*/
|
||||
export interface SiteConfig {
|
||||
/**
|
||||
* 站点开放状态
|
||||
* @example "1" - 启用状态
|
||||
* @example "0" - 维护状态
|
||||
*/
|
||||
site_open: '0' | '1';
|
||||
|
||||
/** 站点访问地址 (需包含协议头) */
|
||||
site_url: string;
|
||||
|
||||
/** 站点名称 (中文/英文品牌标识) */
|
||||
site_name: string;
|
||||
|
||||
/**
|
||||
* 站点LOGO地址
|
||||
* @pattern 支持SVG/PNG格式资源路径
|
||||
*/
|
||||
site_logo: string;
|
||||
|
||||
/**
|
||||
* 公安备案编号
|
||||
* @example "京公网安备 2024042441号-2"
|
||||
*/
|
||||
site_network_security: string;
|
||||
|
||||
/** 站点描述信息 (SEO优化关键字段) */
|
||||
site_description: string;
|
||||
|
||||
/** ICP备案号 (省级备案编号) */
|
||||
site_record_no: string;
|
||||
|
||||
cdn_url?:string;
|
||||
|
||||
cdn_url_params?:string;
|
||||
|
||||
/**
|
||||
* ICP备案跳转链接
|
||||
* @link https://beian.miit.gov.cn/
|
||||
*/
|
||||
site_icp_url: string;
|
||||
|
||||
/**
|
||||
* 公安备案跳转链接
|
||||
* @desc 当前为空时需要隐藏备案跳转按钮
|
||||
*/
|
||||
site_network_security_url: string | null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 文件传输策略配置
|
||||
* @desc 控制文件上传/下载的精细化策略
|
||||
*/
|
||||
export interface FilePolicyConfig {
|
||||
/**
|
||||
* 存储模式
|
||||
* @default "local"
|
||||
* @enum ["local", "remote", "hybrid"] - 混合模式需配合CDN配置
|
||||
*/
|
||||
mode: "local" | "remote" | "hybrid";
|
||||
|
||||
/**
|
||||
* 单文件大小限制(单位:MB)
|
||||
* @minimum 1 - 允许最小1MB
|
||||
* @maximum 2048 - 系统最大支持2GB
|
||||
*/
|
||||
single_limit: number;
|
||||
|
||||
/**
|
||||
* 总传输容量限制(单位:MB)
|
||||
* @note 当模式为remote时自动提升至5000MB
|
||||
*/
|
||||
total_limit: number;
|
||||
|
||||
/**
|
||||
* 并发传输数
|
||||
* @minimum 1
|
||||
* @maximum 50 - 受服务器性能限制
|
||||
*/
|
||||
nums: number;
|
||||
|
||||
/**
|
||||
* 禁止传输的文件类型
|
||||
* @pattern 以逗号分隔的扩展名,不包含点符号
|
||||
* @example "php,ext,exe" - 高危文件类型过滤
|
||||
*/
|
||||
exclude: string;
|
||||
|
||||
/**
|
||||
* 扩展校验规则(可选)
|
||||
* @beta 实验性功能
|
||||
*/
|
||||
advanced?: {
|
||||
/** 哈希校验算法 */
|
||||
hash_algorithm?: "MD5" | "SHA256";
|
||||
/** 病毒扫描开关 */
|
||||
virus_scan?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SMTP 邮件服务配置
|
||||
* @desc 包含加密协议、认证信息及发件人配置
|
||||
* @link [QQ邮箱SMTP文档](https://service.mail.qq.com/detail/0/75)
|
||||
*/
|
||||
export interface EmailConfig {
|
||||
/**
|
||||
* 传输层安全协议
|
||||
* @enum ["ssl", "tls"] - QQ邮箱强制要求SSL加密
|
||||
* @example "ssl" - 标准加密协议
|
||||
*/
|
||||
SMTPSecure: "ssl" | "tls";
|
||||
|
||||
/**
|
||||
* SMTP服务器地址
|
||||
* @pattern 域名或IP地址
|
||||
* @default "smtp.qq.com"
|
||||
*/
|
||||
Host: string;
|
||||
|
||||
/**
|
||||
* 服务端口号
|
||||
* @default 465 - SSL协议专用端口
|
||||
* @see 587 - TLS协议备用端口
|
||||
*/
|
||||
Port: 465 | 587;
|
||||
|
||||
/**
|
||||
* 认证邮箱账号
|
||||
* @format 需开启SMTP服务的完整邮箱
|
||||
* @example "kzhzjdyw888@qq.com"
|
||||
*/
|
||||
Username: `${string}@${string}.${string}`;
|
||||
|
||||
/**
|
||||
* SMTP授权码
|
||||
* @security Sensitive - 需加密存储
|
||||
* @note 非QQ邮箱登录密码
|
||||
*/
|
||||
Password: string;
|
||||
|
||||
/**
|
||||
* 发件人邮箱
|
||||
* @rule 需与认证账号一致
|
||||
* @example "service@company.com"
|
||||
*/
|
||||
From: `${string}@${string}.${string}`;
|
||||
|
||||
/**
|
||||
* 发件人显示名称
|
||||
* @maxLength 30 - 客户端显示限制
|
||||
* @example "【企业名称】系统通知"
|
||||
*/
|
||||
FromName: string;
|
||||
|
||||
/**
|
||||
* 高级连接配置(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 超时时间(毫秒) */
|
||||
timeout?: number;
|
||||
/** 调试模式日志级别 */
|
||||
debugLevel?: "none" | "basic" | "full";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信服务全局配置
|
||||
* @desc 包含服务商认证、签名模板及服务开关
|
||||
*/
|
||||
export interface SMSConfig {
|
||||
/**
|
||||
* 服务开关
|
||||
* @enum ["0", "1"] - 0=禁用,1=启用
|
||||
* @security 敏感操作需二次验证
|
||||
*/
|
||||
enable: "0" | "1";
|
||||
|
||||
/**
|
||||
* 服务商访问密钥ID
|
||||
* @pattern 由服务商颁发的18-32位数字ID
|
||||
* @example "234813346262818816"
|
||||
*/
|
||||
access_key_id: string;
|
||||
|
||||
/**
|
||||
* 服务商访问密钥
|
||||
* @security Sensitive - 需加密存储
|
||||
* @note 泄漏将导致账号被盗风险
|
||||
*/
|
||||
access_key_secret: string;
|
||||
|
||||
/**
|
||||
* 短信签名模板
|
||||
* @template 必须包含 {code} 占位符
|
||||
* @example "【企业名称】,你的验证码是{code},有效期5分钟。"
|
||||
*/
|
||||
sign_name: string;
|
||||
|
||||
/**
|
||||
* 高级配置(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 请求超时时间(毫秒) */
|
||||
timeout?: number;
|
||||
/** 失败重试次数 */
|
||||
retry_times?: number;
|
||||
/** 地域节点 */
|
||||
region_id?: "cn-hangzhou" | "ap-southeast-1";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地文件上传配置
|
||||
* @desc 包含存储路径、域名配置等核心参数
|
||||
*/
|
||||
export interface LocalUploadConfig {
|
||||
/**
|
||||
* 文件存储根目录
|
||||
* @example "public" - 对应项目根目录下的/public文件夹
|
||||
* @pattern 仅允许字母、数字、下划线组合
|
||||
*/
|
||||
root: string;
|
||||
|
||||
/**
|
||||
* 动态子目录名称
|
||||
* @example "upload" - 最终路径为 /public/upload/
|
||||
* @rule 禁止包含路径分隔符(/或\)
|
||||
*/
|
||||
dirname: string;
|
||||
|
||||
/**
|
||||
* 资源访问域名
|
||||
* @format 需包含协议头和端口号(非80/443端口时必须显式声明)
|
||||
* @example "http://cdn.example.com:8080"
|
||||
*/
|
||||
domain: `http://${string}` | `https://${string}`;
|
||||
|
||||
/**
|
||||
* 高级存储策略(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 文件名生成策略 */
|
||||
filenameStrategy?: "timestamp" | "hash" | "original";
|
||||
/** 目录深度分级 */
|
||||
depthLevel?: number;
|
||||
/** 自动清理过期文件(单位:天) */
|
||||
autoPurgeDays?: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 阿里云OSS上传配置
|
||||
* @desc 包含身份认证、存储桶配置及访问策略
|
||||
* @link [OSS官方文档](https://help.aliyun.com/zh/oss)
|
||||
*/
|
||||
interface AliyunOSSConfig {
|
||||
/**
|
||||
* 访问密钥ID
|
||||
* @security Sensitive - 需加密存储
|
||||
* @pattern 由阿里云颁发的LTAI开头的32位字符
|
||||
* @example "LTAI5txxxxxxxxxxxxxxx"
|
||||
*/
|
||||
accessKeyId: string;
|
||||
|
||||
/**
|
||||
* 访问密钥凭证
|
||||
* @security Sensitive - 需二次加密
|
||||
* @note 泄漏将导致存储桶被恶意操控
|
||||
*/
|
||||
accessKeySecret: string;
|
||||
|
||||
/**
|
||||
* 存储桶名称
|
||||
* @rule 全局唯一且符合OSS命名规范
|
||||
* @pattern 全小写字母、数字及连字符组合
|
||||
* @example "madong-tech-prod"
|
||||
*/
|
||||
bucket: string;
|
||||
|
||||
/**
|
||||
* 存储目录路径
|
||||
* @default "upload"
|
||||
* @rule 禁止包含../等路径穿越符号
|
||||
*/
|
||||
dirname: string;
|
||||
|
||||
/**
|
||||
* 自定义访问域名
|
||||
* @format 需包含协议头及CNAME解析
|
||||
* @example "https://oss.madong.tech"
|
||||
*/
|
||||
domain: `http://${string}` | `https://${string}`;
|
||||
|
||||
/**
|
||||
* 区域终端节点
|
||||
* @enum 常用节点
|
||||
* @example "oss-cn-hangzhou.aliyuncs.com" - 杭州地域
|
||||
* @example "oss-ap-southeast-1.aliyuncs.com" - 新加坡地域
|
||||
*/
|
||||
endpoint: string;
|
||||
|
||||
/**
|
||||
* 配置备注说明(可选)
|
||||
* @maxLength 200 - 控制台显示限制
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 高级传输策略(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 分片上传阈值(单位:MB) */
|
||||
multipartThreshold?: number;
|
||||
/** 并行上传线程数 */
|
||||
parallel?: number;
|
||||
/** 超时重试次数 */
|
||||
maxRetries?: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 腾讯云COS存储配置
|
||||
* @desc 包含密钥管理、存储桶策略及访问控制
|
||||
* @link [COS官方文档](https://cloud.tencent.com/document/product/436)
|
||||
*/
|
||||
interface TencentCOSConfig {
|
||||
/**
|
||||
* 云API密钥ID
|
||||
* @security Sensitive - 需加密存储
|
||||
* @pattern 腾讯云标准的AKID开头32位字符
|
||||
* @example "AKID5dxxxxxxxxxxxxxxxxxxxxxx"
|
||||
*/
|
||||
secretId: string;
|
||||
|
||||
/**
|
||||
* 云API密钥凭证
|
||||
* @security Sensitive - 需二次加密
|
||||
* @note 泄漏将导致存储桶数据泄露风险
|
||||
*/
|
||||
secretKey: string;
|
||||
|
||||
/**
|
||||
* 存储桶名称
|
||||
* @rule 命名格式为 [bucket]-[appid]
|
||||
* @example "webassets-1250000000"
|
||||
* @pattern ^[a-z0-9-]+-\d+$
|
||||
*/
|
||||
bucket: string;
|
||||
|
||||
/**
|
||||
* 存储目录路径
|
||||
* @default "uploads"
|
||||
* @rule 禁止使用 ../ 等路径穿越符号
|
||||
*/
|
||||
dirname: string;
|
||||
|
||||
/**
|
||||
* 自定义访问域名
|
||||
* @format 需包含协议头及CDN加速配置
|
||||
* @example "https://cos.madong.tech"
|
||||
*/
|
||||
domain: `http://${string}` | `https://${string}`;
|
||||
|
||||
/**
|
||||
* 存储地域标识
|
||||
* @enum ["ap-beijing", "ap-shanghai", "ap-guangzhou"]
|
||||
* @example "ap-guangzhou" - 广州地域
|
||||
*/
|
||||
region: string;
|
||||
|
||||
/**
|
||||
* 配置描述信息(可选)
|
||||
* @maxLength 100 - 控制台显示限制
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 高级传输配置(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 分块上传阈值(单位:MB) */
|
||||
chunkSize?: number;
|
||||
/** 并发上传线程数 */
|
||||
concurrency?: number;
|
||||
/** 临时密钥有效期(秒) */
|
||||
tempKeyDuration?: number;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 七牛云Kodo存储配置
|
||||
* @desc 包含访问凭证、存储区域策略及域名配置
|
||||
* @link [七牛云开发者文档](https://developer.qiniu.com/)
|
||||
*/
|
||||
interface QiniuConfig {
|
||||
/**
|
||||
* 访问密钥(AK)
|
||||
* @security Sensitive - 需加密存储
|
||||
* @pattern 七牛云标准的32位字符密钥
|
||||
* @example "AK-5dxxxxxxxxxxxxxxxxxxxxxx"
|
||||
*/
|
||||
accessKey: string;
|
||||
|
||||
/**
|
||||
* 安全密钥(SK)
|
||||
* @security Sensitive - 需硬件加密模块保护
|
||||
* @note 泄漏将导致存储桶完全失控
|
||||
*/
|
||||
secretKey: string;
|
||||
|
||||
/**
|
||||
* 存储空间名称
|
||||
* @rule 全局唯一且符合DNS命名规范
|
||||
* @pattern ^[a-z0-9-]{3,63}$ - 全小写字母、数字、连字符
|
||||
* @example "madong-prod-bucket"
|
||||
*/
|
||||
bucket: string;
|
||||
|
||||
/**
|
||||
* 存储目录路径
|
||||
* @default "uploads"
|
||||
* @rule 禁止使用路径操作符(如../)
|
||||
*/
|
||||
dirname: string;
|
||||
|
||||
/**
|
||||
* 自定义加速域名
|
||||
* @format 需完成CNAME解析的HTTPS域名
|
||||
* @example "https://kodo.madong.tech"
|
||||
*/
|
||||
domain: `https://${string}`;
|
||||
|
||||
/**
|
||||
* 存储区域标识
|
||||
* @enum ["z0", "z1", "z2", "na0", "as0"]
|
||||
* @example "z0" - 华东区域
|
||||
* @example "na0" - 北美区域
|
||||
*/
|
||||
region: string;
|
||||
|
||||
/**
|
||||
* 配置备注(可选)
|
||||
* @maxLength 100 - 控制台显示限制
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 高级上传策略(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 分片上传阈值(单位:MB) */
|
||||
chunkSize?: 4 | 8 | 16;
|
||||
/** 直传/代理上传模式 */
|
||||
uploadMode?: "direct" | "proxy";
|
||||
/** 防盗链Token有效期(秒) */
|
||||
antiLeechTTL?: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 亚马逊S3存储配置
|
||||
* @desc 包含IAM凭证、存储桶策略及跨区域复制配置
|
||||
* @link [AWS S3官方文档](https://docs.aws.amazon.com/s3/)
|
||||
*/
|
||||
export interface AmazonS3Config {
|
||||
/**
|
||||
* IAM访问密钥ID
|
||||
* @security Sensitive - 需KMS加密存储
|
||||
* @pattern AWS标准的20位字母数字组合
|
||||
* @example "AKIAIOSFODNN7EXAMPLE"
|
||||
*/
|
||||
key: string;
|
||||
|
||||
/**
|
||||
* IAM安全访问密钥
|
||||
* @security Sensitive - 需硬件安全模块保护
|
||||
* @note 泄漏将导致存储桶完全失控
|
||||
*/
|
||||
secret: string;
|
||||
|
||||
/**
|
||||
* 存储桶名称
|
||||
* @rule 全局唯一且符合DNS命名规范
|
||||
* @pattern ^[a-z0-9.-]{3,63}$ - 全小写字母、数字、点、连字符
|
||||
* @example "madong.enterprise.data"
|
||||
*/
|
||||
bucket: string;
|
||||
|
||||
/**
|
||||
* 存储路径前缀
|
||||
* @default "uploads"
|
||||
* @rule 禁止使用路径操作符(如../)
|
||||
*/
|
||||
dirname: string;
|
||||
|
||||
/**
|
||||
* 自定义访问域名
|
||||
* @format 需完成CNAME解析的HTTPS域名
|
||||
* @example "https://s3.madong.tech"
|
||||
*/
|
||||
domain: `https://${string}`;
|
||||
|
||||
/**
|
||||
* 服务终端节点
|
||||
* @enum ["s3.amazonaws.com", "s3.us-east-2.amazonaws.com"]
|
||||
* @example "s3.ap-southeast-1.amazonaws.com" - 新加坡节点
|
||||
*/
|
||||
endpoint: string;
|
||||
|
||||
/**
|
||||
* 存储区域标识
|
||||
* @enum ["us-east-1", "eu-central-1", "ap-northeast-1"]
|
||||
* @example "ap-northeast-1" - 东京区域
|
||||
*/
|
||||
region: string;
|
||||
|
||||
/**
|
||||
* 访问控制策略
|
||||
* @enum ["private", "public-read", "bucket-owner-full-control"]
|
||||
* @default "private" - 默认私有读写
|
||||
*/
|
||||
acl: string;
|
||||
|
||||
/**
|
||||
* 配置描述(可选)
|
||||
* @maxLength 200 - 控制台显示限制
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
/**
|
||||
* 高级安全策略(可选)
|
||||
*/
|
||||
advanced?: {
|
||||
/** 服务端加密算法 */
|
||||
encryption?: "AES256" | "aws:kms";
|
||||
/** 跨区域复制配置 */
|
||||
replication?: {
|
||||
destinationRegion: string;
|
||||
syncDelayMinutes: number;
|
||||
};
|
||||
/** 生命周期规则(天数) */
|
||||
lifecycleRules?: {
|
||||
transitionToGlacier?: number;
|
||||
expiration?: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import BaseService from "@/api/core/base";
|
||||
import type { DeptRow, DeptTree } from "./dept-model";
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/org/dept';
|
||||
|
||||
export const DeptService = {
|
||||
...BaseService<DeptRow>({ baseUrl }),
|
||||
|
||||
getTree(args?: Record<string, any>): Promise<DeptTree[]> {
|
||||
const params = { ...args, format: 'tree' };
|
||||
return request.get<DeptTree[]>({ url: baseUrl, params });
|
||||
},
|
||||
};
|
||||
|
||||
export default DeptService;
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './dept';
|
||||
export type * from './dept-model';
|
||||
@@ -0,0 +1,51 @@
|
||||
import { DeptTree } from './dept-model'
|
||||
/**
|
||||
* 部门实体接口
|
||||
*/
|
||||
export interface DeptRow {
|
||||
id: string
|
||||
pid: string | number
|
||||
level: string
|
||||
code: string
|
||||
name: string
|
||||
main_leader_id: string
|
||||
phone: string
|
||||
enabled: string
|
||||
sort: string
|
||||
children?: DeptRow[]
|
||||
remark: string
|
||||
}
|
||||
|
||||
export interface DeptTree {
|
||||
[key: string]: any
|
||||
children?: DeptRow[]
|
||||
id: string
|
||||
name: string
|
||||
remark?: string
|
||||
enabled: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 部门树
|
||||
*/
|
||||
export interface DeptTree {
|
||||
id: number | string
|
||||
/**
|
||||
* antd组件必须要这个属性 实际是没有这个属性的
|
||||
*/
|
||||
key?: string
|
||||
pid: number | string
|
||||
name: string
|
||||
sort: number
|
||||
children?: DeptTableTree[]
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export interface DeptOptionsTree {
|
||||
id?: number | string
|
||||
label: string
|
||||
value: string | number
|
||||
children?: DeptOptionsTree[]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import type { DictItemRow } from './types'
|
||||
|
||||
const baseUrl = '/dict/item'
|
||||
|
||||
export const DictItemService = {
|
||||
...BaseService<DictItemRow>({ baseUrl })
|
||||
}
|
||||
|
||||
export default DictItemService
|
||||
@@ -0,0 +1,28 @@
|
||||
import BaseService from "@/api/core/base";
|
||||
import type { DictOptions, DictRow } from "./types";
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/dict/dict';
|
||||
|
||||
export const DictService = {
|
||||
...BaseService<DictRow>({ baseUrl }),
|
||||
|
||||
enumDictList(params: any): Promise<DictRow[]> {
|
||||
return request.get({ url: `${baseUrl}/enum-dict-list`, params });
|
||||
},
|
||||
|
||||
customDictList(params: any): Promise<DictRow[]> {
|
||||
return request.get({ url: `${baseUrl}/custom/list`, params });
|
||||
},
|
||||
|
||||
getByDictType(params: any): Promise<DictOptions[]> {
|
||||
return request.get({ url: `${baseUrl}/options/by-type`, params });
|
||||
},
|
||||
|
||||
getAllDict(params: any): Promise<any[]> {
|
||||
return request.get({ url: `${baseUrl}/enum/list`, params });
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default DictService;
|
||||
@@ -0,0 +1,4 @@
|
||||
export type * from './dict-item-types';
|
||||
export type * from './types';
|
||||
export * from './dict-item';
|
||||
export * from './dict';
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
export interface DictRow {
|
||||
id: string;
|
||||
group_code: string;
|
||||
name: string;
|
||||
code: string;
|
||||
data_type: string;
|
||||
description: string;
|
||||
enabled: number;
|
||||
sort: number;
|
||||
created_by: string;
|
||||
updated_by: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface DictOptions extends DictItemRow {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
export type ApiResponse<T> = Promise<{
|
||||
code: number;
|
||||
data: T;
|
||||
msg: string;
|
||||
}>;
|
||||
|
||||
|
||||
export interface DictItemRow {
|
||||
label: string;
|
||||
value: string | number;
|
||||
id?: string | number;
|
||||
dict_id: string | number;
|
||||
code: string;
|
||||
sort: number;
|
||||
enabled: number;
|
||||
color: string;
|
||||
other_class: string;
|
||||
is_default?: number;
|
||||
created_by: string | number;
|
||||
updated_by: string | number;
|
||||
created_at: string | number;
|
||||
updated_at: string | number;
|
||||
remark: string;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { FeedbackRow } from './types'
|
||||
|
||||
const baseUrl = '/feedback'
|
||||
|
||||
export const FeedbackService = {
|
||||
...BaseService<FeedbackRow>({ baseUrl }),
|
||||
reply(id: string, replyContent: string) {
|
||||
return request.post<FeedbackRow>({
|
||||
url: `${baseUrl}/${id}/reply`,
|
||||
params: { reply_content: replyContent }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export type * from './types'
|
||||
export default FeedbackService
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 问题反馈
|
||||
*/
|
||||
export interface FeedbackRow {
|
||||
id: string
|
||||
type: 'bug' | 'suggestion' | 'correction'
|
||||
content: string
|
||||
contact: string | null
|
||||
images: string[] | null
|
||||
source: 'app' | 'web'
|
||||
reply_content: string | null
|
||||
reply_by: string | null
|
||||
reply_name: string | null
|
||||
reply_at: number | null
|
||||
reply_date: string | null
|
||||
created_at: string | null
|
||||
created_date: string | null
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
import BaseService from "@/api/core/base";
|
||||
import type { GatewayLimiterRow, GatewayBlacklistRow } from "./types";
|
||||
|
||||
|
||||
const baseUrl = '/gateway/limiter'
|
||||
|
||||
export const GatewayLimiterService = {
|
||||
...BaseService<GatewayLimiterRow>({ baseUrl })
|
||||
}
|
||||
|
||||
|
||||
export const GatewayBlacklistService = {
|
||||
...BaseService<GatewayBlacklistRow>({ baseUrl: '/gateway/blacklist' })
|
||||
}
|
||||
|
||||
|
||||
export type * from './types';
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
/**
|
||||
* 限流接口
|
||||
*/
|
||||
export interface GatewayLimiterRow {
|
||||
id: string;
|
||||
name: string;
|
||||
match_type: string;
|
||||
ip: string;
|
||||
priority: number;
|
||||
methods: string;
|
||||
path: string;
|
||||
limit_type: string;
|
||||
limit_value: number;
|
||||
period: number;
|
||||
enabled: number;
|
||||
message: string;
|
||||
created_date: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 限访接口
|
||||
*/
|
||||
export interface GatewayBlacklistRow {
|
||||
id: string;
|
||||
ip: string;
|
||||
name: string;
|
||||
enabled: number;
|
||||
priority: number;
|
||||
methods: string;
|
||||
path: string;
|
||||
message: string;
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
created_date: string;
|
||||
remark: string;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import type { MessageRow } from "./types";
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/message';
|
||||
|
||||
export const MessageService = {
|
||||
...BaseService<MessageRow>({ baseUrl }),
|
||||
|
||||
updateRead(params: string | string[]) {
|
||||
const data = {
|
||||
id: params,
|
||||
status: 'read',
|
||||
};
|
||||
return request.put({ url: `${baseUrl}/${params}/update-read`, data });
|
||||
},
|
||||
|
||||
emptyMessage(params: string | string[]) {
|
||||
const data = {
|
||||
id: params,
|
||||
status: 'deleted',
|
||||
};
|
||||
return request.put({ url: `${baseUrl}/empty`, data });
|
||||
},
|
||||
|
||||
notifyOnFirstLoginToAll(data: any) {
|
||||
return request.post({ url: `${baseUrl}/notify-on-first-login-to-all`, data });
|
||||
},
|
||||
};
|
||||
|
||||
export type * from './types';
|
||||
export default MessageService;
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 系统消息
|
||||
*/
|
||||
export interface MessageRow {
|
||||
id: string;
|
||||
title: string;
|
||||
type: number;
|
||||
content: any;
|
||||
enabled: number;
|
||||
sender_id: string;
|
||||
receiver_id: string;
|
||||
status: string;
|
||||
priority?: string;
|
||||
channel: string;
|
||||
related_id: string;
|
||||
related_type: string;
|
||||
action_url: string;
|
||||
action_params: string;
|
||||
created_by: string | null;
|
||||
created_at: string | null;
|
||||
created_date: string | null;
|
||||
expired_at: string | null;
|
||||
sender?: any;
|
||||
}
|
||||
|
||||
export interface NotificationItem {
|
||||
id?: string;
|
||||
uid?: string;
|
||||
type?: string;
|
||||
avatar: string;
|
||||
date: string;
|
||||
isRead?: boolean;
|
||||
message: string;
|
||||
title: string;
|
||||
send?: any;
|
||||
related_id?: string;
|
||||
channel?: string;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import BaseService from "@/api/core/base";
|
||||
import type { NoticeRow } from "./types";
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/notice';
|
||||
|
||||
export const NoticeService = {
|
||||
...BaseService<NoticeRow>({ baseUrl }),
|
||||
|
||||
publish(data: any) {
|
||||
return request.post({ url: `${baseUrl}/publish`, data });
|
||||
},
|
||||
};
|
||||
|
||||
export type * from './types';
|
||||
export default NoticeService;
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 通知公告
|
||||
*/
|
||||
export interface NoticeRow {
|
||||
id: string;
|
||||
message_id?: string | null;
|
||||
title: string;
|
||||
type: number;
|
||||
content: any;
|
||||
enabled: number;
|
||||
created_by: string | null;
|
||||
updated_by: string | null;
|
||||
created_date: string;
|
||||
updated_date: string | null;
|
||||
created_dept: string | null;
|
||||
remark: string | null;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './post';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,11 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import type { PostRow } from './types';
|
||||
|
||||
const baseUrl = '/org/post';
|
||||
|
||||
export const PostService = {
|
||||
...BaseService<PostRow>({ baseUrl }),
|
||||
getList: BaseService<PostRow>({ baseUrl }).list,
|
||||
};
|
||||
|
||||
export default PostService;
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
/**
|
||||
* 职位接口
|
||||
*/
|
||||
export interface PostRow {
|
||||
id: number | string;
|
||||
dept_id: string | number;
|
||||
code: string;
|
||||
name: string;
|
||||
sort: number;
|
||||
enabled: number;
|
||||
remark: string;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http'
|
||||
import type { ReviewListRequest, ReviewRow, ReviewCreateRequest, ReviewUpdateRequest } from './types'
|
||||
|
||||
|
||||
const baseUrl = '/review';
|
||||
|
||||
export const ReviewService = {
|
||||
...BaseService<ReviewRow>({ baseUrl }),
|
||||
|
||||
/**
|
||||
* 审核通过
|
||||
*/
|
||||
approve(id: number, reason: string = '') {
|
||||
return request.put<any>({
|
||||
url: `/review/${id}/approve`,
|
||||
data: { reason }
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 审核拒绝
|
||||
*/
|
||||
reject(id: number, reason: string = '') {
|
||||
return request.put<any>({
|
||||
url: `/review/${id}/reject`,
|
||||
data: { reason }
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
batchApprove(ids: number[], reason: string = '') {
|
||||
return request.post<any>({
|
||||
url: `/review/batch/approve`,
|
||||
data: { ids, reason }
|
||||
})
|
||||
},
|
||||
|
||||
batchReject(ids: number[], reason: string = '') {
|
||||
return request.post<any>({
|
||||
url: `/review/batch/reject`,
|
||||
data: { ids, reason }
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 反审核
|
||||
*/
|
||||
unapprove(id: number) {
|
||||
return request.put<any>({
|
||||
url: `/setting/review/${id}/unapprove`,
|
||||
method: 'post'
|
||||
})
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// 审核列表请求参数
|
||||
export interface ReviewListRequest {
|
||||
page?: number
|
||||
limit?: number
|
||||
title?: string
|
||||
type?: string // 改为string类型,对应reviewable_type
|
||||
status?: number
|
||||
applicant?: string
|
||||
LIKE_title?: string
|
||||
LIKE_applicant?: string
|
||||
reviewable_type?: string // 新增:审核类型(morph_map别名)
|
||||
}
|
||||
|
||||
// 审核项(支持插件字段映射)
|
||||
export interface ReviewRow {
|
||||
// 基础字段
|
||||
id: number
|
||||
status: number
|
||||
status_text: string
|
||||
reason?: string
|
||||
reviewer_id?: number
|
||||
reviewer_name?: string
|
||||
reviewed_at?: number
|
||||
created_at: number
|
||||
updated_at: number
|
||||
|
||||
// 关联信息
|
||||
reviewable_type: string
|
||||
reviewable_id: number
|
||||
display_name?: string // 审核类型显示名称
|
||||
morph_alias?: string // morph_map别名
|
||||
|
||||
// 映射字段(通过配置动态生成)
|
||||
title: string
|
||||
content: string
|
||||
applicant: string
|
||||
|
||||
// 额外映射字段(插件自定义)
|
||||
[key: string]: any
|
||||
|
||||
// 关联对象
|
||||
reviewer?: {
|
||||
id: number
|
||||
user_name: string
|
||||
real_name: string
|
||||
nick_name: string
|
||||
}
|
||||
}
|
||||
|
||||
// 审核类型配置
|
||||
export interface ReviewTypeConfig {
|
||||
display_name: string
|
||||
model?: string
|
||||
morph_alias?: string
|
||||
priority?: number
|
||||
icon?: string
|
||||
color?: string
|
||||
fields?: Record<string, ReviewFieldConfig>
|
||||
}
|
||||
|
||||
// 字段配置
|
||||
export interface ReviewFieldConfig {
|
||||
type: 'attribute' | 'relation' | 'callback' | 'fixed'
|
||||
source?: string
|
||||
attribute?: string
|
||||
label: string
|
||||
fallback?: string
|
||||
format?: string
|
||||
multiple?: boolean
|
||||
callback?: Function
|
||||
}
|
||||
|
||||
// 创建审核请求参数
|
||||
export interface ReviewCreateRequest {
|
||||
reviewable_type: string // 审核类型(morph_map别名)
|
||||
reviewable_id: number // 关联对象ID
|
||||
reason?: string // 审核原因
|
||||
flow_instance_id?: string // 审批流实例ID
|
||||
extra_data?: Record<string, any> // 扩展数据
|
||||
}
|
||||
|
||||
// 更新审核请求参数
|
||||
export interface ReviewUpdateRequest {
|
||||
reason?: string
|
||||
review_note?: string
|
||||
}
|
||||
|
||||
// 审核操作响应
|
||||
export interface ReviewActionResult {
|
||||
success: boolean
|
||||
message: string
|
||||
data?: any
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import axios from 'axios';
|
||||
|
||||
const { VITE_API_URL } = import.meta.env
|
||||
|
||||
const baseUrl = '/system/auth';
|
||||
|
||||
// 独立的 axios 实例用于刷新 token,避免与主请求拦截器关联
|
||||
const refreshAxios = axios.create({
|
||||
baseURL: VITE_API_URL,
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
/**
|
||||
* 使用 refresh token 刷新 access token(独立实例)
|
||||
* @param refreshToken - refresh token
|
||||
*/
|
||||
export function refreshAccessTokenByRefreshToken(refreshToken: string) {
|
||||
return refreshAxios.post(`${baseUrl}/refresh-token`, {}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${refreshToken}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const AuthService = {
|
||||
...BaseService<any>({ baseUrl }),
|
||||
|
||||
getPublicKey() {
|
||||
return request.get({ url: `/login/auth/public-key` });
|
||||
},
|
||||
|
||||
login(params: any) {
|
||||
return request.post({ url: '/login/login', params });
|
||||
},
|
||||
|
||||
logout(params: any) {
|
||||
return request.post({ url: '/login/logout', params });
|
||||
},
|
||||
|
||||
userInfo() {
|
||||
return request.get({ url: `${baseUrl}/user-info` });
|
||||
},
|
||||
|
||||
roleMenuIds(params: any) {
|
||||
return request.get({ url: `${baseUrl}/role-menu-ids`, params });
|
||||
},
|
||||
|
||||
roleScopeIds(params: any) {
|
||||
return request.get({ url: `${baseUrl}/role-scope-ids`, params });
|
||||
},
|
||||
|
||||
userListByRoleId(params: any) {
|
||||
return request.get({ url: `${baseUrl}/user-list-by-role-id`, params });
|
||||
},
|
||||
|
||||
userListExcludeRoleId(params: any) {
|
||||
return request.get({ url: `${baseUrl}/user-list-exclude-role-id`, params });
|
||||
},
|
||||
|
||||
removeUserRole(data: any) {
|
||||
return request.post({ url: `${baseUrl}/remove-user-role`, data });
|
||||
},
|
||||
|
||||
saveRoleMenu(data: any) {
|
||||
return request.post({ url: `${baseUrl}/save-role-menu`, data });
|
||||
},
|
||||
|
||||
saveUserRole(data: any) {
|
||||
return request.post({ url: `${baseUrl}/save-user-role`, data });
|
||||
},
|
||||
|
||||
getUserTenant() {
|
||||
return request.get({ url: `${baseUrl}/user-tenant` });
|
||||
},
|
||||
|
||||
changeTenant(data: any) {
|
||||
return request.put({ url: `${baseUrl}/change-tenant`, data });
|
||||
},
|
||||
|
||||
tenantGrant(data: any) {
|
||||
return request.put({ url: `${baseUrl}/tenant-grant`, data });
|
||||
},
|
||||
|
||||
getUserPermission() {
|
||||
return request.get({ url: `${baseUrl}/user-permissions`, params: {} });
|
||||
},
|
||||
fetchGetMenuList() {
|
||||
// 获取用户菜单列表-返回前端路由格式
|
||||
return request.get({ url: `${baseUrl}/user-menus`, params: { format: 'art' } });
|
||||
},
|
||||
|
||||
getCaptcha() {
|
||||
return request.get({ url: `/login/captcha` });
|
||||
},
|
||||
|
||||
//刷新token
|
||||
refreshAccessToken(refreshToken: string) {
|
||||
return refreshAccessTokenByRefreshToken(refreshToken);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default AuthService;
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './auth';
|
||||
// export type * from './rbac-model';
|
||||
@@ -0,0 +1,4 @@
|
||||
import * as deptApi from '../org/dept/dept'
|
||||
import * as userApi from './user/user'
|
||||
|
||||
export { deptApi, userApi }
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './menu';
|
||||
export type * from './types'
|
||||
@@ -0,0 +1,32 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import type { MenuRow } from './types';
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/system/menu';
|
||||
|
||||
export const BadgeVariants = [
|
||||
'default',
|
||||
'destructive',
|
||||
'primary',
|
||||
'success',
|
||||
'warning',
|
||||
] as const;
|
||||
|
||||
export const BadgeTypes = [
|
||||
'dot',
|
||||
'normal',
|
||||
] as const;
|
||||
|
||||
export const MenuTypes = [
|
||||
1, 2, 3, 4, 5, 6,
|
||||
] as const;
|
||||
|
||||
export const MenuService = {
|
||||
...BaseService<MenuRow>({ baseUrl }),
|
||||
|
||||
batchStore(data: Record<string, any>) {
|
||||
return request.post({ url: `${baseUrl}/batch-store`, data });
|
||||
},
|
||||
};
|
||||
|
||||
export default MenuService;
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 菜单项基础接口
|
||||
*/
|
||||
export interface MenuItemBase {
|
||||
/** 菜单项唯一标识 */
|
||||
id: string;
|
||||
/** 父级菜单ID */
|
||||
pid: number;
|
||||
/** 所属应用标识 */
|
||||
app?: string | null;
|
||||
/** 菜单显示标题 */
|
||||
title: string;
|
||||
/** 菜单编码(唯一) */
|
||||
code: string;
|
||||
/** 菜单层级(未使用) */
|
||||
level?: null;
|
||||
/** 菜单类型:1-目录 2-页面 */
|
||||
type: 1 | 2 | 3 | 4 | 5 | 6;
|
||||
/** 排序值 */
|
||||
sort: number;
|
||||
/** 路由路径 */
|
||||
path?: string;
|
||||
/** 组件路径 */
|
||||
component?: string;
|
||||
/** 重定向路径 */
|
||||
redirect?: null;
|
||||
/** 菜单图标 */
|
||||
icon?: string;
|
||||
/** 是否显示 */
|
||||
is_show: 0 | 1;
|
||||
/** 是否为外链 */
|
||||
is_link?: 0 | 1;
|
||||
/** 外链地址 */
|
||||
link_url?: null;
|
||||
/** 是否启用 */
|
||||
enabled: 0 | 1;
|
||||
/** 打开方式 */
|
||||
open_type?: 0;
|
||||
/** 是否缓存 */
|
||||
is_cache?: 0 | 1;
|
||||
/** 是否同步 */
|
||||
is_sync?: 0 | 1;
|
||||
/** 是否固定 */
|
||||
is_affix?: 0 | 1;
|
||||
/** 动态参数 */
|
||||
variable?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间字段扩展接口
|
||||
*/
|
||||
export interface TimeFields {
|
||||
/** 创建时间 */
|
||||
created_at?: string;
|
||||
/** 创建人 */
|
||||
created_by?: null;
|
||||
/** 更新时间 */
|
||||
updated_at?: string;
|
||||
/** 更新人 */
|
||||
updated_by?: null;
|
||||
/** 删除时间 */
|
||||
deleted_at?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整菜单项接口
|
||||
*/
|
||||
export interface MenuRow extends MenuItemBase, TimeFields {
|
||||
/** HTTP方法 */
|
||||
methods: string;
|
||||
/** 创建时间(格式化) */
|
||||
created_date: string;
|
||||
/** 更新时间(格式化) */
|
||||
updated_date: string;
|
||||
/** 子菜单项 */
|
||||
children?: MenuRow[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 根菜单项接口(可选子菜单)
|
||||
*/
|
||||
export interface RootMenuItem extends Omit<MenuItem, 'children'> {
|
||||
children?: MenuItem[];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import request from '@/utils/http';
|
||||
import type { UpdateAvatarParam, UpdatePasswordParam, UpdateUserInfoParam, UserSession } from './types';
|
||||
|
||||
/**
|
||||
* 个人中心 API 服务
|
||||
* 符合 RESTful API 规范
|
||||
*/
|
||||
const BASE_URL = '/profile';
|
||||
|
||||
export const ProfileService = {
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
* @returns {Promise<any>} 用户信息
|
||||
*/
|
||||
getProfile() {
|
||||
return request.get({ url: BASE_URL });
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新个人信息
|
||||
* @param {UpdateUserInfoParam} data - 个人信息数据
|
||||
* @returns {Promise<any>} 更新结果
|
||||
*/
|
||||
updateProfile(data: UpdateUserInfoParam) {
|
||||
return request.put({ url: BASE_URL, data });
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新头像
|
||||
* @param {UpdateAvatarParam} data - 头像数据
|
||||
* @returns {Promise<any>} 更新结果
|
||||
*/
|
||||
updateAvatar(data: UpdateAvatarParam) {
|
||||
return request.put({ url: `${BASE_URL}/avatar`, data });
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param {UpdatePasswordParam} data - 密码数据
|
||||
* @returns {Promise<any>} 更新结果
|
||||
*/
|
||||
updatePassword(data: UpdatePasswordParam) {
|
||||
return request.put({ url: `${BASE_URL}/password`, data });
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取在线设备列表
|
||||
* @param {Record<string, any>} params - 查询参数
|
||||
* @returns {Promise<UserSession>} 在线设备列表
|
||||
*/
|
||||
getOnlineDevices(params?: Record<string, any>): Promise<UserSession> {
|
||||
return request.get({ url: `${BASE_URL}/sessions`, params });
|
||||
},
|
||||
|
||||
/**
|
||||
* 强制下线指定设备
|
||||
* @param {string | number} id - 会话ID
|
||||
* @param {Record<string, any>} data - 额外数据
|
||||
* @returns {Promise<any>} 操作结果
|
||||
*/
|
||||
kickoutSession(id: string | number, data?: Record<string, any>): Promise<any> {
|
||||
return request.del({ url: `${BASE_URL}/sessions/${id}`, data });
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新用户偏好设置
|
||||
* @param {Record<string, any>} preferences - 偏好设置
|
||||
* @returns {Promise<any>} 更新结果
|
||||
*/
|
||||
updatePreferences(preferences: Record<string, any>) {
|
||||
return request.put({ url: `${BASE_URL}/update-preferences`, data: { preferences } });
|
||||
},
|
||||
};
|
||||
|
||||
export default ProfileService;
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* 更新密码请求参数
|
||||
*/
|
||||
export interface UpdatePasswordParam {
|
||||
/** 当前密码 */
|
||||
old_password: string;
|
||||
/** 新密码 */
|
||||
new_password: string;
|
||||
/** 确认新密码 */
|
||||
confirm_password: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新个人信息请求参数
|
||||
*/
|
||||
export interface UpdateUserInfoParam {
|
||||
/** 真实姓名 */
|
||||
real_name: string;
|
||||
/** 昵称 */
|
||||
nick_name: string;
|
||||
/** 邮箱 */
|
||||
email: string;
|
||||
/** 手机号 */
|
||||
mobile_phone: string;
|
||||
/** 性别:0=未知,1=男,2=女 */
|
||||
sex: number;
|
||||
/** 个人签名 */
|
||||
signed?: string;
|
||||
/** 地址 */
|
||||
address?: string;
|
||||
/** 头像 */
|
||||
avatar?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新头像请求参数
|
||||
*/
|
||||
export interface UpdateAvatarParam {
|
||||
/** 头像URL */
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户会话信息
|
||||
*/
|
||||
export interface UserSession {
|
||||
id: string;
|
||||
user_name: string;
|
||||
ip: string;
|
||||
ip_location: string;
|
||||
os: string;
|
||||
browser: string;
|
||||
status: number;
|
||||
message: string;
|
||||
login_time: number;
|
||||
key: string;
|
||||
created_at: string;
|
||||
expires_at: string;
|
||||
updated_at: string | null;
|
||||
deleted_at: number | null;
|
||||
remark: string | null;
|
||||
created_date: string;
|
||||
updated_date: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './role';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,20 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { RoleRow } from './types'
|
||||
import type { DeptTree } from '../../org/dept/dept-model'
|
||||
|
||||
const baseUrl = '/system/role'
|
||||
|
||||
export const RoleService = {
|
||||
...BaseService<RoleRow>({ baseUrl }),
|
||||
|
||||
dataScope(id: number | string, data: Record<string, any>): Promise<RoleRow> {
|
||||
return request.put({ url: `${baseUrl}/${id}/data-scope`, data })
|
||||
},
|
||||
|
||||
getScopeDeptTree(): Promise<DeptTree[]> {
|
||||
return request.get({ url: `${baseUrl}/scope/dept` })
|
||||
}
|
||||
}
|
||||
|
||||
export default RoleService
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
export interface RoleRow {
|
||||
[key: string]: any;
|
||||
id: string;
|
||||
pid?: string;
|
||||
name: string
|
||||
code: string;
|
||||
is_super_admin: 0 | 1;
|
||||
role_type: number;
|
||||
data_scope: DataScopeEnum;
|
||||
enabled: 0 | 1;
|
||||
sort: number;
|
||||
permissions?: string[];
|
||||
remark?: string | null;
|
||||
created_by: number;
|
||||
updated_by: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
deleted_at?: string | null;
|
||||
created_date: string;
|
||||
updated_date: string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据权限范围枚举
|
||||
*/
|
||||
export enum DataScopeEnum {
|
||||
ALL = 1, // 全部数据权限
|
||||
CUSTOM = 2, // 自定义权限
|
||||
DEPT = 3, // 本部门
|
||||
DEPT_WITH_CHILD = 4, // 本部门及下级
|
||||
SELF = 5 // 仅本人
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './rule';
|
||||
export type * from './types'
|
||||
@@ -0,0 +1,39 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import type { RouteRow } from './types';
|
||||
|
||||
const baseUrl = '/system/rule';
|
||||
|
||||
export const RuleService = {
|
||||
...BaseService<RouteRow>({ baseUrl }),
|
||||
|
||||
/**
|
||||
* 列表(扫描模式)
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
list(params?: Record<string, any>): Promise<RouteRow[]> {
|
||||
return request.get<RouteRow[]>({ url: `system/rule`, params });
|
||||
},
|
||||
|
||||
/**
|
||||
* 类型(扫描模式,基于tags)
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
cate(params?: Record<string, any>): Promise<any[]> {
|
||||
return request.get({ url: `system/rule-cate`, params });
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 刷新扫描缓存
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
sync(data?: any): Promise<void> {
|
||||
return request.post({ url: `system/rule/refresh`, data });
|
||||
}
|
||||
};
|
||||
|
||||
export default RuleService;
|
||||
@@ -0,0 +1,13 @@
|
||||
export type HttpMethod = "get" | "post" | "put" | "delete" | "patch";
|
||||
|
||||
/**
|
||||
* 路由列表
|
||||
*/
|
||||
export interface RouteRow {
|
||||
name: string;
|
||||
method: Uppercase<HttpMethod>;
|
||||
path: string;
|
||||
title?: string;
|
||||
type?: number;
|
||||
code?: string;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './user';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,39 @@
|
||||
import { TenantRow } from '#/api/platform/tenant'
|
||||
import { Dept } from '../../org/dept'
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*/
|
||||
export interface User extends Api.Auth.UserInfo {
|
||||
id: string
|
||||
user_name: string
|
||||
real_name: string
|
||||
nick_name: string
|
||||
is_super?: number
|
||||
mobile_phone: string
|
||||
email: string
|
||||
avatar: string
|
||||
signed: string
|
||||
dashboard: string
|
||||
dept_id: string
|
||||
enabled: number
|
||||
login_ip: string
|
||||
login_time: string
|
||||
backend_setting: string
|
||||
created_by: string
|
||||
updated_by: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string
|
||||
sex: string
|
||||
remark: string
|
||||
birthday: string
|
||||
tel: string
|
||||
is_locked?: string
|
||||
depts?: Dept
|
||||
posts?: Post[]
|
||||
roles?: Role[]
|
||||
tenant?: any
|
||||
login_date?: string
|
||||
address?: string
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import type { User } from './types';
|
||||
|
||||
/**
|
||||
* 公共接口
|
||||
*/
|
||||
const baseUrl = '/system/admin';
|
||||
|
||||
export const UserService = {
|
||||
...BaseService<User>({
|
||||
baseUrl,
|
||||
forbiddenMethods: ['export'],
|
||||
}),
|
||||
|
||||
resetPassword(data: Record<string, any>): Promise<User[]> {
|
||||
return request.put({ url: `${baseUrl}/reset-password`, data });
|
||||
},
|
||||
|
||||
playUser(data: Record<string, any>) {
|
||||
return request.put({ url: `${baseUrl}/play-user`, data });
|
||||
},
|
||||
|
||||
unPlayUser(data: any) {
|
||||
return request.put({ url: `${baseUrl}/unplay-user`, data });
|
||||
},
|
||||
|
||||
grantRole(data: any) {
|
||||
return request.post({ url: `${baseUrl}/grant-role`, data });
|
||||
},
|
||||
|
||||
locked(data: any) {
|
||||
return request.put({ url: `${baseUrl}/locked`, data });
|
||||
},
|
||||
|
||||
unLocked(data: any) {
|
||||
return request.put({ url: `${baseUrl}/un-locked`, data });
|
||||
},
|
||||
|
||||
preferences(data: any) {
|
||||
return request.put({ url: `${baseUrl}/preferences`, data });
|
||||
},
|
||||
|
||||
getUserInfo() {
|
||||
return request.get<Api.Auth.UserInfo>({ url: `/system/auth/user-info` });
|
||||
},
|
||||
|
||||
getPermCode() {
|
||||
return request.get<string[]>({ url: `/system/auth/perm-code` });
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default UserService;
|
||||
@@ -0,0 +1,18 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import request from '@/utils/http'
|
||||
import type { ApplicationAuthRow, ResetSecretResponse } from './types'
|
||||
|
||||
const baseUrl = '/plugin/application-auth'
|
||||
|
||||
export const ApplicationAuthService = {
|
||||
...BaseService<ApplicationAuthRow>({ baseUrl }),
|
||||
|
||||
resetSecret(id: string | number) {
|
||||
return request.post<ResetSecretResponse>({
|
||||
url: `${baseUrl}/${id}/reset-secret`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export type * from './types'
|
||||
export default ApplicationAuthService
|
||||
@@ -0,0 +1,17 @@
|
||||
export interface ApplicationAuthRow {
|
||||
id: string
|
||||
name: string
|
||||
access_key: string
|
||||
secret_key: string
|
||||
expired_at?: number | null
|
||||
enabled: number
|
||||
description?: string | null
|
||||
created_at?: number | null
|
||||
created_date?: string | null
|
||||
updated_date?: string | null
|
||||
}
|
||||
|
||||
export interface ResetSecretResponse {
|
||||
id: string
|
||||
secret_key: string
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import type { PluginDevelopRow } from './types';
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/plugin/develop';
|
||||
|
||||
export const PluginDevelopService = {
|
||||
...BaseService<PluginDevelopRow>({ baseUrl }),
|
||||
|
||||
/**
|
||||
* 打包插件
|
||||
* @param pluginKey 插件标识
|
||||
*/
|
||||
build(pluginKey: string) {
|
||||
return request.post({
|
||||
url: `${baseUrl}/build`,
|
||||
data: { plugin_key: pluginKey },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新插件
|
||||
* @param id 插件ID
|
||||
* @param data 更新数据
|
||||
*/
|
||||
update(id: number, data: Partial<PluginDevelopRow>) {
|
||||
return request.put({
|
||||
url: `${baseUrl}/${id}`,
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认保存图片到插件目录
|
||||
* @param id 插件ID
|
||||
* @param icon 图标base64
|
||||
* @param cover 封面base64
|
||||
*/
|
||||
confirmImages(id: number, icon?: string, cover?: string) {
|
||||
return request.post({
|
||||
url: `${baseUrl}/confirm-images/${id}`,
|
||||
data: { icon, cover },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default PluginDevelopService;
|
||||
@@ -0,0 +1,32 @@
|
||||
export interface PluginDevelopRow {
|
||||
/** 作者 */
|
||||
author: string;
|
||||
/** 版本号 */
|
||||
version: string;
|
||||
/** 封面 */
|
||||
cover: string;
|
||||
/** 更新时间 */
|
||||
updated_at: number;
|
||||
/** 主键 */
|
||||
id: number;
|
||||
/** 插件标识 */
|
||||
key: string;
|
||||
/** 插件描述 */
|
||||
desc: string;
|
||||
/** 插件支持的应用空表示通用插件 */
|
||||
support_app: string;
|
||||
/** 安装时间 */
|
||||
installed_at: number;
|
||||
/** 插件名称 */
|
||||
title: string;
|
||||
/** 插件图标 */
|
||||
icon: string;
|
||||
/** 状态 */
|
||||
status: number;
|
||||
/** 插件类型app,plugin */
|
||||
type: string;
|
||||
/** 创建时间 */
|
||||
created_at: number;
|
||||
variables: string;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import request from '@/utils/http'
|
||||
import BaseService from '../../../core/base'
|
||||
|
||||
|
||||
const baseUrl = '/generator/code'
|
||||
|
||||
// 代码生成服务
|
||||
export const GeneratorCodeService = {
|
||||
...BaseService<any>({ baseUrl }),
|
||||
getTableList: (params?: any) => {
|
||||
return request.get({
|
||||
url: `${baseUrl}/table-list`,
|
||||
params,
|
||||
})
|
||||
},
|
||||
getPluginDevList: () => {
|
||||
return request.get({
|
||||
url: `/plugin/select`
|
||||
})
|
||||
},
|
||||
getPreview: (id: number | string) => {
|
||||
return request.get({
|
||||
url: `${baseUrl}/${id}/preview`,
|
||||
})
|
||||
},
|
||||
download: (id: string | number, params?: any) => {
|
||||
return request.get({
|
||||
url: `${baseUrl}/${id}/download`,
|
||||
responseType: 'blob',
|
||||
timeout: 20 * 1000,
|
||||
params,
|
||||
})
|
||||
},
|
||||
|
||||
deploy: (id: number | string, params?: any) => {
|
||||
return request.put({
|
||||
url: `${baseUrl}/${id}/deploy`,
|
||||
params,
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// 基础设置类型
|
||||
export interface BasicConfig {
|
||||
tableName: string
|
||||
tableComment: string
|
||||
plugin: string
|
||||
moduleName: string
|
||||
className: string
|
||||
packageName: string
|
||||
author: string
|
||||
remark: string
|
||||
}
|
||||
|
||||
// 字段配置类型
|
||||
export interface FieldConfig {
|
||||
columnName: string
|
||||
columnComment: string
|
||||
dataType: string
|
||||
columnLength: number
|
||||
isPrimaryKey: boolean
|
||||
isRequired: boolean
|
||||
defaultValue?: string
|
||||
javaType?: string
|
||||
htmlType?: string
|
||||
}
|
||||
|
||||
// 生成配置类型
|
||||
export interface GenerateConfig {
|
||||
deleteType: 'logical' | 'physical'
|
||||
editMode: 'dialog' | 'page'
|
||||
sortField: string
|
||||
sortOrder: 'asc' | 'desc'
|
||||
parentMenu: string[]
|
||||
generateFiles: string[]
|
||||
}
|
||||
|
||||
// 关联配置类型
|
||||
export interface RelationConfig {
|
||||
relationTable: string
|
||||
relationType: 'oneToOne' | 'oneToMany' | 'manyToMany'
|
||||
relationField: string
|
||||
targetField: string
|
||||
}
|
||||
|
||||
// 完整的代码生成配置
|
||||
export interface CodeGenerateData {
|
||||
basic: BasicConfig
|
||||
fields: FieldConfig[]
|
||||
config: GenerateConfig
|
||||
relations: RelationConfig[]
|
||||
}
|
||||
|
||||
// API响应类型
|
||||
export interface GenerateResult {
|
||||
success: boolean
|
||||
message: string
|
||||
data?: {
|
||||
filePaths: string[]
|
||||
downloadUrl?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface TableInfo {
|
||||
tableName: string
|
||||
tableComment: string
|
||||
createTime: string
|
||||
updateTime: string
|
||||
}
|
||||
|
||||
export interface ColumnInfo {
|
||||
columnName: string
|
||||
dataType: string
|
||||
columnComment: string
|
||||
columnKey: string
|
||||
isNullable: string
|
||||
columnDefault: string
|
||||
extra: string
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import BaseService from "@/api/core/base";
|
||||
import type {
|
||||
ModuleRow,
|
||||
ModuleSearchParams,
|
||||
ModuleDetailResponse,
|
||||
ModuleInstallParams,
|
||||
ModuleUninstallParams,
|
||||
ModuleDownloadParams,
|
||||
ModuleOperationResponse,
|
||||
ModuleStatistics,
|
||||
ModuleUpgradeRecord,
|
||||
ModuleListResponse,
|
||||
} from "./types";
|
||||
import request from "@/utils/http";
|
||||
|
||||
|
||||
const baseUrl = "/plugin";
|
||||
|
||||
/**
|
||||
* 功能模块API服务
|
||||
*/
|
||||
export const AppsService = {
|
||||
/**
|
||||
* 获取功能模块列表(分页)
|
||||
* GET /tools/modules
|
||||
*/
|
||||
getModuleList(params: ModuleSearchParams): Promise<ModuleListResponse> {
|
||||
return request.get<ModuleListResponse>({
|
||||
url: baseUrl,
|
||||
params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取功能模块详情
|
||||
* GET /tools/modules/detail/{name}
|
||||
*/
|
||||
getModuleDetail(name: string | number): Promise<ModuleDetailResponse> {
|
||||
return request.get<ModuleDetailResponse>({
|
||||
url: `${baseUrl}/detail/${name}`,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 安装功能模块
|
||||
* POST /tools/modules/install
|
||||
*/
|
||||
install(data: ModuleInstallParams): Promise<ModuleOperationResponse> {
|
||||
return request.post<ModuleOperationResponse>({
|
||||
url: `${baseUrl}/install`,
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 卸载功能模块
|
||||
* POST /tools/modules/uninstall
|
||||
*/
|
||||
uninstall(data: ModuleUninstallParams): Promise<ModuleOperationResponse> {
|
||||
return request.post<ModuleOperationResponse>({
|
||||
url: `${baseUrl}/uninstall`,
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载功能模块
|
||||
* POST /tools/modules/{id}/download
|
||||
*/
|
||||
download(data: ModuleDownloadParams): Promise<ModuleOperationResponse> {
|
||||
return request.post<ModuleOperationResponse>({
|
||||
url: `${baseUrl}/download`,
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取功能模块更新记录
|
||||
*/
|
||||
getModuleUpgradeLogs(name: string | number): Promise<ModuleUpgradeRecord> {
|
||||
console.log("getModuleUpgradeLogs", name);
|
||||
return request.get<ModuleUpgradeRecord>({
|
||||
url: `${baseUrl}/${name}/upgrade-logs`,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除功能模块
|
||||
* POST /tools/modules/delete
|
||||
*/
|
||||
delete(name: String): Promise<ModuleOperationResponse> {
|
||||
return request.del<ModuleOperationResponse>({
|
||||
url: `${baseUrl}/${name}`,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 检查功能模块环境
|
||||
*/
|
||||
checkEnvironment(params: any): Promise<ModuleOperationResponse> {
|
||||
return request.get<any>({
|
||||
url: `${baseUrl}/check-environment`,
|
||||
params,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default AppsService;
|
||||
@@ -0,0 +1,303 @@
|
||||
/**
|
||||
* 功能模块基本信息接口
|
||||
*/
|
||||
export interface ModuleRow {
|
||||
/** 模块ID */
|
||||
id: string | number;
|
||||
/** 模块名称 */
|
||||
name: string;
|
||||
/** 模块描述 */
|
||||
description: string;
|
||||
/** 详细描述 */
|
||||
detail_description: string;
|
||||
/** 模块分类 */
|
||||
category: string;
|
||||
/** 当前版本 */
|
||||
version: string;
|
||||
/** 更新时间 */
|
||||
update_time: string;
|
||||
/** 是否已购买 */
|
||||
purchased: boolean;
|
||||
/** 是否已安装 */
|
||||
installed: boolean;
|
||||
/** 是否为新模块 */
|
||||
is_new: boolean;
|
||||
/** 是否为热门模块 */
|
||||
is_hot: boolean;
|
||||
/** 模块海报图片 */
|
||||
poster: string;
|
||||
/** 作者信息 */
|
||||
author?: string;
|
||||
/** 模块价格 */
|
||||
price?: number;
|
||||
/** 评分 */
|
||||
rating?: number;
|
||||
/** 下载次数 */
|
||||
download_count?: number;
|
||||
/** 创建时间 */
|
||||
created_at?: string;
|
||||
/** 更新时间 */
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块更新日志接口
|
||||
*/
|
||||
export interface ModuleUpdateLog {
|
||||
/** 版本号 */
|
||||
version: string;
|
||||
/** 发布日期 */
|
||||
date: string;
|
||||
/** 更新内容 */
|
||||
content: string;
|
||||
/** 是否为重要更新 */
|
||||
is_important?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块版本信息接口
|
||||
*/
|
||||
export interface ModuleVersion {
|
||||
/** 版本号 */
|
||||
version_no: string;
|
||||
/** 发布时间 */
|
||||
release_time: string;
|
||||
/** 更新日志 */
|
||||
upgrade_log: string;
|
||||
/** 是否为重要更新 */
|
||||
is_important: boolean;
|
||||
/** 版本大小 */
|
||||
size?: string;
|
||||
/** 兼容性说明 */
|
||||
compatibility?: string;
|
||||
/** 下载地址 */
|
||||
download_url?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块更新记录接口
|
||||
*/
|
||||
export interface ModuleUpgradeRecord {
|
||||
/** 模块ID */
|
||||
module_id: string | number;
|
||||
/** 模块编码 */
|
||||
module_code: string;
|
||||
/** 模块名称 */
|
||||
module_name: string;
|
||||
/** 版本列表 */
|
||||
version_list: ModuleVersion[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块分类接口
|
||||
*/
|
||||
export interface ModuleCategory {
|
||||
/** 分类键值 */
|
||||
key: string;
|
||||
/** 分类标签 */
|
||||
label: string;
|
||||
/** 分类图标 */
|
||||
icon?: string;
|
||||
/** 模块数量 */
|
||||
count?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块搜索参数接口
|
||||
*/
|
||||
export interface ModuleSearchParams {
|
||||
/** 搜索关键词 */
|
||||
keyword?: string;
|
||||
/** 分类筛选 */
|
||||
category?: string;
|
||||
/** 安装状态筛选 */
|
||||
installed?: boolean;
|
||||
/** 购买状态筛选 */
|
||||
purchased?: boolean;
|
||||
/** 是否为新模块 */
|
||||
is_new?: boolean;
|
||||
/** 是否为热门模块 */
|
||||
is_hot?: boolean;
|
||||
/** 排序字段 */
|
||||
sort_by?: 'name' | 'update_time' | 'rating' | 'download_count';
|
||||
/** 排序方向 */
|
||||
sort_order?: 'asc' | 'desc';
|
||||
/** 当前页码 */
|
||||
current?: number;
|
||||
/** 每页条数 */
|
||||
size?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块安装参数接口
|
||||
*/
|
||||
export interface ModuleInstallParams {
|
||||
/** 模块ID */
|
||||
features_id: string | number;
|
||||
/** 安装配置 */
|
||||
config?: Record<string, any>;
|
||||
/** 是否覆盖安装 */
|
||||
overwrite?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块卸载参数接口
|
||||
*/
|
||||
export interface ModuleUninstallParams {
|
||||
/** 模块ID */
|
||||
name: string | number;
|
||||
/** 是否保留数据 */
|
||||
keep_data?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块下载参数接口
|
||||
*/
|
||||
export interface ModuleDownloadParams {
|
||||
/** 模块ID */
|
||||
name: string | number;
|
||||
/** 版本号 */
|
||||
version?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块操作响应接口
|
||||
*/
|
||||
export interface ModuleOperationResponse {
|
||||
/** 操作是否成功 */
|
||||
success: boolean;
|
||||
/** 操作消息 */
|
||||
message: string;
|
||||
/** 操作数据 */
|
||||
data?: any;
|
||||
/** 操作时间 */
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页响应接口
|
||||
*/
|
||||
export interface PaginatedResponse<T> {
|
||||
/** 数据列表 */
|
||||
items: T[];
|
||||
/** 当前页码 */
|
||||
current: number;
|
||||
/** 每页条数 */
|
||||
size: number;
|
||||
/** 总条数 */
|
||||
total: number;
|
||||
/** 总页数 */
|
||||
pages?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块列表响应接口
|
||||
*/
|
||||
export type ModuleListResponse = PaginatedResponse<ModuleRow>;
|
||||
|
||||
/**
|
||||
* 功能模块详情响应接口
|
||||
*/
|
||||
export interface ModuleDetailResponse extends ModuleRow {
|
||||
/** 更新日志列表 */
|
||||
update_logs: ModuleUpdateLog[];
|
||||
/** 依赖模块 */
|
||||
dependencies?: string[];
|
||||
/** 系统要求 */
|
||||
system_requirements?: string;
|
||||
/** 文档链接 */
|
||||
documentation_url?: string;
|
||||
/** 支持信息 */
|
||||
support_info?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能模块统计信息接口
|
||||
*/
|
||||
export interface ModuleStatistics {
|
||||
/** 总模块数 */
|
||||
total_module: number;
|
||||
/** 已安装模块数 */
|
||||
installed_module: number;
|
||||
/** 可更新模块数 */
|
||||
updatable_module: number;
|
||||
/** 热门模块数 */
|
||||
hot_module: number;
|
||||
/** 新模块数 */
|
||||
new_module: number;
|
||||
/** 按分类统计 */
|
||||
category_stats: Array<{
|
||||
category: string;
|
||||
count: number;
|
||||
installed_count: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
// 分类接口
|
||||
export interface Category {
|
||||
id?: string;
|
||||
name: string;
|
||||
code?: string;
|
||||
}
|
||||
|
||||
// 更新日志接口
|
||||
export interface UpdateLog {
|
||||
version: string;
|
||||
date: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
// 模块接口
|
||||
export interface Module {
|
||||
id: string | number;
|
||||
code: string;
|
||||
name: string;
|
||||
type: string;
|
||||
version: string;
|
||||
status: number;
|
||||
description: string;
|
||||
detail_description: string;
|
||||
author: string;
|
||||
cover: string;
|
||||
poster: string;
|
||||
price: number | string;
|
||||
downloads: number;
|
||||
rating: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
update_time: string;
|
||||
update_logs: UpdateLog[];
|
||||
category: Category | null;
|
||||
category_name: string;
|
||||
tags: Array<{ id: string | number; name: string }>;
|
||||
is_new: number;
|
||||
is_hot: number;
|
||||
purchased: number;
|
||||
installed: number;
|
||||
manual_uninstall: number;
|
||||
composer_dependencies: any[];
|
||||
npm_dependencies: any[];
|
||||
is_installed: number;
|
||||
installed_version: string | null;
|
||||
has_update: number;
|
||||
is_purchased: number;
|
||||
is_downloaded: number;
|
||||
can_uninstall: number;
|
||||
can_download: number;
|
||||
undeletable: number; // 是否不可删除(1: 不可删除/系统内置, 0: 可删除)
|
||||
version_info: {
|
||||
remote: {
|
||||
version: string | null;
|
||||
release_date: string | null;
|
||||
};
|
||||
local: {
|
||||
version: string | null;
|
||||
install_date: string | null;
|
||||
};
|
||||
comparison: {
|
||||
needs_update: number;
|
||||
is_latest: number;
|
||||
version_difference: string | null;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import BaseService from '@/api/core/base'
|
||||
import type { CrontabLogRow, CrontabRow } from './types'
|
||||
import request from '@/utils/http'
|
||||
|
||||
const baseUrl = '/crontab/task'
|
||||
|
||||
/**
|
||||
* 定时任务
|
||||
*/
|
||||
export const CrontabService = {
|
||||
...BaseService<CrontabRow>({ baseUrl }),
|
||||
|
||||
/**
|
||||
* 启动
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
start(id: string | number, params?: Record<string, any>) {
|
||||
return request.put({
|
||||
url: `${baseUrl}/${id}/resume`,
|
||||
params
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 恢复
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
resume(id: string | number, params?: Record<string, any>) {
|
||||
return request.put({ url: `${baseUrl}/${id}/resume`, params })
|
||||
},
|
||||
|
||||
/**
|
||||
* 暂停
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
pause(id: string | number, params?: Record<string, any>) {
|
||||
return request.put({ url: `${baseUrl}/${id}/pause`, params })
|
||||
},
|
||||
|
||||
/**
|
||||
* 立即执行
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
execute(id: string | number, params?: Record<string, any>) {
|
||||
return request.put({ url: `${baseUrl}/${id}/execute`, params })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务日志
|
||||
*/
|
||||
export const CrontabLogService = {
|
||||
...BaseService<CrontabLogRow>({ baseUrl: '/crontab/log' })
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './crontab';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 定时任务接口
|
||||
*/
|
||||
export interface CrontabRow {
|
||||
id: string;
|
||||
biz_id: string;
|
||||
title: string;
|
||||
type: number;
|
||||
task_cycle: number;
|
||||
cycle_rule: string;
|
||||
rule: string;
|
||||
target: string;
|
||||
running_times: string | number;
|
||||
last_running_time: string | number;
|
||||
enabled: number;
|
||||
}
|
||||
|
||||
|
||||
export interface CrontabLogRow {
|
||||
id: string;
|
||||
crontab_id: string;
|
||||
target: string;
|
||||
log: string;
|
||||
return_code: string;
|
||||
running_time: string;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import request from '@/utils/http'
|
||||
import { AuthInfo } from './types'
|
||||
|
||||
const baseUrl = '/madong'
|
||||
|
||||
/** 授权模块服务 */
|
||||
export const ToolsAuthService = {
|
||||
// 获取授权信息
|
||||
getAuthInfo: (params?: any) => {
|
||||
return request.get<AuthInfo>({
|
||||
url: `${baseUrl}/auth-info`,
|
||||
params
|
||||
})
|
||||
},
|
||||
|
||||
// 设置授权信息
|
||||
setAuthInfo: (params: any) => {
|
||||
return request.post<AuthInfo>({
|
||||
url: `${baseUrl}/auth-info`,
|
||||
params
|
||||
})
|
||||
},
|
||||
// 获取框架版本
|
||||
getFrameworkVersion: (params?: any) => {
|
||||
return request.get<any[]>({
|
||||
url: `${baseUrl}/version`,
|
||||
params
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export type * from './types'
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface AuthInfo {
|
||||
company_name: string;
|
||||
domain: string;
|
||||
auth_code: string;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
import BaseService from "@/api/core/base";
|
||||
import request from "@/utils/http";
|
||||
import type { FilesRow } from "./types";
|
||||
|
||||
const baseUrl = "/files";
|
||||
|
||||
export interface SvgIconRecord {
|
||||
icon: string;
|
||||
name: string;
|
||||
filename: string;
|
||||
url: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export const FilesService = {
|
||||
...BaseService<FilesRow>({ baseUrl }),
|
||||
|
||||
uploadFile(data: any) {
|
||||
return request.upload(`${baseUrl}/upload-image`, data);
|
||||
},
|
||||
|
||||
uploadSvgIcon(data: any) {
|
||||
return request.upload(`${baseUrl}/upload-svg-icon`, data);
|
||||
},
|
||||
|
||||
getSvgIcons() {
|
||||
return request.post({
|
||||
url: `${baseUrl}/svg-icons`,
|
||||
}) as Promise<SvgIconRecord[]>;
|
||||
},
|
||||
|
||||
/**
|
||||
* 上传图片返回base64
|
||||
* @param data FormData
|
||||
*/
|
||||
uploadImageBase64(data: any) {
|
||||
return request.upload(`${baseUrl}/upload-image-base64`, data);
|
||||
},
|
||||
|
||||
downloadById(id: string | number) {
|
||||
return request.get({
|
||||
url: `${baseUrl}/download-by-id/${id}`,
|
||||
responseType: "blob",
|
||||
isResponse: true,
|
||||
} as any);
|
||||
},
|
||||
|
||||
/**
|
||||
* 通过文件id集合获取文件信息
|
||||
* @param data
|
||||
*/
|
||||
getFileInfoByIds(params: any) {
|
||||
return request.post({
|
||||
url: "/sys/fileInfo/getFileInfoByIds",
|
||||
params,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 初始化切片
|
||||
* /sys/fileInfo/initiateMultipartUpload
|
||||
*/
|
||||
|
||||
initiateMultipartUpload(params: any) {
|
||||
return request.post({
|
||||
url: "/sys/fileInfo/initiateMultipartUpload",
|
||||
params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 上传切片
|
||||
* /sys/fileInfo/uploadPart
|
||||
*/
|
||||
uploadPart(data: any) {
|
||||
return request.upload("/sys/fileInfo/uploadPart", data);
|
||||
},
|
||||
/**
|
||||
* 已完成分片上传-告知合并
|
||||
* /sys/fileInfo/completeMultipartUpload
|
||||
*/
|
||||
completeMultipartUpload(params: any) {
|
||||
return request.post({
|
||||
url: "/sys/fileInfo/completeMultipartUpload",
|
||||
params,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 取消分片上传
|
||||
* /sys/fileInfo/abortMultipartUpload
|
||||
*/
|
||||
abortMultipartUpload(params: any) {
|
||||
return request.post({
|
||||
url: "/sys/fileInfo/abortMultipartUpload",
|
||||
params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取文件列表
|
||||
* @param params
|
||||
*/
|
||||
getFileList(params: any) {
|
||||
return request.get({
|
||||
url: baseUrl,
|
||||
params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取文件分类列表
|
||||
*/
|
||||
getCategories() {
|
||||
return request.get({
|
||||
url: `${baseUrl}/categories`,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default FilesService;
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './files';
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,26 @@
|
||||
export interface FilesRow {
|
||||
id: string;
|
||||
url: string;
|
||||
size: string;
|
||||
size_info: string;
|
||||
hash: string;
|
||||
filename: string;
|
||||
original_filename: string;
|
||||
base_path: string;
|
||||
path: string;
|
||||
ext: string;
|
||||
content_type: string;
|
||||
platform: string;
|
||||
th_url: string; // 缩略图URL
|
||||
th_filename: string; // 缩略图文件名
|
||||
th_size: string; // 缩略图大小
|
||||
th_size_info: string; // 缩略图大小信息
|
||||
th_content_type: string; // 缩略图内容类型
|
||||
object_id: string;
|
||||
object_type: string;
|
||||
attr: string;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
created_by?: string;
|
||||
updated_by?: string;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./recycle";
|
||||
export type * from "./types";
|
||||
@@ -0,0 +1,15 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import type { RecycleBinRow } from './types';
|
||||
|
||||
const baseUrl = '/system/recycle';
|
||||
|
||||
export const RecycleBinService = {
|
||||
...BaseService<RecycleBinRow>({ baseUrl }),
|
||||
|
||||
restore(data: Record<string, any>) {
|
||||
return request.put({ url: baseUrl, data });
|
||||
},
|
||||
};
|
||||
|
||||
export default RecycleBinService;
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface RecycleBinRow {
|
||||
id?: number | string;
|
||||
data: string;
|
||||
table_name: string;
|
||||
table_prefix: string;
|
||||
enabled: number;
|
||||
ip: string;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/terminal'
|
||||
|
||||
export const TerminalService = {
|
||||
/**
|
||||
* 获取终端配置
|
||||
*/
|
||||
getConfig() {
|
||||
return request.get({ url: `${baseUrl}/config` });
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取命令列表(带分组)
|
||||
*/
|
||||
getCommands() {
|
||||
return request.get({ url: `${baseUrl}/commands` });
|
||||
},
|
||||
|
||||
/**
|
||||
* Web终端请求
|
||||
*/
|
||||
command(commandKey: string, uuid: string, extend: string, eventHandlers: any) {
|
||||
return request.sse({
|
||||
url: baseUrl,
|
||||
params: {
|
||||
command: commandKey,
|
||||
uuid: uuid,
|
||||
extend: extend,
|
||||
server: 'crmd'
|
||||
}
|
||||
}, eventHandlers);
|
||||
},
|
||||
|
||||
/**
|
||||
* 配置更新
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
updateConfig(data: Partial<any>) {
|
||||
return request.post({ url: `${baseUrl}/config`, data });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export type * from './types';
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
export interface TaskItem {
|
||||
// 任务唯一标识
|
||||
uuid: string
|
||||
// 创建时间
|
||||
date: string
|
||||
// 状态
|
||||
status: number
|
||||
// 命令
|
||||
command: string
|
||||
// 命令执行日志
|
||||
message: string[]
|
||||
// 显示命令执行日志
|
||||
showMessage: boolean
|
||||
// 失败阻断后续命令执行
|
||||
blockOnFailure: boolean
|
||||
// 扩展信息,自动发送到后台
|
||||
extend: string
|
||||
// 执行结果回调
|
||||
callback: Function
|
||||
}
|
||||
|
||||
export interface CommandItem {
|
||||
key: string
|
||||
name: string
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface CommandGroup {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
commands: CommandItem[]
|
||||
}
|
||||
|
||||
export interface Terminal {
|
||||
show: boolean
|
||||
showDot: boolean
|
||||
taskList: TaskItem[]
|
||||
packageManager: string
|
||||
showPackageManagerDialog: boolean
|
||||
showConfig: boolean
|
||||
developmentServer: boolean
|
||||
automaticCleanupTask: string
|
||||
npmRegistry: string;
|
||||
composerRegistry: string;
|
||||
commandGroups: CommandGroup[]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { MenuService } from './menu';
|
||||
import { LinkService } from './link';
|
||||
|
||||
export { MenuService, LinkService };
|
||||
@@ -0,0 +1,15 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import type { Link } from './types';
|
||||
|
||||
const baseUrl = '/web/link';
|
||||
|
||||
export const LinkService = {
|
||||
...BaseService<Link>({
|
||||
baseUrl,
|
||||
allowedMethods: [],
|
||||
forbiddenMethods: [],
|
||||
})
|
||||
};
|
||||
|
||||
export default LinkService;
|
||||
@@ -0,0 +1,17 @@
|
||||
export interface Link {
|
||||
id: number;
|
||||
name: string;
|
||||
url: string;
|
||||
logo?: string;
|
||||
sort?: number;
|
||||
status?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface LinkQuery {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
name?: string;
|
||||
status?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
import request from '@/utils/http';
|
||||
import type { Menu } from './types';
|
||||
|
||||
const baseUrl = '/web/menu';
|
||||
|
||||
export const MenuService = {
|
||||
...BaseService<Menu>({
|
||||
baseUrl,
|
||||
allowedMethods: [],
|
||||
forbiddenMethods: [],
|
||||
})
|
||||
};
|
||||
|
||||
export default MenuService;
|
||||
@@ -0,0 +1,33 @@
|
||||
export interface Menu {
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
path?: string;
|
||||
title: string;
|
||||
url?: string;
|
||||
icon?: string;
|
||||
meta: MenuMeta;
|
||||
children?: Menu[];
|
||||
sort?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface MenuMeta {
|
||||
id: number;
|
||||
type: string;
|
||||
menu_type: string;
|
||||
target?: string;
|
||||
hidden?: boolean;
|
||||
disabled?: boolean;
|
||||
badge?: string | number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface MenuQuery {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
name?: string;
|
||||
type?: string;
|
||||
status?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import request from "@/utils/http";
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param params 登录参数
|
||||
* @returns 登录响应
|
||||
*/
|
||||
export function fetchLogin(params: Api.Auth.LoginParams) {
|
||||
return request.post<Api.Auth.LoginResponse>({
|
||||
url: "/api/auth/login",
|
||||
params,
|
||||
// showSuccessMessage: true // 显示成功消息
|
||||
// showErrorMessage: false // 不显示错误消息
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @returns 用户信息
|
||||
*/
|
||||
export function fetchGetUserInfo() {
|
||||
return request.get<Api.Auth.UserInfo>({
|
||||
url: "/api/user/info",
|
||||
// 自定义请求头
|
||||
// headers: {
|
||||
// 'X-Custom-Header': 'your-custom-value'
|
||||
// }
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
export class DictService {
|
||||
// 获取所有字典
|
||||
static getAllDict() {
|
||||
return request.post<any>({
|
||||
url: '/sys/dict/enumDictList',
|
||||
showErrorMessage: false // 不显示错误消息
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import BaseService from '@/api/core/base';
|
||||
|
||||
|
||||
|
||||
import request from '@/utils/http';
|
||||
|
||||
const baseUrl = '/test';
|
||||
|
||||
export const TestService = {
|
||||
...BaseService<any>({ baseUrl }),
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import request from '@/utils/http'
|
||||
import { AppRouteRecord } from '@/types/router'
|
||||
|
||||
// 获取用户列表
|
||||
export function fetchGetUserList(params: Api.SystemManage.UserSearchParams) {
|
||||
return request.get<Api.SystemManage.UserList>({
|
||||
url: '/api/user/list',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取角色列表
|
||||
export function fetchGetRoleList(params: Api.SystemManage.RoleSearchParams) {
|
||||
return request.get<Api.SystemManage.RoleList>({
|
||||
url: '/api/role/list',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取菜单列表
|
||||
export function fetchGetMenuList() {
|
||||
return request.get<AppRouteRecord[]>({
|
||||
url: '/system/auth/user-menus',
|
||||
params: {
|
||||
format: 'art'
|
||||
}
|
||||
})
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user