后台用户管理菜单权限目录:加载增加自动重试与失败提示/重新加载,创建编辑失败时自动恢复
Build Backend JAR / build (push) Has been cancelled

This commit is contained in:
2026-08-27 05:09:40 -04:00
parent 75f23d4568
commit d643ae156a
2 changed files with 65 additions and 8 deletions
+64 -7
View File
@@ -388,7 +388,44 @@
} }
var allColumnsList = []; var allColumnsList = [];
var columnPermissionCatalogReady = false; var columnPermissionCatalogReady = false;
var columnPermissionCatalogState = 'idle'; // idle | loading | ready | failed
var columnPermissionCatalogError = '';
var columnCardsContainerMap = { createColumnPermissionWrap: 'createColumnCards', editColumnPermissionWrap: 'editColumnCards' }; var columnCardsContainerMap = { createColumnPermissionWrap: 'createColumnCards', editColumnPermissionWrap: 'editColumnCards' };
function fetchCatalogWithRetry(url, attempts) {
return fetch(url).then(function (r) {
if (!r.ok) throw new Error('请求失败(' + r.status + ')');
return r.json();
}).catch(function (error) {
if (attempts <= 1) throw error;
return new Promise(function (resolve) { setTimeout(resolve, 700); })
.then(function () { return fetchCatalogWithRetry(url, attempts - 1); });
});
}
function renderPermissionCatalogStatus() {
var wrap = document.getElementById('createColumnPermissionWrap');
if (!wrap) return;
if (columnPermissionCatalogState === 'loading') {
wrap.textContent = '菜单权限加载中…';
} else if (columnPermissionCatalogState === 'failed') {
wrap.innerHTML = '';
var tip = document.createElement('div');
tip.style.color = '#e5484d';
tip.style.fontSize = '13px';
tip.style.padding = '8px 0';
tip.textContent = '菜单权限加载失败' +
(columnPermissionCatalogError ? '' + columnPermissionCatalogError + '' : '') +
'';
var retryBtn = document.createElement('button');
retryBtn.type = 'button';
retryBtn.className = 'col-perm-retry';
retryBtn.textContent = '重新加载';
retryBtn.style.marginLeft = '6px';
retryBtn.style.padding = '2px 10px';
retryBtn.onclick = loadColumnsForPermission;
tip.appendChild(retryBtn);
wrap.appendChild(tip);
}
}
// Hierarchical permission editor: only direct IDs are submitted; descendants are visual inheritance. // Hierarchical permission editor: only direct IDs are submitted; descendants are visual inheritance.
function columnParentId(item) { function columnParentId(item) {
var value = item && item.parent_id != null ? item.parent_id : item && item.parentId; var value = item && item.parent_id != null ? item.parent_id : item && item.parentId;
@@ -424,12 +461,16 @@
return columnTreeFullyCovered(columnId(child), directIds); return columnTreeFullyCovered(columnId(child), directIds);
}); });
} }
var columnPermissionCatalogPending = null;
function loadColumnsForPermission() { function loadColumnsForPermission() {
if (columnPermissionCatalogPending) return columnPermissionCatalogPending;
columnPermissionCatalogReady = false; columnPermissionCatalogReady = false;
columnPermissionCatalogState = 'loading';
columnPermissionCatalogError = '';
renderPermissionCatalogStatus();
var ownedKeys = {}, ownedRoutes = {}; var ownedKeys = {}, ownedRoutes = {};
var ownPermissionRequest = (currentUserRole === 'admin' && currentUserId) var ownPermissionRequest = (currentUserRole === 'admin' && currentUserId)
? fetch('/api/admin/user/' + currentUserId + '/column-permissions') ? fetchCatalogWithRetry('/api/admin/user/' + currentUserId + '/column-permissions', 3)
.then(function (r) { return r.json(); })
.then(function (res) { .then(function (res) {
if (!res.success) throw new Error(res.error || '当前用户权限加载失败'); if (!res.success) throw new Error(res.error || '当前用户权限加载失败');
(res.items || []).forEach(function (item) { (res.items || []).forEach(function (item) {
@@ -438,10 +479,9 @@
}); });
}) })
: Promise.resolve(); : Promise.resolve();
ownPermissionRequest.then(function () { return fetch('/api/admin/columns'); }) var catalogChain = ownPermissionRequest.then(function () { return fetchCatalogWithRetry('/api/admin/columns', 3); })
.then(function (r) { return r.json(); })
.then(function (res) { .then(function (res) {
if (!res.success) return; if (!res.success) throw new Error(res.error || '菜单列表加载失败');
var availableColumns = (res.items || []).filter(function (item) { var availableColumns = (res.items || []).filter(function (item) {
if (item.column_key === 'admin_image_video_task_data' || if (item.column_key === 'admin_image_video_task_data' ||
item.column_key === 'admin_shop_data_crawl_task_data') return false; item.column_key === 'admin_shop_data_crawl_task_data') return false;
@@ -477,17 +517,25 @@
}); });
} }
columnPermissionCatalogReady = true; columnPermissionCatalogReady = true;
columnPermissionCatalogState = 'ready';
renderColumnPermissionWrap('createColumnPermissionWrap'); renderColumnPermissionWrap('createColumnPermissionWrap');
renderColumnPermissionWrap('editColumnPermissionWrap'); renderColumnPermissionWrap('editColumnPermissionWrap');
populateColumnParentSelects(); populateColumnParentSelects();
}).catch(function () { }).catch(function (error) {
columnPermissionCatalogReady = false; columnPermissionCatalogReady = false;
columnPermissionCatalogState = 'failed';
columnPermissionCatalogError = (error && error.message) ? error.message : '';
allColumnsList = []; allColumnsList = [];
var editPermissionWrap = document.getElementById('editColumnPermissionWrap'); var editPermissionWrap = document.getElementById('editColumnPermissionWrap');
if (editPermissionWrap) editPermissionWrap._permissionsReady = false; if (editPermissionWrap) editPermissionWrap._permissionsReady = false;
renderColumnPermissionWrap('createColumnPermissionWrap'); renderColumnPermissionWrap('createColumnPermissionWrap');
renderColumnPermissionWrap('editColumnPermissionWrap'); renderColumnPermissionWrap('editColumnPermissionWrap');
renderPermissionCatalogStatus();
}).finally(function () {
columnPermissionCatalogPending = null;
}); });
columnPermissionCatalogPending = catalogChain;
return catalogChain;
} }
function renderColumnCards(wrapId) { function renderColumnCards(wrapId) {
var wrap = document.getElementById(wrapId); var wrap = document.getElementById(wrapId);
@@ -748,6 +796,9 @@
editPermissionWrap._directIds = {}; editPermissionWrap._directIds = {};
editPermissionWrap._permissionsReady = false; editPermissionWrap._permissionsReady = false;
renderColumnPermissionWrap('editColumnPermissionWrap'); renderColumnPermissionWrap('editColumnPermissionWrap');
if (!columnPermissionCatalogReady && (columnPermissionCatalogState === 'failed' || columnPermissionCatalogState === 'idle')) {
loadColumnsForPermission();
}
fetch('/api/admin/user/' + (u.id) + '/columns') fetch('/api/admin/user/' + (u.id) + '/columns')
.then(function (r) { return r.json(); }) .then(function (r) { return r.json(); })
.then(function (res) { .then(function (res) {
@@ -800,7 +851,13 @@
return; return;
} }
if (!columnPermissionCatalogReady) { if (!columnPermissionCatalogReady) {
msgEl.textContent = '菜单权限尚未加载,请稍后重试'; if (columnPermissionCatalogState === 'failed' || columnPermissionCatalogState === 'idle') {
loadColumnsForPermission();
msgEl.textContent = '菜单权限加载失败,已重新加载,请稍后重试';
msgEl.classList.add('err');
return;
}
msgEl.textContent = '菜单权限尚未加载(加载中),请稍后重试';
msgEl.classList.add('err'); msgEl.classList.add('err');
return; return;
} }
+1 -1
View File
@@ -3209,7 +3209,7 @@
</div> </div>
</div> </div>
</div> </div>
<script src="/static/admin.js?v=dedupe-country-2"></script> <script src="/static/admin.js?v=admin-perm-retry-1"></script>
</body> </body>
</html> </html>