Files
xk-admin/apps/web-antd/src/util/tool.ts
2025-03-07 08:18:45 +08:00

351 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { VbenFormProps } from '#/adapter/form';
import type { DescItem } from '#/components/description';
import { isFunction } from '@vben/utils';
export const omit = (obj: any, keysToOmit: string[]) => {
// 如果 obj 不是对象或者 keysToOmit 不是数组,则直接返回 obj
if (typeof obj !== 'object' || !Array.isArray(keysToOmit)) {
return obj;
}
// 创建一个新的对象,避免修改原始对象
const result = {} as any;
// 遍历 obj 的所有键值对
for (const key in obj) {
// 如果当前键不在要忽略的键列表中,则复制到新对象
if (!keysToOmit.includes(key)) {
result[key] = obj[key];
}
}
return result;
};
export const get = (object: any, path: string) => {
// 如果 object 不是对象或者 path 不是字符串,则直接返回 defaultValue
if (
typeof object !== 'object' ||
object === null ||
typeof path !== 'string'
) {
return object;
}
// 将路径字符串转换为数组
const pathArray = path.split('.').filter(Boolean); // 过滤掉空字符串
let current = object;
// 遍历路径数组
for (const element of pathArray) {
// 如果当前层级不是对象或没有对应的键,则返回 defaultValue
if (
typeof current !== 'object' ||
current === null ||
!(element in current)
) {
return object;
}
// 更新 current 到下一层级
current = current[element];
}
// 返回最终找到的值
return current;
};
export const ifDetail = (renderCallbackParams: any): boolean => {
const schema = renderCallbackParams.schema;
if (isFunction(schema.ifDetail)) {
return schema.ifDetail(renderCallbackParams);
}
return schema.ifDetail !== false;
};
/**
* 将表单元数据转换为详情表单
* @param formOptions
* @param values
*/
export const schemaToDetailForm = (
formOptions: VbenFormProps,
values: any,
): DescItem[] => {
const group: Array<DescItem> = [];
const formSchemas = formOptions.schema;
if (!Array.isArray(formSchemas)) return group;
for (let i = 0; i < formSchemas.length; i++) {
const item = formSchemas[i];
// 找到分割线
if (item?.component === 'Divider') {
group.push({
field: item.fieldName,
label: item.label,
children: [],
} as unknown as DescItem);
// 将分割线后面的数据添加到group中
for (let j = i + 1; j < formSchemas.length; j++) {
const nextItem = formSchemas[j];
// 找到下面的分割线
if (nextItem?.component === 'Divider') {
// 中断
i = j - 1;
break;
} else {
if (
ifDetail({
schema: nextItem,
values,
model: values,
field: item.fieldName,
})
) {
group[group.length - 1]?.children?.push({
field: nextItem?.fieldName,
label: nextItem?.label,
span: nextItem?.detailSpan || 12,
component: nextItem?.component,
componentProps: nextItem?.componentProps,
} as DescItem);
}
}
}
}
}
if (group.length > 0) {
return group;
}
return [
{
field: 'baseinfo',
label: '基本信息',
children: formSchemas
.filter((item) => {
return ifDetail({
schema: item,
values,
model: values,
field: item.fieldName,
});
})
.map((item) => {
return {
field: item.fieldName,
label: item.label,
span: item.detailSpan || 12,
component: item.component,
componentProps: item.componentProps,
} as DescItem;
}),
} as DescItem,
];
};
// 获取子节点id
export const getChildIds = (record: any) => {
const ids = [record.id];
record.children?.forEach((item: any) => {
ids.push(...getChildIds(item));
});
return ids;
};
/**
* 获取所有叶子节点
* @param treeData
*/
export const getLeafNodeIds = (treeData: any) => {
const leafNodeIds: any = [];
function traverse(node: any) {
// 如果当前节点没有 children 或 children 是空数组,则它是叶子节点
if (!node.children || node.children.length === 0) {
leafNodeIds.push(node.id);
} else {
// 否则,递归遍历每个子节点
for (const child of node.children) {
traverse(child);
}
}
}
// 遍历树的根节点
for (const root of treeData) {
traverse(root);
}
return leafNodeIds;
};
/**
* 获取所有节点id
* @param treeData
*/
export const getAllNodeIds = (treeData: any) => {
const allNodeIds: any = [];
function traverse(node: any) {
// 收集当前节点的 id
allNodeIds.push(node.id);
// 如果当前节点有 children则递归遍历每个子节点
if (node.children && node.children.length > 0) {
for (const child of node.children) {
traverse(child);
}
}
}
// 遍历树的根节点
for (const root of treeData) {
traverse(root);
}
return allNodeIds;
};
/**
* -转大驼峰
* @param str
*/
export const toPascalCase = (str: any) => {
// 将连字符或下划线替换为空格,以便后续处理
const words = str.replaceAll(/[-_]/g, ' ').split(' ');
// 将每个单词的首字母大写,并将其余部分保持原样
const pascalCaseWords = words.map((word: any) => {
if (word) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}
return word;
});
// 将处理后的单词拼接成一个新的字符串
return pascalCaseWords.join('');
};
/**
* 转-kebab
*/
export const toKebabCase = (str: string) => {
// 将每个单词的首字母小写,并在单词之间插入连字符
return str
.replaceAll(/([A-Z])/g, (match, _p1, offset) => {
// 如果是第一个字符,直接转为小写
if (offset === 0) {
return match.toLowerCase();
}
// 否则,在大写字母前加上连字符,并将大写字母转为小写
return `-${match.toLowerCase()}`;
})
.toLowerCase(); // 确保整个字符串都是小写
};
export function getFileNameWithoutExtension(path: string) {
// 使用正则表达式匹配最后一个 / 后面的所有字符,但不包括最后一个点(.)之后的内容
const match = path.match(/[^/]+(?=\.[^./]+$|$)/);
return match ? match[0].replace(/\.[^/.]+$/, '') : null;
}
/**
* 数据脱敏
* @param data
* @param type
*/
export function desensitize(data: string, type: 'bankCard' | 'idCard'): string {
if (!data) return '';
switch (type) {
case 'bankCard': {
// 银行卡号脱敏规则显示前6位和后4位中间用*代替
if (data.length < 12) {
throw new Error('Invalid bank card number length');
}
return data.slice(0, 6) + '*'.repeat(data.length - 10) + data.slice(-4);
}
case 'idCard': {
// 身份证号脱敏规则显示前6位和后4位中间用*代替
if (data.length !== 18) {
throw new Error('Invalid ID card number length');
}
return data.slice(0, 6) + '*'.repeat(10) + data.slice(-4);
}
default: {
throw new Error('Unsupported desensitization type');
}
}
}
/**
* 获取操作系统的Icon
* @param str
*/
export function getIcon(str: string) {
switch (str) {
case 'Api Post': {
return 'logos:async-api-icon';
}
case 'Chrome': {
return 'devicon:chrome';
}
case 'Edge':
case 'Microsoft Edge': {
return 'logos:microsoft-edge';
}
case 'Firefox': {
return 'devicon:firefox';
}
case 'Linux': {
return 'logos:linux-tux';
}
case 'Mac': {
return 'wpf:mac-os';
}
case 'Safari': {
return 'devicon:safari';
}
case 'Windows': {
return 'logos:microsoft-windows-icon';
}
default: {
return 'logos:microsoft-windows-icon';
}
}
}
/**
* 获取接诊状态
* @param status
*/
export function getRegisterStatus(status: number) {
switch (status) {
case 0: {
return '待支付';
}
case 1: {
return '待接诊';
}
case 2: {
return '接诊中';
}
case 3: {
return '已结束';
}
case 4: {
return '已取消';
}
case 5: {
return '待评价';
}
case 6: {
return '已评价';
}
case 7: {
return '已拒诊';
}
default: {
return '未知状态';
}
}
}