Партии: оптимистичная блокировка (version) — устаревшие правки/отмена отклоняются (фикс гонки завершить-vs-отменить)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ interface FinishRow {
|
||||
export function MatchDetailPage() {
|
||||
const { matchId } = useParams();
|
||||
const id = matchId ? Number(matchId) : null;
|
||||
const { data: match, isLoading } = useMatch(id);
|
||||
const { data: match, isLoading, refetch } = useMatch(id);
|
||||
const finish = useFinishMatch();
|
||||
const del = useDeleteMatch();
|
||||
const uploadAtt = useUploadMatchAttachment(id ?? 0);
|
||||
@@ -59,8 +59,11 @@ export function MatchDetailPage() {
|
||||
const upd = (i: number, patch: Partial<FinishRow>) =>
|
||||
setRows(finishRows.map((r, idx) => (idx === i ? { ...r, ...patch } : r)));
|
||||
|
||||
// Конфликт версий (кто-то изменил партию с другого устройства) → сообщаем и обновляем.
|
||||
const isStale = (e: unknown) => e instanceof ApiError && e.code === "STALE_WRITE";
|
||||
|
||||
const submitFinish = async () => {
|
||||
if (!id) return;
|
||||
if (!id || !match) return;
|
||||
setError(null);
|
||||
try {
|
||||
await finish.mutateAsync({
|
||||
@@ -73,19 +76,34 @@ export function MatchDetailPage() {
|
||||
})),
|
||||
win_reason: winReason,
|
||||
overall_comment: overall.trim() || null,
|
||||
expected_version: match.version,
|
||||
},
|
||||
});
|
||||
toast.show("Партия завершена");
|
||||
} catch (e) {
|
||||
if (isStale(e)) {
|
||||
toast.show("Партия изменилась на другом устройстве — обновлено");
|
||||
refetch();
|
||||
return;
|
||||
}
|
||||
setError(e instanceof ApiError ? e.message : "Не удалось завершить партию");
|
||||
}
|
||||
};
|
||||
|
||||
const remove = async () => {
|
||||
if (!id) return;
|
||||
await del.mutateAsync(id).catch(() => {});
|
||||
toast.show(inProgress ? "Партия отменена" : "Партия удалена");
|
||||
navigate(-1);
|
||||
if (!id || !match) return;
|
||||
try {
|
||||
await del.mutateAsync({ matchId: id, expectedVersion: match.version });
|
||||
toast.show(inProgress ? "Партия отменена" : "Партия удалена");
|
||||
navigate(-1);
|
||||
} catch (e) {
|
||||
if (isStale(e)) {
|
||||
toast.show("Партия изменилась на другом устройстве — обновлено");
|
||||
refetch();
|
||||
return;
|
||||
}
|
||||
toast.show(e instanceof ApiError ? e.message : "Не удалось выполнить");
|
||||
}
|
||||
};
|
||||
|
||||
const sorted = [...match.participants].sort(
|
||||
|
||||
Reference in New Issue
Block a user