This commit is contained in:
ddrwode
2026-02-27 14:11:12 +08:00
parent 72d379add7
commit 038f105ec5
4 changed files with 202 additions and 2 deletions

View File

@@ -3,18 +3,26 @@
BOSS 账号 API需要登录
- POST /api/accounts -> 添加账号(绑定环境名称到电脑)
- GET /api/accounts -> 查询所有账号(含电脑名称、在线、任务状态)
- POST /api/accounts/fill-boss-ids -> 批量填充缺失的 boss_id触发 check_login
- GET /api/accounts/{id} -> 查询单个账号详情
- DELETE /api/accounts/{id} -> 删除账号
检测登录等操作统一通过 POST /api/tasks 提交task_type 传 check_login 即可。
"""
import logging
from asgiref.sync import async_to_sync
from rest_framework import status
from rest_framework.decorators import api_view
from common.protocol import TaskType
from server.core.response import api_success, api_error
from server.models import BossAccount
from server.models import BossAccount, TaskCreate
from server.serializers import BossAccountSerializer, AccountBindSerializer
from server.core.worker_manager import worker_manager
from server.core.task_dispatcher import task_dispatcher
logger = logging.getLogger("server.api.accounts")
# ────────────────────────── 内部工具 ──────────────────────────
@@ -49,7 +57,7 @@ def account_list(request):
wid = ser.validated_data["worker_id"]
bname = ser.validated_data["browser_name"]
account, _ = BossAccount.objects.get_or_create(
account, created = BossAccount.objects.get_or_create(
worker_id=wid,
browser_name=bname,
defaults={
@@ -58,9 +66,71 @@ def account_list(request):
"is_logged_in": False,
},
)
# 绑定后自动触发检测登录,填充 boss_id
if (created or not account.boss_id) and worker_manager.is_online(wid):
send_fn = worker_manager.get_send_fn(wid)
if send_fn:
req = TaskCreate(task_type=TaskType.CHECK_LOGIN, worker_id=wid, account_name=bname, params={})
task = task_dispatcher.create_task(req)
if async_to_sync(task_dispatcher.dispatch)(task, send_fn):
worker_manager.set_current_task(wid, task.task_id)
account.current_task_id = task.task_id
account.current_task_status = task.status.value
account.save(update_fields=["current_task_id", "current_task_status"])
logger.info("绑定账号后自动触发 check_login: %s@%s", bname, wid)
return api_success(_enrich(account), http_status=status.HTTP_201_CREATED)
@api_view(["POST"])
def fill_boss_ids(request):
"""
为缺少 boss_id 的账号批量触发检测登录任务。
需确保对应 Worker 在线,任务执行完成后会自动更新 boss_id。
"""
from django.db.models import Q
accounts = BossAccount.objects.filter(Q(boss_id="") | Q(boss_id__isnull=True)).exclude(browser_name="")
submitted = 0
skipped = 0
errors = []
for acc in accounts:
wid = acc.worker_id
bname = acc.browser_name
if not worker_manager.is_online(wid):
skipped += 1
errors.append(f"{bname}@{wid}: Worker 不在线")
continue
send_fn = worker_manager.get_send_fn(wid)
if not send_fn:
skipped += 1
errors.append(f"{bname}@{wid}: Worker 连接不可用")
continue
req = TaskCreate(
task_type=TaskType.CHECK_LOGIN,
worker_id=wid,
account_name=bname,
params={},
)
task = task_dispatcher.create_task(req)
success = async_to_sync(task_dispatcher.dispatch)(task, send_fn)
if success:
worker_manager.set_current_task(wid, task.task_id)
acc.current_task_id = task.task_id
acc.current_task_status = task.status.value
acc.save(update_fields=["current_task_id", "current_task_status"])
submitted += 1
else:
skipped += 1
errors.append(f"{bname}@{wid}: 派发失败")
return api_success({
"submitted": submitted,
"skipped": skipped,
"errors": errors[:20],
"message": f"已为 {submitted} 个账号触发检测登录,{skipped} 个跳过",
}, http_status=status.HTTP_200_OK)
@api_view(["GET"])
def account_list_by_worker(request, worker_id):
"""按 worker_id 查询账号列表,兼容 /api/accounts/worker-1 形式。"""

View File

@@ -26,6 +26,7 @@ urlpatterns = [
# ─── 账号 ───
path("api/accounts", accounts.account_list),
path("api/accounts/fill-boss-ids", accounts.fill_boss_ids),
path("api/accounts/<int:account_id>", accounts.account_detail),
path("api/accounts/<str:worker_id>", accounts.account_list_by_worker),