$(document).ready(function() { autoFlashHeight(); const RangeType = { unitType: 1, unit: 2, user: 3, }; const typeIndex = {}; const unitIndex = {}; const userIndex = {}; dataRangeTree.forEach(type => { typeIndex[Number(type.id)] = type; type.units.forEach(unit => { unit.parentTypeId = Number(type.id); unitIndex[Number(unit.id)] = unit; unit.users.forEach(user => { user.parentTypeId = Number(type.id); user.parentUnitId = Number(unit.id); userIndex[Number(user.id)] = user; }); }); }); dataRangeUnassignedUsers.forEach(user => { user.parentTypeId = Number(user.account_group) || 0; userIndex[Number(user.id)] = user; }); const makeSelection = function(config) { return { unitTypeIds: new Set((config.unit_type_ids || []).map(Number)), unitIds: new Set((config.unit_ids || []).map(Number)), userIds: new Set((config.user_ids || []).map(Number)), }; }; const cloneSelection = function(source) { return { unitTypeIds: new Set(Array.from(source.unitTypeIds)), unitIds: new Set(Array.from(source.unitIds)), userIds: new Set(Array.from(source.userIds)), }; }; let savedSelection = makeSelection(dataRangeConfig); let savedConfigured = Boolean(dataRangeConfig.configured); let currentSelection = cloneSelection(savedSelection); const escapeHtml = function(value) { return $('
').text(value === undefined || value === null ? '' : value).html(); }; const containsKeyword = function(value, keyword) { return !keyword || String(value || '').toLowerCase().indexOf(keyword) >= 0; }; const getSelectionSet = function(rangeType) { if (rangeType === RangeType.unitType) return currentSelection.unitTypeIds; if (rangeType === RangeType.unit) return currentSelection.unitIds; return currentSelection.userIds; }; const getSelectionSetFrom = function(selection, rangeType) { if (rangeType === RangeType.unitType) return selection.unitTypeIds; if (rangeType === RangeType.unit) return selection.unitIds; return selection.userIds; }; const getRangeName = function(rangeType, targetId) { let node; if (rangeType === RangeType.unitType) node = typeIndex[targetId]; if (rangeType === RangeType.unit) node = unitIndex[targetId]; if (rangeType === RangeType.user) node = userIndex[targetId]; return node ? node.name : ''; }; const getRangeTitle = function(rangeType) { if (rangeType === RangeType.unitType) return '单位类型'; if (rangeType === RangeType.unit) return '单位'; return '用户'; }; const removeTypeDescendants = function(typeId) { const type = typeIndex[typeId]; if (!type) return; type.units.forEach(unit => { currentSelection.unitIds.delete(Number(unit.id)); unit.users.forEach(user => currentSelection.userIds.delete(Number(user.id))); }); dataRangeUnassignedUsers.forEach(user => { if (Number(user.parentTypeId) === Number(typeId)) currentSelection.userIds.delete(Number(user.id)); }); }; const removeUnitDescendants = function(unitId) { const unit = unitIndex[unitId]; if (!unit) return; unit.users.forEach(user => currentSelection.userIds.delete(Number(user.id))); }; const renderCheckbox = function(rangeType, targetId, disabled) { const checked = getSelectionSet(rangeType).has(Number(targetId)) ? ' checked' : ''; const disabledAttr = disabled ? ' disabled' : ''; return ``; }; const renderNode = function(options) { const indent = options.level * 20; const toggle = options.hasChildren ? '' : ''; const checkbox = options.selectable === false ? '' : renderCheckbox(options.rangeType, options.targetId, options.disabled); const icon = options.rangeType === RangeType.user ? '' : ''; const extra = options.extra ? ` ${escapeHtml(options.extra)}` : ''; return `
${toggle}${checkbox}${icon}${escapeHtml(options.name)}${extra}
`; }; const renderTree = function() { const keyword = $('#data-range-keyword').val().trim().toLowerCase(); const html = []; dataRangeTree.forEach(type => { const typeMatch = containsKeyword(type.name, keyword); const visibleUnits = []; type.units.forEach(unit => { const unitMatch = containsKeyword(unit.name, keyword); const users = typeMatch || unitMatch ? unit.users : unit.users.filter(user => { return containsKeyword(user.name, keyword) || containsKeyword(user.role, keyword); }); if (!keyword || typeMatch || unitMatch || users.length > 0) visibleUnits.push({ unit, users }); }); if (keyword && !typeMatch && visibleUnits.length === 0) return; html.push('
'); html.push(renderNode({ level: 0, hasChildren: visibleUnits.length > 0, rangeType: RangeType.unitType, targetId: Number(type.id), name: type.name, })); html.push('
'); visibleUnits.forEach(item => { const typeSelected = currentSelection.unitTypeIds.has(Number(type.id)); html.push('
'); html.push(renderNode({ level: 1, hasChildren: item.users.length > 0, rangeType: RangeType.unit, targetId: Number(item.unit.id), name: item.unit.name, disabled: typeSelected, })); html.push('
'); item.users.forEach(user => { const unitSelected = currentSelection.unitIds.has(Number(item.unit.id)); html.push(renderNode({ level: 2, hasChildren: false, rangeType: RangeType.user, targetId: Number(user.id), name: user.name, extra: user.role, disabled: typeSelected || unitSelected, })); }); html.push('
'); }); html.push('
'); }); const otherUsers = keyword ? dataRangeUnassignedUsers.filter(user => { return containsKeyword(user.name, keyword) || containsKeyword(user.company, keyword) || containsKeyword(user.role, keyword); }) : dataRangeUnassignedUsers; if (otherUsers.length > 0) { html.push('
'); html.push(renderNode({ level: 0, hasChildren: true, selectable: false, name: '未关联单位用户' })); html.push('
'); otherUsers.forEach(user => { const typeSelected = currentSelection.unitTypeIds.has(Number(user.parentTypeId)); html.push(renderNode({ level: 1, hasChildren: false, rangeType: RangeType.user, targetId: Number(user.id), name: user.name, extra: user.company || user.role, disabled: typeSelected, })); }); html.push('
'); } if (html.length === 0) html.push('
没有匹配的数据
'); $('#data-range-tree').html(html.join('')); }; const renderSelected = function() { const html = []; const appendItems = function(rangeType, ids) { Array.from(ids).sort((a, b) => a - b).forEach(targetId => { html.push('
'); html.push(`${getRangeTitle(rangeType)}`); html.push(`${escapeHtml(getRangeName(rangeType, targetId))}`); html.push(``); html.push('
'); }); }; appendItems(RangeType.unitType, currentSelection.unitTypeIds); appendItems(RangeType.unit, currentSelection.unitIds); appendItems(RangeType.user, currentSelection.userIds); const total = currentSelection.unitTypeIds.size + currentSelection.unitIds.size + currentSelection.userIds.size; if (total === 0) html.push('
暂未选择范围
'); $('#data-range-selected-count').text(total); $('#selected-unit-type-count').text(currentSelection.unitTypeIds.size); $('#selected-unit-count').text(currentSelection.unitIds.size); $('#selected-user-count').text(currentSelection.userIds.size); $('#data-range-selected-list').html(html.join('')); }; const renderSummary = function() { if (!savedConfigured) { $('#data-range-summary').text('当前未配置数据范围,默认可选择当前子项目全部启用成员。'); return; } $('#data-range-summary').text( `已设置:单位类型 ${savedSelection.unitTypeIds.size} 项,单位 ${savedSelection.unitIds.size} 项,具体用户 ${savedSelection.userIds.size} 项。` ); }; const renderMainSelection = function() { const html = []; const appendItems = function(rangeType, ids) { Array.from(ids).sort((a, b) => a - b).forEach(targetId => { const rangeName = getRangeName(rangeType, targetId); if (!rangeName) return; html.push(``); html.push(`${escapeHtml(rangeName)}`); html.push(``); html.push(''); }); }; appendItems(RangeType.unitType, savedSelection.unitTypeIds); appendItems(RangeType.unit, savedSelection.unitIds); appendItems(RangeType.user, savedSelection.userIds); $('#data-range-value-list').html(html.join('')); }; const selectionToRanges = function(selection) { const ranges = []; const appendRanges = function(rangeType, ids) { ids.forEach(targetId => ranges.push({ range_type: rangeType, target_id: targetId })); }; appendRanges(RangeType.unitType, selection.unitTypeIds); appendRanges(RangeType.unit, selection.unitIds); appendRanges(RangeType.user, selection.userIds); return ranges; }; let saving = false; const saveSelection = function(selection, successCallback) { if (saving) return; saving = true; $('#save-data-range').prop('disabled', true); postData(`/sp/${dataRangeSpid}/setting/user/data-range/update`, { module_key: dataRangeModuleKey, ranges: selectionToRanges(selection), }, function(result) { const config = result || { configured: selectionToRanges(selection).length > 0, unit_type_ids: Array.from(selection.unitTypeIds), unit_ids: Array.from(selection.unitIds), user_ids: Array.from(selection.userIds), }; savedSelection = makeSelection(config); savedConfigured = Boolean(config.configured); saving = false; $('#save-data-range').prop('disabled', false); renderMainSelection(); renderSummary(); if (successCallback) successCallback(); }, function() { saving = false; $('#save-data-range').prop('disabled', false); }); }; const refreshModal = function() { renderTree(); renderSelected(); }; $('#open-data-range-modal').on('click keydown', function(event) { if ($(event.target).closest('.remove-main-data-range').length > 0) return; if (event.type === 'keydown' && event.keyCode !== 13 && event.keyCode !== 32) return; event.preventDefault(); currentSelection = cloneSelection(savedSelection); $('#data-range-keyword').val(''); refreshModal(); $('#data-range-modal').modal('show'); }); $('body').on('click', '.remove-main-data-range', function(event) { event.preventDefault(); event.stopPropagation(); if (saving) return; const rangeType = Number($(this).attr('data-range-type')); const targetId = Number($(this).attr('data-target-id')); const nextSelection = cloneSelection(savedSelection); getSelectionSetFrom(nextSelection, rangeType).delete(targetId); saveSelection(nextSelection, function() { toastr.success('授权用户范围已移除'); }); }); $('#data-range-search').click(renderTree); $('#data-range-keyword').on('keydown', function(event) { if (event.keyCode === 13) { event.preventDefault(); renderTree(); } }); $('#data-range-keyword').on('input', renderTree); $('body').on('click', '.data-range-toggle:not(.empty)', function() { const children = $(this).parent().next('.data-range-children'); children.toggleClass('collapsed'); $('i', this).toggleClass('fa-caret-down fa-caret-right'); }); $('body').on('change', '.data-range-check', function() { const rangeType = Number($(this).attr('data-range-type')); const targetId = Number($(this).attr('data-target-id')); const selection = getSelectionSet(rangeType); if (this.checked) { selection.add(targetId); if (rangeType === RangeType.unitType) removeTypeDescendants(targetId); if (rangeType === RangeType.unit) removeUnitDescendants(targetId); } else { selection.delete(targetId); } refreshModal(); }); $('body').on('click', '.remove-data-range', function() { const rangeType = Number($(this).attr('data-range-type')); const targetId = Number($(this).attr('data-target-id')); getSelectionSet(rangeType).delete(targetId); refreshModal(); }); $('#save-data-range').click(function() { saveSelection(currentSelection, function() { $('#data-range-modal').modal('hide'); toastr.success('数据范围保存成功'); }); }); renderMainSelection(); renderSummary(); });