浏览代码

智能材料替换库编辑器

zhangweicheng 6 年之前
父节点
当前提交
215b3a57cd

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

@@ -131,6 +131,40 @@ class ReplaceController extends BaseController{
         }
         response.json(result);
     }
+
+    async saveMaterial(request,response){
+        let result={
+            error:0
+        };
+        try {
+            let data = request.body.data;
+            data = JSON.parse(data);
+            let resultData= await materialFacade.saveMaterial(data);
+            result.data=resultData;
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+
+    async findMaterial (request,response){
+        let result={
+            error:0
+        };
+        try {
+            let data = request.body.data;
+            data = JSON.parse(data);
+            let resultData = await materialFacade.getMaterialByBillsID(data.billsItemID);
+            result.data=resultData;
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
 }
 
 export default ReplaceController;

+ 78 - 7
modules/material_replace_lib/facade/material_replace_facade.js

@@ -11,6 +11,7 @@ let replaceBillModel = mongoose.model("std_replace_bills");
 let replaceMaterialModel = mongoose.model("std_replace_material");
 let StdBillsLib = mongoose.model('std_bills_lib_list');
 let stdBillsModel = mongoose.model('std_bills_lib_bills');
+let stdGLJMode = mongoose.model('std_glj_lib_gljList');
 
 const stdGljLibModel = mongoose.model('std_glj_lib_map');
 
@@ -64,17 +65,87 @@ let materialReplaceLib = {
         return await replaceBillModel.find({libID:libID});
     },
     saveBills:async function(data){
-        let addList = [],updateList =[],deleteList=[];
-        for(let d of data){
-            if(d.type == 'add') addList.push(d);
-            if(d.type == 'update') updateList.push(d);
-            if(d.type == 'delete') deleteList.push(d);
-        }
+        let [addList,updateList,deleteList]  = prepareDatas(data);
         let p = await Promise.all([addBills(addList),updateBills(updateList),deleteBills(deleteList)]);
         return p;
+    },
+    saveMaterial:async function(data){
+        let [addList,updateList,deleteList]  = prepareDatas(data);
+        let p = await Promise.all([addMaterial(addList),replaceMaterial(updateList),deleteMaterial(deleteList)]);
+        return p;
+    },
+    getMaterialByBillsID : async function(billsID){
+       return  await replaceMaterialModel.find({billsItemID:billsID});
     }
 };
 
+
+
+
+function prepareDatas(data) {//整理数据
+    let addList = [],updateList =[],deleteList=[];
+    for(let d of data){
+        if(d.type == 'add') addList.push(d);
+        if(d.type == 'update') updateList.push(d);
+        if(d.type == 'delete') deleteList.push(d);
+    }
+    return [addList,updateList,deleteList]
+}
+
+async function addMaterial(datas) {
+    let newMaterial = [],missCodes=[];
+    for(let d of datas){
+        let stdGLJ = await stdGLJMode.findOne({repositoryId:d.gljLibID,code:d.code});
+        if(stdGLJ){
+            let temM = {
+                libID:d.libID,
+                billsItemID:d.billsItemID,
+                code:d.code,
+                name:stdGLJ.name,
+                specs:stdGLJ.specs,
+                type:stdGLJ.gljType,
+                unit:stdGLJ.unit
+            };
+            temM.ID = uuidV1();
+            newMaterial.push(temM);
+        }else {
+            missCodes.push(d.code);
+        }
+    }
+    if(newMaterial.length>0){
+        await replaceMaterialModel.create(newMaterial);
+    }
+    return {type:'add',list:newMaterial,missCodes:missCodes};
+}
+
+async function replaceMaterial(datas) {
+    let tasks = [],list=[],missCodes = [];
+    for(let d of datas){
+        let stdGLJ = await stdGLJMode.findOne({repositoryId:d.gljLibID,code:d.code});
+        if(stdGLJ){
+            let updateData =  {code:d.code, name:stdGLJ.name, specs:stdGLJ.specs, type:stdGLJ.gljType, unit:stdGLJ.unit};
+            let task = {
+                updateOne:{filter:{ID:d.ID}, update :updateData}
+            };
+            tasks.push(task);
+            list.push({ID:d.ID,updateData:updateData})
+        }else {
+            missCodes.push(d.code)
+        }
+    }
+    if(tasks.length > 0) await replaceMaterialModel.bulkWrite(tasks);
+    return {type:'update',list:list,missCodes:missCodes};
+}
+
+async function deleteMaterial(datas) {
+    let IDList = [];
+    for(let d of datas){
+        if(d.ID) IDList.push(d.ID);
+    }
+    await replaceMaterialModel.deleteMany({ID:{"$in": IDList}});
+    return {type:'delete',list:IDList};
+}
+
 async function addBills(datas) {
     let newBills = [],missCodes=[];
     for(let d of datas){
@@ -130,9 +201,9 @@ async function deleteBills(datas) {
     for(let d of datas){
         if(d.ID) IDList.push(d.ID)
     }
+    await replaceMaterialModel.deleteMany({billsItemID:{"$in": IDList}});//删除清单时要把对应的材料也删除了
     await replaceBillModel.deleteMany({ID:{"$in": IDList}});
     return {type:'delete',list:IDList};
-
 }
 
 

+ 2 - 0
modules/material_replace_lib/routes/material_replace_router.js

@@ -16,6 +16,8 @@ module.exports =function (app){
     repRouter.post("/saveLib", replaceController.auth, replaceController.init, replaceController.saveLib);
     repRouter.post("/deleteLibByID", replaceController.auth, replaceController.init, replaceController.deleteLibByID);
     repRouter.post("/saveBills", replaceController.auth, replaceController.init, replaceController.saveBills);
+    repRouter.post("/saveMaterial", replaceController.auth, replaceController.init, replaceController.saveMaterial);
+    repRouter.post("/findMaterial", replaceController.auth, replaceController.init, replaceController.findMaterial);
     app.use("/materialReplace", repRouter);
 };
 

+ 1 - 1
web/maintain/material_replace_lib/html/edit.html

@@ -12,7 +12,7 @@
             <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">
+                        <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>

+ 215 - 20
web/maintain/material_replace_lib/js/material_replace_edit.js

@@ -5,6 +5,7 @@
 let materialOjb = {
     billsSpread:null,
     materialSpread:null,
+    allBills:JSON.parse(billsList),
     billsList:JSON.parse(billsList),
     materialList:[],
     billsSetting:{
@@ -49,6 +50,9 @@ let materialOjb = {
         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();
 
@@ -68,14 +72,19 @@ let materialOjb = {
             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();
@@ -94,20 +103,53 @@ let materialOjb = {
                         return !me.canDelete(sheet);
                     },
                     callback: function (key, opt) {
-                        sheet.name() == 'billsSheet' ? me.deleteBills(sheet):"";
+                        sheet.name() == 'billsSheet' ? me.deleteBills(sheet):me.deleteMaterial(sheet);
                        console.log( me.rightClickTarget);
                     }
                 }
             }
         });
     },
-    refreshSheet:function(){
+    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;
+        }
+    },
+    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 () {
+        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) {
@@ -117,14 +159,14 @@ let materialOjb = {
             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){
-                        let data = me.getUpdateData(field,newValue,me.billsList[c.row].code);
-                        if(data) updateDatas.push(data);
+                         data = me.getUpdateData(field,newValue,me.billsList[c.row].code);
                     }else if(field == 'code'){//如果是在空白行粘贴,并且是编码列,则是新增,其它的忽略;
-                        let data = me.getUpdateData(field,newValue,null);
-                        if(data) updateDatas.push(data);
+                         data = me.getUpdateData(field,newValue,null);
                     }
+                    if(data) updateDatas.push(data);
                 }else {
                     break;
                 }
@@ -136,8 +178,33 @@ let materialOjb = {
         }
          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(sander,args){
+    onBillsValueChange: function(sender,args){
         let me = materialOjb;
         let field = me.billsSetting.header[args.col].dataCode;
         let code = null;
@@ -153,7 +220,35 @@ let materialOjb = {
         }
         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, "");//去除空格换行等字符;
@@ -168,10 +263,40 @@ let materialOjb = {
         }
         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){//说明是新增
+            if((!isDef(code) || code =='')&&newValue!=null){//说明是新增
                 return {
                     type:'add',
                     code:newValue,
@@ -198,6 +323,19 @@ let materialOjb = {
             }
         }
     },
+    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);
@@ -205,30 +343,87 @@ let materialOjb = {
             for(let r of result){
                 if(r.missCodes && r.missCodes.length >0) missCodes =missCodes.concat(r.missCodes);
                 if(r.type == 'add'){
-                    this.billsList = this.billsList.concat(r.list);
+                    this.allBills = this.allBills.concat(r.list);
                 }if(r.type == 'update'){
                     for(let l of r.list){
-                        this.updateCache(l.code,l.updateData)
+                       this.updateBillsCache(l.code,l.updateData);
                     }
                 }if(r.type == 'delete'){
-                     _.remove(this.billsList,function (item) {
+                    _.remove(this.allBills,function (item) {
                         return _.includes(r.list,item.ID)
                     })
                 }
             }
             if(missCodes.length > 0) alert(`没有找到清单:${missCodes.join("、")}`);
-            this.refreshSheet();
         }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);
+        }
+
     },
-    updateCache:function (code,updateData) {
-        let bill = _.find(this.billsList,{'code':code});
+    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){
-            bill[key] = updateData[key]
+            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;