From 7928000dc6f60d726b23e56c6f618d9db44df053 Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 8 Jul 2026 08:50:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(valuation):=20=E6=96=B0=E5=A2=9E=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E5=8F=AF=E6=8A=98=E5=8F=A0=E5=88=86=E7=BB=84=E8=A1=A8?= =?UTF-8?q?=E5=A4=B4=E5=B7=A5=E5=85=B7=20initCollapsibleGroupHeaders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jqGrid 4.5.4 原生 setGroupHeaders 只支持静态合并表头,不支持点击折叠。 本次在 utils.js 新增通用工具函数,为估值模块前端重构提供基础能力: - initCollapsibleGroupHeaders(jgrid, groupConfig): 生成合并表头 + 点击折叠/展开 - refreshCollapsibleGroupHeaders(jgrid): 列重排/显隐后重建分组边界 - 复用本文件 setcolumnChooser2 已验证的 destroyGroupHeader → 显隐列 → setGroupHeaders 重建模式 - 默认全部展开,折叠态显示 ▶ 展开态显示 ▼ - 与 setcolumnChooser 通过事件委托协调,不依赖 free-jqGrid 商业版 不换库、零全站回归风险。后续提交接入业务页面。 --- YLErpWeb/wwwroot/Scripts/utils.js | 100 ++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/YLErpWeb/wwwroot/Scripts/utils.js b/YLErpWeb/wwwroot/Scripts/utils.js index 3a1e661b..2f65e78d 100644 --- a/YLErpWeb/wwwroot/Scripts/utils.js +++ b/YLErpWeb/wwwroot/Scripts/utils.js @@ -1091,4 +1091,104 @@ main.checkEmail = function (email) { const regex = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/; return regex.test(email); } + +/** + * 可折叠分组表头工具(适用于 jqGrid 4.5.4,不依赖 free-jqGrid / Guriddo 商业版) + * + * 背景:jqGrid 4.5.4 的 setGroupHeaders 只能生成静态合并表头,不支持点击折叠。 + * 本方法在 setGroupHeaders 基础上补齐"点击分组表头折叠/展开"交互, + * 并复用本文件 setcolumnChooser2 已验证的 destroyGroupHeader → 显隐列 → setGroupHeaders 重建模式。 + * + * 用法: + * main.initCollapsibleGroupHeaders($('#listGrid'), [ + * { title: '基本信息', columns: ['交易日', '簿记账户'] }, + * { title: '名义本金', columns: ['合约名义本金', '多头', '空头'] } + * ]); + * + * @param {jQuery} jgrid jqGrid 容器(如 $('#listGrid')) + * @param {Array} groupConfig 分组配置,每项 { title: string, columns: string[] } + * - title 分组表头显示名 + * - columns 该组包含的列(使用 colModel.name) + * 注意:columns 里若包含已被 setcolumnChooser 隐藏的列,会被自动跳过,不影响重建。 + */ +main.initCollapsibleGroupHeaders = function (jgrid, groupConfig) { + if (!groupConfig || !groupConfig.length) return; + + // 存储各分组的折叠状态,key=title,value=true 表示已折叠 + var collapseState = {}; + + // 根据 groupConfig + 当前 colModel 可见性,构造 setGroupHeaders 所需的 groupHeaders 参数。 + // 同步剔除"该组所有列都被隐藏"的分组(与 setcolumnChooser2:185-186 的 notShow 逻辑一致)。 + function buildGroupHeaders() { + var colModel = jgrid.jqGrid('getGridParam', 'colModel'); + var visibleNames = colModel.filter(function (c) { return !c.hidden; }).map(function (c) { return c.name; }); + var groupHeaders = []; + for (var g = 0; g < groupConfig.length; g++) { + var group = groupConfig[g]; + // 计算该分组在当前可见列中的连续段,用于 setGroupHeaders 的 startColumnName/numberOfColumns + var visibleColsInGroup = group.columns.filter(function (n) { return visibleNames.indexOf(n) > -1; }); + if (!visibleColsInGroup.length) continue; // 整组都隐藏,跳过 + groupHeaders.push({ + startColumnName: visibleColsInGroup[0], + numberOfColumns: visibleColsInGroup.length, + titleText: '' + + (collapseState[group.title] ? '▶' : '▼') + ' ' + group.title + '' + }); + } + return groupHeaders; + } + + // 应用一次分组表头(含折叠态显隐),复用 destroyGroupHeader → setGroupHeaders 模式 + function applyGroupHeaders() { + jgrid.jqGrid('destroyGroupHeader', true); // true: 不恢复为单行表头 + // 先按折叠状态显隐列 + for (var g = 0; g < groupConfig.length; g++) { + var group = groupConfig[g]; + if (collapseState[group.title]) { + jgrid.setGridParam().hideCol(group.columns); + } else { + jgrid.setGridParam().showCol(group.columns); + } + } + var groupHeaders = buildGroupHeaders(); + if (groupHeaders.length) { + jgrid.jqGrid('setGroupHeaders', { useColSpanStyle: true, groupHeaders: groupHeaders }); + } + // 保存到 jqGrid 参数,便于与 setcolumnChooser 协调 + jgrid.jqGrid('setGridParam', { collapsibleGroupConfig: groupConfig, collapseState: collapseState }); + bindHeaderClick(); + } + + // 给分组表头单元格绑定 click(事件委托,重建表头后仍生效) + function bindHeaderClick() { + var hbox = jgrid.closest('.ui-jqgrid').find('.ui-jqgrid-hdiv'); + hbox.off('click.collapsibleGroup').on('click.collapsibleGroup', '.group-header-title', function (e) { + e.stopPropagation(); + var idx = $(this).attr('data-group'); + var group = groupConfig[idx]; + if (!group) return; + collapseState[group.title] = !collapseState[group.title]; + applyGroupHeaders(); + }); + } + + applyGroupHeaders(); +}; + +/** + * 重建已初始化的可折叠分组表头。 + * 供 setcolumnChooser / 列重排后调用,确保分组边界与最新的列顺序/可见性同步。 + * @param {jQuery} jgrid + */ +main.refreshCollapsibleGroupHeaders = function (jgrid) { + var cfg = jgrid.jqGrid('getGridParam', 'collapsibleGroupConfig'); + if (!cfg) return; + // 复用已有的 collapseState + var state = jgrid.jqGrid('getGridParam', 'collapseState') || {}; + // 重新初始化(groupConfig 同引用,collapseState 重建以剔除已失效的分组) + main.initCollapsibleGroupHeaders(jgrid, cfg); + // 回填状态 + var freshState = jgrid.jqGrid('getGridParam', 'collapseState') || {}; + Object.keys(state).forEach(function (k) { if (k in freshState) freshState[k] = state[k]; }); +}; \ No newline at end of file