UNPKG

plus-base-on-baosight

Version:

Expansion based on the Baosight methods.

355 lines (346 loc) 10.5 kB
import { CSSProperties } from 'vue'; import { MenuItemDef, DefaultMenuItem } from '../types/index'; export * from './GridCustomExportManager'; export type * from './GridCustomExportManager'; /** * 在AG Grid右下角前方插入文本 * @param erFormHelper * @param grid id * @param template 模板:{type|field|formater}的格式。例:{count|MAT_NO}-统计MAT_NO的数量;{sum|SHEET_NUM|2}-统计SHEET_NUM的和并且保留2位小数;{fun|HEAT_TREAT_MODE|T}-自定义方法统计HEAT_TREAT_MODE字段并且传递参数T * @param opts.fontStyle 显示的字体样式,同CSS * @param opts.fun 自定义函数,当模板中type=fun时,会调用opts.fun方法;回调参数:字段名,行数据,格式化参数。返回值必须为数字!否则无效 */ export function setGridStatusBar( erFormHelper: any, grid: string, template: string, opts?: { fontStyle?: CSSProperties; fun?: (field: string, row: { [key: string]: any }, format: string) => number; } ) { const bar_class_name = '--lxy-ag-grid-tj'; const api = erFormHelper.getGridApi(grid); const bar_opts = erFormHelper.getGrid(grid).statusBar.statusPanels as any[]; const panel_name = bar_opts.at(-1).statusPanel; const bar_instance = erFormHelper.getGridApi(grid)?.getStatusPanel(panel_name) as any; const bar_el = (bar_instance.$el || bar_instance.eGui) as HTMLElement; const outer_el = bar_el.parentElement?.parentElement; const child_el = bar_el.parentElement; let node = createNode(opts?.fontStyle); const has = outer_el?.querySelector(`.${bar_class_name}`); if (!has) { node.apply(); // filter事件 api?.addEventListener('filterChanged', (e: any) => { node.updataValue(); }); (window as any)['TJBAR'] = node; } else { (window as any)['TJBAR']?.updataValue?.(); } // 创建Node function createNode(css?: CSSProperties) { const div = document.createElement('div'); div.innerText = template; div.style.marginLeft = 'auto'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.classList.add(bar_class_name); for (const key in css) { (div.style as any)[key] = String(css[key as any]); } return { apply() { this.updataValue(); outer_el?.insertBefore(div, child_el); }, updataValue() { div.innerText = updateTemplate(template); }, remove() { div.remove(); }, }; } // 替换模板 interface Rules { type: 'count' | 'sum' | 'fun'; field: string; template: string; rule: string; format?: string; value: number; } function updateTemplate(template: string) { const regex = /(?<=\{)[^{}]+(?=\})/g; const res_match = template.match(regex); const rules: Rules[] = []; if (res_match?.length) { res_match.forEach((str, i) => { // 去掉全部空格 const str_old = str; const rule = str.replace(/\s/g, ''); const rule_type = rule.split('|')[0] as any; const rule_field = rule.split('|')[1]; const rule_float = rule.split('|')[2]; rules.push({ type: rule_type, field: rule_field, template: str_old, rule, format: rule_float, value: 0, }); }); } api?.forEachNodeAfterFilterAndSort((node_row, i) => { const data_row = node_row.data.toJSON(); for (let j = 0; j < rules.length; j++) { const item = rules[j]; if (!Reflect.has(data_row, item.field)) { break; } if (item.type === 'sum') { item.value += Number(data_row[item.field]); } if (item.type === 'count') { item.value += data_row[item.field]?.toString() ? 1 : 0; } if (item.type === 'fun') { item.value += opts?.fun?.(item.field, data_row, item?.format ?? '') || 0; } } }); rules.forEach((item) => { const float = Number.parseInt(item.format ?? '0'); let value = item.value.toString(); if (value.includes('.')) { value = Number(value).toFixed(float); } template = template.replace(`{${item.template}}`, value); }); return template; } } /** * 导出多个ag grid数据为Excel * @param erFormHelper * @param name_file 导出之后的文件名,不包括后缀 * @param opts.grid id * @param opts.name_sheet sheet名称,默认从Sheet1开始 * @param opts.columns 需要导出的列,默认全部列 * @param opts.formatter 单元格格式化函数,返回值必须为字符串! */ export function exportGridByMulSheet( erFormHelper: any, name_file: string, opts: { grid: string; name_sheet?: string; columns?: string[]; formatter?: (params: { value: any; row: { [key: string]: any }; column: string }) => string; }[] ) { const data_export = opts.reduce((pre: string[], opt, i) => { const gridApi = erFormHelper.getGridApi(opt.grid); const { grid, name_sheet, columns, formatter } = opt; if (gridApi) { const _opt: { [key: string]: any } = {}; if (name_sheet) { _opt['sheetName'] = name_sheet; } else { _opt['sheetName'] = `Sheet${i + 1}`; } if (columns) { _opt['columnKeys'] = columns; } if (formatter) { _opt['processCellCallback'] = (params: any) => { const { value, node, column } = params; const str = formatter.call(window, { value, row: node?.data, column: column.getColId(), }); return str; }; } const temp = gridApi.getSheetDataForExcel({ ..._opt, }); if (temp) { pre.push(temp); } else { throw `[${grid} sheet data] is undefined.`; } } else { throw `[${grid}] is undefined.`; } return pre; }, []); const api = erFormHelper.getGridApi(opts[0].grid); api?.exportMultipleSheetsAsExcel({ data: data_export, fileName: `${name_file}.xlsx`, }); } /** * 获取grid配置的颜色 * @param erFormHelper * @param grid id */ export function getGridColorConfig(erFormHelper: any, grid: string) { const res: { color: string; desc: string; field: string; mark: string; rule: string; target: string; _data: any[] }[] = []; const gridStyles = (erFormHelper.ConfigInfo.TSI00GRIDSTYLE.data as any[]).filter((item) => item.FUNCTION_ID === grid); gridStyles.map((row) => { const color = (row.FILL_COLOR as string).trim(); const desc = (row.REMARK as string).trim(); const field = (row.COL_NAME as string).trim(); const mark = (row.CONST_PARA as string).trim(); const rule = (row.REGULAR_EXPRESS as string).trim(); const target = (row.FUNCTION_ID as string).trim(); if (desc && !field.startsWith('_')) { res.push({ desc, color, field, mark, rule, target, _data: row }); } }); return res; } /** * 设置grid内容右键菜单,详情可查看官网:https://www.ag-grid.com/react-data-grid/context-menu/#built-in-menu-items * @param erFormHelper * @param grid id */ export function setGridContentMenu(erFormHelper: any, grid: any, menus: (e: any) => (MenuItemDef | DefaultMenuItem)[]) { let api = erFormHelper.getGridApi(grid); api?.setGetContextMenuItems((params: any) => { return menus.call(window, params); }); } /** * 滚动grid到指定index行 * @param erFormHelper * @param grid id * @param targetValue 目标对象,建议尽量为数据中的唯一值字段 * @param opts.keepLine 保留行数,默认为5行 * @param opts.reMerge 是否重新给grid设置数据 * @returns */ export function scrollGridToData(erFormHelper: any, grid: any, targetValue: { [key: string]: any }, opts?: { keepLine?: number; reMerge?: boolean }) { const keepLine = opts?.keepLine ?? 5; const reMerge = opts?.reMerge ?? true; let gridData = erFormHelper.getGridRows(grid, 'all', true); let findIndex = gridData.findIndex((row: { [key: string]: any }, i: number) => Object.keys(targetValue).every((key) => row[key] === targetValue[key]) ); if (findIndex <= -1) return; if (findIndex - keepLine > 0) { findIndex -= keepLine; } const api = erFormHelper.getGridApi(grid); if (reMerge) { erFormHelper.mergeDataToGrid(gridData, grid); } api?.ensureIndexVisible(findIndex, 'top'); setTimeout(() => { erFormHelper.setGridIndicator(grid, { [Object.keys(targetValue)[0]]: Object.values(targetValue)[0] }); }, 100); } /** * 滚动指定grid指定px * @param erFormHelper * @param grid id * @param px 滚动的像素 */ export function scrollGridByPx(erFormHelper: any, grid: string, px: number) { const api = erFormHelper.getGridApi(grid); (api as any).gridBodyCtrl.scrollVertically(px); } /** * AG Grid 筛选管理 * @constructor erFormHelper * @constructor grid id */ export class AgGirdFilterManger { private erFormHelper: any; private recordOn = false; private model_old = {}; private api: any = null; constructor(erFormHelper: any, grid_id: string) { this.erFormHelper = erFormHelper; this.api = this.erFormHelper.getGridApi(grid_id); if (!this.api) { throw new Error(`[${grid_id} is not found]`); } // 添加 filterChanged 事件 this.api.addEventListener('filterChanged', () => { if (this.recordOn) { this.model_old = this.api!.getFilterModel(); } }); } // 记录 用于需要保留当前筛选设置的情况 record = { on: () => { this.recordOn = true; }, off: (clearAll = false) => { this.recordOn = false; clearAll && (this.model_old = {}); }, set: () => { this.api?.setFilterModel(this.model_old); }, }; /** * 设置列筛选 * @param filterOpts 对象格式:{列1英文名:筛选值1,列2英文名:筛选值2,列2英文名:筛选值2,...} */ filter(filterOpts: { [col_name: string]: string }) { Object.entries(filterOpts).forEach(([col_name, col_filter_value]) => { const col = this.api?.getColumnDef(col_name); if (col_name === col?.field) { this.api?.setFilterModel({ [col_name]: { // 低代码列好像都用的 multi filterType: 'multi', filterModels: [ { // 筛选类型 filterType: 'text', // type: 筛选方式 type: 'startWidths', // 筛选的值 filter: col_filter_value, }, ], }, }); } }); } /** * 清除当前筛选设置 */ clear() { this.api?.setFilterModel(null); } } /** * 获取Grid的Nodes数据 * @param erFormHelper * @param grid id * @param toJson 是否转化为json数据 */ export function getGridDataByNodes(erFormHelper: any, grid: string, toJson?: boolean) { const back: { [key: string]: any }[] = []; const api = erFormHelper.getGridApi(grid) as any; api.forEachNode((node: any, i: number) => { if (toJson) { back.push(node.data.toJSON()); } else { back.push(node.data); } }); return back; }