初始化本地仓库

This commit is contained in:
2026-08-31 11:33:59 +08:00
commit 663f74b633
2390 changed files with 402918 additions and 0 deletions
+34
View File
@@ -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>
+136
View File
@@ -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
+11
View File
@@ -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, // 不显示错误消息
});
}
}
+29
View File
@@ -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';
+6
View File
@@ -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; // 已加载扩展(逗号分隔)
}
+46
View File
@@ -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
}
+105
View File
@@ -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';
+4
View File
@@ -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;
}
+119
View File
@@ -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[]
}
+4
View File
@@ -0,0 +1,4 @@
import { MenuService } from './menu';
import { LinkService } from './link';
export { MenuService, LinkService };
+15
View File
@@ -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;
+17
View File
@@ -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;
}
+15
View File
@@ -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;
+33
View File
@@ -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;
}
+29
View File
@@ -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