13 KiB
13 KiB
工具展示版本与无访问模式设计规格
概述
当前工具站只区分 web 和 download 两种访问方式。下载工具的版本来源于 ToolArtifact.version,因此访客端首页和详情页中的“版本”信息只对下载工具有效,网页工具长期显示“暂无版本”。与此同时,当前系统没有“仅展示详情、不提供打开或下载入口”的访问模式,无法承载预告型、资料型或人工分发型工具。
本次设计目标是在现有 Tool 模型上补齐“展示版本”和“无访问模式”能力,保持下载包管理逻辑不变,同时让前台和后台统一拿到一个稳定的展示版本字段。具体策略为:数据库新增 Tool.versionOverride 作为人工维护的展示版本覆盖值;服务端统一计算 displayVersion;访问方式新增 none,用于“只展示详情,不执行 launch”的工具。
目标定位
- 主要用户:后台管理员、公开站访客
- 使用场景:管理员在新增或编辑工具时维护展示版本,并可将工具设置为
download、web或none;访客在首页和详情页查看统一的版本信息,其中none模式工具只提供“查看详情”入口,不提供打开网页或下载操作
约束条件
- 技术限制:前端基于 Vue 3 + Element Plus,服务端基于 NestJS + Prisma + SQLite;本次只做现有模型上的增量改造,不引入新的依赖或新的版本历史表
- 时间限制:本轮只实现版本展示和
none访问模式,不扩展版本历史、发布日期、版本说明等二级能力 - 资源限制:继续复用现有下载包模型、公开列表/详情接口和后台工具管理流程;版本字段仅用于展示,不参与发布校验、不新增额外审核流程
成功标准
- Prisma 数据模型支持
AccessMode.none和Tool.versionOverride - 后台新增/编辑工具表单可以维护“展示版本”,访问方式下拉可选择“无”
- 后台工具列表接口和公开工具列表/详情接口统一返回
displayVersion - 下载工具的
displayVersion计算规则为versionOverride || latestArtifact.version || null - 网页工具和无访问模式工具的
displayVersion计算规则为versionOverride || null - 访客端首页和详情页统一展示
displayVersion,不再依赖下载模式专属的latestVersion none模式在首页主按钮显示“查看详情”,详情页不展示打开/下载主按钮- 直接调用
launch接口访问none模式工具时返回明确错误,且不会产生打开/下载计数 - 现有发布约束保持不变:
web仍要求openUrl,download仍要求安装包或下载地址,none不因为缺少版本而被阻止发布 - 后台概览和模式标签不再把
none模式误显示为“下载模式”
架构设计
系统结构
本次改造分为四层:
- 数据层:在
Tool模型中新增versionOverride字段;在AccessMode枚举中新增none - 映射层:在后台服务和公开服务中统一计算
displayVersion,将“原始覆盖值”和“最终展示值”分离 - 行为层:在
AccessService中显式拒绝none模式的 launch 行为,保证服务端语义闭合 - 展示层:后台编辑页维护
versionOverride,后台列表和访客端页面统一展示displayVersion
版本数据的核心原则如下:
versionOverride是管理员手工维护的原始字段,允许为空displayVersion是接口返回给前端的最终展示值,不直接持久化- 对下载工具,若
versionOverride为空,则自动回退到当前latestArtifact.version - 对网页工具和无访问模式工具,
displayVersion只来自versionOverride latestArtifact.version继续用于安装包管理;displayVersion用于页面展示
访问模式的核心原则如下:
- 新增枚举值
none,内部值固定为none,后台展示文案为“无” none模式工具允许存在详情页和展示版本,但不允许执行 launch- 访客端列表页对
none模式的主按钮改为“查看详情” - 访客端详情页对
none模式不渲染打开/下载按钮 - 服务端若收到对
none模式的 launch 请求,返回409 Conflict
组件划分
| 组件 | 职责 | 依赖 |
|---|---|---|
server/prisma/schema.prisma |
为 AccessMode 增加 none;为 Tool 增加 versionOverride 字段 |
Prisma |
server/prisma/seed.ts |
补齐种子数据中的访问方式和展示版本样例,避免本地初始化后看不到新行为 | Prisma Seed |
server/src/modules/admin-tools/dto/create-tool.dto.ts |
接收 versionOverride,并允许 accessMode=none |
class-validator |
server/src/modules/admin-tools/dto/update-tool.dto.ts |
继承新增字段,支持后台更新展示版本 | CreateToolDto |
server/src/modules/admin-tools/dto/update-access-mode.dto.ts |
接收 none 枚举值,兼容访问方式切换 |
class-validator |
server/src/modules/admin-tools/admin-tools.service.ts |
规范化 versionOverride;列表和详情返回 displayVersion 与 versionOverride;保持发布校验逻辑不因版本字段变化 |
Prisma |
server/src/modules/tools/tools.service.ts |
公开列表和详情统一返回 displayVersion;保留下载工具的 latestVersion 作为兼容字段 |
Prisma |
server/src/modules/access/access.service.ts |
对 none 模式返回明确错误,禁止生成 launch 地址或下载票据 |
Prisma, ConfigService |
server/src/modules/admin-overview/admin-overview.service.ts |
访问方式统计兼容 none,避免概览数据遗漏或模式显示错误 |
Prisma |
client/src/admin/components/ToolFormDialog.vue |
新增“展示版本”输入项;访问方式下拉新增“无”;根据模式调整提示文案 | Element Plus |
client/src/admin/components/AdminToolsSection.vue |
列表增加版本列,访问方式标签兼容 none 文案 |
Element Plus |
client/src/admin/components/AccessModeDialog.vue |
快速修改访问方式时允许选择“无”,并在 none 模式下隐藏 URL 输入项 |
Element Plus |
client/src/admin/AdminApp.vue |
表单数据结构新增 versionOverride;构造创建/更新 payload;访问模式、标签颜色和模式文案兼容 none |
Vue 3 |
client/src/App.vue |
工具卡片统一显示 displayVersion;none 模式主按钮改为“查看详情”并直接路由跳转 |
vue-router, client/src/api.js |
client/src/pages/ToolDetailPage.vue |
摘要区展示 displayVersion;none 模式不显示主操作按钮 |
vue-router, client/src/api.js |
client/src/admin/components/AdminOverviewSection.vue |
模式统计与 Top 工具模式文案兼容 none |
Element Plus |
数据流
版本字段维护流
- 管理员在新增或编辑工具时填写“展示版本”
- 前端将该值作为
versionOverride提交给后台;空字符串在提交前或服务端落库前统一归一化为null - 服务端保存
Tool.versionOverride - 当后台列表、后台详情、公开列表或公开详情查询工具时,服务端统一计算
displayVersion - 前端页面一律渲染
displayVersion,不再直接依赖下载工具专属的latestVersion
displayVersion 计算规则如下:
- 当
tool.accessMode === 'download'时:displayVersion = tool.versionOverride || tool.latestArtifact?.version || null - 当
tool.accessMode === 'web'或tool.accessMode === 'none'时:displayVersion = tool.versionOverride || null
为降低回归风险,下载工具响应中的 latestVersion 字段继续保留,其语义保持为“当前最新安装包版本”;页面展示逻辑统一切换为 displayVersion。
访问模式切换流
- 管理员在新增/编辑表单或访问方式对话框中选择
download、web或none - 当模式为
web时,沿用现有规则,发布时仍要求openUrl - 当模式为
download时,沿用现有规则,发布时仍要求活动安装包或外部下载地址 - 当模式为
none时,不生成 launch 目标,不要求openUrl,前端不展示打开/下载按钮 - 当公开站列表遇到
none模式工具时,主按钮直接路由到详情页 - 当公开站详情页遇到
none模式工具时,仅展示内容和版本,不发起 launch 请求 - 若外部调用者直接请求
POST /api/v1/tools/:id/launch且目标工具为none模式,服务端返回409
前后台显示流
- 后台工具列表新增版本列,显示
row.displayVersion || '-' - 公开首页卡片“版本”行显示
tool.displayVersion || '暂无版本' - 公开详情页摘要区显示
detail.displayVersion || '暂无版本' none模式的卡片副文案和详情摘要不再显示“下载/访问”动词,统一显示“仅详情”- 概览和模式标签遇到
none时显示“无”,不将其归并到下载模式
错误处理
| 错误类型 | 处理方式 |
|---|---|
versionOverride 为空字符串 |
前端提交前或服务端保存前统一归一化为 null,避免空串污染数据 |
| 下载工具没有覆盖版本且没有最新安装包版本 | displayVersion 返回 null,前端显示“暂无版本”,但不阻止发布之外的页面展示 |
none 模式被直接调用 launch 接口 |
服务端返回 409 Conflict,建议复用 TOOL_ACCESS_MODE_MISMATCH 并提供明确消息,如“tool is not launchable in none mode” |
访问方式统计遇到 none |
后台概览必须显式处理该值,避免统计遗漏或错误文案 |
旧前端代码仍读取 latestVersion |
下载工具继续保留该字段,版本展示迁移到 displayVersion 后逐步收敛消费端 |
管理员把工具切换为 none |
页面行为以模式为准,版本仍可展示,但公开站不再允许打开/下载 |
风险评估
| 风险描述 | 类别 | 影响 | 概率 | 缓解策略 |
|---|---|---|---|---|
新增 none 枚举后,现有前端分支把未知模式错误地当成下载模式处理 |
集成风险 | 高 | 中 | 全量检查 accessMode 条件分支,补齐 none 的按钮文案、标签颜色和统计展示 |
下载工具同时存在 latestArtifact.version 和 versionOverride,容易出现展示口径不一致 |
技术风险 | 中 | 中 | 服务端统一生成 displayVersion,前端禁止自行拼接版本来源 |
旧接口调用方继续消费 latestVersion,导致 web/none 工具仍显示“暂无版本” |
范围风险 | 中 | 中 | 在页面和后台列表统一切到 displayVersion,同时短期保留 latestVersion 兼容下载工具 |
增加 none 模式后,后台概览和模式统计遗漏该值 |
集成风险 | 中 | 中 | 同步更新概览服务、模式标签和概览页面文案,避免出现统计不闭合 |
测试策略
- 单元测试:为服务端新增版本解析逻辑编写测试,覆盖三种场景:下载工具无覆盖值时回退安装包版本、下载工具有覆盖值时优先显示覆盖值、
web/none工具只使用覆盖值 - 集成测试:覆盖后台创建/更新工具时提交
versionOverride和accessMode=none;覆盖公开列表和详情接口返回displayVersion;覆盖none模式 launch 接口返回409 - 前端组件测试:覆盖首页卡片在
none模式下显示“查看详情”;覆盖详情页在none模式下不渲染主操作按钮;覆盖版本展示优先使用displayVersion - 验收标准:管理员可维护展示版本;后台工具列表可看到版本;访客端列表与详情都能看到统一版本;下载工具默认继承安装包版本;
none模式只可查看详情、不可 launch;后台概览与模式文案不出现错误映射
决策记录
| 决策 | 理由 | 影响 |
|---|---|---|
使用 Tool.versionOverride + displayVersion,而不是为所有工具新建统一版本表 |
当前需求只需要单值展示和少量覆盖能力,不需要版本历史,增量成本最低 | 需要在服务端增加统一映射逻辑 |
displayVersion 由服务端计算,不在数据库落地 |
避免前端自行拼接版本来源,减少 download/web/none 三种模式的歧义 | 后台和公开接口都要增加该字段 |
下载工具保留 latestVersion,但页面展示切到 displayVersion |
降低旧代码回归风险,同时给新页面一个统一字段 | 服务端响应短期内会同时存在两个版本相关字段 |
访问方式新增 none,而不是用布尔开关控制是否可 launch |
与现有 AccessMode 模型保持一致,语义清晰,便于后台筛选和统计 |
Prisma 枚举、前后端条件分支和概览统计都需要更新 |
none 模式首页主按钮跳详情页,详情页不展示主操作按钮 |
用户已明确选择详情引导型行为,比“禁用按钮”更可用 | 公开站首页和详情页都需增加 none 分支 |
| 版本字段不参与发布校验 | 用户明确要求版本只作展示,不希望改变当前发布约束 | assertPublishInput 和状态流保持现状,只需兼容 none 模式 |