后台管理跳过asin、后台相关数据做数据隔离
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -32,7 +32,7 @@ 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)
|
||||
return None, None, (jsonify({'success': False, 'error': '无权访问数据去重汇总数据'}), 403)
|
||||
return role, current_row, None
|
||||
from ali_oss import upload_file as oss_upload_file
|
||||
|
||||
@@ -48,23 +48,23 @@ ADMIN_MENU_ACCESS_CONFIG = {
|
||||
'dedupe-total-data': {
|
||||
'column_key': 'admin_dedupe_total_data',
|
||||
'route_path': 'dedupe-total-data',
|
||||
'error': '鏃犳潈闄愯闂暟鎹幓閲嶆€绘暟鎹?',
|
||||
'error': '无权访问数据去重汇总数据',
|
||||
},
|
||||
'shop-manage': {
|
||||
'column_key': 'admin_shop_manage',
|
||||
'route_path': 'shop-manage',
|
||||
'error': '鏃犳潈闄愯闂簵閾虹鐞嗘ā鍧?',
|
||||
'error': '无权访问店铺管理模块',
|
||||
},
|
||||
'skip-price-asin': {
|
||||
'column_key': 'admin_skip_price_asin',
|
||||
'route_path': 'skip-price-asin',
|
||||
'error': '鏃犳潈闄愯闂烦杩囪窡浠稟SIN 妯″潡',
|
||||
'error': '无权访问跳过跟价 ASIN 模块',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _safe_version_key(version):
|
||||
"""将版本号转为安全的 OSS 对象名部分"""
|
||||
"""将版本号转换为安全的 OSS 对象名片段"""
|
||||
s = (version or '').strip()
|
||||
s = re.sub(r'[^\w.\-]', '_', s)
|
||||
return s or 'unknown'
|
||||
@@ -138,7 +138,7 @@ def _ensure_admin_menu_access(*menu_names):
|
||||
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)
|
||||
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 {}
|
||||
@@ -148,7 +148,7 @@ def _ensure_admin_menu_access(*menu_names):
|
||||
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 '鏃犳潈闄愯闂綋鍓嶆ā鍧?'
|
||||
error_message = fallback_config.get('error') or '无权访问当前模块'
|
||||
return role, current_row, (jsonify({'success': False, 'error': error_message}), 403)
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ def _ensure_admin_menu_access(*menu_names):
|
||||
@admin_api.route('/users')
|
||||
@admin_required
|
||||
def list_users():
|
||||
"""分页获取用户列表;支持用户名模糊搜索、指定管理员所属普通用户筛选"""
|
||||
"""分页获取用户列表,支持用户名模糊搜索和按管理员归属筛选普通用户"""
|
||||
role, current_row = get_current_admin_role()
|
||||
if not role:
|
||||
return jsonify({'success': False, 'error': '需要管理员权限'}), 403
|
||||
@@ -998,7 +998,7 @@ 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')
|
||||
role, current_row, denied = _ensure_admin_menu_access('shop-manage')
|
||||
if denied:
|
||||
return denied
|
||||
page = max(1, int(request.args.get('page', 1)))
|
||||
@@ -1007,6 +1007,8 @@ def list_shop_manages():
|
||||
shop_name = (request.args.get('shop_name') or '').strip()
|
||||
|
||||
params = {'page': page, 'pageSize': page_size}
|
||||
if role != 'super_admin' and current_row and current_row.get('id'):
|
||||
params['createdById'] = current_row.get('id')
|
||||
if group_id_raw:
|
||||
try:
|
||||
group_id = int(group_id_raw)
|
||||
@@ -1051,7 +1053,7 @@ def list_shop_manages():
|
||||
@admin_api.route('/shop-manage', methods=['POST'])
|
||||
@admin_required
|
||||
def create_shop_manage():
|
||||
_, _, denied = _ensure_admin_menu_access('shop-manage')
|
||||
role, current_row, denied = _ensure_admin_menu_access('shop-manage')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
@@ -1061,10 +1063,15 @@ def create_shop_manage():
|
||||
'mallName': (data.get('mall_name') or '').strip(),
|
||||
'account': (data.get('account') or '').strip(),
|
||||
'password': (data.get('password') or '').strip(),
|
||||
'createdById': current_row.get('id') if current_row else None,
|
||||
}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'POST',
|
||||
'/api/admin/shop-manages',
|
||||
params={
|
||||
'operatorId': current_row.get('id') if current_row else None,
|
||||
'superAdmin': 'true' if role == 'super_admin' else 'false',
|
||||
},
|
||||
json_data=payload,
|
||||
)
|
||||
if error_response is not None:
|
||||
@@ -1090,7 +1097,7 @@ 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')
|
||||
role, current_row, denied = _ensure_admin_menu_access('shop-manage')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
@@ -1104,6 +1111,10 @@ def update_shop_manage(item_id):
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'PUT',
|
||||
f'/api/admin/shop-manages/{item_id}',
|
||||
params={
|
||||
'operatorId': current_row.get('id') if current_row else None,
|
||||
'superAdmin': 'true' if role == 'super_admin' else 'false',
|
||||
},
|
||||
json_data=payload,
|
||||
)
|
||||
if error_response is not None:
|
||||
@@ -1128,12 +1139,16 @@ 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')
|
||||
role, current_row, 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}',
|
||||
params={
|
||||
'operatorId': current_row.get('id') if current_row else None,
|
||||
'superAdmin': 'true' if role == 'super_admin' else 'false',
|
||||
},
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
@@ -1146,12 +1161,13 @@ 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')
|
||||
role, current_row, 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',
|
||||
params={'createdById': current_row.get('id')} if role != 'super_admin' and current_row and current_row.get('id') else None,
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
@@ -1170,11 +1186,14 @@ 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')
|
||||
_, current_row, 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()}
|
||||
payload = {
|
||||
'groupName': (data.get('group_name') or '').strip(),
|
||||
'createdById': current_row.get('id') if current_row else None,
|
||||
}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'POST',
|
||||
'/api/admin/shop-manages/groups',
|
||||
@@ -1198,7 +1217,7 @@ 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')
|
||||
role, current_row, denied = _ensure_admin_menu_access('shop-manage', 'skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
@@ -1206,6 +1225,10 @@ def update_shop_manage_group(item_id):
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'PUT',
|
||||
f'/api/admin/shop-manages/groups/{item_id}',
|
||||
params={
|
||||
'operatorId': current_row.get('id') if current_row else None,
|
||||
'superAdmin': 'true' if role == 'super_admin' else 'false',
|
||||
},
|
||||
json_data=payload,
|
||||
)
|
||||
if error_response is not None:
|
||||
@@ -1302,7 +1325,7 @@ def create_skip_price_asin():
|
||||
item = result.get('data') or {}
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'msg': result.get('message') or '淇濆瓨鎴愬姛',
|
||||
'msg': result.get('message') or '保存成功',
|
||||
'item': {
|
||||
'id': item.get('id'),
|
||||
'group_id': item.get('groupId'),
|
||||
@@ -1331,19 +1354,58 @@ def delete_skip_price_asin_country(item_id, country):
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
return jsonify({'success': True, 'msg': result.get('message') or '鍒犻櫎鎴愬姛'})
|
||||
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')
|
||||
role, current_row, 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}',
|
||||
params={
|
||||
'operatorId': current_row.get('id') if current_row else None,
|
||||
'superAdmin': 'true' if role == 'super_admin' else 'false',
|
||||
},
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
return jsonify({'success': True, 'msg': result.get('message') or '删除成功'})
|
||||
|
||||
|
||||
@admin_api.route('/skip-price-asin/<int:item_id>/country/<country>', methods=['PUT'])
|
||||
@admin_required
|
||||
def update_skip_price_asin_country(item_id, country):
|
||||
_, _, denied = _ensure_admin_menu_access('skip-price-asin')
|
||||
if denied:
|
||||
return denied
|
||||
data = request.get_json() or {}
|
||||
payload = {'asin': (data.get('asin') or '').strip()}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'PUT',
|
||||
f'/api/admin/skip-price-asins/{item_id}/countries/{country}',
|
||||
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],
|
||||
},
|
||||
})
|
||||
|
||||
@@ -23,8 +23,8 @@ bucket_path = "nanri-image/"
|
||||
file_url_pre = f"https://{bucket}.oss-cn-hangzhou.aliyuncs.com/"
|
||||
|
||||
import os
|
||||
# backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://127.0.0.1:18080').rstrip('/')
|
||||
backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://8.136.19.173:18080').rstrip('/')
|
||||
backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://127.0.0.1:18080').rstrip('/')
|
||||
# backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://8.136.19.173:18080').rstrip('/')
|
||||
os.environ['OSS_ACCESS_KEY_ID'] = accessKeyId
|
||||
os.environ['OSS_ACCESS_KEY_SECRET'] = accessKeySecret
|
||||
os.environ['SECRET_KEY'] = "ddffc7c1d02121d9554d7b080b2511b6"
|
||||
|
||||
@@ -1995,10 +1995,35 @@
|
||||
if (!value) return '<span style="color:#999;">-</span>';
|
||||
return '<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">' +
|
||||
'<span>' + value + '</span>' +
|
||||
'<button class="btn btn-sm" data-skip-price-asin-edit="' + item.id + '" data-country="' + country.code + '" data-asin="' + value.replace(/"/g, '"') + '" data-shop-name="' + (item.shop_name || '').replace(/"/g, '"') + '">编辑</button>' +
|
||||
'<button class="btn btn-sm btn-danger" data-skip-price-asin-delete="' + item.id + '" data-country="' + country.code + '" data-shop-name="' + (item.shop_name || '').replace(/"/g, '"') + '">删除</button>' +
|
||||
'</div>';
|
||||
}
|
||||
function bindSkipPriceAsinActions() {
|
||||
document.querySelectorAll('[data-skip-price-asin-edit]').forEach(function(btn) {
|
||||
btn.onclick = function() {
|
||||
var shopName = (btn.dataset.shopName || '').replace(/"/g, '"');
|
||||
var countryCode = btn.dataset.country || '';
|
||||
var currentAsin = (btn.dataset.asin || '').replace(/"/g, '"');
|
||||
var nextAsin = prompt('请输入店铺“' + shopName + '”在 ' + countryCode + ' 的 ASIN', currentAsin);
|
||||
if (nextAsin === null) return;
|
||||
nextAsin = (nextAsin || '').trim();
|
||||
if (!nextAsin) {
|
||||
alert('ASIN 不能为空');
|
||||
return;
|
||||
}
|
||||
fetch('/api/admin/skip-price-asin/' + btn.dataset.skipPriceAsinEdit + '/country/' + countryCode, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ asin: nextAsin })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(res) {
|
||||
if (res.success) loadSkipPriceAsin(skipPriceAsinPage);
|
||||
else alert(res.error || '保存失败');
|
||||
});
|
||||
};
|
||||
});
|
||||
document.querySelectorAll('[data-skip-price-asin-delete]').forEach(function(btn) {
|
||||
btn.onclick = function() {
|
||||
var shopName = (btn.dataset.shopName || '').replace(/"/g, '"');
|
||||
|
||||
Reference in New Issue
Block a user