Files
trade-assistant/backend/app/services/admin.py
T
TradeMate Dev 7b62c2f8b4 feat: 修复 H5 底部导航覆盖 + 更新项目进度文档
## H5 底部导航修复 (Bug #10)
- 精简 App.vue,移除重复 tabbar,仅保留全局样式
- uni-page 设置 height: calc(100% - 50px) + overflow-y: auto
- 内容区域精确停在底部导航上方,独立滚动不再叠加
- 恢复 custom-tab-bar 组件

## 项目进度文档
- PROGRESS.md 更新至 10 个 Bug 修复
- 新增 H5 底部导航修复记录
- 新增历史变更条目
2026-05-12 20:24:42 +08:00

130 lines
4.4 KiB
Python

from typing import Dict, Any, List
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_
from app.models.user import User
from app.models.team import Team, TeamMember
from app.models.analytics import UsageLog
from app.models.customer import Customer
from app.models.quotation import Quotation
from datetime import datetime, timedelta
import logging
logger = logging.getLogger(__name__)
class AdminService:
def __init__(self, db: AsyncSession):
self.db = db
async def get_dashboard(self) -> Dict[str, Any]:
now = datetime.utcnow()
today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
user_count = await self.db.execute(select(func.count(User.id)))
team_count = await self.db.execute(select(func.count(Team.id)))
customer_count = await self.db.execute(select(func.count(Customer.id)))
quotation_count = await self.db.execute(select(func.count(Quotation.id)))
today_logs = await self.db.execute(
select(func.count(UsageLog.id)).where(UsageLog.created_at >= today_start)
)
total_logs = await self.db.execute(select(func.count(UsageLog.id)))
recent_users_result = await self.db.execute(
select(User).order_by(User.created_at.desc()).limit(5)
)
recent_users = recent_users_result.scalars().all()
return {
"users": {
"total": user_count.scalar() or 0,
},
"teams": {
"total": team_count.scalar() or 0,
},
"customers": {
"total": customer_count.scalar() or 0,
},
"quotations": {
"total": quotation_count.scalar() or 0,
},
"usage": {
"today": today_logs.scalar() or 0,
"total": total_logs.scalar() or 0,
},
"recent_users": [
{
"id": str(u.id),
"username": u.username,
"tier": u.tier,
"is_active": u.is_active,
"created_at": u.created_at.isoformat() if u.created_at else None,
}
for u in recent_users
],
}
async def list_users(self, page: int = 1, size: int = 20) -> Dict[str, Any]:
query = select(User).order_by(User.created_at.desc()).offset((page - 1) * size).limit(size)
count_query = select(func.count(User.id))
total = await self.db.execute(count_query)
result = await self.db.execute(query)
users = result.scalars().all()
return {
"items": [
{
"id": str(u.id),
"username": u.username,
"phone": u.phone,
"tier": u.tier,
"is_active": u.is_active,
"created_at": u.created_at.isoformat() if u.created_at else None,
}
for u in users
],
"total": total.scalar(),
"page": page,
"size": size,
}
async def update_user_tier(self, user_id: str, tier: str) -> bool:
result = await self.db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
return False
user.tier = tier
await self.db.flush()
return True
async def toggle_user_active(self, user_id: str) -> bool:
result = await self.db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
return False
user.is_active = not user.is_active
await self.db.flush()
return True
async def get_system_health(self) -> Dict[str, Any]:
return {
"status": "healthy",
"version": "1.0.0",
"timestamp": datetime.utcnow().isoformat(),
}
async def log_usage(self, user_id: str, action: str, detail: Dict = None, ip: str = None, ua: str = None):
try:
log = UsageLog(
user_id=user_id,
action=action,
detail=detail or {},
ip_address=ip,
user_agent=ua,
)
self.db.add(log)
await self.db.flush()
except Exception as e:
logger.warning(f"Failed to log usage: {e}")