Files
thinkyu/報到系統/Forms/MessageAccountManage.aspx
sryang 577060bc78 chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore
- 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
2026-09-10 09:42:37 +08:00

222 lines
13 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%@ Page Title="簡訊帳號管理" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="MessageAccountManage.aspx.cs" Inherits="報到系統.Forms.MessageAccountManage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<link href="<%= ResolveUrlWithSysVer("~/Content/MessageAccountManage.css") %>" rel="stylesheet" type="text/css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div id="messageAccountManageApp" class="page-container">
<div class="page-header">
<h1 class="page-title">簡訊帳號管理</h1>
<p class="page-description">管理計畫的簡訊發送帳號密碼</p>
</div>
<!-- 目前預設平台區塊(含 inline 切換) -->
<div style="margin-bottom:12px; border:1px solid #c8d8f8; border-radius:4px; background:#f0f4ff; overflow:hidden;">
<div style="padding:10px 16px; display:flex; align-items:center; gap:16px;">
<span>目前預設平台:<strong>{{ currentPlatform ? currentPlatform.PlatformName + '' + currentPlatform.PlatformCode + '' : '載入中...' }}</strong></span>
<button type="button" class="btn btn-secondary btn-sm" @click="showSwitchPanel = !showSwitchPanel">
{{ showSwitchPanel ? '收合' : '切換平台' }}
</button>
</div>
<div v-if="showSwitchPanel" style="padding:10px 16px 14px; border-top:1px solid #c8d8f8; background:#fff; display:flex; align-items:center; gap:12px; flex-wrap:wrap;">
<label style="margin:0;">切換為:</label>
<select v-model="switchPlatformCode" class="form-control" style="width:220px;">
<option v-for="p in platforms" :key="p.PlatformCode" :value="p.PlatformCode">{{ p.PlatformName }}{{ p.PlatformCode }}</option>
</select>
<button type="button" class="btn btn-primary btn-sm" @click="setCurrentPlatform">確認切換</button>
<button type="button" class="btn btn-secondary btn-sm" @click="showSwitchPanel = false">取消</button>
</div>
</div>
<!-- 平台設定區塊 -->
<div class="search-panel" style="margin-bottom:12px;">
<div style="display:flex; align-items:center; cursor:pointer; user-select:none;" @click="showPlatformSettings = !showPlatformSettings">
<strong>平台帳號設定</strong>
<span style="margin-left:8px;">{{ showPlatformSettings ? '▲' : '▼' }}</span>
</div>
<div v-if="showPlatformSettings" style="margin-top:12px;">
<div v-for="p in platforms" :key="p.PlatformCode" style="display:flex; align-items:center; gap:12px; margin-bottom:10px; flex-wrap:wrap;">
<span style="min-width:80px; font-weight:bold;">{{ p.PlatformName }}</span>
<input type="text" v-model="p.Account" class="form-control" style="width:200px;" placeholder="主帳號">
<input :type="p.showPwd ? 'text' : 'password'" v-model="p.Password" class="form-control" style="width:200px;" placeholder="主密碼">
<button type="button" class="btn-template" @click="p.showPwd = !p.showPwd">{{ p.showPwd ? '隱藏' : '顯示' }}</button>
<button type="button" class="btn btn-primary btn-sm" @click="savePlatformSetting(p)">儲存</button>
</div>
</div>
</div>
<!-- 搜尋面板 -->
<div class="search-panel">
<div class="search-row">
<div class="search-field-inline autocomplete-field w-6">
<label class="search-label-inline">計畫</label>
<div class="autocomplete-container" style="flex: 1;">
<input
type="text"
v-model="search.projectName"
@input="searchProjects"
@focus="showProjectSuggestions = true"
@blur="hideProjectSuggestions"
class="search-input autocomplete-input"
placeholder="請輸入計畫編號或名稱">
<div class="autocomplete-dropdown" v-if="showProjectSuggestions && projectSuggestions.length > 0">
<div
v-for="suggestion in projectSuggestions"
:key="suggestion.Value"
class="autocomplete-item"
@click="selectProject(suggestion)">
<span class="autocomplete-value">{{ suggestion.Value }}</span>
<span class="autocomplete-name">{{ suggestion.Name }}</span>
</div>
</div>
</div>
</div>
<div class="search-field-inline w-4">
<label class="search-label-inline">平台</label>
<select v-model="search.platformCode" class="search-input">
<option value="">全部</option>
<option v-for="p in platforms" :key="p.PlatformCode" :value="p.PlatformCode">{{ p.PlatformName }}{{ p.PlatformCode }}</option>
</select>
</div>
</div>
<div class="search-actions">
<button type="button" class="btn btn-secondary" @click="clearSearch">清除</button>
<button type="button" class="btn btn-primary" @click="performSearch">搜尋</button>
<button type="button" class="btn btn-success" style="margin-left: 10px;" @click="openAddModal">新增帳號</button>
</div>
</div>
<!-- 列表區域 -->
<div class="result-panel">
<table class="result-table">
<thead>
<tr>
<th class="text-center">計畫代號</th>
<th class="text-center">計畫名稱</th>
<th class="text-center">平台</th>
<th class="text-center">簡訊帳號</th>
<th class="text-center">簡訊密碼</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<tr v-if="loading">
<td colspan="6" class="empty-message">載入中...</td>
</tr>
<tr v-else-if="accountList.length === 0">
<td colspan="6" class="empty-message">查無資料</td>
</tr>
<tr v-else v-for="item in accountList" :key="item.ID">
<td class="text-center">{{ item.ProjectID }}</td>
<td>{{ item.ProjectName || '' }}</td>
<td class="text-center">{{ getPlatformName(item.PlatformCode) }}</td>
<td class="password-cell">
<span v-if="!item.showPassword" class="password-mask">●●●●●●●●</span>
<span v-else class="password-text">{{ item.MMSAccount }}</span>
</td>
<td class="password-cell">
<span v-if="!item.showPassword" class="password-mask">●●●●●●●●</span>
<span v-else class="password-text">{{ item.MMSPassword }}</span>
<button type="button" class="btn-icon" @click.prevent="togglePasswordDisplay(item)">
{{ item.showPassword ? '隱藏' : '顯示' }}
</button>
</td>
<td class="text-center">
<button type="button" class="btn btn-primary btn-sm" @click="openEditModal(item)">編輯</button>
<button type="button" class="btn btn-danger btn-sm" @click="deleteAccount(item)">刪除</button>
</td>
</tr>
</tbody>
</table>
<!-- 分頁 -->
<div class="pagination" v-if="totalCount > 0">
<button type="button" class="btn btn-secondary btn-sm" :disabled="currentPage === 1" @click="previousPage">上一頁</button>
<span class="pagination-info">第 {{ currentPage }} / {{ totalPages }} 頁,共 {{ totalCount }} 筆</span>
<button type="button" class="btn btn-secondary btn-sm" :disabled="currentPage === totalPages" @click="nextPage">下一頁</button>
</div>
</div>
<!-- 新增/編輯彈窗 -->
<div class="modal" :class="{ show: showModal }">
<div class="modal-dialog">
<div class="modal-header">
<h3 class="modal-title">{{ isNewMode ? '新增簡訊帳號' : '編輯簡訊帳號' }}</h3>
</div>
<div class="modal-body">
<!-- 計畫代號 - 自動完成 -->
<div class="form-group-inline autocomplete-field">
<label class="form-label-inline required">計畫代號</label>
<div class="autocomplete-container" style="flex: 1;">
<input
type="text"
v-model="editItem.projectName"
@input="searchEditProjectSuggestions"
@focus="showEditProjectSuggestions = true"
@blur="hideEditProjectSuggestions"
class="form-control autocomplete-input"
:disabled="!isNewMode"
placeholder="請輸入計畫編號或名稱">
<div class="autocomplete-dropdown" v-if="showEditProjectSuggestions && editProjectSuggestions.length > 0">
<div
v-for="suggestion in editProjectSuggestions"
:key="suggestion.Value"
class="autocomplete-item"
@click="selectEditProject(suggestion)">
<span class="autocomplete-value">{{ suggestion.Value }}</span>
<span class="autocomplete-name">{{ suggestion.Name }}</span>
</div>
</div>
</div>
</div>
<div class="error-message" v-if="validationErrors.ProjectID">{{ validationErrors.ProjectID }}</div>
<!-- 使用平台 -->
<div class="form-group-inline">
<label class="form-label-inline">使用平台</label>
<select v-model="editItem.PlatformCode" class="form-control">
<option v-for="p in platforms" :key="p.PlatformCode" :value="p.PlatformCode">{{ p.PlatformName }}{{ p.PlatformCode }}</option>
</select>
</div>
<!-- 簡訊帳號 -->
<div class="form-group-inline">
<label class="form-label-inline required">簡訊帳號</label>
<input type="text"
v-model="editItem.MMSAccount"
class="form-control"
placeholder="請輸入簡訊帳號"
maxlength="50">
<div class="error-message" v-if="validationErrors.MMSAccount">{{ validationErrors.MMSAccount }}</div>
</div>
<!-- 簡訊密碼 -->
<div class="form-group-inline">
<label class="form-label-inline required">簡訊密碼</label>
<input :type="showPassword ? 'text' : 'password'"
v-model="editItem.MMSPassword"
class="form-control"
placeholder="請輸入簡訊密碼"
maxlength="50">
<button type="button" class="btn-template" @click.prevent="toggleEditPasswordDisplay">
{{ showPassword ? '隱藏' : '顯示' }}
</button>
<div class="error-message" v-if="validationErrors.MMSPassword">{{ validationErrors.MMSPassword }}</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @click="closeModal">取消</button>
<button type="button" class="btn btn-primary" @click="saveAccount">存檔</button>
</div>
</div>
</div>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="script" runat="server">
<script src="<%= ResolveUrlWithSysVer("~/Scripts/MessageAccountManage.js") %>"></script>
</asp:Content>