feat(ota): 新增获取各「型号+灰度」分组全局最大版本号接口

- 后端新增 /api/ota/latest-versions 接口,返回所有型号和灰度的最大版本号
- 添加数据库查询,基于全量数据分组聚合版本号,避免分页误判最新版本
- 前端新增 fetchGetOtaLatestVersions 接口调用该后端接口
- 在 OTA 页面加入全局最新版本数据加载与缓存,用于 latest 标签判断
- 修改标签判定逻辑,避免仅基于当前页数据导致的错误标记
- 调用时机调整,增删改 OTA 后刷新全局最新版本数据保持同步
This commit is contained in:
eafonyang
2026-08-17 15:11:50 +08:00
parent 952b8bb76e
commit 19ea48ffc8
4 changed files with 56 additions and 10 deletions
@@ -24,6 +24,14 @@ export function fetchGetOta(id: number) {
});
}
/** 各「型号+灰度」分组的全局最大版本号(latest 标签判断依据,不受分页/筛选影响) */
export function fetchGetOtaLatestVersions() {
return request<{ items: Api.Ota.LatestVersionItem[] }>({
url: '/ota/latest-versions',
method: 'get'
});
}
export function fetchCreateOta(data: Record<string, unknown>) {
return request<Api.Ota.OtaItem>({
url: '/ota/',
+7
View File
@@ -89,6 +89,13 @@ declare namespace Api {
id: number;
[key: string]: unknown;
}
/** 各「型号+灰度」分组的全局最大版本号(latest 标签判断依据) */
interface LatestVersionItem {
model: string;
beta: number;
ver_code: number;
}
}
namespace Blacklist {
@@ -18,6 +18,7 @@ import {
fetchDeleteOta,
fetchDeleteOtaTargetDevice,
fetchGetBlackList,
fetchGetOtaLatestVersions,
fetchGetOtaList,
fetchGetOtaTargetDeviceList,
fetchUpdateOta,
@@ -141,20 +142,25 @@ const formRules: FormRules = {
]
};
const latestVersionMap = computed(() => {
const map: Record<string, number> = {};
for (const row of tableData.value) {
const key = `${row.model || ''}__${row.beta}`;
if (map[key] === undefined || row.verCode > map[key]) {
map[key] = row.verCode;
// 各「型号+灰度」分组的全局最大版本号(latest 标签判断依据)。
// 必须基于全量数据(后端 /ota/latest-versions):若基于当前页数据计算,
// 翻页后「页内」最大版本也会被误标为 latest / latest beta
const latestVersions = ref<Record<string, number>>({});
async function loadLatestVersions() {
const { data, error } = await fetchGetOtaLatestVersions();
if (!error && data) {
const map: Record<string, number> = {};
for (const it of data.items || []) {
map[`${it.model || ''}__${it.beta}`] = it.ver_code;
}
latestVersions.value = map;
}
return map;
});
}
function getLatestTag(row: OtaRow) {
const key = `${row.model || ''}__${row.beta}`;
return latestVersionMap.value[key] === row.verCode;
return latestVersions.value[key] === row.verCode;
}
function renderCopyUrlCell(url: string) {
@@ -356,6 +362,8 @@ function handlePackageRemove() {
async function loadData() {
loading.value = true;
// 同步刷新全局最新版本(latest 标签依据,增删改后保持一致)
loadLatestVersions();
const params: Record<string, unknown> = {
skip: (pagination.page - 1) * pagination.pageSize,
limit: pagination.pageSize,