Browse Source

指标对比代码第二部分

MaiXinRong 7 years ago
parent
commit
415992151d

+ 32 - 3
app/controller/compare_controller.js

@@ -24,9 +24,38 @@ module.exports = app => {
             };
             await this.layout('compare/index.ejs', renderData, 'compare/modal.ejs');
         }
-        // async search (ctx) {
-        //     const
-        // }
+        async search (ctx) {
+            //console.log('start' + new Date());
+            const responseData = {
+                err: 0,
+                msg: '',
+                data: [],
+            };
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                const tenders = data.tenders;
+                for (const tender of tenders) {
+                    if (!tender.lib_id) {
+                        throw '查询的标段有误或不存在';
+                    }
+                    tender.data = await ctx.service.tenderNode.search(tender.lib_id, data.keyword);
+                    for (const n of tender.data) {
+                        const condition = {
+                            lib_id: tender.lib_id,
+                            node_id: n.node_id,
+                        }
+                        n.children = await ctx.service.tenderIndex.getAllDataByCondition({where: condition});
+                    }
+                }
+                responseData.data = tenders;
+            } catch (err) {
+                responseData.err = 1;
+                responseData.msg = err.toString();
+            }
+
+            //console.log('end' + new Date());
+            ctx.body = responseData;
+        }
     }
 
     return CompareController;

+ 4 - 1
app/public/css/main.css

@@ -21,9 +21,12 @@ body {
   overflow-y: auto;
 }
 .sjs-bottom-2{
-  height:360px;
   overflow-y: auto;
 }
+.sjs-bottom-4
+{
+  height:360px
+}
 .form-signin {
     max-width: 500px;
     margin: 150px auto;

+ 176 - 35
app/public/js/compare.js

@@ -21,8 +21,8 @@ $(document).ready(function () {
             this.spread.options.allowUserDragDrop = false;
 
             this.sheet = this.spread.getActiveSheet();
-            this.sheet.options.rowHeaderVisible = false;
-            this.sheet.options.colHeaderVisible = false;
+            //this.sheet.options.rowHeaderVisible = false;
+            //this.sheet.options.colHeaderVisible = false;
 
             this.borderLine = new spreadNS.LineBorder('black', spreadNS.LineStyle.thin);
             this.paperSize = new spreadNS.Print.PaperSize(spreadNS.Print.PaperKind.a4);
@@ -30,60 +30,181 @@ $(document).ready(function () {
             this.initCompareHeader([]);
         }
         initCompareHeader (tenders) {
-            //this.sheet.clear(0, 0, this.sheet.getRowCount(), this.sheet.getColumnCount(), spreadNS.SheetArea.viewport, spreadNS.StorageType.data);
             this.tenders = tenders;
+            const cols = {}, colsName = [];
             const indexColCount = this.tenders.length > 0 ? this.tenders.length + 1 : 0;
+
+            SpreadJsObj.beginMassOperationSheet(this.sheet);
+
+            const spans = this.sheet.getSpans();
+            for (const span of spans) {
+                this.sheet.removeSpan(span.row, span.col);
+            }
             this.sheet.setColumnCount(6 + indexColCount);
             this.sheet.setRowCount(2);
+            this.sheet.frozenRowCount(2);
 
             const hCenter = spreadNS.HorizontalAlign.center;
             const vCenter = spreadNS.VerticalAlign.center;
 
-            this.sheet.getCell(0, 0).text('指标编号').hAlign(hCenter).vAlign(vCenter);
-            this.sheet.addSpan(0, 0, 2, 1);
-            this.sheet.setColumnWidth(0, 120);
+            colsName.push('code');
+            cols.code = 0;
+            this.sheet.getCell(0, cols.code).text('指标编号').hAlign(hCenter).vAlign(vCenter);
+            this.sheet.addSpan(0, cols.code, 2, 1);
+            this.sheet.setColumnWidth(cols.code, 100);
 
-            this.sheet.getCell(0, 1).text('项目或费用名称').hAlign(hCenter).vAlign(vCenter);
-            this.sheet.addSpan(0, 1, 2, 1);
-            this.sheet.setColumnWidth(1, 200);
+            colsName.push('name');
+            cols.name = 1;
+            this.sheet.getCell(0, cols.name).text('项目或费用名称').hAlign(hCenter).vAlign(vCenter);
+            this.sheet.addSpan(0, cols.name, 2, 1);
+            this.sheet.setColumnWidth(cols.name, 220);
 
-            this.sheet.getCell(0, 2).text('指标单位').hAlign(hCenter).vAlign(vCenter);
-            this.sheet.addSpan(0, 2, 2, 2);
-            this.sheet.setColumnWidth(2, 50);
-            this.sheet.setColumnWidth(3, 50);
+            colsName.push('unit1');
+            cols.unit1 = 2;
+            colsName.push('unit2');
+            cols.unit2 = 3;
+            this.sheet.getCell(0, cols.unit1).text('指标单位').hAlign(hCenter).vAlign(vCenter);
+            this.sheet.addSpan(0, cols.unit1, 2, 2);
+            this.sheet.setColumnWidth(cols.unit1, 60);
+            this.sheet.setColumnWidth(cols.unit2, 60);
 
             if (this.tenders.length > 0) {
-                this.sheet.getCell(0, 4).text('经济指标').hAlign(hCenter).vAlign(vCenter);
-                this.sheet.removeSpan(0, 4, spreadNS.SheetArea.viewport);
-                this.sheet.addSpan(0, 4, 1, this.tenders.length);
+                this.sheet.getCell(0, cols.unit2+1).text('经济指标').hAlign(hCenter).vAlign(vCenter);
+                //this.sheet.removeSpan(0, cols.unit2+1, spreadNS.SheetArea.viewport);
+                this.sheet.addSpan(0, cols.unit2+1, 1, this.tenders.length);
                 for (let i = 0, iLen = this.tenders.length; i < iLen; i++) {
-                    this.sheet.getCell(1, 4+i).text(tenders[i].filename).hAlign(hCenter).vAlign(vCenter);
-                    this.sheet.setColumnWidth(4+i, 100);
+                    colsName.push('lib_' + this.tenders[i].lib_id);
+                    cols['lib_' + this.tenders[i].lib_id] = 4+i;
+                    this.sheet.getCell(1, cols['lib_' + this.tenders[i].lib_id])
+                        .text(this.tenders[i].filename).hAlign(hCenter).vAlign(vCenter);
+                    this.sheet.setColumnWidth(cols['lib_' + this.tenders[i].lib_id], 100);
                 }
-                this.sheet.getCell(0, 4+this.tenders.length).text('平均指标').hAlign(hCenter).vAlign(vCenter);
-                this.sheet.removeSpan(0, 4+this.tenders.length, spreadNS.SheetArea.viewport);
-                this.sheet.addSpan(0, 4+this.tenders.length, 2, 1);
-                this.sheet.setColumnWidth(4+this.tenders.length, 100);
+
+                colsName.push('averageIndex');
+                cols.averageIndex = 4+this.tenders.length;
+                this.sheet.getCell(0, cols.averageIndex).text('平均指标').hAlign(hCenter).vAlign(vCenter);
+                //this.sheet.removeSpan(0, cols.averageIndex, spreadNS.SheetArea.viewport);
+                this.sheet.addSpan(0, cols.averageIndex, 2, 1);
+                this.sheet.setColumnWidth(cols.averageIndex, 100);
             }
 
-            this.sheet.getCell(0, 4 + indexColCount).text('计算规则').hAlign(hCenter).vAlign(vCenter);
-            this.sheet.addSpan(0, 4 + indexColCount, 2, 1);
-            this.sheet.setColumnWidth(4 + indexColCount, 300);
+            colsName.push('rule');
+            cols.rule = 4+indexColCount;
+            this.sheet.getCell(0, cols.rule).text('计算规则').hAlign(hCenter).vAlign(vCenter);
+            this.sheet.addSpan(0, cols.rule, 2, 1);
+            this.sheet.setColumnWidth(cols.rule, 300);
+
+            colsName.push('memo');
+            cols.memo = 5+indexColCount;
+            this.sheet.getCell(0, cols.memo).text('备注').hAlign(hCenter).vAlign(vCenter);
+            this.sheet.addSpan(0, cols.memo, 2, 1);
+            this.sheet.setColumnWidth(cols.memo, 100);
 
-            this.sheet.getCell(0, 5 + indexColCount).text('备注').hAlign(hCenter).vAlign(vCenter);
-            this.sheet.addSpan(0, 5 + indexColCount, 2, 1);
-            this.sheet.setColumnWidth(5 + indexColCount, 100);
+            this.colsName = colsName;
+            this.cols = cols;
+            //this.sheet.getRange(-1, -1, this.sheet.getRowCount(), this.sheet.getColumnCount()).setBorder(this.borderLine, {all: true});
 
-            this.sheet.getRange(0, 0, this.sheet.getRowCount(), this.sheet.getColumnCount()).setBorder(this.borderLine, {all: true});
+            SpreadJsObj.endMassOperationSheet(this.sheet);
         }
         sortData (data) {
+            console.log(data);
+            function findTenderData (data, tenderId) {
+                for (const tender of data) {
+                    if (tender.lib_id === tenderId) {
+                        return tender.data;
+                    }
+                }
+                return null;
+            }
+            function findNode(data, src, tenderId) {
+                for (const node of data) {
+                    const field = 'bills_id' + tenderId;
+                    if (node.code === src.code && node.name === src.name && node[field] === src[field]) {
+                        return node;
+                    }
+                }
+                return null;
+            }
+            function findIndex(data, src) {
+                for (const index of data) {
+                    if (index.code === src.code && index.name === src.name) {
+                        return index;
+                    }
+                }
+                return null;
+            }
             const result = [];
+            for (const tender of this.tenders) {
+                const searchData = findTenderData(data, tender.lib_id);
+                for (const node of searchData) {
+                    let sortNode = findNode(result, node, tender.lib_id);
+                    if (!sortNode) {
+                        sortNode = {
+                            code: node.code,
+                            name: node.name,
+                            indexes: [],
+                        };
+                        result.push(sortNode);
+                    }
+                    sortNode['bills_id' + tender.lib_id] = node.bills_id;
+                    for (const index of node.children) {
+                        let sortIndex = findIndex(sortNode.indexes, index);
+                        if (!sortIndex) {
+                            sortIndex = {
+                                code: index.code,
+                                name: index.name,
+                                unit1: index.unit1,
+                                unit2: index.unit2,
+                                sumValue: 0,
+                                rule: index.rule,
+                                memo: index.memo,
+                            };
+                            sortNode.indexes.push(sortIndex)
+                        }
+                        sortIndex['lib_' + tender.lib_id] = index.value;
+                        sortIndex.sumValue += index.value;
+                    }
+                }
+            }
+            console.log(result);
             return result;
         }
         loadData (data) {
+            const self = this;
             this.searchData = data;
-            const showData = this.sortData(this.searchData);
-
+            this.showData = this.sortData(this.searchData);
+            console.log(new Date());
+            function loadNode (node, row) {
+                self.sheet.getCell(row, self.cols.code).text(node.code);
+                self.sheet.getCell(row, self.cols.name).text(node.name);
+                self.sheet.getRange(row, -1, 1, -1).backColor('#dae5ee');
+            }
+            function loadIndex(index, row) {
+                for (const colName of self.colsName) {
+                    if (colName === 'averageIndex') {
+                        const aver = Number((index.sumValue / self.tenders.length).toFixed(2));
+                        self.sheet.getCell(row, self.cols[colName]).value(aver);
+                    } else if (index[colName]) {
+                        self.sheet.getCell(row, self.cols[colName]).value(index[colName]);
+                    }
+                }
+            }
+            let iRow = 2;
+            SpreadJsObj.massOperationSheet(this.sheet, function () {
+                self.sheet.setRowCount(2);
+                for (const node of self.showData) {
+                    self.sheet.addRows(iRow, 1);
+                    loadNode(node, iRow);
+                    iRow += 1;
+                    for (const index of node.indexes) {
+                        self.sheet.addRows(iRow, 1);
+                        loadIndex(index, iRow);
+                        iRow += 1;
+                    }
+                }
+                //self.sheet.getRange(-1, -1, self.sheet.getRowCount(), self.sheet.getColumnCount()).setBorder(self.borderLine, {all: true});
+            });
+            console.log(new Date());
         }
         searchIndex (keyword) {
             const self = this;
@@ -91,9 +212,11 @@ $(document).ready(function () {
                 tenders: this.tenders,
                 keyword: keyword,
             };
-            // postData('/compare/search', data, function (datas) {
-            //     self.loadData(datas);
-            // });
+            console.log(new Date());
+            postData('/compare/search', data, function (datas) {
+                console.log(new Date());
+                self.loadData(datas);
+            });
         }
     }
     const compareObj = new CompareObj($('#compare-spread')[0]);
@@ -107,10 +230,15 @@ $(document).ready(function () {
                 filename: $('td:first', $(select[i])).text(),
             });
         }
+        $('a[href="#generate-data"]').text('造价文件: ' + tender.length);
         compareObj.initCompareHeader(tender);
         $('#generate-data').modal('hide');
     });
 
+    $('#search').click(function () {
+        compareObj.searchIndex($('#keyword').val());
+    })
+
     // $.contextMenu({
     //     selector: '#compare-spread',
     //     build: function ($trigger, e) {
@@ -124,13 +252,26 @@ $(document).ready(function () {
     //             callback: function (key, opt) {
     //                 const printInfo = new spreadNS.Print.PrintInfo();
     //                 printInfo.showBorder(false);
+    //                 printInfo.showGridLine(false);
     //                 printInfo.paperSize(compareObj.paperSize);
     //                 printInfo.orientation(spreadNS.Print.PrintPageOrientation.landscape);
-    //                 printInfo.qualityFactor(6);
+    //                 printInfo.margin({top:20, bottom:20, left:20, right:20, header:10, footer:20});
+    //                 //printInfo.qualityFactor(6);
     //                 compareObj.sheet.printInfo(printInfo);
     //                 compareObj.spread.print();
     //             }
     //         },
+    //         'exportExcel': {
+    //             name: '导出excel',
+    //             callback: function (key, opt) {
+    //                 const excelIo = new GC.Spread.Excel.IO();
+    //                 const fileName = 'e:\\1.xlsx';
+    //                 const sJson = JSON.stringify(compareObj.spread.toJSON());
+    //                 excelIo.save(sJson, function(blob) {
+    //                     saveAs(blob, fileName);
+    //                 });
+    //             }
+    //         }
     //     }
     // });
 });

+ 2 - 1
app/public/js/global.js

@@ -3,8 +3,9 @@ function autoFlashHeight(){
     var cHeader = $(".c-header").height();
     var toptitle = $(".top-title").height();
     var bottomtitle = $(".bottom-title").height();
+    var sjsbottom = $(".sjs-bottom-2").height();
     $(".sjs-height-1").height($(window).height()-cHeader-160);
-    $(".sjs-height-3").height($(window).height()-cHeader-toptitle-bottomtitle-552);
+    $(".sjs-height-3").height($(window).height()-cHeader-toptitle-bottomtitle-sjsbottom-192);
 };
 $(window).resize(autoFlashHeight);
 /*全局自适应高度结束*/

+ 13 - 1
app/public/js/lib_detail.js

@@ -116,5 +116,17 @@ $(document).ready(function() {
                 self.val(self.attr('data-old-value'));
             });
         }
-    })
+    });
+
+    $('#param-visible').click(function () {
+        if (this.innerHTML === '展开') {
+            this.innerHTML = '收起';
+            $('.sjs-bottom-4').show();
+            autoFlashHeight();
+        } else {
+            this.innerHTML = '展开';
+            $('.sjs-bottom-4').hide();
+            autoFlashHeight();
+        }
+    });
 });

+ 8 - 0
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -37,6 +37,14 @@ const SpreadJsObj = {
         sheet.options.protectionOptions = option;
         sheet.options.isProtected = true;
     },
+    beginMassOperationSheet: function (sheet) {
+        sheet.suspendPaint();
+        sheet.suspendEvent();
+    },
+    endMassOperationSheet: function (sheet) {
+        sheet.resumeEvent();
+        sheet.resumePaint();
+    },
     /**
      * sheet批量操作优化(sheet操作大批量数据时, 屏蔽数据刷新, 可优化大量时间)
      * @param {GC.Spread.Sheets.Worksheet} sheet

+ 1 - 0
app/router.js

@@ -34,4 +34,5 @@ module.exports = app => {
 
     // 指标对比
     app.get('/compare', sessionAuth, 'compareController.index');
+    app.post('/compare/search', sessionAuth, 'compareController.search');
 };

+ 7 - 0
app/service/tender_node.js

@@ -21,6 +21,13 @@ module.exports = app => {
             this.tableName = 'tender_node';
         }
 
+        async search (tenderId, keyword) {
+            const searchKey = '%' + keyword + '%';
+            const sql = 'Select * From ??' +
+                '  where `lib_id` = ' + tenderId + ' and (`name` like ? or code like ?)';
+            const sqlParam = [this.tableName, searchKey, searchKey];
+            return await this.db.query(sql, sqlParam);
+        }
     };
 
     return TenderNode;

+ 5 - 7
app/view/compare/index.ejs

@@ -2,13 +2,13 @@
     <div class="panel-title fluid">
         <div class="title-main">
             <div class="btn-group">
-                <a class="btn btn-primary btn-sm" href="#generate-data" data-toggle="modal" data-target="#generate-data">造价文件:<%= libList.length %></a>
+                <a class="btn btn-primary btn-sm" href="#generate-data" data-toggle="modal" data-target="#generate-data">造价文件:0</a>
             </div>
             <div class="btn-group col-2 pr-0">
-                <input type="text" class="form-control form-control-sm m-0" placeholder="输入指标节点编号或者名称" >
+                <input type="text" class="form-control form-control-sm m-0" placeholder="输入指标节点编号或者名称" id="keyword">
             </div>
             <div class="btn-group">
-                <button class="btn btn-sm btn-primary " type="button">搜索</button>
+                <button class="btn btn-sm btn-primary " type="button" id="search">搜索</button>
             </div>
         </div>
     </div>
@@ -16,16 +16,14 @@
         <div class="c-header p-0 col-12">
         </div>
         <div class="c-body">
-            <div class="sjs-height-1" id="compare-spread">
+            <div class="sjs-height-1" id="compare-spread" style="overflow:hidden; border: 1px solid gray;">
             </div>
         </div>
     </div>
 </div>
-<style type="text/css" media="print">
-    @page { size: landscape; }
-</style>
 <script src="/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
 <script src="/public/js/spreadjs/sheets/pluggable/gc.spread.sheets.print.10.0.1.min.js"></script>
+<script src="/public/js/spreadjs/sheets/interop/gc.spread.excelio.10.0.1.min.js"></script>
 <script>
     GC.Spread.Sheets.LicenseKey = "559432293813965#A0y3iTOzEDOzkjMyMDN9UTNiojIklkI1pjIEJCLi4TPB9mM5AFNTd4cvZ7SaJUVy3CWKtWYXx4VVhjMpp7dYNGdx2ia9sEVlZGOTh7NRlTUwkWR9wEV4gmbjBDZ4ElR8N7cGdHVvEWVBtCOwIGW0ZmeYVWVr3mI0IyUiwCMzETN8kzNzYTM0IicfJye&Qf35VfiEzRwEkI0IyQiwiIwEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsIyNyMzM5ADI5ADNwcTMwIjI0ICdyNkIsIibj9SbvNmL4N7bjRnch56ciojIz5GRiwiI8+Y9sWY9QmZ0Jyp96uL9v6L0wap9biY9qiq95q197Wr9g+89iojIh94Wiqi";
 </script>

+ 1 - 1
app/view/compare/modal.ejs

@@ -19,7 +19,7 @@
                 </div>
             </div>
             <div class="modal-footer">
-                <button class="btn btn-primary" id="generate-ok">生成对比结果</button>
+                <button class="btn btn-primary" id="generate-ok">确定</button>
                 <button class="btn btn-secondary" data-dismiss="modal" aria-hidden="true">取消</button>
             </div>
         </div>

+ 14 - 12
app/view/lib/detail.ejs

@@ -51,20 +51,22 @@
                     <!--bottom-->
                     <div>
                         <div class="bottom-title mt-3">
-                            <h5>填写参数</h5>
+                            <h5 class="d-flex justify-content-between">填写参数 <a href="javascript:void(0)" id="param-visible">展开</a></h5>
                         </div>
                         <div class="sjs-bottom-2">
-                            <!--本节点参数-->
-                            <table class="table table-bordered table-sm table-hover">
-                                <thead>
-                                <tr><th colspan="4" class="text-center"><span id="codeName"></span> 参数</th></tr>
-                                <tr>
-                                    <th>参数名称</th><th>绑定分项节点</th><th>参数数值</th>
-                                </tr>
-                                </thead>
-                                <tbody id="paramList">
-                                </tbody>
-                            </table>
+                            <div class="sjs-bottom-4" style="display:none">
+                                <!--本节点参数-->
+                                <table class="table table-bordered table-sm table-hover">
+                                    <thead>
+                                    <tr><th colspan="4" class="text-center"><span id="codeName"></span> 参数</th></tr>
+                                    <tr>
+                                        <th>参数名称</th><th>绑定分项节点</th><th>参数数值</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody id="paramList">
+                                    </tbody>
+                                </table>
+                            </div>
                         </div>
                     </div>
                 </div>

+ 21 - 0
test/app/service/tender_node.test.js

@@ -0,0 +1,21 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2018/5/16
+ * @version
+ */
+
+const { app, assert } = require('egg-mock/bootstrap');
+
+describe('test/app/service/tender_node.test.js', () => {
+    it('test search', function* () {
+        const ctx = app.mockContext();
+        const result = yield ctx.service.tenderNode.search(43, '第一');
+        assert(result.length === 2);
+        assert((result[0].name.indexOf('第一') > -1) || (result[0].name.indexOf('第一') > -1));
+        assert((result[1].name.indexOf('第一') > -1) || (result[1].name.indexOf('第一') > -1));
+    });
+})