/** * 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(); 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){ console.log(data); //要先知道根据期数和编办查找库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 (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; 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); } return {totalSize,items} } 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){ data.condition.name = new RegExp(keyword); let 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 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 items = []; let nameArray = []; if (keyword.length < 3) { nameArray.push(keyword) } else { nameArray = segment.doSegment(keyword, { simple: true, //不返回词性 stripPunctuation: true //去除标点符号 }); } //自定义处理 nameArray = cusSegment(nameArray,keyword); console.log(nameArray); let allInfoPrice = await infoItemsModel.find(data.condition).lean().sort({"_id":1}); let maxNum = 0;//最大匹配数 let matchMap = {};//匹配储存 for (let info of allInfoPrice) { //specs let mstring = info.name + info.spec; mstring = mstring.replace(/混凝土/g, "砼"); info.mstring = mstring; let matchCount = 0; for (let na of nameArray) { if (mstring.indexOf(na) != -1) { matchCount++; } } 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 //按匹配位置排序 如[ '橡胶', '胶圈', '给水' ] 先显示橡胶 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; }