discord.py经济系统商店分页功能(每页5件商品)实现咨询
Discord商店模块分页功能修复方案
原有代码核心问题
- 分页总数计算错误:原代码按每页3个计算总页数,不符合每页5个商品的需求
- 价格格式化逻辑缺陷:仅对第一页前5个商品做千分位处理,其他页商品价格未格式化
- 分页切片逻辑写死:仅支持最多2页展示,商品超过10个时无法正常展示后续内容
- 反应校验逻辑错误:check函数返回值为元组,无法正确过滤用户的点击操作
- 页码边界判断错误:左翻页时允许页码降到0,不符合正常分页逻辑
- 正则语法错误:千分位格式化的正则缺少闭合括号,运行会直接报错
修复后完整代码
import json import re import asyncio import discord from discord.ext import commands # 类定义省略,直接给出修正后的shop命令 @commands.command(aliases=['mall', 'store']) async def shop(self, ctx, cur_page: int = 1): # 读取商店和服务器配置 with open(f'json/servers/{ctx.guild.id}/Shop.json', 'r', encoding='utf-8') as f: shop = json.load(f) with open(f'json/servers/{ctx.guild.id}/{ctx.guild.id}-Server.json', 'r', encoding='utf-8') as f: server_data = json.load(f) currency = server_data["currency"] # 基础分页参数计算 item_list = list(shop.keys()) total_items = len(item_list) per_page = 5 total_page = -(-total_items // per_page) # 向上取整计算总页数 # 页码边界校正 if cur_page < 1: cur_page = 1 elif cur_page > total_page: cur_page = total_page # 生成当前页商品内容 def generate_page_content(page): start = (page - 1) * per_page end = start + per_page current_items = item_list[start:end] content = "" for item_id in current_items: item = shop[item_id] # 千分位格式化价格,补全正则闭合括号 price = re.sub(r"(?<!^)(?=(\d{3})+$)", r",", item["PRICE"]) emoji = item["EMOJI"] if item["EMOJI"] != "None" else "" content += f'{emoji} **{item["NAME"]}** `ID: {item_id}` ─ __{price}__ {currency}\n{item["DESCRIPTION"]}\n\n' return content # 生成初始Embed embed = discord.Embed( description=f'¡Bienvenido a la tienda!\nUsa **`{ctx.prefix}buy <item>`** para comprar y **`{ctx.prefix}iteminfo <item>`** para mas información.\n\n{generate_page_content(cur_page)}', color=0x007fff ) embed.set_author(name=f"Tienda de {ctx.guild.name}", icon_url=ctx.guild.icon.url) embed.set_footer(text=f"Paginas: {cur_page}/{total_page}") msg = await ctx.reply(embed=embed, mention_author=False) # 商品不足1页无需加反应 if total_page <= 1: return # 添加翻页反应 await msg.add_reaction("⬅️") await msg.add_reaction("⏸️") await msg.add_reaction("➡️") # 反应校验规则 def check(reaction, user): return not user.bot and user == ctx.author and str(reaction.emoji) in ['⬅️', '⏸️', '➡️'] # 监听翻页操作 while True: try: reaction, user = await self.bot.wait_for('reaction_add', timeout=300, check=check) except asyncio.TimeoutError: await msg.clear_reactions() break if reaction.emoji == '➡️' and cur_page < total_page: cur_page += 1 elif reaction.emoji == '⬅️' and cur_page > 1: cur_page -= 1 elif reaction.emoji == '⏸️': await msg.clear_reactions() break else: await msg.remove_reaction(reaction, user) continue # 更新Embed内容 new_embed = discord.Embed( description=f'¡Bienvenido a la tienda!\nUsa **`{ctx.prefix}buy <item>`** para comprar y **`{ctx.prefix}iteminfo <item>`** para mas información.\n\n{generate_page_content(cur_page)}', color=0x007fff ) new_embed.set_author(name=f"Tienda de {ctx.guild.name}", icon_url=ctx.guild.icon.url) new_embed.set_footer(text=f"Paginas: {cur_page}/{total_page}") await msg.edit(embed=new_embed) await msg.remove_reaction(reaction, user)
功能说明
修复后的代码支持:
- 每页固定展示5个商品,总页数随商品数量自动计算
- 超过1页自动添加翻页反应,不足1页不显示多余操作
- 页码边界自动校正,不会出现0页或超过总页数的异常情况
- 所有商品价格统一做千分位格式化,逻辑统一
- 5分钟无操作自动清除反应,避免占用资源
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

