diff --git a/backend/blueprints/__pycache__/admin_api.cpython-312.pyc b/backend/blueprints/__pycache__/admin_api.cpython-312.pyc index 4957fdd..f0b8657 100644 Binary files a/backend/blueprints/__pycache__/admin_api.cpython-312.pyc and b/backend/blueprints/__pycache__/admin_api.cpython-312.pyc differ diff --git a/backend/blueprints/admin_api.py b/backend/blueprints/admin_api.py index 180ed78..bc7c75f 100644 --- a/backend/blueprints/admin_api.py +++ b/backend/blueprints/admin_api.py @@ -13,6 +13,24 @@ from werkzeug.security import generate_password_hash from utils.db import get_db from utils.auth import admin_required, get_current_admin_role + + +ALLOWED_DEDUPE_TOTAL_DATA_ADMIN_USERNAMES = {'刘丽泓'} + + +def _can_access_dedupe_total_data(role, current_row): + if role == 'super_admin': + return True + if role != 'admin' or not current_row: + return False + return (current_row.get('username') or '').strip() in ALLOWED_DEDUPE_TOTAL_DATA_ADMIN_USERNAMES + + +def _ensure_dedupe_total_data_access(): + role, current_row = get_current_admin_role() + if not _can_access_dedupe_total_data(role, current_row): + return None, None, (jsonify({'success': False, 'error': '无权限访问数据去重总数据'}), 403) + return role, current_row, None from ali_oss import upload_file as oss_upload_file try: @@ -138,6 +156,7 @@ def list_users(): 'page': page, 'page_size': page_size, 'current_user_role': role, + 'current_user_username': current_row.get('username') or '', 'admins': admins, }) except Exception as e: @@ -603,6 +622,9 @@ def upload_version(): @admin_api.route('/dedupe-total-data') @admin_required def list_dedupe_total_data(): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied page = max(1, int(request.args.get('page', 1))) page_size = min(100, max(1, int(request.args.get('page_size', 15)))) keyword = (request.args.get('keyword') or '').strip() @@ -634,6 +656,9 @@ def list_dedupe_total_data(): @admin_api.route('/dedupe-total-data/import/') @admin_required def dedupe_total_data_import_progress(import_id): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied result, error_response, status = _proxy_backend_java( 'GET', f'/api/admin/dedupe-total-data/import/{import_id}', @@ -658,6 +683,9 @@ def dedupe_total_data_import_progress(import_id): @admin_api.route('/dedupe-total-data/import', methods=['POST']) @admin_required def import_dedupe_total_data(): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied file_storage = request.files.get('file') if not file_storage or file_storage.filename == '': return jsonify({'success': False, 'error': '请选择 Excel 文件'}) @@ -682,6 +710,9 @@ def import_dedupe_total_data(): @admin_api.route('/dedupe-total-data/delete-import/') @admin_required def dedupe_total_data_delete_import_progress(import_id): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied result, error_response, status = _proxy_backend_java( 'GET', f'/api/admin/dedupe-total-data/delete-import/{import_id}', @@ -706,6 +737,9 @@ def dedupe_total_data_delete_import_progress(import_id): @admin_api.route('/dedupe-total-data/delete-import', methods=['POST']) @admin_required def delete_import_dedupe_total_data(): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied file_storage = request.files.get('file') if not file_storage or file_storage.filename == '': return jsonify({'success': False, 'error': '请选择 Excel 文件'}) @@ -730,6 +764,9 @@ def delete_import_dedupe_total_data(): @admin_api.route('/dedupe-total-data', methods=['POST']) @admin_required def create_dedupe_total_data(): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied data = request.get_json() or {} payload = {'dataValue': (data.get('data_value') or '').strip()} result, error_response, status = _proxy_backend_java( @@ -754,6 +791,9 @@ def create_dedupe_total_data(): @admin_api.route('/dedupe-total-data/', methods=['PUT']) @admin_required def update_dedupe_total_data(item_id): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied data = request.get_json() or {} payload = {'dataValue': (data.get('data_value') or '').strip()} result, error_response, status = _proxy_backend_java( @@ -778,6 +818,9 @@ def update_dedupe_total_data(item_id): @admin_api.route('/dedupe-total-data/', methods=['DELETE']) @admin_required def delete_dedupe_total_data(item_id): + _, _, denied = _ensure_dedupe_total_data_access() + if denied: + return denied result, error_response, status = _proxy_backend_java( 'DELETE', f'/api/admin/dedupe-total-data/{item_id}', diff --git a/backend/web_source/admin.html b/backend/web_source/admin.html index 55177a3..4a27176 100644 --- a/backend/web_source/admin.html +++ b/backend/web_source/admin.html @@ -444,6 +444,7 @@ // ========== 用户管理 ========== var userPage = 1, userPageSize = 15; var currentUserRole = 'admin'; + var currentUserUsername = ''; var adminsList = []; function roleLabel(role) { if (role === 'super_admin') return '超级管理员'; @@ -469,6 +470,7 @@ return; } currentUserRole = res.current_user_role || 'admin'; + currentUserUsername = (res.current_user_username || '').trim(); adminsList = res.admins || []; var items = res.items || []; if (items.length === 0) { @@ -514,7 +516,7 @@ function updateDedupeTotalDataAccess() { var tab = document.querySelector('.tab[data-tab="dedupe-total-data"]'); var panel = document.getElementById('panel-dedupe-total-data'); - var canUse = currentUserRole === 'admin' || currentUserRole === 'super_admin'; + var canUse = currentUserRole === 'super_admin' || (currentUserRole === 'admin' && currentUserUsername === '刘丽泓'); if (tab) tab.style.display = canUse ? '' : 'none'; if (panel) panel.style.display = canUse ? '' : 'none'; if (!canUse && tab && tab.classList.contains('active')) {