/** * Created by Mai on 2017/4/14. * 清单模板,新建项目使用 */ let counter = require("../../../public/counter/counter.js"); let mongoose = require('mongoose'); let BillsTemplates = mongoose.model('temp_bills'); let BillsTemplateDAO = function(){}; const BillsTemplateModel = require("../../pm/models/templates/bills_template_model"); const uuidV1 = require('uuid/v1'); const billsUtil = require('../../../public/billsUtil'); BillsTemplateDAO.prototype.getTemplate = function (type, callback) { if (callback) { BillsTemplates.find({'$or': [{tempType: type, deleteInfo: null}, {tempType: type, 'deleteInfo.deleted': {$in: [null, false]}}]}, '-_id').exec() .then(function (result, err) { if (err) { callback(1, '找不到模板', null); } else { callback(0, '', result); } }); return null; } else { return BillsTemplates.find({'$or': [{tempType: type, deleteInfo: null}, {tempType: type, 'deleteInfo.deleted': {$in: [null, false]}}]}, '-_id').exec(); } }; BillsTemplateDAO.prototype.updateTemplate = function (userID, tempType, datas, callback) { var data, project, updateLength = 0, hasError = false, deleteInfo = null; var updateAll = function (err) { if (!err){ updateLength += 1; if (updateLength === datas.length) { callback(0, '', datas); } } else { hasError = true; callback(1, '升级数据出错', null); } }; if (datas){ for (var i = 0; i < datas.length && !hasError; i++){ data = datas[i]; if (data.type === 'update') { BillsTemplates.update({tempType: tempType, ID: data.data.ID}, data.data, updateAll) } else if (data.type === 'new') { data.data['tempType'] = tempType; newProject = new BillsTemplates(data.data); newProject.save(updateAll); } else if (data.type === 'delete') { deleteInfo = {}; deleteInfo['deleted'] = true; deleteInfo['deleteDateTime'] = new Date(); deleteInfo['deleteBy'] = userID; BillsTemplates.update({ID: data.data.ID}, {deleteInfo: deleteInfo}, updateAll); } else { hasError = true; callback(1, '升级数据出错', null) } } } }; BillsTemplateDAO.prototype.getNewBillsTemplateID = function (count, callback) { counter.counterDAO.getIDAfterCount(counter.moduleName.template_bills, count, function (err, result) { var highID = result.sequence_value; if (!err) { callback(0, '', {lowID: highID - count + 1, highID: highID}); } else { callback(1, '获取主键失败', null); } }); } //过滤掉非必要清单的清单模板 BillsTemplateDAO.prototype.getNeedfulTemplate = async function (templateLibID) { let billsTemplateModel = new BillsTemplateModel(); let templateData = await billsTemplateModel.getTemplateDataForNewProj(templateLibID); let billsDatas = JSON.parse(JSON.stringify(templateData)); //设置同层序号,为了后续过滤掉非必要模板数据、插入接口清单数据后,能生成正确的顺序的树 setSeqByNext(billsDatas); function getFlag(data) { return data.flags && data.flags[0] && data.flags[0].flag || ''; } //过滤掉不含清单固定类别的模板数据 (导入接口只包含必要的清单模板数据) let needfulDatas = billsDatas.filter(data => getFlag(data)); sortSeqToNextSibling(needfulDatas); //sortToTreeData(needfulDatas); billsUtil.resetTreeData(needfulDatas, uuidV1); return needfulDatas; }; /* * 将同层的清单数据,按照树结构顺序设置序号 * @param {Array} billsData(清单模板数据) * */ function setSeqByNext(billsData) { //获取同层数据 let sameDepthDatas = {}; //按照ParentID区分 for (let data of billsData) { if (!sameDepthDatas[data.ParentID]) { sameDepthDatas[data.ParentID] = []; } sameDepthDatas[data.ParentID].push(data); } //设置同层节点的序号 for (let attr in sameDepthDatas) { let sameDepth = sameDepthDatas[attr]; let sortedData = getDataBySorted(sameDepth), seq = 1; sortedData.forEach((data => data.seq = seq++)); } //将每个同层的数据设置好序号 //获取根据树结构NextSibling排序的同层数据 function getDataBySorted(datas) { //链断了返回空数组 let target = []; let last = datas.find(data => data.NextSiblingID == -1); while (last && target.length !== datas.length) { target.push(last); last = datas.find(data => data.NextSiblingID == last.ID); if (!last) { break; } } //链断了即清单模板数据的树结构有问题,这里做下兼容: // 1.数据没问题,返回排序过后的同层数据数组 2.数据有问题,返回不排序的同层数组 return target.length === datas.length ? target.reverse() : datas; } } //根据同层序号,设置NextSiblingID function sortSeqToNextSibling(needfulData) { let sameDepthDatas = {}; //按照ParentID区分 for (let data of needfulData) { if (!sameDepthDatas[data.ParentID]) { sameDepthDatas[data.ParentID] = []; } sameDepthDatas[data.ParentID].push(data); } for (let attr in sameDepthDatas) { let sameDepth = sameDepthDatas[attr]; sameDepth.sort((a, b) => a.seq - b.seq); for (let i = 0; i < sameDepth.length; i++) { let cur = sameDepth[i], next = sameDepth[i + 1]; cur.NextSiblingID = next ? next.ID : -1; } } } //清单模板数据转换为uuID树结构数据 function sortToTreeData(needfulData) { sortSeqToNextSibling(needfulData); let uuidMaping = {}; uuidMaping['-1'] = -1; //建立uuid-ID映射 for(let bill of needfulData){ uuidMaping[bill.ID] = uuidV1(); } const reg = /@\d+/; needfulData.forEach(function (template) { template.ID = uuidMaping[template.ID] ? uuidMaping[template.ID] : -1; template.ParentID = uuidMaping[template.ParentID] ? uuidMaping[template.ParentID] : -1; template.NextSiblingID = uuidMaping[template.NextSiblingID] ? uuidMaping[template.NextSiblingID] : -1; const needToParseCalcBase = template.calcBase && reg.test(template.calcBase); if (needToParseCalcBase) { template.calcBase = billsUtil.parseCalcBase(template.calcBase, uuidMaping); } }); } module.exports = new BillsTemplateDAO();