147 lines
9.1 KiB
Markdown
147 lines
9.1 KiB
Markdown
# คู่มือโครงสร้าง JSON สำหรับนำเข้าสินค้า (Product JSON Import Specification)
|
|
|
|
> **DBK Platform tenant example:** Schema fields are shared platform contracts. The HomAroma brand, aroma products, categories, and copy below are reference-tenant sample data only.
|
|
|
|
ระบบนำเข้าสินค้าของ HomAroma รองรับการ Import ผ่านไฟล์ `.json` หรือวาง Payload JSON Array ได้โดยตรงผ่าน:
|
|
1. **หน้าจอ Admin:** เมนู `/products` -> กดปุ่ม **"Import JSON"**
|
|
2. **API Endpoint:** `POST /api/products/bulk` หรือ `POST /api/products`
|
|
|
|
---
|
|
|
|
## 1. รูปแบบโครงสร้าง JSON (JSON Schema)
|
|
|
|
Payload หลักจะต้องเป็น **JSON Array** ของสินค้า โดยรองรับสินค้า 2 รูปแบบหลัก:
|
|
|
|
### แบบที่ 1: สินค้าเดี่ยว (Simple Product - ไม่มีตัวเลือกย่อย)
|
|
เหมาะสำหรับสินค้าที่มีขนาดเดียว ราคาเดียว ไม่ต้องแตก Variant:
|
|
|
|
```json
|
|
{
|
|
"name": "ก้านไม้หอมปรับอากาศ กลิ่นมะลิไทย (Reed Diffuser Jasmine)",
|
|
"categoryName": "Reed Diffuser",
|
|
"brandName": "HomAroma",
|
|
"price": 490,
|
|
"stock": 100,
|
|
"sku": "HA-RD-JAS-100",
|
|
"barcode": "8859123456801",
|
|
"description": "ก้านไม้กระจายความหอมกลิ่นดอกมะลิธรรมชาติ หอมละมุน 4-6 สัปดาห์",
|
|
"details": "ปริมาตร: 100ml\nรวมก้านไม้ไฟเบอร์ 6 ก้าน",
|
|
"images": [
|
|
"https://example.com/uploads/diffuser-1.jpg",
|
|
"https://example.com/uploads/diffuser-2.jpg"
|
|
]
|
|
}
|
|
```
|
|
|
|
> **ระบบ Auto-Handling:** เมื่อใส่ `price`, `stock`, `sku`, `barcode` ไว้ที่ระดับบนสุด ระบบจะสร้าง Default Base Variant ให้โดยอัตโนมัติ
|
|
|
|
---
|
|
|
|
### แบบที่ 2: สินค้าที่มีหลายตัวเลือกย่อย (Variable Product)
|
|
เหมาะสำหรับสินค้าที่มี ขนาด, กลิ่น, หรือสี ให้เลือก:
|
|
|
|
```json
|
|
{
|
|
"name": "น้ำมันหอมระเหย ลาเวนเดอร์ 100% Pure Essential Oil",
|
|
"categoryName": "Aroma Oil",
|
|
"brandName": "HomAroma",
|
|
"description": "น้ำมันหอมระเหยบริสุทธิ์แท้ 100% สกัดจากดอกลาเวนเดอร์ประเทศฝรั่งเศส",
|
|
"details": "วิธีใช้: หยด 3-5 หยดลงในเตาอโรมา\nขนาด: 10ml, 30ml",
|
|
"options": [
|
|
{
|
|
"name": "ขนาด",
|
|
"values": ["10ml", "30ml"]
|
|
}
|
|
],
|
|
"variants": [
|
|
{
|
|
"option1": "10ml",
|
|
"price": 390,
|
|
"stock": 50,
|
|
"sku": "HA-LAV-10ML",
|
|
"barcode": "8859123456701"
|
|
},
|
|
{
|
|
"option1": "30ml",
|
|
"price": 890,
|
|
"stock": 30,
|
|
"sku": "HA-LAV-30ML",
|
|
"barcode": "8859123456702"
|
|
}
|
|
],
|
|
"images": [
|
|
"https://example.com/uploads/lav-1.jpg"
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### แบบที่ 3: รองรับหลายภาษา (Multilingual - รองรับ 8 ภาษา: th, en, ja, zh, vi, ko, lo, it)
|
|
สามารถใส่ข้อความหลายภาษาใน `translations` หรือใส่เป็น Object ที่ฟิลด์ `name`, `description`, `details` ได้โดยตรง:
|
|
|
|
```json
|
|
{
|
|
"name": "น้ำมันหอมระเหย ยูคาลิปตัส",
|
|
"categoryName": "Aroma Oil",
|
|
"brandName": "HomAroma",
|
|
"price": 320,
|
|
"stock": 60,
|
|
"sku": "HA-EUC-10ML",
|
|
"translations": {
|
|
"th": {
|
|
"name": "น้ำมันหอมระเหย ยูคาลิปตัส 100%",
|
|
"description": "ช่วยให้หายใจโล่ง สดชื่น ปลอดโปร่ง",
|
|
"details": "ขนาด: 10ml"
|
|
},
|
|
"en": {
|
|
"name": "Eucalyptus Pure Essential Oil 100%",
|
|
"description": "Refreshes breathing and clarifies the mind.",
|
|
"details": "Size: 10ml"
|
|
},
|
|
"ja": {
|
|
"name": "ユーカリ 100% ピュア エッセンシャルオイル",
|
|
"description": "クリアで清涼感あふれる香りが呼吸をスムーズに整えます。",
|
|
"details": "容量: 10ml"
|
|
},
|
|
"zh": {
|
|
"name": "尤加利 100% 纯天然单方精油",
|
|
"description": "清爽提神的天然尤加利香气,畅通呼吸,净化空气。",
|
|
"details": "规格: 10ml"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 2. พจนานุกรมฟิลด์ (Data Dictionary)
|
|
|
|
| ฟิลด์ | ชนิดข้อมูล | จำเป็น? | คำอธิบายและข้อกำหนด |
|
|
| :--- | :--- | :---: | :--- |
|
|
| `name` | `string` \| `object` | **ใช่** | ชื่อสินค้า (เช่น `"Aroma Oil"` หรือ `{"th": "...", "en": "..."}`) |
|
|
| `categoryName` | `string` | ทางเลือก | ชื่อหมวดหมู่ (หากยังไม่มีในระบบ ระบบจะ **Auto-Create** ให้ทันที) |
|
|
| `categoryId` | `number` | ทางเลือก | รหัสหมวดหมู่เดิมในระบบ (ใช้แทน `categoryName` ได้) |
|
|
| `brandName` | `string` | ทางเลือก | ชื่อแบรนด์ (หากยังไม่มีในระบบ ระบบจะ **Auto-Create** ให้ทันที) |
|
|
| `brandId` | `number` | ทางเลือก | รหัสแบรนด์เดิมในระบบ (ใช้แทน `brandName` ได้) |
|
|
| `description` | `string` \| `object` | ไม่ | คำอธิบายสินค้าโดยย่อ |
|
|
| `details` | `string` \| `object` | ไม่ | รายละเอียดสินค้า วิธีการใช้งาน คุณสมบัติ |
|
|
| `price` | `number` | ไม่* | ราคาจำหน่าย (กรณีสินค้าเดี่ยวไม่มี Variants) |
|
|
| `stock` | `number` | ไม่* | จำนวนสต็อกคงเหลือ (กรณีสินค้าเดี่ยวไม่มี Variants) |
|
|
| `sku` | `string` | ไม่ | รหัสสินค้า SKU |
|
|
| `barcode` | `string` | ไม่ | รหัสบาร์โค้ดสินค้า (สำหรับยิงขายที่ POS) |
|
|
| `images` | `array` | ไม่ | รายการรูปภาพ (รองรับทั้ง Array URL `["https://..."]` หรือ `[{"url": "...", "order": 0}]`) |
|
|
| `options` | `array` | ไม่* | รายการตัวเลือก สูงสุด 3 ตัวเลือก เช่น `[{"name": "ขนาด", "values": ["10ml", "30ml"]}]` |
|
|
| `variants` | `array` | ไม่* | รายการสินค้าย่อย โดย `option1`, `option2`, `option3` จะแมปตามลำดับของ `options` |
|
|
| `translations` | `object` | ไม่ | แผนที่ภาษา รองรับ 8 ภาษา: `th`, `en`, `ja`, `zh`, `vi`, `ko`, `lo`, `it` เช่น `{"th": {...}, "en": {...}, "ja": {...}, ...}` |
|
|
|
|
---
|
|
|
|
## 3. กลไกอัตโนมัติของ Backend (Auto-Provisioning Engine)
|
|
|
|
เมื่อส่ง JSON เข้าสู่ `POST /api/products/bulk`:
|
|
1. **Auto-Category & Auto-Brand:** หากส่ง `categoryName` หรือ `brandName` ที่ยังไม่มีในระบบ ระบบจะสร้าง Category/Brand ใหม่ให้โดยอัตโนมัติ ไม่เกิด Error
|
|
2. **Auto-Default Base Variant:** หากไม่ส่ง `variants` มา แต่ระบุ `price` หรือ `stock` หรือ `sku` ที่ระดับบนสุด ระบบจะแปลงเป็น Single Base Variant ให้อัตโนมัติ ทำให้สินค้าพร้อมขายและตัดสต็อกใน POS ได้ทันที
|
|
3. **Auto-Normalize Images:** แปลงทั้ง String URLs และ Image Objects ให้อยู่ในฟอร์แมตฐานข้อมูลพร้อมกำหนด Order ให้อัตโนมัติ
|
|
4. **Auto-Seed CMS Detail Sections:** ระบบจะสร้าง Section มาตรฐานสำหรับหน้าเว็บ Next.js SSR (Product Main Card, Description, Specifications, Reviews, Related Products) ให้ทันที ทำให้หน้าบ้านแสดงผลได้สมบูรณ์แบบโดยไม่ต้องเข้าไปตั้งค่าทีละชิ้น
|