Browse Source

清单指引“生成数据”和“导出”新增key字段(清单9位编码+清单名称+清单单位+必填的特征与特征值的组合)

lishihao 3 years ago
parent
commit
7f00c6fc83
2 changed files with 48 additions and 26 deletions
  1. 1 0
      modules/all_models/bill_class.js
  2. 47 26
      modules/std_billsGuidance_lib/facade/facades.js

+ 1 - 0
modules/all_models/bill_class.js

@@ -6,6 +6,7 @@ const Schema = mongoose.Schema;
 const billClass = new Schema({
     compilationID: { type: String, index: true},
     name: String,
+    key: String,
     code: String,
     itemCharacter: String,
     class: { type: Number, index: true }, // 分类

+ 47 - 26
modules/std_billsGuidance_lib/facade/facades.js

@@ -539,18 +539,19 @@ function getOptionalData(node, list = []) {
     return list;
 }
 
-    // 获取必填项下的ID和name的键值对
-    function getClassCodeStrData(nodes,data={}){
-        nodes.forEach(node=>{
-           if (isProcessNode(node)&&node.data.required) {
-               node.children.forEach(subNode=>{
-                   data[subNode.data.ID]=subNode.data.name;  
-               })
-           }
-           getClassCodeStrData(node.children,data);
-        })
-       return data;
-   }
+  // 获取必填项下的ID和name的键值对
+  function getClassCodeStrData(nodes,data={classGroups:{},keyGroup:{}}){
+    nodes.forEach(node=>{
+       if (isProcessNode(node)&&node.data.required) {
+           node.children.forEach(subNode=>{
+               data.classGroups[subNode.data.ID]=subNode.data.name;  
+               data.keyGroup[subNode.data.ID]=`${subNode.parent.data.name}:${subNode.data.name}`; 
+           })
+       }
+       getClassCodeStrData(node.children,data);
+    })
+   return data;
+}
 
 
 //获取定额数据
@@ -558,7 +559,7 @@ function getOptionalData(node, list = []) {
     // optionalRationData 选逃定额对象
     // classGroups classCode文字和id键值对
     // classCodeList 各个classCode的pID和ID的关系
-function getItemData(nodes, requireRationData = {}, optionalRationData = {}, classGroups = {}, prefixID = '', prefixSonID = '', IDData = {}) {
+function getItemData(nodes, requireRationData = {}, optionalRationData = {}, classGroups = {}, prefixID = '', prefixSonID = '', IDData = {}, keyGroup={}) {
     const processNodes = nodes.filter(node => isProcessNode(node));
     // const classGroups = []; // 同层必填选项的数组(二维数组)
     processNodes.forEach(processNode => {
@@ -582,15 +583,23 @@ function getItemData(nodes, requireRationData = {}, optionalRationData = {}, cla
                     const kV = {};
                     kV[optionNode.data.ID] = optionNode.data.name;
                     Object.assign(classGroups, kV);
+
+                    const keyData={};
+                    keyData[optionNode.data.ID] = `${optionNode.parent.data.name}:${optionNode.data.name}`;
+                    Object.assign(keyGroup,keyData);
                 } else {
                     const kV = {};
                     kV[optionNode.data.ID] = optionNode.data.name;
                     Object.assign(classGroups, kV);
+
+                    const keyData={};
+                    keyData[optionNode.data.ID] = `${optionNode.parent.data.name}:${optionNode.data.name}`;
+                    Object.assign(keyGroup,keyData);
                     // 后代项是否有必填
                     if (hasRequireData(optionNode)) {
                         //后代项有必填
                         prefixSonID = '';
-                        getItemData(optionNode.children, requireRationData, optionalRationData, classGroups, optionNode.data.ID, prefixSonID, IDData);
+                        getItemData(optionNode.children, requireRationData, optionalRationData, classGroups, optionNode.data.ID, prefixSonID, IDData, keyGroup);
                     } else {
                         //后代项无必填
                         optionNode.children.forEach(subOptionNode => {
@@ -626,7 +635,8 @@ function getItemData(nodes, requireRationData = {}, optionalRationData = {}, cla
                                     classGroups,
                                     prefixID,
                                     requireChildrenID,
-                                    IDData
+                                    IDData,
+                                    keyGroup
 
                                 )
                             })
@@ -639,7 +649,11 @@ function getItemData(nodes, requireRationData = {}, optionalRationData = {}, cla
                        if (!optionalRationData[key]) optionalRationData[key] = [];
                        optionalRationData[key].push(...getOptionalData(processNode));
                        // 因为这里没有按照走整个流程,所以文字和ID的关系需要获取补充
-                      if(hasRequireData(processNode))  Object.assign(classGroups,getClassCodeStrData(processNode.children)) ;
+                      if(hasRequireData(processNode)){
+                        const result =getClassCodeStrData(processNode.children)
+                        Object.assign(classGroups,result.classGroups);
+                        Object.assign(keyGroup,result.keyGroup);
+                      }  
                     }
                 }
             } else {
@@ -657,7 +671,7 @@ function getItemData(nodes, requireRationData = {}, optionalRationData = {}, cla
             }
         }
     })
-    return { requireRationData, optionalRationData, classGroups, IDData }
+    return { requireRationData, optionalRationData, classGroups, IDData, keyGroup}
 }
 
 
@@ -768,7 +782,7 @@ function getErrorRationIDs(requiredRationIDList, optionalRationIDs, allRationIDs
 }
 
 //把classcode和必套选套定额结合在一起
-function combineData(codeData, requireRationData, optionalRationData, classGroups, IDData) {
+function combineData(codeData, requireRationData, optionalRationData, classGroups, IDData, keyGroup) {
     // 这里要记录下已经被绑定的选套定额,因为没有被用的定额需要绑定到各个classcode下
     const matchRationList = [];
     //这里需要把绑定在子节点的定额更新到必填的白色选项中(classcode的值)
@@ -796,13 +810,16 @@ function combineData(codeData, requireRationData, optionalRationData, classGroup
         const optionalRationIDs = [];
         const requiredRationIDs = [];
         let name = '';
+        let key = ''; 
         const classCodeIDs = classCodeData.ID;
         if (/@/.test(classCodeIDs)) {
             classCodeIDs.split('@').forEach((classCodeID) => {
                 if (name) {
-                    name = name + '@' + classGroups[classCodeID]
+                    name = name + '@' + classGroups[classCodeID];
+                    key += keyGroup[classCodeID];
                 } else {
-                    name = classGroups[classCodeID]
+                    name = classGroups[classCodeID];
+                    key = keyGroup[classCodeID];
                 };
                 // 一组的必套定额,先去重
                 const unitRation = [];
@@ -835,10 +852,11 @@ function combineData(codeData, requireRationData, optionalRationData, classGroup
                 }
 
             })
-            return { name, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
+            return { name, key, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
         } else {
             const unitRation = [];
             name = classGroups[classCodeIDs];
+            key = keyGroup[classCodeIDs];
             if (requireRationData[classCodeIDs] && requireRationData[classCodeIDs].length){
                 requireRationData[classCodeIDs].forEach(subItem => {
                     unitRation.push(...new Set(subItem));
@@ -862,7 +880,7 @@ function combineData(codeData, requireRationData, optionalRationData, classGroup
                 optionalRationIDs.push(...optionCombineData[classCodeIDs]);
                 matchRationList.push(...optionalRationData[classCodeIDs]);
             }
-            return { name, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
+            return { name,key, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
         }
     })
     const unMatchRation = [];
@@ -899,7 +917,7 @@ async function generateClassData(libID) {
     guidanceItems.forEach(item => {
         (guidanceMap[item.billsID] || (guidanceMap[item.billsID] = [])).push(item);
     });
-    const bills = await stdBillsModel.find({ billsLibId: lib.billsLibId }, '-_id ID ParentID NextSiblingID name code').lean();
+    const bills = await stdBillsModel.find({ billsLibId: lib.billsLibId }, '-_id ID ParentID NextSiblingID name code unit').lean();
     const billTree = idTree.createNew({ id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true });
     billTree.loadDatas(bills);
     // 叶子清单
@@ -917,9 +935,9 @@ async function generateClassData(libID) {
         guidanceTree.loadDatas(guidanceItems);
         //console.log('getItemClassData start',billNode.data.name,billNode.data.code,billNode.data.ID);
         const classCodeData = getItemClassData(guidanceTree.roots); // 必套定额在这个方法内就获取了,避免重复执行递归方法
-        const { requireRationData, optionalRationData, classGroups, IDData } = getItemData(guidanceTree.roots);
+        const { requireRationData, optionalRationData, classGroups, IDData, keyGroup } = getItemData(guidanceTree.roots);
 
-        const { itemClassData, unMatchRation } = combineData(classCodeData, requireRationData, optionalRationData, classGroups, IDData);
+        const { itemClassData, unMatchRation } = combineData(classCodeData, requireRationData, optionalRationData, classGroups, IDData, keyGroup);
 
         const allRationIDs = guidanceTree.items.filter(node => !!node.data.rationID).map(node => node.data.rationID);
         // 选套定额ID
@@ -935,6 +953,7 @@ async function generateClassData(libID) {
                 classCode: `${billNode.data.code}@${item.name}`,
                 compilationID: lib.compilationId,
                 name: billNode.data.name,
+                key: `${billNode.data.code}${billNode.data.name}${billNode.data.unit}${item.key}`,
                 code: billNode.data.code,
                 requiredRationIDs: item.requiredRationIDs || [],
                 optionalRationIDs: item.optionalRationIDs || [],
@@ -957,6 +976,7 @@ async function generateClassData(libID) {
                 classCode: `${billNode.data.code}`,
                 compilationID: lib.compilationId,
                 name: billNode.data.name,
+                key:`${billNode.data.code}${billNode.data.name}${billNode.data.unit}`,
                 code: billNode.data.code,
                 requiredRationIDs: [],
                 optionalRationIDs: optionalRationIDs || [],
@@ -988,7 +1008,7 @@ async function getClassExcelData(libID) {
     const classData = await billClassModel.find({ compilationID: lib.compilationId }).lean();
     console.log('end');
     console.log(Date.now() - date);
-    const excelData = [['类别', '编码', '清单名称', '必填特征排列组合', '类别别名', '必套定额', '选套定额', '错套定额']];
+    const excelData = [['类别', '编码', '清单名称', '必填特征排列组合', '类别别名', '必套定额', '选套定额', '错套定额','基础样本']];
     classData.forEach(item => {
         const excelItem = [
             item.class,
@@ -999,6 +1019,7 @@ async function getClassExcelData(libID) {
             (item.requiredRationIDs || []).join('@'),
             (item.optionalRationIDs || []).join('@'),
             (item.errorRationIDs || []).join('@'),
+            item.key,
         ];
         excelData.push(excelItem);
     });