Skip to content

v0.0.11 — 在线充值(topup)全链路打通 ​

用户可在控制台「我的余额」卡片直接发起在线充值,复用同一套微信 / 支付宝支付通道;后台新增独立的「充值」设置 Tab,管理员可配置快捷金额、自定义金额与换算比例;同步沉淀《AGENTS.md》开发规范并更新全语种 README。

中文 ​

✨ 新增功能 ​

后端(Go) ​

  • 新增「在线充值」业务模块(OrderTypeTopup=2):
    • 新增 model/topup.go,定义 TopupPreset、CreateTopupOrderInput、TopupOrderPlanInfo 等结构,提供 CreateTopupOrder、ActivateTopupByOrder、ResolveTopupAmount、GetTopupSettings、SaveTopupSettings 等业务函数。
    • 复用 GenerateOrderNo("TP") 生成充值订单号(TP 前缀),写入与套餐订单同一张 orders 表的 type=2 记录,节省一张表。
    • ActivateTopupByOrder 幂等:订单已支付直接返回;激活时调 IncreaseUserQuota 加额度并 RecordTopupLog,TODO 标注退款时不回退 quota(待统一订单管理上线)。
    • 启动时通过 model.AutoMigrate 自动建表,无需手写 DDL。
  • 新增充值系统设置键(model/system_setting.go):
    • topup.enabled(总开关)、topup.allow_custom(是否允许自定义金额)、topup.presets(JSON 数组:[{amount, bonus_quota}, ...])、topup.exchange_rate(默认 1,1 元 = = 1 quota,仅作用于自定义金额)。
    • 分类常量 SystemSettingCategoryTopup = "topup"。
  • 新增 HTTP 接口:
    • POST /api/topup/order(CreateTopupOrder,用户认证):参数 { amount, preset_amount, pay_method },前置校验开关 / 通道 / 金额,命中预设或自定义规则后写订单,复用 controller/buildPayInfo 拿 pay_url / qr_code。
    • GET /api/setting/topup 与 PUT /api/setting/topup(GetTopupSettings / PutTopupSettings,Root 权限):读写上述 4 个 key。
  • 支付回调按订单类型分发(controller/payment.go::processNotify):
    • order.Type == OrderTypeTopup → 调 ActivateTopupByOrder 给用户加 quota;
    • 其余 → 调 ActivatePackageByOrder 激活套餐。
    • MockPay(admin 测试接口)同步按 type 分发,提示文案分别显示「余额已到账」/「套餐已激活」。

前端(web/default-pro/) ​

  • 新增可复用组件 components/TopupModal.vue:
    • props:modelValue、settings、title;emits:update:modelValue、success、error、pay。
    • 顶部「选择金额」chip 列表:依次渲染所有 settings.presets,最后一个 chip 固定为「自定义」(当 settings.allow_custom=true 时显示),点击后才显示金额输入框。
    • 中部支付方式选择器(pay-picker-item 微信 #07C160 / 支付宝 #1677FF 官方品牌色),复用 Plans.vue 既有样式。
    • 底部「支付金额」+「确认充值」按钮;选中自定义但未填金额时禁用提交。
  • 新增设置页 views/setting/TopupSetting.vue(root 可见):表单竖排三段:①总开关(enabled)②允许自定义金额(allow_custom)③自定义金额 1 元 = X quota(exchange_rate,默认 1);快捷金额用 <a-table> 行行内编辑(amount / bonus_quota),支持新增 / 删除;提交前前端预校验金额重复(validateTopupPresets)。
  • 新增路由 /setting/topup:router/index.js 注册子路由,Setting.vue 菜单新增「充值」项(root 可见,icon icon-subscribe-add)。
  • 新增 api/topup.js:topupApi.createOrder({ amount, preset_amount, pay_method })。
  • 扩展 api/setting.js:getTopup() / putTopup(data)。
  • 新增 utils/topup.js 纯函数工具:formatNumber / formatAmount / validateTopupPresets / calcCustomBonus,可在 Node 环境下用 node:test 单测。
  • 仪表盘接入充值弹窗:
    • 控制台 Dashboard.vue 余额卡的「充值」按钮改为弹出 TopupModal,点击前预拉 /api/setting/topup + /api/payment/status,任一失败给出明确 toast;<a-modal> 使用 :visible + @update:visible(踩坑修复:曾误用 :model-value,导致弹窗永远不显示)。
    • 同时弹出二维码 / 转账信息 <a-modal,刷新余额(/api/user/self)。
  • 订单管理表格新增「订单类型」列(Orders.vue):套餐 / 充值 两种两色 chip(type-plan 蓝 / type-topup 橙),方便用户区分。
  • 移除运营 Tab 内的「允许余额充值」占位开关(OperationSetting.vue):该字段已迁移到新充值 Tab,UI 与后端 GetPlanSettings / PutPlanSettings 同步删除读写;DB 中旧 plan.allow_topup 行保留无害。
  • 修复套餐界面硬编码套餐名白名单(Plans.vue):删除 VALID_PLAN_NAMES = ['lite','air','pro','max'] 过滤逻辑,改为显示后端返回的所有套餐(用户反映该过滤导致测试套餐不可见)。

🐛 问题修复 ​

  • 修复仪表盘充值按钮点击无反应:原 <TopupModal> 在 TopupModal.vue 内部把 arco <a-modal> 的可见性绑定到了 :model-value,而 arco 的 <a-modal> 可见性属性是 visible,导致 v-model="topupModalVisible=true 时弹窗永远不显示。已改为 :visible="modelValue" + @update:visible="(v) => emit('update:modelValue', v)"。
  • 修复充值按钮缓存导致的「管理员开启充值但仪表盘无反应」:原代码仅在 topupSettings.value 为 null 时拉取一次,admin 刚开启充值但仪表盘缓存旧值时按钮不会再次请求。已改为每次点击都强制重新拉取 /api/setting/topup,并把错误提示文案改成「请联系管理员在「设置-充值」中开启」。
  • 修复 <a-spin> 在 TopupSetting 设置页父容器宽度异常:补齐 style="width: 100%"。
  • 修复 TopupSetting 表单横排三列不对齐:改为 layout="vertical" 三段竖排。

🚀 数据完整性 ​

  • 快捷金额金额不能重复:后端 model.SaveTopupSettings 用 seenAmounts map 检测重复金额,重复时返回「快捷金额重复:XX 元已存在」并整体拒绝保存;前端 utils/topup.js::validateTopupPresets 提前预校验,避免一次无效请求。

📚 文档 ​

  • 新增项目根目录 AGENTS.md(480 行):面向 Agent / 贡献者的开发规范速查,覆盖 TL;DR / 项目结构 / 开发环境 / 提交规范(Conventional Commits + 中英双语 body + 一文件一 commit 粒度)/ 版本号 / 命名(topup 全局统一)/ 注释约定(文件级 4 行注释 + 导出符号注释 + TODO/XXX + 修改时如何更新)/ 后端规范(响应格式、model 不依赖 Gin、订单号前缀 TB/UP/TP)/ 前端规范(arco <a-modal> 用 :visible 而非 :model-value、<a-spin> 必须 style="width:100%"、工具函数用 node:test)/ 数据库 / 踩坑清单 / 工作流程(先 Plan 模式输出方案再编码)。
  • 同步更新 README.md 与 7 个语言版本(readme/README.{en,zh-TW,ja,ko,ar,de,ru}.md):新增「💰 在线充值(余额)」功能亮点章节;订单与支付章节补充订单类型列 + processNotify 分发说明;开发计划「在线充值」「充值设置中心」从规划移入已完成,新增「充值退款闭环」为进行中。

🔧 重构 ​

  • 移除运营 Tab 的 plan.allow_topup 字段读写(controller/setting_payment.go):精简 GetPlanSettings / PutPlanSettings 返回结构,DB 行保留(不会主动删除)。
  • 清理调试日志:移除为排查充值按钮不响应问题加在 Dashboard.vue::onRechargeClick 的 console.log。

⚠️ 升级注意事项 ​

  • 数据库迁移:新增 4 个 system_settings 键(topup.enabled / topup.allow_custom / topup.presets / topup.exchange_rate),无需迁移脚本,AutoMigrate + 首次调用会按需写入。
  • orders 表复用:本次新增 type=2 的充值订单与既有 type=1 套餐订单存同一张表,无 DDL 变更。
  • 运营 Tab 「套餐运营」小节:UI 上不再有「允许余额充值(仅占位)」开关;如需启用充值,请进入设置 → 充值。
  • 充值功能默认关闭(topup.enabled 未设置时为 false),管理员需到「设置 → 充值」手动开启并配置至少 1 个 preset 或允许自定义金额,前端充值按钮才会触发弹窗。
  • 退款:本期不支持;充值订单 status=3 仅标记,quota 不回退,待统一订单管理上线后补全。
  • 前端构建:新增依赖 qrcode(已在 pnpm-lock.yaml),建议 pnpm install && npm run build 后发布。