# Code128 條碼功能實作文件

## 📋 功能概述

已成功為甜點店 ERP 系統的商品建檔管理模組實作完整的 Code128 條碼功能，包含自動生成商品編號、條碼生成、預覽、下載與列印功能。

---

## 🗂️ 資料結構設計

### Product 介面（已更新）

```typescript
export interface Product {
  id: string;                    // 系統內部 ID
  product_code: string;          // 商品編號（系統自動生成，格式：ICE000001）
  name: string;                  // 商品名稱
  type: ProductType;             // 類型（原物料/成品）
  category: string;              // 分類
  unit: ProductUnit;             // 單位
  barcode_value: string;         // 條碼內容（預設等於商品編號）
  stockQuantity: number;         // 庫存數量
  createdAt: string;             // 建立日期
}
```

### 商品編號規則

- **格式**：`ICE` + 6位數字（例如：ICE000001、ICE000245）
- **生成邏輯**：自動遞增，系統找出最大序號後 +1
- **唯一性**：每個商品編號保證唯一
- **用途**：作為條碼內容的預設值

---

## 🎨 UI 設計與 Wireframe

### 商品對話框結構

```
┌─────────────────────────────────────────────────┐
│  編輯商品 / 新增商品                               │
├─────────────────────────────────────────────────┤
│                                                 │
│  ┌─────────────────────────────────────────┐   │
│  │ 商品編號: ICE000001                      │   │ ← 商品編號區（僅編輯時顯示）
│  │ 系統自動生成，不可修改                    │   │
│  └─────────────────────────────────────────┘   │
│                                                 │
│  商品名稱 *        類型 *                        │
│  [__________]     [原物料 ▼]                    │
│                                                 │
│  分類 *            單位 *                        │
│  [__________]     [公斤 ▼]                      │
│                                                 │
│  庫存數量                                        │
│  [__________]                                   │
│                                                 │
│  ┌─────────────────────────────────────────┐   │
│  │ 條碼資訊                                 │   │ ← 條碼區
│  │                                           │   │
│  │ 條碼內容                                  │   │
│  │ [ICE000001_________] [🔄 重新生成]       │   │
│  │ 條碼內容預設等於商品編號...               │   │
│  │                                           │   │
│  │ 條碼預覽 (Code128)                       │   │
│  │ ┌───────────────────────────────────┐   │   │
│  │ │   ║│││││││││││││││││││││││║       │   │   │
│  │ │        ICE000001                   │   │   │
│  │ └───────────────────────────────────┘   │   │
│  │                                           │   │
│  │ [⬇️ 下載條碼圖片] [🖨️ 列印條碼標籤]      │   │
│  └─────────────────────────────────────────┘   │
│                                                 │
│                          [取消] [儲存變更]      │
└─────────────────────────────────────────────────┘
```

### 條碼區功能說明

1. **商品編號顯示**（僅編輯模式）
   - 藍色背景區塊
   - 顯示格式化的商品編號
   - 註明「系統自動生成，不可修改」

2. **條碼內容**
   - 顯示當前條碼值
   - 唯讀輸入框，等寬字體顯示
   - 「重新生成」按鈕：將條碼值恢復為商品編號

3. **條碼預覽**
   - 使用 Code128 格式
   - 白色背景，虛線邊框
   - 自動即時更新
   - 新增模式提示「條碼將在儲存後顯示」

4. **操作按鈕**
   - 下載條碼圖片（PNG 格式）
   - 列印條碼標籤（包含商品資訊）

---

## 🔧 技術實作

### 使用的套件

```typescript
import JsBarcode from "jsbarcode";
```

### 核心組件

#### 1. BarcodeDisplay 組件

```typescript
// /components/BarcodeDisplay.tsx
// 功能：使用 JsBarcode 生成 Code128 條碼
// 參數：value, width, height, displayValue
```

#### 2. ProductDialog 組件更新

**主要新增功能：**
- 商品編號顯示區域
- 條碼內容輸入框（唯讀）
- 條碼預覽區域
- 重新生成按鈕
- 下載與列印功能

#### 3. ProductManagement 組件更新

**新增函數：**
```typescript
generateProductCode(): string
```
- 自動生成下一個商品編號
- 確保唯一性
- 格式：ICE + 6位數字

---

## 🔄 業務邏輯流程

### 新增商品流程

```
1. 使用者點擊「新增商品」
   ↓
2. 填寫商品基本資料（名稱、類型、分類等）
   ↓
3. 條碼區顯示「條碼將在儲存後顯示」
   ↓
4. 點擊「新增商品」
   ↓
5. 系統自動生成 product_code (例：ICE000007)
   ↓
6. barcode_value 自動設為 product_code
   ↓
7. 商品儲存完成，可再次編輯查看條碼
```

### 編輯商品流程

```
1. 使用者點擊「編輯」按鈕
   ↓
2. 對話框顯示商品編號（藍色區塊）
   ↓
3. 條碼區顯示當前條碼值與 Code128 條碼圖
   ↓
4. 可選操作：
   - 重新生成條碼（恢復為商品編號）
   - 下載條碼圖片
   - 列印條碼標籤
   ↓
5. 修改其他資料後儲存
```

### 重新生成條碼

```
1. 點擊「重新生成條碼」按鈕
   ↓
2. barcode_value 更新為 product_code
   ↓
3. 條碼圖自動重新渲染
   ↓
4. 顯示成功提示訊息
```

### 下載條碼圖片

```
1. 點擊「下載條碼圖片」
   ↓
2. 從 Canvas 取得條碼圖片
   ↓
3. 轉換為 PNG 格式
   ↓
4. 觸發瀏覽器下載
   ↓
5. 檔名：barcode-ICE000001.png
```

### 列印條碼標籤

```
1. 點擊「列印條碼標籤」
   ↓
2. 開啟新視窗
   ↓
3. 顯示條碼圖 + 商品資訊
   - 商品名稱
   - 商品編號
   ↓
4. 自動觸發列印對話框
   ↓
5. 列印完成後關閉視窗
```

---

## 🎯 使用情境範例

### 情境 1：新增新商品「芒果刨冰」

1. 店員點擊「新增商品」
2. 輸入商品資料：
   - 名稱：芒果刨冰
   - 類型：成品
   - 分類：冰品
   - 單位：個
3. 點擊「新增商品」儲存
4. 系統自動生成：
   - product_code: ICE000245
   - barcode_value: ICE000245
5. 商品建立完成，可在倉庫撿貨與 POS 掃碼使用

### 情境 2：商品編號需要恢復

1. 某次誤操作後，條碼內容被意外修改
2. 管理者進入「編輯商品」
3. 看到條碼值與商品編號不一致
4. 點擊「重新生成條碼」
5. 系統將 barcode_value 重置為 product_code
6. 條碼恢復正常，可重新列印標籤

### 情境 3：列印商品標籤

1. 倉庫收到新的原物料「法國麵粉」
2. 管理者編輯該商品資料
3. 點擊「列印條碼標籤」
4. 列印對話框顯示條碼與商品資訊
5. 連接標籤機或一般印表機列印
6. 將標籤貼在商品包裝上

---

## 🔐 權限與錯誤處理

### 權限控管

1. **商品編號修改**
   - 目前設定：不可修改（唯讀）
   - 未來擴充：可設定管理員權限允許修改

2. **條碼重新生成**
   - 所有可編輯商品的使用者皆可使用
   - 建議：可加入操作記錄追蹤

### 錯誤處理

#### 1. 條碼生成失敗

```typescript
// BarcodeDisplay 組件已處理
try {
  JsBarcode(canvasRef.current, value, {...});
} catch (error) {
  console.error("Error generating barcode:", error);
  // 顯示友善錯誤訊息
}
```

**可能原因：**
- 條碼內容包含無效字符
- Code128 不支援的特殊符號

**解決方案：**
- 確保商品編號僅包含英數字
- 顯示錯誤提示給使用者

#### 2. 條碼重複檢查

**目前實作：**
- 商品編號自動遞增，保證唯一性
- barcode_value 預設等於 product_code

**未來建議：**
```typescript
// 儲存前檢查條碼重複
const isDuplicate = products.some(
  p => p.barcode_value === formData.barcode_value && p.id !== product?.id
);

if (isDuplicate) {
  toast.error("條碼內容重複，請重新生成");
  return;
}
```

#### 3. 下載/列印失敗

**處理方式：**
- 檢查 Canvas 元素是否存在
- 瀏覽器權限檢查
- 顯示友善錯誤訊息

---

## 📊 商品列表更新

### 新增欄位

商品列表已更新，新增「商品編號」欄位：

```
| 商品編號   | 商品名稱     | 類型   | 分類     | 條碼      | 單位 | 庫存數量 | 操作 |
|-----------|-------------|--------|---------|-----------|------|----------|------|
| ICE000001 | 法國麵粉    | 原物料 | 烘焙材料 | ICE000001 | 公斤 | 150      | ✏️🗑️ |
| ICE000002 | 草莓蛋糕    | 成品   | 蛋糕    | ICE000002 | 個   | -        | ✏️🗑️ |
```

### 搜尋功能更新

搜尋框已支援商品編號搜尋：
- 商品名稱
- **商品編號（新增）**
- 條碼內容
- 分類

---

## 🚀 未來擴充建議

### 1. 批次條碼列印

```typescript
// 選擇多個商品，一次列印所有條碼標籤
const handleBatchPrint = (selectedProducts: Product[]) => {
  // 生成包含多個條碼的列印頁面
  // 適合一次收貨多種商品的情境
}
```

### 2. 自訂條碼規則

```typescript
// 允許管理員自訂商品編號前綴
interface BarcodeSettings {
  prefix: string;        // 例：ICE, CAKE, RAW
  digitLength: number;   // 例：6
  startNumber: number;   // 例：1
}
```

### 3. 條碼掃描驗證

```typescript
// 使用手機或掃碼槍掃描條碼
// 驗證條碼是否存在於系統中
const handleBarcodeScan = (scannedValue: string) => {
  const product = products.find(p => p.barcode_value === scannedValue);
  if (product) {
    // 顯示商品詳情
  } else {
    // 提示條碼不存在
  }
}
```

### 4. 條碼操作記錄

```typescript
interface BarcodeLog {
  productId: string;
  action: 'generated' | 'regenerated' | 'printed' | 'downloaded';
  oldValue?: string;
  newValue: string;
  timestamp: string;
  userId: string;
}
```

### 5. QR Code 支援

```typescript
// 除了 Code128，也支援 QR Code
// QR Code 可包含更多資訊（URL、JSON 等）
import QRCode from "qrcode";
```

---

## 📝 測試檢查清單

- [x] 新增商品時自動生成商品編號
- [x] barcode_value 預設等於 product_code
- [x] Code128 條碼正確生成並顯示
- [x] 重新生成條碼功能正常
- [x] 下載條碼圖片功能正常
- [x] 列印條碼標籤功能正常
- [x] 商品編號在編輯時唯讀顯示
- [x] 商品列表顯示商品編號
- [x] 搜尋支援商品編號
- [x] 條碼生成錯誤處理
- [x] UI 符合 Guidelines 設計規範
- [x] 響應式設計（桌面版）

---

## 🎨 設計規範遵循

根據 Guidelines.md：

1. **主要動作按鈕**
   - 「新增商品」：使用 `button-filled-primary`
   - 「儲存變更」：使用 `button-filled-primary`

2. **次要動作按鈕**
   - 「取消」：使用 `button-outlined-primary`
   - 「重新生成」：使用 `button-outlined-primary`
   - 「下載條碼圖片」：使用 `button-outlined-primary`
   - 「列印條碼標籤」：使用 `button-outlined-primary`

3. **對比度檢查**
   - 所有按鈕的背景色與文字色皆符合對比度要求
   - 使用 CSS 變數確保一致性

---

## 📚 相關檔案清單

### 新增檔案
- `/components/BarcodeDisplay.tsx` - 條碼顯示組件

### 修改檔案
- `/components/ProductManagement.tsx` - 新增商品編號生成邏輯
- `/components/ProductDialog.tsx` - 新增條碼區域與相關功能
- `/components/ProductTable.tsx` - 新增商品編號欄位

### 參考檔案
- `/styles/globals.css` - 按鈕與樣式定義
- `/guidelines/Guidelines.md` - 設計規範

---

## 💡 使用建議

1. **定期備份商品資料**
   - 商品編號與條碼資訊非常重要
   - 建議定期匯出資料

2. **標籤管理**
   - 建議使用熱感應標籤紙
   - 條碼尺寸適合一般掃碼槍讀取

3. **倉庫作業流程**
   - 收貨時列印標籤並貼在商品上
   - 撿貨時掃描條碼確認商品
   - POS 結帳時掃描條碼計價

4. **條碼品質**
   - 確保列印清晰
   - 避免條碼損壞或污損
   - 定期更換磨損的標籤

---

## 🔧 故障排除

### 問題 1：條碼無法顯示

**可能原因：**
- JsBarcode 套件未正確載入
- 條碼內容包含無效字符

**解決方式：**
- 檢查控制台錯誤訊息
- 確認條碼內容僅包含英數字

### 問題 2：列印視窗空白

**可能原因：**
- 瀏覽器阻擋彈出視窗
- Canvas 尚未完成渲染

**解決方式：**
- 允許瀏覽器彈出視窗
- 確認條碼已正確顯示後再列印

### 問題 3：商品編號重複

**可能原因：**
- 多個使用者同時新增商品
- 資料同步問題

**解決方式：**
- 使用資料庫自動遞增序號
- 實作樂觀鎖定機制

---

## 📞 技術支援

如有任何問題或建議，請聯繫開發團隊。

最後更新：2025-11-28
