128 lines
7.8 KiB
JavaScript
128 lines
7.8 KiB
JavaScript
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) })
|
||
);
|
||
}
|
||
//------------------------------------------------------------------------------------------------------------------------------汇总函数结束
|