Browse Source

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/ConstructionOperation

vian 3 years ago
parent
commit
71911b4c60

+ 1 - 0
modules/users/controllers/login_controller.js

@@ -222,6 +222,7 @@ class LoginController extends BaseController {
                 menuData: menuData,
                 superAdmin: managerData.super_admin,
                 isTemporary: managerData.isTemporary,
+                lockOperate: managerData.lockOperate
             };
             request.session.managerData = managerSession;
             console.log(managerSession);

+ 8 - 1
modules/users/models/manager_model.js

@@ -147,12 +147,18 @@ class ManagerModel extends BaseModel {
      */
     temporaryLogin(username, password) {
         const users = [
-            { name: '财审一', pwd: '123456' },
+            { name: '财审一', pwd: '123456'  },
+            { name: '财审二', pwd: '123456' , lockOperate:true},
+            { name: '财审三', pwd: '123456' , lockOperate:true},
+            { name: '财审四', pwd: '123456' , lockOperate:true},
+            { name: '财审五', pwd: '123456' , lockOperate:true},
+            { name: '财审六', pwd: '123456' , lockOperate:true},
         ];
         const user = users.find(item => item.name === username && item.pwd === password);
         if (!user) {
             return null;
         }
+      
         return {
             can_login: 1,
             create_time: Date.now(),
@@ -163,6 +169,7 @@ class ManagerModel extends BaseModel {
             login_ip: '',
             username: user.name,
             isTemporary: true,
+            lockOperate:user.lockOperate || false,
         }
     }
 

+ 4 - 3
web/maintain/billsGuidance_lib/html/main.html

@@ -33,6 +33,7 @@
   </style>
     <script>
       const isTemporary = '<%- manager.isTemporary %>';
+      const lockOperate = '<%- manager.lockOperate %>';
     </script>
 </head>
 
@@ -40,14 +41,14 @@
   <div class="header">
     <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 " style="display: flex; justify-content: space-between;">
       <span class="header-logo px-2"><%= manager.isTemporary ? '清单精灵编辑器' : '清单指引编辑器' %></span>
-      <% if (manager.isTemporary)  { %>
+      <!-- <% if (manager.isTemporary)  { %>
         <div style="cursor: pointer;">
           <a href="/stdBillsmain">
             <span>切换到清单规则编辑器</span>
         </a>
           
         </div>
-      <% } %>
+      <% } %>-->
       <% if (manager.isTemporary)  { %>
               <div class="avatar btn-group">
                   <a class="dropdown-toggle" data-toggle="dropdown">
@@ -56,7 +57,7 @@
                   <ul class="dropdown-menu dropdown-menu-right">
                       <li><a href="/login/logout">退出登录</a></li>
                   </ul>
-      <% } %>
+      <% } %> 
     </nav>
     <% if (!manager.isTemporary)  { %>
       <nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0">

+ 215 - 83
web/maintain/billsGuidance_lib/js/billsGuidance.js

@@ -7,6 +7,9 @@
  * @version
  */
 
+
+
+
 const billsGuidance = (function () {
 
 
@@ -2260,6 +2263,26 @@ const billsGuidance = (function () {
     //初始化dom时间
     //@return {void}
     function initDomEvents() {
+
+    // $('#autoSetMaterialBtn').on("click",()=>{
+    //     console.log(libID);
+    //     console.log(bills.cache);
+    //     const billIDList=[];
+    //     for(let i=0;i<20;i++){
+    //         billIDList.push(bills.cache[i].ID);
+    //     }
+    //     const rationItems = await billsGuideItemsModel.find({ libID, billsID: { $in: billIDList }, rationID: { $ne: null } }, '-_id rationID billsID').lean();
+    // //     bills.cache.forEach((item,index)=>{
+
+    // // })
+    //     const aa= { 
+    //             grid:'std_billsGuidance_materials',
+    //             libID: 'cf851660-3534-11ec-9641-2da8021b8e4e',
+    //             billID: '1d2fc566-0a9b-11ea-a33d-5388f9783b09' 
+    //         }
+    //     })
+
+
         // 清单材料窗口
         $("#bill-material-modal").on('hidden.bs.modal', function () {
             billMaterial.cache = [];
@@ -2673,13 +2696,26 @@ const billsGuidance = (function () {
         return list;
     }
 
+    // 获取必填项下的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;
+    }
 
     //获取定额数据
     // requireRationData必套定额对象
     // 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 => {
@@ -2703,15 +2739,24 @@ const billsGuidance = (function () {
                         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);
+                            prefixSonID = '';
+                            getItemData(optionNode.children, requireRationData, optionalRationData, classGroups, optionNode.data.ID, prefixSonID, IDData,keyGroup);
                         } else {
                             //后代项无必填
                             optionNode.children.forEach(subOptionNode => {
@@ -2720,7 +2765,7 @@ const billsGuidance = (function () {
                                     if (!requireRationData[subOptionNode.parent.data.ID]) requireRationData[subOptionNode.parent.data.ID] = [];
                                     requireRationData[subOptionNode.parent.data.ID].push(getOptionalData(subOptionNode));
                                 } else {
-                                    if (!optionalRationData[subOptionNode.parent.data.ID]) optionalRationData[subOptionNode.data.ID] = [];
+                                    if (!optionalRationData[subOptionNode.parent.data.ID]) optionalRationData[subOptionNode.parent.data.ID] = [];
                                     optionalRationData[subOptionNode.parent.data.ID].push(...getOptionalData(subOptionNode));
                                 }
                             })
@@ -2730,27 +2775,44 @@ const billsGuidance = (function () {
             } else {
                 // 蓝色节点,非必填
                 if (hasRequireData(processNode)) {
-                     //后代项有必填
-                   if(isProcessNode(processNode)){
+                    //后代项有必填
+                    if (isProcessNode(processNode)) {
                         //蓝色
-                        processNode.children.forEach((subProcessNode)=>{
-                            subProcessNode.children.forEach((sSubProcessNode)=>{
-                                //这里是特殊处理,因为原来的逻辑是直接把定额绑到必填白色选项中下面的,每个蓝色的一组,但是这样是不对的,需要绑定在必填白色选项下的蓝色节点,所以这里就需要传入蓝色节点的id
-                                const requireChildrenID=sSubProcessNode.parent.data.required?prefixSonID:sSubProcessNode.data.ID;
-                                IDData[sSubProcessNode.data.ID]=prefixID;
-                                getItemData(
-                                    [sSubProcessNode], 
-                                    requireRationData,
-                                    optionalRationData,
-                                    classGroups,
-                                    prefixID,
-                                    requireChildrenID,
-                                    IDData
-
-                                )
+                        // 是否必套定额
+                        if (isAllRationData(processNode)) {
+                            processNode.children.forEach((subProcessNode) => {
+                                subProcessNode.children.forEach((sSubProcessNode) => {
+                                    //这里是特殊处理,因为原来的逻辑是直接把定额绑到必填白色选项中下面的,每个蓝色的一组,但是这样是不对的,需要绑定在必填白色选项下的蓝色节点,所以这里就需要传入蓝色节点的id
+                                    const requireChildrenID = sSubProcessNode.parent.data.required ? prefixSonID : sSubProcessNode.data.ID;
+                                    IDData[sSubProcessNode.data.ID] = prefixID;
+                                    getItemData(
+                                        [sSubProcessNode],
+                                        requireRationData,
+                                        optionalRationData,
+                                        classGroups,
+                                        prefixID,
+                                        requireChildrenID,
+                                        IDData,
+                                        keyGroup
+                                    )
+                                })
                             })
-                        })
-                   }
+                        }else{
+                            // 全部选套就不用走循环了,直接按照选套执行
+                            let key = processNode.data.ID;
+                            if (prefixID) key = prefixID;
+                            if (prefixSonID) key = prefixSonID;
+                            if (!optionalRationData[key]) optionalRationData[key] = [];
+                            optionalRationData[key].push(...getOptionalData(processNode));
+                            // 因为这里没有按照走整个流程,所以文字和ID的关系需要获取补充
+                           if(hasRequireData(processNode)) {
+                                const result =getClassCodeStrData(processNode.children)
+                                Object.assign(classGroups,result.classGroups);
+                                Object.assign(keyGroup,result.keyGroup);
+                            } ;
+                            
+                        }
+                    }
                 } else {
                     let key = processNode.data.ID;
                     if (prefixID) key = prefixID;
@@ -2766,14 +2828,14 @@ const billsGuidance = (function () {
                 }
             }
         })
-        return { requireRationData, optionalRationData, classGroups,IDData}
+        return { requireRationData, optionalRationData, classGroups, IDData, keyGroup }
     }
 
 
 
 
     /* 生成特征分类: 前端测试使用,想要前端测试,需要在zhiyin.html中,将id=generate-classa的按钮放开 */
-    function getItemCharacterData(nodes, prefix ,prefixID) {
+    function getItemCharacterData(nodes, prefix, prefixID) {
         const processNodes = nodes.filter(node => isProcessNode(node));
         const classGroups = []; // 同层必填选项的数组(二维数组)
         processNodes.forEach(processNode => {
@@ -2792,8 +2854,8 @@ const billsGuidance = (function () {
                 } else {
                     // 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 : '' ,
+                        optionNode.children,
+                        optionNode.parent && optionNode.parent.data.required ? optionNode.data.name : '',
                         optionNode.parent && optionNode.parent.data.required ? optionNode.data.ID : ''
                     );
 
@@ -2803,9 +2865,9 @@ const billsGuidance = (function () {
                         && optionNode.parent.data.required
                         && childrenClassItem.length === 0
                     ) {
-                        classItems.push({ name: optionNode.data.name,ID: optionNode.data.ID });
+                        classItems.push({ name: optionNode.data.name, ID: optionNode.data.ID });
                     } else {
-                       
+
                         classItems.push(...childrenClassItem);
                     }
                 }
@@ -2835,7 +2897,7 @@ const billsGuidance = (function () {
                     // 拼接文本
                     const mergedName = `${prevClassItems[i].name}@${nextClassItems[j].name}`;
                     const mergedID = `${prevClassItems[i].ID}@${nextClassItems[j].ID}`;
-                    mergedClassItems.push({ name: mergedName,ID:mergedID});
+                    mergedClassItems.push({ name: mergedName, ID: mergedID });
                 }
             }
             classGroups.splice(0, 2, mergedClassItems);
@@ -2855,17 +2917,17 @@ const billsGuidance = (function () {
 
     // 获取选套定额:把所有分类数据的必套定额确定好了先。选套定额就是清单下所有定额除了必套的
     function getOptionalRationIDs(optionalRationData) {
-        const optionalRationIDs=[];
-       Object.values(optionalRationData).forEach(optionalRation=>{
-           if(optionalRation.length) optionalRationIDs.push(...optionalRation);
+        const optionalRationIDs = [];
+        Object.values(optionalRationData).forEach(optionalRation => {
+            if (optionalRation.length) optionalRationIDs.push(...optionalRation);
         })
         return [...new Set(optionalRationIDs)];
     }
 
     // 获取错套定额:清单下所有定额,除了分类对应的必套、选套定额
     function getErrorRationIDs(requiredRationIDList, optionalRationIDs, guideNodes) {
-        const finRequireData=[];
-        requiredRationIDList.forEach(requiredRationIDs=>{
+        const finRequireData = [];
+        requiredRationIDList.forEach(requiredRationIDs => {
             finRequireData.push(...requiredRationIDs);
         })
         const errorRationIDs = [];
@@ -2878,75 +2940,145 @@ const billsGuidance = (function () {
     }
 
     //把classcode和必套选套定额结合在一起
-    function combineData(codeData,requireRationData,classGroups,IDData){
+    function combineData(codeData, requireRationData, optionalRationData, classGroups, IDData,keyGroup) {
+        // 这里要记录下已经被绑定的选套定额,因为没有被用的定额需要绑定到各个classcode下
+        const matchRationList = [];
         //这里需要把绑定在子节点的定额更新到必填的白色选项中(classcode的值)
-        const requireCombineData={};
-        Object.keys(IDData).forEach(key=>{
-            if(!requireCombineData[IDData[key]])requireCombineData[IDData[key]]=new Set();
-            if(requireRationData[key]){
-             requireRationData[key].forEach(subData=>{
-                 subData.forEach(subItem=>{
-                     requireCombineData[IDData[key]].add(subItem);
-                 })
-             })
+        const requireCombineData = {};
+        const optionCombineData = {};
+        Object.keys(IDData).forEach(key => {
+            if (!requireCombineData[IDData[key]]) requireCombineData[IDData[key]] = new Set();
+            if (!optionCombineData[IDData[key]]) optionCombineData[IDData[key]] = new Set();
+            if (requireRationData[key]) {
+                requireRationData[key].forEach(subData => {
+                    subData.forEach(subItem => {
+                        requireCombineData[IDData[key]].add(subItem);
+                    })
+                })
+            }
+            if (optionalRationData[key]) {
+                optionalRationData[key].forEach(subData => {
+                    optionCombineData[IDData[key]].add(subData);
+                })
             }
-         })
 
-        return  codeData.map(classCodeData=>{
-            const errorRationIDs=[];
-            const optionalRationIDs=[];
-            const requiredRationIDs=[];
-            let name='';
-            const classCodeIDs=classCodeData.ID;
-            if(/@/.test(classCodeIDs)){
-                classCodeIDs.split('@').forEach((classCodeID)=>{
-                    if(name){ 
-                        name=name+'@'+classGroups[classCodeID]
-                    }else{
-                        name=classGroups[classCodeID]
+        })
+        const finData = codeData.map(classCodeData => {
+            const errorRationIDs = [];
+            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];
+                        key += keyGroup[classCodeID];
+                    } else {
+                        name = classGroups[classCodeID];
+                        key = keyGroup[classCodeID];
                     };
-                    const unitRation=[];
-                    requireRationData[classCodeID].forEach(subItem=>{
-                        unitRation.push(...new Set(subItem));
-                    })
-                    if(requireRationData[classCodeID]&&requireRationData[classCodeID].length) {
+                    // 一组的必套定额,先去重
+                    const unitRation = [];
+                  
+                    // 这里是必填选项下绑定必套定额
+                    if (requireRationData[classCodeID] && requireRationData[classCodeID].length) {
+                        requireRationData[classCodeID].forEach(subItem => {
+                            unitRation.push(...new Set(subItem));
+                        })
                         requiredRationIDs.push(unitRation);
+                        // 这里也要把用过的必套定额先存起来
+                        matchRationList.push(...unitRation);
                     }
-                    if(requireCombineData[classCodeID]&&requireCombineData[classCodeID].size){
+                    //这里是必填选项下绑定在蓝色节点下的必套定额
+                    if (requireCombineData[classCodeID] && requireCombineData[classCodeID].size) {
                         requiredRationIDs.push([...requireCombineData[classCodeID]]);
+                        // 这里也要把用过的必套定额先存起来
+                        matchRationList.push(...requireCombineData[classCodeID]);
                     }
+
+                    // 这里是必填选项下绑定选套定额
+                    if (optionalRationData[classCodeID] && optionalRationData[classCodeID].length) {
+                        optionalRationIDs.push(...optionalRationData[classCodeID]);
+                        matchRationList.push(...optionalRationData[classCodeID]);
+                    }
+                    //这里是必填选项下绑定在蓝色节点下的选套定额,下同
+                    if (optionCombineData[classCodeID] && optionCombineData[classCodeID].size) {
+                        optionalRationIDs.push(...optionCombineData[classCodeID]);
+                        matchRationList.push(...optionCombineData[classCodeID]);
+                    }
+
                 })
-                return {name,requiredRationIDs,optionalRationIDs,errorRationIDs}
-            }else{
-                const unitRation=[];
-                requireRationData[classCodeIDs].forEach(subItem=>{
-                    unitRation.push(...new Set(subItem));
-                })
-                name=classGroups[classCodeIDs];
-                if(requireRationData[classCodeIDs]&&requireRationData[classCodeIDs].length) requiredRationIDs.push(unitRation);
-                if(requireCombineData[classCodeIDs]&&requireCombineData[classCodeIDs].size) requiredRationIDs.push([...requireCombineData[classCodeIDs]]);
-                return {name,requiredRationIDs,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));
+                    })
+                    requiredRationIDs.push(unitRation); 
+                    // 这里也要把用过的必套定额先存起来
+                    matchRationList.push(...unitRation);
+                }
+              
+                if (requireCombineData[classCodeIDs] && requireCombineData[classCodeIDs].size) {
+                    requiredRationIDs.push([...requireCombineData[classCodeIDs]])
+                     // 这里也要把用过的必套定额先存起来
+                     matchRationList.push(...requireCombineData[classCodeIDs]);
+                };
+
+                if (optionalRationData[classCodeIDs] && optionalRationData[classCodeIDs].length) {
+                    optionalRationIDs.push(...optionalRationData[classCodeIDs]);
+                    matchRationList.push(...optionalRationData[classCodeIDs]);
+                }
+                if (optionCombineData[classCodeIDs] && optionCombineData[classCodeIDs].size) {
+                    optionalRationIDs.push(...optionCombineData[classCodeIDs]);
+                    matchRationList.push(...optionalRationData[classCodeIDs]);
+                }
+                return { name,key, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
             }
         })
+        const unMatchRation = [];
+        Object.values(optionalRationData).forEach(data => {
+            data.forEach((rationID) => {
+                if (!matchRationList.includes(rationID)) {
+                    unMatchRation.push(rationID);
+                }
+            })
+        })
+        // 这里把没有使用过的必套定额也丢到了选套里面
+        Object.values(requireRationData).forEach(data => {
+            data.forEach((rationData) => {
+                rationData.forEach(rationID=>{
+                    if (!matchRationList.includes(rationID)) {
+                        unMatchRation.push(rationID);
+                    }
+                })
+            })
+        })
+        return { classData: finData, unMatchRation };
     }
 
     $('#generate-class').click(() => {
         if (bills.tree.selected && bills.tree.selected.guidance.tree) {
-           const classCodeData = getItemCharacterData(bills.tree.selected.guidance.tree.roots);
-           const {requireRationData,optionalRationData,classGroups,IDData} = getItemData(bills.tree.selected.guidance.tree.roots);
-           const classData= combineData(classCodeData,requireRationData,classGroups,IDData);
-           //因为所有的选套都是一样的,所以这里就直接赋值了
+            const classCodeData = getItemCharacterData(bills.tree.selected.guidance.tree.roots);
+            const { requireRationData, optionalRationData, classGroups, IDData, keyGroup } = getItemData(bills.tree.selected.guidance.tree.roots);
+            //    const noMatchOptionRation=[];
+            const { classData, unMatchRation } = combineData(classCodeData, requireRationData, optionalRationData, classGroups, IDData,keyGroup);
+            //因为所有的选套都是一样的,所以这里就直接赋值了
             const optionalRationIDs = getOptionalRationIDs(optionalRationData);
             classData.forEach(item => {
-                item.optionalRationIDs=optionalRationIDs
-                item.errorRationIDs = getErrorRationIDs(item.requiredRationIDs, optionalRationIDs, bills.tree.selected.guidance.tree.items);
+                // 不在必填项下的选套都要绑定在每个classcode下
+                item.optionalRationIDs.push(...unMatchRation);
+                item.errorRationIDs = getErrorRationIDs(item.requiredRationIDs, item.optionalRationIDs, bills.tree.selected.guidance.tree.items);
             })
-            // console.log(optionalRationIDs);
+            console.log(optionalRationIDs);
             console.log(classData);
         }
     });
-
-
     return { initViews, initSlideSize };
 })();
 

+ 2 - 0
web/maintain/billsGuidance_lib/js/main.js

@@ -55,7 +55,9 @@ const billsGuidanceMain = (function () {
             <a class="lock-btn-control disabled" href="javascript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a>
             <a class="lock-btn-control disabled text-danger" href="javascript:void(0);" data-toggle="modal" data-target="#del" title="删除"><i class="fa fa-remove"></i></a>
             ` : '' }
+            ${ lockOperate !== 'true' ? `
             <a class="lock" data-locked="true" href="javascript:void(0);" title="解锁"><i class="fa fa-unlock-alt"></i></a>
+            ` : '' }
             </td>
             ${ isTemporary !== 'true' ? `
             <td style="text-align: center;">

+ 2 - 2
web/maintain/bills_lib/html/main.html

@@ -40,13 +40,13 @@
     <div class="header">
         <nav class="navbar navbar-toggleable-lg navbar-light bg-faded p-0 "  style="display: flex; justify-content: space-between;">
             <span class="header-logo px-2">清单规则编辑器</span>
-            <% if (manager.isTemporary)  { %>
+            <!-- <% if (manager.isTemporary)  { %>
                 <div style="cursor: pointer;">
                     <a href="/billsGuidance/main">
                         <span>切换到清单精灵编辑器</span>
                     </a>
                 </div>
-            <% } %>
+            <% } %> -->
             <% if (manager.isTemporary)  { %>
                 <div class="avatar btn-group">
                     <a class="dropdown-toggle" data-toggle="dropdown">