From 6e210cdaada04907dd127ce6db5a67f2e6e11f58 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期五, 17 七月 2026 11:34:09 +0800
Subject: [PATCH] add

---
 src/modules/push/entity/deviceonoff.ts           |   45 +++++++++++
 src/modules/push/service/open.ts                 |  109 +++++++++++++++++++++++----
 src/modules/push/controller/admin/deviceonoff.ts |   36 +++++++++
 src/modules/push/controller/app/open.ts          |    6 
 src/modules/push/service/deviceonoff.ts          |   14 +++
 5 files changed, 190 insertions(+), 20 deletions(-)

diff --git a/src/modules/push/controller/admin/deviceonoff.ts b/src/modules/push/controller/admin/deviceonoff.ts
new file mode 100644
index 0000000..833f934
--- /dev/null
+++ b/src/modules/push/controller/admin/deviceonoff.ts
@@ -0,0 +1,36 @@
+import { Inject } from '@midwayjs/core';
+import { CoolController, BaseController } from '@cool-midway/core';
+import { PushDeviceOnoffEntity } from '../../entity/deviceonoff';
+import { PushDeviceOnoffService } from '../../service/deviceonoff';
+
+/**
+ * 璁惧瀵硅薄绠$悊
+ */
+@CoolController({
+  api: ['add', 'delete', 'update', 'info', 'list', 'page'],
+  entity: PushDeviceOnoffEntity,
+  service: PushDeviceOnoffService,
+  pageQueryOp: {
+    keyWordLikeFields: ['a.deviceId', 'a.subSerial', 'a.deviceName'],
+    fieldEq: [
+      { column: 'a.status', requestParam: 'status' },
+      { column: 'a.msgType', requestParam: 'msgType' },
+      { column: 'a.devType', requestParam: 'devType' }
+    ],
+    where: async (ctx) => {
+      const { startTime, endTime } = ctx.request.body;
+      const condition = [];
+      if (startTime && endTime) {
+        condition.push([
+          'a.occurTime BETWEEN :startTime AND :endTime',
+          { startTime, endTime }
+        ]);
+      }
+      return condition;
+    }
+  }
+})
+export class AdminPushDeviceOnoffController extends BaseController {
+  @Inject()
+  pushDeviceOnoffService: PushDeviceOnoffService;
+}
\ No newline at end of file
diff --git a/src/modules/push/controller/app/open.ts b/src/modules/push/controller/app/open.ts
index 4e03d09..1807959 100644
--- a/src/modules/push/controller/app/open.ts
+++ b/src/modules/push/controller/app/open.ts
@@ -89,12 +89,12 @@
   }
 
 
-  @Post('/cameragps', { summary: '鍘熷杞﹁浇鐩戞帶涓婃姤鎺ュ彛' })
-  async uploadCameraGps(
+  @Post('/yingshiyun', { summary: '钀ょ煶浜慦ebhook涓婃姤鎺ュ彛' })
+  async saveYingshiyunMessage(
     @Body() body: any
   ) {
 
-    const result = await this.pushOpenService.receiveCameraGpsMessage(body);
+    const result = await this.pushOpenService.saveYingshiyunMessage(body);
     //return this.ok(result);
 
     return { "messageId": result }
diff --git a/src/modules/push/entity/deviceonoff.ts b/src/modules/push/entity/deviceonoff.ts
new file mode 100644
index 0000000..6a1c6c0
--- /dev/null
+++ b/src/modules/push/entity/deviceonoff.ts
@@ -0,0 +1,45 @@
+import { BaseEntity } from '../../base/entity/base';
+import { Column, Entity, Index } from 'typeorm';
+
+/**
+ * 缁堢璁惧鐨勪笂绾�/涓嬬嚎鏁版嵁
+ */
+@Entity('t_push_device_onoff')
+export class PushDeviceOnoffEntity extends BaseEntity {
+  @Index()
+  @Column({ comment: '璁惧ID' })
+  deviceId: string;
+
+  @Column({ comment: '閫氶亾鍙�', type: 'int' , nullable: true,default:0 })
+  channelNo: number;
+
+  @Column({ comment: '娑堟伅鍞竴ID' })
+  messageId: string;
+
+  @Column({ comment: '娑堟伅鏃堕棿' })
+  messageTime: Date;
+
+  @Column({ comment: '娑堟伅绫诲瀷', dict: ['ONLINE', 'OFFLINE'], default: 'ONLINE' })
+  msgType: string;
+
+  @Column({ comment: '璁惧绫诲瀷' , nullable: true })
+  devType: string;
+
+  @Column({ comment: '璁惧鍚嶇О', nullable: true })
+  deviceName: string;
+
+  @Column({ comment: '瀛愬簭鍒楀彿' , nullable: true })
+  subSerial: string;
+
+  @Column({ comment: '婧愮ID', nullable: true })
+  dasId: string;
+
+  @Column({ comment: 'NAT鐨処P', nullable: true })
+  natIp: string;
+
+  @Column({ comment: '浜嬩欢鍙戠敓鏃堕棿', nullable: true })
+  occurTime: Date;
+
+  @Column({ comment: '娉ㄥ唽鏃堕棿', nullable: true })
+  regTime: Date;
+}
\ No newline at end of file
diff --git a/src/modules/push/service/deviceonoff.ts b/src/modules/push/service/deviceonoff.ts
new file mode 100644
index 0000000..c505d6e
--- /dev/null
+++ b/src/modules/push/service/deviceonoff.ts
@@ -0,0 +1,14 @@
+import { Provide } from '@midwayjs/core';
+import { BaseService } from '@cool-midway/core';
+import { InjectEntityModel } from '@midwayjs/typeorm';
+import { Repository } from 'typeorm';
+import { PushDeviceOnoffEntity } from '../entity/deviceonoff';
+
+/**
+ * 鐩戞帶璁惧鐨勪笂绾�/涓嬬嚎娑堟伅鏈嶅姟
+ */
+@Provide()
+export class PushDeviceOnoffService extends BaseService {
+  @InjectEntityModel(PushDeviceOnoffEntity)
+  pushDeviceOnoffEntity: Repository<PushDeviceOnoffEntity>;
+}
\ No newline at end of file
diff --git a/src/modules/push/service/open.ts b/src/modules/push/service/open.ts
index 9750669..d126d26 100644
--- a/src/modules/push/service/open.ts
+++ b/src/modules/push/service/open.ts
@@ -7,6 +7,7 @@
 import { PushAuditlogEntity } from '../entity/auditlog';
 import { PushCameraGpsEntity } from '../entity/cameragps';
 import { PushVehicleGpsEntity } from '../entity/vehiclegps';
+import { PushDeviceOnoffEntity } from '../entity/deviceonoff';
 import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
 
 /**
@@ -25,6 +26,10 @@
 
   @InjectEntityModel(PushVehicleGpsEntity)
   pushVehicleGpsEntity: Repository<PushVehicleGpsEntity>;
+
+  @InjectEntityModel(PushDeviceOnoffEntity)
+  pushDeviceOnoffEntity: Repository<PushDeviceOnoffEntity>;
+
 
   @InjectEntityModel(PushAuditlogEntity)
   pushAuditlogEntity: Repository<PushAuditlogEntity>;
@@ -76,34 +81,105 @@
       } else {
         siteWeight.businessId = 'UNKNOWN';
         siteWeight.departmentId = -1;
-        await this.writePushAuditLog("weight",{ "deviceNo": data.deviceNo, "requestContent": data, "errorMessage": "鐢靛瓙绉よ繕鏈垎閰嶅埌鍨冨溇鏀堕泦鐐�." });
+        await this.writePushAuditLog("weight", { "deviceNo": data.deviceNo, "requestContent": data, "errorMessage": "鐢靛瓙绉よ繕鏈垎閰嶅埌鍨冨溇鏀堕泦鐐�." });
       }
 
     } catch (err) {
-      await this.writePushAuditLog("weight",{ "deviceNo": data.deviceNo || "UNKNOW", "requestContent": data, "errorMessage": err });
+      await this.writePushAuditLog("weight", { "deviceNo": data.deviceNo || "UNKNOW", "requestContent": data, "errorMessage": err });
     }
 
   }
 
   /**
-   * 鎺ユ敹GPS娑堟伅骞剁紦瀛�
+   * 鎺ユ敹钀ょ煶浜� 娑堟伅骞剁紦瀛�
    */
-  async receiveCameraGpsMessage(body: any) {
-    const messageId = body.msgSeq || Math.random().toString(36).substring(2);
-    await this.midwayCache.set(`push:cameragps:queue:${messageId}`, JSON.stringify(body), 24 * 3600);
-    this.processCameraGpsAsync(messageId).catch(err => {
+  async saveYingshiyunMessage(body: any) {
+    const messageId = body?.header?.messageId || Math.random().toString(36).substring(2);
+    await this.midwayCache.set(`push:yingshiyun:queue:${messageId}`, JSON.stringify(body), 24 * 3600);
+    this.processYingshiyunAsync(messageId).catch(err => {
       console.error('寮傛澶勭悊GPS娑堟伅澶辫触:', err);
     });
-    return  messageId ;
+    return messageId;
   }
 
   /**
-   * 寮傛瑙f瀽杞﹁浇鐩戞帶瑙嗛鐨勪綅缃暟鎹苟鍏ュ簱
+   * 寮傛瑙f瀽钀ょ煶浜戞秷鎭紝鎸夌収娑堟伅绫诲瀷 鍏ュ簱
    */
-  async processCameraGpsAsync(messageId: string) {
-    const dataStr = await this.midwayCache.get(`push:cameragps:queue:${messageId}`) as string | null;
+  async processYingshiyunAsync(messageId: string) {
+    const dataStr = await this.midwayCache.get(`push:yingshiyun:queue:${messageId}`) as string | null;
     if (!dataStr) return;
     const body = JSON.parse(dataStr);
+
+    const type = body?.header?.type;
+
+    try {
+      switch (type) {
+
+        // 璁惧涓婁笅绾�
+        case 'ys.onoffline': {
+          await this.pushDeviceOnoffEntity.save({
+            deviceId:body.header.deviceId,
+            channelNo: body.header.channelNo,
+            messageId: body.header.messageId,
+            messageTime: new Date(body.header.messageTime),
+            msgType: body.body.msgType,
+            devType: body.body.devType,
+            deviceName: body.body.deviceName,
+            subSerial: body.body.subSerial,
+            dasId: body.body.dasId,
+            natIp: body.body.natIp,
+            occurTime: body.body.occurTime,
+            regTime: body.body.regTime
+          });
+          break;
+        }
+
+        // 钀ょ煶鍛婅
+        /*
+        case 'ys.alarm': {
+          await this.pushAlarmRepo.save({
+            messageId,
+            raw: JSON.stringify(body),
+            createTime: new Date(),
+          });
+          break;
+        }
+          */
+
+        // 娴峰悍 ISAPI
+        //case 'ys.open.isapi': {
+          //processCameraGpsAsync(body)
+          //await this.pushIsapiRepo.save({
+          //  messageId,
+          //  raw: JSON.stringify(body),
+          //  createTime: new Date(),
+          //});
+          //break;
+        //}
+
+        default:
+          console.warn('Unknown yingshi webhook type:', type);
+      }
+    } catch (err) {
+      await this.writePushAuditLog(type || 'unknown', {
+        deviceNo: body?.sn || 'UNKNOWN',
+        requestContent: body,
+        errorMessage: err,
+      });
+    }
+
+    // 涓嶇鎴愬姛涓庡惁锛屽垹闄ょ紦瀛樹腑鐨勪换鍔¢槦鍒�
+    await this.midwayCache.del(`push:yingshiyun:queue:${messageId}`);
+
+}
+
+
+
+  /**
+   * 寮傛瑙f瀽杞﹁浇鐩戞帶鐨凣PS鏁版嵁锛屽瓨鍌ㄥ苟娣诲姞涓氬姟琛�
+   */
+  async processCameraGpsAsync(body: any) {
+
 
     try {
       let vehicleNo = '';
@@ -155,21 +231,20 @@
           });
 
         } else {
-          await this.writePushAuditLog("camera_gps",{ "deviceNo": body.sn, "requestContent": body, "errorMessage": "杞﹁浇鐩戞帶杩樻湭鍒嗛厤鍒拌溅杈�" });
+          await this.writePushAuditLog("camera_gps", { "deviceNo": body.sn, "requestContent": body, "errorMessage": "杞﹁浇鐩戞帶杩樻湭鍒嗛厤鍒拌溅杈�" });
         }
       } else {
-        await this.writePushAuditLog("camera_gps",{ "deviceNo": "UNKOWN", "requestContent": body, "errorMessage": "鏈寘鍚澶囧彿SN" });
+        await this.writePushAuditLog("camera_gps", { "deviceNo": "UNKOWN", "requestContent": body, "errorMessage": "鏈寘鍚澶囧彿SN" });
       }
 
-      await this.midwayCache.del(`push:gps:queue:${messageId}`);
-
     } catch (err: any) {
-      await this.writePushAuditLog("camera_gps",{ "deviceNo": body.sn || "UNKNOW", "requestContent": body, "errorMessage": err });
+
+      await this.writePushAuditLog("camera_gps", { "deviceNo": body.sn || "UNKNOW", "requestContent": body, "errorMessage": err });
 
     }
   }
 
-  async writePushAuditLog(pushType:string,data: any) {
+  async writePushAuditLog(pushType: string, data: any) {
     let isSuccess = true;
     let errorMsg = '';
     try {

--
Gitblit v1.9.1