chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
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 = '';
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user