'use strict';
/**
*
*
* @author Zhong
* @date 2018/6/1
* @version
*/
const billsGuidance = (function () {
function sortByCode(arr) {
function recurCompare(a, b, index) {
if (a[index] && !b[index]) {
return 1;
} else if (!a[index] && b[index]) {
return -1;
} else if (a[index] && b[index]) {
let aV = a[index],
bV = b[index];
if (!isNaN(aV) && !isNaN(bV)) {
aV = parseFloat(a[index]);
bV = parseFloat(b[index]);
}
if (aV > bV) {
return 1;
} else if (aV < bV) {
return -1;
} else {
return recurCompare(a, b, index + 1);
}
}
return 0;
}
arr.sort(function (a, b) {
if (!_isDef(a.code) || !_isDef(b.code)) {
return 0;
}
let aArr = a.code.split('-'),
bArr = b.code.split('-');
return recurCompare(aArr, bArr, 0);
});
}
// 导出实例
let curCompilationID = '';
const locked = lockUtil.getLocked();
let moduleName = 'stdBillsGuidance';
//上下拖动的拖动条高度
const verticalResize = 10;
//自执行函数全局变量定义
const libID = getQueryString('libID');
//总工作内容数据
let stdBillsJobData = [];
//总项目特征数据
let stdBillsFeatureData = [];
const bills = {
dom: $('#billsSpread'),
workBook: null,
cache: [],
tree: null,
controller: null,
treeSetting: {
treeCol: 0,
emptyRows: 0,
headRows: 1,
headRowHeight: [40],
defaultRowHeight: 21,
cols: [{
width: 200,
readOnly: true,
showHint: true,
head: {
titleNames: ["项目编码"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "code",
vAlign: 1,
hAlign: 0,
font: "Arial"
}
}, {
width: 200,
readOnly: true,
head: {
titleNames: ["项目名称"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "name",
vAlign: 1,
hAlign: 0,
font: "Arial"
}
}]
},
headers: [
{ name: '项目编码', dataCode: 'code', width: 200, vAlign: 'center', hAlign: 'left', formatter: '@' },
{ name: '项目名称', dataCode: 'name', width: 200, vAlign: 'center', hAlign: 'left', formatter: '@' }
],
events: {
SelectionChanged: function (sender, info) {
billsInitSel(info.newSelections[0].row, info.oldSelections[0]);
}
}
};
const selectedBgColor = '#DFE8F9';
const searchBgColor = 'lemonChiffon';
//项目指引复制整块localStorage key
const itemCopyBlockKey = 'guideItemCopyBlock';
const updateType = {
create: 'create',
update: 'update',
del: 'delete'
};
//项目指引节点状态:展开全部、收起定额
const itemExpandState = {
expand: 1,
contract: 0
};
//项目指引当前节点展开收缩状态,默认展开全部
let curExpandState = 1;
const guideItem = {
dom: $('#guideItemSpread'),
workBook: null,
tree: null,
controller: null,
treeSetting: {
treeCol: 0,
emptyRows: 0,
headRows: 1,
headRowHeight: [40],
defaultRowHeight: 21,
cols: [{
width: 400,
readOnly: locked,
head: {
titleNames: ["项目指引"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "name",
vAlign: 1,
hAlign: 0,
font: "Arial",
formatter: "@"
}
},
{
width: 40,
readOnly: true,
head: {
titleNames: ["输出特征"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "outputItemCharacter",
vAlign: 1,
hAlign: 1,
font: "Arial"
}
},
{
width: 30,
readOnly: true,
head: {
titleNames: ["必填"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "required",
vAlign: 1,
hAlign: 1,
font: "Arial"
}
},
{
width: 30,
readOnly: true,
head: {
titleNames: ["材料"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "isMaterial",
vAlign: 1,
hAlign: 1,
font: "Arial"
}
},
{
width: 30,
readOnly: true,
head: {
titleNames: ["默认"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "isDefaultOption",
vAlign: 1,
hAlign: 1,
font: "Arial"
}
},
{
width: 40,
readOnly: locked,
head: {
titleNames: ["单位"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "unit",
vAlign: 1,
hAlign: 1,
font: "Arial",
formatter: "@"
}
},
{
width: 80,
readOnly: locked,
head: {
titleNames: ["区间"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "interval",
vAlign: 1,
hAlign: 1,
font: "Arial",
formatter: "@"
}
},
]
},
headers: [
{ name: '项目指引', dataCode: 'name', width: 400, vAlign: 'center', hAlign: 'left', formatter: '@' },
{ name: '输出特征', dataCode: 'outputItemCharacter', width: 40, vAlign: 'center', hAlign: 'center' },
{ name: '必填', dataCode: 'required', width: 30, vAlign: 'center', hAlign: 'center' },
{ name: '材料', dataCode: 'isMaterial', width: 30, vAlign: 'center', hAlign: 'center' },
{ name: '默认', dataCode: 'isDefaultOption', width: 30, vAlign: 'center', hAlign: 'center' },
{ name: '单位', dataCode: 'unit', width: 40, vAlign: 'center', hAlign: 'center', formatter: '@' },
{ name: '区间', dataCode: 'interval', width: 80, vAlign: 'center', hAlign: 'center', formatter: '@' },
],
events: {
SelectionChanged: function (sender, info) {
guideItemInitSel(info.newSelections[0].row)
},
EditEnded: function (sender, args) {
edit(args.sheet, [{ row: args.row, col: args.col }]);
},
ButtonClicked: function (sender, args) {
edit(args.sheet, [{ row: args.row, col: args.col }]);
},
RangeChanged: function (sender, args) {
edit(args.sheet, args.changedCells);
},
CellDoubleClick: function (sender, args) {
locateAtRation(args.row);
},
EnterCell: function (sender, args) {
console.log(args.row);
}
}
};
//定额章节树
const section = {
dom: $('#sectionSpread'),
workBook: null,
cache: [],
tree: null,
controller: null,
treeSetting: {
treeCol: 0,
emptyRows: 0,
headRows: 1,
headRowHeight: [40],
defaultRowHeight: 21,
cols: [{
width: 400,
readOnly: true,
head: {
titleNames: ["名称"],
spanCols: [1],
spanRows: [1],
vAlign: [1],
hAlign: [1],
font: ["Arial"]
},
data: {
field: "name",
vAlign: 1,
hAlign: 0,
font: "Arial"
}
}]
},
headers: [
{ name: '名称', dataCode: 'name', width: 400, vAlign: 'center', hAlign: 'left', formatter: '@' },
],
events: {
SelectionChanged: function (sender, info) {
sectionInitSel(info.newSelections[0].row)
}
}
};
const ration = {
dom: $('#rationSpread'),
workBook: null,
datas: [],//所有的数据,搜索定额时,从所有数据中筛选
cache: [],//显示在表格上的数据,添加定额可以有效根据行识别定额
headers: [
{ name: '选择', dataCode: 'select', width: 50, vAlign: 'center', hAlign: 'center' },
{ name: '编码', dataCode: 'code', width: 110, vAlign: 'center', hAlign: 'left', formatter: '@' },
{ name: '名称', dataCode: 'name', width: 250, vAlign: 'center', hAlign: 'left', formatter: '@' },
{ name: '单位', dataCode: 'unit', width: 100, vAlign: 'center', hAlign: 'left', formatter: '@' }
],
events: {
ButtonClicked: function (sender, args) {
if (args.sheet.isEditing()) {
args.sheet.endEdit(true);
}
},
CellDoubleClick: function (sender, args) {
if (ration.headers[args.col].dataCode === 'name') {
let insertDatas = getInsertRations([args.row]);
if (insertDatas.length > 0) {
insert(insertDatas, false);
}
}
}
}
};
const options = {
workBook: {
tabStripVisible: false,
allowContextMenu: false,
allowCopyPasteExcelStyle: false,
allowExtendPasteRange: false,
allowUserDragDrop: false,
allowUserDragFill: false,
scrollbarMaxAlign: true
},
sheet: {
protectionOptions: { allowResizeRows: true, allowResizeColumns: true },
clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values
}
};
/* 清单材料表 */
const materialHeaders = [
{ name: '材料编码', dataCode: 'code', width: 90, vAlign: 'center', hAlign: 'left', formatter: '@' },
{ name: '材料名称', dataCode: 'name', width: 150, vAlign: 'center', hAlign: 'left', formatter: '@' },
{ name: '规格', dataCode: 'specs', width: 130, vAlign: 'center', hAlign: 'left', formatter: '@' }
];
const billMaterial = {
dom: $('#bill-material-spread'),
workBook: null,
cache: [],
headers: materialHeaders,
events: {
EditEnded: function (sender, args) {
editMaterials(args.sheet, [{ row: args.row, col: args.col }]);
},
RangeChanged: function (sender, args) {
editMaterials(args.sheet, args.changedCells);
},
}
}
/* 清单辅助材料录入表 */
const billMaterialHelper = {
dom: $('#bill-material-helper-spread'),
workBook: null,
cache: [],
headers: materialHeaders,
events: {
// 双击添加到清单材料表
CellDoubleClick: function (sender, args) {
// 模拟清单材料表编辑(共用同一个接口)
if (!billMaterialHelper.cache[args.row]) {
return;
}
const code = billMaterialHelper.cache[args.row].code;
const row = billMaterial.cache.length;
const targetSheet = billMaterial.workBook.getSheet(0);
targetSheet.setValue(row, 0, code);
const changedCells = [{ row, col: 0 }];
editMaterials(billMaterial.workBook.getSheet(0), changedCells);
}
}
}
/* 导出excel */
let exportExcelWorkBook = null;
// 显示清单材料数据
function showBillMaterialData(sheet, headers, datas, emptyRow = 0) {
let fuc = function () {
const rowCount = datas.length + emptyRow;
sheet.setRowCount(rowCount);
for (let col = 0, cLen = headers.length; col < cLen; col++) {
for (let row = 0; row < rowCount; row++) {
if (datas[row]) {
sheet.setValue(row, col, datas[row][headers[col]['dataCode']] || '');
} else {
sheet.setValue(row, col, '');
}
}
}
};
renderSheetFunc(sheet, fuc);
}
// 获取清单材料数据
async function getBillMaterials() {
if (!bills.tree.selected) {
return;
}
billMaterial.cache = [];
try {
$.bootstrapLoading.start();
const { billMaterials, allGljList } = await ajaxPost('/billsGuidance/api/getBillMaterials', { libID, billID: bills.tree.selected.data.ID });
billMaterial.cache = billMaterials;
console.log(allGljList);
sortByCode(billMaterial.cache);
billMaterialHelper.cache = allGljList
sortByCode(billMaterialHelper.cache);
} catch (error) {
$('#alert-info').text(error.message);
$('#alert').modal('show');
} finally {
showBillMaterialData(billMaterial.workBook.getSheet(0), billMaterial.headers, billMaterial.cache, 30);
billMaterial.workBook.getSheet(0).showRow(0, GC.Spread.Sheets.VerticalPosition.top);
showBillMaterialData(billMaterialHelper.workBook.getSheet(0), billMaterialHelper.headers, billMaterialHelper.cache);
billMaterialHelper.workBook.getSheet(0).showRow(0, GC.Spread.Sheets.VerticalPosition.top);
$.bootstrapLoading.end();
}
}
function getText(sheet, row, col) {
let text = sheet.getValue(row, col);
text = text ? text.toString().trim() : '';
return text;
}
// 编辑材料表
async function editMaterials(sheet, cells) {
let isChanged = false;
for (let cell of cells) {
const itemCode = billMaterial.cache[cell.row] && billMaterial.cache[cell.row].code || '';
if (itemCode !== getText(sheet, cell.row, 0)) {
isChanged = true;
}
}
if (!isChanged) {
return;
}
let gljCodes = new Set();
const count = sheet.getRowCount();
for (let row = 0; row < count; row++) {
const code = getText(sheet, row, 0);
if (code) {
gljCodes.add(code);
}
}
// 提交数据
try {
$.bootstrapLoading.start();
billMaterial.cache = await ajaxPost('/billsGuidance/api/editBillMaterials', { libID, billID: bills.tree.selected.data.ID, gljCodes: [...gljCodes], compilationID: curCompilationID }, undefined, true);
sortByCode(billMaterial.cache);
} catch (error) {
$('#alert-info').html(error);
$('#alert').modal('show');
} finally {
showBillMaterialData(billMaterial.workBook.getSheet(0), billMaterial.headers, billMaterial.cache, 30);
$.bootstrapLoading.end();
}
}
//渲染时方法,停止渲染
//@param {Object}sheet {Function}func @return {void}
function renderSheetFunc(sheet, func) {
sheet.suspendEvent();
sheet.suspendPaint();
if (func) {
func();
}
sheet.resumeEvent();
sheet.resumePaint();
}
//设置表选项
//@param {Object}workBook {Object}opts @return {void}
function setOptions(workBook, opts) {
for (let opt in opts.workBook) {
workBook.options[opt] = opts.workBook[opt];
}
for (let opt in opts.sheet) {
workBook.getActiveSheet().options[opt] = opts.sheet[opt];
}
}
//建表头
//@param {Object}sheet {Array}headers @return {void}
function buildHeader(sheet, headers) {
let fuc = function () {
sheet.setColumnCount(headers.length);
sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
for (let i = 0, len = headers.length; i < len; i++) {
sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
sheet.getCell(0, i, GC.Spread.Sheets.SheetArea.colHeader).wordWrap(true);
if (headers[i].formatter) {
sheet.setFormatter(-1, i, headers[i].formatter);
}
sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
}
};
renderSheetFunc(sheet, fuc);
}
//表监听事件
//@param {Object}workBook @return {void}
function bindEvent(workBook, events) {
if (Object.keys(events).length === 0) {
return;
}
const Events = GC.Spread.Sheets.Events;
for (let event in events) {
workBook.bind(Events[event], events[event]);
}
}
//建表
//@param {Object}module @return {void}
function buildSheet(module) {
if (!module.workBook) {
module.workBook = new GC.Spread.Sheets.Workbook(module.dom[0], { sheetCount: 1 });
let sheet = module.workBook.getActiveSheet();
if (module === bills) {
sheet.name('stdBillsGuidance_bills');
//默认初始可控制焦点在清单表中
module.workBook.focus();
sheet.options.isProtected = true;
}
else if (module === ration) {
sheet.options.isProtected = true;
sheet.getRange(-1, 0, -1, 1).locked(locked);
sheet.getRange(-1, 1, -1, -1).locked(true);
}
else if (module === guideItem) {
sheet.name('stdBillsGuidance_guidance');
sheetCommonObj.bindEscKey(module.workBook, [{ sheet: sheet, editStarting: null, editEnded: module.events.EditEnded }]);
}
else if (module === billMaterial) {
sheet.options.isProtected = true;
sheet.getRange(-1, 0, -1, 1).locked(locked);
sheet.getRange(-1, 1, -1, -1).locked(true);
sheet.getRange(-1, 2, -1, -1).locked(true);
}
else if (module === billMaterialHelper) {
sheet.options.isProtected = true;
}
setOptions(module.workBook, options);
buildHeader(module.workBook.getActiveSheet(), module.headers);
bindEvent(module.workBook, module.events);
}
lockUtil.lockSpreads([module.workBook], locked);
if (locked) {
// 锁定表格后双击事件失效了,但是需要双击定位,因此重新绑定双击
if (module === guideItem) {
module.workBook.bind('CellDoubleClick', module.events.CellDoubleClick);
}
}
}
//清空表数据
//@param {Object}sheet {Array}headers {Number}rowCount @return {void}
function cleanData(sheet, headers, rowCount) {
renderSheetFunc(sheet, function () {
sheet.clear(-1, 0, -1, headers.length, GC.Spread.Sheets.SheetArea.viewport, GC.Spread.Sheets.StorageType.data);
if (rowCount >= 0) {
sheet.setRowCount(rowCount);
}
});
}
//根据清单获取项目指引
//@param {String}guidanceLibID {Number}billsID {Function}callback @return {void}
function getItemsByBills(guidanceLibID, billsID, callback) {
CommonAjax.post('/billsGuidance/api/getItemsByBills', { guidanceLibID: guidanceLibID, billsID: billsID }, function (rstData) {
if (callback) {
callback(rstData);
}
});
}
//清单表焦点控制
//@param {Number}row @return {void}
function billsInitSel(row, oldSel, force = false) {
let guideSheet = guideItem.workBook.getActiveSheet();
cleanData(guideSheet, guideItem.headers, -1);
let node = bills.tree.items[row];
if (!node) {
$('#editMaterial').addClass('disabled');
return;
}
const billSheet = bills.workBook.getActiveSheet();
setBgColor(billSheet, row, selectedBgColor);
if (oldSel && row !== oldSel.row) {
const orgNode = bills.tree.items[oldSel.row]
setBgColor(billSheet, oldSel.row, orgNode && orgNode.isSearch ? searchBgColor : 'white');
}
bills.tree.selected = node;
$('#editMaterial').removeClass('disabled');
//显示备注
$('.main-side-bottom').find('textarea').val(node.data.comment ? node.data.comment : '');
if (!node.guidance.tree || force) {
getItemsByBills(libID, node.data.ID, function (rstData) {
initTree(node.guidance, guideSheet, guideItem.treeSetting, rstData);
setNodesExpandState(node.guidance.tree.items, curExpandState);
setProcessNodes(guideSheet, node.guidance.tree.items);
renderSheetFunc(guideSheet, function () {
TREE_SHEET_HELPER.refreshNodesVisible(node.guidance.tree.roots, guideSheet, true);
});
//设置底色
setNodesColor(guideSheet, node.guidance.tree.items);
//项目指引初始焦点
guideItemInitSel(guideSheet.getActiveRowIndex() ? guideSheet.getActiveRowIndex() : 0);
});
} else {
setNodesExpandState(node.guidance.tree.items, curExpandState);
node.guidance.controller.showTreeData();
setProcessNodes(guideSheet, node.guidance.tree.items);
//设置底色
setNodesColor(guideSheet, node.guidance.tree.items);
//项目指引初始焦点
guideItemInitSel(guideSheet.getActiveRowIndex() ? guideSheet.getActiveRowIndex() : 0);
}
}
function showCheckBox(sheet, nodes) {
// const checkBoxType = locked ? sheetCommonObj.getReadOnlyCheckBox() : sheetCommonObj.getCheckBox();
const checkBoxType = new GC.Spread.Sheets.CellTypes.CheckBox();
const baseType = new GC.Spread.Sheets.CellTypes.Base();
const outputItemCol = guideItem.headers.findIndex(item => item.dataCode === 'outputItemCharacter');
const requiredCol = guideItem.headers.findIndex(item => item.dataCode === 'required');
const materialCol = guideItem.headers.findIndex(item => item.dataCode === 'isMaterial');
const defaultOption = guideItem.headers.findIndex(item => item.dataCode === 'isDefaultOption');
renderSheetFunc(sheet, function () {
nodes.forEach(node => {
const row = node.serialNo();
if (isOptionNode(node)) {
sheet.setCellType(row, defaultOption, checkBoxType);
sheet.setValue(row, defaultOption, node.data.isDefaultOption || false);
} else {
sheet.setCellType(row, defaultOption, baseType);
sheet.setValue(row, defaultOption, '');
}
if (isProcessNode(node)) {
sheet.setCellType(row, outputItemCol, checkBoxType);
sheet.setCellType(row, requiredCol, checkBoxType);
sheet.setCellType(row, materialCol, checkBoxType);
sheet.setValue(row, outputItemCol, node.data.outputItemCharacter || false);
sheet.setValue(row, requiredCol, node.data.required || false);
sheet.setValue(row, materialCol, node.data.isMaterial || false);
} else {
sheet.setCellType(row, outputItemCol, baseType);
sheet.setCellType(row, requiredCol, baseType);
sheet.setCellType(row, materialCol, baseType);
sheet.setValue(row, outputItemCol, '');
sheet.setValue(row, requiredCol, '');
sheet.setValue(row, materialCol, '');
}
})
});
}
function setReadOnly(sheet, nodes) {
if (locked) {
return;
}
// 单位仅特征/工序行可输入
// 区间仅仅选项行可输入
const unitCol = guideItem.headers.findIndex(item => item.dataCode === 'unit');
const intervalCol = guideItem.headers.findIndex(item => item.dataCode === 'interval');
renderSheetFunc(sheet, function () {
nodes.forEach(node => {
const row = node.serialNo();
sheet.getCell(row, unitCol).locked(!isProcessNode(node));
sheet.getCell(row, intervalCol).locked(!isOptionNode(node));
});
});
}
// 设置选项行相关
function setProcessNodes(sheet, nodes) {
showCheckBox(sheet, nodes);
setReadOnly(sheet, nodes);
}
//设置项目节点展开收起状态:展开全部、收起定额
//@param {Array}nodes(当前清单下的所有项目指引节点) {Number}expandState(展开全部1或收起定额0).
function setNodesExpandState(nodes, expandState) {
if (expandState === itemExpandState.contract) {
//找出所有定额的父节点
let rations = _.filter(nodes, function (node) {
return node.data.type === itemType.ration;
});
let rationParentIDs = [];
for (let ration of rations) {
if (ration.data.ParentID != -1) {
rationParentIDs.push(ration.data.ParentID);
}
}
rationParentIDs = Array.from(new Set(rationParentIDs));
let rationParentNodes = _.filter(nodes, function (node) {
return rationParentIDs.includes(node.data.ID);
});
//收起定额
for (let node of rationParentNodes) {
node.setExpanded(false);
}
} else {
for (let node of nodes) {
node.setExpanded(true);
}
}
}
// 设置行底色
function setBgColor(sheet, row, color) {
const style = new GC.Spread.Sheets.Style();
style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
style.borderRight = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
style.borderBottom = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
style.backColor = color;
sheet.setStyle(row, -1, style);
}
//根据奇偶层级设置节点底色,奇数层为蓝色(树节点深度为偶数)
//@param {Object}sheet {Array}nodes @return {void}
function setNodesColor(sheet, nodes) {
renderSheetFunc(sheet, function () {
for (let node of nodes) {
const color = isProcessNode(node) ? selectedBgColor : 'White';
setBgColor(sheet, node.serialNo(), color);
}
});
}
//选中的节点是否全是同层节点
//@param {Object}sheet {Array}items @return {Boolean}
function itemsSameDepth(sheet, items) {
let sels = sheet.getSelections();
if (sels.length === 0 || items.length === 0) {
return false;
}
let depths = [];
for (let i = 0; i < sels[0].rowCount; i++) {
let row = sels[0].row + i;
let node = items[row];
if (node) {
depths.push(node.depth());
}
}
}
//节点子项是否全是工作内容
//@param {Object}node @return {Boolean}
function allJobChildren(node) {
for (let c of node.children) {
if (c.data.type === itemType.ration) {
return false;
}
}
return true;
}
//节点子项是否全是定额
//@param {Object}node @return {Boolean}
function allRationChildren(node) {
for (let c of node.children) {
if (c.data.type === itemType.job) {
return false;
}
}
return true;
}
//刷新按钮有效性
//@param {Object}node @return {void}
function refreshBtn(node) {
if (locked) {
return;
}
//全部设为无效
$('.tools-btn').children().addClass('disabled');
$('#generate-class').removeClass('disabled');
$('#insertRation').addClass('disabled');
$('#insertAll').addClass('disabled');
$('.main-bottom-content').find('textarea').attr('readonly', true);
//插入
if (bills.tree.selected && bills.tree.selected.guidance.tree) {
$('#insert').removeClass('disabled');
if (node && node.data.type === itemType.ration) {
$('#insert').addClass('disabled');
}
}
//删除
if (node) {
$('#del').removeClass('disabled');
}
if (node && node.data.type === itemType.job) {
//升级
if (node.parent) {
$('#upLevel').removeClass('disabled');
if (node.nextSibling && node.children.length > 0 && !allJobChildren(node)) {
$('#upLevel').addClass('disabled');
}
}
//降级
if (node.preSibling) {
$('#downLevel').removeClass('disabled');
if (node.preSibling.children.length > 0 && !allJobChildren(node.preSibling)) {
$('#downLevel').addClass('disabled');
}
}
}
//上移
if (node && node.preSibling) {
$('#upMove').removeClass('disabled')
}
//下移
if (node && node.nextSibling) {
$('#downMove').removeClass('disabled');
}
//收起定额、展开全部
$('#expandContract').removeClass('disabled');
//插入定额
if (node && (node.children.length === 0 || allRationChildren(node))) {
$('#insertRation').removeClass('disabled');
$('#insertAll').removeClass('disabled');
}
//备注,奇数节点可用
if (isProcessNode(node)) {
$('.main-bottom-content').find('textarea').attr('readonly', false);
}
// 配置材料
$('#editMaterial').removeClass('disabled');
}
//项目指引表焦点控制
//@param {Number}row @return {void}
function guideItemInitSel(row) {
let billsNode = bills.tree.selected;
let node = null;
if (billsNode && billsNode.guidance.tree) {
node = billsNode.guidance.tree.items[row];
if (node) {
billsNode.guidance.tree.selected = node;
//显示备注
$('.main-bottom-content').find('textarea').val(node.data.comment ? node.data.comment : '');
}
}
refreshBtn(node);
}
//初始化当前库名
//@param {String} @return {void}
function initLibName(libName) {
$('#libName')[0].outerHTML = $('#libName')[0].outerHTML.replace("XXX清单指引", libName);
}
//初始化各工作表
//@param {Array}modules @return {void}
function initWorkBooks(modules) {
exportExcelWorkBook = new GC.Spread.Sheets.Workbook($('#excel-spread')[0], { sheetCount: 1 });
for (let module of modules) {
buildSheet(module);
}
}
function tipDivCheck() {
setTimeout(function () {
let tips = $('#autoTip');
if (ration.tipDiv == 'show') {
return;
} else if (ration.tipDiv == 'hide' && tips) {
tips.hide();
ration._toolTipElement = null;
}
}, 600)
}
//获取悬浮提示单元格
//@param {Object}sheet @return {Object}
function getTipCellType(sheet) {
let setting = {};
let TipCellType = function () { };
TipCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
TipCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
return {
x: x,
y: y,
row: context.row,
col: context.col,
cellStyle: cellStyle,
cellRect: cellRect,
sheet: context.sheet,
sheetArea: context.sheetArea
};
};
TipCellType.prototype.processMouseEnter = function (hitinfo) {
let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
if (tag !== undefined && tag) {
text = tag;
}
if (sheet && sheet.getParent().qo) {
setting.pos = SheetDataHelper.getObjPos(sheet.getParent().qo);
}
let delayTimes = 500; //延时时间
let now_timeStamp = +new Date();
this.tipTimeStamp = now_timeStamp;
let me = this;
setTimeout(function () {
if (now_timeStamp - me.tipTimeStamp == 0) {//鼠标停下的时候才显示
if (setting.pos && text && text !== '') {
//固定不显示的div,存储文本获取固定div宽度,toolTipElement由于显示和隐藏,获取宽度不正确
if (!me._fixedTipElement) {
let div = $('#fixedTip1')[0];
if (!div) {
div = document.createElement("div");
$(div).css("padding", 5)
.attr("id", 'fixedTip');
$(div).hide();
document.body.insertBefore(div, null);
}
me._fixedTipElement = div;
}
$(me._fixedTipElement).width('');
$(me._fixedTipElement).html(text);
if (!me._toolTipElement) {
let div = $('#autoTip1')[0];
if (!div) {
div = document.createElement("div");
$(div).css("position", "absolute")
.css("border", "1px #C0C0C0 solid")
.css("box-shadow", "1px 2px 5px rgba(0,0,0,0.4)")
.css("font", "0.9rem Calibri")
.css("padding", 5)
.css("background", '#303133')
.css("color", '#fff')
.attr("id", 'autoTip1');
$(div).hide();
document.body.insertBefore(div, null);
}
me._toolTipElement = div;
$(me._toolTipElement).width('');
//实时读取位置信息
if (hitinfo.sheet && hitinfo.sheet.getParent().qo) {
setting.pos = SheetDataHelper.getObjPos(hitinfo.sheet.getParent().qo);
}
$(me._toolTipElement).html(text);
//定额库定额特殊处理
if ($(hitinfo.sheet.getParent().qo).attr('id') === 'rationSpread') {
let divWidth = $(me._fixedTipElement).width(),
divHeight = $(me._fixedTipElement).height();
if (divWidth > 600) {
divWidth = 590;
$(me._toolTipElement).width(divWidth);
}
let top = setting.pos.y + hitinfo.y - divHeight < 0 ? 0 : setting.pos.y + hitinfo.cellRect.y - divHeight;
$(me._toolTipElement).css("top", top).css("left", setting.pos.x - divWidth);
}
else {
$(me._toolTipElement).css("top", setting.pos.y + hitinfo.y + 15).css("left", setting.pos.x + hitinfo.x + 15);
}
//名称
if (hitinfo.col === 2) {
let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
zoom = hitinfo.sheet.zoom();
let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
let textLength = me.getAutoFitWidth(value, text, acStyle, zoom, { sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport });
let cellWidth = hitinfo.sheet.getCell(-1, hitinfo.col).width();
if (textLength > cellWidth) {
$(me._toolTipElement).css("top", setting.pos.y + hitinfo.y + 15).css("left", setting.pos.x + hitinfo.x + 15);
$(me._toolTipElement).show("fast");
ration.tipDiv = 'show';//做个标记
}
}
else {
$(me._toolTipElement).show("fast");
ration.tipDiv = 'show';//做个标记
}
}
}
}
}, delayTimes);
};
TipCellType.prototype.processMouseLeave = function (hininfo) {
this.tipTimeStamp = +new Date();
ration.tipDiv = 'hide';
if (this._toolTipElement) {
$(this._toolTipElement).hide();
this._toolTipElement = null;
}
tipDivCheck();//延时检查:当tips正在show的时候,就调用了hide方法,会导致tips一直存在,所以设置一个超时处理
}
return new TipCellType();
}
//输出表数据(定额表)
//@param {Object}sheet {Array}headers {Array}datas @return {void}
function showData(sheet, headers, datas) {
let fuc = function () {
sheet.setRowCount(datas.length);
//复选框
let checkBoxType = new GC.Spread.Sheets.CellTypes.CheckBox();
let tipCellType = getTipCellType(sheet);
sheet.setCellType(-1, 0, checkBoxType);
for (let col = 0, cLen = headers.length; col < cLen; col++) {
for (let row = 0, rLen = datas.length; row < rLen; row++) {
sheet.setValue(row, col, datas[row][headers[col]['dataCode']]);
if (col === 1) {
sheet.setTag(row, col, datas[row]['hint']);
}
}
}
sheet.setCellType(-1, 1, tipCellType);
sheet.setCellType(-1, 2, tipCellType);
};
renderSheetFunc(sheet, fuc);
}
//根据定额章节树ID获取定额(从数据缓存中获取,定额数据一开始一次性拉取)
//@param {Number}sectionId {Array}rations @return {Array}
function getRationsBySectionId(sectionId, rations) {
if (!sectionId || !rations) {
return [];
}
return _.filter(rations, { sectionId });
}
//定额章节树焦点控制
//@param {Number}row @return {void}
function sectionInitSel(row) {
let rationSheet = ration.workBook.getActiveSheet();
let sectionNode = section.tree ? section.tree.items[row] : null;
if (sectionNode && sectionNode.children.length === 0) {
let sectionRations = getRationsBySectionId(sectionNode.data.ID, ration.datas);
ration.cache = sectionRations;
showData(rationSheet, ration.headers, sectionRations);
}
else {
cleanData(rationSheet, ration.headers, 0);
}
}
//初始化定额条目
//@param {Number}rationLibId @return {void}
function initRationItems(rationLibId, successCb) {
$.bootstrapLoading.start();
//获取定额章节树
let sectionSheet = section.workBook.getActiveSheet();
CommonAjax.post('/rationRepository/api/getRationTree', { rationLibId: rationLibId }, function (sectionDatas) {
//获取所有定额数据
let reqEntity = { rationLibId: rationLibId, showHint: true, returnFields: '-_id code ID sectionId name unit basePrice rationGljList jobContent annotation' };
CommonAjax.post('/rationRepository/api/getRationItemsByLib', reqEntity, function (rstData) {
section.cache = sectionDatas;
initTree(section, section.workBook.getActiveSheet(), section.treeSetting, sectionDatas);
//初始焦点在第一行(切换库)
sectionSheet.setActiveCell(0, 0);
sortByCode(rstData);
/* rstData.sort(function (a, b) {
let rst = 0;
if(a.code > b.code){
rst = 1;
}
else if(a.code < b.code){
rst = -1;
}
return rst;
}); */
ration.datas = rstData;
sectionInitSel(0);
$.bootstrapLoading.end();
if (successCb) {
successCb();
}
}, function () {
$.bootstrapLoading.end();
});
}, function () {
$.bootstrapLoading.end();
});
}
// 可用的定额库ID
const rationLibIDs = [];
//初始化定额库选择
//@param {String}compilationId @return {void}
function initRationLibs(compilationId) {
CommonAjax.post('/rationRepository/api/getRationLibsByCompilation', { compilationId: compilationId }, function (rstData) {
$('#rationLibSel').empty();
for (let rationLib of rstData) {
rationLibIDs.push(+rationLib.ID);
let opt = ``;
$('#rationLibSel').append(opt);
}
//初始选择
initRationItems(parseInt($('#rationLibSel').select().val()));
$('#rationLibSel').change(function () {
let rationLibId = parseInt($(this).select().val());
initRationItems(rationLibId);
})
});
}
// 变更定额库
function changeRationLib(libID, successCb) {
$('#rationLibSel').val(libID);
initRationItems(libID, successCb);
}
// 设置清单名称文本色
function setBillsForeColor(billsNodes) {
const sheet = bills.workBook.getActiveSheet();
renderSheetFunc(sheet, function () {
for (let bills of billsNodes) {
const row = bills.serialNo();
sheet.setStyle(row, 1, { foreColor: bills.data.hasGuide ? 'darkgreen' : 'black' });
}
});
}
//清单设置悬浮提示信息
//@param {Array}billsNodes(清单节点) {Array}jobs(总的工作内容数据) {Array}items(总的项目特征数据)
function setBillsHint(billsNodes, jobs, items) {
let jobsMapping = {},
itemsMapping = {};
for (let job of jobs) {
jobsMapping[job.id] = job;
}
for (let item of items) {
itemsMapping[item.id] = item;
}
let tagInfo = [];
for (let billsNode of billsNodes) {
let hintArr = [];
let billsItems = billsNode.data.items;
if (billsItems.length > 0) {
//项目特征
hintArr.push('项目特征:');
}
let itemCount = 1,
jobCount = 1;
for (let billsItem of billsItems) {
let itemData = itemsMapping[billsItem.id];
if (itemData) {
//特征值
let eigens = [];
for (let eigen of itemData.itemValue) {
eigens.push(eigen.value);
}
eigens = eigens.join(';');
hintArr.push(`${itemCount}.${itemData.content}${eigens === '' ? '' : ': ' + eigens}`);
itemCount++;
}
}
//工作内容
let billsJobs = billsNode.data.jobs;
if (billsJobs.length > 0) {
hintArr.push('工作内容:');
}
for (let billsJob of billsJobs) {
let jobData = jobsMapping[billsJob.id];
if (jobData) {
hintArr.push(`${jobCount}.${jobData.content}`);
jobCount++;
}
}
/*if(billsNode.data.ruleText && billsNode.data.ruleText !== ''){
hintArr.push('工程量计算规则:');
hintArr.push(billsNode.data.ruleText);
}
if(billsNode.data.recharge && billsNode.data.recharge !== ''){
hintArr.push('补注:');
hintArr.push(billsNode.data.recharge);
}*/
if (hintArr.length > 0) {
tagInfo.push({ row: billsNode.serialNo(), value: hintArr.join('\n') });
}
}
let sheet = bills.workBook.getActiveSheet();
renderSheetFunc(sheet, function () {
for (let tagI of tagInfo) {
sheet.setTag(tagI.row, 0, tagI.value);
}
});
}
//初始化清单的工作内容和项目特征
//@param {Number}billsLibId {Function}callback @return {void}
function initJobAndCharacter(billsLibId, callback) {
CommonAjax.post('/stdBillsEditor/getJobContent', { billsLibId: billsLibId }, function (datas) {
stdBillsJobData = datas;
CommonAjax.post('/stdBillsEditor/getItemCharacter', { billsLibId: billsLibId }, function (datas) {
stdBillsFeatureData = datas;
if (callback) {
callback();
}
});
});
}
let billsLibId = 0;
//获取指引库信息及关联的清单
//@param {Number}libID {Function}callback @return {Object}
function getLibWithBills(libID, callback) {
CommonAjax.post('/billsGuidance/api/getLibWithBills', { libID: libID }, function (rstData) {
billsLibId = rstData.guidanceLib.billsLibId;
initRationLibs(rstData.guidanceLib.compilationId);
curCompilationID = rstData.guidanceLib.compilationId;
bills.cache = rstData.bills;
initLibName(rstData.guidanceLib.name);
/*initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, bills.cache);
//每一棵项目指引树挂在清单节点上
for(let node of bills.tree.items){
node.guidance = {tree: null, controller: null};
}
//默认初始节点
billsInitSel(0);
if(callback){
callback(rstData);
}*/
let initDataCallback = function () {
initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, bills.cache);
//每一棵项目指引树挂在清单节点上
for (let node of bills.tree.items) {
node.guidance = { tree: null, controller: null };
}
//默认初始节点
billsInitSel(0);
if (callback) {
callback(rstData);
}
};
initJobAndCharacter(rstData.guidanceLib.billsLibId, initDataCallback);
}, function (msg) {
window.location.href = '/billsGuidance/main';
});
}
//初始化并输出树
//@param {Object}module {Object}sheet {Object}treeSetting {Array}datas
function initTree(module, sheet, treeSetting, datas) {
module.tree = idTree.createNew({ id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true });
module.controller = TREE_SHEET_CONTROLLER.createNew(module.tree, sheet, treeSetting);
module.tree.loadDatas(datas);
if (module === bills) {
module.tree.roots.forEach(root => {
root.setExpanded(false);
})
}
module.controller.showTreeData();
if (module === bills) {
setBillsHint(bills.tree.items, stdBillsJobData, stdBillsFeatureData);
setBillsForeColor(bills.tree.items);
}
}
//更新清单备注
function updateBillsComment(updateData, callback, errCB) {
CommonAjax.post('/stdBillsEditor/updateBills', updateData, function () {
if (callback) {
callback();
}
}, function () {
if (errCB) {
errCB();
}
});
}
//更新项目指引
//@param {Array}updateDatas {Function}callback @return {void}
function updateGuideItems(updateDatas, callback, errCB) {
CommonAjax.post('/billsGuidance/api/updateItems', { updateDatas: updateDatas }, function (rstData) {
if (callback) {
callback(rstData);
}
}, function () {
if (errCB) {
errCB();
}
$.bootstrapLoading.end();
});
}
//编辑后自动去除换行符回车符
const deESC = /[\n]/g;
//项目指引编辑
//@param {Object}sheet {Array}cells
function edit(sheet, cells) {
let updateDatas = [];
//同步节点数据
let syncDatas = [];
for (let cell of cells) {
const field = guideItem.headers[cell.col].dataCode;
let node = bills.tree.selected.guidance.tree.items[cell.row];
if (field === 'name' || field === 'unit' || field === 'interval') {
let text = sheet.getValue(cell.row, cell.col);
text = text ? text.toString() : '';
text = text.replace(deESC, '');
sheet.setValue(cell.row, cell.col, text);
if (node.data[field] != text) {
syncDatas.push({ node: node, text: text, field, cell });
updateDatas.push({ updateType: updateType.update, findData: { ID: node.getID() }, updateData: { [field]: text } });
}
} else if (field === 'outputItemCharacter' || field === 'required' || field === 'isMaterial' || field === 'isDefaultOption') {
const val = !sheet.getValue(cell.row, cell.col);
sheet.setValue(cell.row, cell.col, val);
syncDatas.push({ node: node, text: val, field, cell });
updateDatas.push({ updateType: updateType.update, findData: { ID: node.getID() }, updateData: { [field]: val } });
}
}
if (updateDatas.length > 0) {
updateGuideItems(updateDatas, function () {
for (let syncData of syncDatas) {
syncData.node.data[syncData.field] = syncData.text;
}
}, function () {
//失败恢复
renderSheetFunc(sheet, function () {
for (let syncData of syncDatas) {
sheet.setValue(syncData.node.serialNo(), syncData.cell.col, syncData.node.data[syncData.field] ? syncData.node.data[syncData.field] : '');
}
});
});
}
}
//项目指引插入,支持一次插入多条数据
//@param {Array}datas {Boolean}tobeChild(插入成为子项) {Function}callback @return {void}
function insert(datas, tobeChild, callback = null) {
$.bootstrapLoading.start();
let sheet = guideItem.workBook.getActiveSheet();
let controller = bills.tree.selected.guidance.controller;
let selected = bills.tree.selected.guidance.tree.selected;
let updateDatas = [];
//建立数组下标索引
let newDataIndex = {};
for (let i = 0; i < datas.length; i++) {
let newNodeData = {
libID: libID, ID: uuid.v1(), ParentID: selected ? selected.getParentID() : -1, NextSiblingID: selected ? selected.getNextSiblingID() : -1,
billsID: bills.tree.selected.getID(),
outputItemCharacter: true,
};
//定额类型插入当前工作内容焦点行,
if (selected && ((selected.data.type === itemType.job && datas[i].type === itemType.ration) || tobeChild)) {
newNodeData.ParentID = selected.getID();
newNodeData.NextSiblingID = -1;
}
Object.assign(newNodeData, datas[i]);
newDataIndex[i] = newNodeData;
}
for (let i = 0; i < datas.length; i++) {
//第一个节点
if (i === 0) {
//非插入成子节点,更新选中节点NestSiblingID
if (selected && !((selected.data.type === itemType.job && datas[i].type === itemType.ration) || tobeChild)) {
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.getID() }, updateData: { NextSiblingID: newDataIndex[i].ID } });
}
}
//非最后一个节点
if (i !== datas.length - 1) {
newDataIndex[i].NextSiblingID = newDataIndex[i + 1].ID;
}
updateDatas.push({ updateType: updateType.create, updateData: newDataIndex[i] });
}
updateGuideItems(updateDatas, function () {
const outputItemCol = guideItem.headers.findIndex(item => item.dataCode === 'outputItemCharacter');
for (let updateData of updateDatas) {
if (updateData.updateType === updateType.create) {
let newNode = controller.insertByIDS(updateData.updateData.ID, updateData.updateData.ParentID, updateData.updateData.NextSiblingID);
//同步data
Object.assign(newNode.data, updateData.updateData);
const row = newNode.serialNo();
sheet.setValue(row, 0, newNode.data.name);
if (newNode.data.outputItemCharacter !== undefined) {
sheet.setValue(row, outputItemCol, newNode.data.outputItemCharacter);
}
setProcessNodes(sheet, [newNode]);
refreshBtn(newNode);
}
}
if (!bills.tree.selected.data.hasGuide && bills.tree.selected.guidance.tree.items.length) {
bills.tree.selected.data.hasGuide = true;
setBillsForeColor([bills.tree.selected]);
}
if (callback) {
callback();
}
setNodesColor(sheet, bills.tree.selected.guidance.tree.items);
guideItem.workBook.focus(true);
$.bootstrapLoading.end();
});
}
// 删除定额(嵌套删除自身及后代定额)
function delRations() {
const selected = bills.tree.selected.guidance.tree.selected;
if (!selected) {
return;
}
if (selected.data.type === itemType.ration) {
del({ row: selected.serialNo(), col: 0, rowCount: 1, colCount: 1 });
return;
}
const rations = selected.getPosterity().filter(item => item.data.type === itemType.ration);
if (!rations.length) {
return;
}
const updateDatas = rations.map(item => ({ updateType: updateType.del, findData: { ID: item.data.ID } }));
const rationIDs = rations.map(r => r.data.ID);
$.bootstrapLoading.start();
updateGuideItems(updateDatas, function () {
const guideSheet = guideItem.workBook.getSheet(0);
const treeNodes = bills.tree.selected.guidance.tree.items.filter(item => !rationIDs.includes(item.data.ID));
const state = bills.tree.selected.guidance.tree.getExpState(treeNodes);
const treeData = treeNodes.map(item => item.data);
initTree(bills.tree.selected.guidance, guideSheet, guideItem.treeSetting, treeData);
bills.tree.selected.guidance.tree.setExpandedByState(bills.tree.selected.guidance.tree.items, state);
renderSheetFunc(guideSheet, function () {
TREE_SHEET_HELPER.refreshNodesVisible(bills.tree.selected.guidance.tree.roots, guideSheet, true);
});
//设置底色
setNodesColor(guideSheet, bills.tree.selected.guidance.tree.items);
//项目指引初始焦点
guideItemInitSel(guideSheet.getActiveRowIndex() ? guideSheet.getActiveRowIndex() : 0);
$.bootstrapLoading.end();
guideItem.workBook.focus(true)
});
}
//项目指引删除操作
//@return {void}
function del(selArea = null) {
$.bootstrapLoading.start();
let controller = bills.tree.selected.guidance.controller;
let selNodes = [];
let sheet = guideItem.workBook.getSheet(0);
let sel = selArea ? selArea : sheet.getSelections()[0];
if (sel) {
sel.row = sel.row === -1 ? 0 : sel.row;
for (let i = 0; i < sel.rowCount; i++) {
if (bills.tree.selected.guidance.tree.items[sel.row + i]) {
selNodes.push(bills.tree.selected.guidance.tree.items[sel.row + i]);
}
}
}
//选中的块节点
let blockNodes = getBlockNodes(selNodes);
let updateDatas = [];
function getDelDatas(nodes) {
for (let node of nodes) {
updateDatas.push({ updateType: updateType.del, findData: { ID: node.getID() } });
if (node.children.length > 0) {
getDelDatas(node.children);
}
}
}
getDelDatas(blockNodes);
//更新相关的前节点
for (let node of blockNodes) {
if (node.preSibling && !blockNodes.includes(node.preSibling)) {
let next = node;
while (next.nextSibling && blockNodes.includes(next.nextSibling)) {
next = next.nextSibling;
}
updateDatas.push({ updateType: updateType.update, findData: { ID: node.preSibling.getID() }, updateData: { NextSiblingID: next.getNextSiblingID() } });
}
}
updateGuideItems(updateDatas, function () {
console.log(blockNodes);
controller.m_delete(blockNodes);
guideItemInitSel(sheet.getActiveRowIndex());
refreshBtn(bills.tree.selected.guidance.tree.selected);
setNodesColor(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
setProcessNodes(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
if (bills.tree.selected.data.hasGuide && !bills.tree.selected.guidance.tree.items.length) {
bills.tree.selected.data.hasGuide = false;
setBillsForeColor([bills.tree.selected]);
}
$.bootstrapLoading.end();
guideItem.workBook.focus(true)
});
}
//项目指引升级
//@return {void}
function upLevel() {
$.bootstrapLoading.start();
let controller = bills.tree.selected.guidance.controller;
let selected = bills.tree.selected.guidance.tree.selected;
let updateDatas = [];
//更新父节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.getParentID() }, updateData: { NextSiblingID: selected.getID() } });
//更新选中节点
updateDatas.push({
updateType: updateType.update, findData: { ID: selected.getID() },
updateData: { ParentID: selected.parent.getParentID(), NextSiblingID: selected.parent.getNextSiblingID(), unit: '', interval: '' }
});
if (selected.nextSibling && selected.children.length > 0) {
//更新选中节点最末子节点
let lastChild = selected.children[selected.children.length - 1];
updateDatas.push({ updateType: updateType.update, findData: { ID: lastChild.getID() }, updateData: { NextSiblingID: -1 } });
}
//选中节点的所有后兄弟节点成为选中节点的子项
let selectedNextIDs = [];
let sNext = selected.nextSibling;
while (sNext) {
selectedNextIDs.push(sNext.getID());
sNext = sNext.nextSibling;
}
for (let sID of selectedNextIDs) {
updateDatas.push({ updateType: updateType.update, findData: { ID: sID }, updateData: { ParentID: selected.getID() } });
}
updateGuideItems(updateDatas, function () {
controller.upLevel();
const sheet = guideItem.workBook.getActiveSheet();
refreshBtn(bills.tree.selected.guidance.tree.selected);
setNodesColor(sheet, bills.tree.selected.guidance.tree.items);
setProcessNodes(sheet, bills.tree.selected.guidance.tree.items);
const unitCol = guideItem.headers.findIndex(item => item.dataCode === 'unit');
const intervalCol = guideItem.headers.findIndex(item => item.dataCode === 'interval');
sheet.setValue(selected.serialNo(), unitCol, '');
sheet.setValue(selected.serialNo(), intervalCol, '');
$.bootstrapLoading.end();
guideItem.workBook.focus(true)//31574
});
}
//项目指引降级
//@return {void}
function downLevel() {
$.bootstrapLoading.start();
let controller = bills.tree.selected.guidance.controller;
let selected = bills.tree.selected.guidance.tree.selected;
let updateDatas = [];
//更新前兄弟节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.preSibling.getID() }, updateData: { NextSiblingID: selected.getNextSiblingID() } });
//更新前兄弟节点最末子节点
if (selected.preSibling.children.length > 0) {
let lastChild = selected.preSibling.children[selected.preSibling.children.length - 1];
updateDatas.push({ updateType: updateType.update, findData: { ID: lastChild.getID() }, updateData: { NextSiblingID: selected.getID() } });
}
//更新选中节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.getID() }, updateData: { ParentID: selected.preSibling.getID(), NextSiblingID: -1, unit: '', interval: '' } });
updateGuideItems(updateDatas, function () {
controller.downLevel();
const sheet = guideItem.workBook.getActiveSheet();
refreshBtn(bills.tree.selected.guidance.tree.selected);
setNodesColor(sheet, bills.tree.selected.guidance.tree.items);
setProcessNodes(sheet, bills.tree.selected.guidance.tree.items);
const unitCol = guideItem.headers.findIndex(item => item.dataCode === 'unit');
const intervalCol = guideItem.headers.findIndex(item => item.dataCode === 'interval');
sheet.setValue(selected.serialNo(), unitCol, '');
sheet.setValue(selected.serialNo(), intervalCol, '');
$.bootstrapLoading.end();
guideItem.workBook.focus(true)
});
}
//项目指引上移
//@return {void}
function upMove() {
$.bootstrapLoading.start();
let controller = bills.tree.selected.guidance.controller;
let selected = bills.tree.selected.guidance.tree.selected;
let updateDatas = [];
//更新前节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.preSibling.getID() }, updateData: { NextSiblingID: selected.getNextSiblingID() } });
//更新前前节点
if (selected.preSibling.preSibling) {
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.preSibling.preSibling.getID() }, updateData: { NextSiblingID: selected.getID() } });
}
//更新选中节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.getID() }, updateData: { NextSiblingID: selected.preSibling.getID() } });
updateGuideItems(updateDatas, function () {
controller.upMove();
refreshBtn(bills.tree.selected.guidance.tree.selected);
setNodesColor(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
setProcessNodes(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
$.bootstrapLoading.end();
guideItem.workBook.focus(true)
});
}
//项目指引下移
//@return {void}
function downMove() {
$.bootstrapLoading.start();
let controller = bills.tree.selected.guidance.controller;
let selected = bills.tree.selected.guidance.tree.selected;
let updateDatas = [];
//更新下节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.getNextSiblingID() }, updateData: { NextSiblingID: selected.getID() } });
//更新前节点
if (selected.preSibling) {
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.preSibling.getID() }, updateData: { NextSiblingID: selected.getNextSiblingID() } });
}
//更新选中节点
updateDatas.push({ updateType: updateType.update, findData: { ID: selected.getID() }, updateData: { NextSiblingID: selected.nextSibling.getNextSiblingID() } });
updateGuideItems(updateDatas, function () {
controller.downMove();
refreshBtn(bills.tree.selected.guidance.tree.selected);
setNodesColor(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
setProcessNodes(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
$.bootstrapLoading.end();
guideItem.workBook.focus(true)
});
}
//获取定额类型的项目指引名称,通过定额转换
//@param {Object}ration @return {String}
function getRationItemName(ration) {
let arr = [];
arr.push(ration.code ? ration.code : '');
arr.push(ration.name ? ration.name : '');
arr.push(ration.basePrice ? ration.basePrice : '');
let rst = arr.join(' ');
rst += `/${ration.unit ? ration.unit : ''}`;
return rst;
}
//获取选中的定额表行
//@return {Array}
function getCheckedRationRows(all) {
let rst = [];
let sheet = ration.workBook.getActiveSheet();
for (let i = 0; i < sheet.getRowCount(); i++) {
// 全选
if (all) {
rst.push(i);
continue;
}
let checked = sheet.getValue(i, 0);
if (checked) {
rst.push(i);
}
}
return rst;
}
//清空选中定额表行
//@param {Array}rows @return {void}
function clearCheckedRation(rows) {
let sheet = ration.workBook.getActiveSheet();
renderSheetFunc(sheet, function () {
for (let row of rows) {
sheet.setValue(row, 0, 0);
}
});
}
//获取要插入的定额数据
//@param {Array}rows @return {Array}
function getInsertRations(rows) {
let rst = [];
//当前已存在定额
let curRationIems = [];
let selected = bills.tree.selected.guidance.tree.selected;
if (selected) {
if (selected.data.type === itemType.job) {
curRationIems = selected.children;
}
else {
curRationIems = selected.parent ? selected.parent.children : selected.tree.roots;
}
}
for (let row of rows) {
let selRation = ration.cache[row];
if (selRation) {
//添加的定额是否已存在,不重复添加
let isExist = false;
for (let curRation of curRationIems) {
if (curRation.data.rationID == selRation.ID) {
isExist = true;
break;
}
}
if (!isExist) {
rst.push({ type: itemType.ration, name: getRationItemName(selRation), rationID: selRation.ID });
}
}
}
return rst;
}
//获取块节点父项不存在于选中节点中的节点
//@param {Array}nodes(选中的节点) @return {Array}
function getBlockNodes(nodes) {
let nodeMapping = {};
for (let node of nodes) {
nodeMapping[node.data.ID] = node;
}
//块节点,父项不存在于选中节点中的节点
let blockNodes = [];
for (let node of nodes) {
if (!nodeMapping[node.data.ParentID]) {
blockNodes.push(node);
}
}
return blockNodes;
}
//允许复制整块,如果有多个块节点,且块节点的父项不同,则不可复制
//@param {Array}nodes(块节点) @return {Boolean}
function canCopyBlock(nodes) {
if (!nodes || nodes.length === 0) {
return false;
}
let pID = nodes[0].data.ParentID;
for (let node of nodes) {
if (node.data.ParentID !== pID) {
return false;
}
}
return true;
}
//允许粘贴整块 有粘贴数据,节点存在,如果粘贴到的节点为定额数据,粘贴数据为全定额数据
//@param {Object}node(粘贴到的节点)
function canPasteBlock(node) {
let pasteDatas = JSON.parse(getLocalCache(itemCopyBlockKey));
if (!pasteDatas || pasteDatas.length === 0) {
return false;
}
if (!node) {
return false;
}
//若粘贴到定额节点,则数据须全为定额
if (node.data.type === itemType.ration) {
for (let data of pasteDatas) {
if (data.type !== itemType.ration) {
return false;
}
}
}
//若粘贴到非定额节点,则粘贴的顶层数据须全为非定额
else {
let topDatas = _.filter(pasteDatas, { ParentID: -1 });
for (let topData of topDatas) {
if (topData.type === itemType.ration) {
return false;
}
}
}
return true;
}
//复制整块,将块节点下所有节点数据复制一份,并且重新生成ID、ParentID、NextSiblingID,使用localStorage存储
//@param {Array}nodes(块节点) @return {void}
function copyBlocks(nodes) {
nodes = _.cloneDeep(nodes);
//将块节点的ParentID暂时设置为-1
for (let topNode of nodes) {
topNode.data.ParentID = -1;
}
let copyDatas = [];
let copyNodes = [];
//获取块节点包含的所有节点(包括自己)
function containNodes(nodes) {
for (let node of nodes) {
copyNodes.push(node);
if (node.children.length > 0) {
containNodes(node.children);
}
}
}
containNodes(nodes);
for (let node of copyNodes) {
copyDatas.push(node.data);
}
console.log(`copyDatas`);
console.log(copyDatas);
setLocalCache(itemCopyBlockKey, JSON.stringify(copyDatas));
}
//粘贴整块,整块数据粘贴到相关节点,并成为其后项
//@param {Object}node(粘贴到的节点) @return {void}
function pasteBlock(node) {
let itemObj = bills.tree.selected.guidance;
let pasteDatas = JSON.parse(getLocalCache(itemCopyBlockKey));
//整理ID
let IDMapping = {};
for (let data of pasteDatas) {
data.newID = uuid.v1();
IDMapping[data.ID] = data;
}
for (let data of pasteDatas) {
let nextData = IDMapping[data.NextSiblingID];
data.NextSiblingID = nextData ? nextData.newID : -1;
let parentData = IDMapping[data.ParentID];
data.ParentID = parentData ? parentData.newID : -1;
}
for (let data of pasteDatas) {
data.ID = data.newID;
delete data.newID;
}
let updateDatas = [];
//将最顶层的块数据的ParentID设置成粘贴到节点的ParentID,并设置新的billsID
let topDatas = _.filter(pasteDatas, { ParentID: -1 });
for (let topData of topDatas) {
topData.ParentID = node.getParentID();
}
//更新数据
//更新插入的最末顶层数据NextSiblingID
if (node.nextSibling) {
topDatas[topDatas.length - 1].NextSiblingID = node.getNextSiblingID();
}
//新建节点
for (let data of pasteDatas) {
data.libID = libID;
data.billsID = node.data.billsID;
delete data._id;
updateDatas.push({ updateType: updateType.create, updateData: data });
}
console.log(`pasteDatas`);
console.log(pasteDatas);
//更新粘贴到的节点的NextSiblingID
updateDatas.push({ updateType: updateType.update, findData: { ID: node.data.ID }, updateData: { NextSiblingID: topDatas[0].ID } })
$.bootstrapLoading.start();
updateGuideItems(updateDatas, function (rstData) {
$.bootstrapLoading.end();
node.data.NextSiblingID = topDatas[0].ID;
let newNodes = itemObj.tree.insertDatasTo(node.data, pasteDatas);
cleanData(guideItem.workBook.getActiveSheet(), guideItem.headers, -1);
itemObj.controller.showTreeData();
setNodesColor(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
setProcessNodes(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
}, function () {
$.bootstrapLoading.end();
});
}
// 双击定位定额
async function locateAtRation(row) {
const node = bills.tree.selected.guidance.tree.items[row];
if (!node || !node.data.rationID) {
return;
}
const rationItem = ration.datas.find(item => item.ID === node.data.rationID);
// 当前库没有找到,需要后端查找
if (!rationItem) {
const findedRation = await ajaxPost('/rationRepository/api/getRationByID', { ID: node.data.rationID });
if (!findedRation || !rationLibIDs.includes(findedRation.rationRepId)) {
alert('无法定位此定额,此定额已被删除');
return;
}
changeRationLib(findedRation.rationRepId, () => {
located(findedRation.ID, findedRation.sectionId);
})
} else {
located(rationItem.ID, rationItem.sectionId);
}
function located(rationID, sectionID) {
if (!section.tree) {
return;
}
const sectionNode = section.tree.nodes[section.tree.prefix + sectionID];
if (!sectionNode) {
return;
}
// 定位到对应章节树
const sectionSheet = section.workBook.getActiveSheet();
const sectionRow = sectionNode.serialNo();
expandSearchNodes(sectionSheet, [sectionNode], section.tree.roots);
sectionSheet.setSelection(sectionRow, 0, 1, 1);
sectionSheet.showRow(sectionRow, GC.Spread.Sheets.VerticalPosition.center);
sectionInitSel(sectionRow);
// 定位到对应定额
const locatedRationRow = ration.cache.findIndex(item => item.ID === rationID);
if (locatedRationRow !== -1) {
const rationSheet = ration.workBook.getActiveSheet();
rationSheet.setSelection(locatedRationRow, 1, 1, 1);
rationSheet.showRow(locatedRationRow, GC.Spread.Sheets.VerticalPosition.center);
}
}
}
//初始化右键菜单
//@return {void}
function initContextMenu() {
$.contextMenu({
selector: '#guideItemSpread',
build: function ($triggerElement, e) {
//控制允许右键菜单在哪个位置出现
let sheet = guideItem.workBook.getSheet(0);
let offset = $("#guideItemSpread").offset(),
x = e.pageX - offset.left,
y = e.pageY - offset.top;
let target = sheet.hitTest(x, y);
if (target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined') {//在表格内
let sel = sheet.getSelections()[0];
if (sel && sel.rowCount === 1) {
sheet.setActiveCell(target.row, target.col);
}
sel = sheet.getSelections()[0];
let selNodes = [];
if (sel) {
sel.row = sel.row === -1 ? 0 : sel.row;
for (let i = 0; i < sel.rowCount; i++) {
if (bills.tree.selected.guidance.tree.items[sel.row + i]) {
selNodes.push(bills.tree.selected.guidance.tree.items[sel.row + i]);
}
}
}
//块节点
let blockNodes = getBlockNodes(selNodes);
//右键在多选内则不重设焦点
if (!sel || sel.rowCount === 1 || !(target.row >= sel.row && target.row <= sel.row + sel.rowCount - 1)) {
sheet.setActiveCell(target.row, target.col);
}
guideItemInitSel(target.row);
return {
callback: function () { },
items: {
"copy": {
name: "复制整块",
disabled: function () {
return locked || !canCopyBlock(blockNodes);
},
icon: "fa-copy",
callback: function (key, opt) {
copyBlocks(blockNodes);
}
},
"paste": {
name: "粘贴整块",
disabled: function () {
let pasteNode = bills.tree.selected.guidance.tree.items[target.row];
return locked || !canPasteBlock(pasteNode);
},
icon: "fa-paste",
callback: function (key, opt) {
let pasteNode = bills.tree.selected.guidance.tree.items[target.row];
pasteBlock(pasteNode);
}
},
"delRations": {
name: '删除定额',
disabled: function () {
let node = bills.tree.selected.guidance.tree.items[target.row];
return locked || !node
},
icon: "fa-remove",
callback: function (key, opt) {
$('#delRationAlert').modal('show');
}
},
"del": {
name: '删除',
disabled: function () {
let node = bills.tree.selected.guidance.tree.items[target.row];
return locked || !node
},
icon: "fa-remove",
callback: function (key, opt) {
$('#delAlert').modal('show');
}
},
"insertSibling": {
name: '插入行',
disabled: function () {
let node = bills.tree.selected.guidance.tree.items[target.row];
return locked || !node || node.data.type !== itemType.job;
},
icon: "fa-arrow-left",
callback: function (key, opt) {
insert([{ type: itemType.job, name: '' }], false);
}
},
"insertChild": {
name: '插入子项',
disabled: function () {
let node = bills.tree.selected.guidance.tree.items[target.row];
return locked || !node || node.data.type !== itemType.job || !allJobChildren(node);
},
icon: 'fa-arrow-left',
callback: function (key, opt) {
insert([{ type: itemType.job, name: '' }], true);
}
}
}
};
}
else {
return false;
}
}
});
}
// 替换定额
function replaceRation(newRation, orgItem) {
if (newRation.ID === orgItem.data.rationID) {
return;
}
$.bootstrapLoading.start();
const updateAttrs = { name: getRationItemName(newRation), rationID: newRation.ID };
const updateData = [{ updateType: updateType.update, findData: { ID: orgItem.getID() }, updateData: updateAttrs }];
updateGuideItems(updateData, function () {
Object.assign(orgItem.data, updateAttrs);
const row = orgItem.serialNo();
guideItem.workBook.getSheet(0).setValue(row, 0, orgItem.data.name);
$.bootstrapLoading.end();
});
}
// 初始化清单右键菜单
function initRationContextMenu() {
$.contextMenu({
selector: '#rationSpread',
build: function ($triggerElement, e) {
//控制允许右键菜单在哪个位置出现
let sheet = ration.workBook.getActiveSheet();;
let offset = $("#rationSpread").offset(),
x = e.pageX - offset.left,
y = e.pageY - offset.top;
let target = sheet.hitTest(x, y);
if (target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined') {//在表格内
let sel = sheet.getSelections()[0];
if (sel && sel.rowCount === 1) {
sheet.setActiveCell(target.row, target.col);
}
sel = sheet.getSelections()[0];
if (sel) {
sel.row = sel.row === -1 ? 0 : sel.row;
}
//右键在多选内则不重设焦点
if (!sel || sel.rowCount === 1 || !(target.row >= sel.row && target.row <= sel.row + sel.rowCount - 1)) {
sheet.setActiveCell(target.row, target.col);
}
return {
callback: function () { },
items: {
"replace": {
name: "替换定额",
disabled: function () {
return locked || !bills.tree.selected || !bills.tree.selected.guidance || !bills.tree.selected.guidance.tree || !bills.tree.selected.guidance.tree.selected || bills.tree.selected.guidance.tree.selected.data.type !== itemType.ration;
},
icon: "fa-copy",
callback: function (key, opt) {
const row = sheet.getActiveRowIndex();
if (!ration.cache[row]) {
return;
}
replaceRation(ration.cache[row], bills.tree.selected.guidance.tree.selected);
// copyBlocks(blockNodes);
}
},
}
};
}
else {
return false;
}
}
});
}
// 初始化定额右键菜单
function initBillsContextMenu() {
$.contextMenu({
selector: '#billsSpread',
build: function ($triggerElement, e) {
//控制允许右键菜单在哪个位置出现
let sheet = bills.workBook.getActiveSheet();;
let offset = $("#billsSpread").offset(),
x = e.pageX - offset.left,
y = e.pageY - offset.top;
let target = sheet.hitTest(x, y);
if (target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined') {//在表格内
let sel = sheet.getSelections()[0];
if (sel && sel.rowCount === 1) {
sheet.setActiveCell(target.row, target.col);
}
sel = sheet.getSelections()[0];
if (sel) {
sel.row = sel.row === -1 ? 0 : sel.row;
}
//右键在多选内则不重设焦点
if (!sel || sel.rowCount === 1 || !(target.row >= sel.row && target.row <= sel.row + sel.rowCount - 1)) {
sheet.setActiveCell(target.row, target.col);
}
billsInitSel(target.row, { row: bills.tree.selected.serialNo() });
return {
callback: function () { },
items: {
"replace": {
name: "配置材料",
disabled: function () {
return !bills.tree.selected;
},
icon: "fa-edit",
callback: function (key, opt) {
$('#bill-material-modal').modal('show');
}
},
}
};
}
else {
return false;
}
}
});
}
//展开至搜索出来点的节点
//@param {Array}nodes @return {void}
function expandSearchNodes(sheet, nodes, roots) {
renderSheetFunc(sheet, function () {
function expParentNode(node) {
if (node.parent) {
if (!node.parent.expanded) {
node.parent.setExpanded(true);
}
expParentNode(node.parent);
}
}
for (let node of nodes) {
expParentNode(node);
}
TREE_SHEET_HELPER.refreshNodesVisible(roots, sheet, true);
});
}
// 清空搜索高亮
function clearHighLight(sheet) {
renderSheetFunc(sheet, () => {
for (let i = 0; i < sheet.getRowCount(); i++) {
setBgColor(sheet, i, 'white')
}
});
}
// 清空搜索状态
// 关闭搜索清单结果
function closeSearchBills(sheet) {
if (!bills.tree) {
return;
}
$('#searchBillsResult').hide();
bills.tree.items.forEach(node => {
node.isSearch = false;
});
clearHighLight(sheet);
setBgColor(sheet, sheet.getActiveRowIndex(), selectedBgColor);
}
// 搜索清单
function searchBills() {
if (!bills.tree || !bills.workBook) {
return;
}
const sheet = bills.workBook.getActiveSheet();
const str = $('#searchBillText').val().trim();
// 空搜索字符,关闭搜索
if (!str) {
if ($('#searchBillsResult').is(':visible')) {
closeSearchBills(sheet);
}
return;
}
// 过滤清单
const result = bills.tree.items.filter(item => {
const codeIs = item.data.code ? item.data.code.indexOf(str) !== -1 : false;
const nameIs = item.data.name ? item.data.name.indexOf(str) !== -1 : false;
return codeIs || nameIs;
});
if (!result.length) {
closeSearchBills(sheet);
return;
}
// 显示搜索结果
$("#searchBillsResult").show();
$('#searchBillsCount').text(result.length);
//展开搜索出来的节点
expandSearchNodes(sheet, result, bills.tree.roots);
// 标黄结果
clearHighLight(sheet);
const col = sheet.getActiveColumnIndex();
renderSheetFunc(sheet, function () {
bills.controller.setTreeSelected(result[0]);
bills.tree.items.forEach(node => {
if (result.includes(node)) {
setBgColor(sheet, node.serialNo(), searchBgColor);
node.isSearch = true; // 标记为搜索结果,防止被焦点行变更恢复颜色
} else {
node.isSearch = false;
}
})
});
//搜索初始定位
const row = sheet.getActiveRowIndex();
sheet.setSelection(result[0].serialNo(), col, 1, 1);
billsInitSel(result[0].serialNo(), { row });
sheet.showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
let curIndex = 0;
// 上一条
$('#preBill').unbind('click');
$('#preBill').bind('click', () => {
const node = result[curIndex - 1];
if (!node) {
return;
}
curIndex -= 1;
const col = sheet.getActiveColumnIndex();
const row = node.serialNo();
const orgRow = sheet.getActiveRowIndex();
sheet.setSelection(row, col, 1, 1);
billsInitSel(row, { row: orgRow });
sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
});
// 下一条
$('#nextBills').unbind('click');
$('#nextBills').bind('click', () => {
const node = result[curIndex + 1];
if (!node) {
return;
}
curIndex += 1;
const col = sheet.getActiveColumnIndex();
const row = node.serialNo();
const orgRow = sheet.getActiveRowIndex();
sheet.setSelection(row, col, 1, 1);
billsInitSel(row, { row: orgRow });
sheet.showRow(row, GC.Spread.Sheets.VerticalPosition.center);
});
}
//初始化dom时间
//@return {void}
function initDomEvents() {
// 清单材料窗口
$("#bill-material-modal").on('hidden.bs.modal', function () {
billMaterial.cache = [];
showBillMaterialData(billMaterial.workBook.getSheet(0), billMaterial.headers, billMaterial.cache, 30);
});
$("#bill-material-modal").on('shown.bs.modal', function () {
if (billMaterial.workBook && billMaterialHelper.workBook) {
billMaterialHelper.workBook.refresh();
billMaterial.workBook.refresh();
getBillMaterials();
}
});
/* 自动配置材料 */
$('#autoSetMaterial').click(async function() {
$.bootstrapLoading.start();
try {
await ajaxPost('/billsGuidance/api/autoSetMaterial', { libID}, 1000 * 60 * 10);
// 刷新显示
window.location.reload();
} catch (error) {
alert(error);
}
$.bootstrapLoading.end();
});
/* excel */
// 生成excel
$('#buildExcel').click(function () {
if (bills && bills.tree) {
$('#excel-modal').modal('show');
}
});
$("#excel-modal").on('hidden.bs.modal', function () {
$('#excel-info').text(`导出排版中:`);
$('#excel-spread').hide();
$('#export-excel-confirm').hide();
$('#excel-dialog').width('500px');
if (exportExcelWorkBook) {
exportExcelWorkBook.clearSheets();
exportExcelWorkBook.addSheet();
}
});
let excelInstance;
$("#excel-modal").on('shown.bs.modal', async function () {
exportExcelWorkBook.refresh();
if (bills.tree) {
excelInstance = new ExportExcel(exportExcelWorkBook, bills.tree, libID);
try {
// await excelInstance.paintOnSheet();
await excelInstance.paintOnWorkBook();
} catch (error) {
console.log(error);
alert(error);
$("#excel-modal").modal('hide');
}
}
});
$('#export-excel-confirm').click(() => {
if (excelInstance) {
excelInstance.export();
}
})
$('#insert').click(function () {
insert([{ type: itemType.job, name: '', outputItemCharacter: true }], false);
});
$('#delConfirm').click(function () {
del();
$('#delAlert').modal('hide');
});
$('#delRationConfirm').click(function () {
delRations();
$('#delRationAlert').modal('hide');
});
$('#del').click(function () {
$('#delAlert').modal('show');
});
$('#upLevel').click(function () {
upLevel();
});
$('#downLevel').click(function () {
downLevel();
});
$('#upMove').click(function () {
upMove();
});
$('#downMove').click(function () {
downMove();
});
// 收起清单至第二层
$('#expandToSecond').click(function () {
if (!bills.tree || !bills.workBook) {
return;
}
bills.tree.roots.forEach(root => {
root.setExpanded(true);
root.children.forEach(item => {
item.setExpanded(false);
});
});
const billSheet = bills.workBook.getActiveSheet();
renderSheetFunc(billSheet, function () {
TREE_SHEET_HELPER.refreshNodesVisible(bills.tree.roots, billSheet, true);
});
})
//收起定额、展开全部
$('#expandContract').click(function () {
//目前状态时展开全部节点状态,点击则收起定额
let tree = bills.tree.selected.guidance.tree,
itemSheet = guideItem.workBook.getActiveSheet();
if (curExpandState === itemExpandState.expand) {
curExpandState = itemExpandState.contract;
$(this).html(' 展开全部');
setNodesExpandState(tree.items, itemExpandState.contract);
} else {
curExpandState = itemExpandState.expand;
$(this).html(' 收起定额');
setNodesExpandState(tree.items, itemExpandState.expand);
}
renderSheetFunc(itemSheet, function () {
TREE_SHEET_HELPER.refreshNodesVisible(tree.roots, itemSheet, true);
});
});
// 配置材料
$('#editMaterial').click(function () {
if (bills && bills.tree && bills.tree.selected) {
$('#bill-material-modal').modal('show');
}
});
// 插入选中定额
$('#insertRation').click(function () {
let checkedRows = getCheckedRationRows();
let insertDatas = getInsertRations(checkedRows);
if (insertDatas.length > 0) {
insert(insertDatas, false, function () {
//清空选择
clearCheckedRation(checkedRows);
});
}
else {
clearCheckedRation(checkedRows);
}
});
// 插入全部定额
$('#insertAll').click(function () {
let isAll = true;
let checkedRows = getCheckedRationRows(isAll);
let insertDatas = getInsertRations(checkedRows);
if (insertDatas.length > 0) {
insert(insertDatas, false);
}
});
// 搜索清单
$("#searchBillBtn").click(searchBills);
$('#searchBillText').keyup(function (e) {
delayKeyup(function () {
$('#searchBillBtn').click();
});
});
// 关闭搜索清单
$('#closeSearchBills').click(() => {
if (!bills.workBook) {
return;
}
const sheet = bills.workBook.getActiveSheet();
closeSearchBills(sheet);
})
//搜索定额
$('#searchBtn').click(function () {
let searchStr = $('#searchText').val();
if (!searchStr || searchStr === '') {
ration.cache = ration.datas;
}
else {
let reg = new RegExp(searchStr, 'i');
ration.cache = _.filter(ration.datas, function (data) {
return reg.test(data.code) || reg.test(data.name);
});
}
$('.top-content').hide();
$('#deResize').hide();
$('#searchCount').text(`搜索结果: ${ration.cache.length}`);
$('#rationSearchResult').show();
autoFlashHeight();
ration.workBook.refresh();
let rationSheet = ration.workBook.getActiveSheet();
renderSheetFunc(rationSheet, function () {
clearCheckedRation(getCheckedRationRows());
showData(rationSheet, ration.headers, ration.cache);
})
});
//关闭搜索
$('#rationSearchResult a').click(function () {
$('.top-content').show();
$('#deResize').show();
$('#rationSearchResult').hide();
autoFlashHeight();
renderSheetFunc(ration.workBook.getActiveSheet(), function () {
clearCheckedRation(getCheckedRationRows());
});
section.workBook.refresh();
ration.workBook.refresh();
$('#searchText').val('');
//恢复章节树下的定额
sectionInitSel(section.workBook.getActiveSheet().getActiveRowIndex());
});
let keyupTime = 0,
delayTime = 500;
function delayKeyup(callback) {
let nowTime = Date.now();
keyupTime = nowTime;
setTimeout(function () {
if (nowTime - keyupTime == 0) {
callback();
}
}, delayTime);
}
//执行搜索
$('#searchText').keyup(function (e) {
delayKeyup(function () {
$('#searchBtn').click();
});
});
//编辑清单备注
$('.main-side-bottom').find('textarea').keyup(function () {
let me = this;
let node = bills.tree.selected;
let comment = $(me).val();
delayKeyup(function () {
if (node) {
let updateData = { lastOperator: userAccount, billsLibId: billsLibId, updateId: node.getID(), field: 'comment', data: comment };
updateBillsComment(updateData, function () {
node.data.comment = comment;
}, function () {
$(me).val(node.data.comment || '');
})
}
});
});
//编辑选项备注
$('.main-bottom-content').find('textarea').keyup(function () {
let me = this;
let node = bills.tree.selected.guidance.tree.selected;
let comment = $(me).val();
delayKeyup(function () {
if (node) {
let updateDatas = [{ updateType: updateType.update, findData: { ID: node.getID() }, updateData: { comment: comment } }];
updateGuideItems(updateDatas, function (rstData) {
node.data.comment = comment;
}, function () {
$(me).val(node.data.comment || '');
});
}
});
});
//定额高度拖动调整
let heightEleObj = {
module: moduleName,
resize: $('#deResize'),
top: $('#topContent'),
topSpread: $('#sectionSpread'),
bottom: $('#bottomContent'),
bottomSpread: $('#rationSpread')
},
heightLimit = {
min: 150,
max: `$(window).height()-$('.header').height()-$('.sidebar-tools-bar').height()-150-10`,
notTopSpread: 0,
notBottomSpread: 0,
};
SlideResize.verticalSlide(heightEleObj, heightLimit, function () {
if (section.workBook) {
section.workBook.refresh();
}
if (ration.workBook) {
ration.workBook.refresh();
}
});
/*slideResize(rationLibResizeEles, {min: 147, max: 680}, 'height', function() {
//autoFlashHeight();
if(section.workBook){
section.workBook.refresh();
}
if(ration.workBook){
ration.workBook.refresh();
}
});*/
//左右拖动
//清单表与项目指引表
let leftElesObj = {};
leftElesObj.module = moduleName;
leftElesObj.resize = $('#slideResizeLeft');
leftElesObj.parent = $('#dataRow');
leftElesObj.left = $('#leftContent');
leftElesObj.right = $('#midContent');
SlideResize.horizontalSlide(leftElesObj, { min: 200, max: `$('#dataRow').width() - $('#rightContent').width() - 200` }, function () {
refreshALlWorkBook();
});
//人材机表与人材机组成物表
let rightElesObj = {};
rightElesObj.module = moduleName;
rightElesObj.resize = $('#slideResizeRight');
rightElesObj.parent = $('#dataRow');
rightElesObj.left = $('#midContent');
rightElesObj.right = $('#rightContent');
SlideResize.horizontalSlide(rightElesObj, { min: 200, max: `$('#dataRow').width() - $('#leftContent').width() - 200` }, function () {
refreshALlWorkBook();
});
}
//刷新全部工作簿
//@return {void}
function refreshALlWorkBook() {
if (bills.workBook) {
bills.workBook.refresh();
}
if (guideItem.workBook) {
guideItem.workBook.refresh();
}
if (section.workBook) {
section.workBook.refresh();
}
if (ration.workBook) {
ration.workBook.refresh();
}
$('.main-side-bottom').find('textarea').height($('.main-side-bottom').height() - 20);
$('.main-side-bottom').find('textarea').width($('.main-side-bottom').width() - 25);
$('.main-bottom-content').find('textarea').height($('.main-bottom-content').height() - 20);
$('.main-bottom-content').find('textarea').width($('.main-bottom-content').width() - 25);
}
//读取拖动相关
//@return {void}
function initSlideSize() {
//定额表上下
let heightEleObj = {
module: moduleName,
top: $('#topContent'),
topSpread: $('#sectionSpread'),
bottom: $('#bottomContent'),
bottomSpread: $('#rationSpread')
};
if (!$('#rationSearchResult').is(':visible')) {
SlideResize.loadVerticalHeight(heightEleObj.module, heightEleObj,
{
totalHeight: `$(window).height()-$('.header').height()-$('.sidebar-tools-bar').height()-10`,
notTopSpread: 0, notBottomSpread: 0
}, function () {
if (section.workBook) {
section.workBook.refresh();
}
if (ration.workBook) {
ration.workBook.refresh();
}
});
}
//水平
SlideResize.loadHorizonWidth(moduleName, [$('#slideResizeLeft'), $('#slideResizeRight')], [$('#leftContent'), $('#midContent'), $('#rightContent')], function () {
refreshALlWorkBook();
});
}
//初始化视图
//@param {void} @return {void}
function initViews() {
let modules = [bills, guideItem, section, ration, billMaterial, billMaterialHelper];
initWorkBooks(modules);
lockUtil.lockTools($(document.body), locked);
getLibWithBills(libID);
initDomEvents();
initContextMenu();
initRationContextMenu();
//initBillsContextMenu();
initSlideSize();
}
// 判断蓝色子项和孙子项是否打勾了必填
function hasRequireData(node) {
const requiredList = node.getPosterity().filter(subNode =>
subNode.data.required === true
);
if (requiredList.length) { return true }
return false;
}
// 这里判断有无无定额的情况,有的就返回true,没有就返回false
function isAllRationData(node) {
let isRequired = true;
if (node.children && node.children.length) {
node.children.forEach(subNode => {
if (!subNode.children || !subNode.children.length) {
isRequired = false;
}
})
}
//这里是兼容第一层直接是定额的白色节点
if (node.children && node.children.length) {
node.children.forEach(subNode => {
if (subNode.data.rationID) {
isRequired = true;
}
})
}
return isRequired;
}
// 获取选套定额
function getOptionalData(node, list = []) {
if (isProcessNode(node)) {
node.children.forEach(element => {
if (element.children && element.children.length) {
element.children.forEach(item => {
if (item.data.rationID) {
list.push(item.data.rationID);
} else if (isProcessNode(item)) {
getOptionalData(item, list)
}
})
}
});
} else {
node.children.forEach(element => {
if (element.data.rationID) {
list.push(element.data.rationID);
}
});
}
return list;
}
// 获取必填项下的ID和name的键值对
function getClassCodeStrData(nodes,data={classGroups:{},keyGroup:{}}){
nodes.forEach(node=>{
if (isProcessNode(node)&&node.data.required) {
node.children.forEach(subNode=>{
data.classGroups[subNode.data.ID]=subNode.data.name;
data.keyGroup[subNode.data.ID]=`${subNode.parent.data.name}:${subNode.data.name}`;
})
}
getClassCodeStrData(node.children,data);
})
return data;
}
//获取定额数据
// requireRationData必套定额对象
// optionalRationData 选逃定额对象
// classGroups classCode文字和id键值对
// classCodeList 各个classCode的pID和ID的关系
function getItemData(nodes, requireRationData = {}, optionalRationData = {}, classGroups = {}, prefixID = '', prefixSonID = '', IDData = {},keyGroup={}) {
const processNodes = nodes.filter(node => isProcessNode(node));
// const classGroups = []; // 同层必填选项的数组(二维数组)
processNodes.forEach(processNode => {
// 蓝色节点,必填
if (processNode.data.required) {
// 白色节点
const optionNodes = processNode.children.filter(node => isOptionNode(node));
optionNodes.forEach(optionNode => {
if (!requireRationData[optionNode.data.ID]) requireRationData[optionNode.data.ID] = [];
if (!optionalRationData[optionNode.data.ID]) optionalRationData[optionNode.data.ID] = [];
//白色节点下没有蓝色节点,就是到底了
if (!optionNode.children.some(subOptionNode => isProcessNode(subOptionNode))) {
// 是否必套定额
if (isAllRationData(optionNode)) {
optionNode.children.forEach(subOptionNode => {
requireRationData[optionNode.data.ID].push([subOptionNode.data.rationID]);
})
} else {
optionalRationData[optionNode.data.ID] = getOptionalData(optionNode);
}
const kV = {};
kV[optionNode.data.ID] = optionNode.data.name;
Object.assign(classGroups, kV);
const keyData={};
keyData[optionNode.data.ID] = `${optionNode.parent.data.name}:${optionNode.data.name}`;
Object.assign(keyGroup,keyData);
} else {
const kV = {};
kV[optionNode.data.ID] = optionNode.data.name;
Object.assign(classGroups, kV);
const keyData={};
keyData[optionNode.data.ID] = `${optionNode.parent.data.name}:${optionNode.data.name}`;
Object.assign(keyGroup,keyData);
// 后代项是否有必填
if (hasRequireData(optionNode)) {
//后代项有必填
prefixSonID = '';
getItemData(optionNode.children, requireRationData, optionalRationData, classGroups, optionNode.data.ID, prefixSonID, IDData,keyGroup);
} else {
//后代项无必填
optionNode.children.forEach(subOptionNode => {
// 是否必套定额
if (isAllRationData(optionNode)) {
if (!requireRationData[subOptionNode.parent.data.ID]) requireRationData[subOptionNode.parent.data.ID] = [];
requireRationData[subOptionNode.parent.data.ID].push(getOptionalData(subOptionNode));
} else {
if (!optionalRationData[subOptionNode.parent.data.ID]) optionalRationData[subOptionNode.parent.data.ID] = [];
optionalRationData[subOptionNode.parent.data.ID].push(...getOptionalData(subOptionNode));
}
})
}
}
})
} else {
// 蓝色节点,非必填
if (hasRequireData(processNode)) {
//后代项有必填
if (isProcessNode(processNode)) {
//蓝色
// 是否必套定额
if (isAllRationData(processNode)) {
processNode.children.forEach((subProcessNode) => {
subProcessNode.children.forEach((sSubProcessNode) => {
//这里是特殊处理,因为原来的逻辑是直接把定额绑到必填白色选项中下面的,每个蓝色的一组,但是这样是不对的,需要绑定在必填白色选项下的蓝色节点,所以这里就需要传入蓝色节点的id
const requireChildrenID = sSubProcessNode.parent.data.required ? prefixSonID : sSubProcessNode.data.ID;
IDData[sSubProcessNode.data.ID] = prefixID;
getItemData(
[sSubProcessNode],
requireRationData,
optionalRationData,
classGroups,
prefixID,
requireChildrenID,
IDData,
keyGroup
)
})
})
}else{
// 全部选套就不用走循环了,直接按照选套执行
let key = processNode.data.ID;
if (prefixID) key = prefixID;
if (prefixSonID) key = prefixSonID;
if (!optionalRationData[key]) optionalRationData[key] = [];
optionalRationData[key].push(...getOptionalData(processNode));
// 因为这里没有按照走整个流程,所以文字和ID的关系需要获取补充
if(hasRequireData(processNode)) {
const result =getClassCodeStrData(processNode.children)
Object.assign(classGroups,result.classGroups);
Object.assign(keyGroup,result.keyGroup);
} ;
}
}
} else {
let key = processNode.data.ID;
if (prefixID) key = prefixID;
if (prefixSonID) key = prefixSonID;
// 是否必套定额
if (isAllRationData(processNode)) {
if (!requireRationData[key]) requireRationData[key] = [];
requireRationData[key].push(getOptionalData(processNode));
} else {
if (!optionalRationData[key]) optionalRationData[key] = [];
optionalRationData[key].push(...getOptionalData(processNode));
}
}
}
})
return { requireRationData, optionalRationData, classGroups, IDData, keyGroup }
}
/* 生成特征分类: 前端测试使用,想要前端测试,需要在zhiyin.html中,将id=generate-classa的按钮放开 */
function getItemCharacterData(nodes, prefix, prefixID) {
const processNodes = nodes.filter(node => isProcessNode(node));
const classGroups = []; // 同层必填选项的数组(二维数组)
processNodes.forEach(processNode => {
const classItems = [];
const optionNodes = processNode.children.filter(node => isOptionNode(node));
optionNodes.forEach(optionNode => {
// const name = prefix ? `${prefix}@${optionNode.data.name}` : optionNode.data.name;
if (optionNode.parent && optionNode.parent.data.required && (!optionNode.children
|| !optionNode.children.length
|| (optionNode.children[0].data && optionNode.children[0].data.rationID)
|| !optionNode.children.some(node => isProcessNode(node)))) {
// 必套定额
classItems.push({ name: optionNode.data.name, ID: optionNode.data.ID });
} else {
// classItems.push(...getItemCharacterData(optionNode.children, optionNode.parent && optionNode.parent.data.required ? optionNode.data.name : ''));
const childrenClassItem = getItemCharacterData(
optionNode.children,
optionNode.parent && optionNode.parent.data.required ? optionNode.data.name : '',
optionNode.parent && optionNode.parent.data.required ? optionNode.data.ID : ''
);
//如果返回的子项为空,但是父项又勾选了必填,则要把本身存入数组
if (optionNode.parent
&& optionNode.parent.data.required
&& childrenClassItem.length === 0
) {
classItems.push({ name: optionNode.data.name, ID: optionNode.data.ID });
} else {
classItems.push(...childrenClassItem);
}
}
});
if (classItems.length) {
classGroups.push(classItems);
}
});
// 拼接上一文本
if (classGroups[0] && classGroups[0].length) {
// classGroups[0] = classGroups[0].map(name => prefix ? `${prefix}@${name}` : name);
classGroups[0] = classGroups[0].map(item => {
item.name = prefix ? `${prefix}@${item.name}` : item.name
item.ID = prefixID ? `${prefixID}@${item.ID}` : item.ID
return item;
});
}
// 二维数组内容排列组合
while (classGroups.length > 1) {
const prevClassItems = classGroups[0];
const nextClassItems = classGroups[1];
const mergedClassItems = [];
for (let i = 0; i < prevClassItems.length; i++) {
for (let j = 0; j < nextClassItems.length; j++) {
// 拼接文本
const mergedName = `${prevClassItems[i].name}@${nextClassItems[j].name}`;
const mergedID = `${prevClassItems[i].ID}@${nextClassItems[j].ID}`;
mergedClassItems.push({ name: mergedName, ID: mergedID });
}
}
classGroups.splice(0, 2, mergedClassItems);
}
// 去重(类别别名要唯一)
const items = classGroups[0] || [];
const nameMap = {};
const rst = [];
items.forEach(item => {
if (!nameMap[item.name]) {
rst.push(item);
}
nameMap[item.name] = true;
});
return rst;
}
// 获取选套定额:把所有分类数据的必套定额确定好了先。选套定额就是清单下所有定额除了必套的
function getOptionalRationIDs(optionalRationData) {
const optionalRationIDs = [];
Object.values(optionalRationData).forEach(optionalRation => {
if (optionalRation.length) optionalRationIDs.push(...optionalRation);
})
return [...new Set(optionalRationIDs)];
}
// 获取错套定额:清单下所有定额,除了分类对应的必套、选套定额
function getErrorRationIDs(requiredRationIDList, optionalRationIDs, guideNodes) {
const finRequireData = [];
requiredRationIDList.forEach(requiredRationIDs => {
finRequireData.push(...requiredRationIDs);
})
const errorRationIDs = [];
guideNodes.forEach(node => {
if (node.data.rationID && !finRequireData.includes(node.data.rationID) && !optionalRationIDs.includes(node.data.rationID)) {
errorRationIDs.push(node.data.rationID);
}
});
return [...new Set(errorRationIDs)];
}
//把classcode和必套选套定额结合在一起
function combineData(codeData, requireRationData, optionalRationData, classGroups, IDData,keyGroup) {
// 这里要记录下已经被绑定的选套定额,因为没有被用的定额需要绑定到各个classcode下
const matchRationList = [];
//这里需要把绑定在子节点的定额更新到必填的白色选项中(classcode的值)
const requireCombineData = {};
const optionCombineData = {};
Object.keys(IDData).forEach(key => {
if (!requireCombineData[IDData[key]]) requireCombineData[IDData[key]] = new Set();
if (!optionCombineData[IDData[key]]) optionCombineData[IDData[key]] = new Set();
if (requireRationData[key]) {
requireRationData[key].forEach(subData => {
subData.forEach(subItem => {
requireCombineData[IDData[key]].add(subItem);
})
})
}
if (optionalRationData[key]) {
optionalRationData[key].forEach(subData => {
optionCombineData[IDData[key]].add(subData);
})
}
})
const finData = codeData.map(classCodeData => {
const errorRationIDs = [];
const optionalRationIDs = [];
const requiredRationIDs = [];
let name = '';
let key = '';
const classCodeIDs = classCodeData.ID;
if (/@/.test(classCodeIDs)) {
classCodeIDs.split('@').forEach((classCodeID) => {
if (name) {
name = name + '@' + classGroups[classCodeID];
key += keyGroup[classCodeID];
} else {
name = classGroups[classCodeID];
key = keyGroup[classCodeID];
};
// 一组的必套定额,先去重
const unitRation = [];
// 这里是必填选项下绑定必套定额
if (requireRationData[classCodeID] && requireRationData[classCodeID].length) {
requireRationData[classCodeID].forEach(subItem => {
unitRation.push(...new Set(subItem));
})
requiredRationIDs.push(unitRation);
// 这里也要把用过的必套定额先存起来
matchRationList.push(...unitRation);
}
//这里是必填选项下绑定在蓝色节点下的必套定额
if (requireCombineData[classCodeID] && requireCombineData[classCodeID].size) {
requiredRationIDs.push([...requireCombineData[classCodeID]]);
// 这里也要把用过的必套定额先存起来
matchRationList.push(...requireCombineData[classCodeID]);
}
// 这里是必填选项下绑定选套定额
if (optionalRationData[classCodeID] && optionalRationData[classCodeID].length) {
optionalRationIDs.push(...optionalRationData[classCodeID]);
matchRationList.push(...optionalRationData[classCodeID]);
}
//这里是必填选项下绑定在蓝色节点下的选套定额,下同
if (optionCombineData[classCodeID] && optionCombineData[classCodeID].size) {
optionalRationIDs.push(...optionCombineData[classCodeID]);
matchRationList.push(...optionCombineData[classCodeID]);
}
})
return { name,key, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
} else {
const unitRation = [];
name = classGroups[classCodeIDs];
key = keyGroup[classCodeIDs];
if (requireRationData[classCodeIDs] && requireRationData[classCodeIDs].length){
requireRationData[classCodeIDs].forEach(subItem => {
unitRation.push(...new Set(subItem));
})
requiredRationIDs.push(unitRation);
// 这里也要把用过的必套定额先存起来
matchRationList.push(...unitRation);
}
if (requireCombineData[classCodeIDs] && requireCombineData[classCodeIDs].size) {
requiredRationIDs.push([...requireCombineData[classCodeIDs]])
// 这里也要把用过的必套定额先存起来
matchRationList.push(...requireCombineData[classCodeIDs]);
};
if (optionalRationData[classCodeIDs] && optionalRationData[classCodeIDs].length) {
optionalRationIDs.push(...optionalRationData[classCodeIDs]);
matchRationList.push(...optionalRationData[classCodeIDs]);
}
if (optionCombineData[classCodeIDs] && optionCombineData[classCodeIDs].size) {
optionalRationIDs.push(...optionCombineData[classCodeIDs]);
matchRationList.push(...optionalRationData[classCodeIDs]);
}
return { name,key, requiredRationIDs, optionalRationIDs: [...new Set(optionalRationIDs)], errorRationIDs }
}
})
const unMatchRation = [];
Object.values(optionalRationData).forEach(data => {
data.forEach((rationID) => {
if (!matchRationList.includes(rationID)) {
unMatchRation.push(rationID);
}
})
})
// 这里把没有使用过的必套定额也丢到了选套里面
Object.values(requireRationData).forEach(data => {
data.forEach((rationData) => {
rationData.forEach(rationID=>{
if (!matchRationList.includes(rationID)) {
unMatchRation.push(rationID);
}
})
})
})
return { classData: finData, unMatchRation };
}
$('#generate-class').click(() => {
if (bills.tree.selected && bills.tree.selected.guidance.tree) {
const classCodeData = getItemCharacterData(bills.tree.selected.guidance.tree.roots);
const { requireRationData, optionalRationData, classGroups, IDData, keyGroup } = getItemData(bills.tree.selected.guidance.tree.roots);
// const noMatchOptionRation=[];
const { classData, unMatchRation } = combineData(classCodeData, requireRationData, optionalRationData, classGroups, IDData,keyGroup);
//因为所有的选套都是一样的,所以这里就直接赋值了
const optionalRationIDs = getOptionalRationIDs(optionalRationData);
classData.forEach(item => {
// 不在必填项下的选套都要绑定在每个classcode下
item.optionalRationIDs.push(...unMatchRation);
item.errorRationIDs = getErrorRationIDs(item.requiredRationIDs, item.optionalRationIDs, bills.tree.selected.guidance.tree.items);
})
console.log(optionalRationIDs);
console.log(classData);
}
});
return { initViews, initSlideSize, bills };
})();
$(document).ready(function () {
billsGuidance.initViews();
});