# 开发日志

## 2026-05-08

### 修复：版本管理更新保存不生效

**问题描述：**
- 编辑版本时，将"可选更新"切换为"强制更新"后保存，提示成功但实际未生效
- 编辑版本页面进入后没有数据，全是默认状态

**根因分析：**

1. **编辑页数据获取错误**
   - `[id].vue` 中 `fetchVersion()` 使用了 `data?.version || data`，由于 API 返回的 data 对象包含 `version` 字段（版本号字符串），导致 `data?.version` 返回的是版本号字符串而非版本对象，后续取 `ver.application_id` 等字段均为 `undefined`

2. **Switch 组件事件绑定错误**
   - 项目使用了 Reka UI 的 Switch 组件，该组件明确要求使用 `v-model` 绑定，不支持 `:checked` + `@update:checked` 方式
   - 原代码 `@update:checked` 事件实际上不会触发，导致 `formData.update_strategy` 始终为初始值 `optional`
   - 这是版本更新不生效的真正根因

**修复方案：**

| 文件 | 修改内容 |
|------|----------|
| `frontend/src/pages/admin/versions/[id].vue` | 1. `fetchVersion()` 直接使用 `api.get()` 返回值而非 `data?.version`<br>2. Switch 改用 `v-model="isForcedUpdate"` 绑定 computed getter/setter |
| `frontend/src/pages/admin/versions/create.vue` | Switch 改用 `v-model="isForcedUpdate"` 绑定 computed getter/setter |
| `frontend/src/pages/admin/versions/components/columns.ts` | 状态列改为根据 `update_strategy` 判断（`optional`/`forced`），移除旧的 `active`/`superseded` 判断 |
| `backend/internal/router/admin/versions.go` | 改用 `DB.Model().Where().Updates()` 替代 `DB.Save()`，添加 `RowsAffected` 检查和调试日志 |

**技术要点：**
- Reka UI 的 `SwitchRoot` 组件必须使用 `v-model` 双向绑定，不能使用 `v-model:checked` 或 `:checked` + `@update:checked`
- 组件源码注释：[Switch.vue](../../frontend/src/components/ui/switch/Switch.vue) 第 5-9 行

```vue
<!-- 正确 -->
<UiSwitch v-model="isForcedUpdate" />

<!-- 错误：值不会正确更新 -->
<UiSwitch v-model:checked="form.enabled" />
<UiSwitch :checked="val" @update:checked="val = $event" />
```

---

### 修复：版本状态判断逻辑

**问题描述：**
- 状态列误展示为更新策略（optional/forced），应与策略区分开
- 状态应反映该版本是否仍然生效

**正确逻辑：**
- 同一应用下，版本按 ID 升序排列（ID 越大越新）
- 若存在**更新版本**（ID 更大）且策略为**强制更新** → 当前版本状态为 `superseded`（失效）
- 否则 → 当前版本状态为 `active`（生效）

**举例：**
| 版本 | 策略 | 状态 | 说明 |
|------|------|------|------|
| v1.0.0 (ID=1) | optional | **生效** | 没有比它新的版本 |
| v1.0.0 (ID=1) | optional | **失效** | ID=2 的 v1.0.1 是强制更新 |
| v1.0.0 (ID=1) | forced | **生效** | ID=2 的 v1.0.2 是可选更新 |

**修改文件：**

| 文件 | 修改内容 |
|------|----------|
| `backend/internal/router/admin/versions.go` | `handleGetAllVersions`: 查询所有版本，按 app 分组收集 forced 版本 ID，遍历时检查是否有 ID 更大的 forced 版本<br>`handleGetVersionByID`: 用 COUNT 查询是否有同应用下 ID 更大且策略为 forced 的版本 |
| `frontend/src/pages/admin/versions/components/columns.ts` | 恢复状态列展示 `status` 字段的 `active`/`superseded` |
