|
@@ -1,898 +1,7 @@
|
|
|
-
|
|
|
-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: 60, dataCode: 'serialNo', dataType: 'Number', hAlign: 'center', vAlign: 'center' },
|
|
|
- { headerName: '地区', headerWidth: $('#area-spread').width() - 80, 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 = [];
|
|
|
- let reSort = false;
|
|
|
- changedCells.forEach(({ row, col }) => {
|
|
|
- const field = setting.header[col].dataCode;
|
|
|
- let value = sheet.getValue(row, col);
|
|
|
- if (field === 'serialNo') {
|
|
|
- reSort = true;
|
|
|
- value = +value;
|
|
|
- }
|
|
|
- updateData.push({
|
|
|
- row,
|
|
|
- field,
|
|
|
- value,
|
|
|
- ID: cache[row].ID,
|
|
|
- });
|
|
|
- });
|
|
|
- try {
|
|
|
- await ajaxPost('/priceInfo/editArea', { updateData }, TIME_OUT);
|
|
|
- updateData.forEach(({ row, field, value }) => cache[row][field] = value);
|
|
|
- if (reSort) {
|
|
|
- cache.sort((a, b) => a.serialNo - b.serialNo);
|
|
|
- showData(sheet, cache, setting.header);
|
|
|
- }
|
|
|
- } catch (err) {
|
|
|
- // 恢复各单元格数据
|
|
|
- sheetCommonObj.renderSheetFunc(sheet, () => {
|
|
|
- changedCells.forEach(({ row, col, field }) => {
|
|
|
- sheet.setValue(row, col, cache[row][field]);
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- 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);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
});
|