Skip to content

feat(subscription): 新增总额度订阅类型支持#1904

Open
MoRan23 wants to merge 41 commits into
Wei-Shaw:mainfrom
MoRan23:main
Open

feat(subscription): 新增总额度订阅类型支持#1904
MoRan23 wants to merge 41 commits into
Wei-Shaw:mainfrom
MoRan23:main

Conversation

@MoRan23

@MoRan23 MoRan23 commented Apr 24, 2026

Copy link
Copy Markdown

变更说明

本 PR 主要新增了 总额度订阅类型(total_quota 的支持,覆盖了数据库结构、订阅分配、额度消费、请求校验、事件清理以及前端展示链路。

和现有按日 / 周 / 月窗口累计的订阅模式不同,total_quota 通过 quota event 记录和管理一笔或多笔可累计的总额度,并在请求生命周期中按事件顺序消费额度。

目的

为 Sub2API 添加在指定订阅时间内,可用的总额度类型的订阅支持,如24h内总额100$,将不随窗口刷新。

本次改动

  • 新增 total_quota 订阅类型

    • 新增分组订阅类型 total_quota
    • 支持配置 total_limit_usd
    • 补齐前后端类型与接口字段
  • 新增总额度事件模型

    • 新增 user_subscription_quota_events
    • 新增对应 Ent schema / repository / service 逻辑
    • 支持记录额度总量、已用额度、起止时间、来源信息
  • 支持总额度订阅的创建与追加

    • 首次分配时创建 total quota 订阅
    • 已存在 total quota 订阅时,追加新的 quota event,而不是覆盖原额度
    • 保持分配逻辑幂等,避免重复发放
  • 接入总额度消费链路

    • 在请求计费链路中按 quota event 消费总额度
    • API Key 鉴权阶段支持 total quota 订阅额度校验
    • 对齐请求前校验与请求后扣费行为,减少生命周期不一致问题
  • 完善 quota event 生命周期管理

    • 追加新额度事件时,退役已耗尽的旧事件
    • 增加过期 quota event 的批量清理
    • 新增 quota summary 聚合,支持剩余额度 / 已用额度 / 最近即将过期额度展示
  • 修复 total quota 相关边界问题

    • 保留 total quota 分组下空限制字段语义,避免更新时被错误覆盖
    • 限制不适用于 total quota 的手动调整 / reset 行为,避免语义混乱
  • 补充前端支持

    • 管理端分组页支持配置 total_quota
    • 管理端 / 用户端订阅页支持展示总额度进度
    • 兑换页与相关展示页支持 total_quota 分组展示

行为

  • 创建

    • 在创建分组时,除余额、订阅之外,会显示总额度订阅。要求输入限制的总额度。
  • 分配

    • 允许管理员分配以及用户自行进行兑换码兑换。
    • 无法进行订阅时间调整、额度重置。
  • 计费

    • 每单次的订阅事件将会单独计算,用户同时使用多个同类订阅将会创建多个订阅事件,扣费时按照先后进行扣费,并会惰性的清理过期的订阅事件。
    • 如果用户在到期事件前未消耗完全额度,将被清除剩余额度,在多订阅事件中的表现为减去总额度。
  • ui

    • 前端将显示最近一次过期时间点将过期多少额度。

测试

已执行:

go test ./internal/service ./internal/repository ./internal/server ./internal/server/middleware
go test -tags=unit ./...
go test -tags=integration ./...

pnpm --dir frontend run lint:check
pnpm --dir frontend run typecheck

且在自建中转已稳定运行一段时间

hesklso2 added 30 commits April 20, 2026 11:55
# Conflicts:
#	backend/internal/service/openai_images.go
#	frontend/src/views/admin/GroupsView.vue
# Conflicts:
#	backend/ent/client.go
#	backend/ent/ent.go
#	backend/ent/mutation.go
# Conflicts:
#	backend/ent/group.go
#	backend/ent/migrate/schema.go
#	backend/ent/mutation.go
#	backend/ent/runtime/runtime.go
#	backend/internal/handler/admin/group_handler.go
#	backend/internal/handler/dto/mappers.go
#	backend/internal/repository/api_key_repo.go
#	backend/internal/repository/group_repo.go
#	backend/internal/service/admin_service.go
#	frontend/src/types/index.ts
#	frontend/src/views/admin/GroupsView.vue
# Conflicts:
#	backend/ent/client.go
hesklso2 added 11 commits June 22, 2026 17:43
# Conflicts:
#	backend/internal/repository/user_subscription_repo.go
# Conflicts:
#	backend/ent/group.go
#	backend/ent/migrate/schema.go
#	backend/ent/runtime/runtime.go
#	backend/internal/handler/admin/group_handler.go
#	backend/internal/service/admin_service.go
#	backend/internal/service/subscription_expiry_service_test.go
#	backend/internal/service/subscription_service.go
#	frontend/src/views/admin/GroupsView.vue
# Conflicts:
#	backend/ent/client.go
#	backend/ent/group.go
#	backend/ent/migrate/schema.go
#	backend/ent/mutation.go
#	backend/ent/runtime/runtime.go
#	backend/internal/service/admin_service.go
#	backend/internal/service/gateway_service.go
#	backend/internal/service/setting_service.go
#	frontend/src/i18n/locales/en.ts
#	frontend/src/i18n/locales/zh.ts
#	frontend/src/views/admin/GroupsView.vue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants