完成匹配、跟价、权限部分

This commit is contained in:
super
2026-04-17 12:52:16 +08:00
parent ecc8b6ce6c
commit d5764f3b50
63 changed files with 8858 additions and 1473 deletions

View File

@@ -62,6 +62,34 @@ ADMIN_MENU_ACCESS_CONFIG = {
},
}
ADMIN_MENU_ACCESS_CONFIG.update({
'users': {
'column_key': 'admin_users',
'route_path': 'users',
'error': '无权访问用户管理模块',
},
'columns': {
'column_key': 'admin_columns',
'route_path': 'columns',
'error': '无权访问栏目权限配置模块',
},
'shop-keys': {
'column_key': 'admin_shop_keys',
'route_path': 'shop-keys',
'error': '无权访问店铺密钥管理模块',
},
'history': {
'column_key': 'admin_history',
'route_path': 'history',
'error': '无权访问查看生成记录模块',
},
'version': {
'column_key': 'admin_version',
'route_path': 'version',
'error': '无权访问版本管理模块',
},
})
def _safe_version_key(version):
"""将版本号转换为安全的 OSS 对象名片段"""
@@ -98,10 +126,155 @@ def _format_permission_item(item):
'column_key': item.get('columnKey') or '',
'menu_type': item.get('menuType') or 'app',
'route_path': item.get('routePath') or '',
'sort_order': item.get('sortOrder') if item.get('sortOrder') is not None else 0,
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
}
def _parse_optional_int(value):
if value is None:
return None
text = str(value).strip()
if text == '':
return None
return int(text)
def _ensure_column_sort_schema():
conn = get_db()
try:
with conn.cursor() as cur:
try:
cur.execute("ALTER TABLE columns ADD COLUMN sort_order INT NOT NULL DEFAULT 0 COMMENT '菜单排序' AFTER route_path")
except Exception:
pass
try:
cur.execute("UPDATE columns SET sort_order = id WHERE sort_order IS NULL OR sort_order = 0")
except Exception:
pass
conn.commit()
finally:
conn.close()
def _load_local_column_sort_map():
_ensure_column_sort_schema()
conn = get_db()
try:
with conn.cursor() as cur:
cur.execute("SELECT id, sort_order FROM columns")
rows = cur.fetchall()
return {int(row['id']): int(row.get('sort_order') or 0) for row in rows if row.get('id') is not None}
finally:
conn.close()
def _load_local_columns(menu_type=None):
_ensure_column_sort_schema()
conn = get_db()
try:
with conn.cursor() as cur:
sql = """
SELECT id, name, column_key, menu_type, route_path, sort_order, created_at
FROM columns
"""
params = []
if menu_type:
sql += " WHERE menu_type = %s"
params.append(menu_type)
sql += " ORDER BY sort_order ASC, id ASC"
cur.execute(sql, params)
return cur.fetchall()
finally:
conn.close()
def _sync_local_columns_from_backend(items):
if not items:
return
_ensure_column_sort_schema()
conn = get_db()
try:
with conn.cursor() as cur:
for item in items:
item_id = item.get('id')
if item_id is None:
continue
sort_order = item.get('sort_order')
cur.execute(
"""
INSERT INTO columns (id, name, column_key, menu_type, route_path, sort_order, created_at)
VALUES (%s, %s, %s, %s, %s, %s, COALESCE(%s, NOW()))
ON DUPLICATE KEY UPDATE
name = VALUES(name),
column_key = VALUES(column_key),
menu_type = VALUES(menu_type),
route_path = VALUES(route_path),
sort_order = CASE
WHEN columns.sort_order IS NULL OR columns.sort_order = 0 THEN VALUES(sort_order)
ELSE columns.sort_order
END
""",
(
int(item_id),
item.get('name') or '',
item.get('column_key') or '',
item.get('menu_type') or 'app',
item.get('route_path') or '',
int(sort_order if sort_order not in (None, '') else item_id),
item.get('created_at') or None,
),
)
conn.commit()
finally:
conn.close()
def _set_local_column_sort_order(column_id, sort_order):
_ensure_column_sort_schema()
conn = get_db()
try:
with conn.cursor() as cur:
cur.execute(
"UPDATE columns SET sort_order = %s WHERE id = %s",
(int(sort_order), int(column_id)),
)
conn.commit()
finally:
conn.close()
def _get_next_local_column_sort_order():
_ensure_column_sort_schema()
conn = get_db()
try:
with conn.cursor() as cur:
cur.execute("SELECT COALESCE(MAX(sort_order), 0) AS max_sort FROM columns")
row = cur.fetchone() or {}
return int(row.get('max_sort') or 0) + 1
finally:
conn.close()
def _swap_local_column_sort_order(column_id, target_id):
_ensure_column_sort_schema()
conn = get_db()
try:
with conn.cursor() as cur:
cur.execute("SELECT id, sort_order FROM columns WHERE id IN (%s, %s) ORDER BY id", (int(column_id), int(target_id)))
rows = cur.fetchall()
if len(rows) != 2:
raise ValueError('菜单不存在')
by_id = {int(row['id']): int(row.get('sort_order') or 0) for row in rows}
left_sort = by_id.get(int(column_id), 0) or int(column_id)
right_sort = by_id.get(int(target_id), 0) or int(target_id)
cur.execute("UPDATE columns SET sort_order = %s WHERE id = %s", (right_sort, int(column_id)))
cur.execute("UPDATE columns SET sort_order = %s WHERE id = %s", (left_sort, int(target_id)))
conn.commit()
finally:
conn.close()
def _sync_user_column_permissions(user_id, column_ids):
_, error_response, status = _proxy_backend_java(
'PUT',
@@ -111,8 +284,14 @@ def _sync_user_column_permissions(user_id, column_ids):
return error_response, status
def _get_current_admin_id(current_row=None):
if current_row and current_row.get('id'):
return current_row.get('id')
return session.get('user_id')
def _get_current_admin_permission_sets():
user_id = session.get('user_id')
user_id = _get_current_admin_id()
if not user_id:
return set(), set()
conn = get_db()
@@ -152,6 +331,60 @@ def _ensure_admin_menu_access(*menu_names):
return role, current_row, (jsonify({'success': False, 'error': error_message}), 403)
def _ensure_dedupe_total_data_access():
return _ensure_admin_menu_access('dedupe-total-data')
def _load_current_admin_menu_items():
role, current_row = get_current_admin_role()
if not role or not current_row:
return None, None, None, (jsonify({'success': False, 'error': '需要管理员权限'}), 403)
user_id = _get_current_admin_id(current_row)
if not user_id:
return role, current_row, None, (jsonify({'success': False, 'error': '当前登录用户缺少有效ID'}), 400)
result, error_response, status = _proxy_backend_java(
'GET',
f'/api/admin/permission-users/{user_id}/column-permissions',
params={'menuType': 'admin'},
)
if error_response is not None:
return role, current_row, None, (error_response, status)
items = [_format_permission_item(item) for item in (result.get('data') or [])]
return role, current_row, items, None
@admin_api.route('/current-user')
@admin_required
def get_admin_current_user():
role, current_row = get_current_admin_role()
if not role or not current_row:
return jsonify({'success': False, 'error': '需要管理员权限'}), 403
return jsonify({
'success': True,
'item': {
'id': current_row.get('id'),
'username': current_row.get('username') or session.get('username') or '',
'role': role,
}
})
@admin_api.route('/current-user/menus')
@admin_required
def get_admin_current_user_menus():
_, _, items, denied = _load_current_admin_menu_items()
if denied:
return denied
return jsonify({'success': True, 'items': items})
@admin_api.route('/logout', methods=['POST'])
@admin_required
def admin_logout():
session.clear()
return jsonify({'success': True, 'msg': '退出成功', 'redirect': '/login'})
# ---------- 用户管理 ----------
@admin_api.route('/users')
@@ -162,7 +395,13 @@ def list_users():
if not role:
return jsonify({'success': False, 'error': '需要管理员权限'}), 403
page = max(1, int(request.args.get('page', 1)))
page_size = min(50, max(5, int(request.args.get('page_size', 15))))
_, _, denied = _ensure_admin_menu_access('users', 'history', 'shop-manage', 'skip-price-asin')
if denied:
return denied
_, _, denied = _ensure_admin_menu_access('users', 'history', 'shop-manage', 'skip-price-asin')
if denied:
return denied
page_size = min(999, max(5, int(request.args.get('page_size', 15))))
offset = (page - 1) * page_size
search_username = (request.args.get('username') or request.args.get('search') or '').strip()
created_by_id_arg = request.args.get('created_by_id') or request.args.get('admin_id')
@@ -249,6 +488,9 @@ def list_users():
@admin_api.route('/user', methods=['POST'])
@admin_required
def create_user():
_, _, denied = _ensure_admin_menu_access('users')
if denied:
return denied
data = request.get_json() or {}
username = (data.get('username') or '').strip()
password = data.get('password') or ''
@@ -312,6 +554,9 @@ def create_user():
def update_user(uid):
"""更新用户(密码、角色)"""
data = request.get_json() or {}
_, _, denied = _ensure_admin_menu_access('users')
if denied:
return denied
password = data.get('password')
want_role = (data.get('role') or '').strip() or data.get('role')
role, current_row = get_current_admin_role()
@@ -368,6 +613,9 @@ def update_user(uid):
@admin_required
def delete_user(uid):
"""删除用户"""
_, _, denied = _ensure_admin_menu_access('users')
if denied:
return denied
if session.get('user_id') == uid:
return jsonify({'success': False, 'error': '不能删除当前登录账号'})
role, current_row = get_current_admin_role()
@@ -405,6 +653,9 @@ def delete_user(uid):
@admin_required
def history():
"""管理员分页获取所有生成记录"""
_, _, denied = _ensure_admin_menu_access('history')
if denied:
return denied
page = max(1, int(request.args.get('page', 1)))
page_size = min(50, max(10, int(request.args.get('page_size', 15))))
offset = (page - 1) * page_size
@@ -473,28 +724,49 @@ def history():
@admin_api.route('/columns')
@admin_required
def list_columns():
params = {}
_, _, denied = _ensure_admin_menu_access('columns', 'users')
if denied:
return denied
menu_type = (request.args.get('menu_type') or '').strip()
if menu_type:
params['menuType'] = menu_type
params = {'menuType': menu_type} if menu_type else None
result, error_response, status = _proxy_backend_java(
'GET',
'/api/admin/permission-menus',
params=params or None,
params=params,
)
if error_response is not None:
return error_response, status
return jsonify({'success': True, 'items': [_format_permission_item(item) for item in (result.get('data') or [])]})
if error_response is None:
_sync_local_columns_from_backend([_format_permission_item(item) for item in (result.get('data') or [])])
local_rows = _load_local_columns(menu_type or None)
items = [
{
'id': row.get('id'),
'name': row.get('name') or '',
'column_key': row.get('column_key') or '',
'menu_type': row.get('menu_type') or 'app',
'route_path': row.get('route_path') or '',
'sort_order': int(row.get('sort_order') or 0),
'created_at': str(row.get('created_at') or '')[:16].replace('T', ' '),
}
for row in local_rows
]
return jsonify({'success': True, 'items': items})
@admin_api.route('/column', methods=['POST'])
@admin_required
def create_column():
_, _, denied = _ensure_admin_menu_access('columns')
if denied:
return denied
data = request.get_json() or {}
name = (data.get('name') or '').strip()
column_key = (data.get('column_key') or '').strip()
menu_type = (data.get('menu_type') or 'app').strip() or 'app'
menu_type = (data.get('menu_type') or '').strip() or 'admin'
route_path = (data.get('route_path') or '').strip()
try:
sort_order = _parse_optional_int(data.get('sort_order'))
except (TypeError, ValueError):
return jsonify({'success': False, 'error': '排序必须是数字'})
if not name:
return jsonify({'success': False, 'error': '栏目名不能为空'})
if not column_key:
@@ -514,17 +786,27 @@ def create_column():
if error_response is not None:
return error_response, status
item = result.get('data') or {}
_sync_local_columns_from_backend([_format_permission_item(item)])
if item.get('id') is not None:
_set_local_column_sort_order(item.get('id'), sort_order if sort_order is not None else _get_next_local_column_sort_order())
return jsonify({'success': True, 'msg': result.get('message') or '创建成功', 'id': item.get('id')})
@admin_api.route('/column/<int:cid>', methods=['PUT'])
@admin_required
def update_column(cid):
_, _, denied = _ensure_admin_menu_access('columns')
if denied:
return denied
data = request.get_json() or {}
name = (data.get('name') or '').strip()
column_key = (data.get('column_key') or '').strip()
menu_type = (data.get('menu_type') or 'app').strip() or 'app'
menu_type = (data.get('menu_type') or '').strip() or 'admin'
route_path = (data.get('route_path') or '').strip()
try:
sort_order = _parse_optional_int(data.get('sort_order'))
except (TypeError, ValueError):
return jsonify({'success': False, 'error': '排序必须是数字'})
if not name:
return jsonify({'success': False, 'error': '栏目名不能为空'})
if not column_key:
@@ -543,32 +825,76 @@ def update_column(cid):
)
if error_response is not None:
return error_response, status
_sync_local_columns_from_backend([{
'id': cid,
'name': name,
'column_key': column_key,
'menu_type': menu_type,
'route_path': route_path,
'sort_order': sort_order if sort_order is not None else cid,
'created_at': None,
}])
if sort_order is not None:
_set_local_column_sort_order(cid, sort_order)
return jsonify({'success': True, 'msg': result.get('message') or '更新成功'})
@admin_api.route('/column/reorder', methods=['POST'])
@admin_required
def reorder_column():
_, _, denied = _ensure_admin_menu_access('columns')
if denied:
return denied
data = request.get_json() or {}
try:
column_id = int(data.get('column_id'))
target_id = int(data.get('target_id'))
except (TypeError, ValueError):
return jsonify({'success': False, 'error': '菜单重排参数无效'}), 400
if column_id == target_id:
return jsonify({'success': True, 'msg': '排序未变化'})
try:
_swap_local_column_sort_order(column_id, target_id)
except ValueError as exc:
return jsonify({'success': False, 'error': str(exc)}), 400
except Exception as exc:
return jsonify({'success': False, 'error': str(exc)}), 500
return jsonify({'success': True, 'msg': '排序更新成功'})
@admin_api.route('/column/<int:cid>', methods=['DELETE'])
@admin_required
def delete_column(cid):
_, _, denied = _ensure_admin_menu_access('columns')
if denied:
return denied
result, error_response, status = _proxy_backend_java(
'DELETE',
f'/api/admin/permission-menus/{cid}',
)
if error_response is not None:
return error_response, status
conn = get_db()
try:
with conn.cursor() as cur:
cur.execute("DELETE FROM columns WHERE id = %s", (cid,))
conn.commit()
finally:
conn.close()
return jsonify({'success': True, 'msg': result.get('message') or '删除成功'})
@admin_api.route('/user/<int:uid>/columns')
@admin_required
def get_user_columns(uid):
params = {}
_, _, denied = _ensure_admin_menu_access('users')
if denied:
return denied
menu_type = (request.args.get('menu_type') or '').strip()
if menu_type:
params['menuType'] = menu_type
result, error_response, status = _proxy_backend_java(
'GET',
f'/api/admin/permission-users/{uid}/columns',
params=params or None,
params={'menuType': menu_type} if menu_type else None,
)
if error_response is not None:
return error_response, status
@@ -579,14 +905,14 @@ def get_user_columns(uid):
@admin_api.route('/user/<int:uid>/column-permissions')
@admin_required
def get_user_column_permissions(uid):
params = {}
_, _, denied = _ensure_admin_menu_access('users')
if denied:
return denied
menu_type = (request.args.get('menu_type') or '').strip()
if menu_type:
params['menuType'] = menu_type
result, error_response, status = _proxy_backend_java(
'GET',
f'/api/admin/permission-users/{uid}/column-permissions',
params=params or None,
params={'menuType': menu_type} if menu_type else None,
)
if error_response is not None:
return error_response, status
@@ -610,6 +936,9 @@ def _set_user_column_permissions(cur, user_id, column_ids):
@admin_api.route('/versions')
@admin_required
def list_versions():
_, _, denied = _ensure_admin_menu_access('version')
if denied:
return denied
"""获取版本列表"""
try:
conn = get_db()
@@ -637,6 +966,9 @@ def list_versions():
@admin_required
def upload_version():
"""接收版本号 + zip 文件,上传到 OSS写入 web_config"""
_, _, denied = _ensure_admin_menu_access('version')
if denied:
return denied
version = (request.form.get('version') or '').strip()
if not version:
return jsonify({'success': False, 'error': '请填写版本号'})
@@ -675,6 +1007,9 @@ def upload_version():
@admin_api.route('/shop-keys')
@admin_required
def list_shop_keys():
_, _, denied = _ensure_admin_menu_access('shop-keys')
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))))
result, error_response, status = _proxy_backend_java(
@@ -707,6 +1042,9 @@ def list_shop_keys():
@admin_api.route('/shop-key', methods=['POST'])
@admin_required
def create_shop_key():
_, _, denied = _ensure_admin_menu_access('shop-keys')
if denied:
return denied
data = request.get_json() or {}
payload = {
'ziniaoAccountName': (data.get('ziniao_account_name') or '').strip(),
@@ -736,6 +1074,9 @@ def create_shop_key():
@admin_api.route('/shop-key/<int:item_id>', methods=['PUT'])
@admin_required
def update_shop_key(item_id):
_, _, denied = _ensure_admin_menu_access('shop-keys')
if denied:
return denied
data = request.get_json() or {}
payload = {
'ziniaoAccountName': (data.get('ziniao_account_name') or '').strip(),
@@ -765,6 +1106,9 @@ def update_shop_key(item_id):
@admin_api.route('/shop-key/<int:item_id>', methods=['DELETE'])
@admin_required
def delete_shop_key(item_id):
_, _, denied = _ensure_admin_menu_access('shop-keys')
if denied:
return denied
result, error_response, status = _proxy_backend_java(
'DELETE',
f'/api/admin/shop-keys/{item_id}',
@@ -1007,8 +1351,9 @@ 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 current_row and current_row.get('id'):
params['operatorId'] = current_row.get('id')
params['superAdmin'] = 'true' if role == 'super_admin' else 'false'
if group_id_raw:
try:
group_id = int(group_id_raw)
@@ -1164,10 +1509,16 @@ def list_shop_manage_groups():
role, current_row, denied = _ensure_admin_menu_access('shop-manage', 'skip-price-asin')
if denied:
return denied
params = {}
if current_row and current_row.get('id'):
params['operatorId'] = current_row.get('id')
params['superAdmin'] = 'true' if role == 'super_admin' else 'false'
if role != 'super_admin' and current_row and current_row.get('id'):
params['createdById'] = current_row.get('id')
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,
params=params,
)
if error_response is not None:
return error_response, status
@@ -1175,6 +1526,8 @@ def list_shop_manage_groups():
{
'id': item.get('id'),
'group_name': item.get('groupName') or '',
'user_id': item.get('userId'),
'username': item.get('username') or '',
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
}
@@ -1186,17 +1539,22 @@ def list_shop_manage_groups():
@admin_api.route('/shop-manage-group', methods=['POST'])
@admin_required
def create_shop_manage_group():
_, current_row, 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 {}
payload = {
'groupName': (data.get('group_name') or '').strip(),
'userId': data.get('user_id'),
'createdById': current_row.get('id') if current_row else None,
}
result, error_response, status = _proxy_backend_java(
'POST',
'/api/admin/shop-manages/groups',
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:
@@ -1208,6 +1566,8 @@ def create_shop_manage_group():
'item': {
'id': item.get('id'),
'group_name': item.get('groupName') or '',
'user_id': item.get('userId'),
'username': item.get('username') or '',
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
},
@@ -1221,7 +1581,10 @@ def update_shop_manage_group(item_id):
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(),
'userId': data.get('user_id'),
}
result, error_response, status = _proxy_backend_java(
'PUT',
f'/api/admin/shop-manages/groups/{item_id}',
@@ -1240,6 +1603,8 @@ def update_shop_manage_group(item_id):
'item': {
'id': item.get('id'),
'group_name': item.get('groupName') or '',
'user_id': item.get('userId'),
'username': item.get('username') or '',
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
},
@@ -1249,7 +1614,7 @@ 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')
role, current_row, denied = _ensure_admin_menu_access('skip-price-asin')
if denied:
return denied
page = max(1, int(request.args.get('page', 1)))
@@ -1258,6 +1623,9 @@ def list_skip_price_asins():
shop_name = (request.args.get('shop_name') or '').strip()
asin = (request.args.get('asin') or '').strip()
params = {'page': page, 'pageSize': page_size}
if current_row and current_row.get('id'):
params['operatorId'] = current_row.get('id')
params['superAdmin'] = 'true' if role == 'super_admin' else 'false'
if group_id_raw:
try:
group_id = int(group_id_raw)
@@ -1305,19 +1673,31 @@ def list_skip_price_asins():
@admin_api.route('/skip-price-asin', methods=['POST'])
@admin_required
def create_skip_price_asin():
_, _, denied = _ensure_admin_menu_access('skip-price-asin')
role, current_row, denied = _ensure_admin_menu_access('skip-price-asin')
if denied:
return denied
data = request.get_json() or {}
asin_mappings = data.get('asin_mappings') or {}
fallback_asin = (data.get('asin') or '').strip()
if not fallback_asin and isinstance(asin_mappings, dict):
for value in asin_mappings.values():
fallback_asin = (value or '').strip()
if fallback_asin:
break
payload = {
'groupId': data.get('group_id'),
'shopName': (data.get('shop_name') or '').strip(),
'countries': data.get('countries') or [],
'asin': (data.get('asin') or '').strip(),
'asin': fallback_asin,
'asinMappings': asin_mappings,
}
result, error_response, status = _proxy_backend_java(
'POST',
'/api/admin/skip-price-asins',
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:
@@ -1345,12 +1725,16 @@ def create_skip_price_asin():
@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')
role, current_row, 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}',
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
@@ -1379,7 +1763,7 @@ def delete_shop_manage_group(item_id):
@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')
role, current_row, denied = _ensure_admin_menu_access('skip-price-asin')
if denied:
return denied
data = request.get_json() or {}
@@ -1387,6 +1771,10 @@ def update_skip_price_asin_country(item_id, country):
result, error_response, status = _proxy_backend_java(
'PUT',
f'/api/admin/skip-price-asins/{item_id}/countries/{country}',
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:

View File

@@ -122,10 +122,18 @@ def init_db():
cur.execute("ALTER TABLE columns ADD COLUMN route_path VARCHAR(255) NOT NULL DEFAULT '' COMMENT '菜单路由或页面标识' AFTER menu_type")
except Exception:
pass
try:
cur.execute("ALTER TABLE columns ADD COLUMN sort_order INT NOT NULL DEFAULT 0 COMMENT '菜单排序' AFTER route_path")
except Exception:
pass
try:
cur.execute("UPDATE columns SET menu_type = 'app' WHERE menu_type IS NULL OR menu_type = ''")
except Exception:
pass
try:
cur.execute("UPDATE columns SET sort_order = id WHERE sort_order IS NULL OR sort_order = 0")
except Exception:
pass
cur.execute("""
CREATE TABLE IF NOT EXISTS user_column_permission (
user_id INT NOT NULL,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff