- 群聊命令「签到」(别名: 每日签到/打卡),白名单群聊或管理员可用 - 复用 xapi /bot/gacha/sign-in + /bot/points/add,与抽卡/WPF 共用 bot_gacha_daily_sign_in 表 - 积分随机 1-100,流水沿用 gacha_sign/抽卡签到;先到先得,重复签到提示已签到 - 新增 10 个单元测试,ruff 通过;更新 PLUGINS.md / README.md
7.2 KiB
7.2 KiB
独立每日签到插件(与抽卡签到共用数据)
Goal
在 danding-bot 中新增独立「签到」插件:用户发送「签到」命令即可完成每日签到并领取积分;抽卡插件(onmyoji_gacha)的「抽卡后自动签到」保持原功能不变;两个入口与 WPF 客户端共用同一份签到数据(xapi bot_gacha_daily_sign_in 表,每用户每天一条,先到先得)。
What I already know
- 签到数据唯一权威源:xapi DanDing 库
bot_gacha_daily_sign_in表,UNIQUE(bot_user_id, sign_date),WPF 与 QQ Bot 已共用(xapidocs/bot-api.mdL126、Application/Bot/gacha_router.pyL203-284、Application/DanDing/wpf_gacha.pyL183-226)。 - QQ 抽卡签到现状:
onmyoji_gacha插件在抽卡/三连抽成功后调用POST /bot/gacha/sign-in(Body: user/token/user_id/points_awarded → data: {success, signed_already, signed_today, sign_date, points_awarded})记录签到,再调用/bot/points/add发积分(source=gacha_sign,reason=抽卡签到,随机 1-100 分)。 - WPF 签到:
POST /DD/gacha/sign-in在同一事务内写签到记录 + 发 Bot 积分(BOT_GACHA_WPF_SIGN_IN_POINTS默认 20,source=gacha_sign,reason=抽卡签到)。重复签到返回signed_already=true且不重复发积分。 - xapi 无
GET /bot/gacha/sign-in状态查询路由(只有内部 helper),但写接口返回signed_already,重复签到可直接提示"今天已签到"。 - 客户端 HTTP 封装已有现成模式:
onmyoji_gacha/data_manager.py(DataManager._request 模式)与danding_points/api.py(PointsAPI.add_points → POST /bot/points/add)。 - 权限模式:
onmyoji_gacha用白名单(ALLOWED_GROUP_ID=621016172 / ALLOWED_USER_ID=1424473282)的 check_permission Rule。 - 本任务不需要改 xapi(复用现有
/bot/gacha/sign-in+/bot/points/add即可实现共用数据),不涉及跨端契约新增。
Requirements
- 新增独立签到插件(目录
danding_bot/plugins/sign_in/) - 群聊命令「签到」(别名:每日签到、打卡),白名单权限(ALLOWED_GROUP_ID / ALLOWED_USER_ID,与抽卡一致)
- 命令触发签到:调用 xapi
POST /bot/gacha/sign-in记录签到,成功后调用/bot/points/add发放积分 - 积分规则:随机 1-100(与抽卡签到一致)
- 积分流水 source=
gacha_sign、reason=抽卡签到(沿用现有标记,与 WPF/抽卡共用事件语义) - 重复签到(signed_already=true):提示"今天已签到",不发积分
- onmyoji_gacha 抽卡签到保持现状,不做任何改动
- 不新增「签到状态」查询命令(保持最小范围;重复签到提示利用响应自带的 sign_date/points_awarded)
- 更新 PLUGINS.md / README.md 文档
Acceptance Criteria
- 发送「签到」:首次签到成功,返回签到成功 + 积分 + 当前余额
- 同一天再次「签到」:提示已签到,不重复发积分
- 抽卡签到与新命令签到互斥(共用 daily_sign_in 去重),先到先得:先抽卡后命令 → 命令提示已签到;先命令后抽卡 → 抽卡不重复发积分(抽卡插件原有逻辑已处理)
- 权限:白名单外的群/用户收到无权限提示(Rule 拒绝后命令不触发)
- 测试覆盖(10 个 unit tests,mock xapi aiohttp 调用,全部通过)
- ruff lint 通过(新文件 0 违规)
实现状态(2026-08-16)
- 已实现:
danding_bot/plugins/danding_sign_in/(init/config/api/service/rules 5 文件) - 已实现:
tests/test_danding_sign_in_plugin.py(10 用例全绿) - 已更新文档:PLUGINS.md(新增 #14 + 抽卡章节交叉引用)、README.md(新增 #8)
- 测试环境:无 conda bot 环境,用 xapi env(pytest 9.0.2 + aiohttp + pydantic 2.13)跑通;无 nonebot 环境,rules.py 采用延迟导入 nonebot 保证可测
- 代码复用决策:编排逻辑(先记录后发积分)未从 onmyoji_gacha 复制,而是自包含实现同模式 —— 避免 import onmyoji_gacha 包触发其 init matcher/路由注册耦合;若将来出现第 3 个签到入口,再提取共享模块(规则三)
- 既有测试套件:72 通过 + 1 失败(test_danding_qqpush_article_render 中文编码问题,与本任务无关,环境性失败)
Definition of Done (team quality bar)
- Tests added/updated (unit/integration where appropriate)
- Lint / typecheck / CI green
- Docs/notes updated if behavior changes
- Rollout/rollback considered if risky
Technical Approach
- 新插件
danding_bot/plugins/sign_in/,模块结构仿照现有插件惯例:__init__.py:NoneBot matcher 注册(on_command("签到", aliases={每日签到, 打卡}, priority=5, rule=check_permission()))+ handlerconfig.py:Pydantic 配置(API host/token/白名单/积分区间,复用 onmyoji_gacha 配置命名惯例)api.py:xapi 客户端(封装POST /bot/gacha/sign-in,仿 DataManager._request 模式)service.py或直接编排:记录签到 → 发积分 → 格式化消息(先记录后发积分,避免重复发积分,复用onmyoji_gacha/sign_in.py的 award_daily_sign_in_points 模式)
- 数据共用:直接调用与抽卡插件相同的 xapi 端点(
/bot/gacha/sign-in+/bot/points/add),天然共用bot_gacha_daily_sign_in表,无需改动 onmyoji_gacha 插件。 - 可复用现有代码:
points_api(danding_points/api.py 的 PointsAPI)直接 import;签到编排可直接复用onmyoji_gacha/sign_in.py的award_daily_sign_in_points(或独立实现同模式)。 - 测试:
tests/test_sign_in_plugin.py,仿tests/test_onmyoji_gacha_http_api.py的 FakeSession/FakeResponse 模式 mock aiohttp。
Decision (ADR-lite)
Context: 用户需要独立签到命令,且与抽卡签到共用数据、不破坏抽卡签到。
Decision: 新插件复用 xapi 现有 /bot/gacha/sign-in + /bot/points/add 端点(与抽卡插件同源),数据自然共用;积分 source/reason 沿用 gacha_sign/抽卡签到;命令仅群聊 + 白名单;积分随机 1-100。
Consequences: 零 xapi 改动、零契约新增;抽卡插件零改动(回归风险最低);流水无法区分签到触发入口(可接受,因为每天只有一次签到);「签到状态/连续天数」查询能力暂缺,后续需要时另开任务(契约先行)。
Out of Scope
- 不改 xapi(无新增端点)
- 不做签到排行榜/连续签到统计/签到状态查询命令
- 不迁移签到数据表位置
- 不改 onmyoji_gacha 抽卡签到逻辑
Technical Notes
- xapi 契约:
C:\Users\14244\source\repos\Danding_Webs\xapi_new_web\docs\bot-api.mdL114-126 - 表结构:
bot_gacha_daily_sign_in(migrations/DanDing/013_create_bot_data_migration_tables.py L99-109) - 客户端参考:
danding_bot/plugins/onmyoji_gacha/data_manager.py(_request 模式)、danding_bot/plugins/onmyoji_gacha/sign_in.py(先记录后发积分编排)、danding_bot/plugins/danding_points/api.py(PointsAPI.add_points) - 测试模式参考:
tests/test_onmyoji_gacha_http_api.py(FakeSession/FakeResponse mock aiohttp) - 任务创建于 2026-08-16(Trellis 自动加日期前缀)