feat(myTischtennis): implement asynchronous team data fetching and job status tracking
- Added a new endpoint to start an asynchronous job for fetching team data, allowing for non-blocking operations. - Implemented job status tracking to retrieve the status of ongoing fetch jobs, enhancing user experience with real-time updates. - Updated the frontend to initiate async fetch requests and poll for job completion, improving data retrieval efficiency and user feedback.
This commit is contained in:
@@ -1176,20 +1176,50 @@ export default {
|
||||
myTischtennisSuccess.value = '';
|
||||
|
||||
try {
|
||||
const response = await apiClient.post('/mytischtennis/fetch-team-data', {
|
||||
const startResponse = await apiClient.post('/mytischtennis/fetch-team-data/async', {
|
||||
clubTeamId: teamToEdit.value.id
|
||||
}, { timeout: 30000 });
|
||||
|
||||
if (response.data && response.data.success) {
|
||||
const successMessage = getSafeMessage(response.data.message, 'Teamdaten erfolgreich abgerufen.');
|
||||
});
|
||||
|
||||
const jobId = startResponse?.data?.jobId;
|
||||
if (!jobId) {
|
||||
throw new Error('Async-Job konnte nicht gestartet werden.');
|
||||
}
|
||||
|
||||
const maxPollAttempts = 120; // ~4 Minuten bei 2s Intervall
|
||||
let completedResponse = null;
|
||||
for (let attempt = 0; attempt < maxPollAttempts; attempt++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
const pollResponse = await apiClient.get(`/mytischtennis/fetch-team-data/jobs/${jobId}`, {
|
||||
timeout: 15000
|
||||
});
|
||||
const job = pollResponse?.data?.job;
|
||||
if (!job) continue;
|
||||
|
||||
if (job.status === 'completed') {
|
||||
completedResponse = job.result;
|
||||
break;
|
||||
}
|
||||
|
||||
if (job.status === 'failed') {
|
||||
const failedMsg = getSafeMessage(job.error, 'Daten konnten nicht abgerufen werden.');
|
||||
throw new Error(failedMsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!completedResponse) {
|
||||
throw new Error('Zeitüberschreitung beim Abruf (Async-Job läuft zu lange).');
|
||||
}
|
||||
|
||||
if (completedResponse && completedResponse.success) {
|
||||
const successMessage = getSafeMessage(completedResponse.message, 'Teamdaten erfolgreich abgerufen.');
|
||||
myTischtennisSuccess.value = successMessage;
|
||||
|
||||
const teamName = getSafeMessage(response.data.data?.teamName, teamToEdit.value?.name || 'Unbekanntes Team');
|
||||
const fetchedCount = getSafeMessage(String(response.data.data?.fetchedCount ?? ''), '0');
|
||||
const teamName = getSafeMessage(completedResponse.data?.teamName, teamToEdit.value?.name || 'Unbekanntes Team');
|
||||
const fetchedCount = getSafeMessage(String(completedResponse.data?.fetchedCount ?? ''), '0');
|
||||
let detailsMessage = `Team: ${teamName}\nAbgerufene Datensätze: ${fetchedCount}`;
|
||||
|
||||
if (response.data.data?.tableUpdate) {
|
||||
const tableUpdate = getSafeMessage(response.data.data.tableUpdate);
|
||||
if (completedResponse.data?.tableUpdate) {
|
||||
const tableUpdate = getSafeMessage(completedResponse.data.tableUpdate);
|
||||
if (tableUpdate) {
|
||||
detailsMessage += `\n\nTabellenaktualisierung:\n${tableUpdate}`;
|
||||
}
|
||||
@@ -1201,23 +1231,25 @@ export default {
|
||||
detailsMessage,
|
||||
'success'
|
||||
);
|
||||
} else if (response.data && response.data.success === false) {
|
||||
const errorTitle = response.data.needsMyTischtennisReauth ? 'Login bei myTischtennis erforderlich' : 'Fehler';
|
||||
const errorMessage = getSafeMessage(response.data.error, 'Daten konnten nicht abgerufen werden.');
|
||||
const details = response.data.debug ? getSafeMessage(JSON.stringify(response.data.debug, null, 2)) : '';
|
||||
} else if (completedResponse && completedResponse.success === false) {
|
||||
const errorTitle = completedResponse.needsMyTischtennisReauth ? 'Login bei myTischtennis erforderlich' : 'Fehler';
|
||||
const errorMessage = getSafeMessage(completedResponse.error, 'Daten konnten nicht abgerufen werden.');
|
||||
const details = completedResponse.debug ? getSafeMessage(JSON.stringify(completedResponse.debug, null, 2)) : '';
|
||||
await showInfo(
|
||||
errorTitle,
|
||||
errorMessage,
|
||||
details,
|
||||
response.data.needsMyTischtennisReauth ? 'warning' : 'error'
|
||||
completedResponse.needsMyTischtennisReauth ? 'warning' : 'error'
|
||||
);
|
||||
myTischtennisError.value = errorMessage;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Team-Daten:', error);
|
||||
const isTimeout = error?.code === 'ECONNABORTED';
|
||||
const isTimeout = error?.code === 'ECONNABORTED' || /Zeitüberschreitung/i.test(String(error?.message || ''));
|
||||
const errData = error?.response?.data || {};
|
||||
const errorMsg = isTimeout ? 'Zeitüberschreitung beim Abruf (Timeout).' : getSafeMessage(errData.message || errData.error, 'Daten konnten nicht abgerufen werden.');
|
||||
const errorMsg = isTimeout
|
||||
? 'Zeitüberschreitung beim Abruf (Timeout).'
|
||||
: getSafeMessage(error?.message || errData.message || errData.error, 'Daten konnten nicht abgerufen werden.');
|
||||
const details = errData.debug ? getSafeMessage(JSON.stringify(errData.debug, null, 2)) : '';
|
||||
myTischtennisError.value = errorMsg;
|
||||
await showInfo('Fehler', errorMsg, details, isTimeout ? 'warning' : 'error');
|
||||
|
||||
Reference in New Issue
Block a user