bills_controller.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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 { insertData, removeData } = JSON.parse(LZString.decompressFromUTF16(compressData));
  232. //导入表
  233. let importDateA = +new Date();
  234. let updateFrontData = await importSheet(insertData, removeData, 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, removeData, 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, projectID);
  266. let deleteDatas = await billsData.newDeepDeleteBill(removeData.rBillIDs, removeData.rRationIDs);
  267. //新增清单数据
  268. await billsData.importBills(excelBills);
  269. //返回数据以更新前端
  270. return { fixedBill: fixedBill, insert: { bill: excelBills, ration: [] }, remove: { bill: deleteDatas.bill, ration: deleteDatas.ration } };
  271. }
  272. function getImportFlag(position) {
  273. const fixedItem = { 'fbfx': fixedFlag.SUB_ENGINERRING, 'jscsxm': fixedFlag.CONSTRUCTION_TECH, 'zzcsxm': fixedFlag.CONSTRUCTION_ORGANIZATION };
  274. return fixedItem[position] ? fixedItem[position] : null;
  275. }
  276. function isDef(data) {
  277. return typeof data !== 'undefined' && data !== null && data !== '';
  278. }
  279. async function doBillsOrRationsDelete(data) {
  280. let billTask = [];
  281. let deleteBillIDs = [];
  282. let rationTask = [];
  283. let deleteRationIDs = [];
  284. let qd_query = null;
  285. let sub_query = null;
  286. if (data['bills']) {
  287. billTask = generateUpdateTasks(data['bills'], data.projectID, data.user_id);
  288. for (let b_key in data['bills']) {
  289. if (data['bills'][b_key] === true) {
  290. deleteBillIDs.push(b_key + '');
  291. }
  292. }
  293. if (deleteBillIDs.length > 0) {
  294. qd_query = { projectID: data.projectID, billID: { "$in": deleteBillIDs } };
  295. }
  296. }
  297. if (data['ration']) {
  298. rationTask = generateUpdateTasks(data['ration'], data.projectID, data.user_id);
  299. for (let r_key in data['ration']) {
  300. if (data['ration'][r_key] === true) {
  301. deleteRationIDs.push(r_key + '');
  302. }
  303. }
  304. if (deleteRationIDs.length > 0) {
  305. if (qd_query == null) {//说明没删除清单
  306. qd_query = { projectID: data.projectID, rationID: { "$in": deleteRationIDs } };
  307. } else {
  308. qd_query = {
  309. "$or": [
  310. { projectID: data.projectID, billID: { "$in": deleteBillIDs } },
  311. { projectID: data.projectID, rationID: { "$in": deleteRationIDs } }
  312. ]
  313. }
  314. }
  315. sub_query = { projectID: data.projectID, rationID: { "$in": deleteRationIDs } };
  316. }
  317. }
  318. //先删除工程量明细
  319. if (qd_query != null) {
  320. await quantity_detail.deleteByQuery(qd_query);
  321. }
  322. if (sub_query != null) {
  323. await raiton_facade.deleteSubListByQuery(sub_query);
  324. }
  325. if (rationTask.length > 0) {
  326. await ration_model.model.bulkWrite(rationTask);//删除定额
  327. }
  328. if (billTask.length > 0) {
  329. await billsData.model.bulkWrite(billTask);//删除清单
  330. }
  331. return 'success';
  332. }
  333. function generateSingleDeleteTasks(data) {
  334. let updateData = data.updateData;
  335. updateData[data.ID] = true;
  336. let tasks = generateUpdateTasks(updateData, data.projectID, data.user_id);
  337. return tasks;
  338. }
  339. function generateUpdateTasks(data, projectID, user_id) {
  340. let tasks = [];
  341. let updateData = data;
  342. let deleteInfo = { deleted: true, deleteDateTime: new Date(), deleteBy: user_id };
  343. for (let key in updateData) {
  344. let task = {
  345. updateOne: {
  346. filter: {
  347. ID: key,
  348. projectID: projectID
  349. }
  350. }
  351. };
  352. if (updateData[key] === true) {
  353. //原先是假删除,现在改成真删除
  354. task = {
  355. deleteOne: {
  356. filter: {
  357. ID: key,
  358. projectID: projectID
  359. }
  360. }
  361. }
  362. /* task.updateOne.update={
  363. deleteInfo:deleteInfo
  364. };*/
  365. } else {
  366. task.updateOne.update = updateData[key];
  367. }
  368. tasks.push(task);
  369. }
  370. return tasks;
  371. }