Переглянути джерело

送出檢核、拿掉不需要的頁面

master
Joanne.Chuang 2 тижднів тому
джерело
коміт
cd0d2f2ba1
13 змінених файлів з 76 додано та 119 видалено
  1. +6
    -5
      Altob.NtuInvoiceGateway/Models/InvoiceRequest.cs
  2. +0
    -10
      Altob.NtuInvoiceGateway/Pages/Index.cshtml
  3. +0
    -18
      Altob.NtuInvoiceGateway/Pages/Index.cshtml.cs
  4. +16
    -33
      Altob.NtuInvoiceGateway/Pages/Invoice.cshtml
  5. +46
    -7
      Altob.NtuInvoiceGateway/Pages/Invoice.cshtml.cs
  6. +0
    -8
      Altob.NtuInvoiceGateway/Pages/Privacy.cshtml
  7. +0
    -18
      Altob.NtuInvoiceGateway/Pages/Privacy.cshtml.cs
  8. +2
    -2
      Altob.NtuInvoiceGateway/Pages/Shared/_Layout.cshtml
  9. +2
    -2
      Altob.NtuInvoiceGateway/Pages/Shared/_SimpleLayout.cshtml
  10. +1
    -1
      Altob.NtuInvoiceGateway/Pages/TestPostInvoice.cshtml
  11. +1
    -1
      Altob.NtuInvoiceGateway/Pages/TestPostInvoice.cshtml.cs
  12. +0
    -12
      Altob.NtuInvoiceGateway/appsettings.Development.json
  13. +2
    -2
      Altob.NtuInvoiceGateway/appsettings.json

+ 6
- 5
Altob.NtuInvoiceGateway/Models/InvoiceRequest.cs Переглянути файл

@@ -22,11 +22,11 @@ public class InvoiceRequest

[StringLength(64, ErrorMessage = "Email長度不能超過64個字元")]
[EmailAddress(ErrorMessage = "Email格式不正確")]
public string? Email { get; set; }
public string? Email { get; set; } = string.Empty;

[StringLength(8, ErrorMessage = "手機條碼長度不能超過8個字元")]
[RegularExpression(@"^\/[A-Z0-9.+\-]{7}$", ErrorMessage = "手機條碼格式不正確,必須為8碼,第一碼為/,其餘為大寫英數字、點、加號或減號")]
public string? CarrierID { get; set; }
public string? CarrierID { get; set; } = string.Empty;

[Required(ErrorMessage = "停車場站代號為必填")]
[StringLength(1, ErrorMessage = "停車場站代號長度不能超過1個字元")]
@@ -42,10 +42,11 @@ public class InvoiceRequest

[StringLength(8, ErrorMessage = "購買者統編長度不能超過8個字元")]
[RegularExpression(@"^\d{8}$", ErrorMessage = "統編格式不正確,必須為8位數字")]
public string? BuyerIdentifier { get; set; }
public string? BuyerIdentifier { get; set; } = string.Empty;

// [StringLength(7, ErrorMessage = "愛心碼長度不能超過7個字元")]
// public string? LoveCode { get; set; }
[StringLength(6, ErrorMessage = "愛心碼長度不能超過6碼")]
[RegularExpression(@"^$|^\d{6}$", ErrorMessage = "愛心碼須為空值或6位數字")]
public string LoveCode { get; set; } = string.Empty;

[Required(ErrorMessage = "稅別為必填")]
[StringLength(1, ErrorMessage = "稅別長度不能超過1個字元")]


+ 0
- 10
Altob.NtuInvoiceGateway/Pages/Index.cshtml Переглянути файл

@@ -1,10 +0,0 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

+ 0
- 18
Altob.NtuInvoiceGateway/Pages/Index.cshtml.cs Переглянути файл

@@ -1,18 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Altob.NtuInvoiceGateway.Pages;

public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;

public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}

public void OnGet()
{
}
}

+ 16
- 33
Altob.NtuInvoiceGateway/Pages/Invoice.cshtml Переглянути файл

@@ -45,15 +45,16 @@
@if (!string.IsNullOrEmpty(Model.SuccessMessage))
{
<div class="alert alert-success alert-dismissible fade show" role="alert">
@Model.SuccessMessage
@Model.SuccessMessage 1111
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
}

<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger mb-3"></div>
<form method="post" asp-page-handler="ToEndPoint">
<div asp-validation-summary="All" class="text-danger mb-3"></div>

<!-- 隱藏欄位:系統傳入的資料 -->
<input type="hidden" asp-for="InvoiceData.Identifier" />
<input type="hidden" asp-for="InvoiceData.TransDateTime" />
<input type="hidden" asp-for="InvoiceData.TransAmount" />
<input type="hidden" asp-for="InvoiceData.DeviceID" />
@@ -62,23 +63,8 @@
<input type="hidden" asp-for="InvoiceData.OrderID" />
<input type="hidden" asp-for="InvoiceData.TaxType" />

@{
if (string.IsNullOrWhiteSpace(Model.InvoiceData.Identifier))
{
Model.InvoiceData.Identifier = Model.CompanyTaxId;
}
}

<div class="mb-3">
<label asp-for="InvoiceData.Identifier" class="form-label">開發票者統編</label>
<input asp-for="InvoiceData.Identifier"
class="form-control"
maxlength="8" />
<span asp-validation-for="InvoiceData.Identifier" class="text-danger"></span>
</div>

<div class="alert alert-info mb-4">
<strong>注意:</strong>以下三個選項只能填寫其中一個
<strong>注意:</strong>以下三個選項至少需填寫一個
</div>

<div class="row mb-3">
@@ -123,26 +109,23 @@
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
// 確保只有一個選項被填寫
document.addEventListener('DOMContentLoaded', function() {
const exclusiveFields = [
const requiredGroup = [
document.querySelector('input[name="InvoiceData.Email"]'),
document.querySelector('input[name="InvoiceData.CarrierID"]'),
document.querySelector('input[name="InvoiceData.BuyerIdentifier"]')
// document.querySelector('input[name="InvoiceData.LoveCode"]')
];

exclusiveFields.forEach(field => {
if (field) {
field.addEventListener('input', function() {
if (this.value) {
exclusiveFields.forEach(otherField => {
if (otherField !== this) {
otherField.value = '';
}
});
}
});
const form = document.querySelector('form[method="post"]');
if (!form) {
return;
}

form.addEventListener('submit', function(event) {
const hasValue = requiredGroup.some(field => field && field.value.trim() !== '');
if (!hasValue) {
event.preventDefault();
alert('Email、手機條碼、購買者統編至少需填寫一項。');
}
});
});


+ 46
- 7
Altob.NtuInvoiceGateway/Pages/Invoice.cshtml.cs Переглянути файл

@@ -4,6 +4,7 @@ using Microsoft.Extensions.Options;
using Altob.NtuInvoiceGateway.Models;
using System.Text;
using System.Text.Json;
using System.Linq;

namespace Altob.NtuInvoiceGateway.Pages;

@@ -46,6 +47,7 @@ public class InvoiceModel : PageModel

public async Task<IActionResult> OnPostAsync()
{
NormalizeInvoiceData();
// 檢查是否為 JSON 請求(外部系統轉頁)
if (Request.ContentType?.Contains("application/json") == true)
{
@@ -64,6 +66,7 @@ public class InvoiceModel : PageModel
if (jsonData != null)
{
InvoiceData = jsonData;
NormalizeInvoiceData();
DisplayTransDateTime = InvoiceData.TransDateTime;
DisplayTransAmount = InvoiceData.TransAmount;
ModelState.Clear(); // ensure Razor uses the JSON payload values
@@ -76,11 +79,14 @@ public class InvoiceModel : PageModel
_logger.LogError(ex, "Error parsing JSON request");
ErrorMessage = "接收轉頁資料時發生錯誤";
}

// 顯示表單讓用戶填寫
return Page();
}

// 顯示表單讓用戶填寫
return Page();
}
public async Task<IActionResult> OnPostToEndPointAsync()
{
NormalizeInvoiceData();
// 處理表單提交
// 保留發票資訊顯示
DisplayTransDateTime = InvoiceData.TransDateTime;
@@ -99,19 +105,30 @@ public class InvoiceModel : PageModel

if (!ModelState.IsValid)
{
var invalidFields = ModelState
.Where(entry => entry.Value?.Errors.Count > 0)
.Select(entry =>
{
var fieldName = string.IsNullOrEmpty(entry.Key) ? "表單" : entry.Key;
var messages = string.Join("、", entry.Value!.Errors.Select(e => e.ErrorMessage));
return $"{fieldName}:{messages}";
});

ErrorMessage = "資料驗證失敗,請檢查欄位輸入";
_logger.LogWarning("Invoice submission validation failed: {ValidationErrors}", string.Join(" | ", invalidFields));
return Page();
}

// 驗證 Email, CarrierID, BuyerIdentifier 只能填寫其中一個
// 驗證 Email, CarrierID, BuyerIdentifier 至少填寫一個
int filledCount = 0;
if (!string.IsNullOrEmpty(InvoiceData.Email)) filledCount++;
if (!string.IsNullOrEmpty(InvoiceData.CarrierID)) filledCount++;
if (!string.IsNullOrEmpty(InvoiceData.BuyerIdentifier)) filledCount++;
// if (!string.IsNullOrEmpty(InvoiceData.LoveCode)) filledCount++;

if (filledCount != 1)
if (filledCount == 0)
{
ErrorMessage = "Email、手機條碼、購買者統編只能填寫其中一個";
ErrorMessage = "Email、手機條碼、購買者統編至少需填寫一個";
return Page();
}

@@ -176,10 +193,32 @@ public class InvoiceModel : PageModel
}
catch (Exception ex)
{
#if DEBUG
ErrorMessage = $"系統錯誤:{ex.Message}";
#else
ErrorMessage = $"系統錯誤";
#endif
_logger.LogError(ex, "Error submitting invoice for OrderID: {OrderID}", InvoiceData.OrderID);
}

return Page();
}

private void NormalizeInvoiceData()
{
InvoiceData ??= new InvoiceRequest();

InvoiceData.Identifier = InvoiceData.Identifier ?? string.Empty;
InvoiceData.TransDateTime = InvoiceData.TransDateTime ?? string.Empty;
InvoiceData.TransAmount = InvoiceData.TransAmount ?? string.Empty;
InvoiceData.DeviceID = InvoiceData.DeviceID ?? string.Empty;
InvoiceData.Email = InvoiceData.Email ?? string.Empty;
InvoiceData.CarrierID = InvoiceData.CarrierID ?? string.Empty;
InvoiceData.LocationID = InvoiceData.LocationID ?? string.Empty;
InvoiceData.CarPlateNum = InvoiceData.CarPlateNum ?? string.Empty;
InvoiceData.OrderID = InvoiceData.OrderID ?? string.Empty;
InvoiceData.BuyerIdentifier = InvoiceData.BuyerIdentifier ?? string.Empty;
InvoiceData.LoveCode = InvoiceData.LoveCode ?? string.Empty;
InvoiceData.TaxType = InvoiceData.TaxType ?? string.Empty;
}
}

+ 0
- 8
Altob.NtuInvoiceGateway/Pages/Privacy.cshtml Переглянути файл

@@ -1,8 +0,0 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

+ 0
- 18
Altob.NtuInvoiceGateway/Pages/Privacy.cshtml.cs Переглянути файл

@@ -1,18 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Altob.NtuInvoiceGateway.Pages;

public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;

public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}

public void OnGet()
{
}
}

+ 2
- 2
Altob.NtuInvoiceGateway/Pages/Shared/_Layout.cshtml Переглянути файл

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"] - Altob.NtuInvoiceGateway</title>
<title>@ViewData["Title"]</title>
<script type="importmap"></script>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
@@ -39,7 +39,7 @@

<footer class="border-top footer text-muted">
<div class="container">
&copy; 2026 - Altob.NtuInvoiceGateway - <a asp-area="" asp-page="/Privacy">Privacy</a>
&copy; 2026 - Altob 歐特儀
</div>
</footer>



+ 2
- 2
Altob.NtuInvoiceGateway/Pages/Shared/_SimpleLayout.cshtml Переглянути файл

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"] - Altob.NtuInvoiceGateway</title>
<title>@ViewData["Title"]</title>
<script type="importmap"></script>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
@@ -18,7 +18,7 @@

<footer class="border-top footer text-muted mt-5">
<div class="container text-center">
&copy; 2026 - Altob.NtuInvoiceGateway
&copy; 2026 - Altob ¼Ú¯S»ö
</div>
</footer>



+ 1
- 1
Altob.NtuInvoiceGateway/Pages/TestPostInvoice.cshtml Переглянути файл

@@ -51,7 +51,7 @@
</div>
<div class="col-md-6">
<label class="form-label">設備代號 (DeviceID) *</label>
<input type="text" class="form-control" name="InvoiceData.DeviceID" value="NtuInvoiceGateway" required>
<input type="text" class="form-control" name="InvoiceData.DeviceID" value="NtuInvGateway" required>
</div>
</div>



+ 1
- 1
Altob.NtuInvoiceGateway/Pages/TestPostInvoice.cshtml.cs Переглянути файл

@@ -15,7 +15,7 @@ public class TestPostInvoiceModel : PageModel
{
CompanyTaxId = companyInfo.Value.TaxId;
CurrentTransDateTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
CurrentOrderNo = DateTime.Now.ToString("ORDERyyyyMMddHHmmssfff");
CurrentOrderNo = string.Format($"Order{DateTime.Now:yyyyMMddHHmmss}");
}

public void OnGet()


+ 0
- 12
Altob.NtuInvoiceGateway/appsettings.Development.json Переглянути файл

@@ -1,12 +0,0 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"InvoiceApi": {
"Endpoint": "http://192.168.110.72:22055/api/Intella/invoiceInfo"
}
}

+ 2
- 2
Altob.NtuInvoiceGateway/appsettings.json Переглянути файл

@@ -1,8 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
"Default": "Debug",
"Microsoft.AspNetCore": "Information"
}
},
"AllowedHosts": "*",


Завантаження…
Відмінити
Зберегти