更新处理相关内容
This commit is contained in:
@@ -48,6 +48,8 @@ admin_api = Blueprint('admin_api', __name__, url_prefix='/api/admin')
|
||||
_backend_java_session_local = threading.local()
|
||||
_column_sort_schema_checked = False
|
||||
_column_sort_schema_lock = threading.Lock()
|
||||
_product_category_schema_checked = False
|
||||
_product_category_schema_lock = threading.Lock()
|
||||
|
||||
ADMIN_MENU_ACCESS_CONFIG = {
|
||||
'dedupe-total-data': {
|
||||
@@ -70,6 +72,11 @@ ADMIN_MENU_ACCESS_CONFIG = {
|
||||
'route_path': 'query-asin',
|
||||
'error': '无权访问查询 ASIN 模块',
|
||||
},
|
||||
'product-categories': {
|
||||
'column_key': 'admin_product_categories',
|
||||
'route_path': 'product-categories',
|
||||
'error': '无权访问商品类目模块',
|
||||
},
|
||||
}
|
||||
|
||||
ADMIN_MENU_ACCESS_CONFIG.update({
|
||||
@@ -300,6 +307,92 @@ def _get_next_local_column_sort_order():
|
||||
conn.close()
|
||||
|
||||
|
||||
PRODUCT_CATEGORY_DEFAULT_TREE = [
|
||||
{
|
||||
'name': '护肤品',
|
||||
'key': 'skincare',
|
||||
'children': [
|
||||
('面霜', 'skincare_cream'),
|
||||
('精华', 'skincare_essence'),
|
||||
('面膜', 'skincare_mask'),
|
||||
('爽肤水', 'skincare_toner'),
|
||||
('身体乳', 'skincare_body_lotion'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': '彩妆',
|
||||
'key': 'makeup',
|
||||
'children': [
|
||||
('口红', 'makeup_lipstick'),
|
||||
('粉底', 'makeup_foundation'),
|
||||
('眼影', 'makeup_eyeshadow'),
|
||||
('睫毛', 'makeup_mascara'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': '洗护',
|
||||
'key': 'haircare',
|
||||
'children': [
|
||||
('洗发水', 'haircare_shampoo'),
|
||||
('护发素', 'haircare_conditioner'),
|
||||
('染发剂', 'haircare_hair_dye'),
|
||||
('烫发膏', 'haircare_perm_cream'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': '功效类',
|
||||
'key': 'functional',
|
||||
'children': [
|
||||
('防晒', 'functional_sunscreen'),
|
||||
('祛斑', 'functional_spot_removal'),
|
||||
('美白', 'functional_whitening'),
|
||||
('祛痘产品', 'functional_acne_care'),
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': '香氛',
|
||||
'key': 'fragrance',
|
||||
'children': [
|
||||
('香水', 'fragrance_perfume'),
|
||||
('香薰精油(高酒精属于危险品)', 'fragrance_essential_oil_hazardous'),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _ensure_local_admin_menu_item(name, column_key, route_path, sort_order):
|
||||
_ensure_column_sort_schema()
|
||||
conn = get_db()
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
INSERT INTO columns (name, column_key, menu_type, route_path, sort_order)
|
||||
VALUES (%s, %s, 'admin', %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
menu_type = 'admin',
|
||||
route_path = VALUES(route_path),
|
||||
sort_order = VALUES(sort_order)
|
||||
""",
|
||||
(name, column_key, route_path, int(sort_order)),
|
||||
)
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def _ensure_product_category_schema():
|
||||
global _product_category_schema_checked
|
||||
if _product_category_schema_checked:
|
||||
return
|
||||
with _product_category_schema_lock:
|
||||
if _product_category_schema_checked:
|
||||
return
|
||||
_ensure_local_admin_menu_item('商品类目', 'admin_product_categories', 'product-categories', 66)
|
||||
_product_category_schema_checked = True
|
||||
|
||||
|
||||
def _swap_local_column_sort_order(column_id, target_id):
|
||||
_ensure_column_sort_schema()
|
||||
conn = get_db()
|
||||
@@ -440,6 +533,20 @@ def _ensure_backend_menu_access(*menu_names):
|
||||
return role, current_row, (jsonify({'success': False, 'error': error_message}), 403)
|
||||
|
||||
|
||||
def _ensure_product_category_access():
|
||||
role, current_row, items, denied = _load_current_backend_menu_items()
|
||||
if denied:
|
||||
return role, current_row, denied
|
||||
if role == 'super_admin':
|
||||
return role, current_row, None
|
||||
for item in items or []:
|
||||
if (item.get('column_key') or '').strip() == 'admin_product_categories':
|
||||
return role, current_row, None
|
||||
if (item.get('route_path') or '').strip() == 'product-categories':
|
||||
return role, current_row, None
|
||||
return role, current_row, (jsonify({'success': False, 'error': '无权访问商品类目模块'}), 403)
|
||||
|
||||
|
||||
def _get_column_ids_by_route_paths(route_paths, menu_type='admin'):
|
||||
normalized_paths = [(path or '').strip() for path in (route_paths or []) if (path or '').strip()]
|
||||
if not normalized_paths:
|
||||
@@ -496,6 +603,7 @@ def get_admin_current_user():
|
||||
@admin_api.route('/current-user/menus')
|
||||
@login_required
|
||||
def get_admin_current_user_menus():
|
||||
_ensure_product_category_schema()
|
||||
_, _, items, denied = _load_current_backend_menu_items()
|
||||
if denied:
|
||||
return denied
|
||||
@@ -874,6 +982,7 @@ def list_columns():
|
||||
_, _, denied = _ensure_admin_menu_access('columns', 'users')
|
||||
if denied:
|
||||
return denied
|
||||
_ensure_product_category_schema()
|
||||
menu_type = (request.args.get('menu_type') or '').strip()
|
||||
local_rows = _load_local_columns(menu_type or None)
|
||||
items = [
|
||||
@@ -1072,6 +1181,117 @@ def _set_user_column_permissions(cur, user_id, column_ids):
|
||||
|
||||
# ---------- 版本管理(web_config) ----------
|
||||
|
||||
# ---------- 商品类目 ----------
|
||||
|
||||
|
||||
def _format_product_category_item(item, include_children=True):
|
||||
formatted = {
|
||||
'id': item.get('id'),
|
||||
'parent_id': item.get('parentId'),
|
||||
'name': item.get('name') or '',
|
||||
'category_key': item.get('categoryKey') or '',
|
||||
'sort_order': item.get('sortOrder') if item.get('sortOrder') is not None else 0,
|
||||
'description': item.get('description') or '',
|
||||
'is_builtin': bool(item.get('isBuiltin')),
|
||||
'child_count': item.get('childCount') if item.get('childCount') is not None else 0,
|
||||
'level': item.get('level') if item.get('level') is not None else 0,
|
||||
'path': item.get('path') or '',
|
||||
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
|
||||
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
|
||||
}
|
||||
if include_children:
|
||||
formatted['children'] = [_format_product_category_item(child) for child in (item.get('children') or [])]
|
||||
return formatted
|
||||
|
||||
|
||||
def _build_product_category_payload_for_java(data):
|
||||
sort_order = data.get('sort_order') if 'sort_order' in data else data.get('sortOrder')
|
||||
parent_id = data.get('parent_id') if 'parent_id' in data else data.get('parentId')
|
||||
if parent_id == '':
|
||||
parent_id = None
|
||||
if sort_order == '':
|
||||
sort_order = None
|
||||
return {
|
||||
'parentId': parent_id,
|
||||
'name': (data.get('name') or '').strip(),
|
||||
'sortOrder': sort_order,
|
||||
'description': (data.get('description') or '').strip(),
|
||||
}
|
||||
|
||||
|
||||
@admin_api.route('/product-categories')
|
||||
@login_required
|
||||
def list_product_categories():
|
||||
_ensure_product_category_schema()
|
||||
_, _, denied = _ensure_product_category_access()
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java('GET', '/api/admin/product-categories')
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
payload = result.get('data') or {}
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'tree': [_format_product_category_item(item) for item in (payload.get('tree') or [])],
|
||||
'items': [_format_product_category_item(item, include_children=False) for item in (payload.get('items') or [])],
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/product-category', methods=['POST'])
|
||||
@login_required
|
||||
def create_product_category():
|
||||
_ensure_product_category_schema()
|
||||
_, _, denied = _ensure_product_category_access()
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'POST',
|
||||
'/api/admin/product-category',
|
||||
json_data=_build_product_category_payload_for_java(request.get_json() or {}),
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'msg': result.get('message') or '创建成功',
|
||||
'item': _format_product_category_item(result.get('data') or {}, include_children=False),
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/product-category/<int:item_id>', methods=['PUT'])
|
||||
@login_required
|
||||
def update_product_category(item_id):
|
||||
_ensure_product_category_schema()
|
||||
_, _, denied = _ensure_product_category_access()
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'PUT',
|
||||
f'/api/admin/product-category/{item_id}',
|
||||
json_data=_build_product_category_payload_for_java(request.get_json() or {}),
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'msg': result.get('message') or '保存成功',
|
||||
'item': _format_product_category_item(result.get('data') or {}, include_children=False),
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/product-category/<int:item_id>', methods=['DELETE'])
|
||||
@login_required
|
||||
def delete_product_category(item_id):
|
||||
_ensure_product_category_schema()
|
||||
_, _, denied = _ensure_product_category_access()
|
||||
if denied:
|
||||
return denied
|
||||
result, error_response, status = _proxy_backend_java('DELETE', f'/api/admin/product-category/{item_id}')
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
return jsonify({'success': True, 'msg': result.get('message') or '删除成功'})
|
||||
|
||||
|
||||
@admin_api.route('/versions')
|
||||
@admin_required
|
||||
def list_versions():
|
||||
|
||||
@@ -23,10 +23,10 @@ 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://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://47.111.163.154:18080').rstrip('/')
|
||||
# backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://121.196.149.225:18080').rstrip('/')
|
||||
backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://121.196.149.225:18080').rstrip('/')
|
||||
os.environ['OSS_ACCESS_KEY_ID'] = accessKeyId
|
||||
os.environ['OSS_ACCESS_KEY_SECRET'] = accessKeySecret
|
||||
os.environ['SECRET_KEY'] = "ddffc7c1d02121d9554d7b080b2511b6"
|
||||
|
||||
3523
backend/static/admin.js
Normal file
3523
backend/static/admin.js
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user