/** * Created by Zhong on 2017/8/22. */ const mongoose = require('mongoose'); const complementaryGljModel = mongoose.model('complementary_glj_lib'); const stdGljModel = mongoose.model('std_glj_lib_gljList'); const gljClassModel = mongoose.model('std_glj_lib_gljClass'); const compleClassModel = mongoose.model('complementary_glj_section'); const _ = require('lodash'); import counter from "../../../public/counter/counter"; import async from "async"; import STDGLJLibGLJListModel from "../../common/std/std_glj_lib_glj_list_model"; const libType = { stdGLJ: 1, complementaryGLJs: 2 }; class GljDao { getGljTypes (gljLibId, callback){ gljClassModel.find({"repositoryId": gljLibId},function(err,data){ if(data.length) { callback(0,data); } else if(err) callback("获取人材机类型错误!",false); }) } _exist(data, attr){ return data && data[attr] !== 'undefined' && data[attr]; } sortToNumber(datas){ for(let i = 0, len = datas.length; i < len; i++){ let data = datas[i]._doc; if(this._exist(data, 'basePrice')){ data['basePrice'] = parseFloat(data['basePrice']); } if(this._exist(data, 'component')){ for(let j = 0, jLen = data['component'].length; j < jLen; j++){ let comGljObj = data['component'][j]._doc; if(this._exist(comGljObj, 'consumeAmt')){ comGljObj['consumeAmt'] = parseFloat(comGljObj['consumeAmt']); } } } } } async getQueryByType (condition) { const { userID, compilationId, gljLibId, code, type, queryExtend, replace, location, classList, search } = condition; let model = null, query = {}, countQuery = {}, matchLocation = false; if (type === libType.stdGLJ) { model = stdGljModel; query.repositoryId = gljLibId; } else { model = complementaryGljModel; query.userId = userID; query.compilationId = compilationId; } // 分类树 if (classList.length) { query.gljClass = {$in: classList}; } // 定位 if (location) { // 替换定位,则先看看能不能找到替换的人材机,能找到的话就能定位要被替换人材机所在分类树 const replaceQuery = {...query, ...replace}; const replaceData = await model.findOne(replaceQuery); if (replaceData) { query.gljClass = replaceData.gljClass; matchLocation = true; } } // 替换过滤类型 if (replace) { // 人材机类型是“混凝土、砂浆、配合比、商品混凝土、商品砂浆”时,筛选的可替换的人材机类型应是“混凝土、或砂浆、或配合比、或商品混凝土、或商品砂浆”。 const materialTypes = [202, 203, 204, 205, 206]; query.gljType = materialTypes.includes(replace.gljType) ? {$in: materialTypes} : replace.gljType; } // 添加组成物时的查询扩展 if (queryExtend) { Object.assign(query, queryExtend); } // 搜索关键字 if (search) { query.$or = [{code: {'$regex': search, $options: '$i'}}, {name: {'$regex': search, $options: '$i'}}]; } countQuery = {...query}; // 上一次分页的最末人材机编码 if (code) { query.code = {$gt: code}; } return { model, query, countQuery, matchLocation }; } async getGLJPaging (condition) { const queryData = await this.getQueryByType(condition); // 定位(替换初始化) // 替换触发的人材机选择界面,只有在初始化时才定位,其他操作下是正常的分页 if (queryData.matchLocation) { // 返回的数据,为编码小于等于替换的编码,再加附加条数 const limitQuery = _.cloneDeep(queryData.query); limitQuery.code = {$lte: condition.replace.code}; const lteLimit = await queryData.model.count(limitQuery); const additionalLimit = 10; const limit = lteLimit + additionalLimit; // 显示的数据不能太少,否则数据没有占满整个表格区域(实际上数据条目应该超过表格显示区域),让人误以为数据只有那么点,不再滚动触发分页 condition.limit = limit > condition.limit ? limit : condition.limit; } //const gljs = await queryData.model.find(queryData.query).lean().sort({code: 1}).skip(condition.index).limit(condition.limit); // 分页使用skip的话,跳过的条数多的话性能会下降,因此不使用 const gljs = await queryData.model.find(queryData.query).lean().sort({code: 1}).limit(condition.limit); const total = await queryData.model.find(queryData.countQuery).count(); return condition.type === libType.stdGLJ ? {stdGLJ: gljs, complementaryGLJs: [], total: total} : {stdGLJ: [], complementaryGLJs: gljs, total: total} } async getGLJDataSync (gljLibId, userId, compilationId) { const stdGljs = await stdGljModel.find({repositoryId: gljLibId}).lean(); const complementaryGljs = await complementaryGljModel.find({userId, compilationId}).lean(); return { stdGljs, complementaryGljs } } //获得用户的补充工料机和用户当前所在编办的标准工料机 async getGljItems (stdGljLibId, userId, compilationId, projection, callback){ let me = this; let rst = {stdGljs: [], complementaryGljs: []}; //批量获取异步 async.parallel([ async function (cb) { try{ let stdGljs = await stdGljModel.find({repositoryId: stdGljLibId}, projection).lean(); me.sortToNumber(stdGljs); rst.stdGljs = stdGljs; cb(null); } catch (err){ cb(err); } }, function (cb) { complementaryGljModel.find({userId: userId, compilationId: compilationId}, '-_id', {lean: true}, function (err, complementaryGljs) { if(err){ cb(err); } else{ me.sortToNumber(complementaryGljs); rst.complementaryGljs = complementaryGljs; cb(null); } }); } ], function (err) { if(err){ callback(err, null); } else{ callback(0, rst); } }) }; async getStdItems (stdGljLibId, projection, callback) { try { let stdItems = await stdGljModel.find({repositoryId: stdGljLibId}, projection).lean(); callback(0, stdItems); } catch (err) { callback(1, null); } } getGljItemsByCode (repositoryId, codes, callback){ gljModel.find({"repositoryId": repositoryId,"code": {"$in": codes}},function(err,data){ if(err) callback(true, "") else callback(false, data); }) }; updateComponent(userId, updateArr, callback){ let parallelFucs = []; for(let i = 0; i < updateArr.length; i++){ parallelFucs.push((function(obj){ return function (cb) { if(typeof obj.component === 'undefined'){ obj.component = []; } complementaryGljModel.update({userId: userId, ID: obj.ID}, obj, function (err, result) { if(err){ cb(err); } else{ cb(null, obj); } }) } })(updateArr[i])); } async.parallel(parallelFucs, function (err, result) { if(err){ callback(err, '更新组成物错误!', null); } else{ callback(0, '成功!', result); } }); } //-oprtor mixUpdateGljItems (userId, compilationId, updateItems, addItems, rIds, callback) { if (updateItems.length == 0 && rIds.length == 0) { GljDao.addGljItems(userId, compilationId, addItems, callback); } else if(rIds.length > 0 && updateItems.length > 0){ async.parallel([ function (cb) { GljDao.removeGljItems(rIds, cb); }, function (cb) { GljDao.updateGljItems(userId, compilationId, updateItems, cb); } ], function (err) { if(err){ callback(true, "Fail to update and delete", false) } else{ callback(false, "Save successfully", false); } }) } else if (rIds.length > 0 && updateItems.length === 0) { GljDao.removeGljItems(rIds, callback); } else if(updateItems.length > 0 || addItems.length > 0){ GljDao.updateGljItems(userId, compilationId, updateItems, function(err, results){ if (err) { callback(true, "Fail to update", false); } else { if (addItems && addItems.length > 0) { GljDao.addGljItems(userId, compilationId, addItems, callback); } else { callback(false, "Save successfully", results); } } }); } } static removeGljItems (rIds, callback) { if (rIds && rIds.length > 0) { complementaryGljModel.collection.remove({ID: {$in: rIds}}, null, function(err, docs){ if (err) { callback(true, "Fail to remove", false); } else { callback(false, "Remove successfully", docs); } }) } else { callback(false, "No records were deleted!", null); } } static addGljItems (userId, compilationId, items, callback) { if (items && items.length > 0) { counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){ var maxId = result.sequence_value; var arr = []; for (var i = 0; i < items.length; i++) { var obj = new complementaryGljModel(items[i]); obj.ID = (maxId - (items.length - 1) + i); obj.userId = userId; obj.compilationId = compilationId; arr.push(obj); } complementaryGljModel.collection.insert(arr, null, function(err, docs){ if (err) { callback(true, "Fail to add", false); } else { callback(false, "Add successfully", docs); } }); }); } else { callback(true, "No source", false); } } static updateGljItems(userId, compilationId, items, callback) { var functions = []; for (var i=0; i < items.length; i++) { functions.push((function(doc) { return function(cb) { var filter = {}; if (doc.ID) { filter.ID = doc.ID; } else { filter.userId = userId; filter.compilationId = compilationId; filter.code = doc.code; } complementaryGljModel.update(filter, doc, cb); }; })(items[i])); } async.parallel(functions, function(err, results) { callback(err, results); }); } /** * 获取组成物数据 * * @param {Number} gljId * @return {Promise} */ async getComponent(gljId) { let result = []; let libGljData = await complementaryGljModel.findOne({ID: gljId}); if (libGljData === null || libGljData.component.length <= 0) { return result; } // 标准工料机库 let componentIdListStd = []; // 补充工料机库 let componentIdListCpt = []; let componentConsume = {}; // 整理数据 for (let component of libGljData.component) { if (component.isStd) { componentIdListStd.push(component.ID); } else { componentIdListCpt.push(component.ID); } let isStdFlag = component.isStd ? 'std' : 'cpt'; //对于补充人材机的组成物,不会有多单价的情况 componentConsume[component.ID + '_' + isStdFlag] = component.consumeAmt; } // 查找标准库数据 let condition = {}; let componentStdGljData = []; if (componentIdListStd.length > 0) { let gljListModel = new STDGLJLibGLJListModel(); condition = {ID: {$in: componentIdListStd}}; componentStdGljData = await gljListModel.findDataByCondition(condition, null, false); } // 查找补充库数据 let componentCptGljData = []; if (componentIdListCpt.length > 0) { condition = {ID: {$in: componentIdListCpt}}; componentCptGljData = await complementaryGljModel.find(condition); } if (componentCptGljData === null && componentStdGljData === null) { return result; } // 整理数据 if (componentStdGljData.length > 0) { componentStdGljData = JSON.stringify(componentStdGljData); componentStdGljData = JSON.parse(componentStdGljData); for(let gljData of componentStdGljData) { gljData.connectCode = libGljData.code; gljData.consumption = componentConsume[gljData.ID + '_std']; gljData.from='std'; result.push(gljData); } } if (componentCptGljData.length > 0) { componentCptGljData = JSON.stringify(componentCptGljData); componentCptGljData = JSON.parse(componentCptGljData); for(let gljData of componentCptGljData) { gljData.connectCode = libGljData.code; gljData.consumption = componentConsume[gljData.ID + '_cpt']; gljData.from='cpt'; result.push(gljData); } } return result; } async getMixedTree(gljLibId, userId, compilationId){ let rst = {std: [], comple: []}; rst.std = await gljClassModel.find({repositoryId: gljLibId}).lean(); rst.comple = await compleClassModel.find({userId: userId, compilationId: compilationId}).lean(); return rst; } } export default GljDao;