WebberUI

統一發票對獎器(React)

台灣統一發票對獎的 React 元件:輸入發票號碼末 3 碼或全 8 碼即時比對獎號(獎號由 props 提供),中獎噴彩帶、獎金滾動、獎項徽章,未中獎則溫和搖頭並可一鍵再對下一張。

這是 WebberUI Pro 元件

上線活動期間免費:註冊或登入後,在上方預覽區按「複製安裝指令」就能直接安裝,不需付費、不用綁信用卡。下方那條指令未登入時會回 401。

怎麼安裝 Pro 元件 →查看方案 →

台灣統一發票每兩個月開獎一次,對獎是全民活動。這個元件把「期別標題+ 8 格數字輸入+結果面板」包成一個自足的對獎器:獎號由 prizes 傳入,內建 matchInvoice() 依財政部公告的給獎規則判定特別獎、特獎、頭獎系列(末 8~3 碼)與增開六獎;也支援只輸入末 3 碼的快速模式(僅能判定六獎/增開六獎,並提示補完整號碼確認更高獎項)。中獎時彩帶粒子噴發、獎金以滾動數字呈現並掛上獎項徽章;未中獎則是溫和的搖頭動畫與「再對下一張」按鈕。輸入格為 OTP 式獨立格:自動跳格、貼上自動分配、inputMode="numeric"、Backspace 回退。

載入預覽⋯
npx shadcn@latest add "https://webberui.com/r/invoice-lottery-checker.json?t=<安裝 token>"

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

<InvoiceLotteryChecker />

安裝

npx shadcn@latest add "https://webberui.com/r/invoice-lottery-checker.json?t=<安裝 token>"

或在 components.json 設定 registries 後,改用 @webberui/invoice-lottery-checker 安裝。

使用

import {
  InvoiceLotteryChecker,
  matchInvoice,
} from "@/components/ui/invoice-lottery-checker";

// 示範獎號,非真實開獎結果——正式使用時請改由後端或財政部公開資料餵入
const prizes = {
  special: "13579246",
  grand: "24680135",
  first: ["11223344", "55667788", "99001122"],
  additionalSixth: ["357", "802"],
};

<InvoiceLotteryChecker
  prizes={prizes}
  period="115 年 5–6 月"
  onResult={(result, number) =>
    console.log(number, result.prize, result.amount)
  }
  note="示範獎號,非真實開獎結果"
/>

// 對獎函式可單獨使用(例如批次對整疊發票)
matchInvoice("10203788", prizes); // { prize: "sixth", amount: 200, matchedDigits: 3, partial: false }
matchInvoice("788", prizes);      // { prize: "sixth", amount: 200, matchedDigits: 3, partial: true }

Props

Prop型別預設值說明
prizesInvoicePrizes本期獎號(特別獎、特獎、頭獎三組、增開六獎)
periodstring"本期統一發票"期別標題,例如「115 年 5–6 月」
mode"full" | "last3""full"對獎模式:full 輸入完整 8 碼;last3 只輸入末 3 碼(僅能判定六獎/增開六獎)
valuestring受控值(僅數字);不提供時為非受控模式
defaultValuestring""非受控模式的初始值
onChange(value: string) => void值變動時回呼,參數為清洗後的純數字字串
onResult(result: InvoiceMatchResult, number: string) => void每次完成對獎時回呼(自動或手動皆會觸發)
autoCheckbooleantrue輸入滿格後自動對獎;為 false 時需按「對獎」按鈕或 Enter
showConfettibooleantrue中獎時是否噴發彩帶
showPrizesbooleantrue是否在下方列出本期獎號
notestring底部備註文字,例如「示範獎號,非真實開獎結果」
classNamestring透傳到最外層容器

InvoicePrizes

欄位型別預設值說明
specialstring特別獎號碼(8 碼)
grandstring特獎號碼(8 碼)
firststring[]頭獎號碼(8 碼 × 3 組)
additionalSixthstring[]增開六獎號碼(3 碼,可多組)

InvoiceMatchResult

欄位型別預設值說明
prizeInvoicePrizeTier中獎層級:"special""grand""first""second""third""fourth""fifth""sixth""additionalSixth";未中獎為 null
amountnumber獎金(新台幣元);未中獎為 0
matchedDigitsnumber與中獎號碼相符的末幾碼數;未中獎為 0
partialboolean是否只以末 3 碼比對(號碼未滿 8 碼);為 true 時更高獎項尚未確認

另外具名匯出 matchInvoice(number, prizes)sanitizeInvoiceNumber(raw, maxLength?)INVOICE_PRIZE_LABELS(獎項中文名稱)、INVOICE_PRIZE_AMOUNTS(各獎項獎金)與 InvoicePrizeTier 型別,方便在表單層或批次對獎時重複使用同一套規則。

細節

  • 給獎規則:特別獎 8 碼全中 1,000 萬;特獎 8 碼全中 200 萬;頭獎三組任一組——8 碼全中 20 萬、末 7 碼 4 萬、末 6 碼 1 萬、末 5 碼 4,000、末 4 碼 1,000、末 3 碼 200(六獎);增開六獎末 3 碼 200。多組同時符合時取最高獎項
  • 只輸入 3 碼時(mode="last3"),只能判定六獎/增開六獎,中獎面板改為提示「末三碼相符,請輸入完整號碼確認更高獎項」,onResult 收到的 partialtrue
  • 結果面板只在「號碼與對獎當下一致」時顯示:使用者一按 Backspace 改動號碼,面板就自動收起;autoCheck 下同一個滿格號碼只會對一次,改動後再滿格才會重對
  • 彩帶粒子以 motion 小方塊自行實作,不依賴其他元件;每片的散落位置、旋轉與大小由確定性偽隨機算出,render 期間不呼叫 Math.random,SSR 與 CSR 輸出一致
  • 8 碼模式把末 3 格稍微隔開並在頭獎列表加粗末 3 碼——那是六獎的判定依據,一眼就能核對
  • 元件不內建任何真實獎號:正式使用時請由後端或財政部公開資料餵入 prizes;示範與 playground 使用的全是虛構號碼並以 note 標明

可及性

  • 實際輸入由單一原生 input 承載(inputMode="numeric"pattern="[0-9]*"maxLength),視覺格子僅為展示並以 aria-hidden 隱藏,鍵盤與行動裝置數字鍵盤行為與一般輸入框一致;labelhtmlFor 綁定
  • 對獎結果置於 role="status"aria-live="polite" 區域,中獎層級、獎金與提示都會被螢幕閱讀器朗讀;輸入框以 aria-describedby 指向該區域
  • 「對獎」與「再對下一張」皆為 type="button",具 focus-visible 環;Enter 鍵可手動對獎,並已處理中文輸入法組字中的 Enter(isComposing 與 Safari 的 keyCode 229
  • 使用者系統開啟「減少動態效果」時,停用彩帶、獎金滾動、搖頭、格子彈入與游標閃爍動畫,直接顯示最終結果與文字

本頁目錄