From fa884f5d201b0805fdb2c9cecf056b7c73a4f2fa Mon Sep 17 00:00:00 2001 From: zhangjiming Date: Thu, 3 Apr 2025 15:59:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E6=B5=8B=E9=87=8F?= =?UTF-8?q?=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 6 +- src/routes/measure.ts | 410 ++++++++-------------------------------------- src/routes/measureTask.ts | 360 ++++++++++++++++++++++++++++++++++++++++ src/routes/mobile.ts | 1 - src/types/mobileWsType.ts | 66 ++++++++ src/utils/wss.ts | 13 ++ 6 files changed, 509 insertions(+), 347 deletions(-) create mode 100644 src/routes/measureTask.ts create mode 100644 src/types/mobileWsType.ts diff --git a/src/index.ts b/src/index.ts index 8f309de..4970815 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,12 +9,13 @@ import path from "path"; import cmdRouter from "./routes/cmd"; import authRouter from "./routes/auth"; -import measureRouter from "./routes/measure"; +import measureTaskRouter from "./routes/measureTask"; import measureAnalysisRouter from "./routes/measureAnalysis"; import measureDataRouter from "./routes/measureData"; import railRouter from "./routes/rail"; import calibrationRouter from "./routes/calibration"; import mobileRouter from "./routes/mobile"; +import measureRouter from "./routes/measure"; // import { defaultStatus, StatusDatagram } from "./types/wsTypes"; import { WsProxy } from "./utils/wss"; @@ -55,10 +56,11 @@ app.use("/api/mobile", mobileRouter); app.use("/api/cmd", cmdRouter); app.use("/api/auth", authRouter); app.use("/api/measurement-analysis", measureAnalysisRouter); -app.use("/api/measurement-task", measureRouter); +app.use("/api/measurement-task", measureTaskRouter); app.use("/api/measurement-data", measureDataRouter); app.use("/api/standard-rail", railRouter); app.use("/api/calibration", calibrationRouter); +app.use("/api/measure", measureRouter); const storage = multer.diskStorage({ destination: function (req, file, cb) { diff --git a/src/routes/measure.ts b/src/routes/measure.ts index c28b3d7..997d956 100644 --- a/src/routes/measure.ts +++ b/src/routes/measure.ts @@ -3,358 +3,80 @@ import { delay } from "../utils/helper"; const router = express.Router(); import points from "../utils/measure.json"; -import { MeasureState } from "../types/wsTypes"; + import { WsProxy } from "../utils/wss"; + let ptIndex = 0; let intervalId1: ReturnType; let intervalId2: ReturnType; -router.post("/cache-measurement", async (req, res) => { - await delay(100); - // setTimeout(() => { - // wsSend(req.app.locals["wss"], { - // type: "cmd", - // data: { - // commandId: req.body.commandId, - // status: "D0000", - // }, - // }); - // }, 2000); - - // const measure: MeasureState["data"] = req.app.locals["measure"]; - // measure.taskStatus = "IDLE"; - // wsSend(req.app.locals["wss"], { - // messageType: "STATE", - // data: req.app.locals["measure"], - // path: "/measurement-task/get-task-state", - // }); +router.post("/start", (req, res) => { + setTimeout(() => { + ptIndex = 0; + WsProxy.sendMobile({ + type: 'measure-event', + data: { event: "START_RECORD_LEFT" }, + }); + }, 10); + intervalId1 = setInterval(() => { + if (ptIndex >= points.length / 2) { + clearInterval(intervalId1); + WsProxy.sendMobile({ + type: 'measure-event', + data: { event: "FINISH_RECORD_LEFT" }, + }); + setTimeout(() => { + WsProxy.sendMobile({ + type: 'measure-event', + data: { event: "START_RECORD_RIGHT" }, + }); + intervalId2 = setInterval(() => { + if (ptIndex >= points.length) { + clearInterval(intervalId2); + ptIndex = 0; + WsProxy.sendMobile({ + type: 'measure-event', + data: { event: "FINISH_RECORD_RIGHT" }, + }); + return; + } + WsProxy.sendMobile({ + type: 'measure-point', + data: { + x: points[ptIndex].x, + y: points[ptIndex].y + 1, + }, + }); + ptIndex = ptIndex + 2; + }, 10); + }, 2000); + return; + } + // 从中心向左边画 + const tempIdx = Math.max(Math.floor(points.length / 2) - ptIndex, 0); + WsProxy.sendMobile({ + type: 'measure-point', + data: { + x: points[tempIdx].x, + y: points[tempIdx].y + 1, + }, + }); + ptIndex = ptIndex + 2; + }, 10); - res.json({ status: 0 }); -}); + res.json({ success: true }); +}) -router.post("/start-measurement", (req, res) => { - setTimeout(() => { - ptIndex = 0; - WsProxy.send({ - messageType: "EVENT", - data: "START_RECORD_LEFT", - path: "/api/measurement-task/event", - }) - }); - intervalId1 = setInterval(() => { - if (ptIndex >= points.length / 2) { - clearInterval(intervalId1); - WsProxy.send({ - messageType: "EVENT", - data: "FINISH_RECORD_LEFT", - path: "/api/measurement-task/event", - }); - setTimeout(() => { - WsProxy.send({ - messageType: "EVENT", - data: "START_RECORD_RIGHT", - path: "/api/measurement-task/event", - }); - intervalId2 = setInterval(() => { - if (ptIndex >= points.length) { - clearInterval(intervalId2); - ptIndex = 0; - WsProxy.send({ - messageType: "EVENT", - data: "FINISH_RECORD_RIGHT", - path: "/api/measurement-task/event", - }); - return; - } - WsProxy.send({ - messageType: "STATE", - data: { - x: points[ptIndex].x, - y: points[ptIndex].y + 1, - }, - path: "/api/measurement-task/point-report", - }); - ptIndex = ptIndex + 2; - }, 10); - }, 2000); - return; - } - WsProxy.send({ - messageType: "STATE", - data: { - x: points[ptIndex].x, - y: points[ptIndex].y + 1, - }, - path: "/api/measurement-task/point-report", - }); - ptIndex = ptIndex + 2; - }, 10); - - res.json({ status: 0 }); -}); -router.post("/stop-measurement", async (req, res) => { - ptIndex = 0; +router.post("/stop", (req, res) => { + ptIndex = 0; clearInterval(intervalId1); clearInterval(intervalId2); - res.json({ status: 0 }); -}); -router.post("/save-analysis-report/6001", async (req, res) => { - await delay(100); - res.json({ - status: 0, - data: { - railHeadWidth: 0, - w1: 0, - angleAnalysisList: [ - { - base: { - x: "-31.20880", - y: "5.46060", - }, - measure: { - x: "-18.33515", - y: "18.33426", - }, - pointA: { - x: "-32.62301", - y: "4.04639", - }, - pointB: { - x: "-29.79458", - y: "6.87482", - }, - distance: "18.206", - describe: "-45.0°", - }, - { - base: { - x: "-28.51641", - y: "3.39466", - }, - measure: { - x: "-22.92048", - y: "13.08709", - }, - pointA: { - x: "-29.51641", - y: "1.66261", - }, - pointB: { - x: "-27.51641", - y: "5.12671", - }, - distance: "11.192", - describe: "-30.0°", - }, - { - base: { - x: "-25.38106", - y: "2.09596", - }, - measure: { - x: "-24.26901", - y: "6.24616", - }, - pointA: { - x: "-25.89870", - y: "0.16410", - }, - pointB: { - x: "-24.86342", - y: "4.02781", - }, - distance: "4.297", - describe: "-15.0°", - }, - { - base: { - x: "-21.01959", - y: "1.19347", - }, - measure: { - x: "-20.63937", - y: "3.34981", - }, - pointA: { - x: "-21.36689", - y: "-0.77615", - }, - pointB: { - x: "-20.67230", - y: "3.16308", - }, - distance: "2.190", - describe: "-10.0°", - }, - { - base: { - x: "-14.10020", - y: "0.28251", - }, - measure: { - x: "-14.04551", - y: "0.90758", - }, - pointA: { - x: "-14.27451", - y: "-1.70988", - }, - pointB: { - x: "-13.92589", - y: "2.27490", - }, - distance: "0.627", - describe: "-5.0°", - }, - { - base: { - x: "0.00000", - y: "0.00000", - }, - measure: { - x: "0.00000", - y: "0.00000", - }, - pointA: { - x: "0.03000", - y: "-1.99977", - }, - pointB: { - x: "-0.03000", - y: "1.99977", - }, - distance: "0.000", - describe: "0.0°", - }, - { - base: { - x: "9.91970", - y: "0.02682", - }, - measure: { - x: "9.91964", - y: "0.02864", - }, - pointA: { - x: "9.98950", - y: "-1.97196", - }, - pointB: { - x: "9.84990", - y: "2.02560", - }, - distance: "0.002", - describe: "2.0°", - }, - { - base: { - x: "14.10020", - y: "0.28251", - }, - measure: { - x: "14.05095", - y: "0.84548", - }, - pointA: { - x: "14.27451", - y: "-1.70988", - }, - pointB: { - x: "13.92589", - y: "2.27490", - }, - distance: "0.565", - describe: "5.0°", - }, - { - base: { - x: "21.01959", - y: "1.19347", - }, - measure: { - x: "20.66094", - y: "3.22749", - }, - pointA: { - x: "21.36689", - y: "-0.77615", - }, - pointB: { - x: "20.67230", - y: "3.16308", - }, - distance: "2.065", - describe: "10.0°", - }, - { - base: { - x: "25.38106", - y: "2.09596", - }, - measure: { - x: "24.31693", - y: "6.06734", - }, - pointA: { - x: "25.89870", - y: "0.16410", - }, - pointB: { - x: "24.86342", - y: "4.02781", - }, - distance: "4.111", - describe: "15.0°", - }, - { - base: { - x: "28.51641", - y: "3.39466", - }, - measure: { - x: "23.09930", - y: "12.77737", - }, - pointA: { - x: "29.51641", - y: "1.66261", - }, - pointB: { - x: "27.51641", - y: "5.12671", - }, - distance: "10.834", - describe: "30.0°", - }, - { - base: { - x: "31.20880", - y: "5.46060", - }, - measure: { - x: "18.68979", - y: "17.97962", - }, - pointA: { - x: "32.62301", - y: "4.04639", - }, - pointB: { - x: "29.79458", - y: "6.87482", - }, - distance: "17.705", - describe: "45.0°", - }, - ], - }, - timestamp: 1741697350184, - }); -}); + res.json({ success: true }); +}) + +router.post("/save", (req, res) => { + res.json({ success: true }); +}) -router.post("/save-report", async (req, res) => { - await delay(100); - res.json({ status: 0 }); -}); -export default router; +export default router; \ No newline at end of file diff --git a/src/routes/measureTask.ts b/src/routes/measureTask.ts new file mode 100644 index 0000000..c28b3d7 --- /dev/null +++ b/src/routes/measureTask.ts @@ -0,0 +1,360 @@ +import express from "express"; +import { delay } from "../utils/helper"; +const router = express.Router(); + +import points from "../utils/measure.json"; +import { MeasureState } from "../types/wsTypes"; +import { WsProxy } from "../utils/wss"; +let ptIndex = 0; +let intervalId1: ReturnType; +let intervalId2: ReturnType; + +router.post("/cache-measurement", async (req, res) => { + await delay(100); + // setTimeout(() => { + // wsSend(req.app.locals["wss"], { + // type: "cmd", + // data: { + // commandId: req.body.commandId, + // status: "D0000", + // }, + // }); + // }, 2000); + + // const measure: MeasureState["data"] = req.app.locals["measure"]; + // measure.taskStatus = "IDLE"; + // wsSend(req.app.locals["wss"], { + // messageType: "STATE", + // data: req.app.locals["measure"], + // path: "/measurement-task/get-task-state", + // }); + + res.json({ status: 0 }); +}); + +router.post("/start-measurement", (req, res) => { + setTimeout(() => { + ptIndex = 0; + WsProxy.send({ + messageType: "EVENT", + data: "START_RECORD_LEFT", + path: "/api/measurement-task/event", + }) + }); + intervalId1 = setInterval(() => { + if (ptIndex >= points.length / 2) { + clearInterval(intervalId1); + WsProxy.send({ + messageType: "EVENT", + data: "FINISH_RECORD_LEFT", + path: "/api/measurement-task/event", + }); + setTimeout(() => { + WsProxy.send({ + messageType: "EVENT", + data: "START_RECORD_RIGHT", + path: "/api/measurement-task/event", + }); + intervalId2 = setInterval(() => { + if (ptIndex >= points.length) { + clearInterval(intervalId2); + ptIndex = 0; + WsProxy.send({ + messageType: "EVENT", + data: "FINISH_RECORD_RIGHT", + path: "/api/measurement-task/event", + }); + return; + } + WsProxy.send({ + messageType: "STATE", + data: { + x: points[ptIndex].x, + y: points[ptIndex].y + 1, + }, + path: "/api/measurement-task/point-report", + }); + ptIndex = ptIndex + 2; + }, 10); + }, 2000); + return; + } + WsProxy.send({ + messageType: "STATE", + data: { + x: points[ptIndex].x, + y: points[ptIndex].y + 1, + }, + path: "/api/measurement-task/point-report", + }); + ptIndex = ptIndex + 2; + }, 10); + + res.json({ status: 0 }); +}); +router.post("/stop-measurement", async (req, res) => { + ptIndex = 0; + clearInterval(intervalId1); + clearInterval(intervalId2); + + res.json({ status: 0 }); +}); +router.post("/save-analysis-report/6001", async (req, res) => { + await delay(100); + res.json({ + status: 0, + data: { + railHeadWidth: 0, + w1: 0, + angleAnalysisList: [ + { + base: { + x: "-31.20880", + y: "5.46060", + }, + measure: { + x: "-18.33515", + y: "18.33426", + }, + pointA: { + x: "-32.62301", + y: "4.04639", + }, + pointB: { + x: "-29.79458", + y: "6.87482", + }, + distance: "18.206", + describe: "-45.0°", + }, + { + base: { + x: "-28.51641", + y: "3.39466", + }, + measure: { + x: "-22.92048", + y: "13.08709", + }, + pointA: { + x: "-29.51641", + y: "1.66261", + }, + pointB: { + x: "-27.51641", + y: "5.12671", + }, + distance: "11.192", + describe: "-30.0°", + }, + { + base: { + x: "-25.38106", + y: "2.09596", + }, + measure: { + x: "-24.26901", + y: "6.24616", + }, + pointA: { + x: "-25.89870", + y: "0.16410", + }, + pointB: { + x: "-24.86342", + y: "4.02781", + }, + distance: "4.297", + describe: "-15.0°", + }, + { + base: { + x: "-21.01959", + y: "1.19347", + }, + measure: { + x: "-20.63937", + y: "3.34981", + }, + pointA: { + x: "-21.36689", + y: "-0.77615", + }, + pointB: { + x: "-20.67230", + y: "3.16308", + }, + distance: "2.190", + describe: "-10.0°", + }, + { + base: { + x: "-14.10020", + y: "0.28251", + }, + measure: { + x: "-14.04551", + y: "0.90758", + }, + pointA: { + x: "-14.27451", + y: "-1.70988", + }, + pointB: { + x: "-13.92589", + y: "2.27490", + }, + distance: "0.627", + describe: "-5.0°", + }, + { + base: { + x: "0.00000", + y: "0.00000", + }, + measure: { + x: "0.00000", + y: "0.00000", + }, + pointA: { + x: "0.03000", + y: "-1.99977", + }, + pointB: { + x: "-0.03000", + y: "1.99977", + }, + distance: "0.000", + describe: "0.0°", + }, + { + base: { + x: "9.91970", + y: "0.02682", + }, + measure: { + x: "9.91964", + y: "0.02864", + }, + pointA: { + x: "9.98950", + y: "-1.97196", + }, + pointB: { + x: "9.84990", + y: "2.02560", + }, + distance: "0.002", + describe: "2.0°", + }, + { + base: { + x: "14.10020", + y: "0.28251", + }, + measure: { + x: "14.05095", + y: "0.84548", + }, + pointA: { + x: "14.27451", + y: "-1.70988", + }, + pointB: { + x: "13.92589", + y: "2.27490", + }, + distance: "0.565", + describe: "5.0°", + }, + { + base: { + x: "21.01959", + y: "1.19347", + }, + measure: { + x: "20.66094", + y: "3.22749", + }, + pointA: { + x: "21.36689", + y: "-0.77615", + }, + pointB: { + x: "20.67230", + y: "3.16308", + }, + distance: "2.065", + describe: "10.0°", + }, + { + base: { + x: "25.38106", + y: "2.09596", + }, + measure: { + x: "24.31693", + y: "6.06734", + }, + pointA: { + x: "25.89870", + y: "0.16410", + }, + pointB: { + x: "24.86342", + y: "4.02781", + }, + distance: "4.111", + describe: "15.0°", + }, + { + base: { + x: "28.51641", + y: "3.39466", + }, + measure: { + x: "23.09930", + y: "12.77737", + }, + pointA: { + x: "29.51641", + y: "1.66261", + }, + pointB: { + x: "27.51641", + y: "5.12671", + }, + distance: "10.834", + describe: "30.0°", + }, + { + base: { + x: "31.20880", + y: "5.46060", + }, + measure: { + x: "18.68979", + y: "17.97962", + }, + pointA: { + x: "32.62301", + y: "4.04639", + }, + pointB: { + x: "29.79458", + y: "6.87482", + }, + distance: "17.705", + describe: "45.0°", + }, + ], + }, + timestamp: 1741697350184, + }); +}); + +router.post("/save-report", async (req, res) => { + await delay(100); + res.json({ status: 0 }); +}); +export default router; diff --git a/src/routes/mobile.ts b/src/routes/mobile.ts index 11e7b82..2419f2f 100644 --- a/src/routes/mobile.ts +++ b/src/routes/mobile.ts @@ -100,7 +100,6 @@ router.get("/getUploadedRecords", async (req, res) => { router.get("/getUnuploadRecords", async (req, res) => { const lastId = +(req.query?.lastId || '0'); const size = +(req.query?.size || '10'); - console.log("lastId:", lastId, " size:", size); const query: Prisma.measurementFindManyArgs = { where: { upload: false }, orderBy: { diff --git a/src/types/mobileWsType.ts b/src/types/mobileWsType.ts new file mode 100644 index 0000000..3f85110 --- /dev/null +++ b/src/types/mobileWsType.ts @@ -0,0 +1,66 @@ +export type PeripheralStatus = { + type: "peripheral-status"; + data: { + connected: boolean; + power: number; + inclinatorX: number; + inclinatorY: number; + temperature: number; + }; +}; + +export type MeasureEvent = { + type: "measure-event"; + data: { + event: + | "START_RECORD_LEFT" + | "FINISH_RECORD_LEFT" + | "START_RECORD_RIGHT" + | "FINISH_RECORD_RIGHT" + | "WRONG_SIDE"; + }; +}; + +export type MeasurePoint = { + type: "measure-point"; + data: { + x: number; + y: number; + }; +}; + +export type BleList = { + type: "ble-list"; + data: Array<{ + mac: string; // 蓝牙设备的 MAC 地址(唯一标识) + name: string; // 蓝牙设备的可读名称(如型号/别名) + linked: boolean; //该设备是否已链接 + // ... 后续补充 + }>; +}; + +export type SyncProgress = { + type: "sync-progress"; // 数据类型:同步进度状态上报 + data: { + remaining: number; // 剩余未同步数量 + fail: number; // 同步失败数量 + total: number; // 总数量 + finish: boolean; // 是否同步完成(true 表示全部完成) + }; +}; + +export type SyncItemFinish = { + type: "sync-item-finish"; // 数据类型:单项数据同步完成上报 + data: { + id: number; // 数据同步任务的 ID + success: boolean; // 是否同步成功(true 表示成功,false 表示失败) + }; +}; + +export type MobileDatagram = + | PeripheralStatus + | MeasureEvent + | MeasurePoint + | BleList + | SyncProgress + | SyncItemFinish; diff --git a/src/utils/wss.ts b/src/utils/wss.ts index 5d9edd2..3d39c34 100644 --- a/src/utils/wss.ts +++ b/src/utils/wss.ts @@ -1,6 +1,7 @@ import http from "http"; import { Server, WebSocket } from "ws"; import { Datagram } from "../types/wsTypes"; +import { MobileDatagram } from "../types/mobileWsType"; export class WsProxy { public static server: Server; @@ -62,4 +63,16 @@ export class WsProxy { }); } } + + public static sendMobile(data: MobileDatagram, ws?: WebSocket) { + if (ws) { + ws.send(JSON.stringify(data)); + } else { + this.server.clients.forEach(ws => { + if (ws.readyState === ws.OPEN) { + ws.send(JSON.stringify(data)); + } + }); + } + } }