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 = []; 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 '未知状态'; } } }