This commit is contained in:
qsc
2025-12-24 22:43:06 +08:00
parent 02982f7a62
commit 40e0ad8fca
4 changed files with 85 additions and 141 deletions
+7 -1
View File
@@ -8,9 +8,15 @@
"jx3api_token": { "jx3api_token": {
"description": "JX3API Token", "description": "JX3API Token",
"type": "string", "type": "string",
"default": "v2aa6e74d48abb7b9", "default": "",
"hint": "前往https://www.jx3api.com/注册并购买Token。" "hint": "前往https://www.jx3api.com/注册并购买Token。"
}, },
"jx3api_ticket": {
"description": "推栏标识",
"type": "string",
"default": "",
"hint": "通过抓包推栏APP账号登录信息获取推栏标识"
},
"kfjk": { "kfjk": {
"description": "开服监控配置", "description": "开服监控配置",
"type": "object", "type": "object",
+51 -125
View File
@@ -12,8 +12,22 @@ class JX3Service:
def __init__(self, api_config,db: AsyncSQLite,config:AstrBotConfig): def __init__(self, api_config,db: AsyncSQLite,config:AstrBotConfig):
self._api = APIClient() self._api = APIClient()
self._db = db self._db = db
# 获取API配置文件
self._api_config = api_config self._api_config = api_config
# 获取插件配置文件
self._config = config self._config = config
# 获取配置中的 Token
self.token = self._config.get("jx3api_token", "")
if self.token == "":
logger.info("获取配置token失败,请正确填写token,否则部分功能无法正常使用")
else:
logger.info(f"获取配置token成功。{self.token}")
# 获取配置中的 ticket
self.ticket = self._config.get("jx3api_ticket", "")
if self.ticket == "":
logger.info("获取配置ticket失败,请正确填写ticket,否则部分功能无法正常使用")
else:
logger.info(f"获取配置ticket成功。{self.ticket}")
def _init_return_data(self) -> Dict[str, Any]: def _init_return_data(self) -> Dict[str, Any]:
@@ -71,6 +85,7 @@ class JX3Service:
logger.error(f"基础请求调用出错 ({config_key}): {e}") logger.error(f"基础请求调用出错 ({config_key}): {e}")
return None return None
# --- 业务功能函数 --- # --- 业务功能函数 ---
async def helps(self) -> Dict[str, Any]: async def helps(self) -> Dict[str, Any]:
"""帮助""" """帮助"""
@@ -88,6 +103,7 @@ class JX3Service:
return return_data return return_data
async def richang(self,server: str, num: int = 0) -> Dict[str, Any]: async def richang(self,server: str, num: int = 0) -> Dict[str, Any]:
"""日常活动""" """日常活动"""
return_data = self._init_return_data() return_data = self._init_return_data()
@@ -190,8 +206,6 @@ class JX3Service:
status_str = f"{server}服务器当前维护中,等会再来吧!\n维护时间:{status_time}" status_str = f"{server}服务器当前维护中,等会再来吧!\n维护时间:{status_time}"
status_bool = False status_bool = False
return_data["status"] = status_bool return_data["status"] = status_bool
return_data["data"] = status_str return_data["data"] = status_str
return_data["code"] = 200 return_data["code"] = 200
@@ -417,15 +431,9 @@ class JX3Service:
"""物价查询""" """物价查询"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 2. 确定外观名称和 ID # 2. 确定外观名称和 ID
params_search = {"name": Name,"token": token, "server": server} params_search = {"name": Name,"token": self.token, "server": server}
search_data: Optional[Dict[str, Any]] = await self._base_request("jx3_wujia", "GET", params=params_search) search_data: Optional[Dict[str, Any]] = await self._base_request("jx3_wujia", "GET", params=params_search)
if not search_data: if not search_data:
@@ -446,85 +454,51 @@ class JX3Service:
return return_data return return_data
async def jiaoyihang(self, Name: str , server: str) -> Dict[str, Any]: async def jiaoyihang(self, name: str , server: str) -> Dict[str, Any]:
"""区服交易行""" """区服交易行"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 1. 查找物品 ID 列表 (多页) # 1. 构造请求参数
api_config_search = self._api_config["jx3box_item"] params = {"server": server, "name": name,"token": self.token}
search_params = api_config_search.get("params", {}).copy()
search_params["keyword"] = Name
# 使用 all_pages 获取所有数据 # 2. 调用基础请求
all_items: List[Dict[str, Any]] = await self._api.all_pages( data: Optional[Dict[str, Any]] = await self._base_request(
"GET", "jx3_jiaoyihang", "GET", params=params
api_config_search["url"],
params_data=search_params, # 对应到 APIClient.all_pages
out_key="data",
list_key="data"
) )
if not all_items: if not data:
return_data["msg"] = "未找到该物品" return_data["msg"] = "未找到该物品"
return return_data return return_data
# 2. 提取 ID、IconID 和 Name # 2. 数据处理
fields = ["IconID", "Name", "id"] result = []
# 安全提取字段,并确保 id 存在且是数字
result = [extract_fields([item], fields)[0] for item in all_items if item.get("id") is not None]
lists_id = [str(item.get("id")) for item in result if item.get("id") is not None] try:
strlists_id = ",".join(lists_id) for item in data:
inner_list = item.get("data", [])
first = inner_list[0] if inner_list else {}
new_item = {
"name": item.get("name"),
"icon": f"https://icon.jx3box.com/icon/{item.get('icon')}.png",
"sever": first.get("server"),
"count": len(inner_list),
"unit_price": gold_to_string(first.get("unit_price")),
"created": datetime.fromtimestamp(first.get("created")).strftime("%Y-%m-%d %H:%M:%S"),
}
result.append(new_item)
except Exception as e:
logger.error(f"处理交易行数据失败: {e}")
return_data["msg"] = "处理交易行数据失败"
if not strlists_id: return_data["data"]["list"] = result
return_data["msg"] = "未找到有效的物品ID"
return return_data
# 3. 查询物品价格 (jx3box_itemprice)
api_config_price = self._api_config["jx3box_itemprice"]
price_params = api_config_price.get("params", {}).copy()
price_params["itemIds"] = strlists_id
price_params["server"] = server
price_data: Optional[Dict[str, Dict[str, Any]]] = await self._api.get(
api_config_price["url"], params=price_params, out_key="data"
)
if not price_data:
return_data["msg"] = "未找到在售物品"
return return_data
# 4. 合并数据和格式化
fieldsjyh = ["ItemId", "SampleSize", "LowestPrice", "AvgPrice", "Date"]
resultjyh = [{f: v[f] for f in fieldsjyh} for v in price_data.values()]
#合并表格数据
# 先建立一个字典映射,加快查找
map_result = {item["id"]: {"IconID": item["IconID"], "Name": item["Name"]} for item in result}
# 遍历 resultjyh,合并字段
for item in resultjyh:
if item["ItemId"] in map_result:
item.update(map_result[item["ItemId"]])
#处理数据
for item in resultjyh:
item["LowestPrice"] = gold_to_string(item["LowestPrice"])
item["AvgPrice"] = gold_to_string(item["AvgPrice"])
item["IconID"] = f"https://icon.jx3box.com/icon/{item['IconID']}.png"
# 5. 模板渲染 # 5. 模板渲染
try: try:
return_data["temp"] = load_template("jiaoyihang.html") return_data["temp"] = load_template("jiaoyihang.html")
return_data["data"] = {
"items": resultjyh,
"server": server,
"update_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
return_data["code"] = 200 return_data["code"] = 200
except FileNotFoundError as e: except FileNotFoundError as e:
logger.error(f"加载模板失败: {e}") logger.error(f"加载模板失败: {e}")
return_data["msg"] = "系统错误:模板文件不存在" return_data["msg"] = "系统错误:模板文件不存在"
except Exception as e:
logger.error(f"模板渲染数据准备失败: {e}")
return_data["msg"] = "系统错误:数据处理失败"
return return_data return return_data
@@ -533,14 +507,8 @@ class JX3Service:
"""角色名片""" """角色名片"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "name": name,"token": token} params = {"server": server, "name": name,"token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -562,14 +530,8 @@ class JX3Service:
"""随机名片""" """随机名片"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "body": body, "force":force, "token": token} params = {"server": server, "body": body, "force":force, "token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -591,14 +553,8 @@ class JX3Service:
"""烟花查询""" """烟花查询"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "name": name,"token": token} params = {"server": server, "name": name,"token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -637,14 +593,8 @@ class JX3Service:
"""的卢记录""" """的卢记录"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "token": token} params = {"server": server, "token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -679,14 +629,8 @@ class JX3Service:
"""团队招募""" """团队招募"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "keyword": keyword, "token": token} params = {"server": server, "keyword": keyword, "token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -720,14 +664,8 @@ class JX3Service:
"""战绩+名片""" """战绩+名片"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "name":name, "mode":mode, "token": token} params = {"server": server, "name":name, "mode":mode, "token": self.token, "ticket": self.ticket}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -766,14 +704,8 @@ class JX3Service:
"""角色奇遇""" """角色奇遇"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "name": name, "token": token} params = {"server": server, "name": name, "token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
@@ -819,14 +751,8 @@ class JX3Service:
"""阵营拍卖""" """阵营拍卖"""
return_data = self._init_return_data() return_data = self._init_return_data()
# 获取配置中的 Token
token = self._config.get("jx3api_token", "")
if token == "":
return_data["msg"] = "系统未配置API访问Token"
return return_data
# 1. 构造请求参数 # 1. 构造请求参数
params = {"server": server, "name": name, "token": token} params = {"server": server, "name": name, "token": self.token}
# 2. 调用基础请求 # 2. 调用基础请求
data: Optional[Dict[str, Any]] = await self._base_request( data: Optional[Dict[str, Any]] = await self._base_request(
+10
View File
@@ -265,5 +265,15 @@
"limit": 20, "limit": 20,
"token": "" "token": ""
} }
},
"jx3_jiaoyihang":{
"url":"https://www.jx3api.com/data/trade/market",
"method":"GET",
"description":"获取剑网三区服交易行数据",
"params":{
"server": "梦江南",
"name": "玄晶",
"token": ""
}
} }
} }
+12 -10
View File
@@ -86,29 +86,31 @@
<div class="container"> <div class="container">
<h1>剑网3交易行价格查询</h1> <h1>剑网3交易行价格查询</h1>
<div class="server-info">服务器:{{ server }}</div>
<div class="table-wrapper"> <div class="table-wrapper">
<table> <table>
<thead> <thead>
<tr> <tr>
<th>服务器</th>
<th>图标</th>
<th>物品名称</th> <th>物品名称</th>
<th>最低</th> <th></th>
<th>数量</th> <th>数量</th>
<th>数据更新时间</th> <th>时间</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in items %} {% for item in list %}
<tr> <tr>
<td>{{ item.sever }}</td>
<td class="item-col"> <td class="item-col">
<img src="{{ item.IconID }}" alt="icon"> <img src="{{ item.icon }}" alt="icon">
{{ item.Name }}
</td> </td>
<td>{{ item.AvgPrice }}</td> <td>{{ item.name }}</td>
<td>{{ item.SampleSize }}</td> <td>{{ item.unit_price }}</td>
<td>{{ item.Date }}</td> <td>{{ item.count }}</td>
<td>{{ item.created }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>