<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"} ] } ] } } ```