perf:优化webui配置展示,优化log显示,修复表达审核
This commit is contained in:
@@ -78,7 +78,7 @@ class ChatManager:
|
||||
"""初始化聊天管理器"""
|
||||
try:
|
||||
await self.load_all_sessions_from_db()
|
||||
logger.info(f"已加载 {len(self.sessions)} 个会话记录到内存中")
|
||||
logger.debug(f"已加载 {len(self.sessions)} 个会话记录到内存中")
|
||||
except Exception as e:
|
||||
logger.error(f"初始化聊天管理器出现错误: {e}")
|
||||
|
||||
|
||||
@@ -829,20 +829,19 @@ def initialize_logging(verbose: bool = True):
|
||||
reconfigure_existing_loggers()
|
||||
|
||||
# 启动日志清理任务
|
||||
start_log_cleanup_task(verbose=verbose)
|
||||
start_log_cleanup_task()
|
||||
|
||||
# 只在 verbose=True 时输出详细的初始化信息
|
||||
if verbose:
|
||||
logger = get_logger("logger")
|
||||
console_level = LOG_CONFIG.get("console_log_level", LOG_CONFIG.get("log_level", "INFO"))
|
||||
file_level = LOG_CONFIG.get("file_log_level", LOG_CONFIG.get("log_level", "INFO"))
|
||||
|
||||
logger.info("日志系统已初始化:")
|
||||
logger.info(f" - 控制台级别: {console_level}")
|
||||
logger.info(f" - 文件级别: {file_level}")
|
||||
max_log_files = max(1, int(LOG_CONFIG.get("max_log_files", 30) or 30))
|
||||
log_cleanup_days = max(1, int(LOG_CONFIG.get("log_cleanup_days", 30) or 30))
|
||||
logger.info(f" - 轮转份数: {max_log_files}个文件|自动清理: {log_cleanup_days}天前的日志")
|
||||
logger.info(
|
||||
f"日志系统已初始化:控制台={console_level},文件={file_level},"
|
||||
f"轮转={max_log_files}个文件,清理={log_cleanup_days}天前"
|
||||
)
|
||||
|
||||
|
||||
def cleanup_old_logs():
|
||||
@@ -875,12 +874,8 @@ def cleanup_old_logs():
|
||||
logger.error(f"清理旧日志文件时出错: {e}")
|
||||
|
||||
|
||||
def start_log_cleanup_task(verbose: bool = True):
|
||||
"""启动日志清理任务
|
||||
|
||||
Args:
|
||||
verbose: 是否输出启动信息。默认为 True。
|
||||
"""
|
||||
def start_log_cleanup_task():
|
||||
"""启动日志清理任务"""
|
||||
global _cleanup_task_started
|
||||
|
||||
# 防止重复启动清理任务
|
||||
@@ -897,12 +892,6 @@ def start_log_cleanup_task(verbose: bool = True):
|
||||
cleanup_thread = threading.Thread(target=cleanup_task, daemon=True)
|
||||
cleanup_thread.start()
|
||||
|
||||
if verbose:
|
||||
logger = get_logger("logger")
|
||||
max_log_files = max(1, int(LOG_CONFIG.get("max_log_files", 30) or 30))
|
||||
log_cleanup_days = max(1, int(LOG_CONFIG.get("log_cleanup_days", 30) or 30))
|
||||
logger.info(f"已启动日志清理任务,将自动清理{log_cleanup_days}天前的日志文件(轮转份数限制: {max_log_files}个文件)")
|
||||
|
||||
|
||||
def shutdown_logging():
|
||||
"""优雅关闭日志系统,释放所有文件句柄"""
|
||||
|
||||
@@ -40,6 +40,7 @@ class BotConfig(ConfigBase):
|
||||
"x-icon": "wifi",
|
||||
"x-layout": "inline-right",
|
||||
"x-input-width": "12rem",
|
||||
"x-row": "bot-platform-account",
|
||||
},
|
||||
)
|
||||
"""平台"""
|
||||
@@ -51,6 +52,7 @@ class BotConfig(ConfigBase):
|
||||
"x-icon": "user",
|
||||
"x-layout": "inline-right",
|
||||
"x-input-width": "12rem",
|
||||
"x-row": "bot-platform-account",
|
||||
},
|
||||
)
|
||||
"""QQ账号"""
|
||||
|
||||
@@ -134,7 +134,7 @@ def _setup_anti_crawler(app: FastAPI):
|
||||
"basic": t("startup.webui_anti_crawler_mode_basic"),
|
||||
}
|
||||
mode_desc = mode_descriptions.get(anti_crawler_mode, t("startup.webui_anti_crawler_mode_basic"))
|
||||
logger.info(t("startup.webui_anti_crawler_configured", mode_desc=mode_desc))
|
||||
logger.debug(t("startup.webui_anti_crawler_configured", mode_desc=mode_desc))
|
||||
except Exception as e:
|
||||
logger.error(t("startup.webui_anti_crawler_config_failed", error=e), exc_info=True)
|
||||
|
||||
@@ -159,7 +159,7 @@ def _register_api_routes(app: FastAPI):
|
||||
for router in get_all_routers():
|
||||
app.include_router(router)
|
||||
|
||||
logger.info(t("startup.webui_api_routes_registered"))
|
||||
logger.debug(t("startup.webui_api_routes_registered"))
|
||||
except Exception as e:
|
||||
logger.error(t("startup.webui_api_routes_register_failed", error=e), exc_info=True)
|
||||
|
||||
@@ -217,7 +217,7 @@ def _setup_static_files(app: FastAPI):
|
||||
response.headers["X-Robots-Tag"] = "noindex, nofollow, noarchive"
|
||||
return response
|
||||
|
||||
logger.info(t("startup.webui_static_files_configured", static_path=static_path))
|
||||
logger.debug(t("startup.webui_static_files_configured", static_path=static_path))
|
||||
|
||||
|
||||
def _resolve_static_path() -> Path | None:
|
||||
@@ -247,6 +247,5 @@ def show_access_token():
|
||||
token_manager = get_token_manager()
|
||||
current_token = token_manager.get_token()
|
||||
logger.info(t("startup.webui_access_token", token=current_token))
|
||||
logger.info(t("startup.webui_access_token_login_hint"))
|
||||
except Exception as e:
|
||||
logger.error(t("startup.webui_access_token_failed", error=e))
|
||||
|
||||
@@ -15,6 +15,7 @@ from src.common.logger import get_logger
|
||||
from src.webui.dependencies import require_auth
|
||||
|
||||
logger = get_logger("webui.expression")
|
||||
EXCLUDE_IDS_QUERY = Query(None, description="需要排除的表达方式 ID")
|
||||
|
||||
# 创建路由器
|
||||
router = APIRouter(prefix="/expression", tags=["Expression"], dependencies=[Depends(require_auth)])
|
||||
@@ -660,8 +661,10 @@ async def get_review_list(
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
|
||||
filter_type: str = Query("unchecked", description="筛选类型: unchecked/passed/rejected/all"),
|
||||
order: str = Query("latest", description="排序方式: latest/random"),
|
||||
search: Optional[str] = Query(None, description="搜索关键词"),
|
||||
chat_id: Optional[str] = Query(None, description="聊天ID筛选"),
|
||||
exclude_ids: Optional[List[int]] = EXCLUDE_IDS_QUERY,
|
||||
) -> ReviewListResponse:
|
||||
"""获取待审核或已审核的表达方式列表。
|
||||
|
||||
@@ -669,8 +672,10 @@ async def get_review_list(
|
||||
page: 页码。
|
||||
page_size: 每页数量。
|
||||
filter_type: 筛选类型,可选 unchecked、passed、rejected 或 all。
|
||||
order: 排序方式,可选 latest 或 random。
|
||||
search: 搜索关键词。
|
||||
chat_id: 聊天 ID 筛选条件。
|
||||
exclude_ids: 需要排除的表达方式 ID。
|
||||
|
||||
Returns:
|
||||
ReviewListResponse: 审核列表响应。
|
||||
@@ -689,11 +694,17 @@ async def get_review_list(
|
||||
if chat_id:
|
||||
statement = statement.where(col(Expression.session_id) == chat_id)
|
||||
|
||||
# 排序:创建时间倒序
|
||||
statement = statement.order_by(
|
||||
case((col(Expression.create_time).is_(None), 1), else_=0),
|
||||
col(Expression.create_time).desc(),
|
||||
)
|
||||
if exclude_ids:
|
||||
statement = statement.where(~col(Expression.id).in_(exclude_ids))
|
||||
|
||||
if order == "random":
|
||||
statement = statement.order_by(func.random())
|
||||
else:
|
||||
# 排序:创建时间倒序
|
||||
statement = statement.order_by(
|
||||
case((col(Expression.create_time).is_(None), 1), else_=0),
|
||||
col(Expression.create_time).desc(),
|
||||
)
|
||||
|
||||
offset = (page - 1) * page_size
|
||||
statement = statement.offset(offset).limit(page_size)
|
||||
@@ -731,7 +742,7 @@ class BatchReviewItem(BaseModel):
|
||||
|
||||
id: int
|
||||
rejected: bool
|
||||
require_unchecked: bool = True # 默认要求未检查状态
|
||||
require_unchecked: bool = True # 前端保留的来源标记,人工审核提交时不再阻断覆盖
|
||||
|
||||
|
||||
class BatchReviewRequest(BaseModel):
|
||||
@@ -790,14 +801,6 @@ async def batch_review_expressions(
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
# 冲突检测:未审核列表发起的操作只允许处理仍处于未审核状态的条目。
|
||||
if item.require_unchecked and expression.checked:
|
||||
results.append(
|
||||
BatchReviewResultItem(id=item.id, success=False, message="该表达方式已被审核,请刷新列表后重试")
|
||||
)
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
# 更新状态
|
||||
with get_db_session() as session:
|
||||
db_expression = session.exec(
|
||||
|
||||
Reference in New Issue
Block a user