dev
This commit is contained in:
@@ -26,31 +26,31 @@ 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", response_model=SearchSkillResponse)
|
@router.get('/skills/', operation_id='skillsList', response_model=SearchSkillResponse)
|
||||||
async def get_skills_list(
|
async def get_skills_list(
|
||||||
redis: RedisDep,
|
redis: RedisDep,
|
||||||
skillName: Annotated[str, Param(..., description="技能名称,支持模糊查询")] = None,
|
skillName: Annotated[str, Param(..., description='技能名称,支持模糊查询')] = None,
|
||||||
) -> SearchSkillResponse:
|
) -> 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
|
||||||
|
|
||||||
@@ -58,8 +58,7 @@ async def get_skills_list(
|
|||||||
data = (
|
data = (
|
||||||
list(
|
list(
|
||||||
filter(
|
filter(
|
||||||
lambda x: re.sub(r"\s+", "", skillName)
|
lambda x: re.sub(r'\s+', '', skillName) in re.sub(r'\s+', '', x['skillName']),
|
||||||
in re.sub(r"\s+", "", x["skillName"]),
|
|
||||||
skills_list,
|
skills_list,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -69,55 +68,50 @@ async def get_skills_list(
|
|||||||
return response(data=data)
|
return response(data=data)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/jobInfo/", operation_id="jobsInfo", response_model=JobInfoResponse)
|
@router.get('/jobInfo/', operation_id='jobsInfo', response_model=JobInfoResponse)
|
||||||
async def get_jobs_info(
|
async def get_jobs_info(
|
||||||
redis: RedisDep,
|
redis: RedisDep,
|
||||||
jobName: Annotated[str, Query(..., description="职业名称,支持模糊查询")] = None,
|
jobName: Annotated[str, Query(..., description='职业名称,支持模糊查询')] = None,
|
||||||
) -> JobInfoResponse:
|
) -> JobInfoResponse:
|
||||||
"""
|
"""
|
||||||
根据职业名称,获取对应的职业转职信息
|
根据职业名称,获取对应的职业转职信息
|
||||||
"""
|
"""
|
||||||
adventure_info = get_redis_info(redis, "dcalc:adventure", get_adv_list)
|
adventure_info = get_redis_info(redis, 'dcalc:adventure', get_adv_list)
|
||||||
|
jobName = jobName.replace('(', '(').replace(')', ')')
|
||||||
result = []
|
result = []
|
||||||
for adv in adventure_info:
|
for adv in adventure_info:
|
||||||
matched_children = [
|
matched_children = [child for child in adv.get('children', []) if jobName in child.get('title', '') or jobName in child.get('name', '')]
|
||||||
child
|
|
||||||
for child in adv.get("children", [])
|
|
||||||
if jobName in child.get("title", "") or jobName in child.get("name", "")
|
|
||||||
]
|
|
||||||
if matched_children:
|
if matched_children:
|
||||||
parent = {k: v for k, v in adv.items() if k != "children"}
|
parent = {k: v for k, v in adv.items() if k != 'children'}
|
||||||
for child in matched_children:
|
for child in matched_children:
|
||||||
entry = parent.copy()
|
entry = parent.copy()
|
||||||
entry["child"] = child
|
entry['child'] = child
|
||||||
result.append(
|
result.append(
|
||||||
{
|
{
|
||||||
"jobId": entry.get("name", ""),
|
'jobId': entry.get('name', ''),
|
||||||
"jobName": entry.get("title", ""),
|
'jobName': entry.get('title', ''),
|
||||||
"jobGrowId": child.get("name", ""),
|
'jobGrowId': child.get('name', ''),
|
||||||
"jobGrowName": child.get("title", ""),
|
'jobGrowName': child.get('title', ''),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return response(data=result)
|
return response(data=result)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{jobId}/{jobGrowId}/skills/", operation_id="skillsByJob",response_model=SkillsListResponse)
|
@router.get('/{jobId}/{jobGrowId}/skills/', operation_id='skillsByJob', response_model=SkillsListResponse)
|
||||||
async def get_cn_skills_by_job(
|
async def get_cn_skills_by_job(
|
||||||
redis: RedisDep,
|
redis: RedisDep,
|
||||||
jobId: Annotated[str, Path(..., description="职业")],
|
jobId: Annotated[str, Path(..., description='职业')],
|
||||||
jobGrowId: Annotated[str, Path(..., description="转职")],
|
jobGrowId: Annotated[str, Path(..., description='转职')],
|
||||||
) -> SkillsListResponse:
|
) -> 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(
|
with open(f'./openapi/data/{jobId}/{jobGrowId}/cn/skill_tree.json', encoding='utf-8') as f:
|
||||||
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
|
||||||
|
|
||||||
@@ -125,124 +119,112 @@ async def get_cn_skills_by_job(
|
|||||||
return response(data=skills_list)
|
return response(data=skills_list)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{jobId}/{jobGrowId}/{skillId}/", operation_id="skillDetail", response_model=SkillDetailResponse)
|
@router.get('/{jobId}/{jobGrowId}/{skillId}/', operation_id='skillDetail', response_model=SkillDetailResponse)
|
||||||
async def get_cn_skill_info(
|
async def get_cn_skill_info(
|
||||||
redis: RedisDep,
|
redis: RedisDep,
|
||||||
jobId: Annotated[str, Path(..., description="职业")],
|
jobId: Annotated[str, Path(..., description='职业')],
|
||||||
jobGrowId: Annotated[str, Path(..., description="转职")],
|
jobGrowId: Annotated[str, Path(..., description='转职')],
|
||||||
skillId: Annotated[str, Path(..., description="技能")],
|
skillId: Annotated[str, Path(..., description='技能')],
|
||||||
level: Annotated[int, Param(..., description="技能等级")] = None,
|
level: Annotated[int, Param(..., description='技能等级')] = None,
|
||||||
) -> SkillDetailResponse:
|
) -> 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(
|
with open(
|
||||||
f"./openapi/data/{jobId}/{jobGrowId}/cn/skillDetail/{skillId}.json",
|
f'./openapi/data/{jobId}/{jobGrowId}/cn/skillDetail/{skillId}.json',
|
||||||
encoding="utf-8",
|
encoding='utf-8',
|
||||||
) as f:
|
) as f:
|
||||||
skill_data = json.load(f)
|
skill_data = json.load(f)
|
||||||
if (
|
if 'levelInfo' in skill_data and 'optionDesc' in skill_data['levelInfo'] and skill_data['levelInfo']['optionDesc'] is not None:
|
||||||
"levelInfo" in skill_data
|
skill_data['levelInfo']['optionDesc'] = replace_placeholders(skill_data['levelInfo']['optionDesc'])
|
||||||
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(
|
detail = list(filter(lambda x: x['level'] == level, skill_info['levelInfo']['rows']))
|
||||||
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(
|
skill_info['levelInfo']['detail'] = skill_info['levelInfo'].get('optionDesc', '')
|
||||||
"optionDesc", ""
|
for key in skill_info['levelInfo']['optionValue'].keys():
|
||||||
)
|
skill_info['levelInfo']['detail'] = skill_info['levelInfo']['detail'].replace(
|
||||||
for key in skill_info["levelInfo"]["optionValue"].keys():
|
f'{{{key}}}',
|
||||||
skill_info["levelInfo"]["detail"] = skill_info["levelInfo"][
|
str(skill_info['levelInfo']['optionValue'][key]),
|
||||||
"detail"
|
|
||||||
].replace(
|
|
||||||
f"{{{key}}}",
|
|
||||||
str(skill_info["levelInfo"]["optionValue"][key]),
|
|
||||||
)
|
)
|
||||||
del skill_info["levelInfo"]["rows"]
|
del skill_info['levelInfo']['rows']
|
||||||
skill_info["attribute"] = {}
|
skill_info['attribute'] = {}
|
||||||
skill_info["attribute"].update(skill_info["levelInfo"])
|
skill_info['attribute'].update(skill_info['levelInfo'])
|
||||||
del skill_info["levelInfo"]
|
del skill_info['levelInfo']
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return response(
|
return response(
|
||||||
code=404,
|
code=404,
|
||||||
message=f"技能信息未找到: {jobId} {jobGrowId} {skillId}",
|
message=f'技能信息未找到: {jobId} {jobGrowId} {skillId}',
|
||||||
data=None,
|
data=None,
|
||||||
)
|
)
|
||||||
return response(data=skill_info)
|
return response(data=skill_info)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/skillData/summary/", operation_id="skillDataSummary",response_model=SkillDataSummaryResponse)
|
@router.get('/skillData/summary/', operation_id='skillDataSummary', response_model=SkillDataSummaryResponse)
|
||||||
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[
|
skills: Annotated[
|
||||||
str,
|
str,
|
||||||
Param(
|
Param(
|
||||||
...,
|
...,
|
||||||
description="技能列表字符串,逗号拼接技能名称,不传递或者传递为空时,查询所有",
|
description='技能列表字符串,逗号拼接技能名称,不传递或者传递为空时,查询所有',
|
||||||
),
|
),
|
||||||
] = "",
|
] = '',
|
||||||
weapons: Annotated[
|
weapons: Annotated[
|
||||||
str,
|
str,
|
||||||
Param(
|
Param(
|
||||||
...,
|
...,
|
||||||
description="武器类型列表字符串,逗号拼接武器类型名称,不传递或者传递为空时,查询所有",
|
description='武器类型列表字符串,逗号拼接武器类型名称,不传递或者传递为空时,查询所有',
|
||||||
),
|
),
|
||||||
] = "",
|
] = '',
|
||||||
) -> SkillDataSummaryResponse:
|
) -> SkillDataSummaryResponse:
|
||||||
"""
|
"""
|
||||||
获取技能数据汇总信息
|
获取技能数据汇总信息
|
||||||
"""
|
"""
|
||||||
key = f"openapi:skillData:summary:{job}"
|
job = job.replace('(', '(').replace(')', ')')
|
||||||
|
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:
|
k = re.search(r'^\d+(?:-\d+)?(.*?)_', i)
|
||||||
|
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', '')
|
||||||
res.append(
|
res.append({'weapon': weapon if weapon else '通用', 'skills': skill_data, 'job': k})
|
||||||
{"weapon": weapon if weapon else "通用", "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']
|
||||||
|
skill['职业'] = item['job']
|
||||||
data.extend(items or [])
|
data.extend(items 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)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from enum import Enum
|
|||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from api.core.Response import Return as Response
|
from api.core.Response import Return as Response
|
||||||
|
|
||||||
|
|
||||||
class SkillInfo(BaseModel):
|
class SkillInfo(BaseModel):
|
||||||
skillId: str = Field(..., description='技能ID')
|
skillId: str = Field(..., description='技能ID')
|
||||||
"""技能ID"""
|
"""技能ID"""
|
||||||
@@ -153,6 +154,8 @@ class SkillSummaryItem(BaseModel):
|
|||||||
理论秒伤: float | str | None = Field(..., description='理论秒伤')
|
理论秒伤: float | str | None = Field(..., description='理论秒伤')
|
||||||
SP: float | None | str = Field(..., description='SP')
|
SP: float | None | str = Field(..., description='SP')
|
||||||
武器类型: str | None = Field(..., description='武器类型')
|
武器类型: str | None = Field(..., description='武器类型')
|
||||||
|
职业: str | None = Field(..., description='职业')
|
||||||
|
|
||||||
|
|
||||||
class JobInfo(BaseModel):
|
class JobInfo(BaseModel):
|
||||||
jobId: str = Field(..., description='职业ID')
|
jobId: str = Field(..., description='职业ID')
|
||||||
@@ -164,6 +167,7 @@ class JobInfo(BaseModel):
|
|||||||
jobGrowName: str = Field(..., description='转职名称')
|
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]]
|
||||||
|
|||||||
@@ -433,15 +433,15 @@ class Character(CharacterProperty):
|
|||||||
# region 计算相关
|
# region 计算相关
|
||||||
def SetDetail(self, info: dict[str, dict]) -> None:
|
def SetDetail(self, info: dict[str, dict]) -> None:
|
||||||
self.charEquipInfo = {}
|
self.charEquipInfo = {}
|
||||||
self.charOathInfo = []
|
# self.charOathInfo = []
|
||||||
self.bindAwake = info.get('bindAwake', 50)
|
self.bindAwake = info.get('bindAwake', 50)
|
||||||
"""打造信息导入"""
|
"""打造信息导入"""
|
||||||
for key in info['equips']:
|
for key in info['equips']:
|
||||||
# 导入部位打造信息、装备信息、贴膜信息
|
# 导入部位打造信息、装备信息、贴膜信息
|
||||||
self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key)
|
self.charEquipInfo[key] = CharacterEquipInfo(info['equips'][key], self.equVersion, key)
|
||||||
for key in info['oaths']:
|
# for key in info['oaths']:
|
||||||
# 导入誓约打造信息、誓约信息
|
# # 导入誓约打造信息、誓约信息
|
||||||
self.charOathInfo.append(CharacterOathInfo(info['oaths'][key], self.equVersion, key))
|
# self.charOathInfo.append(CharacterOathInfo(info['oaths'][key], self.equVersion, key))
|
||||||
|
|
||||||
def getInfo(self):
|
def getInfo(self):
|
||||||
"""返回到前端信息"""
|
"""返回到前端信息"""
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ class Equipments:
|
|||||||
self.init_stones()
|
self.init_stones()
|
||||||
self.init_emblem()
|
self.init_emblem()
|
||||||
self.init_jades()
|
self.init_jades()
|
||||||
self.init_oaths()
|
# self.init_oaths()
|
||||||
self.init_oath_suits()
|
# self.init_oath_suits()
|
||||||
self.engine.dispose()
|
self.engine.dispose()
|
||||||
|
|
||||||
def init_equs(self):
|
def init_equs(self):
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ class CharacterOathInfo:
|
|||||||
self.__dict__.update(info)
|
self.__dict__.update(info)
|
||||||
self.id = str(self.id)
|
self.id = str(self.id)
|
||||||
oath = get_equipment(equVerison).oath_dict.get(self.id, None)
|
oath = get_equipment(equVerison).oath_dict.get(self.id, None)
|
||||||
print(position, oath)
|
|
||||||
if oath is not None and position in oath.position:
|
if oath is not None and position in oath.position:
|
||||||
self.oathInfo = oath.adapt(self.adaptation)
|
self.oathInfo = oath.adapt(self.adaptation)
|
||||||
self.adaptation = min(self.adaptation, self.oathInfo.max_adaptation)
|
self.adaptation = min(self.adaptation, self.oathInfo.max_adaptation)
|
||||||
|
|||||||
+1
-1
Submodule backend/openapi updated: f30150255e...03f3bbf037
Reference in New Issue
Block a user