searchModel.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /**
  2. * Created by Zhong on 2018/1/9.
  3. */
  4. const mongoose = require('mongoose');
  5. const compleRationModel = mongoose.model('complementary_ration_items');
  6. const complementaryGljModel = mongoose.model('complementary_glj_lib');
  7. const stdGljModel = mongoose.model('std_glj_lib_gljList');
  8. const compleRationSectionTreeModel = mongoose.model('complementary_ration_section_tree');
  9. const rationLibModel = mongoose.model('std_ration_lib_map');
  10. let stdSectionTreeModel = require ('../../ration_repository/models/ration_section_tree').Model;
  11. let stdRationModel = require ('../../ration_repository/models/ration_item').Model;
  12. const compleRationLib = 'compleRationLib';
  13. class SearchDao{
  14. async getRationItem(userId, compilationId, rationRepIds, code, ID, callback){
  15. let ration = null;
  16. let otherLibs=[];
  17. try{
  18. let firstLib = rationRepIds[0];//优先取第一个
  19. for (let l of rationRepIds){
  20. if(l != firstLib && l != compleRationLib){
  21. otherLibs.push(l);
  22. }
  23. }
  24. if(firstLib == compleRationLib){//说明选中的是补充定额库
  25. ration = await this.getCompleRation(userId,compilationId,code,ID);
  26. }else {
  27. firstLib = parseInt(firstLib);
  28. let firstQuery = {rationRepId: firstLib, code: code};
  29. if(ID){
  30. firstQuery = {ID: ID};
  31. }
  32. ration = await this.getStdRation(firstQuery);
  33. }
  34. if(ration == null){//选中的定额库或者默认的定额库中没有找到定额,才走常规的流程查找其它定额库
  35. let stdQuery = {rationRepId: {$in: otherLibs}, code: code};
  36. if(ID){
  37. stdQuery = {ID: ID};
  38. }
  39. ration = await this.getStdRation(stdQuery);
  40. if(ration == null) ration = await this.getCompleRation(userId,compilationId,code,ID);
  41. }
  42. if(isDef(ration)){
  43. if (ration.type === 'std') {
  44. let stdChapter = await stdSectionTreeModel.findOne({rationRepId: ration.rationRepId, ID: ration.sectionId, $or: [{isDeleted: null}, {isDeleted: false}]});
  45. if(isDef(stdChapter)){
  46. ration.chapter = stdChapter._doc;
  47. }
  48. } else {
  49. let compleChapter = await compleRationSectionTreeModel.findOne({ID: ration.sectionId, $or: [{isDeleted: null}, {isDeleted: false}]});
  50. if(isDef(compleChapter)){
  51. ration.chapter = compleChapter._doc;
  52. }
  53. }
  54. }
  55. if(callback){
  56. callback(0, ration);
  57. }
  58. }
  59. catch(err){
  60. if(callback){
  61. callback(err, null);
  62. }
  63. }
  64. return ration;
  65. }
  66. async getCompleRation(userId,compilationId,code,ID){
  67. let ration = null;
  68. let compleQuery = {userId: userId, compilationId: compilationId, code: code, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]};
  69. if(ID){
  70. compleQuery.ID = ID;
  71. }
  72. let compleRation = await compleRationModel.findOne(compleQuery);
  73. if(isDef(compleRation)){
  74. ration = compleRation._doc;
  75. ration.type = 'complementary';
  76. }
  77. return ration
  78. }
  79. async getStdRation(query){
  80. let ration = null;
  81. let stdRation = await stdRationModel.findOne(query);
  82. if(isDef(stdRation)){
  83. ration = stdRation._doc;
  84. ration.type = 'std';
  85. }
  86. return ration;
  87. }
  88. // 设置定额所属定额库数据
  89. async setRationLibName(stdRations, compleRations) {
  90. const rationLibIDSet = new Set();
  91. stdRations.forEach(ration => {
  92. rationLibIDSet.add(ration.rationRepId);
  93. });
  94. const rationLibNameList = await rationLibModel.find({ ID: { $in: [...rationLibIDSet] } }, '-_id dispName ID').lean();
  95. const rationLibNameMap = {};
  96. rationLibNameList.forEach(lib => rationLibNameMap[lib.ID] = lib.dispName);
  97. stdRations.forEach(ration => {
  98. ration.rationLibName = rationLibNameMap[ration.rationRepId];
  99. });
  100. compleRations.forEach(ration => ration.rationLibName = '我的补充定额');
  101. }
  102. //@param {Object}skip({std: Number, comple: Number})
  103. async findRation(userId, compilationId, rationRepId, keyword, skip, callback){
  104. //每次限制结果数
  105. const limit = 50;
  106. //结果数
  107. let resultCount = 0,
  108. rst = {data: [], count: null};
  109. try{
  110. //是否需要查找补充定额
  111. let findCompleRtion = rationRepId.length > 0 && rationRepId.includes(compleRationLib) ? true : false;
  112. //剔除补充定额库id
  113. if (rationRepId.includes(compleRationLib)) {
  114. rationRepId.splice(rationRepId.indexOf(compleRationLib), 1);
  115. }
  116. let filter = {
  117. 'rationRepId': {$in: rationRepId},
  118. '$and': [{
  119. '$or': [{'code': {'$regex': keyword, $options: '$i'}}, {'name': {'$regex': keyword, $options: '$i'}}]
  120. }, {
  121. '$or': [{'isDeleted': {"$exists":false}}, {'isDeleted': null}, {'isDeleted': false}, {deleteInfo: null}]
  122. }]
  123. };
  124. let compleFilter = {
  125. userId: userId,
  126. compilationId: compilationId,
  127. '$and': [{
  128. '$or': [{'code': {'$regex': keyword, $options: '$i'}}, {'name': {'$regex': keyword, $options: '$i'}}]
  129. }, {
  130. '$or': [{deleteInfo: null}, {'deleteInfo.deleted': false}]
  131. }]
  132. };
  133. //结果数
  134. if (skip && skip.std === 0 && skip.comple === 0) {
  135. resultCount += rationRepId.length === 0 ? 0 : await stdRationModel.find(filter).count();
  136. resultCount += findCompleRtion ? await compleRationModel.find(compleFilter).count() : 0;
  137. rst.count = resultCount;
  138. }
  139. //搜索定额
  140. let stdGljIds = [],
  141. comGljIds = [];
  142. let stdRations = rationRepId.length === 0 ? [] : await stdRationModel.find(filter).lean().sort({code: 1}).skip(skip.std).limit(limit);
  143. for(let i = 0, len = stdRations.length; i < len; i++){
  144. stdRations[i].type = 'std';
  145. for(let glj of stdRations[i].rationGljList){
  146. stdGljIds.push(glj.gljId);
  147. }
  148. }
  149. let compleRations = [];
  150. let residueLimit = limit - stdRations.length;
  151. if (residueLimit > 0) {
  152. compleRations = findCompleRtion ? await compleRationModel.find(compleFilter).lean().sort({code: 1}).skip(skip.comple).limit(residueLimit) : [];
  153. for(let i = 0, len = compleRations.length; i <len; i++){
  154. compleRations[i].type = 'complementary';
  155. for(let glj of compleRations[i].rationGljList){
  156. if(glj.type === 'std'){
  157. stdGljIds.push(glj.gljId);
  158. }
  159. else {
  160. comGljIds.push(glj.gljId);
  161. }
  162. }
  163. }
  164. }
  165. // 设置定额所属定额库名称
  166. await this.setRationLibName(stdRations, compleRations);
  167. //设置悬浮信息
  168. stdGljIds = Array.from(new Set(stdGljIds));
  169. comGljIds = Array.from(new Set(comGljIds));
  170. let gljIDMapping = {};
  171. if(stdGljIds.length > 0){
  172. let stdGljs = await stdGljModel.find({ID: {$in: stdGljIds}}, '-_id ID code name specs unit gljType');
  173. for(let stdGlj of stdGljs){
  174. gljIDMapping[stdGlj.ID] = stdGlj;
  175. }
  176. }
  177. if(comGljIds.length > 0){
  178. let comGljs = await complementaryGljModel.find({ID: {$in: stdGljIds}});
  179. for(let comGlj of comGljs){
  180. gljIDMapping[comGlj.ID] = comGlj;
  181. }
  182. }
  183. for(let ration of stdRations){
  184. let hintsArr = [];
  185. //对人材机进行排序
  186. ration.rationGljList.sort(function (a, b) {
  187. let gljA = gljIDMapping[a.gljId],
  188. gljB = gljIDMapping[b.gljId];
  189. if(gljA && gljB){
  190. let aV = gljA.gljType + gljA.code,
  191. bV = gljB.gljType + gljB.code;
  192. if(aV > bV) {
  193. return 1;
  194. } else if(aV < bV) {
  195. return -1;
  196. }
  197. }
  198. return 0;
  199. });
  200. for(let rationGlj of ration.rationGljList){
  201. let glj = gljIDMapping[rationGlj.gljId];
  202. if(glj){
  203. hintsArr.push(` ${glj.code} ${glj.name}${glj.specs ? ' ' + glj.specs : ''} ${glj.unit} ${rationGlj.consumeAmt}`);
  204. }
  205. }
  206. hintsArr.push(`基价 元 ${ration.basePrice}`);
  207. if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
  208. hintsArr.push(`工作内容:`);
  209. hintsArr = hintsArr.concat(ration.jobContent.split('\n'));
  210. }
  211. if(ration.annotation && ration.annotation.toString().trim() !== ''){
  212. hintsArr.push(`附注:`);
  213. hintsArr = hintsArr.concat(ration.annotation.split('\n'));
  214. }
  215. ration.hint = hintsArr.join('<br>');
  216. }
  217. for(let ration of compleRations){
  218. let hintsArr = [];
  219. for(let rationGlj of ration.rationGljList){
  220. let glj = gljIDMapping[rationGlj.gljId];
  221. if(glj){
  222. hintsArr.push(` ${glj.code} ${glj.name}${glj.specs ? ' ' + glj.specs : ''} ${glj.unit} ${rationGlj.consumeAmt}`);
  223. }
  224. }
  225. hintsArr.push(`基价 元 ${ration.basePrice}`);
  226. if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
  227. hintsArr.push(`工作内容:`);
  228. hintsArr = hintsArr.concat(ration.jobContent.split('\n'));
  229. }
  230. if(ration.annotation && ration.annotation.toString().trim() !== ''){
  231. hintsArr.push(`附注:`);
  232. hintsArr = hintsArr.concat(ration.annotation.split('\n'));
  233. }
  234. ration.hint = hintsArr.join('<br>');
  235. }
  236. rst.data = stdRations.concat(compleRations);
  237. callback(0, rst);
  238. }
  239. catch(err){
  240. console.log(err);
  241. callback(err, null);
  242. }
  243. }
  244. }
  245. function isDef(v){
  246. return v !== undefined && v !== null;
  247. }
  248. module.exports = SearchDao;