SOURCE

var pubFun = {
    启用log: false,
    转MIS明细行: function (part) {
        var dtl = {
            roomName: part.空间,
            clsId: part.clsId,
            prdId: part.prdId,
            prdName: part.产品名称,
            prdSpc: part.产品型号,
            matName: part.基材,
            qty_q: part.块数,
            qty_a: part.数量,
            ut: part.单位 == "平方米" ? "平方" : part.单位,
            up: part.单价,
            amt: part.金额,
            clr: part.面材,
            wth: Number(part.宽),
            hgt: Number(part.高),
            thk: Number(part.厚),
            dtls: [],
            prdType: part.prdType,
            upType: part.upType,
            qtyType: part.qtyType,
            参数列表: part.参数,
            对方货号: part.对方货号,
            材料类型: part.材料类型,
            barCode: part.条码,
            ID: part.id,
		    ext1:part.id,
        };
        //记录ext1,ext2 映射关系,用于后续报表加以处理
        dtl.ext1=part.id;
        dtl.ext2=part.parId;

        dtl.参数列表 = dtl.参数列表 != null && dtl.参数列表 != "" ? JSON.parse(dtl.参数列表) : null;
        dtl.info = pubFun.format("产品ID:{0},名称:{1}, 规格:{2}*{3}*{4}={5},对方货号:{6},材料类型:{7}",
            dtl.ID, dtl.prdName, dtl.wth, dtl.hgt, dtl.thk, dtl.qty_q, dtl.对方货号, dtl.材料类型);
        return dtl;
    },
    转MIS子表行: function (part) {
        var dtl = {
            roomName: part.roomName,
            clsId: part.clsId,
            prdName: part.产品名称,
            prdSpc: part.产品型号,
            matName: part.基材,
            qty_q: part.块数,
            qty_a: part.数量,
            ut: part.单位 == "平方米" ? "平方" : part.单位,
            up: part.单价,
            amt: part.金额,
            clr: part.面材,
            wth: Number(part.宽),
            hgt: Number(part.高),
            thk: Number(part.厚),
            dtls: [],
            prdType: part.prdType,
            upType: part.upType,
            qtyType: part.qtyType,
            barCode: part.条码,
            参数列表: part.参数,
            对方货号: part.对方货号,
            材料类型: part.材料类型,
            ID: part.id
        };
        dtl.参数列表 = dtl.参数列表 != null && dtl.参数列表 != "" ? JSON.parse(dtl.参数列表) : null;
        dtl.info = pubFun.format("产品ID:{0},名称:{1}, 规格:{2}*{3}*{4}={5},对方货号:{6},材料类型:{7}",
            dtl.ID, dtl.prdName, dtl.wth, dtl.hgt, dtl.thk, dtl.qty_q, dtl.对方货号, dtl.材料类型);
        return dtl;
    },
    获取MIS产品信息: function (对方货号, 材料类型,产品名称) {
        var prdtList = helper.getPrdListBySupSpc(对方货号);
        if (prdtList == null || prdtList.size() == 0) {
            var msg = 产品名称+ " 对应的产品编码[" + 对方货号 + "]在MIS系统中未对应设置!";
            throw msg;
        }
        var prdt = null;
        if (prdtList.size() == 1) {
            prdt = prdtList.get(0);
        } else {
            for (var i = 0; i < prdtList.size(); i++) {
                var prdName = prdtList.get(i).prdName;
                if (prdName.indexOf(材料类型) > -1) {
                    prdt = prdtList.get(i);
                    break;
                }
            }
        }
        return prdt;
    },
    设置明细行产品属性: function (明细行) {
        var prdt = pubFun.获取MIS产品信息(明细行.对方货号, 明细行.材料类型,明细行.prdName);
        if (prdt == null) {
            var msg = " 产品编码[" + 明细行.对方货号 + "]在MIS系统中无法通过材料确定唯一值!,材质类型:" + 明细行.材料类型;
            throw msg;
        }
        明细行.clsId = prdt.clsId;
        明细行.prdId = prdt.prdId;
        明细行.prdType = prdt.prdType;
        明细行.ut = prdt.prdUt;
        明细行.upType = prdt.upType;
        明细行.qtyType = prdt.qtyType;
	    明细行.prdSpc = prdt.prdSpc;
    },
    format: function (args) {

        var str = arguments[0];
        var arglist = [];
        for (var i = 1; i < arguments.length; i++) {
            arglist.push(arguments[i]);
        }

        if (arglist.length > 0) {
            var result = str;
            if (arglist.length == 1 && typeof (arglist[0]) == "object") {
                for (var key in arglist[0]) {
                    var reg = new RegExp("({" + key + "})", "g");
                    result = result.replace(reg, arglist[0][key]);
                }
            } else {
                for (var i = 0; i < arglist.length; i++) {
                    if (arglist[i] == undefined) {
                        return "";
                    } else {
                        var reg = new RegExp("({[" + i + "]})", "g");
                        result = result.replace(reg, arglist[i]);
                    }
                }
            }
            return result;
        } else {
            return str;
        }
    },
    log: function (args) {
        var arglist = [];
        var res = pubFun.format.apply(null, arguments);
        if (pubFun.启用log == true) {
             console.log(res);
        }
        console.log(res);
    }

}
var dealOper = function () {
    this.处理器列表 = [];
    this.结果集 = [];
    this.注册处理器 = function (处理器) {
        this.处理器列表.push(处理器);
    };
    this.进行处理 = function (data) {
        pubFun.log("总共{0}个数据", data.length);
        var i = 0;
        for (var s in data) {
            //转MIS明细行
            var oribean = data[s];
            var bean = pubFun.转MIS明细行(oribean);
            

            //开启LOG
            var typea = bean.对方货号.substr(0, 2);
            if (typea == "GT") {
                pubFun.启用log = true;
            } else {
                pubFun.启用log = false;
            }
            pubFun.log("正在处理第{0}个数据-------------------------------------------------------", i);
            pubFun.log("{0}", bean.info);
            //获取处理器
            var 处理器 = this.获取匹配处理器(bean);
            pubFun.log("获取到处理器,{0},正在执行处理", 处理器.name);
            //执行处理
            处理器.执行处理(this.结果集, bean);
            if (oribean.订单子表 != null && oribean.订单子表.length > 0) {
                pubFun.log("准备处理子表数据,共{0}个数据", oribean.订单子表.length);
                var a = 0
                for (var f in oribean.订单子表) {
                    //转MIS子表行
                    var subBean = pubFun.转MIS子表行(oribean.订单子表[f]);
                    pubFun.log("正在处理第{0}个子表数据,{1}", a,
                        subBean.info);
                    //获取处理器
                    var 处理器a = this.获取匹配处理器(subBean, bean);
                    pubFun.log("获取到处理器,{0},正在执行处理", 处理器a.name);
                    //执行处理
                    处理器a.执行处理(this.结果集, bean, subBean);
                    a++;
                }
                //子表处理完事件通知
                if (处理器.子表处理完成 != null) {
                    处理器.子表处理完成(bean);
                }
            }
            i++;
        }
        //执行完之后的通知
        for (var s in this.处理器列表) {
            if (this.处理器列表[s].执行完成事件 != null) {
                this.处理器列表[s].执行完成事件(this.结果集);
            }
        }
    };
    this.获取匹配处理器 = function (bean) {
        var 默认处理器 = null;
        for (var s in this.处理器列表) {
            if (this.处理器列表[s].执行匹配 != null && this.处理器列表[s].执行匹配(bean) == true) {
                return this.处理器列表[s];
            } else if (this.处理器列表[s].执行匹配 == null) {
                默认处理器 = this.处理器列表[s];
            }

        }
        return 默认处理器;
    };
    this.返回分组结果集 = function () {
        //示例数据
        var groupDtl = [{
            clsId: 323,
            roomlist: [
                {
                    roomName: "厨房",
                    dtls: []
                },
                {
                    roomName: "次卧",
                    dtls: []
                }]
        }];
        groupDtl = [];
        function setGroupDtl(dtl) {
            var clsId = dtl.clsId;
            var roomName = dtl.roomName;
            var clsObj = null;
            var roomObj = null;
            for (var i = 0; i < groupDtl.length; i++) {
                if (groupDtl[i].clsId == clsId) {
                    clsObj = groupDtl[i];
                    break;
                }
            }
            if (clsObj == null) {
                clsObj = { clsId: clsId, roomlist: [] };
                groupDtl.push(clsObj);
            }
            for (var i = 0; i < clsObj.roomlist.length; i++) {
                if (clsObj.roomlist[i].roomName == roomName) {
                    roomObj = clsObj.roomlist[i];
                    break;
                }
            }
            if (roomObj == null) {
                roomObj = { roomName: roomName, dtls: [] };
                clsObj.roomlist.push(roomObj);
            }
            roomObj.dtls.push(dtl);

        }
        //对结果分组
        for (var i = 0; i < this.结果集.length; i++) {
            var dtl = this.结果集[i];
            setGroupDtl(dtl);
        }
        //索引订单号;
        var cusName = dataOper.经销商;
        cusName = "测试客户";
        var cusrName = dataOper.终端客户;
        var cust = helper.getCustByName(cusName);
        if (cust == null) {
            throw "客户名称[" + cusName + "]在MIS系统中未建档!";
        }
        //设定已经导入的订单分类
        for (var i = 0; i < groupDtl.length; i++) {
            var group = groupDtl[i];
            for (var j = 0; j < group.roomlist.length; j++) {
                var room = group.roomlist[j];
                //throw JSON.stringify(room);
                var salOrder = helper.getSalListByCusInfo(cust.cusId, group.clsId, cusrName, room.roomName);
                if (salOrder != null) {
                    room.ordId = salOrder.ordId;
                    room.pNo = salOrder.pNo;
                    room.pDate = salOrder.pDate;
                }
                room.cusId = cust.cusId;
                room.cusName = cusName;
                room.cusrName = cusrName;
                room.clsId = group.clsId;
            }
        }
        //res;
        return groupDtl;
    }
}
var Oper = new dealOper();
//门板处理器
Oper.注册处理器({
    name: "门板处理器",
    执行匹配: function (bean) {
        var 类型 = bean.对方货号.substr(0, 2);
        if (类型 == "MB") {
            return true;
        }
        return false;
    },
    执行处理: function (结果集, bean, subBean) {
        if (subBean.对方货号 == null) {
            throw pubFun.format("对方货号未设定.{0}", subBean.info);
        }
        if (subBean.对方货号.indexOf("&") == -1) {
            throw pubFun.format("门板的对方货号设定方式必须为[MB&基础型号&门片型号],{0}", subBean.info);
        }
        //列出门型对方货号,门片对方货号
        var s = subBean.对方货号.substr(3, subBean.对方货号.length);
        var pos = s.lastIndexOf("&");
        var supSpc = s.substr(0, pos);
        var mpSpc = s.substr(pos + 1, s.length - pos - 1);

        //主门型的处理
        var prdt = pubFun.获取MIS产品信息(supSpc, subBean.材料类型);
        if (prdt == null) {
            var msg = pubFun.format("门型对方货号不存在!,{0},{1}", supSpc, subBean.info);
            throw msg;
        }
        subBean.prdId = prdt.prdId;
        subBean.clsId = prdt.clsId;
        subBean.prdType = prdt.prdType;
        subBean.upType = prdt.upType;
        subBean.qtyType = prdt.qtyType;
        //门片的处理
        var mp = helper.getFMpInfoBySupSpc(prdt.clsId, mpSpc);
        if (mp == null) {
            var msg = pubFun.format("门片对方货号不存在!{0},{1}", mpSpc, subBean.info);
            throw msg;
        }
        subBean.mpId = mp.mpId;
        //材质
        subBean.matId = 0;

        //空间
        subBean.roomName = bean.roomName; //需要按房间分组
        subBean.rem = bean.prdName;
        //设置门板参数
        this.门板参数设置(subBean);

        结果集.push(subBean);
        pubFun.log("已添加门板至结果集");

    },
    门板参数设置: function (subBean) {
        subBean.kw = subBean.参数列表.hinge.kx;
        this.设置铰链位置(subBean);
        pubFun.log("已设定门板参数!");
    },
    设置铰链位置: function (subBean) {
        var str = "";
        for (var i = 1; i <= 6; i++) {
            var pos = subBean.参数列表.hinge["p" + i];
            str = str + pos + "/";
        }
        //helper.setDtlBeanParam(subBean,"@铰链孔",str);
   

    }

});
//封边带处理器
Oper.注册处理器({
    name: "封边带处理器",
    五金列表: [],
    执行匹配: function (明细行) {
        return 明细行.对方货号 == "XWJ_FBD";
    },
    执行处理: function (结果集, 明细行,子表行) {
        pubFun.设置明细行产品属性(子表行);
        子表行.qty_a = 子表行.wth * 子表行.qty_q * 0.001;
        子表行.qty_q = 0;
        子表行.wth = null;
        子表行.hgt = null;
        子表行.prdSpc = 子表行.prdName;
        子表行.prdName = "封边带";
        子表行.ut = "米";
        子表行.roomName=明细行.roomName;
        var key = this.getKey(子表行);
        var 五金 = this.获取封边带ByKey(key);
        if (五金 == null) {
            子表行.fKey = key;
            this.五金列表.push(子表行);
        } else {
            五金.qty_a = 五金.qty_a + 子表行.qty_a;
        }
    },
    执行完成事件: function (结果集) {
        for (var i = 0; i < this.五金列表.length; i++) {
            var 五金 = this.五金列表[i];
            五金.qty_a = Math.round(五金.qty_a * 10) / 10;
            五金.qty_q = 1;
            结果集.push(this.五金列表[i]);
        }
    },

    getKey: function (子表行) {
        return 子表行.prdId + 子表行.prdName + 子表行.prdSpc;
    },
    获取封边带ByKey: function (key) {
        for (var i = 0; i < this.五金列表.length; i++) {
            var 五金 = this.五金列表[i];
            if (五金.fKey == key) {
                find = true;
                return 五金;
            }
        }
    }
});
//五金处理器
Oper.注册处理器({
    name: "五金处理器",
    五金列表: [],
    执行匹配: function (bean) {
        var 类型 = bean.对方货号.substr(0, 2);
        if (类型 == "WJ") {
            return true;
        }
        return false;
    },
    执行处理: function (结果集, 明细行) {
        pubFun.设置明细行产品属性(明细行);
        var key = this.getKey(明细行);
        if (this.是否封边带(明细行)) {
            明细行.qty_a = 明细行.wth * 明细行.qty_q * 0.001;
        }
        var 五金 = this.获取五金明细行ByKey(key);
        if (五金 == null) {
            明细行.fKey = key;
            this.五金列表.push(明细行);
        } else {
            五金.qty_a = 五金.qty_a + 明细行.qty_a;
            五金.qty_q = 五金.qty_q + 明细行.qty_q;
        }
        pubFun.log("获取到五金Key:{0}", key)
    },
    执行完成事件: function (结果集) {
        for (var i = 0; i < this.五金列表.length; i++) {
            var 五金 = this.五金列表[i];
            五金.wth = 五金.wth == 0 ? null : 五金.wth;
            五金.hgt = 五金.hgt == 0 ? null : 五金.hgt;
            五金.thk = 五金.thk == 0 ? null : 五金.thk;
            五金.qty_a = Math.round(五金.qty_a * 10) / 10;
            五金.barCode = "";
            结果集.push(五金);
        }
    },
    是否封边带: function (明细行) {
        return 明细行.对方货号 == "WJ_FBD";
    },
    getKey: function (明细行) {
        if (this.是否封边带(明细行)) {
            return 明细行.prdId + 明细行.prdName;
        } else {
            return 明细行.prdId + 明细行.prdName + 明细行.wth + 明细行.hgt + 明细行.thk;
        }
    },
    获取五金明细行ByKey: function (key) {
        for (var i = 0; i < this.五金列表.length; i++) {
            var 五金 = this.五金列表[i];
            if (五金.fKey == key) {
                find = true;
                return 五金;
            }
        }
    }
});
//柜板处理器
Oper.注册处理器({
    name: "柜板处理器",
    执行匹配: function (bean) {
        var 类型 = bean.对方货号;
        if (类型 == "GB" || 类型 == "GT_ZJ_CT") {
            return true;
        }
        return false;
    },
    执行处理: function (结果集, 明细行, 子表行) {
        pubFun.log("已添加该行至明细行!,明细行id:{0}", 明细行.ID);
        if (子表行.对方货号 == "GB" && 子表行.hgt < 30) {
            var s = 子表行.thk;
            子表行.thk = 子表行.hgt;
            子表行.hgt = s;
        }
        明细行.dtls.push(子表行);
    },

});
//柜体处理器
Oper.注册处理器({
    name: "柜体处理器",
    执行匹配: function (bean) {
        var 类型 = bean.对方货号.substr(0, 2);
        if (类型 == "GT") {
            return true;
        }
        return false;
    },
    执行处理: function (结果集, 明细行) {
        pubFun.设置明细行产品属性(明细行);
        pubFun.log("已添加该行至结果集!");
        结果集.push(明细行);
    },
    子表处理完成: function (明细行) {
        //添加柜体计价,以及金额汇总
        if (明细行.amt > 0) {
            柜体另计价 = {
                itm: 明细行.dtls.length + 1,
                prdName: "柜体计价",
                qty_a: 明细行.qty_a,
                up: 明细行.up,
                ut: 明细行.ut,
                amt: 明细行.amt,
                sType: "费用",

            }
            pubFun.log("已添加柜体另计价项目")
            明细行.dtls.push(柜体另计价);
        }
        //单价汇总
        var amt = 0;
        for (var s in 明细行.dtls) {
            var subdtl = 明细行.dtls[s];
            amt = amt + subdtl.amt;
        }
        明细行.up = 0;
        明细行.amt = Math.round(amt * 10) / 10;
        pubFun.log("完成子表处理,当前明细行:{0},金额:{1}", 明细行.info, 明细行.amt);

    },


});

//默认处理器
Oper.注册处理器({
    name: "默认处理器",
    执行处理: function (结果集, 明细行, 子表行) {
        if (子表行 == null) {
            pubFun.设置明细行产品属性(明细行);
            结果集.push(明细行);
        } else {
            pubFun.设置明细行产品属性(子表行);
            结果集.push(子表行);
        }
    }
});

Oper.进行处理(dataOper.订单明细);
var result = Oper.返回分组结果集();
result;
//console.error(JSON.stringify(result, null, 4));




console 命令行工具 X clear

                    
>
console