import { ErrorShowType } from '../constants/index.cjs';
import { d as ProTableResponse, A as ApiResponse } from '../api-DFOs5fnc.cjs';
import dayjs from 'dayjs';
import React from 'react';
/**
* API 错误处理增强工具
*
* 在请求层 error-handler 的基础上,提供业务层的错误处理包装。
* 包含 ProTable 请求包装器、统一错误处理器等。
*
*/
/**
* API 错误处理配置
*/
interface ApiErrorHandlerConfig {
/** message 展示函数 */
showMessage?: (content: string, type: 'success' | 'error' | 'warning' | 'info') => void;
/** notification 展示函数 */
showNotification?: (options: {
message: string;
description?: string;
}) => void;
/** 重定向函数 */
redirect?: (path: string) => void;
/** 登录过期回调 */
onUnauthorized?: () => void;
/** 登录过期的状态码 */
unauthorizedCodes?: (string | number)[];
/** notification 标题,默认 'Request Error' */
notificationTitle?: string;
/** 重定向路径,默认 '/error' */
redirectPath?: string;
}
/**
* 创建项目级 API 错误处理器
*
* @param config - 错误处理配置
* @returns 错误处理函数
*
* @example
* ```ts
* const handleApiError = createApiErrorHandler({
* showMessage: (content, type) => message[type](content),
* showNotification: ({ message: msg, description }) => notification.error({ message: msg, description }),
* onUnauthorized: () => emitLoginRequired(),
* unauthorizedCodes: [401, 10014],
* notificationTitle: '请求错误',
* });
*
* // 在请求拦截器中使用
* handleApiError(error, ErrorShowType.ERROR_MESSAGE);
* ```
*/
declare function createApiErrorHandler(config: ApiErrorHandlerConfig): (error: unknown, showType?: ErrorShowType) => void;
/**
* 从错误对象中提取错误消息
*
* @param error - 错误对象
* @param defaultMessage - 默认错误消息,默认 'Unknown error'
* @returns 错误消息字符串
*/
declare function extractErrorMessage(error: unknown, defaultMessage?: string): string;
/**
* 从错误对象中提取错误码
*
* @param error - 错误对象
* @returns 错误码
*/
declare function extractErrorCode(error: unknown): string | number | undefined;
/**
* 包装 ProTable 的 request 函数,自动处理错误并返回标准格式
*
* 确保即使 API 调用失败,ProTable 也不会崩溃,始终返回合法的空数据。
*
* @param requestFn - 原始请求函数
* @param options - 配置选项
* @returns 包装后的请求函数
*
* @example
* ```ts
* const safeRequest = wrapProTableRequest(
* async (params) => {
* const res = await getUserList(params);
* return { data: res.data.list, total: res.data.total, success: true };
* },
* { onError: (err) => message.error(err.message) }
* );
*
*
* ```
*/
declare function wrapProTableRequest>(requestFn: (params: P) => Promise>, options?: {
/** 错误回调 */
onError?: (error: Error) => void;
}): (params: P) => Promise>;
/**
* API 辅助函数
*
* 提供 API 响应判断、安全执行等通用工具。
* 从 types/api.ts 迁移而来,types/ 目录应仅包含类型定义。
*/
/**
* 判断 API 响应是否成功
*
* 仅通过 `code` 与 `successCode` 比较来判断,不做隐式回退。
* 如果后端使用 `0` 作为成功码,请传 `successCode: 0`。
*
* @param response - API 响应对象
* @param successCode - 成功状态码,默认 '200'
* @returns 是否成功
*
* @example
* ```ts
* const res = await fetchUser(1);
* if (isApiSuccess(res)) {
* console.log(res.data);
* }
*
* // 后端使用 0 作为成功码
* if (isApiSuccess(res, 0)) { ... }
* ```
*/
declare function isApiSuccess(response: ApiResponse | null | undefined, successCode?: string | number): boolean;
/**
* 安全地执行 API 调用并处理错误
*
* @param apiFn - API 调用函数
* @param options - 配置选项
* @returns API 响应数据或 null
*
* @example
* ```ts
* // 获取数据
* const data = await executeApiAction(
* () => fetchUser(1),
* {
* onSuccess: (data, msg) => message.success(msg),
* onError: (msg) => message.error(msg),
* }
* );
*
* // 执行操作并判断成功
* const data = await executeApiAction(
* () => deleteUser(id),
* {
* successMsg: 'Deleted',
* onSuccess: (data, msg) => message.success(msg),
* onError: (msg) => message.error(msg),
* }
* );
* if (data !== null) actionRef.current?.reload();
* ```
*/
declare function executeApiAction(apiFn: () => Promise>, options?: {
/** 成功时的提示消息 */
successMsg?: string;
/** 失败时的提示消息 (覆盖 API 返回的 msg) */
errorMsg?: string;
/** 成功回调 */
onSuccess?: (data: T, msg: string) => void;
/** 错误回调 */
onError?: (msg: string, code: string | number) => void;
/** 成功状态码 */
successCode?: string | number;
/** 默认失败提示,默认 'Operation failed' */
defaultErrorMsg?: string;
/** 默认网络错误提示,默认 'Network error' */
defaultNetworkErrorMsg?: string;
}): Promise;
/**
* 认证工具函数工厂
*
*
* 通过配置适配不同的认证方式。
*/
/**
* AuthManager 配置
*/
interface AuthManagerConfig {
/** token/session 在 localStorage 中的 key */
tokenKey: string;
/** 过期时间存储 key (可选,用于 session 有效期管理) */
expireKey?: string;
/** 会话有效期 (毫秒),不设置则不自动过期 */
ttlMs?: number;
/** 需要在 clearAuth 时额外清除的 localStorage key 列表 */
extraStorageKeys?: string[];
/** 登出后的回调 (如跳转登录页) */
onUnauthorized?: () => void;
}
/**
* AuthManager 实例
*/
interface AuthManager {
/** 获取 token (自动检查过期) */
getToken: () => string | null;
/** 设置 token (自动写入过期时间) */
setToken: (token: string) => void;
/** 清除所有认证信息 */
clearAuth: () => void;
/** 处理未授权状态 (清除认证 + 执行 onUnauthorized 回调) */
handleUnauthorized: () => void;
/** 检查是否已认证 */
isAuthenticated: () => boolean;
}
declare function createAuthManager(config: AuthManagerConfig): AuthManager;
/**
* 登录事件常量 (用于跨组件通信触发登录模态框)
*/
declare const LOGIN_REQUIRED_EVENT = "auth:login-required";
/**
* 触发登录请求事件
*
* @example
* ```ts
* // 在 request interceptor 中
* emitLoginRequired();
*
* // 在组件中监听
* window.addEventListener('auth:login-required', () => setLoginVisible(true));
* ```
*/
declare function emitLoginRequired(): void;
/**
* 剪贴板工具函数
*
* 使用 Clipboard API (所有现代浏览器均支持)
*/
/**
* 复制文本到剪贴板
*
* @param text - 要复制的文本
* @returns 是否复制成功
*
* @example
* ```ts
* const success = await copyToClipboard('Hello World');
* if (success) {
* message.success('已复制到剪贴板');
* }
* ```
*/
declare function copyToClipboard(text: string): Promise;
/**
* 业务辅助格式化工具
*
* 包含特定业务场景逻辑(如中文面议、Java 后端数据格式)。
*/
/**
* 格式化价格显示(支持面议状态)
*
* @category Business Helpers
* @param price - 价格值
* @param options - 配置选项
* @returns 格式化后的价格字符串
*/
declare function formatPrice(price: number | string | undefined | null, options?: {
prefix?: string;
suffix?: string;
negotiableText?: string;
}): string;
/**
* 判断价格是否为面议
*
* 统一的价格面议判断逻辑,支持 undefined / null / 空字符串 / NaN / 负数。
*
* @category Business Helpers
* @param price - 价格值
* @returns 是否面议
*/
declare function isNegotiablePrice(price: number | string | undefined | null): boolean;
/**
* 格式化地址显示
*
* 将逗号分隔的地址字符串替换为指定分隔符(默认空格)。
*
* @category Business Helpers
* @param location - 地址字符串
* @param separator - 分隔符,默认 ' '
* @returns 格式化后的地址
*/
declare function formatLocation(location: string | undefined | null, separator?: string): string;
/** 布尔标志类型:支持数字、字符串、布尔值 */
type BooleanFlag = number | string | boolean | undefined | null;
/**
* 检查布尔标志是否为真值
*
* 支持后端返回的多种布尔表示形式(数字 1、字符串 "1"、布尔值等)。
*
* @category Business Helpers
* @param flag - 布尔标志值
* @param trueLabels - 额外的真值标签列表
* @returns 是否为真
*/
declare function checkBooleanFlag(flag: BooleanFlag, trueLabels?: string[]): boolean;
/** Java 字符串数组输入类型:字符串或字符串数组 */
type JavaStringArrayInput = string | string[] | undefined | null;
/**
* 解析 Java String 数组格式
*
* 支持 JSON 数组字符串 `["a","b"]` 和普通字符串,自动过滤空值。
* 用于对接 Java 后端返回的字符串数组字段。
*
* @category Business Helpers
* @param val - 输入值
* @returns 解析后的字符串数组
*/
declare function parseJavaStringArray(val: JavaStringArrayInput): string[];
/**
* 格式化相关常量
*/
/** 空值占位符 */
declare const EMPTY_PLACEHOLDER = "--";
/**
* 日期时间格式化工具
*/
/** 默认日期格式 */
declare const DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
/** 默认日期时间格式 */
declare const DEFAULT_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
/**
* 初始化格式化工具的 locale 设置
*
* 在应用启动时调用一次,设置 dayjs 的全局 locale。
* 如果不调用,dayjs 将使用默认的 'en' locale。
*
* @param locale - dayjs locale 名称,如 'zh-cn'
*/
declare function initFormatters(locale: string): void;
/**
* 格式化日期
*
* @param date - 日期值 (字符串/数字/Date/dayjs)
* @param format - 格式模板,默认 'YYYY-MM-DD'
* @returns 格式化后的日期字符串,无效日期返回 '--'
*/
declare function formatDate(date: string | number | Date | dayjs.Dayjs | null | undefined, format?: string): string;
/**
* 格式化日期时间
*
* @param date - 日期值
* @param format - 格式模板,默认 'YYYY-MM-DD HH:mm:ss'
* @returns 格式化后的日期时间字符串
*/
declare function formatDateTime(date: string | number | Date | dayjs.Dayjs | null | undefined, format?: string): string;
/**
* 格式化为相对时间 (如 "5分钟前"、"3天前")
*
* 30天以内显示相对时间,超过30天显示具体日期。
*
* @param date - 日期值
* @param thresholdDays - 超过此天数显示具体日期,默认 30
* @returns 相对时间字符串
*/
declare function formatRelativeTime(date: string | number | Date | dayjs.Dayjs | null | undefined, thresholdDays?: number): string;
/**
* 数字格式化工具
*/
/**
* 格式化数字 (千分位分隔)
*
* 使用 `Intl.NumberFormat` 实现,支持多语言 locale、性能更优。
*
* @param num - 数字
* @param precision - 小数位数,默认不处理
* @param locale - BCP 47 语言标签,如 'zh-CN'、'en-US',默认使用浏览器 locale
* @returns 格式化后的字符串
*/
declare function formatNumber(num: number | string | null | undefined, precision?: number, locale?: string): string;
/**
* 格式化货币
*
* 使用 `Intl.NumberFormat` 实现,支持多语言 locale。
* 默认使用前缀符号模式(`¥1,234.50`),与原有行为一致。
*
* @param amount - 金额
* @param currency - 货币符号,默认 '¥'
* @param precision - 小数位数,默认 2
* @param locale - BCP 47 语言标签,默认使用浏览器 locale
* @returns 格式化后的货币字符串
*/
declare function formatCurrency(amount: number | string | null | undefined, currency?: string, precision?: number, locale?: string): string;
/**
* 格式化百分比
*
* @param value - 数值 (0-1 或 0-100)
* @param decimals - 小数位数,默认 2
* @param isRatio - 是否为比率 (0-1),默认 false
* @returns 格式化后的百分比字符串
*/
declare function formatPercentage(value: number | null | undefined, decimals?: number, isRatio?: boolean): string;
/**
* 格式化文件大小
*
* @param bytes - 字节数
* @param decimals - 小数位数,默认 2
* @returns 格式化后的文件大小字符串
*/
declare function formatBytes(bytes: number | null | undefined, decimals?: number): string;
/**
* 文本格式化工具
*/
/**
* 格式化手机号 (脱敏)
*
* @param phone - 手机号
* @param mask - 掩码字符,默认 '*'
* @returns 脱敏后的手机号
*/
declare function formatPhone(phone: string | null | undefined, mask?: string): string;
/**
* 格式化文本 (截断 + 省略号)
*
* @param text - 原始文本
* @param maxLength - 最大长度,默认 50
* @param suffix - 省略后缀,默认 '...'
* @returns 截断后的文本
*/
declare function formatText(text: string | null | undefined, maxLength?: number, suffix?: string): string;
/**
* 可配置的日志工具
*
*/
/** 日志级别 */
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
/**
* 消息展示接口 (适配 antd message API)
*/
interface MessageApi {
info: (content: string) => void;
warning: (content: string) => void;
error: (content: string) => void;
success: (content: string) => void;
}
/** Logger 配置 */
interface LoggerOptions {
/** 日志前缀 */
prefix?: string;
/** 最低日志级别,低于此级别的日志不会输出 */
level?: LogLevel;
/**
* 是否为生产环境(用于决定是否抑制日志)
*
* 默认 false。消费方应根据自身构建工具传入:
* - UmiJS: `process.env.NODE_ENV === 'production'`
* - Vite: `import.meta.env.PROD`
*/
isProduction?: boolean;
/** 生产环境下是否仍输出所有级别日志,默认 false (仅输出 warn/error) */
enableAllInProduction?: boolean;
/** 是否显示时间戳,默认 true */
showTimestamp?: boolean;
/**
* 消息展示 API 实例 (可选,适配 antd message 等)
*
* 传入后,info/warn/error/success 方法会同时调用 UI 提示。
*
* @example
* ```ts
* import { message } from 'antd';
* const logger = createLogger({ prefix: 'App', messageApi: message });
* logger.error('操作失败'); // 同时输出到 console 和 antd message
* ```
*/
messageApi?: MessageApi;
}
/** Logger 实例 */
interface Logger {
debug(message: string, ...args: unknown[]): void;
info(message: string, ...args: unknown[]): void;
warn(message: string, ...args: unknown[]): void;
error(message: string, ...args: unknown[]): void;
/** 成功日志 (info 级别) */
success(message: string, ...args: unknown[]): void;
}
/**
* 创建 Logger 实例
*
* @param options - Logger 配置
* @returns Logger 实例
*
* @example
* ```ts
* // 基础用法 (纯 console)
* const logger = createLogger({ prefix: 'Auth' });
* logger.info('User logged in', { userId: 123 });
*
* // 集成 antd message
* import { message } from 'antd';
* const logger = createLogger({ prefix: 'App', messageApi: message });
* logger.error('操作失败'); // console.error + antd message.error
* logger.success('保存成功'); // console.info + antd message.success
* ```
*/
declare function createLogger(options?: LoggerOptions): Logger;
/**
* 导航 / 面包屑工具函数
*
* 提供面包屑生成、菜单数据构建等通用导航功能。
*/
/**
* 面包屑项
*/
interface BreadcrumbItem {
/** 显示文本 */
title: string;
/** 链接路径 */
path?: string;
/** 图标 */
icon?: React.ReactNode;
}
/**
* 路由配置项(简化版)
*/
interface RouteItem {
/** 路径 */
path: string;
/** 名称 */
name?: string;
/** 图标 */
icon?: React.ReactNode;
/** 子路由 */
routes?: RouteItem[];
/** 是否隐藏 */
hideInMenu?: boolean;
/** 是否隐藏面包屑 */
hideInBreadcrumb?: boolean;
/** 额外数据 */
[key: string]: unknown;
}
/**
* 菜单项
*/
interface MenuItem {
/** 唯一标识 */
key: string;
/** 显示文本 */
label: string;
/** 链接路径 */
path?: string;
/** 图标 */
icon?: React.ReactNode;
/** 子菜单 */
children?: MenuItem[];
/** 是否禁用 */
disabled?: boolean;
}
/**
* 将路径段转换为可读标题
*
* @param segment - 路径段
* @returns 可读标题
*
* @example
* ```ts
* pathSegmentToTitle('user-management') // '用户管理' (需要路由配置) 或 'User Management'
* pathSegmentToTitle('userList') // 'User List'
* ```
*/
declare function pathSegmentToTitle(segment: string): string;
/**
* 根据当前路径和路由配置生成面包屑
*
* @param pathname - 当前路径
* @param routes - 路由配置
* @param homeTitle - 首页标题,默认 'Home'
* @returns 面包屑项数组
*
* @example
* ```ts
* const breadcrumbs = generateBreadcrumbItems('/system/user/edit/1', routes);
* // => [{ title: '首页', path: '/' }, { title: '系统管理', path: '/system' }, { title: '用户管理', path: '/system/user' }, { title: '编辑' }]
* ```
*/
declare function generateBreadcrumbItems(pathname: string, routes: RouteItem[], homeTitle?: string): BreadcrumbItem[];
/**
* 根据路由配置和权限生成菜单数据
*
* @param routes - 路由配置
* @param permissions - 用户权限列表(可选,不传则不做权限过滤)
* @param options - 配置选项
* @returns 菜单数据
*
* @example
* ```ts
* const menuData = generateMenuData(routes, userPermissions);
* ```
*/
declare function generateMenuData(routes: RouteItem[], permissions?: string[], options?: {
/** 权限字段名,默认 'access' */
accessKey?: string;
/** 父路径前缀 */
parentPath?: string;
}): MenuItem[];
/**
* 在菜单数据中查找匹配路径的菜单项
*
* @param menuItems - 菜单数据
* @param path - 要查找的路径
* @returns 匹配的菜单项,未找到返回 null
*/
declare function findMenuItemByPath(menuItems: MenuItem[], path: string): MenuItem | null;
/**
* Web Vitals 性能监控工具
*
* 提供 Core Web Vitals 性能指标的采集和报告功能。
* 默认仅在开发模式下输出到控制台,也支持自定义上报。
*
*/
/**
* 性能指标数据
*/
interface PerformanceMetric {
/** 指标名称 */
name: string;
/** 指标值 */
value: number;
/** 评级 (good / needs-improvement / poor) */
rating?: string;
/** 导航类型 */
navigationType?: string;
}
/**
* 性能监控配置
*/
interface PerformanceMonitoringOptions {
/** 是否启用,默认 false(消费方根据自身环境判断后显式开启) */
enabled?: boolean;
/** 指标上报回调 */
onMetric?: (metric: PerformanceMetric) => void;
/** 是否在控制台输出,默认 true */
consoleOutput?: boolean;
}
/**
* 初始化性能监控
*
* 采集 Core Web Vitals 指标:
* - LCP (Largest Contentful Paint): 最大内容绘制时间
* - INP (Interaction to Next Paint): 交互到下一次绘制延迟(2024 年 3 月起取代 FID)
* - CLS (Cumulative Layout Shift): 累积布局偏移
* - FCP (First Contentful Paint): 首次内容绘制
* - TTFB (Time to First Byte): 首字节到达时间
*
* @param options - 配置选项
*
* @example
* ```ts
* // 开发模式:显式启用并输出到控制台
* initPerformanceMonitoring({ enabled: import.meta.env.DEV });
*
* // 生产模式:上报到分析服务
* initPerformanceMonitoring({
* enabled: true,
* consoleOutput: false,
* onMetric: (metric) => {
* analytics.track('web_vital', metric);
* },
* });
* ```
*/
/**
* 清理函数类型,调用后断开所有观察器
*/
type PerformanceCleanup = () => void;
declare function initPerformanceMonitoring(options?: PerformanceMonitoringOptions): PerformanceCleanup;
/**
* 权限检查工具函数
*/
/**
* 检查菜单权限
*
* 编码使用冒号分隔层级(与 SDK PermissionConfigCompiler 一致):
* - `*` 匹配所有权限
* - `admin:*` 匹配 admin 下的所有子权限
* - `admin:topic` 精确匹配
*
* @param userMenus - 用户拥有的菜单权限列表
* @param code - 要检查的权限 code
* @returns 是否有权限
*
* @example
* ```ts
* const menus = ['admin:system:user', 'admin:system:role', 'dashboard'];
* checkMenuPermission(menus, 'admin:system:user') // true
* checkMenuPermission(menus, 'admin:*') // true (有 admin 下的子权限)
* checkMenuPermission(menus, 'settings') // false
* ```
*/
declare function checkMenuPermission(userMenus: string[] | undefined | null, code: string): boolean;
/**
* 检查按钮权限
*
* @param userButtons - 用户拥有的按钮权限列表
* @param code - 要检查的按钮权限 code
* @returns 是否有权限
*
* @example
* ```ts
* const buttons = ['user:create', 'user:edit', 'role:view'];
* checkButtonPermission(buttons, 'user:create') // true
* checkButtonPermission(buttons, 'user:delete') // false
* ```
*/
declare function checkButtonPermission(userButtons: string[] | undefined | null, code: string): boolean;
/**
* 批量检查多个权限 (全部满足)
*
* @param userPermissions - 用户权限列表
* @param codes - 要检查的权限列表
* @returns 是否全部有权限
*/
declare function checkAllPermissions(userPermissions: string[] | undefined | null, codes: string[]): boolean;
/**
* 批量检查多个权限 (任一满足)
*
* @param userPermissions - 用户权限列表
* @param codes - 要检查的权限列表
* @returns 是否有任一权限
*/
declare function checkAnyPermission(userPermissions: string[] | undefined | null, codes: string[]): boolean;
/**
* 中国行政区划数据工具
*
* 将行政区划数据转换为 Ant Design Cascader 组件所需的格式。
* 使用 china-division 包 (optional peer dependency) 或自定义数据源。
*
* **注意**: 该模块专为中国行政区划设计 (China-specific)。
* 数据源通过 `setRegionDataSource()` 注入,不直接依赖具体数据包。
*/
/**
* 级联选项
*/
interface CascaderOption {
/** 显示文本 */
label: string;
/** 值 */
value: string;
/** 子选项 */
children?: CascaderOption[];
}
/**
* 省/自治区/直辖市
*/
interface ProvinceItem {
code: string;
name: string;
}
/**
* 城市
*/
interface CityItem {
code: string;
name: string;
provinceCode: string;
}
/**
* 区/县
*/
interface AreaItem {
code: string;
name: string;
cityCode: string;
provinceCode: string;
}
/**
* 原始地区数据
*/
interface RegionDataSource {
provinces: ProvinceItem[];
cities: CityItem[];
areas: AreaItem[];
}
/**
* 地区数据配置
*/
interface RegionConfig {
/**
* Cascader option 的 value 使用哪个字段
* - 'code': 使用行政区划编码 (默认, 如 '110000')
* - 'name': 使用名称 (如 '北京市')
*/
valueField?: 'code' | 'name';
}
/**
* 重置缓存 (测试用)
*/
declare function resetRegionCache(): void;
/**
* 设置数据源
*
* 如果使用 china-division 包, 需要在应用初始化时调用此方法设置数据源。
*
* @example
* ```ts
* import provinces from 'china-division/dist/provinces.json';
* import cities from 'china-division/dist/cities.json';
* import areas from 'china-division/dist/areas.json';
*
* setRegionDataSource({ provinces, cities, areas });
* ```
*/
declare function setRegionDataSource(data: RegionDataSource, config?: RegionConfig): void;
/**
* 获取省市区三级级联数据
*
* @returns Ant Design Cascader 格式的省市区数据
*
* @example
* ```tsx
* import { getRegionData } from '@aspect/shared/utils';
*
*
* ```
*/
declare function getRegionData(): CascaderOption[];
/**
* 获取省市二级级联数据 (不含区/县)
*
* @returns Ant Design Cascader 格式的省市数据
*
* @example
* ```tsx
*
* ```
*/
declare function getCityData(): CascaderOption[];
/**
* 根据地区编码获取名称
*
* @param code - 行政区划编码
* @returns 地区名称, 未找到返回 code 本身
*
* @example
* ```ts
* getRegionName('110000'); // => '北京市'
* getRegionName('110100'); // => '北京市' (市辖区)
* getRegionName('110101'); // => '东城区'
* ```
*/
declare function getRegionName(code: string): string;
/**
* 根据编码数组获取完整地址文本
*
* @param codes - [省编码, 市编码?, 区编码?]
* @param separator - 分隔符, 默认 ' '
* @returns 完整地址文本
*
* @example
* ```ts
* getRegionFullText(['110000', '110100', '110101']);
* // => '北京市 北京市 东城区'
*
* getRegionFullText(['110000', '110100', '110101'], '/');
* // => '北京市/北京市/东城区'
* ```
*/
declare function getRegionFullText(codes: string[], separator?: string): string;
/**
* HTML 净化工具函数
*
* dompurify 作为可选 peerDependency,使用参数注入模式避免硬依赖。
*/
/** DOMPurify sanitize 函数签名 */
type SanitizeFn = (html: string, options?: Record) => string;
/**
* 初始化 HTML 净化器
*
* 在应用启动时调用一次,传入 DOMPurify 实例。
*
* @param purify - DOMPurify 实例 (import DOMPurify from 'dompurify')
*
* @example
* ```ts
* // 在 app.tsx 中初始化
* import DOMPurify from 'dompurify';
* import { initSanitizer } from '@aspect/shared/utils';
* initSanitizer(DOMPurify);
* ```
*/
declare function initSanitizer(purify: {
sanitize: SanitizeFn;
}): void;
/**
* 净化 HTML 字符串,防止 XSS 攻击
*
* 需先通过 `initSanitizer` 初始化 DOMPurify。
*
* @param html - 待净化的 HTML 字符串
* @param options - DOMPurify 选项
* @returns 净化后的安全 HTML 字符串
*
* @example
* ```ts
* const safeHtml = sanitizeHtml('Hello
');
* // 'Hello
'
* ```
*/
declare function sanitizeHtml(html: string, options?: Record): string;
/**
* 移除所有 HTML 标签,只保留纯文本
*
* @param html - HTML 字符串
* @returns 纯文本
*/
declare function stripHtmlTags(html: string): string;
/**
* localStorage/sessionStorage 安全封装 + TTL + 内存缓存
*/
/** 存储类型 */
type StorageType = 'local' | 'session';
/** 存储选项 */
interface StorageOptions {
/** 存储类型,默认 'local' */
storageType?: StorageType;
/** 过期时间 (毫秒),不设置则永不过期 */
ttl?: number;
}
/**
* 安全读取存储数据
*
* @param key - 存储 key
* @param storageType - 存储类型,默认 'local'
* @returns 解析后的数据或 null
*
* @example
* ```ts
* const user = safeGetStorage('currentUser');
* const token = safeGetStorage('token');
* ```
*/
declare function safeGetStorage(key: string, storageType?: StorageType): T | null;
/**
* 安全写入存储数据
*
* @param key - 存储 key
* @param value - 要存储的数据
* @param options - 存储选项 (TTL 等)
* @returns 是否写入成功
*
* @example
* ```ts
* safeSetStorage('user', { id: 1, name: 'test' });
* safeSetStorage('token', 'abc123', { ttl: 7 * 24 * 60 * 60 * 1000 }); // 7天过期
* safeSetStorage('cache', data, { storageType: 'session' });
* ```
*/
declare function safeSetStorage(key: string, value: unknown, options?: StorageOptions): boolean;
/**
* 安全删除存储数据
*
* @param key - 存储 key
* @param storageType - 存储类型,默认 'local'
*/
declare function safeRemoveStorage(key: string, storageType?: StorageType): void;
/**
* 清空指定类型的存储
*
* @param storageType - 存储类型,默认 'local'
*/
declare function clearStorage(storageType?: StorageType): void;
/**
* 检查存储项是否已过期
*
* @param key - 存储 key
* @param storageType - 存储类型,默认 'local'
* @returns 是否已过期 (不存在也返回 true)
*/
declare function isStorageExpired(key: string, storageType?: StorageType): boolean;
/**
* 清理所有已过期的存储项
*
* @param storageType - 存储类型,默认 'local'
* @returns 清理的条数
*/
declare function cleanExpiredStorage(storageType?: StorageType): number;
/**
* 获取存储空间大小 (估算,单位字节)
*
* @param storageType - 存储类型,默认 'local'
* @returns 估算大小 (字节)
*/
declare function getStorageSize(storageType?: StorageType): number;
/**
* 内存缓存配置
*/
interface MemoryCacheOptions {
/** 最大缓存条数,默认 100 */
maxSize?: number;
/** 默认过期时间 (毫秒),默认不过期 */
defaultTtl?: number;
}
/**
* 内存缓存实例
*/
interface MemoryCache {
/** 获取缓存值 */
get(key: string): T | undefined;
/** 设置缓存值 */
set(key: string, value: unknown, ttl?: number): void;
/** 删除缓存值 */
delete(key: string): boolean;
/** 检查 key 是否存在 (且未过期) */
has(key: string): boolean;
/** 清空所有缓存 */
clear(): void;
/** 获取当前缓存大小 */
readonly size: number;
}
/**
* 创建内存缓存实例
*
* @param options - 缓存配置
* @returns 缓存实例
*
* @example
* ```ts
* const cache = createMemoryCache({ maxSize: 50, defaultTtl: 60000 });
* cache.set('key', { data: 'value' });
* const value = cache.get<{ data: string }>('key');
* ```
*/
declare function createMemoryCache(options?: MemoryCacheOptions): MemoryCache;
/**
* 主题管理工具
*
* 提供主题管理的核心逻辑:主题切换、持久化、DOM 更新、系统偏好检测等。
*
*/
/**
* 主题定义
*/
interface ThemeDefinition {
/** 主题 ID */
id: string;
/** 主题名称 */
name: string;
/** 是否为暗色主题 */
isDark: boolean;
/** 主色调 */
primaryColor?: string;
/** 自定义 CSS 变量 */
cssVars?: Record;
/** antd 主题 token */
token?: Record;
}
/**
* 主题管理器配置
*/
interface ThemeManagerOptions {
/** 可用的主题列表 */
themes: ThemeDefinition[];
/** 默认主题 ID */
defaultThemeId?: string;
/** 存储 key,默认 'app-theme' */
storageKey?: string;
/** 是否跟随系统暗色偏好,默认 false */
followSystem?: boolean;
}
/**
* 主题管理器
*/
interface ThemeManager {
/** 获取当前主题 */
getCurrentTheme: () => ThemeDefinition;
/** 获取当前主题 ID */
getCurrentThemeId: () => string;
/** 切换主题 */
setTheme: (themeId: string) => void;
/** 获取所有可用主题 */
getThemes: () => ThemeDefinition[];
/** 判断当前是否为暗色主题 */
isDark: () => boolean;
/** 切换明暗模式 */
toggleDarkMode: () => void;
}
/**
* 创建主题管理器
*
* @param options - 主题管理器配置
* @returns 主题管理器实例
*
* @example
* ```ts
* const themeManager = createThemeManager({
* themes: [
* { id: 'light', name: '明亮', isDark: false, primaryColor: '#1677ff' },
* { id: 'dark', name: '暗色', isDark: true, primaryColor: '#1668dc' },
* ],
* defaultThemeId: 'light',
* followSystem: true,
* });
*
* // 切换主题
* themeManager.setTheme('dark');
* // 获取当前主题
* const theme = themeManager.getCurrentTheme();
* ```
*/
declare function createThemeManager(options: ThemeManagerOptions): ThemeManager;
/**
* 将主题应用到 DOM
*
* - 设置 `` 的 `data-theme` 属性
* - 设置 `` 的 `class` (dark/light)
* - 设置 CSS 变量
*
* @param theme - 主题定义
*/
declare function applyThemeToDom(theme: ThemeDefinition): void;
/**
* 检测系统是否偏好暗色模式
*
* @returns 系统是否偏好暗色模式
*/
declare function getSystemPrefersDark(): boolean;
/**
* 判断主题 ID 是否对应暗色主题
*
* @param themeId - 主题 ID
* @param themes - 主题列表
* @returns 是否为暗色主题
*/
declare function isDarkTheme(themeId: string, themes: ThemeDefinition[]): boolean;
/**
* 监听系统暗色模式变化
*
* @param callback - 变化回调
* @returns 取消监听的函数
*
* @example
* ```ts
* const unwatch = watchSystemDarkMode((isDark) => {
* themeManager.setTheme(isDark ? 'dark' : 'light');
* });
*
* // 清理
* unwatch();
* ```
*/
declare function watchSystemDarkMode(callback: (isDark: boolean) => void): () => void;
/**
* 通用树操作工具函数
*
* 提供对树形结构数据的常用操作:扁平化、查找、过滤、映射、构建等。
* 适用于菜单树、分类树、组织树、权限树等各种树形场景。
*
*/
/**
* 将树形结构扁平化为一维数组
*
* @param tree - 树节点数组
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 扁平化后的节点数组(不含 children 属性)
*
* @example
* ```ts
* const tree = [
* { id: 1, name: 'A', children: [{ id: 2, name: 'B' }] },
* { id: 3, name: 'C' },
* ];
* flattenTree(tree);
* // => [{ id: 1, name: 'A' }, { id: 2, name: 'B' }, { id: 3, name: 'C' }]
* ```
*/
declare function flattenTree>(tree: T[], childrenKey?: string): T[];
/**
* 在树中查找满足条件的第一个节点
*
* @param tree - 树节点数组
* @param predicate - 匹配函数
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 匹配的节点,未找到返回 null
*
* @example
* ```ts
* const node = findNodeInTree(tree, (n) => n.id === 5);
* ```
*/
declare function findNodeInTree>(tree: T[], predicate: (node: T) => boolean, childrenKey?: string): T | null;
/**
* 在树中查找目标节点的父节点
*
* @param tree - 树节点数组
* @param predicate - 目标节点匹配函数
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 父节点,未找到或目标在根层级时返回 null
*
* @example
* ```ts
* const parent = findParentNode(tree, (n) => n.id === 5);
* ```
*/
declare function findParentNode>(tree: T[], predicate: (node: T) => boolean, childrenKey?: string): T | null;
/**
* 过滤树节点,保留匹配节点及其祖先路径
*
* 如果子节点匹配,其所有祖先节点也会被保留(即使祖先节点本身不匹配)。
*
* @param tree - 树节点数组
* @param predicate - 匹配函数
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 过滤后的新树
*
* @example
* ```ts
* const filtered = filterTree(menuTree, (n) => n.visible !== false);
* ```
*/
declare function filterTree>(tree: T[], predicate: (node: T) => boolean, childrenKey?: string): T[];
/**
* 从扁平列表构建树形结构
*
* @param list - 扁平节点列表
* @param options - 配置选项
* @returns 树形结构数组
*
* @example
* ```ts
* const list = [
* { id: 1, parentId: 0, name: 'Root' },
* { id: 2, parentId: 1, name: 'Child 1' },
* { id: 3, parentId: 1, name: 'Child 2' },
* ];
* const tree = buildTreeFromFlat(list, { rootParentId: 0 });
* ```
*/
declare function buildTreeFromFlat>(list: T[], options?: {
/** ID 字段名,默认 'id' */
idKey?: string;
/** 父 ID 字段名,默认 'parentId' */
parentIdKey?: string;
/** 子节点字段名,默认 'children' */
childrenKey?: string;
/** 根节点的 parentId 值,默认 null/undefined/0/'' */
rootParentId?: string | number | null;
}): T[];
/**
* 映射树的每个节点,生成新树
*
* @param tree - 原始树
* @param mapper - 映射函数
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 映射后的新树
*
* @example
* ```ts
* const options = mapTree(categories, (node) => ({
* label: node.name,
* value: node.id,
* }));
* ```
*/
declare function mapTree, R extends Record>(tree: T[], mapper: (node: T, depth: number) => R, childrenKey?: string): R[];
/**
* 判断一个节点是否是另一个节点的后代
*
* 单次遍历实现:找到祖先节点后立即在其子树中搜索目标,避免两次全树遍历。
*
* @param tree - 树节点数组
* @param ancestorId - 祖先节点 ID
* @param targetId - 目标节点 ID
* @param idKey - ID 字段名,默认 'id'
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 是否为后代关系
*
* @example
* ```ts
* isDescendant(tree, 1, 5) // true: 节点 5 是节点 1 的后代
* ```
*/
declare function isDescendant>(tree: T[], ancestorId: string | number, targetId: string | number, idKey?: string, childrenKey?: string): boolean;
/**
* 获取从根到目标节点的路径
*
* @param tree - 树节点数组
* @param predicate - 目标节点匹配函数
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 路径数组(从根到目标),未找到返回空数组
*
* @example
* ```ts
* const path = getNodePath(tree, (n) => n.id === 5);
* // => [rootNode, parentNode, targetNode]
* ```
*/
declare function getNodePath>(tree: T[], predicate: (node: T) => boolean, childrenKey?: string): T[];
/**
* 递归排序树的每一层节点
*
* @param tree - 树节点数组
* @param compareFn - 比较函数,同 Array.sort
* @param childrenKey - 子节点字段名,默认 'children'
* @returns 排序后的新树
*
* @example
* ```ts
* const sorted = sortTree(menuTree, (a, b) => a.orderSeq - b.orderSeq);
* ```
*/
declare function sortTree>(tree: T[], compareFn: (a: T, b: T) => number, childrenKey?: string): T[];
/**
* 遍历树的每个节点(深度优先)
*
* @param tree - 树节点数组
* @param callback - 回调函数,返回 false 可中止遍历
* @param childrenKey - 子节点字段名,默认 'children'
*
* @example
* ```ts
* walkTree(menuTree, (node, depth) => {
* console.log(' '.repeat(depth) + node.name);
* });
* ```
*/
declare function walkTree>(tree: T[], callback: (node: T, depth: number, parent: T | null) => undefined | false, childrenKey?: string): void;
/**
* URL / 路由工具函数
*
* 提供安全的 URL 操作、外部链接处理、查询字符串解析等通用功能。
*
*/
/**
* 安全地在新标签页中打开 URL
*
* 自动添加 `noopener,noreferrer` 安全属性,防止新窗口通过 window.opener 访问原页面。
* 出于安全考虑,拒绝 `javascript:` / `data:` / `vbscript:` / `file:` 协议。
*
* @param url - 要打开的 URL
* @param features - 窗口特性字符串(可选)
* @returns 新窗口的引用,打开失败返回 null
*
* @example
* ```ts
* openInNewTab('https://example.com');
* openInNewTab('/detail/123'); // 相对路径也支持
* ```
*/
declare function openInNewTab(url: string, features?: string): Window | null;
/**
* 标准化外部 URL
*
* 自动为缺少协议的 URL 补充 `https://` 前缀。
*
* @param url - 原始 URL
* @returns 标准化后的 URL
*
* @example
* ```ts
* normalizeExternalUrl('example.com') // 'https://example.com'
* normalizeExternalUrl('http://example.com') // 'http://example.com'
* normalizeExternalUrl('https://example.com') // 'https://example.com'
* normalizeExternalUrl('//cdn.example.com/a.js') // '//cdn.example.com/a.js'
* ```
*/
declare function normalizeExternalUrl(url: string): string;
/**
* 判断是否为外部链接
*
* @param url - URL 字符串
* @returns 是否为外部链接
*
* @example
* ```ts
* isExternalUrl('https://example.com') // true
* isExternalUrl('http://example.com') // true
* isExternalUrl('//cdn.example.com') // true
* isExternalUrl('/dashboard') // false
* isExternalUrl('about') // false
* ```
*/
declare function isExternalUrl(url: string): boolean;
/**
* 拼接公共资源路径
*
* @param path - 资源相对路径
* @param baseUrl - 基础 URL,默认为空(使用相对路径)
* @returns 完整的资源 URL
*
* @example
* ```ts
* getPublicUrl('/images/logo.png', 'https://cdn.example.com')
* // => 'https://cdn.example.com/images/logo.png'
*
* getPublicUrl('images/logo.png')
* // => '/images/logo.png'
* ```
*/
declare function getPublicUrl(path: string, baseUrl?: string): string;
/**
* 构建查询字符串
*
* 自动过滤 null、undefined 和空字符串值。
*
* @param params - 参数对象
* @returns 查询字符串(不含 '?')
*
* @example
* ```ts
* buildQueryString({ page: 1, keyword: 'test', status: null })
* // => 'page=1&keyword=test'
*
* buildQueryString({ tags: ['a', 'b'] })
* // => 'tags=a&tags=b'
* ```
*/
declare function buildQueryString(params: Record): string;
/**
* 解析查询字符串为对象
*
* @param search - 查询字符串(可以带或不带 '?')
* @returns 参数对象
*
* @example
* ```ts
* parseQueryString('?page=1&keyword=test')
* // => { page: '1', keyword: 'test' }
*
* parseQueryString('tags=a&tags=b')
* // => { tags: ['a', 'b'] }
* ```
*/
declare function parseQueryString(search: string): Record;
/**
* 安全地打开外部链接(标准化 + 新标签页)
*
* @param url - 外部 URL
* @returns 新窗口的引用
*
* @example
* ```ts
* openExternalUrl('example.com') // 自动补 https:// 并在新标签页打开
* ```
*/
declare function openExternalUrl(url: string): Window | null;
/**
* 获取资源 URL
*
* 处理资源路径,支持绝对 URL、data URI 和相对路径。
* 绝对 URL 和 data URI 直接返回,其他路径通过 getPublicUrl 拼接。
*
* @param path - 资源路径
* @param baseUrl - 基础 URL(可选),用于拼接相对路径
* @returns 完整的资源 URL 或 undefined
*
* @example
* ```ts
* getResourceUrl('https://cdn.example.com/avatar.png') // 直接返回
* getResourceUrl('data:image/png;base64,...') // 直接返回
* getResourceUrl('/uploads/avatar.png', '/api') // '/api/uploads/avatar.png'
* getResourceUrl(null) // undefined
* ```
*/
declare function getResourceUrl(path?: string | null, baseUrl?: string): string | undefined;
/**
* 通用验证器工具函数
*/
/**
* 密码强度级别
*/
type PasswordStrength = 'weak' | 'medium' | 'strong';
/**
* 密码强度检测结果
*/
interface PasswordStrengthResult {
/** 强度级别 */
strength: PasswordStrength;
/** 强度分数 (0-100) */
score: number;
/** 建议列表 */
suggestions: string[];
}
/**
* 密码强度建议消息(可自定义以支持国际化)
*/
interface PasswordMessages {
empty: string;
minLength: string;
lowercase: string;
uppercase: string;
digit: string;
special: string;
}
/**
* 文件验证选项
*/
interface FileValidateOptions {
/** 允许的文件类型 (MIME 类型或扩展名) */
allowedTypes?: string[];
/** 最大文件大小 (字节) */
maxSize?: number;
}
/**
* 验证邮箱格式
*
* @param email - 邮箱地址
* @returns 是否有效
*/
declare function validateEmail(email: string): boolean;
/**
* 验证中国手机号格式
*
* @param phone - 手机号
* @returns 是否有效
*/
declare function validatePhone(phone: string): boolean;
/**
* 验证 URL 格式
*
* @param url - URL 字符串
* @returns 是否有效
*/
declare function validateURL(url: string): boolean;
/**
* 检测密码强度
*
* @param password - 密码
* @param messages - 自定义建议消息(可选,用于国际化)
* @returns 密码强度结果
*
* @example
* ```ts
* const result = validatePasswordStrength('Abc123!@#');
* // { strength: 'strong', score: 85, suggestions: [] }
*
* // 自定义中文消息
* const result = validatePasswordStrength('abc', {
* empty: '请输入密码',
* minLength: '密码长度至少8位',
* lowercase: '建议包含小写字母',
* uppercase: '建议包含大写字母',
* digit: '建议包含数字',
* special: '建议包含特殊字符',
* });
* ```
*/
declare function validatePasswordStrength(password: string, messages?: Partial): PasswordStrengthResult;
/**
* 验证中国身份证号
*
* @param idCard - 身份证号
* @returns 是否有效
*/
declare function validateIdCard(idCard: string): boolean;
/**
* 验证银行卡号 (Luhn 算法)
*
* @param cardNo - 银行卡号
* @returns 是否有效
*/
declare function validateBankCard(cardNo: string): boolean;
/**
* 验证文件类型
*
* @param file - 文件对象
* @param allowedTypes - 允许的类型 (MIME 类型或扩展名,如 ['.jpg', '.png', 'image/jpeg'])
* @returns 是否有效
*/
declare function validateFileType(file: {
name: string;
type?: string;
}, allowedTypes: string[]): boolean;
/**
* 验证文件大小
*
* @param file - 文件对象
* @param maxSize - 最大大小 (字节)
* @returns 是否在限制内
*/
declare function validateFileSize(file: {
size: number;
}, maxSize: number): boolean;
/**
* 验证数字范围
*
* @param value - 数值
* @param min - 最小值 (含)
* @param max - 最大值 (含)
* @returns 是否在范围内
*/
declare function validateNumberRange(value: number, min: number, max: number): boolean;
/**
* ValueEnum / Select Options 转换工具
*
* 用于将常量映射表转换为 ProTable valueEnum 格式或 Ant Design Select options 格式。
* 三个项目大量使用 ProTable 的 valueEnum,均有手工转换逻辑。
*
*/
/**
* ProTable valueEnum 项
*/
interface ValueEnumItem {
/** 显示文本 */
text: string;
/** 状态(ProTable 内置:success, error, processing, warning, default) */
status?: 'success' | 'error' | 'processing' | 'warning' | 'default';
/** 颜色 */
color?: string;
/** 是否禁用 */
disabled?: boolean;
}
/**
* ProTable valueEnum 类型
*/
type ValueEnumMap = Record;
/**
* Select/Radio 选项
*/
interface OptionItem {
/** 显示文本 */
label: string;
/** 值 */
value: V;
/** 颜色(可选) */
color?: string;
/** 是否禁用 */
disabled?: boolean;
}
/**
* 常量映射项的通用结构
*/
interface ConstantMapItem {
text: string;
color?: string;
status?: 'success' | 'error' | 'processing' | 'warning' | 'default';
disabled?: boolean;
}
/**
* createValueEnum 选项
*/
interface CreateValueEnumOptions {
/** 当 useOriginalStatus 为 false 时使用的默认 status */
defaultStatus?: 'success' | 'error' | 'processing' | 'warning' | 'default';
/** 是否使用原始映射中的 status 字段,默认 true */
useOriginalStatus?: boolean;
}
/**
* 将常量映射表转换为 ProTable valueEnum 格式
*
* @param map - 常量映射表 `{ key: { text, color?, status? } }`
* @param options - 可选配置
* @returns ProTable 可用的 valueEnum 对象
*
* @example
* ```ts
* const STATUS_MAP = {
* 1: { text: '启用', color: 'green', status: 'success' },
* 0: { text: '禁用', color: 'red', status: 'error' },
* } as const;
*
* // 使用原始 status
* const valueEnum = createValueEnum(STATUS_MAP);
*
* // 统一使用 Default status
* const valueEnum2 = createValueEnum(STATUS_MAP, {
* useOriginalStatus: false,
* defaultStatus: 'default',
* });
*
*
* ```
*/
declare function createValueEnum(map: Record, options?: CreateValueEnumOptions): ValueEnumMap;
/**
* 从数组创建 valueEnum
*
* @param arr - 数据数组
* @param valueKey - 值字段名
* @param labelKey - 文本字段名
* @param options - 可选配置
* @returns ProTable 可用的 valueEnum 对象
*
* @example
* ```ts
* const categories = [
* { id: 1, name: '分类A' },
* { id: 2, name: '分类B' },
* ];
* const valueEnum = createValueEnumFromArray(categories, 'id', 'name');
* // => { 1: { text: '分类A' }, 2: { text: '分类B' } }
* ```
*/
declare function createValueEnumFromArray>(arr: T[], valueKey: keyof T & string, labelKey: keyof T & string, options?: {
/** 颜色字段名 */
colorKey?: keyof T & string;
/** 状态字段名 */
statusKey?: keyof T & string;
}): ValueEnumMap;
/**
* 将常量映射表转换为 Select/Radio 的 options 数组
*
* @param map - 常量映射表
* @returns Select/Radio 可用的 options 数组
*
* @example
* ```ts
* const STATUS_MAP = {
* 1: { text: '启用', color: 'green' },
* 0: { text: '禁用', color: 'red' },
* };
*
* const options = createSelectOptionsFromMap(STATUS_MAP);
* // => [{ label: '启用', value: '1', color: 'green' }, { label: '禁用', value: '0', color: 'red' }]
*
*
* ```
*/
declare function createSelectOptionsFromMap(map: Record): OptionItem[];
/**
* 从数组创建 Select/Radio 的 options 数组
*
* @param arr - 数据数组
* @param valueKey - 值字段名
* @param labelKey - 文本字段名
* @returns options 数组
*
* @example
* ```ts
* const roles = [{ id: 1, roleName: '管理员' }, { id: 2, roleName: '普通用户' }];
* const options = createSelectOptionsFromArray(roles, 'id', 'roleName');
* // => [{ label: '管理员', value: 1 }, { label: '普通用户', value: 2 }]
* ```
*/
declare function createSelectOptionsFromArray, V = T[keyof T]>(arr: T[], valueKey: keyof T & string, labelKey: keyof T & string): OptionItem[];
/**
* 获取枚举映射中指定值的显示文本
*
* @param map - 常量映射表
* @param value - 枚举值
* @param defaultText - 默认文本,默认 '--'
* @returns 显示文本
*
* @example
* ```ts
* getEnumText(STATUS_MAP, 1) // '启用'
* getEnumText(STATUS_MAP, 999) // '--'
* ```
*/
declare function getEnumText(map: Record, value: string | number | null | undefined, defaultText?: string): string;
/**
* 获取枚举映射中指定值的颜色
*
* @param map - 常量映射表
* @param value - 枚举值
* @param defaultColor - 默认颜色,默认 'default'
* @returns 颜色值
*
* @example
* ```ts
* getEnumColor(STATUS_MAP, 1) // 'green'
* getEnumColor(STATUS_MAP, 999) // 'default'
* ```
*/
declare function getEnumColor(map: Record, value: string | number | null | undefined, defaultColor?: string): string;
/**
* 水印配置工具
*
* 生成 Ant Design App 组件 watermark 属性,或独立使用的 canvas 水印。
*
*/
/**
* 水印配置选项
*/
interface WatermarkOptions {
/** 水印文字内容 (如用户名, 可以是字符串或数组) */
content?: string | string[];
/** 是否启用, 默认 true */
enabled?: boolean;
/** 字体大小, 默认 14 */
fontSize?: number;
/** 字体颜色, 默认 'rgba(0, 0, 0, 0.15)' */
fontColor?: string;
/** 旋转角度 (度), 默认 -22 */
rotate?: number;
/** 水印之间的间距 [水平, 垂直], 默认 [100, 100] */
gap?: [number, number];
/** 水印相对于容器的偏移 [x, y] */
offset?: [number, number];
/** z-index, 默认 9 */
zIndex?: number;
/** 字体族, 默认 sans-serif */
fontFamily?: string;
/** 字体粗细, 默认 'normal' */
fontWeight?: 'normal' | 'light' | 'bold' | number;
}
/**
* Ant Design Watermark props 子集
*/
interface AntdWatermarkProps {
content?: string | string[];
font?: {
fontSize?: number;
color?: string;
fontFamily?: string;
fontWeight?: 'normal' | 'light' | 'bold' | number;
};
rotate?: number;
gap?: [number, number];
offset?: [number, number];
zIndex?: number;
}
/**
* 创建 Ant Design Watermark 组件的 props
*
* @param options - 水印配置
* @returns 当 enabled=false 或 content 为空时返回 undefined, 否则返回 Watermark props
*
* @example
* ```tsx
* import { Watermark } from 'antd';
*
* const watermarkProps = createWatermarkConfig({
* content: currentUser?.name,
* enabled: process.env.NODE_ENV === 'production',
* });
*
* // 在 layout childrenRender 中使用
* const layout = {
* childrenRender: (children) => watermarkProps
* ? {children}
* : children,
* };
* ```
*
* @example
* ```tsx
* // 多行水印
* const watermarkProps = createWatermarkConfig({
* content: [currentUser?.name ?? '', dayjs().format('YYYY-MM-DD')],
* fontSize: 12,
* fontColor: 'rgba(0, 0, 0, 0.1)',
* });
* ```
*/
declare function createWatermarkConfig(options: WatermarkOptions): AntdWatermarkProps | undefined;
/**
* 创建简单的用户水印配置
*
* 常见场景的快捷方式: 仅传用户名即可。
*
* @param userName - 用户名
* @param enabled - 是否启用,默认 true。消费方应根据自身环境判断:
* - UmiJS: `process.env.NODE_ENV === 'production'`
* - Vite: `import.meta.env.PROD`
* @returns Watermark props 或 undefined
*
* @example
* ```tsx
* const watermarkProps = createUserWatermark(currentUser?.name, import.meta.env.PROD);
* ```
*/
declare function createUserWatermark(userName?: string | null, enabled?: boolean): AntdWatermarkProps | undefined;
export { type AntdWatermarkProps, type ApiErrorHandlerConfig, type AuthManager, type AuthManagerConfig, type BreadcrumbItem, type CascaderOption, type CreateValueEnumOptions, DEFAULT_DATETIME_FORMAT, DEFAULT_DATE_FORMAT, EMPTY_PLACEHOLDER, type FileValidateOptions, LOGIN_REQUIRED_EVENT, type LogLevel, type Logger, type LoggerOptions, type MemoryCache, type MemoryCacheOptions, type MenuItem, type MessageApi, type OptionItem, type PasswordMessages, type PasswordStrength, type PasswordStrengthResult, type PerformanceCleanup, type PerformanceMetric, type PerformanceMonitoringOptions, type RegionConfig, type RegionDataSource, type RouteItem, type StorageOptions, type StorageType, type ThemeDefinition, type ThemeManager, type ThemeManagerOptions, type ValueEnumItem, type ValueEnumMap, type WatermarkOptions, applyThemeToDom, buildQueryString, buildTreeFromFlat, checkAllPermissions, checkAnyPermission, checkBooleanFlag, checkButtonPermission, checkMenuPermission, cleanExpiredStorage, clearStorage, copyToClipboard, createApiErrorHandler, createAuthManager, createLogger, createMemoryCache, createSelectOptionsFromArray, createSelectOptionsFromMap, createThemeManager, createUserWatermark, createValueEnum, createValueEnumFromArray, createWatermarkConfig, emitLoginRequired, executeApiAction, extractErrorCode, extractErrorMessage, filterTree, findMenuItemByPath, findNodeInTree, findParentNode, flattenTree, formatBytes, formatCurrency, formatDate, formatDateTime, formatLocation, formatNumber, formatPercentage, formatPhone, formatPrice, formatRelativeTime, formatText, generateBreadcrumbItems, generateMenuData, getCityData, getEnumColor, getEnumText, getNodePath, getPublicUrl, getRegionData, getRegionFullText, getRegionName, getResourceUrl, getStorageSize, getSystemPrefersDark, initFormatters, initPerformanceMonitoring, initSanitizer, isApiSuccess, isDarkTheme, isDescendant, isExternalUrl, isNegotiablePrice, isStorageExpired, mapTree, normalizeExternalUrl, openExternalUrl, openInNewTab, parseJavaStringArray, parseQueryString, pathSegmentToTitle, resetRegionCache, safeGetStorage, safeRemoveStorage, safeSetStorage, sanitizeHtml, setRegionDataSource, sortTree, stripHtmlTags, validateBankCard, validateEmail, validateFileSize, validateFileType, validateIdCard, validateNumberRange, validatePasswordStrength, validatePhone, validateURL, walkTree, watchSystemDarkMode, wrapProTableRequest };