图片更新

This commit is contained in:
2025-11-27 02:01:51 +08:00
parent 039c10bd7b
commit 3fbaef6878
3 changed files with 168 additions and 51 deletions
+156 -49
View File
@@ -8,9 +8,17 @@ from api.dp import RedisDep
import re import re
from typing import Annotated from typing import Annotated
from api.types.open import SkillDataSummaryResponse, SkillDetailResponse, SkillsListResponse, SearchSkillResponse from api.types.open import (
JobInfoResponse,
SkillDataSummaryResponse,
SkillDetailResponse,
SkillsListResponse,
SearchSkillResponse,
)
import os import os
from core.character.adventure import get_adv_list
router = APIRouter() router = APIRouter()
register_gzip_request(router) register_gzip_request(router)
@@ -18,47 +26,98 @@ register_gzip_request(router)
def replace_placeholders(template): def replace_placeholders(template):
# 匹配 <int>、<float>、<float1>、<float2> 等 # 匹配 <int>、<float>、<float1>、<float2> 等
pattern = re.compile(r'<(int|float\d*)>') pattern = re.compile(r"<(int|float\d*)>")
idx = 0 idx = 0
def repl(match): def repl(match):
nonlocal idx nonlocal idx
idx += 1 idx += 1
return f'{{value{idx}}}' return f"{{value{idx}}}"
return pattern.sub(repl, template) return pattern.sub(repl, template)
@router.get('/skills/', operation_id='skillsList') @router.get("/skills/", operation_id="skillsList")
async def get_skills_list(redis: RedisDep, skillName: Annotated[str, Param(..., description='技能名称,支持模糊查询')]) -> SearchSkillResponse: async def get_skills_list(
redis: RedisDep,
skillName: Annotated[str, Param(..., description="技能名称,支持模糊查询")],
) -> SearchSkillResponse:
""" """
根据技能名称,获取对应的技能列表信息 根据技能名称,获取对应的技能列表信息
""" """
key = 'openapi:skills' key = "openapi:skills"
def get_skills(): def get_skills():
# This function should retrieve the skills list from the data source # This function should retrieve the skills list from the data source
# For now, we return a placeholder list # For now, we return a placeholder list
with open('./openapi/data/skills.json', encoding='utf-8') as f: with open("./openapi/data/skills.json", encoding="utf-8") as f:
skills_data = json.load(f) skills_data = json.load(f)
return skills_data return skills_data
skills_list = get_redis_info(redis, key, get_skills) skills_list = get_redis_info(redis, key, get_skills)
data = list(filter(lambda x: re.sub(r'\s+', '', skillName) in re.sub(r'\s+', '', x['skillName']), skills_list)) if skillName else skills_list data = (
list(
filter(
lambda x: re.sub(r"\s+", "", skillName)
in re.sub(r"\s+", "", x["skillName"]),
skills_list,
)
)
if skillName
else skills_list
)
return response(data=data) return response(data=data)
@router.get('/{jobId}/{jobGrowId}/skills/', operation_id='skillsByJob') @router.get("/jobInfo/", operation_id="jobsInfo")
async def get_cn_skills_by_job(redis: RedisDep, jobId: Annotated[str, Path(..., description='职业')], jobGrowId: Annotated[str, Path(..., description='转职')]) -> SkillsListResponse: async def get_jobs_info(
redis: RedisDep,
jobName: Annotated[str, Query(..., description="职业名称,支持模糊查询")],
) -> JobInfoResponse:
"""
根据职业名称,获取对应的职业转职信息
"""
adventure_info = get_redis_info(redis, "dcalc:adventure", get_adv_list)
result = []
for adv in adventure_info:
matched_children = [
child
for child in adv.get("children", [])
if jobName in child.get("title", "") or jobName in child.get("name", "")
]
if matched_children:
parent = {k: v for k, v in adv.items() if k != "children"}
for child in matched_children:
entry = parent.copy()
entry["child"] = child
result.append(
{
"jobId": entry.get("name", ""),
"jobName": entry.get("title", ""),
"jobGrowId": child.get("name", ""),
"jobGrowName": child.get("title", ""),
}
)
return response(data=result)
@router.get("/{jobId}/{jobGrowId}/skills/", operation_id="skillsByJob")
async def get_cn_skills_by_job(
redis: RedisDep,
jobId: Annotated[str, Path(..., description="职业")],
jobGrowId: Annotated[str, Path(..., description="转职")],
) -> SkillsListResponse:
""" """
获取职业技能列表 获取职业技能列表
""" """
key = f'openapi:{jobId}:{jobGrowId}:skills' key = f"openapi:{jobId}:{jobGrowId}:skills"
def get_skills_by_job(): def get_skills_by_job():
# This function should retrieve the skills by job and jobGrow # This function should retrieve the skills by job and jobGrow
# For now, we return a placeholder list # For now, we return a placeholder list
with open(f'./openapi/data/{jobId}/{jobGrowId}/cn/skill_tree.json', encoding='utf-8') as f: with open(
f"./openapi/data/{jobId}/{jobGrowId}/cn/skill_tree.json", encoding="utf-8"
) as f:
skills_data = json.load(f) skills_data = json.load(f)
return skills_data return skills_data
@@ -66,82 +125,130 @@ async def get_cn_skills_by_job(redis: RedisDep, jobId: Annotated[str, Path(...,
return response(data=skills_list) return response(data=skills_list)
@router.get('/{jobId}/{jobGrowId}/{skillId}/', operation_id='skillDetail') @router.get("/{jobId}/{jobGrowId}/{skillId}/", operation_id="skillDetail")
async def get_cn_skill_info(redis: RedisDep, jobId: Annotated[str, Path(..., description='职业')], jobGrowId: Annotated[str, Path(..., description='转职')], skillId: Annotated[str, Path(..., description='技能')], level: Annotated[int, Param(..., description='技能等级')] = None) -> SkillDetailResponse: async def get_cn_skill_info(
redis: RedisDep,
jobId: Annotated[str, Path(..., description="职业")],
jobGrowId: Annotated[str, Path(..., description="转职")],
skillId: Annotated[str, Path(..., description="技能")],
level: Annotated[int, Param(..., description="技能等级")] = None,
) -> SkillDetailResponse:
""" """
获取技能详细信息 获取技能详细信息
""" """
skill_info = {} skill_info = {}
key = f'openapi:{jobId}:{jobGrowId}:{skillId}' key = f"openapi:{jobId}:{jobGrowId}:{skillId}"
try: try:
def get_skill_info(): def get_skill_info():
# This function should retrieve the skill info based on job and jobGrow # This function should retrieve the skill info based on job and jobGrow
# For now, we return a placeholder dictionary # For now, we return a placeholder dictionary
with open(f'./openapi/data/{jobId}/{jobGrowId}/cn/skillDetail/{skillId}.json', encoding='utf-8') as f: with open(
f"./openapi/data/{jobId}/{jobGrowId}/cn/skillDetail/{skillId}.json",
encoding="utf-8",
) as f:
skill_data = json.load(f) skill_data = json.load(f)
if 'levelInfo' in skill_data and 'optionDesc' in skill_data['levelInfo'] and skill_data['levelInfo']['optionDesc'] is not None: if (
skill_data['levelInfo']['optionDesc'] = replace_placeholders(skill_data['levelInfo']['optionDesc']) "levelInfo" in skill_data
and "optionDesc" in skill_data["levelInfo"]
and skill_data["levelInfo"]["optionDesc"] is not None
):
skill_data["levelInfo"]["optionDesc"] = replace_placeholders(
skill_data["levelInfo"]["optionDesc"]
)
return skill_data return skill_data
skill_info = get_redis_info(redis, key, get_skill_info) skill_info = get_redis_info(redis, key, get_skill_info)
if level is not None: if level is not None:
level = max(0, min(level, skill_info.get('maxLevel', 0))) level = max(0, min(level, skill_info.get("maxLevel", 0)))
if 'levelInfo' in skill_info and 'rows' in skill_info['levelInfo']: if "levelInfo" in skill_info and "rows" in skill_info["levelInfo"]:
detail = list(filter(lambda x: x['level'] == level, skill_info['levelInfo']['rows'])) detail = list(
filter(
lambda x: x["level"] == level, skill_info["levelInfo"]["rows"]
)
)
if detail and len(detail) > 0: if detail and len(detail) > 0:
skill_info['levelInfo'].update(detail[0]) skill_info["levelInfo"].update(detail[0])
skill_info['levelInfo']['detail'] = skill_info['levelInfo'].get('optionDesc', '') skill_info["levelInfo"]["detail"] = skill_info["levelInfo"].get(
for key in skill_info['levelInfo']['optionValue'].keys(): "optionDesc", ""
skill_info['levelInfo']['detail'] = skill_info['levelInfo']['detail'].replace(f'{{{key}}}', str(skill_info['levelInfo']['optionValue'][key])) )
del skill_info['levelInfo']['rows'] for key in skill_info["levelInfo"]["optionValue"].keys():
skill_info['attribute'] = {} skill_info["levelInfo"]["detail"] = skill_info["levelInfo"][
skill_info['attribute'].update(skill_info['levelInfo']) "detail"
del skill_info['levelInfo'] ].replace(
f"{{{key}}}",
str(skill_info["levelInfo"]["optionValue"][key]),
)
del skill_info["levelInfo"]["rows"]
skill_info["attribute"] = {}
skill_info["attribute"].update(skill_info["levelInfo"])
del skill_info["levelInfo"]
except FileNotFoundError: except FileNotFoundError:
return response(code=404, message=f'技能信息未找到: {jobId} {jobGrowId} {skillId}', data=None) return response(
code=404,
message=f"技能信息未找到: {jobId} {jobGrowId} {skillId}",
data=None,
)
return response(data=skill_info) return response(data=skill_info)
@router.get('/skillData/summary/', operation_id='skillDataSummary') @router.get("/skillData/summary/", operation_id="skillDataSummary")
async def get_skill_data_summary( async def get_skill_data_summary(
redis: RedisDep, redis: RedisDep,
job: Annotated[str, Param(..., description='职业')], job: Annotated[str, Param(..., description="职业")],
skills: Annotated[str, Param(..., description='技能列表字符串,逗号拼接技能名称,不传递或者传递为空时,查询所有')] = "", skills: Annotated[
weapons: Annotated[str, Param(..., description='武器类型列表字符串,逗号拼接武器类型名称,不传递或者传递为空时,查询所有')] = "", str,
Param(
...,
description="技能列表字符串,逗号拼接技能名称,不传递或者传递为空时,查询所有",
),
] = "",
weapons: Annotated[
str,
Param(
...,
description="武器类型列表字符串,逗号拼接武器类型名称,不传递或者传递为空时,查询所有",
),
] = "",
) -> SkillDataSummaryResponse: ) -> SkillDataSummaryResponse:
""" """
获取技能数据汇总信息 获取技能数据汇总信息
""" """
key = f'openapi:skillData:summary:{job}' key = f"openapi:skillData:summary:{job}"
data = [] data = []
skills = skills.split(',') if skills else [] skills = skills.split(",") if skills else []
weapons = weapons.split(',') if weapons else [] weapons = weapons.split(",") if weapons else []
try: try:
def get_skill_data_summary(): def get_skill_data_summary():
# This function should retrieve the skill data summary based on job # This function should retrieve the skill data summary based on job
# For now, we return a placeholder dictionary # For now, we return a placeholder dictionary
summary_dir = './openapi/summary/' summary_dir = "./openapi/summary/"
json_files = [f for f in os.listdir(summary_dir) if f.endswith('.json')] json_files = [f for f in os.listdir(summary_dir) if f.endswith(".json")]
res = [] res = []
for i in json_files: for i in json_files:
if job in i: if job in i:
with open(os.path.join(summary_dir, i), encoding='utf-8') as f: with open(os.path.join(summary_dir, i), encoding="utf-8") as f:
skill_data = json.load(f) skill_data = json.load(f)
weapon = i.split('_')[-1].replace('.json', '') weapon = i.split("_")[-1].replace(".json", "")
print(weapon, i) print(weapon, i)
res.append({ res.append(
"weapon": weapon if weapon else "通用", {"weapon": weapon if weapon else "通用", "skills": skill_data}
'skills': skill_data )
})
return res return res
job_summary = get_redis_info(redis, key, get_skill_data_summary) job_summary = get_redis_info(redis, key, get_skill_data_summary)
for item in job_summary: for item in job_summary:
if (len(weapons) == 0 or item['weapon'] in weapons): if len(weapons) == 0 or item["weapon"] in weapons:
items = list(filter(lambda x: x['技能名称'] in skills, item['skills'])) if len(skills) > 0 else item['skills'] items = (
list(filter(lambda x: x["技能名称"] in skills, item["skills"]))
if len(skills) > 0
else item["skills"]
)
for skill in items: for skill in items:
skill['武器类型'] = item['weapon'] skill["武器类型"] = item["weapon"]
data.extend(skills or []) data.extend(skills or [])
except FileNotFoundError as e: except FileNotFoundError as e:
print(f'File not found: {e}') print(f"File not found: {e}")
return response(data=[]) return response(data=[])
return response(data=data) return response(data=data)
+10
View File
@@ -157,8 +157,18 @@ class SkillSummaryItem(BaseModel):
SP: float | None = Field(..., description='SP') SP: float | None = Field(..., description='SP')
武器类型: str = Field(..., description='武器类型') 武器类型: str = Field(..., description='武器类型')
class JobInfo(BaseModel):
jobId: str = Field(..., description='职业ID')
"""职业ID"""
jobName: str = Field(..., description='职业名称')
"""职业名称"""
jobGrowId: str = Field(..., description='转职ID')
"""转职ID"""
jobGrowName: str = Field(..., description='转职名称')
"""转职名称"""
SkillDetailResponse = Response[SkillDetail | None] SkillDetailResponse = Response[SkillDetail | None]
SearchSkillResponse = Response[list[SkillInfo]] SearchSkillResponse = Response[list[SkillInfo]]
SkillsListResponse = Response[list[SkillListItem]] SkillsListResponse = Response[list[SkillListItem]]
SkillDataSummaryResponse = Response[list[SkillSummaryItem]] SkillDataSummaryResponse = Response[list[SkillSummaryItem]]
JobInfoResponse = Response[list[JobInfo]]
+1 -1
Submodule images updated: 4eddb6dddf...5097bd72e3