chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,528 @@
|
||||
(() => {
|
||||
'use strict';
|
||||
|
||||
new Vue({
|
||||
el: '#messageAccountManageApp',
|
||||
data: {
|
||||
// API
|
||||
apiName: 'MessageAccountManage',
|
||||
// 搜尋條件
|
||||
search: {
|
||||
projectName: '',
|
||||
platformCode: ''
|
||||
},
|
||||
// 搜尋結果
|
||||
accountList: [],
|
||||
loading: false,
|
||||
// 分頁
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
// 搜尋專案自動完成
|
||||
projectSuggestions: [],
|
||||
showProjectSuggestions: false,
|
||||
projectSearchTimeout: null,
|
||||
// 彈窗
|
||||
showModal: false,
|
||||
isNewMode: true,
|
||||
editItem: {
|
||||
ID: 0,
|
||||
ProjectID: '',
|
||||
MMSAccount: '',
|
||||
MMSPassword: '',
|
||||
PlatformCode: '',
|
||||
projectName: '',
|
||||
DB_APPNO: 0
|
||||
},
|
||||
// 編輯模式專案自動完成
|
||||
editProjectSuggestions: [],
|
||||
showEditProjectSuggestions: false,
|
||||
editProjectSearchTimeout: null,
|
||||
// 驗證錯誤訊息
|
||||
validationErrors: {
|
||||
ProjectID: '',
|
||||
MMSAccount: '',
|
||||
MMSPassword: ''
|
||||
},
|
||||
// 編輯狀態
|
||||
showPassword: false,
|
||||
// 平台
|
||||
platforms: [],
|
||||
currentPlatform: null,
|
||||
showPlatformSettings: false,
|
||||
showSwitchPanel: false,
|
||||
switchPlatformCode: ''
|
||||
},
|
||||
computed: {
|
||||
totalPages() {
|
||||
return Math.ceil(this.totalCount / this.pageSize);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('[MessageAccountManage] Vue app mounted');
|
||||
// 初始載入資料
|
||||
this.performSearch();
|
||||
this.loadPlatforms();
|
||||
this.loadCurrentPlatform();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 依 PlatformCode 取得平台顯示名稱
|
||||
*/
|
||||
getPlatformName(platformCode) {
|
||||
if (!platformCode) return '系統預設';
|
||||
const p = this.platforms.find(function(x) { return x.PlatformCode === platformCode; });
|
||||
return p ? p.PlatformName + '(' + p.PlatformCode + ')' : platformCode;
|
||||
},
|
||||
|
||||
/**
|
||||
* 執行搜尋
|
||||
*/
|
||||
async performSearch() {
|
||||
this.currentPage = 1;
|
||||
await this.loadAccounts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 載入簡訊帳號資料
|
||||
*/
|
||||
async loadAccounts() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const response = await this.$api.call(this.apiName, 'Search', {
|
||||
pageNo: this.currentPage,
|
||||
pageSize: this.pageSize,
|
||||
projectID: this.search.projectID || '',
|
||||
platformCode: this.search.platformCode || ''
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
this.accountList = response.Data || [];
|
||||
this.totalCount = response.TotalCount || 0;
|
||||
|
||||
// 初始化密碼隱藏狀態 (使用 $set 確保響應式)
|
||||
this.accountList.forEach(item => {
|
||||
this.$set(item, 'showPassword', false);
|
||||
});
|
||||
|
||||
console.log('[MessageAccountManage] 載入成功,共 ' + this.totalCount + ' 筆');
|
||||
} else {
|
||||
this.$message.error(response.Message || '查詢失敗');
|
||||
this.accountList = [];
|
||||
this.totalCount = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MessageAccountManage] 載入錯誤:', error);
|
||||
this.$message.error('載入資料發生錯誤');
|
||||
this.accountList = [];
|
||||
this.totalCount = 0;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 清除搜尋條件
|
||||
*/
|
||||
clearSearch() {
|
||||
this.search = {
|
||||
projectName: '',
|
||||
platformCode: ''
|
||||
};
|
||||
this.projectSuggestions = [];
|
||||
this.showProjectSuggestions = false;
|
||||
this.performSearch();
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜尋計畫 (搜尋區自動完成)
|
||||
*/
|
||||
searchProjects() {
|
||||
// 清除之前的超時
|
||||
if (this.projectSearchTimeout) {
|
||||
clearTimeout(this.projectSearchTimeout);
|
||||
}
|
||||
|
||||
const keyword = this.search.projectName.trim();
|
||||
|
||||
// 如果輸入為空,清空建議和ProjectID
|
||||
if (!keyword) {
|
||||
this.projectSuggestions = [];
|
||||
this.search.projectID = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 延遲搜尋以避免過多API呼叫
|
||||
this.projectSearchTimeout = setTimeout(async () => {
|
||||
try {
|
||||
const response = await this.$api.call(this.apiName, 'SearchProjects', {
|
||||
keyword: keyword
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
this.projectSuggestions = response.Data || [];
|
||||
this.showProjectSuggestions = this.projectSuggestions.length > 0;
|
||||
} else {
|
||||
this.projectSuggestions = [];
|
||||
this.showProjectSuggestions = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MessageAccountManage] 搜尋計畫錯誤:', error);
|
||||
this.projectSuggestions = [];
|
||||
this.showProjectSuggestions = false;
|
||||
}
|
||||
}, 300);
|
||||
},
|
||||
|
||||
/**
|
||||
* 選擇計畫 (搜尋區)
|
||||
*/
|
||||
selectProject(suggestion) {
|
||||
this.search.projectID = suggestion.Value;
|
||||
this.search.projectName = `${suggestion.Value} - ${suggestion.Name}`;
|
||||
this.projectSuggestions = [];
|
||||
this.showProjectSuggestions = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 隱藏計畫建議 (搜尋區 - 延遲隱藏以允許點擊)
|
||||
*/
|
||||
hideProjectSuggestions() {
|
||||
setTimeout(() => {
|
||||
this.showProjectSuggestions = false;
|
||||
}, 200);
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜尋編輯模式的計畫 (自動完成)
|
||||
*/
|
||||
searchEditProjectSuggestions() {
|
||||
// 清除之前的超時
|
||||
if (this.editProjectSearchTimeout) {
|
||||
clearTimeout(this.editProjectSearchTimeout);
|
||||
}
|
||||
|
||||
const keyword = this.editItem.projectName.trim();
|
||||
|
||||
// 如果輸入為空,清空建議和ProjectID
|
||||
if (!keyword) {
|
||||
this.editProjectSuggestions = [];
|
||||
this.editItem.ProjectID = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 延遲搜尋以避免過多API呼叫
|
||||
this.editProjectSearchTimeout = setTimeout(async () => {
|
||||
try {
|
||||
const response = await this.$api.call(this.apiName, 'SearchProjects', {
|
||||
keyword: keyword
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
this.editProjectSuggestions = response.Data || [];
|
||||
this.showEditProjectSuggestions = this.editProjectSuggestions.length > 0;
|
||||
} else {
|
||||
this.editProjectSuggestions = [];
|
||||
this.showEditProjectSuggestions = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MessageAccountManage] 搜尋編輯模式計畫錯誤:', error);
|
||||
this.editProjectSuggestions = [];
|
||||
this.showEditProjectSuggestions = false;
|
||||
}
|
||||
}, 300);
|
||||
},
|
||||
|
||||
/**
|
||||
* 選擇編輯模式的計畫
|
||||
*/
|
||||
selectEditProject(suggestion) {
|
||||
this.editItem.ProjectID = suggestion.Value;
|
||||
this.editItem.projectName = `${suggestion.Value} - ${suggestion.Name}`;
|
||||
this.editProjectSuggestions = [];
|
||||
this.showEditProjectSuggestions = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 隱藏編輯模式的計畫建議 (延遲隱藏以允許點擊)
|
||||
*/
|
||||
hideEditProjectSuggestions() {
|
||||
setTimeout(() => {
|
||||
this.showEditProjectSuggestions = false;
|
||||
}, 200);
|
||||
},
|
||||
|
||||
/**
|
||||
* 換頁
|
||||
*/
|
||||
goToPage(page) {
|
||||
if (page < 1 || page > this.totalPages) return;
|
||||
this.currentPage = page;
|
||||
this.loadAccounts();
|
||||
},
|
||||
|
||||
/**
|
||||
* 上一頁
|
||||
*/
|
||||
previousPage() {
|
||||
if (this.currentPage > 1) {
|
||||
this.goToPage(this.currentPage - 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 下一頁
|
||||
*/
|
||||
nextPage() {
|
||||
if (this.currentPage < this.totalPages) {
|
||||
this.goToPage(this.currentPage + 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 開啟新增彈窗
|
||||
*/
|
||||
openAddModal() {
|
||||
this.isNewMode = true;
|
||||
this.editItem = {
|
||||
ID: 0,
|
||||
ProjectID: '',
|
||||
MMSAccount: '',
|
||||
MMSPassword: '',
|
||||
PlatformCode: this.currentPlatform ? this.currentPlatform.PlatformCode : '',
|
||||
projectName: '',
|
||||
DB_APPNO: 0
|
||||
};
|
||||
this.showEditProjectSuggestions = false;
|
||||
this.showPassword = false;
|
||||
this.clearValidationErrors();
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 開啟編輯彈窗
|
||||
*/
|
||||
openEditModal(item) {
|
||||
this.isNewMode = false;
|
||||
this.editItem = {
|
||||
ID: item.ID,
|
||||
ProjectID: item.ProjectID,
|
||||
MMSAccount: item.MMSAccount,
|
||||
MMSPassword: item.MMSPassword,
|
||||
PlatformCode: item.PlatformCode || '',
|
||||
projectName: item.ProjectName ? `${item.ProjectID} - ${item.ProjectName}` : item.ProjectID,
|
||||
DB_APPNO: item.DB_APPNO
|
||||
};
|
||||
this.editProjectSuggestions = [];
|
||||
this.showEditProjectSuggestions = false;
|
||||
this.showPassword = false;
|
||||
this.clearValidationErrors();
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 關閉彈窗
|
||||
*/
|
||||
closeModal() {
|
||||
this.showModal = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 清除驗證錯誤訊息
|
||||
*/
|
||||
clearValidationErrors() {
|
||||
this.validationErrors = {
|
||||
ProjectID: '',
|
||||
MMSAccount: '',
|
||||
MMSPassword: ''
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 驗證輸入
|
||||
*/
|
||||
validateInput() {
|
||||
this.clearValidationErrors();
|
||||
let isValid = true;
|
||||
|
||||
// 驗證計畫代號
|
||||
if (!this.editItem.ProjectID || this.editItem.ProjectID.trim() === '') {
|
||||
this.validationErrors.ProjectID = '計畫代號為必填欄位';
|
||||
isValid = false;
|
||||
} else if (this.editItem.ProjectID.length > 20) {
|
||||
this.validationErrors.ProjectID = '計畫代號最長 20 個字元';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// 驗證簡訊帳號
|
||||
if (!this.editItem.MMSAccount || this.editItem.MMSAccount.trim() === '') {
|
||||
this.validationErrors.MMSAccount = '簡訊帳號為必填欄位';
|
||||
isValid = false;
|
||||
} else if (this.editItem.MMSAccount.length > 50) {
|
||||
this.validationErrors.MMSAccount = '簡訊帳號最長 50 個字元';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// 驗證簡訊密碼
|
||||
if (!this.editItem.MMSPassword || this.editItem.MMSPassword.trim() === '') {
|
||||
this.validationErrors.MMSPassword = '簡訊密碼為必填欄位';
|
||||
isValid = false;
|
||||
} else if (this.editItem.MMSPassword.length > 50) {
|
||||
this.validationErrors.MMSPassword = '簡訊密碼最長 50 個字元';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
},
|
||||
|
||||
/**
|
||||
* 儲存簡訊帳號
|
||||
*/
|
||||
async saveAccount() {
|
||||
if (!this.validateInput()) return;
|
||||
|
||||
try {
|
||||
// 準備資料
|
||||
const item = {
|
||||
ID: this.editItem.ID,
|
||||
ProjectID: this.editItem.ProjectID.trim(),
|
||||
MMSAccount: this.editItem.MMSAccount.trim(),
|
||||
MMSPassword: this.editItem.MMSPassword.trim(),
|
||||
PlatformCode: this.editItem.PlatformCode.trim(),
|
||||
DB_APPNO: this.editItem.DB_APPNO
|
||||
};
|
||||
|
||||
const response = await this.$api.call(this.apiName, 'Save', {
|
||||
isNew: this.isNewMode,
|
||||
item: item
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
this.$message.success(response.Message || '儲存成功');
|
||||
this.closeModal();
|
||||
this.loadAccounts();
|
||||
} else {
|
||||
this.$message.error(response.Message || '儲存失敗');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MessageAccountManage] 儲存錯誤:', error);
|
||||
this.$message.error('儲存發生錯誤');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 刪除簡訊帳號
|
||||
*/
|
||||
async deleteAccount(item) {
|
||||
if (!confirm(`確定要刪除計畫「${item.ProjectID}」的簡訊帳號設定嗎?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.$api.call(this.apiName, 'Delete', {
|
||||
id: item.ID,
|
||||
dbAppNo: item.DB_APPNO
|
||||
});
|
||||
|
||||
if (response.Success) {
|
||||
this.$message.success(response.Message || '刪除成功');
|
||||
this.loadAccounts();
|
||||
} else {
|
||||
this.$message.error(response.Message || '刪除失敗');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MessageAccountManage] 刪除錯誤:', error);
|
||||
this.$message.error('刪除發生錯誤');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 切換密碼顯示/隱藏
|
||||
*/
|
||||
togglePasswordDisplay(item) {
|
||||
this.$set(item, 'showPassword', !item.showPassword);
|
||||
},
|
||||
|
||||
/**
|
||||
* 切換編輯模式密碼顯示/隱藏
|
||||
*/
|
||||
toggleEditPasswordDisplay() {
|
||||
this.showPassword = !this.showPassword;
|
||||
},
|
||||
|
||||
/**
|
||||
* 載入所有平台清單
|
||||
*/
|
||||
async loadPlatforms() {
|
||||
try {
|
||||
const res = await this.$api.call(this.apiName, 'GetPlatforms', {});
|
||||
if (res.Success && res.Data) {
|
||||
this.platforms = res.Data.map(p => Object.assign({ showPwd: false }, p));
|
||||
if (!this.switchPlatformCode && this.platforms.length > 0) {
|
||||
this.switchPlatformCode = this.platforms[0].PlatformCode;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[loadPlatforms]', e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 載入目前預設平台
|
||||
*/
|
||||
async loadCurrentPlatform() {
|
||||
try {
|
||||
const res = await this.$api.call(this.apiName, 'GetCurrentPlatform', {});
|
||||
if (res.Success) this.currentPlatform = res.Data;
|
||||
} catch (e) {
|
||||
console.error('[loadCurrentPlatform]', e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 儲存單一平台帳號設定
|
||||
*/
|
||||
async savePlatformSetting(platform) {
|
||||
try {
|
||||
const res = await this.$api.call(this.apiName, 'SavePlatform', {
|
||||
item: {
|
||||
ID: platform.ID,
|
||||
PlatformCode: platform.PlatformCode,
|
||||
PlatformName: platform.PlatformName,
|
||||
Account: platform.Account,
|
||||
Password: platform.Password,
|
||||
Remark: platform.Remark
|
||||
}
|
||||
});
|
||||
if (res.Success) {
|
||||
this.$message.success(res.Message || '儲存成功');
|
||||
} else {
|
||||
this.$message.error(res.Message || '儲存失敗');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[savePlatformSetting]', e);
|
||||
this.$message.error('儲存發生錯誤');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 切換預設平台
|
||||
*/
|
||||
async setCurrentPlatform() {
|
||||
try {
|
||||
const res = await this.$api.call(this.apiName, 'SetCurrentPlatform', { platformCode: this.switchPlatformCode });
|
||||
if (res.Success) {
|
||||
this.$message.success(res.Message || '切換成功');
|
||||
this.showSwitchPanel = false;
|
||||
await this.loadCurrentPlatform();
|
||||
} else {
|
||||
this.$message.error(res.Message || '切換失敗');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[setCurrentPlatform]', e);
|
||||
this.$message.error('切換發生錯誤');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user