From 5135f7ba9aa09b8aa1a82ce971031df4b8a995ae Mon Sep 17 00:00:00 2001 From: joseph le Date: Wed, 20 May 2026 14:05:53 +0700 Subject: [PATCH] Update api erp, short log --- .../app/controllers/healcheck_controller.ts | 41 ++++++++-------- BACKEND/app/ultils/helper.ts | 47 +++++++++---------- FRONTEND/src/untils/helper.ts | 39 ++++++++------- 3 files changed, 63 insertions(+), 64 deletions(-) diff --git a/BACKEND/app/controllers/healcheck_controller.ts b/BACKEND/app/controllers/healcheck_controller.ts index c59b9a4..9b03e44 100644 --- a/BACKEND/app/controllers/healcheck_controller.ts +++ b/BACKEND/app/controllers/healcheck_controller.ts @@ -7,7 +7,7 @@ const remoteUrl = process.env.ERP_URL || 'https://stage.nswteam.net' export default class HealCheckController { // GET /health-check - async check({}: HttpContext) { + async check({ }: HttpContext) { try { const header = { Authorization: 'Bearer ' + process.env.ERP_TOKEN, @@ -21,21 +21,21 @@ export default class HealCheckController { status: true, message: 'Checking api update note SN success', } - const responseDataSN = await axios.post( - remoteUrl + '/api/transferGetData', + + const responseDataSN = await axios.get( + remoteUrl + '/api/stock-model-serial/get-list-for-test-log', { - urlAPI: '/api/stock-model-serial/get-list-for-test-log', - filter: { - where: { - _q: 'FOC1425Z3RN', + params: { + filter: { + where: { + _q: 'FOC1425Z3RN', + }, }, + orgId: ['5fadc798f070e4b64b53ac9c', '5fadc7b0f070e4b64b53ac9d'], }, - orgId: ['5fadc798f070e4b64b53ac9c', '5fadc7b0f070e4b64b53ac9d'], - }, - { headers: header, } - ) + ); if (!responseDataSN?.data?.data || responseDataSN?.data?.data?.length === 0) { dataCheckNote = { name: 'update-note-sn', @@ -47,18 +47,15 @@ export default class HealCheckController { // console.log(payload) const resSN = await axios.post( - remoteUrl + '/api/transferPostData', + remoteUrl + '/api/stock-model-serial/data-save-for-test-log', { - urlAPI: '/api/stock-model-serial/data-save-for-test-log', - data: { - id: dataSN?.id, - serialNumberA: dataSN?.serialNumberA, - productModelId: dataSN?.productModelId, - orgId: dataSN?.orgId, - condition: dataSN?.condition, - testNotes: dataSN?.testNotes, - healthCheck: true, - }, + id: dataSN?.id, + serialNumberA: dataSN?.serialNumberA, + productModelId: dataSN?.productModelId, + orgId: dataSN?.orgId, + condition: dataSN?.condition, + testNotes: dataSN?.testNotes, + healthCheck: true, }, { headers: header, diff --git a/BACKEND/app/ultils/helper.ts b/BACKEND/app/ultils/helper.ts index 2374ac8..460b0b1 100644 --- a/BACKEND/app/ultils/helper.ts +++ b/BACKEND/app/ultils/helper.ts @@ -216,8 +216,8 @@ export function mapToLineFormat(input: InputData) { const license = dataLicense?.textfsm && Array.isArray(dataLicense.textfsm) ? dataLicense.textfsm - ?.filter((el: any) => el.LICENSE_TYPE === 'Permanent') - .map((v: any) => v.FEATURE) + ?.filter((el: any) => el.LICENSE_TYPE === 'Permanent') + .map((v: any) => v.FEATURE) : '' // // Mode (DPEL / DPELP) @@ -681,21 +681,20 @@ export async function updateNoteToERP(sn: string, note: string) { const header = { Authorization: 'Bearer ' + process.env.ERP_TOKEN, } - const responseDataSN = await axios.post( - remoteUrl + '/api/transferGetData', + const responseDataSN = await axios.get( + remoteUrl + '/api/stock-model-serial/get-list-for-test-log', { - urlAPI: '/api/stock-model-serial/get-list-for-test-log', - filter: { - where: { - _q: sn, + params: { + filter: { + where: { + _q: 'FOC1425Z3RN', + }, }, + orgId: ['5fadc798f070e4b64b53ac9c', '5fadc7b0f070e4b64b53ac9d'], }, - orgId: ['5fadc798f070e4b64b53ac9c', '5fadc7b0f070e4b64b53ac9d'], - }, - { headers: header, } - ) + ); // console.log('updateNoteToERP', responseDataSN?.data?.data) if (!responseDataSN?.data?.data || responseDataSN?.data?.data?.length === 0) { @@ -718,11 +717,8 @@ export async function updateNoteToERP(sn: string, note: string) { } // console.log(payload) await axios.post( - remoteUrl + '/api/transferPostData', - { - urlAPI: '/api/stock-model-serial/data-save-for-test-log', - data: payload, - }, + remoteUrl + '/api/stock-model-serial/data-save-for-test-log', + payload, { headers: header, } @@ -1445,20 +1441,19 @@ export async function getIncomingInfoBySN(sn: string) { const header = { Authorization: 'Bearer ' + process.env.ERP_TOKEN, } - const responseDataSN = await axios.post( - remoteUrl + '/api/transferGetData', + const responseDataSN = await axios.get( + remoteUrl + '/api/package-po/get-incoming-by-sn', { - urlAPI: '/api/package-po/get-incoming-by-sn', - filter: { - where: { - serialNumber: sn, + params: { + filter: { + where: { + serialNumber: sn, + }, }, }, - }, - { headers: header, } - ) + ); if (!responseDataSN?.data?.data) { return diff --git a/FRONTEND/src/untils/helper.ts b/FRONTEND/src/untils/helper.ts index ecd3543..1658ff4 100644 --- a/FRONTEND/src/untils/helper.ts +++ b/FRONTEND/src/untils/helper.ts @@ -249,35 +249,42 @@ export function convertFromKilobytesString( * @returns {string} Chuỗi log đã được rút gọn theo định dạng yêu cầu */ export function createShortLog(rawLog: string): string { - const shortLog = []; + const shortLog: string[] = []; - // 1. Tách show inventory - const invRegex = - /(NAME:\s*"[^"]*",\s*DESCR:\s*"[^"]*"\r?\nPID:\s*[^,]+,\s*VID:\s*[^,]+,\s*SN:\s*\S+)/i; - const invMatch = rawLog.match(invRegex); - if (invMatch) { - shortLog.push(invMatch[1].trim()); + // 1. Tách TOÀN BỘ show inventory bằng vòng lặp Regex + // Sử dụng cờ /gi để quét toàn bộ file tìm các khối NAME + PID kế tiếp + const invRegex = /(NAME:\s*"[^"]*",\s*DESCR:\s*"[^"]*"\s*PID:\s*[^,]+,\s*VID:\s*[^,]*,\s*SN:[^\r\n]*)/gi; + const invMatches = rawLog.match(invRegex); + if (invMatches && invMatches.length > 0) { + // Gom tất cả các module tìm thấy và trim() sạch sẽ khoảng trắng dư thừa + const allModules = invMatches.map(module => module.trim()).join('\n\n'); + shortLog.push(allModules); } - // 2. Tách show version (Đã fix vụ bỏ phần thừa ở giữa) - const verRegex = - /(System image file is[^\r\n]+)[\s\S]*?(cisco\s+[a-zA-Z0-9\-]+\s+\([^)]+\)\s+processor[\s\S]*?Configuration register is 0x[0-9a-fA-F]+)/i; + // 2. Tách show version (Cập nhật để bắt được cả Cisco/cisco và các dòng ISR/Catalyst khác nhau) + // - Group 1: System image file + // - Nhảy qua đoạn rác (Cryptographic/License info rườm rà) + // - Group 2: Bắt đầu từ chữ Cisco (bất kể hoa thường) + Mã máy + "processor" cho đến hết Config register + const verRegex = /(System image file is[^\r\n]+)[\s\S]*?((?:[Cc]isco)\s+\S+.*processor[\s\S]*?Configuration register is 0x[0-9a-fA-F]+)/i; const verMatch = rawLog.match(verRegex); if (verMatch) { - shortLog.push(`${verMatch[1].trim()}\n${verMatch[2].trim()}`); + // verMatch[1] là dòng System image + // verMatch[2] là đoạn từ "cisco ISR..." hoặc "Cisco CISCO..." đến hết + shortLog.push(`\n${verMatch[1].trim()}\n${verMatch[2].trim()}`); } // 3. Tách show license - const licRegex = - /(Index\s+1\s+Feature:[\s\S]*?)(?=\r?\n[a-zA-Z0-9\-\_]+[#>]|$)/i; + // Hỗ trợ cả định dạng cũ (Index 1 Feature) và định dạng Suite mới trên IOS-XE + const licRegex = /(Index\s+1\s+Feature:[\s\S]*?)(?=\r?\n[a-zA-Z0-9\-\_]+[#>]|$)/i; const licMatch = rawLog.match(licRegex); - if (licMatch) { - shortLog.push("\n" + licMatch[1].trim()); + if (licMatch && licMatch[1]) { + shortLog.push(`\n${licMatch[1].trim()}`); } - return shortLog.join("\n"); + return shortLog.join('\n'); } + /** * Hàm in log ra máy in vật lý trong môi trường Web (React/Vue/Vanilla) * @param shortLog - Chuỗi log đã được rút gọn