diff --git a/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml b/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml index de8a8a5..db15e55 100644 --- a/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml +++ b/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml @@ -39,13 +39,10 @@ - @if (!string.IsNullOrEmpty(Model.SuccessMessage)) - { - - } +
@@ -93,7 +90,7 @@ *@ -
+
@@ -119,6 +116,8 @@ const errorAlert = document.getElementById('formErrorMessage'); const errorText = document.getElementById('formErrorMessageText'); const errorCloseBtn = errorAlert?.querySelector('[data-error-close]'); + const successAlert = document.getElementById('formSuccessMessage'); + const submitButtonContainer = document.getElementById('submitButtonContainer'); const showError = (message) => { if (!errorAlert || !errorText) { @@ -151,9 +150,18 @@ } const overlay = document.getElementById('formSubmittingOverlay'); - const submitButtons = form?.querySelectorAll('button[type="submit"], input[type="submit"]'); + const submitButtons = form.querySelectorAll('button[type="submit"], input[type="submit"]'); let isSubmitting = false; + const hideSubmitButtonAfterSuccess = () => { + if (successAlert && !successAlert.classList.contains('d-none')) { + submitButtonContainer?.classList.add('d-none'); + submitButtons.forEach(btn => btn.disabled = true); + } + }; + + hideSubmitButtonAfterSuccess(); + const lockForm = () => { if (overlay) { overlay.classList.remove('d-none'); diff --git a/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml.cs b/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml.cs index e0cf2f0..83dcf2a 100644 --- a/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml.cs +++ b/Altob.NtuInvoiceGateway/Pages/Invoice.cshtml.cs @@ -15,6 +15,7 @@ public class InvoiceModel : PageModel private readonly IHttpClientFactory _httpClientFactory; private readonly CompanyInfo _companyInfo; private readonly InvoiceApiOptions _invoiceApiOptions; + private const string ServiceName = "NtuInvoiceGateway"; public InvoiceModel( ILogger logger, @@ -48,6 +49,9 @@ public class InvoiceModel : PageModel public async Task OnPostAsync() { NormalizeInvoiceData(); + var actionName = nameof(OnPostAsync); + _logger.LogInformation("{ServiceName} - {ActionName} received JSON redirect payload {@InvoiceData}", + ServiceName, actionName, InvoiceData); // 檢查是否為 JSON 請求(外部系統轉頁) if (Request.ContentType?.Contains("application/json") == true) { @@ -56,6 +60,7 @@ public class InvoiceModel : PageModel // 從 Request Body 讀取 JSON 資料 using var reader = new StreamReader(Request.Body); var jsonContent = await reader.ReadToEndAsync(); + _logger.LogInformation("{ServiceName} - {ActionName} JSON payload content: {JsonPayload}", ServiceName, actionName, jsonContent); var jsonData = JsonSerializer.Deserialize(jsonContent, new JsonSerializerOptions { @@ -71,12 +76,12 @@ public class InvoiceModel : PageModel DisplayTransAmount = InvoiceData.TransAmount; ModelState.Clear(); // ensure Razor uses the JSON payload values - _logger.LogInformation("Received JSON redirect for OrderID: {OrderID}", InvoiceData.OrderID); + _logger.LogInformation("{ServiceName} - {ActionName} received redirect for OrderID: {OrderID}", ServiceName, actionName, InvoiceData.OrderID); } } catch (Exception ex) { - _logger.LogError(ex, "Error parsing JSON request"); + _logger.LogError(ex, "{ServiceName} - {ActionName} error parsing JSON request", ServiceName, actionName); ErrorMessage = "接收轉頁資料時發生錯誤"; } } @@ -91,6 +96,9 @@ public class InvoiceModel : PageModel // 保留發票資訊顯示 DisplayTransDateTime = InvoiceData.TransDateTime; DisplayTransAmount = InvoiceData.TransAmount; + var actionName = nameof(OnPostToEndPointAsync); + _logger.LogInformation("{ServiceName} - {ActionName} received invoice submission payload {@InvoiceData}", + ServiceName, actionName, InvoiceData); // 判斷是否為初始轉頁(三個選項都沒填寫) bool isInitialRedirect = string.IsNullOrEmpty(InvoiceData.Email) && @@ -115,7 +123,7 @@ public class InvoiceModel : PageModel }); ErrorMessage = "資料驗證失敗,請檢查欄位輸入"; - _logger.LogWarning("Invoice submission validation failed: {ValidationErrors}", string.Join(" | ", invalidFields)); + _logger.LogWarning("{ServiceName} - {ActionName} validation failed: {ValidationErrors}", ServiceName, actionName, string.Join(" | ", invalidFields)); return Page(); } @@ -135,7 +143,7 @@ public class InvoiceModel : PageModel if (string.IsNullOrWhiteSpace(_invoiceApiOptions.Endpoint)) { ErrorMessage = "未設定外部發票 API 的位址"; - _logger.LogError("Invoice API endpoint is not configured"); + _logger.LogError("{ServiceName} - {ActionName} Invoice API endpoint is not configured", ServiceName, actionName); return Page(); } @@ -162,12 +170,16 @@ public class InvoiceModel : PageModel { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + _logger.LogInformation("{ServiceName} - {ActionName} sending API payload: {RequestBody}", + ServiceName, actionName, requestBody); var content = new StringContent(requestBody, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(_invoiceApiOptions.Endpoint, content); var responseContent = await response.Content.ReadAsStringAsync(); + _logger.LogInformation("{ServiceName} - {ActionName} received API response status {StatusCode} body: {ResponseBody}", + ServiceName, actionName, response.StatusCode, responseContent); var apiResponse = JsonSerializer.Deserialize(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true @@ -176,19 +188,21 @@ public class InvoiceModel : PageModel if (!response.IsSuccessStatusCode) { ErrorMessage = $"提交失敗:{apiResponse?.msg ?? response.StatusCode.ToString()}"; - _logger.LogWarning("Invoice submission failed with HTTP {StatusCode} for OrderID: {OrderID}", response.StatusCode, InvoiceData.OrderID); + _logger.LogWarning("{ServiceName} - {ActionName} submission failed with HTTP {StatusCode} for OrderID: {OrderID}", + ServiceName, actionName, response.StatusCode, InvoiceData.OrderID); return Page(); } if (apiResponse?.msgCode == "0000") { SuccessMessage = "發票資訊提交成功!"; - _logger.LogInformation("Invoice submitted successfully for OrderID: {OrderID}", InvoiceData.OrderID); + _logger.LogInformation("{ServiceName} - {ActionName} submitted successfully for OrderID: {OrderID}", + ServiceName, actionName, InvoiceData.OrderID); } else { ErrorMessage = $"提交失敗:{apiResponse?.msg ?? "未知錯誤"}"; - _logger.LogWarning("Invoice submission failed: {Message}", apiResponse?.msg); + _logger.LogWarning("{ServiceName} - {ActionName} submission failed: {Message}", ServiceName, actionName, apiResponse?.msg); } } catch (Exception ex) @@ -198,7 +212,8 @@ public class InvoiceModel : PageModel #else ErrorMessage = $"系統錯誤"; #endif - _logger.LogError(ex, "Error submitting invoice for OrderID: {OrderID}", InvoiceData.OrderID); + _logger.LogError(ex, "{ServiceName} - {ActionName} error submitting invoice for OrderID: {OrderID}", + ServiceName, actionName, InvoiceData.OrderID); } return Page();