imetting_backend/app/api/endpoints/client_downloads.py

392 lines
12 KiB
Python
Raw Normal View History

2025-10-21 09:28:52 +00:00
from fastapi import APIRouter, HTTPException, Depends
from app.models.models import (
ClientDownload,
CreateClientDownloadRequest,
UpdateClientDownloadRequest,
ClientDownloadListResponse
)
from app.core.database import get_db_connection
from app.core.auth import get_current_user, get_current_admin_user
from app.core.response import create_api_response
from typing import Optional
router = APIRouter()
@router.get("/downloads", response_model=dict)
async def get_client_downloads(
platform_type: Optional[str] = None,
platform_name: Optional[str] = None,
is_active: Optional[bool] = None,
page: int = 1,
size: int = 50
):
"""
获取客户端下载列表公开接口所有用户可访问
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor(dictionary=True)
# 构建查询条件
where_clauses = []
params = []
if platform_type:
where_clauses.append("platform_type = %s")
params.append(platform_type)
if platform_name:
where_clauses.append("platform_name = %s")
params.append(platform_name)
if is_active is not None:
where_clauses.append("is_active = %s")
params.append(is_active)
where_clause = " AND ".join(where_clauses) if where_clauses else "1=1"
# 获取总数
count_query = f"SELECT COUNT(*) as total FROM client_downloads WHERE {where_clause}"
cursor.execute(count_query, params)
total = cursor.fetchone()['total']
# 获取列表数据
offset = (page - 1) * size
list_query = f"""
SELECT * FROM client_downloads
WHERE {where_clause}
ORDER BY platform_type, platform_name, version_code DESC
LIMIT %s OFFSET %s
"""
cursor.execute(list_query, params + [size, offset])
clients = cursor.fetchall()
cursor.close()
return create_api_response(
code="200",
message="获取成功",
data={
"clients": clients,
"total": total,
"page": page,
"size": size
}
)
except Exception as e:
return create_api_response(
code="500",
message=f"获取客户端下载列表失败: {str(e)}"
)
@router.get("/downloads/latest", response_model=dict)
async def get_latest_clients():
"""
获取所有平台的最新版本客户端公开接口用于首页下载
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor(dictionary=True)
query = """
SELECT * FROM client_downloads
WHERE is_active = TRUE AND is_latest = TRUE
ORDER BY platform_type, platform_name
"""
cursor.execute(query)
clients = cursor.fetchall()
cursor.close()
# 按平台类型分组
mobile_clients = []
desktop_clients = []
for client in clients:
if client['platform_type'] == 'mobile':
mobile_clients.append(client)
else:
desktop_clients.append(client)
return create_api_response(
code="200",
message="获取成功",
data={
"mobile": mobile_clients,
"desktop": desktop_clients
}
)
except Exception as e:
return create_api_response(
code="500",
message=f"获取最新客户端失败: {str(e)}"
)
@router.get("/downloads/{platform_name}/latest", response_model=dict)
async def get_latest_version_by_platform(platform_name: str):
"""
获取指定平台的最新版本公开接口用于客户端版本检查
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor(dictionary=True)
query = """
SELECT * FROM client_downloads
WHERE platform_name = %s AND is_active = TRUE AND is_latest = TRUE
LIMIT 1
"""
cursor.execute(query, (platform_name,))
client = cursor.fetchone()
cursor.close()
if not client:
return create_api_response(
code="404",
message=f"未找到平台 {platform_name} 的客户端"
)
return create_api_response(
code="200",
message="获取成功",
data=client
)
except Exception as e:
return create_api_response(
code="500",
message=f"获取客户端版本失败: {str(e)}"
)
@router.get("/downloads/{id}", response_model=dict)
async def get_client_download_by_id(id: int):
"""
获取指定ID的客户端详情公开接口
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor(dictionary=True)
query = "SELECT * FROM client_downloads WHERE id = %s"
cursor.execute(query, (id,))
client = cursor.fetchone()
cursor.close()
if not client:
return create_api_response(
code="404",
message="客户端不存在"
)
return create_api_response(
code="200",
message="获取成功",
data=client
)
except Exception as e:
return create_api_response(
code="500",
message=f"获取客户端详情失败: {str(e)}"
)
@router.post("/downloads", response_model=dict)
async def create_client_download(
request: CreateClientDownloadRequest,
current_user: dict = Depends(get_current_admin_user)
):
"""
创建新的客户端版本仅管理员
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor()
# 如果设置为最新版本,先将同平台的其他版本设为非最新
if request.is_latest:
update_query = """
UPDATE client_downloads
SET is_latest = FALSE
WHERE platform_name = %s
"""
cursor.execute(update_query, (request.platform_name,))
# 插入新版本
insert_query = """
INSERT INTO client_downloads (
platform_type, platform_name, version, version_code,
download_url, file_size, release_notes, is_active,
is_latest, min_system_version, created_by
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
cursor.execute(insert_query, (
request.platform_type,
request.platform_name,
request.version,
request.version_code,
request.download_url,
request.file_size,
request.release_notes,
request.is_active,
request.is_latest,
request.min_system_version,
current_user['user_id']
))
new_id = cursor.lastrowid
conn.commit()
cursor.close()
return create_api_response(
code="200",
message="客户端版本创建成功",
data={"id": new_id}
)
except Exception as e:
return create_api_response(
code="500",
message=f"创建客户端版本失败: {str(e)}"
)
@router.put("/downloads/{id}", response_model=dict)
async def update_client_download(
id: int,
request: UpdateClientDownloadRequest,
current_user: dict = Depends(get_current_admin_user)
):
"""
更新客户端版本信息仅管理员
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor(dictionary=True)
# 检查客户端是否存在
cursor.execute("SELECT * FROM client_downloads WHERE id = %s", (id,))
existing = cursor.fetchone()
if not existing:
cursor.close()
return create_api_response(
code="404",
message="客户端不存在"
)
# 如果设置为最新版本,先将同平台的其他版本设为非最新
if request.is_latest:
update_query = """
UPDATE client_downloads
SET is_latest = FALSE
WHERE platform_name = %s AND id != %s
"""
cursor.execute(update_query, (existing['platform_name'], id))
# 构建更新语句
update_fields = []
params = []
if request.version is not None:
update_fields.append("version = %s")
params.append(request.version)
if request.version_code is not None:
update_fields.append("version_code = %s")
params.append(request.version_code)
if request.download_url is not None:
update_fields.append("download_url = %s")
params.append(request.download_url)
if request.file_size is not None:
update_fields.append("file_size = %s")
params.append(request.file_size)
if request.release_notes is not None:
update_fields.append("release_notes = %s")
params.append(request.release_notes)
if request.is_active is not None:
update_fields.append("is_active = %s")
params.append(request.is_active)
if request.is_latest is not None:
update_fields.append("is_latest = %s")
params.append(request.is_latest)
if request.min_system_version is not None:
update_fields.append("min_system_version = %s")
params.append(request.min_system_version)
if not update_fields:
cursor.close()
return create_api_response(
code="400",
message="没有要更新的字段"
)
# 执行更新
update_query = f"""
UPDATE client_downloads
SET {', '.join(update_fields)}
WHERE id = %s
"""
params.append(id)
cursor.execute(update_query, params)
conn.commit()
cursor.close()
return create_api_response(
code="200",
message="客户端版本更新成功"
)
except Exception as e:
return create_api_response(
code="500",
message=f"更新客户端版本失败: {str(e)}"
)
@router.delete("/downloads/{id}", response_model=dict)
async def delete_client_download(
id: int,
current_user: dict = Depends(get_current_admin_user)
):
"""
删除客户端版本仅管理员
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor()
# 检查是否存在
cursor.execute("SELECT * FROM client_downloads WHERE id = %s", (id,))
if not cursor.fetchone():
cursor.close()
return create_api_response(
code="404",
message="客户端不存在"
)
# 执行删除
cursor.execute("DELETE FROM client_downloads WHERE id = %s", (id,))
conn.commit()
cursor.close()
return create_api_response(
code="200",
message="客户端版本删除成功"
)
except Exception as e:
return create_api_response(
code="500",
message=f"删除客户端版本失败: {str(e)}"
)