Files
boss_dp/server/models.py
Your Name 0ac1e9549c 哈哈
2026-02-14 16:49:44 +08:00

126 lines
5.2 KiB
Python
Raw 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.

# -*- coding: utf-8 -*-
"""
数据模型Django ORM 表模型 + Pydantic 内存模型。
"""
from __future__ import annotations
import time
import uuid
from typing import Any, Dict, List, Optional
from django.db import models
from pydantic import BaseModel, Field
from common.protocol import TaskStatus, TaskType
# ══════════════════════════════════════════════════════════════
# Django ORM 模型
# ══════════════════════════════════════════════════════════════
class BossAccount(models.Model):
"""BOSS 账号登录状态表。"""
worker_id = models.CharField(max_length=64, verbose_name="Worker 标识")
browser_id = models.CharField(max_length=128, default="", verbose_name="比特浏览器窗口 ID")
browser_name = models.CharField(max_length=128, default="", verbose_name="比特浏览器窗口名称(环境名)")
boss_username = models.CharField(max_length=128, default="", verbose_name="BOSS 直聘用户名")
is_logged_in = models.BooleanField(default=False, verbose_name="是否已登录")
current_task_id = models.CharField(max_length=32, null=True, blank=True, verbose_name="当前检测任务 ID")
current_task_status = models.CharField(max_length=32, null=True, blank=True, verbose_name="当前检测任务状态")
checked_at = models.DateTimeField(null=True, blank=True, verbose_name="最近一次检测时间")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
db_table = "boss_account"
unique_together = [("worker_id", "browser_id")]
verbose_name = "BOSS 账号"
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.browser_name}@{self.worker_id}"
class TaskLog(models.Model):
"""任务执行记录表。"""
task_id = models.CharField(max_length=32, unique=True, verbose_name="任务 ID")
task_type = models.CharField(max_length=64, verbose_name="任务类型")
worker_id = models.CharField(max_length=64, default="", verbose_name="执行的 Worker")
status = models.CharField(max_length=32, default="", verbose_name="最终状态")
params = models.JSONField(null=True, blank=True, verbose_name="任务参数")
result = models.JSONField(null=True, blank=True, verbose_name="任务结果")
error = models.TextField(null=True, blank=True, verbose_name="错误信息")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
class Meta:
db_table = "task_log"
verbose_name = "任务日志"
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.task_id} ({self.task_type})"
class AuthToken(models.Model):
"""登录 token 表:每个用户名仅保留当前有效 token。"""
username = models.CharField(max_length=64, unique=True, verbose_name="用户名")
token = models.CharField(max_length=64, verbose_name="当前有效 token")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
class Meta:
db_table = "auth_token"
verbose_name = "登录 Token"
verbose_name_plural = verbose_name
def __str__(self):
return self.username
# ══════════════════════════════════════════════════════════════
# Pydantic 内存模型(非数据库,用于 Worker 运行时状态与任务调度)
# ══════════════════════════════════════════════════════════════
# ─── Worker ───
class BrowserProfile(BaseModel):
"""比特浏览器窗口信息Worker 上报)。"""
id: str
name: str = ""
remark: str = ""
class WorkerInfo(BaseModel):
"""一台 Worker 的运行时信息(内存中保存)。"""
worker_id: str
worker_name: str = ""
browsers: List[BrowserProfile] = []
online: bool = True
last_heartbeat: float = Field(default_factory=time.time)
connected_at: float = Field(default_factory=time.time)
current_task_id: Optional[str] = None
# ─── Task ───
class TaskCreate(BaseModel):
"""前端提交任务的请求体(也用于内部创建任务)。"""
task_type: TaskType
worker_id: Optional[str] = None
account_name: Optional[str] = None
params: Dict[str, Any] = {}
class TaskInfo(BaseModel):
"""任务完整信息(内存中保存)。"""
task_id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
task_type: TaskType
status: TaskStatus = TaskStatus.PENDING
worker_id: Optional[str] = None
account_name: Optional[str] = None
params: Dict[str, Any] = {}
progress: Optional[str] = None
result: Any = None
error: Optional[str] = None
created_at: float = Field(default_factory=time.time)
updated_at: float = Field(default_factory=time.time)