|
|
@@ -0,0 +1,729 @@
|
|
|
+'use strict';
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * @author Zhong
|
|
|
+ * @date 2019/3/15
|
|
|
+ * @version
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+* 数据标准接口
|
|
|
+* 导出符合标准接口要求的xml
|
|
|
+* */
|
|
|
+
|
|
|
+const XMLStandard = (function () {
|
|
|
+ //属性类型
|
|
|
+ const TYPE = {
|
|
|
+ DATE: 1, //日期类型YYYY-MM-DD
|
|
|
+ DATE_TIME: 2, //日期类型YYY-MM-DDTHH:mm:ss
|
|
|
+ INT: 3, //整数类型
|
|
|
+ DECIMAL: 4, //数值类型,不限制小数位数
|
|
|
+ NUM2: 5, //数值类型2:最多两位小数
|
|
|
+ BOOL: 6 //布尔型
|
|
|
+ };
|
|
|
+ const WHITE_SPACE = {
|
|
|
+ COLLAPSE: 1 //移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多个连续的空格会被缩减为一个单一的空格)
|
|
|
+ };
|
|
|
+ /*
|
|
|
+ * 标准文件中的约束(唯一性)
|
|
|
+ * path为'.//'时,路径为:当前上下文中一级或多级深度
|
|
|
+ * path为'a/b'时,路径为: 当前上下文a节点下节点b
|
|
|
+ * */
|
|
|
+ const CONSTRAINTS = {
|
|
|
+ //建设项目上下文的约束
|
|
|
+ PROJECT: [
|
|
|
+ {path: './/', selector: '单项工程', field: '编号'}, //建设项目下所有单项工程,编号唯一
|
|
|
+ {path: './/', selector: '单位工程', field: '编号'}, //建设项目下所有单位工程,编号唯一
|
|
|
+ ],
|
|
|
+ //单位工程上下文的约束
|
|
|
+ TENDER: [
|
|
|
+ {path: './/', selector: '清单项目', field: '项目编码'}, //单位工程下所有清单项目,项目编码唯一
|
|
|
+ {path: './/', selector: '公式计算措施项', field: '序号'}, //单位工程下所有公式措施项,序号唯一
|
|
|
+ {path: './/', selector: '人材机', field: '代码'}, //单位工程下所有人材机,代码唯一
|
|
|
+ {path: './/', selector: '暂列金额明细', field: '编号'}, //单位工程下所有暂列金额明细,编号唯一
|
|
|
+ {path: './/', selector: '专业工程暂估明细', field: '编号'}, //单位工程下所有专业工程暂估明细,编号唯一
|
|
|
+ {path: './/', selector: '总承包服务费费用项', field: '编号'}, //单位工程下所有总承包服务费费用项,编号唯一
|
|
|
+ {path: '其他项目清单/计日工/人工', selector: '计日工项目', field: '编号'}, //单位工程/其他项目清单/计日工/人工下所有计日工项目,编号唯一
|
|
|
+ {path: '其他项目清单/计日工/材料', selector: '计日工项目', field: '编号'}, //单位工程/其他项目清单/计日工/材料下所有计日工项目,编号唯一
|
|
|
+ {path: '其他项目清单/计日工/施工机械', selector: '计日工项目', field: '编号'}, //单位工程/其他项目清单/计日工/施工机械下所有计日工项目,编号唯一
|
|
|
+ {path: './/', selector: '其他列项', field: '序号'}, //单位工程下所有其他列项,序号唯一
|
|
|
+ {path: './/', selector: '费用项', field: '序号'}, //单位工程下所有费用项,序号唯一
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ /*
|
|
|
+ * 唯一性约束检查
|
|
|
+ * 无法在创建节点时就检查,需要形成完整的数据后检查
|
|
|
+ * @param{Object}element(节点) {Array}constraints(约束数据)
|
|
|
+ * */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 检查
|
|
|
+ * 创建节点时检查节点的数据
|
|
|
+ * 1.长度限制minLen,maxLen
|
|
|
+ * 2.值的限制,固定范围:enumeration
|
|
|
+ * @param {Array}datas(需要检查的属性数据)
|
|
|
+ * @return {Array}没通过的属性
|
|
|
+ * */
|
|
|
+ function check(datas) {
|
|
|
+ let rst = [];
|
|
|
+ let dateReg = /([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))/;
|
|
|
+ for (let data of datas) {
|
|
|
+ data.value = typeof data.value === 'undefined' || data.value === null ? '' : data.value.toString();
|
|
|
+ if (data.whiteSpace && data.whiteSpace === WHITE_SPACE.COLLAPSE) {
|
|
|
+ data.value = data.value.replace(/[\r,\n,\t]/g, ' ');
|
|
|
+ data.value = data.value.trim();
|
|
|
+ data.value = data.value.replace(/\s{1,}/g, ' ');
|
|
|
+ }
|
|
|
+ if (!data.value && !data.minLen && !data.enumeration) { //值为空,且没有限制最小字符数,且没有限制值,则跳过
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (data.minLen && data.value.length < data.minLen){
|
|
|
+ rst.push(`“${data.name}”字符数不可小于${data.minLen}个`);
|
|
|
+ } else if (data.maxLen && data.value.length > data.maxLen) {
|
|
|
+ rst.push(`“${data.name}”字符数不可大于${data.maxLen}个`);
|
|
|
+ } else if (data.enumeration && !data.enumeration.includes(data.value)) {
|
|
|
+ rst.push(`“${data.name}”只能从“${data.enumeration.join(';')}”中选择`);
|
|
|
+ } else if (data.type && data.type === TYPE.DATE && !dateReg.test(data.value)) {
|
|
|
+ rst.push(`“${data.name}”日期格式必须是YYYY-MM-DD`);
|
|
|
+ } else if (data.type && data.type === TYPE.INT && !Number.isInteger(parseFloat(data.value))) {
|
|
|
+ rst.push(`“${data.name}”必须为整数`);
|
|
|
+ } else if (data.type && data.type === TYPE.DECIMAL && isNaN(parseFloat(data.value))) {
|
|
|
+ rst.push(`“${data.name}”必须为数值`)
|
|
|
+ } else if (data.type && data.type === TYPE.NUM2) {
|
|
|
+ let v = parseFloat(data.value);
|
|
|
+ if (isNaN(v)) {
|
|
|
+ rst.push(`“${data.name}”必须为数值`);
|
|
|
+ } else if (data.value.split('.')[1].length > 2){
|
|
|
+ rst.push(`“${data.name}”小数位数不得多于两位`);
|
|
|
+ }
|
|
|
+ } else if (data.type && data.type === TYPE.BOOL && !['true', 'false'].includes(data.value.toString())) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return rst;
|
|
|
+ }
|
|
|
+ //从fees数组中获取相关费用
|
|
|
+ function getFee(fees, feeFields) {
|
|
|
+ let fields = feeFields.split('.');
|
|
|
+ let fee = fees.find(data => data.feeName === fields[0]);
|
|
|
+ if (fee) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return fee[fields[1]] || 0;
|
|
|
+ }
|
|
|
+ //造成导出失败
|
|
|
+ let failList = [];
|
|
|
+ /*
|
|
|
+ * 定义不设置一个Node方法统一进入的原因:模板化比较直观,不分开定义节点的话,调用传参也很麻烦而且不直观。
|
|
|
+ * 一个节点对应一个构造方法,方便其他版本开发、接收的人看起来更直观
|
|
|
+ * @param {String}name(节点名) {Array}attrs(节点属性数据)
|
|
|
+ * @return {void}
|
|
|
+ * */
|
|
|
+ function element(name, attrs) {
|
|
|
+ this.element = name;
|
|
|
+ this.attrs = attrs;
|
|
|
+ this.children = [];
|
|
|
+ this.fail = check(attrs);
|
|
|
+ for (let fail of this.fail) {
|
|
|
+ failList.push(`${name}-${fail}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //根据字段获取基本信息、工程特征
|
|
|
+ function getValueByKey(data, key) {
|
|
|
+ for (let d of data) {
|
|
|
+ if (d.key === key) {
|
|
|
+ return d.value;
|
|
|
+ }
|
|
|
+ if (d.items && d.items.length > 0) {
|
|
|
+ let findData = d.items.find(x => x.key === key);
|
|
|
+ if (findData) {
|
|
|
+ return findData.value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ //建设项目定义
|
|
|
+ //source:来源数据
|
|
|
+ function Project(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '项目编号', value: getValueByKey(source.basicInformation, 'projNumber'), minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '项目名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '建设单位', value: getValueByKey(source.basicInformation, 'constructionUnit')},
|
|
|
+ {name: '标准版本号', value: '3.2.2'},
|
|
|
+ {name: '标准名称', value: '重庆造价软件数据交换标准(清单计价)'},
|
|
|
+ {name: '文件类型', value: getValueByKey(source.basicInformation, 'fileKind'), enumeration: ['招标', '投标', '控制价', '结算', '其他']},
|
|
|
+ {name: '计税方法', value: 'todo'},
|
|
|
+ ];
|
|
|
+ element.call(this, '标段', attrs);
|
|
|
+ }
|
|
|
+ //项目信息定义
|
|
|
+ function ProjectInfo(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '工程规模', value: getValueByKey(source.basicInformation, 'projectScale')},
|
|
|
+ {name: '工程所在地', value: getValueByKey(source.basicInformation, 'projLocation')},
|
|
|
+ {name: '工程地址', value: getValueByKey(source.basicInformation, 'projAddress')},
|
|
|
+ {name: '施工单位', value: getValueByKey(source.basicInformation, 'buildingUnit')},
|
|
|
+ {name: '编制单位', value: getValueByKey(source.basicInformation, 'establishmentUnit')},
|
|
|
+ {name: '审核单位', value: getValueByKey(source.basicInformation, 'auditUnit')},
|
|
|
+ {name: '编制人', value: getValueByKey(source.basicInformation, 'buildingUnitAuthor')},
|
|
|
+ {name: '审核人', value: 'todo'},
|
|
|
+ {name: '开工日期', value: getValueByKey(source.basicInformation, 'commencementDate'), type: TYPE.DATE},
|
|
|
+ {name: '竣工日期', value: getValueByKey(source.basicInformation, 'completionDate'), type: TYPE.DATE},
|
|
|
+ {name: '编制日期', value: getValueByKey(source.basicInformation, 'establishDate'), type: TYPE.DATE},
|
|
|
+ {name: '审核日期', value: getValueByKey(source.basicInformation, 'auditDate'), type: TYPE.DATE},
|
|
|
+ {name: '材料价格期', value: getValueByKey(source.basicInformation, 'materialPricePeriod')},
|
|
|
+ {name: '合同价类型', value: getValueByKey(source.basicInformation, 'contractPriceType')},
|
|
|
+
|
|
|
+ ];
|
|
|
+ element.call(this, '项目信息', attrs);
|
|
|
+ }
|
|
|
+ //招标信息定义
|
|
|
+ function BiddingInfo(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '招标代理机构', value: getValueByKey(source.basicInformation, 'tenderingAgency')},
|
|
|
+ {name: '造价工程师', value: getValueByKey(source.basicInformation, 'tenderCostEngineer')},
|
|
|
+ {name: '造价工程师注册证号', value: getValueByKey(source.basicInformation, 'tenderCostEngineerNo')},
|
|
|
+ {name: '招标工期', value: getValueByKey(source.basicInformation, 'tenderPeriod'), type: TYPE.INT},
|
|
|
+ {name: '控制总价', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '招标信息', attrs);
|
|
|
+ }
|
|
|
+ //投标信息定义
|
|
|
+ function BidInfo(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '投标人', value: getValueByKey(source.basicInformation, 'bidder')},
|
|
|
+ {name: '造价工程师', value: getValueByKey(source.basicInformation, 'bidCostEngineer')},
|
|
|
+ {name: '造价工程师注册证号', value: getValueByKey(source.basicInformation, 'bidCostEngineerNo')},
|
|
|
+ {name: '项目经理', value: getValueByKey(source.basicInformation, 'projectManager')},
|
|
|
+ {name: '投标工期', value: getValueByKey(source.basicInformation, 'biddingPeriod')},
|
|
|
+ {name: '投标保证金', value: getValueByKey(source.basicInformation, 'biddingMargin'), type: TYPE.NUM2},
|
|
|
+ {name: '质量承诺', value: getValueByKey(source.basicInformation, 'qualityCommitment')},
|
|
|
+ {name: '担保类型', value: getValueByKey(source.basicInformation, 'guaranteeType')},
|
|
|
+ {name: '投标总价', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '投标信息', attrs);
|
|
|
+ }
|
|
|
+ //编制说明定义
|
|
|
+ function CompilationIllustration(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '内容', value: source.compilationIllustration},
|
|
|
+ ];
|
|
|
+ element.call(this, '编制说明', attrs);
|
|
|
+ }
|
|
|
+ //系统信息定义
|
|
|
+ function SystemInfo(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: 'ID1', value: source.softInfo},
|
|
|
+ {name: 'ID2', value: ''},
|
|
|
+ {name: '生成时间', value: source.generatedTime, type: TYPE.DATE_TIME},
|
|
|
+ ];
|
|
|
+ element.call(this, '系统信息', attrs);
|
|
|
+ }
|
|
|
+ //费用构成定义
|
|
|
+ function FeeFrom(summaryInfo) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '工程费合计', value: summaryInfo.engineeringCost, type: TYPE.NUM2},
|
|
|
+ {name: '分部分项清单合计', value: summaryInfo.subEngineering, type: TYPE.NUM2},
|
|
|
+ {name: '措施项目清单合计', value: summaryInfo.measure, type: TYPE.NUM2},
|
|
|
+ {name: '安全文明施工专项费', value: summaryInfo.safetyConstruction, type: TYPE.NUM2},
|
|
|
+ {name: '其他项目清单合计', value: summaryInfo.other, type: TYPE.NUM2},
|
|
|
+ {name: '规费', value: summaryInfo.charge, type: TYPE.NUM2},
|
|
|
+ {name: '税金', value: summaryInfo.tax, type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '费用构成', attrs);
|
|
|
+ }
|
|
|
+ //单项工程定义
|
|
|
+ function engineering(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, minLen: 1, maxLen: 255},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255},
|
|
|
+ {name: '金额', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '单项工程', attrs);
|
|
|
+ }
|
|
|
+ //单位工程定义
|
|
|
+ function tender(source) {
|
|
|
+ const TAX = {
|
|
|
+ 1: '一般计税',
|
|
|
+ 2: '简易计税'
|
|
|
+ };
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, minLen: 1, maxLen: 255},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255},
|
|
|
+ {name: '专业', value: source.property.engineering},
|
|
|
+ {name: '金额', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2},
|
|
|
+ {name: '定额库编码', value: source.property.defaultRationLibCode},
|
|
|
+ {name: '计税方法', value: TAX[source.property.taxType]},
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ //工程特征定义
|
|
|
+ function engFeature(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '建筑分类', value: source.feature.buildingClass, },
|
|
|
+ {name: '工程分类', value: source.feature.projClass, },
|
|
|
+ {name: '建设规模', value: 'todo', },
|
|
|
+ {name: '工程类别', value: source.basicInformation.projectCategory} //取建设项目的工程类别
|
|
|
+ ];
|
|
|
+ element.call(this, '工程特征', attrs);
|
|
|
+ }
|
|
|
+ //特征项定义
|
|
|
+ function featureItem(feature) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编码', value: ''},
|
|
|
+ {name: '名称', value: feature.dispName},
|
|
|
+ {name: '内容', value: feature.value},
|
|
|
+ ];
|
|
|
+ element.call(this, '特征项', attrs);
|
|
|
+ }
|
|
|
+ //单位工程费汇总定义
|
|
|
+ function tenderFeeSummary() {
|
|
|
+ element.call(this, '单位工程费汇总', []);
|
|
|
+ }
|
|
|
+ //计价程序费用行定义
|
|
|
+ function dxfyRow(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '序号', value: source.code},
|
|
|
+ {name: '行代号', value: source.rowCode},
|
|
|
+ {name: '项目名称', value: source.name},
|
|
|
+ {name: '计算基础表达式', value: source.calcBase},
|
|
|
+ {name: '计算基础说明', value: source.calcBaseAnnotation},
|
|
|
+ {name: '费率', value: source.feeRate},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '费用类别', value: source.feeType, type: TYPE.INT},
|
|
|
+ {name: '备注', value: source.remark},
|
|
|
+ ];
|
|
|
+ element.call(this, '计价程序费用行', attrs);
|
|
|
+ }
|
|
|
+ //分部分项清单
|
|
|
+ function fbfxBills() {
|
|
|
+ element.call(this, '分部分项清单', []);
|
|
|
+ }
|
|
|
+ //清单分部定义
|
|
|
+ function fbBills(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, maxLen: 20},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee')},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '清单分部', attrs);
|
|
|
+ }
|
|
|
+ //清单项目定义
|
|
|
+ function fxbills(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '项目编码', value: source.code, minLen: 1, maxLen: 20},
|
|
|
+ {name: '项目名称', value: source.name, minLen: 1, maxLen: 500},
|
|
|
+ {name: '单位', value: source.unit, minLen: 1, maxLen: 20},
|
|
|
+ {name: '工程量', value: source.quantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '综合单价', value: getFee(source.fees, 'common.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '综合合价', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '主要清单标志', value: source.mainBills, type: TYPE.BOOL},
|
|
|
+ {name: '暂估清单标志', value: source.isEstimate, type: TYPE.BOOL},
|
|
|
+ {name: '备注', value: source.remark},
|
|
|
+ ];
|
|
|
+ element.call(this, '清单项目', attrs);
|
|
|
+ }
|
|
|
+ //项目特征定义
|
|
|
+ function itemCharacter() {
|
|
|
+ element.call(this, '项目特征', []);
|
|
|
+ }
|
|
|
+ //特征定义
|
|
|
+ function feature(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '特征名称', value: source.name},
|
|
|
+ {name: '特征描述', value: source.value},
|
|
|
+ ];
|
|
|
+ element.call(this, '特征', attrs);
|
|
|
+ }
|
|
|
+ //工程内容定义
|
|
|
+ function jobContent() {
|
|
|
+ element.call(this, '工程内容', []);
|
|
|
+ }
|
|
|
+ //内容定义
|
|
|
+ function content(content) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '内容', value: content}
|
|
|
+ ];
|
|
|
+ element.call(this, '内容', attrs);
|
|
|
+ }
|
|
|
+ //组价内容定义
|
|
|
+ function priceContent() {
|
|
|
+ element.call(this, '组价内容', []);
|
|
|
+ }
|
|
|
+ //定额子目定义
|
|
|
+ function ration(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '定额编号', value: source.viewCode, minLen: 1, maxLen: 80},
|
|
|
+ {name: '项目名称', value: source.viewCode, minLen: 1, maxLen: 255},
|
|
|
+ {name: '单位', value: source.unit, minLen: 1, maxLen: 20},
|
|
|
+ {name: '定额库编码', value: source.libCode},
|
|
|
+ {name: '原始定额编号', value: source.code, minLen: 1, maxLen: 80},
|
|
|
+ {name: '子目类型', value: source.code, type: TYPE.INT, enumeration: [0, 1, 2, 3, 4, 5, 6]},
|
|
|
+ {name: '工程量', value: source.quantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '工程量计算式', value: source.quantityEXP},
|
|
|
+ {name: '定额单价', value: getFee(source.fees, 'rationUnitPrice.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '定额合价', value: getFee(source.fees, 'rationUnitPrice.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '综合单价', value: getFee(source.fees, 'common.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '综合合价', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '单价构成文件ID', value: 0, type: TYPE.INT}, //todo
|
|
|
+ {name: '分包标志', value: source.isSubcontract, type: TYPE.BOOL},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '定额子目', attrs);
|
|
|
+ }
|
|
|
+ //工料分析定义
|
|
|
+ function gljAnalyze() {
|
|
|
+ element.call(this, '工料分析', []);
|
|
|
+ }
|
|
|
+ //人材机含量定义
|
|
|
+ function gljContent(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '人材机代码', value: source.code, minLen: 1, maxLen: 20},
|
|
|
+ {name: '消耗量', value: source.quantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '总消耗量', value: source.totalQuantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '数量计算方式', value: 1, type: TYPE.INT},
|
|
|
+ ];
|
|
|
+ element.call(this, '人材机含量', attrs);
|
|
|
+ }
|
|
|
+ //费用组成
|
|
|
+ function feeContent(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '基价人工费单价', value: getFee(source.fees, 'labour.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '基价人工费合价', value: getFee(source.fees, 'labour.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '定额人工基价调整单价', value: 0, type: TYPE.DECIMAL}, //调整价目前只有08有,默认设置成0
|
|
|
+ {name: '定额人工基价调整合价', value: 0, type: TYPE.NUM2},
|
|
|
+ {name: '基价材料费单价', value: getFee(source.fees, 'material.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '基价材料费合价', value: getFee(source.fees, 'material.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '基价机械费单价', value: getFee(source.fees, 'machine.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '基价机械费合价', value: getFee(source.fees, 'machine.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '定额机上人工基价调整单价', value: 0, type: TYPE.DECIMAL},
|
|
|
+ {name: '定额机上人工基价调整合价', value: 0, type: TYPE.NUM2},
|
|
|
+ {name: '未计材料单价', value: getFee(source.fees, 'unratedMaterial.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '未计材料合价', value: getFee(source.fees, 'unratedMaterial.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '人材机价差单价', value: getFee(source.fees, 'gljDiff.unitFee'), type: TYPE.DECIMAL}, //人材机价差通过人工、材料、机械价差相加得出
|
|
|
+ {name: '人材机价差合价', value: getFee(source.fees, 'gljDiff.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '暂估材料单价', value: getFee(source.fees, 'estimate.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '暂估材料合价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '管理费单价', value: getFee(source.fees, 'manage.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '管理费合价', value: getFee(source.fees, 'manage.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '利润单价', value: getFee(source.fees, 'profit.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '利润合价', value: getFee(source.fees, 'profit.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '风险单价', value: getFee(source.fees, 'risk.unitFee'), type: TYPE.DECIMAL}, //重庆08叫风险费 重庆18叫一般风险费
|
|
|
+ {name: '风险合价', value: getFee(source.fees, 'risk.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '一般风险单价', value: getFee(source.fees, 'risk.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '一般风险合价', value: getFee(source.fees, 'risk.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其他风险单价', value: getFee(source.fees, 'otherRisk.unitFee'), type: TYPE.DECIMAL},
|
|
|
+ {name: '其他风险合价', value: getFee(source.fees, 'otherRisk.totalFee'), type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '费用组成', attrs);
|
|
|
+ }
|
|
|
+ //措施项目清单定义
|
|
|
+ function csxmBills(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '措施项目清单', attrs);
|
|
|
+ }
|
|
|
+ //组织措施清单定义
|
|
|
+ function zzcsBills(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '组织措施清单', attrs);
|
|
|
+ }
|
|
|
+ //组织措施分类定义
|
|
|
+ function zzcsClass(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编码', value: source.code, maxLen: 20},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '组织措施分类', attrs);
|
|
|
+ }
|
|
|
+ //公式计算措施项
|
|
|
+ function formulaCalcMeasure(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '序号', value: source.code, minLen: 1, maxLen:20},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255},
|
|
|
+ {name: '计算基础表达式', value: source.calcBase},
|
|
|
+ {name: '计算基础说明', value: source.calcBaseAnnotation},
|
|
|
+ {name: '费率', value: source.feeRate},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee')},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee')},
|
|
|
+ {name: '暂估价标志', value: getFee(source.fees, 'common.totalFee')},
|
|
|
+ {name: '备注', value: source.remark},
|
|
|
+ {name: '费用类别', value: source.feeType, enumeration: [120201, 1204, 10041, 1206]},
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ //技术措施清单定义
|
|
|
+ function jscsBills(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '技术措施清单', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2},
|
|
|
+ ];
|
|
|
+ element.call(this, '技术措施清单', attrs);
|
|
|
+ }
|
|
|
+ //技术措施分类
|
|
|
+ function jscsClass(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code},
|
|
|
+ {name: '名称', value: source.name},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.DECIMAL},
|
|
|
+ ];
|
|
|
+ element.call(this, '技术措施分类', attrs);
|
|
|
+ }
|
|
|
+ //其他项目清单定义
|
|
|
+ function otherBills() {
|
|
|
+ element.call(this, '其他项目清单', []);
|
|
|
+ }
|
|
|
+ //暂列金额定义
|
|
|
+ function provisional(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}
|
|
|
+ ];
|
|
|
+ element.call(this, '暂列金额', attrs);
|
|
|
+ }
|
|
|
+ //暂列金额明细定义
|
|
|
+ function provisionalDetail(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '项目名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '计量单位', value: source.unit, maxLen: 20},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '暂列金额明细', attrs);
|
|
|
+ }
|
|
|
+ //专业工程暂估价定义
|
|
|
+ function engineeringEstimate(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee')}
|
|
|
+ ];
|
|
|
+ element.call(this, '专业工程暂估价', attrs);
|
|
|
+ }
|
|
|
+ //专业工程暂估明细定义
|
|
|
+ function engineeringEstimateDetail(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '工程名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '工程内容', value: 'todo', maxLen: 2000}, //todo
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '专业工程暂估明细', attrs);
|
|
|
+ }
|
|
|
+ //计日工定义
|
|
|
+ function dayWork(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee')}
|
|
|
+ ];
|
|
|
+ element.call(this, '', attrs);
|
|
|
+ }
|
|
|
+ //人工定义
|
|
|
+ function labour() {
|
|
|
+ element.call(this, '人工', []);
|
|
|
+ }
|
|
|
+ //计日工项目定义
|
|
|
+ function dayWorkItem(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '单位', value: source.unit, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '数量', value: source.quantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '综合单价', value: source.quantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '综合合价', value: source.quantity, type: TYPE.NUM2},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '计日工项目', attrs);
|
|
|
+ }
|
|
|
+ //材料定义
|
|
|
+ function material() {
|
|
|
+ element.call(this, '材料', []);
|
|
|
+ }
|
|
|
+ //施工机械定义
|
|
|
+ function machine() {
|
|
|
+ element.call(this, '施工机械', []);
|
|
|
+ }
|
|
|
+ //总承包服务费定义
|
|
|
+ function turnKeyContract(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}
|
|
|
+ ];
|
|
|
+ element.call(this, '总承包服务费', attrs);
|
|
|
+ }
|
|
|
+ //总承包服务费分类定义
|
|
|
+ function turnKeyContractClass(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name:'编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name:'名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name:'备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '总承包服务费分类', attrs);
|
|
|
+ }
|
|
|
+ //总承包服务费费用项定义
|
|
|
+ function turnKeyContractItem(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '工程名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '计算基础', value: 0, type: TYPE.DECIMAL}, //todo
|
|
|
+ {name: '服务内容', value: '', maxLen: 255}, //todo
|
|
|
+ {name: '费率', value: source.feeRate, type: TYPE.DECIMAL},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '备注', value: source.remark}
|
|
|
+ ];
|
|
|
+ element.call(this, '总承包服务费费用项', attrs);
|
|
|
+ }
|
|
|
+ //其他定义
|
|
|
+ function other(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}
|
|
|
+ ];
|
|
|
+ element.call(this, '其他', attrs);
|
|
|
+ }
|
|
|
+ //其他列项定义
|
|
|
+ function otherItem(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '序号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '计算基础', value: source.calcBase, maxLen: 255},
|
|
|
+ {name: '费率', value: source.feeRate, type: TYPE.DECIMAL},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '不计入合价标志', value: source.isEstimate, type: TYPE.BOOL},
|
|
|
+ {name: '备注', value: source.remark, maxLen: 255}
|
|
|
+ ];
|
|
|
+ element.call(this, '其他列项', attrs);
|
|
|
+ }
|
|
|
+ //规费和税金清单定义
|
|
|
+ function chargeTaxBills() {
|
|
|
+ element.call(this, '规费和税金清单', []);
|
|
|
+ }
|
|
|
+ //费用项定义
|
|
|
+ function feeItem(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '序号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '行代号', value: source.rowCode, maxLen: 20},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '计算基础表达式', value: source.calcBase, maxLen: 255},
|
|
|
+ {name: '计算基础说明', value: source.calcBaseAnnotation, maxLen: 255},
|
|
|
+ {name: '费率', value: source.feeRate, type: TYPE.DECIMAL},
|
|
|
+ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2},
|
|
|
+ {name: '费用类别', value: source.feeType, enumeration: [800, 900, 9001, 9002, 9003]},
|
|
|
+ {name: '备注', value: source.remark, maxLen: 255}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ //人材机汇总定义
|
|
|
+ function gljSummary() {
|
|
|
+ element.call(this, '人材机汇总', []);
|
|
|
+ }
|
|
|
+ //人材机定义
|
|
|
+ function glj(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '代码', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '规格', value: source.spec, maxLen: 255},
|
|
|
+ {name: '单位', value: source.unit, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '原始代码', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '费用类别', value: source.feeType, enumeration: [1, 2, 3, 4]},
|
|
|
+ {name: '配比类别', value: '', type: TYPE.INT}, //todo
|
|
|
+ {name: '主要材料类别', value: '', type: TYPE.INT}, //todo
|
|
|
+ {name: '主要材料单位系数', value: '', type: TYPE.DECIMAL}, //todo
|
|
|
+ {name: '材料耗用类型', value: '', type: TYPE.INT}, //todo
|
|
|
+ {name: '供货方式', value: '', type: TYPE.INT}, //todo
|
|
|
+ {name: '暂估材料标志', value: !!source.is_evaluate, type: TYPE.BOOL},
|
|
|
+ {name: '不计税设备标志', value: !!source.is_adjust_price, type: TYPE.BOOL}, //todo
|
|
|
+ {name: '单价不从明细汇总标志', value: !!source.excludeRatio, type: TYPE.BOOL}, //todo
|
|
|
+ {name: '定额价', value: source.basePrice, type: TYPE.DECIMAL},
|
|
|
+ {name: '定额价调整', value: '', type: TYPE.DECIMAL}, //todo
|
|
|
+ {name: '市场价', value: source.marketPrice, type: TYPE.DECIMAL},
|
|
|
+ {name: '数量', value: source.quantity, type: TYPE.DECIMAL},
|
|
|
+ {name: '产地', value: source.originPlace, maxLen: 255},
|
|
|
+ {name: '厂家', value: source.vender, maxLen: 255},
|
|
|
+ {name: '质量等级', value: source.qualityGrace, maxLen: 255},
|
|
|
+ {name: '品牌', value: source.brand, maxLen: 255},
|
|
|
+ {name: '备注', value: source.quantity, maxLen: 255},
|
|
|
+ ];
|
|
|
+ element.call(this, '人材机', attrs);
|
|
|
+ }
|
|
|
+ //人材机配比定义
|
|
|
+ function gljRatio(source) {
|
|
|
+ let attrs = [
|
|
|
+ {name: '明细材料代码', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE},
|
|
|
+ {name: '数量', value: source.quantity, type: TYPE.DECIMAL}
|
|
|
+ ];
|
|
|
+ element.call(this, '人材机配比', attrs);
|
|
|
+ }
|
|
|
+ return function (granularity) {
|
|
|
+ this.GRANULARITY = {
|
|
|
+ PROJECT: 1, //导出建设项目
|
|
|
+ ENGINEERING: 2, //导出单项工程
|
|
|
+ TENDER: 3 //导出单位工程
|
|
|
+ };
|
|
|
+ //默认导出建设项目
|
|
|
+ if (!granularity || ![1, 2, 3].includes(granularity)) {
|
|
|
+ granularity = this.GRANULARITY.PROJECT;
|
|
|
+ }
|
|
|
+ this.failList = failList;
|
|
|
+ this.granularity = granularity;
|
|
|
+ //目前的数据
|
|
|
+ let curData = null;
|
|
|
+ //唯一性约束
|
|
|
+ let contraints = {};
|
|
|
+
|
|
|
+ async function loadProject(tenderID) {
|
|
|
+ //拉取标段数据:建设项目、单项工程、单位工程数据
|
|
|
+ let projectData = await ajaxPost('/pm/api/getProjectByGranularity', {user_id: userID, tenderID: tenderID, granularity: granularity});
|
|
|
+ if (!projectData) {
|
|
|
+ throw '获取项目数据错误';
|
|
|
+ }
|
|
|
+ //标段
|
|
|
+ let project = curData = new Project({basicInformation: projectData.property.basicInformation, name: projectData.name});
|
|
|
+ //项目信息
|
|
|
+ let projectInfo = new ProjectInfo({basicInformation: projectData.property.basicInformation});
|
|
|
+ project.children.push(projectInfo);
|
|
|
+ //招标信息
|
|
|
+ let biddingInfo = new BiddingInfo({basicInformation: projectData.property.basicInformation, summaryInfo: projectData.summaryInfo[projectData.ID]});
|
|
|
+ projectInfo.children.push(biddingInfo);
|
|
|
+ //投标信息
|
|
|
+ let bidInfo = new BidInfo({basicInformation: projectData.property.basicInformation, summaryInfo: projectData.summaryInfo[projectData.ID]});
|
|
|
+ projectInfo.children.push(bidInfo);
|
|
|
+ //编制说明
|
|
|
+ let compilationIll = new CompilationIllustration({compilationIllustration: projectData.property.compilationIllustration});
|
|
|
+ project.children.push(compilationIll);
|
|
|
+ //系统信息
|
|
|
+ let generatedTime = moment(Date.now()).format('YYYY-MM-DDTHH:mm:ss'),
|
|
|
+ sysInfoSource = {softInfo: projectData.softInfo, generatedTime},
|
|
|
+ sysInfo = new SystemInfo(sysInfoSource);
|
|
|
+ project.children.push(sysInfo);
|
|
|
+ //费用构成
|
|
|
+ let feeForm = new FeeFrom(projectData.summaryInfo[projectData.ID]);
|
|
|
+ project.children.push(feeForm);
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * 加载数据
|
|
|
+ * */
|
|
|
+ this.loadData = async function(tenderID) {
|
|
|
+ await loadProject(tenderID);
|
|
|
+ return curData;
|
|
|
+ };
|
|
|
+ /*
|
|
|
+ * 转换数据,将数据转换成可被导出成xml的结构
|
|
|
+ * {element: '标段', attrs: [{name: '属性1', value: 't'}], children: [...]} to
|
|
|
+ * {'标段': {...}, '_属性1': t}
|
|
|
+ * */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 导出数据
|
|
|
+ * */
|
|
|
+ this.toXml = function () {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+})();
|