deal_bills.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Mai
  6. * @date 2018/5/8
  7. * @version
  8. */
  9. module.exports = app => {
  10. class DealBills extends app.BaseService {
  11. /**
  12. * 构造函数
  13. * @param ctx
  14. */
  15. constructor(ctx) {
  16. super(ctx);
  17. this.tableName = 'deal_bills';
  18. }
  19. async getSum(tenderId) {
  20. const sql = 'SELECT Sum(`total_price`) As `total_price` ' +
  21. ' From ' + this.tableName +
  22. ' WHERE `tender_id` = ? ';
  23. const sqlParam = [tenderId];
  24. return await this.db.queryOne(sql, sqlParam);
  25. }
  26. /**
  27. * 导入Excel数据(node-xlsx)
  28. *
  29. * @param {Array} sheet - Excel文件中的全部工作表
  30. * @param {Number} tenderId - 所属标段Id
  31. * @returns {Promise<boolean>}
  32. */
  33. async importData(sheet, tenderId) {
  34. let result = false;
  35. const transaction = await this.db.beginTransaction();
  36. try {
  37. const bills = [];
  38. // 识别表头导入
  39. let iCode = -1, iName = -1, iUnit = -1, iUp = -1, iQty = -1, iTp = -1, bCheckCol = false;
  40. for (let iRow = 0; iRow < sheet.data.length; iRow++) {
  41. const row = sheet.data[iRow];
  42. if (!bCheckCol) {
  43. for (let iCol = 0; iCol < row.length; iCol++) {
  44. const value = row[iCol];
  45. if (typeof value !== "string") { continue }
  46. if (['清单编号', '子目号', '子目编号', '编号', '清单号'].indexOf(value) >= 0) iCode = iCol;
  47. if (['清单名称', '名称', '子目名称'].indexOf(value) >= 0) iName = iCol;
  48. if (value.indexOf('单位') >= 0) iUnit = iCol;
  49. if (value.indexOf('单价') >= 0) iUp = iCol;
  50. if (value.indexOf('数量') >= 0) iQty = iCol;
  51. if (value.indexOf('金额') >= 0 || value.indexOf('合价') >= 0) iTp = iCol;
  52. }
  53. bCheckCol = (iCode >= 0 && iName >= 0 && iUnit >= 0 && iUp >= 0 && iQty >= 0);
  54. if (!bCheckCol) {
  55. iCode = -1;
  56. iName = -1;
  57. iUnit = -1;
  58. iUp = -1;
  59. iQty = -1;
  60. }
  61. } else {
  62. const code = this.ctx.helper._.trim(row[iCode]);
  63. console.log(code);
  64. if (this.ctx.helper.validBillsCode(code)) {
  65. const data = {
  66. deal_id: bills.length + 1,
  67. tender_id: tenderId,
  68. code: code,
  69. name: row[iName],
  70. unit: row[iUnit],
  71. unit_price: row[iUp],
  72. quantity: row[iQty],
  73. };
  74. if ((data.unit_price && !this._.isNumber(data.unit_price)) || (data.quantity && !this._.isNumber(data.quantity))) {
  75. throw '导入的Excel的数据类型有误,请检查第' + (iRow + 1) + '行';
  76. }
  77. bills.push(data);
  78. }
  79. }
  80. }
  81. if (!bCheckCol) {
  82. throw '导入的Excel表头定义有误,请下载示例检查';
  83. }
  84. // 固定列,从第一行开始导入
  85. // let iCode = 0, iName = 1, iUnit = 2, iUp = 4, iQty = 3;
  86. // for (let iRow = 1; iRow < sheet.data.length; iRow++) {
  87. // const data = {
  88. // deal_id: bills.length + 1,
  89. // tender_id: tenderId,
  90. // code: row[iCode],
  91. // name: row[iName],
  92. // unit: row[iUnit],
  93. // unit_price: row[iUp],
  94. // quantity: row[iQty],
  95. // };
  96. // if (!data.code || data.code === '' || !data.name || data.name === '') continue;
  97. // if ((data.unit_price && !this._.isNumber(data.unit_price)) || (data.quantity && !this._.isNumber(data.quantity))) {
  98. // throw '导入的Excel的数据类型有误,请检查第' + (iRow + 1) + '行';
  99. // }
  100. // bills.push(data);
  101. // }
  102. if (bills.length > 0) {
  103. await transaction.delete(this.tableName, {tender_id: tenderId});
  104. const billsResult = await transaction.insert(this.tableName, bills);
  105. if (billsResult.affectedRows !== bills.length) {
  106. throw '导入签约清单数据出错';
  107. }
  108. } else {
  109. throw 'Excel文件中无签约清单数据';
  110. }
  111. await transaction.commit();
  112. result = true;
  113. } catch (err) {
  114. await transaction.rollback();
  115. throw err;
  116. }
  117. return result;
  118. }
  119. /**
  120. * 导入Excel数据(js-xlsx)
  121. *
  122. * @param {Array} sheet - Excel文件中的全部工作表
  123. * @param {Number} tenderId - 所属标段Id
  124. * @returns {Promise<boolean>}
  125. */
  126. async importDataJsXlsx(sheet, tenderId) {
  127. let result = false;
  128. // 整理数据
  129. const bills = [];
  130. let iCode = -1, iName = -1, iUnit = -1, iUp = -1, iQty = -1, iTp = -1, bCheckCol = false;
  131. for (let iRow = 0; iRow < sheet.rows.length; iRow++) {
  132. const row = sheet.rows[iRow];
  133. if (!bCheckCol) {
  134. for (let iCol = 0; iCol < row.length; iCol++) {
  135. const value = row[iCol];
  136. if (typeof value !== "string") { continue }
  137. if (value === '子目号' || value === '清单编号') iCode = iCol;
  138. if (value.indexOf('名称') >= 0) iName = iCol;
  139. if (value.indexOf('单位') >= 0) iUnit = iCol;
  140. if (value.indexOf('单价') >= 0) iUp = iCol;
  141. if (value.indexOf('数量') >= 0) iQty = iCol;
  142. if (value.indexOf('金额') >= 0 || value.indexOf('合价') >= 0) iTp = iCol;
  143. }
  144. bCheckCol = (iCode >= 0 && iName >= 0 && iUnit >= 0 && iUp >= 0 && iQty >= 0 && iTp >= 0);
  145. if (!bCheckCol) {
  146. iCode = -1;
  147. iName = -1;
  148. iUnit = -1;
  149. iUp = -1;
  150. iQty = -1;
  151. iTp = -1;
  152. }
  153. } else {
  154. const code = this.ctx.helper.replaceReturn(this.ctx.helper._.trim(row[iCode]));
  155. //if (this.ctx.helper.validBillsCode(code)) {
  156. if (code) {
  157. const data = {
  158. deal_id: bills.length + 1,
  159. tender_id: tenderId,
  160. code: code,
  161. name: this.ctx.helper.replaceReturn(row[iName]),
  162. unit: this.ctx.helper.replaceReturn(row[iUnit]),
  163. unit_price: (row[iUp] === undefined || row[iUp] === null) ? 0 : this._.toNumber(row[iUp]),
  164. quantity: (row[iQty] === undefined || row[iQty] === null) ? 0 : this._.toNumber(row[iQty]),
  165. total_price: (row[iTp] === undefined || row[iTp] === null) ? 0 : this._.toNumber(row[iTp]),
  166. };
  167. if (this._.isNaN(data.unit_price) || this._.isNaN(data.quantity) || this._.isNaN(data.total_price)) {
  168. throw '导入的Excel的数据类型有误,请检查第' + (iRow + 1) + '行';
  169. }
  170. bills.push(data);
  171. }
  172. }
  173. }
  174. if (!bCheckCol) {
  175. throw '导入的Excel表头定义有误,请下载示例检查';
  176. }
  177. // 写入数据
  178. const transaction = await this.db.beginTransaction();
  179. try {
  180. if (bills.length > 0) {
  181. await transaction.delete(this.tableName, {tender_id: tenderId});
  182. const billsResult = await transaction.insert(this.tableName, bills);
  183. if (billsResult.affectedRows !== bills.length) {
  184. throw '导入签约清单数据出错';
  185. }
  186. } else {
  187. throw 'Excel文件中无签约清单数据';
  188. }
  189. await transaction.commit();
  190. result = true;
  191. } catch (err) {
  192. await transaction.rollback();
  193. throw err;
  194. }
  195. return result;
  196. }
  197. /*
  198. * 报表用
  199. * @param {Number} tenderId - 所属标段Id
  200. */
  201. async getDataByTenderId(tenderId) {
  202. const sql = 'SELECT Bills.* FROM ' + this.tableName + ' As Bills WHERE tender_id = ?';
  203. const sqlParam = [tenderId];
  204. return await this.db.query(sql, sqlParam);
  205. // let rst = await this.getDataByCondition({tender_id: tenderId});
  206. // return rst;
  207. }
  208. }
  209. return DealBills;
  210. }