feat(valuation): 新增通用可折叠分组表头工具 initCollapsibleGroupHeaders

jqGrid 4.5.4 原生 setGroupHeaders 只支持静态合并表头,不支持点击折叠。
本次在 utils.js 新增通用工具函数,为估值模块前端重构提供基础能力:

- initCollapsibleGroupHeaders(jgrid, groupConfig): 生成合并表头 + 点击折叠/展开
- refreshCollapsibleGroupHeaders(jgrid): 列重排/显隐后重建分组边界
- 复用本文件 setcolumnChooser2 已验证的 destroyGroupHeader → 显隐列 → setGroupHeaders 重建模式
- 默认全部展开,折叠态显示 ▶ 展开态显示 ▼
- 与 setcolumnChooser 通过事件委托协调,不依赖 free-jqGrid 商业版

不换库、零全站回归风险。后续提交接入业务页面。
This commit is contained in:
hjhan
2026-07-08 08:50:14 +08:00
parent b3c2fdfe38
commit 7928000dc6
+100
View File
@@ -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=titlevalue=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: '<span class="group-header-title" data-group="' + g + '">' +
(collapseState[group.title] ? '&#9654;' : '&#9660;') + '&nbsp;' + group.title + '</span>'
});
}
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]; });
};