/** * Created by zhang on 2018/7/13. */ const locked = lockUtil.getLocked(); let TEMPLATE_BILLS_SETTING = { emptyRows: 1, headRows: 1, headRowHeight: [35], treeCol: 1, cols: [ { width: 80, readOnly: locked, head: { titleNames: ["类别"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "type", vAlign: 0, hAlign: 1, font: "Arail", }, }, { width: 200, readOnly: locked, head: { titleNames: ["编号"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "code", vAlign: 0, hAlign: 3, font: "Arail", formatter: "@", }, }, { width: 300, readOnly: locked, head: { titleNames: ["名称"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "name", vAlign: 0, hAlign: 3, font: "Arail", }, }, { width: 50, readOnly: locked, head: { titleNames: ["单位"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "unit", vAlign: 0, hAlign: 1, font: "Arail", }, }, { width: 80, readOnly: locked, head: { titleNames: ["工程量"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "quantity", type: "Number", vAlign: 0, hAlign: 2, font: "Arail", }, }, { width: 200, readOnly: locked, head: { titleNames: ["清单固定类别"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "flagsIndex.fixed.flag", vAlign: 0, hAlign: 3, font: "Arail", }, }, { width: 40, readOnly: locked, head: { titleNames: ["不可\n删除"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "cantDelete", vAlign: 0, hAlign: 1, font: "Arail", }, }, { width: 200, readOnly: locked, head: { titleNames: ["计价规则"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "itemCharacterText", vAlign: 0, hAlign: 3, font: "Arail", }, }, { width: 200, readOnly: locked, head: { titleNames: ["计价内容"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "jobContentText", vAlign: 0, hAlign: 3, font: "Arail", }, }, { width: 250, readOnly: locked, head: { titleNames: ["计算基数"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "calcBase", vAlign: 0, hAlign: 3, font: "Arail", }, }, { width: 50, readOnly: locked, head: { titleNames: ["费率ID"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "feeRateID", type: "Number", vAlign: 0, hAlign: 1, font: "Arail", }, }, { width: 50, readOnly: true, head: { titleNames: ["ID"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "ID", vAlign: 0, hAlign: 1, font: "Arail", }, }, { width: 50, readOnly: true, head: { titleNames: ["ParentID"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "ParentID", vAlign: 0, hAlign: 1, font: "Arail", }, }, { width: 50, readOnly: true, head: { titleNames: ["NextSiblingID"], spanCols: [1], spanRows: [1], vAlign: [1], hAlign: [1], font: ["Arial"], }, data: { field: "NextSiblingID", vAlign: 0, hAlign: 1, font: "Arail", }, }, ], }; $(document).ready(function () { autoFlashHeight(); let RefreshBaseActn = function (tree) { if (locked) { return; } let setButtonValid = function (valid, btn) { if (valid) { btn.removeClass("disabled"); } else { btn.addClass("disabled"); } }; setButtonValid(tree.selected && tree.selected.canUpLevel(), $("#upLevel")); setButtonValid(tree.selected && tree.selected.canDownLevel(), $("#downLevel")); setButtonValid(tree.selected && tree.selected.canUpMove(), $("#upMove")); setButtonValid(tree.selected && tree.selected.canDownMove(), $("#downMove")); setButtonValid(tree.selected ? true : false, $("#delete")); }; let RefreshBillsData = function (datas) { datas.forEach(function (data) { let node = tree.findNode(data.data.ID); if (node) { setFlagsIndex(data.data, node.data.flagsIndex); $.extend(true, node.data, data.data); } }); }; let getNameValueComboCellType = function (datas) { let comboItems = []; for (let data of datas) { comboItems.push({ text: data.name, value: data.value }); } let combo = new GC.Spread.Sheets.CellTypes.ComboBox(); combo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value).items(comboItems); return combo; }; let getFixedFlagCellType = function () { let billsFixedFlagData = JSON.parse(billsFixedFlagList); return getNameValueComboCellType(billsFixedFlagData); }; let getNameToValueMap = function (listString) { let map = {}; let datas = JSON.parse(listString); for (let data of datas) { map[data.name] = data.value; } return map; }; let getTypeFlagCellType = function () { let billsTypeFlagData = JSON.parse(billsTypeFlagList); return getNameValueComboCellType(billsTypeFlagData); }; let setFee = function (data, fullField, value) { let fields = fullField.split("."), valueField = data; for (let i in fields) { if (valueField[fields[i]]) { if (i == fields.length - 1) { valueField[fields[i]] = value; } else { valueField = valueField[fields[i]]; } } else { if (i == fields.length - 1) { valueField[fields[i]] = value; } else { valueField[fields[i]] = {}; } valueField = valueField[fields[i]]; } } }; let getRealValue = function (value, map) { //中文到实际值的转换 if (value) value = value.replace(/[\s\r\n]/g, ""); //去掉空格,回车等无用字符 if (map[value] !== undefined && map[value] !== null) value = map[value]; return value; }; let setUpdateData = function (node, data, col, value, setting) { let fieldName = setting.cols[col].data.field; let valueType = setting.cols[col].data.type; if (fieldName == "type") { value = getRealValue(value, typeMap); } if (fieldName == "flagsIndex.fixed.flag") { value = getRealValue(value, fixedFlagMap); } if (/flagsIndex/.test(fieldName)) { data.data.flags = []; let flagField = fieldName.split("."); data.data.flags.push({ fieldName: flagField[1], flag: value }); } else { if (value && valueType == "Number") value = parseInt(value); setFee(data.data, fieldName, value); } }; let setFlagsIndex = function (data, flagsIndex) { if (data.flags) { flagsIndex ? (data.flagsIndex = flagsIndex) : (data.flagsIndex = {}); for (let flag of data.flags) { data.flagsIndex[flag.fieldName] = flag; } } }; billsTemplateData = billsTemplateData.replace(/\n/g, "\\n"); let templateData = JSON.parse(billsTemplateData); for (let data of templateData) { setFlagsIndex(data); /* if (data.flags) { data.flagsIndex = {}; for (let flag of data.flags) { data.flagsIndex[flag.fieldName] = flag; } }*/ } for (col of TEMPLATE_BILLS_SETTING.cols) { if (col.data.field === "type" && TEMPLATE_BILLS_SETTING.cols.indexOf(col) !== TEMPLATE_BILLS_SETTING.treeCol) { col.data.cellType = getTypeFlagCellType(); } else if (col.data.field === "flagsIndex.fixed.flag" && TEMPLATE_BILLS_SETTING.cols.indexOf(col) !== TEMPLATE_BILLS_SETTING.treeCol) { col.data.cellType = getFixedFlagCellType(); } else if (col.data.field === 'cantDelete' && TEMPLATE_BILLS_SETTING.cols.indexOf(col) !== TEMPLATE_BILLS_SETTING.treeCol) { col.data.cellType = new GC.Spread.Sheets.CellTypes.CheckBox(); } } let tree = idTree.createNew({ id: "ID", pid: "ParentID", nid: "NextSiblingID", rootId: -1, autoUpdate: true }); let billsSpread = TREE_SHEET_HELPER.createNewSpread($("#billsSpread")[0]); sheetCommonObj.bindEscKey(billsSpread, [{ sheet: billsSpread.getSheet(0), editStarting: null, editEnded: billsOnEditEnded }]); let controller = TREE_SHEET_CONTROLLER.createNew(tree, billsSpread.getActiveSheet(), TEMPLATE_BILLS_SETTING); let fixedFlagMap = getNameToValueMap(billsFixedFlagList); let typeMap = getNameToValueMap(billsTypeFlagList); //format code //billsSpread.getSheet(0).setFormatter(-1, 1, '@'); controller.bind("refreshBaseActn", RefreshBaseActn); function onButtonClicked(sender, info) { if (info.sheet.isEditing()) { info.sheet.endEdit(true); } const fieldName = controller.setting.cols[info.col].data.field; var node = controller.tree.items[info.row]; if (node && fieldName === 'cantDelete') { const isChecked = Boolean(info.sheet.getValue(info.row, info.col)); const data = { type: "update", data: { ID: node.getID() } }; setFee(data.data, fieldName, isChecked); console.log(isChecked); const updateData = [data]; CommonAjax.post( updateUrl, updateData, function (data) { setFee(node.data, fieldName, isChecked); controller.refreshTreeNode([node], false); }, function () { controller.refreshTreeNode([node], false); } ); } } function billsOnEditEnded(sender, info) { var node = controller.tree.items[info.row]; var fieldName = controller.setting.cols[info.col].data.field; var valueType = controller.setting.cols[info.col].data.type; let value = info.editingText; if (node) { var data = { type: "update", data: { ID: node.getID() } }; if (/flagsIndex/.test(fieldName)) { data.data.flags = []; let flagField = fieldName.split("."); data.data.flags.push({ fieldName: flagField[1], flag: info.editingText }); } else { if (value && valueType == "Number") value = parseInt(info.editingText); setFee(data.data, fieldName, value); } var updateData = [data]; CommonAjax.post( updateUrl, updateData, function (data) { setFee(node.data, fieldName, value); controller.refreshTreeNode([node], false); }, function () { controller.refreshTreeNode([node], false); } ); } else { info.sheet.getCell(info.row, info.col).value(""); } } billsSpread.bind(GC.Spread.Sheets.Events.EditEnded, billsOnEditEnded); billsSpread.bind(GC.Spread.Sheets.Events.ButtonClicked, onButtonClicked); billsSpread.bind(GC.Spread.Sheets.Events.ClipboardPasted, function (e, info) { console.log("ClipboardPasted"); var node, iRow, iCol, curRow, curCol, datas = [], data, fieldName, valueType, value, updateData; for (iRow = 0; iRow < info.cellRange.rowCount; iRow++) { curRow = info.cellRange.row + iRow; node = controller.tree.items[curRow]; if (node) { data = { type: "update", data: { ID: node.getID() } }; for (iCol = 0; iCol < info.cellRange.colCount; iCol++) { curCol = info.cellRange.col + iCol; value = info.sheet.getText(curRow, curCol); setUpdateData(node, data, curCol, value, controller.setting); } datas.push(data); } } CommonAjax.post( updateUrl, datas, function (data) { RefreshBillsData(data); controller.showTreeData(); }, function () { controller.showTreeData(); } ); }); billsSpread.bind(GC.Spread.Sheets.Events.RangeChanged, function (e, info) { let datas = []; let changGroup = _.groupBy(info.changedCells, "row"); for (let row in changGroup) { let node = controller.tree.items[row]; if (node) { let data = { type: "update", data: { ID: node.getID() } }; for (let cell of changGroup[row]) { let value = info.sheet.getText(cell.row, cell.col); if (value == "") value = null; setUpdateData(node, data, cell.col, value, controller.setting); } datas.push(data); } } CommonAjax.post( updateUrl, datas, function (data) { RefreshBillsData(data); controller.showTreeData(); }, function () { controller.showTreeData(); } ); }); tree.loadDatas(templateData); controller.showTreeData(); let sel = billsSpread.getActiveSheet().getSelections()[0]; controller.setTreeSelected(tree.items[sel.row == -1 ? 0 : sel.row]); //初始化选中项 RefreshBaseActn(tree); lockUtil.lockSpreadsAndTools([billsSpread], $(document.body), locked); $("#insert").click(function () { let me = this; $(me).addClass("disabled"); var selected = controller.tree.selected, updateData; if (selected) { updateData = controller.tree.getInsertData(selected.getParentID(), selected.getNextSiblingID()); } else { updateData = controller.tree.getInsertData(); } if (updateData.length > 0) { CommonAjax.post(updateUrl, updateData, function (data) { controller.insert(); controller.showTreeData(); $(me).removeClass("disabled"); }); } else { alert("新增节点失败, 请重试."); $(me).removeClass("disabled"); } }); $("#m_insert_confirm").click(function () { let me = this; let insertCount = $("#insertCount").val(); if (isNaN(insertCount) || insertCount < 1) { $("#insertError").show(); return; } $(me).addClass("disabled"); let selected = controller.tree.selected, updateData; if (selected) { updateData = controller.tree.getInsertDatas(insertCount, selected.getParentID(), selected.getNextSiblingID()); } else { updateData = controller.tree.getInsertDatas(insertCount); } if (updateData.length > 0) { CommonAjax.post(updateUrl, updateData, function (data) { data = _.filter(data, { type: "new" }); console.log(data); controller.m_insert(data); controller.showTreeData(); $("#insertInputDiv").modal("hide"); $("#insertError").hide(); $(me).removeClass("disabled"); }); } else { alert("新增节点失败, 请重试."); $(me).removeClass("disabled"); } /* var selected = controller.tree.selected, updateData; if (selected) { updateData = controller.tree.getInsertData(selected.getParentID(), selected.getNextSiblingID()); } else { updateData = controller.tree.getInsertData(); } if (updateData.length > 0) { CommonAjax.post(updateUrl, updateData, function (data) { controller.insert(); controller.showTreeData(); $(me).removeClass('disabled'); }); } else { alert('新增节点失败, 请重试.'); $(me).removeClass('disabled'); }*/ }); $("#delete").click(function () { let me = this; $(me).addClass("disabled"); let [deleteMap, deleteNodes] = getNodesAndMapFromSheet(controller); if (deleteNodes.length > 0) { let updateData = controller.tree.getDeleteDatas(deleteMap, deleteNodes); CommonAjax.post(updateUrl, updateData, function (data) { controller.m_delete(deleteNodes); controller.showTreeData(); $(me).removeClass("disabled"); }); } }); $("#upLevel").click(function () { let me = this; $(me).addClass("disabled"); let [dMap, dNodes] = getNodesAndMapFromSheet(controller); let newNodes = [dNodes[0]]; if (dNodes.length > 1) { //如果是多选,则去掉与第一个节点不同级的节点 for (let i = 1; i < dNodes.length; i++) { if (dNodes[i].parent == dNodes[0].parent) newNodes.push(dNodes[i]); } } let updateDatas = controller.tree.getUpLevelDatas(newNodes); if (updateDatas.length > 0) { CommonAjax.post(updateUrl, updateDatas, function (data) { controller.m_upLevel(newNodes); for (let u of updateDatas) { let node = controller.tree.findNode(u.data.ID); refreshNodeData(node, u.data); } controller.showTreeData(); $(me).removeClass("disabled"); }); } }); $("#downLevel").click(function () { let me = this; $(me).addClass("disabled"); let [dMap, dNodes] = getNodesAndMapFromSheet(controller); let newNodes = [dNodes[0]]; if (dNodes.length > 1) { //如果是多选,则去掉与第一个节点不同级的节点 for (let i = 1; i < dNodes.length; i++) { if (dNodes[i].parent == dNodes[0].parent) newNodes.push(dNodes[i]); } } let updateDatas = controller.tree.getDownLevelDatas(newNodes); if (updateDatas.length > 0) { CommonAjax.post(updateUrl, updateDatas, function (data) { controller.m_downLevel(newNodes); for (let u of updateDatas) { let node = controller.tree.findNode(u.data.ID); refreshNodeData(node, u.data); } controller.showTreeData(); $(me).removeClass("disabled"); }); } }); $("#upMove").click(function () { let me = this; $(me).addClass("disabled"); var selected = controller.tree.selected, updateData; if (selected) { updateData = selected.getUpMoveData(); CommonAjax.post(updateUrl, updateData, function (data) { controller.upMove(); controller.showTreeData(); $(me).removeClass("disabled"); }); } }); $("#downMove").click(function () { let me = this; $(me).addClass("disabled"); var selected = controller.tree.selected, updateData; if (selected) { updateData = selected.getDownMoveData(); CommonAjax.post(updateUrl, updateData, function (data) { controller.downMove(); controller.showTreeData(); $(me).removeClass("disabled"); }); } }); function getNodesAndMapFromSheet(controller) { //表格中选中的节点整理,只留下父节点 let selection = controller.sheet.getSelections()[0], map = {}, nodes = []; for (let i = 0; i < selection.rowCount; i++) { let tem_node = controller.tree.items[selection.row + i]; if (i == 0) { //第一个直接添加; map[tem_node.getID()] = tem_node; nodes.push(tem_node); } else { setNodeToMapAndArray(tem_node, map, nodes); } } return [map, nodes]; } function setNodeToMapAndArray(node, map, array) { let nodeID = node.getID(); if (map[nodeID] == undefined || map[nodeID] == null) { newMap(node, node.parent, map, array); } function newMap(node, parent, map, array) { let nodeID = node.getID(); if (parent == null) { //说明已经是最顶层了 map[nodeID] = node; array.push(node); } else { let parentID = parent.getID(); if (map[parentID] == undefined || map[parentID] == null) { newMap(node, parent.parent, map, array); } } } } function refreshNodeData(node, data) { for (let key in data) { if (key == "ID") continue; node.data[key] = data[key]; } } });