anhui_maanshan.js 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. /*
  2. * @Descripttion: 安徽-马鞍山 接口
  3. * @Author: vian
  4. * @Date: 2020-08-17 15:40:08
  5. */
  6. // INTERFACE_EXPORT =,必须这么写,这样才能在导出时动态加载脚本后,覆盖前端代码
  7. INTERFACE_EXPORT = (() => {
  8. 'use strict';
  9. /**
  10. *
  11. * @param {String} areaKey - 地区标识,如:'安徽@马鞍山',有些地区的接口只是取值上有不同,共有一个接口脚本, 需要通过地区标识确定一些特殊处理
  12. * @param {Number} exportKind - 导出类型,招标、投标、控制价
  13. * @param {Object} projectData - 项目表数据:{ 建设项目Data, children: [单位工程...] }
  14. * @param {Object} tenderDetailMap - 单位工程ID与getData接口数据(projectObj.project的结构)的映射。
  15. * @return {Promise<Array>} - 返回的数据结构必须按照规定:[{ data, exportKind, fileName }],参考web\building_saas\standard_interface\index.js中的注释说明
  16. */
  17. async function entry(areaKey, exportKind, projectData, tenderDetailMap) {
  18. const {
  19. CONFIG: {
  20. TYPE,
  21. WHITE_SPACE
  22. },
  23. UTIL: {
  24. getValueByKey,
  25. getHan,
  26. getFee,
  27. getUnitFee,
  28. generateHardwareId,
  29. },
  30. Element,
  31. } = INTERFACE_EXPORT_BASE;
  32. const {
  33. EXPORT_KIND: { BID_INVITATION, BID_SUBMISSION, CONTROL },
  34. fixedFlag,
  35. RationType,
  36. } = window.commonConstants
  37. const GljType = gljUtil.gljType;
  38. const { isEmptyVal, isDef } = window.commonUtil;
  39. const isBidInvitation = exportKind === BID_INVITATION; // 是否是招标
  40. const isBidSubmission = exportKind === BID_SUBMISSION; // 是否是投标
  41. const isControl = exportKind === CONTROL; // 是否是控制价
  42. // 节点定义--------------------------------
  43. const subArea = areaKey.split('@')[1];
  44. // 建设项目基本信息
  45. function JingJiBiao(projectName, information) {
  46. const taxModeMap = {
  47. '一般计税': '1',
  48. '简易计税': '2',
  49. };
  50. const czzt = {
  51. [BID_INVITATION]: '招标',
  52. [BID_SUBMISSION]: '投标',
  53. [CONTROL]: '招标控制',
  54. };
  55. const attrs = [
  56. { name: 'Xmbh', value: getValueByKey(information, 'projNum'), minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 项目编号,招标xsd中有规定minLen whiteSpace,这里投标招标统一处理
  57. { name: 'Xmmc', value: projectName }, // 项目名称
  58. { name: 'Bzlx', value: '清单' }, // 项目编制类型
  59. { name: 'Jjyj', value: '【18清单】2018部颁清单计价依据' }, // 计价依据
  60. { name: 'Xmqzzh', value: getValueByKey(information, 'startEndChainages') }, // 项目起止桩号
  61. { name: 'Jsdw', value: getValueByKey(information, 'constructingUnits') }, // 建设单位
  62. { name: 'Czzt', value: czzt[exportKind] }, // 操作状态:招标、投标、招标控制,即导出接口时,所选的文件类型
  63. { name: 'Jsfs', value: taxModeMap[getValueByKey(information, 'taxMode')] || '1', type: TYPE.INT }, // 计税方式,默认1。1=一般计税 2=简易计税
  64. { name: 'Version', value: ['淮北', '铜陵', '亳州', '六安', '张掖', '安庆'].includes(subArea) ? '1.1' : '1.0' },
  65. ];
  66. Element.call(this, 'JingJiBiao', attrs);
  67. }
  68. // 招标信息
  69. function ZhaoBiaoXx(information) {
  70. const attrs = [
  71. { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
  72. { name: 'Zxr', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
  73. { name: 'ZbrDb', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
  74. { name: 'ZxrDb', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
  75. { name: 'Bzr', value: getValueByKey(information, 'compileApprover') }, // 编制人
  76. { name: 'Fhr', value: getValueByKey(information, 'reviewApprover') }, // 复核人
  77. { name: 'BzTime', value: getValueByKey(information, 'compileDate'), type: TYPE.DATE }, // 编制时间
  78. { name: 'FhTime', value: getValueByKey(information, 'reviewDate'), type: TYPE.DATE }, // 复核时间
  79. ];
  80. // 额外字段
  81. const extraMap = {
  82. '淮北': [
  83. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  84. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  85. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  86. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  87. ],
  88. '铜陵': [
  89. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  90. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  91. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  92. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  93. ],
  94. '亳州': [
  95. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  96. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  97. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  98. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  99. ],
  100. '六安': [
  101. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  102. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  103. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  104. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  105. ],
  106. '张掖': [
  107. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  108. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  109. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  110. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  111. ],
  112. '安庆': [
  113. { name: 'ZbrNssbh', value: '' }, // 招标人纳税识别号
  114. { name: 'ZxrNssbh', value: '' }, // 造价咨询人纳税识别号
  115. { name: 'ZbrDbSfzh', value: '' }, // 招标人法定代表人或其授权人身份证号
  116. { name: 'ZxrDbSfzh', value: '' }, // 造价咨询人法定代表或其授权人纳税识别号
  117. ],
  118. };
  119. if (extraMap[subArea]) {
  120. attrs.push(...extraMap[subArea]);
  121. }
  122. Element.call(this, 'ZhaoBiaoXx', attrs);
  123. }
  124. // 招标控制价信息
  125. function ZhaoBiaoKzXx(information, totalCost) {
  126. const attrs = [
  127. { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
  128. { name: 'Zxr', value: getValueByKey(information, 'costConsultant') }, // 造价咨询人
  129. { name: 'ZbrDb', value: getValueByKey(information, 'tenderAuthorizer') }, // 招标人法定代表人或其授权人
  130. { name: 'ZxrDb', value: getValueByKey(information, 'consultantAuthorizer') }, // 造价咨询人法定代表人或其授权人
  131. { name: 'Bzr', value: getValueByKey(information, 'compileApprover') }, // 编制人
  132. { name: 'Fhr', value: getValueByKey(information, 'reviewApprover') }, // 复核人
  133. { name: 'BzTime', value: getValueByKey(information, 'compileDate'), type: TYPE.DATE }, // 编制时间
  134. { name: 'FhTime', value: getValueByKey(information, 'reviewDate'), type: TYPE.DATE }, // 复核时间
  135. { name: 'Zbkzj', value: totalCost, type: TYPE.DECIMAL }, // 控制价总价(元),取“投标报价”的金额。
  136. ];
  137. // 额外字段
  138. const extraMap = {
  139. '淮北': [
  140. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  141. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  142. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  143. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  144. ],
  145. '铜陵': [
  146. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  147. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  148. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  149. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  150. ],
  151. '亳州': [
  152. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  153. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  154. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  155. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  156. ],
  157. '六安': [
  158. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  159. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  160. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  161. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  162. ],
  163. '张掖': [
  164. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  165. { name: 'ZxrNssbh', value: getValueByKey(information, 'costConsultantTaxpayerIdentificationNo') }, // 造价咨询人纳税识别号
  166. { name: 'ZbrDbSfzh', value: getValueByKey(information, 'tenderAuthorizerIDNo') }, // 招标人法定代表人或其授权人身份证号
  167. { name: 'ZxrDbSfzh', value: getValueByKey(information, 'consultantAuthorizerTaxpayerIdentificationNo') }, // 造价咨询人法定代表或其授权人纳税识别号
  168. ],
  169. '安庆': [
  170. { name: 'ZbrNssbh', value: '' }, // 招标人纳税识别号
  171. { name: 'ZxrNssbh', value: '' }, // 造价咨询人纳税识别号
  172. { name: 'ZbrDbSfzh', value: '' }, // 招标人法定代表人或其授权人身份证号
  173. { name: 'ZxrDbSfzh', value: '' }, // 造价咨询人法定代表或其授权人纳税识别号
  174. ],
  175. };
  176. if (extraMap[subArea]) {
  177. attrs.push(...extraMap[subArea]);
  178. }
  179. Element.call(this, 'ZhaoBiaoKzXx', attrs);
  180. }
  181. // 招标控制价信息
  182. function TouBiaoXx(information, totalCost) {
  183. const attrs = [
  184. { name: 'Zbr', value: getValueByKey(information, 'tendereeName') }, // 招标人
  185. { name: 'Tbr', value: getValueByKey(information, 'bidder') }, // 投标人
  186. { name: 'TbrDb', value: getValueByKey(information, 'bidderAuthorizer') }, // 投标人法定代表或其授权
  187. { name: 'Bzr', value: getValueByKey(information, 'compileApprover') }, // 编制人
  188. { name: 'BzTime', value: getValueByKey(information, 'compileDate'), type: TYPE.DATE }, // 编制时间
  189. // { name: 'Tbzj', value: totalCost, type: TYPE.DECIMAL }, // 控制价总价(元),取“投标报价”的金额。
  190. { name: 'Tbzj', value: (totalCost).toFixed(2) }, // 控制价总价(元),取“投标报价”的金额。 //根据需求,固定写死2位小数,所以不设定Decimal,当string来看
  191. ];
  192. // 额外字段
  193. const extraMap = {
  194. '淮北': [
  195. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  196. { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
  197. { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
  198. ],
  199. '铜陵': [
  200. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  201. { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
  202. { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
  203. ],
  204. '亳州': [
  205. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  206. { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
  207. { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
  208. ],
  209. '六安': [
  210. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  211. { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
  212. { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
  213. ],
  214. '张掖': [
  215. { name: 'ZbrNssbh', value: getValueByKey(information, 'tendereeTaxpayerIdentificationNo') }, // 招标人纳税识别号
  216. { name: 'TbrNssbh', value: getValueByKey(information, 'bidderTaxpayerIdentificationNo') }, // 投标人纳税识别号
  217. { name: 'TbrDbSfzh', value: getValueByKey(information, 'bidderAuthorizerTaxpayerIdentificationNo') }, // 投标人法定代表或其授权人身份证号
  218. ],
  219. '安庆': [
  220. { name: 'ZbrNssbh', value: '' }, // 招标人纳税识别号
  221. { name: 'TbrNssbh', value: '' }, // 投标人纳税识别号
  222. { name: 'TbrDbSfzh', value: '' }, // 投标人法定代表或其授权人身份证号
  223. ],
  224. };
  225. if (extraMap[subArea]) {
  226. attrs.push(...extraMap[subArea]);
  227. }
  228. Element.call(this, 'TouBiaoXx', attrs);
  229. }
  230. // 单项工程信息,因项目管理中无“单项工程”这一层,从单位工程的工程特征信息中拼凑出来
  231. function Dxgcxx(code, name) {
  232. const attrs = [
  233. { name: 'Dxgcbh', value: code, minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 单项工程编号
  234. { name: 'Dxgcmc', value: name }, // 单项工程名称
  235. ];
  236. Element.call(this, 'Dxgcxx', attrs);
  237. }
  238. // 单位工程信息
  239. function Dwgcxx(tenderName, feature) {
  240. const attrs = [
  241. { name: 'Dwgcbh', value: getValueByKey(feature, 'unitProjNo'), minLen: 1, whiteSpace: WHITE_SPACE.COLLAPSE }, // 单位工程编号
  242. { name: 'Dwgcmc', value: tenderName }, // 单位工程名称
  243. ];
  244. Element.call(this, 'Dwgcxx', attrs);
  245. }
  246. // 取费信息(费率信息)
  247. function Qfxx() {
  248. Element.call(this, 'Qfxx');
  249. }
  250. // 计价费率表
  251. function JjFlb() {
  252. Element.call(this, 'JjFlb');
  253. }
  254. // 费率明细名称-编码映射表
  255. const FeeRateCodeMap = {
  256. '冬季施工增加费': 'DJF',
  257. '雨季施工增加费': 'YJF',
  258. '夜间施工增加费': 'YEF',
  259. '工地转移费': 'ZYF',
  260. '高原地区施工增加费': 'GYF',
  261. '风沙地区施工增加费': 'FSF',
  262. '沿海地区施工增加费': 'YHF',
  263. '行车干扰施工增加费': 'XCF',
  264. '施工辅助费': 'SFF',
  265. '养老保险费': 'YLF',
  266. '失业保险费': 'SYF',
  267. '医疗保险费': 'YBF',
  268. '住房公积金': 'ZFF',
  269. '工伤保险费': 'GSF',
  270. '基本费用': 'JBF',
  271. '主副食运费补贴': 'YFF',
  272. '职工探亲路费': 'TQF',
  273. '职工取暖补贴': 'QNF',
  274. '财务费用': 'CWF',
  275. '利润': 'LR',
  276. '税金': 'SJ',
  277. };
  278. // 费率工程名称-取费类别映射表
  279. const FeeRateTypeMap = {
  280. '土方': 1,
  281. '路基': 1,
  282. '石方': 3,
  283. '运输': 2,
  284. '路面': 4,
  285. '隧道': 11,
  286. '构造物Ⅰ': 5,
  287. '构造物Ⅰ(不计冬)': 16,
  288. '构造物Ⅱ': 6,
  289. '构造物Ⅲ(桥梁)': 9,
  290. '桥梁': 9,
  291. '构造物Ⅲ(除桥以外不计雨夜)': 8,
  292. '技术复杂大桥': 10,
  293. '钢材及钢结构(桥梁)': 12,
  294. '钢材及钢结构': 12,
  295. '钢材及钢结构(除桥以外不计夜)': 13,
  296. '费率为0': 17,
  297. '路面(不计雨)': 18,
  298. '构造物Ⅰ(不计雨)': 19,
  299. '构造物Ⅲ(除桥以外)': 7,
  300. '钢材及钢结构(除桥以外)': 20,
  301. '设备': 15,
  302. '量价': 14,
  303. };
  304. // 计价费率表明细,造价书费率页面左侧最底层数据
  305. function JjFlbMx(rootItem, item) {
  306. const rate = isEmptyVal(item.rate) ? '100' : item.rate; // 为空时输出=100,为0时输出=0
  307. const attrs = [
  308. { name: 'Bm', value: FeeRateCodeMap[item.name] }, // 编码
  309. { name: 'Name', value: item.name }, // 名称
  310. { name: 'Fl', value: rate, type: TYPE.DECIMAL }, // 费率
  311. { name: 'Qflb', value: FeeRateTypeMap[rootItem.name], type: TYPE.INT }, // 取费类别
  312. ];
  313. Element.call(this, 'JjFlbMx', attrs);
  314. }
  315. // 计价费率项
  316. function JjFlx() {
  317. Element.call(this, 'JjFlx');
  318. }
  319. // 计价费率项明细,造价书费率页面右侧最顶层数据
  320. function JjFlxMx(item) {
  321. // 编码取名称拼音首字母
  322. const allHanName = getHan(item.name || '');
  323. const code = pinyinUtil.getFirstLetter(allHanName).toLowerCase();
  324. let value;
  325. if (isDef(item.value)) {
  326. value = item.value;
  327. } else {
  328. const selected = item.optionList.find(item => item.selected);
  329. value = selected && selected.name || '';
  330. }
  331. const attrs = [
  332. { name: 'Bm', value: code }, // 编码
  333. { name: 'Mc', value: item.name }, // 名称
  334. { name: 'ShuZhi', value: value }, // 数值
  335. ];
  336. Element.call(this, 'JjFlxMx', attrs);
  337. }
  338. // 清单项目
  339. function QdXm() {
  340. Element.call(this, 'QdXm');
  341. }
  342. // 标题类别:1=100~700清单合计,2=暂估价合计,3=清单不包含暂估价合计,4=计日工,5=暂列金额(不含计日工总额)),6=投标报价,0=其他
  343. const BillsTitleType = {
  344. [fixedFlag.ONE_SEVEN_BILLS]: '1',
  345. [fixedFlag.PROVISIONAL_TOTAL]: '2',
  346. [fixedFlag.BILLS_TOTAL_WT_PROV]: '3',
  347. [fixedFlag.DAYWORK_LABOR]: '4',
  348. [fixedFlag.PROVISIONAL]: '5',
  349. [fixedFlag.TOTAL_COST]: '6',
  350. };
  351. // 标题映射
  352. /* 写死:
  353. “第100章至700章清单”输出=1、
  354. “已包含在清单合计中的材料、工程设备、专业工程暂估价合计”输出=9、
  355. “清单合计减去材料、工程设备、专业工程暂估价合计”输出=10、
  356. “计日工合计”输出=11、
  357. “暂列金额(不含计日工总额)”输出=12、
  358. “投标报价”输出=13;
  359. 如果有新增的同级的大项费用,则以14开始编号 */
  360. const BillsTitleValue = {
  361. [fixedFlag.ONE_SEVEN_BILLS]: '1',
  362. [fixedFlag.PROVISIONAL_TOTAL]: '9',
  363. [fixedFlag.BILLS_TOTAL_WT_PROV]: '10',
  364. [fixedFlag.DAYWORK_LABOR]: '11',
  365. [fixedFlag.PROVISIONAL]: '12',
  366. [fixedFlag.TOTAL_COST]: '13',
  367. };
  368. let curTitleValue;
  369. // 清单标题 造价书的第一层数据。
  370. function QdBt(node, allNodes) {
  371. const row = node.row();
  372. const orgFee = getFee(node.data.fees, 'common.tenderTotalFee');
  373. const fee = isBidInvitation ? '0' : orgFee;
  374. const flag = node.getFlag();
  375. // 编号:清单编码有值则直接取,无值则写死
  376. const bm = node.data.code || BillsTitleValue[flag] || curTitleValue++;
  377. const titleType = BillsTitleType[flag];
  378. const calcBase = titleType === '5'
  379. ? orgFee
  380. : node.data.calcBase
  381. ? cbParser.toFExpr(node.data.calcBase, allNodes)
  382. : '';
  383. const attrs = [
  384. { name: 'Xh', value: row, type: TYPE.INT }, // 序号
  385. { name: 'Bm', value: bm }, // 编码
  386. { name: 'Name', value: node.data.name }, // 名称
  387. { name: 'Je', value: fee, type: TYPE.DECIMAL }, // 金额
  388. { name: 'Code', value: `F${row}` }, // 行引用
  389. { name: 'Jsgs', value: calcBase }, // 计算基数
  390. { name: 'Lb', value: titleType, type: TYPE.INT }, // 类别
  391. { name: 'Bz', value: node.data.remark }, // 备注
  392. ];
  393. Element.call(this, 'QdBt', attrs);
  394. }
  395. // 清单明细 (只有100-700章清单标题输出)
  396. function QdMx(node, allNodes) {
  397. const row = node.row();
  398. const name = node.data.name || '';
  399. // 编码: 清单编码有值则取清单编码,无值则:清单非章级的,读取清单编码列。章级的清单,写死:“清单第100章总则”输出=100,“清单第200章”输出=200,依次类推。可以判断章级的,取清单名称中的数字。
  400. let code = node.data.code || '';
  401. if (!code) {
  402. const codeMatched = name.match(/第\s*(\d+)\s*章/);
  403. if (codeMatched && codeMatched[1]) {
  404. code = codeMatched[1];
  405. }
  406. }
  407. const iszg = node.data.specialProvisional === '专业工程';
  408. const calcBaseBeFee = iszg || node.getFlag() === fixedFlag.PROVISIONAL;
  409. const orgFee = getFee(node.data.fees, 'common.tenderTotalFee');
  410. const calcBase = calcBaseBeFee
  411. ? orgFee
  412. : node.data.calcBase
  413. ? cbParser.toFExpr(node.data.calcBase, allNodes)
  414. : '';
  415. const attrs = [
  416. { name: 'Xh', value: row, type: TYPE.INT }, // 序号
  417. { name: 'Qdbm', value: code, minLen: 1 }, // 编码
  418. { name: 'Name', value: node.data.name }, // 名称
  419. { name: 'Dw', value: node.data.unit }, // 单位
  420. { name: 'Sl', value: node.data.quantity, type: TYPE.DECIMAL }, // 工程量
  421. { name: 'Sl2', value: '0', type: TYPE.DECIMAL }, // 工程量2
  422. { name: 'Rgf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketLabour.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 人工费
  423. { name: 'Clf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketMaterial.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 材料费
  424. { name: 'Jxf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketMachine.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 机械费
  425. { name: 'Sbf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'marketEquipment.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 设备费
  426. { name: 'Csf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'measure.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 措施费
  427. { name: 'Glf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'manage.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 企业管理费
  428. { name: 'Gf', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'force.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 规费
  429. { name: 'Lr', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'profit.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 利润
  430. { name: 'Sj', value: isBidInvitation ? '0' : getUnitFee(getFee(node.data.fees, 'tax.tenderTotalFee'),node.data.quantity,2), type: TYPE.DECIMAL }, // 税金
  431. { name: 'Zhdj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 单价
  432. { name: 'Zhhj', value: isBidInvitation ? '0' : orgFee, type: TYPE.DECIMAL }, // 合价
  433. { name: 'Zgj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'estimate.tenderTotalFee'), type: TYPE.DECIMAL }, // 暂估价
  434. { name: 'Iszg', value: iszg, type: TYPE.BOOL }, // 是否暂定 如果专项暂定列选择了“专业工程”,则输出true,否则是false。
  435. { name: 'Djfx', value: !!node.data.unitPriceAnalysis, type: TYPE.BOOL }, // 单价分析
  436. { name: 'Jsgs', value: calcBase }, // 计算基数
  437. { name: 'Bl', value: '' }, // 变量
  438. { name: 'Bz', value: node.data.remark }, // 备注
  439. ];
  440. Element.call(this, 'QdMx', attrs);
  441. }
  442. // 定额组价
  443. function Qdxdezj() {
  444. Element.call(this, 'Qdxdezj');
  445. }
  446. // 定额租价明细 招标文件不输出
  447. function QdxdezjMx(ration) {
  448. const typeMap = {
  449. [RationType.RATION]: '1',
  450. [RationType.VOLUME_PRICE + GljType.LABOUR]: '2',
  451. [RationType.VOLUME_PRICE + GljType.GENERAL_MATERIAL]: '3',
  452. [RationType.VOLUME_PRICE + GljType.GENERAL_MACHINE]: '4',
  453. [RationType.VOLUME_PRICE + GljType.EQUIPMENT]: '2',
  454. };
  455. const typeKey = (ration.type || '') + (ration.subType || '');
  456. const type = typeMap[typeKey];
  457. const attrs = [
  458. { name: 'Debm', value: ration.code }, // 编码
  459. { name: 'Mc', value: ration.name }, // 名称
  460. { name: 'Dw', value: ration.unit }, // 单位
  461. { name: 'Sl', value: ration.tenderQuantity, type: TYPE.DECIMAL }, // 工程量
  462. { name: 'Dj', value: getFee(ration.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 单价
  463. { name: 'Hj', value: getFee(ration.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 合价
  464. { name: 'Rgf', value: getUnitFee(getFee(ration.fees, 'marketLabour.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 人工费
  465. { name: 'Clf', value: getUnitFee(getFee(ration.fees, 'marketMaterial.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 材料费
  466. { name: 'Jxf', value: getUnitFee(getFee(ration.fees, 'marketMachine.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 机械费
  467. { name: 'Sbf', value: getUnitFee(getFee(ration.fees, 'marketEquipment.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 设备费
  468. { name: 'Csf', value: getUnitFee(getFee(ration.fees, 'measure.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 措施费
  469. { name: 'Glf', value: getUnitFee(getFee(ration.fees, 'manage.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 企业管理费
  470. { name: 'Gf', value: getUnitFee(getFee(ration.fees, 'force.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 规费
  471. { name: 'Lr', value: getUnitFee(getFee(ration.fees, 'profit.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 利润
  472. { name: 'Sj', value: getUnitFee(getFee(ration.fees, 'tax.tenderTotalFee'),ration.tenderQuantity,2), type: TYPE.DECIMAL }, // 税金
  473. { name: 'Delb', value: type, type: TYPE.INT }, // 取定额/量价/设备的类别。(1=普通定额,2=人工,3=材料,4=机械,5=设备)
  474. { name: 'Iszd', value: 'false', type: TYPE.BOOL }, // 暂时,全部取fals
  475. ];
  476. Element.call(this, 'QdxdezjMx', attrs);
  477. }
  478. // 定额人材机含量
  479. function Qdxdercjhl() {
  480. Element.call(this, 'Qdxdercjhl');
  481. }
  482. // 定额人材机含量明细
  483. function QdxdercjhlMx(rcjID, quantity) {
  484. const attrs = [
  485. { name: 'RcjId', value: rcjID }, // 人材机资源ID
  486. { name: 'Sl', value: quantity, type: TYPE.DECIMAL }, // 消耗量
  487. ]
  488. Element.call(this, 'QdxdercjhlMx', attrs);
  489. }
  490. // 清单人材机含量
  491. function Qdxrcjhl() {
  492. Element.call(this, 'Qdxrcjhl');
  493. }
  494. // 清单人材机含量明细
  495. function QdxrcjhlMx(item) {
  496. const attrs = [
  497. { name: 'RcjId', value: item.rcjID }, // 人材机资源ID
  498. { name: 'Rcjhl', value: item.contain, type: TYPE.DECIMAL }, // 含量:取叶子清单下所有的人材机的含量,=各定额下的人材机总消耗量之和,再除以清单工程量
  499. { name: 'Rcjhj', value: item.totalPrice, type: TYPE.DECIMAL }, // 合价:人材机含量*人材机预算价
  500. { name: 'Zgjbz', value: item.isEvaluate, type: TYPE.BOOL }, // 是否暂估,根据资源ID,读取工料机汇总界面对应的“是否暂估”
  501. { name: 'Zcbz', value: 'false', type: TYPE.BOOL }, // 主材标记,公路上无此概念,默认输出=fales
  502. { name: 'Zyclbz', value: item.isMainMaterial, type: TYPE.BOOL }, // 根据资源ID,读取工料机汇总界面对应的“主要材料”
  503. ]
  504. Element.call(this, 'QdxrcjhlMx', attrs);
  505. }
  506. // 计日工
  507. function Jrg() {
  508. Element.call(this, 'Jrg');
  509. }
  510. // 计日工标题
  511. function JrgBt(node) {
  512. const typeMap = {
  513. [fixedFlag.LABOUR_SERVICE]: '1',
  514. [fixedFlag.MATERIAL]: '2',
  515. [fixedFlag.CONSTRUCTION_MACHINE]: '3',
  516. };
  517. const attrs = [
  518. { name: 'Name', value: node.data.name }, // 名称
  519. { name: 'Je', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 金额
  520. { name: 'Lb', value: typeMap[node.getFlag()], type: TYPE.INT }, // 类别:1=劳务;2=材料;3=施工机械
  521. { name: 'Bz', value: node.data.remark }, // 备注
  522. ];
  523. Element.call(this, 'JrgBt', attrs);
  524. }
  525. // 计日工明细
  526. function JrgMx(node) {
  527. const attrs = [
  528. { name: 'Bh', value: node.data.code }, // 编码
  529. { name: 'Name', value: node.data.name }, // 名称
  530. { name: 'Dw', value: node.data.unit }, // 单位
  531. { name: 'Sl', value: node.data.quantity, type: TYPE.DECIMAL }, // 工程量
  532. { name: 'Dj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee'), type: TYPE.DECIMAL }, // 单价
  533. { name: 'Hj', value: isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderUnitFee'), type: TYPE.DECIMAL }, // 合价
  534. ];
  535. Element.call(this, 'JrgMx', attrs);
  536. }
  537. // 暂估材料表、评标材料表
  538. function gljRefRoot(eleName) {
  539. Element.call(this, eleName);
  540. }
  541. // 暂估材料表、评标材料表明细
  542. function gljRefElement(eleName, glj) {
  543. const attrs = [
  544. { name: 'Xh', value: glj.seq }, // 序号
  545. { name: 'RcjId', value: projectGLJIDToRcjID[glj.projectGLJID] }, // 资源ID
  546. { name: 'Bm', value: glj.code }, // 编码
  547. { name: 'Mc', value: glj.name }, // 名称
  548. { name: 'Ggxh', value: glj.specs }, // 规格型号
  549. { name: 'Dw', value: glj.unit }, // 单位
  550. { name: 'Sl', value: BID_INVITATION ? '0' : glj.quantity, type: TYPE.DECIMAL }, // 工程量
  551. { name: 'Dj', value: glj.marketPrice, type: TYPE.DECIMAL }, // 暂定价、单价
  552. { name: 'Hj', value: BID_INVITATION ? '0' : glj.totalPrice, type: TYPE.DECIMAL }, // 合价
  553. { name: 'Bz', value: glj.remark }, // 备注
  554. ];
  555. Element.call(this, eleName, attrs);
  556. }
  557. // 人材机汇总
  558. function Rcjhz() {
  559. Element.call(this, 'Rcjhz');
  560. }
  561. // 人材机汇总明细
  562. function RcjhzMx(glj) {
  563. const rootTypeReg = /\d/;
  564. let rootType = rootTypeReg.exec(glj.type)[0];
  565. if (!['1', '2', '3'].includes(rootType)) {
  566. rootType = '2';
  567. }
  568. const attrs = [
  569. { name: 'RcjId', value: projectGLJIDToRcjID[glj.id] }, // 资源ID
  570. { name: 'RcjBm', value: glj.code }, // 编码
  571. { name: 'Name', value: glj.name }, // 名称
  572. { name: 'Ggxh', value: glj.specs }, // 规格型号
  573. { name: 'Dw', value: glj.unit }, // 单位
  574. { name: 'Dj', value: glj.priceInfo.tenderPrice, type: TYPE.DECIMAL }, // 预算价,调后
  575. { name: 'Sl', value: glj.tenderQuantity, type: TYPE.DECIMAL }, // 总消耗量
  576. { name: 'Hj', value: glj.priceInfo.totalPrice, type: TYPE.DECIMAL }, // 合价,人材料总消耗量*预算价
  577. { name: 'Cd', value: '' }, // 产地
  578. { name: 'Gycs', value: '' }, // 厂商
  579. { name: 'Rcjlb', value: rootType, type: TYPE.INT }, // 人材机类型 1=人工;2=材料;3=机械
  580. { name: 'Jgbz', value: 'false', type: TYPE.BOOL }, // 供材方
  581. { name: 'Zyclbz', value: !!glj.is_main_material, type: TYPE.BOOL }, // 主要材料
  582. { name: 'Zgjbz', value: !!glj.is_evaluate, type: TYPE.BOOL }, // 是否暂估
  583. { name: 'Zcbz', value: 'false' , type: TYPE.BOOL }, // 主材标记
  584. ];
  585. console.log(!!glj.is_main_material);
  586. Element.call(this, 'RcjhzMx', attrs);
  587. }
  588. // 配比组成
  589. function PbZc() {
  590. Element.call(this, 'PbZc');
  591. }
  592. // 配比明细
  593. function PbZcMx(ratio) {
  594. const attrs = [
  595. { name: 'RcjId', value: projectGLJIDToRcjID[ratio.projectGLJID] }, // 组成物对应人材机汇总的资源ID
  596. { name: 'Sl', value: ratio.consumption, type: TYPE.DECIMAL }, // 组成物消耗量
  597. ];
  598. Element.call(this, 'PbZcMx', attrs);
  599. }
  600. // 校验信息
  601. function Jyxx(cpuID, diskID, macID, toMD5Value) {
  602. const attrs = [
  603. { name: 'SoftName', value: '珠海纵横创新软件有限公司' }, // 公司名
  604. { name: 'SoftNum', value: md5(toMD5Value) }, // 校验数据
  605. { name: 'MacAdress', value: macID }, // mac地址
  606. { name: 'DogNum', value: userID }, // 加密锁号,取用户ID
  607. { name: 'ComputerName', value: USER_NAME }, // 计算机名,取用户名称
  608. { name: 'HDDSerial', value: diskID }, // 硬盘序列号
  609. { name: 'CPUSerial', value: cpuID }, // CPU序列号
  610. ];
  611. Element.call(this, 'Jyxx', attrs);
  612. }
  613. // 组装数据 --------------------------------------
  614. // 组装建设项目数据
  615. function setupConstruction(constructionData) {
  616. const information = constructionData.property && constructionData.property.basicInformation || [];
  617. const summaryInfo = constructionData.summaryInfo[constructionData.ID];
  618. const jingJiBiao = new JingJiBiao(constructionData.name, information);
  619. if (isBidInvitation) {
  620. jingJiBiao.children.push(new ZhaoBiaoXx(information));
  621. } else if (isControl) {
  622. jingJiBiao.children.push(new ZhaoBiaoKzXx(information, summaryInfo.totalCost));
  623. } else {
  624. jingJiBiao.children.push(new TouBiaoXx(information, summaryInfo.totalCost));
  625. }
  626. // 将单位工程工程特征中,单项工程编号、名称相同的,插入到建设项目和分段(单位工程)的中间层。
  627. const midLayerMap = {}; // 单项工程key(code@name)与单项工程节点映射
  628. for (const tenderData of constructionData.children) {
  629. const feature = tenderData.property && tenderData.property.projectFeature || [];
  630. const midLayerCode = getValueByKey(feature, 'singleProjNo');
  631. const midLayerName = getValueByKey(feature, 'singleProjName');
  632. const midLayerKey = `${midLayerCode}@${midLayerName}`;
  633. if (!midLayerMap[midLayerKey]) {
  634. jingJiBiao.children.push(midLayerMap[midLayerKey] = new Dxgcxx(midLayerCode, midLayerName));
  635. }
  636. midLayerMap[midLayerKey].children.push(setupTender(tenderData, information, feature));
  637. }
  638. // 校验信息
  639. const [cpuID, diskID, macID] = generateHardwareId().split(';');
  640. const suffix = INTERFACE_CONFIG[areaKey]['fileSuffix'][exportKind];
  641. // 需要md5的值:MD5(“WHGLZTB”+项目名称+机器码+加密锁锁号)机器码取mac地址,加密锁锁号取用户账号id
  642. const toMD5Suffix = suffix.split('.')[1];
  643. const toMD5Value = `${toMD5Suffix}${constructionData.name}${macID}${userID}`;
  644. jingJiBiao.children.push(new Jyxx(cpuID, diskID, macID, suffix, toMD5Value));
  645. return [{
  646. data: jingJiBiao,
  647. exportKind,
  648. fileName: `${constructionData.name}${suffix}`
  649. }];
  650. }
  651. // getData接口数据
  652. let curDetail;
  653. // 需要先设置项目人材机的关联ID(从1开始),因为定额人材机等一些节点需要用到这个关联ID
  654. const projectGLJIDToRcjID = {}; // 项目人材机ID与新生成的整形ID映射
  655. const projectGLJMap = {}; // 项目人材机与项目人材机数据映射
  656. // 组装单位工程数据
  657. function setupTender(tenderData, info, feature) {
  658. curDetail = tenderDetailMap[tenderData.ID];
  659. curDetail.projectGLJ.datas.gljList.forEach((glj, index) => {
  660. projectGLJIDToRcjID[glj.id] = index + 1;
  661. projectGLJMap[glj.id] = glj;
  662. });
  663. curTitleValue = 14;
  664. const dwgcxx = new Dwgcxx(tenderData.name, feature);
  665. dwgcxx.children.push(
  666. setupFeeRate(curDetail.FeeRate, info),
  667. setupBills(curDetail.mainTree),
  668. ...setupGLJList(curDetail)
  669. );
  670. return dwgcxx;
  671. }
  672. // 组装费率数据
  673. function setupFeeRate(feeRateDetail, info) {
  674. const qfxx = new Qfxx();
  675. const jjflb = new JjFlb();
  676. // 费率界面左侧底层数据
  677. let curRootItem;
  678. feeRateDetail.datas.rates.forEach(item => {
  679. if (!item.ParentID) {
  680. curRootItem = item;
  681. } else if (!item.sum) { // 最底层
  682. const curFeeRateType = FeeRateTypeMap[curRootItem.name];
  683. const exclude = [18, 19, 20];
  684. if (!exclude.includes(curFeeRateType)) {
  685. jjflb.children.push(new JjFlbMx(curRootItem, item));
  686. }
  687. }
  688. });
  689. // 费率界面右侧顶层数据
  690. // 除右侧数据外,还应拼凑工程所在地、费率标准的数据。
  691. const jjflx = new JjFlx();
  692. // 工程所在地取建设项目-基本信息中的“工程所在地”;
  693. const locationItem = { name: '工程所在地', value: getValueByKey(info, 'location') };
  694. jjflx.children.push(new JjFlxMx(locationItem));
  695. // 费率标准取,费率-重选标准中当前用的费率标准名称。
  696. const feeRateStandardItem = { name: '费率标准', value: feeRateDetail.datas.libName };
  697. jjflx.children.push(new JjFlxMx(feeRateStandardItem));
  698. const flxmxData = feeRateDetail
  699. .getAllSubRates()
  700. .filter(item => !item.isSub)
  701. .map(item => new JjFlxMx(item));
  702. jjflx.children.push(...flxmxData);
  703. qfxx.children.push(jjflb, jjflx);
  704. return qfxx;
  705. }
  706. // 组装清单数据
  707. function setupBills(mainTree) {
  708. const qdxm = new QdXm();
  709. mainTree.roots.forEach(node => {
  710. const flag = node.getFlag();
  711. const qdbt = new QdBt(node, mainTree.items);
  712. if (flag === fixedFlag.ONE_SEVEN_BILLS) { // 100章到700章清单需要输出详细数据
  713. qdbt.children.push(...setupSubBills(node.children, mainTree.items));
  714. } else if (flag === fixedFlag.DAYWORK_LABOR) {
  715. qdbt.children.push(setupDaywork(node.children));
  716. }
  717. qdxm.children.push(qdbt);
  718. });
  719. function setupSubBills(nodes, allNodes) {
  720. const rst = [];
  721. nodes.forEach(node => {
  722. const qdmx = new QdMx(node, allNodes);
  723. rst.push(qdmx);
  724. const subIsRations = node.children.length && !node.source.children.length;
  725. if (subIsRations) {
  726. qdmx.children.push(...setupRations(node.children));
  727. qdmx.children.push(...setupBillsContain(node.data,node.children));
  728. } else {
  729. qdmx.children.push(...setupSubBills(node.children, allNodes));
  730. }
  731. });
  732. return rst;
  733. }
  734. function setupDaywork(nodes) {
  735. const dayworkRoot = new Jrg();
  736. const dayworkBT = nodes.map(node => {
  737. const bt = new JrgBt(node);
  738. const dayworkMX = node.children.map(child => new JrgMx(child));
  739. bt.children.push(...dayworkMX);
  740. return bt;
  741. });
  742. dayworkRoot.children.push(...dayworkBT);
  743. return dayworkRoot;
  744. }
  745. return qdxm;
  746. }
  747. // 组装定额、定额人材机数据
  748. function setupRations(rationNodes) {
  749. // 招标文件不输出
  750. if (isBidInvitation) {
  751. return [];
  752. }
  753. const rationRoot = new Qdxdezj();
  754. const rationEles = rationNodes.map(node => {
  755. const rationEle = new QdxdezjMx(node.data);
  756. /* // 定额人材机
  757. let rationGLJList = curDetail.ration_glj.datas.filter(glj => glj.rationID === node.data.ID);
  758. rationGLJList = gljUtil.sortRationGLJ(rationGLJList); */
  759. const rationGLJRoot = new Qdxdercjhl();
  760. const rationGLJEles = node.data.rationGLJList.map(glj => new QdxdercjhlMx(projectGLJIDToRcjID[glj.projectGLJID], glj.tenderQuantity));
  761. rationGLJRoot.children.push(...rationGLJEles);
  762. rationEle.children.push(rationGLJRoot);
  763. return rationEle;
  764. });
  765. rationRoot.children.push(...rationEles);
  766. return [rationRoot];
  767. }
  768. // 组装清单人材机含量数据
  769. function setupBillsContain(bills,rationNodes) {
  770. if (isBidInvitation) {
  771. return [];
  772. }
  773. const rationIDMap = {};
  774. for(const node of rationNodes){
  775. rationIDMap[node.data.ID] = node.data;
  776. }
  777. // 读取清单下的人材机,先将各定额下的人材机汇总,相同的合并(相同的项目人材机ID)
  778. const gljList = curDetail.ration_glj.datas.filter(glj => glj.billsItemID === bills.ID);
  779. if (!gljList) {
  780. return [];
  781. }
  782. const map = {};
  783. gljList.forEach(glj => {
  784. if (!map[glj.projectGLJID]) {
  785. const projectGLJ = projectGLJMap[glj.projectGLJID];
  786. map[glj.projectGLJID] = {
  787. rcjID: projectGLJIDToRcjID[glj.projectGLJID],
  788. totalQuantity: !!rationIDMap[glj.rationID]?gljOprObj.getTotalQuantity(glj,rationIDMap[glj.rationID]):0 ,
  789. price: projectGLJ.priceInfo.tenderPrice,
  790. isEvaluate: !!projectGLJ.is_evaluate,
  791. isMainMaterial: !!projectGLJ.is_main_material
  792. };
  793. } else {
  794. const subQuantity = !!rationIDMap[glj.rationID]?gljOprObj.getTotalQuantity(glj,rationIDMap[glj.rationID]):0;
  795. map[glj.projectGLJID].totalQuantity = scMathUtil.roundTo(map[glj.projectGLJID].totalQuantity + subQuantity, -6);
  796. }
  797. });
  798. const containItems = Object
  799. .values(map)
  800. .map(glj => {
  801. const contain = glj.totalQuantity / (bills.quantity || 1);
  802. return {
  803. rcjID: glj.rcjID,
  804. contain: scMathUtil.roundTo(contain, -6), // 固定取6位
  805. totalPrice: scMathUtil.roundTo(contain * glj.price, -2), // 固定取2位
  806. isEvaluate: glj.isEvaluate,
  807. isMainMaterial: glj.isMainMaterial
  808. };
  809. });
  810. const root = new Qdxrcjhl();
  811. root.children.push(...containItems.map(item => new QdxrcjhlMx(item)));
  812. return [root]
  813. }
  814. // 组装人材机汇总相关表数据
  815. function setupGLJList(tenderDetail) {
  816. // 暂估材料
  817. const zgcl = new gljRefRoot('ZgCl');
  818. zgcl.children = tenderDetail.evaluateMaterialData.map(glj => new gljRefElement('ZgClMx', glj));
  819. // 评标材料
  820. const jpcl = new gljRefRoot('JpCl');
  821. jpcl.children = tenderDetail.bidMaterialData.map(glj => new gljRefElement('JpClMx', glj));
  822. if (isBidInvitation) {
  823. return [zgcl, jpcl];
  824. }
  825. // 人材机汇总 (招标不导出)
  826. const rcjhz = new Rcjhz();
  827. rcjhz.children = tenderDetail.projectGLJ.datas.gljList.map(pGLJ => {
  828. const gljElement = new RcjhzMx(pGLJ);
  829. // 组成物
  830. const connectKey = gljUtil.getIndex(pGLJ, gljKeyArray);
  831. const ratioData = tenderDetail.projectGLJ.datas.mixRatioMap[connectKey];
  832. if (ratioData && ratioData.length) {
  833. const pbzc = new PbZc();
  834. pbzc.children = ratioData.map(ratio => new PbZcMx(ratio));
  835. gljElement.children.push(pbzc);
  836. }
  837. return gljElement;
  838. });
  839. return [zgcl, jpcl, rcjhz];
  840. }
  841. return setupConstruction(projectData);
  842. }
  843. return {
  844. entry,
  845. };
  846. })();