下线店铺管理-检测店铺密码功能:后台 UI 按钮/徽标、Python 代理路由、Java 接口与 service 全套移除,V105 迁移删除 biz_shop_credential_check 表及历史记录
Build Backend JAR / build (push) Has been cancelled
Build Backend JAR / build (push) Has been cancelled
This commit is contained in:
+40
-62
@@ -528,6 +528,10 @@
|
||||
function columnMenuType(item) {
|
||||
return String(item && item.menu_type || 'app').toLowerCase() === 'admin' ? 'admin' : 'app';
|
||||
}
|
||||
// 数据层一级分组(不映射真实页面),只用于权限树层级与「上级菜单」候选。
|
||||
function isAdminMenuGroup(item) {
|
||||
return String(item && item.column_key || '').indexOf('admin_group_') === 0;
|
||||
}
|
||||
function columnDescendantIds(id) {
|
||||
var result = [], pending = [Number(id)];
|
||||
while (pending.length) {
|
||||
@@ -640,7 +644,7 @@
|
||||
if (!directIds[id] || item._structureOnly) return;
|
||||
var card = document.createElement('span');
|
||||
card.className = 'column-permission-card';
|
||||
card.textContent = (item.name || '') + ' (' + (item.column_key || '') + ')';
|
||||
card.textContent = item.name || '未命名';
|
||||
var btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.className = 'col-card-remove';
|
||||
@@ -740,7 +744,7 @@
|
||||
renderColumnPermissionWrap(wrapId);
|
||||
};
|
||||
var text = document.createElement('span');
|
||||
text.textContent = (item.name || '') + ' (' + (item.column_key || '') + ')';
|
||||
text.textContent = item.name || '未命名';
|
||||
if (inherited || structureOnly) text.className = 'inherited-label';
|
||||
label.appendChild(checkbox);
|
||||
label.appendChild(text);
|
||||
@@ -759,7 +763,7 @@
|
||||
}
|
||||
[
|
||||
{ key: 'admin', label: '后台菜单' },
|
||||
{ key: 'app', label: 'APP(软件)菜单' }
|
||||
{ key: 'app', label: '软件菜单' }
|
||||
].forEach(function (group) {
|
||||
var groupItems = allColumnsList.filter(function (item) {
|
||||
return columnMenuType(item) === group.key;
|
||||
@@ -835,13 +839,27 @@
|
||||
var blockedIds = editingId > 0 ? [editingId].concat(columnDescendantIds(editingId)) : [];
|
||||
select.innerHTML = '<option value="">无(一级菜单)</option>';
|
||||
allColumnsList.filter(function (item) {
|
||||
return !item._structureOnly && String(item.menu_type || 'app') === String(menuType) && blockedIds.indexOf(columnId(item)) < 0;
|
||||
// 只有一级分组可以作为上级菜单;分组行可能对管理员不可直接授予(structureOnly),
|
||||
// 但作为父级仍然合法,因此不做 _structureOnly 过滤。
|
||||
return isAdminMenuGroup(item)
|
||||
&& String(item.menu_type || 'app') === String(menuType)
|
||||
&& blockedIds.indexOf(columnId(item)) < 0;
|
||||
}).forEach(function (item) {
|
||||
var option = document.createElement('option');
|
||||
option.value = item.id;
|
||||
option.textContent = (item.name || '') + ' (' + (item.column_key || '') + ')';
|
||||
option.textContent = item.name || '未命名';
|
||||
select.appendChild(option);
|
||||
});
|
||||
// 兜底:编辑旧菜单时当前父级可能不是分组行,原值保留在选项里避免误改层级。
|
||||
if (current && !Array.prototype.some.call(select.options, function (option) {
|
||||
return option.value === String(current);
|
||||
})) {
|
||||
var legacy = allColumnsList.find(function (candidate) { return String(columnId(candidate)) === String(current); });
|
||||
var fallback = document.createElement('option');
|
||||
fallback.value = current;
|
||||
fallback.textContent = (legacy && legacy.name ? legacy.name : '原上级菜单') + '(原上级)';
|
||||
select.appendChild(fallback);
|
||||
}
|
||||
select.value = current;
|
||||
});
|
||||
}
|
||||
@@ -2365,7 +2383,7 @@
|
||||
items.forEach(function (u) {
|
||||
var opt = document.createElement('option');
|
||||
opt.value = u.id;
|
||||
opt.textContent = u.username + ' (' + roleLabel(u.role || 'normal') + ')';
|
||||
opt.textContent = u.username || '';
|
||||
sel.appendChild(opt);
|
||||
});
|
||||
sel.value = cur || '';
|
||||
@@ -3221,35 +3239,6 @@
|
||||
shopPasswordIcon(false) + '</button></span>';
|
||||
}
|
||||
|
||||
function renderShopCheckBadge(check) {
|
||||
if (!check) return '';
|
||||
var map = {
|
||||
'SUCCESS': ['ok', '密码正确'],
|
||||
'FAILED': ['bad', '密码错误'],
|
||||
'RUNNING': ['run', '检测中'],
|
||||
'PENDING': ['wait', '等待客户端'],
|
||||
'NO_NEED_LOGIN': ['warn', '已登录态'],
|
||||
'ERROR': ['bad', '检测异常']
|
||||
};
|
||||
var entry = map[check.status] || ['wait', check.status || '未知'];
|
||||
var tipText = [check.status, check.detail, check.check_finished_at].filter(Boolean).join(' · ');
|
||||
return '<div class="shop-check-badge ' + entry[0] + '" title="' + escapeHtml(tipText) + '">' + escapeHtml(entry[1]) + '</div>';
|
||||
}
|
||||
|
||||
var shopCheckPollTimer = null;
|
||||
function startShopCheckPolling() {
|
||||
if (shopCheckPollTimer) return;
|
||||
var ticks = 0;
|
||||
shopCheckPollTimer = setInterval(function () {
|
||||
ticks += 1;
|
||||
loadShopManage(shopManagePage);
|
||||
if (ticks >= 9) {
|
||||
clearInterval(shopCheckPollTimer);
|
||||
shopCheckPollTimer = null;
|
||||
}
|
||||
}, 20000);
|
||||
}
|
||||
|
||||
function renderShopTableText(value, fallback) {
|
||||
var text = String(value == null ? '' : value).trim();
|
||||
var shown = text || fallback || '-';
|
||||
@@ -3279,12 +3268,11 @@
|
||||
'<td class="shop-col-mall">' + renderShopTableText(item.mall_name) + '</td>' +
|
||||
'<td class="shop-col-automation">' + renderShopTableText(item.zn_username) + '</td>' +
|
||||
'<td class="shop-col-account">' + renderShopTableText(item.account) + '</td>' +
|
||||
'<td class="shop-col-password">' + renderShopPasswordCell(item) + renderShopCheckBadge(item.latest_check) + '</td>' +
|
||||
'<td class="shop-col-password">' + renderShopPasswordCell(item) + '</td>' +
|
||||
'<td class="shop-col-created">' + renderShopTableText(item.created_at) + '</td>' +
|
||||
'<td class="shop-col-updated">' + renderShopTableText(item.updated_at) + '</td>' +
|
||||
'<td class="shop-col-actions">' +
|
||||
'<button type="button" class="btn btn-sm" data-shop-manage-edit="' + escapeHtml(item.id) + '" data-shop-manage="' + (JSON.stringify(item).replace(/"/g, '"')) + '">编辑</button> ' +
|
||||
'<button type="button" class="btn btn-sm btn-check" data-shop-credential-check="' + escapeHtml(item.id) + '" data-shop-check-name="' + escapeHtml(item.shop_name || '') + '">检测密码</button> ' +
|
||||
'<button type="button" class="btn btn-sm btn-danger" data-shop-manage-delete="' + escapeHtml(item.id) + '" data-shop-manage-name="' + escapeHtml(item.shop_name || '') + '">删除</button>' +
|
||||
'</td></tr>';
|
||||
}).join('');
|
||||
@@ -3365,29 +3353,6 @@
|
||||
});
|
||||
};
|
||||
});
|
||||
document.querySelectorAll('[data-shop-credential-check]').forEach(function (btn) {
|
||||
btn.onclick = function () {
|
||||
var name = (btn.dataset.shopCheckName || '').replace(/"/g, '"');
|
||||
btn.disabled = true;
|
||||
btn.textContent = '已提交...';
|
||||
fetch('/api/admin/shop-manage/' + encodeURIComponent(btn.dataset.shopCredentialCheck) + '/credential-check?shop_name=' + encodeURIComponent(name), { method: 'POST' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
if (res.success) {
|
||||
alert(res.msg || '检测任务已创建,客户端将在 1 分钟内执行');
|
||||
startShopCheckPolling();
|
||||
loadShopManage(shopManagePage);
|
||||
} else {
|
||||
alert(res.error || '发起检测失败');
|
||||
}
|
||||
})
|
||||
.catch(function () { alert('发起检测失败'); })
|
||||
.finally(function () {
|
||||
btn.disabled = false;
|
||||
btn.textContent = '检测密码';
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getInvalidAsinDataLockedGroupId() {
|
||||
@@ -5838,6 +5803,7 @@
|
||||
var COLUMN_PAGE_CATALOG = [
|
||||
{ name: '用户管理', column_key: 'admin_users', route_path: 'users', menu_type: 'admin' },
|
||||
{ name: '菜单权限配置', column_key: 'admin_columns', route_path: 'columns', menu_type: 'admin' },
|
||||
{ name: '分组管理', column_key: 'admin_group_manage', route_path: 'group-manage', menu_type: 'admin' },
|
||||
{ name: '去重数据汇总', column_key: 'admin_dedupe_total_data', route_path: 'dedupe-total-data', menu_type: 'admin' },
|
||||
{ name: '品牌数据库', column_key: 'admin_invalid_asin_data', route_path: 'invalid-asin-data', menu_type: 'admin' },
|
||||
{ name: '查询ASIN', column_key: 'admin_query_asin', route_path: 'query-asin', menu_type: 'admin' },
|
||||
@@ -5846,7 +5812,7 @@
|
||||
{ name: '店铺管理', column_key: 'admin_shop_manage', route_path: 'shop-manage', menu_type: 'admin' },
|
||||
{ name: '最低价ASIN设置', column_key: 'admin_skip_price_asin', route_path: 'skip-price-asin', menu_type: 'admin' },
|
||||
{ name: '店铺数据记录', column_key: 'admin_shop_data_crawl_tasks', route_path: 'shop-data-crawl-tasks', menu_type: 'admin' },
|
||||
{ name: '视频任务管理', column_key: 'admin_image_video_tasks', route_path: 'image-video-tasks', menu_type: 'admin' },
|
||||
{ name: '视频任务记录', column_key: 'admin_image_video_tasks', route_path: 'image-video-tasks', menu_type: 'admin' },
|
||||
{ name: '生成记录', column_key: 'admin_history', route_path: 'history', menu_type: 'admin' },
|
||||
{ name: '软件版本管理', column_key: 'admin_version', route_path: 'version', menu_type: 'admin' },
|
||||
{ name: '数字人版本管理', column_key: 'digital_human_version', route_path: 'digital-human-version', menu_type: 'admin' },
|
||||
@@ -5892,14 +5858,17 @@
|
||||
var options = [];
|
||||
var push = function (item) {
|
||||
var key = columnPageValue(item.column_key, item.route_path);
|
||||
// 分组行(route_path 为空)不映射真实页面,不出现在页面选择器里。
|
||||
if (!item.column_key || !item.route_path || seen[key]) return;
|
||||
seen[key] = true;
|
||||
options.push({ value: key, label: (item.name || item.route_path) + '(' + item.route_path + ')' });
|
||||
options.push({ value: key, label: item.name || item.route_path });
|
||||
};
|
||||
COLUMN_PAGE_CATALOG.forEach(function (item) {
|
||||
if (String(item.menu_type) === String(menuType)) push(item);
|
||||
});
|
||||
allColumnsList.forEach(function (item) {
|
||||
// 一级分组行不是真实页面,不能作为新增菜单的页面来源。
|
||||
if (isAdminMenuGroup(item)) return;
|
||||
if (String(item.menu_type || 'app') === String(menuType)) push(item);
|
||||
});
|
||||
return options;
|
||||
@@ -5921,6 +5890,15 @@
|
||||
el.textContent = option.label;
|
||||
select.appendChild(el);
|
||||
});
|
||||
// 编辑分组行时没有合法页面可选,追加分组虚拟项兜底
|
||||
// (用户改不回页面时才需要,保存时按分组处理)。
|
||||
if (select.value === '' && current) {
|
||||
var fallback = document.createElement('option');
|
||||
fallback.value = current;
|
||||
fallback.textContent = '(分组菜单)';
|
||||
select.appendChild(fallback);
|
||||
select.value = current;
|
||||
}
|
||||
select.value = current;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user