|
|
@@ -11,6 +11,7 @@ $(document).ready(function() {
|
|
|
// 初始化 SpreadJS
|
|
|
this.spread = SpreadJsObj.createNewSpread($('#filing-spread')[0]);
|
|
|
this.spread.options.showHorizontalScrollbar = false; // 隐藏水平滚动条
|
|
|
+ this.spread.options.allowUndo = false; // 名称逐次保存到服务端,不使用仅修改单元格的撤销。
|
|
|
this.sheet = this.spread.getActiveSheet();
|
|
|
this.treeIcons = {
|
|
|
closed: new Image(),
|
|
|
@@ -41,7 +42,7 @@ $(document).ready(function() {
|
|
|
this.spreadSetting = {
|
|
|
cols: [
|
|
|
{
|
|
|
- title: '分类名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 220, formatter: '@', cellType: 'tree',
|
|
|
+ title: '分类名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 220, formatter: '@', cellType: 'tree', showTips: true,
|
|
|
getValue: function(data) {
|
|
|
return data.name;
|
|
|
},
|
|
|
@@ -53,8 +54,10 @@ $(document).ready(function() {
|
|
|
size: 18,
|
|
|
};
|
|
|
},
|
|
|
+ getTip: function(data) { return _.escape(data.name || ''); },
|
|
|
+ readOnly: data => !this._canEditFilingName(data),
|
|
|
},
|
|
|
- { title: '文件数', colSpan: '1', rowSpan: '1', field: 'total_file_count', hAlign: 1, width: 70, formatter: '@' },
|
|
|
+ { title: '文件数', colSpan: '1', rowSpan: '1', field: 'total_file_count', hAlign: 1, width: 70, formatter: '@', readOnly: true },
|
|
|
],
|
|
|
emptyRows: 0,
|
|
|
headRows: 1,
|
|
|
@@ -63,7 +66,7 @@ $(document).ready(function() {
|
|
|
headColWidth: [25],
|
|
|
headerFont: '12px 微软雅黑',
|
|
|
font: '12px 微软雅黑',
|
|
|
- readOnly: true,
|
|
|
+ readOnly: false,
|
|
|
selectedBackColor: '#e8f4fd',
|
|
|
};
|
|
|
|
|
|
@@ -74,11 +77,15 @@ $(document).ready(function() {
|
|
|
this.curPage = 1;
|
|
|
this.curTotalPage = 1;
|
|
|
this.curFiling = null;
|
|
|
- this.selectRemoveNode = null;
|
|
|
+ this.selectRemoveNodes = [];
|
|
|
+ this._directorySaving = false;
|
|
|
+ this._reloadingFiling = false;
|
|
|
this.fileOrderKey = 'fileOrderSjs';
|
|
|
this.fileOrder = getLocalCache(this.fileOrderKey) || 'create_time|desc';
|
|
|
this.curFilingKey = 'cur-filing-sjs-' + window.location.pathname.split('/')[2];
|
|
|
this._isRenaming = false;
|
|
|
+ this._nameEdit = null;
|
|
|
+ this._nameSaving = false;
|
|
|
|
|
|
this._bindEvents();
|
|
|
this._initNameClipboard();
|
|
|
@@ -229,7 +236,7 @@ $(document).ready(function() {
|
|
|
|
|
|
// 选中行变化事件
|
|
|
this.spread.bind(spreadNS.Events.SelectionChanged, async function(e, info) {
|
|
|
- if (self._isRenaming) return;
|
|
|
+ if (self._isRenaming || self._reloadingFiling) return;
|
|
|
const node = SpreadJsObj.getSelectObject(self.sheet);
|
|
|
if (node && (!self.curFiling || self.curFiling.id !== node.id)) {
|
|
|
await self.setCurFiling(node);
|
|
|
@@ -282,66 +289,7 @@ $(document).ready(function() {
|
|
|
self.nextPage();
|
|
|
});
|
|
|
|
|
|
- // 双击行内重命名分类
|
|
|
- $('#filing-spread').dblclick(function() {
|
|
|
- if (!canFiling) return;
|
|
|
- if (self._isRenaming) return;
|
|
|
- const node = SpreadJsObj.getSelectObject(self.sheet);
|
|
|
- if (!node || node.is_fixed) return;
|
|
|
-
|
|
|
- self._isRenaming = true;
|
|
|
- const rowIndex = self.filingTree.nodes.indexOf(node);
|
|
|
- const cellRect = self.sheet.getCellRect(rowIndex, 0);
|
|
|
- const containerRect = $('#filing-spread')[0].getBoundingClientRect();
|
|
|
-
|
|
|
- const inputLeft = containerRect.left + window.scrollX + cellRect.x + 2;
|
|
|
- const inputTop = containerRect.top + window.scrollY + cellRect.y + 2;
|
|
|
- const inputWidth = cellRect.width - 4;
|
|
|
- const inputHeight = cellRect.height - 4;
|
|
|
-
|
|
|
- const $input = $('<input type="text" class="form-control form-control-sm">')
|
|
|
- .val(node.name)
|
|
|
- .css({
|
|
|
- position: 'absolute',
|
|
|
- left: inputLeft,
|
|
|
- top: inputTop,
|
|
|
- width: inputWidth,
|
|
|
- height: inputHeight,
|
|
|
- zIndex: 1000,
|
|
|
- fontSize: '12px',
|
|
|
- padding: '0 4px',
|
|
|
- border: '2px solid #4a90d9',
|
|
|
- borderRadius: '2px',
|
|
|
- outline: 'none',
|
|
|
- boxShadow: '0 0 4px rgba(74,144,217,0.4)',
|
|
|
- });
|
|
|
-
|
|
|
- let handled = false;
|
|
|
- const finishEdit = async (save) => {
|
|
|
- if (handled) return;
|
|
|
- handled = true;
|
|
|
- const newName = $input.val().trim();
|
|
|
- $input.remove();
|
|
|
- self._isRenaming = false;
|
|
|
- if (save && newName && newName !== node.name) {
|
|
|
- await self.renameFiling(node, newName);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- $input.on('keydown', function(e) {
|
|
|
- if (e.keyCode === 13) { // Enter
|
|
|
- e.preventDefault();
|
|
|
- finishEdit(true);
|
|
|
- } else if (e.keyCode === 27) { // Escape
|
|
|
- e.preventDefault();
|
|
|
- finishEdit(false);
|
|
|
- }
|
|
|
- });
|
|
|
- $input.on('blur', function() { finishEdit(true); });
|
|
|
-
|
|
|
- $('body').append($input);
|
|
|
- $input.focus().select();
|
|
|
- });
|
|
|
+ this._bindFilingNameEditing();
|
|
|
|
|
|
// 分类右键菜单
|
|
|
$.contextMenu({
|
|
|
@@ -357,20 +305,20 @@ $(document).ready(function() {
|
|
|
name: '粘贴名称',
|
|
|
icon: 'fa-paste',
|
|
|
callback: function() { self._showNamePastePreview(); },
|
|
|
- disabled: function() { return !self._referenceNameClipboard || self._namePasteSaving; },
|
|
|
+ disabled: function() { return !self._referenceNameClipboard || self._namePasteSaving || self._nameSaving; },
|
|
|
},
|
|
|
'delete': {
|
|
|
name: '删除',
|
|
|
icon: 'fa-trash-o',
|
|
|
callback: function () {
|
|
|
- const node = SpreadJsObj.getSelectObject(self.sheet);
|
|
|
- if (!node || node.is_fixed) return;
|
|
|
- self.selectRemoveNode = node;
|
|
|
- $('#del-filing').modal('show');
|
|
|
+ self._showDeletePreview();
|
|
|
},
|
|
|
disabled: function () {
|
|
|
- const node = SpreadJsObj.getSelectObject(self.sheet);
|
|
|
- return !canFiling || !node || node.is_fixed;
|
|
|
+ const nodes = self._getSelectedFilings();
|
|
|
+ return self._directorySaving || self._nameSaving || projectFileLocked || !nodes.length || nodes.some(node => {
|
|
|
+ const permission = self._getFilingPermission(node.id);
|
|
|
+ return Number(node.is_fixed) || !permission.can_view || !permission.can_edit_dir;
|
|
|
+ });
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -596,47 +544,91 @@ $(document).ready(function() {
|
|
|
* 添加同级分类
|
|
|
*/
|
|
|
addSiblingFiling(node) {
|
|
|
- const self = this;
|
|
|
const treePid = node.tree_pid === -1 ? '-1' : this._findOriginalId(node.tree_pid);
|
|
|
- postData('filing/add', { tree_pid: treePid, tree_pre_id: node.id }, function(result) {
|
|
|
- filing.push(result);
|
|
|
- self._reloadFilingTree();
|
|
|
- });
|
|
|
+ this._addFiling({ tree_pid: treePid, tree_pre_id: node.id, name: '' });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 添加子级分类
|
|
|
*/
|
|
|
addChildFiling(node) {
|
|
|
- const self = this;
|
|
|
- postData('filing/add', { tree_pid: node.id }, function(result) {
|
|
|
- filing.push(result);
|
|
|
- self._reloadFilingTree();
|
|
|
- });
|
|
|
+ this._addFiling({ tree_pid: node.id, name: '' });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 重新加载归档树
|
|
|
*/
|
|
|
- _reloadFilingTree() {
|
|
|
- const convertedData = this._convertData(filing);
|
|
|
- this.filingTree.loadDatas(convertedData);
|
|
|
- SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Tree, this.filingTree);
|
|
|
- this.refreshFileCountHint();
|
|
|
+ _reloadFilingTree(focusId) {
|
|
|
+ const expanded = new Map(this.filingTree.nodes.map(node => [node.id, node.expanded]));
|
|
|
+ const currentId = focusId || (this.curFiling && this.curFiling.id);
|
|
|
+ const topRow = this.sheet.getViewportTopRow(1);
|
|
|
+ const topNode = this.filingTree.nodes[topRow];
|
|
|
+ this._reloadingFiling = true;
|
|
|
+ let currentNode;
|
|
|
+ try {
|
|
|
+ this.filingTree.loadDatas(this._convertData(filing));
|
|
|
+ this.filingTree.nodes.forEach(node => {
|
|
|
+ if (expanded.has(node.id)) node.expanded = expanded.get(node.id);
|
|
|
+ });
|
|
|
+ currentNode = this.filingTree.nodes.find(node => node.id === currentId);
|
|
|
+ if (focusId && currentNode) {
|
|
|
+ let parent = this.filingTree.getParent(currentNode);
|
|
|
+ while (parent) {
|
|
|
+ parent.expanded = true;
|
|
|
+ parent = this.filingTree.getParent(parent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.filingTree.refreshNodeVisible();
|
|
|
+ SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Tree, this.filingTree);
|
|
|
+ this.resizeSpreadColumns();
|
|
|
+ const highlightedRows = this.sheet.getSelections().map(selection => selection.row)
|
|
|
+ .filter(row => row >= 0 && row < this.sheet.getRowCount());
|
|
|
+ this.sheet.clearSelection();
|
|
|
+ if (currentNode) {
|
|
|
+ const selectedRow = this.filingTree.nodes.indexOf(currentNode);
|
|
|
+ this.sheet.setSelection(selectedRow, 0, 1, 1);
|
|
|
+ // 程序定位选区后,单独刷新组件绘制的整行选中背景。
|
|
|
+ SpreadJsObj.reloadRowsBackColor(this.sheet, [...new Set(highlightedRows.concat(selectedRow))]);
|
|
|
+ } else {
|
|
|
+ highlightedRows.forEach(row => {
|
|
|
+ this.sheet.getRange(row, 0, 1, this.sheet.getColumnCount()).backColor(this.sheet.getDefaultStyle().backColor);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ const targetRow = focusId && currentNode ? this.filingTree.nodes.indexOf(currentNode)
|
|
|
+ : this.filingTree.nodes.findIndex(node => topNode && node.id === topNode.id);
|
|
|
+ if (targetRow >= 0) this.sheet.showRow(targetRow, focusId ? spreadNS.VerticalPosition.center : spreadNS.VerticalPosition.top);
|
|
|
+ this.refreshFileCountHint();
|
|
|
+ } finally {
|
|
|
+ this._reloadingFiling = false;
|
|
|
+ }
|
|
|
+ this.curFiling = null;
|
|
|
+ if (currentNode) {
|
|
|
+ this.setCurFiling(currentNode).catch(() => { $('#file-view').hide(); });
|
|
|
+ if (focusId) this.spread.focus();
|
|
|
+ } else {
|
|
|
+ canFiling = false;
|
|
|
+ $('.js-can-edit-dir').hide();
|
|
|
+ $('#file-view').hide();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 删除分类
|
|
|
*/
|
|
|
- delFiling(node, callback) {
|
|
|
+ delFiling(nodes, callback) {
|
|
|
+ if (this._directorySaving || this._nameSaving || !nodes.length) return;
|
|
|
const self = this;
|
|
|
- const parent = this.filingTree.getParent(node);
|
|
|
- postData('filing/del', { id: node.id }, function(result) {
|
|
|
+ const modal = $('#filesjs-del-filing');
|
|
|
+ this._directorySaving = true;
|
|
|
+ $('button', modal).prop('disabled', true);
|
|
|
+ $('#filesjs-del-filing-error').text('');
|
|
|
+ postData('filing/del', { ids: nodes.map(node => node.id) }, function(result) {
|
|
|
// 更新 filing 数组:移除已删除的节点
|
|
|
if (result && result.delete) {
|
|
|
for (const delId of result.delete) {
|
|
|
const idx = filing.findIndex(x => x.id === delId);
|
|
|
if (idx >= 0) filing.splice(idx, 1);
|
|
|
+ delete filingPermissionMap[delId];
|
|
|
}
|
|
|
}
|
|
|
// 更新兄弟节点的 tree_order
|
|
|
@@ -648,33 +640,34 @@ $(document).ready(function() {
|
|
|
}
|
|
|
// 重新加载树
|
|
|
self._reloadFilingTree();
|
|
|
- $('#file-view').hide();
|
|
|
- self.curFiling = null;
|
|
|
+ self._directorySaving = false;
|
|
|
+ $('button', modal).prop('disabled', false);
|
|
|
if (callback) callback();
|
|
|
+ toastr.success(`已删除 ${result.delete.length} 个分类`);
|
|
|
+ }, function(error) {
|
|
|
+ self._directorySaving = false;
|
|
|
+ $('button', modal).prop('disabled', false);
|
|
|
+ $('#filesjs-del-filing-error').text(error || '删除失败,请重试');
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 重命名分类
|
|
|
*/
|
|
|
- async renameFiling(node, newName) {
|
|
|
- const result = await postDataAsync('filing/save', { id: node.id, name: newName });
|
|
|
- const srcNode = filing.find(x => x.id === node.id || x.id == node.id);
|
|
|
- if (srcNode) srcNode.name = newName;
|
|
|
- node.name = newName;
|
|
|
- const countHint = node.total_file_count > 0 ? `(${node.total_file_count})` : '';
|
|
|
- node.name = newName;
|
|
|
- const rowIndex = this.filingTree.nodes.indexOf(node);
|
|
|
- if (rowIndex >= 0) {
|
|
|
- SpreadJsObj.reLoadRowsData(this.sheet, [rowIndex]);
|
|
|
- }
|
|
|
- let parent = this.filingTree.getParent(node);
|
|
|
- while (parent) {
|
|
|
- const pIdx = this.filingTree.nodes.indexOf(parent);
|
|
|
- if (pIdx >= 0) SpreadJsObj.reLoadRowsData(this.sheet, [pIdx]);
|
|
|
- parent = this.filingTree.getParent(parent);
|
|
|
- }
|
|
|
- return result;
|
|
|
+ renameFiling(node, newName) {
|
|
|
+ this._nameSaving = true;
|
|
|
+ const finishSave = () => {
|
|
|
+ this._nameSaving = false;
|
|
|
+ const row = this.filingTree.nodes.findIndex(item => item.id === node.id);
|
|
|
+ if (row >= 0) SpreadJsObj.reLoadRowsData(this.sheet, [row]);
|
|
|
+ };
|
|
|
+ postData('filing/save', { id: node.id, name: newName }, () => {
|
|
|
+ const source = filing.find(item => item.id === node.id);
|
|
|
+ if (source) source.name = newName;
|
|
|
+ const currentNode = this.filingTree.nodes.find(item => item.id === node.id);
|
|
|
+ if (currentNode) currentNode.name = newName;
|
|
|
+ finishSave();
|
|
|
+ }, finishSave, false);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -873,6 +866,9 @@ $(document).ready(function() {
|
|
|
const differ = count - (node.file_count || 0);
|
|
|
node.file_count = count;
|
|
|
node.total_file_count = count;
|
|
|
+ // 分类增删后会从 filing 重建树,同步原始数据以保留最新文件数。
|
|
|
+ const source = filing.find(item => item.id === node.id);
|
|
|
+ if (source) source.file_count = count;
|
|
|
// 更新 SpreadJS 显示
|
|
|
const rowIndex = this.filingTree.nodes.indexOf(node);
|
|
|
if (rowIndex >= 0) {
|
|
|
@@ -1014,6 +1010,7 @@ $(document).ready(function() {
|
|
|
this._pasteReferenceText(text);
|
|
|
}, true);
|
|
|
this.sheet.bind(spreadNS.Events.ClipboardPasting, (e, info) => {
|
|
|
+ if (this._isRenaming || this.sheet.isEditing()) return;
|
|
|
info.cancel = true;
|
|
|
this._pasteReferenceText(info.pasteData ? info.pasteData.text : '');
|
|
|
});
|
|
|
@@ -1131,7 +1128,7 @@ $(document).ready(function() {
|
|
|
}
|
|
|
|
|
|
_showNamePastePreview() {
|
|
|
- if (this._namePasteSaving || $('#filing-name-paste').hasClass('show')) return;
|
|
|
+ if (this._namePasteSaving || this._nameSaving || $('#filing-name-paste').hasClass('show')) return;
|
|
|
const clipboard = this._referenceNameClipboard;
|
|
|
if (!clipboard) { toastr.warning('请先从右侧参考文件复制名称'); return; }
|
|
|
if (this._isRenaming) return;
|
|
|
@@ -1163,7 +1160,7 @@ $(document).ready(function() {
|
|
|
}
|
|
|
|
|
|
_savePastedNames() {
|
|
|
- if (this._namePasteSaving || !this._namePasteItems.length || this._namePasteItems.some(item => item.errors.length)) return;
|
|
|
+ if (this._namePasteSaving || this._nameSaving || !this._namePasteItems.length || this._namePasteItems.some(item => item.errors.length)) return;
|
|
|
const items = this._namePasteItems.map(item => ({ id: item.id, old_name: item.old_name, name: item.name }));
|
|
|
if (!items.some(item => item.name !== item.old_name)) return;
|
|
|
const modal = $('#filing-name-paste');
|
|
|
@@ -1192,6 +1189,119 @@ $(document).ready(function() {
|
|
|
$('#filing-name-paste-error').text(error || '保存失败,请重试;若名称已变化,请刷新页面后重新粘贴。');
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+ _addFiling(data) {
|
|
|
+ if (this._directorySaving || this._nameSaving || !canFiling || this._isRenaming) return;
|
|
|
+ this._directorySaving = true;
|
|
|
+ postData('filing/add', data, result => {
|
|
|
+ for (const update of result.update || []) {
|
|
|
+ const source = filing.find(node => node.id === update.id);
|
|
|
+ if (source) Object.assign(source, update);
|
|
|
+ }
|
|
|
+ for (const node of result.create || []) {
|
|
|
+ if (!filing.some(source => source.id === node.id)) filing.push(node);
|
|
|
+ }
|
|
|
+ Object.assign(filingPermissionMap, result.permissionMap || {});
|
|
|
+ this._directorySaving = false;
|
|
|
+ const created = (result.create || [])[0];
|
|
|
+ this._reloadFilingTree(created && created.id);
|
|
|
+ }, () => { this._directorySaving = false; });
|
|
|
+ }
|
|
|
+
|
|
|
+ _getSelectedFilings() {
|
|
|
+ const rows = new Set();
|
|
|
+ for (const selection of this.sheet.getSelections()) {
|
|
|
+ const first = Math.max(0, selection.row);
|
|
|
+ const last = selection.row < 0 ? this.filingTree.nodes.length
|
|
|
+ : Math.min(first + selection.rowCount, this.filingTree.nodes.length);
|
|
|
+ for (let row = first; row < last; row++) {
|
|
|
+ if (this.sheet.getRowVisible(row)) rows.add(row);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return [...rows].sort((a, b) => a - b).map(row => this.filingTree.nodes[row]);
|
|
|
+ }
|
|
|
+
|
|
|
+ _showDeletePreview() {
|
|
|
+ if (this._directorySaving || this._nameSaving || this._isRenaming || projectFileLocked) return;
|
|
|
+ const nodes = this._getSelectedFilings();
|
|
|
+ if (!nodes.length) return;
|
|
|
+ const included = new Set(nodes.map(node => node.id));
|
|
|
+ // 树节点按父子顺序排列,检查选中的分类以及折叠的子分类。
|
|
|
+ const scope = this.filingTree.nodes.filter(node => {
|
|
|
+ const parent = this.filingTree.getParent(node);
|
|
|
+ if (parent && included.has(parent.id)) included.add(node.id);
|
|
|
+ return included.has(node.id);
|
|
|
+ });
|
|
|
+ if (scope.some(node => Number(node.file_count || 0) !== 0 || Number(node.total_file_count || 0) !== 0)) {
|
|
|
+ toastr.error('此分类已存在文件,请先删除所有文件。');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (scope.some(node => Number(node.is_fixed))) {
|
|
|
+ toastr.error('固定分类不可删除');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (scope.some(node => {
|
|
|
+ const permission = this._getFilingPermission(node.id);
|
|
|
+ return !permission.can_view || !permission.can_edit_dir;
|
|
|
+ })) {
|
|
|
+ toastr.error('部分分类或子分类没有编辑目录权限,无法删除');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.selectRemoveNodes = nodes;
|
|
|
+ const list = $('#filesjs-del-filing-list').empty();
|
|
|
+ nodes.forEach(node => { $('<li>').text(node.name || '(未命名分类)').appendTo(list); });
|
|
|
+ $('#filesjs-del-filing-summary').text(`已选择 ${nodes.length} 个分类,确认删除?`);
|
|
|
+ $('#filesjs-del-filing-error').text('');
|
|
|
+ $('#filesjs-del-filing').modal('show');
|
|
|
+ }
|
|
|
+
|
|
|
+ _canEditFilingName(node) {
|
|
|
+ if (!node || projectFileLocked || Number(node.is_fixed)) return false;
|
|
|
+ const permission = this._getFilingPermission(node.id);
|
|
|
+ return Boolean(Number(permission.can_view) && Number(permission.can_edit_dir));
|
|
|
+ }
|
|
|
+
|
|
|
+ _bindFilingNameEditing() {
|
|
|
+ this.sheet.bind(spreadNS.Events.EditStarting, (e, info) => {
|
|
|
+ const node = this.filingTree.nodes[info.row];
|
|
|
+ if (info.col !== 0 || !this._canEditFilingName(node) || this._directorySaving
|
|
|
+ || this._nameSaving || this._namePasteSaving || this._reloadingFiling) {
|
|
|
+ info.cancel = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this._isRenaming = true;
|
|
|
+ this._nameEdit = { node, row: info.row, oldName: String(node.name || '') };
|
|
|
+ });
|
|
|
+ this.sheet.bind(spreadNS.Events.EditEnded, (e, info) => { this._finishFilingNameEdit(info); });
|
|
|
+ $('#filing-spread')[0].addEventListener('keydown', e => {
|
|
|
+ if (e.isComposing || e.keyCode === 229) return;
|
|
|
+ // 不允许快捷键绕过单个名称保存,批量替换继续走粘贴确认弹窗。
|
|
|
+ if (!this.sheet.isEditing() && (e.keyCode === 46 || e.keyCode === 8 || ((e.ctrlKey || e.metaKey) && e.keyCode === 88))) {
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopImmediatePropagation();
|
|
|
+ } else if ((e.ctrlKey || e.metaKey) && e.keyCode === 13) {
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopImmediatePropagation();
|
|
|
+ if (this.sheet.isEditing()) this.sheet.endEdit();
|
|
|
+ }
|
|
|
+ }, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ _finishFilingNameEdit(info) {
|
|
|
+ const editing = this._nameEdit;
|
|
|
+ this._nameEdit = null;
|
|
|
+ this._isRenaming = false;
|
|
|
+ if (!editing || info.col !== 0 || info.row !== editing.row) return;
|
|
|
+ // Esc 取消时 editingText 仍是输入内容;读取实际单元格值,避免误保存。
|
|
|
+ const value = String(this.sheet.getValue(info.row, 0) || '');
|
|
|
+ if (value === editing.oldName) return;
|
|
|
+ const newName = value.trim();
|
|
|
+ if (!newName || newName === editing.oldName) {
|
|
|
+ this.sheet.setValue(info.row, 0, editing.oldName);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.renameFiling(editing.node, newName);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 初始化
|
|
|
@@ -2496,13 +2606,19 @@ $(document).ready(function() {
|
|
|
});
|
|
|
|
|
|
// 删除分类确认弹窗
|
|
|
- $('#del-filing-ok').off('click').on('click', function() {
|
|
|
- if (filingSjs.selectRemoveNode) {
|
|
|
- filingSjs.delFiling(filingSjs.selectRemoveNode, function() {
|
|
|
- $('#del-filing').modal('hide');
|
|
|
+ $('#filesjs-del-filing-ok').on('click', function() {
|
|
|
+ if (filingSjs.selectRemoveNodes.length) {
|
|
|
+ filingSjs.delFiling(filingSjs.selectRemoveNodes, function() {
|
|
|
+ $('#filesjs-del-filing').modal('hide');
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
+ $('#filesjs-del-filing').on('hide.bs.modal', function(e) {
|
|
|
+ if (filingSjs._directorySaving) e.preventDefault();
|
|
|
+ }).on('hidden.bs.modal', function() {
|
|
|
+ filingSjs.selectRemoveNodes = [];
|
|
|
+ filingSjs.spread.focus();
|
|
|
+ });
|
|
|
|
|
|
// 批量删除确认
|
|
|
$('#batch-del-file-ok').off('click').on('click', function() {
|