feat: 添加历史记录相关端口

This commit is contained in:
DLmaster361
2025-08-14 16:31:49 +08:00
parent 1f5cf3acff
commit 2326cfcaa3
5 changed files with 146 additions and 8 deletions

View File

@@ -28,6 +28,7 @@ from .scripts import router as scripts_router
from .plan import router as plan_router
from .queue import router as queue_router
from .dispatch import router as dispatch_router
from .history import router as history_router
from .setting import router as setting_router
__all__ = [
@@ -36,5 +37,6 @@ __all__ = [
"plan_router",
"queue_router",
"dispatch_router",
"history_router",
"setting_router",
]

84
app/api/history.py Normal file
View File

@@ -0,0 +1,84 @@
# AUTO_MAA:A MAA Multi Account Management and Automation Tool
# Copyright © 2024-2025 DLmaster361
# Copyright © 2025 MoeSnowyFox
# This file is part of AUTO_MAA.
# AUTO_MAA is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
# AUTO_MAA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
# Contact: DLmaster_361@163.com
import datetime
from pathlib import Path
from fastapi import APIRouter, Body
from app.core import Config
from app.models.schema import *
router = APIRouter(prefix="/api/history", tags=["历史记录"])
@router.post(
"/search",
summary="搜索历史记录总览信息",
response_model=HistorySearchOut,
status_code=200,
)
async def search_history(history: HistorySearchIn) -> HistorySearchOut:
try:
data = await Config.search_history(
history.mode,
datetime.datetime.strptime(history.start_date, "%Y-%m-%d"),
datetime.datetime.strptime(history.end_date, "%Y-%m-%d"),
)
for date, users in data.items():
for user, records in users.items():
record = await Config.merge_statistic_info(records)
record["index"] = [HistoryIndexItem(**_) for _ in record["index"]]
record = HistoryData(**record)
data[date][user] = record
except Exception as e:
return HistorySearchOut(
code=500,
status="error",
message=f"{type(e).__name__}: {str(e)}",
data={},
)
return HistorySearchOut(data=data)
@router.post(
"/data",
summary="从指定文件内获取历史记录数据",
response_model=HistoryDataGetOut,
status_code=200,
)
async def get_history_data(history: HistoryDataGetIn = Body(...)) -> HistoryDataGetOut:
try:
path = Path(history.jsonPath)
data = await Config.merge_statistic_info([path])
data.pop("index", None)
data["log_content"] = path.with_suffix(".log").read_text(encoding="utf-8")
data = HistoryData(**data)
except Exception as e:
return HistoryDataGetOut(
code=500,
status="error",
message=f"{type(e).__name__}: {str(e)}",
data=HistoryData(**{}),
)
return HistoryDataGetOut(data=data)

View File

@@ -1552,7 +1552,7 @@ class AppConfig(GlobalConfig):
logger.success(f"通用日志统计完成,日志路径:{log_path.with_suffix('.log')}")
def merge_statistic_info(self, statistic_path_list: List[Path]) -> dict:
async def merge_statistic_info(self, statistic_path_list: List[Path]) -> dict:
"""
合并指定数据统计信息文件
@@ -1617,11 +1617,13 @@ class AppConfig(GlobalConfig):
single_data[key]
)
data["index"][actual_date] = [
actual_date.strftime("%d%H:%M:%S"),
("完成" if single_data[key] == "Success!" else "异常"),
json_file,
]
data["index"][actual_date] = {
"date": actual_date.strftime("%d%H:%M:%S"),
"status": (
"完成" if single_data[key] == "Success!" else "异常"
),
"jsonFile": str(json_file),
}
data["index"] = [data["index"][_] for _ in sorted(data["index"])]
@@ -1631,7 +1633,7 @@ class AppConfig(GlobalConfig):
return {k: v for k, v in data.items() if v}
def search_history(
async def search_history(
self, mode: str, start_date: datetime, end_date: datetime
) -> dict:
"""
@@ -1694,7 +1696,7 @@ class AppConfig(GlobalConfig):
for k, v in sorted(history_dict.items(), key=lambda x: x[0], reverse=True)
}
def clean_old_history(self):
async def clean_old_history(self):
"""删除超过用户设定天数的历史记录文件(基于目录日期)"""
if self.get("Function", "HistoryRetentionTime") == 0:

View File

@@ -407,6 +407,30 @@ class MaaPlanConfig(BaseModel):
Sunday: Optional[MaaPlanConfig_Item] = Field(None, description="周日")
class HistoryIndexItem(BaseModel):
date: str = Field(..., description="日期")
status: str = Field(..., description="状态")
jsonFile: str = Field(..., description="对应JSON文件")
class HistoryData(BaseModel):
index: Optional[List[HistoryIndexItem]] = Field(
None, description="历史记录索引列表"
)
recruit_statistics: Optional[Dict[str, int]] = Field(
None, description="公招统计数据, key为星级, value为对应的公招数量"
)
drop_statistics: Optional[Dict[str, Dict[str, int]]] = Field(
None, description="掉落统计数据, 格式为 { '关卡号': { '掉落物': 数量 } }"
)
error_info: Optional[Dict[str, str]] = Field(
None, description="报错信息, key为时间戳, value为错误描述"
)
log_content: Optional[str] = Field(
None, description="日志内容, 仅在提取单条历史记录数据时返回"
)
class ScriptCreateIn(BaseModel):
type: Literal["MAA", "General"] = Field(
..., description="脚本类型: MAA脚本, 通用脚本"
@@ -638,6 +662,29 @@ class TaskMessage(BaseModel):
data: Dict[str, Any] = Field(..., description="消息数据具体内容根据type类型而定")
class HistorySearchIn(BaseModel):
mode: Literal["按日合并", "按周合并", "按年月并"] = Field(
..., description="合并模式"
)
start_date: str = Field(..., description="开始日期, 格式YYYY-MM-DD")
end_date: str = Field(..., description="结束日期, 格式YYYY-MM-DD")
class HistorySearchOut(OutBase):
data: Dict[str, Dict[str, HistoryData]] = Field(
...,
description="历史记录索引数据字典, 格式为 { '日期': { '用户名': [历史记录信息] } }",
)
class HistoryDataGetIn(BaseModel):
jsonPath: str = Field(..., description="需要提取数据的历史记录JSON文件")
class HistoryDataGetOut(OutBase):
data: HistoryData = Field(..., description="历史记录数据")
class SettingGetOut(OutBase):
data: GlobalConfig = Field(..., description="全局设置数据")