初始化 HyperNode-AI 控制面。
包含节点账本、每日清算,以及 Ubuntu 交互式部署脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
"""用户与节点登记。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.clock import add_months, utcnow
|
||||
from app.config import settings
|
||||
from app.errors import AppError
|
||||
from app.models import ComputeNode, NodeStatus, User
|
||||
from app.money import money
|
||||
from app.services.common import get_user_by_wallet
|
||||
|
||||
|
||||
def register_user(session: Session, wallet_address: str) -> User:
|
||||
wallet = wallet_address.strip()
|
||||
if session.scalar(select(User).where(User.wallet_address == wallet)) is not None:
|
||||
raise AppError("钱包地址已注册", 409)
|
||||
user = User(wallet_address=wallet, created_at=utcnow())
|
||||
session.add(user)
|
||||
try:
|
||||
session.flush()
|
||||
except IntegrityError as exc:
|
||||
session.rollback()
|
||||
raise AppError("钱包地址已注册", 409) from exc
|
||||
return user
|
||||
|
||||
|
||||
def register_node(
|
||||
session: Session,
|
||||
wallet_address: str,
|
||||
sn: str,
|
||||
purchase_amount: Decimal,
|
||||
callback_url: str | None = None,
|
||||
) -> ComputeNode:
|
||||
user = get_user_by_wallet(session, wallet_address.strip())
|
||||
serial = sn.strip()
|
||||
if session.scalar(select(ComputeNode).where(ComputeNode.sn == serial)) is not None:
|
||||
raise AppError("节点序列号已存在", 409)
|
||||
callback = _normalize_callback(callback_url)
|
||||
started = utcnow()
|
||||
node = ComputeNode(
|
||||
user_id=user.id,
|
||||
sn=serial,
|
||||
purchase_amount=money(purchase_amount),
|
||||
license_months=settings.license_months,
|
||||
licensed_at=started,
|
||||
license_expires_at=add_months(started, settings.license_months),
|
||||
status=NodeStatus.OFFLINE,
|
||||
callback_url=callback,
|
||||
created_at=started,
|
||||
updated_at=started,
|
||||
)
|
||||
session.add(node)
|
||||
try:
|
||||
session.flush()
|
||||
except IntegrityError as exc:
|
||||
session.rollback()
|
||||
raise AppError("节点序列号已存在", 409) from exc
|
||||
return node
|
||||
|
||||
|
||||
def _normalize_callback(callback_url: str | None) -> str | None:
|
||||
if callback_url is None or callback_url.strip() == "":
|
||||
return None
|
||||
parsed = urlparse(callback_url.strip())
|
||||
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
|
||||
raise AppError("callback_url 必须是 http 或 https 地址")
|
||||
return callback_url.strip()
|
||||
Reference in New Issue
Block a user