"use strict"; const { mapItemsToUploadData } = require("./field-mapper"); const { MqttUploader } = require("./mqtt-uploader"); const { AliyunUploader } = require("./aliyun-uploader"); class UploadManager { constructor({ mqttConfig, aliyunConfig, logger }) { this.logger = logger; this.mqtt = new MqttUploader({ config: mqttConfig, logger }); this.aliyun = new AliyunUploader({ config: aliyunConfig, logger }); this._lastUpload = null; // { deviceNo, timestamp, mqttResult, aliyunResult } } start() { this.mqtt.start(); this.aliyun.start(); this.logger.upload("system", "start", "", "上传模块已启动"); } getStatus() { return { mqtt: this.mqtt.getStatus(), aliyun: this.aliyun.getStatus(), lastUpload: this._lastUpload, }; } stop() { this.mqtt.stop(); this.aliyun.stop(); } async upload({ serialNumber, ip, items }) { const deviceNo = String(serialNumber || "").trim(); if (!deviceNo) { this.logger.upload("system", "validate", "", "设备序列号为空,跳过上传"); return { ok: false, deviceNo: null, code: "DEVICE_NO_MISSING", reason: "serialNumber is required" }; } // 将 items [{id, value}] 映射为阿里云字段格式 const deviceData = mapItemsToUploadData(items); // suedtime: yyyy-MM-dd HH:mm:ss const now = new Date(); const suedtime = now.getFullYear() + "-" + String(now.getMonth() + 1).padStart(2, "0") + "-" + String(now.getDate()).padStart(2, "0") + " " + String(now.getHours()).padStart(2, "0") + ":" + String(now.getMinutes()).padStart(2, "0") + ":" + String(now.getSeconds()).padStart(2, "0"); // 构建上传 payload const payload = { msgType: "device_data", clientCode: this.mqtt.config.clientCode || null, n: deviceNo, deviceType: "GC-110N", suedtime, IPAddress: ip || "", ...deviceData, timestamp: now.toISOString(), }; this.logger.upload("system", "upload", deviceNo, `开始上传 IP=${ip}`); // 顺序执行:先 MQTT 再阿里云(互不影响) const mqttResult = await this.mqtt.publish(deviceNo, payload); const aliyunResult = await this.aliyun.upload(deviceNo, payload); const result = { ok: (mqttResult.ok || !mqttResult.enabled) && (aliyunResult.ok || !aliyunResult.enabled), deviceNo, mqtt: mqttResult, aliyun: aliyunResult, }; this._lastUpload = { deviceNo, timestamp: now.toISOString(), mqttOk: mqttResult.ok, aliyunOk: aliyunResult.ok, }; return result; } } module.exports = { UploadManager };