function CreateReceiptImportApp() { const loadMarker = document.getElementById('receiptImportApp'); if (loadMarker) { DoCreateReceiptImportApp(); } } function DoCreateReceiptImportApp() { new Vue({ el: '#receiptImportApp', mixins: [DateMixin, ToastMixin, ApiMixin, Base64Mixin], data: { selectedFile: null, isProcessing: false, validationMessages: [], validationSuccess: false, validatedRowCount: 0, importMessages: [], importSuccess: false, importSuccessCount: 0, importFailCount: 0, importDone: false }, methods: { async downloadTemplate() { try { this.isProcessing = true; const result = await this.callApiWithErrorMsg('領據處理', 'DownloadImportTemplate', {}, '下載範本'); const excelData = result.Data && result.Data.excelData; if (!excelData) { this.ShowError('下載失敗:未取得範本檔案資料'); return; } const blob = this.Base64ToBlob(excelData); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = (result.Data && result.Data.fileName) || '領據資料匯入格式.xlsx'; link.click(); this.ShowSuccess('範本下載成功'); } catch (error) { console.error('downloadTemplate error:', error); } finally { this.isProcessing = false; } }, onFileSelected(event) { const file = event.target.files[0]; if (!file) return; this.selectedFile = file; this.validationMessages = []; this.validationSuccess = false; this.validatedRowCount = 0; this.importMessages = []; this.importSuccess = false; this.importSuccessCount = 0; this.importFailCount = 0; this.importDone = false; }, uploadFile() { if (!this.selectedFile) { this.ShowWarning('請先選擇檔案'); return; } this.isProcessing = true; this.validationMessages = []; this.validationSuccess = false; this.validatedRowCount = 0; const formData = new FormData(); formData.append('file', this.selectedFile); const uploadUrl = API_BASE + '/ReceiptUploadHandler.ashx'; fetch(uploadUrl, { method: 'POST', body: formData }) .then(response => { if (!response.ok) { throw new Error('HTTP error! status: ' + response.status); } return response.text(); }) .then(text => { try { const result = JSON.parse(text); if (result && result.Success) { const uploadedFilePath = result.Data; this.ShowSuccess('檔案上傳成功'); this.ValidateUploadedFile(uploadedFilePath); } else { const errorMsg = result ? result.Message : '上傳失敗'; this.ShowError('上傳失敗:' + errorMsg); this.isProcessing = false; } } catch (e) { console.error('Parse response error:', e, 'Response text:', text); this.ShowError('檔案上傳失敗:回應格式錯誤'); this.isProcessing = false; } }) .catch(error => { console.error('Upload error:', error); this.ShowError('檔案上傳失敗:' + error.message); this.isProcessing = false; }); }, async ValidateUploadedFile(filePath) { try { const result = await this.callApiWithErrorMsg('領據處理', 'ValidateImportFile', { filePath: filePath }, '驗證檔案'); const data = result.Data || {}; if (data.Success) { this.validationSuccess = true; this.validatedRowCount = data.RowCount || 0; const warnings = data.Warnings || []; if (warnings.length > 0) { this.validationMessages = ['驗證通過,但有以下重複資料警告:'].concat(warnings); this.ShowWarning('驗證通過,但有重複資料,請確認後再匯入'); } else { this.validationMessages = ['驗證通過']; this.ShowSuccess('檔案驗證成功'); } } else { this.validationSuccess = false; this.validationMessages = data.Errors || ['驗證失敗']; this.ShowError('檔案驗證失敗'); } } catch (error) { console.error('ValidateUploadedFile error:', error); this.validationSuccess = false; } finally { this.isProcessing = false; } }, async importData() { if (!this.validationSuccess) { this.ShowWarning('請先上傳並驗證檔案'); return; } if (this.importDone) { this.ShowWarning('匯入已完成,請點擊「重新匯入」開始新的匯入'); return; } try { this.isProcessing = true; const result = await this.callApiWithErrorMsg('領據處理', 'ImportReceiptData', {}, '匯入'); const data = result.Data || {}; const successCount = data.successCount || 0; const failCount = data.failCount || 0; const failedRows = data.failedRows || []; this.importSuccessCount = successCount; this.importFailCount = failCount; this.importMessages = failedRows; this.importSuccess = (failCount === 0); if (this.importSuccess) { this.ShowSuccess('匯入成功,共匯入 ' + successCount + ' 筆'); } else { this.ShowWarning('匯入完成,成功 ' + successCount + ' 筆,失敗 ' + failCount + ' 筆'); } this.importDone = true; } catch (error) { console.error('importData error:', error); this.importSuccess = false; } finally { this.isProcessing = false; } }, resetImport() { this.selectedFile = null; this.validationMessages = []; this.validationSuccess = false; this.validatedRowCount = 0; this.importMessages = []; this.importSuccess = false; this.importSuccessCount = 0; this.importFailCount = 0; this.importDone = false; const fileInput = document.querySelector('#receiptImportApp input[type="file"]'); if (fileInput) { fileInput.value = ''; } }, } }); }