refactor: optimize structure, stability and runtime performance

This commit is contained in:
2026-02-07 00:35:11 +08:00
parent fae21329d7
commit bf29ac1924
44 changed files with 6894 additions and 4792 deletions

View File

@@ -40,6 +40,48 @@ def _emit(event: str, data: object, *, room: str | None = None) -> None:
pass
def _emit_account_update(user_id: int, account) -> None:
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
def _request_json(default=None):
if default is None:
default = {}
data = request.get_json(silent=True)
return data if isinstance(data, dict) else default
def _ensure_accounts_loaded(user_id: int) -> dict:
accounts = safe_get_user_accounts_snapshot(user_id)
if accounts:
return accounts
load_user_accounts(user_id)
return safe_get_user_accounts_snapshot(user_id)
def _get_user_account(user_id: int, account_id: str, *, refresh_if_missing: bool = False):
account = safe_get_account(user_id, account_id)
if account or (not refresh_if_missing):
return account
load_user_accounts(user_id)
return safe_get_account(user_id, account_id)
def _validate_browse_type_input(raw_browse_type, *, default=BROWSE_TYPE_SHOULD_READ):
browse_type = validate_browse_type(raw_browse_type, default=default)
if not browse_type:
return None, (jsonify({"error": "浏览类型无效"}), 400)
return browse_type, None
def _cancel_pending_account_task(user_id: int, account_id: str) -> bool:
try:
scheduler = get_task_scheduler()
return bool(scheduler.cancel_pending_task(user_id=user_id, account_id=account_id))
except Exception:
return False
@api_accounts_bp.route("/api/accounts", methods=["GET"])
@login_required
def get_accounts():
@@ -49,8 +91,7 @@ def get_accounts():
accounts = safe_get_user_accounts_snapshot(user_id)
if refresh or not accounts:
load_user_accounts(user_id)
accounts = safe_get_user_accounts_snapshot(user_id)
accounts = _ensure_accounts_loaded(user_id)
return jsonify([acc.to_dict() for acc in accounts.values()])
@@ -63,20 +104,18 @@ def add_account():
current_count = len(database.get_user_accounts(user_id))
is_vip = database.is_user_vip(user_id)
if not is_vip and current_count >= 3:
if (not is_vip) and current_count >= 3:
return jsonify({"error": "普通用户最多添加3个账号升级VIP可无限添加"}), 403
data = request.json
username = data.get("username", "").strip()
password = data.get("password", "").strip()
remark = data.get("remark", "").strip()[:200]
data = _request_json()
username = str(data.get("username", "")).strip()
password = str(data.get("password", "")).strip()
remark = str(data.get("remark", "")).strip()[:200]
if not username or not password:
return jsonify({"error": "用户名和密码不能为空"}), 400
accounts = safe_get_user_accounts_snapshot(user_id)
if not accounts:
load_user_accounts(user_id)
accounts = safe_get_user_accounts_snapshot(user_id)
accounts = _ensure_accounts_loaded(user_id)
for acc in accounts.values():
if acc.username == username:
return jsonify({"error": f"账号 '{username}' 已存在"}), 400
@@ -92,7 +131,7 @@ def add_account():
safe_set_account(user_id, account_id, account)
log_to_client(f"添加账号: {username}", user_id)
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
_emit_account_update(user_id, account)
return jsonify(account.to_dict())
@@ -103,15 +142,15 @@ def update_account(account_id):
"""更新账号信息(密码等)"""
user_id = current_user.id
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id)
if not account:
return jsonify({"error": "账号不存在"}), 404
if account.is_running:
return jsonify({"error": "账号正在运行中,请先停止"}), 400
data = request.json
new_password = data.get("password", "").strip()
data = _request_json()
new_password = str(data.get("password", "")).strip()
new_remember = data.get("remember", account.remember)
if not new_password:
@@ -147,7 +186,7 @@ def delete_account(account_id):
"""删除账号"""
user_id = current_user.id
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id)
if not account:
return jsonify({"error": "账号不存在"}), 404
@@ -159,7 +198,6 @@ def delete_account(account_id):
username = account.username
database.delete_account(account_id)
safe_remove_account(user_id, account_id)
log_to_client(f"删除账号: {username}", user_id)
@@ -196,12 +234,12 @@ def update_remark(account_id):
"""更新备注"""
user_id = current_user.id
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id)
if not account:
return jsonify({"error": "账号不存在"}), 404
data = request.json
remark = data.get("remark", "").strip()[:200]
data = _request_json()
remark = str(data.get("remark", "")).strip()[:200]
database.update_account_remark(account_id, remark)
@@ -217,17 +255,18 @@ def start_account(account_id):
"""启动账号任务"""
user_id = current_user.id
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id)
if not account:
return jsonify({"error": "账号不存在"}), 404
if account.is_running:
return jsonify({"error": "任务已在运行中"}), 400
data = request.json or {}
browse_type = validate_browse_type(data.get("browse_type"), default=BROWSE_TYPE_SHOULD_READ)
if not browse_type:
return jsonify({"error": "浏览类型无效"}), 400
data = _request_json()
browse_type, browse_error = _validate_browse_type_input(data.get("browse_type"), default=BROWSE_TYPE_SHOULD_READ)
if browse_error:
return browse_error
enable_screenshot = data.get("enable_screenshot", True)
ok, message = submit_account_task(
user_id=user_id,
@@ -249,7 +288,7 @@ def stop_account(account_id):
"""停止账号任务"""
user_id = current_user.id
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id)
if not account:
return jsonify({"error": "账号不存在"}), 404
@@ -259,20 +298,16 @@ def stop_account(account_id):
account.should_stop = True
account.status = "正在停止"
try:
scheduler = get_task_scheduler()
if scheduler.cancel_pending_task(user_id=user_id, account_id=account_id):
account.status = "已停止"
account.is_running = False
safe_remove_task_status(account_id)
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
log_to_client(f"任务已取消: {account.username}", user_id)
return jsonify({"success": True, "canceled": True})
except Exception:
pass
if _cancel_pending_account_task(user_id, account_id):
account.status = "已停止"
account.is_running = False
safe_remove_task_status(account_id)
_emit_account_update(user_id, account)
log_to_client(f"任务已取消: {account.username}", user_id)
return jsonify({"success": True, "canceled": True})
log_to_client(f"停止任务: {account.username}", user_id)
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
_emit_account_update(user_id, account)
return jsonify({"success": True})
@@ -283,23 +318,20 @@ def manual_screenshot(account_id):
"""手动为指定账号截图"""
user_id = current_user.id
account = safe_get_account(user_id, account_id)
if not account:
load_user_accounts(user_id)
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id, refresh_if_missing=True)
if not account:
return jsonify({"error": "账号不存在"}), 404
if account.is_running:
return jsonify({"error": "任务运行中,无法截图"}), 400
data = request.json or {}
data = _request_json()
requested_browse_type = data.get("browse_type", None)
if requested_browse_type is None:
browse_type = normalize_browse_type(account.last_browse_type)
else:
browse_type = validate_browse_type(requested_browse_type, default=BROWSE_TYPE_SHOULD_READ)
if not browse_type:
return jsonify({"error": "浏览类型无效"}), 400
browse_type, browse_error = _validate_browse_type_input(requested_browse_type, default=BROWSE_TYPE_SHOULD_READ)
if browse_error:
return browse_error
account.last_browse_type = browse_type
@@ -317,12 +349,16 @@ def manual_screenshot(account_id):
def batch_start_accounts():
"""批量启动账号"""
user_id = current_user.id
data = request.json or {}
data = _request_json()
account_ids = data.get("account_ids", [])
browse_type = validate_browse_type(data.get("browse_type", BROWSE_TYPE_SHOULD_READ), default=BROWSE_TYPE_SHOULD_READ)
if not browse_type:
return jsonify({"error": "浏览类型无效"}), 400
browse_type, browse_error = _validate_browse_type_input(
data.get("browse_type", BROWSE_TYPE_SHOULD_READ),
default=BROWSE_TYPE_SHOULD_READ,
)
if browse_error:
return browse_error
enable_screenshot = data.get("enable_screenshot", True)
if not account_ids:
@@ -331,11 +367,10 @@ def batch_start_accounts():
started = []
failed = []
if not safe_get_user_accounts_snapshot(user_id):
load_user_accounts(user_id)
_ensure_accounts_loaded(user_id)
for account_id in account_ids:
account = safe_get_account(user_id, account_id)
account = _get_user_account(user_id, account_id)
if not account:
failed.append({"id": account_id, "reason": "账号不存在"})
continue
@@ -357,7 +392,13 @@ def batch_start_accounts():
failed.append({"id": account_id, "reason": msg})
return jsonify(
{"success": True, "started_count": len(started), "failed_count": len(failed), "started": started, "failed": failed}
{
"success": True,
"started_count": len(started),
"failed_count": len(failed),
"started": started,
"failed": failed,
}
)
@@ -366,39 +407,29 @@ def batch_start_accounts():
def batch_stop_accounts():
"""批量停止账号"""
user_id = current_user.id
data = request.json
data = _request_json()
account_ids = data.get("account_ids", [])
if not account_ids:
return jsonify({"error": "请选择要停止的账号"}), 400
stopped = []
if not safe_get_user_accounts_snapshot(user_id):
load_user_accounts(user_id)
_ensure_accounts_loaded(user_id)
for account_id in account_ids:
account = safe_get_account(user_id, account_id)
if not account:
continue
if not account.is_running:
account = _get_user_account(user_id, account_id)
if (not account) or (not account.is_running):
continue
account.should_stop = True
account.status = "正在停止"
stopped.append(account_id)
try:
scheduler = get_task_scheduler()
if scheduler.cancel_pending_task(user_id=user_id, account_id=account_id):
account.status = "已停止"
account.is_running = False
safe_remove_task_status(account_id)
except Exception:
pass
if _cancel_pending_account_task(user_id, account_id):
account.status = "已停止"
account.is_running = False
safe_remove_task_status(account_id)
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
_emit_account_update(user_id, account)
return jsonify({"success": True, "stopped_count": len(stopped), "stopped": stopped})