456 lines
16 KiB
JavaScript
456 lines
16 KiB
JavaScript
function CreateTrainFareApp() {
|
||
const loadMarker = document.getElementById('TrainFareAPP');
|
||
if (loadMarker) {
|
||
DoCreateTrainFareApp();
|
||
}
|
||
}
|
||
|
||
function DoCreateTrainFareApp() {
|
||
trainFareApp = new Vue({
|
||
el: "#TrainFareAPP",
|
||
mixins: [DateMixin, ToastMixin, ApiMixin],
|
||
data: {
|
||
versions: [],
|
||
selectedVersionId: '',
|
||
isEditMode: false,
|
||
|
||
originStations: [],
|
||
destStations: [],
|
||
fareData: {},
|
||
editFareData: {},
|
||
|
||
loading: false
|
||
},
|
||
mounted() {
|
||
this.LoadVersions();
|
||
},
|
||
methods: {
|
||
async LoadVersions() {
|
||
try {
|
||
const result = await this.callApiWithErrorMsg('火車票價維護', 'GetVersions', {}, '載入版本清單');
|
||
this.versions = result.Data || [];
|
||
if (!this.selectedVersionId && this.versions.length > 0) {
|
||
this.selectedVersionId = this.versions[0].Value;
|
||
this.LoadFareTable();
|
||
}
|
||
} catch (error) {
|
||
console.error('LoadVersions error:', error);
|
||
}
|
||
},
|
||
|
||
async LoadFareTable() {
|
||
if (!this.selectedVersionId) {
|
||
this.originStations = [];
|
||
this.destStations = [];
|
||
this.fareData = {};
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.loading = true;
|
||
const result = await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'GetFareTable',
|
||
{ versionId: this.selectedVersionId },
|
||
'載入票價表'
|
||
);
|
||
|
||
const data = result.Data || {};
|
||
this.originStations = data.originStations || [];
|
||
this.destStations = data.destStations || [];
|
||
this.fareData = data.fares || {};
|
||
this.editFareData = JSON.parse(JSON.stringify(this.fareData));
|
||
this.isEditMode = false;
|
||
} catch (error) {
|
||
console.error('LoadFareTable error:', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
EnterEditMode() {
|
||
this.editFareData = JSON.parse(JSON.stringify(this.fareData));
|
||
this.isEditMode = true;
|
||
},
|
||
|
||
CancelEdit() {
|
||
this.editFareData = {};
|
||
this.isEditMode = false;
|
||
},
|
||
|
||
async SaveChanges() {
|
||
if (!this.selectedVersionId) {
|
||
this.ShowWarning('請先選擇版本');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.loading = true;
|
||
await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'SaveFareTable',
|
||
{
|
||
versionId: this.selectedVersionId,
|
||
fares: JSON.stringify(this.editFareData)
|
||
},
|
||
'儲存'
|
||
);
|
||
this.ShowSuccess('儲存成功');
|
||
this.isEditMode = false;
|
||
this.LoadVersions();
|
||
this.LoadFareTable();
|
||
} catch (error) {
|
||
console.error('SaveChanges error:', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
async DeleteVersion() {
|
||
if (!this.selectedVersionId) {
|
||
this.ShowWarning('請先選擇版本');
|
||
return;
|
||
}
|
||
|
||
if (!confirm(`確定要刪除版本 ${this.selectedVersionId} 嗎?`)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.loading = true;
|
||
await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'DeleteVersion',
|
||
{ versionId: this.selectedVersionId },
|
||
'刪除'
|
||
);
|
||
this.ShowSuccess('版本刪除成功');
|
||
this.selectedVersionId = '';
|
||
this.LoadVersions();
|
||
this.LoadFareTable();
|
||
} catch (error) {
|
||
console.error('DeleteVersion error:', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
GetFare(origin, destination) {
|
||
const key = `${origin}_${destination}`;
|
||
return this.fareData[key] || '';
|
||
},
|
||
|
||
GetFareInput(origin, destination) {
|
||
if (origin === destination) return null;
|
||
const key = `${origin}_${destination}`;
|
||
return this.editFareData[key] || null;
|
||
},
|
||
|
||
SetFareInput(origin, destination, value) {
|
||
if (origin === destination) return;
|
||
const key = `${origin}_${destination}`;
|
||
// 轉換為整數,空值或非數字時設為 0
|
||
const numValue = parseInt(value) || 0;
|
||
this.$set(this.editFareData, key, numValue);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function CreateTrainFareImportExportApp() {
|
||
const loadMarker = document.getElementById('TrainFareImportExportAPP');
|
||
if (loadMarker) {
|
||
DoCreateTrainFareImportExportApp();
|
||
}
|
||
}
|
||
|
||
function DoCreateTrainFareImportExportApp() {
|
||
const importExportApp = new Vue({
|
||
el: "#TrainFareImportExportAPP",
|
||
mixins: [DateMixin, ToastMixin, ApiMixin, Base64Mixin],
|
||
data: {
|
||
activeTab: 'export',
|
||
versions: [],
|
||
exportVersionId: '',
|
||
exportResponse: null,
|
||
|
||
selectedFile: null,
|
||
uploadedFilePath: null,
|
||
importPreviewData: {},
|
||
importOriginStations: [],
|
||
importDestStations: [],
|
||
checkResult: null,
|
||
|
||
loading: false
|
||
},
|
||
computed: {
|
||
isImportButtonDisabled() {
|
||
// 匯入按鈕禁用條件:
|
||
// 1. 沒有上傳檔案
|
||
// 2. 沒有驗證結果
|
||
// 3. 驗證失敗
|
||
// 4. 驗證未完成(success 不為 true)
|
||
return !this.uploadedFilePath ||
|
||
!this.checkResult ||
|
||
!this.checkResult.success;
|
||
},
|
||
exportOriginStations() {
|
||
return this.exportResponse?.Data?.originStations || [];
|
||
},
|
||
exportDestStations() {
|
||
return this.exportResponse?.Data?.destStations || [];
|
||
},
|
||
exportData() {
|
||
return this.exportResponse?.Data?.fares || {};
|
||
}
|
||
},
|
||
mounted() {
|
||
this.LoadVersions();
|
||
},
|
||
watch: {
|
||
exportVersionId() {
|
||
// 版本選擇改變時,重置匯出數據
|
||
this.exportResponse = null;
|
||
}
|
||
},
|
||
methods: {
|
||
async LoadVersions() {
|
||
try {
|
||
const result = await this.callApiWithErrorMsg('火車票價維護', 'GetVersions', {}, '載入版本清單');
|
||
this.versions = result.Data || [];
|
||
} catch (error) {
|
||
console.error('LoadVersions error:', error);
|
||
}
|
||
},
|
||
|
||
async DownloadTemplate() {
|
||
try {
|
||
const result = await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'GetExcelTemplate',
|
||
{},
|
||
'下載範本'
|
||
);
|
||
|
||
// 下載 Excel 檔案
|
||
const excelData = result.Data;
|
||
if (!excelData) {
|
||
this.ShowError('下載失敗:未取得範本檔案資料');
|
||
return;
|
||
}
|
||
|
||
const blob = this.Base64ToBlob(excelData);
|
||
const link = document.createElement('a');
|
||
link.href = URL.createObjectURL(blob);
|
||
link.download = '火車票價_匯入範本.xlsx';
|
||
link.click();
|
||
|
||
this.ShowSuccess('範本下載成功');
|
||
} catch (error) {
|
||
console.error('DownloadTemplate error:', error);
|
||
}
|
||
},
|
||
|
||
async ExportData() {
|
||
if (!this.exportVersionId) {
|
||
this.ShowWarning('請選擇版本');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.loading = true;
|
||
const result = await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'ExportFareData',
|
||
{ versionId: this.exportVersionId },
|
||
'匯出'
|
||
);
|
||
|
||
// 儲存完整響應以供計算屬性使用
|
||
this.exportResponse = result;
|
||
|
||
// 下載 Excel 檔案
|
||
const excelData = result.ExcelData;
|
||
if (!excelData) {
|
||
this.ShowError('匯出失敗:未取得 Excel 檔案資料');
|
||
return;
|
||
}
|
||
|
||
const blob = this.Base64ToBlob(excelData);
|
||
const link = document.createElement('a');
|
||
link.href = URL.createObjectURL(blob);
|
||
link.download = `火車票價_版本${this.exportVersionId}_${new Date().getTime()}.xlsx`;
|
||
link.click();
|
||
|
||
this.ShowSuccess('匯出成功');
|
||
} catch (error) {
|
||
console.error('ExportData error:', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
OnFileSelected(event) {
|
||
const file = event.target.files[0];
|
||
if (!file) return;
|
||
|
||
this.selectedFile = file;
|
||
this.checkResult = null;
|
||
this.importPreviewData = {};
|
||
this.importOriginStations = [];
|
||
this.importDestStations = [];
|
||
|
||
this.UploadFile(file);
|
||
},
|
||
|
||
UploadFile(file) {
|
||
if (!file) {
|
||
this.ShowError('請選擇檔案');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const formData = new FormData();
|
||
formData.append('file', file);
|
||
|
||
// 使用 .ashx Handler 上傳檔案
|
||
const uploadUrl = `${API_BASE}/TrainFareUploadHandler.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);
|
||
}
|
||
} catch (e) {
|
||
console.error('Parse response error:', e);
|
||
console.error('Response text:', text);
|
||
this.ShowError('檔案上傳失敗:回應格式錯誤');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Upload error:', error);
|
||
this.ShowError('檔案上傳失敗:' + error.message);
|
||
});
|
||
} catch (error) {
|
||
console.error('UploadFile error:', error);
|
||
this.ShowError('檔案上傳出錯:' + error.message);
|
||
}
|
||
},
|
||
|
||
async ValidateUploadedFile(filePath) {
|
||
try {
|
||
const result = await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'ValidateImportFile',
|
||
{ filePath: filePath },
|
||
'驗證檔案'
|
||
);
|
||
|
||
this.checkResult = {
|
||
success: result.Success,
|
||
errors: result.Data?.Errors || []
|
||
};
|
||
|
||
if (this.checkResult.success) {
|
||
// 解析預覽資料
|
||
this.uploadedFilePath = filePath;
|
||
this.importPreviewData = result.Data?.Fares || {};
|
||
this.importOriginStations = result.Data?.OriginStations || [];
|
||
this.importDestStations = result.Data?.DestStations || [];
|
||
this.ShowSuccess('檔案驗證成功');
|
||
} else {
|
||
this.ShowError('檔案驗證失敗');
|
||
this.uploadedFilePath = null;
|
||
}
|
||
} catch (error) {
|
||
console.error('ValidateUploadedFile error:', error);
|
||
this.uploadedFilePath = null;
|
||
}
|
||
},
|
||
|
||
CancelImport() {
|
||
this.selectedFile = null;
|
||
this.uploadedFilePath = null;
|
||
this.checkResult = null;
|
||
this.importPreviewData = {};
|
||
this.importOriginStations = [];
|
||
this.importDestStations = [];
|
||
const fileInput = document.querySelector('input[type="file"]');
|
||
if (fileInput) {
|
||
fileInput.value = '';
|
||
}
|
||
},
|
||
|
||
async ImportData() {
|
||
// 匯入按鈕已被禁用,不應該執行到這裡
|
||
// 但仍保留安全檢查作為雙重保障
|
||
if (!this.uploadedFilePath || !this.checkResult || !this.checkResult.success) {
|
||
this.ShowWarning('請先上傳並驗證檔案');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.loading = true;
|
||
const result = await this.callApiWithErrorMsg(
|
||
'火車票價維護',
|
||
'ImportFareData',
|
||
{
|
||
mode: 'new',
|
||
versionId: null,
|
||
filePath: this.uploadedFilePath
|
||
},
|
||
'匯入'
|
||
);
|
||
|
||
this.ShowSuccess('匯入成功');
|
||
this.CancelImport();
|
||
|
||
// 更新版本清單
|
||
if (trainFareApp) {
|
||
trainFareApp.LoadVersions();
|
||
}
|
||
this.LoadVersions();
|
||
} catch (error) {
|
||
console.error('ImportData error:', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
GetExportFare(origin, destination) {
|
||
const key = `${origin}_${destination}`;
|
||
return this.exportData[key] || '';
|
||
},
|
||
|
||
GetImportFare(origin, destination) {
|
||
const key = `${origin}_${destination}`;
|
||
return this.importPreviewData[key] || '';
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
//// 頁面載入時建立 Vue 應用
|
||
//document.addEventListener('DOMContentLoaded', function () {
|
||
// CreateTrainFareApp();
|
||
// CreateTrainFareImportExportApp();
|
||
//});
|