facades.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Zhong
  6. * @date 2018/6/1
  7. * @version
  8. */
  9. import mongoose from 'mongoose';
  10. import CompilationModel from "../../users/models/compilation_model";
  11. import moment from 'moment';
  12. const uuidV1 = require('uuid/v1');
  13. const billsLibModel = mongoose.model('std_bills_lib_list');
  14. const billsGuideLibModel = mongoose.model('std_billsGuidance_lib');
  15. const billsGuideItemsModel = mongoose.model('std_billsGuidance_items');
  16. const stdBillsLibModel = mongoose.model('std_bills_lib_list');
  17. const stdBillsModel = mongoose.model('std_bills_lib_bills');
  18. const stdBillsJobsModel = mongoose.model('std_bills_lib_jobContent');
  19. const stdRationModel = mongoose.model('std_ration_lib_ration_items');
  20. const _ = require('lodash');
  21. module.exports = {
  22. getLibWithBills,
  23. getItemsBybills,
  24. getItemsByCode,
  25. };
  26. async function getBillsGuideLibs(findData) {
  27. return await billsGuideLibModel.find(findData);
  28. }
  29. async function getLibWithBills(libID, isGuidanceLib){
  30. let billsLibId = libID;
  31. if (isGuidanceLib) {
  32. const guidanceLib = await getBillsGuideLibs({ID: libID});
  33. if(guidanceLib.length === 0){
  34. throw '不存在此指引库!';
  35. }
  36. const billsLib = await stdBillsLibModel.findOne({billsLibId: guidanceLib[0].billsLibId});
  37. if(!billsLib){
  38. throw '引用的清单规则库不存在!';
  39. }
  40. billsLibId = billsLib.billsLibId;
  41. }
  42. const bills = await stdBillsModel.find({ billsLibId }, '-_id').lean();
  43. return { bills };
  44. }
  45. function getAttrs(field, datas){
  46. let rst = [];
  47. for(let data of datas){
  48. if(data[field]){
  49. rst.push(data[field]);
  50. }
  51. }
  52. return rst;
  53. }
  54. //定额项目指所引用定额是否被删除
  55. function rationAllExist(rationItems, stdRationIdx) {
  56. for(let item of rationItems){
  57. if(!stdRationIdx[item.rationID]){
  58. return false;
  59. }
  60. }
  61. return true;
  62. }
  63. //将同层树结构转为顺序数组
  64. function chainToArr(nodes){
  65. let rst = [];
  66. let tempIdx = {};
  67. let nodeIdx = {};
  68. //建索引
  69. for(let node of nodes){
  70. tempIdx[node.ID] = {ID: node.ID, NextSiblingID: node.NextSiblingID, preSibling: null, nextSibling: null};
  71. nodeIdx[node.ID] = node;
  72. }
  73. //建链
  74. for(let i in tempIdx){
  75. let temp = tempIdx[i];
  76. if(temp.NextSiblingID != -1){
  77. let next = tempIdx[temp.NextSiblingID];
  78. temp.nextSibling = next;
  79. next.preSibling = temp;
  80. }
  81. }
  82. let firstNode = null;
  83. for(let i in tempIdx){
  84. if(!tempIdx[i].preSibling){
  85. firstNode = tempIdx[i];
  86. break;
  87. }
  88. }
  89. //获得顺序队列
  90. while(firstNode){
  91. rst.push(nodeIdx[firstNode.ID]);
  92. firstNode = firstNode.nextSibling;
  93. }
  94. return rst;
  95. }
  96. async function getItemsBybills(guidanceLibID, billsID){
  97. const type = {job: 0, ration: 1};
  98. let items = await billsGuideItemsModel.find({libID: guidanceLibID, billsID: billsID, deleted: false});
  99. let rationItems = _.filter(items, {type: type.ration});
  100. let rationIds = getAttrs('rationID', rationItems);
  101. let stdRations = await stdRationModel.find({ID: {$in: rationIds}, $or: [{isDeleted: null}, {isDeleted: false}]});
  102. let stdRationIndex = {};
  103. for(let stdRation of stdRations){
  104. stdRationIndex[stdRation.ID] = stdRation;
  105. }
  106. //判断定额完整性
  107. if(!rationAllExist(rationItems, stdRationIndex)){
  108. //建定额链, 排序后再清除不存在的定额,保证顺序正确性
  109. rationItems = chainToArr(rationItems);
  110. //清除已被删除的定额
  111. let removeIds = [];
  112. _.remove(rationItems, function (item) {
  113. if(!stdRationIndex[item.rationID]){
  114. removeIds.push(item.ID);
  115. return true;
  116. }
  117. return false;
  118. });
  119. _.remove(items, function (item) {
  120. return removeIds.includes(item.ID);
  121. });
  122. await billsGuideItemsModel.remove({ID: {$in: removeIds}});
  123. //重组树结构
  124. let bulkArr = [];
  125. for(let i = 0, len = rationItems.length; i < len; i++){
  126. rationItems[i].NextSiblingID = rationItems[i + 1] ? rationItems[i + 1].ID : -1;
  127. bulkArr.push({updateOne: {filter: {ID: rationItems[i].ID}, update: {$set: {NextSiblingID: rationItems[i].NextSiblingID}}}});
  128. }
  129. await billsGuideItemsModel.bulkWrite(bulkArr);
  130. }
  131. return items;
  132. }
  133. async function getItemsByCode(guidanceLibID, code){
  134. let rst = [];
  135. let guidanceLib = await billsGuideLibModel.findOne({ID: guidanceLibID});
  136. if (!guidanceLib) {
  137. return rst;
  138. }
  139. let stdBills = await stdBillsModel.findOne({code: code, billsLibId: guidanceLib.billsLibId}).lean();
  140. if (!stdBills) {
  141. return rst;
  142. }
  143. let items = await getItemsBybills(guidanceLibID, stdBills.ID);
  144. return items;
  145. }