|
@@ -0,0 +1,239 @@
|
|
|
+
|
|
|
+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);
|
|
|
+}
|
|
|
+
|
|
|
+// 获取当前表中行数据
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
+const UpdateType = {
|
|
|
+ UPDATE: 'update',
|
|
|
+ DELETE: 'delete',
|
|
|
+ CREATE: 'create',
|
|
|
+};
|
|
|
+
|
|
|
+const TIME_OUT = 10000;
|
|
|
+
|
|
|
+const SUMMARY_BOOK = (() => {
|
|
|
+ const locked = lockUtil.getLocked();
|
|
|
+ const setting = {
|
|
|
+ header: [
|
|
|
+ { headerName: '主从对应码', headerWidth: 200, dataCode: 'masterSubCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
|
|
|
+ { headerName: '别名编码', headerWidth: 100, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
|
|
|
+ { headerName: '计算式', headerWidth: 100, dataCode: 'expString', dataType: 'String', hAlign: 'left', vAlign: 'center' },
|
|
|
+ { headerName: '材料名称', headerWidth: 350, dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' },
|
|
|
+ { headerName: '规格型号', headerWidth: 200, dataCode: 'specs', dataType: 'String', hAlign: 'left', vAlign: 'center' },
|
|
|
+ { headerName: '单位', headerWidth: 80, dataCode: 'unit', dataType: 'String', hAlign: 'center', vAlign: 'center' },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ // 初始化表格
|
|
|
+ const workBook = initSheet($('#summary-spread')[0], setting);
|
|
|
+ workBook.options.allowUserDragDrop = true;
|
|
|
+ workBook.options.allowUserDragFill = true;
|
|
|
+ lockUtil.lockSpreads([workBook], locked);
|
|
|
+ const sheet = workBook.getSheet(0);
|
|
|
+
|
|
|
+ // 当前数据缓存
|
|
|
+ const cache = [];
|
|
|
+ // 清空
|
|
|
+ function clear() {
|
|
|
+ cache.length = 0;
|
|
|
+ sheet.setRowCount(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ let loading = false;
|
|
|
+ // 当前页面数据总量
|
|
|
+ let totalCount = 0;
|
|
|
+ // 当前页数
|
|
|
+ let curPage = 0;
|
|
|
+
|
|
|
+ // 搜索内容
|
|
|
+ let searchStr = '';
|
|
|
+
|
|
|
+ // 加载分页数据
|
|
|
+ const loadPageData = async (page) => {
|
|
|
+ curPage = page;
|
|
|
+ loading = true;
|
|
|
+ const data = await ajaxPost('/priceInfoSummary/getPagingData', { page, searchStr, pageSize: 100 }, TIME_OUT);
|
|
|
+ totalCount = data.totalCount;
|
|
|
+ cache.push(...data.items);
|
|
|
+ showData(sheet, cache, setting.header, 5);
|
|
|
+ loading = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 搜索
|
|
|
+ const handleSearch = (val) => {
|
|
|
+ searchStr = val;
|
|
|
+ clear();
|
|
|
+ loadPageData(0);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 无限滚动加载
|
|
|
+ const onTopRowChanged = (sender, args) => {
|
|
|
+ const bottomRow = args.sheet.getViewportBottomRow(1);
|
|
|
+ console.log(cache.length, totalCount, loading, cache.length - 1, bottomRow)
|
|
|
+ if (cache.length >= totalCount || loading) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (cache.length - 1 <= bottomRow) {
|
|
|
+ loadPageData(curPage + 1, searchStr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sheet.bind(GC.Spread.Sheets.Events.TopRowChanged, _.debounce(onTopRowChanged, 100));
|
|
|
+
|
|
|
+ // 编辑处理
|
|
|
+ async function handleEdit(changedCells) {
|
|
|
+ $.bootstrapLoading.start();
|
|
|
+ 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();
|
|
|
+ postData.push({ type: UpdateType.CREATE, data: rowData });
|
|
|
+ insertData.push(rowData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (postData.length) {
|
|
|
+ await ajaxPost('/priceInfoSummary/editSummaryData', { 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);
|
|
|
+ }
|
|
|
+ $.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.RangeChanged, function (e, info) {
|
|
|
+ const changedRows = [];
|
|
|
+ let preRow;
|
|
|
+ info.changedCells.forEach(({ row }) => {
|
|
|
+ if (row !== preRow) {
|
|
|
+ changedRows.push({ row });
|
|
|
+ }
|
|
|
+ preRow = row;
|
|
|
+ });
|
|
|
+ handleEdit(changedRows);
|
|
|
+ });
|
|
|
+
|
|
|
+ const initData = async () => {
|
|
|
+ try {
|
|
|
+ $.bootstrapLoading.start();
|
|
|
+ await loadPageData(0);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ alert(error.message);
|
|
|
+ }
|
|
|
+ $.bootstrapLoading.end();
|
|
|
+ }
|
|
|
+
|
|
|
+ initData();
|
|
|
+
|
|
|
+ return {
|
|
|
+ sheet,
|
|
|
+ handleSearch,
|
|
|
+ }
|
|
|
+})()
|