Русифицировать README и интерфейс HY2XS admin

This commit is contained in:
2026-04-25 23:51:21 +05:00
parent 84a4e94567
commit 2b4a45ad23
167 changed files with 632 additions and 699 deletions
+26 -24
View File
@@ -1,11 +1,11 @@
/**
* 格式化字节大小
* @param bytes 字节数
* @param decimals 小数位数,默认为 2
* @returns 格式化后的字节大小字符串
* Форматирование размера в байтах
* @param bytes Количество байт
* @param decimals Количество знаков после запятой, по умолчанию 2
* @returns Отформатированная строка размера
*/
export const formatBytes = (bytes: number, decimals = 2): string => {
// 检查是否为特殊值
// Проверка специального значения
if (bytes === -1) {
return "Unlimited";
}
@@ -13,21 +13,21 @@ export const formatBytes = (bytes: number, decimals = 2): string => {
return "0 Bytes";
}
// 计算单位和大小
// Расчёт единицы и размера
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
// 返回格式化后的字符串
// Возврат отформатированной строки
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
};
export const calculateBytes = (value = 0, unit = "Bytes"): number => {
// 将单位转换为大写,并去除空格
// Приведение единицы к верхнему регистру и удаление пробелов
const formattedUnit = unit.toUpperCase().trim();
// 定义存储单位和对应的字节数的映射关系
// Маппинг единиц хранения на количество байт
const unitToBytes: Record<string, number> = {
BYTES: 1,
KB: 1024 ** 1,
@@ -40,7 +40,7 @@ export const calculateBytes = (value = 0, unit = "Bytes"): number => {
YB: 1024 ** 8,
};
// 检查传入的单位是否存在于映射关系中
// Проверка наличия единицы в маппинге
if (!Object.prototype.hasOwnProperty.call(unitToBytes, formattedUnit)) {
throw new Error("Invalid unit");
}
@@ -49,47 +49,49 @@ export const calculateBytes = (value = 0, unit = "Bytes"): number => {
return -1;
}
// 计算并返回字节数
// Расчёт и возврат количества байт
return value * unitToBytes[formattedUnit];
};
/**
* 格式化存储容量单位
* @param bytes 存储容量(字节数)
* @param decimals 小数位数,默认为 2
* @returns 格式化后的存储容量值
* Форматирование единицы хранения
* @param bytes Объём хранения в байтах
* @param decimals Количество знаков после запятой, по умолчанию 2
* @returns Отформатированное значение объёма хранения
*/
export const formatStorageCapacity = (bytes: number, decimals = 2): number => {
// 检查输入是否有效
// Проверка корректности входных данных
if (!bytes || bytes <= 0) {
return bytes;
}
// 计算存储单位
// Расчёт единицы хранения
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const i = Math.floor(Math.log(bytes) / Math.log(k));
// 格式化存储容量值并返回
// Форматирование и возврат объёма хранения
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
};
/**
* 格式化存储容量单位
* @param bytes 存储容量(字节数)
* @returns 格式化后的存储单位
* Форматирование единицы хранения
* @param bytes Объём хранения в байтах
* @returns Отформатированная единица хранения
*/
export const formatStorageUnit = (bytes: number): string => {
// 检查输入是否有效
// Проверка корректности входных данных
if (!bytes || bytes <= 0) {
return "Bytes";
}
// 计算存储单位
// Расчёт единицы хранения
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
// 返回格式化后的存储单位
// Возврат отформатированной единицы хранения
return sizes[i];
};
+4 -2
View File
@@ -1,5 +1,5 @@
/**
* 浅拷贝,忽略 null,支持嵌套对象
* Поверхностное копирование с игнорированием null и поддержкой вложенных объектов
* @param target
* @param source
*/
@@ -26,7 +26,7 @@ export const assignWith = <T>(target: T, source: Partial<T>): void => {
};
/**
* 深拷贝,忽略 null,支持嵌套对象
* Глубокое копирование с игнорированием null и поддержкой вложенных объектов
* @param source
*/
export const deepCopy = <T>(source: Partial<T>): T => {
@@ -49,3 +49,5 @@ export const deepCopy = <T>(source: Partial<T>): T => {
return objCopy as T;
};
+3 -1
View File
@@ -2,7 +2,7 @@
import i18n from "@/lang/index";
export function translateRouteTitleI18n(title: any) {
// 判断是否存在国际化配置,如果没有原生返回
// Проверяет наличие локализованного заголовка, иначе возвращает исходное значение
const hasKey = i18n.global.te("route." + title);
if (hasKey) {
const translatedTitle = i18n.global.t("route." + title);
@@ -10,3 +10,5 @@ export function translateRouteTitleI18n(title: any) {
}
return title;
}
+2
View File
@@ -37,3 +37,5 @@ export function isExternal(path: string) {
const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
return isExternal;
}
+12 -10
View File
@@ -2,14 +2,14 @@ import axios, { InternalAxiosRequestConfig, AxiosResponse } from "axios";
import { useAccountStoreHook } from "@/store/modules/account";
const dynamicBase = (window as any).__dynamic_base__ || "";
// 创建 axios 实例
// Создание axios instance
const service = axios.create({
baseURL: `${dynamicBase}${import.meta.env.VITE_APP_BASE_API}`,
timeout: 50000,
headers: { "Content-Type": "application/json;charset=utf-8" },
});
// 请求拦截器
// Request interceptor
service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const accountStore = useAccountStoreHook();
@@ -23,40 +23,42 @@ service.interceptors.request.use(
}
);
// 响应拦截器
// Response interceptor
service.interceptors.response.use(
(response: AxiosResponse) => {
const { code, message } = response.data;
if (code === 20000) {
return response.data;
}
// 响应数据为二进制流处理(文件导出)
// Обработка бинарного ответа при экспорте файлов
if (response.data instanceof ArrayBuffer || response.data instanceof Blob) {
return response;
}
ElMessage.error(message || "系统出错");
ElMessage.error(message || "Системная ошибка");
return Promise.reject(new Error(message || "Error"));
},
(error: any) => {
if (error.response.data) {
const { code, msg } = error.response.data;
// token 过期,重新登录
// Token истёк, нужен повторный вход
if (code === "A0230") {
ElMessageBox.confirm("当前页面已失效,请重新登录", "提示", {
confirmButtonText: "确定",
ElMessageBox.confirm("Текущая сессия истекла, войдите снова", "Подтверждение", {
confirmButtonText: "ОК",
type: "warning",
}).then(() => {
localStorage.clear();
window.location.href = "/";
});
} else {
ElMessage.error(msg || "系统出错");
ElMessage.error(msg || "Системная ошибка");
}
}
return Promise.reject(error.message);
}
);
// 导出 axios 实例
// Export axios instance
export default service;
+2
View File
@@ -67,3 +67,5 @@ export const scrollTo = (to: number, duration: number, callback?: any) => {
};
animateScroll();
};
+19 -17
View File
@@ -1,7 +1,7 @@
/**
* 将时间戳转换为格式化日期时间字符串(YYYY-MM-DD HH:mm:ss
* @param timestamp 时间戳
* @returns 格式化日期时间字符串
* Преобразует timestamp в строку даты и времени формата YYYY-MM-DD HH:mm:ss.
* @param timestamp Timestamp.
* @returns Отформатированная строка даты и времени.
*/
export const timestampToDateTime = (timestamp: number): string => {
const date = new Date(timestamp);
@@ -35,24 +35,24 @@ export const calculateTimeDifference = (timestamp: number): string => {
const parts: string[] = [];
if (days > 0) {
parts.push(`${days}`);
parts.push(`${days} дн.`);
}
if (remainingHours > 0) {
parts.push(`${remainingHours}小时`);
parts.push(`${remainingHours} ч.`);
}
if (remainingMinutes > 0) {
parts.push(`${remainingMinutes}分钟`);
parts.push(`${remainingMinutes} мин.`);
}
if (remainingSeconds > 0) {
parts.push(`${remainingSeconds}`);
parts.push(`${remainingSeconds} с.`);
}
return parts.join(" ");
};
/**
* 获取一小时后的时间戳
* @returns 一周后的时间戳
* Возвращает timestamp через один час.
* @returns Timestamp через один час.
*/
export const getHourLater = (): number => {
const date = new Date();
@@ -61,8 +61,8 @@ export const getHourLater = (): number => {
};
/**
* 获取一天后的时间戳
* @returns 一周后的时间戳
* Возвращает timestamp через один день.
* @returns Timestamp через один день.
*/
export const getDayLater = (): number => {
const date = new Date();
@@ -71,8 +71,8 @@ export const getDayLater = (): number => {
};
/**
* 获取一周后的时间戳
* @returns 一周后的时间戳
* Возвращает timestamp через одну неделю.
* @returns Timestamp через одну неделю.
*/
export const getWeekLater = (): number => {
const date = new Date();
@@ -81,8 +81,8 @@ export const getWeekLater = (): number => {
};
/**
* 获取一个月后的时间戳
* @returns 一个月后的时间戳
* Возвращает timestamp через один месяц.
* @returns Timestamp через один месяц.
*/
export const getMonthLater = (): number => {
const date = new Date();
@@ -91,11 +91,13 @@ export const getMonthLater = (): number => {
};
/**
* 获取一年后的时间戳
* @returns 一年后的时间戳
* Возвращает timestamp через один год.
* @returns Timestamp через один год.
*/
export const getYearLater = (): number => {
const date = new Date();
date.setFullYear(date.getFullYear() + 1);
return date.getTime();
};