Browse Source

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost into 1.0.0_online

zhongzewei 6 years ago
parent
commit
435c3dec76

+ 1 - 1
gulpfile.js

@@ -276,7 +276,7 @@ gulp.task('main_css',function () {
     return css(mainOptions);
 })
 
-gulp.task('main_inject',['main_minify','main_css'],function () {
+gulp.task('main_inject',['main_minify'],function () {//, ['main_minify','main_css'  ] main css 打包到一起会出现样式冲突问题, 现改成不打包
     return inject(mainOptions);
 })
 

+ 1 - 0
modules/all_models/ration_coe.js

@@ -22,6 +22,7 @@ var coeListSchema = mongoose.Schema({
     content: String,                    // 说明
     original_code:String,               //原人材机编码
     option_codes:String,                //可选人材机编码
+    option_list:[Schema.Types.Mixed],//下拉列表选项
     select_code:String,
     rationID:String,
     projectID:Number,

+ 1 - 0
modules/all_models/stdRation_coe.js

@@ -25,6 +25,7 @@ const coeListSchema = new Schema({
     content: String,                    // 说明
     original_code:String,               //原人材机编码
     option_codes:String,                //可选人材机编码
+    option_list:[Schema.Types.Mixed],//下拉列表选项
     coes: [coeSchema]
 }, {versionKey: false});
 

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

@@ -277,6 +277,9 @@ class GLJController extends BaseController {
      * @return {void}
      */
     async getProjectInfo(request, response) {
+        if(typeof request.body.data == "string"){
+            request.body = JSON.parse(request.body.data)
+        }
         let projectId = request.body.project_id;
         let rootProjectID = request.body.rootProjectID;
         projectId = parseInt(projectId);

+ 1 - 0
modules/main/facade/ration_facade.js

@@ -312,6 +312,7 @@ async function addRationCoe(std,newRation,compilation) {
                 newCoe.content = libCoe.content;
                 newCoe.original_code = libCoe.original_code;
                 newCoe.option_codes = libCoe.option_codes;
+                newCoe.option_list = libCoe.option_list;
                 newCoe.isAdjust=0;
                 newCoe.coes = libCoe.coes;
                 newCoe.rationID = newRation.ID;

+ 1 - 1
public/web/common_ajax.js

@@ -173,7 +173,7 @@ async function ajaxPost(url, data) {
             cache: false,
             timeout: 50000,
             success: function(result){
-                if (result.error === 0) {
+                if (result.error === 0 || result.err ===0) {
                     resolve(result.data);
                 } else {
                     alert('error: ' + result.message);

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

@@ -300,7 +300,7 @@ var sheetCommonObj = {
         //let combo = new GC.Spread.Sheets.CellTypes.ComboBox();
         let dynamicCombo = sheetCommonObj.getDynamicCombo(true);
         if(options){
-            dynamicCombo.itemHeight(options.length).items(options);
+            dynamicCombo.items(options);
             if(editorValueType==true){
                 dynamicCombo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value);
             }

+ 7 - 1
web/building_saas/css/custom.css

@@ -283,7 +283,8 @@ input.text-right{
 }
 
 .cus-width{
-    width: 100%;
+    width: 100px;
+    margin-left: 10px;
 }
 .more{
     padding-left:.25rem!important
@@ -299,4 +300,9 @@ input.text-right{
 
 .zmhs-link{
     padding:0.4em 0.4em !important;
+}
+
+/*修改tooltip默认最大宽度 */
+.tooltip-inner{
+    max-width: 400px !important;
 }

+ 1 - 1
web/building_saas/fee_rates/fee_rate.html

@@ -3,7 +3,7 @@
 <div >
 <div class="toolsbar_feeRate px-1 ">
     <div class="form-inline py-1">
-        <label  class="mx-2" >使用费率文件:<span id="feeRateFileName">费率1</span>(<label class="a_color" id="pop-lv"><span id="projectCount">3</span> 个单位工程使用</label>)
+        <label  class="mx-2" >使用费率文件:<span id="feeRateFileName">费率1</span>(<label class="a_color" id="pop-lv">与<span id="projectCount">3</span> 个单位工程同步</label>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-lv" id="changFeeRateFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" id="saveAs" data-target="#copy-lv"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>

+ 1 - 1
web/building_saas/glj/html/project_glj.html

@@ -5,7 +5,7 @@
 </style>
 <div class="toolsbar px-1" id="projectGljToolsBar">
     <div class="form-inline py-1">
-        <label class="mx-2">使用单价文件:<span id="current-name"></span>(<label class="a_color" id="pop-used-list" data-original-title="" title=""><span id="used-project-count">0</span>个单位工程使用</label>)
+        <label class="mx-2">使用单价文件:<span id="current-name"></span>(<label class="a_color" id="pop-used-list" data-original-title="" title=""><span id="used-project-count">0</span>个单位工程同步</label>)
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#change-unitFile"><i class="fa fa-exchange"></i> 选择其他</a>
             <a class="btn btn-sm ml-1" href="#" data-toggle="modal" data-target="#unitFile-save-as"><i class="fa fa-files-o"></i> 另存单独用</a></label>
     </div>

+ 1 - 0
web/building_saas/main/html/calc_program_manage.html

@@ -14,6 +14,7 @@
     </div>
     <div class="toolsbar px-1" />
     <div class="container-fluid">
+        <div style="height:35px;width:100%;line-height:35px;font-size:15px;">总计算程序-设置</div>
         <div class="row">
             <div class="col-lg-2 p-0">
 <!--                <div id="divSelect" style="text-align:left;height:45px;line-height:45px;">

+ 6 - 6
web/building_saas/main/html/main.html

@@ -7,7 +7,7 @@
     <meta http-equiv="x-ua-compatible" content="ie=edge">
     <title><%= projectData.name !== undefined ? projectData.name : '造价书' %>-纵横建筑云计价</title>
 
-    <!-- inject:css -->
+
     <link rel="stylesheet" href="/lib/jquery-ui/jquery-ui.css" type="text/css">
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/lib/spreadjs/sheets/css/gc.spread.sheets.sc.css" type="text/css">
@@ -24,7 +24,7 @@
     <link rel="stylesheet" href="/lib/spreadjs/views/gc.spread.views.dataview.10.0.0.css">
     <!-- jquery.contextmenu -->
    <!-- <link rel="stylesheet" href="/lib/jquery-contextmenu/jquery.contextMenu.css" type="text/css">-->
-    <!-- endinject -->
+   
     <link rel="shortcut icon" href="/web/building_saas/css/favicon.ico">
     <link rel="icon" type="image/gif" href="/web/building_saas/css/animated_favicon1.gif">
     <style type="text/css">
@@ -70,7 +70,7 @@
                 <li class="nav-item"><a class="active" data-toggle="tab" href="#zaojiashu" id="tab_zaojiashu" role="tab">造价书</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#project_glj" id="tab_project_glj" data-name="tab_project_glj" role="tab">人材机汇总</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#fee_rates" id="tab_fee_rate" role="tab" >费率</a></li>
-                <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab">计算程序</a></li>
+                <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab" style="display:none">计算程序</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#tender_price" id="tab_tender_price" role="tab">调价</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#reports" role="tab" id="tab_report" onclick="rptTplObj.iniPage();">报表</a></li>
             </ul>
@@ -121,6 +121,7 @@
                               <a href="javascript:void(0)"  class="dropdown-item" name="lockBills"> <i class="fa fa-lock" aria-hidden="true"></i> 锁定清单</a>
                               <% } %>
                               <a id="switchTznr" href="javascript:void(0);"  class="dropdown-item"><i class="fa fa-eye" aria-hidden="true"></i> 显示特征</a>
+                              <a id = "menu_calc_program_manage"  href="javascript:void(0);" class="dropdown-item"><i class="fa fa-calculator" aria-hidden="true"></i> 总计算程序</a>
                           </div>
                       </div>
                  <!--   <span class="btn btn-light btn-sm">
@@ -300,12 +301,11 @@
                                                               <option value="3">模板子目分别放在对应混凝土子目下</option>
                                                           </select>
                                                       </div>
-                                                      <div class="col-1">
+                                                      <div class="">
                                                           <button class=" btn btn-primary btn-sm cus-width" type="button" id="apply_mbzm">应用</button>
-                                                      </div>
-                                                      <div class="col-1">
                                                           <button class=" btn btn-primary btn-sm cus-width" type="button" id="next_mbzm">下一条</button>
                                                       </div>
+
                                                   </div>
                                               </div>
                                               <div class=" ovf-hidden" style="" id="mbzmSpread"></div>

+ 46 - 24
web/building_saas/main/js/views/calc_program_manage.js

@@ -6,6 +6,8 @@ let calcProgramManage = {
     datas: [],
     mainSpread: null,
     detailSpread: null,
+    mainSheet: null,
+    detailSheet: null,
     mainSetting: {
         header:[
             // {headerName:"ID",headerWidth:80,dataCode:"ID", hAlign: "center"},
@@ -49,30 +51,30 @@ let calcProgramManage = {
             me.detailSpread = null;
         };
         me.mainSpread = sheetCommonObj.buildSheet($('#mainSpread')[0], me.mainSetting, me.datas.length);
+        me.mainSheet = me.mainSpread.getSheet(0);
         sheetCommonObj.spreadDefaultStyle(me.mainSpread);
         me.detailSpread = sheetCommonObj.buildSheet($('#detailSpread')[0], me.detailSetting, me.datas[0].calcItems.length);
+        me.detailSheet = me.detailSpread.getSheet(0);
         sheetCommonObj.spreadDefaultStyle(me.detailSpread);
         let arr = projectObj.project.calcProgram.compiledFeeTypeNames.slice();
         // arr.delete('暂估费');
         let fieldName = new GC.Spread.Sheets.CellTypes.ComboBox();
         fieldName.items(arr);
-        me.detailSpread.getSheet(0).getRange(-1, 4, -1, 1).cellType(fieldName);
+        me.detailSheet.getRange(-1, 4, -1, 1).cellType(fieldName);
 
-        me.mainSpread.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onMainEnterCell);
-        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.ValueChanged, me.onDetailValueChanged);
-        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
-        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.EnterCell, me.onDetailEnterCell);
-        me.detailSpread.getSheet(0).bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        me.mainSheet.bind(GC.Spread.Sheets.Events.EnterCell, me.onMainEnterCell);
+        me.detailSheet.bind(GC.Spread.Sheets.Events.ValueChanged, me.onDetailValueChanged);
+        me.detailSheet.bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
+        me.detailSheet.bind(GC.Spread.Sheets.Events.EnterCell, me.onDetailEnterCell);
+        me.detailSheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, me.onClipboardPasting);
+        sheetCommonObj.showData(me.mainSheet, me.mainSetting, me.datas);
 
-        let mSheet = me.mainSpread.getSheet(0);
-        sheetCommonObj.showData(mSheet, me.mainSetting, me.datas);
-
-        let dSheet = me.detailSpread.getSheet(0);
-        dSheet.name('calc_detail');
-        feeRateObject.setFeeRateCellCol(dSheet,_.findIndex(me.detailSetting.header,{'dataCode':'feeRate'}));
-        dSheet.getRange(-1, _.findIndex(me.detailSetting.header, {'dataCode': 'dispExprUser'}), -1, 1).cellType(calcBaseView.getCalcBaseCellType('ration'));
-        sheetCommonObj.showData(dSheet, me.detailSetting, me.datas[0].calcItems);
-        customRowHeader(dSheet, me.datas[0].calcItems.length);
+        me.detailSheet.name('calc_detail');
+        feeRateObject.setFeeRateCellCol(me.detailSheet, _.findIndex(me.detailSetting.header,{'dataCode':'feeRate'}));
+        me.detailSheet.getRange(-1, _.findIndex(me.detailSetting.header, {'dataCode': 'dispExprUser'}), -1, 1).cellType(calcBaseView.getCalcBaseCellType('ration'));
+        sheetCommonObj.showData(me.detailSheet, me.detailSetting, me.datas[0].calcItems);
+        me.getfeeRateColor(me.datas[0].calcItems);
+        customRowHeader(me.detailSheet, me.datas[0].calcItems.length);
         if(!projectReadOnly){
             me.loadMainContextMenu();
             me.loadDetailContextMenu();
@@ -109,11 +111,11 @@ let calcProgramManage = {
         var row = args.sheet.getActiveRowIndex();
 
         me.detailSpread.suspendPaint();
-        var dSheet = me.detailSpread.getSheet(0);
         var dData = me.datas[row].calcItems;
-        dSheet.setRowCount(dData.length, GC.Spread.Sheets.SheetArea.viewport);
-        sheetCommonObj.showData(dSheet, me.detailSetting, dData);
-        customRowHeader(dSheet, dData.length);
+        me.detailSheet.setRowCount(dData.length, GC.Spread.Sheets.SheetArea.viewport);
+        sheetCommonObj.showData(me.detailSheet, me.detailSetting, dData);
+        me.getfeeRateColor(dData);
+        customRowHeader(me.detailSheet, dData.length);
         me.detailSpread.resumePaint();
     },
     onRangeChanged:function (sender,args) {
@@ -254,14 +256,20 @@ let calcProgramManage = {
                         newTemplate.custom = true;
                         newTemplate.calcItems = [];
                         $.extend(true, newTemplate.calcItems, template.calcItems);
+                        // 清理掉费率ID关联
+                        for (let ci of newTemplate.calcItems){
+                            if (ci.feeRateID || ci.feeRateID == null)
+                                delete ci.feeRateID;
+                        };
 
                         let data = {
                             'projectID': projectObj.project.ID(),
                             'ID': newTemplate.ID,
                             'name': newTemplate.name,
                             'custom': newTemplate.custom,
-                            'calcItems': template.calcItems
+                            'calcItems': newTemplate.calcItems
                         };
+
                         calcProgramManage.addTemplate(data, function (rst) {
                             if (rst){
                                 let ts = projectObj.project.calcProgram.templates;
@@ -269,11 +277,12 @@ let calcProgramManage = {
                                 projectObj.project.calcProgram.compileTemplateMaps();
                                 projectObj.project.calcProgram.compileTemplate(newTemplate);
                                 calcProgramManage.buildSheet();
-                                calcProgramManage.mainSpread.getActiveSheet().setSelection(ts.length - 1, 0, 1, 1);
+                                calcProgramManage.mainSheet.setSelection(ts.length - 1, 0, 1, 1);
+                                calcProgramManage.mainSheet.showRow(ts.length - 1, GC.Spread.Sheets.VerticalPosition.center);
                                 calcProgramManage.refreshDetailSheet();
+                                $.bootstrapLoading.end();
                             }
                         });
-                        $.bootstrapLoading.end();
                     }
                 },
                 "reNameTemplate": {
@@ -335,6 +344,7 @@ let calcProgramManage = {
                         return !canDelete;
                     },
                     callback: function () {
+                        $.bootstrapLoading.start();
                         let template = calcProgramManage.getSelectionInfo().template;
                         if (analyzer.templateIsUsed(template.ID)) {
                             $.bootstrapLoading.end();
@@ -349,12 +359,14 @@ let calcProgramManage = {
                             };
                             calcProgramManage.deleteTemplate(data, function (rst) {
                                 if (rst){
-                                    let idx = calcProgramManage.mainSpread.getActiveSheet().getActiveRowIndex();
+                                    let idx = calcProgramManage.mainSheet.getActiveRowIndex();
                                     projectObj.project.calcProgram.templates.splice(idx, 1);
                                     projectObj.project.calcProgram.compileTemplateMaps();
                                     calcProgramManage.buildSheet();
-                                    calcProgramManage.mainSpread.getActiveSheet().setSelection(idx - 1, 0, 1, 1);
+                                    calcProgramManage.mainSheet.setSelection(idx - 1, 0, 1, 1);
+                                    calcProgramManage.mainSheet.showRow(idx - 1, GC.Spread.Sheets.VerticalPosition.center);
                                     calcProgramManage.refreshDetailSheet();
+                                    $.bootstrapLoading.end();
                                 }
                             });
                         };
@@ -505,8 +517,18 @@ let calcProgramManage = {
             let detailSheet = me.detailSpread.getActiveSheet();
             detailSheet.setRowCount(calcItems.length);
             sheetCommonObj.showData(detailSheet, me.detailSetting, calcItems);
+            me.getfeeRateColor(calcItems);
             customRowHeader(detailSheet, calcItems.length);
         }
+    },
+    getfeeRateColor: function (calcItems) {    // 有费率ID关联的变个色
+        var me = this;
+        for (let i = 0; i < calcItems.length; i++) {
+            if (calcItems[i].feeRateID != undefined && calcItems[i].feeRateID != null)
+                me.detailSheet.getCell(i, 3).foreColor("#0aa8ea")
+            else
+                me.detailSheet.getCell(i, 3).foreColor("black");
+        }
     }
 };
 

+ 1 - 2
web/building_saas/main/js/views/fee_rate_view.js

@@ -955,7 +955,7 @@ function getPopoverContent() {
     var usageProjects = feeRateFile.usageProjects;
     let names = _.map(usageProjects,'name');
     let popover_content = names.join('<br>');
-    return popover_content;
+    return "费率的变化,将自动影响以下单位工程造价:<br>"+ popover_content;
 }
 
 $(function(){
@@ -1146,4 +1146,3 @@ function changeFRadioClick() {
         $("#fromOther").show();
     }
 }
-

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

@@ -130,7 +130,7 @@ projectGljObject={
         $("#used-project-count").text(usedCount);
     },
     getUsedTenderInfo:function() {
-        return projectGljObject.usedTenderList.join("<br>");
+        return "人材机单价的变化,将自动影响以下单位工程造价:<br>"+projectGljObject.usedTenderList.join("<br>");
     },
     filterLibGLJForMixRatio:function () {
         let me = this;

+ 4 - 0
web/building_saas/main/js/views/project_view.js

@@ -3289,3 +3289,7 @@ $('#calcBaseFeeRateConf').click(function () {
         $('#calcBaseFeeRate').modal('hide');
     }
 });
+
+$('#menu_calc_program_manage').click(function () {
+    $('#tab_calc_program_manage').click();
+});

+ 9 - 4
web/building_saas/main/js/views/zmhs_view.js

@@ -20,7 +20,8 @@ let zmhs_obj = {
         getText:{
             forContent:function (item) {
                if(gljUtil.isDef(item.select_code)&&item.select_code!=""){
-                   return item.select_code;
+                   let option = _.find(item.option_list,{"value":item.select_code})
+                   return option?option.text:item.select_code;
                }else {
                    return item.content;
                }
@@ -28,7 +29,7 @@ let zmhs_obj = {
             }
         },
         autoFit:true,
-        fitRow:['name']
+        fitRow:['name','content']
     },
     cusSpread:null,
     cusSheet:null,
@@ -151,9 +152,12 @@ let zmhs_obj = {
 
     getComboBoxForCodes:function (coe,i) {
         this.coeSheet.getCell(i, 2, GC.Spread.Sheets.SheetArea.viewport).locked(false);
-        let options = coe.option_codes.split("|");
+        let options = coe.option_list; //coe.option_codes.split("|");
         let combo = sheetCommonObj.getDynamicCombo(true);
-        combo.itemHeight(options.length).items(options);
+        let buttonRow =  this.coeSheet.getViewportBottomRow(1);
+        console.log(buttonRow);
+        combo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value);
+        combo.items(options).maxDropDownItems(buttonRow - i -1 < 3 ?3:buttonRow - i -1 );//itemHeight(options.length).
         this.coeSheet.setCellType(i, 2, combo, GC.Spread.Sheets.SheetArea.viewport);
         this.coeSheet.setValue(i, 2, coe.select_code);
 
@@ -230,6 +234,7 @@ let zmhs_obj = {
 
     refresh:function () {
         $('#coeSpread').is(':visible')&&this.coeSpread?this.coeSpread.refresh():'';
+        $('#coeSpread').is(':visible')&&this.coeSpread?this.showDatas():'';//这里combobox下拉框要重新加载一下
         $('#cusSpread').is(':visible')&&this.cusSpread?this.cusSpread.refresh():'';
         $('#assSpread').is(':visible')&&this.assSpread?this.assSpread.refresh():'';
     },

+ 70 - 0
web/building_saas/pm/html/project-management.html

@@ -616,6 +616,76 @@
         </div>
     </div>
 </div>
+
+<!--弹出 批量替换单价文件-->
+<div class="modal fade" id="m_replace_file" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="mr_title">批量替换单价文件</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <input type="hidden" id="mr_from">
+            <div class="modal-body">
+                <div class="row">
+                    <div class="col-6">
+                        <h5>选择项目</h5>
+                        <div class="modal-auto-height">
+                            <div id="replaceSpread" style="height: 100%"></div>
+                        </div>
+                        <div class="custom-control custom-checkbox">
+                            <input type="checkbox" class="custom-control-input" id="customCheck1">
+                            <label class="custom-control-label" for="customCheck1">自动勾选同专业工程</label>
+                        </div>
+                    </div>
+                    <div class="col-6">
+                        <h5>更换为</h5>
+                        <div class="form-group">
+                            <div class="custom-control custom-radio custom-control-inline">
+                                <input type="radio" id="customRadioInline33" name="select_from" value="0" class="custom-control-input" checked>
+                                <label class="custom-control-label" for="customRadioInline33">从本建设项目中选择</label>
+                            </div>
+                            <div class="custom-control custom-radio custom-control-inline">
+                                <input type="radio" id="customRadioInline44" name="select_from" value="1" class="custom-control-input">
+                                <label class="custom-control-label" for="customRadioInline44">从其他建设项目中复制</label>
+                            </div>
+                        </div>
+                        <!--从本建设项目中选择-->
+                        <label id="project_name">9.21<!--本建设项目名称--></label>
+                        <div class="form-group" id = "fromProject">
+                            <select class="form-control" id="currentOptions">
+                                <option>测试5单价文件</option><!--单价文件-->
+                            </select>
+                        </div>
+                        <!--从其他建设项目中复制-->
+                        <div id = "fromOther">
+                            <div class="form-group" >
+                                <label>选择建设项目</label>
+                                <select class="form-control" id="otherProject" >
+                                    <option>10.9建筑例题内测</option><!--建设项目-->
+                                </select>
+                            </div>
+                            <div class="form-group">
+                                <select class="form-control" id="otherFileOptions">
+                                    <option>10.9建筑例题内测单价文件</option><!--建设项目下单价文件-->
+                                </select>
+                                <span class="form-text text-muted">你选择的单价文件将复制一份至新项目,不会影响原建设项目的单价文件。</span>
+                            </div>
+                        </div>
+
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <a href="" class="btn btn-primary mr-3">确定</a>
+            </div>
+        </div>
+    </div>
+</div>
+
 <!--弹出删除 单价/费率 文件-->
 <div class="modal fade" id="del-wj" data-backdrop="static">
     <div class="modal-dialog" role="document">

+ 185 - 11
web/building_saas/pm/js/pm_newMain.js

@@ -55,8 +55,10 @@ const projTreeObj = {
     tree: null,
     workBook: null,
     copyToWorkBook:null,
+    replaceWorkBook:null,
     copySelected:null,
     preSelection: null,
+    changeInfo:null,
     setting: {
         tree: {
             id: 'ID',
@@ -116,7 +118,28 @@ const projTreeObj = {
             allowUserDragFill: false,
             scrollbarMaxAlign : true,
             showDragDropTip:false
-        }},
+        }
+    },
+    replaceSetting:{
+        header: [
+            {name: '工程列表', dataCode: 'name', width: 250, vAlign: 'center', hAlign: 'left'},
+            {name: '选择', dataCode: 'selected', width: 50, vAlign: 'center', cellType:'checkBox'}
+        ],
+        //选中行颜色
+        style: {
+            defalutBackColor: 'White',
+            selectedColor: '#BBFFFF'
+        },
+        options: {
+            tabStripVisible:  false,
+            allowCopyPasteExcelStyle : false,
+            allowExtendPasteRange: false,
+            allowUserDragDrop : false,
+            allowUserDragFill: false,
+            scrollbarMaxAlign : true,
+            showDragDropTip:false
+        }
+    },
     renderSheetFuc: function (sheet, fuc) {
         sheet.suspendPaint();
         sheet.suspendEvent();
@@ -137,6 +160,7 @@ const projTreeObj = {
         sheet.bind(_events.EditStarting, this.onCellEditing);
         sheet.bind(_events.ClipboardPasting,this.onCellEditing);
         workBook.bind(_events.DragDropBlock, this.onDragDropBlock);
+        workBook.bind(GC.Spread.Sheets.Events.ButtonClicked, this.changeFileClick)
     },
     buildHeader: function (sheet, headers) {
         let me = this;
@@ -469,6 +493,14 @@ const projTreeObj = {
         let me = projTreeObj;
         me.initSelection(args.newSelections[0], args.oldSelections[0],args.sheet);
     },
+    changeFileClick:async function (sender,args) {
+        if(args.sheet.name() == "projectSheet"){
+            await projTreeObj.initFileChangePage(projTreeObj.setting.header[args.col].dataCode);
+            $("#mr_from").val(projTreeObj.setting.header[args.col].dataCode);
+            $("#project_name").text(projTreeObj.tree.selected.data.name);
+            $('#m_replace_file').modal('show');
+        }
+    },
     onDragDropBlock : function (sender,args) {//拖动移动项目位置
         let selected = projTreeObj.tree.selected;
         let targetNode = projTreeObj.tree.items[args.toRow];
@@ -834,7 +866,7 @@ const projTreeObj = {
             function withingClickArea(){
                 return hitinfo.x > centerX + halfBoxLength && hitinfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength;
             }
-            if(hitinfo.sheet.name() != "copyToSheet"){//如果是复制到sheet,不用执行
+            if(hitinfo.sheet.name() === "projectSheet"){//只有项目管理界面才执行
                 //单项文件,进入造价书界面
                  if(node.data.projType === projectType.tender && withingClickArea()){
                     let timeoutTime = 200;
@@ -906,10 +938,11 @@ const projTreeObj = {
         }
         return new TreeNodeCellType();
     },
-    setCellValue: function (cell, node,sheet) {
+    setCellValue: function (cell, node,sheet,setting) {
         //const sheet = this.workBook.getActiveSheet();
+        if(!setting) setting = this.setting;
         const {row, col} = cell;
-        let dataCode = this.setting.header[col]['dataCode'];
+        let dataCode = setting.header[col]['dataCode'];
         let value = '';
         if(dataCode === 'unitPriceFile'){
             if(node.data.projType === projectType.tender){
@@ -929,9 +962,10 @@ const projTreeObj = {
         }
         sheet.setValue(row, col, value);
     },
-    showTreeData: function (nodes, headers,sheet) {
+    showTreeData: function (nodes, setting,sheet) {
+        let headers = setting.header;
         let me = this;
-        let tree = sheet.name() == "copyToSheet"?me.copyTree:me.tree;
+        let tree = nodes.length>0?nodes[0].tree:me.tree;//sheet.name() == "copyToSheet"?me.copyTree:me.tree;
         let fuc = function(){
             sheet.setRowCount(0);
             sheet.setRowCount(nodes.length);
@@ -941,8 +975,16 @@ const projTreeObj = {
                 for(let j = 0; j < headers.length; j++){
                     sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
                     sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
-                    me.setCellValue({row: i, col: j}, nodes[i],sheet);
+                    if(headers[j].cellType == "checkBox"){
+                        sheet.setCellType(i, j,new GC.Spread.Sheets.CellTypes.CheckBox(),GC.Spread.Sheets.SheetArea.viewport);
+                        sheet.getCell(i, j).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
+                    }
+                    me.setCellValue({row: i, col: j}, nodes[i],sheet,setting);
                     let dataCode = headers[j].dataCode;
+                    if(nodes[i].data.projType == "Tender" && (dataCode=="feeRateFile" || dataCode == "unitPriceFile")) {
+                        sheet.setCellType(i, j,sheetCommonObj.getSelectButton(headers[j].width),GC.Spread.Sheets.SheetArea.viewport);
+                        sheet.getCell(i, j,GC.Spread.Sheets.SheetArea.viewport).locked(false);
+                    }
                     //sheet.setValue(i, j, nodes[i]['data'][dataCode]);
                 }
                 sheet.getCell(i, 1,GC.Spread.Sheets.SheetArea.viewport).locked(true);
@@ -1015,6 +1057,95 @@ const projTreeObj = {
         }
 
     },
+    initFileChangePage:async function (from) {
+        let title = from == "unitPriceFile" ?"批量替换单价文件":"批量替换费率文件";
+        $("#mr_title").text(title);
+        this.initHtmlByFromRadio();
+        let result = from == "unitPriceFile"?await this.setUnitFileChangeFileData():await this.setFeeRateChangeFileData();
+        console.log(result);
+        this.changeInfo = result;
+        this.loadFileOptions(this.changeInfo,from);
+
+    },
+    setFeeRateChangeFileData:async function(){
+        //userID
+        let node = projTreeObj.tree.selected;
+        let data={"user_id":userID, "projectID":node.data.ID, "rootProjectID":node.data.property.rootProjectID};
+        let result = await ajaxPost("/feeRates/getChangeInfo",data);
+        this.getFileListWithPath(result.others);
+        return result;
+
+    },
+    setUnitFileChangeFileData:async function(){
+        let node = projTreeObj.tree.selected;
+        let data ={"project_id":node.data.ID,"rootProjectID":node.data.property.rootProjectID};
+        let result = await ajaxPost("/glj/get-project-info",data);
+        this.getFileListWithPath(result.other);
+        console.log(result);
+        //数据结构不一样,这里做一下转换
+        let t_result = {
+            currentProject:{
+                ID:node.data.ID,
+                currentOptions:result.self,
+            },
+            others:result.other
+        }
+        return t_result;
+
+
+    },
+
+
+
+    getFileListWithPath:function (list) {
+        for(let n of list){
+            let node = projTreeObj.tree.findNode(n.ID);
+            if(node) n.name = getPathName(node);
+        }
+
+        function getPathName(node) {
+            if(node.parent && node.parent.data){
+                return getPathName(node.parent)+"\\"+node.data.name
+            }else {
+                return node.data?node.data.name:"";
+            }
+        }
+
+    },
+    loadFileOptions:function (data,from) {
+        let idField = "ID",optionField ="optionList";
+        if(from == "unitPriceFile"){
+            idField = 'id';
+            optionField = 'unitPriceList'
+        }
+        $('#currentOptions').empty();
+        for(let c of data.currentProject.currentOptions){
+            var option =  $("<option>").val(c[idField]).text(c.name);
+            $('#currentOptions').append(option);
+        }
+        $('#otherProject').empty();
+        for(let p of data.others){
+            var option =  $("<option>").val(p.ID).text(p.name);
+            $('#otherProject').append(option);
+        }
+        $('#otherFileOptions').empty();
+        if(data.others.length>0){
+            for(let f of data.others[0][optionField]){
+                var option =  $("<option>").val(f[idField]).text(f.name);
+                $('#otherFileOptions').append(option);
+            }
+        }
+    },
+    initHtmlByFromRadio:function () {
+        var radioV= $("input[name='select_from']:checked").val();
+        if(radioV == "0"){
+            $("#fromProject").show();
+            $("#fromOther").hide();
+        } else {
+            $("#fromProject").hide();
+            $("#fromOther").show();
+        }
+    },
     initCopyToSpread:function () {
         let me = this;
         me.copyToWorkBook =  projTreeObj.buildSheet(me.copyToWorkBook,'copyToSpread',me.copyToSetting);
@@ -1026,11 +1157,27 @@ const projTreeObj = {
             datas.push(i.data);
         }
         me.copyTree  = pmTree.createNew(projTreeObj.setting, datas);
-        me.showTreeData(me.copyTree.items, me.copyToSetting.header, sheet);
+        me.showTreeData(me.copyTree.items, me.copyToSetting, sheet);
         me.copySelected = null;
         let initSel = sheet.getSelections()[0] ? sheet.getSelections()[0] : {row: 0, rowCount: 1};
         projTreeObj.initSelection(initSel,null,sheet);
     },
+    initReplaceSpread:function () {
+        let me = this;
+        me.replaceWorkBook =  projTreeObj.buildSheet(me.replaceWorkBook,'replaceSpread',me.replaceSetting);
+        let sheet = me.replaceWorkBook.getActiveSheet();
+        sheet.options.isProtected = true;
+        sheet.name('replaceSheet');
+        let datas = [];
+        for(let i of me.tree.items){
+            datas.push(i.data);
+        }
+        me.replaceTree  = pmTree.createNew(projTreeObj.setting, datas);
+        me.showTreeData(me.replaceTree.items, me.replaceSetting, sheet);
+
+    },
+
+
     insert: function (data, parent, next) {
         let preNode = this.tree.items[this.preSelection.row];
         let node = this.tree.addNodeData(data, parent, next);
@@ -1544,11 +1691,19 @@ $(document).ready(function() {
     });*/
 
     $('#copy-to-dialog').on('shown.bs.modal', function () {
-        console.log('shown copy to ');
         projTreeObj.initCopyToSpread();
        // copytoZTree = ConvertTreeToZtree(projTreeObj.tree, $('#treeDemo2'), null);
     });
 
+    $('#m_replace_file').on('shown.bs.modal', function () {
+        // projTreeObj.tree.selected
+        projTreeObj.initReplaceSpread();
+    });
+    $("input[name='select_from']").each(function(){
+        $(this).click(function(){
+            projTreeObj.initHtmlByFromRadio();
+        });
+    });
     // 复制到操作
     $("#copy-to-confirm").click(function() {
         let originalNode = projTreeObj.tree.selected;
@@ -1651,7 +1806,6 @@ $(document).ready(function() {
         }else {
             $('#taxType_div').show();
         }
-        console.log(taxTypeArray);
     }
 
     function getStdCalcProgramFiles(){
@@ -1730,9 +1884,10 @@ function initProjects(callback) {
             projTreeObj.tree.selected = projTreeObj.tree.items[0];
             projTreeObj.workBook = projTreeObj.buildSheet(projTreeObj.workBook,'projSpread',projTreeObj.setting);
             projTreeObj.workBook.getSheet(0).frozenColumnCount(2);
+            projTreeObj.workBook.getSheet(0).name('projectSheet');
             sheetCommonObj.spreadDefaultStyle(projTreeObj.workBook);
             projTreeObj.sumEngineeringCost();
-            projTreeObj.showTreeData(projTreeObj.tree.items, projTreeObj.setting.header, projTreeObj.workBook.getActiveSheet());
+            projTreeObj.showTreeData(projTreeObj.tree.items, projTreeObj.setting, projTreeObj.workBook.getActiveSheet());
             //初始选择
             let initSel = projTreeObj.workBook.getSheet(0).getSelections()[0] ? projTreeObj.workBook.getSheet(0).getSelections()[0] : {row: 0, rowCount: 1};
             projTreeObj.initSelection(initSel,null,projTreeObj.workBook.getActiveSheet());
@@ -3434,6 +3589,25 @@ $('#share-confirm').click(function(){
     }
 });*/
 
+//批量替换文件,切换建设项目
+$('#otherProject').change(function(){
+    let optionList = [],idField = 'ID';
+    var newVal = $(this).val();
+    var projects = projTreeObj.changeInfo.others;
+    var selected = _.find(projects,{ID:parseInt(newVal)});
+    if($("#mr_from").val() =="unitPriceFile"){
+        idField = 'id';
+        optionList = selected.unitPriceList;
+    }else {
+        optionList =  selected.optionList;
+    }
+    $('#otherFileOptions').empty();
+    for(let f of optionList){
+        let option =  $("<option>").val(f[idField]).text(f.name);
+        $('#otherFileOptions').append(option);
+    }
+});
+
 //分享给...界面确认
 $('#shareToConfirm').click(function () {
     let selected = projTreeObj.tree.selected;

+ 1 - 1
web/common/html/header.html

@@ -2,7 +2,7 @@
     <% if(controller === 'boot' || controller === 'pm'){ %>
     <!--<a style="text-decoration: none" href="javascript:void(0);" class="header-logo">-->
     <% }else { %>
-    <div class="mx-2"><a href="/pm" class="btn btn-sm" data-toggle="tooltip" title="返回"><i class="fa fa-angle-left" style="font-size:24px"></i></a></div>
+    <div class="mx-2"><a href="/pm" class="btn btn-sm" data-toggle="tooltip" title="返回项目管理"><i class="fa fa-angle-left" style="font-size:24px"></i></a></div>
         <!--<a style="text-decoration: none" href="/pm" class="header-logo">-->
     <% } %>
     <div class="header-logo">