提供給台大案英特拉線上繳費填寫發票資訊用
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

193 строки
9.4KB

  1. @page
  2. @model InvoiceModel
  3. @{
  4. ViewData["Title"] = "消費者發票資訊填寫";
  5. Layout = "_SimpleLayout";
  6. }
  7. <div class="container mt-4">
  8. <div class="row justify-content-center">
  9. <div class="col-md-8">
  10. <div class="alert alert-secondary text-center mb-3" role="alert">
  11. <h5 class="mb-0">營業人:@Model.CompanyName(統編:@Model.CompanyTaxId)</h5>
  12. </div>
  13. @* @if (!string.IsNullOrEmpty(Model.DisplayTransDateTime) || !string.IsNullOrEmpty(Model.DisplayTransAmount)) *@
  14. @* { *@
  15. <div class="card mb-3 border-info">
  16. <div class="card-body bg-light">
  17. <div class="row">
  18. <div class="col-md-6">
  19. <label class="form-label fw-bold">發票日期:</label>
  20. <span class="ms-2">@Model.DisplayTransDateTime</span>
  21. </div>
  22. <div class="col-md-6">
  23. <label class="form-label fw-bold">發票金額:</label>
  24. <span class="ms-2">NT$ @Model.DisplayTransAmount</span>
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. @* } *@
  30. <div class="card shadow-sm">
  31. <div class="card-header bg-primary text-white">
  32. <h4 class="mb-0">消費者發票資訊填寫</h4>
  33. </div>
  34. <div class="card-body">
  35. <div id="formErrorMessage" class="alert alert-danger alert-dismissible fade show @(string.IsNullOrEmpty(Model.ErrorMessage) ? "d-none" : string.Empty)" role="alert">
  36. <span id="formErrorMessageText">@Model.ErrorMessage</span>
  37. <button type="button" class="btn-close" aria-label="Close" data-error-close></button>
  38. </div>
  39. <div id="formSuccessMessage" class="alert alert-success alert-dismissible fade show @(string.IsNullOrEmpty(Model.SuccessMessage) ? "d-none" : string.Empty)" role="alert">
  40. <span id="formSuccessMessageText">@Model.SuccessMessage</span>
  41. <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
  42. </div>
  43. <form method="post" asp-page-handler="ToEndPoint">
  44. <div asp-validation-summary="All" class="text-danger mb-3"></div>
  45. <!-- 隱藏欄位:系統傳入的資料 -->
  46. <input type="hidden" asp-for="InvoiceData.Identifier" />
  47. <input type="hidden" asp-for="InvoiceData.TransDateTime" />
  48. <input type="hidden" asp-for="InvoiceData.TransAmount" />
  49. <input type="hidden" asp-for="InvoiceData.DeviceID" />
  50. <input type="hidden" asp-for="InvoiceData.LocationID" />
  51. <input type="hidden" asp-for="InvoiceData.CarPlateNum" />
  52. <input type="hidden" asp-for="InvoiceData.OrderID" />
  53. <input type="hidden" asp-for="InvoiceData.TaxType" />
  54. <div class="alert alert-info mb-4">
  55. <strong>注意:</strong>以下四個選項至少需填寫一個
  56. </div>
  57. <div class="row mb-3">
  58. <div class="col-md-6">
  59. <label asp-for="InvoiceData.Email" class="form-label">消費者信箱(寄送發票開立通知用)</label>
  60. <input asp-for="InvoiceData.Email" class="form-control" type="email" maxlength="64" placeholder="example@email.com" />
  61. <span asp-validation-for="InvoiceData.Email" class="text-danger"></span>
  62. </div>
  63. <div class="col-md-6">
  64. <label asp-for="InvoiceData.CarrierID" class="form-label">手機條碼</label>
  65. <input asp-for="InvoiceData.CarrierID" class="form-control" maxlength="8" placeholder="/ABC1234" />
  66. <small class="form-text text-muted">8碼,第1碼為/,例:/ABC1234</small>
  67. <span asp-validation-for="InvoiceData.CarrierID" class="text-danger"></span>
  68. </div>
  69. </div>
  70. <div class="row mb-3">
  71. <div class="col-md-6">
  72. <label asp-for="InvoiceData.BuyerIdentifier" class="form-label">購買者統編</label>
  73. <input asp-for="InvoiceData.BuyerIdentifier" class="form-control" maxlength="8" placeholder="12345678" />
  74. <small class="form-text text-muted">8位數字</small>
  75. <span asp-validation-for="InvoiceData.BuyerIdentifier" class="text-danger"></span>
  76. </div>
  77. <div class="col-md-6">
  78. <label asp-for="InvoiceData.LoveCode" class="form-label">捐贈碼</label>
  79. <input asp-for="InvoiceData.LoveCode" class="form-control" maxlength="7" placeholder="123456" />
  80. <small class="form-text text-muted">輸入為捐贈發票</small>
  81. <span asp-validation-for="InvoiceData.LoveCode" class="text-danger"></span>
  82. </div>
  83. </div>
  84. <div id="submitButtonContainer" class="d-grid gap-2 mt-4 @(string.IsNullOrEmpty(Model.SuccessMessage) ? string.Empty : "d-none")">
  85. <button type="submit" class="btn btn-primary btn-lg">送出</button>
  86. </div>
  87. </form>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. <div id="formSubmittingOverlay" class="position-fixed top-0 start-0 w-100 h-100 bg-white bg-opacity-75 d-none" style="z-index: 1050;">
  94. <div class="d-flex justify-content-center align-items-center h-100">
  95. <div class="text-center">
  96. <div class="spinner-border text-primary mb-3" role="status" aria-hidden="true"></div>
  97. <p class="fw-semibold mb-0">資料送出中,請稍候...</p>
  98. </div>
  99. </div>
  100. </div>
  101. @section Scripts {
  102. @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
  103. <script>
  104. document.addEventListener('DOMContentLoaded', function() {
  105. const errorAlert = document.getElementById('formErrorMessage');
  106. const errorText = document.getElementById('formErrorMessageText');
  107. const errorCloseBtn = errorAlert?.querySelector('[data-error-close]');
  108. const successAlert = document.getElementById('formSuccessMessage');
  109. const submitButtonContainer = document.getElementById('submitButtonContainer');
  110. const showError = (message) => {
  111. if (!errorAlert || !errorText) {
  112. alert(message);
  113. return;
  114. }
  115. errorText.textContent = message;
  116. errorAlert.classList.remove('d-none');
  117. };
  118. const hideError = () => {
  119. if (!errorAlert || !errorText) {
  120. return;
  121. }
  122. errorText.textContent = '';
  123. errorAlert.classList.add('d-none');
  124. };
  125. errorCloseBtn?.addEventListener('click', hideError);
  126. const requiredGroup = [
  127. document.querySelector('input[name="InvoiceData.Email"]'),
  128. document.querySelector('input[name="InvoiceData.CarrierID"]'),
  129. document.querySelector('input[name="InvoiceData.BuyerIdentifier"]'),
  130. document.querySelector('input[name="InvoiceData.LoveCode"]')
  131. ];
  132. const form = document.querySelector('form[method="post"]');
  133. if (!form) {
  134. return;
  135. }
  136. const overlay = document.getElementById('formSubmittingOverlay');
  137. const submitButtons = form.querySelectorAll('button[type="submit"], input[type="submit"]');
  138. let isSubmitting = false;
  139. const hideSubmitButtonAfterSuccess = () => {
  140. if (successAlert && !successAlert.classList.contains('d-none')) {
  141. submitButtonContainer?.classList.add('d-none');
  142. submitButtons.forEach(btn => btn.disabled = true);
  143. }
  144. };
  145. hideSubmitButtonAfterSuccess();
  146. const lockForm = () => {
  147. if (overlay) {
  148. overlay.classList.remove('d-none');
  149. }
  150. submitButtons?.forEach(btn => btn.disabled = true);
  151. isSubmitting = true;
  152. };
  153. form.addEventListener('submit', function(event) {
  154. if (isSubmitting) {
  155. event.preventDefault();
  156. return;
  157. }
  158. const hasValue = requiredGroup.some(field => field && field.value.trim() !== '');
  159. if (!hasValue) {
  160. event.preventDefault();
  161. showError('Email、手機條碼、購買者統編、捐贈碼至少需填寫一項。');
  162. return;
  163. }
  164. hideError();
  165. lockForm();
  166. });
  167. });
  168. </script>
  169. }