<style type="text/css">
.Lbl_Highlight {
color: #0000BF;
}
.Bar_Highlight {
background-color: #0000BF;
color: #FFF;
}
.Lbl_Danger {
color: #BF0000;
}
.Bar_Danger {
background-color: #BF0000;
color: #FFF;
}
pt-3{padding-top: 3px;}
pr-3{padding-right: 3px;}
pb-3{padding-bottom: 3px;}
pl-3{padding-left: 3px;}
pAll-3{padding: 3px;}
.no_bg,
.no_bg>pre,
pre.no_bg,
.markdown-body:not(.next-editor) .no_bg>pre,
.markdown-body:not(.next-editor) .bar_edit_info>pre {
background: transparent;
}
.markdown-body:not(.next-editor) .bar_edit_info>pre {
text-align: right;
padding: 0;
}
</style>
<h2 style="text-align: center;">
RFQ 料件管理:Parts
</h2>
<div class="bar_edit_info">
author: Franklin, Mar. 28, 2024
</div>
<div class="Lbl_Highlight">
◎ 料件管理 Issues:
</div>
<ul>
<li>#135: 檢視料件</li>
<li>#136: 編輯料件</li>
<li>#137: 新增料件</li>
<li>#138: 基本查詢料件</li>
<li>#193: 進階查詢料件</li>
</ul>
<div class="Lbl_Highlight">
◎ 變數說明:
</div>
| 類型 | 回傳變數名稱 | 值 |
| -------- | -------- | -------- |
| 回傳自定義代碼 | ResponseCode::OK | 200 |
| 回傳自定義代碼 | ResponseCode::do_nothing | 0 |
說明:
<ul>
<li>
回傳自定義代碼: 這常用在 <span class="Lbl_Highlight">回傳的JSON</span> {"code": xxx} 用以表達多樣的處理資訊;
<div>
<span class="Lbl_Danger">不同於 <span class="pl-3 pr-3 Bar_Danger">Http Status Code</span></span>
</div>
</li>
</ul>
---
### 通用 API: [料件管理]頁面參數
Issue #136, #137 會用到
---
```url=
[GET] {{prefix}}/part/get-view-param
```
⚠(無參數)
```
Response Sample:
```
```json=
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": {
// ---- [product line] 列表 => 沒資料的話,會是 null
"product_lines": [
{
"id": 123,
"brand_id": 10,
"name": "xxxProduct Line Item",
// ---- [負責人]資料,來自 product line id => 有可能是 NULL
"owner": {
"user_id": 123,
"name": "xxx負責人"
},
// ---- [代理人]資料,來自 product line id => 有可能是 NULL
"agent": {
"user_id": 456,
"name": "xxx代理人"
},
}
],
// ---- [MSL] 列表 => 沒資料的話,會是 null
"msl_list": [
{
"id": 123,
"code": "xxx", // 這個要帶入<option>的 value, 可能有 NULL, 表示 "所有"
"name": "xxx", // 這個是<option>顯示內容
}
],
// ---- [Packing] 列表 => 沒資料的話,會是 null
"packing_list": [
{
"id": 123,
"code": "xxx", // 這個要帶入<option>的 value, 可能有 NULL, 表示 "所有"
"name": "xxx", // 這個是<option>顯示內容
}
],
// ---- [MPN Type] 列表 => 沒資料的話,會是 null
"mpn_type_list": [
{
"id": 123,
"code": "xxx", // 這個要帶入<option>的 value, 可能有 NULL, 表示 "所有"
"name": "xxx", // 這個是<option>顯示內容
}
]
}
}
```
---
### 通用 API: get [相似料件] Auto Complete
Issue #136, #137, #193 會用到
---
```url=
[GET] {{prefix}}/part/get-similar-parts
```
```
Request 參數:
```
```json=
{
"mpnKeyword": "xxx" // 部分或全部的 [MPN 關鍵字]
}
```
```
Response Sample:
```
```json=
// ---- 沒資料的情境
{
"code": ResponseCode::do_nothing, // 請看上面[變數說明]
"message": "沒資料",
"data": null
}
// ---- 有資料的情境
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": [
{
"id": 5,
"mpn": "xxxMPN"
}
]
}
```
---
### 通用 API: 料件進階查詢[MFG 關鍵字] Auto Complete
Issue #193 會用到, MFG 其實是查詢[品牌資料], "brand" table
---
```url=
[GET] {{prefix}}/brands/get-similar-brands
```
```
Request 參數:
```
```json=
{
"mfgKeyword": "xxx" // 部分或全部的 [MFG 關鍵字]
}
```
```
Response Sample:
```
```json=
// ---- 沒資料的情境
{
"code": ResponseCode::do_nothing, // 請看上面變數說明,
"message": "沒資料",
"data": null
}
// ---- 有資料的情境
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": [
{
"id": 5,
// ---- 因為資料表有這兩種欄位,是否這兩個名稱都要顯示在 auto complete 項目內,待確認
"name": "xxxMFG",
"short_name": "xxxMFG", // 很有可能是 NULL
}
]
}
```
---
### 通用 API: 料件進階查詢[Product Line 關鍵字] Auto Complete
Issue #193 會用到
---
```url=
[GET] {{prefix}}/part/get-similar-productLines
```
```
Request 參數:
```
```json=
{
"productLineKeyword": "xxx" // 部分或全部的 [Product Line 關鍵字]
}
```
```
Response Sample:
```
```json=
// ---- 沒資料的情境
{
"code": ResponseCode::do_nothing, // 請看上面[變數說明]
"message": "沒資料",
"data": null
}
// ---- 有資料的情境
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": [
{
"id": 5,
"name": "xxxProduct Line"
}
]
}
```
---
### 通用 API: [MPN] 檢核(在 "parts" table 不能重複)
Issue #137 會用到, 在 [MPN]input 的 onblur 事件觸發
---
```url=
[GET] {{prefix}}/part/vali-part
```
```
Request 參數:
```
```json=
{
"mpnKeyword": "xxx" // 部分或全部的 [MPN 關鍵字]
}
```
<div class="Lbl_Danger">
⚠ 如果驗證失敗(MPN重複),HTTP Status 會是 <span class="pl-3 pr-3 Bar_Danger">422</span>
</div>
```
Response Sample:
```
```json=
// ---- [MPN]正常
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "", // 重複的話,會顯示 "[MPN]已存在, 不可重複"
// 這個是[20240506] Alan 要求要補上,
// 事實上沒功能,當MPN 存在時,才會有資料
"data": null
}
// ---- [MPN]已存在
{
"code": -5,
"message": "[MPN]已存在"
}
```
---
### 通用 API: [MFG] 檢核(檢查 brand name 必須存在)
Issue #137 會用到, 在 [MFG]input 的 onblur 事件觸發
---
```url=
[GET] {{prefix}}/brands/vali-brand
```
```
Request 參數:
```
```json=
{
"mfgKeyword": "xxx" // 部分或全部的 [MFG 關鍵字]
}
```
<div class="Lbl_Danger">
⚠ 如果驗證失敗(Brand Name不存在),HTTP Status 會是 <span class="pl-3 pr-3 Bar_Danger">422</span>
</div>
```
Response Sample:
```
```json=
// ---- [MFG]正常
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": {
"brand_id": 123 // 如果沒資料,會呈現 NULL
}
}
// ---- [MFG]不存在
{
"code": -5,
"message": "[MFG]不存在"
}
```
---
### 通用 API: 取得 [product_lines] by [MFG](產品名稱)
Issue #137 會用到, 在 [MFG]input 的 onblur 事件觸發
---
```url=
[GET] {{prefix}}/part/get-product-lines
```
```
Request 參數:
```
```json=
{
"mfg": "xxx" // 完整的 [MFG](品牌名稱)
}
```
<div class="Lbl_Highlight">
⚠ HTTP Status 一律都是 200
</div>
```
Response Sample:
```
```json=
// ---- [MFG]正常
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": { // 如果沒資料,會呈現 NULL
{
"id": 1,
"brand_id": 52,
"name": "rem",
"owner": { // 負責人
"user_id": 5,
"name": "xxx"
},
"agent": null // 代理人
},
{
"id": 1,
"brand_id": 52,
"name": "rem",
"owner": null, // 負責人
"agent": { // 代理人
"user_id": 27,
"name": "xxx"
}
}
}
}
// ---- [MFG]不存在
{
"code": -5,
"message": "[MFG]不存在",
"data": null
}
```
---
### 135 檢視料件
---
```url=
[GET] {{prefix}}/part/{{partId}}
```
| url 參數 | 內容 |
| -------- | -------- |
| partId | 料件 id |
```
Response Sample:
```
```json=
// ---- 沒資料的情境
{
"code": ResponseCode::do_nothing, // 請看上面[變數說明]
"message": "沒資料",
"data": null
}
// ---- 有資料的情境
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": {
"id": 5,
"brand_id": 45,
"product_line_id": 46,
"product_line_name": "xxx名稱",
"mpn": "corporis-4",
// ---- 潮濕敏感等級 listcode => 有可能是 NULL
"msl": "XXX",
"spq": 1110,
// ---- 零件包裝方式 listcode => 有可能是 NULL
"packing": "XXX",
"package": "esse",
// ---- [type_code] 就是 [MPN Type] listcode => 有可能是 NULL
"type_code": "XXX",
"datasheet_url": "http://xxx.net/",
"is_runner_part": 0,
"is_active": 1,
"created_at": null,
"updated_at": null,
// ---- GNEPN, 可能是 null
"GNEPN": "xxx",
// ---- GFM, 可能是 null, 就是 brand name, 與 "brands.id" 對應
"mfg": "xxx",
// ---- [負責人]資料,來自 product line id
"owner": {
"user_id": 123,
"name": "xxx負責人"
},
// ---- [代理人]資料,來自 product line id
"agent": {
"user_id": 456,
"name": "xxx代理人"
},
// ---- [相似料件] => 沒資料的話,就是 null
"similar_parts": [
{
"part_id": 123,
"mpn": "xxx"
}
],
// ---- [相似料件] JSON, key 是 part_id(料件id), 方便前端一些地方操作(例如添加/移除料件會用到)
"similar_parts_pair": {
"405": {
"mpn": "xxxxx"
}
},
// ---- Tag 組裝字串, 有可能是 NULL; 如果不是null, 這個欄位值可以直接帶入輸入框
"tags_str": "TagA,TagB,TagC",
// ---- Tag 原始陣列,有可能是 NULL
"tags": [
{"id": 1, "name": "TagA"},
{"id": 2, "name": "TagB"},
{"id": 3, "name": "TagC"}
]
}
}
```
---
### 136 編輯料件
---
```url=
[PUT] {{prefix}}/part/{{partId}}
```
⚠ Issue #136 還會用到另外2個 API, 寫在上面:
- 通用 API: [料件管理]頁面參數
- 通用 API: [相似料件]
⚠ Issue #136 會用到 <span class="Lbl_Highlight">[新增 GNEPN]</span>
<span class="Lbl_Highlight">[後端開發]</span> 可參考這裡(前端請忽略):
https://gitserver.gneic.com/backend/TtService/-/wikis/home/api/parts/create-gnepn
⚠ Issue #136 也會用到 <span class="Lbl_Highlight">[更新 GNEPN 的相關資訊]</span>
<span class="Lbl_Highlight">[後端開發]</span> 可參考這裡(前端請忽略):
https://gitserver.gneic.com/tiptop/websocket/-/wikis/wiki/gnepn/GneGNEPNUPD
```
Request 參數:
```
⚠ 參數沒有 [mpn], [mfg] 這兩個欄位
```json=
{
// -------- 以下都是 Required 欄位
"product_line_id": 46,
"msl": "XXX",
"spq": 1110,
"packing": "XXX",
"package": "esse",
"type_code": "XXX", // 這是 [MPN Type] 欄位
"datasheet_url": "http://xxx.net/",
"is_runner_part": 0, // [Runner Parts] 欄位,勾選請輸入 1, 未勾選輸入 0
"is_active": 1, // [料件有效] 欄位,勾選請輸入 1, 未勾選輸入 0
// [相似料號 id] 陣列, 若帶入 null, 或空陣列,
// => !!! 視同不要任何相似料件,會把現有的相似料件全刪除 !!!
"similar_parts": [1,2,3,4],
// [Tag]欄位 => 若帶入 null, 或空陣列,會把現有的 Tag 都刪除(by 當前使用者 id)
"tags": ["TagA", "TagB"]
}
```
```
Response Sample:
```
```json=
{
// ResponseCode::OK: 代表成功(請看上面[變數說明]), 負數: 代表失敗
"code": ResponseCode::OK,
"message": "",
"data": {
// 如果有要[產生 GNEPN], 產生成功後這裡會帶入數值;
// 但也有可能本來就有 GNEPN 了,這裡一樣會帶入現有的 GNEPN
"newGNEPN": null
}
}
```
<div class="Lbl_Danger">
⚠ 如果更新失敗,HTTP Status 會是 <span class="pl-3 pr-3 Bar_Danger">400</span>
</div>
---
### 136-1 產生 GNEPN
---
```url=
[POST] {{prefix}}/part/gen-gnepn/{{partId}}
```
⚠ 沒有參數
```
Response Sample:
```
```json=
{
// ResponseCode::OK: 代表成功(請看上面[變數說明]), 負數: 代表失敗
"code": ResponseCode::OK,
"message": "",
"data": {
"newGNEPN": "42-DOLORUM-35",
"hasExisted": false // GNEPN 是否子存在
}
}
```
⚠ 如果原本 GNEPN 已存在,此處回傳參數 "code" 依然是 ResponseCode::OK,
只不過 "hasExited": true, 然後 "message": "[GNEPN] 早先已新增"
---
### 137 新增料件
---
```url=
[POST] {{prefix}}/part
```
⚠ Issue #137 還會用到另外4個 API, 都寫在上面:
- 通用 API: [料件管理]頁面參數
- 通用 API: [相似料件]
- 通用 API: [MPN] 檢核
- 通用 API: [MFG] 檢核
⚠ Issue #137 會用到 <span class="Lbl_Highlight">[新增 GNEPN]</span>
<span class="Lbl_Highlight">[後端開發]</span> 可參考這裡(前端請忽略):
https://gitserver.gneic.com/backend/TtService/-/wikis/home/api/parts/create-gnepn
```
Request 參數:
```
```json=
{
// -------- 以下是 Required 欄位
"mpn": "corporis-4", // [MPN]一律[大寫]
"mfg": 'xxxBrand', // [MFG] 欄位就是 brand name
"product_line_id": 46,
"msl": "XXX",
"spq": 1110,
"packing": "XXX",
"package": "esse",
"type_code": "XXX", // 這是 [MPN Type] 欄位
"datasheet_url": "http://xxx.net/",
"is_runner_part": 0, // [Runner Parts] 欄位,勾選請輸入 1, 未勾選輸入 0
"is_active": 1, // [料件有效] 欄位,勾選請輸入 1, 未勾選輸入 0
// [相似料號 id] 陣列, 若帶入 null, 或空陣列,
// => !!! 視同不要任何相似料件,會把現有的相似料件全刪除 !!!
"similar_parts": [1,2,3,4],
// [Tag]欄位 => 若帶入 null, 或空陣列,會把現有的 Tag 都刪除(by 當前使用者 id)
"tags": ["TagA", "TagB"],
// -------- 以下是 Optional 欄位
// 這是要產生 GNEPN 會用到的功能,也就是按下 "Save & Gen GNEPN"
// 輸入1: 表示需要產生 GNEPN, 其他數字,或是沒有設定此欄位,就不產生
// 這個功能現階段還沒有實際作用,等這一兩星期完成了,會另外通知,目前只是預留欄位
"isGenGNEPN": 1
}
```
```
Response Sample:
```
⚠ 新增成功的 Http Status 為 <span class="pl-3 pr-3 Bar_Highlight">201</span>
<div class="Lbl_Danger">
⚠ 如果新增失敗,HTTP Status 會是 <span class="pl-3 pr-3 Bar_Danger">400</span>
</div>
<br>
```json=
{
// ResponseCode::OK: 代表成功(請看上面[變數說明]), 負數: 代表失敗
"code": ResponseCode::OK,
"message": "",
"data": {
"partId": 123, // 新增後的 id
// 新增的 GNEPN, 預設 null; 如果指定要產生 GNEPN 的話,新增成功後,這裡會有值
"newGNEPN": "xxxGNEPN"
}
}
```
---
### 138 查詢料件, 193 進階查詢
---
```url=
[GET] {{prefix}}/part
```
```
Request 參數:
```
```json=
{
// -------- 以下都是 Optional 欄位
"page": 1, // [分頁]頁碼 => 需要 merge 在 request() 裡面
"size": 10, // [分頁] limit, 也就是 paginate() 參數, page size
// ======== 前 2 個欄位給 Issue 138(基本查詢)用
// ---- [關鍵字]: 給 Issue 138 用的, 包含 MPN, GNEPN, Tag
"keyword": "xxx",
// ---- 是否有[GNEPN]: 0沒有, 1有, 其他數字或忽略此欄位都是[不指定(有或沒有)]
"hasGNEPN": 1,
// 單獨針對[GNE Part] => 也就是 [GNEPN] 關鍵字
"gnepartKeyword": "xxx",
// [MPN] 關鍵字, Issue #138 col filter & #193 會用到
"mpnKeyword": "xxx",
// [MFG] 關鍵字, Issue #138 col filter & #193 會用到
"mfgKeyword": "xxx",
"mslKeyword": "xxx", // [MSL] 關鍵字
"spqKeyword": "xxx", // [SPQ] 關鍵字
"packingKeyword": "xxx", // [Packing] 關鍵字
"packageKeyword": "xxx", // [Package] 關鍵字
"typeCodeKeyword": "xxx", // [MPN Type] 關鍵字 => 對應到 [type_code] 欄位
"dataSheetKeyword": "xxx", // [datasheet_url] 關鍵字
"is_active": 1, // [is_active: 輸入 0 或 1]
"createdAtKeyword": "2024-04-11", // [創建時間] 關鍵字
"updatedAtKeyword": "2024-04-11", // [更新時間] 關鍵字
"ownerKeyword": "xxx", // [負責人] 關鍵字
"agentKeyword": "xxx", // [代理人] 關鍵字
// [Product Line] 關鍵字, Issue #138 col filter & #193 會用到
"productLineKeyword": "xxx",
// [Tag] 關鍵字[陣列], Issue #193 會用到
"tagKeywords": ["xxx", "yyy", "zzz"]
}
```
```
Response Sample:
```
```json=
// ---- 沒資料的情境
{
"code": ResponseCode::do_nothing, // 請看上面[變數說明]
"message": "沒資料",
"data": {
// ---- 分頁相關資訊
"page": {
"last": 1, // [最後一頁]的頁碼
"current": 1, // [當前頁面]的頁碼
"per_page": 10, // 每頁[資料筆數]
"total": 200 // 符合查詢條件的[總資料數]
},
// ---- 主要紀錄
"lists": null
}
}
// ---- 有資料的情境
{
"code": ResponseCode::OK, // 請看上面[變數說明]
"message": "",
"data": {
// ---- 分頁相關資訊
"page": {
"last": 1, // [最後一頁]的頁碼
"current": 1, // [當前頁面]的頁碼
"per_page": 10, // 每頁[資料筆數]
"total": 200 // 符合查詢條件的[總資料數]
},
// ---- 主要紀錄
"lists": [
{
"id": 5,
"brand_id": 45,
"product_line_id": 46,
"product_line_name": "xxx名稱",
"mpn": "corporis-4",
// ---- 潮濕敏感等級 listcode => 有可能是 NULL
"msl": "XXX",
"spq": 1110,
// ---- 零件包裝方式 listcode => 有可能是 NULL
"packing": "XXX",
"package": "esse",
// ---- [type_code] 就是 [MPN Type] listcode => 有可能是 NULL
"type_code": "XXX",
"datasheet_url": "http://xxx.net/",
"is_runner_part": 0,
"is_active": 1,
"created_at": null,
"updated_at": null,
// ---- GNEPN, 可能是 null
"GNEPN": "xxx",
// ---- MFG, 可能是 null, 就是 brand name, 與 "brands.id" 對應
"mfg": "xxx",
// ---- [負責人]資料,來自 product line id, 可為 null
"owner": {
"user_id": 123,
"name": "xxx負責人"
},
// ---- [代理人]資料,來自 product line id, 可為 null
"agent": {
"user_id": 456,
"name": "xxx代理人"
},
// ---- [相似料件] Array => 沒資料的話,就是 null
"similar_parts": [
{
"part_id": 123,
"mpn": "xxx"
}
],
// ---- [相似料件] JSON, key 是 part_id(料件id), 方便前端一些地方操作(例如添加/移除料件會用到)
"similar_parts_pair": {
"405": {
"mpn": "xxxxx"
}
},
// ---- Tag 組裝字串, 有可能是 NULL; 如果不是null, 這個欄位值可以直接帶入輸入框
"tags_str": "TagA,TagB,TagC",
// ---- Tag 原始陣列,有可能是 NULL
"tags": [
{"id": 1, "name": "TagA"},
{"id": 2, "name": "TagB"},
{"id": 3, "name": "TagC"}
]
}
]
}
}
```