uploadExcelByUrl.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import LuckyExcel from 'luckyexcel';
  2. import { getToken } from '@/utils/utils';
  3. import moment from 'moment';
  4. window.moment = moment;
  5. const uploadExcelByUrl = (nodeType, versionId, project) => {
  6. const TEMPLATE_URL =
  7. 'https://water-service-test.oss-cn-hangzhou.aliyuncs.com/public/bom/psr1121-2.xlsx';
  8. // 'https://water-service-test.oss-cn-hangzhou.aliyuncs.com/public/bom/psr1010.xlsx';
  9. // 'https://water-service-test.oss-cn-hangzhou.aliyuncs.com/public/bom/psr1009.xlsx';
  10. // 'https://water-service-test.oss-cn-hangzhou.aliyuncs.com/public/bom/psr1008.xlsx';
  11. // 'https://gt-digitization.oss-cn-hangzhou.aliyuncs.com/public/bom/psr0913.xlsx';
  12. return new Promise((resolve, reject) => {
  13. LuckyExcel.transformExcelToLuckyByUrl(
  14. TEMPLATE_URL,
  15. '模板.xlsx',
  16. async (exportJson, luckysheetfile) => {
  17. let [record] = await getExcel(versionId);
  18. let len = exportJson.sheets.length;
  19. const excelData = exportJson.sheets;
  20. delete record.id;
  21. record.index = len + '_' + Math.floor(Math.random() * 100);
  22. record.status = '0';
  23. record.name = '清单';
  24. // var sheets = [...excelData, record];
  25. var res = [];
  26. const category = getCategoryData(record);
  27. // 处理Estimate表
  28. // initEstimate(sheets[0], category);
  29. // 处理psr预算
  30. excelData[1].status = 1;
  31. res.push(initPSR(excelData[1], category, project?.project_name));
  32. if (nodeType == 4) {
  33. // 隐藏现金流表
  34. excelData[3].hide = 1;
  35. excelData[3].status = 0;
  36. // 处理现金流
  37. res.push(initActual(excelData[3], category, project));
  38. }
  39. res.push(record);
  40. // 隐藏Estimate表
  41. excelData[0].hide = 1;
  42. excelData[0].status = 0;
  43. res.push(excelData[0]);
  44. resolve(res.map((item, index) => ({ ...item, order: index })));
  45. }
  46. );
  47. });
  48. };
  49. async function getExcel(gridKey) {
  50. var formData = new FormData();
  51. formData.append('gridKey', gridKey);
  52. let res = await fetch(
  53. `/api/v1/purchase/record/sheet?gridKey=${gridKey}&JWT-TOKEN=${getToken()}`,
  54. {
  55. method: 'POST',
  56. body: formData,
  57. }
  58. ).then(response => response.text());
  59. return JSON.parse(JSON.parse(res));
  60. }
  61. function getCellValue(cell) {
  62. let v = '';
  63. if (cell.v) {
  64. v = cell.v;
  65. } else if (cell?.ct?.s) {
  66. v = cell.ct.s.map(item => item.v).join('');
  67. }
  68. return v;
  69. }
  70. function formatNumber(str) {
  71. if (str.length < 6) return str;
  72. const number = parseFloat(str);
  73. if (!isNaN(number) && number % 1 !== 0) {
  74. return number.toFixed(1);
  75. }
  76. return str;
  77. }
  78. // 根据清单获取表分类总价
  79. function getCategoryData(bom) {
  80. let bomData = [],
  81. bomTitle = {};
  82. bom.celldata.forEach(item => {
  83. let v = getCellValue(item.v);
  84. if (item.r == 0) {
  85. // 设置表头
  86. bomTitle[item.c] = v.trim();
  87. } else {
  88. let key = bomTitle[item.c];
  89. if (!bomData[item.r - 1]) {
  90. bomData[item.r - 1] = {};
  91. }
  92. bomData[item.r - 1][key] = v;
  93. }
  94. });
  95. let category = {
  96. 'GT-UF膜': 0,
  97. 原平制造: 0,
  98. 其它膜: 0,
  99. 水泵: 0,
  100. 阀门: 0,
  101. 加药系统: 0,
  102. 过滤器: 0,
  103. 空压机: 0,
  104. 非标: 0,
  105. 仪表: 0,
  106. 电气自控: 0,
  107. 双胞胎硬件: 0,
  108. 材料: 0,
  109. 安装: 0,
  110. 土建: 0,
  111. 运输: 0,
  112. 其它: 0,
  113. };
  114. bomData.forEach(item => {
  115. if (category.hasOwnProperty(item['类别'])) {
  116. let price = parseFloat(item['总价'] || item['总价(元)']);
  117. if (isNaN(price)) return;
  118. category[item['类别']] += price;
  119. }
  120. });
  121. return category;
  122. }
  123. // 处理现金流表
  124. function initActual(actual, category, project) {
  125. let actualCategory = [];
  126. actual.celldata.forEach((item, i, celldata) => {
  127. if (item.c == 0 && item.v?.v) {
  128. // LuckyExcel会将序号转float后再次转回string,导致小数出现精度问题
  129. // 序号后超过2位数的固定处理,不超过两位数的保留一位小数
  130. switch (item.r) {
  131. case 65:
  132. item.v.v = '5.10';
  133. break;
  134. case 66:
  135. item.v.v = '5.11';
  136. break;
  137. case 126:
  138. item.v.v = '9.12';
  139. break;
  140. case 127:
  141. item.v.v = '9.13';
  142. break;
  143. case 147:
  144. item.v.v = '10.12';
  145. break;
  146. case 148:
  147. item.v.v = '10.13';
  148. break;
  149. case 262:
  150. item.v.v = '17.15';
  151. break;
  152. case 264:
  153. item.v.v = '17.17';
  154. case 266:
  155. item.v.v = '17.19';
  156. break;
  157. default:
  158. // 处理序号转float出现多余小数的情况
  159. item.v.v = formatNumber(item.v?.v);
  160. break;
  161. }
  162. } else if (item.c == 1 && item.r == 0) {
  163. item.v.v = project?.project_name;
  164. } else if (item.c == 1 && item.r == 1) {
  165. item.v.v = project?.project_full_code;
  166. } else if (item.c == 2) {
  167. // 清单分类的总价填入对应预算列
  168. // c=2 为名称列
  169. let value = getCellValue(item.v);
  170. // 判断该行是否为类型总列
  171. if (category.hasOwnProperty(value)) {
  172. // 名称后第三列为预算列
  173. celldata[i + 3].v.v = category[value];
  174. }
  175. } else if (item.c == 12 && item.r == 5) {
  176. // 设置第一个月时间
  177. let start_date = moment('1900-01-01 00:00:00');
  178. let end_date = moment().startOf('month');
  179. item.v.v = end_date.diff(start_date, 'days');
  180. }
  181. });
  182. return actual;
  183. }
  184. // 处理毛利概算表
  185. function initEstimate(estimate, category) {
  186. estimate.celldata.forEach(item => {
  187. if (item.r == 15 && item.c == 2) {
  188. // 金科制造中心-UF膜
  189. item.v.v = category['GT-UF膜'];
  190. } else if (item.r == 14 && item.c == 2) {
  191. // 金科制造中心设备制造费
  192. item.v.v = category['原平制造'];
  193. } else if (item.r == 16 && item.c == 2) {
  194. // 设备购置费
  195. item.v.v =
  196. category['其它膜'] +
  197. category['水泵'] +
  198. category['阀门'] +
  199. category['加药系统'] +
  200. category['过滤器'] +
  201. category['空压机'] +
  202. category['非标'] +
  203. category['仪表'] +
  204. category['电气自控'] +
  205. category['材料'] +
  206. category['运输'] +
  207. category['其它'];
  208. } else if (item.r == 18 && item.c == 2) {
  209. // 数字双胞胎
  210. item.v.v = category['双胞胎硬件'];
  211. } else if (item.r == 19 && item.c == 2) {
  212. // 安装
  213. item.v.v = category['安装'];
  214. } else if (item.r == 20 && item.c == 2) {
  215. // 土建
  216. item.v.v = category['土建'];
  217. }
  218. });
  219. return estimate;
  220. }
  221. // 处理PSR表预算
  222. function initPSR(psr, category, projectName) {
  223. psr.celldata.forEach(item => {
  224. if (item.r == 0 && item.c == 1) {
  225. item.v.v = projectName;
  226. } else if (item.r == 38 && item.c == 2) {
  227. item.v.v = category['GT-UF膜'];
  228. } else if (item.r == 37 && item.c == 2) {
  229. item.v.v = category['原平制造'];
  230. } else if (item.r == 36 && item.c == 2) {
  231. item.v.v =
  232. category['其它膜'] +
  233. category['水泵'] +
  234. category['阀门'] +
  235. category['加药系统'] +
  236. category['过滤器'] +
  237. category['空压机'] +
  238. category['非标'] +
  239. category['仪表'] +
  240. category['电气自控'] +
  241. category['材料'] +
  242. category['运输'] +
  243. category['其它'];
  244. } else if (item.r == 39 && item.c == 2) {
  245. item.v.v = category['双胞胎硬件'];
  246. } else if (item.r == 40 && item.c == 2) {
  247. item.v.v = category['安装'];
  248. } else if (item.r == 41 && item.c == 2) {
  249. item.v.v = category['土建'];
  250. }
  251. });
  252. return psr;
  253. }
  254. export default uploadExcelByUrl;