|
@@ -9,6 +9,12 @@
|
|
|
*/
|
|
|
|
|
|
const ckBillsSpread = window.location.pathname + '-billsSelect';
|
|
|
+const invalidFields = {
|
|
|
+ parent: ['sgfh_qty', 'sgfh_tp', 'sjcl_qty', 'sjcl_tp', 'qtcl_qty', 'qtcl_tp', 'deal_qty', 'deal_tp', 'unit_price'],
|
|
|
+ gcl: ['dgn_qty1', 'dgn_qty2'],
|
|
|
+ posCode: ['b_code'],
|
|
|
+ posCalc: ['sgfh_qty', 'sgfh_tp', 'sjcl_qty', 'sjcl_tp', 'qtcl_qty', 'qtcl_tp'],
|
|
|
+};
|
|
|
function transExpr(expr) {
|
|
|
return $.trim(expr).replace('\t', '').replace('=', '').replace('%', '/100');
|
|
|
}
|
|
@@ -56,7 +62,7 @@ $(document).ready(() => {
|
|
|
loadExprToInput(sheet) {
|
|
|
const sel = sheet.getSelections()[0];
|
|
|
const col = sheet.zh_setting.cols[sel.col], cell = sheet.getCell(sel.row, sel.col);
|
|
|
- if (col.type === 'Number') {
|
|
|
+ if (col && col.type === 'Number') {
|
|
|
const data = SpreadJsObj.getSelectObject(sheet);
|
|
|
if (data) {
|
|
|
$('#bills-expr').val(data[col.field]).attr('field', col.field).attr('org', data[col.field]);
|
|
@@ -233,7 +239,7 @@ $(document).ready(() => {
|
|
|
* 新增节点
|
|
|
* @param spread
|
|
|
*/
|
|
|
- baseOpr: function (sheet, type) {
|
|
|
+ baseOpr: function (sheet, type, addCount = 1) {
|
|
|
const self = this;
|
|
|
const [tree, node, count] = this.getDefaultSelectInfo(sheet);
|
|
|
if (!tree || !node || !count) return;
|
|
@@ -281,7 +287,7 @@ $(document).ready(() => {
|
|
|
postType: type,
|
|
|
postData: {
|
|
|
id: node.ledger_id,
|
|
|
- count: count,
|
|
|
+ count: type === 'add' ? addCount : count,
|
|
|
}
|
|
|
}, function (result) {
|
|
|
const refreshData = tree.loadPostData(result);
|
|
@@ -389,17 +395,113 @@ $(document).ready(() => {
|
|
|
}
|
|
|
},
|
|
|
clipboardPasting: function (e, info) {
|
|
|
- if (info.sheet.zh_setting) {
|
|
|
- const range = info.cellRange;
|
|
|
- for (let iRow = range.row; iRow < range.row + range.rowCount; iRow++) {
|
|
|
- const node = info.sheet.zh_tree.nodes[iRow];
|
|
|
- if (info.sheet.zh_tree.checkNodeUsed(node, pos)) {
|
|
|
- toastr.warning('"' + node.code + node.b_code + ' ' + node.name +'"已计量,请勿修改');
|
|
|
- info.cancel = true;
|
|
|
- return;
|
|
|
+ const tree = info.sheet.zh_tree, setting = info.sheet.zh_setting;
|
|
|
+ info.cancel = true;
|
|
|
+ if (!setting || !tree) return;
|
|
|
+ // const range = info.cellRange;
|
|
|
+ // for (let iRow = range.row; iRow < range.row + range.rowCount; iRow++) {
|
|
|
+ // const node = tree.nodes[iRow];
|
|
|
+ // if (tree.checkNodeUsed(node, pos)) {
|
|
|
+ // toastr.warning('"' + node.code + node.b_code + ' ' + node.name +'"已计量,请勿修改');
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ const pasteData = info.pasteData.html
|
|
|
+ ? SpreadJsObj.analysisPasteHtml(info.pasteData.html)
|
|
|
+ : (info.pasteData.text === ''
|
|
|
+ ? SpreadJsObj.Clipboard.getAnalysisPasteText()
|
|
|
+ : SpreadJsObj.analysisPasteText(info.pasteData.text));
|
|
|
+ const hint = {
|
|
|
+ usedUp: {type: 'warning', msg: '节点已计量,不可修改单价'},
|
|
|
+ usedCode: {type: 'warning', msg: '节点已计量,编号不可修改为空值'},
|
|
|
+ invalidExpr: {type: 'warning', msg: '粘贴的表达式非法'},
|
|
|
+ posCode: {type: 'warning', msg: '清单含有计量单元,请先删除计量单元,再修改清单编号为空'},
|
|
|
+ posQty: {type: 'warning', msg: '清单含有计量单元,数量金额根据计量单元汇总计算所得,不可修改'},
|
|
|
+ parent: {type: 'warning', msg: '含有子项的清单,不可粘贴数量、单价、金额'},
|
|
|
+ gcl: {type: 'warning', msg: '工程量清单,不可粘贴项目节数量'},
|
|
|
+ };
|
|
|
+ const datas = [], filterNodes = [];
|
|
|
+
|
|
|
+ for (let iRow = 0; iRow < info.cellRange.rowCount; iRow ++) {
|
|
|
+ const curRow = info.cellRange.row + iRow;
|
|
|
+ const node = tree.nodes[curRow];
|
|
|
+ if (!node) continue;
|
|
|
+
|
|
|
+ let bPaste = false;
|
|
|
+ const data = info.sheet.zh_tree.getNodeKeyData(node);
|
|
|
+ for (let iCol = 0; iCol < info.cellRange.colCount; iCol++) {
|
|
|
+ const curCol = info.cellRange.col + iCol;
|
|
|
+ const colSetting = info.sheet.zh_setting.cols[curCol];
|
|
|
+ if (node.children && node.children.length > 0 && invalidFields.parent.indexOf(colSetting.field) >= 0) {
|
|
|
+ toastMessageUniq(hint.parent);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!_.isEmpty(node.b_code) && invalidFields.gcl.indexOf(colSetting.field) >= 0) {
|
|
|
+ toastMessageUniq(hint.gcl);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ const lPos = pos.getLedgerPos(node.id);
|
|
|
+ if (lPos && lPos.length > 0) {
|
|
|
+ if (value === '' && colSetting.field === 'b_code') {
|
|
|
+ toastMessageUniq(hint.posCode);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (colSetting.field === 'sgfh_qty' || colSetting.field === 'sgfh_tp' ||
|
|
|
+ colSetting.field === 'sjcl_qty' || colSetting.field === 'sjcl_tp' ||
|
|
|
+ colSetting.field === 'qtcl_qty' || colSetting.field === 'qtcl_tp') {
|
|
|
+ toastMessageUniq(hint.posQty);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const value = trimInvalidChar(pasteData[iRow][iCol]);
|
|
|
+ if (tree.checkNodeUsed(node, pos) && col.field === 'unit_price') {
|
|
|
+ toastMessageUniq (hint.usedUp);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (colSetting.type === 'Number') {
|
|
|
+ const num = _.toNumber(value);
|
|
|
+ if (num) {
|
|
|
+ data[colSetting.field] = num;
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ data[colSetting.field] = math.evaluate(transExpr(value));
|
|
|
+ } catch (err) {
|
|
|
+ toastMessageUniq(hint.invalidExpr);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (node.used && (col.field === 'code' || col.field ==='b_code')
|
|
|
+ && data[colSetting.field] !== '' && value === '') {
|
|
|
+ toastMessageUniq(hint.usedCode);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ data[colSetting.field] = value;
|
|
|
}
|
|
|
+ bPaste = true;
|
|
|
+ }
|
|
|
+ if (bPaste) {
|
|
|
+ datas.push(data);
|
|
|
+ } else {
|
|
|
+ filterNodes.push(node);
|
|
|
}
|
|
|
}
|
|
|
+ if (datas.length > 0) {
|
|
|
+ postData(window.location.pathname + '/update', {postType: 'update', postData: datas}, function (result) {
|
|
|
+ const refreshNode = tree.loadPostData(result);
|
|
|
+ if (refreshNode.update) {
|
|
|
+ refreshNode.update = refreshNode.update.concat(filterNodes);
|
|
|
+ }
|
|
|
+ billsTreeSpreadObj.refreshTree(info.sheet, refreshNode);
|
|
|
+ }, function () {
|
|
|
+ SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
|
|
|
+ }
|
|
|
},
|
|
|
clipboardPasted: function (e, info) {
|
|
|
const hint = {
|
|
@@ -616,7 +718,7 @@ $(document).ready(() => {
|
|
|
$('a[name=cpc]').click(function () {
|
|
|
billsSpread.commandManager().execute({
|
|
|
cmd: this.getAttribute('type'),
|
|
|
- sheetName: billsSpread.getActiveSheet().name()
|
|
|
+ sheetName: billsSheet.name()
|
|
|
});
|
|
|
});
|
|
|
|
|
@@ -660,10 +762,34 @@ $(document).ready(() => {
|
|
|
billsSpread.bind(spreadNS.Events.EditStarting, billsTreeSpreadObj.editStarting);
|
|
|
billsSpread.bind(spreadNS.Events.EditEnded, billsTreeSpreadObj.editEnded);
|
|
|
billsSpread.bind(spreadNS.Events.ClipboardPasting, billsTreeSpreadObj.clipboardPasting);
|
|
|
- billsSpread.bind(spreadNS.Events.ClipboardPasted, billsTreeSpreadObj.clipboardPasted);
|
|
|
+ billsSpread.bind(spreadNS.Events.ClipboardChanging, function (e, info) {
|
|
|
+ const copyText = SpreadJsObj.getFilterCopyText(info.sheet);
|
|
|
+ SpreadJsObj.Clipboard.setCopyData(copyText);
|
|
|
+ });
|
|
|
SpreadJsObj.addDeleteBind(billsSpread, billsTreeSpreadObj.deletePress);
|
|
|
SpreadJsObj.addCutEvents(billsSpread, billsTreeSpreadObj.cut);
|
|
|
let batchInsertObj;
|
|
|
+ $.contextMenu.types.batchInsert = function (item, opt, root) {
|
|
|
+ if ($.isFunction(item.icon)) {
|
|
|
+ item._icon = item.icon.call(this, this, $t, key, item);
|
|
|
+ } else {
|
|
|
+ if (typeof(item.icon) === 'string' && item.icon.substring(0, 3) === 'fa-') {
|
|
|
+ // to enable font awesome
|
|
|
+ item._icon = root.classNames.icon + ' ' + root.classNames.icon + '--fa fa ' + item.icon;
|
|
|
+ } else {
|
|
|
+ item._icon = root.classNames.icon + ' ' + root.classNames.icon + '-' + item.icon;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.addClass(item._icon);
|
|
|
+ const $obj = $('<div>' + item.name + '<input class="text-right ml-1 mr-1" type="tel" max="20" min="1" value="' + item.value + '" style="width: 30px; padding-right: 4px;">行</div>')
|
|
|
+ .appendTo(this);
|
|
|
+ const $input = $obj.find('input');
|
|
|
+ const event = () => { item.batchInsert($input[0], root); };
|
|
|
+ $obj.on('click', event).keypress(function (e) {if (e.keyCode === 13) { event(); }});
|
|
|
+ $input.click((e) => {e.stopPropagation();})
|
|
|
+ .keyup((e) => {if (e.keyCode === 13) item.batchInsert($input[0], root);})
|
|
|
+ .on('input', function () {this.value = this.value.replace(/[^\d]/g, '');});
|
|
|
+ };
|
|
|
// 右键菜单
|
|
|
$.contextMenu({
|
|
|
selector: '#bills-spread',
|
|
@@ -725,6 +851,24 @@ $(document).ready(() => {
|
|
|
return !(valid && first && sameParent && !(first.level === 1 && first.node_type) && !nodeUsed);
|
|
|
}
|
|
|
},
|
|
|
+ 'batchInsert': {
|
|
|
+ name: '批量插入',
|
|
|
+ type: 'batchInsert',
|
|
|
+ value: '2',
|
|
|
+ icon: 'fa-sign-in',
|
|
|
+ batchInsert: function (obj, root) {
|
|
|
+ if (_.toNumber(obj.value) > _.toNumber(obj.max)) {
|
|
|
+ obj.value = obj.max;
|
|
|
+ toastr.warning('批量插入不可多于' + obj.max);
|
|
|
+ } else if (_.toNumber(obj.value) < _.toNumber(obj.min)) {
|
|
|
+ obj.value = obj.min;
|
|
|
+ toastr.warning('批量插入不可少于' + obj.min);
|
|
|
+ } else {
|
|
|
+ billsTreeSpreadObj.baseOpr(billsSheet, 'add', parseInt(obj.value));
|
|
|
+ root.$menu.trigger('contextmenu:hide');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
'batchInsertBillsPos': {
|
|
|
name: '批量插入清单-计量单元',
|
|
|
icon: 'fa-sign-in',
|
|
@@ -1036,7 +1180,7 @@ $(document).ready(() => {
|
|
|
selectionChanged: function (e, info) {
|
|
|
const col = info.sheet.zh_setting.cols[info.newSelections[0].col];
|
|
|
const cell = info.sheet.getCell(info.newSelections[0].col, info.newSelections[0].col);
|
|
|
- if (col.type === 'Number') {
|
|
|
+ if (col && col.type === 'Number') {
|
|
|
const data = SpreadJsObj.getSelectObject(info.sheet);
|
|
|
if (data) {
|
|
|
$('#pos-expr').val(data[col.field]).attr('field', col.field).attr('org', data[col.field])
|