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) {
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) {
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,'
'); //replaceAll('\n','
',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);
});