importStdInterfaceBase.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Zhong
  6. * @date 2019/6/28
  7. * @version
  8. */
  9. const XML_IMPORT_BASE = (() => {
  10. // 清单类型
  11. const BILLS_TYPE ={
  12. DXFY: 1, //大项费用
  13. FB: 2, //分部
  14. FX: 3, //分项
  15. BILLS: 4, //清单
  16. BX: 5 //补项
  17. };
  18. // 项目类型
  19. const PROJECT_TYPE = {
  20. PROJECT: 'Project',
  21. ENGINEERING: 'Engineering',
  22. TENDER: 'Tender'
  23. };
  24. // 人材机调整法
  25. const ADJUST_TYPE = {
  26. INFO: 'priceInfo', //造价信息差额调整法
  27. COE: 'priceCoe' //价格指数调整法
  28. };
  29. const CONFIG = Object.freeze({
  30. BILLS_TYPE,
  31. PROJECT_TYPE,
  32. ADJUST_TYPE
  33. });
  34. /*
  35. * 读取文件转换为utf-8编码的字符串
  36. * @param {Blob}file
  37. * @return {Promise}
  38. * */
  39. function readAsTextSync(file) {
  40. return new Promise((resolve, reject) => {
  41. let fr = new FileReader();
  42. fr.readAsText(file); // 默认utf-8,如果出现乱码,得看导入文件是什么编码
  43. fr.onload = function () {
  44. resolve(this.result);
  45. };
  46. fr.onerror = function () {
  47. reject('读取文件失败,请重试。');
  48. }
  49. });
  50. }
  51. /*
  52. * 根据字段数组获得所要字段的值 eg: 要获取标段下的单项工程: ['标段', '单项工程'];
  53. * @param {Object}source 源数据
  54. * {Array}fields 字段数组
  55. * @return {String}
  56. * @example getValue(source, ['标段', '_文件类型'])
  57. * */
  58. function getValue(source, fields) {
  59. let cur = source;
  60. for (let field of fields) {
  61. if (!cur[field]) {
  62. return '';
  63. }
  64. cur = cur[field];
  65. }
  66. return cur || '';
  67. }
  68. // 获取数据类型
  69. function _plainType(v) {
  70. return Object.prototype.toString.call(v).slice(8, -1);
  71. }
  72. /*
  73. * 获取某字段的值,强制返回数组
  74. * @param {Object}source 数据源
  75. * {Array}fields 取的字段
  76. * @return {Array}
  77. * @example arrayValue(source, ['标段', '单项工程'])
  78. * */
  79. function arrayValue(source, fields) {
  80. let target = getValue(source, fields);
  81. if (_plainType(target) === 'Object') {
  82. target = [target];
  83. } else if (_plainType(target) !== 'Array') {
  84. target = []
  85. }
  86. return target;
  87. }
  88. // 获取费用
  89. function getFee(fees, fields) {
  90. if (!Array.isArray(fees) || !fees.length) {
  91. return '0';
  92. }
  93. let feeData = fees.find(fee => fee.fieldName === fields[0]);
  94. return feeData[fields[1]] || '0';
  95. }
  96. // 获取固定ID
  97. function getFlag(data) {
  98. return data.flags && data.flags[0] && data.flags[0].flag || 0;
  99. }
  100. /*
  101. * 递归获取相关数据,eg:获取组织措施清单下的所有子清单,该子清单们可能由分类及公式措施项各种组合组成。(参考调用处)
  102. * @param {Object}src(数据源) {Array}fields(二维数组,数组里的成员由需要取的字段组成)
  103. * eg: ['组织措施分类'], ['公式计算措施项'],该层数据可能由组织措施分类 或 公式计算措施项组成 (同层不可同时存在)
  104. * {Function} 获得源数据后,需要提取的数据方法
  105. * @return {Array}
  106. * */
  107. function getItemsRecur(src, fields, extractFuc) {
  108. let itemsSrc = [],
  109. curField = [''];
  110. for (let field of fields) {
  111. itemsSrc = arrayValue(src, field);
  112. if (itemsSrc.length) {
  113. curField = field;
  114. break;
  115. }
  116. }
  117. return itemsSrc.map(itemSrc => {
  118. let obj = extractFuc(itemSrc, curField);
  119. obj.items = getItemsRecur(itemSrc, fields, extractFuc);
  120. return obj;
  121. });
  122. }
  123. /*
  124. * 转换计算基数
  125. * 1.有子项数据,则清空基数
  126. * 2.行代号引用转换为ID引用
  127. * 3.对应字典代号转换,对应字典里找不到则设置成金额
  128. * @param {Array}billsData 清单数据
  129. * {Object}CalcBaseMap 基数映射
  130. * @return {void}
  131. * */
  132. function transformCalcBase(billsData, CalcBaseMap) {
  133. //行代号 - ID映射
  134. let rowCodeMap = {};
  135. billsData.forEach(data => {
  136. if (data.rowCode) {
  137. rowCodeMap[data.rowCode] = data.ID;
  138. }
  139. });
  140. for (let bills of billsData) {
  141. if (!bills.calcBase) {
  142. continue;
  143. }
  144. let sub = billsData.find(data => data.ParentID === bills.ID);
  145. //有子项数据,则清空基数,费率
  146. if (sub) {
  147. bills.calcBase = '';
  148. bills.feeRate = '';
  149. continue;
  150. }
  151. //提取基数
  152. bills.calcBase = bills.calcBase.replace(/\s/g, '');
  153. let bases = bills.calcBase.split(/[\+\-\*\/]/g);
  154. //提取操作符
  155. let oprs = bills.calcBase.match(/[\+\-\*\/]/g);
  156. //转换后的基数
  157. let newBase = [];
  158. let illegal = false; //不合法
  159. for (let base of bases) {
  160. if (rowCodeMap[base]) { //行引用
  161. newBase.push(`@${rowCodeMap[base]}`);
  162. } else if (CalcBaseMap[base]) { //基数字典
  163. newBase.push(CalcBaseMap[base]);
  164. } else { //都没匹配到,说明软件无法识别此基数
  165. illegal = true;
  166. break;
  167. }
  168. };
  169. if (illegal) {
  170. let fee = getFee(bills.fees, ['common', 'totalFee']);
  171. let feeRate = bills.feeRate && parseFloat(bills.feeRate) !== 0 ? parseFloat(bills.feeRate) : 0;
  172. if (fee && parseFloat(fee) !== 0 && feeRate) {
  173. bills.calcBase = scMathUtil.roundForObj(parseFloat(fee) * 100 / feeRate, 2);
  174. } else {
  175. bills.calcBase = fee !== '0' ? fee : '';
  176. }
  177. } else {
  178. let newCalcBase = '';
  179. for (let i = 0; i < newBase.length; i++) {
  180. newCalcBase += newBase[i];
  181. if (oprs && oprs[i]) {
  182. newCalcBase += oprs[i];
  183. }
  184. }
  185. bills.calcBase = newCalcBase;
  186. }
  187. }
  188. }
  189. // 获取必要的清单模板
  190. async function getNeedfulTemplate(templateLibID) {
  191. return await ajaxPost('/template/bills/api/getNeedfulTemplate',
  192. {templateLibID});
  193. }
  194. const UTIL = Object.freeze({
  195. getValue,
  196. arrayValue,
  197. getFee,
  198. transformCalcBase
  199. });
  200. })();