From e81756833c9ab5cdda5efa57ebe1795814e4c089 Mon Sep 17 00:00:00 2001 From: sky121113 Date: Tue, 16 Jun 2026 10:30:06 +0800 Subject: [PATCH] =?UTF-8?q?[FEAT]=20=E7=B6=A0=E7=95=8C=E9=9B=BB=E5=AD=90?= =?UTF-8?q?=E7=99=BC=E7=A5=A8=E8=A8=AD=E5=AE=9A=E6=95=B4=E7=B5=84=E9=81=B8?= =?UTF-8?q?=E5=A1=AB=E4=B8=80=E6=97=A6=E5=95=9F=E7=94=A8=E5=8D=B3=E5=85=A8?= =?UTF-8?q?=E6=AC=84=E5=BF=85=E5=A1=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. PaymentConfigController 的 store/update 新增 ecpay_invoice 群組條件式驗證:四欄全空時整組選填,只要填寫任一欄(store_id/hash_key/hash_iv/email)即透過 required_with 強制其餘全部必填。 2. email 欄位加上格式驗證,從源頭避免空值導致綠界開立失敗(綠界規定 CustomerPhone 與 CustomerEmail 至少擇一,本系統 email 為唯一來源)。 3. 新增三語系驗證訊息與表單提示 key(zh_TW/en/ja),維持字母排序與斜線不逸出。 4. create/edit 表單加入動態必填提示:填入任一欄時 label 顯示紅色星號,並於各欄下方顯示 @error 驗證訊息。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../BasicSettings/PaymentConfigController.php | 30 +++++++++++++++++-- lang/en.json | 3 ++ lang/ja.json | 3 ++ lang/zh_TW.json | 3 ++ .../payment-configs/create.blade.php | 23 ++++++++------ .../payment-configs/edit.blade.php | 23 ++++++++------ 6 files changed, 65 insertions(+), 20 deletions(-) diff --git a/app/Http/Controllers/Admin/BasicSettings/PaymentConfigController.php b/app/Http/Controllers/Admin/BasicSettings/PaymentConfigController.php index 080dab4..fd769e7 100644 --- a/app/Http/Controllers/Admin/BasicSettings/PaymentConfigController.php +++ b/app/Http/Controllers/Admin/BasicSettings/PaymentConfigController.php @@ -51,7 +51,7 @@ class PaymentConfigController extends AdminController 'name' => 'required|string|max:255', 'company_id' => 'nullable|exists:companies,id', 'settings' => 'required|array', - ]); + ] + $this->ecpayInvoiceRules(), $this->ecpayInvoiceMessages()); PaymentConfig::create([ 'name' => $request->name, @@ -83,7 +83,7 @@ class PaymentConfigController extends AdminController 'name' => 'required|string|max:255', 'company_id' => 'nullable|exists:companies,id', 'settings' => 'required|array', - ]); + ] + $this->ecpayInvoiceRules(), $this->ecpayInvoiceMessages()); $paymentConfig->update([ 'name' => $request->name, @@ -105,4 +105,30 @@ class PaymentConfigController extends AdminController return redirect()->route('admin.basic-settings.payment-configs.index') ->with('success', __('Payment Configuration deleted successfully.')); } + + /** + * 綠界電子發票群組驗證規則:整組選填,但只要填了任一欄, + * store_id / hash_key / hash_iv / email 即全部必填(綠界開立發票需金鑰齊備, + * 且 email 為「電話/信箱擇一」的唯一來源,缺一即無法開立)。 + * 依賴 ConvertEmptyStringsToNull middleware:空欄送出為 null,required_with 不會誤觸發。 + */ + private function ecpayInvoiceRules(): array + { + $g = 'settings.ecpay_invoice'; + return [ + "{$g}.store_id" => "nullable|string|max:20|required_with:{$g}.hash_key,{$g}.hash_iv,{$g}.email", + "{$g}.hash_key" => "nullable|string|max:64|required_with:{$g}.store_id,{$g}.hash_iv,{$g}.email", + "{$g}.hash_iv" => "nullable|string|max:64|required_with:{$g}.store_id,{$g}.hash_key,{$g}.email", + "{$g}.email" => "nullable|email|max:100|required_with:{$g}.store_id,{$g}.hash_key,{$g}.hash_iv", + ]; + } + + /** 綠界電子發票群組的驗證訊息(三語系)。 */ + private function ecpayInvoiceMessages(): array + { + return [ + 'settings.ecpay_invoice.*.required_with' => __('ECPay e-invoice is optional, but once any field is filled, Store ID / Hash Key / Hash IV / Email are all required.'), + 'settings.ecpay_invoice.email.email' => __('Please enter a valid ECPay e-invoice notification email.'), + ]; + } } diff --git a/lang/en.json b/lang/en.json index 24fd147..af9f119 100644 --- a/lang/en.json +++ b/lang/en.json @@ -609,6 +609,7 @@ "EASY_MERCHANT_ID": "EASY_MERCHANT_ID (EasyWallet)", "ECPay Invoice": "ECPay Invoice", "ECPay Invoice Settings Description": "ECPay Invoice Settings Description", + "ECPay e-invoice is optional, but once any field is filled, Store ID / Hash Key / Hash IV / Email are all required.": "ECPay e-invoice is optional, but once any field is filled, Store ID / Hash Key / Hash IV / Email are all required.", "ECPay has no such invoice; marked as pending re-issue": "ECPay has no such invoice; marked as pending re-issue", "ECPay query failed": "ECPay query failed", "ESUN": "ESUN", @@ -1404,6 +1405,7 @@ "Optional notes...": "Optional notes...", "Optional remarks": "Optional remarks", "Optional remarks...": "Optional remarks...", + "Optional. If you fill in any field, all fields below become required.": "Optional. If you fill in any field, all fields below become required.", "Or Choose Custom Date": "Or Choose Custom Date", "Order Details": "Order Details", "Order Info": "Order Info", @@ -1536,6 +1538,7 @@ "Please check the form for errors.": "Please check the form for errors.", "Please confirm the details below": "Please confirm the details below", "Please enter Webhook URL first.": "Please enter Webhook URL first.", + "Please enter a valid ECPay e-invoice notification email.": "Please enter a valid ECPay e-invoice notification email.", "Please enter address first": "Please enter address first", "Please enter configuration name": "Please enter configuration name", "Please enter machine flavor": "Please enter machine flavor", diff --git a/lang/ja.json b/lang/ja.json index 9ba9716..2b11923 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -609,6 +609,7 @@ "EASY_MERCHANT_ID": "EASY_MERCHANT_ID (悠遊付)", "ECPay Invoice": "ECPay 電子領収書", "ECPay Invoice Settings Description": "ECPay 電子領収書設定", + "ECPay e-invoice is optional, but once any field is filled, Store ID / Hash Key / Hash IV / Email are all required.": "ECPay 電子インボイスは任意ですが、いずれかの項目を入力した場合は、店舗 ID / Hash Key / Hash IV / Email がすべて必須になります。", "ECPay has no such invoice; marked as pending re-issue": "ECPay has no such invoice; marked as pending re-issue", "ECPay query failed": "ECPay query failed", "ESUN": "玉山銀行", @@ -1404,6 +1405,7 @@ "Optional notes...": "任意のメモ...", "Optional remarks": "任意の備考", "Optional remarks...": "任意の備考...", + "Optional. If you fill in any field, all fields below become required.": "任意。いずれかの項目を入力すると、以下のすべての項目が必須になります。", "Or Choose Custom Date": "または日付を選択", "Order Details": "注文詳細", "Order Info": "注文情報", @@ -1536,6 +1538,7 @@ "Please check the form for errors.": "フォームのエラーを確認してください。", "Please confirm the details below": "以下の詳細を確認してください", "Please enter Webhook URL first.": "最初にWebhook URLを入力してください。", + "Please enter a valid ECPay e-invoice notification email.": "有効な ECPay 電子インボイス通知用メールアドレスを入力してください。", "Please enter address first": "先に住所を入力してください", "Please enter configuration name": "設定名を入力してください", "Please enter machine flavor": "機台フレーバーを入力してください", diff --git a/lang/zh_TW.json b/lang/zh_TW.json index ef72f1b..711715e 100644 --- a/lang/zh_TW.json +++ b/lang/zh_TW.json @@ -609,6 +609,7 @@ "EASY_MERCHANT_ID": "EASY_MERCHANT_ID (悠遊付)", "ECPay Invoice": "綠界電子發票", "ECPay Invoice Settings Description": "綠界科技電子發票設定", + "ECPay e-invoice is optional, but once any field is filled, Store ID / Hash Key / Hash IV / Email are all required.": "綠界電子發票為選填,但只要填寫任一欄位,特店 ID / Hash Key / Hash IV / Email 即全部必填。", "ECPay has no such invoice; marked as pending re-issue": "綠界查無此發票,已標記為待補開", "ECPay query failed": "綠界查詢失敗", "ESUN": "玉山銀行", @@ -1404,6 +1405,7 @@ "Optional notes...": "備註內容(選填)...", "Optional remarks": "選填備註", "Optional remarks...": "選填備註...", + "Optional. If you fill in any field, all fields below become required.": "選填。只要填寫任一欄位,以下欄位即全部必填。", "Or Choose Custom Date": "或選擇自訂日期", "Order Details": "訂單詳情", "Order Info": "單據資訊", @@ -1536,6 +1538,7 @@ "Please check the form for errors.": "請檢查欄位內容是否正確。", "Please confirm the details below": "請確認以下詳細資訊", "Please enter Webhook URL first.": "請先輸入 Webhook 網址。", + "Please enter a valid ECPay e-invoice notification email.": "請輸入有效的綠界電子發票通知 Email。", "Please enter address first": "請先輸入地址", "Please enter configuration name": "請輸入設定名稱", "Please enter machine flavor": "請輸入機台風味", diff --git a/resources/views/admin/basic-settings/payment-configs/create.blade.php b/resources/views/admin/basic-settings/payment-configs/create.blade.php index fd7fdb4..94385c9 100644 --- a/resources/views/admin/basic-settings/payment-configs/create.blade.php +++ b/resources/views/admin/basic-settings/payment-configs/create.blade.php @@ -98,22 +98,27 @@ -
+
+

{{ __('Optional. If you fill in any field, all fields below become required.') }}

- - + + + @error('settings.ecpay_invoice.store_id')

{{ $message }}

@enderror
- - + + + @error('settings.ecpay_invoice.hash_key')

{{ $message }}

@enderror
- - + + + @error('settings.ecpay_invoice.hash_iv')

{{ $message }}

@enderror
- - + + + @error('settings.ecpay_invoice.email')

{{ $message }}

@enderror
diff --git a/resources/views/admin/basic-settings/payment-configs/edit.blade.php b/resources/views/admin/basic-settings/payment-configs/edit.blade.php index f489773..b3ed426 100644 --- a/resources/views/admin/basic-settings/payment-configs/edit.blade.php +++ b/resources/views/admin/basic-settings/payment-configs/edit.blade.php @@ -102,22 +102,27 @@ -
+
+

{{ __('Optional. If you fill in any field, all fields below become required.') }}

- - + + + @error('settings.ecpay_invoice.store_id')

{{ $message }}

@enderror
- - + + + @error('settings.ecpay_invoice.hash_key')

{{ $message }}

@enderror
- - + + + @error('settings.ecpay_invoice.hash_iv')

{{ $message }}

@enderror
- - + + + @error('settings.ecpay_invoice.email')

{{ $message }}

@enderror