fix: 修复flake8 lint检查错误
All checks were successful
continuous-integration/drone/push Build is passing

- 删除废弃的 admin_positions_backup.py 备份文件
- 修复 courses.py 缺失的 select 导入
- 修复 coze_gateway.py 异常变量作用域问题
- 修复 scheduler_service.py 无用的 global 声明
- 添加 TYPE_CHECKING 导入解决模型前向引用警告
This commit is contained in:
yuliang_guo
2026-01-31 17:43:39 +08:00
parent 18d6d5aff3
commit 41a2f7944a
6 changed files with 25 additions and 173 deletions

View File

@@ -1,158 +0,0 @@
# 此文件备份了admin.py中的positions相关路由代码
# 这些路由已移至positions.py为避免冲突从admin.py中移除
@router.get("/positions")
async def list_positions(
keyword: Optional[str] = Query(None, description="关键词"),
page: int = Query(1, ge=1),
pageSize: int = Query(20, ge=1, le=100),
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
"""
获取岗位列表stub 数据)
返回结构兼容前端data.list/total/page/pageSize
"""
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
try:
items = _sample_positions()
if keyword:
kw = keyword.lower()
items = [
p for p in items if kw in (p.get("name", "") + p.get("description", "")).lower()
]
total = len(items)
start = (page - 1) * pageSize
end = start + pageSize
page_items = items[start:end]
return ResponseModel(
code=200,
message="获取岗位列表成功",
data={
"list": page_items,
"total": total,
"page": page,
"pageSize": pageSize,
},
)
except Exception as exc:
# 记录错误堆栈由全局异常中间件处理;此处返回统一结构
return ResponseModel(code=500, message=f"服务器错误:{exc}")
@router.get("/positions/tree")
async def get_position_tree(
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
"""
获取岗位树stub 数据)
"""
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
try:
items = _sample_positions()
id_to_node: Dict[int, Dict[str, Any]] = {}
for p in items:
node = {**p, "children": []}
id_to_node[p["id"]] = node
roots: List[Dict[str, Any]] = []
for p in items:
parent_id = p.get("parentId")
if parent_id and parent_id in id_to_node:
id_to_node[parent_id]["children"].append(id_to_node[p["id"]])
else:
roots.append(id_to_node[p["id"]])
return ResponseModel(code=200, message="获取岗位树成功", data=roots)
except Exception as exc:
return ResponseModel(code=500, message=f"服务器错误:{exc}")
@router.get("/positions/{position_id}")
async def get_position_detail(
position_id: int,
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
items = _sample_positions()
for p in items:
if p["id"] == position_id:
return ResponseModel(code=200, message="获取岗位详情成功", data=p)
return ResponseModel(code=404, message="岗位不存在")
@router.get("/positions/{position_id}/check-delete")
async def check_position_delete(
position_id: int,
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
# stub允许删除非根岗位
deletable = position_id != 1
reason = "根岗位不允许删除" if not deletable else ""
return ResponseModel(code=200, message="检查成功", data={"deletable": deletable, "reason": reason})
@router.post("/positions")
async def create_position(
payload: Dict[str, Any],
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
# stub直接回显并附带一个伪ID
payload = dict(payload)
payload.setdefault("id", 999)
payload.setdefault("createTime", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
return ResponseModel(code=200, message="创建岗位成功", data=payload)
@router.put("/positions/{position_id}")
async def update_position(
position_id: int,
payload: Dict[str, Any],
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
# stub直接回显
updated = {"id": position_id, **payload}
return ResponseModel(code=200, message="更新岗位成功", data=updated)
@router.delete("/positions/{position_id}")
async def delete_position(
position_id: int,
current_user: User = Depends(get_current_user),
_db: AsyncSession = Depends(get_db),
) -> ResponseModel:
not_admin = _ensure_admin(current_user)
if not_admin:
return not_admin
# stub直接返回成功
return ResponseModel(code=200, message="删除岗位成功", data={"id": position_id})

View File

@@ -4,6 +4,7 @@
from typing import List, Optional from typing import List, Optional
from fastapi import APIRouter, Depends, Query, status, BackgroundTasks, Request from fastapi import APIRouter, Depends, Query, status, BackgroundTasks, Request
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from app.core.deps import get_db, get_current_user, require_admin, require_admin_or_manager, User from app.core.deps import get_db, get_current_user, require_admin, require_admin_or_manager, User

View File

@@ -203,25 +203,29 @@ async def send_message(request: SendMessageRequest, user=Depends(get_current_use
}, },
} }
except CozeException as e: except CozeException as coze_err:
logger.error(f"发送消息失败: {e}") logger.error(f"发送消息失败: {coze_err}")
if request.stream: if request.stream:
# 流式响应的错误处理 # 流式响应的错误处理 - 捕获异常信息避免闭包问题
err_code = coze_err.code
err_message = coze_err.message
err_details = coze_err.details
async def error_generator(): async def error_generator():
yield { yield {
"event": "error", "event": "error",
"data": { "data": {
"code": e.code, "code": err_code,
"message": e.message, "message": err_message,
"details": e.details, "details": err_details,
}, },
} }
return EventSourceResponse(error_generator()) return EventSourceResponse(error_generator())
else: else:
raise HTTPException( raise HTTPException(
status_code=e.status_code or 500, status_code=coze_err.status_code or 500,
detail={"code": e.code, "message": e.message, "details": e.details}, detail={"code": err_code, "message": err_message, "details": err_details},
) )
except Exception as e: except Exception as e:
logger.error(f"未知错误: {e}", exc_info=True) logger.error(f"未知错误: {e}", exc_info=True)

View File

@@ -2,9 +2,12 @@
课程相关数据库模型 课程相关数据库模型
""" """
from enum import Enum from enum import Enum
from typing import List, Optional from typing import List, Optional, TYPE_CHECKING
from datetime import datetime from datetime import datetime
if TYPE_CHECKING:
from app.models.growth_path import GrowthPathNode
from sqlalchemy import ( from sqlalchemy import (
String, String,
Text, Text,

View File

@@ -2,10 +2,14 @@
成长路径相关数据库模型 成长路径相关数据库模型
""" """
from enum import Enum from enum import Enum
from typing import List, Optional from typing import List, Optional, TYPE_CHECKING
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
if TYPE_CHECKING:
from app.models.course import Course
from app.models.user import User
from sqlalchemy import ( from sqlalchemy import (
String, String,
Text, Text,
@@ -84,7 +88,7 @@ class GrowthPathNode(BaseModel, SoftDeleteMixin):
) )
# 关联关系 # 关联关系
growth_path: Mapped["GrowthPath"] = relationship( growth_path: Mapped["GrowthPath"] = relationship( # noqa: F821
"GrowthPath", back_populates="nodes" "GrowthPath", back_populates="nodes"
) )
course: Mapped["Course"] = relationship("Course") course: Mapped["Course"] = relationship("Course")
@@ -146,7 +150,7 @@ class UserGrowthPathProgress(BaseModel):
# 关联关系 # 关联关系
user: Mapped["User"] = relationship("User") user: Mapped["User"] = relationship("User")
growth_path: Mapped["GrowthPath"] = relationship("GrowthPath") growth_path: Mapped["GrowthPath"] = relationship("GrowthPath") # noqa: F821
class UserNodeCompletion(BaseModel): class UserNodeCompletion(BaseModel):
@@ -203,4 +207,4 @@ class UserNodeCompletion(BaseModel):
node: Mapped["GrowthPathNode"] = relationship( node: Mapped["GrowthPathNode"] = relationship(
"GrowthPathNode", back_populates="user_completions" "GrowthPathNode", back_populates="user_completions"
) )
growth_path: Mapped["GrowthPath"] = relationship("GrowthPath") growth_path: Mapped["GrowthPath"] = relationship("GrowthPath") # noqa: F821

View File

@@ -261,8 +261,6 @@ def start_scheduler():
def stop_scheduler(): def stop_scheduler():
"""停止调度器""" """停止调度器"""
global scheduler
if scheduler and scheduler.running: if scheduler and scheduler.running:
scheduler.shutdown() scheduler.shutdown()
logger.info("定时任务调度器已停止") logger.info("定时任务调度器已停止")