修复: 设备切换防竞态 + isModified 设备模式比较基准修正

This commit is contained in:
2026-04-13 15:48:43 +08:00
parent e0983a693a
commit 717832aa4f

View File

@@ -85,6 +85,10 @@ const saving = ref(false);
const formDataMap = ref<Record<string, Record<string, any>>>({});
// 记录用户修改过的字段
const dirtyFieldsMap = ref<Record<string, Set<string>>>({});
// 设备模式下缓存的全局默认参数: { algoCode: { paramKey: value } }
const originalGlobalParamsMap = ref<Record<string, Record<string, any>>>({});
// 防竞态loadAlgorithms 请求版本计数器
let loadRequestId = 0;
const currentAlgo = computed(() => {
return algorithms.value.find((a) => a.algoCode === activeTab.value);
@@ -131,9 +135,35 @@ async function onDeviceChange() {
async function loadAlgorithms() {
loading.value = true;
const currentRequestId = ++loadRequestId;
try {
// 设备模式下,先请求全局默认参数作为比较基准
if (isDeviceMode.value) {
try {
const globalData = await getAlgorithmList(undefined);
if (currentRequestId !== loadRequestId) return;
if (Array.isArray(globalData)) {
for (const algo of globalData) {
try {
const gp = JSON.parse(algo.globalParams || '{}');
const schema = JSON.parse(algo.paramSchema || '{}');
const baseline: Record<string, any> = {};
for (const k of Object.keys(schema)) {
baseline[k] = gp[k] !== undefined ? gp[k] : schema[k]?.default;
}
originalGlobalParamsMap.value[algo.algoCode] = baseline;
} catch { /* empty */ }
}
}
} catch { /* empty */ }
}
const deviceId = selectedDeviceId.value || undefined;
const data = await getAlgorithmList(deviceId);
// 防竞态:请求期间设备已切换,丢弃本次响应
if (currentRequestId !== loadRequestId) return;
algorithms.value = Array.isArray(data) ? data : [];
if (algorithms.value.length > 0) {
// 保持当前 tab如果不存在则切到第一个
@@ -149,9 +179,13 @@ async function loadAlgorithms() {
activeTab.value = '';
}
} catch {
message.error('加载算法列表失败');
if (currentRequestId === loadRequestId) {
message.error('加载算法列表失败');
}
} finally {
loading.value = false;
if (currentRequestId === loadRequestId) {
loading.value = false;
}
}
}
@@ -194,10 +228,20 @@ function getSchemaDefault(key: string): any {
return currentSchema.value[key]?.default;
}
/** 获取比较基准值:设备模式用全局默认,全局模式用 schema default */
function getBaselineValue(key: string): any {
if (isDeviceMode.value) {
const algo = currentAlgo.value;
if (algo) {
const ogp = originalGlobalParamsMap.value[algo.algoCode];
if (ogp && ogp[key] !== undefined) return ogp[key];
}
}
return getSchemaDefault(key);
}
function isModified(key: string): boolean {
const form = currentFormData.value;
const defaultVal = getSchemaDefault(key);
return form[key] !== defaultVal;
return currentFormData.value[key] !== getBaselineValue(key);
}
async function handleSave() {
@@ -209,11 +253,11 @@ async function handleSave() {
const form = currentFormData.value;
const schema = currentSchema.value;
// 只保存与 paramSchema default 不同的字段
// 只保存与基准值不同的字段(设备模式对比全局默认,全局模式对比 schema default
const toSave: Record<string, any> = {};
for (const key of Object.keys(schema)) {
const defaultVal = schema[key]?.default;
if (form[key] !== defaultVal) {
const baselineVal = getBaselineValue(key);
if (form[key] !== baselineVal) {
toSave[key] = form[key];
}
}
@@ -248,9 +292,9 @@ async function handleSave() {
function resetToDefault(key: string) {
const code = activeTab.value;
const defaultVal = getSchemaDefault(key);
const baselineVal = getBaselineValue(key);
if (formDataMap.value[code]) {
formDataMap.value[code]![key] = defaultVal;
formDataMap.value[code]![key] = baselineVal;
onFieldChange(key);
}
}