Files
tools-show/design/specs/2026-04-14-tool-display-version-none-mode-design.md
2026-04-15 13:47:39 +08:00

13 KiB
Raw Permalink Blame History

工具展示版本与无访问模式设计规格

概述

当前工具站只区分 webdownload 两种访问方式。下载工具的版本来源于 ToolArtifact.version,因此访客端首页和详情页中的“版本”信息只对下载工具有效,网页工具长期显示“暂无版本”。与此同时,当前系统没有“仅展示详情、不提供打开或下载入口”的访问模式,无法承载预告型、资料型或人工分发型工具。

本次设计目标是在现有 Tool 模型上补齐“展示版本”和“无访问模式”能力,保持下载包管理逻辑不变,同时让前台和后台统一拿到一个稳定的展示版本字段。具体策略为:数据库新增 Tool.versionOverride 作为人工维护的展示版本覆盖值;服务端统一计算 displayVersion;访问方式新增 none,用于“只展示详情,不执行 launch”的工具。

目标定位

  • 主要用户:后台管理员、公开站访客
  • 使用场景:管理员在新增或编辑工具时维护展示版本,并可将工具设置为 downloadwebnone;访客在首页和详情页查看统一的版本信息,其中 none 模式工具只提供“查看详情”入口,不提供打开网页或下载操作

约束条件

  • 技术限制:前端基于 Vue 3 + Element Plus服务端基于 NestJS + Prisma + SQLite本次只做现有模型上的增量改造不引入新的依赖或新的版本历史表
  • 时间限制:本轮只实现版本展示和 none 访问模式,不扩展版本历史、发布日期、版本说明等二级能力
  • 资源限制:继续复用现有下载包模型、公开列表/详情接口和后台工具管理流程;版本字段仅用于展示,不参与发布校验、不新增额外审核流程

成功标准

  • Prisma 数据模型支持 AccessMode.noneTool.versionOverride
  • 后台新增/编辑工具表单可以维护“展示版本”,访问方式下拉可选择“无”
  • 后台工具列表接口和公开工具列表/详情接口统一返回 displayVersion
  • 下载工具的 displayVersion 计算规则为 versionOverride || latestArtifact.version || null
  • 网页工具和无访问模式工具的 displayVersion 计算规则为 versionOverride || null
  • 访客端首页和详情页统一展示 displayVersion,不再依赖下载模式专属的 latestVersion
  • none 模式在首页主按钮显示“查看详情”,详情页不展示打开/下载主按钮
  • 直接调用 launch 接口访问 none 模式工具时返回明确错误,且不会产生打开/下载计数
  • 现有发布约束保持不变:web 仍要求 openUrldownload 仍要求安装包或下载地址,none 不因为缺少版本而被阻止发布
  • 后台概览和模式标签不再把 none 模式误显示为“下载模式”

架构设计

系统结构

本次改造分为四层:

  1. 数据层:在 Tool 模型中新增 versionOverride 字段;在 AccessMode 枚举中新增 none
  2. 映射层:在后台服务和公开服务中统一计算 displayVersion,将“原始覆盖值”和“最终展示值”分离
  3. 行为层:在 AccessService 中显式拒绝 none 模式的 launch 行为,保证服务端语义闭合
  4. 展示层:后台编辑页维护 versionOverride,后台列表和访客端页面统一展示 displayVersion

版本数据的核心原则如下:

  1. versionOverride 是管理员手工维护的原始字段,允许为空
  2. displayVersion 是接口返回给前端的最终展示值,不直接持久化
  3. 对下载工具,若 versionOverride 为空,则自动回退到当前 latestArtifact.version
  4. 对网页工具和无访问模式工具,displayVersion 只来自 versionOverride
  5. latestArtifact.version 继续用于安装包管理;displayVersion 用于页面展示

访问模式的核心原则如下:

  1. 新增枚举值 none,内部值固定为 none,后台展示文案为“无”
  2. none 模式工具允许存在详情页和展示版本,但不允许执行 launch
  3. 访客端列表页对 none 模式的主按钮改为“查看详情”
  4. 访客端详情页对 none 模式不渲染打开/下载按钮
  5. 服务端若收到对 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;列表和详情返回 displayVersionversionOverride;保持发布校验逻辑不因版本字段变化 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 工具卡片统一显示 displayVersionnone 模式主按钮改为“查看详情”并直接路由跳转 vue-router, client/src/api.js
client/src/pages/ToolDetailPage.vue 摘要区展示 displayVersionnone 模式不显示主操作按钮 vue-router, client/src/api.js
client/src/admin/components/AdminOverviewSection.vue 模式统计与 Top 工具模式文案兼容 none Element Plus

数据流

版本字段维护流

  1. 管理员在新增或编辑工具时填写“展示版本”
  2. 前端将该值作为 versionOverride 提交给后台;空字符串在提交前或服务端落库前统一归一化为 null
  3. 服务端保存 Tool.versionOverride
  4. 当后台列表、后台详情、公开列表或公开详情查询工具时,服务端统一计算 displayVersion
  5. 前端页面一律渲染 displayVersion,不再直接依赖下载工具专属的 latestVersion

displayVersion 计算规则如下:

  1. tool.accessMode === 'download' 时:displayVersion = tool.versionOverride || tool.latestArtifact?.version || null
  2. tool.accessMode === 'web'tool.accessMode === 'none' 时:displayVersion = tool.versionOverride || null

为降低回归风险,下载工具响应中的 latestVersion 字段继续保留,其语义保持为“当前最新安装包版本”;页面展示逻辑统一切换为 displayVersion

访问模式切换流

  1. 管理员在新增/编辑表单或访问方式对话框中选择 downloadwebnone
  2. 当模式为 web 时,沿用现有规则,发布时仍要求 openUrl
  3. 当模式为 download 时,沿用现有规则,发布时仍要求活动安装包或外部下载地址
  4. 当模式为 none 时,不生成 launch 目标,不要求 openUrl,前端不展示打开/下载按钮
  5. 当公开站列表遇到 none 模式工具时,主按钮直接路由到详情页
  6. 当公开站详情页遇到 none 模式工具时,仅展示内容和版本,不发起 launch 请求
  7. 若外部调用者直接请求 POST /api/v1/tools/:id/launch 且目标工具为 none 模式,服务端返回 409

前后台显示流

  1. 后台工具列表新增版本列,显示 row.displayVersion || '-'
  2. 公开首页卡片“版本”行显示 tool.displayVersion || '暂无版本'
  3. 公开详情页摘要区显示 detail.displayVersion || '暂无版本'
  4. none 模式的卡片副文案和详情摘要不再显示“下载/访问”动词,统一显示“仅详情”
  5. 概览和模式标签遇到 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.versionversionOverride,容易出现展示口径不一致 技术风险 服务端统一生成 displayVersion,前端禁止自行拼接版本来源
旧接口调用方继续消费 latestVersion,导致 web/none 工具仍显示“暂无版本” 范围风险 在页面和后台列表统一切到 displayVersion,同时短期保留 latestVersion 兼容下载工具
增加 none 模式后,后台概览和模式统计遗漏该值 集成风险 同步更新概览服务、模式标签和概览页面文案,避免出现统计不闭合

测试策略

  • 单元测试:为服务端新增版本解析逻辑编写测试,覆盖三种场景:下载工具无覆盖值时回退安装包版本、下载工具有覆盖值时优先显示覆盖值、web/none 工具只使用覆盖值
  • 集成测试:覆盖后台创建/更新工具时提交 versionOverrideaccessMode=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 模式