zhangweicheng 7 anni fa
parent
commit
b01f9b482d

+ 2 - 0
modules/material_replace_lib/controllers/material_replace_controller.js

@@ -34,6 +34,7 @@ class ReplaceController extends BaseController{
             let gljLib = await  materialFacade.findGLJLibByComID(compilationId);
             let billsList = await materialFacade.findBillsByLibID(libID);
             //let templateDatas = await materialFacade.getTemplateDatasByLibID(libID);
+            //let stdBills = await  materialFacade.getStdBillsByLib(billsLibId);
 
             let randerData = {
                 title:'材料替换库',
@@ -45,6 +46,7 @@ class ReplaceController extends BaseController{
                 billsLibId:billsLibId,
                 gljLibID:gljLib.ID,
                 libID:libID,
+                //stdBills:JSON.stringify(stdBills),
                 LicenseKey:config.getLicenseKey(process.env.NODE_ENV),
                 layout: 'maintain/common/html/edit_layout'
             };

+ 4 - 0
modules/material_replace_lib/facade/material_replace_facade.js

@@ -76,6 +76,10 @@ let materialReplaceLib = {
     },
     getMaterialByBillsID : async function(billsID){
        return  await replaceMaterialModel.find({billsItemID:billsID});
+    },
+    getStdBillsByLib:async function(libID){
+        let bills = await stdBillsModel.find({billsLibId: libID},['ID','code','name','items']);
+        return bills;
     }
 };
 function prepareDatas(data) {//整理数据

+ 77 - 0
web/maintain/material_replace_lib/html/edit_新编辑版本.html

@@ -0,0 +1,77 @@
+<nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0 second_header">
+    <ul class="nav nav-tabs" role="tablist">
+        <li class="nav-item">
+            <a class="nav-link active px-3" href="javascript: void(0);">材料替换</a>
+        </li>
+    </ul>
+</nav>
+
+<div class="main">
+    <div class="content" >
+        <div class="container-fluid" >
+            <div class="row">
+                <div class="tools-bar p-1 d-flex justify-content-between col-lg-12" style="background: #f7f7f7;">
+                    <div class="input-group input-group-sm col-lg-4">
+                        <input class="form-control" placeholder="搜索定位" type="text" id = 'keyword'>
+                        <span class="input-group-btn">
+                              <button class="btn btn-secondary" type="button"><i class="fa fa-search"></i></button>
+                            </span>
+                        <a class="btn btn-sm btn-link"  style="color: #0275d8;cursor:pointer" data-toggle="modal" data-target="#guize"">关于规则</a>
+                    </div>
+                </div>
+                <div class="main-content col-lg-4 p-0">
+                    <div class="main-data" id="billsSpread"></div>
+                </div>
+                <div class="col-lg-4 main-side p-0">
+
+                </div>
+                <div class="col-lg-4 main-side p-0" id="materialSpread"></div>
+
+            </div>
+        </div>
+        <input type="hidden" id="libID" value="<%= libID %>">
+        <input type="hidden" id="gljLibID" value="<%= gljLibID %>">
+        <input type="hidden" id="billsLibId" value="<%= billsLibId %>">
+        <div style="display: none">
+            <textarea  id = "testStd" type="hidden"><%= stdBills %></textarea>
+        </div>
+
+    </div>
+</div>
+
+<!--弹出关于规则-->
+<div class="modal fade" id="guize" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">关于规则</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <table class="table table-bordered">
+                    <thead><tr><th width="90">规则名称</th><th>规则解释</th></tr></thead>
+                    <tr><td>规则1</td><td>材料及规格:MU5烧结页岩空心砖</td></tr>
+                    <tr><td>规则2</td><td>1.混凝土种类:商品混凝土<br>2.混凝土强度等级:C30</td></tr>
+                </table>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+
+</div>
+
+<script type="text/javascript">
+    //自适应高度
+    $(".main-data").height($(window).height()-$(".header").height()-$(".tools-bar").height()-$(".navbar").height()-16);
+    let billsList = '<%- billsList %>';
+
+</script>
+<script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.js"></script>
+<script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+<script type="text/javascript" src="/public/web/sheet/sheet_data_helper.js"></script>
+
+<script type="text/javascript" src="/web/maintain/material_replace_lib/js/material_replace_edit.js"></script>

+ 478 - 0
web/maintain/material_replace_lib/js/material_replace_edit_新编辑版本.js

@@ -0,0 +1,478 @@
+/**
+ * Created by zhang on 2018/8/23.
+ */
+
+let materialOjb = {
+    billsSpread:null,
+    materialSpread:null,
+    allBills:JSON.parse(billsList),
+    billsList:JSON.parse(billsList),
+    stdBills:JSON.parse($("#testStd").val()),
+    materialList:[],
+    billsTreeSetting: {
+        treeCol: 0,
+        emptyRows: 0,
+        headRows: 1,
+        headRowHeight: [40],
+        defaultRowHeight: 21,
+        cols: [{
+            width: 200,
+            readOnly: true,
+            head: {
+                titleNames: ["项目编码"],
+                spanCols: [1],
+                spanRows: [1],
+                vAlign: [1],
+                hAlign: [1],
+                font: ["Arial"]
+            },
+            data: {
+                field: "code",
+                vAlign: 1,
+                hAlign: 0,
+                font: "Arial"
+            }
+        }, {
+            width: 200,
+            readOnly: true,
+            head: {
+                titleNames: ["项目名称"],
+                spanCols: [1],
+                spanRows: [1],
+                vAlign: [1],
+                hAlign: [1],
+                font: ["Arial"]
+            },
+            data: {
+                field: "name",
+                vAlign: 1,
+                hAlign: 0,
+                font: "Arial"
+            }
+        }]
+    },
+   /* billsSetting:{
+        header: [
+            {headerName: "清单编号", headerWidth: 180, dataCode: "code", dataType: "String",formatter: "@"},
+            {headerName: "清单名称", headerWidth: 240, dataCode: "name", dataType: "String"},
+            {headerName: "规则", headerWidth: 150, dataCode: "rule", hAlign: "left", dataType: "String",cellType:'comboBox',editorValueType:true,options:[{text:"规则1",value:1},{text:"规则2",value:2}]}
+        ],
+        view: {
+            lockColumns: [1]
+        },
+        headerHeight:45
+    },*/
+    materialSetting:{
+        header: [
+            {headerName: "材料编号", headerWidth: 180, dataCode: "code", dataType: "String",formatter: "@"},
+            {headerName: "材料名称", headerWidth: 240, dataCode: "name", dataType: "String",cellType:'tipsCell'},
+            {headerName: "规格", headerWidth: 150, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'}
+        ],
+        view: {
+            lockColumns: [1,2]
+        },
+        headerHeight:45
+    },
+    initSpread:function () {
+      /*  if(!this.billsSpread){
+            this.billsSpread = SheetDataHelper.createNewSpread($("#billsSpread")[0]);
+        }
+        if(!this.materialSpread){
+            this.materialSpread = SheetDataHelper.createNewSpread($("#materialSpread")[0]);
+        }
+        this.billsSheet = this.billsSpread .getSheet(0);
+        sheetCommonObj.initSheet(this.billsSheet,this.billsSetting, 30);
+        this.billsSheet.name('billsSheet');
+        this.billsSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onBillsValueChange);
+        this.billsSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onBillsSelectionChange);
+        this.billsSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onBillsRangeChange);
+
+        this.initRightClick("billsSpread",this.billsSpread);
+
+
+        this.materialSheet = this.materialSpread .getSheet(0);
+        sheetCommonObj.initSheet(this.materialSheet,this.materialSetting, 30);
+        this.materialSheet.name('materialSheet');
+        this.materialSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onMaterialValueChange);
+        this.materialSheet.bind(GC.Spread.Sheets.Events.EditStarting, this.onMaterialEditStarting);
+        this.materialSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onMaterialRangeChange);
+        this.initRightClick("materialSpread",this.materialSpread);
+        this.refreshSheet();*/
+
+    },
+    canDelete : function (sheet) {
+        let me = this;
+        let sel =  sheet.getSelections()[0];
+        let datas = sheet.name() == 'billsSheet'?me.billsList:me.materialList;
+        if(sel.row === undefined || sel.row < 0) return false ;//一行都没选中时,不能删除
+        if((sel.row + sel.rowCount) > datas.length) return false;//选中了空行,不能删除
+        return true;
+    },
+    deleteBills : async function(sheet){
+        let me = this,deleteList = [];
+        let sel = sheet.getSelections()[0];
+        for(let i = 0;i<sel.rowCount;i++){
+            if(me.billsList[sel.row + i]) deleteList.push(getDeleteDatas(me.billsList[sel.row + i]));
+        }
+        if(deleteList.length > 0) await me.saveBills(deleteList);
+        function getDeleteDatas(tem) {
+            return {type:'delete', ID:tem.ID}
+        }
+
+    },
+    deleteMaterial:async function(sheet){
+        let me = this,deleteList = [];
+        let sel = sheet.getSelections()[0];
+        for(let i = 0; i<sel.rowCount;i++){
+            if(me.materialList[sel.row + i]) deleteList.push(me.getMaterialUpdateData(null,me.materialList[sel.row + i].ID,true));
+        }
+        if(deleteList.length > 0) await me.saveMaterial(deleteList);
+    },
+    initRightClick : function(id,spread) {
+        let me = this;
+        let sheet = spread.getActiveSheet();
+        $.contextMenu({
+            selector: '#'+id,
+            build: function ($trigger, e) {
+                me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, spread);
+                return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
+                    me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
+            },
+            items: {
+                "delete": {
+                    name: "删除",
+                    icon: 'fa-trash-o',
+                    disabled: function () {
+                        return !me.canDelete(sheet);
+                    },
+                    callback: function (key, opt) {
+                        sheet.name() == 'billsSheet' ? me.deleteBills(sheet):me.deleteMaterial(sheet);
+                       console.log( me.rightClickTarget);
+                    }
+                }
+            }
+        });
+    },
+    refreshSheet:async function(){
+        this.getBillsList();
+        sheetCommonObj.showData(this.billsSheet,this.billsSetting,this.billsList);
+        this.billsSheet.setRowCount(this.billsList.length + 30);
+        this.showMaterialList();
+    },
+    getBillsList:function () {
+        let keyword = $("#keyword").val();
+        if(isDef(keyword)&&keyword!==''){
+            this.billsList = _.filter(this.allBills,function (item) {
+                return item.code.indexOf(keyword)!=-1 || item.name.indexOf(keyword)!=-1;
+            })
+        }else {
+            this.billsList = this.allBills;
+        }
+        this.billsList = _.sortBy(this.billsList,'code');
+    },
+    getMateriaList:async function () {
+        let billsItemID =  this.getCurrentBillsID();
+        if(billsItemID){
+            this.materialList = await this.getMaterialByBillsID(billsItemID)//getMaterialByBills
+        }else {
+            this.materialList = [];
+        }
+    },
+    showMaterialList:async function () {
+        await this.getMateriaList();
+        this.refreshMaterialSheet();
+    },
+    refreshMaterialSheet:function () {
+        this.materialList = _.sortBy(this.materialList,'code');
+        sheetCommonObj.showData(this.materialSheet,this.materialSetting,this.materialList);
+        this.materialSheet.setRowCount(this.materialList.length + 30);
+    },
+    onBillsSelectionChange:function (sender,args) {
+        let me = materialOjb;
+        let nsel = args.newSelections?args.newSelections[0]:null;
+        let osel = args.oldSelections?args.oldSelections[0]:null;
+        if(nsel && osel && nsel.row != osel.row){
+            me.showMaterialList();
+            me.materialSheet.showRow(0, GC.Spread.Sheets.VerticalPosition.top);
+        }
+        args.sheet.repaint();
+    },
+    onBillsRangeChange:function (sender,args) {
+        let me = materialOjb;
+        let updateDatas = [];
+        if(args.action == GC.Spread.Sheets.RangeChangedAction.paste){
+            for(let c of args.changedCells){
+                let field = me.billsSetting.header[c.col].dataCode;
+                let newValue =  args.sheet.getCell(c.row,c.col).value();
+                let data = null;
+                if(me.validateBills(field,newValue)){
+                    if(c.row < me.billsList.length){
+                         data = me.getUpdateData(field,newValue,me.billsList[c.row].code);
+                    }else if(field == 'code'){//如果是在空白行粘贴,并且是编码列,则是新增,其它的忽略;
+                         data = me.getUpdateData(field,newValue,null);
+                    }
+                    if(data) updateDatas.push(data);
+                }else {
+                    break;
+                }
+            }
+            if(updateDatas.length > 0){
+                me.saveBills(updateDatas);
+                return;
+            }
+        }
+         me.refreshSheet();
+    },
+    onMaterialRangeChange:function(sender,args){
+        let me = materialOjb;
+        let updateDatas = [];
+        if(args.action == GC.Spread.Sheets.RangeChangedAction.paste){
+            for(let c of args.changedCells){
+                let code =  args.sheet.getCell(c.row,c.col).value(),data = null;
+                if(me.validateMaterial(code)){
+                    if(c.row < me.materialList.length){
+                         data = me.getMaterialUpdateData(code,me.materialList[c.row].ID);
+                    }else {//如果是在空白行粘贴,并且是编码列,则是新增,其它的忽略;
+                         data = me.getMaterialUpdateData(code,null);
+                    }
+                    if(data) updateDatas.push(data);
+                }else {
+                    break;
+                }
+            }
+            if(updateDatas.length > 0){
+                me.saveMaterial(updateDatas);
+                return;
+            }
+        }
+        me.showMaterialList();
+    },
+
+
+    onBillsValueChange: function(sender,args){
+        let me = materialOjb;
+        let field = me.billsSetting.header[args.col].dataCode;
+        let code = null;
+        if(args.row < me.billsList.length){
+            code = me.billsList[args.row].code;
+        }
+        if(me.validateBills(field,args.newValue)){
+            let data = me.getUpdateData(field,args.newValue,code);
+            if (data){
+                me.saveBills([data]);
+                return;
+            }
+        }
+        me.refreshSheet();
+    },
+    onMaterialEditStarting : function (sender,args) {
+        let me = materialOjb;
+        if(!me.getCurrentBillsID()) args.cancel = true; //如果没选中清单则不能编辑
+    },
+
+    onMaterialValueChange:function(sender,args){
+        let me = materialOjb;
+        let ID = null;
+        if(args.row < me.materialList.length){
+            ID = me.materialList[args.row].ID;
+        }
+        if(me.validateMaterial(args.newValue)){
+            let data = me.getMaterialUpdateData(args.newValue,ID);
+            if(data){
+                me.saveMaterial([data]);
+                return
+            }
+        }
+        me.showMaterialList();
+
+    },
+    validateMaterial:function (value) {
+        value = value.toString().replace(/[\s\r\n]/g, "");//去除空格换行等字符;
+        if(_.find(this.materialList,{code:value})){
+            alert("人材机:"+value+" 已存在");
+            return false;
+        }
+        return true;
+    },
+    validateBills:function (field,value) {
+        if(field == 'code'){
+            value = value.toString().replace(/[\s\r\n]/g, "");//去除空格换行等字符;
+            if(value.length !== 9){
+                alert("清单长度不正确");
+                return false;
+            }
+            if(_.find(this.billsList,{'code':value})) {
+                alert("清单:"+value+" 已存在");
+                return false;
+            }
+        }
+        return true;
+    },
+    getCurrentBillsID:function(){
+      let sel = this.billsSheet.getSelections()[0];
+      if(sel.row < this.billsList.length){
+           return this.billsList[sel.row].ID;
+      }
+      return null;
+    },
+    getMaterialUpdateData:function(code,ID,isDelete){
+        if(isDelete == true){
+            return {type:'delete', ID:ID}
+        }
+        code = code.toString().replace(/[\s\r\n]/g, "");//去除空格换行等字符;
+        if((!isDef(ID)||ID=='')&& code != null){//新增
+            let billsItemID = this.getCurrentBillsID();
+            return {
+                type:'add',
+                code:code,
+                billsItemID:billsItemID,
+                libID:$('#libID').val(),
+                gljLibID:parseInt($('#gljLibID').val())
+            }
+        }else { //替换材料
+            return {
+                type:'update',
+                ID:ID,
+                code:code,
+                gljLibID:parseInt($('#gljLibID').val())
+            }
+        }
+    },
+    getUpdateData:function (field,newValue,code) {
+        if(field == 'code'){
+            newValue = newValue.toString().replace(/[\s\r\n]/g, "");//去除空格换行等字符;
+            if((!isDef(code) || code =='')&&newValue!=null){//说明是新增
+                return {
+                    type:'add',
+                    code:newValue,
+                    libID:$('#libID').val(),
+                    billsLibId:parseInt($('#billsLibId').val())
+                }
+            }else {//说明是替换
+                return {
+                    type:'update',
+                    oldCode:code.toString(),
+                    newCode:newValue,
+                    libID:$('#libID').val(),
+                    billsLibId:parseInt($('#billsLibId').val())
+                }
+            }
+        }else if(isDef(code)){
+            let updateData = {};
+            updateData[field] = newValue;
+            return {
+                type:'update',
+                oldCode:code.toString(),
+                libID:$('#libID').val(),
+                updateData:updateData
+            }
+        }
+    },
+    saveMaterial:async function(datas){
+        try {
+            let result = await ajaxPost("/materialReplace/saveMaterial",datas);
+            let missCodes = [];
+            for(let r of result){
+                if(r.missCodes && r.missCodes.length >0) missCodes =missCodes.concat(r.missCodes);
+            }
+            if(missCodes.length > 0) alert(`没有找到人材机:${missCodes.join("、")}`);
+        }catch (err){
+            console.log(err);
+        }
+        this.showMaterialList();
+    },
+    saveBills:async function (datas) {
+        try {
+            let result = await ajaxPost("/materialReplace/saveBills",datas);
+            let missCodes = [];
+            for(let r of result){
+                if(r.missCodes && r.missCodes.length >0) missCodes =missCodes.concat(r.missCodes);
+                if(r.type == 'add'){
+                    this.allBills = this.allBills.concat(r.list);
+                }if(r.type == 'update'){
+                    for(let l of r.list){
+                       this.updateBillsCache(l.code,l.updateData);
+                    }
+                }if(r.type == 'delete'){
+                    _.remove(this.allBills,function (item) {
+                        return _.includes(r.list,item.ID)
+                    })
+                }
+            }
+            if(missCodes.length > 0) alert(`没有找到清单:${missCodes.join("、")}`);
+        }catch (err){
+            console.log(err);
+        }
+        this.refreshSheet();
+    },
+    saveDatas:async function (datas,type ='bills') {
+        try {
+            let currentList = type =='bills'?this.billsList:this.materialList;
+            let url = type =='bills'?"/materialReplace/saveBills":"/materialReplace/saveMaterial";
+            let text = type =='bills'?"清单":"人材机";
+            let result = await ajaxPost(url,datas);
+            let missCodes = [];
+            for(let r of result){
+                if(r.missCodes && r.missCodes.length >0) missCodes =missCodes.concat(r.missCodes);
+                if(r.type == 'add'){
+                    currentList = currentList.concat(r.list);
+                }if(r.type == 'update'){
+                    for(let l of r.list){
+                        type =='bills'?this.updateBillsCache(l.code,l.updateData):this.updateMaterialCache(l.ID,l.updateData);
+                    }
+                }if(r.type == 'delete'){
+                    _.remove(currentList,function (item) {
+                        return _.includes(r.list,item.ID)
+                    })
+                }
+            }
+            if(missCodes.length > 0) alert(`没有找到${text}:${missCodes.join("、")}`);
+        }catch (err){
+            console.log(err);
+        }
+
+    },
+    getMaterialByBillsID:async function(billsItemID){
+        try {
+            let result = await ajaxPost("/materialReplace/findMaterial",{billsItemID:billsItemID});
+            return result;
+        }catch (err){
+            console.log(err);
+            return [];
+        }
+    },
+    updateMaterialCache:function (ID,updateData) {
+        this.updateCache(this.materialList,{'ID':ID},updateData)
+    },
+
+    updateBillsCache:function (code,updateData) {
+         this.updateCache(this.allBills,{'code':code},updateData)
+    },
+
+    updateCache:function (list,condition,updateData) {
+        let item = _.find(list,condition);
+        for(let key in updateData){
+            item[key] = updateData[key]
+        }
+    }
+};
+let last = 0;
+
+$(document).ready(function () {
+    $("#keyword").on('input propertychange', function(event) {
+        last = event.timeStamp;//利用event的timeStamp来标记时间,这样每次事件都会修改last的值,注意last必需为全局变量
+        setTimeout(function () {    //设时延迟0.5s执行
+            if (last - event.timeStamp == 0) { //如果时间差为0(也就是你停止输入0.5s之内都没有其它的keyup事件发生)则做你想要做的事
+               materialOjb.refreshSheet();
+            }
+
+        }, 500);
+    })
+});
+
+function isDef(obj) {
+    return obj!==undefined && obj!==null;
+}
+
+materialOjb.initSpread();
+