Files

132 lines
4.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
邮箱池控制器(PRD-00009 MT-1)
职责:
- 解析 HTTP 请求参数
- 调用 services/pool.py 的业务方法
- 将 service 层业务结果映射为 FD 统一响应格式
- 将 PoolServiceError 映射为统一错误响应
响应格式(FD-00009 §6):
- 成功:{"success": true, "data": {...}}
- 失败:{"success": false, "error": "error_code", "message": "错误说明"}
HTTP 状态码映射(TD-00009 §6.3):
- 参数错误 → 400
- 归属/凭据错误 → 403
- 状态冲突 → 409
- 业务失败(如 no_available_account) → 200 + success=false
"""
from __future__ import annotations
from flask import jsonify, request
from outlook_web.services.pool import (
PoolServiceError,
claim_random,
complete_claim,
get_pool_stats,
release_claim,
)
def _success_response(data: dict, http_status: int = 200):
"""统一成功响应:{"success": true, "data": {...}}"""
return jsonify({"success": True, "data": data}), http_status
def _error_response(error_code: str, message: str, http_status: int = 400):
"""统一失败响应:{"success": false, "error": "...", "message": "..."}"""
return jsonify({"success": False, "error": error_code, "message": message}), http_status
def api_claim_random():
body = request.get_json(silent=True) or {}
caller_id = body.get("caller_id", "")
task_id = body.get("task_id", "")
provider = body.get("provider")
try:
account = claim_random(
caller_id=caller_id,
task_id=task_id,
provider=provider,
)
return _success_response(
{
"account_id": account["id"],
"email": account["email"],
"claim_token": account["claim_token"],
"lease_expires_at": account["lease_expires_at"],
}
)
except PoolServiceError as exc:
return _error_response(exc.error_code, str(exc), exc.http_status)
def api_claim_release():
body = request.get_json(silent=True) or {}
account_id = body.get("account_id")
claim_token = body.get("claim_token", "")
caller_id = body.get("caller_id", "")
task_id = body.get("task_id", "")
reason = body.get("reason")
if account_id is None:
return _error_response("account_id_missing", "account_id 不能为空", 400)
try:
account_id = int(account_id)
except (TypeError, ValueError):
return _error_response("account_id_invalid", "account_id 必须为整数", 400)
try:
release_claim(
account_id=account_id,
claim_token=claim_token,
caller_id=caller_id,
task_id=task_id,
reason=reason,
)
return _success_response({"account_id": account_id, "pool_status": "available"})
except PoolServiceError as exc:
return _error_response(exc.error_code, str(exc), exc.http_status)
def api_claim_complete():
body = request.get_json(silent=True) or {}
account_id = body.get("account_id")
claim_token = body.get("claim_token", "")
caller_id = body.get("caller_id", "")
task_id = body.get("task_id", "")
result = body.get("result", "")
detail = body.get("detail")
if account_id is None:
return _error_response("account_id_missing", "account_id 不能为空", 400)
try:
account_id = int(account_id)
except (TypeError, ValueError):
return _error_response("account_id_invalid", "account_id 必须为整数", 400)
try:
new_status = complete_claim(
account_id=account_id,
claim_token=claim_token,
caller_id=caller_id,
task_id=task_id,
result=result,
detail=detail,
)
return _success_response({"account_id": account_id, "pool_status": new_status})
except PoolServiceError as exc:
return _error_response(exc.error_code, str(exc), exc.http_status)
def api_pool_stats():
try:
stats = get_pool_stats()
return _success_response(stats)
except Exception as exc:
return _error_response("internal_error", str(exc), 500)