|  | @@ -1532,159 +1532,6 @@ $(document).ready(() => {
 | 
	
		
			
				|  |  |          $('#row-view').modal('hide');
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    class SearchLedger {
 | 
	
		
			
				|  |  | -        constructor(obj, mainSpread) {
 | 
	
		
			
				|  |  | -            const self = this;
 | 
	
		
			
				|  |  | -            this.obj = obj;
 | 
	
		
			
				|  |  | -            this.mainSpread = mainSpread;
 | 
	
		
			
				|  |  | -            this.spreadSetting = {
 | 
	
		
			
				|  |  | -                cols: [
 | 
	
		
			
				|  |  | -                    {title: '项目节编号', field: 'code', hAlign: 0, width: 120, formatter: '@'},
 | 
	
		
			
				|  |  | -                    {title: '清单编号', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
 | 
	
		
			
				|  |  | -                    {title: '名称', field: 'name', width: 150, hAlign: 0, formatter: '@'},
 | 
	
		
			
				|  |  | -                    {title: '单位', field: 'unit', width: 50, hAlign: 1, formatter: '@'},
 | 
	
		
			
				|  |  | -                    {title: '单价', field: 'unit_price', hAlign: 2, width: 50},
 | 
	
		
			
				|  |  | -                    {title: '数量', field: 'quantity', hAlign: 2, width: 50},
 | 
	
		
			
				|  |  | -                    {title: '完成率(%)', field: 'complete_percent', hAlign: 2, width: 70},
 | 
	
		
			
				|  |  | -                ],
 | 
	
		
			
				|  |  | -                emptyRows: 0,
 | 
	
		
			
				|  |  | -                headRows: 1,
 | 
	
		
			
				|  |  | -                headRowHeight: [32],
 | 
	
		
			
				|  |  | -                defaultRowHeight: 21,
 | 
	
		
			
				|  |  | -                headerFont: '12px 微软雅黑',
 | 
	
		
			
				|  |  | -                font: '12px 微软雅黑',
 | 
	
		
			
				|  |  | -                readOnly: true,
 | 
	
		
			
				|  |  | -                selectedBackColor: '#fffacd',
 | 
	
		
			
				|  |  | -            };
 | 
	
		
			
				|  |  | -            this.spread = SpreadJsObj.createNewSpread($('#search-result', this.obj)[0]);
 | 
	
		
			
				|  |  | -            SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting);
 | 
	
		
			
				|  |  | -            $('#keyword', this.obj).bind('keydown', function(e) {
 | 
	
		
			
				|  |  | -                if (e.keyCode == 13) self.searchText();
 | 
	
		
			
				|  |  | -            });
 | 
	
		
			
				|  |  | -            $('#searchLedger', this.obj).bind('click', () => {self.searchText()});
 | 
	
		
			
				|  |  | -            $('#over', this.obj).bind('change', () => {self.searchOver()});
 | 
	
		
			
				|  |  | -            $('#empty', this.obj).bind('change', () => {self.searchLess()});
 | 
	
		
			
				|  |  | -            this.spread.getActiveSheet().bind(GC.Spread.Sheets.Events.CellDoubleClick, function (e, info) {
 | 
	
		
			
				|  |  | -                const sheet = info.sheet;
 | 
	
		
			
				|  |  | -                const data = sheet.zh_data;
 | 
	
		
			
				|  |  | -                if (!data) { return }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                const curBills = data[info.row];
 | 
	
		
			
				|  |  | -                if (!curBills) { return }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                SpreadJsObj.locateTreeNode(self.mainSpread.getActiveSheet(), curBills.ledger_id, true);
 | 
	
		
			
				|  |  | -                stagePosSpreadObj.loadCurPosData();
 | 
	
		
			
				|  |  | -            });
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        calculateCompletePercent() {
 | 
	
		
			
				|  |  | -            if (!this.searchResult) return;
 | 
	
		
			
				|  |  | -            for (const sr of this.searchResult) {
 | 
	
		
			
				|  |  | -                const base = ZhCalc.add(sr.total_price, sr.end_qc_tp);
 | 
	
		
			
				|  |  | -                sr.complete_percent = base !== 0 ? ZhCalc.mul(ZhCalc.div(sr.end_gather_tp, base), 100, 2) : 0;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        searchText() {
 | 
	
		
			
				|  |  | -            const keyword = $('#keyword', this.obj).val();
 | 
	
		
			
				|  |  | -            if (keyword !== '') {
 | 
	
		
			
				|  |  | -                $('#over', this.obj)[0].checked = false;
 | 
	
		
			
				|  |  | -                $('#empty', this.obj)[0].checked = false;
 | 
	
		
			
				|  |  | -                this.searchResult = [];
 | 
	
		
			
				|  |  | -                const sortData = SpreadJsObj.getSortData(this.mainSpread.getActiveSheet());
 | 
	
		
			
				|  |  | -                for (const node of sortData) {
 | 
	
		
			
				|  |  | -                    if ((node.code && node.code.indexOf(keyword) > -1) ||
 | 
	
		
			
				|  |  | -                        node.b_code && node.b_code.indexOf(keyword) > -1 ||
 | 
	
		
			
				|  |  | -                        node.name && node.name.indexOf(keyword) > -1) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                this.calculateCompletePercent();
 | 
	
		
			
				|  |  | -                SpreadJsObj.loadSheetData(this.spread.getActiveSheet(), 'data', this.searchResult);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        searchOver() {
 | 
	
		
			
				|  |  | -            this.searchResult = [];
 | 
	
		
			
				|  |  | -            const sortData = SpreadJsObj.getSortData(this.mainSpread.getActiveSheet());
 | 
	
		
			
				|  |  | -            const checkPosOver = function (bills) {
 | 
	
		
			
				|  |  | -                const posRange = stagePos.ledgerPos[itemsPre + bills.id] || [];
 | 
	
		
			
				|  |  | -                if (posRange.length > 0) {
 | 
	
		
			
				|  |  | -                    for (const p of posRange) {
 | 
	
		
			
				|  |  | -                        if (p.end_contract_qty > p.quantity) return true;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                return false;
 | 
	
		
			
				|  |  | -            };
 | 
	
		
			
				|  |  | -            for (const node of sortData) {
 | 
	
		
			
				|  |  | -                if (node.children && node.children.length > 0) continue;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                if (checkPosOver(node)) {
 | 
	
		
			
				|  |  | -                    const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                    data.visible = true;
 | 
	
		
			
				|  |  | -                    this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                } else if (node.end_gather_qty) {
 | 
	
		
			
				|  |  | -                    if (!node.quantity || Math.abs(node.end_gather_qty) > Math.abs(ZhCalc.add(node.quantity, node.end_qc_qty))) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                } else if (node.end_gather_tp) {
 | 
	
		
			
				|  |  | -                    if (!node.total_price || Math.abs(node.end_gather_tp) > Math.abs(ZhCalc.add(node.total_price, node.end_qc_tp))) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            this.calculateCompletePercent();
 | 
	
		
			
				|  |  | -            SpreadJsObj.loadSheetData(this.spread.getActiveSheet(), 'data', this.searchResult);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        searchEmpty() {
 | 
	
		
			
				|  |  | -            this.searchResult = [];
 | 
	
		
			
				|  |  | -            const sortData = SpreadJsObj.getSortData(this.mainSpread.getActiveSheet());
 | 
	
		
			
				|  |  | -            for (const node of sortData) {
 | 
	
		
			
				|  |  | -                if (node.children && node.children.length > 0) continue;
 | 
	
		
			
				|  |  | -                if (node.quantity) {
 | 
	
		
			
				|  |  | -                    if (!node.end_gather_qty || checkZero(node.end_gather_qty)) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                } else if (node.total_price) {
 | 
	
		
			
				|  |  | -                    if (!node.end_gather_tp || checkZero(node.end_gather_tp)) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            this.calculateCompletePercent();
 | 
	
		
			
				|  |  | -            SpreadJsObj.loadSheetData(this.spread.getActiveSheet(), 'data', this.searchResult);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        searchLess() {
 | 
	
		
			
				|  |  | -            this.searchResult = [];
 | 
	
		
			
				|  |  | -            const sortData = SpreadJsObj.getSortData(this.mainSpread.getActiveSheet());
 | 
	
		
			
				|  |  | -            for (const node of sortData) {
 | 
	
		
			
				|  |  | -                if (node.children && node.children.length > 0) continue;
 | 
	
		
			
				|  |  | -                if (node.quantity) {
 | 
	
		
			
				|  |  | -                    if (ZhCalc.sub(ZhCalc.add(node.quantity, node.end_qc_qty), node.end_gather_qty) > 0) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                } else if (node.total_price) {
 | 
	
		
			
				|  |  | -                    if (ZhCalc.sub(ZhCalc.add(node.total_price, node.end_qc_tp), node.end_gather_tp) > 0) {
 | 
	
		
			
				|  |  | -                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | -                        data.visible = true;
 | 
	
		
			
				|  |  | -                        this.searchResult.push(data);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            this.calculateCompletePercent();
 | 
	
		
			
				|  |  | -            SpreadJsObj.loadSheetData(this.spread.getActiveSheet(), 'data', this.searchResult);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      const posSearch = (function () {
 | 
	
		
			
				|  |  |          let resultArr = [];
 | 
	
		
			
				|  |  |          const search = function () {
 | 
	
	
		
			
				|  | @@ -2698,7 +2545,61 @@ $(document).ready(() => {
 | 
	
		
			
				|  |  |              tabPanel.addClass('active');
 | 
	
		
			
				|  |  |              showTools(tab.hasClass('active'));
 | 
	
		
			
				|  |  |              if (tab.attr('content') === '#search' && !searchLedger) {
 | 
	
		
			
				|  |  | -                searchLedger = new SearchLedger($('#search'), slSpread);
 | 
	
		
			
				|  |  | +                searchLedger = $.billsSearch({
 | 
	
		
			
				|  |  | +                    selector: '#search',
 | 
	
		
			
				|  |  | +                    searchSpread: slSpread,
 | 
	
		
			
				|  |  | +                    searchRangeStr: '项目节编号/名称',
 | 
	
		
			
				|  |  | +                    searchOver: true,
 | 
	
		
			
				|  |  | +                    searchEmpty: true,
 | 
	
		
			
				|  |  | +                    resultSpreadSetting: {
 | 
	
		
			
				|  |  | +                        cols: [
 | 
	
		
			
				|  |  | +                            {title: '项目节编号', field: 'code', hAlign: 0, width: 120, formatter: '@'},
 | 
	
		
			
				|  |  | +                            {title: '清单编号', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
 | 
	
		
			
				|  |  | +                            {title: '名称', field: 'name', width: 150, hAlign: 0, formatter: '@'},
 | 
	
		
			
				|  |  | +                            {title: '单位', field: 'unit', width: 50, hAlign: 1, formatter: '@'},
 | 
	
		
			
				|  |  | +                            {title: '单价', field: 'unit_price', hAlign: 2, width: 50},
 | 
	
		
			
				|  |  | +                            {title: '数量', field: 'quantity', hAlign: 2, width: 50},
 | 
	
		
			
				|  |  | +                            {title: '完成率(%)', field: 'complete_percent', hAlign: 2, width: 70},
 | 
	
		
			
				|  |  | +                        ],
 | 
	
		
			
				|  |  | +                        emptyRows: 0,
 | 
	
		
			
				|  |  | +                        headRows: 1,
 | 
	
		
			
				|  |  | +                        headRowHeight: [32],
 | 
	
		
			
				|  |  | +                        defaultRowHeight: 21,
 | 
	
		
			
				|  |  | +                        headerFont: '12px 微软雅黑',
 | 
	
		
			
				|  |  | +                        font: '12px 微软雅黑',
 | 
	
		
			
				|  |  | +                        selectedBackColor: '#fffacd',
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    afterLocated: function () {
 | 
	
		
			
				|  |  | +                        stagePosSpreadObj.loadCurPosData();
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    checkLess: function (node) {
 | 
	
		
			
				|  |  | +                        if (node.quantity) {
 | 
	
		
			
				|  |  | +                            return ZhCalc.sub(ZhCalc.add(node.quantity, node.end_qc_qty), node.end_gather_qty) > 0;
 | 
	
		
			
				|  |  | +                        } else if (node.total_price) {
 | 
	
		
			
				|  |  | +                            return ZhCalc.sub(ZhCalc.add(node.total_price, node.end_qc_tp), node.end_gather_tp) > 0;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    checkOver: function (node) {
 | 
	
		
			
				|  |  | +                        const posRange = stagePos.ledgerPos[itemsPre + node.id] || [];
 | 
	
		
			
				|  |  | +                        if (posRange.length > 0) {
 | 
	
		
			
				|  |  | +                            for (const p of posRange) {
 | 
	
		
			
				|  |  | +                                if (p.end_contract_qty > p.quantity) return true;
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                            return false;
 | 
	
		
			
				|  |  | +                        } else if (node.end_gather_qty) {
 | 
	
		
			
				|  |  | +                            return !node.quantity || Math.abs(node.end_gather_qty) > Math.abs(ZhCalc.add(node.quantity, node.end_qc_qty));
 | 
	
		
			
				|  |  | +                        } else if (node.end_gather_tp) {
 | 
	
		
			
				|  |  | +                            return !node.total_price || Math.abs(node.end_gather_tp) > Math.abs(ZhCalc.add(node.total_price, node.end_qc_tp));
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    checkEmpty: function (node) {
 | 
	
		
			
				|  |  | +                        if (node.quantity) {
 | 
	
		
			
				|  |  | +                            return !node.end_gather_qty || checkZero(node.end_gather_qty);
 | 
	
		
			
				|  |  | +                        } else if (node.total_price) {
 | 
	
		
			
				|  |  | +                            return !node.end_gather_tp || checkZero(node.end_gather_tp);
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                });
 | 
	
		
			
				|  |  |                  searchLedger.spread.refresh();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              if (tab.attr('content') === '#fujian') {
 |