UNPKG

plus-base-on-baosight

Version:

Expansion based on the Baosight methods.

371 lines (357 loc) 11.2 kB
const os = require('os'); export * from '../ag-grid/index.ts'; /** * 根据Object生成sql * @param data Object类型数据 * @param opts.type sql类型:新增(add) 删除(del) 修改(modify) * @param opts.table sql表名 * @param opts.key sql中的判断主键字段名:... WHERE key=value * @param opts.exclude 需要从data中排除的字段 * @param opts.fun 回调函数 * @returns 生成的sql字符串 */ export function createSqlByObject( data: { [key: string]: any }[], opts: { type: 'add' | 'del' | 'modify'; table: string; key?: string; exclude?: string[]; fun?: ( row: { [key: string]: any }, index: number, opts_: { type: 'add' | 'del' | 'modify'; p1: string[]; p2: any[]; } ) => void | string; } ) { return data.reduce((pre: string, row: { [key: string]: any }, rowIndex) => { const part1: any[] = []; // field 数组 const part2: any[] = []; // value 数组 // 处理单行数据 if (opts.type !== 'del') { Object.entries(row).map(([field, value]) => { value = value.toString().trim(); if (!value) return; if (opts?.exclude?.includes(field)) { // 除特殊字符外 直接跳过 } else { // 新增 or 自定义 if (opts.type === 'add') { part1.push(field); part2.push(`'${value}'`); } // 修改 if (opts.type === 'modify') { part1.push(`${field} = ${value}`); } } }); } // 回调 opts.fun?.apply(window, [row, rowIndex, { type: opts.type, p1: part1, p2: part2 }]); // 新增 if (opts.type === 'add') { pre += `INSERT INTO ${opts.table} (${part1.join(',')}) values (${part2.join(',')});`; } // 修改 if (opts.type === 'modify') { if (opts.key) { pre += `UPDATA ${opts.table} SET ${part1.join(',')} WHEREW ${opts.key} = '${row[opts.key]};'`; } else { throw Error('[modify]时,[opts.key]不能为空'); } } // 删除 if (opts.type === 'del') { if (opts.key) { pre += `DELETE FROM ${opts.table} WHEREW ${opts.key} = '${row[opts.key]}';`; } else { throw Error('[del]时,[opts.key]不能为空'); } } return pre; }, ''); } /** * 指定数组中某段范围的数据移动到指定位置之后 * @param arr 需要处理的数组 * @param index_from 指定范围开始位置 * @param index_to 指定范围结束位置 * @param index_end 指定移动到的目标位置 * @returns 返回重排序后的结果数组 */ export function arrayMoveRangeToEnd(arr: { [key: string]: any }[], index_from: number, index_to: number, index_end: number) { // 判断是往前插入 还是 往后插入 let res: any[] = []; if (index_end < index_from) { // 往前插入 需从尾部删除目标区域数据个数 // 拆分为5个部分 const top = arr.slice(0, index_end); const target = arr.slice(index_end, index_end + 1); const mid = arr.slice(index_end + 1, index_from); const range_data = arr.slice(index_from, index_to + 1); const btm = arr.slice(index_to + 1); // 重新组合5部分 res = top.concat(target).concat(range_data).concat(mid).concat(btm); } else { // 往后插入 // 拆分为5个部分 const top = arr.slice(0, index_from); const range_data = arr.slice(index_from, index_to + 1); const mid = arr.slice(index_to + 1, index_end); const target = arr.slice(index_end, index_end + 1); const btm = arr.slice(index_end + 1); // 重新组合5部分 res = top.concat(mid).concat(target).concat(range_data).concat(btm); } return res; } /** * 指定对象数组中某个成员对象的key-value,将对应成员移动到另一个成员value值的前面 * @param arr 需要处理的数组 * @param key 指定对象key * @param val_from 移动的key对应的value * @param val_to 移动的key对应的value * @returns 返回重排序后的结果数组 */ export function arrayObjMoveToForward(arr: { [key: string]: any }[], key: string, val_from: string, val_to: string) { const i = arr.reduce( (pre: { index_from: number; index_to: number }, row, i) => { if (row[key] === val_from) { pre.index_from = i; } if (row[key] === val_to) { pre.index_to = i; } return pre; }, { index_from: -1, index_to: -1, } ); // plan_no_from plan_no_to 将数据分为3段 let part1: any[] = []; let part2: any[] = []; let part3: any[] = []; let resGridData: { [key: string]: any }[] = []; if (i.index_from < i.index_to) { // 从上往下移 part1 = arr.slice(0, i.index_from); part2 = arr.slice(i.index_from, i.index_to); part3 = arr.slice(i.index_to); part3.unshift(part2[0]); part2.splice(0, 1); resGridData = part1.concat(part2).concat(part3); } if (i.index_from > i.index_to) { // 从下往上移 part1 = arr.slice(0, i.index_to); part2 = arr.slice(i.index_to, i.index_from); part3 = arr.slice(i.index_from); part1.push(part3[0]); part3.splice(0, 1); resGridData = part1.concat(part2).concat(part3); } return resGridData; } /** * 防抖函数 * @param func 需要防抖的函数 * @param wait 延迟时间 * @param immediate 是否立即执行一次 */ export function debounce(func: Function, wait = 0, immediate: boolean = false) { let timeout: NodeJS.Timeout | null; return function executedFunction(...args: any[]) { const later = function () { timeout = null; if (!immediate) func.apply(window, args); }; const callNow = immediate && !timeout; timeout && clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(window, args); }; } /** * 获取当前网络IP和MAC,vue中需挂载在vite.config.ts中运行,可通过全局变量/消息通信发送到页面 */ export function getNetworkMacAndIp() { let IP = '127.0.0.1'; let MAC = ''; const networkInterfaces = os.networkInterfaces(); for (const iface of Object.values(networkInterfaces)) { for (const details of iface as any) { if (details.family === 'IPv4' && details.mac !== '00:00:00:00:00:00' && details.address !== '127.0.0.1') { MAC = details.mac; IP = details.address; return { MAC, IP }; } } } return { MAC, IP }; } /** * 复制文本到剪切板,已过滤了兼容性 * @param 需要复制的文本 */ export function copyTextToClipboard(str: string) { if (navigator.clipboard) { // 框架对非安全模式浏览器做了限制 navigator.clipboard.writeText(str); } else { // 这里做兼容性处理 const dom = document.createElement('input'); dom.value = str; document.body.appendChild(dom); dom.select(); document.execCommand('copy'); document.body.removeChild(dom); dom.remove(); } } /** * 锚点缩放 * @param topDomClassName 顶部锚点元素className * @param bottomDomClassName 底部锚点元素className * @param aim_rate 正确的锚点缩放比例 * @param move_val 偏移值 * @returns 相对于aim_rate的缩放比例 */ export function getZoomByDoms(topDomClassName: string, bottomDomClassName: string, aim_rate: number, move_val: number = 0) { // 获取锚点的最顶部元素(锚点顶部) const mid_top_el = document.getElementsByClassName(topDomClassName)[0]; // 获取锚点的最底部元素(锚点底部) const mid_bottom_el = document.getElementsByClassName(bottomDomClassName)[0]; // 都获取到了 if (mid_top_el && mid_bottom_el) { // 取锚点元素的高(锚点高度) const mid_height = getElClientRects(mid_bottom_el)?.leftTopPoint[1]! - getElClientRects(mid_top_el)?.leftTopPoint[1]! + move_val; // 当前计算出的相对于锚点-整个屏幕高度的比例 const now_rate = mid_height / document.documentElement.clientHeight; // console.log('理论比:', aim_rate, '当前比:', now_rate); // console.log('相差缩放比:', aim_rate / now_rate, '约算结果:', Number((aim_rate / now_rate).toFixed(3))); // 计算出实际比与理论比的相对比 即最终结果 return Number((aim_rate / now_rate).toFixed(3)); } // 默认不缩放 即 1 return 1; } /** * 获取元素尺寸信息 * @param el 需要获取尺寸信息的元素 */ export function getElClientRects(el: Element | HTMLElement) { if (el) { const el1_client_rects = el.getClientRects()[0]; return { // 储存原始数据 _client_rects: el1_client_rects, // 计算数据 leftTopPoint: [el1_client_rects.x, el1_client_rects.y], leftBottomPoint: [el1_client_rects.x, el1_client_rects.y - el1_client_rects.height], rightTopPoint: [el1_client_rects.x + el1_client_rects.width, el1_client_rects.y], rightBottomPoint: [el1_client_rects.x + el1_client_rects.width, el1_client_rects.y - el1_client_rects.height], }; } return null; } /** * 获取系统缩放比例 */ export function reSetSysZoom() { let ratio = 0; let screen = window.screen as any; let ua = navigator.userAgent.toLowerCase(); if (window.devicePixelRatio !== undefined) { ratio = window.devicePixelRatio; } else if (~ua.indexOf('msie')) { if (screen.deviceXDPI && screen.logicalXDPI) { ratio = screen.deviceXDPI / screen.logicalXDPI; } } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) { ratio = window.outerWidth / window.innerWidth; } if (ratio) { ratio = Math.round(ratio * 100); } return 100 / Number(ratio); } /** * 下载文件 * @param url 需要下载的文件url * @param success 下载成功后的回调函数 */ export function downByUrl(url: string, success?: () => void) { const a = document.createElement('a'); a.href = url; a.click(); a.remove(); success && success(); } /** * Object深度合并 * @param obj1 对象1 * @param obj2 对象2,可选;为空时,程序等同于深拷贝 * @returns 合并后的对象 */ export function deepMerge(obj1: { [key: string]: any }, obj2?: { [key: string]: any }) { if (obj2) { const result = deepClone(obj1); for (const key in obj2) { const value = obj2[key]; const isNorObj = typeof obj2[key] === 'object' && obj2[key] !== null; const isArr = Array.isArray(value); const isData = value instanceof Date; if (value && isNorObj && !isArr && !isData) { result[key] = deepMerge(result[key] || {}, obj2[key]); } else { result[key] = value; } } return result; } else { return deepClone(obj1); } } /** * 深拷贝 * @param obj 对象 * @param hash 通常无需传值 * @returns 深拷贝后的对象 */ export function deepClone(obj: { [key: string]: any }, hash = new WeakMap()) { if (obj === null) return null; if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); if (typeof obj !== 'object') return obj; if (hash.has(obj)) return hash.get(obj); const cloneObj: { [key: string]: any } = Array.isArray(obj) ? [] : {}; hash.set(obj, cloneObj); for (const key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj; } /** * 将Map类型转换为eBFR字符串参数 * @param map * @param addTimeStampOnEnd * @returns */ export function mapToeBFRParams(map: Map<string, string>, addTimeStampOnEnd = true) { const res = Array.from(map).map(([field, value]) => { return `@${field}@$$${value};;`; }); if (addTimeStampOnEnd) { return res.join('') + new Date().getTime(); } return res.join(''); }