import { InjectClient, Provide, Inject } from '@midwayjs/core';
|
import { BaseService } from '@cool-midway/core';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { Repository } from 'typeorm';
|
import { PushWeightEntity } from '../entity/weight';
|
import { PushSiteweightEntity } from '../entity/siteweight';
|
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';
|
|
/**
|
* 开放接口业务逻辑服务
|
*/
|
@Provide()
|
export class PushOpenService extends BaseService {
|
@InjectEntityModel(PushWeightEntity)
|
pushWeightEntity: Repository<PushWeightEntity>;
|
|
@InjectEntityModel(PushSiteweightEntity)
|
pushSiteweightEntity: Repository<PushSiteweightEntity>;
|
|
@InjectEntityModel(PushCameraGpsEntity)
|
pushCameraGpsEntity: Repository<PushCameraGpsEntity>;
|
|
@InjectEntityModel(PushVehicleGpsEntity)
|
pushVehicleGpsEntity: Repository<PushVehicleGpsEntity>;
|
|
@InjectEntityModel(PushDeviceOnoffEntity)
|
pushDeviceOnoffEntity: Repository<PushDeviceOnoffEntity>;
|
|
|
@InjectEntityModel(PushAuditlogEntity)
|
pushAuditlogEntity: Repository<PushAuditlogEntity>;
|
|
|
@InjectClient(CachingFactory, 'default')
|
midwayCache: MidwayCache;
|
|
/**
|
* 上报称重数据核心业务
|
*/
|
async reportWeight(data: any) {
|
const logTime = new Date();
|
|
try {
|
// 1. 保存原始称重数据
|
const rawWeight = new PushWeightEntity();
|
rawWeight.deviceNo = data.deviceNo;
|
rawWeight.uploadTime = data.uploadTime
|
? new Date(data.uploadTime)
|
: new Date();
|
rawWeight.garbageType = data.garbageType;
|
rawWeight.weight = data.garbageWeight || 0;
|
rawWeight.extraData =
|
typeof data.extraData === 'object'
|
? JSON.stringify(data.extraData)
|
: data.extraData;
|
await this.pushWeightEntity.save(rawWeight);
|
|
// 2. 模拟关联基础数据模块查询获取商户信息并写入业务称重表
|
const siteWeight = new PushSiteweightEntity();
|
siteWeight.deviceNo = data.deviceNo;
|
siteWeight.uploadTime = rawWeight.uploadTime;
|
siteWeight.garbageType = data.garbageType;
|
siteWeight.weight = data.garbageWeight || 0;
|
siteWeight.extraData = rawWeight.extraData;
|
|
// 动态查询设备基础数据关联信息
|
const iotDevices = await this.nativeQuery(
|
'SELECT businessId, departmentId FROM t_basicdata_iot WHERE iotCode = ? LIMIT 1',
|
[data.deviceNo],
|
);
|
|
if (iotDevices && iotDevices.length > 0) {
|
siteWeight.businessId = iotDevices[0].businessId;
|
siteWeight.departmentId = iotDevices[0].departmentId;
|
await this.pushSiteweightEntity.save(siteWeight);
|
|
} else {
|
siteWeight.businessId = 'UNKNOWN';
|
siteWeight.departmentId = -1;
|
await this.writePushAuditLog("weight", { "deviceNo": data.deviceNo, "requestContent": data, "errorMessage": "电子秤还未分配到垃圾收集点." });
|
}
|
|
} catch (err) {
|
await this.writePushAuditLog("weight", { "deviceNo": data.deviceNo || "UNKNOW", "requestContent": data, "errorMessage": 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;
|
}
|
|
/**
|
* 异步解析萤石云消息,按照消息类型 入库
|
*/
|
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}`);
|
|
}
|
|
|
|
/**
|
* 异步解析车载监控的GPS数据,存储并添加业务表
|
*/
|
async processCameraGpsAsync(body: any) {
|
|
|
try {
|
let vehicleNo = '';
|
if (body.sn) {
|
|
const gpsData = body.data || {};
|
const statusVal = gpsData.status === 'A' ? 'A' : 'B';
|
|
await this.pushCameraGpsEntity.save({
|
sn: body.sn,
|
msgSeq: body.msgSeq,
|
createDate: body.createDate && !isNaN(Number(body.createDate))
|
? new Date(Number(body.createDate))
|
: new Date(),
|
gpsTime: gpsData.gpsTime
|
? new Date(gpsData.gpsTime.replace(' ', 'T'))
|
: new Date(),
|
longitude: gpsData.longitude,
|
latitude: gpsData.latitude,
|
speed: gpsData.speed,
|
direction: gpsData.direction,
|
elevation: gpsData.elevation,
|
status: statusVal,
|
});
|
|
const iotDevice: any[] = await this.nativeQuery(
|
'SELECT businessId FROM t_basicdata_iot WHERE iotCode = ? LIMIT 1',
|
[body.sn]
|
);
|
if (iotDevice && iotDevice.length > 0 && iotDevice[0].businessId) {
|
vehicleNo = `vehicle_${iotDevice[0].businessId}`;
|
|
await this.pushVehicleGpsEntity.save({
|
sn: body.sn,
|
msgSeq: body.msgSeq,
|
createDate: body.createDate && !isNaN(Number(body.createDate))
|
? new Date(Number(body.createDate))
|
: new Date(),
|
vehicleNo,
|
gpsTime: gpsData.gpsTime
|
? new Date(gpsData.gpsTime.replace(' ', 'T'))
|
: new Date(),
|
longitude: gpsData.longitude,
|
latitude: gpsData.latitude,
|
speed: gpsData.speed,
|
direction: gpsData.direction,
|
elevation: gpsData.elevation,
|
status: statusVal,
|
});
|
|
} else {
|
await this.writePushAuditLog("camera_gps", { "deviceNo": body.sn, "requestContent": body, "errorMessage": "车载监控还未分配到车辆" });
|
}
|
} else {
|
await this.writePushAuditLog("camera_gps", { "deviceNo": "UNKOWN", "requestContent": body, "errorMessage": "未包含设备号SN" });
|
}
|
|
} catch (err: any) {
|
|
await this.writePushAuditLog("camera_gps", { "deviceNo": body.sn || "UNKNOW", "requestContent": body, "errorMessage": err });
|
|
}
|
}
|
|
async writePushAuditLog(pushType: string, data: any) {
|
let isSuccess = true;
|
let errorMsg = '';
|
try {
|
const auditLog = new PushAuditlogEntity();
|
auditLog.logTime = new Date();
|
auditLog.pushType = pushType;
|
auditLog.deviceNo = data.deviceNo || 'unknown-device';
|
auditLog.requestContent = JSON.stringify(data.requestContent);
|
auditLog.errorMessage = data.errorMessage || 'unknown-erroe';
|
await this.pushAuditlogEntity.save(auditLog);
|
|
} catch (err) {
|
isSuccess = false;
|
}
|
|
}
|
|
|
|
|
|
}
|