searchModel.js 12 KB

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