""" 产品审核 API """ import uuid import json from datetime import datetime from flask import Blueprint, request, jsonify, session from config import DATA_DIR, MODELS_FILE, GPUS_FILE, CPUS_FILE from utils import load_data, save_data reviews_bp = Blueprint('api_reviews', __name__) PENDING_FILE = DATA_DIR / 'pending_reviews.json' @reviews_bp.route('/api/reviews') def api_reviews(): """获取待审核列表""" reviews = load_data(PENDING_FILE) # 筛选参数 status = request.args.get('status', 'pending') # pending, approved, rejected, all limit = int(request.args.get('limit', 100)) if status != 'all': reviews = [r for r in reviews if r.get('status', 'pending') == status] # 按时间倒序 reviews = sorted(reviews, key=lambda x: x.get('created_at', ''), reverse=True) return jsonify(reviews[:limit]) @reviews_bp.route('/api/reviews/count') def api_reviews_count(): """获取待审核数量""" reviews = load_data(PENDING_FILE) pending_count = len([r for r in reviews if r.get('status', 'pending') == 'pending']) return jsonify({'count': pending_count}) @reviews_bp.route('/api/reviews/') def api_review_detail(review_id): """获取审核详情""" reviews = load_data(PENDING_FILE) review = next((r for r in reviews if r['id'] == review_id), None) if not review: return jsonify({'error': 'Review not found'}), 404 return jsonify(review) @reviews_bp.route('/api/reviews//approve', methods=['POST']) def api_approve_review(review_id): """通过审核""" reviews = load_data(PENDING_FILE) review = next((r for r in reviews if r['id'] == review_id), None) if not review: return jsonify({'error': 'Review not found'}), 404 if review.get('status') != 'pending': return jsonify({'error': '该申请已处理'}), 400 # 获取数据文件 category_id = review.get('category_id') data_file = get_data_file(category_id) if not data_file: return jsonify({'error': 'Unknown category'}), 400 # 添加数据到正式文件 items = load_data(data_file) item_data = review.get('data', {}) # 确保有ID和时间戳 if 'id' not in item_data or not item_data['id']: item_data['id'] = uuid.uuid4().hex[:12] item_data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') item_data['visible'] = True item_data['approved'] = True item_data['approved_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') items.append(item_data) save_data(data_file, items) # 更新审核状态 review['status'] = 'approved' review['approved_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') review['approved_by'] = session.get('username', 'admin') save_data(PENDING_FILE, reviews) return jsonify({'success': True, 'item': item_data}) @reviews_bp.route('/api/reviews//reject', methods=['POST']) def api_reject_review(review_id): """拒绝审核""" reviews = load_data(PENDING_FILE) review = next((r for r in reviews if r['id'] == review_id), None) if not review: return jsonify({'error': 'Review not found'}), 404 if review.get('status') != 'pending': return jsonify({'error': '该申请已处理'}), 400 data = request.get_json() or {} reason = data.get('reason', '') # 更新审核状态 review['status'] = 'rejected' review['rejected_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') review['rejected_by'] = session.get('username', 'admin') review['reject_reason'] = reason save_data(PENDING_FILE, reviews) return jsonify({'success': True}) def get_data_file(category_id): """获取类别对应的数据文件""" builtin_map = { 'ai-models': MODELS_FILE, 'gpus': GPUS_FILE, 'cpus': CPUS_FILE } if category_id in builtin_map: return builtin_map[category_id] # 动态分类 return DATA_DIR / f'items_{category_id}.json' # ─── 内部函数:提交审核 ─────────────────────────────────────────────────────── def submit_for_review(category_id, data, source='web', submitter=None): """ 提交产品到审核队列 参数: category_id: 分类ID data: 产品数据(dict) source: 来源 web/api submitter: 提交者 """ reviews = load_data(PENDING_FILE) review = { 'id': uuid.uuid4().hex[:12], 'category_id': category_id, 'data': data, 'source': source, 'submitter': submitter or 'anonymous', 'status': 'pending', # pending, approved, rejected 'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S') } reviews.append(review) save_data(PENDING_FILE, reviews) return review