$(document).ready(function() { autoFlashHeight(); $('#filing').height($(".sjs-height-0").height() - $('#add-slibing').parent().parent().height() - 10); class FilingObj { constructor(setting) { // 原始数据整理后的树结构,用来整理zTree显示 this.dragTree = createDragTree({ id: 'id', pid: 'tree_pid', level: 'tree_level', order: 'tree_order', rootId: '-1' }); // 界面显示的zTree this.setting = setting; this.filingTree = null; $('#filing').height($(".sjs-height-0").height()-$('.d-flex',".sjs-height-0").height() - 10); } _loadFilingSourceNode() { const self = this; const loadChildren = function(children) { for (const child of children) { if (child.children && child.children.length > 0) loadChildren(child.children); child.source_node = self.dragTree.getItems(child.id); } }; const nodes = this.filingTree.getNodes(); loadChildren(nodes); } calcTotalFileCount() { this.dragTree.recursiveFun(this.dragTree.children, x => { if (x.children && x.children.length > 0) { x.total_file_count = x.children.reduce((pre, c) => { return pre + c.total_file_count }, 0); } else { x.total_file_count = x.file_count || 0; } }); } loadFiling() { if (this.filingTree) $.fn.zTree.destroy(this.setting.treeId); const sortNodes = this.dragTree.nodes.map(x => { const result = { id: x.id, tree_pid: x.tree_pid, name: x.name + (x.total_file_count > 0 ? `(${x.total_file_count})` : ''), spid: x.spid, }; return result; }); this.filingTree = $.fn.zTree.init($('#filing'), this.setting, sortNodes); this._loadFilingSourceNode(); const curCache = getLocalCache(this.curFilingKey); const curNode = curCache ? this.filingTree.getNodeByParam('id', curCache) : null; if (curNode){ this.filingTree.selectNode(curNode); filingObj.setCurFiling(curNode); } } analysisFiling(data) { this.dragTree.loadDatas(data); this.calcTotalFileCount(); this.loadFiling(); } addSiblingFiling(node) { const self = this; postData(`${window.location.pathname}/update`, { updateType: 'add', tree_pid: node.tree_pid, tree_pre_id: node.id }, function(result) { const refreshData = self.dragTree.loadPostData(result); const newNode = refreshData.create[0]; const nodes = self.filingTree.addNodes(node.getParentNode(), node.getIndex() + 1, [{ id: newNode.id, tree_pid: newNode.tree_pid, name: newNode.name, spid: newNode.spid }]); nodes[0].source_node = newNode; }); } addChildFiling(node) { const self = this; postData(`${window.location.pathname}/update`, { updateType: 'add', tree_pid: node.id }, function(result) { const refreshData = self.dragTree.loadPostData(result); const newNode = refreshData.create[0]; const nodes = self.filingTree.addNodes(node, -1, [{ id: newNode.id, tree_pid: newNode.tree_pid, name: newNode.name, spid: newNode.spid}]); nodes[0].source_node = newNode; }); } delFiling(node, callback) { if (node.file_count > 0) return; const parent = node.getParentNode(); const self = this; postData(`${window.location.pathname}/update`, { updateType: 'del', id: node.id }, function(result) { self.dragTree.loadPostData(result); self.filingTree.removeNode(node); self.calcTotalFileCount(); if (parent) { const path = parent.getPath(); for (const p of path) { p.name = p.source_node.name + (p.source_node.total_file_count > 0 ? `(${p.source_node.total_file_count})` : ''); filingObj.filingTree.updateNode(p); } } if (callback) callback(); }); } async renameFiling(node, newName) { const result = await postDataAsync(`${window.location.pathname}/update`, { updateType:'save', id: node.id, name: newName }); node.source_node.name = newName; node.name = node.source_node.name + (node.source_node.total_file_count > 0 ? `(${node.source_node.total_file_count})` : ''); return result; } async setCurFiling(node) { filingObj.curFiling = node; } moveFiling(node, tree_pid, tree_order) { if (node.file_count > 0) return; if (tree_pid === node.source_node.tree_pid && tree_order === node.source_node.tree_order) return; const self = this; postData(`${window.location.pathname}/update`, { updateType: 'move', id: node.id, tree_pid, tree_order }, function(result) { const refresh = self.dragTree.loadPostData(result); self.calcTotalFileCount(); const updated = []; for (const u of refresh.update) { if (!u) continue; const node = self.filingTree.getNodeByParam('id', u.id); if (node) { const path = node.getPath(); for (const p of path) { if (updated.indexOf(p.id) >= 0) continue; p.name = p.source_node.name + (p.source_node.total_file_count > 0 ? `(${p.source_node.total_file_count})` : ''); filingObj.filingTree.updateNode(p); updated.push(p.id); } } } }); } batchUpdateFiling(data, callback) { const self = this; postData(`${window.location.pathname}/update`, data, function(result) { self.analysisFiling(result); if (callback) callback(); }) } } const levelTreeSetting = { treeId: 'filing', view: { selectedMulti: false, showIcon: false, }, data: { simpleData: { idKey: 'id', pIdKey: 'tree_pid', rootPId: '-1', enable: true, } }, edit: { enable: !readOnly, showRemoveBtn: !readOnly, showRenameBtn: !readOnly, renameTitle: '编辑', removeTitle: '删除', drag: { isCopy: false, isMove: false, pre: false, next: false, inner: false, }, editNameSelectAll: true, }, callback: { onClick: async function (e, key, node) { if (filingObj.curFiling && filingObj.curFiling.id === node.id) return; filingObj.setCurFiling(node); }, beforeRename: async function(key, node, newName, isCancel) { if (!isCancel) await filingObj.renameFiling(node, newName); return true; }, beforeRemove: function(key, node, isCancel) { filingObj.deleteNode = node; $('#del-filing').modal('show'); return false; }, beforeDrop: function(key, nodes, target, moveType, isCopy) { if (readOnly) return false; if (!target) return false; const order = nodes[0].getIndex() + 1; const targetOrder = target.getIndex() + 1; const targetParent = target.getParentNode(); const targetMax = targetParent ? targetParent.children.length : filingObj.dragTree.children.length; if (moveType === 'prev') { if (target.tree_pid === nodes[0].tree_pid) { if (targetOrder > order) { filingObj.moveFiling(nodes[0], target.tree_pid, targetOrder === 1 ? 1 : targetOrder - 1); } else { filingObj.moveFiling(nodes[0], target.tree_pid, targetOrder === 1 ? 1 : targetOrder); } } else { filingObj.moveFiling(nodes[0], target.tree_pid, targetOrder === 1 ? 1 : targetOrder); } } else if (moveType === 'next') { if (target.tree_pid === nodes[0].tree_pid) { if (targetOrder < order) { filingObj.moveFiling(nodes[0], target.tree_pid, targetOrder === targetMax ? targetMax : targetOrder + 1); } else { filingObj.moveFiling(nodes[0], target.tree_pid, targetOrder === targetMax ? targetMax : targetOrder); } } else { filingObj.moveFiling(nodes[0], target.tree_pid, targetOrder + 1); } } else if (moveType === 'inner') { filingObj.moveFiling(nodes[0], target.tree_id, targetMax + 1); } } } }; const filingObj = new FilingObj(levelTreeSetting); filingObj.analysisFiling(filingData); $('#add-slibing').click(() => { if (!filingObj.curFiling) return; filingObj.addSiblingFiling(filingObj.curFiling); }); $('#add-child').click(() => { if (!filingObj.curFiling) return; filingObj.addChildFiling(filingObj.curFiling); }); $('#del-filing-ok').click(() => { if (!filingObj.deleteNode) return; filingObj.delFiling(filingObj.deleteNode, function() { $('#del-filing').modal('hide'); delete filingObj.deleteNode; }); }); class MultiObj { constructor(setting) { this.modal = $(`#${setting.modal}`); this.spread = SpreadJsObj.createNewSpread($(`#${setting.spread}`)[0]); this.sheet = this.spread.getActiveSheet(); this.spreadSetting = { cols: [ { title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 250, formatter: '@', readOnly: true, cellType: 'tree' }, { title: '文件数', colSpan: '1', rowSpan: '1', field: 'file_count', hAlign: 1, width: 50, readOnly: true }, { title: '授权', colSpan: '1', rowSpan: '1', field: 'permission_count', hAlign: 1, width: 50, readOnly: true }, { title: '固定', colSpan: '1', rowSpan: '1', field: 'is_fixed', hAlign: 1, width: 50, cellType: 'checkbox' }, { title: '提示', colSpan: '1', rowSpan: '1', field: 'tips', hAlign: 0, width: 280, formatter: '@', wordWrap: 1 }, ], emptyRows: 0, headRows: 1, headRowHeight: [32], defaultRowHeight: 21, headerFont: '12px 微软雅黑', font: '12px 微软雅黑', }; SpreadJsObj.initSheet(this.sheet, this.spreadSetting); this.checkTree = createNewPathTree('base', { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', isLeaf: 'is_leaf', fullPath: 'full_path', rootId: -1, }); const self = this; this.modal.bind('shown.bs.modal', function() { self.spread.refresh(); }); this.spread.bind(spreadNS.Events.ButtonClicked, function(e, info) { if (!info.sheet.zh_setting) return; const sheet = info.sheet, cellType = sheet.getCellType(info.row, info.col); if (cellType instanceof spreadNS.CellTypes.CheckBox) { if (sheet.isEditing()) sheet.endEdit(true); } const col = info.sheet.zh_setting.cols[info.col]; if (col.field !== 'is_fixed') return; const tree = self.checkTree; const node = tree.nodes[info.row]; if (node.level <= 1 && node.is_fixed) { toastr.warning('顶层节点不可取消固定'); SpreadJsObj.reLoadRowsData(info.sheet, [info.row]); return; } const row = []; if (!node.is_fixed) { const relas = []; if (node.level > 1) { const parents = tree.getAllParents(node); for (const p of parents) { relas.push(...p.children); if (p.level === 1) relas.push(p); } } else { relas.push(node); } for (const p of relas) { p.is_fixed = true; row.push(tree.nodes.indexOf(p)); } } else { const parent = tree.getParent(node); const posterity = tree.getPosterity(parent); for (const p of posterity) { p.is_fixed = false; row.push(tree.nodes.indexOf(p)); } } SpreadJsObj.reLoadRowsData(info.sheet, row); }); this.spread.bind(spreadNS.Events.EditEnded, function(e, info) { if (!info.sheet.zh_setting) return; const col = info.sheet.zh_setting.cols[info.col]; const node = SpreadJsObj.getSelectObject(info.sheet); node[col.field] = trimInvalidChar(info.editingText); SpreadJsObj.reLoadRowData(info.sheet, info.row) }); $(`#${setting.modal}-ok`).click(function() { try { const data = self.getMultiUpdateData(); filingObj.batchUpdateFiling(data, function() { window.location.reload(); }); } catch(err) { toastr.error(err.stack ? '保存配置数据错误' : err); } }); } reCalcFilingType() { for (const node of this.checkTree.nodes) { delete node.new_filing_type; node.is_fixed = node.is_fixed ? 1 : 0; if (node.file_count > 0 && node.is_fixed !== node.org_is_fixed) { throw `【${node.name}】下已存在文件,不可修改是否为固定节点`; } if (node.permission_count > 0 && node.is_fixed !== node.org_is_fixed) { throw `【${node.name}】下已授权给用户,不可修改是否为固定节点`; } } const sftIndex = []; const getNewSft = function () { let i = 1; while(sftIndex[i]) { i++; } return i; }; for (const node of this.checkTree.nodes) { if (node.file_count || node.permission_count) { node.new_filing_type = node.filing_type; } else if (node.is_fixed) { node.new_filing_type = getNewSft(); } else { const parent = this.checkTree.getParent(node); if (!parent) return [false, '顶层节点必须为固定节点']; node.new_filing_type = parent.new_filing_type; } sftIndex[node.new_filing_type] = node; } } getMultiUpdateData() { this.reCalcFilingType(); const data = []; const getUpdateData = function(children) { for (const [i, node] of children.entries()) { data.push({ id: node.id, is_fixed: node.is_fixed, filing_type: node.new_filing_type, tree_order: i + 1, tips: node.tips || '' }); // data.push({ id: node.id, is_fixed: node.is_fixed, filing_type: node.filing_type, file_count: node.file_count, new_filing_type: node.new_filing_type, tree_order: i + 1, tips: node.tips || '' }); if (node.children) getUpdateData(node.children); } }; getUpdateData(this.checkTree.children); return {updateType: 'multi', data}; } _convertData(sourceTree) { const data = []; for (const node of sourceTree.nodes) { const parent = node.tree_pid === '-1' ? undefined : data.find(x => { return x.id === node.tree_pid; }); const child = sourceTree.nodes.find(x => { return x.tree_pid === node.id; }); data.push({ id: node.id, tree_id: data.length + 1, tree_pid: parent ? parent.tree_id : -1, order: node.tree_order + 1, level: node.tree_level, is_leaf: !child, full_path: '', name: node.name, org_is_fixed: node.is_fixed, is_fixed: node.is_fixed, filing_type: node.filing_type, tips: node.tips, file_count: node.file_count, permission_count: node.permission_count, }); } return data; } calculateFileCount(arr) { let count = 0; for (const a of arr) { if (a.children && a.children.length > 0) a.file_count = this.calculateFileCount(a.children); count = count + a.file_count; } return count; } reload(sourceTree) { this.checkTree.loadDatas(this._convertData(sourceTree)); this.calculateFileCount(this.checkTree.children); SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Tree, this.checkTree); } show() { this.modal.modal('show'); } } let multiObj = new MultiObj({ modal: 'multi-set', spread: 'multi-spread' }); $('#multi-setting').click(() => { multiObj.reload(filingObj.dragTree); multiObj.show(); }); });