feat: 外观专利改直连 LLM(DeepSeek/Gemini)、无效ASIN菜单更名 BRAND_DB、紫鸟店铺索引场景化
Build Backend JAR / build (push) Has been cancelled

- AppearancePatent:Coze 工作流切换为 llm-host 直连模型(title/appearance 双模型、行并发、重试),配置键迁移并保留旧环境变量兜底
- InvalidAsinDataMapper 补充按值+品牌唯一键查询
- ZiniaoShopIndexService 新增店铺分类/索引场景
- V98:无效ASIN菜单 rename 补充 BRAND_DB;docs 架构优化规划
- 配套单测更新
This commit is contained in:
2026-08-31 17:02:59 +08:00
parent 14a41e64f1
commit c8cd851b2f
20 changed files with 1291 additions and 2338 deletions
+45 -1
View File
@@ -1359,7 +1359,7 @@ _SHOP_DATA_CRAWL_ADMIN_COLUMNS = f"""
r.result_file_size, r.result_content_type, r.row_count,
r.success AS result_success, r.error_message AS result_error,
r.created_at AS result_created_at,
t.task_no, t.status AS task_status, t.request_json, t.result_json,
t.task_no, t.status AS task_status, t.request_json,
t.error_message AS task_error, t.created_at, t.updated_at, t.finished_at,
{_SHOP_DATA_CRAWL_LATEST_TIME_SQL} AS latest_file_updated_at,
df.country_codes_json, COALESCE(df.row_count, r.row_count) AS row_count_display,
@@ -3395,6 +3395,19 @@ def delete_invalid_asin_data(item_id):
# ---------- 店铺管理 ----------
def _format_shop_manage_item(item):
latest_check = item.get('latestCheck')
if isinstance(latest_check, dict):
latest_check = {
'id': latest_check.get('id'),
'status': latest_check.get('status') or '',
'detail': latest_check.get('detail') or '',
'client_host': latest_check.get('clientHost') or '',
'try_requested_at': (latest_check.get('tryRequestedAt') or '').replace('T', ' ')[:19],
'check_started_at': (latest_check.get('checkStartedAt') or '').replace('T', ' ')[:19],
'check_finished_at': (latest_check.get('checkFinishedAt') or '').replace('T', ' ')[:19],
}
else:
latest_check = None
return {
'id': item.get('id'),
'group_id': item.get('groupId'),
@@ -3404,6 +3417,7 @@ def _format_shop_manage_item(item):
'zn_username': item.get('znUsername') or '',
'account': item.get('account') or '',
'password': item.get('passwordMasked') or '',
'latest_check': latest_check,
'created_at': (item.get('createdAt') or '').replace('T', ' ')[:16],
'updated_at': (item.get('updatedAt') or '').replace('T', ' ')[:16],
}
@@ -3483,6 +3497,36 @@ def list_shop_manages():
})
@admin_api.route('/shop-manage/<int:item_id>/credential-check', methods=['POST'])
@login_required
def create_shop_credential_check(item_id):
role, current_row, denied = _ensure_backend_menu_access('shop-manage')
if denied:
return denied
shop_name = (request.args.get('shop_name') or '').strip()
if not shop_name:
return jsonify({'success': False, 'error': '店铺名不能为空'}), 400
internal_token = _resolve_internal_token()
if not internal_token:
return jsonify({'success': False, 'error': '内部凭据服务未配置'}), 503
result, error_response, status = _proxy_backend_java(
'POST',
'/api/admin/shop-credential-checks',
json_data={'shopName': shop_name},
headers={'X-Internal-Token': internal_token},
)
if error_response is not None:
return error_response, status
check = result.get('data') or {}
return jsonify({
'success': True,
'msg': '检测任务已创建,客户端将在 1 分钟内执行',
'check': {'id': check.get('id'), 'status': check.get('status') or 'PENDING'},
})
@admin_api.route('/shop-manage/<int:item_id>/credential')
@login_required
def get_shop_manage_credential(item_id):