Parcourir la source

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/YangHuOperation

TonyKang il y a 5 ans
Parent
commit
9db6c208b3

+ 7 - 1
modules/common/const/bills_fixed.js

@@ -57,7 +57,11 @@ const fixedFlag = {
     //安全生产费
     SAFE_COST:27,
     //100章清单
-    ONE_HUNDRED_BILLS: 28
+    ONE_HUNDRED_BILLS: 28,
+    // 一二三部分合计
+    ONE_TO_THREE_TOTAL: 29,
+    // 前期工作费
+    PRELIMINARY_WORK: 30,
 };
 /*建筑安装工程费、土地使用及拆迁补偿费、养护工程其他费用、预备费、基本预备费、价差预备费、一二三四部分合计、贷款利息、总造价、
 
@@ -71,6 +75,7 @@ const fixedFlagList = [
     {name: "预备费", value: fixedFlag.BUDGET_FEE},
     {name: "基本预备费", value: fixedFlag.BASE_BUDGET_FEE},
     {name: "价差预备费", value: fixedFlag.SPREAD_BUDGET_FEE},
+    {name: "一二三部分合计", value: fixedFlag.ONE_TO_THREE_TOTAL},
     {name: "一二三四部分合计", value: fixedFlag.ONE_TO_FOUR_TOTAL},
     {name: "贷款利息", value: fixedFlag.LOAN_INTEREST},
     {name: "总造价", value: fixedFlag.TOTAL_COST},
@@ -83,6 +88,7 @@ const fixedFlagList = [
     {name: "设计文件审查费", value: fixedFlag.DOCUMENT_REVIEW_FEE},
     {name: "勘察设计费", value: fixedFlag.SURVEY_DESIGN_FEE},
     {name: "招标代理及标底编制费", value: fixedFlag.AGENT_BASE_FEE},
+    {name: "前期工作费", value: fixedFlag.PRELIMINARY_WORK},
     {name: "第100章至700章清单", value: fixedFlag.ONE_SEVEN_BILLS},
     {name: "专项暂定合计", value: fixedFlag.PROVISIONAL_TOTAL},
     {name: "清单合计扣除专项暂定合计", value: fixedFlag.BILLS_TOTAL_WT_PROV},

+ 9 - 0
modules/common/std/std_ration_lib_map_model.js

@@ -52,6 +52,15 @@ class STDRationLibMapModel extends BaseModel {
         return result;
     }
 
+    // 获取所有费用定额的所有定额库
+    async getAllRationLibs() {
+        const libs = await this.findDataByCondition({deleted: false}, null, false);
+        return libs.map(libData => ({
+            id: libData.ID,
+            name: libData.dispName
+        }));
+    }
+
 }
 
 export default STDRationLibMapModel;

+ 54 - 1
modules/std_glj_lib/controllers/gljController.js

@@ -226,7 +226,60 @@ class GljController extends BaseController{
                 }
                 //更新人材机价格
                 await gljDao.batchUpdateGljPrice(gljLibId, sheet[0].data);
-                console.log('endeeee');
+                // 删除文件
+                if(uploadFullName && fs.existsSync(uploadFullName)){
+                    fs.unlink(uploadFullName);
+                }
+                response.json(responseData);
+            }
+            catch (error){
+                console.log(error);
+                if(uploadFullName && fs.existsSync(uploadFullName)){
+                    fs.unlink(uploadFullName);
+                }
+                responseData.err = 1;
+                responseData.msg = error;
+                response.json(responseData);
+            }
+        });
+    }
+
+    async importComponents(request, response) {
+        let responseData = {
+            err: 0,
+            msg: ''
+        };
+        const allowHeader = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
+        const uploadOption = {
+            uploadDir: './public'
+        };
+        const form = new multiparty.Form(uploadOption);
+        let uploadFullName;
+        form.parse(request, async function(err, fields, files) {
+            try{
+                const gljLibId = fields.gljLibId !== undefined && fields.gljLibId.length > 0 ?
+                    fields.gljLibId[0] : 0;
+                if (gljLibId <= 0) {
+                    throw '参数错误';
+                }
+                const file = files.file !== undefined ? files.file[0] : null;
+                if (err || file === null) {
+                    throw '上传失败';
+                }
+                // 判断类型
+                if (file.headers['content-type'] === undefined || allowHeader.indexOf(file.headers['content-type']) < 0) {
+                    throw '不支持该类型';
+                }
+                // 重命名文件名
+                uploadFullName = uploadOption.uploadDir + '/' + file.originalFilename;
+                fs.renameSync(file.path, uploadFullName);
+
+                const sheet = excel.parse(uploadFullName);
+                if (sheet[0] === undefined || sheet[0].data === undefined || sheet[0].data.length <= 0) {
+                    throw 'excel没有对应数据';
+                }
+                // 更新组成物
+                await gljDao.importComponents(gljLibId, sheet[0].data);
                 // 删除文件
                 if(uploadFullName && fs.existsSync(uploadFullName)){
                     fs.unlink(uploadFullName);

+ 102 - 16
modules/std_glj_lib/models/gljModel.js

@@ -297,29 +297,57 @@ class GljDao  extends OprDao{
 
     static addGljItems (repId, lastOpr, items, callback) {
         if (items && items.length > 0) {
-            counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){
-                var maxId = result.sequence_value;
-                var arr = [];
-                for (var i = 0; i < items.length; i++) {
-                    var obj = new gljModel(items[i]);
-                    obj.ID = (maxId - (items.length - 1) + i);
-                    obj.repositoryId = repId;
-                    arr.push(obj);
+            const codes = [];
+            items.forEach(item => codes.push(item.code));
+            gljModel.find({repositoryId: repId, code: {$in: codes}}, '-_id code', {lean: true}, (err, codeData) => {
+                if (err) {
+                    callback(true, '判断编码唯一性失败', false);
+                    return;
                 }
-                gljModel.collection.insert(arr, null, function(err, docs){
-                    if (err) {
-                        callback(true, "Fail to add", false);
+                const insertData = [];
+                const failCode = [];
+                items.forEach(item => {
+                    const matchData = codeData.find(codeItem => codeItem.code === item.code);
+                    if (!matchData) {
+                        insertData.push(item);
                     } else {
+                        failCode.push(item.code);
+                    }
+                });
+                if (!insertData.length) {
+                    callback(false, 'empty data', {insertData, failCode});
+                    return;
+                }
+                counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, (counterErr, counterData) => {
+                    if (counterErr) {
+                        callback(true, '获取人材机ID失败', false);
+                        return;
+                    }
+                    const maxId = counterData.sequence_value;
+                    for (let i = 0; i < insertData.length; i++) {
+                        insertData[i].ID = (maxId - (insertData.length - 1) + i);
+                        insertData[i].repositoryId = repId;
+                    }
+                    const task = [];
+                    insertData.forEach(item => {
+                        task.push({
+                            insertOne: {document: item}
+                        });
+                    });
+                    gljModel.bulkWrite(task, (insertErr, rst) => {
+                        if (insertErr) {
+                            callback(true, '新增数据失败', false);
+                            return;
+                        }
                         GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                             if(err){
                                 callback(true, "Fail to update Operator", false);
-                            }
-                            else{
-                                callback(false, "Add successfully", docs);
+                            } else{
+                                callback(false, "Add successfully", {insertData, failCode});
                             }
                         });
-                    }
-                })
+                    });
+                });
             });
         } else {
             callback(true, "No source", false);
@@ -637,6 +665,64 @@ class GljDao  extends OprDao{
         }
 
     }
+
+    async importComponents(gljLibId, sheetData) {
+        const gljLib = await gljMapModel.findOne({ID: gljLibId});
+        if (!gljLib) {
+            throw '不存在此人材机库';
+        }
+        const compilation = await compilationModel.findOne({_id: mongoose.Types.ObjectId(gljLib.compilationId)});
+        if (!compilation) {
+            throw '不存在此费用定额';
+        }
+        // 将所有人材机进行编码映射
+        const allGLJs = await gljModel.find({repositoryId: gljLibId}, {ID: true, code: true}).lean();
+        const codeMapping = {};
+        allGLJs.forEach(glj => codeMapping[glj.code] = glj);
+        // excel表格列号与字段的映射
+        const colMapping = {
+            // 材料编码
+            code: 0,
+            // 组成物编码
+            componentCode: 1,
+            // 组成物消耗量
+            consumeAmt: 2
+        };
+        // 跳过列头
+        for (let row = 1; row < sheetData.length; row++) {
+            const rowData = sheetData[row];
+            const code = rowData[colMapping.code];
+            const componentCode = rowData[colMapping.componentCode];
+            const consumeAmt = +rowData[colMapping.consumeAmt];
+            const glj = codeMapping[code];
+            const component = codeMapping[componentCode];
+            if (!glj || !component) {
+                continue;
+            }
+            if (!glj.component) {
+                glj.component = [];
+            }
+            glj.component.push({
+                ID: component.ID,
+                consumeAmt: consumeAmt
+            });
+        }
+        // 更新数据
+        const tasks = [];
+        allGLJs.filter(glj => glj.component && glj.component.length).forEach(glj => {
+            tasks.push({
+                updateOne: {
+                    filter: {
+                        ID: glj.ID
+                    },
+                    update: {$set: {component: glj.component}}
+                }
+            });
+        });
+        if (tasks.length) {
+            await gljModel.bulkWrite(tasks);
+        }
+    }
 }
 
 export default GljDao;

+ 1 - 0
modules/std_glj_lib/routes/routes.js

@@ -43,6 +43,7 @@ module.exports = function (app) {
     router.post("/getGljItemsOccupied",gljController.auth, gljController.init, gljController.getGljItemsOccupied);
     router.post("/isUsed",gljController.auth, gljController.init, gljController.isUsed);//工料机是否被引用
     router.post('/importPrice', gljController.auth, gljController.init, gljController.importPrice);
+    router.post('/importComponents', gljController.auth, gljController.init, gljController.importComponents);
 
 
     app.use("/stdGljRepository/api", router);

+ 2 - 1
modules/users/controllers/compilation_controller.js

@@ -204,7 +204,8 @@ class CompilationController extends BaseController {
 
             // 获取定额库
             let stdRationLibMapModel = new STDRationLibMapModel();
-            rationList = await stdRationLibMapModel.getRationLib(selectedCompilation._id);
+            //rationList = await stdRationLibMapModel.getRationLib(selectedCompilation._id);
+            rationList = await stdRationLibMapModel.getAllRationLibs();
 
             // 获取工料机库
             let stdGLJLibMapModel = new STDGLJLibMapModel();

+ 1 - 4
web/maintain/std_glj_lib/html/main.html

@@ -33,11 +33,8 @@
                 <div class="col-md-8">
                     <div class="warp-p2 mt-3">
                         <table class="table table-hover table-bordered">
-                            <thead><tr><th>人材机库名称</th><th>费用定额</th><th>定额库</th><th width="160">添加时间</th><th width="90">操作</th><th width="90">价格数据</th><th width="90">补充模板</th></tr></thead>
+                            <thead><tr><th>人材机库名称</th><th>费用定额</th><th>定额库</th><th width="160">添加时间</th><th width="90">操作</th><th width="90">价格数据</th><th width="100">组成物数据</th><th width="90">补充模板</th></tr></thead>
                             <tbody id="showArea">
-                            <!--    <tr><td><a href="gongliao.html">XX工料机库</a></td><td>重庆2018</td><td>XXX定额库(重庆2018)</td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>
-                                <tr><td><a href="gongliao.html">XX工料机库</a></td><td>重庆2018</td><td></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>
-                                <tr><td><a href="gongliao.html">XX工料机库</a></td><td>重庆2018</td><td></td><td>2017-01-01 </td><td><a href="javacript:void(0);" data-toggle="modal" data-target="#edit" title="编辑"><i class="fa fa-pencil-square-o"></i></a> <a href="javacript:void(0);" data-toggle="modal" data-target="#del" class="text-danger" title="删除"><i class="fa fa-remove"></i></a></td></tr>-->
                             </tbody>
                         </table>
                     </div>

+ 24 - 14
web/maintain/std_glj_lib/js/glj.js

@@ -38,7 +38,7 @@ $(document).ready(function () {
     SlideResize.horizontalSlide(rightElesObj, {min: 200, max: `$('#dataRow').width() - $('#leftContent').width() - 200`}, function () {
         let resizeRate = SlideResize.resizeWidth * 100 / $('#midContent').width(),
             sheetRate = 100 - resizeRate;
-        $('#leftResize').css('width', `${resizeRate}%`);
+        $('#slideResizeLeft').css('width', `${resizeRate}%`);
         $('#GLJListSheet').css('width', `${sheetRate}%`);
         refreshALlWorkBook();
     });
@@ -1418,6 +1418,15 @@ let repositoryGljObj = {
             me.saveInString(updateArr)
         }
         if(addArr.length > 0){
+            const codeMap = {};
+            const uniqueCodeAddArr =[];
+            addArr.forEach(item => {
+                if (!codeMap[item.code]) {
+                    codeMap[item.code] = 1;
+                    uniqueCodeAddArr.push(item);
+                }
+            });
+            addArr = uniqueCodeAddArr;
             me.saveInString(addArr);
         }
         $.ajax({
@@ -1431,7 +1440,17 @@ let repositoryGljObj = {
                 if (result.error) {
                     alert(result.message);
                 } else {
-                    me.updateCache(addArr, updateArr, removeIds, result);
+                    const failCodes = result.data.failCode;
+                    if (failCodes && failCodes.length) {
+                        let failText = '';
+                        failCodes.forEach(code => {
+                            failText += `<p>编码“${code}”已存在</p>`;
+                        });
+                        $('#alertText').html(failText);
+                        $('#codeAlert').modal('show');
+                    }
+                    const insertData = result.data.insertData;
+                    me.updateCache(insertData, updateArr, removeIds);
                     //me.sortGlj();
                     if(me.currentOprParent === 1){
                         me.currentCache = me.getParentCache(me.parentNodeIds["_pNodeId_" + me.gljCurTypeId]);
@@ -1503,10 +1522,10 @@ let repositoryGljObj = {
         }
         return rst;
     },
-    updateCache: function(addArr, updateArr, removeIds, result) {
+    updateCache: function(insertData, updateArr, removeIds) {
         let me = this, cacheSection = me.gljList;
-        if (addArr.length > 0) {
-            me.gljList = me.gljList.concat(addArr);
+        if (insertData && insertData.length > 0) {
+            me.gljList = me.gljList.concat(insertData);
             cacheSection = me.gljList;
         }
         for (let i = removeIds.length - 1; i >= 0; i--) {
@@ -1516,15 +1535,6 @@ let repositoryGljObj = {
                 }
             }
         }
-        if (result && result.data && result.data.ops && result.data.ops.length > 0) {
-            for (let i = 0; i < result.data.ops.length; i++) {
-                for (let j = 0; j < cacheSection.length; j++) {
-                    if (cacheSection[j]['code'] == result.data.ops[i]['code']) {
-                        cacheSection[j]["ID"] = result.data.ops[i]["ID"];
-                    }
-                }
-            }
-        }
         for (let i = 0; i < updateArr.length; i++) {
             for (let j = 0; j < cacheSection.length; j++) {
                 if (updateArr[i]["ID"] && cacheSection[j]["ID"]) {

+ 31 - 4
web/maintain/std_glj_lib/js/main.js

@@ -122,7 +122,13 @@ $(function () {
         });
     });
     let selLibId = -1;
+    const importType = {
+        price: 1,
+        component: 2
+    };
+    let importAction;
     $("#showArea").on("click", ".import-data", function () {
+        importAction = importType.price;
         let id = $(this).data("id");
         id = parseInt(id);
         if (isNaN(id) || id <= 0) {
@@ -131,10 +137,20 @@ $(function () {
         selLibId = id;
         $("#import").modal("show");
     });
-    //导入单价数据
-    $("#data-import").click(function() {
+    $("#showArea").on("click", ".import-components", function () {
+        importAction = importType.component;
+        let id = $(this).data("id");
+        id = parseInt(id);
+        if (isNaN(id) || id <= 0) {
+            return false;
+        }
+        selLibId = id;
+        $("#import").modal("show");
+    });
+    function importExcel(url) {
         $.bootstrapLoading.start();
         const self = $(this);
+        console.log(self);
         try {
             let formData = new FormData();
             let file = $("input[name='import_data']")[0];
@@ -148,7 +164,7 @@ $(function () {
             }
             formData.append('gljLibId', selLibId);
             $.ajax({
-                url: 'api/importPrice',
+                url: url,
                 type: 'POST',
                 data: formData,
                 cache: false,
@@ -186,6 +202,16 @@ $(function () {
             alert(error);
             $.bootstrapLoading.end();
         }
+    }
+    //导入数据
+    $("#data-import").click(function() {
+        // 导入单价
+        if (importAction === importType.price) {
+            importExcel.call(this, '/stdGljRepository/api/importPrice');
+        } else {
+            // 导入组成物
+            importExcel.call(this, '/stdGljRepository/api/importComponents');
+        }
     });
     //设置补充人材机库分类树模板
     $("#showArea").on("click", ".set-comple", function () {
@@ -260,6 +286,7 @@ function getAllGljLib(callback){
                         "<i class='fa fa-pencil-square-o'></i></a> <a href='javascript:void(0);' data-toggle='modal' data-target='#del' class='text-danger' title='删除'>" +
                         "<i class='fa fa-remove'></i></a></td>" +
                         "<td><a class='btn btn-secondary btn-sm import-data' href='javacript:void(0);' data-id='"+ id +"' title='导入数据'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
+                        "<td><a class='btn btn-secondary btn-sm import-components' href='javacript:void(0);' data-id='"+ id +"' title='导入组成物'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
                         "<td><a class='btn btn-secondary btn-sm set-comple' href='javacript:void(0);' data-id='"+ id +"' title='将分类树设为补充模板数据'><i class='fa fa-sign-in fa-rotate-90'></i>设置</a></td>" +
                         "</tr>");
                 }
@@ -274,7 +301,6 @@ function getCompilationList(callback){
         url: 'api/getCompilationList',
         dataType: 'json',
         success: function (result) {
-            //addoptions
             for(let i = 0; i < result.data.length; i++){
                 let $option =  $("<option >"+ result.data[i].name +"</option>");
                 $option.val( result.data[i]._id);
@@ -310,6 +336,7 @@ function createGljLib(gljLibObj, dispNamesArr, usedCom){
                     "<i class='fa fa-pencil-square-o'></i></a> <a href='javascript:void(0);' data-toggle='modal' data-target='#del' class='text-danger' title='删除'>" +
                     "<i class='fa fa-remove'></i></a></td>" +
                     "<td><a class='btn btn-secondary btn-sm import-data' href='javacript:void(0);' data-id='"+ id +"' title='导入数据'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
+                    "<td><a class='btn btn-secondary btn-sm import-components' href='javacript:void(0);' data-id='"+ id +"' title='导入组成物'><i class='fa fa-sign-in fa-rotate-90'></i>导入</a></td>" +
                     "<td><a class='btn btn-secondary btn-sm set-comple' href='javacript:void(0);' data-id='"+ id +"' title='将分类树设为补充模板数据'><i class='fa fa-sign-in fa-rotate-90'></i>设置</a></td>" +
                     "</tr>");
             }