refactor: 补全services层+消除core/models.py冗余+修复network.py缩进错误
高优先级问题1 - Router层业务逻辑泄漏: - 新建 services/proxy_service.py: 从routers/proxy.py提取ProxyService类, 封装代理/白名单测试逻辑、全局状态管理、所有core/ import - 新建 services/account_service.py: 从routers/accounts.py提取 split_account_line、cookie_account_ids_query、parse_and_build_accounts, 封装core.douyu.email_verifier的import - 重写routers/proxy.py为薄HTTP/WS层,移除所有core/直接依赖 - 精简routers/accounts.py,从account_service导入业务函数 - 将_active_batches全局状态移入login_service.py的BatchRegistry类 - routers/login.py改为使用batch_registry单例 高优先级问题2 - 两套models.py冗余: - 删除core/models.py(Account dataclass + ProxyConfig死代码) - 在core/douyu/login.py新增AccountLike Protocol替代Account dataclass - login_service.py中Account(...)构造改为SimpleNamespace(...) - 清理core/__init__.py导出 附带修复: - core/geetest/common/network.py的get_picture()函数缩进错误 (缺少if match:块和data赋值语句)
This commit is contained in:
@@ -1,41 +1,20 @@
|
||||
"""账号管理路由"""
|
||||
|
||||
import re
|
||||
import csv
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from ..database import get_db
|
||||
from ..models import User, Account, AuditLog, LoginTask
|
||||
from ..schemas import AccountImport, AccountAssign, AccountTag, AccountOut, BatchAssign
|
||||
from ..deps import get_current_user, require_permission
|
||||
from ..permissions import user_has_permission
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import joinedload
|
||||
from ..services.account_service import (
|
||||
cookie_account_ids_query, parse_and_build_accounts,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/api/accounts", tags=["账号管理"])
|
||||
|
||||
EMAIL_PATTERN = re.compile(r'^[^\s@|]+@[^\s@|]+\.[^\s@|]+$')
|
||||
|
||||
|
||||
def _split_account_line(line: str) -> list[str]:
|
||||
if '|' in line:
|
||||
return line.split('|')
|
||||
if '\t' in line:
|
||||
return line.split('\t')
|
||||
if ',' in line:
|
||||
return next(csv.reader([line]))
|
||||
return line.split()
|
||||
|
||||
|
||||
def _cookie_account_ids_query(db: Session):
|
||||
"""返回有成功登录记录(cookie非空)的账号ID子查询。"""
|
||||
return db.query(LoginTask.account_id).filter(
|
||||
LoginTask.status == 'success',
|
||||
LoginTask.cookie != '',
|
||||
LoginTask.cookie.isnot(None),
|
||||
).distinct()
|
||||
|
||||
|
||||
@router.get("", response_model=list[AccountOut])
|
||||
def list_accounts(
|
||||
@@ -50,7 +29,7 @@ def list_accounts(
|
||||
|
||||
# 只展示已成功登录过的账号
|
||||
if has_cookie:
|
||||
query = query.filter(Account.id.in_(_cookie_account_ids_query(db)))
|
||||
query = query.filter(Account.id.in_(cookie_account_ids_query(db)))
|
||||
|
||||
# 权限控制:客服只能看分配给自己的
|
||||
if not user_has_permission(current, "account:view_all"):
|
||||
@@ -91,39 +70,7 @@ def import_accounts(
|
||||
current: User = Depends(require_permission("account:import")),
|
||||
):
|
||||
"""批量导入账号。格式:用户名|密码|邮箱|邮箱密码|标签(可选)"""
|
||||
from core.douyu.email_verifier import get_email_config_for_account
|
||||
|
||||
accounts = []
|
||||
skipped = 0
|
||||
for line_num, line in enumerate(req.text.strip().split('\n'), 1):
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
parts = _split_account_line(line)
|
||||
if len(parts) < 4:
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
username, password, email, email_password = [p.strip() for p in parts[:4]]
|
||||
tag = parts[4].strip() if len(parts) > 4 else ""
|
||||
if not all([username, password, email, email_password]):
|
||||
skipped += 1
|
||||
continue
|
||||
if not EMAIL_PATTERN.match(email):
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
email_cfg = get_email_config_for_account(email)
|
||||
accounts.append(Account(
|
||||
username=username,
|
||||
password=password,
|
||||
email=email,
|
||||
email_password=email_password,
|
||||
email_imap_server=email_cfg['server'],
|
||||
email_imap_port=email_cfg.get('port', 993),
|
||||
email_imap_ssl=email_cfg.get('ssl', True),
|
||||
tag=tag,
|
||||
))
|
||||
accounts, skipped = parse_and_build_accounts(req.text)
|
||||
|
||||
if accounts:
|
||||
db.add_all(accounts)
|
||||
@@ -187,7 +134,7 @@ def batch_assign_accounts(
|
||||
raise HTTPException(status_code=400, detail="只能分配给客服角色")
|
||||
|
||||
# 只能分配已成功登录过的账号(有cookie)
|
||||
cookie_ids_query = _cookie_account_ids_query(db).subquery()
|
||||
cookie_ids_query = cookie_account_ids_query(db).subquery()
|
||||
invalid_ids = db.query(Account.id).filter(
|
||||
Account.id.in_(req.account_ids),
|
||||
Account.id.notin_(cookie_ids_query),
|
||||
@@ -220,7 +167,7 @@ def assignments_summary(
|
||||
current: User = Depends(require_permission("account:assign")),
|
||||
):
|
||||
"""分配概览:每个客服分配了多少账号(仅统计已成功登录的账号)。"""
|
||||
cookie_subq = _cookie_account_ids_query(db).subquery()
|
||||
cookie_subq = cookie_account_ids_query(db).subquery()
|
||||
cookie_accounts = db.query(Account).filter(Account.id.in_(cookie_subq)).subquery()
|
||||
|
||||
results = (
|
||||
|
||||
Reference in New Issue
Block a user