| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 | 
							- /**
 
-  * Created by zhang on 2020/7/20
 
-  */
 
- module.exports={
 
-   getOptions,
 
-   getDataByCondition,
 
-   getClassByAreaID,
 
-   mutiApplyInfoPrice
 
- };
 
- const mongoose = require('mongoose');
 
- let infoLibModel = mongoose.model("std_price_info_lib");
 
- let infoClassModel = mongoose.model("std_price_info_class");
 
- let infoItemsModel = mongoose.model("std_price_info_items");
 
- let infoAreasModel = mongoose.model("std_price_info_areas");
 
- let unitPriceModel = mongoose.model("unit_price"); 
 
- let _ = require("lodash");
 
- let gljUtil = require('../../../public/web/gljUtil');
 
- const scMathUtil = require('../../../public/scMathUtil').getUtil();
 
- let projectfacade = require('./project_facade');
 
- // 载入模块
 
- var Segment = require('segment');
 
- // 创建实例
 
- var segment = new Segment();
 
- // 使用默认的识别模块及字典,载入字典文件需要1秒,仅初始化时执行一次即可
 
- segment.useDefault();
 
- let nodejieba = require('../../dict/jieba');
 
- let nameWeightMap ={ 
 
-  // '普通':-99
 
- }
 
- async function getOptions(data,compilation){//data 是预留对象,暂时不用
 
-   let compilationID = compilation._id;
 
-   let areaMap={};
 
-   let periodMap={};
 
-   let areas =await infoAreasModel.find({"compilationID":compilationID}).lean();
 
-   let libList = await infoLibModel.find({"compilationID":compilationID}).lean();
 
-   for(let l of libList){
 
-     // for(let area of l.areas){
 
-     //   if(!areaMap[area]) areas.push(area);
 
-     // }
 
-     //2020-05
 
-     let periodArray = l.period.split("-");
 
-     periodMap[periodArray[0]]?periodMap[periodArray[0]].push(periodArray[1]):periodMap[periodArray[0]]=[periodArray[1]]
 
-   }
 
-  
 
-  
 
-   for(let key in periodMap){
 
-     periodMap[key] = _.sortBy(periodMap[key]);
 
-   }
 
-   return {areas:areas,periodMap:periodMap}
 
- }
 
- async function getClassByAreaID(data,compilation){
 
-   //要先知道根据期数和编办查找库ID
 
-   let newList = [];
 
-   let lib = await infoLibModel.findOne({compilationID:compilation._id,period:data.period})
 
-   if(lib){
 
-     let tList =await getClassList(data.areaID,lib.ID);
 
-     newList.push(...tList);
 
-     if(data.commonInfoPriceID){
 
-       cList = await getClassList(data.commonInfoPriceID,lib.ID);
 
-       newList.push(...cList);
 
-     }  
 
-   }
 
-   
 
-   async function getClassList(areaID,libID){
 
-     let temList = [];
 
-     let infoClass =  await infoClassModel.find({areaID:areaID,libID:libID}).lean();
 
-     let parentMap=_.groupBy(infoClass, 'ParentID');
 
-     for(let key in parentMap){
 
-       parentMap[key] = projectfacade.sortChildren(parentMap[key]);
 
-     }
 
-     
 
-     if(parentMap && parentMap['-1']){
 
-       getChildern(parentMap['-1'],temList,parentMap)
 
-     }
 
-     return temList;
 
-   }
 
-   function getChildern(children,list,pm){
 
-     for(let c of children){
 
-       list.push(c);
 
-       if(pm[c.ID]){
 
-         getChildern(pm[c.ID],list,pm)
 
-       }
 
-     }
 
-   }
 
-   return newList;
 
- }
 
- async function getDataByCondition(data,compilation){
 
-   let result = {};
 
-   data.condition["compilationID"] = compilation._id;
 
-   //特殊处理重庆的,地区选择非“通用”时,搜索范围应是当前选择的地区,加上“通用”中的信息价。
 
-   if (data.condition.commonInfoPriceID) { 
 
-     let idArray = [data.condition.areaID,data.condition.commonInfoPriceID];
 
-     data.condition.areaID = {$in: idArray}
 
-     delete data.condition.commonInfoPriceID;
 
-   }
 
-   //根据地区+期数+材料编号的前4位与信息价材料的分类编号匹配,如果有数据,则显示数据出来。
 
-   //先按编号匹配
 
-   if (data.code) { 
 
-     result = await getDataByCode(data.code, data);
 
-     if (result.totalSize > 0) return result;
 
-     //如果分类编码有结果,但是确没有匹配的条数,说明关键字没匹配上,直接返回没有信息价
 
-     if(result.allItems > 0 && result.totalSize === 0){
 
-       return result;
 
-     }
 
-   }
 
-  
 
-   //编号匹配不上的情况:
 
-   //有关键字的情况
 
-   if (data.keyWord) { 
 
-     return await getDataByKeyWord(data.keyWord,data);
 
-   } 
 
-   //查询所有的情况
 
-   if(data.lastID){ //有最后一行说明是查询下一页
 
-     data.condition["_id"] = {$gt:mongoose.Types.ObjectId(data.lastID)};
 
-   }else{
 
-     result.totalSize = await infoItemsModel.find(data.condition).count();
 
-   }
 
-   result.items = await infoItemsModel.find(data.condition).lean().sort({"_id":1}).limit(50);
 
-   return result;
 
- }
 
- async function getDataByCode(code, data) { 
 
-   let condition = { ...data.condition };
 
-   condition.code = code;
 
-  /*  
 
-   2021-03-31 先按编号去取,所有匹配结果再过滤,不能再分类了
 
-  let totalSize = await infoItemsModel.find(condition).count();
 
-   if (data.lastID) { //有最后一行说明是查询下一页
 
-     condition["_id"] = {$gt:mongoose.Types.ObjectId(data.lastID)};
 
-   }
 
-   let items = [];
 
-   if (totalSize > 0) { 
 
-     items = await infoItemsModel.find(condition).lean().sort({"_id":1}).limit(50);
 
-   } */
 
-    
 
-  //新需求 --------- 
 
-   let  allItems = await infoItemsModel.find(condition).lean().sort({"_id":1});
 
-   let items = [];
 
-   if(data.keyWord && allItems.length > 1){
 
-     for(let item of allItems){
 
-       if(item.name.indexOf(data.keyWord) != -1) items.push(item) //有完全匹配的,就不用编码下的返回所有数据了
 
-     }
 
-   }
 
-   //没有完全匹配的,分词匹配关键字
 
-   if (items.length === 0){
 
-     let nameArray =  nodejieba.cut(data.keyWord);
 
-     nameArray = cusSegment(nameArray,data.keyWord);
 
-     let result = getMatchPrice(allItems,nameArray);
 
-     items = result.items;
 
-   }
 
-   let totalSize = items.length;
 
-   //新需求结束 --------- 
 
-   return {totalSize,items,allItems}
 
- }
 
- async function getDataByKeyWord(keyword, data) {
 
-   //先按全字匹配
 
-   let fullResult =await getDataByFullKeyWord(keyword, data);
 
-   if(fullResult.totalSize > 0) return fullResult;
 
-   //如果没有才按模糊匹配
 
-  return await getDataByFuzzyMatch(keyword, data);
 
- }
 
- //按全关键字匹配
 
- async function getDataByFullKeyWord(keyword, data){
 
-   let items = [];  
 
-   data.condition.name =  new RegExp(keyword);
 
-   items = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
 
-  
 
-   delete data.condition.name;
 
-   return{totalSize:items.length,items}
 
- }
 
- function handelThreeWord(word){
 
-   let arr = [];
 
-   getArr(word[0]+word[1],arr);
 
-   getArr(word[1]+word[2],arr);
 
-   if(arr.length > 0) return arr;
 
-   return[word];
 
-   function getArr(tem,list){
 
-     let nameArray = segment.doSegment(tem, {
 
-       simple: true, //不返回词性
 
-       stripPunctuation: true //去除标点符号
 
-     });
 
-     //说明是一个词
 
-     if(nameArray.length == 1) list.push(tem)
 
-   }
 
- }
 
- function getShortNameArray(nameArray){
 
-   let newArray = [];
 
-   for(let n of nameArray){
 
-     if(n.length >= 5){
 
-       newArray.push(...nodejieba.cutSmall(n,3)) 
 
-     }else{
 
-       newArray.push(n);
 
-     }
 
-   }
 
-   return newArray;
 
- }
 
- function getMatchPrice(allInfoPrice,nameArray,needHandleLongWord = true){
 
-   let items = [];
 
-   let maxNum = 0;//最大匹配数
 
-   let matchMap = {};//匹配储存
 
-   let handleLongWord = false;
 
-   if(needHandleLongWord){
 
-     for(let na of nameArray){
 
-       if(na.length >= 5) handleLongWord = true;
 
-     }
 
-   }
 
-   
 
-   for (let info of allInfoPrice) { 
 
-     //specs
 
-     let mstring = info.name + info.specs;
 
-     mstring = mstring.replace(/混凝土/g, "砼");
 
-     info.mstring = mstring;
 
-     let matchCount = 0;
 
-     for (let na of nameArray) { 
 
-       if (mstring.indexOf(na) != -1) { 
 
-         matchCount++;
 
-         if(needHandleLongWord && na.length >= 5) handleLongWord = false//有5个字的,并且匹配上了,这里就为false不用再处理一次了
 
-       }
 
-     }  
 
-     if (matchCount > 0) { 
 
-       matchMap[matchCount] ? matchMap[matchCount].push(info) : matchMap[matchCount] = [info];
 
-       if (matchCount > maxNum) maxNum = matchCount;
 
-     }
 
-   }
 
-   if (maxNum > 0) items = matchMap[maxNum];
 
-   totalSize = items.length
 
-   return {totalSize,items,handleLongWord};
 
- }
 
- //自定义特殊处理
 
- function cusSegment(nameArray,keyword){
 
-   let temArr = [];
 
-   for (let a of nameArray) { 
 
-      //混凝土 和 砼 统一认成砼
 
-     if (a == "混凝土") a = '砼';
 
-     if(a == '砼'||a == '砖' ){
 
-       temArr.push(a);
 
-     }else if(a.length > 1){
 
-       //如果是三个字的词,优先识别成两个字
 
-       if(a.length == 3){
 
-         let sArr = handelThreeWord(a);
 
-         temArr.push(...sArr);
 
-       }else{
 
-         temArr.push(a);
 
-       }
 
-     }
 
-   }
 
-   if (keyword.length == 1 && temArr.length == 0) temArr.push(keyword);
 
-   return temArr;
 
- }
 
- //模糊匹配
 
- async function getDataByFuzzyMatch(keyword, data){
 
-   let nameArray = [];
 
-   if (keyword.length < 3) {
 
-     nameArray.push(keyword)
 
-   } else { 
 
-     nameArray = nodejieba.cut(keyword)
 
-   }
 
-  
 
-   //自定义处理
 
-   nameArray = cusSegment(nameArray,keyword);
 
-   console.log(nameArray);
 
-   let allInfoPrice = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
 
-   let {totalSize,items,handleLongWord}  = getMatchPrice(allInfoPrice,nameArray)
 
-   if(handleLongWord === true){
 
-     nameArray = getShortNameArray(nameArray);
 
-     console.log(`二次匹配:[${nameArray}]`);
 
-     let newResult  = getMatchPrice(allInfoPrice,nameArray,false)
 
-     totalSize = newResult.totalSize;
 
-     items = newResult.items;
 
-   }
 
-   //关键词按权重排序,为了给结果排序
 
-   nameArray = _.sortBy(nameArray,(name)=>{
 
-     if(nameWeightMap[name]) return nameWeightMap[name]*-1;//sortBy是升序排序,我们要的是权重越小排到越后即倒序 所以这里乘以-1
 
-     return 1
 
-   })
 
-   //按匹配位置排序 如[ '橡胶', '胶圈', '给水' ] 先显示橡胶
 
-   items = _.sortBy(items,(item)=>{
 
-     let ms = item.mstring;
 
-     for(let i = 0;i < nameArray.length;i ++){
 
-       if (ms.indexOf(nameArray[i]) != -1) return i;
 
-     }
 
-   })
 
-   return {totalSize,items}
 
- }
 
- async function mutiApplyInfoPrice(data,compilation){
 
-   data.condition["compilationID"] = compilation._id;
 
-   let infoPrices = await infoItemsModel.find(data.condition).lean();
 
-   let tasks = [];
 
-   let projectGLJMap = {};
 
-   for(let info of infoPrices){
 
-     let index = gljUtil.getIndex(info,["name","specs","unit"]);
 
-     if(data.pgljMap[index]){
 
-       for(let obj of data.pgljMap[index]){
 
-         let infoPrice = gljUtil.getInfoMarketPrice(info,data.taxType);
 
-         infoPrice = scMathUtil.roundToString(infoPrice,data.decimal);
 
-         let doc = {'market_price':infoPrice,'priceFrom':data.priceFrom};
 
-         let task = {
 
-           updateOne:{
 
-               filter:{'id':obj.unitPriceID},
 
-               update:doc
 
-           }
 
-         };
 
-         tasks.push(task);
 
-         projectGLJMap[obj.pgljID] = {index:obj.fullIndex,doc:doc};
 
-       }  
 
-     }
 
-   }
 
-   if(tasks.length > 0) await unitPriceModel.bulkWrite(tasks);
 
-   return projectGLJMap;
 
- }
 
 
  |