1.签到系统错误修复2.商店系统修复bug并更新购买逻辑3.将炉灰加入商店并添加炉渣配方4.修改一些炼金系统的逻辑

This commit is contained in:
2025-11-09 21:46:21 +08:00
parent f0cc04d2c1
commit 22d2271bac
6 changed files with 200 additions and 62 deletions

View File

@@ -30,7 +30,7 @@ Yolo模式: Off
- 暴露 get_user_name/url/points 与 adjust_user_points 接口供其他插件调用。 - 暴露 get_user_name/url/points 与 adjust_user_points 接口供其他插件调用。
- 通过 asyncio.Lock 确保写入串行, 保存失败会记录错误日志。 - 通过 asyncio.Lock 确保写入串行, 保存失败会记录错误日志。
# 当前执行步骤:"3. 实施配置插件" # 当前执行步骤:"4. 修复签到唯一约束"
# 任务进度 # 任务进度
@@ -67,4 +67,13 @@ Yolo模式: Off
[2025-11-07_22:33:00] [2025-11-07_22:33:00]
- 已修改: Plugins/WPSPointSystem->Plugins/WPSConfigSystem - 已修改: Plugins/WPSPointSystem->Plugins/WPSConfigSystem
- 原因: user_id相关的最优先表被注册在此处 - 原因: user_id相关的最优先表被注册在此处
- 阻碍因素: 无
- 状态: 成功
[2025-11-09_19:35:08]
- 已修改: `Plugins/WPSConfigSystem.py`
- 更改: 在记录每日签到时使用 INSERT ... ON CONFLICT(user_id) DO UPDATE避免跨日签到触发唯一约束错误
- 原因: 保障每日签到功能在重复执行时保持幂等性
- 阻碍因素: 无
- 状态: 成功

View File

@@ -45,7 +45,7 @@ WPS Bot 插件体系,现有 `WPSConfigAPI` 提供积分管理与签到积分
- 重新整理依赖关系与命令注册,确保未注册商品或物品未找到时返回明确错误提示(如“未找到商店商品”“背包未注册物品”)。 - 重新整理依赖关系与命令注册,确保未注册商品或物品未找到时返回明确错误提示(如“未找到商店商品”“背包未注册物品”)。
- 暴露额外接口:`list_registered_modes()``get_store_snapshot()` 等辅助方法供其他插件调试或扩展使用。 - 暴露额外接口:`list_registered_modes()``get_store_snapshot()` 等辅助方法供其他插件调试或扩展使用。
# 当前执行步骤:"5. 重新规划命令拆分" # 当前执行步骤:"10. 购买排序优化"
实施清单: 实施清单:
1. 重构 `WPSStoreSystem`:新增 `purchase_item`/`sell_item` 公共方法,并将 `callback` 限制为 `商店` 指令。 1. 重构 `WPSStoreSystem`:新增 `purchase_item`/`sell_item` 公共方法,并将 `callback` 限制为 `商店` 指令。
@@ -109,6 +109,36 @@ WPS Bot 插件体系,现有 `WPSConfigAPI` 提供积分管理与签到积分
- 原因:满足命令拆分要求,避免未注册商品时误返回帮助信息 - 原因:满足命令拆分要求,避免未注册商品时误返回帮助信息
- 阻碍因素:无 - 阻碍因素:无
- 状态:未确认 - 状态:未确认
2025-11-09_19:18:39
- 已修改:`Plugins/WPSStoreSystem.py`
- 更改:玩家出售与系统商品展示统一使用物品名称,扩展 `PlayerListing` 并在加载时补充物品名
- 原因确保商店界面不再暴露物品ID提升可读性
- 阻碍因素:无
- 状态:未确认
2025-11-09_19:35:08
- 已修改:`Plugins/WPSStoreSystem.py` `PWF/CoreModules/plugin_interface.py`
- 更改:出售指令支持 `<数量> <单价>` 参数,调整逻辑使用玩家自定 single price并在表注册时自动补齐缺失列
- 原因:允许运营自定售价并避免旧表缺列导致的运行错误
- 阻碍因素:无
- 状态:成功
2025-11-09_19:45:00
- 已修改:`Plugins/WPSStoreSystem.py`
- 更改:购买流程统一收集匹配来源,按价格升序排序;同价时优先玩家,再按系统、常驻顺序处理
- 原因:满足按价格优先购买的需求,确保同价时玩家商品优先售出
- 阻碍因素:无
- 状态:进行中
2025-11-09_19:50:00
- 已修改:`Plugins/WPSAlchemyGame.py`
- 更改:炼金插件依赖商店系统,在注册炉灰物品后同步为整点刷新候选,单价 8 分、限购 999
- 原因:补充基础货源,便于验证按价格排序的购买流程
- 阻碍因素:无
- 状态:成功
2025-11-09_21:22:44
- 已修改:`Plugins/WPSStoreSystem.py`
- 更改玩家出售展示改为调用配置接口获取昵称避免暴露纯数字ID
- 原因:提升商店玩家出售区的可读性与一致性
- 阻碍因素:无
- 状态:未确认
# 最终审查 # 最终审查
(待补充) (待补充)

2
PWF

Submodule PWF updated: 4d3d841dda...7deef9092a

View File

@@ -15,6 +15,7 @@ from .WPSBackpackSystem import (
WPSBackpackSystem, WPSBackpackSystem,
) )
from .WPSConfigSystem import WPSConfigAPI from .WPSConfigSystem import WPSConfigAPI
from .WPSStoreSystem import WPSStoreSystem
from .WPSFortuneSystem import WPSFortuneSystem from .WPSFortuneSystem import WPSFortuneSystem
@@ -40,7 +41,7 @@ class WPSAlchemyGame(WPSAPI):
ASH_ITEM_NAME = "炉灰" ASH_ITEM_NAME = "炉灰"
SLAG_ITEM_ID = "alchemy_slag" SLAG_ITEM_ID = "alchemy_slag"
SLAG_ITEM_NAME = "炉渣" SLAG_ITEM_NAME = "炉渣"
MAX_BATCH_TIMES = 9999 MAX_BATCH_TIMES = 99
_PHASE_TABLE: List[Tuple[float, float, str, str]] = [ _PHASE_TABLE: List[Tuple[float, float, str, str]] = [
(0.1481481481, 0.0, "爆炸", "💥 炼金反噬,积分化为飞灰……"), (0.1481481481, 0.0, "爆炸", "💥 炼金反噬,积分化为飞灰……"),
@@ -58,7 +59,7 @@ class WPSAlchemyGame(WPSAPI):
@override @override
def dependencies(self) -> List[type]: def dependencies(self) -> List[type]:
return [WPSAPI, WPSBackpackSystem, WPSConfigAPI, WPSFortuneSystem] return [WPSAPI, WPSBackpackSystem, WPSConfigAPI, WPSFortuneSystem, WPSStoreSystem]
@override @override
def wake_up(self) -> None: def wake_up(self) -> None:
@@ -83,6 +84,19 @@ class WPSAlchemyGame(WPSAPI):
"Warning", "Warning",
f"{ConsoleFrontColor.YELLOW}注册炉灰物品时出现问题: {exc}{ConsoleFrontColor.RESET}", f"{ConsoleFrontColor.YELLOW}注册炉灰物品时出现问题: {exc}{ConsoleFrontColor.RESET}",
) )
else:
try:
store_system = Architecture.Get(WPSStoreSystem)
store_system.register_mode(
item_id=self.ASH_ITEM_ID,
price=8,
limit_amount=999,
)
except Exception as exc:
logger.Log(
"Warning",
f"{ConsoleFrontColor.YELLOW}注册炉灰商店模式时出现问题: {exc}{ConsoleFrontColor.RESET}",
)
try: try:
backpack.register_item( backpack.register_item(
self.SLAG_ITEM_ID, self.SLAG_ITEM_ID,
@@ -180,7 +194,7 @@ class WPSAlchemyGame(WPSAPI):
if points <= 0: if points <= 0:
return "❌ 投入积分必须大于 0" return "❌ 投入积分必须大于 0"
config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI) config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI)
current_points = config_api.get_user_points(chat_id, user_id) current_points = config_api.get_user_points(user_id)
if current_points < points: if current_points < points:
return f"❌ 积分不足,需要 {points} 分,当前仅有 {current_points}" return f"❌ 积分不足,需要 {points} 分,当前仅有 {current_points}"
@@ -205,7 +219,7 @@ class WPSAlchemyGame(WPSAPI):
backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem) backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
backpack.add_item(user_id, self.ASH_ITEM_ID, ash_reward) backpack.add_item(user_id, self.ASH_ITEM_ID, ash_reward)
final_points = config_api.get_user_points(chat_id, user_id) final_points = config_api.get_user_points(user_id)
extra_line = "" extra_line = ""
if ash_reward > 0: if ash_reward > 0:
extra_line = ( extra_line = (

View File

@@ -160,21 +160,21 @@ class WPSConfigAPI(WPSAPI):
except (TypeError, ValueError): except (TypeError, ValueError):
return 0 return 0
def get_user_name(self, chat_id: int, user_id: int) -> Optional[str]: def get_user_name(self, user_id: int) -> Optional[str]:
record = self._get_user_record(user_id) record = self._get_user_record(user_id)
if not record: if not record:
return f"user_{user_id}" return f"user_{user_id}"
value = record.get("username") value = record.get("username")
return str(value) if value else f"user_{user_id}" return str(value) if value else f"user_{user_id}"
def get_user_url(self, chat_id: int, user_id: int) -> Optional[str]: def get_user_url(self, user_id: int) -> Optional[str]:
record = self._get_user_record(user_id) record = self._get_user_record(user_id)
if not record: if not record:
return None return None
value = record.get("userurl") value = record.get("userurl")
return str(value) if value else None return str(value) if value else None
def get_user_points(self, chat_id: int, user_id: int) -> int: def get_user_points(self, user_id: int) -> int:
record = self._get_user_record(user_id) record = self._get_user_record(user_id)
if not record: if not record:
return 0 return 0
@@ -224,7 +224,15 @@ class WPSCheckinAPI(WPSAPI):
def _set_today_checkin_status(self, user_id: int) -> None: def _set_today_checkin_status(self, user_id: int) -> None:
cursor = get_db().conn.cursor() cursor = get_db().conn.cursor()
cursor.execute("INSERT INTO daily_checkin (user_id, checkin_date) VALUES (?, ?)", (user_id, datetime.now().strftime("%Y-%m-%d"))) cursor.execute(
"""
INSERT INTO daily_checkin (user_id, checkin_date)
VALUES (?, ?)
ON CONFLICT(user_id) DO UPDATE SET
checkin_date = excluded.checkin_date
""",
(user_id, datetime.now().strftime("%Y-%m-%d")),
)
get_db().conn.commit() get_db().conn.commit()
async def do_callback(self, message: str, chat_id: int, user_id: int) -> Optional[str]: async def do_callback(self, message: str, chat_id: int, user_id: int) -> Optional[str]:
@@ -259,7 +267,7 @@ class WPSCheckinAPI(WPSAPI):
return f'''# 📅 Daily 命令帮助 return f'''# 📅 Daily 命令帮助
- checkin: 签到 - checkin: 签到
--- ---
- 当前分数: {wps_config_api.get_user_points(chat_id, user_id)} - 当前分数: {wps_config_api.get_user_points(user_id)}
- 今日签到状态: {"已签到" if self._get_today_checkin_status(user_id) else "未签到"} - 今日签到状态: {"已签到" if self._get_today_checkin_status(user_id) else "未签到"}
''' '''

View File

@@ -59,6 +59,7 @@ class StoreEntry(BaseModel):
class PlayerListing(BaseModel): class PlayerListing(BaseModel):
user_id: int user_id: int
item_id: str item_id: str
item_name: str
price: int price: int
quantity: int quantity: int
created_at: datetime created_at: datetime
@@ -390,6 +391,7 @@ class WPSStoreSystem(WPSAPI):
system_entries, permanent_entries = self._fetch_system_entries() system_entries, permanent_entries = self._fetch_system_entries()
player_listings = self._fetch_player_listings() player_listings = self._fetch_player_listings()
return self._format_store_markdown( return self._format_store_markdown(
chat_id=chat_id,
user_id=user_id, user_id=user_id,
system_entries=system_entries, system_entries=system_entries,
permanent_entries=permanent_entries, permanent_entries=permanent_entries,
@@ -413,25 +415,63 @@ class WPSStoreSystem(WPSAPI):
system_entries, permanent_entries = self._fetch_system_entries() system_entries, permanent_entries = self._fetch_system_entries()
player_listings = self._fetch_player_listings() player_listings = self._fetch_player_listings()
target = self._resolve_system_entry(identifier, system_entries, permanent_entries) matched_system_entries = self._resolve_system_entries(
if target: identifier=identifier,
return await self._purchase_system_entry( system_entries=system_entries,
entry=target, permanent_entries=permanent_entries,
)
matched_player_listings = await self._resolve_player_listings(
identifier=identifier,
listings=player_listings,
)
if not matched_system_entries and not matched_player_listings:
return "❌ 未找到匹配的商品请确认名称或物品ID是否正确"
candidates: list[tuple[int, int, str, StoreEntry | PlayerListing]] = []
for idx, listing in enumerate(matched_player_listings):
candidates.append((listing.price, 0, f"player-{idx}", listing))
for idx, entry in enumerate(system_entries):
if entry in matched_system_entries["system"]:
candidates.append((entry.price, 1, f"system-{idx}", entry))
for idx, entry in enumerate(permanent_entries):
if entry in matched_system_entries["permanent"]:
candidates.append((entry.price, 2, f"permanent-{idx}", entry))
if not candidates:
return "❌ 未找到匹配的商品请确认名称或物品ID是否正确"
candidates.sort(key=lambda item: (item[0], item[1], item[2]))
for price, source_priority, _, payload in candidates:
if source_priority == 0:
listing = payload # type: ignore[assignment]
response = await self._purchase_player_listing(
listing=listing,
quantity=quantity,
chat_id=chat_id,
user_id=user_id,
)
if not response.startswith(""):
return response
if "库存不足" in response:
continue
return response
entry = payload # type: ignore[assignment]
response = await self._purchase_system_entry(
entry=entry,
quantity=quantity, quantity=quantity,
chat_id=chat_id, chat_id=chat_id,
user_id=user_id, user_id=user_id,
) )
if not response.startswith(""):
return response
if "库存不足" in response:
continue
return response
listing = await self._resolve_player_listing(identifier, player_listings) return "❌ 所有匹配的商品已售罄或库存不足"
if listing:
return await self._purchase_player_listing(
listing=listing,
quantity=quantity,
chat_id=chat_id,
user_id=user_id,
)
return "❌ 未找到匹配的商品请确认名称或物品ID是否正确"
async def sell_item( async def sell_item(
self, self,
@@ -440,12 +480,15 @@ class WPSStoreSystem(WPSAPI):
user_id: int, user_id: int,
identifier: str, identifier: str,
quantity: int, quantity: int,
price: int,
) -> str: ) -> str:
identifier = identifier.strip() identifier = identifier.strip()
if not identifier: if not identifier:
return "❌ 出售指令格式错误请提供物品名称或ID" return "❌ 出售指令格式错误请提供物品名称或ID"
if quantity < 0: if quantity < 0:
return "❌ 出售数量必须大于或等于0" return "❌ 出售数量必须大于或等于0"
if price < 0:
return "❌ 出售单价必须是非负整数"
backpack = Architecture.Get(WPSBackpackSystem) backpack = Architecture.Get(WPSBackpackSystem)
item_id, definition = self._resolve_item(identifier) item_id, definition = self._resolve_item(identifier)
if item_id is None: if item_id is None:
@@ -482,10 +525,6 @@ class WPSStoreSystem(WPSAPI):
elif diff < 0: elif diff < 0:
backpack.add_item(user_id, item_id, -diff) backpack.add_item(user_id, item_id, -diff)
try:
price = self._derive_player_price(item_id)
except ValueError as exc:
return f"❌ 当前物品 {definition.name} 未设置售价,无法出售({exc})"
cursor = get_db().conn.cursor() cursor = get_db().conn.cursor()
cursor.execute( cursor.execute(
f""" f"""
@@ -505,10 +544,6 @@ class WPSStoreSystem(WPSAPI):
if available_qty < quantity: if available_qty < quantity:
return f"❌ 背包数量不足,当前拥有 {available_qty}{definition.name}" return f"❌ 背包数量不足,当前拥有 {available_qty}{definition.name}"
try:
price = self._derive_player_price(item_id)
except ValueError as exc:
return f"❌ 当前物品 {definition.name} 未设置售价,无法出售({exc})"
backpack.set_item_quantity(user_id, item_id, available_qty - quantity) backpack.set_item_quantity(user_id, item_id, available_qty - quantity)
cursor = get_db().conn.cursor() cursor = get_db().conn.cursor()
@@ -532,7 +567,7 @@ class WPSStoreSystem(WPSAPI):
return """# 🛒 商店指令帮助 return """# 🛒 商店指令帮助
- `商店`:查看当前系统商品与玩家出售列表 - `商店`:查看当前系统商品与玩家出售列表
- `购买 <物品名称或ID> <数量>`:购买指定商品 - `购买 <物品名称或ID> <数量>`:购买指定商品
- `出售 <物品名称或ID> <数量>`:上架自己的出售物品(限一种) - `出售 <物品名称或ID> <数量> <单价>`:上架或更新自己的出售物品(限一种)
""" """
def _fetch_system_entries(self) -> Tuple[List[StoreEntry], List[StoreEntry]]: def _fetch_system_entries(self) -> Tuple[List[StoreEntry], List[StoreEntry]]:
@@ -582,11 +617,19 @@ class WPSStoreSystem(WPSAPI):
) )
rows = cursor.fetchall() rows = cursor.fetchall()
listings: List[PlayerListing] = [] listings: List[PlayerListing] = []
backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
for row in rows: for row in rows:
item_id = row["item_id"]
try:
definition = backpack._get_definition(item_id) # type: ignore[attr-defined]
item_name = definition.name
except Exception:
item_name = item_id
listings.append( listings.append(
PlayerListing( PlayerListing(
user_id=row["user_id"], user_id=row["user_id"],
item_id=row["item_id"], item_id=item_id,
item_name=item_name,
price=row["price"], price=row["price"],
quantity=row["quantity"], quantity=row["quantity"],
created_at=self._parse_datetime(row["created_at"]), created_at=self._parse_datetime(row["created_at"]),
@@ -598,12 +641,14 @@ class WPSStoreSystem(WPSAPI):
def _format_store_markdown( def _format_store_markdown(
self, self,
*, *,
chat_id: int,
user_id: int, user_id: int,
system_entries: List[StoreEntry], system_entries: List[StoreEntry],
permanent_entries: List[StoreEntry], permanent_entries: List[StoreEntry],
player_listings: List[PlayerListing], player_listings: List[PlayerListing],
) -> str: ) -> str:
lines: List[str] = ["# 🏬 每小时商店"] lines: List[str] = ["# 🏬 每小时商店"]
config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI)
if permanent_entries: if permanent_entries:
lines.append("## ♾️ 常驻商品") lines.append("## ♾️ 常驻商品")
for entry in permanent_entries: for entry in permanent_entries:
@@ -613,7 +658,7 @@ class WPSStoreSystem(WPSAPI):
else f"限购 {entry.limit_amount}" else f"限购 {entry.limit_amount}"
) )
lines.append( lines.append(
f"- `{entry.item_id}` · {entry.display_name}|价格 {entry.price} 分|{limit_text}" f"- {entry.display_name}|价格 {entry.price} 分|{limit_text}"
) )
if system_entries: if system_entries:
lines.append("## ⏱️ 本时段商品") lines.append("## ⏱️ 本时段商品")
@@ -623,7 +668,7 @@ class WPSStoreSystem(WPSAPI):
else: else:
stock_text = f"剩余:{entry.remaining_amount}" stock_text = f"剩余:{entry.remaining_amount}"
lines.append( lines.append(
f"- `{entry.item_id}` · {entry.display_name}|价格 {entry.price} 分|{stock_text}" f"- {entry.display_name}|价格 {entry.price} 分|{stock_text}"
) )
if not permanent_entries and not system_entries: if not permanent_entries and not system_entries:
lines.append("> ⚠️ 当前没有可售的系统商品") lines.append("> ⚠️ 当前没有可售的系统商品")
@@ -631,9 +676,11 @@ class WPSStoreSystem(WPSAPI):
lines.append("## 👥 玩家出售") lines.append("## 👥 玩家出售")
if player_listings: if player_listings:
for listing in player_listings: for listing in player_listings:
owner = "" if listing.user_id == user_id else f"玩家 {listing.user_id}" owner = ""
if listing.user_id != user_id:
owner = config_api.get_user_name(listing.user_id)
lines.append( lines.append(
f"- {owner}`{listing.item_id}`|数量 {listing.quantity}|价格 {listing.price}" f"- {owner}{listing.item_name}|数量 {listing.quantity}|价格 {listing.price}"
) )
else: else:
lines.append("> 当前暂无玩家出售信息") lines.append("> 当前暂无玩家出售信息")
@@ -689,27 +736,32 @@ class WPSStoreSystem(WPSAPI):
f"当前剩余积分:{new_points}" f"当前剩余积分:{new_points}"
) )
async def _resolve_player_listing( async def _resolve_player_listings(
self, self,
identifier: str, identifier: str,
listings: List[PlayerListing], listings: List[PlayerListing],
) -> Optional[PlayerListing]: ) -> List[PlayerListing]:
if not listings: if not listings:
return None return []
backpack = Architecture.Get(WPSBackpackSystem) backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
identifier_lower = identifier.lower() identifier_lower = identifier.lower()
matches: List[PlayerListing] = []
for listing in listings: for listing in listings:
if listing.quantity <= 0: if listing.quantity <= 0:
continue continue
if listing.item_id.lower() == identifier_lower: if listing.item_id.lower() == identifier_lower:
return listing matches.append(listing)
continue
if listing.item_name.lower() == identifier_lower:
matches.append(listing)
continue
try: try:
definition = backpack._get_definition(listing.item_id) # type: ignore[attr-defined] definition = backpack._get_definition(listing.item_id) # type: ignore[attr-defined]
except Exception: except Exception:
continue continue
if definition.name.lower() == identifier_lower: if definition.name.lower() == identifier_lower:
return listing matches.append(listing)
return None return matches
async def _purchase_player_listing( async def _purchase_player_listing(
self, self,
@@ -772,19 +824,22 @@ class WPSStoreSystem(WPSAPI):
f"当前剩余积分:{buyer_new_points}" f"当前剩余积分:{buyer_new_points}"
) )
def _resolve_system_entry( def _resolve_system_entries(
self, self,
identifier: str, identifier: str,
system_entries: List[StoreEntry], system_entries: List[StoreEntry],
permanent_entries: List[StoreEntry], permanent_entries: List[StoreEntry],
) -> Optional[StoreEntry]: ) -> Dict[str, List[StoreEntry]]:
identifier_lower = identifier.lower() identifier_lower = identifier.lower()
for entry in permanent_entries + system_entries: matched_system: List[StoreEntry] = []
if entry.item_id.lower() == identifier_lower: matched_permanent: List[StoreEntry] = []
return entry for entry in permanent_entries:
if entry.display_name.lower() == identifier_lower: if entry.item_id.lower() == identifier_lower or entry.display_name.lower() == identifier_lower:
return entry matched_permanent.append(entry)
return None for entry in system_entries:
if entry.item_id.lower() == identifier_lower or entry.display_name.lower() == identifier_lower:
matched_system.append(entry)
return {"system": matched_system, "permanent": matched_permanent}
def _get_user_listing(self, user_id: int) -> Optional[PlayerListing]: def _get_user_listing(self, user_id: int) -> Optional[PlayerListing]:
cursor = get_db().conn.cursor() cursor = get_db().conn.cursor()
@@ -799,9 +854,17 @@ class WPSStoreSystem(WPSAPI):
row = cursor.fetchone() row = cursor.fetchone()
if not row: if not row:
return None return None
item_id = row["item_id"]
backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
try:
definition = backpack._get_definition(item_id) # type: ignore[attr-defined]
item_name = definition.name
except Exception:
item_name = item_id
return PlayerListing( return PlayerListing(
user_id=row["user_id"], user_id=row["user_id"],
item_id=row["item_id"], item_id=item_id,
item_name=item_name,
price=row["price"], price=row["price"],
quantity=row["quantity"], quantity=row["quantity"],
created_at=self._parse_datetime(row["created_at"]), created_at=self._parse_datetime(row["created_at"]),
@@ -975,25 +1038,38 @@ class WPSStoreSellCommand(WPSAPI):
message = self.parse_message_after_at(message).strip() message = self.parse_message_after_at(message).strip()
if not message: if not message:
return await self._send_error( return await self._send_error(
"❌ 出售指令格式错误,请使用:`出售 <物品名称或ID> <数量>`", "❌ 出售指令格式错误,请使用:`出售 <物品名称或ID> <数量> <单价>`",
chat_id, chat_id,
user_id, user_id,
) )
tokens = [token.strip() for token in message.split() if token.strip()] tokens = [token.strip() for token in message.split() if token.strip()]
if len(tokens) < 2: if len(tokens) < 3:
return await self._send_error( return await self._send_error(
"❌ 出售指令格式错误,请使用:`出售 <物品名称或ID> <数量>`", "❌ 出售指令格式错误,请使用:`出售 <物品名称或ID> <数量> <单价>`",
chat_id, chat_id,
user_id, user_id,
) )
identifier = " ".join(tokens[:-1]).strip() identifier = " ".join(tokens[:-2]).strip()
quantity_token = tokens[-1] quantity_token = tokens[-2]
price_token = tokens[-1]
if not identifier:
return await self._send_error(
"❌ 出售指令格式错误请提供物品名称或ID",
chat_id,
user_id,
)
try: try:
quantity = int(quantity_token) quantity = int(quantity_token)
except ValueError: except ValueError:
return await self._send_error("❌ 出售数量必须是整数", chat_id, user_id) return await self._send_error("❌ 出售数量必须是整数", chat_id, user_id)
try:
price = int(price_token)
except ValueError:
return await self._send_error("❌ 出售单价必须是整数", chat_id, user_id)
if price < 0:
return await self._send_error("❌ 出售单价必须是非负整数", chat_id, user_id)
store_api = Architecture.Get(WPSStoreSystem) store_api = Architecture.Get(WPSStoreSystem)
response = await store_api.sell_item( response = await store_api.sell_item(
@@ -1001,6 +1077,7 @@ class WPSStoreSellCommand(WPSAPI):
user_id=user_id, user_id=user_id,
identifier=identifier, identifier=identifier,
quantity=quantity, quantity=quantity,
price=price,
) )
return await self.send_markdown_message(response, chat_id, user_id) return await self.send_markdown_message(response, chat_id, user_id)