chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
// ========================================
|
||||
// 匯出參加人員 - Vue.js 應用程式
|
||||
// 檔案位置:Scripts/SignUpExport.js
|
||||
// ========================================
|
||||
|
||||
(() => {
|
||||
'use strict';
|
||||
|
||||
// 檔案下載工具 - 使用後端生成的 Base64
|
||||
const FileDownloader = {
|
||||
downloadFromBase64: function(base64String, fileName) {
|
||||
const link = document.createElement('a');
|
||||
link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + base64String;
|
||||
link.download = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
};
|
||||
|
||||
new Vue({
|
||||
el: '#signUpExportApp',
|
||||
data: {
|
||||
// API
|
||||
apiNameClasses: 'ClassesService',
|
||||
apiNameSignUp: 'SignUpService',
|
||||
// 活動列表
|
||||
courses: [],
|
||||
selectedCourseID: '',
|
||||
// 包含已結案
|
||||
includeClosed: false,
|
||||
// 簽到退時間格式
|
||||
timeFormat: 'datetime',
|
||||
// 匯出資料
|
||||
signupData: null,
|
||||
exporting: false,
|
||||
exportMessage: '',
|
||||
exportSuccess: false
|
||||
},
|
||||
watch: {
|
||||
selectedCourseID: function(newVal) {
|
||||
if (newVal) {
|
||||
this.loadExportData();
|
||||
} else {
|
||||
this.signupData = null;
|
||||
}
|
||||
},
|
||||
includeClosed() {
|
||||
this.loadCourses();
|
||||
},
|
||||
timeFormat() {
|
||||
if (this.selectedCourseID) {
|
||||
this.loadExportData();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('[SignUpExport] Vue app mounted');
|
||||
// 初始載入活動清單
|
||||
this.loadCourses();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 載入活動清單
|
||||
*/
|
||||
async loadCourses() {
|
||||
try {
|
||||
const response = await this.$api.call(this.apiNameClasses, 'SearchClasses', {
|
||||
pageIndex: 1,
|
||||
pageSize: 1000,
|
||||
courseCode: '',
|
||||
courseName: '',
|
||||
courseDate1: null,
|
||||
courseDate2: null,
|
||||
courseLocation: '',
|
||||
projectID: '',
|
||||
closed: this.includeClosed ? null : false
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
const convertedData = this.$dataConvert.convertDatesInObject(response.Data || []);
|
||||
this.courses = convertedData;
|
||||
console.log('[SignUpExport] 載入活動清單成功');
|
||||
} else {
|
||||
this.$message.error(response.Message || '載入活動清單失敗');
|
||||
this.courses = [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[SignUpExport] 載入活動清單錯誤:', error);
|
||||
this.$message.error('載入活動清單發生錯誤');
|
||||
this.courses = [];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 當活動選擇改變時載入資料
|
||||
*/
|
||||
async loadExportData() {
|
||||
if (!this.selectedCourseID) {
|
||||
this.signupData = null;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.$api.call(this.apiNameSignUp, 'ExportSignUps', {
|
||||
courseID: this.selectedCourseID,
|
||||
timeFormat: this.timeFormat
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
this.signupData = response.Data;
|
||||
this.exportMessage = '';
|
||||
console.log('[SignUpExport] 載入匯出資料成功');
|
||||
} else {
|
||||
this.$message.error(response.Message || '載入資料失敗');
|
||||
this.signupData = null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[SignUpExport] 載入資料錯誤:', error);
|
||||
this.$message.error('載入資料發生錯誤');
|
||||
this.signupData = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 執行匯出 - 使用後端 NPOI 生成的 Excel 檔案
|
||||
*/
|
||||
async executeExport() {
|
||||
if (!this.signupData) {
|
||||
this.$message.warning('沒有可匯出的資料');
|
||||
return;
|
||||
}
|
||||
|
||||
this.exporting = true;
|
||||
this.exportMessage = '';
|
||||
|
||||
try {
|
||||
// signupData 已經包含後端生成的 Base64 檔案
|
||||
const fileBase64 = this.signupData.FileBase64;
|
||||
const fileName = this.signupData.FileName;
|
||||
|
||||
if (!fileBase64 || !fileName) {
|
||||
this.$message.error('缺少匯出資料');
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用後端生成的檔案進行下載
|
||||
FileDownloader.downloadFromBase64(fileBase64, fileName);
|
||||
|
||||
this.exportSuccess = true;
|
||||
this.exportMessage = `成功匯出 ${this.signupData.DataCount} 筆資料`;
|
||||
this.$message.success('匯出成功');
|
||||
} catch (error) {
|
||||
console.error('[SignUpExport] 匯出錯誤:', error);
|
||||
this.exportSuccess = false;
|
||||
this.exportMessage = '匯出失敗:' + error.message;
|
||||
this.$message.error('匯出發生錯誤');
|
||||
} finally {
|
||||
this.exporting = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 清除選擇
|
||||
*/
|
||||
clearSelection() {
|
||||
this.selectedCourseID = '';
|
||||
this.signupData = null;
|
||||
this.exportMessage = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* 格式化檔案大小
|
||||
*/
|
||||
formatFileSize(bytes) {
|
||||
if (bytes === 0) return '0 B';
|
||||
const k = 1024;
|
||||
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user