You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:48:03