chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,641 @@
|
||||
let taxReceiptApp = null;
|
||||
|
||||
function CreateTaxReceiptApp() {
|
||||
const loadMarker = document.getElementById('taxReceiptApp');
|
||||
if (loadMarker) {
|
||||
DoCreateTaxReceiptApp();
|
||||
}
|
||||
}
|
||||
|
||||
function DoCreateTaxReceiptApp() {
|
||||
taxReceiptApp = new Vue({
|
||||
el: '#taxReceiptApp',
|
||||
mixins: [ToastMixin, ApiMixin],
|
||||
data: {
|
||||
activeTab: 0,
|
||||
currentYear: '',
|
||||
currentClosingMonth: '',
|
||||
newClosingMonth: '',
|
||||
loading: false,
|
||||
message: '',
|
||||
messageType: 'info',
|
||||
summaryTable: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
identity: '',
|
||||
paymentMethod: '',
|
||||
identityOptions: [],
|
||||
paymentMethodOptions: [],
|
||||
dataList: [],
|
||||
loading: false,
|
||||
message: '',
|
||||
messageType: 'info'
|
||||
},
|
||||
detailTable: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
identity: '',
|
||||
certificateType: '',
|
||||
identityOptions: [],
|
||||
certificateTypeOptions: [],
|
||||
dataList: [],
|
||||
selectAll: false,
|
||||
senderEmail: '',
|
||||
emailSubject: '',
|
||||
emailBody: '',
|
||||
loading: false,
|
||||
message: '',
|
||||
messageType: 'info',
|
||||
emailMessage: '',
|
||||
emailMessageType: 'info',
|
||||
previewData: [],
|
||||
showEmailPreview: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initializeData();
|
||||
this.loadSummaryTableDropdowns();
|
||||
this.loadDetailTableDropdowns();
|
||||
// 確保預覽窗口初始為關閉狀態
|
||||
this.detailTable.showEmailPreview = false;
|
||||
this.detailTable.previewData = [];
|
||||
},
|
||||
mounted() {
|
||||
this.loadClosingMonthData();
|
||||
// 再次確保預覽窗口初始為關閉狀態
|
||||
this.$nextTick(() => {
|
||||
this.detailTable.showEmailPreview = false;
|
||||
this.detailTable.previewData = [];
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
initializeData() {
|
||||
// 取得現行年度
|
||||
const now = new Date();
|
||||
this.currentYear = now.getFullYear().toString();
|
||||
},
|
||||
|
||||
async loadClosingMonthData() {
|
||||
try {
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'GetClosingMonth',
|
||||
{},
|
||||
'載入關帳年月資料'
|
||||
);
|
||||
|
||||
if (result && result.Data) {
|
||||
this.currentClosingMonth = result.Data.currentClosingMonth || '';
|
||||
// 初始化新關帳年月為目前月份
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
this.newClosingMonth = `${year}-${month}`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('載入關帳年月失敗:', error);
|
||||
this.showMessage('載入關帳年月失敗: ' + (error.message || '請檢查網路連線'), 'danger');
|
||||
}
|
||||
},
|
||||
|
||||
validateMonth() {
|
||||
if (!this.newClosingMonth) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 驗證格式 YYYY-MM
|
||||
const pattern = /^\d{4}-\d{2}$/;
|
||||
if (!pattern.test(this.newClosingMonth)) {
|
||||
this.showMessage('年月格式不正確,請使用 YYYY-MM 格式', 'danger');
|
||||
this.newClosingMonth = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 驗證年份
|
||||
const [year, month] = this.newClosingMonth.split('-');
|
||||
const yearNum = parseInt(year);
|
||||
const monthNum = parseInt(month);
|
||||
|
||||
// 月份範圍驗證
|
||||
if (monthNum < 1 || monthNum > 12) {
|
||||
this.showMessage('月份必須介於 01 到 12 之間', 'danger');
|
||||
this.newClosingMonth = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 年份不能超過現在
|
||||
const currentYear = new Date().getFullYear();
|
||||
if (yearNum > currentYear) {
|
||||
this.showMessage('年份不能超過現在', 'danger');
|
||||
this.newClosingMonth = '';
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
async saveClosingMonth() {
|
||||
if (!this.newClosingMonth) {
|
||||
this.showMessage('請輸入調整的關帳年月', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// 再次驗證
|
||||
this.validateMonth();
|
||||
if (!this.newClosingMonth) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 確認操作
|
||||
if (!confirm(`確認要將領據關帳年月調整為 ${this.newClosingMonth} 嗎?\n此操作將影響領據的修改權限。`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
const params = {
|
||||
closingMonth: this.newClosingMonth
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'UpdateClosingMonth',
|
||||
params,
|
||||
'保存關帳年月'
|
||||
);
|
||||
|
||||
if (result && result.Success) {
|
||||
this.showMessage('關帳年月已成功更新', 'success');
|
||||
this.currentClosingMonth = this.newClosingMonth;
|
||||
// 清除輸入欄位
|
||||
setTimeout(() => {
|
||||
this.clearForm();
|
||||
}, 1500);
|
||||
} else {
|
||||
this.showMessage(result.Message || '保存失敗,請稍後重試', 'danger');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存失敗:', error);
|
||||
this.showMessage('保存失敗: ' + (error.message || '請檢查網路連線'), 'danger');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
clearForm() {
|
||||
this.newClosingMonth = '';
|
||||
this.message = '';
|
||||
},
|
||||
|
||||
showMessage(text, type = 'info') {
|
||||
this.message = text;
|
||||
this.messageType = type;
|
||||
|
||||
// 3 秒後自動隱藏訊息
|
||||
if (type === 'success' || type === 'info') {
|
||||
setTimeout(() => {
|
||||
this.message = '';
|
||||
}, 3000);
|
||||
}
|
||||
},
|
||||
|
||||
async loadSummaryTableDropdowns() {
|
||||
try {
|
||||
// 加載身分別選項
|
||||
const identityResult = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'GetDropdownLists',
|
||||
{ key: '身分別' },
|
||||
'載入身分別選項'
|
||||
);
|
||||
if (identityResult && identityResult.Data) {
|
||||
this.summaryTable.identityOptions = identityResult.Data.filter(item => item.Value !== '');
|
||||
}
|
||||
|
||||
// 加載付款方式選項
|
||||
const paymentResult = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'GetDropdownLists',
|
||||
{ key: '付款方式' },
|
||||
'載入付款方式選項'
|
||||
);
|
||||
if (paymentResult && paymentResult.Data) {
|
||||
this.summaryTable.paymentMethodOptions = paymentResult.Data.filter(item => item.Value !== '');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加載下拉清單失敗:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async searchSummaryTable() {
|
||||
this.summaryTable.loading = true;
|
||||
this.summaryTable.message = '';
|
||||
this.summaryTable.dataList = [];
|
||||
|
||||
try {
|
||||
const params = {
|
||||
起日: this.summaryTable.startDate ? this.parseDate(this.summaryTable.startDate) : null,
|
||||
迄日: this.summaryTable.endDate ? this.parseDate(this.summaryTable.endDate) : null,
|
||||
身分別: this.summaryTable.identity || null,
|
||||
付款方式: this.summaryTable.paymentMethod || null,
|
||||
輸出方式: 'DATA'
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'SearchSummaryTable',
|
||||
params,
|
||||
'查詢個人費用彙整表'
|
||||
);
|
||||
|
||||
if (result && result.Success) {
|
||||
this.summaryTable.dataList = result.Data || [];
|
||||
if (this.summaryTable.dataList.length === 0) {
|
||||
this.summaryTable.message = '查詢完成,但未找到符合條件的資料';
|
||||
this.summaryTable.messageType = 'info';
|
||||
} else {
|
||||
this.summaryTable.message = `查詢完成,共找到 ${this.summaryTable.dataList.length} 筆資料`;
|
||||
this.summaryTable.messageType = 'success';
|
||||
}
|
||||
} else {
|
||||
this.summaryTable.message = result.Message || '查詢失敗,請稍後重試';
|
||||
this.summaryTable.messageType = 'danger';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查詢失敗:', error);
|
||||
this.summaryTable.message = '查詢失敗: ' + (error.message || '請檢查網路連線');
|
||||
this.summaryTable.messageType = 'danger';
|
||||
} finally {
|
||||
this.summaryTable.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async exportSummaryTable() {
|
||||
if (this.summaryTable.dataList.length === 0) {
|
||||
this.summaryTable.message = '沒有資料可以匯出,請先執行查詢';
|
||||
this.summaryTable.messageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
this.summaryTable.loading = true;
|
||||
this.summaryTable.message = '';
|
||||
|
||||
try {
|
||||
const params = {
|
||||
起日: this.summaryTable.startDate ? this.parseDate(this.summaryTable.startDate) : null,
|
||||
迄日: this.summaryTable.endDate ? this.parseDate(this.summaryTable.endDate) : null,
|
||||
身分別: this.summaryTable.identity || null,
|
||||
付款方式: this.summaryTable.paymentMethod || null,
|
||||
輸出方式: 'EXPORT'
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'SearchSummaryTable',
|
||||
params,
|
||||
'匯出個人費用彙整表'
|
||||
);
|
||||
|
||||
if (result && result.Success && result.Data) {
|
||||
// 下載 Excel 檔案
|
||||
const excelData = result.Data;
|
||||
if (excelData.excelData && excelData.fileName) {
|
||||
this.downloadExcel(excelData.excelData, excelData.fileName);
|
||||
this.summaryTable.message = '匯出成功';
|
||||
this.summaryTable.messageType = 'success';
|
||||
} else {
|
||||
this.summaryTable.message = '匯出失敗:無法取得檔案';
|
||||
this.summaryTable.messageType = 'danger';
|
||||
}
|
||||
} else {
|
||||
this.summaryTable.message = result.Message || '匯出失敗,請稍後重試';
|
||||
this.summaryTable.messageType = 'danger';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('匯出失敗:', error);
|
||||
this.summaryTable.message = '匯出失敗: ' + (error.message || '請檢查網路連線');
|
||||
this.summaryTable.messageType = 'danger';
|
||||
} finally {
|
||||
this.summaryTable.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
parseDate(dateString) {
|
||||
if (!dateString) return null;
|
||||
const date = new Date(dateString);
|
||||
return date.toISOString().split('T')[0];
|
||||
},
|
||||
|
||||
formatCurrency(value) {
|
||||
if (!value) return '0';
|
||||
return new Intl.NumberFormat('zh-TW', {
|
||||
style: 'currency',
|
||||
currency: 'TWD',
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0
|
||||
}).format(value);
|
||||
},
|
||||
|
||||
downloadExcel(excelBase64, fileName) {
|
||||
const binaryString = atob(excelBase64);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
const blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(link);
|
||||
},
|
||||
|
||||
async loadDetailTableDropdowns() {
|
||||
try {
|
||||
// 加載身分別選項
|
||||
const identityResult = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'GetDropdownLists',
|
||||
{ key: '身分別' },
|
||||
'載入身分別選項'
|
||||
);
|
||||
if (identityResult && identityResult.Data) {
|
||||
this.detailTable.identityOptions = identityResult.Data.filter(item => item.Value !== '');
|
||||
}
|
||||
|
||||
// 加載憑證類別選項
|
||||
const certResult = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'GetDropdownLists',
|
||||
{ key: '憑證類別' },
|
||||
'載入憑證類別選項'
|
||||
);
|
||||
if (certResult && certResult.Data) {
|
||||
this.detailTable.certificateTypeOptions = certResult.Data.filter(item => item.Value !== '');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加載下拉清單失敗:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async searchDetailTable() {
|
||||
this.detailTable.loading = true;
|
||||
this.detailTable.message = '';
|
||||
this.detailTable.dataList = [];
|
||||
this.detailTable.selectAll = false;
|
||||
|
||||
try {
|
||||
const params = {
|
||||
起日: this.detailTable.startDate ? this.parseDate(this.detailTable.startDate) : null,
|
||||
迄日: this.detailTable.endDate ? this.parseDate(this.detailTable.endDate) : null,
|
||||
身分別: this.detailTable.identity || null,
|
||||
憑證類別: this.detailTable.certificateType || null,
|
||||
輸出方式: 'DATA'
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'SearchDetailTable',
|
||||
params,
|
||||
'查詢扣繳明細'
|
||||
);
|
||||
|
||||
if (result && result.Success) {
|
||||
var resultData = (result.Data || []).map(item => ({
|
||||
...item,
|
||||
selected: false,
|
||||
showDetail: false
|
||||
}));
|
||||
this.detailTable.dataList = resultData;
|
||||
|
||||
if (this.detailTable.dataList.length === 0) {
|
||||
this.detailTable.message = '查詢完成,但未找到符合條件的資料';
|
||||
this.detailTable.messageType = 'info';
|
||||
} else {
|
||||
this.detailTable.message = `查詢完成,共找到 ${this.detailTable.dataList.length} 筆資料`;
|
||||
this.detailTable.messageType = 'success';
|
||||
}
|
||||
} else {
|
||||
this.detailTable.message = result.Message || '查詢失敗,請稍後重試';
|
||||
this.detailTable.messageType = 'danger';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查詢失敗:', error);
|
||||
this.detailTable.message = '查詢失敗: ' + (error.message || '請檢查網路連線');
|
||||
this.detailTable.messageType = 'danger';
|
||||
} finally {
|
||||
this.detailTable.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async exportDetailTable(kind) {
|
||||
if (this.detailTable.dataList.length === 0) {
|
||||
this.detailTable.message = '沒有資料可以匯出,請先執行查詢';
|
||||
this.detailTable.messageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
this.detailTable.loading = true;
|
||||
this.detailTable.message = '';
|
||||
|
||||
try {
|
||||
const params = {
|
||||
起日: this.detailTable.startDate ? this.parseDate(this.detailTable.startDate) : null,
|
||||
迄日: this.detailTable.endDate ? this.parseDate(this.detailTable.endDate) : null,
|
||||
身分別: this.detailTable.identity || null,
|
||||
憑證類別: this.detailTable.certificateType || null,
|
||||
輸出方式: `EXPORT_${kind}`,
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'SearchDetailTable',
|
||||
params,
|
||||
'匯出扣繳明細'
|
||||
);
|
||||
|
||||
if (result && result.Success && result.Data) {
|
||||
const excelData = result.Data;
|
||||
if (excelData.excelData && excelData.fileName) {
|
||||
this.downloadExcel(excelData.excelData, excelData.fileName);
|
||||
this.detailTable.message = '匯出成功';
|
||||
this.detailTable.messageType = 'success';
|
||||
} else {
|
||||
this.detailTable.message = '匯出失敗:無法取得檔案';
|
||||
this.detailTable.messageType = 'danger';
|
||||
}
|
||||
} else {
|
||||
this.detailTable.message = result.Message || '匯出失敗,請稍後重試';
|
||||
this.detailTable.messageType = 'danger';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('匯出失敗:', error);
|
||||
this.detailTable.message = '匯出失敗: ' + (error.message || '請檢查網路連線');
|
||||
this.detailTable.messageType = 'danger';
|
||||
} finally {
|
||||
this.detailTable.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
toggleSelectAll() {
|
||||
this.detailTable.dataList.forEach(item => {
|
||||
item.selected = this.detailTable.selectAll;
|
||||
});
|
||||
},
|
||||
|
||||
async previewEmail() {
|
||||
// 檢查是否有選中的項目
|
||||
const selectedItems = this.detailTable.dataList.filter(item => item.selected);
|
||||
|
||||
if (selectedItems.length === 0) {
|
||||
this.detailTable.emailMessage = '請先勾選要發送的項目';
|
||||
this.detailTable.emailMessageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
// 檢查郵件設定
|
||||
if (!this.detailTable.senderEmail) {
|
||||
this.detailTable.emailMessage = '請輸入寄件人郵箱';
|
||||
this.detailTable.emailMessageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.detailTable.emailSubject) {
|
||||
this.detailTable.emailMessage = '請輸入郵件主旨';
|
||||
this.detailTable.emailMessageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.detailTable.emailBody) {
|
||||
this.detailTable.emailMessage = '請輸入郵件內文';
|
||||
this.detailTable.emailMessageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
this.detailTable.loading = true;
|
||||
this.detailTable.emailMessage = '';
|
||||
|
||||
try {
|
||||
// 提取選中項目的編號作為講師非講師編號
|
||||
const 講師非講師編號 = selectedItems.map(item => item.講師_非講師編號);
|
||||
|
||||
const params = {
|
||||
起日: this.detailTable.startDate ? this.parseDate(this.detailTable.startDate) : null,
|
||||
迄日: this.detailTable.endDate ? this.parseDate(this.detailTable.endDate) : null,
|
||||
身分別: this.detailTable.identity || null,
|
||||
憑證類別: this.detailTable.certificateType || null,
|
||||
輸出方式: 'PREVIEW',
|
||||
講師非講師編號: 講師非講師編號,
|
||||
寄件人郵箱: this.detailTable.senderEmail,
|
||||
郵件主旨: this.detailTable.emailSubject,
|
||||
郵件內文: this.detailTable.emailBody
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'SendEmail',
|
||||
params,
|
||||
'預覽郵件'
|
||||
);
|
||||
|
||||
if (result && result.Success && result.Data) {
|
||||
this.detailTable.previewData = result.Data || [];
|
||||
this.detailTable.showEmailPreview = true;
|
||||
this.detailTable.emailMessage = '';
|
||||
} else {
|
||||
this.detailTable.emailMessage = result.Message || '預覽失敗,請稍後重試';
|
||||
this.detailTable.emailMessageType = 'danger';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('預覽失敗:', error);
|
||||
this.detailTable.emailMessage = '預覽失敗: ' + (error.message || '請檢查網路連線');
|
||||
this.detailTable.emailMessageType = 'danger';
|
||||
} finally {
|
||||
this.detailTable.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
closeEmailPreview() {
|
||||
this.detailTable.showEmailPreview = false;
|
||||
this.detailTable.previewData = [];
|
||||
},
|
||||
|
||||
async sendEmail() {
|
||||
// 檢查是否有選中的項目
|
||||
const selectedItems = this.detailTable.dataList.filter(item => item.selected);
|
||||
|
||||
if (selectedItems.length === 0) {
|
||||
this.detailTable.emailMessage = '請先勾選要發送的項目';
|
||||
this.detailTable.emailMessageType = 'warning';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm(`確認要發送郵件給 ${selectedItems.length} 位收件者嗎?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.detailTable.loading = true;
|
||||
this.detailTable.emailMessage = '';
|
||||
|
||||
try {
|
||||
// 提取選中項目的編號作為講師非講師編號
|
||||
const 講師非講師編號 = selectedItems.map(item => item.講師_非講師編號);
|
||||
|
||||
const params = {
|
||||
起日: this.detailTable.startDate ? this.parseDate(this.detailTable.startDate) : null,
|
||||
迄日: this.detailTable.endDate ? this.parseDate(this.detailTable.endDate) : null,
|
||||
身分別: this.detailTable.identity || null,
|
||||
憑證類別: this.detailTable.certificateType || null,
|
||||
輸出方式: 'SENDMAIL',
|
||||
講師非講師編號: 講師非講師編號,
|
||||
寄件人郵箱: this.detailTable.senderEmail,
|
||||
郵件主旨: this.detailTable.emailSubject,
|
||||
郵件內文: this.detailTable.emailBody
|
||||
};
|
||||
|
||||
const result = await this.callApiWithErrorMsg(
|
||||
'領據處理',
|
||||
'SendEmail',
|
||||
params,
|
||||
'發送郵件'
|
||||
);
|
||||
|
||||
if (result && result.Success) {
|
||||
this.detailTable.emailMessage = `郵件已排定發送給 ${selectedItems.length} 位收件者`;
|
||||
this.detailTable.emailMessageType = 'success';
|
||||
|
||||
// 關閉預覽小窗
|
||||
this.detailTable.showEmailPreview = false;
|
||||
this.detailTable.previewData = [];
|
||||
|
||||
// 清空勾選
|
||||
this.detailTable.dataList.forEach(item => {
|
||||
item.selected = false;
|
||||
});
|
||||
this.detailTable.selectAll = false;
|
||||
} else {
|
||||
this.detailTable.emailMessage = result.Message || '發送失敗,請稍後重試';
|
||||
this.detailTable.emailMessageType = 'danger';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('發送失敗:', error);
|
||||
this.detailTable.emailMessage = '發送失敗: ' + (error.message || '請檢查網路連線');
|
||||
this.detailTable.emailMessageType = 'danger';
|
||||
} finally {
|
||||
this.detailTable.loading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
canSendEmail() {
|
||||
const hasSelected = this.detailTable.dataList.some(item => item.selected);
|
||||
const hasEmail = this.detailTable.senderEmail && this.detailTable.senderEmail.trim().length > 0;
|
||||
const hasSubject = this.detailTable.emailSubject && this.detailTable.emailSubject.trim().length > 0;
|
||||
const hasBody = this.detailTable.emailBody && this.detailTable.emailBody.trim().length > 0;
|
||||
return hasSelected && hasEmail && hasSubject && hasBody && !this.detailTable.loading;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user