bills_controller.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * Created by jimiz on 2017/4/7.
  3. */
  4. let mongoose = require('mongoose');
  5. var billsData = require('../models/bills');
  6. let ration_model = require('../models/ration');
  7. let ProjectsData = require('../../pm/models/project_model').project;
  8. let logger = require("../../../logs/log_helper").logger;
  9. let quantity_detail = require("../facade/quantity_detail_facade");
  10. let bill_facade = require("../facade/bill_facade");
  11. let raiton_facade = require("../facade/ration_facade");
  12. let stdBillsModel = mongoose.model('std_bills_lib_bills');
  13. let stdBillJobsModel = mongoose.model('std_bills_lib_jobContent');
  14. let stdBillCharacterModel = mongoose.model('std_bills_lib_itemCharacter');
  15. const { fixedFlag } = require('../../../public/common_constants');
  16. let LZString = require('lz-string');
  17. const uuidV1 = require('uuid/v1');
  18. const billType ={
  19. DXFY:1,//大项费用
  20. FB:2,//分部
  21. FX:3,//分项
  22. BILL:4,//清单
  23. BX:5//补项
  24. };
  25. //上传的09表、广联达表
  26. const uploadType = {lj: 'lj', gld: 'gld'};
  27. // 上传控件
  28. const multiparty = require("multiparty");
  29. const fs = require("fs");
  30. // excel解析
  31. const excel = require("node-xlsx");
  32. const urlencode = require('urlencode');
  33. //统一回调函数
  34. var callback = function(req, res, err, message, data){
  35. res.json({error: err, message: message, data: data});
  36. };
  37. module.exports = {
  38. getData: function(req, res){
  39. var data = JSON.parse(req.body.data);
  40. billsData.getData(data.projectId, function(err, message, billsList){
  41. if (err === 0) {
  42. callback(req, res, err, message, billsList);
  43. } else {
  44. callback(req, res, err, message, null);
  45. }
  46. });
  47. },
  48. getItemTemplate: function(req, res){
  49. //var data = JSON.parse(req.body.data);
  50. billsData.getItemTemplate(function(err, message, billsItem){
  51. if (billsItem) {
  52. callback(req, res, err, message, billsItem);
  53. } else {
  54. callback(req, res, err, message, null);
  55. }
  56. });
  57. },
  58. allocIDs: function(req, res){
  59. billsData.allocIDs(function(err, message, data){
  60. if (err) {
  61. callback(req, res, err, message, data);
  62. } else {
  63. callback(req, res, err, message, null);
  64. }
  65. });
  66. },
  67. //zhong 2017-9-1
  68. updateCharacterContent: function (req, res) {
  69. let data = JSON.parse(req.body.data);
  70. let findSet = data.findSet,
  71. updateObj = data.updateObj,
  72. txtObj = data.txtObj;
  73. billsData.updateCharacterContent(findSet, updateObj, txtObj, function (err, message) {
  74. callback(req, res, err, message, null);
  75. });
  76. },
  77. updateBills: async function (req, res) {
  78. try{
  79. let data = JSON.parse(req.body.data);
  80. await billsData.updateBills(data.updateDatas);
  81. callback(req, res, 0, 'success', null);
  82. }
  83. catch (err){
  84. callback(req, res, 1, err, null);
  85. }
  86. },
  87. updateBill: async function(request, response) {
  88. const data = JSON.parse(request.body.data);
  89. const findSet = data.findSet;
  90. const updateData = data.updateData;
  91. let settingData = {};
  92. // 筛选出要保存在项目属性的设置
  93. for (const index in updateData) {
  94. if (updateData[index].field === 'addRule') {
  95. settingData = updateData[index].value;
  96. delete updateData[index];
  97. }
  98. }
  99. /* // 更新项目属性
  100. const propertyUpdateData = {
  101. property: 'addRule',
  102. data: settingData
  103. };*/
  104. //const projectResult = await ProjectsData.updateProjectProperty(findSet.projectID, propertyUpdateData);
  105. const result = await billsData.updateBill(findSet, updateData);
  106. const message = !result ? '修改失败' : '修改成功';
  107. const err = !result ? 1 : 0;
  108. callback(request, response, err, message, null);
  109. },
  110. singleDelete:async function(req, res){
  111. let result={
  112. error:0
  113. }
  114. try {
  115. let data = req.body.data;
  116. data = JSON.parse(data);
  117. let tasks = generateSingleDeleteTasks(data);
  118. let resultData= await billsData.model.bulkWrite(tasks);
  119. //删除工程量明细
  120. await quantity_detail.deleteByQuery({projectID: data.projectID, billID: data.ID}) ;
  121. result.data=resultData;
  122. }catch (err){
  123. logger.err(err);
  124. result.error=1;
  125. result.message = err.message;
  126. }
  127. res.json(result);
  128. },
  129. multiDelete:async function(req, res){
  130. let result={
  131. error:0
  132. };
  133. try {
  134. let data = req.body.data;
  135. data = JSON.parse(data);
  136. result.data=await doBillsOrRationsDelete(data);
  137. }catch (err){
  138. logger.err(err);
  139. result.error=1;
  140. result.message = err.message;
  141. }
  142. res.json(result);
  143. },
  144. getSectionInfo:async function(req, res){
  145. let result={
  146. error:0
  147. }
  148. try {
  149. let data = req.body.data;
  150. data = JSON.parse(data);
  151. let sectionInfo= await bill_facade.getSectionInfo(data);
  152. result.data=sectionInfo;
  153. }catch (err){
  154. logger.err(err);
  155. result.error=1;
  156. result.message = err.message;
  157. }
  158. res.json(result);
  159. },
  160. reorganizeFBFX:async function(req,res){
  161. let result={
  162. error:0
  163. }
  164. try {
  165. let data = req.body.data;
  166. data = JSON.parse(data);
  167. let reorganizeResult= await bill_facade.reorganizeFBFX(data);
  168. result.data=reorganizeResult;
  169. }catch (err){
  170. logger.err(err);
  171. result.error=1;
  172. result.message = err.message;
  173. }
  174. res.json(result);
  175. },
  176. pasteBlock:async function(req,res){
  177. let result={
  178. error:0
  179. };
  180. try {
  181. let data = req.body.data;
  182. data = JSON.parse(data);
  183. let pasteResult = await bill_facade.pasteBlock(data,req.session.sessionCompilation);
  184. result.data = pasteResult;
  185. }catch (err){
  186. logger.err(err);
  187. result.error=1;
  188. result.message = err.message;
  189. }
  190. res.json(result);
  191. },
  192. //下载导入清单示例
  193. downloadExample: async function(request, response) {
  194. try {
  195. const filePath = './public/static/清单示例.xlsx';
  196. const stats = fs.statSync(filePath);
  197. // 下载相关header
  198. const name = urlencode('清单示例.xlsx');
  199. //res.setHeader("Content-Disposition", "attachment; filename* = UTF-8''"+name);
  200. response.set({
  201. 'Content-Type': 'application/octet-stream',
  202. 'Content-Disposition': "attachment; filename* = UTF-8''" + name,
  203. 'Content-Length': stats.size
  204. });
  205. fs.createReadStream(filePath).pipe(response);
  206. } catch (error) {
  207. response.end(error);
  208. }
  209. },
  210. //导入清单
  211. import: async function(req, res){
  212. let responseData = {
  213. err: 0,
  214. msg: '',
  215. data: []
  216. };
  217. const form = new multiparty.Form();
  218. form.parse(req, async function(err, fields, files) {
  219. try{
  220. const projectID = fields.projectID !== undefined && fields.projectID.length > 0 ?
  221. parseInt(fields.projectID[0]) : 0;
  222. if (projectID <= 0) {
  223. throw '参数错误';
  224. }
  225. //导入清单数据
  226. let compressData = fields.compressData !== undefined && fields.compressData.length > 0 ?
  227. fields.compressData[0] : null;
  228. if(compressData === null){
  229. throw 'excel没有对应数据'
  230. }
  231. let importData = JSON.parse(LZString.decompressFromUTF16(compressData));
  232. //导入表
  233. let importDateA = +new Date();
  234. let updateFrontData = await importSheet(importData, req.session.sessionUser.id, projectID);
  235. if(updateFrontData){
  236. responseData.data.push(updateFrontData);
  237. }
  238. let importDateB = +new Date();
  239. console.log(`导入时间: ${importDateB - importDateA}=========================================================================`);
  240. res.json(responseData);
  241. }
  242. catch (error){
  243. responseData.err = 1;
  244. console.log(error);
  245. responseData.msg = typeof error === 'object' ? '上传失败' : error;
  246. res.json(responseData);
  247. }
  248. });
  249. },
  250. insertBills: async function (req, res) {
  251. let data = JSON.parse(req.body.data);
  252. try {
  253. await bill_facade.insertBills(data.postData);
  254. callback(req, res, 0, 'success', null);
  255. } catch (err) {
  256. callback(req, res, 1, err, null);
  257. }
  258. }
  259. };
  260. async function importSheet(excelBills, userID, projectID,){
  261. //导入位置的有固定行
  262. let flag = fixedFlag.ONE_SEVEN_BILLS; //第100章至700章清单
  263. let fixedBill = await billsData.model.findOne({projectID: projectID, 'flags.flag': flag, deleteInfo: null});
  264. //删除相关数据
  265. let deleteDatas = await billsData.deepDeleteBill([fixedBill], userID);
  266. //新增清单数据
  267. await billsData.importBills(excelBills);
  268. //返回数据以更新前端
  269. return {fixedBill: fixedBill, insert: {bill: excelBills, ration: []}, remove: {bill: deleteDatas.bill, ration: deleteDatas.ration}};
  270. }
  271. function getImportFlag(position){
  272. const fixedItem = {'fbfx': fixedFlag.SUB_ENGINERRING, 'jscsxm': fixedFlag.CONSTRUCTION_TECH, 'zzcsxm': fixedFlag.CONSTRUCTION_ORGANIZATION};
  273. return fixedItem[position] ? fixedItem[position] : null;
  274. }
  275. function isDef(data){
  276. return typeof data !== 'undefined' && data !== null && data !== '';
  277. }
  278. async function doBillsOrRationsDelete(data) {
  279. let billTask = [];
  280. let deleteBillIDs = [];
  281. let rationTask=[];
  282. let deleteRationIDs=[];
  283. let qd_query=null;
  284. let sub_query=null;
  285. if(data['bills']){
  286. billTask = generateUpdateTasks(data['bills'],data.projectID,data.user_id);
  287. for(let b_key in data['bills']){
  288. if(data['bills'][b_key]===true){
  289. deleteBillIDs.push(b_key+'');
  290. }
  291. }
  292. if(deleteBillIDs.length>0){
  293. qd_query={projectID: data.projectID, billID: {"$in": deleteBillIDs}};
  294. }
  295. }
  296. if(data['ration']){
  297. rationTask = generateUpdateTasks(data['ration'],data.projectID,data.user_id);
  298. for(let r_key in data['ration']){
  299. if(data['ration'][r_key]===true){
  300. deleteRationIDs.push(r_key+'');
  301. }
  302. }
  303. if(deleteRationIDs.length>0){
  304. if(qd_query==null){//说明没删除清单
  305. qd_query={projectID: data.projectID, rationID: {"$in": deleteRationIDs}};
  306. }else {
  307. qd_query={
  308. "$or":[
  309. {projectID: data.projectID, billID: {"$in": deleteBillIDs}},
  310. {projectID: data.projectID, rationID: {"$in": deleteRationIDs}}
  311. ]
  312. }
  313. }
  314. sub_query={projectID: data.projectID, rationID: {"$in": deleteRationIDs}};
  315. }
  316. }
  317. //先删除工程量明细
  318. if(qd_query!=null){
  319. await quantity_detail.deleteByQuery(qd_query) ;
  320. }
  321. if(sub_query!=null){
  322. await raiton_facade.deleteSubListByQuery(sub_query);
  323. }
  324. if(rationTask.length>0){
  325. await ration_model.model.bulkWrite(rationTask);//删除定额
  326. }
  327. if(billTask.length>0){
  328. await billsData.model.bulkWrite(billTask);//删除清单
  329. }
  330. return 'success';
  331. }
  332. function generateSingleDeleteTasks(data) {
  333. let updateData = data.updateData;
  334. updateData[data.ID]=true;
  335. let tasks = generateUpdateTasks(updateData,data.projectID,data.user_id);
  336. return tasks;
  337. }
  338. function generateUpdateTasks(data,projectID,user_id) {
  339. let tasks=[];
  340. let updateData = data;
  341. let deleteInfo={deleted: true, deleteDateTime: new Date(), deleteBy: user_id};
  342. for(let key in updateData){
  343. let task={
  344. updateOne:{
  345. filter:{
  346. ID:key,
  347. projectID:projectID
  348. }
  349. }
  350. };
  351. if(updateData[key]===true){
  352. //原先是假删除,现在改成真删除
  353. task = {
  354. deleteOne:{
  355. filter:{
  356. ID:key,
  357. projectID:projectID
  358. }
  359. }
  360. }
  361. /* task.updateOne.update={
  362. deleteInfo:deleteInfo
  363. };*/
  364. }else {
  365. task.updateOne.update=updateData[key];
  366. }
  367. tasks.push(task);
  368. }
  369. return tasks;
  370. }