|  | @@ -605,6 +605,101 @@ const showSelectTab = function(select, spread, afterShow) {
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |          return {spread: resultSpread};
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  | +    $.listSearch = function (setting) {
 | 
	
		
			
				|  |  | +        if (!setting.selector || !setting.searchSpread || !setting.resultSpreadSetting) return;
 | 
	
		
			
				|  |  | +        if (!setting.searchRangeStr) setting.searchRangeStr = '清单编号/名称';
 | 
	
		
			
				|  |  | +        const resultId = setting.id + '-search-result';
 | 
	
		
			
				|  |  | +        const obj = $(setting.selector);
 | 
	
		
			
				|  |  | +        let filter = [];
 | 
	
		
			
				|  |  | +        if (setting.searchOver || setting.searchEmpty) {
 | 
	
		
			
				|  |  | +            filter.push('<select class="input-group-text" id="search-filter">');
 | 
	
		
			
				|  |  | +            filter.push('<option value="">台账</option>');
 | 
	
		
			
				|  |  | +            if (setting.customSearch) {
 | 
	
		
			
				|  |  | +                for (const cs of setting.customSearch) {
 | 
	
		
			
				|  |  | +                    if (cs.valid) filter.push('<option value="' + cs.key + '">' + cs.title + '</option>');
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            filter.push('</select>');
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        obj.html(
 | 
	
		
			
				|  |  | +            '                        <div class="sjs-bar">\n' +
 | 
	
		
			
				|  |  | +            '                            <div class="input-group input-group-sm pb-1">\n' +
 | 
	
		
			
				|  |  | +            '                                <div class="input-group-prepend">\n' +
 | 
	
		
			
				|  |  | +            filter.join('') +
 | 
	
		
			
				|  |  | +            '                                </div>' +
 | 
	
		
			
				|  |  | +            '                                <input id="searchKeyword" type="text" class="form-control" autocomplete="off" placeholder="可查找 ' + setting.searchRangeStr + '" aria-label="Recipient\'s username" aria-describedby="button-addon2">\n' +
 | 
	
		
			
				|  |  | +            '                                <div class="input-group-append">\n' +
 | 
	
		
			
				|  |  | +            '                                    <button class="btn btn-outline-secondary" type="button"">搜索</button>\n' +
 | 
	
		
			
				|  |  | +            '                                </div>\n' +
 | 
	
		
			
				|  |  | +            '                            </div>\n' +
 | 
	
		
			
				|  |  | +            '                        </div>\n' +
 | 
	
		
			
				|  |  | +            '                        <div id="' + resultId + '" class="sjs-sh">\n' +
 | 
	
		
			
				|  |  | +            '                        </div>'
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  | +        autoFlashHeight();
 | 
	
		
			
				|  |  | +        const resultSpread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
 | 
	
		
			
				|  |  | +        SpreadJsObj.initSheet(resultSpread.getActiveSheet(), setting.resultSpreadSetting);
 | 
	
		
			
				|  |  | +        const searchSheet = setting.searchSpread.getActiveSheet();
 | 
	
		
			
				|  |  | +        let searchResult = [];
 | 
	
		
			
				|  |  | +        const search = function () {
 | 
	
		
			
				|  |  | +            const filter = $('#search-filter').val();
 | 
	
		
			
				|  |  | +            if (filter) {
 | 
	
		
			
				|  |  | +                searchCustom(filter);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                searchList();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        const searchList = function () {
 | 
	
		
			
				|  |  | +            const keyword = $('#searchKeyword', obj).val();
 | 
	
		
			
				|  |  | +            searchResult = [];
 | 
	
		
			
				|  |  | +            const sortData = SpreadJsObj.getSortData(searchSheet);
 | 
	
		
			
				|  |  | +            for (const [i, node] of sortData.entries()) {
 | 
	
		
			
				|  |  | +                if (setting.check(node, keyword)) {
 | 
	
		
			
				|  |  | +                    const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | +                    data.searchIndex = i;
 | 
	
		
			
				|  |  | +                    data.visible = true;
 | 
	
		
			
				|  |  | +                    searchResult.push(data);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        const getCheckFun = function (key) {
 | 
	
		
			
				|  |  | +            const cs = setting.customSearch.find(function (x) {return x.key === key});
 | 
	
		
			
				|  |  | +            return cs ? cs.check : null;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        const searchCustom = function (key) {
 | 
	
		
			
				|  |  | +            const keyword = $('#searchKeyword', obj).val();
 | 
	
		
			
				|  |  | +            const checkFun = getCheckFun(key);
 | 
	
		
			
				|  |  | +            searchResult = [];
 | 
	
		
			
				|  |  | +            const sortData = SpreadJsObj.getSortData(searchSheet);
 | 
	
		
			
				|  |  | +            for (const [i, node] of sortData.entries()) {
 | 
	
		
			
				|  |  | +                if (checkFun && checkFun(node)) {
 | 
	
		
			
				|  |  | +                    if (setting.check(node, keyword)) {
 | 
	
		
			
				|  |  | +                        const data = JSON.parse(JSON.stringify(node));
 | 
	
		
			
				|  |  | +                        data.searchIndex = i;
 | 
	
		
			
				|  |  | +                        data.visible = true;
 | 
	
		
			
				|  |  | +                        searchResult.push(data);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        $('input', obj).bind('keydown', function (e) {
 | 
	
		
			
				|  |  | +            if (e.keyCode == 13) search();
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        $('button', obj).bind('click', () => {search()});
 | 
	
		
			
				|  |  | +        resultSpread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
 | 
	
		
			
				|  |  | +            const cur = SpreadJsObj.getSelectObject(info.sheet);
 | 
	
		
			
				|  |  | +            if (!cur) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            SpreadJsObj.locateRow(searchSheet, cur.searchIndex);
 | 
	
		
			
				|  |  | +            if (setting.afterLocated) {
 | 
	
		
			
				|  |  | +                setting.afterLocated();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        return {spread: resultSpread};
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      $.billsTag = function (setting) {
 | 
	
		
			
				|  |  |          if (!setting.selector || !setting.relaSpread) return;
 |