Procházet zdrojové kódy

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

zhongzewei před 7 roky
rodič
revize
ba24da84c1

+ 1 - 0
config/gulpConfig.js

@@ -109,6 +109,7 @@ module.exports = {
         'web/building_saas/main/js/main_ajax.js',
         'web/building_saas/main/js/main.js',
         'web/building_saas/main/js/controllers/project_controller.js',
+        'web/building_saas/main/js/controllers/block_controller.js',
         'web/building_saas/main/js/views/side_tools.js',
         'web/building_saas/main/js/views/std_bills_lib.js',
         'web/building_saas/main/js/views/std_ration_lib.js',

+ 1 - 0
modules/fee_rates/facade/fee_rates_facade.js

@@ -388,6 +388,7 @@ async function changeFeeRateFileFromOthers(jdata) {
     let newFeeRateFile = {};
     newFeeRateFile.ID = uuidV1();
     newFeeRateFile.name = data.name;
+    newFeeRateFile.userID = data.userID;
     newFeeRateFile.libName = feeRateFile.libName;
     newFeeRateFile.libID=feeRateFile.libID;
     newFeeRateFile.rootProjectID = data.rootProjectID;

+ 18 - 0
modules/glj/controllers/glj_controller.js

@@ -330,6 +330,24 @@ class GLJController extends BaseController {
 
             // 查找对应单价文件的项目工料机数据
             let unitPriceModel = new UnitPriceModel();
+            if(type ===1){//从其它项目复制,则先复制一份数据。
+                let needCopyList = await unitPriceModel.findDataByCondition({unit_price_file_id: changeUnitPriceId}, null, false);
+                if(needCopyList){
+                    // 过滤mongoose格式
+                    needCopyList = JSON.stringify(needCopyList);
+                    needCopyList = JSON.parse(needCopyList);
+                    let copyList = [];
+                    for(let n of needCopyList){
+                        delete n._id;  // 删除原有id信息
+                        delete n.id;
+                        n.unit_price_file_id = targetUnitPriceFile.id;
+                        copyList.push(n);
+                    }
+                    copyList.length>0 ? await unitPriceModel.add(copyList):'';
+                }
+            }
+
+
             let copyResult = await unitPriceModel.copyNotExist(currentUnitPriceId, targetUnitPriceFile.id,projectId);
             // 复制成功后更改project数据
             if (!copyResult) {

+ 21 - 3
modules/main/controllers/bills_controller.js

@@ -7,7 +7,7 @@ let ration_model = require('../models/ration');
 let ProjectsData = require('../../pm/models/project_model').project;
 let logger = require("../../../logs/log_helper").logger;
 let quantity_detail = require("../facade/quantity_detail_facade");
-let bill_detail = require("../facade/bill_facade");
+let bill_facade = require("../facade/bill_facade");
 let ration_glj = mongoose.model('ration_glj');
 let ration_coe = mongoose.model('ration_coe');
 let rationInstallationModel = mongoose.model('ration_installation');
@@ -140,7 +140,7 @@ module.exports = {
         try {
             let data = req.body.data;
             data = JSON.parse(data);
-            let sectionInfo= await bill_detail.getSectionInfo(data);
+            let sectionInfo= await bill_facade.getSectionInfo(data);
             result.data=sectionInfo;
         }catch (err){
             logger.err(err);
@@ -156,7 +156,7 @@ module.exports = {
         try {
             let data = req.body.data;
             data = JSON.parse(data);
-            let reorganizeResult= await bill_detail.reorganizeFBFX(data);
+            let reorganizeResult= await bill_facade.reorganizeFBFX(data);
             result.data=reorganizeResult;
         }catch (err){
             logger.err(err);
@@ -165,6 +165,24 @@ module.exports = {
         }
         res.json(result);
     },
+    pasteBlock:async function(req,res){
+        let result={
+            error:0
+        }
+        try {
+            let data = req.body.data;
+            data = JSON.parse(data);
+            let pasteResult = await bill_facade.pasteBlock(data);
+            result.data = pasteResult;
+        }catch (err){
+            logger.err(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
+    },
+
+
     upload: async function(req, res){
         let responseData = {
             err: 0,

+ 10 - 2
modules/main/facade/bill_facade.js

@@ -7,7 +7,7 @@ let Bills_Lib = mongoose.model('std_bills_lib_bills');
 let bill_Model = require('../models/bills').model;
 let _ = require("lodash");
 module.exports={
-   getSectionInfo : async function (data) {
+    getSectionInfo : async function (data) {
         let conditions=[];
         let fxList=[];
         let sectionInfo ={};
@@ -54,8 +54,16 @@ module.exports={
             result =await bill_Model.bulkWrite(tasks);
         }
         return result;
+    },
+    pasteBlock : async function(data){
+
+
+
+
+
+        console.log(data);
     }
-}
+};
 
 function generateBillTasks(data) {
     let tasks=[];

+ 1 - 0
modules/main/models/project_consts.js

@@ -45,4 +45,5 @@ let commonConst = {
     UT_DELETE: 'ut_delete'
 };
 
+
 module.exports = {projectConst: projectConst, commonConst: commonConst, projectConstList: projectConstList};

+ 1 - 0
modules/main/routes/bills_route.js

@@ -17,6 +17,7 @@ module.exports = function (app) {
     billsRouter.post('/multiDelete',billsController.multiDelete);
     billsRouter.post('/getSectionInfo', billsController.getSectionInfo);
     billsRouter.post('/reorganizeFBFX', billsController.reorganizeFBFX);
+    billsRouter.post('/pasteBlock', billsController.pasteBlock);
     billsRouter.post('/upload', billsController.upload);
     app.use('/bills', billsRouter);
 };

+ 4 - 2
modules/pm/facade/pm_facade.js

@@ -78,7 +78,7 @@ async function copyProject(userID, compilationID,data) {
         createProject(projectMap),
         copyProjectSetting(originalID,newProjectID),
         copyBills(newProjectID,billMap),
-        copyRations(newProjectID,billMap.uuidMaping,rationMap),
+        copyRations(newProjectID,billMap.uuidMaping,rationMap,projectGLJMap.IDMap),
         copyProjectGLJ(projectGLJMap.datas),
         commonCopy(newProjectID,originalProperty.calcProgramFile.ID,calcProgramFileID,calcProgramsModel),
         commonCopy(newProjectID,originalProperty.labourCoeFile.ID,labourCoeFileID,labourCoesModel),
@@ -153,7 +153,7 @@ async function copyBills(newProjectID,billMap) {
     return billMap.datas;
 }
 
-async function copyRations(newProjectID,billsIDMap,rationMap) {
+async function copyRations(newProjectID,billsIDMap,rationMap,projectGLJIDMap) {
     let uuidMaping = rationMap.uuidMaping;
     for(let doc of rationMap.datas){
         doc.projectID = newProjectID;
@@ -161,6 +161,8 @@ async function copyRations(newProjectID,billsIDMap,rationMap) {
         if(doc.billsItemID){
             doc.billsItemID = billsIDMap[doc.billsItemID]?billsIDMap[doc.billsItemID]:-1;
         }
+        //绑定定类型的工料机 项目工料机ID
+        doc.type==3&&doc.projectGLJID&&projectGLJIDMap[doc.projectGLJID]?doc.projectGLJID = projectGLJIDMap[doc.projectGLJID]:'';
     }
     if(rationMap.datas.length > 0){
         await insertMany(rationMap.datas,rationModel);

+ 2 - 2
modules/pm/models/project_model.js

@@ -263,7 +263,7 @@ ProjectsDAO.prototype.udpateUserFiles = async function (userId, datas, callback)
                 }, {$set: {'property.unitPriceFile.name': data.updateData.name}});
             }
             else if (data.updateType === updateType.update && data.fileType === fileType.feeRateFile) {
-                await FeeRateFiles.update({userID: userId, ID: data.updateData.ID}, data.updateData);
+                await FeeRateFiles.update({ID: data.updateData.ID}, data.updateData);
                 await Projects.update({
                     userID: userId,
                     'property.feeFile.id': data.updateData.ID
@@ -279,7 +279,7 @@ ProjectsDAO.prototype.udpateUserFiles = async function (userId, datas, callback)
             }
             else if (data.updateType === updateType.delete && data.fileType === fileType.feeRateFile) {
                 data.updateData.deleteInfo = deleteInfo;
-                await FeeRateFiles.update({userID: userId, ID: data.updateData.ID}, data.updateData);
+                await FeeRateFiles.update({ID: data.updateData.ID}, data.updateData);
             }
             else throw '未知文件类型,删除失败'
         }

+ 1 - 0
public/web/sheet/sheet_common.js

@@ -12,6 +12,7 @@ var sheetCommonObj = {
         spreadBook.options.showVerticalScrollbar = true;
         spreadBook.options.allowCopyPasteExcelStyle = false;
         spreadBook.options.allowUserDragDrop = true;
+        spreadBook.options. allowUserEditFormula = false;
         return spreadBook;
     },
 

+ 1 - 0
public/web/sheet/sheet_data_helper.js

@@ -53,6 +53,7 @@ var SheetDataHelper = {
         spread.options.allowCopyPasteExcelStyle = false;
         spread.options.allowUserDragDrop = false;
         spread.options.allowUndo = false;//that.mainSpread.commandManager().setShortcutKey(undefined, GC.Spread.Commands.Key.z, true, false, false, false); 屏蔽undo
+        spread.options. allowUserEditFormula = false;
         spread.getActiveSheet().setRowCount(3);
         return spread;
     },

+ 4 - 0
public/web/tree_sheet/tree_sheet_controller.js

@@ -144,6 +144,8 @@ var TREE_SHEET_CONTROLLER = {
                 if (this.tree.selected.upMove()) {
                     TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
                         TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [that.tree.selected, that.tree.selected.nextSibling], true);
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected,that.tree.selected.serialNo());
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected.nextSibling,that.tree.selected.nextSibling.serialNo());
                         that.sheet.setSelection(that.tree.selected.serialNo(), sels[0].col, 1, 1);
                         if (that.event.refreshBaseActn) {
                             that.event.refreshBaseActn(that.tree);
@@ -158,6 +160,8 @@ var TREE_SHEET_CONTROLLER = {
                 if (this.tree.selected.downMove()) {
                     TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
                         TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, [that.tree.selected, that.tree.selected.preSibling], true);
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected,that.tree.selected.serialNo());
+                        TREE_SHEET_HELPER.refreshChildrenVisiable(that.sheet,that.tree,that.tree.selected.preSibling,that.tree.selected.preSibling.serialNo());
                         that.sheet.setSelection(that.tree.selected.serialNo(), sels[0].col, 1, 1);
                         if (that.event.refreshBaseActn) {
                             that.event.refreshBaseActn(that.tree);

+ 8 - 0
public/web/tree_sheet/tree_sheet_helper.js

@@ -180,6 +180,14 @@ var TREE_SHEET_HELPER = {
             }
         });
     },
+    refreshChildrenVisiable:function(sheet,tree,node,row){
+        let iCount = node.posterityCount(), i, child;
+        for (i = 0; i < iCount; i++) {
+            child = tree.items[row + i + 1];
+            sheet.setRowVisible(row + i + 1, child.visible, GC.Spread.Sheets.SheetArea.viewport);
+        }
+       sheet.invalidateLayout();
+    },
     showTreeData: function (setting, sheet, tree) {
         let indent = 20;
         let levelIndent = -5;

+ 9 - 1
web/building_saas/js/global.js

@@ -85,4 +85,12 @@ function getLocalCache(key) {
     }
 
     return storage.getItem(key);
-}
+}
+
+function removeLocalCache(key) {
+    const storage = window.localStorage;
+    if (!storage || key === '') {
+        return null;
+    }
+    return storage.removeItem(key);
+}

+ 41 - 4
web/building_saas/main/html/main.html

@@ -56,9 +56,9 @@
               <!--造价书-->
               <div class="toolsbar px-1 d-flex justify-content-between">
                   <div class="tools-btn btn-group align-top">
-                    <a href="" class="btn btn-sm" title="复制"><i class="fa fa-files-o" aria-hidden="true"></i></a>
-                    <a href="" class="btn btn-sm" title="剪切"><i class="fa fa-scissors" aria-hidden="true"></i></a>
-                    <a href="" class="btn btn-sm" title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" title="复制" ><i class="fa fa-files-o" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" title="剪切"><i class="fa fa-scissors" aria-hidden="true"></i></a>
+                    <a href="javascript:void(0)" class="btn btn-sm" title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>
                  <!--   <a href="javascript:void(0)" class="btn btn-sm" id="insert" title="插入"><i class="fa fa-sign-in" aria-hidden="true"></i></a>-->
                     <a href="javascript:void(0)" class="btn btn-sm" id="delete" title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
                     <a href="javascript:void(0)" class="btn btn-sm" id="upLevel" title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
@@ -83,7 +83,6 @@
                       <% } else { %>
                       <a href="javascript:void(0)" class="btn btn-sm" name="lockBills"  title="锁定清单"> <i class="fa fa-lock" aria-hidden="true"></i> 锁定清单</a>
                       <% } %>
-
                   </div>
                   <div class="tools-btn">
                       <a href="javacript:void(0);" data-toggle="modal" data-target="#column" class="btn btn-sm"><i class="fa fa-table" aria-hidden="true"></i> 列设置</a>
@@ -1073,6 +1072,43 @@
             </div>
         </div>
     </div>
+
+    <!--弹出 粘帖位置选择-->
+    <div class="modal fade" id="pastePosition" 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">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label >插入为选定节点的:</label>
+                        <div>
+                            <div class="form-check form-check-inline">
+                                <input class="form-check-input" type="radio" name="pastePositionRadio" id="next_node" value="next">
+                                <label class="form-check-label" for="next_node">后项</label>
+                            </div>
+                            <div class="form-check form-check-inline">
+                                <input class="form-check-input" type="radio" name="pastePositionRadio" id="pre_node" value="pre">
+                                <label class="form-check-label" for="pre_node">前项</label>
+                            </div>
+                            <div class="form-check form-check-inline">
+                                <input class="form-check-input" type="radio" name="pastePositionRadio" id="sub_node" value="sub">
+                                <label class="form-check-label" for="sub_node">子项</label>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <button class="btn btn-primary" id="paste_confirm">确定</button>
+                </div>
+            </div>
+        </div>
+    </div>
         <!-- JS. -->
         <script type="text/javascript" src="/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
 
@@ -1173,6 +1209,7 @@
         <script type="text/javascript" src="/web/building_saas/main/js/main_ajax.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/main.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/controllers/project_controller.js"></script>
+        <script type="text/javascript" src="/web/building_saas/main/js/controllers/block_controller.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/side_tools.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/std_bills_lib.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/std_ration_lib.js"></script>

+ 446 - 0
web/building_saas/main/js/controllers/block_controller.js

@@ -0,0 +1,446 @@
+/**
+ * Created by zhang on 2018/5/10.
+ */
+let BlockController = {
+    datas:[],
+    copyBtnDisable:function (selected) {
+        if(this.isDXFYorMainEq(selected)){
+            return true;
+        }
+        if(selected.sourceType == ModuleNames.ration && selected.data.type == rationType.install){
+            return true;
+        }
+        return false;
+    },
+    pasteBtnDisable:function (selected) {
+        let blockData = this.getBlockData();
+        let Bills = projectObj.project.Bills;
+        if(this.isDXFYorMainEq(selected)){
+            return true;
+        }
+        if(blockData == null){
+            return true;
+        }
+        if(blockData.firstNodeType != blockType.RATION && blockData.isFBFX !=  Bills.isFBFX(selected)){//除了复制定额外,焦点行和复制的块不是来自同一个地方(分部分项工其它)
+            return true;
+        }
+        if(selected.sourceType == Bills.getSourceType() && selected.data.type == billType.FX && blockData.firstNodeType == blockType.FB){//焦点行是分项,复制块的第一层是分部,则无效。
+            return true;
+        }
+        if(blockData.firstNodeType == blockType.RATION && selected.sourceType == Bills.getSourceType()){ //复制的是定额/量价/工料机、焦点行是分部/清单父项则无效
+            if( selected.data.type == billType.FB ){
+                return true;
+            }
+            if(MainTreeCol.readOnly.billsParent(selected)){
+                return true;
+            }
+        }
+        if(blockData.firstNodeType != blockType.RATION && selected.sourceType == ModuleNames.ration){
+            return true;
+        }
+        return false;
+    },
+    isDXFYorMainEq:function (node) {//焦点行是大项费用或定额下的主材设备
+        if(node.sourceType == ModuleNames.bills && node.data.type == billType.DXFY){//焦点行是大项费用则无效;
+            return true;
+        }
+        if(node.sourceType == ModuleNames.ration_glj){// 焦点行是定额下的主材设备则无效;
+            return true;
+        }
+        return false;
+    },
+
+    getBlockData:function () {
+        let blockString =getLocalCache('project_block');
+        if(blockString !=null){
+            return JSON.parse(blockString);
+        }
+        return null;
+    },
+
+    copyBlock:function (selected) {
+        let startTime = +new Date();
+        let blockOjb = {
+            compilationID:projectInfoObj.projectInfo.compilation
+        };
+        if(selected.sourceType == projectObj.project.Bills.getSourceType()){
+            blockOjb.firstNodeType = selected.data.type;
+        }else if(selected.sourceType == projectObj.project.Ration.getSourceType()){
+            blockOjb.firstNodeType = blockType.RATION;
+        }
+        blockOjb.isFBFX = projectObj.project.Bills.isFBFX(selected);
+        let ration_glj_Map = _.groupBy(projectObj.project.ration_glj.datas, 'rationID');
+        blockOjb.data = this.getNodeDatas(selected,ration_glj_Map);
+        let getDataTime = +new Date();
+        console.log(`复制所用时间——${getDataTime - startTime}`);
+        blockOjb.copyTime = +new Date();//设置复制时间,可以用来做过期处理
+        setLocalCache('project_block',JSON.stringify(blockOjb));
+        let endTime = +new Date();
+        console.log(`复制所用时间——${endTime - startTime}`);
+    },
+    getNodeDatas : function (node,ration_glj_Map) {
+        let data = node.data;
+        data.sourceType =  node.sourceType;
+        if(node.sourceType == projectObj.project.Bills.getSourceType()){
+            data.quantity_details = projectObj.project.quantity_detail.getDetailByBillID(data.ID);
+        }
+        if(node.sourceType == projectObj.project.Ration.getSourceType()){
+            if(node.data.type == rationType.install){ //如果是生成的安装增加费,则跳过
+                return null;
+            }
+            let gljList = ration_glj_Map[data.ID]?ration_glj_Map[data.ID]:[];//gljOprObj.filterGljByRation(node.data, datas);
+            gljList = gljOprObj.combineWithProjectGlj(gljList,false);
+            data.ration_gljs = gljList;
+            data.ration_coes = projectObj.project.ration_coe.getCoeByRationID(data.ID);
+            data.ration_installations =  projectObj.project.ration_installation.getInstallationByRationID(data.ID);
+            data.quantity_details = projectObj.project.quantity_detail.getDetailByRationID(data.ID);
+        }else if(node.children.length>0){
+            let children = [];
+            for(let c of node.children){
+                let tem_data = this.getNodeDatas(c,ration_glj_Map);
+                tem_data?children.push(tem_data):'';
+            }
+            data.children = children;
+        }
+        return data;
+    },
+    pasteBlock:function (selected) {
+        let blockData = this.getBlockData();
+        let position = this.initOptionDiv(selected,blockData);
+        if(position == null){
+            return;
+        }
+        this.confirmPaste(blockData,selected,position);
+        //do paste
+    },
+
+    initOptionDiv:function (selected,blockData) {
+        let Bills = projectObj.project.Bills;
+        if( blockData.firstNodeType == blockType.RATION){//如果剪切板中是复制的定额块
+            if(selected.sourceType == ModuleNames.ration && selected.data.type != rationType.install ){//焦点行是定额/量价/工料机,则粘贴为后项
+                return "next";
+            }
+            if(isFXorBX(selected)||(selected.sourceType === Bills.getSourceType()&& selected.source.children.length == 0)){//焦点行是分项/叶子清单,且无基数计算,则粘贴到分项/叶子清单下
+                if(selected.data.calcBase ==null||selected.data.calcBase ==undefined|| selected.data.calcBase == ""){//无基数计算
+                    return "sub";
+                }
+            }
+        }
+
+        //设置选项的初始值
+        setRadioProp('next_node',{checked:true,disabled:false});
+        setRadioProp('pre_node',{checked:false,disabled:false});
+        if(Bills.isFBFX(selected)){//  (2.1)、焦点行属于“分部分项工程”:
+            //复制块的第一层、焦点行的类型都是“分部”
+            if(blockData.firstNodeType == blockType.FB && isFB(selected)){
+                //默认为当前行的后项,可选前项、子项。
+                setRadioProp('sub_node',{checked:false,disabled:false});
+            }
+            //复制块的第一层、焦点行的类型都是“分项”或补项
+            if(blockIsFXorBX(blockData.firstNodeType) && isFXorBX(selected)){
+                //默认为当前行的后项,可选前项,子项灰显不可选。
+                setRadioProp('sub_node',{checked:false,disabled:true});
+            }
+            //复制块的第一层是分项,焦点行是分部,且分部下无子项或者子项是分项
+            if(blockIsFXorBX(blockData.firstNodeType)&& isFB(selected)){
+                if(selected.children.length == 0 || isFXorBX(selected.children[0])){
+                    return 'sub';//不弹出选择窗口,直接粘贴为子项。
+                }
+            }
+        }else {//焦点行不属于“分部分项工程”
+            if(blockData.firstNodeType == blockType.BILL &&selected.sourceType == Bills.getSourceType()){//如果剪切板中是从“分部分项工程”以外复制的清单块
+                if(selected.children.length==0 || selected.children[0].sourceType == Bills.getSourceType()){//焦点行没有子项,或者子项是清单,判断是否有基数计算
+                    if(selected.data.calcBase && selected.data.calcBase!=""){//如果焦点行有基数计算,则子项灰显不可选。
+                        setRadioProp('sub_node',{checked:false,disabled:true});
+                    }else{//如果焦点行没有基数计算,则子项可选。
+                        setRadioProp('sub_node',{checked:false,disabled:false});
+                    }
+                }else {
+                    setRadioProp('sub_node',{checked:false,disabled:true});
+                }
+            }
+        }
+        $("#pastePosition").modal({show:true});
+        return null;
+
+       function setRadioProp(id,options) {
+           $("#"+id).prop("checked",options.checked);
+           $("#"+id).prop("disabled",options.disabled);
+       }
+
+       function isFB(selected) {
+           return selected.sourceType == Bills.getSourceType() && selected.data.type == billType.FB;
+       }
+
+       function isFXorBX(selected) {//是分项或者补项
+            if(selected.sourceType == Bills.getSourceType()){
+                return   selected.data.type == billType.FX || selected.data.type == billType.BX;
+            }
+            return false;
+       }
+       function blockIsFXorBX(type) {
+           return type == blockType.FX||blockType.BX;
+       }
+
+    },
+    /**
+     * @param blockData
+     * @param selected
+     * @param position next/pre/sub
+     */
+    confirmPaste:function (blockData,selected,position) {
+        let Bills = projectObj.project.Bills;
+        let parent = null,next = null,pre = null;
+        let updateData = [],billUpdate = null;
+        let billsIDMap = {};//用来做新旧ID映射
+        if(blockData.compilationID != projectInfoObj.projectInfo.compilation){//如果编办不一样,不能复制
+            alert("编办不一致,不能粘贴!");
+            return;
+        }
+        if(position == 'next'){ //插入为选中节点的后项,即选中节点为前项
+            parent = selected.parent;
+            next = selected.nextSibling;
+            pre = selected;
+        }
+        if(position == 'pre'){//插入为选中节点的前项,即选中节点为后项
+            parent = selected.parent;
+            next = selected;
+            pre = selected.preSibling;
+        }
+        if(position == 'sub'){//即选中节点为父项
+            parent = selected;
+            pre = selected.lastChild();
+        }
+        let parentID = parent?parent.getID():-1;
+        let nextID = next?next.getID():-1;
+        if(blockData.firstNodeType == blockType.RATION){ //复制的是定额,需根据新的父项信息和工程量明细计算工程量
+            blockData.data.billsItemID = parentID;
+            let billsQuantity = scMathUtil.roundForObj(parent.data.quantity,getDecimal("quantity",parent));
+            this.calcRationQuantityAndContain(billsQuantity,blockData.data);
+            //如果粘贴位置不属于分部分项工程,或者不是安装工程,则把安装增加费内容置空
+            if(!Bills.isFBFX(parent)|| projectInfoObj.projectInfo.property.engineering!=engineeringType.BUILD_IN){
+                blockData.data.ration_installations = [];
+            }
+            //计算序列号
+            this.calcRationSerialNo(parentID,blockData,updateData,pre,next);
+        }else {
+            blockData.data.ParentID = parentID;
+            blockData.data.NextSiblingID=nextID;
+            if(pre){
+                billUpdate = {type:blockData.data.sourceType,query:{ID:pre.getID()},doc:{NextSiblingID:blockData.data.ID}};
+            }
+        }
+        let dataMap = this.preparePasteData(blockData.data,billsIDMap);
+        if(billUpdate){
+            billUpdate.doc.NextSiblingID = billsIDMap[billUpdate.doc.NextSiblingID];
+            updateData.push(billUpdate);
+        }
+        dataMap.updateData = updateData;
+        console.log(dataMap);
+        $.bootstrapLoading.start();
+        CommonAjax.post('/bills/pasteBlock',dataMap,function (data) {
+             $.bootstrapLoading.end();
+
+
+        })
+
+        //  delete fees / feesIndex /__v
+    },
+
+    preparePasteData : function (data,billsIDMap) {
+        let me = this;
+        me.datas = _.cloneDeep(projectObj.project.Bills.datas);
+        let bills = [],rations=[],ration_gljs = [],ration_coes = [],quantity_details = [],ration_installations = [];
+
+        eachData(data);
+        for(let b of bills){//更新ID
+            billsIDMap[b.ParentID]?b.ParentID = billsIDMap[b.ParentID]:'';
+            billsIDMap[b.NextSiblingID]?b.NextSiblingID = billsIDMap[b.NextSiblingID]:'';
+        }
+
+
+        return {bills:bills,rations:rations,ration_gljs:ration_gljs,ration_coes:ration_coes,quantity_details:quantity_details,ration_installations:ration_installations};
+
+        function eachData(data) {
+            if(data.sourceType == 'bills'){
+                let tem_b = createBillsData(data);
+                bills.push(tem_b);
+                for(let d of data.quantity_details){
+                    quantity_details.push(createQuantityDetails(d,tem_b,'bills'));
+                }
+                if(data.children && data.children.length>0){
+                    for(let c of data.children){
+                        eachData(c);
+                    }
+                }
+            }
+
+            if( data.sourceType == 'ration'){
+                let tem_r = createRationData(data);
+                rations.push(tem_r);
+                for(let d of data.quantity_details){
+                    quantity_details.push(createQuantityDetails(d,tem_r, 'ration'));
+                }
+                for(let g of data.ration_gljs){
+                    let tem_rg = createSubList(g,tem_r);
+                    tem_rg.billsItemID = tem_r.billsItemID;
+                    ration_gljs.push(tem_rg);
+                }
+                for(let o of data.ration_coes){
+                    ration_coes.push(createSubList(o,tem_r));
+                }
+                for(let ri of data.ration_installations){
+                    ration_installations.push(createSubList(ri,tem_r));
+                }
+            }
+
+        }
+
+        function createSubList(subData,rationData) {
+            let tem_sub = _.cloneDeep(subData);
+            delete tem_sub._id;
+            tem_sub.ID = uuid.v1();
+            tem_sub.projectID = projectObj.project.ID();
+            tem_sub.rationID = rationData.ID;
+            return tem_sub;
+        }
+
+        function createQuantityDetails(detailData,pdata,type) {
+            let tem_detail = _.cloneDeep(detailData);
+            tem_detail.ID = uuid.v1();
+            tem_detail.projectID = projectObj.project.ID();
+            if(type == 'bills'){
+                tem_detail.billID = pdata.ID;
+            }
+            if(type == 'ration'){
+                tem_detail.rationID = pdata.ID;
+            }
+            return tem_detail;
+        }
+
+        function createRationData(rationData) {
+            let tem_ration = _.cloneDeep(rationData);
+            //删除旧数据
+            delete tem_ration.fees;
+            delete tem_ration.feesIndex;
+            delete tem_ration.ration_gljs;
+            delete tem_ration.ration_coes;
+            delete tem_ration.ration_installations;
+            delete tem_ration.quantity_details;
+            delete tem_ration.__v;
+            delete tem_ration.sourceType;
+
+            tem_ration.projectID = projectObj.project.ID();
+            tem_ration.ID = uuid.v1();
+            billsIDMap[tem_ration.billsItemID]?tem_ration.billsItemID = billsIDMap[tem_ration.billsItemID]:'';
+
+            let firstLibID = rationLibObj.getFirstStdRationLibID();
+            if(firstLibID){
+                tem_ration.prefix = projectObj.project.Ration.getRationPrefix(firstLibID,tem_ration);
+            }
+            return tem_ration;
+
+        }
+
+        function createBillsData(billsData) { //ID、重新生成code
+            let temData = _.cloneDeep(billsData);
+            //删除旧数据
+            delete  temData.fees;
+            delete  temData.feesIndex;
+            delete  temData.children;
+            delete  temData.quantity_details;
+            delete  temData.__v;
+            delete  temData.sourceType;
+
+            temData.projectID = projectObj.project.ID();
+            let newID = uuid.v1(); //新的清单ID
+            billsIDMap[temData.ID] = newID;
+            temData.ID = newID; //新的清单ID
+            if(temData.billsLibId && temData.billsLibId!="" && temData.code.length == 12){//是从清单库来的
+                let value = temData.code.substr(0,9);
+                if (value&&value.length === 9 && /^[\d]+$/.test(value)) {
+                    temData.code = projectObj.project.Bills.newFormatCode(value);
+                }
+            }
+
+            me.datas.push(temData);//为了下一个清单的std code 一样
+            return temData;
+        }
+    },
+
+    calcRationSerialNo:function (billsItemID,blockData,updateData,pre,next) {
+        let br = projectObj.project.Ration.getBillsSortRation(billsItemID);
+        if(next == null){ //没有下一树节点,即为最后节点
+            blockData.data.serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1;
+        }else {//有下一节点
+            let startIndex =0;
+            if(pre){
+                startIndex = br.indexOf(pre.data)+1;
+            }
+            blockData.data.serialNo = br[startIndex].serialNo;
+            for(let i = startIndex;i < br.length; i++){
+                let br_serialNo =  i < br.length - 1 ? br [i + 1].serialNo : br[i].serialNo + 1;
+                updateData.push({type:blockData.data.sourceType,query:{ID:br[i].ID},doc:{serialNo:br_serialNo}});//更新兄弟节点序列号
+            }
+        }
+
+    },
+
+    calcRationQuantityAndContain : function (billsQuantity,ration) {//计算定额工程量和含量
+        let EXPString = ration.quantityEXP+"";
+        if(EXPString.indexOf("QDL") != -1){
+            if(EXPString=="QDL"){//定额的工程量是直接通过清单量填进来的;
+                let times = parseInt(ration.unit);
+                if(isNaN(times)){
+                    times = 1;
+                }
+                ration.quantity = scMathUtil.roundForObj(billsQuantity / times,getDecimal("ration.quantity"));
+                billsQuantity?ration.contain = scMathUtil.roundForObj(ration.quantity/billsQuantity,getDecimal("process")):ration.contain = 0;
+            } else {//如果定额的工程量是通过计算出来的,则应该重新计算。
+                let tem_contain = scMathUtil.roundForObj(ration.contain,getDecimal("process"));
+                let tem_quantity = scMathUtil.roundForObj(billsQuantity*tem_contain,getDecimal("ration.quantity")); //this.autoTransformQuantity(tem_quantity,rationNode);
+                ration.quantity = tem_quantity;
+            }
+        }else {//GCLMXHJ
+            let tem_contain=0;
+            if(billsQuantity&&billsQuantity!=0){
+                let children_quantity = scMathUtil.roundForObj(ration.quantity,getDecimal("ration.quantity"));
+                // children_quantity = scMathUtil.roundForObj(this.reverseQuantity(children_quantity,rationNode),getDecimal("quantity",rationNode));  原先是要反算的,现在改成不用反算了
+                tem_contain =scMathUtil.roundForObj(children_quantity/billsQuantity,getDecimal("process"));
+            }
+            ration.contain = tem_contain;
+        }
+    },
+
+   newFormatCode : function (stdCode, filterCode) {
+        let matchs = this.sameStdCode(stdCode, filterCode);
+        let format = function (Number) {
+            let s = Number + '';
+            while (s.length < 3) {
+                s = '0' + s;
+            }
+            return s;
+        };
+        for (let i = 0; i <= matchs.length; i++) {
+            let formatCode = stdCode + format(i+1);
+            if (matchs.indexOf(formatCode) === -1) {
+                return formatCode;
+            }
+        }
+    },
+    sameStdCode : function (stdCode, filterCode) {
+        let reg = new RegExp('^' + stdCode), matchs= [];
+        for (let data of this.datas) {
+            if (data.code && data.code.length === 12 && reg.test(data.code) && data.code !== filterCode) {
+                matchs.push(data.code);
+            }
+        }
+        return matchs;
+    },
+
+
+    removeBlock:function () {
+        removeLocalCache('project_block');
+    }
+
+};

+ 3 - 0
web/building_saas/main/js/models/cache_tree.js

@@ -143,6 +143,9 @@ var cacheTree = {
         Node.prototype.firstChild = function () {
             return this.children.length === 0 ? null : this.children[0];
         };
+        Node.prototype.lastChild = function () {
+            return this.children.length === 0 ? null : this.children[this.children.length - 1];
+        };
         Node.prototype.depth = function () {
             return this.parent ? this.parent.depth() + 1 : 0;
         };

+ 1 - 0
web/building_saas/main/js/models/fee_rate.js

@@ -546,6 +546,7 @@ var FeeRate = {
                 "projectID": projectID,
                 "feeRateFileID":feeRateFileID,
                 "name":name,
+                "userID":userID,
                 "rootProjectID":me.getActivateFeeRate().rootProjectID
             };
             CommonAjax.post('/feeRates/changeFeeRateFileFromOthers', data, function (data) {

+ 7 - 0
web/building_saas/main/js/models/main_consts.js

@@ -329,6 +329,13 @@ const engineeringType = {
     // 安装修缮工程
     BUILD_IN_REPAIR: 14
 };
+const blockType ={
+    RATION:1,//定额
+    FB:2,//分部
+    FX:3,//分项
+    BILL:4,//清单
+    BX:5//补项
+};
 
 const installFeeType = ['子目费用','分项费用','措施费用'];
 const installSectionBase = ['分别按人材机乘系数','人工','材料','机械'];

+ 8 - 1
web/building_saas/main/js/models/quantity_detail.js

@@ -452,6 +452,13 @@ var quantity_detail = {
             });
             return temp;
         };
+        quantity_detail.prototype.getDetailByRationID = function (rationID) {
+          return _.filter(this.datas,{'rationID':rationID});
+        };
+        quantity_detail.prototype.getDetailByBillID = function (billID) {
+            return _.filter(this.datas,{'billID':billID});
+        };
+
         quantity_detail.prototype.deleteByRation = function(ration){
             var detail_list = this.datas;
             _.remove(detail_list,{'rationID':ration.ID});
@@ -595,7 +602,7 @@ var quantity_detail = {
                     }else {
                         let tem_contain=0;
                         if(value&&value!=0){
-                           let children_quantity = scMathUtil.roundForObj(rationNode.data.quantity,getDecimal("quantity"),rationNode);
+                           let children_quantity = scMathUtil.roundForObj(rationNode.data.quantity,getDecimal("quantity",rationNode));
                             // children_quantity = scMathUtil.roundForObj(this.reverseQuantity(children_quantity,rationNode),getDecimal("quantity",rationNode));  原先是要反算的,现在改成不用反算了
                             tem_contain =scMathUtil.roundForObj(children_quantity/value,getDecimal("process"));
                         }

+ 4 - 0
web/building_saas/main/js/models/ration_coe.js

@@ -53,6 +53,10 @@ var ration_coe = {
                 }
             }
         };
+        ration_coe.prototype.getCoeByRationID = function (rationID) {
+           let coeList = _.filter(this.datas, {'rationID': rationID});
+           return coeList;
+        };
         ration_coe.prototype.refreshAfterUpdate=function(data){
             var coe_list = projectObj.project.ration_coe.datas;
             var coe_index= _.findIndex(coe_list,function(coe){

+ 4 - 0
web/building_saas/main/js/models/ration_installation.js

@@ -32,6 +32,10 @@ let ration_installation = {
                 }
             }
         };
+        ration_installation.prototype.getInstallationByRationID = function (rationID) {
+            let insList = _.filter(this.datas, {'rationID': rationID});
+            return insList;
+        };
         ration_installation.prototype.getBySectionID = function(sectionID){
             var ri_list = this.datas;
             return _.filter(ri_list,{'sectionId':sectionID});

+ 3 - 3
web/building_saas/main/js/views/fee_rate_view.js

@@ -10,9 +10,9 @@ var feeRateObject={
     mainFeeRateData:null,
     mainFeeRateSetting:{
         header: [
-            {headerName: "专业名称", headerWidth: 550, dataCode: "name", dataType: "String"},
-            {headerName: "值%", headerWidth: 250, dataCode: "rate", dataType: "Number",hAlign: "right",decimalField:"feeRate"},
-            {headerName: "备注", dataCode: "memo", dataType: "String"}
+            {headerName: "专业名称", headerWidth: 250, dataCode: "name", dataType: "String"},
+            {headerName: "值%", headerWidth: 80, dataCode: "rate", dataType: "Number",hAlign: "right",decimalField:"feeRate"},
+            {headerName: "备注", headerWidth: 150, dataCode: "memo", dataType: "String"}
         ],
         view: {
             lockColumns: [0]

+ 64 - 18
web/building_saas/main/js/views/glj_view.js

@@ -357,7 +357,7 @@ var gljOprObj = {
 
     onClipboardPasting: function (sender, args) {
         var me = gljOprObj;
-        if(args.cellRange.rowCount!=1||args.cellRange.colCount!=1){
+        if(args.sheetName!="quantity_detail"&&(args.cellRange.rowCount!=1||args.cellRange.colCount!=1)){//工程量明细做特殊处理
             args.cancel = true;
         }
     },
@@ -397,7 +397,8 @@ var gljOprObj = {
             me.onEditDetailSheet(args);
         }
     },
-    onEditDetailSheet: function (args) {
+    onEditDetailSheet: function (args,callback) {
+        console.log(args);
         var me = gljOprObj;
         if (args.row > me.detailData.length) {
             return;
@@ -407,14 +408,16 @@ var gljOprObj = {
         }
         var selected = projectObj.project.mainTree.selected;//因为使用了延时方法,所以要先取得选中行;
         var detailList = me.detailData;
-        args.editingText = args.editingText.replace(/(/g, "(");//替换中文左右括号;
-        args.editingText = args.editingText.replace(/)/g, ")");
+        if(args.editingText){
+            args.editingText = args.editingText.replace(/(/g, "(");//替换中文左右括号;
+            args.editingText = args.editingText.replace(/)/g, ")");
+        }
         setTimeout(function () {//这里须用延时执行的办法,不然的弹窗确认窗口会和spreadjs 的事件有冲突,造成定额工料机数据不会根据树结点更新的问题
             if (args.row == detailList.length) {
-                projectObj.project.quantity_detail.saveQuantityDetail(args, me.detailSetting.header[args.col].dataCode, selected);
+                projectObj.project.quantity_detail.saveQuantityDetail(args, me.detailSetting.header[args.col].dataCode, selected,callback);
             }
             if (args.row < detailList.length) {
-                projectObj.project.quantity_detail.updateQuantityDetail(args, me.detailSetting.header[args.col].dataCode, detailList[args.row], selected);
+                projectObj.project.quantity_detail.updateQuantityDetail(args, me.detailSetting.header[args.col].dataCode, detailList[args.row], selected,callback);
             }
         }, 100);
 
@@ -725,21 +728,64 @@ var gljOprObj = {
     },
     onRangeChanged: function (sender, args) {
         var me = gljOprObj;
-        if (args.action == GC.Spread.Sheets.RangeChangedAction.clear) {
-            args.editingText = null;
-        }else if(args.action == GC.Spread.Sheets.RangeChangedAction.paste){
-            args.editingText = args.sheet.getCell(args.row,args.col).value();
+        console.log(args);
+        if(args.sheetName == 'quantity_detail'){
+            me.batchUpdateQuantityDetail(args);
         }else {
-            return;
+            if (args.action == GC.Spread.Sheets.RangeChangedAction.clear) {
+                args.editingText = null;
+            }else if(args.action == GC.Spread.Sheets.RangeChangedAction.paste){
+                args.editingText = args.sheet.getCell(args.row,args.col).value();
+            }else {
+                return;
+            }
+            if (args.sheetName == 'ration_glj') {
+                me.onEditGLJSheet(args);
+            }
+            if (args.sheetName == 'ration_ass') {
+                me.updateRationAss(args);
+            }
         }
-        if (args.sheetName == 'ration_glj') {
-            me.onEditGLJSheet(args);
+    },
+
+    batchUpdateQuantityDetail:function (args) {
+        let me = gljOprObj;
+        let updateArray = [];
+        for(let i =0;i<args.changedCells.length;i++){
+            let c = args.changedCells[i];
+            let tem = {
+                row:c.row,
+                col:c.col,
+                editingText:args.sheet.getCell(c.row,c.col).text(),
+                sheet:args.sheet,
+                sheetName:args.sheetName,
+                index:i
+            };
+            updateArray.push(tem);
         }
-        if (args.sheetName == 'ration_ass') {
-            me.updateRationAss(args);
+        console.log(updateArray);
+
+
+    },
+
+    testBatchUpdate:function () {
+        let me=gljOprObj;
+        let temA = [1,2,3];
+        me.b(1,a);
+
+
+        function a(v) {
+            let index = temA.indexOf(v);
+            if(index < temA.length-1){
+               me.b(temA[index+1],a)
+            }
         }
 
     },
+    b:function (g,callback) {
+        console.log(g);
+        callback(g);
+    },
     generateHtmlString: function () {
 //        return "<div id='edit'><div>";
 
@@ -945,7 +991,7 @@ var gljOprObj = {
         }
         this.sheetData = newList;
     },
-    combineWithProjectGlj: function (ration_gljs) {
+    combineWithProjectGlj: function (ration_gljs,needRatio=true) {
         var projectGLJData = projectObj.project.projectGLJ.datas;
         var projectGljs = projectGLJData.gljList;
         var mixRatioMap = projectGLJData.mixRatioMap;
@@ -960,7 +1006,7 @@ var gljOprObj = {
                     ration_gljs[i].isAdd = glj.unit_price.is_add;
                     ration_gljs[i]=this.setGLJPrice(ration_gljs[i],glj);//设置工料机价格
                     var connect_index = this.getIndex(glj, gljKeyArray);
-                    if (mixRatioMap.hasOwnProperty(connect_index)) {
+                    if (needRatio==true&&mixRatioMap.hasOwnProperty(connect_index)) {
                         var mixRatios = this.getMixRationShowDatas(mixRatioMap[connect_index], projectGljs);
                         ration_gljs[i].subList = mixRatios;
                     }
@@ -1865,4 +1911,4 @@ function compareRationGLJ(a, b) {
         }
     }
     return false;
-}
+}

+ 1 - 1
web/building_saas/main/js/views/project_glj_view.js

@@ -625,7 +625,7 @@ $(function () {
 
     $("#unitFile-save-as").on('shown.bs.modal', function () {
         // 获取当前建设项数据
-        $("#save-as-name").val(projectGljObject.usedUnitPriceInfo.name + '(复件)');
+        $("#save-as-name").val(projectGljObject.usedUnitPriceInfo.name + '副本');
     });
 
     // 从其他建设项目中复制 选择建设项目

+ 53 - 11
web/building_saas/main/js/views/project_view.js

@@ -927,20 +927,13 @@ var projectObj = {
                     callback: function () {
                         project.calcProgram.calcAllNodesAndSave();
                     }
-                }/*,
+                },
                 "spr2":'--------',
                 "copyBlock": {
                     name: '复制整块',
                     icon: 'fa-copy',
                     disabled: function () {
-                        let selected = project.mainTree.selected;
-                        if(selected.sourceType == project.Bills.getSourceType() && selected.data.type == billType.DXFY){//焦点行是大项费用则无效;
-                            return true;
-                        }
-                        if(selected.sourceType == project.ration_glj.getSourceType()){// 焦点行是定额下的主材设备则无效;
-                            return true;
-                        }
-                        return false;
+                        return BlockController.copyBtnDisable(project.mainTree.selected);
                     },
                     callback: function () {
                         $.bootstrapLoading.start();
@@ -956,10 +949,13 @@ var projectObj = {
                 "pasteBlock": {
                     name: '粘贴整块',
                     icon: 'fa-paste',
+                    disabled: function (){
+                        return BlockController.pasteBtnDisable(project.mainTree.selected);
+                    },
                     callback: function () {
-
+                        BlockController.pasteBlock(project.mainTree.selected);
                     }
-                }*/
+                }
             }
         });
     },
@@ -1582,6 +1578,42 @@ $('#property_ok').click(function () {
     }
 });
 
+function testShow() {
+    var controller = projectObj.mainController, project = projectObj.project;
+    var selected = controller.tree.selected, parent = selected.parent;
+    var showinfo = "<label>确认要删除当前选中行吗?</label>";
+    var showN = false;
+    var cancelText = "否";
+    if(selected.sourceType == project.Bills.getSourceType()&&selected.data.type==billType.FB&&selected.children.length>0){//选中的是分部,并且有子项
+        if(isSingleSelect()||selectionChecking()){
+            showinfo = "<label>是否删除其下的子项?</label><br><label>【是】则删除分部行及其下的所有子项,</label><br><label>【否】则仅删除当前分部行,子项保留,</label><br><label>【取消】则取消删除</label>";
+            showN = true;
+            cancelText = "取消";
+        }
+    }
+    $('#delete_showinfo').html(showinfo);
+    showN==true? $('#deleteN').show():$('#deleteN').hide();
+    $('#deleteCancel').text(cancelText);
+
+    function selectionChecking() {
+        let selection = projectObj.mainSpread.getActiveSheet().getSelections()[0];
+        let mainTreeMap = {};
+        for(let i =0;i<selection.rowCount;i++){
+            let tem_node = controller.tree.items[selection.row+i];
+            if(i==0){//第一个直接添加;
+                mainTreeMap[tem_node.getID()] = tem_node;
+            }else {
+                project.Bills.setNodeToMap(tem_node,mainTreeMap);
+            }
+        }
+        let nodes = changeMapToArray(mainTreeMap);
+        if(nodes.length==1){
+            return true
+        }
+        return false;
+    }
+}
+
 $('#delete_row').on('shown.bs.modal', function (e) {
     var controller = projectObj.mainController, project = projectObj.project;
     var selected = controller.tree.selected, parent = selected.parent;
@@ -1866,6 +1898,16 @@ $(function () {
         spreadAutoFocus(subSpread,projectObj.mainSpread);
     });
 
+    $("#paste_confirm").click(function (){
+        let selected = projectObj.project.mainTree.selected;
+        let blockData = BlockController.getBlockData();
+        let position = $("input[name='pastePositionRadio']:checked").val();
+        BlockController.confirmPaste(blockData,selected,position);
+        $("#pastePosition").modal("hide");
+
+    });
+
+
     function spreadAutoFocus(spread,relateSpread) {
         if(relateSpread&&relateSpread.getActiveSheet().isEditing()){//关联的spread不在编辑状态的情况下,才自动获得焦点;
             return;

+ 2 - 2
web/building_saas/main/js/views/sub_fee_rate_views.js

@@ -11,8 +11,8 @@ var subRateObject={
     subRateSheet:null,
     subRateSetting:{
         header: [
-            {headerName: "参数名称", headerWidth: 250, dataCode: "name", dataType: "String"},
-            {headerName: "参数值", headerWidth: 200, dataCode: "optionValue", dataType: "String",getText:'forOption'}
+            {headerName: "参数名称", headerWidth: 110, dataCode: "name", dataType: "String"},
+            {headerName: "参数值", headerWidth: 150, dataCode: "optionValue", dataType: "String",getText:'forOption'}
         ],
         view: {
             lockColumns: [0]