anhui_maanshan.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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: { TYPE },
  20. UTIL: {
  21. getValueByKey,
  22. getHan,
  23. getFee,
  24. },
  25. Element,
  26. } = INTERFACE_EXPORT_BASE;
  27. const {
  28. EXPORT_KIND: { BID_INVITATION, BID_SUBMISSION, CONTROL },
  29. fixedFlag,
  30. } = window.commonConstants
  31. const { isEmptyVal, isDef } = window.commonUtil;
  32. const czzt = {
  33. [BID_INVITATION]: '招标',
  34. [BID_SUBMISSION]: '投标',
  35. [CONTROL]: '招标控制',
  36. };
  37. const isBidInvitation = exportKind === BID_INVITATION; // 是否是招标
  38. const isBidSubmission = exportKind === BID_SUBMISSION; // 是否是投标
  39. const isControl = exportKind === CONTROL; // 是否是控制价
  40. // 节点定义--------------------------------
  41. // 建设项目基本信息
  42. function JingJiBiao(projectName, information) {
  43. const attrs = [
  44. { name: 'Xmbh', value: getValueByKey(information, 'projNum') }, // 项目编号
  45. { name: 'Xmmc', value: projectName }, // 项目名称
  46. { name: 'Bzlx', value: '清单' }, // 项目编制类型
  47. { name: 'Jjyj', value: '【18清单】2018部颁清单计价依据' }, // 计价依据
  48. { name: 'Xmqzzh', value: getValueByKey(information, '') }, // 项目起止桩号
  49. { name: 'Jsdw', value: getValueByKey(information, '') }, // 建设单位
  50. { name: 'Czzt', value: czzt[exportKind] }, // 操作状态:招标、投标、招标控制,即导出接口时,所选的文件类型
  51. { name: 'Jsfs', value: getValueByKey(information, '') || '1', type: TYPE.INT }, // 计税方式,默认1。1=一般计税 2=简易计税
  52. { name: 'Version', value: '1.0' },
  53. ];
  54. Element.call(this, 'JingJiBiao', attrs);
  55. }
  56. const subArea = areaKey.split('@')[1];
  57. // 招标信息
  58. function ZhaoBiaoXx(information) {
  59. const attrs = [
  60. { name: 'Zbr', value: getValueByKey(information, '') }, // 招标人
  61. { name: 'Zxr', value: getValueByKey(information, '') }, // 造价咨询人
  62. { name: 'ZbrDb', value: getValueByKey(information, '') }, // 招标人法定代表人或其授权人
  63. { name: 'ZxrDb', value: getValueByKey(information, '') }, // 造价咨询人法定代表人或其授权人
  64. { name: 'Bzr', value: getValueByKey(information, '') }, // 编制人
  65. { name: 'Fhr', value: getValueByKey(information, '') }, // 复核人
  66. { name: 'BzTime', value: getValueByKey(information, ''), type: TYPE.DATE }, // 编制时间
  67. { name: 'FhTime', value: getValueByKey(information, ''), type: TYPE.DATE }, // 复核时间
  68. ];
  69. // 额外字段
  70. const extraMap = {
  71. '淮北': [
  72. { name: 'ZbrNssbh', value: getValueByKey(information, '') }, // 招标人纳税识别号
  73. { name: 'ZxrNssbh', value: getValueByKey(information, '') }, // 造价咨询人纳税识别号
  74. { name: 'ZbrDbSfzh', value: getValueByKey(information, '') }, // 招标人法定代表人或其授权人身份证号
  75. { name: 'ZxrNssbh', value: getValueByKey(information, '') }, // 造价咨询人法定代表或其授权人纳税识别号
  76. ]
  77. };
  78. if (extraMap[subArea]) {
  79. attrs.push(...extraMap[subArea]);
  80. }
  81. Element.call(this, 'ZhaoBiaoXx', attrs);
  82. }
  83. // 招标控制价信息
  84. function ZhaoBiaoKzXx(information) {
  85. const attrs = [
  86. { name: 'Zbr', value: getValueByKey(information, '') }, // 招标人
  87. { name: 'Zxr', value: getValueByKey(information, '') }, // 造价咨询人
  88. { name: 'ZbrDb', value: getValueByKey(information, '') }, // 招标人法定代表人或其授权人
  89. { name: 'ZxrDb', value: getValueByKey(information, '') }, // 造价咨询人法定代表人或其授权人
  90. { name: 'Bzr', value: getValueByKey(information, '') }, // 编制人
  91. { name: 'Fhr', value: getValueByKey(information, '') }, // 复核人
  92. { name: 'BzTime', value: getValueByKey(information, ''), type: TYPE.DATE }, // 编制时间
  93. { name: 'FhTime', value: getValueByKey(information, ''), type: TYPE.DATE }, // 复核时间
  94. { name: 'Zbkzj', value: getValueByKey(information, ''), type: TYPE.DECIMAL }, // 控制价总价(元),取“投标报价”的金额。
  95. ];
  96. // 额外字段
  97. const extraMap = {
  98. '淮北': [
  99. { name: 'ZbrNssbh', value: getValueByKey(information, '') }, // 招标人纳税识别号
  100. { name: 'ZxrNssbh', value: getValueByKey(information, '') }, // 造价咨询人纳税识别号
  101. { name: 'ZbrDbSfzh', value: getValueByKey(information, '') }, // 招标人法定代表人或其授权人身份证号
  102. { name: 'ZxrNssbh', value: getValueByKey(information, '') }, // 造价咨询人法定代表或其授权人纳税识别号
  103. ]
  104. };
  105. if (extraMap[subArea]) {
  106. attrs.push(...extraMap[subArea]);
  107. }
  108. Element.call(this, 'ZhaoBiaoKzXx', attrs);
  109. }
  110. // 招标控制价信息
  111. function TouBiaoXx(information) {
  112. const attrs = [
  113. { name: 'Zbr', value: getValueByKey(information, '') }, // 招标人
  114. { name: 'Tbr', value: getValueByKey(information, '') }, // 投标人
  115. { name: 'TbrDb', value: getValueByKey(information, '') }, // 投标人法定代表或其授权
  116. { name: 'Bzr', value: getValueByKey(information, '') }, // 编制人
  117. { name: 'BzTime', value: getValueByKey(information, ''), type: TYPE.DATE }, // 编制时间
  118. { name: 'Tbzj', value: getValueByKey(information, ''), type: TYPE.DECIMAL }, // 控制价总价(元),取“投标报价”的金额。
  119. ];
  120. // 额外字段
  121. const extraMap = {
  122. '淮北': [
  123. { name: 'ZbrNssbh', value: getValueByKey(information, '') }, // 招标人纳税识别号
  124. { name: 'TbrNssbh', value: getValueByKey(information, '') }, // 投标人纳税识别号
  125. { name: 'TbrDbsfzh', value: getValueByKey(information, '') }, // 投标人法定代表或其授权人身份证号
  126. ]
  127. };
  128. if (extraMap[subArea]) {
  129. attrs.push(...extraMap[subArea]);
  130. }
  131. Element.call(this, 'TouBiaoXx', attrs);
  132. }
  133. // 单项工程信息,因项目管理中无“单项工程”这一层,从单位工程的工程特征信息中拼凑出来
  134. function Dxgcxx(code, name) {
  135. const attrs = [
  136. { name: 'Dxgcbh', value: code }, // 单项工程编号
  137. { name: 'Dxgcmc', value: name }, // 单项工程名称
  138. ];
  139. Element.call(this, 'Dxgcxx', attrs);
  140. }
  141. // 单位工程信息
  142. function Dwgcxx(tenderName, feature) {
  143. const attrs = [
  144. { name: 'Dwgcbh', value: getValueByKey(feature, '') }, // 单位工程编号
  145. { name: 'Dwgcmc', value: tenderName }, // 单位工程名称
  146. ];
  147. Element.call(this, 'Dwgcxx', attrs);
  148. }
  149. // 取费信息(费率信息)
  150. function Qfxx() {
  151. Element.call(this, 'Qfxx');
  152. }
  153. // 计价费率表
  154. function JjFlb() {
  155. Element.call(this, 'JjFlb');
  156. }
  157. // 费率明细名称-编码映射表
  158. const FeeRateCodeMap = {
  159. 冬季施工增加费: 'DJF',
  160. 雨季施工增加费: 'YJF',
  161. 夜间施工增加费: 'YEF',
  162. 工地转移费: 'ZYF',
  163. 高原施工增加费: 'GYF',
  164. 风沙地区增加费: 'FSF',
  165. 沿海地区增加费: 'YHF',
  166. 行车干扰增加费: 'XCF',
  167. 施工辅助费: 'SFF',
  168. 养老保险费: 'YLF',
  169. 失业保险费: 'SYF',
  170. 医疗保险费: 'YBF',
  171. 住房公积金: 'ZFF',
  172. 工伤保险费: 'GSF',
  173. 基本费用: 'JBF',
  174. 主副食运费补贴: 'YFF',
  175. 职工探亲补贴: 'TQF',
  176. 职工取暖补贴: 'QNF',
  177. 财务费用: 'CWF',
  178. 利润: 'LR',
  179. 税金: 'SJ',
  180. };
  181. // 费率工程名称-取费类别映射表
  182. const FeeRateTypeMap = {
  183. 土方: 1,
  184. 石方: 3,
  185. 运输: 2,
  186. 路面: 4,
  187. 隧道: 11,
  188. 构造物I: 5,
  189. '构造物I(不计冬)': 16,
  190. 构造物II: 6,
  191. '构造物III(桥梁)': 9,
  192. '构造物III(除桥以外不计雨)': 8,
  193. 技术复杂大桥: 10,
  194. '钢材及钢结构(桥梁)': 12,
  195. '钢材及钢结构(除桥以外不计夜)': 13,
  196. '费率为0': 17,
  197. '路面(不计雨)': 4,
  198. '构造物I(不计雨)': 16,
  199. '构造物III(除桥以外)': 8,
  200. '钢材及钢结构(除桥以外)': 13,
  201. 设备: 15,
  202. 量价: 14,
  203. };
  204. // 计价费率表明细,造价书费率页面左侧最底层数据
  205. function JjFlbMx(rootItem, item) {
  206. const rate = isEmptyVal(item.rate) ? '100' : item.rate; // 为空时输出=100,为0时输出=0
  207. const attrs = [
  208. { name: 'Bm', value: FeeRateCodeMap[item.name] }, // 编码
  209. { name: 'Name', value: item.name }, // 名称
  210. { name: 'Fl', value: rate, type: TYPE.DECIMAL }, // 费率
  211. { name: 'Qflb', value: FeeRateTypeMap[rootItem.name], type: TYPE.INT }, // 取费类别
  212. ];
  213. Element.call(this, 'JjFlbMx', attrs);
  214. }
  215. // 计价费率项
  216. function JjFlx() {
  217. Element.call(this, 'JjFlx');
  218. }
  219. // 计价费率项明细,造价书费率页面右侧最顶层数据
  220. function JjFlxMx(item) {
  221. // 编码取名称拼音首字母
  222. const allHanName = getHan(item.name || '');
  223. const code = pinyinUtil.getFirstLetter(allHanName).toLowerCase();
  224. let value;
  225. if (isDef(item.value)) {
  226. value = item.value;
  227. } else {
  228. const selected = item.optionList.find(item => item.selected);
  229. value = selected.name;
  230. }
  231. const attrs = [
  232. { name: 'Bm', value: code }, // 编码
  233. { name: 'Mc', value: item.name }, // 名称
  234. { name: 'ShuZhi', value: value }, // 数值
  235. ];
  236. Element.call(this, 'JjFlxMx', attrs);
  237. }
  238. // 清单项目
  239. function QdXm() {
  240. Element.call(this, 'QdXm');
  241. }
  242. // 标题类别:1=100~700清单合计,2=暂估价合计,3=清单不包含暂估价合计,4=计日工,5=暂列金额(不含计日工总额)),6=投标报价,0=其他
  243. const BillsTitleType = {
  244. [fixedFlag.ONE_SEVEN_BILLS]: '1',
  245. [fixedFlag.PROVISIONAL_TOTAL]: '2',
  246. [fixedFlag.BILLS_TOTAL_WT_PROV]: '3',
  247. [fixedFlag.DAYWORK_LABOR]: '4',
  248. [fixedFlag.PROVISIONAL]: '5',
  249. [fixedFlag.TOTAL_COST]: '6',
  250. };
  251. // 清单标题 造价书的第一层数据。
  252. function QdBt(node) {
  253. const row = node.row();
  254. const fee = isBidInvitation ? '0' : getFee(node.data.fees, 'common.tenderTotalFee')
  255. const attrs = [
  256. { name: 'Xh', value: row, type: TYPE.INT }, // 序号
  257. { name: 'Bm', value: node.data.code }, // 编码
  258. { name: 'Name', value: node.data.name }, // 名称
  259. { name: 'Je', value: fee, type: TYPE.DECIMAL }, // 金额
  260. { name: 'Code', value: `F${row}` }, // 行引用
  261. { name: 'Jsgs', value: node.data.calcBase }, // 计算基数
  262. { name: 'Lb', value: BillsTitleType[node.getFlag()], type: TYPE.INT }, // 类别
  263. ];
  264. Element.call(this, 'QdBt', attrs);
  265. }
  266. // 清单明细 (只有100-700章清单标题输出)
  267. function QdMx(node) {
  268. const row = node.row();
  269. const attrs = [
  270. { name: 'Xh', value: row, type: TYPE.INT }, // 序号
  271. { name: 'Qdbm', value: node.data.code }, // 编码
  272. { name: 'Name', value: node.data.name }, // 名称
  273. { name: 'Dw', value: node.data.unit }, // 单位
  274. { name: 'Sl', value: node.data.quantity, type: TYPE.DECIMAL }, // 工程量
  275. { name: 'Sl2', value: '0', type: TYPE.DECIMAL }, // 工程量2
  276. { name: 'Rgf', value: isBidInvitation ? '0' : getFee(node.data.fees, 'labour.tenderTotalFee'), type: TYPE.DECIMAL }, // 人工费
  277. ];
  278. Element.call(this, 'QdMx', attrs);
  279. }
  280. // 组装数据 --------------------------------------
  281. // 组装费率数据
  282. function setupFeeRate(feeRateDetail) {
  283. const qfxx = new Qfxx();
  284. const jjflb = new JjFlb();
  285. // 费率界面左侧底层数据
  286. let curRootItem;
  287. feeRateDetail.datas.rates.forEach(item => {
  288. if (!item.ParentID) {
  289. curRootItem = item;
  290. } else if (!item.sum) { // 最底层
  291. jjflb.children.push(new JjFlbMx(curRootItem, item));
  292. }
  293. });
  294. // 费率界面右侧顶层数据
  295. const jjflx = new JjFlx();
  296. const flxmxData = feeRateDetail
  297. .getAllSubRates()
  298. .filter(item => !item.isSub)
  299. .map(item => new JjFlxMx(item));
  300. jjflx.children.push(...flxmxData);
  301. qfxx.children.push(jjflb, jjflx);
  302. return qfxx;
  303. }
  304. // 组装清单数据
  305. function setupBills(mainTree) {
  306. const qdxm = new QdXm();
  307. const qdbtData = mainTree.roots.map(node => new QdBt(node));
  308. qdxm.children.push(...qdbtData);
  309. return qdxm;
  310. }
  311. // 组装单位工程数据
  312. function setupTender(tenderData, feature) {
  313. const detail = tenderDetailMap[tenderData.ID];
  314. const dwgcxx = new Dwgcxx(tenderData.name, feature);
  315. dwgcxx.children.push(
  316. setupFeeRate(detail.FeeRate),
  317. setupBills(detail.mainTree)
  318. );
  319. return dwgcxx;
  320. }
  321. // 组装建设项目数据
  322. function setupConstruction(constructionData) {
  323. const information = constructionData.property && constructionData.property.basicInformation || [];
  324. const jingJiBiao = new JingJiBiao(constructionData.name, information);
  325. // 将单位工程工程特征中,单项工程编号、名称相同的,插入到建设项目和分段(单位工程)的中间层。
  326. const midLayerMap = {}; // 单项工程key(code@name)与单项工程节点映射
  327. for (const tenderData of constructionData.children) {
  328. const feature = tenderData.property && tenderData.property.projectFeature || [];
  329. const midLayerCode = getValueByKey(feature, 'singleProjNo');
  330. const midLayerName = getValueByKey(feature, 'singleProjName');
  331. const midLayerKey = `${midLayerCode}@${midLayerName}`;
  332. if (!midLayerMap[midLayerKey]) {
  333. jingJiBiao.children.push(midLayerMap[midLayerKey] = new Dxgcxx(midLayerCode, midLayerName));
  334. }
  335. midLayerMap[midLayerKey].children.push(setupTender(tenderData, feature));
  336. }
  337. const suffix = INTERFACE_CONFIG[areaKey]['fileSuffix'][exportKind];
  338. return [{
  339. data: jingJiBiao,
  340. exportKind,
  341. fileName: `${constructionData.name}${suffix}`
  342. }];
  343. }
  344. return setupConstruction(projectData);
  345. }
  346. return {
  347. entry,
  348. };
  349. })();