| 
					
				 | 
			
			
				@@ -0,0 +1,883 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function setAlign(sheet, headers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const fuc = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        headers.forEach(({ hAlign, vAlign }, index) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheetCommonObj.setAreaAlign(sheet.getRange(-1, index, -1, 1), hAlign, vAlign) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheetCommonObj.renderSheetFunc(sheet, fuc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function setFormatter(sheet, headers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const fuc = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        headers.forEach(({ formatter }, index) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (formatter) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sheet.setFormatter(-1, index, formatter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheetCommonObj.renderSheetFunc(sheet, fuc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function initSheet(dom, setting) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const workBook = sheetCommonObj.buildSheet(dom, setting); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const sheet = workBook.getSheet(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setAlign(sheet, setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setFormatter(sheet, setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return workBook; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function showData(sheet, data, headers, emptyRows) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const fuc = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.setRowCount(data.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data.forEach((item, row) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            headers.forEach(({ dataCode }, col) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sheet.setValue(row, col, item[dataCode] || ''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (emptyRows) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.addRows(data.length, emptyRows); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheetCommonObj.renderSheetFunc(sheet, fuc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const TIME_OUT = 10000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const libID = window.location.search.match(/libID=([^&]+)/)[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const UpdateType = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    UPDATE: 'update', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DELETE: 'delete', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    CREATE: 'create', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const DEBOUNCE_TIME = 200; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const locked = lockUtil.getLocked(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 地区表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const AREA_BOOK = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const cache = areaList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const setting = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        header: [{ headerName: '地区', headerWidth: $('#area-spread').width(), dataCode: 'name', dataType: 'String', hAlign: 'center', vAlign: 'center' }] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化表格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const workBook = initSheet($('#area-spread')[0], setting); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lockUtil.lockSpreads([workBook], locked); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowExtendPasteRange = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragDrop = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const sheet = workBook.getSheet(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 排序显示 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cache.sort((a, b) => a.serialNo - b.serialNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 显示数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    showData(sheet, cache, setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 编辑处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function handleEdit(changedCells) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        changedCells.forEach(({ row, col }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                row, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ID: cache[row].ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name: sheet.getValue(row, col) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editArea', { updateData }, TIME_OUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.forEach(({ row, name }) => cache[row].name = name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 恢复各单元格数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheetCommonObj.renderSheetFunc(sheet, () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                changedCells.forEach(({ row }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    sheet.setValue(cache[row].name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const changedCells = [{ row: info.row, col: info.col }]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleEdit(changedCells); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.RangeChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleEdit(info.changedCells); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const curArea = { ID: null }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 焦点变更处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const debounceSelectionChanged = _.debounce(function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const row = info.newSelections && info.newSelections[0] ? info.newSelections[0].row : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleSelectionChanged(row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, DEBOUNCE_TIME, { leading: true }); // leading = true : 先触发再延迟 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function handleSelectionChanged(row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const areaItem = cache[row]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        curArea.ID = areaItem && areaItem.ID || null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CLASS_BOOK.initData(libID, curArea.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, debounceSelectionChanged); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 新增 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function insert() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const data = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            compilationID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ID: uuid.v1(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            name: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/insertArea', { insertData: [data] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 新增的数据总是添加在最后 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.addRows(cache.length, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cache.push(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const lastRow = cache.length - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.setSelection(lastRow, 0, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.showRow(lastRow, GC.Spread.Sheets.VerticalPosition.top); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handleSelectionChanged(lastRow); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 删除 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function del() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/deleteArea', { deleteData: [curArea.ID] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const index = cache.findIndex(item => item.ID === curArea.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.deleteRows(index, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cache.splice(index, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const row = sheet.getActiveRowIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handleSelectionChanged(row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 右键功能 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function buildContextMenu() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $.contextMenu({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            selector: '#area-spread', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            build: function ($triggerElement, e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 控制允许右键菜单在哪个位置出现 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const offset = $('#area-spread').offset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const x = e.pageX - offset.left; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const y = e.pageY - offset.top; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const target = sheet.hitTest(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (target.hitTestType === 3) { // 在表格内 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const sel = sheet.getSelections()[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (sel && sel.rowCount === 1 && typeof target.row !== 'undefined') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        const orgRow = sheet.getActiveRowIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (orgRow !== target.row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            sheet.setActiveCell(target.row, target.col); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            handleSelectionChanged(target.row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        items: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            insert: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                name: '新增', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                icon: "fa-arrow-left", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                disabled: function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    return locked; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                callback: function (key, opt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    insert(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            del: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                name: '删除', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                icon: "fa-arrow-left", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                disabled: function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    return locked || !cache[target.row]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                callback: function (key, opt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    del(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    buildContextMenu(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleSelectionChanged, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        curArea, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 分类表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const CLASS_BOOK = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const setting = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        header: [{ headerName: '分类', headerWidth: $('#area-spread').width(), dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' }], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        controller: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cols: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    data: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        field: 'name', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        vAlign: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        hAlign: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        font: 'Arial' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            headRows: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            headRowHeight: [30], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            emptyRows: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeCol: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tree: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            id: 'ID', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pid: 'ParentID', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            nid: 'NextSiblingID', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rootId: -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化表格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const workBook = initSheet($('#class-spread')[0], setting); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowExtendPasteRange = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragDrop = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const sheet = workBook.getSheet(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let tree; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let controller; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function initData(libID, areaID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!areaID) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tree = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.setRowCount(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PRICE_BOOK.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const data = await ajaxPost('/priceInfo/getClassData', { libID, areaID }, TIME_OUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tree = idTree.createNew(setting.tree); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tree.loadDatas(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tree.selected = tree.items.length > 0 ? tree.items[0] : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller = TREE_SHEET_CONTROLLER.createNew(tree, sheet, setting.controller, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.showTreeData(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handleSelectionChanged(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.setSelection(0, 0, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lockUtil.lockSpreads([workBook], locked); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            console.log(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tree = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.setRowCount(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 编辑处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function handleEdit(changedCells) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        changedCells.forEach(({ row, col }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                row, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: { ID: tree.items[row].data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                update: { name: sheet.getValue(row, col) } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }, TIME_OUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.forEach(({ row, update: { name } }) => tree.items[row].data.name = name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 恢复各单元格数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheetCommonObj.renderSheetFunc(sheet, () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                changedCells.forEach(({ row }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    sheet.setValue(tree.items[row].data.name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const changedCells = [{ row: info.row, col: info.col }]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleEdit(changedCells); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.RangeChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleEdit(info.changedCells); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 树操作相关 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $insert = $('#tree-insert'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $remove = $('#tree-remove'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $upLevel = $('#tree-up-level'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $downLevel = $('#tree-down-level'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $downMove = $('#tree-down-move'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $upMove = $('#tree-up-move'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $calcPriceIndex = $('#calc-price-index'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 插入 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let canInsert = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function insert() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!canInsert) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canInsert = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const selected = tree.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const newItem = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                libID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                areaID: AREA_BOOK.curArea.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ID: uuid.v1(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ParentID: '-1', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                NextSiblingID: '-1' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                newItem.ParentID = selected.data.ParentID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: newItem.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (selected.nextSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    newItem.NextSiblingID = selected.nextSibling.data.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.CREATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                document: newItem 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.insertByID(newItem.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handleSelectionChanged(sheet.getActiveRowIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            console.log(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canInsert = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $insert.click(_.debounce(insert, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 删除 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let canRemove = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function remove() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!canRemove) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canRemove = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const selected = tree.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const children = selected.getPosterity(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            [selected, ...children].forEach(node => updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.DELETE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: { ID: node.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected.preSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.preSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: selected.data.NextSiblingID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.delete(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handleSelectionChanged(sheet.getActiveRowIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canRemove = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $remove.click(_.debounce(remove, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 升级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let canUpLevel = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function upLevel() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!canUpLevel) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canUpLevel = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const selected = tree.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected.preSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.preSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: -1 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected.parent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.parent.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: selected.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: { ID: selected.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                update: { ParentID: selected.parent.data.ParentID, NextSiblingID: selected.parent.data.NextSiblingID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let curNode = selected.nextSibling; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while (curNode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: curNode.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { ParentID: selected.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                curNode = curNode.nextSibling; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.upLevel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            refreshTreeButton(tree.selected); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canUpLevel = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $upLevel.click(_.debounce(upLevel, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 降级 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let canDownLevel = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function downLevel() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!canDownLevel) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canDownLevel = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const selected = tree.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected.preSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.preSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: selected.data.NextSiblingID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const preSiblingLastChild = selected.preSibling.children[selected.preSibling.children.length - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (preSiblingLastChild) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        filter: { ID: preSiblingLastChild.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        update: { NextSiblingID: selected.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { ParentID: selected.preSibling.data.ID, NextSiblingID: -1 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.downLevel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            refreshTreeButton(tree.selected); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canDownLevel = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $downLevel.click(_.debounce(downLevel, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 下移 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let canDownMove = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function downMove() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!canDownMove) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canDownMove = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const selected = tree.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected.preSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.preSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: selected.data.NextSiblingID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: { ID: selected.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                update: { NextSiblingID: selected.nextSibling.data.NextSiblingID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: { ID: selected.nextSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                update: { NextSiblingID: selected.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.downMove(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            refreshTreeButton(tree.selected); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canDownMove = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $downMove.click(_.debounce(downMove, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 上移 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let canUpMove = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function upMove() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!canUpMove) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canUpMove = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const selected = tree.selected; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (selected.preSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: selected.preSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: selected.data.NextSiblingID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const prePreSibling = selected.preSibling.preSibling; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (prePreSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    filter: { ID: prePreSibling.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    update: { NextSiblingID: selected.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateData.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type: UpdateType.UPDATE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: { ID: selected.data.ID }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                update: { NextSiblingID: selected.preSibling.data.ID } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ajaxPost('/priceInfo/editClassData', { updateData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            controller.upMove(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            refreshTreeButton(tree.selected); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canUpMove = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $upMove.click(_.debounce(upMove, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 刷新树操作按钮有效性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function refreshTreeButton(selected) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (locked) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $insert.removeClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $remove.removeClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $upLevel.removeClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $downLevel.removeClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $downMove.removeClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $upMove.removeClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!selected) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $remove.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $upLevel.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $downLevel.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $downMove.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $upMove.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!selected.preSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                $downLevel.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                $upMove.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!selected.nextSibling) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                $downMove.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!selected.parent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                $upLevel.addClass('disabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 焦点变更处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const curClass = { ID: null }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function handleSelectionChanged(row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const classNode = tree.items[row] || null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tree.selected = classNode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        refreshTreeButton(classNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        curClass.ID = classNode && classNode.data && classNode.data.ID || null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const classIDList = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (classNode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            classIDList.push(classNode.data.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const children = classNode.getPosterity(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            children.forEach(child => classIDList.push(child.data.ID)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PRICE_BOOK.initData(classIDList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const debounceSelectionChanged = _.debounce(function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const row = info.newSelections && info.newSelections[0] ? info.newSelections[0].row : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleSelectionChanged(row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, DEBOUNCE_TIME, { leading: true }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, debounceSelectionChanged); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $calcPriceIndex.click(_.debounce(async()=>{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const data = await ajaxPost('/priceInfo/calcPriceIndex', { libID, period:curLibPeriod,compilationID }, TIME_OUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //alert(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(data){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              const htmlStr = data.replace(/\n/gm,'<br>'); //replaceAll('\n','<br>',data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              $("#result-info-body").html(htmlStr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              $("#result-info").modal('show'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              alert('计算完成!') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            console.log(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, DEBOUNCE_TIME, { leading: true })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        initData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleSelectionChanged, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        curClass, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 关键字表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const KEYWORD_BOOK = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const setting = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        header: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '关键字', headerWidth: 200, dataCode: 'keyword', dataType: 'String', hAlign: 'left', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '单位', headerWidth: 70, dataCode: 'unit', dataType: 'String', hAlign: 'center', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '关键字效果', headerWidth: 100, dataCode: 'coe', dataType: 'String', hAlign: 'center', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '组别', headerWidth: 50, dataCode: 'group', dataType: 'String', hAlign: 'center', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '选项号', headerWidth: 70, dataCode: 'optionCode', dataType: 'String', hAlign: 'center', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化表格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const workBook = initSheet($('#keyword-spread')[0], setting); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragDrop = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lockUtil.lockSpreads([workBook], true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const sheet = workBook.getSheet(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 显示关键字数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const showKeywordData = (keywordList) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        showData(sheet, keywordList, setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        showKeywordData  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 价格信息表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const PRICE_BOOK = (() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const setting = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        header: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '编码', headerWidth: 100, dataCode: 'code', dataType: 'String', hAlign: 'left', vAlign: 'center' ,formatter: "@"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '别名编码', headerWidth: 70, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center' ,formatter: "@"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '名称', headerWidth: 200, dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '规格型号', headerWidth: 120, dataCode: 'specs', dataType: 'String', hAlign: 'left', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '单位', headerWidth: 80, dataCode: 'unit', dataType: 'String', hAlign: 'center', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '不含税价', headerWidth: 80, dataCode: 'noTaxPrice', dataType: 'String', hAlign: 'right', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '含税价', headerWidth: 80, dataCode: 'taxPrice', dataType: 'String', hAlign: 'right', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '月份备注', headerWidth: 140, dataCode: 'dateRemark', dataType: 'String', hAlign: 'left', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { headerName: '计算式', headerWidth: 100, dataCode: 'expString', dataType: 'String', hAlign: 'left', vAlign: 'center' }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化表格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const workBook = initSheet($('#price-spread')[0], setting); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragDrop = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    workBook.options.allowUserDragFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lockUtil.lockSpreads([workBook], locked); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const sheet = workBook.getSheet(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let cache = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 清空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function clear() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cache = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.setRowCount(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 初始化数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function initData(classIDList) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!classIDList || !classIDList.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        $.bootstrapLoading.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cache = await ajaxPost('/priceInfo/getPriceData', { classIDList }, TIME_OUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cache = _.sortBy(cache,'classCode'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            showData(sheet, cache, setting.header, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const row = sheet.getActiveRowIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const keywordList = cache[row] && cache[row].keywordList || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            KEYWORD_BOOK.showKeywordData(keywordList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cache = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.setRowCount(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alert(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 获取当前表中行数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function getRowData(sheet, row, headers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const item = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        headers.forEach(({ dataCode }, index) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const value = sheet.getValue(row, index) || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                item[dataCode] = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return item; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 获取表数据和缓存数据的不同数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function getRowDiffData(curRowData, cacheRowData, headers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let item = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        headers.forEach(({ dataCode }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const curValue = curRowData[dataCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const cacheValue = cacheRowData[dataCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!cacheValue && !curValue) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (cacheValue !== curValue) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!item) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    item = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                item[dataCode] = curValue || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return item; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 编辑处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async function handleEdit(changedCells) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const postData = []; // 请求用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 更新缓存用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const updateData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const deleteData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const insertData = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            changedCells.forEach(({ row }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (cache[row]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const rowData = getRowData(sheet, row, setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (Object.keys(rowData).length) { // 还有数据,更新 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        const diffData = getRowDiffData(rowData, cache[row], setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (diffData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            postData.push({ type: UpdateType.UPDATE, ID: cache[row].ID, data: diffData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            updateData.push({ row, data: diffData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { // 该行无数据了,删除 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        postData.push({ type: UpdateType.DELETE, ID: cache[row].ID }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        deleteData.push(cache[row]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { // 新增 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const rowData = getRowData(sheet, row, setting.header); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (Object.keys(rowData).length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rowData.ID = uuid.v1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rowData.libID = libID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rowData.compilationID = compilationID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rowData.areaID = AREA_BOOK.curArea.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rowData.classID = CLASS_BOOK.curClass.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        rowData.period = curLibPeriod; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        postData.push({ type: UpdateType.CREATE, data: rowData }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        insertData.push(rowData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (postData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                await ajaxPost('/priceInfo/editPriceData', { postData }, TIME_OUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 更新缓存,先更新然后删除,最后再新增,防止先新增后缓存数据的下标与更新、删除数据的下标对应不上 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                updateData.forEach(item => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Object.assign(cache[item.row], item.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                deleteData.forEach(item => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const index = cache.indexOf(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (index >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        cache.splice(index, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                insertData.forEach(item => cache.push(item)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (deleteData.length || insertData.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    showData(sheet, cache, setting.header, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 恢复各单元格数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            showData(sheet, cache, setting.header, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const changedCells = [{ row: info.row }]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleEdit(changedCells); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const row = info.newSelections && info.newSelections[0] ? info.newSelections[0].row : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 显示关键字数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const keywordList = cache[row] && cache[row].keywordList || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        KEYWORD_BOOK.showKeywordData(keywordList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sheet.bind(GC.Spread.Sheets.Events.RangeChanged, function (e, info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const changedRows = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let preRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        info.changedCells.forEach(({ row }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (row !== preRow) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                changedRows.push({ row }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            preRow = row; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handleEdit(changedRows); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clear, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        initData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$(document).ready(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.log('进入信息价'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    $('[data-toggle="tooltip"]').tooltip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AREA_BOOK.handleSelectionChanged(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const $range = $(document.body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lockUtil.lockTools($range, locked); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 |