浏览代码

fix(client): 后台清单指引库,清单精灵必套选套逻辑修改

lishihao 3 年之前
父节点
当前提交
84b2ee6241
共有 1 个文件被更改,包括 206 次插入61 次删除
  1. 206 61
      modules/std_billsGuidance_lib/facade/facades.js

+ 206 - 61
modules/std_billsGuidance_lib/facade/facades.js

@@ -1,4 +1,4 @@
-'use strict';
+'use strict';
 
 /**
  *
@@ -483,71 +483,216 @@ function isOptionNode(node) {
     return node && node.depth() % 2 === 1 && node.data.type === 0
 }
 
+    // 判断蓝色子项和孙子项是否打勾了必填
+    function hasRequireData(node, hasRequire = false) {
+        if (node.children
+            && node.children.length
+            && node.children[0].children
+            && node.children[0].children.length
+            && isProcessNode(node.children[0].children[0])
+        ) {
+            node.children.forEach(subNode => {
+                if (subNode.children && subNode.children.length) {
+                    subNode.children.forEach(subSubNode => {
+                        if (subSubNode.data.required) {
+                            hasRequire = true;
+                        }
+                    })
+                } else {
+                    subNode.children.forEach(subSubNode => {
+                        hasRequire = hasRequireData(subSubNode.children);
+                    })
+                }
+            })
+        }
+        return hasRequire;
+    }
+
+    // 这里判断有无无定额的情况,有的就返回true,没有就返回false
+    function isRequireData(node) {
+        let isRequired = true;
+        if (node.children && node.children.length) {
+            node.children.forEach(subNode => {
+                if (!subNode.children || !subNode.children.length) {
+                    isRequired = false;
+                }
+            })
+        }
+        return isRequired;
+    }
+    // 获取选套定额
+    function getOptionalData(node, list = []) {
+        node.children.forEach(element => {
+            if (element.children && element.children.length) {
+                element.children.forEach(item => {
+                    if (item.data.rationID) {
+                        list.push(item.data.rationID);
+                    } else if (isProcessNode(item)) {
+                        getOptionalData(item, list)
+                    }
+                })
+            }
+        });
+        return list;
+    }
+
+    // 获取最底层的定额
+    // 只判断必套的和最简单的情况,选套的还没加
+    function getSubData(nodes, requireRation = [], optionalRation = []) {
+        nodes.forEach(node => {
+            if (node.children && node.children.length > 0) {
+                // node为白色,儿子为蓝色
+                if (isProcessNode(node.children[0])) {
+                    getSubData(node.children, requireRation, optionalRation);
+                } else {
+                    // node为蓝色
+                    const nodeRation = [];
+                    // 判断当前蓝色节点有没有打勾必填,有就再走一次遍历,没有就下一步判断
+                    if (hasRequireData(node)) {
+                        // 获取必套的逻辑
+                        getSubData(node.children, requireRation, optionalRation);
+                    } else {
+                        // 判断当前蓝色节点下有没有无定额的情况,存在无定额的就下面全是选套,无无定额的情况就下面全是必套
+                        if (isRequireData(node)) {
+                            node.children.forEach((subNode) => {
+                                if (subNode.children && subNode.children[0] && subNode.children[0].data.rationID) {
+                                    nodeRation.push(subNode.children[0].data.rationID);
+                                } else {
+                                    getSubData(subNode.children, requireRation, optionalRation);
+                                }
+                            })
+                        } else {
+                            // 这里是选套的逻辑
+                            optionalRation.push(...getOptionalData(node));
+                        }
+                    }
+                    if (nodeRation.length) requireRation.push(nodeRation);
+                }
+            }
+        })
+        return { requireRation, optionalRation };
+    }
 // 从指引节点,获取分类特征、必套定额数据
 function getItemClassData(nodes, prefix) {
-    const processNodes = nodes.filter(node => isProcessNode(node));
-    const classGroups = []; // 同层必填选项的数组(二维数组)
-    processNodes.forEach(processNode => {
-        const classItems = [];
-        const optionNodes = processNode.children.filter(node => isOptionNode(node));
-        optionNodes.forEach(optionNode => {
-            if (optionNode.parent && optionNode.parent.data.required && (!optionNode.children 
-                || !optionNode.children.length 
-                || (optionNode.children[0].data && optionNode.children[0].data.rationID) 
-                || !optionNode.children.some(node => isProcessNode(node)))) {
-                // 必套定额
-                const requiredRationIDs = optionNode.children && optionNode.children.length ?
-                    optionNode.children.filter(node => !!node.data.rationID).map(node => node.data.rationID) : [];
-                classItems.push({ name: optionNode.data.name, requiredRationIDs });
-            } else {
-                const childrenClassItem = getItemClassData(optionNode.children, optionNode.parent && optionNode.parent.data.required ? optionNode.data.name : '');
-                //如果返回的子项为空,但是父项又勾选了必填,则要把本身存入数组
-                if(optionNode.parent && optionNode.parent.data.required && childrenClassItem.length === 0){
-                    classItems.push({ name: optionNode.data.name, requiredRationIDs:[] });
-                }else{
-                    classItems.push(...childrenClassItem);
-                }    
+    let nodeRequireRation = [];
+        let optionalRationList = [];
+        const processNodes = nodes.filter(node => isProcessNode(node));
+        const classGroups = []; // 同层必填选项的数组(二维数组)
+        processNodes.forEach(processNode => {
+            const classItems = [];
+            const optionNodes = processNode.children.filter(node => isOptionNode(node));
+            optionNodes.forEach(optionNode => {
+                // const name = prefix ? `${prefix}@${optionNode.data.name}` : optionNode.data.name;
+                if (optionNode.parent && optionNode.parent.data.required && (!optionNode.children
+                    || !optionNode.children.length
+                    || (optionNode.children[0].data && optionNode.children[0].data.rationID)
+                    || !optionNode.children.some(node => isProcessNode(node)))) {
+
+                    // 必套定额
+                    const requiredRationIDs = optionNode.children && optionNode.children.length ?
+                        optionNode.children.filter(node => !!node.data.rationID).map(node => node.data.rationID) : [];
+                    classItems.push({ name: optionNode.data.name, requiredRationIDs: [requiredRationIDs], optionalRationIDs: [] });
+
+                } else {
+                   
+                    if (optionNode.parent&& optionNode.parent.data.required) {
+                        //这里就开始遍历必填项下面的节点
+                        const { requireRation, optionalRation } = getSubData([optionNode]);
+                        nodeRequireRation = requireRation;
+                        optionalRationList = optionalRation;
+                    }else {
+                        // 非必填的蓝色节点
+                        // 子项是否有勾中必填
+                       if( hasRequireData(optionNode.parent)){
+                           // 获取必套的逻辑
+                           const { requireRation, optionalRation }= getSubData([optionNode.parent]);
+                           nodeRequireRation = requireRation;
+                           optionalRationList = optionalRation;
+                       }else{
+                        // 子项没有勾中必填
+                        // 判断当前蓝色节点下有没有无定额的情况,存在无定额的就下面全是选套,无无定额的情况就下面全是必套
+                        if (isRequireData(optionNode.parent)) {
+                            optionNode.children.forEach((subNode) => {
+                                if (subNode.children && subNode.children[0] && subNode.children[0].data.rationID) {
+                                    nodeRation.push(subNode.children[0].data.rationID);
+                                } else {
+                                    getSubData(subNode.children);
+                                }
+                            })
+                        } else {
+                            
+                            // 这里是选套的逻辑
+                            if(optionNode.children&&optionNode.children.length){
+                                optionalRationList.push(...getOptionalData(optionNode.parent));
+                            }
+                            
+                        }
+                       }
+                    }
+
+                    // classItems.push(...getItemCharacterData(optionNode.children, optionNode.parent && optionNode.parent.data.required ? optionNode.data.name : ''));
+                    const childrenClassItem = getItemCharacterData(optionNode.children, optionNode.parent && optionNode.parent.data.required ? optionNode.data.name : '');
+
+                    //如果返回的子项为空,但是父项又勾选了必填,则要把本身存入数组
+                    if (optionNode.parent
+                        && optionNode.parent.data.required
+                        && childrenClassItem.length === 0
+                    ) {
+                        classItems.push({ name: optionNode.data.name, requiredRationIDs: nodeRequireRation, optionalRationIDs: optionalRationList });
+                    } else {
+                        if (childrenClassItem.length > 0) {
+                           
+                            childrenClassItem.map(item => {
+                                item.requiredRationIDs =nodeRequireRation;
+                                item.optionalRationIDs = optionalRationList;
+                            })
+                        }
+                        classItems.push(...childrenClassItem);
+                    }
+                }
+            });
+            if (classItems.length) {
+                classGroups.push(classItems);
+
             }
         });
-        if (classItems.length) {
-            classGroups.push(classItems);
+        // 拼接上一文本
+        if (classGroups[0] && classGroups[0].length) {
+            // classGroups[0] = classGroups[0].map(name => prefix ? `${prefix}@${name}` : name);
+            classGroups[0] = classGroups[0].map(item => {
+                item.name = prefix ? `${prefix}@${item.name}` : item.name
+                return item;
+            });
         }
-    });
-    // 拼接上一文本
-    if (classGroups[0] && classGroups[0].length) {
-      
-        classGroups[0] = classGroups[0].map(item => {
-            item.name = prefix ? `${prefix}@${item.name}` : item.name
-            return item;
-        });
-    }
-    // 二维数组内容排列组合
-    while (classGroups.length > 1) {
-        const prevClassItems = classGroups[0];
-        const nextClassItems = classGroups[1];
-        const mergedClassItems = [];
-        for (let i = 0; i < prevClassItems.length; i++) {
-            for (let j = 0; j < nextClassItems.length; j++) {
-                // 拼接文本
-                const mergedName = `${prevClassItems[i].name}@${nextClassItems[j].name}`;
-                // 拼接必套定额
-                const mergedRationIDs = [...prevClassItems[i].requiredRationIDs, ...nextClassItems[j].requiredRationIDs];
-                mergedClassItems.push({name: mergedName, requiredRationIDs: mergedRationIDs});
+        // 二维数组内容排列组合
+        while (classGroups.length > 1) {
+            const prevClassItems = classGroups[0];
+            const nextClassItems = classGroups[1];
+            const mergedClassItems = [];
+            for (let i = 0; i < prevClassItems.length; i++) {
+                for (let j = 0; j < nextClassItems.length; j++) {
+                    // 拼接文本
+                    const mergedName = `${prevClassItems[i].name}@${nextClassItems[j].name}`;
+                    // 拼接必套定额
+                    const mergedRationIDs = [...prevClassItems[i].requiredRationIDs, ...nextClassItems[j].requiredRationIDs];
+                    const mergedOptionalRationIDs = [...prevClassItems[i].optionalRationIDs, ...nextClassItems[j].optionalRationIDs]
+
+                    mergedClassItems.push({ name: mergedName, requiredRationIDs: mergedRationIDs, optionalRationIDs: mergedOptionalRationIDs });
+                }
             }
+            classGroups.splice(0, 2, mergedClassItems);
         }
-        classGroups.splice(0, 2, mergedClassItems);
-    }
-    // 去重(类别别名要唯一)
-    const items = classGroups[0] || [];
-    const nameMap = {};
-    const rst = [];
-    items.forEach(item => {
-        if (!nameMap[item.name]) {
-            rst.push(item);
-        }
-        nameMap[item.name] = true;
-    });
-    return rst;
+        // 去重(类别别名要唯一)
+        const items = classGroups[0] || [];
+        const nameMap = {};
+        const rst = [];
+        items.forEach(item => {
+            if (!nameMap[item.name]) {
+                rst.push(item);
+            }
+            nameMap[item.name] = true;
+        });
+        return rst;
 }
 
 // 获取选套定额:把所有分类数据的必套定额确定好了先。选套定额就是清单下所有定额除了必套的
@@ -613,7 +758,7 @@ async function generateClassData(libID) {
         const itemClassData = getItemClassData(guidanceTree.roots); // 必套定额在这个方法内就获取了,避免重复执行递归方法
         const allRationIDs = guidanceTree.items.filter(node => !!node.data.rationID).map(node => node.data.rationID);
         // 选套定额ID
-        const optionalRationIDs = getOptionalRationIDs(itemClassData, allRationIDs);
+        // const optionalRationIDs = getOptionalRationIDs(itemClassData, allRationIDs);
         //if(itemClassData.length > 1000) console.log('getItemClassData end',billNode.data.name,billNode.data.code,billNode.data.ID,itemClassData.length)
         itemClassData.forEach(item => {
             // 错套定额
@@ -627,7 +772,7 @@ async function generateClassData(libID) {
                 name: billNode.data.name,
                 code: billNode.data.code,
                 requiredRationIDs: item.requiredRationIDs || [],
-                optionalRationIDs,
+                optionalRationIDs:item.optionalRationIDs || [],
                 errorRationIDs,
             });
         });