feat: add local auth billing and usage management

This commit is contained in:
inman committed 2026-08-12 12:13:06 +08:00
1 parent f642b5e71f
commit 196fdde83f
119 files changed
+15695 -2650

No files matched your search

+55 -26
View File
@@ -2,7 +2,7 @@
[完整中文说明](./README.zh-CN.md)
这是 `智念AIGC平台` 的 Web 极简 MVP。当前产品只保留核心闭环:统一创作图片/视频、查看结果、局部重绘、智能超清和必要设置。
这是 `智念AIGC平台` 的 Web 极简 MVP。当前产品只保留核心闭环:统一创作图片/视频、在任务模块查看详情与下载结果,以及必要设置。
运维部署与 API 对接:
@@ -51,16 +51,33 @@ Docker 部署默认使用 `docker-compose.yml` 同时启动 Web 服务和 `zhini
## Web MVP 信息架构
- `/` 自动跳转到 `/create`
- `/create` 创作,合并图片、视频、局部重绘、智能超清
- `/assets` 结果,保留历史资产和历史生成任务
- `/image-edit` 兼容旧入口,自动跳转到创作页的局部重绘
- `/create` 创作,合并图片和视频
- `/create` 右侧任务模块,保留历史任务、详情、结果预览和下载
- `/image-edit` 兼容旧入口,自动跳转到普通创作页
- `/billing` 计费中心,组织余额、成员消耗和管理员组织上账
- `/logs` 日志,管理员可见
- `/settings` 设置,管理员可见
- `/accounts` 账号管理,管理员可见
- `/accounts` 账户安全与账号管理,所有登录用户可见;管理员额外维护组织和成员
普通用户主导航只显示创作和结果;管理员会额外看到日志、设置和账号管理。不包含工作台、项目、模板中心、Billing 或桌面端入口。
普通用户主导航显示创作、账号和计费;管理员会额外看到日志、设置和用量。账号页中的组织和成员管理仍由管理员权限控制。不包含独立结果目录、工作台、项目、模板中心或桌面端入口。
## 账户登录 / SSO
## 平台账号体系
平台不再依赖外部 OAuth2/SSO。浏览器用户统一使用手机号和密码登录,账号数据由平台自己管理:生产环境使用 Supabase/Postgres,本地开发使用 `.runtime/data/platform-accounts.json`。
平台支持超级管理员、组织管理员和普通用户三层角色。组织管理员只能管理本组织普通用户和查看组织汇总用量,不能查看日志、系统配置或管理组织生命周期;普通用户只能访问自己的创作、素材、任务和账户安全。
核心配置:`ZHINIAN_AUTH_REQUIRED`、`ZHINIAN_AUTH_SESSION_SECRET`、`NEXT_PUBLIC_SUPABASE_URL`、`SUPABASE_SERVICE_ROLE_KEY`、`ZHINIAN_DATA_DIR`。
首次部署时执行一次:
```bash
npm run bootstrap:admin -- --phone 13800138000 --password '请替换为强密码' --name '平台超级管理员'
```
旧账号迁移使用 `npm run migrate:accounts -- path/to/legacy-accounts.json`。迁移会按旧 owner ID 和手机号更新历史素材、任务、项目、模板及用量归属;外部密码不会迁移。
## 旧版外部认证(已停用)
发布环境默认要求账户登录。Web 登录支持两种方式:一是 OAuth2 Authorization Code,用户跳转到认证中心登录,本服务在 `/api/auth/callback` 后端换 token;二是在本项目登录页直接输入账号、密码和图形验证码,由本服务后端调用 `${AUTH_BASE}/oauth2/token` 的 password grant。两种方式都会通过 `${AUTH_BASE}/oauth2/jwks` 本地验签 JWT,再写入 HttpOnly 会话 cookie。
@@ -84,14 +101,14 @@ https://你的域名/api/auth/callback
- `ZHINIAN_AUTH_ISSUER=https://pig4cloud.com`
- `ZHINIAN_AUTH_PASSWORD_ENC_KEY=thanks,pig4cloud`:按认证中心 `security.encode-key` 对 password grant 的密码做 AES-CFB 加密
- `ZHINIAN_AUTH_SESSION_SECRET`:长随机字符串,用于签名本地登录态
- `ZHINIAN_ADMIN_AUTHORITIES`:逗号分隔的管理员权限码;命中后可访问 `/logs`、`/settings`、`/accounts`
- `ZHINIAN_ADMIN_AUTHORITIES`:逗号分隔的专用管理员角色精确白名单,例如 `ROLE_ADMIN,SUPER_ADMIN`
- `ZHINIAN_ADMIN_USERS=ceshiop`:逗号分隔的管理员账号;默认 `ceshiop` 是管理员
`/create`、`/assets`、`/settings`、`/logs`、`/accounts`、第一方生成/资产 API、以及本地上传和生成结果文件都会受登录态保护。`/logs`、`/settings`、`/accounts` 和 `/api/admin/*` 需要管理员权限。`/api/v1/*` 继续使用 `ZHINIAN_API_KEYS`,不走浏览器 SSO。
`/create`、`/billing`、`/settings`、`/logs`、`/accounts`、`/usage`、第一方生成/资产/用量/计费 API、以及本地上传和生成结果文件都会受登录态保护。`/logs`、`/settings`、`/usage` 和 `/api/admin/*` 要求管理员登录入口创建的会话,以及管理员账号或专用角色白名单;`/accounts` 对所有登录用户开放,普通用户只看到自己的账户信息和修改密码,管理员额外看到组织与成员管理。普通入口登录始终是普通会话,即使使用管理员账号也不会显示或开放管理功能。`ROLE_1`、`sys_user_view` 和其他通用 `SYS_*` 权限不会授予管理员访问权。`/api/v1/*` 继续使用 `ZHINIAN_API_KEYS`,不走浏览器 SSO。
如果认证中心客户端未加入 `security.ignore-clients`,`/oauth2/token` 可能返回“验证码不能为空”。普通账号登录默认使用 `custom/custom`;登录页里的“管理员登录”入口使用 `app/app`。两组 client 都需要认证中心允许 password grant。
如果认证中心客户端未加入 `security.ignore-clients`,`/oauth2/token` 可能返回“验证码不能为空”。普通账号登录默认使用 `custom/custom`;登录页里的“管理员登录”入口使用 `app/app`。两组 client 都需要认证中心允许 password grant。普通账号从管理员入口登录会收到无权限提示且不会写入会话;旧版未记录入口类型的会话统一按普通会话处理。
## 组织账号管理
## 旧版组织账号接口(已停用)
后台账号管理通过组织模块接口维护成员、角色、部门绑定和成员状态,并通过企业端用户接口创建用户、重置密码。按运维提供的组织能力接口文档,需要在服务端配置:
@@ -105,23 +122,31 @@ https://你的域名/api/auth/callback
成员分页列表通过 `hotelStaff` 的 `/adminOrganization/organizationMember/organizationMemberList` 对外代理;只有直连基础组织服务内部 `/organizationMember/organizationMemberList` 时才需要 `from: Y`。创建账号会优先调用 `/adminOrganization/organizationMember/addOrganizationMemberAndCreatePlatformUser`,密码重置调用 `/adminPcUser/resetPlatformUserPassword`;这些接口默认使用当前登录账号的 token,要求该账号具备管理员角色 `1`。
## 账号、组织用量与计费
平台用量页统计登录用户使用真实服务商后成功完成的任务;失败、取消、过期、Mock 和开放 API 客户端任务不会计入。普通用户点击页头账号 ID 查看快捷周期和最近记录;管理员通过 `/usage` 按日期、组织、账号、功能类型和服务商查看汇总、趋势及明细。
计费目录由平台维护各接口的标准成本与参数档案,超级管理员只调整上浮倍率。真实生成任务提交时按“基础标准成本 × 参数档位系数 × 任务数量 × 组合倍率”报价并从组织余额冻结,单价、参数、倍率、数量和最终金额会快照到任务;每个任务在创作结果和历史任务中显示扣费状态。普通用户余额不足时会被拒绝提交并提示“余额不足,请先充值”,不会提交服务商;超级管理员仍计算并记录生成费用,但不检查或扣减组织额度,也不产生钱包扣费、退款流水。Seedance 成功后按上游 `usage.completion_tokens` 重新结算,多退少补;没有返回用量时保留冻结金额。组织成员通过 `/billing` 查看组织余额、自己的消耗和账务流水,余额属于组织而不是个人;充值和人工余额调整也只记入组织账本,不设置个人上账归属。
当前组织余额由超级管理员直接上账,充值和人工余额调整不选择个人归属;未来接入用户自主支付时,支付成功回调自动入账,不设置人工审核队列。余额不足或未配置对应计费规则时,真实生成任务不会提交给服务商;本地 Mock 任务免计费。未绑定组织的开放 API 任务暂保持兼容,不纳入组织余额扣费。
系统首次打开超管计费中心或提交真实任务时会自动补齐平台标准价格目录,不覆盖已有目录。当前默认目录为:百炼 `wan2.7-image-pro` ¥0.50/张,百炼 `wan2.7-i2v-2026-04-25` 720P ¥0.60/秒、1080P ¥1.00/秒;火山方舟 `doubao-seedance-2-0-260128` 480P/720P/1080P/4K 分别为 ¥0.46/秒、¥0.99/秒、¥2.48/秒、¥5.05/秒;EvoLink `gpt-image-2` medium/1K/1:1/无参考图基础估算 ¥0.34/张(固定汇率 1 USD = 7.20 CNY),并列出质量、分辨率、画面比例和参考图数量档位;即梦 `jimeng_seedream46_cvtob` 暂按公开资源包折算参考 ¥0.20/张,官方实时计费以控制台为准。参数化报价按基础成本乘以所选参数档位系数,组合倍率取所选档位中的最高倍率;超管只在 `/billing` 调整倍率,标准成本和参数档案由平台维护。
任务会快照账号、租户和组织归属,用量记录不会随任务、素材或账号删除。统计统一采用 `Asia/Shanghai`,明细不展示提示词、素材或生成结果。
## 图片创作引擎
图片生成和局部重绘支持在设置页「状态」里按功能切换创作引擎:
图片生成支持在设置页「状态」里按功能切换创作引擎:
- `jimeng`:默认引擎,走火山 Visual 即梦能力。
- `evolink`:走 EvoLink GPT Image 2 中转站,提交任务后轮询 EvoLink task 结果。
- `bailian`: uses Alibaba Cloud Model Studio Wan 2.7 for text/reference image generation and image-to-video.
智能超清仍走即梦超清能力。
## 即梦图片能力
V1 接入三类能力:
V1 接入图片生成能力:
- `image.generate`:即梦图片生成 4.6,默认 `req_key=jimeng_seedream46_cvtob`
- `image.inpaint`:交互编辑 inpainting,默认 `req_key=jimeng_image2image_dream_inpaint`
- `image.upscale`:智能超清,默认 `req_key=jimeng_i2i_seed3_tilesr_cvtob`
后端统一走火山 Visual 异步任务:
@@ -132,7 +157,7 @@ V1 接入三类能力:
## EvoLink 图片能力
设置 `IMAGE_GENERATE_ENGINE=evolink` 或 `IMAGE_INPAINT_ENGINE=evolink` 后,对应功能会使用 EvoLink:
设置 `IMAGE_GENERATE_ENGINE=evolink` 后,图片生成会使用 EvoLink:
- 提交:`POST /v1/images/generations`
- 查询:`GET /v1/tasks/{task_id}`
@@ -149,8 +174,8 @@ V1 接入三类能力:
- 素材统一上传:一个入口上传图片、视频或音频,不再拆分参考图、主体、分镜等栏目。
- `@素材` 引用:上传后自动绑定为 `@图片1`、`@视频1`、`@音频1`,chip 和 @ 候选项都显示缩略图。
- 提示词校验:通过 `/api/prompt/assemble` 检查提示词中引用的素材是否已绑定。
- 工作台只负责生成输入和提交,不展示任务列表或最近结果。
- 结果保存:图片和视频生成结果会写入资产记录,并在 `/assets` 保留历史任务与历史资产。
- 任务模块:创作页右侧直接展示任务列表,点击任务可查看完整提示词、输入要素、生成参数、状态和结果。
- 结果保存:图片和视频生成结果会写入资产记录,并在任务详情和任务卡中提供预览与下载。
未配置 `SEEDANCE_API_KEY` 时,`SEEDANCE_MOCK=auto` 会自动使用旧模板样片作为 mock 成品,方便先验收工作流。
@@ -177,6 +202,8 @@ cp .env.example .env.local
- `ZHINIAN_AUTH_SESSION_SECRET`
- `ZHINIAN_ADMIN_AUTHORITIES`
- `ZHINIAN_ADMIN_USERS`
- `ZHINIAN_BILLING_REQUIRED=1`:启用真实任务组织计费;本地调试可设为 `0`
- `ZHINIAN_BILLING_ACCOUNT_NAME`、`ZHINIAN_BILLING_ACCOUNT_BANK`、`ZHINIAN_BILLING_ACCOUNT_NUMBER`、`ZHINIAN_BILLING_CONTACT`:对公收款账户信息,为未来自动支付入账预留
- `ZHINIAN_ORG_API_BASE_URL`
- `ZHINIAN_ORG_API_TOKEN`
- `ZHINIAN_STAFF_API_BASE_URL`
@@ -184,7 +211,6 @@ cp .env.example .env.local
- `ZHINIAN_ORG_TENANT_ID`
- `ZHINIAN_ORG_ID`
- `IMAGE_GENERATE_ENGINE=jimeng` 或 `evolink`
- `IMAGE_INPAINT_ENGINE=jimeng` 或 `evolink`
- `VOLCENGINE_ACCESS_KEY_ID`
- `VOLCENGINE_SECRET_ACCESS_KEY`
- `VOLCENGINE_REGION=cn-north-1`
@@ -194,14 +220,13 @@ cp .env.example .env.local
- `EVOLINK_BASE_URL=https://api.evolink.ai`
- `EVOLINK_IMAGE_MODEL=gpt-image-2`
- `EVOLINK_IMAGE_QUALITY=medium`
- `EVOLINK_IMAGE_RESOLUTION=2K`
- `EVOLINK_MOCK=auto`
- `SEEDANCE_API_KEY`
- `SEEDANCE_BASE_URL`
- `SEEDANCE_MODEL`
- `SEEDANCE_RATIO`:支持 `16:9`、`4:3`、`1:1`、`3:4`、`9:16`、`21:9`、`adaptive`
- `SEEDANCE_DURATION`:Seedance 2.0 支持 `4` 到 `15` 的整数秒,或 `-1` 让模型自动选择
- `SEEDANCE_RESOLUTION`:支持 `480p`、`720p`、`1080p`;Seedance 2.0 fast 不支持 `1080p`
- `SEEDANCE_RESOLUTION`:支持 `480p`、`720p`、`1080p`、`4k`;Seedance 2.0 fast 不支持 `1080p`
- `SEEDANCE_MOCK`
- `ALI_OSS_*`:用于上传素材和生成结果转存
- `NEXT_PUBLIC_SUPABASE_URL`
@@ -218,11 +243,16 @@ Supabase/Postgres 表结构在:
supabase/schema.sql
```
升级已启用 Supabase 的部署时,先在 Supabase SQL Editor 重新执行该幂等脚本。它会迁移用量快照字段、按 `job_id` 去重历史记录,并解除任务删除对用量记录的级联删除。
当前仍保留必要数据表,供上传、生成任务和用量记录使用:
- `assets`
- `generation_jobs`
- `usage_events`
- `billing_price_rules`
- `billing_wallets`
- `billing_ledger`
## 任务管理与开放 API
@@ -258,8 +288,6 @@ ZHINIAN_INTERNAL_WORKER_TOKEN=change-me-worker-token
- `GET /api/generations/image`
- `GET /api/generations/image/[id]`
- `POST /api/generations/image/[id]/retry`
- `POST /api/assets/[id]/inpaint`
- `POST /api/assets/[id]/upscale`
- `POST /api/generations/video`
- `GET /api/generations/video`
- `GET /api/generations/video/[id]`
@@ -276,7 +304,8 @@ ZHINIAN_INTERNAL_WORKER_TOKEN=change-me-worker-token
当前已覆盖:
- 即梦能力矩阵:4.6/inpainting/upscale 启用
- 即梦能力矩阵:图片生成启用
- 组织钱包、计费规则、管理员上账和扣费幂等流水
- 即梦请求参数构造
- 分镜提示词与 `@素材` 引用编排
- 火山 Visual 签名 canonical request