951 lines
42 KiB
Plaintext
951 lines
42 KiB
Plaintext
<%@ Page Title="" Language="C#" MasterPageFile="~/Site2.Master" AutoEventWireup="true" CodeBehind="財稅作業與領據關帳.aspx.cs" Inherits="Education.Forms.領據系統.財稅作業與領據關帳" %>
|
|
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
|
|
<link rel="stylesheet" href="<%= ResolveClientUrl("~/Styles/領據資料處理.css") %>" />
|
|
<style>
|
|
.tab-container {
|
|
display: flex;
|
|
border-bottom: 2px solid #ddd;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.tab-button {
|
|
flex: 1;
|
|
padding: 10px 16px;
|
|
background: #f8f9fa;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
border-bottom: 3px solid transparent;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.tab-button:hover {
|
|
background: #e9ecef;
|
|
}
|
|
|
|
.tab-button.active {
|
|
background: #fff;
|
|
border-bottom-color: #007bff;
|
|
color: #007bff;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.tab-content {
|
|
padding: 15px 0;
|
|
}
|
|
|
|
.tab-pane {
|
|
animation: fadeIn 0.3s;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.form-section {
|
|
background: #f8f9fa;
|
|
padding: 15px;
|
|
border-radius: 4px;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.form-label {
|
|
font-weight: 500;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.form-group {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* .form-control, .form-control:focus {
|
|
border: 1px solid #ced4da;
|
|
padding: 6px 12px;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.form-control:focus {
|
|
border-color: #80bdff;
|
|
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
|
|
}
|
|
*/
|
|
.alert {
|
|
padding: 10px 12px;
|
|
border-radius: 4px;
|
|
margin-bottom: 12px;
|
|
border-left: 4px solid;
|
|
}
|
|
|
|
.alert-warning {
|
|
background: #fff3cd;
|
|
border-left-color: #ffc107;
|
|
color: #856404;
|
|
}
|
|
|
|
.alert-info {
|
|
background: #d1ecf1;
|
|
border-left-color: #17a2b8;
|
|
color: #0c5460;
|
|
}
|
|
|
|
.alert-success {
|
|
background: #d4edda;
|
|
border-left-color: #28a745;
|
|
color: #155724;
|
|
}
|
|
|
|
.alert-danger {
|
|
background: #f8d7da;
|
|
border-left-color: #dc3545;
|
|
color: #721c24;
|
|
}
|
|
|
|
.text-danger {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.table {
|
|
width: 100%;
|
|
}
|
|
|
|
.table thead th {
|
|
vertical-align: bottom;
|
|
border-bottom: 2px solid #dee2e6;
|
|
background: #f8f9fa;
|
|
font-weight: 600;
|
|
padding: 8px;
|
|
border: 1px solid #dee2e6;
|
|
/*font-size: 12px;*/
|
|
}
|
|
|
|
.table tbody td {
|
|
padding: 8px;
|
|
border: 1px solid #dee2e6;
|
|
vertical-align: middle;
|
|
/*font-size: 12px;*/
|
|
}
|
|
|
|
.table tbody tr:nth-child(even) {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.table tbody tr:hover {
|
|
background: #e9ecef;
|
|
}
|
|
|
|
.table-striped tbody tr:nth-child(odd) {
|
|
background: #fff;
|
|
}
|
|
|
|
.table-bordered {
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
.table-bordered thead th,
|
|
.table-bordered tbody td {
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
/* .table-sm th,
|
|
.table-sm td {
|
|
padding: 5px;
|
|
font-size: 11px;
|
|
}
|
|
*/
|
|
.table-light {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.table-responsive {
|
|
display: block;
|
|
width: 100%;
|
|
overflow-x: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.card {
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 4px;
|
|
margin-bottom: 15px;
|
|
background: white;
|
|
}
|
|
|
|
.card-body {
|
|
padding: 15px;
|
|
}
|
|
|
|
h5 {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
margin-bottom: 0 !important;
|
|
margin-top: 0 !important;
|
|
}
|
|
|
|
.blue80 {
|
|
background: #007bff;
|
|
color: white;
|
|
border-color: #007bff;
|
|
}
|
|
|
|
.blue80:hover:not(:disabled) {
|
|
background: #0056b3;
|
|
border-color: #004085;
|
|
}
|
|
|
|
.row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
margin-right: -6px;
|
|
margin-left: -6px;
|
|
gap: 8px;
|
|
}
|
|
|
|
.col-md-3,
|
|
.col-md-6,
|
|
.col-md-12 {
|
|
flex: 0 0 calc(25% - 12px);
|
|
margin: 0;
|
|
}
|
|
|
|
.col-md-6 {
|
|
flex: 0 0 calc(50% - 12px);
|
|
}
|
|
|
|
.col-md-12 {
|
|
flex: 0 0 calc(100% - 12px);
|
|
}
|
|
|
|
.col-md-4 {
|
|
flex: 0 0 calc(33.333% - 12px);
|
|
margin: 0;
|
|
}
|
|
|
|
.col-md-2 {
|
|
flex: 0 0 calc(16.666% - 12px);
|
|
margin: 0;
|
|
}
|
|
|
|
.mb-2 {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.mb-3 {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.mb-4 {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.mt-3 {
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.mt-4 {
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.ml-2 {
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.button {
|
|
padding: 0 5px;
|
|
/* border: none;
|
|
border-radius: 4px;*/
|
|
cursor: pointer;
|
|
font-weight: 500;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.button:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.green80 {
|
|
background: #28a745;
|
|
color: white;
|
|
border-color: #28a745;
|
|
}
|
|
|
|
.green80:hover:not(:disabled) {
|
|
background: #218838;
|
|
border-color: #1e7e34;
|
|
}
|
|
|
|
.blue80 {
|
|
background: #007bff;
|
|
color: white;
|
|
border-color: #007bff;
|
|
}
|
|
|
|
.blue80:hover:not(:disabled) {
|
|
background: #0056b3;
|
|
border-color: #004085;
|
|
}
|
|
/* 郵件預覽小窗樣式 */
|
|
.modal-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1000;
|
|
visibility: visible;
|
|
opacity: 1;
|
|
}
|
|
|
|
.modal-overlay[style*="display: none"],
|
|
[v-cloak] .modal-overlay {
|
|
display: none !important;
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
}
|
|
|
|
.modal-dialog {
|
|
background: white;
|
|
border-radius: 4px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
width: 90%;
|
|
max-width: 1200px;
|
|
max-height: 90vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.modal-header {
|
|
padding: 15px;
|
|
border-bottom: 2px solid #dee2e6;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.modal-header h5 {
|
|
margin: 0;
|
|
color: #333;
|
|
}
|
|
|
|
.modal-close-btn {
|
|
background: none;
|
|
border: none;
|
|
font-size: 24px;
|
|
cursor: pointer;
|
|
color: #999;
|
|
padding: 0;
|
|
width: 30px;
|
|
height: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.modal-close-btn:hover {
|
|
color: #333;
|
|
}
|
|
|
|
.modal-body {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 15px;
|
|
}
|
|
|
|
.email-preview-item {
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 4px;
|
|
margin-bottom: 15px;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.email-preview-header {
|
|
padding: 12px 15px;
|
|
background: #007bff;
|
|
color: white;
|
|
border-radius: 4px 4px 0 0;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.email-preview-info {
|
|
padding: 12px 15px;
|
|
border-bottom: 1px solid #dee2e6;
|
|
background: white;
|
|
}
|
|
|
|
.email-preview-info-row {
|
|
display: flex;
|
|
margin-bottom: 8px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.email-preview-info-row:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.email-preview-label {
|
|
font-weight: 500;
|
|
min-width: 80px;
|
|
color: #333;
|
|
}
|
|
|
|
.email-preview-content {
|
|
flex: 1;
|
|
color: #666;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.email-preview-body {
|
|
padding: 12px 15px;
|
|
background: white;
|
|
border-bottom: 1px solid #dee2e6;
|
|
color: #333;
|
|
line-height: 1.6;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.email-preview-table {
|
|
padding: 12px 15px;
|
|
background: white;
|
|
}
|
|
|
|
.attachment-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.attachment-table thead th {
|
|
background: #f0f0f0;
|
|
padding: 8px;
|
|
border: 1px solid #dee2e6;
|
|
text-align: left;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
|
|
.attachment-table tbody td {
|
|
padding: 8px;
|
|
border: 1px solid #dee2e6;
|
|
color: #333;
|
|
}
|
|
|
|
.attachment-table tbody tr:nth-child(even) {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.attachment-table tbody tr:hover {
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.attachment-table .summary-row {
|
|
background: #e9ecef;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.attachment-table .summary-row td {
|
|
border-top: 2px solid #dee2e6;
|
|
}
|
|
|
|
.modal-footer {
|
|
padding: 12px 15px;
|
|
border-top: 1px solid #dee2e6;
|
|
background: #f8f9fa;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
}
|
|
|
|
.btn-close {
|
|
background: #6c757d;
|
|
color: white;
|
|
border: none;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.btn-close:hover {
|
|
background: #5a6268;
|
|
}
|
|
</style>
|
|
</asp:Content>
|
|
|
|
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
|
|
<div id="taxReceiptApp">
|
|
<!-- Tab 區塊 -->
|
|
<div class="tab-container">
|
|
<button type="button" class="tab-button" :class="{ active: activeTab === 0 }" v-on:click="activeTab = 0">個人費用彙整表</button>
|
|
<button type="button" class="tab-button" :class="{ active: activeTab === 1 }" v-on:click="activeTab = 1">扣繳明細及寄發通知</button>
|
|
<button type="button" class="tab-button" :class="{ active: activeTab === 2 }" v-on:click="activeTab = 2">領據關帳</button>
|
|
</div>
|
|
|
|
<!-- Tab 內容 -->
|
|
<div class="tab-content">
|
|
<!-- Tab 0: 個人費用彙整表 -->
|
|
<div v-if="activeTab === 0" class="tab-pane">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<!-- 查詢表單 -->
|
|
<div class="form-section mb-4">
|
|
<h5 class="mb-3">查詢條件</h5>
|
|
<div class="alert alert-info mb-3" style="margin-bottom: 12px !important;">
|
|
ⓘ 僅列出已完成列印的領據及差旅費資料
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">起日:</label>
|
|
<input type="date" class="form-control" v-model="summaryTable.startDate">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">迄日:</label>
|
|
<input type="date" class="form-control" v-model="summaryTable.endDate">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">身分別:</label>
|
|
<select class="form-control" v-model="summaryTable.identity">
|
|
<option value="">-- 全部 --</option>
|
|
<option v-for="item in summaryTable.identityOptions" :key="item.Value" :value="item.Value">
|
|
{{ item.Name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">付款方式:</label>
|
|
<select class="form-control" v-model="summaryTable.paymentMethod">
|
|
<option value="">-- 全部 --</option>
|
|
<option v-for="item in summaryTable.paymentMethodOptions" :key="item.Value" :value="item.Value">
|
|
{{ item.Name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<!-- 操作按鈕 -->
|
|
<div class="col-md-4">
|
|
<button type="button" class="button green80" v-on:click="searchSummaryTable" :disabled="summaryTable.loading">
|
|
<span v-if="summaryTable.loading">查詢中...</span>
|
|
<span v-else>查詢</span>
|
|
</button>
|
|
<button type="button" class="button blue80 ml-2" v-on:click="exportSummaryTable" :disabled="summaryTable.loading || summaryTable.dataList.length === 0">
|
|
<span v-if="summaryTable.loading">處理中...</span>
|
|
<span v-else>匯出</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 查詢結果訊息 -->
|
|
<div v-if="summaryTable.message" :class="['alert', 'alert-' + summaryTable.messageType, 'mt-3']" role="alert">
|
|
{{ summaryTable.message }}
|
|
</div>
|
|
|
|
<!-- 查詢結果表格 -->
|
|
<div v-if="summaryTable.dataList.length > 0" class="mt-3">
|
|
<h5 class="mb-2">查詢結果 (共 {{ summaryTable.dataList.length }} 筆)</h5>
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-bordered table-sm">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>領款人姓名</th>
|
|
<th>身分證字號</th>
|
|
<th>堂數</th>
|
|
<th>扣繳類別</th>
|
|
<th>帳戶名</th>
|
|
<th>付款金額</th>
|
|
<th>匯款帳號</th>
|
|
<th>銀行分行代碼</th>
|
|
<th>銀行分行</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="(item, index) in summaryTable.dataList" :key="index">
|
|
<td>{{ item.領款人姓名 }}</td>
|
|
<td>{{ item.身分證字號 }}</td>
|
|
<td class="ta-right">{{ item.堂數 }}</td>
|
|
<td>{{ item.扣繳類別名稱 }}</td>
|
|
<td>{{ item.帳戶名 }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.付款金額) }}</td>
|
|
<td>{{ item.匯款帳號 }}</td>
|
|
<td>{{ item.銀行分行代碼 }}</td>
|
|
<td>{{ item.銀行分行 }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab 1: 扣繳明細及寄發通知 -->
|
|
<div v-if="activeTab === 1" class="tab-pane">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<!-- 查詢條件區塊 -->
|
|
<div class="form-section">
|
|
<h5 class="mb-3">查詢條件</h5>
|
|
<div class="alert alert-info mb-3" style="margin-bottom: 12px !important;">
|
|
ⓘ 僅列出已完成列印的領據資料
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">起日:</label>
|
|
<input type="date" class="form-control" v-model="detailTable.startDate">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">迄日:</label>
|
|
<input type="date" class="form-control" v-model="detailTable.endDate">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">身分別:</label>
|
|
<select class="form-control" v-model="detailTable.identity">
|
|
<option value="">-- 全部 --</option>
|
|
<option v-for="item in detailTable.identityOptions" :key="item.Value" :value="item.Value">
|
|
{{ item.Name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">憑證類別:</label>
|
|
<select class="form-control" v-model="detailTable.certificateType">
|
|
<option value="">-- 全部 --</option>
|
|
<option v-for="item in detailTable.certificateTypeOptions" :key="item.Value" :value="item.Value">
|
|
{{ item.Name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<button type="button" class="button green80" v-on:click="searchDetailTable" :disabled="detailTable.loading">
|
|
<span v-if="detailTable.loading">查詢中...</span>
|
|
<span v-else>查詢</span>
|
|
</button>
|
|
<button type="button" class="button blue80 ml-2" style="width:auto" v-on:click="exportDetailTable('SUMMARY')" :disabled="detailTable.loading || detailTable.dataList.length === 0">
|
|
<span v-if="detailTable.loading">處理中...</span>
|
|
<span v-else>匯出扣繳彙整表</span>
|
|
</button>
|
|
<button type="button" class="button blue80 ml-2" style="width:auto" v-on:click="exportDetailTable('DETAIL')" :disabled="detailTable.loading || detailTable.dataList.length === 0">
|
|
<span v-if="detailTable.loading">處理中...</span>
|
|
<span v-else>匯出扣繳明細表</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 查詢結果訊息 -->
|
|
<div v-if="detailTable.message" :class="['alert', 'alert-' + detailTable.messageType, 'mt-3']" role="alert">
|
|
{{ detailTable.message }}
|
|
</div>
|
|
|
|
<!-- 查詢結果表格 -->
|
|
<div v-if="detailTable.dataList.length > 0" class="mt-3">
|
|
<h5 class="mb-2">查詢結果 (共 {{ detailTable.dataList.length }} 筆)</h5>
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-bordered table-sm">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th style="width: 40px;"><input type="checkbox" v-model="detailTable.selectAll" v-on:change="toggleSelectAll"></th>
|
|
<th style="width: 40px;"></th>
|
|
<th>已發送</th>
|
|
<th>領款人姓名</th>
|
|
<th>身分證字號</th>
|
|
<th>戶籍地址</th>
|
|
<th>扣繳類別</th>
|
|
<th class="ta-right">合計金額</th>
|
|
<th class="ta-right">應扣繳稅額</th>
|
|
<th class="ta-right">服務費</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-for="(item, index) in detailTable.dataList">
|
|
<tr :key="'row-' + index">
|
|
<td class="ta-center"><input type="checkbox" v-model="item.selected"></td>
|
|
<td class="ta-center" style="cursor: pointer;" v-on:click="item.showDetail = !item.showDetail">
|
|
{{ item.showDetail ? '▼' : '▶' }}
|
|
</td>
|
|
<td class="ta-center">{{
|
|
!item.明細 || item.明細.length === 0 ? '未發送' :
|
|
item.明細.filter(function(d){ return d.郵件已發送 === '1'; }).length === item.明細.length ? '已全部發送' :
|
|
item.明細.filter(function(d){ return d.郵件已發送 === '1'; }).length === 0 ? '未發送' :
|
|
'已部分發送'
|
|
}}</td>
|
|
<td class="ta-center">{{ item.領款人姓名 }}</td>
|
|
<td class="ta-center">{{ item.身分證字號 }}</td>
|
|
<td>{{ item.戶籍地址 }}</td>
|
|
<td class="ta-center">{{ item.扣繳類別名稱 }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.講師勞務費合計) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.應扣繳稅額合計) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.服務費合計) }}</td>
|
|
</tr>
|
|
<tr v-show="item.showDetail" class="table-light" :key="'detail-' + index">
|
|
<td colspan="10" style="padding: 10px;">
|
|
<div class="table-responsive">
|
|
<table class="table table-sm" style="margin-bottom: 0;">
|
|
<thead>
|
|
<tr>
|
|
<th>序</th>
|
|
<th>已發送</th>
|
|
<th>計畫代號</th>
|
|
<th>活動日期</th>
|
|
<th>活動名稱/事由</th>
|
|
<th>扣繳類別</th>
|
|
<th class="ta-right">講師/勞務費</th>
|
|
<th class="ta-right">應扣繳稅額</th>
|
|
<th class="ta-right">服務費</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="(detail, detailIndex) in (item.明細 || [])" :key="'detail-' + index + '-' + detailIndex">
|
|
<td class="ta-center">{{ detailIndex + 1 }}</td>
|
|
<td class="ta-center">{{ detail.郵件已發送 === '1' ? '是' : '否' }}</td>
|
|
<td class="ta-center">{{ detail.計畫代號 }}</td>
|
|
<td class="ta-center">{{ detail.活動日期 }}</td>
|
|
<td>{{ detail.活動名稱事由 }}</td>
|
|
<td class="ta-center">{{ item.扣繳類別名稱 }}</td>
|
|
<td class="ta-right">{{ formatCurrency(detail.講師勞務費) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(detail.應扣繳稅額) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(detail.服務費) }}</td>
|
|
</tr>
|
|
<tr v-if="!item.明細 || item.明細.length === 0">
|
|
<td colspan="8" style="text-align: center; color: #999;">沒有明細資料</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</template>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 郵件設定區塊 -->
|
|
<div v-if="detailTable.dataList.length > 0" class="form-section mt-4">
|
|
<h5 class="mb-3">寄件人與郵件內容</h5>
|
|
<div class="row mb-2">
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label class="form-label">寄件人郵箱:</label>
|
|
<input type="email" class="form-control" v-model="detailTable.senderEmail" placeholder="example@example.com" style="width: calc(100% - 8rem);">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label class="form-label">郵件主旨:</label>
|
|
<input type="text" class="form-control" v-model="detailTable.emailSubject" placeholder="輸入郵件主旨" style="width: calc(100% - 8rem);">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label class="form-label">郵件內文:</label>
|
|
<textarea class="form-control" v-model="detailTable.emailBody" rows="5" placeholder="輸入郵件內文" style="width: calc(100% - 8rem);"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<button type="button" class="button blue80" v-on:click="previewEmail" :disabled="!canSendEmail">預覽</button>
|
|
<button type="button" class="button green80 ml-2" v-on:click="sendEmail" :disabled="!canSendEmail">發送</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 郵件預覽/結果訊息 -->
|
|
<div v-if="detailTable.emailMessage" :class="['alert', 'alert-' + detailTable.emailMessageType, 'mt-3']" role="alert">
|
|
{{ detailTable.emailMessage }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab 2: 領據關帳 -->
|
|
<div v-if="activeTab === 2" class="tab-pane">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<!-- 提示訊息 -->
|
|
<div class="alert alert-warning">
|
|
<strong>重要提醒:</strong><br />
|
|
費用出帳後,財務即將領據關帳。<br />
|
|
領據關帳後,只能作廢不能修改,唯總管理處財務部可修改。
|
|
</div>
|
|
|
|
<!-- 表單區域 -->
|
|
<div class="form-section">
|
|
<div class="row mb-2">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label class="form-label">領據現行年度:</label>
|
|
<input type="text" class="form-control" v-model="currentYear" readonly>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-2">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label class="form-label">領據已關帳年月:</label>
|
|
<input type="text" class="form-control" v-model="currentClosingMonth" readonly>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-2">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label class="form-label">調整關帳年月為:<span class="text-danger">*</span></label>
|
|
<input type="month" class="form-control" v-model="newClosingMonth" v-on:change="validateMonth">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 操作按鈕 -->
|
|
<div class="row mt-3">
|
|
<div class="col-md-6">
|
|
<button type="button" class="button green80" v-on:click="saveClosingMonth" :disabled="loading || !newClosingMonth">
|
|
<span v-if="loading">處理中...</span>
|
|
<span v-else>確定</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 訊息提示 -->
|
|
<div v-if="message" :class="['alert', 'alert-' + messageType, 'mt-3']" role="alert">
|
|
{{ message }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 郵件預覽小窗 -->
|
|
<div v-if="detailTable.showEmailPreview" class="modal-overlay" v-on:click.self="closeEmailPreview">
|
|
<div class="modal-dialog">
|
|
<!-- Modal Header -->
|
|
<div class="modal-header">
|
|
<h5>郵件預覽 (共 {{ detailTable.previewData.length }} 封)</h5>
|
|
<button type="button" class="modal-close-btn" v-on:click="closeEmailPreview">×</button>
|
|
</div>
|
|
|
|
<!-- Modal Body -->
|
|
<div class="modal-body">
|
|
<div v-if="detailTable.previewData.length === 0" style="text-align: center; padding: 30px; color: #999;">
|
|
沒有郵件數據
|
|
</div>
|
|
|
|
<template v-for="(email, index) in detailTable.previewData">
|
|
<div class="email-preview-item" :key="index">
|
|
<!-- 郵件頭部 -->
|
|
<div class="email-preview-header">
|
|
郵件 {{ index + 1 }} / {{ detailTable.previewData.length }}
|
|
</div>
|
|
|
|
<!-- 郵件資訊 -->
|
|
<div class="email-preview-info">
|
|
<div class="email-preview-info-row">
|
|
<div class="email-preview-label">收件人:</div>
|
|
<div class="email-preview-content">{{ email.收件人姓名 }} <{{ email.收件人郵箱 }}></div>
|
|
</div>
|
|
<div class="email-preview-info-row">
|
|
<div class="email-preview-label">主旨:</div>
|
|
<div class="email-preview-content">{{ email.主旨 }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 郵件內文 -->
|
|
<div class="email-preview-body">
|
|
{{ email.內文 }}
|
|
</div>
|
|
|
|
<!-- 附件表格 -->
|
|
<div class="email-preview-table">
|
|
<table class="attachment-table">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 10%;">序</th>
|
|
<th style="width: 12%;">計畫代號</th>
|
|
<th style="width: 12%;">活動日期</th>
|
|
<th style="width: 20%;">活動名稱/事由</th>
|
|
<th style="width: 12%;">扣繳類別</th>
|
|
<th style="width: 12%; text-align: right;">講師勞務費</th>
|
|
<th style="width: 12%; text-align: right;">應扣繳稅額</th>
|
|
<th style="width: 12%; text-align: right;">服務費</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-if="email.明細 && email.明細.length > 0">
|
|
<tr v-for="(item, itemIndex) in email.明細" :key="itemIndex">
|
|
<td>{{ itemIndex + 1 }}</td>
|
|
<td>{{ item.計畫代號 }}</td>
|
|
<td>{{ item.活動日期 }}</td>
|
|
<td>{{ item.活動名稱事由 }}</td>
|
|
<td>{{ item.扣繳類別名稱 }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.講師勞務費) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.應扣繳稅額) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(item.服務費) }}</td>
|
|
</tr>
|
|
<!-- 表尾合計 -->
|
|
<tr class="summary-row">
|
|
<td colspan="5" style="text-align: right; padding: 8px;">合計:</td>
|
|
<td class="ta-right">{{ formatCurrency(email.講師勞務費合計) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(email.應扣繳稅額合計) }}</td>
|
|
<td class="ta-right">{{ formatCurrency(email.服務費合計) }}</td>
|
|
</tr>
|
|
</template>
|
|
<tr v-else>
|
|
<td colspan="8" style="text-align: center; color: #999;">沒有附件資料</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<!-- Modal Footer -->
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn-close" v-on:click="closeEmailPreview">關閉</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- 隱藏欄位 -->
|
|
<input type="hidden" id="ctl00_ContentPlaceHolder1_hidCurrentYear" runat="server" />
|
|
<input type="hidden" id="ctl00_ContentPlaceHolder1_hidCurrentClosingMonth" runat="server" />
|
|
|
|
</asp:Content>
|