提交工作更新
This commit is contained in:
Binary file not shown.
@@ -19,6 +19,8 @@ ALLOWED_DEDUPE_TOTAL_DATA_ADMIN_USERNAMES = {'刘丽泓'}
|
||||
|
||||
|
||||
def _can_access_dedupe_total_data(role, current_row):
|
||||
_, _, denied = _ensure_admin_menu_access('dedupe-total-data')
|
||||
return denied is None
|
||||
if role == 'super_admin':
|
||||
return True
|
||||
if role != 'admin' or not current_row:
|
||||
@@ -27,6 +29,7 @@ def _can_access_dedupe_total_data(role, current_row):
|
||||
|
||||
|
||||
def _ensure_dedupe_total_data_access():
|
||||
return _ensure_admin_menu_access('dedupe-total-data')
|
||||
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)
|
||||
@@ -41,6 +44,24 @@ except ImportError:
|
||||
|
||||
admin_api = Blueprint('admin_api', __name__, url_prefix='/api/admin')
|
||||
|
||||
ADMIN_MENU_ACCESS_CONFIG = {
|
||||
'dedupe-total-data': {
|
||||
'column_key': 'admin_dedupe_total_data',
|
||||
'route_path': 'dedupe-total-data',
|
||||
'error': '鏃犳潈闄愯闂暟鎹幓閲嶆€绘暟鎹?',
|
||||
},
|
||||
'shop-manage': {
|
||||
'column_key': 'admin_shop_manage',
|
||||
'route_path': 'shop-manage',
|
||||
'error': '鏃犳潈闄愯闂簵閾虹鐞嗘ā鍧?',
|
||||
},
|
||||
'skip-price-asin': {
|
||||
'column_key': 'admin_skip_price_asin',
|
||||
'route_path': 'skip-price-asin',
|
||||
'error': '鏃犳潈闄愯闂烦杩囪窡浠稟SIN 妯″潡',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _safe_version_key(version):
|
||||
"""将版本号转为安全的 OSS 对象名部分"""
|
||||
@@ -90,6 +111,47 @@ def _sync_user_column_permissions(user_id, column_ids):
|
||||
return error_response, status
|
||||
|
||||
|
||||
def _get_current_admin_permission_sets():
|
||||
user_id = session.get('user_id')
|
||||
if not user_id:
|
||||
return set(), set()
|
||||
conn = get_db()
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""SELECT c.column_key, c.route_path
|
||||
FROM user_column_permission ucp
|
||||
INNER JOIN columns c ON c.id = ucp.column_id
|
||||
WHERE ucp.user_id = %s AND c.menu_type = 'admin'""",
|
||||
(user_id,),
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
finally:
|
||||
conn.close()
|
||||
key_set = {(row.get('column_key') or '').strip() for row in rows if (row.get('column_key') or '').strip()}
|
||||
route_set = {(row.get('route_path') or '').strip() for row in rows if (row.get('route_path') or '').strip()}
|
||||
return key_set, route_set
|
||||
|
||||
|
||||
def _ensure_admin_menu_access(*menu_names):
|
||||
role, current_row = get_current_admin_role()
|
||||
if role == 'super_admin':
|
||||
return role, current_row, None
|
||||
if role != 'admin' or not current_row:
|
||||
return role, current_row, (jsonify({'success': False, 'error': '闇€瑕佺鐞嗗憳鏉冮檺'}), 403)
|
||||
key_set, route_set = _get_current_admin_permission_sets()
|
||||
for menu_name in menu_names:
|
||||
config = ADMIN_MENU_ACCESS_CONFIG.get(menu_name) or {}
|
||||
column_key = (config.get('column_key') or '').strip()
|
||||
route_path = (config.get('route_path') or '').strip()
|
||||
if (column_key and column_key in key_set) or (route_path and route_path in route_set):
|
||||
return role, current_row, None
|
||||
fallback_menu = menu_names[0] if menu_names else ''
|
||||
fallback_config = ADMIN_MENU_ACCESS_CONFIG.get(fallback_menu) or {}
|
||||
error_message = fallback_config.get('error') or '鏃犳潈闄愯闂綋鍓嶆ā鍧?'
|
||||
return role, current_row, (jsonify({'success': False, 'error': error_message}), 403)
|
||||
|
||||
|
||||
# ---------- 用户管理 ----------
|
||||
|
||||
@admin_api.route('/users')
|
||||
@@ -936,6 +998,9 @@ def delete_dedupe_total_data(item_id):
|
||||
@admin_api.route('/shop-manages')
|
||||
@admin_required
|
||||
def list_shop_manages():
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage')
|
||||
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))))
|
||||
group_id_raw = (request.args.get('group_id') or '').strip()
|
||||
@@ -986,6 +1051,9 @@ def list_shop_manages():
|
||||
@admin_api.route('/shop-manage', methods=['POST'])
|
||||
@admin_required
|
||||
def create_shop_manage():
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
payload = {
|
||||
'groupId': data.get('group_id'),
|
||||
@@ -1022,6 +1090,9 @@ def create_shop_manage():
|
||||
@admin_api.route('/shop-manage/<int:item_id>', methods=['PUT'])
|
||||
@admin_required
|
||||
def update_shop_manage(item_id):
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
payload = {
|
||||
'groupId': data.get('group_id'),
|
||||
@@ -1057,6 +1128,9 @@ def update_shop_manage(item_id):
|
||||
@admin_api.route('/shop-manage/<int:item_id>', methods=['DELETE'])
|
||||
@admin_required
|
||||
def delete_shop_manage(item_id):
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage')
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'DELETE',
|
||||
f'/api/admin/shop-manages/{item_id}',
|
||||
@@ -1072,6 +1146,9 @@ def delete_shop_manage(item_id):
|
||||
@admin_api.route('/shop-manage-groups')
|
||||
@admin_required
|
||||
def list_shop_manage_groups():
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage', 'skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'GET',
|
||||
'/api/admin/shop-manages/groups',
|
||||
@@ -1093,6 +1170,9 @@ def list_shop_manage_groups():
|
||||
@admin_api.route('/shop-manage-group', methods=['POST'])
|
||||
@admin_required
|
||||
def create_shop_manage_group():
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage', 'skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
payload = {'groupName': (data.get('group_name') or '').strip()}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
@@ -1118,6 +1198,9 @@ def create_shop_manage_group():
|
||||
@admin_api.route('/shop-manage-group/<int:item_id>', methods=['PUT'])
|
||||
@admin_required
|
||||
def update_shop_manage_group(item_id):
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage', 'skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
payload = {'groupName': (data.get('group_name') or '').strip()}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
@@ -1140,9 +1223,123 @@ def update_shop_manage_group(item_id):
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/skip-price-asins')
|
||||
@admin_required
|
||||
def list_skip_price_asins():
|
||||
_, _, denied = _ensure_admin_menu_access('skip-price-asin')
|
||||
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))))
|
||||
group_id_raw = (request.args.get('group_id') or '').strip()
|
||||
shop_name = (request.args.get('shop_name') or '').strip()
|
||||
asin = (request.args.get('asin') or '').strip()
|
||||
params = {'page': page, 'pageSize': page_size}
|
||||
if group_id_raw:
|
||||
try:
|
||||
group_id = int(group_id_raw)
|
||||
if group_id > 0:
|
||||
params['groupId'] = group_id
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
if shop_name:
|
||||
params['shopName'] = shop_name
|
||||
if asin:
|
||||
params['asin'] = asin
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'GET',
|
||||
'/api/admin/skip-price-asins',
|
||||
params=params,
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
payload = result.get('data') or {}
|
||||
items = [
|
||||
{
|
||||
'id': item.get('id'),
|
||||
'group_id': item.get('groupId'),
|
||||
'group_name': item.get('groupName') or '',
|
||||
'shop_name': item.get('shopName') or '',
|
||||
'asin_de': item.get('asinDe') or '',
|
||||
'asin_uk': item.get('asinUk') or '',
|
||||
'asin_fr': item.get('asinFr') or '',
|
||||
'asin_it': item.get('asinIt') or '',
|
||||
'asin_es': item.get('asinEs') or '',
|
||||
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
|
||||
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
|
||||
}
|
||||
for item in (payload.get('items') or [])
|
||||
]
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'items': items,
|
||||
'total': payload.get('total') or 0,
|
||||
'page': payload.get('page') or page,
|
||||
'page_size': payload.get('pageSize') or page_size,
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/skip-price-asin', methods=['POST'])
|
||||
@admin_required
|
||||
def create_skip_price_asin():
|
||||
_, _, denied = _ensure_admin_menu_access('skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
payload = {
|
||||
'groupId': data.get('group_id'),
|
||||
'shopName': (data.get('shop_name') or '').strip(),
|
||||
'countries': data.get('countries') or [],
|
||||
'asin': (data.get('asin') or '').strip(),
|
||||
}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'POST',
|
||||
'/api/admin/skip-price-asins',
|
||||
json_data=payload,
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
item = result.get('data') or {}
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'msg': result.get('message') or '淇濆瓨鎴愬姛',
|
||||
'item': {
|
||||
'id': item.get('id'),
|
||||
'group_id': item.get('groupId'),
|
||||
'group_name': item.get('groupName') or '',
|
||||
'shop_name': item.get('shopName') or '',
|
||||
'asin_de': item.get('asinDe') or '',
|
||||
'asin_uk': item.get('asinUk') or '',
|
||||
'asin_fr': item.get('asinFr') or '',
|
||||
'asin_it': item.get('asinIt') or '',
|
||||
'asin_es': item.get('asinEs') or '',
|
||||
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
|
||||
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/skip-price-asin/<int:item_id>/country/<country>', methods=['DELETE'])
|
||||
@admin_required
|
||||
def delete_skip_price_asin_country(item_id, country):
|
||||
_, _, denied = _ensure_admin_menu_access('skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'DELETE',
|
||||
f'/api/admin/skip-price-asins/{item_id}/countries/{country}',
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
return jsonify({'success': True, 'msg': result.get('message') or '鍒犻櫎鎴愬姛'})
|
||||
|
||||
|
||||
@admin_api.route('/shop-manage-group/<int:item_id>', methods=['DELETE'])
|
||||
@admin_required
|
||||
def delete_shop_manage_group(item_id):
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage', 'skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'DELETE',
|
||||
f'/api/admin/shop-manages/groups/{item_id}',
|
||||
|
||||
Reference in New Issue
Block a user