// 价格信息表 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); } // 是否正在检测重复数据 let isCheckingRepeat = false; // 初始化数据 async function initData(classIDList) { isCheckingRepeat = false; $('#check-repeat').text('检测重复别名编码'); if (!classIDList || !classIDList.length) { return clear(); } $.bootstrapLoading.start(); try { cache = await ajaxPost('/priceInfo/getPriceData', { classIDList }, 1000 * 60 * 10); 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(); } } // 编辑处理 async function handleEdit(changedCells, needLoading = true) { $.bootstrapLoading.start(); const areaID = AREA_BOOK.curArea.ID; 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, areaID, compilationID, period: curLibPeriod, data: diffData }); updateData.push({ row, data: diffData }); } } else { // 该行无数据了,删除 postData.push({ type: UpdateType.DELETE, ID: cache[row].ID, areaID, compilationID, period: curLibPeriod }); 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, isCheckingRepeat ? 0 : 5); } } } catch (err) { // 恢复各单元格数据 showData(sheet, cache, setting.header, 5); } $.bootstrapLoading.end(); } 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); }); // 显示重复别名编码数据 let orgCache = [...cache]; const showRepeatData = () => { if (isCheckingRepeat) { $('#check-repeat').text('检测重复别名编码'); isCheckingRepeat = false; cache = orgCache; showData(sheet, cache, setting.header, 5); return; } $('#check-repeat').text('检测重复别名编码(检测中)'); isCheckingRepeat = true; const tableData = []; const classCodeMap = {}; cache.forEach(item => { const classCode = item.classCode || ''; if (!classCodeMap[classCode]) { classCodeMap[classCode] = 1; } else { classCodeMap[classCode] = classCodeMap[classCode] + 1; } }); cache.forEach(item => { const classCode = item.classCode || ''; if (classCodeMap[classCode] > 1) { tableData.push(item); } }); orgCache = [...cache]; cache = tableData; showData(sheet, cache, setting.header); } return { clear, initData, showRepeatData, } })(); $(document).ready(() => { // 检测重复别名编码 $('#check-repeat').click(() => { PRICE_BOOK.showRepeatData(); }); });