# 前端页面 ## 布局 单页面应用,无需路由。自上而下: ``` ┌─────────────────────────────────────────┐ │ ConfigSelector │ │ [选择配置 ▼] [+ 添加配置] │ ├─────────────────────────────────────────┤ │ VersionTable │ │ ┌──────────┬────────────────┬────────┐ │ │ │ MC 版本 │ 构建产物 │ 源码 │ │ │ ├──────────┼────────────────┼────────┤ │ │ │ 1.21 │ xxx-1.0.0-... │ xxx.. │ │ │ │ 1.21.1 │ xxx-1.0.0-... │ xxx.. │ │ │ └──────────┴────────────────┴────────┘ │ ├─────────────────────────────────────────┤ │ [一键发布] │ └─────────────────────────────────────────┘ ``` ## 组件 ### ConfigSelector - 下拉框列出 `configs/` 目录下所有配置(按 `name` 显示) - 选中后触发后端解析,刷新 VersionTable - 右侧 `[修改配置]` `[+ 添加配置]` 两个按钮,图标使用 Ant Design 图标库 - 修改配置:弹出 ConfigModal,预填当前配置数据,保存时覆盖原文件 - 添加配置:弹出 ConfigModal,空白表单,保存时创建新文件 - ConfigModal 添加 / 修改共用同一个组件,通过是否传入已有配置数据区分模式 ### VersionTable - 每行:MC 版本 | 兼容范围 | 构建产物文件名 | 源码文件名 - MC 版本与兼容范围由后端计算,版本范围计算逻辑封装在 `lib/utils/mcVersion.ts`,前后端共用 - 构建产物和源码分别匹配 `filename_format` 和 `source_filename_format` - 最后一个版本的兼容范围含泛匹配,显示格式:若覆盖完整的大版本则显示 `1.19.x` / `26.x` 等,否则显示 `1.20.1-1.20.3` 等具体范围。截止版本下拉框可编辑;下拉可选值取 Modrinth 与 CurseForge 元数据 API 返回的 MC 版本并集 - 已发布版本对比(平台差异)留到 PublishModal 第一页分别展示 - 切换 config 后后台解析期间,Table 使用 Ant Design 自带的加载状态 ### PublishModal 点击 `[一键发布]` 后弹出,分两页。 #### 第一页:版本选择 1. 弹出后加载 Modrinth 和 CurseForge 已有版本数据,Table 使用 Ant Design 自带的加载状态 2. 加载完成后,左右两栏布局: - 左栏:Modrinth 版本列表 - 右栏:CurseForge 版本列表 3. 每栏顶部为**待发布版本**(绿色高亮),按顺序排列;下方为已有版本(另一颜色) 4. 每个版本行最左侧有复选框: - 待发布版本:默认勾选,可选择取消 - 已有版本:复选框禁用 - 若某待发布版本在平台上已存在(版本号完全一致),显示为已有版本颜色,复选框禁用 5. 点击"下一步"进入第二页 #### 第二页:发布设置 - **Changelog**:Markdown 编辑器,带 Code / Preview 切换(类似 GitHub 评论框) - **version_type**:下拉选择 `release`(默认) / `beta` / `alpha` - 平台不再勾选(第一页已通过版本复选框隐式确定:某平台无任何勾选的待发布版本即不发布该平台) - 点击"确认发布"开始执行 - 提供"上一步"按钮返回第一页修改选择 #### 发布执行与进度 - 一个 mod version 对应多个 MC version 变体,按顺序逐个提交,**不可并行** - 任一请求失败则取消后续所有任务 - 点击确认后显示两个进度条(仅显示有发布任务的平台): - `平台名: 已发布数 / 总发布数` - 全部完成后或失败后,弹出结果 Modal 显示最终状态 ### ConfigModal 添加 / 修改共用一个 Modal 组件。添加模式为空表单;修改模式预填当前配置数据,保存时覆盖原文件。 弹出后需请求 Modrinth 和 CurseForge API 获取可选值,Table / Select 使用 Ant Design 自带的加载状态。加载完成后显示表单: **通用字段** | 字段 | 控件 | 说明 | |------|------|------| | `name` | Input | 配置文件显示名称 | | `project_dir` | Input + 目录选择 | 项目目录绝对路径 | | `minecraft_properties_dir` | Input | 默认 `./properties` | | `project_properties_path` | Input | 默认 `./gradle.properties` | | `mod_version_field` | Input | 默认 `mod_version` | | `filename_format` | Input | 含 `${version}` `${mc_version}` | | `source_filename_format` | Input | 含 `${version}` `${mc_version}` | **Modrinth 字段** | 字段 | 控件 | 说明 | |------|------|------| | `project_id` | Input | 项目 ID(8 位 base62)。输入后使用 Ant Design 防抖 hook 自动查询项目名称并显示在输入框下方以供确认 | | `version_name` | Input | 模板字符串,含占位符。默认 `"ModName v${version} for Minecraft ${mc_version_range}"`。使用防抖自动显示匹配到的版本数量 | | `version` | Input | 模板字符串,含占位符 | | `loaders` | Select(多选) | 选项从 `GET /tag/loader` 获取 | | `environment` | Select | 运行环境,必填。选项使用 Ant Design OptGroup 分组,具体分组参考 `docs/modrinth/upload.md` 中的 `environment` 枚举值章节 | | `dependencies` | 动态列表 | 每项含 `dependency_type`(Select:required/optional/incompatible/embedded)和 `project_id`(Input) | **CurseForge 字段** | 字段 | 控件 | 说明 | |------|------|------| | `project_id` | InputNumber | 项目 ID(数字)。输入后使用 Ant Design 防抖 hook 自动查询项目名称并显示在输入框下方以供确认 | | `version_name` | Input | 模板字符串,含占位符。默认 `"#{filename_format}"`。使用防抖自动显示匹配到的版本数量 | | `environment` | Select(多选) | 选项从 Game Version Types API(Environment 类型)获取 | | `loaders` | Select(多选) | 选项从 Game Version Types API(Modloader 类型)获取 | | `relations` | 动态列表 | 每项含 `slug`(Input)和 `type`(Select:embeddedLibrary/incompatible/optionalDependency/requiredDependency/tool) | > **防抖策略**:`project_id` 和 `version_name` 的防抖延迟需设置较长(建议 800ms~1s),避免触发两个平台 API 的速率限制。 底部:保存按钮,写入 `configs/{name}.json`。