Skip to content

Latest commit

 

History

History
123 lines (91 loc) · 9.8 KB

File metadata and controls

123 lines (91 loc) · 9.8 KB

开发规范

本文记录 CSubtitleWorkstation 的项目开发惯例。新增功能、重构页面、抽取组件或提交代码前,优先按这里的规则判断。

基本原则

  • 先尊重现有产品边界,再新增入口。工具页、压制页、信息页、Aegisub 能力之间不要重复造入口。
  • 功能扩展先写清楚范围,再实现。尤其是工具页、新流程、新分类,先列出放在哪里、解决什么问题、哪些能力暂缓。
  • 保持实现靠近当前代码结构。前端页面逻辑放在对应 src/views,可复用 UI 放在 src/components,可复用纯逻辑放在 src/utils,Tauri 调用封装放在 src/api
  • 默认值必须来自真实配置或代码,不从界面文案推断。涉及 AppConfig::defaultserde(default)、本地持久化字段时,要先读代码确认。
  • 不给用户隐藏的默认规则。词库、替换表、自动修正规则默认应为空,除非明确要求内置 starter rules。

什么时候使用通用组件

满足以下任意情况,应优先抽成通用组件或复用已有通用组件:

  • 两个及以上页面出现同一种交互结构,例如弹窗、表格编辑、原文/结果预览、文件选择、保存覆盖确认。
  • UI 骨架一致,只是标题、说明、按钮文案、校验开关或提示文案不同。
  • 多个页面共享同一种数据结构、解析规则、序列化规则或校验规则。
  • 用户操作心智一致,分开实现会导致按钮位置、字段顺序、错误提示或可访问性行为不一致。
  • 后续维护需要同步改动多个页面,例如词库编辑、规则列表、保存覆盖流程。

已有例子:

  • RuleDictionaryModal.vue 是自定义词库的统一弹窗骨架。
  • ruleDictionary.ts 是词库解析、序列化、增删改、有效规则过滤的共享逻辑。
  • 字幕校对、繁简转换、CC 字幕整理应共享同一个词库弹窗结构,只调整各自的说明、校验能力和业务映射。

什么时候不要抽通用组件

以下情况先保留在页面内,等第二个真实场景出现后再抽:

  • 只有一个页面使用,抽取后只是把模板搬到另一个文件。
  • 两个功能看起来相似,但输入输出关系、状态机、错误处理或用户目标不同。
  • 组件需要暴露大量业务开关才能兼容多个页面,导致通用组件比页面本身更难读。
  • 抽取会把页面核心流程拆散,例如压制任务编排、媒体处理命令预览、复杂保存流程。
  • 复用的是视觉外观但不是交互模型。这类优先复用 CSS class、设计 token 或小控件,而不是抽大组件。

判断标准:通用组件应该消除真实重复,并让页面只表达业务差异;如果页面需要为通用组件做大量适配,说明抽象过早。

通用组件设计规则

  • 通用组件负责交互骨架和稳定行为,页面负责业务文案、业务开关和数据来源。
  • props 应表达能力差异,例如是否校验正则、是否支持捕获组、弹窗标题、说明、ARIA 标签。
  • 不要为了一个页面写死文案、默认词库、路径、业务状态或后端命令。
  • 组件事件保持少而清晰,优先使用 v-model 管理主要值,用明确事件处理确认、关闭、删除等动作。
  • 同一个组件在不同页面使用时,结构应一致;差异放在说明文字、字段标签、校验策略和提交映射上。
  • 可访问性属性要作为组件契约维护。Vue 组件 props 使用 camelCase 传入,例如 ariaLabel

文件输入交互

  • 需要用户选择本地文件或目录的功能,必须同时支持拖拽和点击选择。
  • 空状态优先使用压制页 VideoMetaCard.vue 的 dropzone 模式:明确提示“拖入什么文件”、支持格式、以及一个 选择文件 按钮。
  • 已选择文件后,优先使用 PathPickerField.vue 展示当前路径和 选择 按钮;需要清除、编辑输出路径或命名模板时,再扩展为业务组件。
  • 多输入场景要按文件类型自动分发,例如视频、字幕、音频、封面图、TS 分片目录,而不是要求用户按严格顺序操作。
  • 拖拽进入时要有全局或页面级 overlay 提示,说明松开后会被当前页面如何处理。
  • 文件选择对话框必须设置明确的标题和扩展名过滤;目录选择、保存路径和输入文件选择要分开处理。
  • 输出路径应优先自动生成,但允许用户手动修改;用户手动修改后,不要因为输入文件变化随意覆盖用户选择。

命令型流程

涉及 ffmpeg、批处理、文件转换、压制、封装、合并、拆分等会执行外部命令或长任务的功能,交互应参考压制页:

  • 必须有命令预览能力,优先复用 CommandPreviewCard.vue 展示最终命令参数。
  • 参数变化后自动刷新命令预览,使用 debounce,避免每个输入字符都触发后端构建。
  • 命令预览默认可以折叠;主操作区优先复用 CommandTaskActions.vue 提供 显示命令预览 / 隐藏命令预览、开始和取消按钮。
  • 主操作按钮放在操作区右侧或主要位置,文案使用具体动作,例如 开始压制开始转换开始合并
  • 运行中主按钮切换为取消动作,使用 danger 样式,例如 取消压制取消转换
  • 主按钮必须绑定完整的可执行条件:依赖环境可用、必填输入存在、输出路径存在、当前没有运行、额外输入满足当前模式。
  • 运行时锁定会改变命令的输入项、模式切换和文件选择;只允许查看日志、复制日志、取消任务等安全操作。
  • 任务进度和日志优先复用 JobLogPanel.vue,保持空态、进度、耗时、ETA、速度、日志复制等表现一致。
  • 失败信息要落到日志或 toast 中;如果失败原因属于不兼容容器、缺少 ffmpeg、缺少滤镜等,应给出下一步去哪里处理。

选项控件基准

新增选项控件时,优先参考压制页已有控件,而不是临时写一套新样式:

  • 下拉选择:使用 AppSelect.vue。适用于编码器、码率模式、样式选择、命名模板等有限枚举;需要描述时用 option description。
  • 数字输入:参考 EncodeSettingsFields.vue 的质量值、码率输入。必须限制 min / max 或在 setter 中 clamp;允许留空时用 nullundefined 表示“不生成参数”。
  • 布尔开关:使用 checkbox,并让标签文字说明开启后的真实效果,例如是否启用 LOGO、反交错、AVS、自定义词库。
  • 互斥模式:使用分段按钮或 tablist,例如工具页的模式切换、繁简转换方向;按钮要有 active 态,运行中需要禁用。
  • 自定义文本参数:使用单行 input 或 textarea,并明确说明会拼到什么命令或规则中;危险参数不要悄悄生效。
  • 文件路径:使用只读路径 input 或路径行加 选择 按钮;输出路径需要支持保存对话框或可编辑路径。
  • 参数说明:涉及 ffmpeg 参数、质量、码率、编码器差异时,使用 InfoHint.vue 给出说明和对应命令片段。
  • 图形化复杂配置:例如 LOGO 布局这类需要预览和拖拽的配置,应使用专门编辑器组件,而不是堆叠普通输入框。
  • 操作按钮样式:普通次级操作用 secondary,命令预览切换可使用 secondary command-toggle,危险取消用 danger,主要执行动作使用默认主按钮样式。

工具页功能边界

  • 工具页适合放短流程、明确输入输出、通常 0 到 10 秒内能完成的辅助能力。
  • 压制参数、字幕压制、LOGO、水印、旋转、镜像、缩放、帧率、码率、反交错等优先留在压制页。
  • 视频信息展示优先留在信息页,不在工具页重复做只读信息卡。
  • 通用字幕编辑、时间轴、样式、格式转换、复杂清理优先交给 Aegisub。
  • 工具页当前按 文字处理格式转换媒体处理 组织;新增工具要先判断属于哪一类,还是应该留在现有页面。
  • 格式转换 放字幕格式转换、容器格式转换这类“同一内容换输出格式”的入口,例如 字幕格式转换视频转 MP4

字典和规则类功能

  • 默认不内置词库或替换规则,避免用户不知情地改变文本。
  • 同类规则编辑优先复用 RuleDictionaryModal.vueruleDictionary.ts
  • 共享规则结构保持 targetpattern 语义一致;如果某页面后端契约不同,在页面层做映射。
  • 繁简转换需要保持 from = patternto = target 的业务映射,不改变共享弹窗的左右字段心智。
  • 字幕校对和 CC 字幕整理启用正则校验及捕获组能力;繁简转换按普通词条替换处理。

前后端分层

  • Vue 页面不直接散落 invoke 调用,优先通过 src/api/* 封装 Tauri command。
  • Rust command 负责本地文件、任务执行、命令拼装、错误返回;前端负责状态、交互、预览和结果展示。
  • 共享纯逻辑优先放 src/utils,避免在多个页面复制解析和格式化代码。
  • 后端新增 command 时同步检查注册位置、前端 API 封装和必要测试。

验证要求

  • 前端或共享组件变更后,至少运行 npm run build
  • Rust command、配置模型、后端服务或命令注册变更后,运行 cargo test
  • 只改文档时不强制跑构建,但要检查 Markdown 文件位置和命名是否符合现有 docs 结构。

Git 规范

  • 提交信息必须使用中文,并保留 Conventional Commits 前缀,例如 feat: 增加环境检测提示
  • 拉取代码必须使用 rebase,例如 git pull --rebase
  • 提交前检查 git status --short,不要把无关用户改动混入当前提交。
  • 如果状态显示有文件变更但 diff 不明显,重新检查暂存区和工作区,不要直接回滚用户改动。