-
-
-
- Ausgewählte Datei: {{ pendingUploadFile?.name }}
-
- Typ: {{ pendingUploadType === 'code_list' ? 'Code-Liste' : 'Pin-Liste' }}
-
- Team: {{ teamToEdit?.name }}
-
- Liga: {{ getTeamLeagueName() }}
-
-
-
-
-
-
-
-
-
-
📄 Hochgeladene Dokumente
-
-
-
- | Dateiname |
- Typ |
- Größe |
- Aktionen |
-
-
-
-
- | {{ document.originalFileName }} |
-
-
- {{ document.documentType === 'code_list' ? 'Code-Liste' : 'Pin-Liste' }}
-
- |
- {{ formatFileSize(document.fileSize) }} |
-
-
- |
-
-
-
-
-
🔄 Automatische Jobs
@@ -443,10 +382,8 @@ export default {
const selectedSeasonId = ref(null);
const currentSeason = ref(null);
const teamDocuments = ref([]);
- const pendingUploadFile = ref(null);
- const pendingUploadType = ref(null);
- const showLeagueSelection = ref(false);
const parsingInProgress = ref(false);
+ const parsingDocuments = ref({});
// PDF-Dialog Variablen
const showPDFViewer = ref(false);
@@ -594,42 +531,34 @@ export default {
const uploadCodeList = () => {
if (!teamToEdit.value) return;
+ if (parsingInProgress.value) {
+ return;
+ }
- // Erstelle ein verstecktes File-Input-Element
const input = document.createElement('input');
input.type = 'file';
input.accept = '.pdf,.doc,.docx,.txt,.csv';
input.onchange = async (event) => {
const file = event.target.files[0];
if (!file) return;
-
- // Speichere die Datei und den Typ für späteres Parsing
- pendingUploadFile.value = file;
- pendingUploadType.value = 'code_list';
-
- // Zeige Liga-Auswahl für Parsing
- showLeagueSelection.value = true;
+ await uploadAndParseDocument(file, 'code_list');
};
input.click();
};
const uploadPinList = () => {
if (!teamToEdit.value) return;
+ if (parsingInProgress.value) {
+ return;
+ }
- // Erstelle ein verstecktes File-Input-Element
const input = document.createElement('input');
input.type = 'file';
input.accept = '.pdf,.doc,.docx,.txt,.csv';
input.onchange = async (event) => {
const file = event.target.files[0];
if (!file) return;
-
- // Speichere die Datei und den Typ für späteres Parsing
- pendingUploadFile.value = file;
- pendingUploadType.value = 'pin_list';
-
- // Zeige Liga-Auswahl für Parsing
- showLeagueSelection.value = true;
+ await uploadAndParseDocument(file, 'pin_list');
};
input.click();
};
@@ -702,136 +631,153 @@ export default {
}
};
- const confirmUploadAndParse = async () => {
- if (!pendingUploadFile.value || !teamToEdit.value?.leagueId) {
- alert('Team ist keiner Liga zugeordnet!');
+ const uploadAndParseDocument = async (file, documentType) => {
+ if (!teamToEdit.value?.leagueId) {
+ await showInfo(
+ 'Hinweis',
+ 'Dieses Team ist keiner Liga zugeordnet.',
+ 'Bitte ordnen Sie dem Team zuerst eine Liga zu, damit Dokumente verarbeitet werden können.',
+ 'warning'
+ );
return;
}
-
+
+ if (parsingInProgress.value) {
+ return;
+ }
+
parsingInProgress.value = true;
-
+
try {
-
- // Schritt 1: Datei als Team-Dokument hochladen
const formData = new FormData();
- formData.append('document', pendingUploadFile.value);
- formData.append('documentType', pendingUploadType.value);
-
+ formData.append('document', file);
+ formData.append('documentType', documentType);
+
const uploadResponse = await apiClient.post(`/team-documents/club-team/${teamToEdit.value.id}/upload`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
-
-
- // Schritt 2: Datei parsen (nur für PDF/TXT-Dateien)
- const fileExtension = pendingUploadFile.value.name.toLowerCase().split('.').pop();
+
+ const fileExtension = file.name.toLowerCase().split('.').pop();
+ const documentLabel = documentType === 'code_list' ? 'Code-Liste' : 'Pin-Liste';
+
if (fileExtension === 'pdf' || fileExtension === 'txt') {
const parseResponse = await apiClient.post(`/team-documents/${uploadResponse.data.id}/parse?leagueid=${teamToEdit.value.leagueId}`);
-
-
const { parseResult, saveResult } = parseResponse.data;
-
- let message = `${pendingUploadType.value === 'code_list' ? 'Code-Liste' : 'Pin-Liste'} erfolgreich hochgeladen und geparst!\n\n`;
+
+ let message = `${documentLabel} erfolgreich hochgeladen und geparst!\n\n`;
message += `Gefundene Spiele: ${parseResult.matchesFound}\n`;
message += `Neue Spiele erstellt: ${saveResult.created}\n`;
- message += `Spiele aktualisiert: ${saveResult.updated}\n`;
-
+ message += `Spiele aktualisiert: ${saveResult.updated}`;
+
if (saveResult.errors.length > 0) {
- message += `\nFehler: ${saveResult.errors.length}\n`;
+ message += `\n\nFehler: ${saveResult.errors.length}\n`;
message += saveResult.errors.slice(0, 3).join('\n');
if (saveResult.errors.length > 3) {
message += `\n... und ${saveResult.errors.length - 3} weitere`;
}
}
-
- // Debug-Informationen anzeigen wenn keine Matches gefunden wurden
+
+ let dialogTitle = 'Erfolg';
+ let dialogType = 'success';
+
if (parseResult.matchesFound === 0) {
- message += `\n\n--- DEBUG-INFORMATIONEN ---\n`;
- message += `Text-Länge: ${parseResult.debugInfo.totalTextLength} Zeichen\n`;
- message += `Zeilen: ${parseResult.debugInfo.totalLines}\n`;
- message += `Erste Zeilen:\n`;
- parseResult.debugInfo.firstFewLines.forEach((line, index) => {
- message += `${index + 1}: "${line}"\n`;
- });
- message += `\nLetzte Zeilen:\n`;
- parseResult.debugInfo.lastFewLines.forEach((line, index) => {
- message += `${parseResult.debugInfo.totalLines - 5 + index + 1}: "${line}"\n`;
- });
- // Fehler-Dialog wenn nichts gefunden wurde
- await showInfo('Fehler', message, '', 'error');
+ dialogTitle = 'Keine Spiele gefunden';
+ dialogType = 'warning';
+ if (parseResult.debugInfo) {
+ message += `\n\nHinweis: Keine Spiele erkannt.\nZeilen im Dokument: ${parseResult.debugInfo.totalLines}`;
+ }
} else if (saveResult.errors.length > 0) {
- // Warnung wenn Spiele gefunden wurden, aber Fehler auftraten
- await showInfo('Warnung', message, '', 'warning');
- } else {
- // Erfolg wenn alles geklappt hat
- await showInfo('Erfolg', message, '', 'success');
+ dialogTitle = 'Warnung';
+ dialogType = 'warning';
}
+
+ await showInfo(dialogTitle, message, '', dialogType);
} else {
- // Für andere Dateitypen nur Upload-Bestätigung
- await showInfo('Information', `${pendingUploadType.value === 'code_list' ? 'Code-Liste' : 'Pin-Liste'} "${pendingUploadFile.value.name}" wurde erfolgreich hochgeladen!`, '', 'info');
+ await showInfo('Information', `${documentLabel} "${file.name}" wurde erfolgreich hochgeladen!`, '', 'info');
}
-
- // Dokumente neu laden
+
await loadTeamDocuments();
-
} catch (error) {
console.error('Fehler beim Hochladen und Parsen der Datei:', error);
- await showInfo('Fehler', 'Fehler beim Hochladen und Parsen der Datei', '', 'error');
+ const responseData = error?.response?.data || {};
+ const errorMessage = responseData.message || responseData.error || error.message || 'Fehler beim Hochladen und Parsen der Datei';
+ await showInfo('Fehler', errorMessage, '', 'error');
} finally {
parsingInProgress.value = false;
- pendingUploadFile.value = null;
- pendingUploadType.value = null;
- showLeagueSelection.value = false;
}
};
-
- const cancelUpload = () => {
- pendingUploadFile.value = null;
- pendingUploadType.value = null;
- showLeagueSelection.value = false;
- };
-
- const getTeamLeagueName = () => {
- if (!teamToEdit.value?.leagueId) return 'Keine Liga zugeordnet';
- const league = leagues.value.find(l => l.id === teamToEdit.value.leagueId);
- return league ? league.name : 'Unbekannte Liga';
- };
-
-
-
- const parsePDF = async (document) => {
- // Finde das Team für dieses Dokument
+const parsePDF = async (document) => {
const team = teams.value.find(t => t.id === document.clubTeamId);
if (!team || !team.leagueId) {
- alert('Team ist keiner Liga zugeordnet!');
+ await showInfo(
+ 'Hinweis',
+ 'Dieses Team ist keiner Liga zugeordnet.',
+ 'Bitte ordnen Sie dem Team zuerst eine Liga zu, um PDF-Dateien zu parsen.',
+ 'warning'
+ );
return;
}
+
+ if (parsingDocuments.value[document.id]) {
+ return;
+ }
+
+ parsingDocuments.value = {
+ ...parsingDocuments.value,
+ [document.id]: true
+ };
try {
-
const response = await apiClient.post(`/team-documents/${document.id}/parse?leagueid=${team.leagueId}`);
-
-
const { parseResult, saveResult } = response.data;
-
- let message = `PDF erfolgreich geparst!\n\n`;
- message += `Gefundene Spiele: ${parseResult.matchesFound}\n`;
+
+ let message = `Gefundene Spiele: ${parseResult.matchesFound}\n`;
message += `Neue Spiele erstellt: ${saveResult.created}\n`;
- message += `Spiele aktualisiert: ${saveResult.updated}\n`;
-
- if (saveResult.errors.length > 0) {
- message += `\nFehler: ${saveResult.errors.length}\n`;
+ message += `Spiele aktualisiert: ${saveResult.updated}`;
+
+ let dialogTitle = 'Erfolg';
+ let dialogType = 'success';
+
+ if (parseResult.matchesFound === 0) {
+ dialogTitle = 'Keine Spiele gefunden';
+ dialogType = 'warning';
+ if (parseResult.debugInfo) {
+ message += `\n\nHinweis: Keine Spiele erkannt.\nZeilen im Dokument: ${parseResult.debugInfo.totalLines}`;
+ }
+ } else if (saveResult.errors.length > 0) {
+ dialogTitle = 'Warnung';
+ dialogType = 'warning';
+ message += `\n\nFehler: ${saveResult.errors.length}\n`;
message += saveResult.errors.slice(0, 3).join('\n');
if (saveResult.errors.length > 3) {
message += `\n... und ${saveResult.errors.length - 3} weitere`;
}
}
-
- this.showInfo('Fehler', message, '', 'error');
+
+ await showInfo(dialogTitle, message, '', dialogType);
+ await loadTeamDocuments();
} catch (error) {
console.error('Fehler beim Parsen der PDF:', error);
- this.showInfo('Fehler', 'Fehler beim Parsen der PDF-Datei', '', 'error');
+ const responseData = error?.response?.data || {};
+ const status = error?.response?.status;
+ let errorMessage = responseData.message || responseData.error || error.message || 'Fehler beim Parsen der PDF-Datei';
+ let details = '';
+
+ if (status === 404 && responseData.error === 'documentnotfound') {
+ errorMessage = 'Das ausgewählte Dokument wurde nicht gefunden.';
+ } else if (status === 400 && responseData.error === 'missingleagueid') {
+ errorMessage = 'Für das ausgewählte Team wurde keine Liga übermittelt.';
+ } else if (error.code === 'ENOENT' || errorMessage.includes('ENOENT')) {
+ errorMessage = 'Die PDF-Datei konnte nicht gefunden werden.';
+ details = 'Bitte laden Sie die Datei erneut hoch und versuchen Sie es noch einmal.';
+ }
+
+ await showInfo('Fehler', errorMessage, details, 'error');
+ } finally {
+ const { [document.id]: _ignored, ...rest } = parsingDocuments.value;
+ parsingDocuments.value = rest;
}
};
@@ -1289,10 +1235,8 @@ export default {
selectedSeasonId,
currentSeason,
teamDocuments,
- pendingUploadFile,
- pendingUploadType,
- showLeagueSelection,
parsingInProgress,
+ parsingDocuments,
showPDFViewer,
pdfUrl,
pdfDialogTitle,
@@ -1317,9 +1261,6 @@ export default {
uploadPinList,
loadTeamDocuments,
loadAllTeamDocuments,
- confirmUploadAndParse,
- cancelUpload,
- getTeamLeagueName,
parsePDF,
getTeamDocuments,
showPDFDialog,