203 lines
6.8 KiB
Python
203 lines
6.8 KiB
Python
"""
|
|
主播服务
|
|
"""
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy import and_, desc, func
|
|
from typing import List, Optional, Dict, Any
|
|
from ..models.streamer import StreamerProfile, StreamerStatus
|
|
from ..models.user import User, UserRole
|
|
from ..models.game import Chest
|
|
from ..schemas.streamer import (
|
|
StreamerProfileCreate,
|
|
StreamerProfileUpdate,
|
|
StreamerStatistics,
|
|
StreamerChestList,
|
|
StreamerBetRecord
|
|
)
|
|
|
|
|
|
class StreamerService:
|
|
"""主播服务"""
|
|
|
|
@staticmethod
|
|
def create_streamer_profile(db: Session, streamer_data: StreamerProfileCreate) -> StreamerProfile:
|
|
"""创建主播配置"""
|
|
# 检查用户是否存在且角色为主播
|
|
user = db.query(User).filter(User.id == streamer_data.user_id).first()
|
|
if not user:
|
|
raise ValueError("用户不存在")
|
|
|
|
if user.role != UserRole.STREAMER:
|
|
raise ValueError("用户不是主播角色")
|
|
|
|
# 检查是否已存在配置
|
|
existing = db.query(StreamerProfile).filter(StreamerProfile.user_id == streamer_data.user_id).first()
|
|
if existing:
|
|
raise ValueError("主播配置已存在")
|
|
|
|
db_streamer = StreamerProfile(**streamer_data.dict())
|
|
db.add(db_streamer)
|
|
db.commit()
|
|
db.refresh(db_streamer)
|
|
return db_streamer
|
|
|
|
@staticmethod
|
|
def get_streamer_profile(db: Session, streamer_id: int) -> Optional[StreamerProfile]:
|
|
"""获取主播配置"""
|
|
return db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
|
|
@staticmethod
|
|
def get_streamer_by_user_id(db: Session, user_id: int) -> Optional[StreamerProfile]:
|
|
"""根据用户ID获取主播配置"""
|
|
return db.query(StreamerProfile).filter(StreamerProfile.user_id == user_id).first()
|
|
|
|
@staticmethod
|
|
def update_streamer_profile(
|
|
db: Session,
|
|
streamer: StreamerProfile,
|
|
streamer_data: StreamerProfileUpdate
|
|
) -> StreamerProfile:
|
|
"""更新主播配置"""
|
|
update_data = streamer_data.dict(exclude_unset=True)
|
|
for field, value in update_data.items():
|
|
setattr(streamer, field, value)
|
|
|
|
db.commit()
|
|
db.refresh(streamer)
|
|
return streamer
|
|
|
|
@staticmethod
|
|
def get_streamer_list(
|
|
db: Session,
|
|
skip: int = 0,
|
|
limit: int = 20,
|
|
status: Optional[str] = None,
|
|
sort_by: str = "created_at",
|
|
order: str = "desc"
|
|
) -> List[StreamerProfile]:
|
|
"""获取主播列表"""
|
|
query = db.query(StreamerProfile)
|
|
|
|
if status:
|
|
query = query.filter(StreamerProfile.status == status)
|
|
|
|
# 排序
|
|
if order.lower() == "desc":
|
|
query = query.order_by(desc(getattr(StreamerProfile, sort_by)))
|
|
else:
|
|
query = query.order_by(getattr(StreamerProfile, sort_by))
|
|
|
|
return query.offset(skip).limit(limit).all()
|
|
|
|
@staticmethod
|
|
def get_streamer_statistics(db: Session, streamer_id: int) -> StreamerStatistics:
|
|
"""获取主播统计信息"""
|
|
streamer = db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
if not streamer:
|
|
raise ValueError("主播不存在")
|
|
|
|
# 统计宝箱信息
|
|
total_chests = db.query(func.count(Chest.id)).filter(
|
|
Chest.streamer_id == streamer.user_id
|
|
).scalar() or 0
|
|
|
|
active_chests = db.query(func.count(Chest.id)).filter(
|
|
Chest.streamer_id == streamer.user_id,
|
|
Chest.status == "下注中"
|
|
).scalar() or 0
|
|
|
|
# 计算总获奖(需要根据实际业务逻辑)
|
|
total_winnings = 0
|
|
total_commission = int(total_winnings * float(streamer.commission_rate) / 100)
|
|
|
|
# 计算平均宝箱价值
|
|
average_chest_value = int(total_winnings / total_chests) if total_chests > 0 else 0
|
|
|
|
# 计算成功率(这里简化处理)
|
|
success_rate = 0.75 # 示例值
|
|
|
|
return StreamerStatistics(
|
|
total_chests=total_chests,
|
|
active_chests=active_chests,
|
|
total_winnings=total_winnings,
|
|
total_commission=total_commission,
|
|
average_chest_value=average_chest_value,
|
|
success_rate=success_rate
|
|
)
|
|
|
|
@staticmethod
|
|
def get_streamer_chests(
|
|
db: Session,
|
|
streamer_id: int,
|
|
skip: int = 0,
|
|
limit: int = 20,
|
|
status: Optional[str] = None
|
|
) -> List[StreamerChestList]:
|
|
"""获取主播宝箱列表"""
|
|
streamer = db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
if not streamer:
|
|
raise ValueError("主播不存在")
|
|
|
|
query = db.query(Chest).filter(Chest.streamer_id == streamer.user_id)
|
|
|
|
if status:
|
|
query = query.filter(Chest.status == status)
|
|
|
|
chests = query.order_by(desc(Chest.created_at)).offset(skip).limit(limit).all()
|
|
|
|
return [StreamerChestList.from_orm(chest) for chest in chests]
|
|
|
|
@staticmethod
|
|
def suspend_streamer(db: Session, streamer_id: int, reason: str = None) -> bool:
|
|
"""暂停主播"""
|
|
streamer = db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
if not streamer:
|
|
raise ValueError("主播不存在")
|
|
|
|
streamer.status = StreamerStatus.SUSPENDED
|
|
db.commit()
|
|
return True
|
|
|
|
@staticmethod
|
|
def activate_streamer(db: Session, streamer_id: int) -> bool:
|
|
"""激活主播"""
|
|
streamer = db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
if not streamer:
|
|
raise ValueError("主播不存在")
|
|
|
|
streamer.status = StreamerStatus.ACTIVE
|
|
db.commit()
|
|
return True
|
|
|
|
@staticmethod
|
|
def ban_streamer(db: Session, streamer_id: int, reason: str = None) -> bool:
|
|
"""封禁主播"""
|
|
streamer = db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
if not streamer:
|
|
raise ValueError("主播不存在")
|
|
|
|
streamer.status = StreamerStatus.BANNED
|
|
db.commit()
|
|
return True
|
|
|
|
@staticmethod
|
|
def check_streamer_chest_limit(db: Session, streamer_id: int) -> Dict[str, Any]:
|
|
"""检查主播宝箱数量限制"""
|
|
streamer = db.query(StreamerProfile).filter(StreamerProfile.id == streamer_id).first()
|
|
if not streamer:
|
|
raise ValueError("主播不存在")
|
|
|
|
active_chests = db.query(func.count(Chest.id)).filter(
|
|
Chest.streamer_id == streamer.user_id,
|
|
Chest.status == "下注中"
|
|
).scalar() or 0
|
|
|
|
max_chests = streamer.max_active_chests
|
|
|
|
return {
|
|
"active_chests": active_chests,
|
|
"max_chests": max_chests,
|
|
"can_create": active_chests < max_chests,
|
|
"remaining": max_chests - active_chests
|
|
}
|