2026-07-12 01:07:26 +08:00
|
|
|
"""
|
|
|
|
|
ParamHub API 客户端服务
|
|
|
|
|
"""
|
|
|
|
|
import requests
|
|
|
|
|
from config import Config
|
|
|
|
|
|
|
|
|
|
class ParamHubClient:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.base_url = Config.PARAMHUB_BASE_URL
|
|
|
|
|
self.password = Config.PARAMHUB_PASSWORD
|
|
|
|
|
self.session = None
|
|
|
|
|
|
|
|
|
|
def login(self):
|
|
|
|
|
"""登录获取session"""
|
|
|
|
|
try:
|
|
|
|
|
self.session = requests.Session()
|
|
|
|
|
response = self.session.post(
|
|
|
|
|
f'{self.base_url}/login',
|
|
|
|
|
json={'password': self.password}
|
|
|
|
|
)
|
|
|
|
|
return response.json().get('success', False)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"登录失败: {str(e)}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def get_categories(self):
|
|
|
|
|
"""获取所有分类"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
response = self.session.get(f'{self.base_url}/api/categories?all=1')
|
|
|
|
|
return response.json()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"获取分类失败: {str(e)}")
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def get_category_fields(self, category_id):
|
|
|
|
|
"""获取分类的字段配置"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
response = self.session.get(f'{self.base_url}/api/categories/{category_id}')
|
|
|
|
|
return response.json()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"获取分类字段失败: {str(e)}")
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def submit_for_review(self, category_type, data, category_id=None):
|
|
|
|
|
"""
|
|
|
|
|
提交数据到待审核区
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
category_type: 分类类型 (model/gpu/cpu/dynamic)
|
|
|
|
|
data: 产品数据
|
|
|
|
|
category_id: 分类ID(用于动态分类)
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
(success, review_id or error_message)
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
# 根据分类类型选择API端点
|
|
|
|
|
if category_type == 'model':
|
|
|
|
|
endpoint = f'{self.base_url}/api/models'
|
|
|
|
|
elif category_type == 'gpu':
|
|
|
|
|
endpoint = f'{self.base_url}/api/gpus'
|
|
|
|
|
elif category_type == 'cpu':
|
|
|
|
|
endpoint = f'{self.base_url}/api/cpus'
|
|
|
|
|
elif category_type == 'dynamic' and category_id:
|
|
|
|
|
endpoint = f'{self.base_url}/api/items/{category_id}'
|
|
|
|
|
else:
|
|
|
|
|
return False, "无效的分类类型或缺少分类ID"
|
|
|
|
|
|
|
|
|
|
# 添加审核模式需要的字段
|
|
|
|
|
data['status'] = 'pending'
|
|
|
|
|
|
|
|
|
|
response = self.session.post(endpoint, json=data)
|
|
|
|
|
result = response.json()
|
|
|
|
|
|
|
|
|
|
if response.status_code == 200 or response.status_code == 201:
|
|
|
|
|
return True, result.get('review_id', 'submitted')
|
|
|
|
|
else:
|
|
|
|
|
return False, result.get('error', '提交失败')
|
|
|
|
|
except Exception as e:
|
|
|
|
|
return False, str(e)
|
|
|
|
|
|
|
|
|
|
def get_reviews(self, status='pending'):
|
|
|
|
|
"""获取待审核列表"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
response = self.session.get(f'{self.base_url}/api/reviews?status={status}')
|
|
|
|
|
return response.json()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"获取审核列表失败: {str(e)}")
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def get_review_count(self):
|
|
|
|
|
"""获取待审核数量"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
response = self.session.get(f'{self.base_url}/api/reviews/count')
|
|
|
|
|
return response.json().get('count', 0)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"获取审核数量失败: {str(e)}")
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def send_notification(self, message):
|
|
|
|
|
"""发送通知到后台管理"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
# 使用通知API发送通知
|
|
|
|
|
response = self.session.post(
|
|
|
|
|
f'{self.base_url}/api/notifications',
|
|
|
|
|
json={'message': message}
|
|
|
|
|
)
|
|
|
|
|
return response.status_code == 200 or response.status_code == 201
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"发送通知失败: {str(e)}")
|
|
|
|
|
return False
|
2026-07-16 23:35:39 +08:00
|
|
|
|
|
|
|
|
def check_product_exists(self, product_name):
|
|
|
|
|
"""
|
|
|
|
|
检查产品是否已存在于系统中(已发布或待审核)
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
product_name: 产品名称
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
{
|
|
|
|
|
'exists': bool,
|
|
|
|
|
'status': str ('published'/'pending'/None),
|
|
|
|
|
'message': str
|
|
|
|
|
}
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
if not self.session:
|
|
|
|
|
self.login()
|
|
|
|
|
|
|
|
|
|
# 1. 检查已发布的产品(通过搜索API)
|
|
|
|
|
response = self.session.get(
|
|
|
|
|
f'{self.base_url}/api/search',
|
|
|
|
|
params={'q': product_name}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if response.status_code == 200:
|
|
|
|
|
result = response.json()
|
|
|
|
|
|
|
|
|
|
# 检查是否匹配(精确匹配或包含匹配)
|
|
|
|
|
product_name_lower = product_name.lower().strip()
|
|
|
|
|
|
|
|
|
|
# 检查已发布的模型
|
|
|
|
|
for model in result.get('models', []):
|
|
|
|
|
name = model.get('name', '').lower().strip()
|
|
|
|
|
if product_name_lower == name or product_name_lower in name or name in product_name_lower:
|
|
|
|
|
return {
|
|
|
|
|
'exists': True,
|
|
|
|
|
'status': 'published',
|
|
|
|
|
'message': f'产品 "{product_name}" 已在已发布的模型中',
|
|
|
|
|
'category': 'ai-models',
|
|
|
|
|
'data': model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 检查已发布的GPU
|
|
|
|
|
for gpu in result.get('gpus', []):
|
|
|
|
|
name = gpu.get('name', '').lower().strip()
|
|
|
|
|
if product_name_lower == name or product_name_lower in name or name in product_name_lower:
|
|
|
|
|
return {
|
|
|
|
|
'exists': True,
|
|
|
|
|
'status': 'published',
|
|
|
|
|
'message': f'产品 "{product_name}" 已在已发布的GPU中',
|
|
|
|
|
'category': 'gpus',
|
|
|
|
|
'data': gpu
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 检查已发布的CPU
|
|
|
|
|
for cpu in result.get('cpus', []):
|
|
|
|
|
name = cpu.get('name', '').lower().strip()
|
|
|
|
|
if product_name_lower == name or product_name_lower in name or name in product_name_lower:
|
|
|
|
|
return {
|
|
|
|
|
'exists': True,
|
|
|
|
|
'status': 'published',
|
|
|
|
|
'message': f'产品 "{product_name}" 已在已发布的CPU中',
|
|
|
|
|
'category': 'cpus',
|
|
|
|
|
'data': cpu
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 检查待审核列表
|
|
|
|
|
response = self.session.get(
|
|
|
|
|
f'{self.base_url}/api/reviews',
|
|
|
|
|
params={'status': 'pending'}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if response.status_code == 200:
|
|
|
|
|
reviews = response.json()
|
|
|
|
|
product_name_lower = product_name.lower().strip()
|
|
|
|
|
|
|
|
|
|
for review in reviews:
|
|
|
|
|
review_data = review.get('data', {})
|
|
|
|
|
review_name = review_data.get('name', '').lower().strip()
|
|
|
|
|
|
|
|
|
|
if product_name_lower == review_name or product_name_lower in review_name or review_name in product_name_lower:
|
|
|
|
|
return {
|
|
|
|
|
'exists': True,
|
|
|
|
|
'status': 'pending',
|
|
|
|
|
'message': f'产品 "{product_name}" 已在待审核列表中',
|
|
|
|
|
'review_id': review.get('id'),
|
|
|
|
|
'category': review.get('category_id'),
|
|
|
|
|
'data': review
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 产品不存在
|
|
|
|
|
return {
|
|
|
|
|
'exists': False,
|
|
|
|
|
'status': None,
|
|
|
|
|
'message': f'产品 "{product_name}" 未在系统中找到'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"检查产品是否存在失败: {str(e)}")
|
|
|
|
|
# 出错时返回不存在,允许后续处理
|
|
|
|
|
return {
|
|
|
|
|
'exists': False,
|
|
|
|
|
'status': None,
|
|
|
|
|
'message': f'检查失败: {str(e)}'
|
|
|
|
|
}
|
2026-07-12 01:07:26 +08:00
|
|
|
|
|
|
|
|
# 全局客户端实例
|
|
|
|
|
paramhub_client = ParamHubClient()
|