imetting_backend/app/api/endpoints/client_downloads.py

406 lines
13 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()
2025-12-11 08:48:12 +00:00
@router.get("/clients", response_model=dict)
2025-10-21 09:28:52 +00:00
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)}"
)
2025-12-11 08:48:12 +00:00
@router.get("/clients/latest", response_model=dict)
2025-10-21 09:28:52 +00:00
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 = []
2025-12-11 08:48:12 +00:00
terminal_clients = []
2025-10-21 09:28:52 +00:00
for client in clients:
if client['platform_type'] == 'mobile':
mobile_clients.append(client)
2025-12-11 08:48:12 +00:00
elif client['platform_type'] == 'desktop':
2025-10-21 09:28:52 +00:00
desktop_clients.append(client)
2025-12-11 08:48:12 +00:00
elif client['platform_type'] == 'terminal':
terminal_clients.append(client)
2025-10-21 09:28:52 +00:00
return create_api_response(
code="200",
message="获取成功",
data={
"mobile": mobile_clients,
2025-12-11 08:48:12 +00:00
"desktop": desktop_clients,
"terminal": terminal_clients
2025-10-21 09:28:52 +00:00
}
)
except Exception as e:
return create_api_response(
code="500",
message=f"获取最新客户端失败: {str(e)}"
)
2025-12-11 08:48:12 +00:00
@router.get("/clients/latest/by-platform", response_model=dict)
async def get_latest_version_by_platform_type_and_name(
platform_type: str,
platform_name: str
):
2025-10-21 09:28:52 +00:00
"""
2025-12-11 08:48:12 +00:00
通过平台类型和平台名称获取最新版本公开接口用于客户端版本检查
参数
platform_type: 平台类型 (mobile, desktop, terminal)
platform_name: 具体平台 (ios, android, windows, mac_intel, mac_m, linux, mcu)
2025-10-21 09:28:52 +00:00
"""
try:
with get_db_connection() as conn:
cursor = conn.cursor(dictionary=True)
query = """
SELECT * FROM client_downloads
2025-12-11 08:48:12 +00:00
WHERE platform_type = %s
AND platform_name = %s
AND is_active = TRUE
AND is_latest = TRUE
2025-10-21 09:28:52 +00:00
LIMIT 1
"""
2025-12-11 08:48:12 +00:00
cursor.execute(query, (platform_type, platform_name))
2025-10-21 09:28:52 +00:00
client = cursor.fetchone()
cursor.close()
if not client:
return create_api_response(
code="404",
2025-12-11 08:48:12 +00:00
message=f"未找到平台类型 {platform_type} 下的 {platform_name} 客户端"
2025-10-21 09:28:52 +00:00
)
return create_api_response(
code="200",
message="获取成功",
data=client
)
except Exception as e:
return create_api_response(
code="500",
message=f"获取客户端版本失败: {str(e)}"
)
2025-12-11 08:48:12 +00:00
@router.get("/clients/{id}", response_model=dict)
2025-10-21 09:28:52 +00:00
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)}"
)
2025-12-11 08:48:12 +00:00
@router.post("/clients", response_model=dict)
2025-10-21 09:28:52 +00:00
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)}"
)
2025-12-11 08:48:12 +00:00
@router.put("/clients/{id}", response_model=dict)
2025-10-21 09:28:52 +00:00
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)}"
)
2025-12-11 08:48:12 +00:00
@router.delete("/clients/{id}", response_model=dict)
2025-10-21 09:28:52 +00:00
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)}"
)