Merge branch 'main' of https://github.com/ddcat-ai/open-ai-canvas
Some checks failed
Publish container images / Quality checks (push) Has been cancelled
Publish container images / Resolve build version (push) Has been cancelled
Publish container images / Build open-ai-canvas-backend (amd64) (push) Has been cancelled
Publish container images / Build open-ai-canvas-backend (arm64) (push) Has been cancelled
Publish container images / Build open-ai-canvas-web (multi) (push) Has been cancelled
Publish container images / Build open-ai-canvas-yingce-agent (multi) (push) Has been cancelled
Publish container images / Publish open-ai-canvas-backend manifest (push) Has been cancelled
Publish container images / Publish open-ai-canvas-web manifest (push) Has been cancelled
Publish container images / Publish open-ai-canvas-yingce-agent manifest (push) Has been cancelled
Publish container images / Publish release assets (push) Has been cancelled

This commit is contained in:
2026-10-14 16:28:42 +08:00
573 changed files with 129685 additions and 3164 deletions

View File

@@ -45,7 +45,9 @@ Schema 45 新增 `upload_reservations`:`id`、`user_id`、`size`、`day`、`ex
`auth_sessions.reauthenticated_at` 记录当前会话的 Linux.do 重新核验时间,有效 5 分钟;`o_auth_states.reauth_user_id/reauth_session_id` 绑定发起重新核验的账号及会话。重新核验只允许原绑定的第三方身份,不创建账号或新登录会话。`auth_verifications.session_id/credential_hash` 将 `profile_email` 用途的验证码绑定到当前用户、当前会话和密码状态。密码、邮箱修改及旧会话撤销在同一事务提交;登录会话签发同时检查账号凭据,阻止并发旧密码登录在撤销之后再创建会话。升级执行 `migrate-schema up` / `verify`,禁止手工修改既有迁移记录。
当前结构版本为 53;版本 53 新增独立登录日志表 `login_logs`,详见本页“用户登录日志”。版本 50 新增 `canvas_mutation_receipts`,按 `(user_id, canvas_id, mutation_id)` 唯一记录画布 operations 请求摘要、确定性结果和提交 revision,供响应丢失后的幂等重放使用;receipt 与画布内容、revision 在同一事务提交。版本 49 `banner_sort_order` 为 `banner_announcements` 增加可配置的 `sort_order` 展示顺序;版本 48 `channel_proxy_url` 为 `model_channels` 增加渠道级出站代理地址 `proxy_url`,支持 `socks5://`、`http://`、`https://`;留空时沿用全局代理。代理地址只返回管理员视图,普通用户目录不暴露渠道代理或其中的认证信息。版本 42 `cloud_agent_pi_sessions` 新增 `cloud_agent_pi_sessions` 表,按运行 ID 保存 Pi 原生 JSONL 会话快照、用户 ID、乐观并发 revision 和更新时间;会话正文由 Agent runtime 管理,Go 只将其作为不透明快照读写,不替代有界控制检查点、事件日志或任务记录。版本 41 `resource_thumbnail` 为 `resources` 增加缩略图元数据。版本 40 `builtin_skill_tombstones` 新增内置技能删除记录,管理员删除平台技能后,后续启动同步不会重新创建该技能;版本 39 `skill_library_categories` 新增 `skill_library_categories` 表,并为 `user_skill_states` 增加 `library_category_id`,保存个人技能库分类及每个用户对技能的归类;分类不改变 `skills.tag` 的技能广场共享分类。版本 38 `prefixed_id_sequence_reconcile` 创建(若缺失)并校准 `id_sequences`:`CHANNEL`、`MODEL`、`PTIER`、`ATTEMPT`、`LMODEL`、`REVISION`、`ROUTE` 按对应业务表的最大有效 ID 前移,包含软删除记录,不回退已有序列、不重写业务 ID。分配新 ID 时再次校准并检查冲突;SQLite → PostgreSQL 迁移完成后也校准序列。 `cloud_agent_gemini_cache` 创建 `cloud_agent_gemini_caches`,保存用户范围内的官方 Gemini 缓存元数据;版本 37 `cloud_agent_gemini_cache_identity` 将缓存标识约束修正为 `(user_id, cache_key)`,移除旧的全局 cache_key 唯一索引。版本 35 `auth_notifications` 为认证通知与组合验证补齐 `auth_verifications`、`notification_quotas`、`sms_channels`、`sms_records` 四张表,并为 `users` 增加 `phone`、`email_verified_at`、`phone_verified_at`,为 `email_verification_codes` 增加 `attempts`;同时创建非空手机号唯一索引。版本 34 `task_media_recovery` 为 `tasks` 增加 `media_recovery_json`(text)和 `media_stage`(最长 24 字)。版本 33 `oauth_state_accepted_terms` 为 `o_auth_states` 增加非空布尔列 `accepted_terms`,默认 `false`,不替历史流程补造同意记录。
当前结构版本为 54;版本 53 新增独立登录日志表 `login_logs`,详见本页“用户登录日志”。版本 50 新增 `canvas_mutation_receipts`,按 `(user_id, canvas_id, mutation_id)` 唯一记录画布 operations 请求摘要、确定性结果和提交 revision,供响应丢失后的幂等重放使用;receipt 与画布内容、revision 在同一事务提交。版本 49 `banner_sort_order` 为 `banner_announcements` 增加可配置的 `sort_order` 展示顺序;版本 48 `channel_proxy_url` 为 `model_channels` 增加渠道级出站代理地址 `proxy_url`,支持 `socks5://`、`http://`、`https://`;留空时沿用全局代理。代理地址只返回管理员视图,普通用户目录不暴露渠道代理或其中的认证信息。版本 42 `cloud_agent_pi_sessions` 新增 `cloud_agent_pi_sessions` 表,按运行 ID 保存 Pi 原生 JSONL 会话快照、用户 ID、乐观并发 revision 和更新时间;会话正文由 Agent runtime 管理,Go 只将其作为不透明快照读写,不替代有界控制检查点、事件日志或任务记录。版本 41 `resource_thumbnail` 为 `resources` 增加缩略图元数据。版本 40 `builtin_skill_tombstones` 新增内置技能删除记录,管理员删除平台技能后,后续启动同步不会重新创建该技能;版本 39 `skill_library_categories` 新增 `skill_library_categories` 表,并为 `user_skill_states` 增加 `library_category_id`,保存个人技能库分类及每个用户对技能的归类;分类不改变 `skills.tag` 的技能广场共享分类。版本 38 `prefixed_id_sequence_reconcile` 创建(若缺失)并校准 `id_sequences`:`CHANNEL`、`MODEL`、`PTIER`、`ATTEMPT`、`LMODEL`、`REVISION`、`ROUTE` 按对应业务表的最大有效 ID 前移,包含软删除记录,不回退已有序列、不重写业务 ID。分配新 ID 时再次校准并检查冲突;SQLite → PostgreSQL 迁移完成后也校准序列。 `cloud_agent_gemini_cache` 创建 `cloud_agent_gemini_caches`,保存用户范围内的官方 Gemini 缓存元数据;版本 37 `cloud_agent_gemini_cache_identity` 将缓存标识约束修正为 `(user_id, cache_key)`,移除旧的全局 cache_key 唯一索引。版本 35 `auth_notifications` 为认证通知与组合验证补齐 `auth_verifications`、`notification_quotas`、`sms_channels`、`sms_records` 四张表,并为 `users` 增加 `phone`、`email_verified_at`、`phone_verified_at`,为 `email_verification_codes` 增加 `attempts`;同时创建非空手机号唯一索引。版本 34 `task_media_recovery` 为 `tasks` 增加 `media_recovery_json`(text)和 `media_stage`(最长 24 字)。版本 33 `oauth_state_accepted_terms` 为 `o_auth_states` 增加非空布尔列 `accepted_terms`,默认 `false`,不替历史流程补造同意记录。
版本 54 `workbench_tools_and_presets` 新增 `workbench_tools` 与 `workbench_presets`:工具记录生图/视频类型、分类、名称、说明、资源 ID、排序、能力/指南 JSON、启用状态、版本和操作人;预设记录工具外键、名称、说明、提示词模板、默认参数 JSON、排序、启用状态、版本和操作人。普通用户目录只返回启用工具与预设;管理写入均做管理员校验和审计。工具图标/封面必须引用管理员名下就绪图片资源,发布后的引用进入资源删除保护;用户目录通过服务端授权的短期 display 资源地址展示,不放宽资源所有者访问边界。工作台任务使用专属 DTO,由服务端确认工具/预设仍启用、参考资源归属与媒体类型,并从逻辑模型目录解析执行配置后复用现有任务 admission、计费和队列。`imageWorkbenchEnabled` 与 `videoWorkbenchEnabled` 位于 `feature_availability` JSON,默认关闭;分别保护目录读取和新任务提交。版本 48 `channel_proxy_url` 为 `model_channels` 增加渠道级出站代理地址 `proxy_url`,支持 `socks5://`、`http://`、`https://`;留空时沿用全局代理。代理地址只返回管理员视图,普通用户目录不暴露渠道代理或其中的认证信息。版本 42 `cloud_agent_pi_sessions` 新增 `cloud_agent_pi_sessions` 表,按运行 ID 保存 Pi 原生 JSONL 会话快照、用户 ID、乐观并发 revision 和更新时间;会话正文由 Agent runtime 管理,Go 只将其作为不透明快照读写,不替代有界控制检查点、事件日志或任务记录。版本 41 `resource_thumbnail` 为 `resources` 增加缩略图元数据。版本 40 `builtin_skill_tombstones` 新增内置技能删除记录,管理员删除平台技能后,后续启动同步不会重新创建该技能;版本 39 `skill_library_categories` 新增 `skill_library_categories` 表,并为 `user_skill_states` 增加 `library_category_id`,保存个人技能库分类及每个用户对技能的归类;分类不改变 `skills.tag` 的技能广场共享分类。版本 38 `prefixed_id_sequence_reconcile` 创建(若缺失)并校准 `id_sequences`:`CHANNEL`、`MODEL`、`PTIER`、`ATTEMPT`、`LMODEL`、`REVISION`、`ROUTE` 按对应业务表的最大有效 ID 前移,包含软删除记录,不回退已有序列、不重写业务 ID。分配新 ID 时再次校准并检查冲突;SQLite → PostgreSQL 迁移完成后也校准序列。 `cloud_agent_gemini_cache` 创建 `cloud_agent_gemini_caches`,保存用户范围内的官方 Gemini 缓存元数据;版本 37 `cloud_agent_gemini_cache_identity` 将缓存标识约束修正为 `(user_id, cache_key)`,移除旧的全局 cache_key 唯一索引。版本 35 `auth_notifications` 为认证通知与组合验证补齐 `auth_verifications`、`notification_quotas`、`sms_channels`、`sms_records` 四张表,并为 `users` 增加 `phone`、`email_verified_at`、`phone_verified_at`,为 `email_verification_codes` 增加 `attempts`;同时创建非空手机号唯一索引。版本 34 `task_media_recovery` 为 `tasks` 增加 `media_recovery_json`(text)和 `media_stage`(最长 24 字)。版本 33 `oauth_state_accepted_terms` 为 `o_auth_states` 增加非空布尔列 `accepted_terms`,默认 `false`,不替历史流程补造同意记录。
升级前备份,按既有流程执行 `migrate-schema up` 和 `verify` 后再启动新后端。旧版本二进制不支持版本 42,回退需恢复匹配的数据库备份,并评估备份之后的新写入;不能只切回旧镜像。关闭自动迁移的生产环境必须运行正式迁移;手工改表不能更新 `schema_migrations` 的版本与校验和记录。
@@ -74,6 +76,8 @@ Schema 45 新增 `upload_reservations`:`id`、`user_id`、`size`、`day`、`ex
渠道模型的文本能力 JSON 还可声明 `contextWindowTokens` 与 `maxOutputTokens`。这两个字段是模型能力合同,不是数据库或 Agent checkpoint 的容量配置;旧记录读取时补 128K / 16K 默认值。运行状态、journal 和 transcript 的持久化边界仍由既有 runtime 表及其 512KB checkpoint 校验负责,本阶段没有通过扩大 checkpoint 绕过模型上下文限制。
历史发布曾使用版本 51 `workbench_tools_and_presets`,后续版本将个人资料安全、头像预设和登录日志依次固定为 51–53,并将工作台迁移规范为 54。迁移器仅在版本 51 的名称为 `workbench_tools_and_presets` 且校验和精确为 `sha256:workbench-tools-presets-v51-20261014`、不存在更高迁移记录、且工作台表完整时,将该已成功应用记录在同一事务中归一到规范版本 54,然后继续应用 51–53;既有应用时间保留。其他未知名称、校验和或部分迁移状态仍拒绝启动,不通过删除、改名或伪造记录绕过检查。
历史发布曾使用版本 6 `asset_library_folders`,之后合并引入了上述 6/7 顺序冲突。迁移器仅在该历史记录的名称和校验和均精确匹配时选择历史顺序:保留版本 6 的素材目录记录及时间,在版本 7 应用 `resource_playback_variant`,再继续版本 8。新数据库及已采用“6 播放副本、7 素材目录”的数据库保持原顺序;状态检查与启动校验采用同一套识别规则。未知名称、被改动的校验和或冲突的版本 7 记录仍会拒绝迁移,不通过删除、改名或伪造已应用记录绕过检查。
升级前备份数据库,迁移命令必须沿用部署实际配置的数据库连接和数据目录。开发环境启用自动迁移时重新启动新代码即可;关闭自动迁移的部署先使用新构建的 `migrate-schema up`,然后 `migrate-schema verify`,成功后启动 Backend。迁移与记录写入在事务中执行;此修复不提供降级迁移,回退旧二进制可能无法识别历史顺序,应恢复匹配的备份和版本,不手工改迁移表。
@@ -243,7 +247,7 @@ docker compose -f docker-compose.deploy.yml up -d backend web
| 表 | 用途 | 关键边界 |
| --- | --- | --- |
| `model_channels` | 保存系统渠道与用户渠道的连接配置和排序 | 系统渠道密钥不进入公开目录;废弃渠道级前台名称,历史 `public_alias` 列保留但不再用于取名或 API 返回;按 `sort_order, created_at, id` 升序展示 |
| `channel_models` | 保存系统渠道中的调用标识、上游模型 ID、模型展示名、渠道展示名、描述、Logo、排序、能力、协议和版本状态 | 创作目录跨渠道按 `display_name` 分组一级,`channel_label` 为二级、最长 80 字、空值使用所属渠道名称;`description` 最长 500 字、非空、默认空字符串;同一渠道内调用标识唯一,跨渠道归组不依赖调用标识;模型排序不递增价格或能力版本 |
| `channel_models` | 保存系统渠道中的调用标识、上游模型 ID、模型展示名、渠道展示名、描述、Logo、排序、能力、协议和版本状态 | 创作目录跨渠道按 `display_name` 分组一级,未设置归入 `未分类`;`channel_label` 为二级、最长 80 字,空值或与上游 ID 相同的值表示不固化、读取时回退上游模型 ID;`description` 最长 500 字、非空、默认空字符串;同一渠道内调用标识唯一,跨渠道归组不依赖调用标识;模型排序不递增价格或能力版本 |
| `channel_model_price_tiers` | 保存系统模型按规格匹配的上游 SKU 与价格 | 价格档与渠道模型同事务保存;未启用或未完成定价的规格不进入普通用户目录。档位 `provider_model_key` 非空时优先于渠道模型上游键发往供应商;管理端修改模型级上游 ID 时,与旧值相同的档位键自动级联跟随,其余显式 SKU 保持不变 |
| `logical_models` | 保存逻辑模型的名称、Logo、能力类型和归档状态 | 不再作为创作端模型选择目录的数据源;既有任务与供应线路仍通过 revision 和 route 关联;`code` 仅在 `archived_at IS NULL` 的活动记录中唯一 |

View File

@@ -205,17 +205,17 @@ CANVAS_BACKEND_DATA_DIR=/明确的数据目录 ./migrate-schema repair-canvas-re
### 用户模型目录
`GET /model-catalog` 固定返回 `source=system`,直接查询所有启用系统渠道下的渠道模型,目录数据在 `channels[].models[]`,`models` 固定为空数组。不受逻辑模型开关影响,不反查逻辑模型或供应线路。每项的 `modelKey` 是调用标识,`displayName` 是模型展示名,`icon` 是模型图标键,`channelLabel` 是可选的渠道展示名(默认空字符串)。后台渠道模型创建与更新请求使用相同的 `channelLabel` 字段;服务端去除首尾空白并限制为 80 字,空字符串表示使用所属渠道名称。
`GET /model-catalog` 固定返回 `source=system`,直接查询所有启用系统渠道下的渠道模型,目录数据在 `channels[].models[]`,`models` 固定为空数组。不受逻辑模型开关影响,不反查逻辑模型或供应线路。每项的 `modelKey` 是调用标识,`displayName` 是一级分组展示名(未设置时归入 `未分类`),`icon` 是模型图标键,`channelLabel` 是二级渠道展示名。后台渠道模型创建与更新请求使用相同的 `channelLabel` 字段;服务端去除首尾空白后限制为 80 字,空值或与上游模型 ID 相同的值表示不固化该名称,读取时回退到上游模型 ID(默认与上游 ID 保持一致,上游改名时自动跟随)。
渠道模型创建、更新、管理列表、公开目录和会话模型价格信息均使用 `description` 表达模型描述。服务端去除首尾空白后限制为 500 字,允许空字符串清除描述;无管理员权限或超长内容拒绝保存。创作端二级选项常驻展示该字段,不依赖悬浮 Tooltip;未填写的系统模型不按名称生成宣传文案。
以上模型接口同时使用 `tags: [{ text, color }]` 传递有序展示标签,例如 `[{"text":"限时特价","color":"purple"},{"text":"官方1折","color":"gold"}]`。最多 5 个,文字去除首尾空白后为 1–12 字且不可重复;颜色仅接受 `purple`、`blue`、`green`、`gold`、`orange`、`pink`。创建/更新由管理员操作,非法标签拒绝整个保存;提交 `tags: []`(或省略字段)清空标签。用户模型选择器在对应二级渠道项中常驻展示,标签不参与路由、价格计算或权限判断。
创作端跨渠道按模型 `displayName` 分组为一级菜单,二级菜单使用每条模型的 `channelLabel`,例如 `MiniMax H3 → 秘塔(满血渠道)`。选中值继续使用 `channelId::modelKey`,报价和生成请求保留该渠道身份。展示字段不参与路由、权限及计费。系统渠道的“前台名称/前台显示别名”已移除,管理 API 不再接受或返回 `publicAlias`。
创作端跨渠道按模型 `displayName` 分组为一级菜单(新导入模型默认 `未分类`),二级菜单使用每条模型的 `channelLabel`;未手动设置时与上游模型 ID 保持一致,例如 `MiniMax H3 → minimax-h3`。选中值继续使用 `channelId::modelKey`,报价和生成请求保留该渠道身份。展示字段不参与路由、权限及计费。系统渠道的“前台名称/前台显示别名”已移除,管理 API 不再接受或返回 `publicAlias`。
同一产品在不同渠道中使用相同的模型展示名即可归组,`modelKey` 可以不同;相同 `modelKey` 但展示名不同会分为不同组。一级顺序与图标按后台渠道和模型排序首次出现的位置确定,二级保持后台渠道与模型顺序。即使二级展示名相同,也保留独立选项及各自能力、价格,不自动改写历史配置或交换两个展示字段。
`GET /admin/references` 的 `channels[]` 同时返回 `modelDisplayNames`,包含系统渠道已创建模型的一级分组名称(含停用模型,空展示名使用产品模型标识)。编辑器“模型展示名(一级目录)”汇总去重后提供可搜索下拉,并允许输入新分组;保存后刷新引用数据。
`GET /admin/references` 的 `channels[]` 同时返回 `modelDisplayNames`,包含系统渠道已创建模型的一级分组名称(含停用模型)。已设置过展示名的分组保留原值,即使与模型 ID 相同也算作已分组;未设置的模型不进入该列表,避免把模型 ID 当成一级分组。编辑器“模型展示名(一级目录)”汇总去重后提供可搜索下拉,点击即可展开全部已有分组,同时允许输入新分组;保存后刷新引用数据。
以下接口需要登录 Cookie,返回 `data.quote`,仅校验和报价,不创建任务、账单或冻结余额,不调用供应商生成接口。

View File

@@ -15,6 +15,12 @@ description: 当前项目已实现的核心工作台能力与使用入口
“账户与设置”新增“个人信息”,展示账号名称与绑定邮箱状态。用户可预览并保存个人头像或恢复系统默认头像,顶栏、侧栏、账户卡片与创作消息同步更新。密码修改与邮箱更换分别保存;修改密码需要当前密码,邮箱更换还需要新邮箱验证码,成功后退出所有登录会话。纯 Linux.do 账号可重新授权核验身份后设置本地密码或更换邮箱。沿用现有设置页、表单、按钮反馈与主题,未增加昵称、用户名或角色编辑。
## 生图与视频工作台
普通用户可分别使用生图、视频工作台。通过工具卡片选择场景,套用预设提示词,按所选模型能力配置参数和参考素材;生成结果、运行任务及历史详情在同一页面查看。管理员在「工作台工具」维护分类、图标/封面、预设、使用说明与示例素材,并在「功能开放」分别控制两个入口。新入口默认关闭;工作台任务经过统一任务与计费服务创建。
详见[生图与视频工作台](./workbench)。
## 可美 KM Seedream 图片
`km-kemei-seedream` 声明式插件接入 Seedream 5.0 Pro / Flash 的文生图与参考图编辑,支持 URL / Base64 响应并由宿主统一保存图片。精确模型 ID 与扩展参数见插件包内 `docs/interface.md`。
@@ -479,24 +485,24 @@ SEO 标题、描述、可选关键词会投影到浏览器 metadata、Open Graph
开启时一级分类也可在后台新增、改名、排序、停用和选择图示,未归入技能仍有默认入口。
## 创作首页纵深画廊与灵感库
## 创作首页、最近画布与灵感大厅
创作页空态是直线纵深图片画廊:11 张横版卡片沿 Z 轴前后排队,当前一张在最前、最大,其余依次后退缩小并左右对称。滚轮、两侧按钮和自动轮播都能切换,切换只动 `transform` 与 `opacity`。卡片带玻璃描边、圆角和投影,底部是「行动点 / 标题 / 描述」三段信息,只有最前那张露出。队列跟随输入框的创作类型:选图片只排图片灵感,选视频只排视频灵感,选文本用本项目原创条目。每次进场和每次换类型都重新随机抽一批,并记住最近出现过哪些,走完一轮自动换批。
根路径 `/` 与 `/create` 共用创作首页。空态首屏提供紧凑标题、文本/图片/视频/Agent 模式、真实提示词输入区和快捷创作入口。下方一行展示创建画布与最近更新的 4 个画布,支持打开、查看全部和窄屏横向浏览;读取失败提供重试,创建后明确区分本机保存与云端同步。
工作区左侧「创作」下方新增灵感页 `/inspirations`,展示全部提示词,按来源、分类和创作类型筛选,支持搜索、收藏、视图切换和分页;自建灵感支持新建、编辑、删除和 JSON 导入导出,改动只存在本地。
灵感大厅合并到创作首页下方,不再提供独立灵感导航或 `/inspirations` 页面路由。类型与搜索常驻,来源、分类、收藏/隐藏和排序收拢在更多筛选中;默认每页 12 条。新建、编辑、隐藏/恢复、收藏与 JSON 导入导出继续保留,本地改动按账号 scope 持久化。使用灵感会关闭详情、回填首页提示词并返回输入区,不自动生成。
生产 Nginx 对 `/inspirations` 与 `/inspirations/` 精确返回 SPA 入口,支持直接打开和刷新;`/inspirations/*.json` 继续提供静态目录数据,避免页面路径与同名目录冲突而跳转到容器端口。
内置提示词统一提供中文正文,详情阅读、复制、编辑和回填创作使用同一份中文内容。已有中文来源直接采用中文版本,其余外文正文翻译后随静态目录发布;模型名、引用标记和模板参数保留原有用途。来源及原页链接显示遵循后台来源展示开关。
外部提示词由 `web/scripts/import-inspirations.mjs` 同步:`awesome-seedance`、好好学 AI 提示词库、YouMind 的两个姊妹库。脚本同时为画廊池生成本地缩略图(560px、webp、约 35KB 一张)。上游封面平均 400KB~700KB,直接引用一屏 11 张要拉 5MB 以上,换成本地缩略图后约 400KB。
译文维护在 `web/scripts/data/inspiration-prompts-zh.json`,记录原文 SHA-256;导入脚本写入目录前校验原文版本,缺译会停止导入。
画廊池走 `public/inspirations/gallery-pool.json` 运行时拉取,不打进首屏 JS:几百条提示词正文压在包里是白背的,而这份数据只服务画廊一处。池子按来源等距抽取以横跨各分类,并且只收描述非空的条目,保证卡片三行版式不缺角;这些条目仍留在全量目录里供灵感页展示。
外部提示词由 `web/scripts/import-inspirations.mjs` 同步。`web/public/inspirations/*.json` 继续提供静态目录数据,灵感大厅进入可视区域附近后才按需加载全量目录,浏览器缓存与会话内缓存避免重复请求;封面保持稳定比例,加载失败显示占位内容。
### 相关实现
- `web/src/pages/create/creation-inspiration-tunnel.tsx`、`creation-inspiration-tunnel.css`:纵深画廊组件与样式。
- `web/src/pages/inspirations/`:灵感页、详情弹窗、编辑弹窗与样式。
- `web/src/lib/inspirations/`:来源登记表、条目类型与解析、原创条目、上游版本号(`catalog.ts`、`resolve.ts`、`source-revisions.ts`)。
- `web/src/services/inspiration-catalog.ts`:全量目录与画廊池的运行时加载和内存缓存。
- `web/src/pages/create/index.tsx`、`creation-product.css`:首页组合、提示词回填与紧凑布局。
- `web/src/pages/create/creation-recent-canvases.tsx`:最近画布查询、创建与快捷入口。
- `web/src/pages/inspirations/`:内嵌灵感大厅、详情/编辑弹窗与样式。
- `web/src/lib/inspirations/`:来源登记、条目类型、解析、原创条目与上游版本。
- `web/src/services/inspiration-catalog.ts`:静态目录的运行时加载与内存缓存。
- `web/src/stores/use-inspiration-store.ts`:自建、覆盖、隐藏与收藏的本地持久化。
- `web/scripts/import-inspirations.mjs`:外部来源同步、缩略图生成与画廊池落盘。
- `web/public/inspirations/`、`web/public/inspiration-thumbs/`:全量目录、画廊池与本地缩略图。
- `web/scripts/import-inspirations.mjs`:外部来源同步、缩略图生成与目录落盘。

View File

@@ -5,6 +5,40 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
# 待测试
## 图片与视频电商出品工作室
- 已实现:`/toolbox/image` 与 `/toolbox/video` 保留紧凑工作区入口,移除顶部品牌介绍区;提供创作流程条、重置入口、快捷出品目标和工具选择弹窗。弹窗桌面五列,961px 以下四列、768px 以下两列;选择工具后空提示词自动套用首个预设,已有内容可通过预设入口追加或替换。
- 已实现:重置后结果区保持空态,旧提交与轮询响应不会重新展示结果;历史任务保留。结果标题、任务列表和详情统一使用模型展示名;生成按钮收窄。模型选择器禁用位移、图标缩放、箭头过渡及弹层进出场动画,键盘聚焦仅滚动菜单。
- 已实现:服务启动时在事务内补齐 118 个内置工具(69 图片、49 视频)及每个工具 3 个提示词预设,固定 ID、重复启动不覆盖已有管理员编辑和下线状态;不引用其他安装实例的资源 ID。
- 已验证:`cd web && bun run typecheck`、`bun run lint`、`bun run build` 通过;`git diff --check` 通过。
- [ ] 用户验收:真实登录态访问 `/toolbox/image` 和 `/toolbox/video`,确认快捷目标卡使用真实工具、图片/视频切换、工具弹层、素材上传和生成提交均正常。
- [ ] 用户验收:明暗主题、窄屏滚动、不同工具数量、工具封面缺失、生成中/成功/失败结果状态下,确认布局和色彩层级符合预期。
## 千问 AI 平台(QianWenAI MAAS)图像协议插件
- 已实现:新增独立协议插件 `qianwenai-maas-image`,Base URL `https://maas.qianwenaiapi.com`,创建端点 `POST /api/v1/services/aigc/multimodal-generation/generation`,查询 `GET /api/v1/tasks/{{taskId}}`。与百炼的 `dashscope-qwen-image` 报文形状一致,但网关域名不同,不能互相替代。
- 已验证:manifest 关键字段与百炼多模态模板逐字段对照一致(仅 id/name/baseUrl/endpoint/providerOptions 命名空间按预期不同);JSON 合法;插件包 `qianwenai-maas-image.yingce-plugin` 已生成。Go 测试已补齐,真实 API 请求未发出。
- 实现位置:`plugin-packages/qianwenai-maas-image/`、`plugin-packages/generate-catalog.mjs`、`backend/internal/protocol/qianwenai_maas_image_test.go`。
- [ ] 用户验收:用千问 AI 平台真实 API Key 配置渠道,文生图与图生图各跑一次,确认返回图片能正常落盘;确认渠道 Base URL 填 `https://maas.qianwenaiapi.com`。
- [ ] 未验证:真实请求未发出,模型 ID(`qwen-image-3.0-pro` 等)是否在平台侧全部开通需按实际账号确认。
## 灵感库中文提示词
- 已实现:内置目录与首页画廊的提示词统一为中文;复用来源中文正文,补齐外文翻译;导入时校验原文摘要,缺译或旧译文阻止覆盖。
- [ ] 用户验收:抽查图片、长视频分镜和模板参数,确认中文表达、时长、镜头要求和参考素材语义符合预期。
- [ ] 用户验收:本地及线上刷新后,详情、复制、编辑和一键创作均使用中文,收藏与自定义修改保持正常。
## 创作页提交闸门只覆盖提交阶段
- 已修复:`submit()` 的提交闸门原来一直持有到整条生成结束(只在 `finally` 释放,而 `finally` 要等任务出结果才执行),因此上一条还在生成时点发送会被 `tryAcquire()` **静默拒绝**——没有提示也没有反应,表现为「按钮在转、点不动」。重试走同一条 submit 路径,一并被挡住。
- 已实现:闸门改为令牌制(`tryAcquire()` 返回令牌,`release(token)` 只对持有者生效,避免并发提交互相解锁);任务一旦建成(`bindTask`)立刻放闸,与已有的 `busy` 释放时机对齐,因此上一条生成中也能继续提交下一条;被拒绝时改为给出提示,不再静默丢弃。
- 说明:该闸门在 `4f18367`(v1.6.5)就已存在,不是本次改动引入;它只需要防住同一次创建任务被重复触发(连点、回车连击),不该跨越整个生成过程。
- 实现位置:`web/src/pages/create/creation-submit-gate.ts`、`web/src/pages/create/index.tsx`,单测 `web/test/creation-submit-gate.test.ts`。
- [x] 验证:`tsc --noEmit`、ESLint、`bun run build` 通过;`bun test` 2204 通过(唯一失败项 `agent-api-reliability` 在纯净上游基线上同样失败,与本改动无关);闸门单测含「持有者令牌」并发用例。
- [ ] 用户验收:真实登录态下先提交一条慢任务(视频),在它「生成中」时输入新提示词再提交一条,确认**第二条能正常创建**、两条并行推进、按钮在输入后恢复为「发送」;确认快速连点仍只会创建一条。
- [ ] 未验证:`busy` 仍是布尔量,两条并发时按钮可能提前约 100ms 变可点(闸门仍会拦住并提示);提交阶段本身卡住时闸门会一直被占,此时只给提示。
## 用户登录日志
- 已实现:管理员菜单 `/admin/login-logs`、筛选分页详情、后端认证事件记录、schema v53、失败脱敏和会话/日志原子提交。
@@ -27,6 +61,19 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
- 代码审查已修正资料刷新未同步全局头像,以及 Linux.do 重新验证在会话时区变化时未保存验证状态的问题;覆盖取消请求、账户切换、错误响应归属、头像保存后迟到响应,以及 UTC−12/UTC+14 会话的回归测试通过。
- [ ] 用户验收:真实页面明暗主题和窄屏,头像全局刷新与失败保留、原密码错误、新邮箱发送及通知失败状态。
- [ ] 外部联调:真实 SMTP 发送新邮箱验证码/旧邮箱通知,真实 Linux.do 授权回调与不同账号拒绝,实际 PostgreSQL 并发事务。本地测试使用隔离数据与模拟上游,不等同于这些外部联调已完成。
## 局部重绘默认模型同步
- 已修复:局部重绘弹窗打开时,将默认显示的图片模型同步到实际请求模型;下拉框显示与提交使用同一字段,无需手动重新选择模型。
- 已修复:局部重绘任务优先使用提交的图片模型,并将 `model` 与 `imageModel` 统一为本次选中的模型。
- [ ] 上传图片,在全局当前模型与默认图片模型不同的情况下打开局部重绘,直接涂抹、填写修改要求并生成,确认不再出现「所选模型与任务能力不匹配」。
- [ ] 在弹窗中切换图片模型,以及从已有生成图片打开局部重绘,确认提交模型与显示模型一致。
## 裁剪与调整尺寸的跨域原图读取
- 已修复:裁剪、调整尺寸和宫格切分共用原图读取入口,优先复用缓存或 `browser-process` 授权的资源 Blob;无缓存时以 CORS fetch 读取字节并构造可导出的 Blob URL,操作结束释放临时 URL。
- 已修复:资源 Blob 读取失败时直接保留错误,不再退回展示地址;HTTP 图片加载在设置 src 前启用 CORS,覆盖同源资源接口重定向到 OSS/CDN 的情况。
- [x] `image-raster.node.test.ts` 7 项专项测试通过,覆盖 CORS 设置顺序、模拟重定向的裁剪/缩放/切分导出、缓存与无缓存原图、读取失败不降级、HTTP 错误及 Blob URL 释放。测试使用模拟 Image/Canvas,不替代真实浏览器 CORS 验收。
- [ ] 使用本地上传图片及刷新后恢复的云端图片,分别执行裁剪、三种插值方式的调整尺寸和宫格切分,确认输出尺寸、原图保留和结果保存。
- [ ] 验证资源接口重定向及 OSS/CDN CORS 配置;允许跨域读取时应成功导出,拒绝读取或授权失效时应明确失败。尚未进行完整前端类型检查、构建或真实站点联调。
## 系统模型「拉取模型」弹窗搜索
@@ -37,13 +84,23 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
- [x] 验证:`bun test test/channel-model-import-selection.test.ts` 9 项通过(空关键字返回全部、大小写不敏感、首尾空白、无命中返回空、全选并入去重、关键字外勾选保留、无关键字时与旧行为一致);`tsc --noEmit`、ESLint、`bun run build` 均通过。
- [ ] 用户验收:需要管理员登录且上游能返回大量模型才能打开该弹窗,因此**未做真实界面验收**。请在真实后台点「拉取模型」确认:搜索框位置与自动聚焦、输入关键字后列表实时收窄、全选/取消选中只影响匹配项、清空后恢复全部、以及几百个模型时的滚动与性能。
## 灵感页路由与导航
## 创作参考内容的远端素材选择
- 已修复:Nginx 对 `/inspirations` 与 `/inspirations/` 精确返回 SPA 入口,避免同名静态目录触发带容器端口的 301;目录下的 JSON 仍按静态文件提供。
- 已修复:顶部面包屑补齐灵感路由标题,显示「站点名称 / 灵感」,与侧栏一致,不再回退到站点名称。
- [x] 使用生产同版本 Nginx 容器复现旧配置的 301;修改后配置检查通过,两个页面路径及查询参数返回入口文件且无重定向,五个真实 JSON 文件返回原内容和正确类型。该验证只覆盖网关,不替代真实页面验收。
- [ ] 更新前端镜像后,通过实际域名直接打开和刷新两个路径,确认不跳转到 `:3000`、不返回 403,且灵感目录正常加载。
- [ ] 通过侧栏进入、直接打开及刷新灵感页,确认面包屑显示「灵感」。
- 已修复:创作页按素材类型与当前模式能力校验远端条目,不再把本地未缓存的素材误判为不适用;确认时使用弹窗返回的素材记录,仅按需缓存实际选中的远端素材。
- 已修复:确认时重新校验媒体类型与视频模型能力,缺失或不支持的条目明确报错;保持现有参考数量上限。
- [x] 新增远端素材回归测试,并与创作引用、素材库入口和画布素材选择测试一同运行,35 项通过;前端类型检查通过。
- [ ] 在本地未缓存云端素材的浏览器中选择图片、视频和音频,确认支持的条目可选并能添加;跨页选择后确认应保留选择顺序,再次打开弹窗应保留已选状态。
- [ ] 切换到图片创作及不同视频模型,确认不支持的媒体类型保持禁用,参考数量仍受模型上限约束;云端素材读取失败时保留弹窗并显示错误。
## 创作首页与灵感大厅整合
- 已实现:首页首屏压缩为标题、创作模式、提示词区与快捷入口;无附件时参考内容入口合并到输入工具栏。下方一行展示创建入口和最近更新的 4 个画布,保留查看全部、加载失败重试和窄屏横向浏览。
- 已实现:灵感大厅迁入创作首页,移除独立页面路由、侧栏入口与预加载;保留搜索、类型/来源/分类/收藏隐藏筛选、分页、详情、编辑、导入导出。使用灵感会关闭详情、回填提示词并返回输入区,不自动生成。
- 已实现:来源展示开关同时作用于卡片和详情;封面失败显示占位,触摸操作常显,键盘焦点与减少动效可用。根路径及 `/create` 的页面壳和侧栏高亮一致。
- 已验证:前端生产构建、最终类型检查、UI lint 与补丁格式检查通过;已有路由、游客访问与灵感目录专项测试 13 项通过。真实 Chrome 游客首页 11 项断言通过:1440/2048/768/390px 无页面横向溢出、真实主题按钮切换暗色、创建入口打开登录弹窗、灵感详情回填真实输入框、独立灵感导航移除、`/create` 高亮与无未捕获运行时异常。已查看实际页面截图;未提交生成任务或用真实账号创建画布。
- 已验证:与 GitHub Actions 同命令的冻结依赖安装、变更文件格式检查、Typecheck 和 UI lint 通过;前端全量测试 2302 项通过、0 失败,pretest 通过;预演 P0 Chrome E2E 65 项断言通过。修复灵感大厅、详情、样式和最近画布组件的四处 CI 格式问题;发布版本与更新日志对齐 `v1.6.8.2`。
- [ ] 用户验收:登录态最近画布排序、创建并进入画布、云端同步失败提示、查看全部;切换账号后列表不串数据。
- [ ] 用户验收:明暗主题与 390/768/1440px 布局、滚动、弹窗、空态和完整长提示词编辑;收藏、新建/编辑、隐藏恢复与 JSON 导入导出正常,来源开关显示一致。
## 画布素材缺失时的本地强制覆盖