ZhangQiangEcologyKit/汇总函数.js
liozvqe f7b2c69435 搜索函数加多选
搜索函数加多选
2025-07-05 14:38:04 +08:00

128 lines
7.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

let detNum = 1;
let isUpdating = false;
let detcompCodeFI = "field247341";//综合能力编码
let detexamScoreFI = "field247353";//考试得分
let detminScoreFI = "field247343";//最低分
let detmaxScoreFI = "field247344";//最高分
let ScoreFI = "field246848";//职级评定分数
WfForm.bindDetailFieldChangeEvent(detexamScoreFI, function (id, rowIndex, value) {//考评得分汇总
let rdname = WfForm.getFieldValue(rdnameFI);
let rowArr = WfForm.getDetailAllRowIndexStr("detail_" + detNum).split(",");
if (rowArr.length > 0 && rdname != "") {
if (!isUpdating) {//手动修改判断
updateScores(rowIndex);// 执行更新金额操作
}
}
});
//------------------------------------------------------------------------------------------------------------------------------汇总函数开始
function updateScores(rowIndex) {
if (isUpdating) return;
isUpdating = true;
let compCode = WfForm.getFieldValue(detcompCodeFI + "_" + rowIndex);
let scoreStr = WfForm.getFieldValue(detexamScoreFI + "_" + rowIndex);
let score = scoreStr != "" ? parseFloat(scoreStr) : null; // 保持未填写状态
let minScore = parseFloat(WfForm.getFieldValue(detminScoreFI + "_" + rowIndex)) || 0;
let maxScore = parseFloat(WfForm.getFieldValue(detmaxScoreFI + "_" + rowIndex)) || 0;
// **评分超范围检查**
if (score != null && (score < minScore || score > maxScore)) {
WfForm.showMessage(`评分必须在 ${minScore} - ${maxScore} 之间!`, 2, 3); //错误信息3s后消失
WfForm.changeFieldValue(detexamScoreFI + "_" + rowIndex, { value: "" });
}
// 第一步:形成初始数据
let rowArr = WfForm.getDetailAllRowIndexStr("detail_" + detNum).split(",");
let nodeMap = {}; // 用 "本级编码" 作为 key 存储节点数据
rowArr.forEach(rowIndex => {
let code = WfForm.getFieldValue(detcompCodeFI + "_" + rowIndex); // 本级编码
let value = WfForm.getFieldValue(detexamScoreFI + "_" + rowIndex); // 数值
nodeMap[code] = {
rowIndex,
code,
value: parseFloat(value) || 0, // 确保是数值
parentCode: null, // 暂时空
rootId: null // 暂时空
};
});
// 第二步为每个节点确定其直接上级编码parentCode
for (let code in nodeMap) {
let node = nodeMap[code]; // 当前节点对象
let candidate = code; // 从当前编码开始尝试向上找父级
// 尝试逐级截断后两位,查找是否存在合法父节点
while (candidate.length > 2) {
candidate = candidate.slice(0, -2); // 去掉末尾两位,尝试变成父级编码
if (nodeMap[candidate]) { // 如果该编码在 nodeMap 中存在,说明是合法父节点
node.parentCode = candidate; // 记录父级编码
break; // 找到后退出循环
}
}
}
// 第三步每个节点查询roorid
for (let code in nodeMap) {
let rootCode = code;
while (nodeMap[rootCode] && nodeMap[rootCode].parentCode) {
rootCode = nodeMap[rootCode].parentCode; // 向上找父节点
}
nodeMap[code].rootId = rootCode; // 给当前节点赋值根节点ID
}
// 第四步:以 rootId 分组,形成平铺结构
const groupedByRoot = {};
for (let code in nodeMap) {
const node = nodeMap[code];
if (!groupedByRoot[node.rootId]) {
groupedByRoot[node.rootId] = [];
}
groupedByRoot[node.rootId].push(node); // 平铺加入该 rootId 的分组
}
// console.log("按 rootId 分组的节点集合:", groupedByRoot);
//查询出受影响的rootid
let rootId = nodeMap[compCode].rootId;
let chain = getAffectedChain(groupedByRoot[rootId], compCode);//受影响的节点
// console.log("受影响的链路(修改前原始值):", chain.map(node => ({ ...node })));
sumDirectChildrenValue(groupedByRoot[rootId], chain);//更新受影响数值
updateDetailFormValues(chain, detexamScoreFI);//更新明细表数值
// 获取所有 rootId 对应的“根节点对象”
let rootNodes = Object.values(nodeMap).filter(node => node.code == node.rootId);
// 汇总根节点的得分
let totalTopScore = rootNodes.reduce((sum, node) => {
return sum + (parseFloat(node.value) || 0);
}, 0);
// 写入主表字段(如:总得分)
WfForm.changeFieldValue(ScoreFI, { value: totalTopScore });
isUpdating = false;
}
//------------------------------------------------------------------------------------------------------------------------------获取从指定节点 compCode 一直向上的链路,直到根节点,返回包含所有这些节点的数组
function getAffectedChain(nodes, compCode) {
const map = {}; // 初始化一个映射对象,用于存储 code -> 节点对象 的映射
// 遍历所有节点,将它们以 code 为键存入 map 中,方便后续快速查找父节点
nodes.forEach(node => {
map[node.code] = node;
});
const chain = []; // 用于存储从 compCode 到 root 的链路节点数组
let currentCode = compCode; // 当前处理的节点编码,初始为 compCode
// 当当前编码存在并且在映射中能找到对应节点时,一直向上查找 parentCode
while (currentCode && map[currentCode]) {
chain.push(map[currentCode]); // 将当前节点对象加入链路数组中
currentCode = map[currentCode].parentCode; // 更新当前编码为当前节点的 parentCode继续向上查找
}
return chain; // 返回从 compCode 到 root 的链路节点数组(顺序是从子到父)
}
//------------------------------------------------------------------------------------------------------------------------------汇总金额
function sumDirectChildrenValue(nodes, chain) {
// 遍历链路中从上级开始的节点(不包含第一个节点,即受影响的“当前节点”)
for (let i = 1; i < chain.length; i++) {
const node = chain[i];
// 找当前节点的直接子节点
const children = nodes.filter(n => n.parentCode == node.code);
// 汇总子节点的 value 值
const total = children.reduce((sum, child) => sum + (Number(child.value) || 0), 0);
// 更新当前节点的 value 字段
node.value = total;
}
}
//------------------------------------------------------------------------------------------------------------------------------修改明细的额函数
function updateDetailFormValues(chain, fieldPrefix) {
chain.forEach(node =>
WfForm.changeFieldValue(`${fieldPrefix}_${node.rowIndex}`, { value: String(node.value) })
);
}
//------------------------------------------------------------------------------------------------------------------------------汇总函数结束