修改部分规则模块删除无用前端 新增前端界面

This commit is contained in:
zouju
2026-02-06 17:22:22 +08:00
parent 000f8d4bc5
commit a440094138
583 changed files with 26241 additions and 26046 deletions

View 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}`;
};

View 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();
}
}

View 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;

View 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();
};

View 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);
};