修改部分规则模块删除无用前端 新增前端界面
This commit is contained in:
23
modeler/src/utils/datetime.ts
Normal file
23
modeler/src/utils/datetime.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of the kernelstudio package.
|
||||
*
|
||||
* (c) 2014-2025 zlin <admin@kernelstudio.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
* that was distributed with this source code.
|
||||
*/
|
||||
|
||||
|
||||
export const formatDatetime = (date: Date): string => {
|
||||
// 获取年、月、日
|
||||
const year = date.getFullYear();
|
||||
// 月份是0开始的,需要+1,并且补0(保证两位数)
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
// 获取时、分、秒
|
||||
const hours = date.getHours().toString().padStart(2, '0');
|
||||
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||||
const seconds = date.getSeconds().toString().padStart(2, '0');
|
||||
// 拼接成目标格式
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
70
modeler/src/utils/event.ts
Normal file
70
modeler/src/utils/event.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the kernelstudio package.
|
||||
*
|
||||
* (c) 2014-2025 zlin <admin@kernelstudio.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
* that was distributed with this source code.
|
||||
*/
|
||||
|
||||
export class EventError {
|
||||
code: number;
|
||||
status: number;
|
||||
message: string | null;
|
||||
stack: string | null;
|
||||
|
||||
constructor(code = 500, status = 500, message: string | null = null, stack: string | null = null) {
|
||||
this.code = code;
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
|
||||
export class EventListener {
|
||||
|
||||
private readonly _listeners: Record<string, Function[]>;
|
||||
|
||||
constructor(listeners: Record<string, Function[]> = {}) {
|
||||
this._listeners = listeners;
|
||||
}
|
||||
|
||||
all(): Record<string, Function[]> {
|
||||
return {...this._listeners}; // 返回副本,避免外部直接修改
|
||||
}
|
||||
|
||||
has(name: string): boolean {
|
||||
return Array.isArray(this._listeners[name]) && this._listeners[name].length > 0;
|
||||
}
|
||||
|
||||
on(name: string, fn: Function): void {
|
||||
if (!Array.isArray(this._listeners[name])) {
|
||||
this._listeners[name] = [];
|
||||
}
|
||||
this._listeners[name].push(fn);
|
||||
}
|
||||
|
||||
off(name: string): void {
|
||||
delete this._listeners[name];
|
||||
}
|
||||
|
||||
emit(name: string, options?: any): void {
|
||||
const listeners = this._listeners[name];
|
||||
if (Array.isArray(listeners)) {
|
||||
// 复制一份避免在执行中修改数组导致问题
|
||||
[...listeners].forEach(f => f(options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const safePreventDefault = (event: any) => {
|
||||
if (event && typeof event.preventDefault === 'function') {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
export const safeStopPropagation = (event: any) => {
|
||||
if (event && typeof event.stopPropagation === 'function') {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
338
modeler/src/utils/request.ts
Normal file
338
modeler/src/utils/request.ts
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* This file is part of the kernelstudio package.
|
||||
*
|
||||
* (c) 2014-2025 zlin <admin@kernelstudio.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
* that was distributed with this source code.
|
||||
*/
|
||||
|
||||
import axios, { type AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
|
||||
import { message, notification } from 'ant-design-vue';
|
||||
import { getToken } from './token';
|
||||
import type { BasicResponse } from '@/types';
|
||||
|
||||
// 扩展Axios请求配置,添加自定义的showMessage属性
|
||||
export interface CustomAxiosRequestConfig extends AxiosRequestConfig {
|
||||
showMessage?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息提示工具
|
||||
* 根据内容长度自动选择使用message(短内容)或notification(长内容)
|
||||
* @param success - 是否为成功状态
|
||||
* @param content - 消息内容
|
||||
* @param title - 消息标题(仅长内容时显示),默认值为'消息提示'
|
||||
*/
|
||||
export const showMessage = (
|
||||
success: boolean,
|
||||
content: string,
|
||||
title: string = '消息提示',
|
||||
): void => {
|
||||
if (!content) return;
|
||||
|
||||
const type: 'success' | 'error' = success ? 'success' : 'error';
|
||||
|
||||
if (content.length > 40) {
|
||||
notification[type]({
|
||||
message: title,
|
||||
description: content,
|
||||
});
|
||||
} else {
|
||||
message[type](content);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理响应后的消息通知
|
||||
* @param response - Axios响应对象
|
||||
* @returns 原响应对象
|
||||
*/
|
||||
export const handleResponseNotification = <T extends BasicResponse>(
|
||||
response: AxiosResponse<T>,
|
||||
): AxiosResponse<T> => {
|
||||
const { config, data } = response;
|
||||
// 当配置允许显示且有消息时展示
|
||||
if (data.msg && (config as CustomAxiosRequestConfig).showMessage && data.code !== 200) {
|
||||
showMessage(false, data.msg);
|
||||
}
|
||||
|
||||
return response; // 返回完整响应对象而非仅数据
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理请求出错后的逻辑
|
||||
* @param error - Axios错误对象
|
||||
* @returns 拒绝的Promise
|
||||
*/
|
||||
export const errorOnRequest = <T extends BasicResponse>(error: AxiosError<T>): Promise<never> => {
|
||||
const response = error.response;
|
||||
|
||||
if (!response) {
|
||||
showMessage(false, '网络错误');
|
||||
} else {
|
||||
const { status, data } = response;
|
||||
const errorData = data;
|
||||
|
||||
if (status === 500 || (errorData && errorData.code === 500)) {
|
||||
showMessage(false, errorData?.msg || '服务器出现错误.');
|
||||
} else if (status === 403 || (errorData && errorData.code === 403)) {
|
||||
showMessage(false, '无权限访问.');
|
||||
} else if (status === 401 || (errorData && errorData.code === 401)) {
|
||||
showMessage(false, '请认证后访问.');
|
||||
} else if (status === 400 || (errorData && errorData.code === 400)) {
|
||||
showMessage(false, '请求错误.');
|
||||
} else if (errorData && errorData.msg) {
|
||||
const isSuccess = errorData.success ?? false;
|
||||
if (!isSuccess) {
|
||||
showMessage(false, errorData.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
/**
|
||||
* 构建请求头
|
||||
* @param defaults - 默认请求头
|
||||
* @param needToken - 是否需要携带token,默认true
|
||||
* @returns 构建后的请求头
|
||||
*/
|
||||
export const buildRequestHeaders = (
|
||||
defaults: Record<string, string> = {},
|
||||
needToken: boolean = true,
|
||||
): Record<string, string> => {
|
||||
const headers = { ...defaults };
|
||||
const token = getToken();
|
||||
if (token && needToken) {
|
||||
headers['Authorization'] = 'Bearer ' + token;
|
||||
}
|
||||
return headers;
|
||||
};
|
||||
|
||||
/**
|
||||
* HTTP请求客户端类,封装Axios实现各类HTTP请求
|
||||
*/
|
||||
export class HttpRequestClient {
|
||||
private client: AxiosInstance;
|
||||
|
||||
constructor(client: AxiosInstance) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Axios实例
|
||||
* @param config - 自定义请求配置
|
||||
* @param addDefaultInterceptors - 是否添加默认拦截器,默认为true
|
||||
* @returns Axios实例
|
||||
*/
|
||||
static build<T extends BasicResponse = BasicResponse>(
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
addDefaultInterceptors: boolean = true,
|
||||
): AxiosInstance {
|
||||
// 基础请求头
|
||||
const headers = buildRequestHeaders({
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
});
|
||||
|
||||
// 创建Axios实例 - 移除了不支持的crossDomain配置
|
||||
const axiosInstance = axios.create({
|
||||
timeout: 60000,
|
||||
withCredentials: true,
|
||||
responseType: 'json',
|
||||
headers,
|
||||
data: {},
|
||||
...config, // 合并用户配置(用户配置优先级更高)
|
||||
});
|
||||
|
||||
// 添加默认拦截器
|
||||
if (addDefaultInterceptors) {
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response: AxiosResponse<T>) => handleResponseNotification<T>(response),
|
||||
(error: AxiosError<T>) => errorOnRequest<T>(error),
|
||||
);
|
||||
}
|
||||
|
||||
return axiosInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建HttpRequestClient实例
|
||||
* @param config - 自定义请求配置
|
||||
* @param addDefaultInterceptors - 是否添加默认拦截器,默认为true
|
||||
* @returns HttpRequestClient实例
|
||||
*/
|
||||
static create<T extends BasicResponse = BasicResponse>(
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
addDefaultInterceptors: boolean = true,
|
||||
): HttpRequestClient {
|
||||
const axiosInstance = this.build<T>(config, addDefaultInterceptors);
|
||||
return new HttpRequestClient(axiosInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON格式POST请求
|
||||
* @param url - 请求URL
|
||||
* @param data - 请求数据
|
||||
* @param config - 自定义请求配置
|
||||
* @returns 响应数据Promise
|
||||
*/
|
||||
postJson<T extends BasicResponse = BasicResponse>(
|
||||
url: string,
|
||||
data: Record<string, any> = {},
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
): Promise<T> {
|
||||
const requestConfig: CustomAxiosRequestConfig = {
|
||||
url,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: buildRequestHeaders({
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
'Accept': 'application/json',
|
||||
}),
|
||||
transformRequest: [(data) => JSON.stringify(data)],
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.client<T>(requestConfig).then(response => response.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单格式POST请求
|
||||
* @param url - 请求URL
|
||||
* @param data - 请求数据(键值对)
|
||||
* @param config - 自定义请求配置
|
||||
* @returns 响应数据Promise
|
||||
*/
|
||||
post<T extends BasicResponse = BasicResponse>(
|
||||
url: string,
|
||||
data: Record<string, any> = {},
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
): Promise<T> {
|
||||
const requestConfig: CustomAxiosRequestConfig = {
|
||||
url,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: buildRequestHeaders({
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}),
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.client<T>(requestConfig).then(response => response.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
* @param url - 请求URL
|
||||
* @param params - URL参数
|
||||
* @param config - 自定义请求配置
|
||||
* @returns 响应数据Promise
|
||||
*/
|
||||
get<T extends BasicResponse = BasicResponse>(
|
||||
url: string,
|
||||
params: Record<string, any> = {},
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
): Promise<T> {
|
||||
const requestConfig: CustomAxiosRequestConfig = {
|
||||
url,
|
||||
method: 'GET',
|
||||
params,
|
||||
headers: buildRequestHeaders({}),
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.client<T>(requestConfig).then(response => response.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE请求
|
||||
* @param url - 请求URL
|
||||
* @param params - URL参数
|
||||
* @param config - 自定义请求配置
|
||||
* @returns 响应数据Promise
|
||||
*/
|
||||
delete<T extends BasicResponse = BasicResponse>(
|
||||
url: string,
|
||||
params: Record<string, any> = {},
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
): Promise<T> {
|
||||
const requestConfig: CustomAxiosRequestConfig = {
|
||||
url,
|
||||
method: 'DELETE',
|
||||
params,
|
||||
headers: buildRequestHeaders({}),
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.client<T>(requestConfig).then(response => response.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON格式PUT请求
|
||||
* @param url - 请求URL
|
||||
* @param data - 请求数据
|
||||
* @param config - 自定义请求配置
|
||||
* @returns 响应数据Promise
|
||||
*/
|
||||
putJson<T extends BasicResponse = BasicResponse>(
|
||||
url: string,
|
||||
data: Record<string, any> = {},
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
): Promise<T> {
|
||||
const requestConfig: CustomAxiosRequestConfig = {
|
||||
url,
|
||||
method: 'PUT',
|
||||
data,
|
||||
headers: buildRequestHeaders({
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
'Accept': 'application/json',
|
||||
}),
|
||||
transformRequest: [(data) => JSON.stringify(data)],
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.client<T>(requestConfig).then(response => response.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单格式PUT请求
|
||||
* @param url - 请求URL
|
||||
* @param data - 请求数据(键值对)
|
||||
* @param config - 自定义请求配置
|
||||
* @returns 响应数据Promise
|
||||
*/
|
||||
put<T extends BasicResponse = BasicResponse>(
|
||||
url: string,
|
||||
data: Record<string, any> = {},
|
||||
config: CustomAxiosRequestConfig = {},
|
||||
): Promise<T> {
|
||||
const requestConfig: CustomAxiosRequestConfig = {
|
||||
url,
|
||||
method: 'PUT',
|
||||
data,
|
||||
headers: buildRequestHeaders({
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}),
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.client<T>(requestConfig).then(response => response.data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 原始请求(无基础URL,不添加额外前缀)
|
||||
*/
|
||||
export const originalAxios: AxiosInstance = HttpRequestClient.build<BasicResponse>();
|
||||
export const originalRequest: HttpRequestClient = new HttpRequestClient(originalAxios);
|
||||
|
||||
/**
|
||||
* 通用请求(带基础URL)
|
||||
*/
|
||||
export const generalAxios: AxiosInstance = HttpRequestClient.build<BasicResponse>({
|
||||
baseURL: '/api',
|
||||
});
|
||||
export const request: HttpRequestClient = new HttpRequestClient(generalAxios);
|
||||
|
||||
export default request;
|
||||
13
modeler/src/utils/strings.ts
Normal file
13
modeler/src/utils/strings.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* This file is part of the kernelstudio package.
|
||||
*
|
||||
* (c) 2014-2025 zlin <admin@kernelstudio.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
* that was distributed with this source code.
|
||||
*/
|
||||
|
||||
export const generateKey = (type: string | null = ''): string => {
|
||||
return `${type ? (type + '_') : ''}${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`
|
||||
.replace('-', '_').toLowerCase();
|
||||
};
|
||||
25
modeler/src/utils/token.ts
Normal file
25
modeler/src/utils/token.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of the kernelstudio package.
|
||||
*
|
||||
* (c) 2014-2025 zlin <admin@kernelstudio.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
* that was distributed with this source code.
|
||||
*/
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
import type { NullableString } from '@/types';
|
||||
|
||||
const TokenKey = 'Admin-Token';
|
||||
|
||||
export const getToken = (): NullableString => {
|
||||
return Cookies.get(TokenKey) as NullableString;
|
||||
};
|
||||
|
||||
export const setToken = (token: string): void => {
|
||||
Cookies.set(TokenKey, token);
|
||||
};
|
||||
|
||||
export const removeToken = (): void => {
|
||||
Cookies.remove(TokenKey);
|
||||
};
|
||||
Reference in New Issue
Block a user