20260731:平台对接优化,JSON解析
This commit is contained in:
parent
1b5536fc8c
commit
84f681e9d9
@ -15,6 +15,7 @@ import com.fastbee.iot.domain.Device;
|
|||||||
import com.fastbee.iot.model.ThingsModels.ValueItem;
|
import com.fastbee.iot.model.ThingsModels.ValueItem;
|
||||||
import com.fastbee.iot.platform.domain.*;
|
import com.fastbee.iot.platform.domain.*;
|
||||||
import com.fastbee.iot.platform.flow.FlowContext;
|
import com.fastbee.iot.platform.flow.FlowContext;
|
||||||
|
import com.fastbee.iot.platform.model.json.*;
|
||||||
import com.fastbee.iot.platform.flow.PlatformFlowExecutor;
|
import com.fastbee.iot.platform.flow.PlatformFlowExecutor;
|
||||||
import com.fastbee.iot.platform.mapper.PlatformFlowMapper;
|
import com.fastbee.iot.platform.mapper.PlatformFlowMapper;
|
||||||
import com.fastbee.iot.platform.mapper.PlatformInterfaceMapper;
|
import com.fastbee.iot.platform.mapper.PlatformInterfaceMapper;
|
||||||
@ -94,8 +95,9 @@ public class DcpPlatformAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String sensorType = mapping.getSensorType();
|
String sensorType = mapping.getSensorType();
|
||||||
PlatformInterface pushInterface = loadPushInterface(mapping);
|
PlatformInterface pushInterface = interfaceMapper.selectById(mapping.getPushInterfaceId());
|
||||||
JSONArray requestSchema = loadRequestSchema(pushInterface);
|
|
||||||
|
List<RequestSchemaField> requestSchema = pushInterface.getRequestSchemaParsed();
|
||||||
String interfaceCode = resolveInterfaceCode(sensorType, pushInterface);
|
String interfaceCode = resolveInterfaceCode(sensorType, pushInterface);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -127,8 +129,8 @@ public class DcpPlatformAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String sensorType = mapping.getSensorType();
|
String sensorType = mapping.getSensorType();
|
||||||
PlatformInterface pushInterface = loadPushInterface(mapping);
|
PlatformInterface pushInterface = interfaceMapper.selectById(mapping.getPushInterfaceId());
|
||||||
JSONArray requestSchema = loadRequestSchema(pushInterface);
|
List<RequestSchemaField> requestSchema = pushInterface.getRequestSchemaParsed();
|
||||||
String interfaceCode = resolveInterfaceCode(sensorType, pushInterface);
|
String interfaceCode = resolveInterfaceCode(sensorType, pushInterface);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -151,38 +153,33 @@ public class DcpPlatformAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray fieldMappings = parseJsonArray(mapping.getFieldMapping());
|
List<FieldMappingItem> fieldMappings = mapping.getFieldMappingParsed();
|
||||||
String baseUrl = platform.getBaseUrl() + pushPath;
|
String baseUrl = platform.getBaseUrl() + pushPath;
|
||||||
|
|
||||||
// 解析 extra_mapping 中的 itemFieldMappings 和 reportIntervalSec
|
// 解析 extra_mapping 中的 itemFieldMappings 和 reportIntervalSec
|
||||||
int reportIntervalSec = 300;
|
int reportIntervalSec = 300;
|
||||||
JSONArray itemFieldMappings = null;
|
List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings = null;
|
||||||
String fieldName = resolveArrayFieldName(requestSchema);
|
String fieldName = resolveArrayFieldName(requestSchema);
|
||||||
JSONObject extra = null;
|
ExtraMappingConfig extra = mapping.getExtraMappingParsed();
|
||||||
if (StringUtils.hasText(mapping.getExtraMapping())) {
|
if (extra != null) {
|
||||||
extra = JSON.parseObject(mapping.getExtraMapping());
|
reportIntervalSec = extra.getReportIntervalSec() != null ? extra.getReportIntervalSec() : 300;
|
||||||
reportIntervalSec = extra.getIntValue("reportIntervalSec", 300);
|
itemFieldMappings = extra.getItemFieldMappings();
|
||||||
itemFieldMappings = extra.getJSONArray("itemFieldMappings");
|
if (StringUtils.hasText(extra.getFieldName())) {
|
||||||
if (StringUtils.hasText(extra.getString("fieldName"))) {
|
fieldName = extra.getFieldName();
|
||||||
fieldName = extra.getString("fieldName");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JSONObject arrayFieldSchema = findArrayFieldSchema(requestSchema, fieldName);
|
RequestSchemaField arrayFieldSchema = findArrayFieldSchema(requestSchema, fieldName);
|
||||||
String arrayMode = resolveArrayMode(arrayFieldSchema, extra);
|
String arrayMode = resolveArrayMode(arrayFieldSchema, extra);
|
||||||
|
|
||||||
// 从 onboard_config 取 sensorId
|
// 从 onboard_config 取 sensorId
|
||||||
String sensorId = reportSerialNumber;
|
String sensorId = reportSerialNumber;
|
||||||
if (StringUtils.hasText(subMapping.getOnboardConfig())) {
|
OnboardConfig onboardCfg = subMapping.getOnboardConfigParsed();
|
||||||
JSONObject config = JSON.parseObject(subMapping.getOnboardConfig());
|
if (onboardCfg != null && StringUtils.hasText(onboardCfg.getSensorId())) {
|
||||||
String cfgSensorId = config.getString("sensorId");
|
sensorId = onboardCfg.getSensorId();
|
||||||
if (StringUtils.hasText(cfgSensorId)) {
|
|
||||||
sensorId = cfgSensorId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建当前设备的数据项
|
// 构建当前设备的数据项
|
||||||
JSONObject currentItem = buildArrayItem(
|
JSONObject currentItem = buildArrayItem(userAuth, mapping, requestSchema, reportData, fieldName, itemFieldMappings, sensorId);
|
||||||
platform, mapping, requestSchema, reportData, fieldName, itemFieldMappings, sensorId);
|
|
||||||
if (currentItem == null || currentItem.isEmpty()) {
|
if (currentItem == null || currentItem.isEmpty()) {
|
||||||
log.warn("[DCP] 网关子设备 {} 数据映射为空,跳过推送", reportSerialNumber);
|
log.warn("[DCP] 网关子设备 {} 数据映射为空,跳过推送", reportSerialNumber);
|
||||||
return;
|
return;
|
||||||
@ -261,33 +258,32 @@ public class DcpPlatformAdapter {
|
|||||||
/**
|
/**
|
||||||
* 请求 schema 是否包含数组字段
|
* 请求 schema 是否包含数组字段
|
||||||
*/
|
*/
|
||||||
private boolean hasArrayField(JSONArray requestSchema) {
|
private boolean hasArrayField(List<RequestSchemaField> requestSchema) {
|
||||||
if (requestSchema == null || requestSchema.isEmpty()) {
|
if (requestSchema == null || requestSchema.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < requestSchema.size(); i++) {
|
for (RequestSchemaField field : requestSchema) {
|
||||||
JSONObject field = requestSchema.getJSONObject(i);
|
if ("array".equalsIgnoreCase(field.getType())) {
|
||||||
if ("array".equalsIgnoreCase(field.getString("type"))) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveArrayFieldName(JSONArray requestSchema) {
|
private String resolveArrayFieldName(List<RequestSchemaField> requestSchema) {
|
||||||
JSONObject firstArrayField = findFirstArrayFieldSchema(requestSchema);
|
RequestSchemaField firstArrayField = findFirstArrayFieldSchema(requestSchema);
|
||||||
if (firstArrayField != null && StringUtils.hasText(firstArrayField.getString("name"))) {
|
if (firstArrayField != null && StringUtils.hasText(firstArrayField.getName())) {
|
||||||
return firstArrayField.getString("name");
|
return firstArrayField.getName();
|
||||||
}
|
}
|
||||||
return "sensorData";
|
return "sensorData";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveArrayMode(JSONObject arrayFieldSchema, JSONObject extra) {
|
private String resolveArrayMode(RequestSchemaField arrayFieldSchema, ExtraMappingConfig extra) {
|
||||||
String mode = null;
|
String mode = null;
|
||||||
if (extra != null && StringUtils.hasText(extra.getString("arrayMode"))) {
|
if (extra != null && StringUtils.hasText(extra.getArrayMode())) {
|
||||||
mode = extra.getString("arrayMode");
|
mode = extra.getArrayMode();
|
||||||
} else if (arrayFieldSchema != null && StringUtils.hasText(arrayFieldSchema.getString("arrayMode"))) {
|
} else if (arrayFieldSchema != null && StringUtils.hasText(arrayFieldSchema.getArrayMode())) {
|
||||||
mode = arrayFieldSchema.getString("arrayMode");
|
mode = arrayFieldSchema.getArrayMode();
|
||||||
}
|
}
|
||||||
if (!StringUtils.hasText(mode)) {
|
if (!StringUtils.hasText(mode)) {
|
||||||
return ARRAY_MODE_REFERENCE_PAIR;
|
return ARRAY_MODE_REFERENCE_PAIR;
|
||||||
@ -310,14 +306,9 @@ public class DcpPlatformAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 兼容历史配置:从 onboard_config 取基准点原始序列号
|
// 兼容历史配置:从 onboard_config 取基准点原始序列号
|
||||||
if (StringUtils.hasText(subMapping.getOnboardConfig())) {
|
OnboardConfig config = subMapping.getOnboardConfigParsed();
|
||||||
try {
|
if (config != null && StringUtils.hasText(config.getRefSerialNumber())) {
|
||||||
JSONObject config = JSON.parseObject(subMapping.getOnboardConfig());
|
return config.getRefSerialNumber();
|
||||||
String refSensorId = config.getString("refSerialNumber");
|
|
||||||
if (StringUtils.hasText(refSensorId)) {
|
|
||||||
return refSensorId;
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
}
|
}
|
||||||
// 回退:用网关本身的序列号
|
// 回退:用网关本身的序列号
|
||||||
return mapping.getSerialNumber();
|
return mapping.getSerialNumber();
|
||||||
@ -385,7 +376,7 @@ public class DcpPlatformAdapter {
|
|||||||
|
|
||||||
private void handleNormalPush(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
private void handleNormalPush(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
String reportSerialNumber, String payload, String pushPath,
|
String reportSerialNumber, String payload, String pushPath,
|
||||||
String interfaceCode, JSONArray requestSchema) {
|
String interfaceCode, List<RequestSchemaField> requestSchema) {
|
||||||
Object body = buildPushBody(platform, userAuth, mapping, payload, requestSchema);
|
Object body = buildPushBody(platform, userAuth, mapping, payload, requestSchema);
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
log.warn("[DCP] 设备 {} 字段映射结果为空,跳过推送", mapping.getSerialNumber());
|
log.warn("[DCP] 设备 {} 字段映射结果为空,跳过推送", mapping.getSerialNumber());
|
||||||
@ -397,7 +388,7 @@ public class DcpPlatformAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object buildPushBody(PlatformInstance platform, PlatformUserAuth userAuth,PlatformDeviceMapping mapping,
|
private Object buildPushBody(PlatformInstance platform, PlatformUserAuth userAuth,PlatformDeviceMapping mapping,
|
||||||
String payload, JSONArray requestSchema) {
|
String payload, List<RequestSchemaField> requestSchema) {
|
||||||
if (!StringUtils.hasText(payload)) {
|
if (!StringUtils.hasText(payload)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -406,7 +397,7 @@ public class DcpPlatformAdapter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray fieldMappings = parseJsonArray(mapping.getFieldMapping());
|
List<FieldMappingItem> fieldMappings = mapping.getFieldMappingParsed();
|
||||||
if (requestSchema == null || requestSchema.isEmpty()) {
|
if (requestSchema == null || requestSchema.isEmpty()) {
|
||||||
return buildLegacyPushBody(mapping.getPlatformDeviceId(), fieldMappings, reportData);
|
return buildLegacyPushBody(mapping.getPlatformDeviceId(), fieldMappings, reportData);
|
||||||
}
|
}
|
||||||
@ -421,7 +412,7 @@ public class DcpPlatformAdapter {
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object buildLegacyPushBody(String platformDeviceId, JSONArray fieldMappings, JSONObject reportData) {
|
private Object buildLegacyPushBody(String platformDeviceId, List<FieldMappingItem> fieldMappings, JSONObject reportData) {
|
||||||
if (fieldMappings == null || fieldMappings.isEmpty()) {
|
if (fieldMappings == null || fieldMappings.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -430,10 +421,9 @@ public class DcpPlatformAdapter {
|
|||||||
dcpData.put("deviceId", platformDeviceId);
|
dcpData.put("deviceId", platformDeviceId);
|
||||||
dcpData.put("epoch", nowIsoTimestamp());
|
dcpData.put("epoch", nowIsoTimestamp());
|
||||||
|
|
||||||
for (int i = 0; i < fieldMappings.size(); i++) {
|
for (FieldMappingItem fm : fieldMappings) {
|
||||||
JSONObject fm = fieldMappings.getJSONObject(i);
|
String identifier = fm.getIdentifier();
|
||||||
String identifier = fm.getString("identifier");
|
String platformField = fm.getPlatformField();
|
||||||
String platformField = fm.getString("platformField");
|
|
||||||
if (!StringUtils.hasText(identifier) || !StringUtils.hasText(platformField)) {
|
if (!StringUtils.hasText(identifier) || !StringUtils.hasText(platformField)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -459,7 +449,7 @@ public class DcpPlatformAdapter {
|
|||||||
*/
|
*/
|
||||||
private void handleSubDeviceSimplePush(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
private void handleSubDeviceSimplePush(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
PlatformDeviceSubMapping subMapping, String reportSerialNumber, String payload,
|
PlatformDeviceSubMapping subMapping, String reportSerialNumber, String payload,
|
||||||
String pushPath, String interfaceCode, JSONArray requestSchema) {
|
String pushPath, String interfaceCode, List<RequestSchemaField> requestSchema) {
|
||||||
Object body = buildSubDevicePushBody(platform, userAuth, mapping, subMapping, payload, requestSchema);
|
Object body = buildSubDevicePushBody(platform, userAuth, mapping, subMapping, payload, requestSchema);
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
log.warn("[DCP] 网关子设备 {} 字段映射结果为空,跳过推送", reportSerialNumber);
|
log.warn("[DCP] 网关子设备 {} 字段映射结果为空,跳过推送", reportSerialNumber);
|
||||||
@ -477,7 +467,7 @@ public class DcpPlatformAdapter {
|
|||||||
*/
|
*/
|
||||||
private Object buildSubDevicePushBody(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
private Object buildSubDevicePushBody(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
PlatformDeviceSubMapping subMapping, String payload,
|
PlatformDeviceSubMapping subMapping, String payload,
|
||||||
JSONArray requestSchema) {
|
List<RequestSchemaField> requestSchema) {
|
||||||
JSONObject reportData = parsePayloadToMap(payload);
|
JSONObject reportData = parsePayloadToMap(payload);
|
||||||
if (reportData == null || reportData.isEmpty()) {
|
if (reportData == null || reportData.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
@ -487,7 +477,7 @@ public class DcpPlatformAdapter {
|
|||||||
String platformDeviceId = StringUtils.hasText(subMapping.getPlatformDeviceId())
|
String platformDeviceId = StringUtils.hasText(subMapping.getPlatformDeviceId())
|
||||||
? subMapping.getPlatformDeviceId() : mapping.getPlatformDeviceId();
|
? subMapping.getPlatformDeviceId() : mapping.getPlatformDeviceId();
|
||||||
|
|
||||||
JSONArray fieldMappings = parseJsonArray(mapping.getFieldMapping());
|
List<FieldMappingItem> fieldMappings = mapping.getFieldMappingParsed();
|
||||||
if (requestSchema == null || requestSchema.isEmpty()) {
|
if (requestSchema == null || requestSchema.isEmpty()) {
|
||||||
return buildLegacyPushBody(platformDeviceId, fieldMappings, reportData);
|
return buildLegacyPushBody(platformDeviceId, fieldMappings, reportData);
|
||||||
}
|
}
|
||||||
@ -528,18 +518,17 @@ public class DcpPlatformAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject buildObjectBySchema(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
private JSONObject buildObjectBySchema(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
JSONArray requestSchema, JSONObject reportData,
|
List<RequestSchemaField> requestSchema, JSONObject reportData,
|
||||||
JSONArray fieldMappings) {
|
List<FieldMappingItem> fieldMappings) {
|
||||||
JSONObject body = new JSONObject();
|
JSONObject body = new JSONObject();
|
||||||
if (requestSchema == null || requestSchema.isEmpty()) {
|
if (requestSchema == null || requestSchema.isEmpty()) {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < requestSchema.size(); i++) {
|
for (RequestSchemaField schemaField : requestSchema) {
|
||||||
JSONObject schemaField = requestSchema.getJSONObject(i);
|
if ("array".equalsIgnoreCase(schemaField.getType())) {
|
||||||
if ("array".equalsIgnoreCase(schemaField.getString("type"))) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String fieldName = schemaField.getString("name");
|
String fieldName = schemaField.getName();
|
||||||
if (!StringUtils.hasText(fieldName)) {
|
if (!StringUtils.hasText(fieldName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -552,15 +541,15 @@ public class DcpPlatformAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveSchemaFieldValue(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
private Object resolveSchemaFieldValue(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
JSONObject schemaField, JSONObject reportData,
|
RequestSchemaField schemaField, JSONObject reportData,
|
||||||
JSONArray fieldMappings) {
|
List<FieldMappingItem> fieldMappings) {
|
||||||
String source = schemaField.getString("source");
|
String source = schemaField.getSource();
|
||||||
String fieldName = schemaField.getString("name");
|
String fieldName = schemaField.getName();
|
||||||
String configField = schemaField.getString("field");
|
String configField = schemaField.getField();
|
||||||
String contextKey = schemaField.getString("contextKey");
|
String contextKey = schemaField.getContextKey();
|
||||||
|
|
||||||
if ("fixed".equals(source)) {
|
if ("fixed".equals(source)) {
|
||||||
return schemaField.get("value");
|
return schemaField.getValue();
|
||||||
}
|
}
|
||||||
if ("device".equals(source)) {
|
if ("device".equals(source)) {
|
||||||
return resolveDeviceField(mapping, configField);
|
return resolveDeviceField(mapping, configField);
|
||||||
@ -590,11 +579,11 @@ public class DcpPlatformAdapter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject buildArrayItem(PlatformInstance platform, PlatformDeviceMapping mapping,
|
private JSONObject buildArrayItem(PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
JSONArray requestSchema, JSONObject reportData, String fieldName,
|
List<RequestSchemaField> requestSchema, JSONObject reportData, String fieldName,
|
||||||
JSONArray itemFieldMappings, String subDeviceId) {
|
List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings, String subDeviceId) {
|
||||||
JSONObject arrayFieldSchema = findArrayFieldSchema(requestSchema, fieldName);
|
RequestSchemaField arrayFieldSchema = findArrayFieldSchema(requestSchema, fieldName);
|
||||||
JSONArray itemSchema = arrayFieldSchema == null ? null : arrayFieldSchema.getJSONArray("itemSchema");
|
List<RequestSchemaField> itemSchema = arrayFieldSchema == null ? null : arrayFieldSchema.getItemSchema();
|
||||||
if (itemSchema == null || itemSchema.isEmpty()) {
|
if (itemSchema == null || itemSchema.isEmpty()) {
|
||||||
return buildLegacyArrayItem(reportData, itemFieldMappings, subDeviceId);
|
return buildLegacyArrayItem(reportData, itemFieldMappings, subDeviceId);
|
||||||
}
|
}
|
||||||
@ -602,20 +591,18 @@ public class DcpPlatformAdapter {
|
|||||||
JSONObject item = new JSONObject();
|
JSONObject item = new JSONObject();
|
||||||
boolean hasThingsModelField = false;
|
boolean hasThingsModelField = false;
|
||||||
boolean hasThingsModelValue = false;
|
boolean hasThingsModelValue = false;
|
||||||
for (int i = 0; i < itemSchema.size(); i++) {
|
for (RequestSchemaField schemaField : itemSchema) {
|
||||||
JSONObject schemaField = itemSchema.getJSONObject(i);
|
String itemFieldName = schemaField.getName();
|
||||||
String itemFieldName = schemaField.getString("name");
|
|
||||||
if (!StringUtils.hasText(itemFieldName)) {
|
if (!StringUtils.hasText(itemFieldName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isThingsModelSource(schemaField.getString("source"))) {
|
if (isThingsModelSource(schemaField.getSource())) {
|
||||||
hasThingsModelField = true;
|
hasThingsModelField = true;
|
||||||
}
|
}
|
||||||
Object value = resolveArrayItemFieldValue(
|
Object value = resolveArrayItemFieldValue(userAuth, mapping, schemaField, reportData, itemFieldMappings, subDeviceId);
|
||||||
platform, mapping, schemaField, reportData, itemFieldMappings, subDeviceId);
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
item.put(itemFieldName, value);
|
item.put(itemFieldName, value);
|
||||||
if (isThingsModelSource(schemaField.getString("source"))) {
|
if (isThingsModelSource(schemaField.getSource())) {
|
||||||
hasThingsModelValue = true;
|
hasThingsModelValue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -626,51 +613,51 @@ public class DcpPlatformAdapter {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject buildLegacyArrayItem(JSONObject reportData, JSONArray itemFieldMappings, String subDeviceId) {
|
private JSONObject buildLegacyArrayItem(JSONObject reportData, List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings, String subDeviceId) {
|
||||||
Map<String, Object> itemValues = extractItemValues(reportData, itemFieldMappings);
|
Map<String, Object> itemValues = extractItemValues(reportData, itemFieldMappings);
|
||||||
Object height = itemValues.get("height");
|
Object height = itemValues.get("height");
|
||||||
Object temperature = itemValues.get("temperature");
|
Object temperature = itemValues.get("temperature");
|
||||||
if (height == null && temperature == null) {
|
if (height == null && temperature == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String heightIdentifier = findIdentifier(itemFieldMappings, "height");
|
String heightIdentifier = findIdentifierFromItem(itemFieldMappings, "height");
|
||||||
String epochIdentifier = StringUtils.hasText(heightIdentifier)
|
String epochIdentifier = StringUtils.hasText(heightIdentifier)
|
||||||
? heightIdentifier : findFirstIdentifier(itemFieldMappings);
|
? heightIdentifier : findFirstIdentifierFromItem(itemFieldMappings);
|
||||||
Object epoch = resolveEpoch(reportData, epochIdentifier);
|
Object epoch = resolveEpoch(reportData, epochIdentifier);
|
||||||
return buildSensorDataItem(epoch, height, temperature, subDeviceId);
|
return buildSensorDataItem(epoch, height, temperature, subDeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveArrayItemFieldValue(PlatformInstance platform, PlatformDeviceMapping mapping,
|
private Object resolveArrayItemFieldValue(PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
JSONObject schemaField, JSONObject reportData,
|
RequestSchemaField schemaField, JSONObject reportData,
|
||||||
JSONArray itemFieldMappings, String subDeviceId) {
|
List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings, String subDeviceId) {
|
||||||
String source = schemaField.getString("source");
|
String source = schemaField.getSource();
|
||||||
String fieldName = schemaField.getString("name");
|
String fieldName = schemaField.getName();
|
||||||
if ("fixed".equals(source)) {
|
if ("fixed".equals(source)) {
|
||||||
return schemaField.get("value");
|
return schemaField.getValue();
|
||||||
}
|
}
|
||||||
if ("subDeviceId".equals(source)) {
|
if ("subDeviceId".equals(source)) {
|
||||||
return subDeviceId;
|
return subDeviceId;
|
||||||
}
|
}
|
||||||
if ("ts".equals(source)) {
|
if ("ts".equals(source)) {
|
||||||
return resolveTimestampValue(reportData, itemFieldMappings, fieldName, schemaField.getString("contextKey"));
|
return resolveTimestampValueFromItem(reportData, itemFieldMappings, fieldName, schemaField.getContextKey());
|
||||||
}
|
}
|
||||||
if ("device".equals(source)) {
|
if ("device".equals(source)) {
|
||||||
return resolveDeviceField(mapping, schemaField.getString("field"));
|
return resolveDeviceField(mapping, schemaField.getField());
|
||||||
}
|
}
|
||||||
if ("auth".equals(source)) {
|
if ("auth".equals(source)) {
|
||||||
return resolveJsonField(platform.getAuthConfig(), schemaField.getString("field"));
|
return resolveJsonField(userAuth.getAuthConfig(), schemaField.getField());
|
||||||
}
|
}
|
||||||
if ("extra".equals(source)) {
|
if ("extra".equals(source)) {
|
||||||
return resolveJsonField(platform.getExtraConfig(), schemaField.getString("field"));
|
return resolveJsonField(userAuth.getExtraConfig(), schemaField.getField());
|
||||||
}
|
}
|
||||||
if (isThingsModelSource(source)) {
|
if (isThingsModelSource(source)) {
|
||||||
String identifier = findIdentifier(itemFieldMappings, fieldName);
|
String identifier = findIdentifierFromItem(itemFieldMappings, fieldName);
|
||||||
return StringUtils.hasText(identifier) ? reportData.get(identifier) : null;
|
return StringUtils.hasText(identifier) ? reportData.get(identifier) : null;
|
||||||
}
|
}
|
||||||
if ("context".equals(source)) {
|
if ("context".equals(source)) {
|
||||||
String contextKey = schemaField.getString("contextKey");
|
String contextKey = schemaField.getContextKey();
|
||||||
if ("reportTime".equals(contextKey) || "epoch".equals(fieldName)) {
|
if ("reportTime".equals(contextKey) || "epoch".equals(fieldName)) {
|
||||||
return resolveTimestampValue(reportData, itemFieldMappings, fieldName, contextKey);
|
return resolveTimestampValueFromItem(reportData, itemFieldMappings, fieldName, contextKey);
|
||||||
}
|
}
|
||||||
Object contextValue = reportData.get(contextKey);
|
Object contextValue = reportData.get(contextKey);
|
||||||
if (contextValue != null) {
|
if (contextValue != null) {
|
||||||
@ -680,33 +667,51 @@ public class DcpPlatformAdapter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject findArrayFieldSchema(JSONArray requestSchema, String fieldName) {
|
private RequestSchemaField findArrayFieldSchema(List<RequestSchemaField> requestSchema, String fieldName) {
|
||||||
if (requestSchema == null || requestSchema.isEmpty() || !StringUtils.hasText(fieldName)) {
|
if (requestSchema == null || requestSchema.isEmpty() || !StringUtils.hasText(fieldName)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < requestSchema.size(); i++) {
|
for (RequestSchemaField schemaField : requestSchema) {
|
||||||
JSONObject schemaField = requestSchema.getJSONObject(i);
|
if ("array".equalsIgnoreCase(schemaField.getType())
|
||||||
if ("array".equalsIgnoreCase(schemaField.getString("type"))
|
&& fieldName.equals(schemaField.getName())) {
|
||||||
&& fieldName.equals(schemaField.getString("name"))) {
|
|
||||||
return schemaField;
|
return schemaField;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject findFirstArrayFieldSchema(JSONArray requestSchema) {
|
private RequestSchemaField findFirstArrayFieldSchema(List<RequestSchemaField> requestSchema) {
|
||||||
if (requestSchema == null || requestSchema.isEmpty()) {
|
if (requestSchema == null || requestSchema.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < requestSchema.size(); i++) {
|
for (RequestSchemaField schemaField : requestSchema) {
|
||||||
JSONObject schemaField = requestSchema.getJSONObject(i);
|
if ("array".equalsIgnoreCase(schemaField.getType())) {
|
||||||
if ("array".equalsIgnoreCase(schemaField.getString("type"))) {
|
|
||||||
return schemaField;
|
return schemaField;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isThingsModelSource(String source) {
|
||||||
|
return "thingsModel".equals(source) || "identifier".equals(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPayloadDrivenValue(JSONObject body, List<RequestSchemaField> requestSchema) {
|
||||||
|
if (body == null || body.isEmpty() || requestSchema == null || requestSchema.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (RequestSchemaField schemaField : requestSchema) {
|
||||||
|
if ("array".equalsIgnoreCase(schemaField.getType())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isThingsModelSource(schemaField.getSource()) || "context".equals(schemaField.getSource()) || "ts".equals(schemaField.getSource())
|
||||||
|
&& body.containsKey(schemaField.getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private JSONObject copyJsonObject(JSONObject source) {
|
private JSONObject copyJsonObject(JSONObject source) {
|
||||||
if (source == null || source.isEmpty()) {
|
if (source == null || source.isEmpty()) {
|
||||||
return new JSONObject();
|
return new JSONObject();
|
||||||
@ -714,51 +719,6 @@ public class DcpPlatformAdapter {
|
|||||||
return JSON.parseObject(source.toJSONString());
|
return JSON.parseObject(source.toJSONString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasPayloadDrivenValue(JSONObject body, JSONArray requestSchema) {
|
|
||||||
if (body == null || body.isEmpty() || requestSchema == null || requestSchema.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < requestSchema.size(); i++) {
|
|
||||||
JSONObject schemaField = requestSchema.getJSONObject(i);
|
|
||||||
if ("array".equalsIgnoreCase(schemaField.getString("type"))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (usesPayload(schemaField.getString("source"))
|
|
||||||
&& body.containsKey(schemaField.getString("name"))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean usesPayload(String source) {
|
|
||||||
return isThingsModelSource(source) || "context".equals(source) || "ts".equals(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isThingsModelSource(String source) {
|
|
||||||
return "thingsModel".equals(source) || "identifier".equals(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlatformInterface loadPushInterface(PlatformDeviceMapping mapping) {
|
|
||||||
if (mapping.getPushInterfaceId() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return interfaceMapper.selectById(mapping.getPushInterfaceId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONArray loadRequestSchema(PlatformInterface pushInterface) {
|
|
||||||
if (pushInterface == null || !StringUtils.hasText(pushInterface.getRequestSchema())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(pushInterface.getRequestSchema());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("[DCP] 解析 requestSchema 失败 interfaceId={} err={}",
|
|
||||||
pushInterface.getId(), e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String resolvePushPath(PlatformDeviceMapping mapping, PlatformInterface pushInterface) {
|
private String resolvePushPath(PlatformDeviceMapping mapping, PlatformInterface pushInterface) {
|
||||||
if (pushInterface != null && StringUtils.hasText(pushInterface.getPath())) {
|
if (pushInterface != null && StringUtils.hasText(pushInterface.getPath())) {
|
||||||
return pushInterface.getPath();
|
return pushInterface.getPath();
|
||||||
@ -775,19 +735,7 @@ public class DcpPlatformAdapter {
|
|||||||
return "dcp_push_" + sensorType;
|
return "dcp_push_" + sensorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONArray parseJsonArray(String json) {
|
private Object resolveThingsModelValue(JSONObject reportData, List<FieldMappingItem> fieldMappings,
|
||||||
if (!StringUtils.hasText(json)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(json);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("[DCP] 解析 JSON 数组失败: {}", e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object resolveThingsModelValue(JSONObject reportData, JSONArray fieldMappings,
|
|
||||||
String platformField, String fallbackKey) {
|
String platformField, String fallbackKey) {
|
||||||
String identifier = findIdentifier(fieldMappings, platformField);
|
String identifier = findIdentifier(fieldMappings, platformField);
|
||||||
if (StringUtils.hasText(identifier)) {
|
if (StringUtils.hasText(identifier)) {
|
||||||
@ -799,7 +747,7 @@ public class DcpPlatformAdapter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveTimestampValue(JSONObject reportData, JSONArray fieldMappings,
|
private Object resolveTimestampValue(JSONObject reportData, List<FieldMappingItem> fieldMappings,
|
||||||
String platformField, String fallbackKey) {
|
String platformField, String fallbackKey) {
|
||||||
String identifier = findIdentifier(fieldMappings, platformField);
|
String identifier = findIdentifier(fieldMappings, platformField);
|
||||||
if (StringUtils.hasText(identifier)) {
|
if (StringUtils.hasText(identifier)) {
|
||||||
@ -815,6 +763,22 @@ public class DcpPlatformAdapter {
|
|||||||
return nowIsoTimestamp();
|
return nowIsoTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object resolveTimestampValueFromItem(JSONObject reportData, List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings,
|
||||||
|
String platformField, String fallbackKey) {
|
||||||
|
String identifier = findIdentifierFromItem(itemFieldMappings, platformField);
|
||||||
|
if (StringUtils.hasText(identifier)) {
|
||||||
|
return resolveEpoch(reportData, identifier);
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(fallbackKey) && reportData.containsKey(fallbackKey + "__ts")) {
|
||||||
|
return resolveEpoch(reportData, fallbackKey);
|
||||||
|
}
|
||||||
|
String firstIdentifier = findFirstIdentifierFromItem(itemFieldMappings);
|
||||||
|
if (StringUtils.hasText(firstIdentifier)) {
|
||||||
|
return resolveEpoch(reportData, firstIdentifier);
|
||||||
|
}
|
||||||
|
return nowIsoTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
private Object resolveDeviceField(PlatformDeviceMapping mapping, String field) {
|
private Object resolveDeviceField(PlatformDeviceMapping mapping, String field) {
|
||||||
if (mapping == null || !StringUtils.hasText(field)) {
|
if (mapping == null || !StringUtils.hasText(field)) {
|
||||||
return null;
|
return null;
|
||||||
@ -863,41 +827,61 @@ public class DcpPlatformAdapter {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> extractItemValues(JSONObject reportData, JSONArray itemFieldMappings) {
|
private Map<String, Object> extractItemValues(JSONObject reportData,
|
||||||
|
List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings) {
|
||||||
Map<String, Object> values = new HashMap<>();
|
Map<String, Object> values = new HashMap<>();
|
||||||
if (itemFieldMappings == null) return values;
|
if (itemFieldMappings == null) return values;
|
||||||
for (int i = 0; i < itemFieldMappings.size(); i++) {
|
for (ExtraMappingConfig.ItemFieldMapping im : itemFieldMappings) {
|
||||||
JSONObject im = itemFieldMappings.getJSONObject(i);
|
if (StringUtils.hasText(im.getIdentifier()) && StringUtils.hasText(im.getPlatformField())) {
|
||||||
String platformField = im.getString("platformField");
|
values.put(im.getPlatformField(), reportData.get(im.getIdentifier()));
|
||||||
String identifier = im.getString("identifier");
|
|
||||||
if (StringUtils.hasText(identifier) && StringUtils.hasText(platformField)) {
|
|
||||||
values.put(platformField, reportData.get(identifier));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String findIdentifier(JSONArray itemFieldMappings, String platformField) {
|
private String findIdentifier(List<FieldMappingItem> itemFieldMappings, String platformField) {
|
||||||
if (itemFieldMappings == null || !StringUtils.hasText(platformField)) {
|
if (itemFieldMappings == null || !StringUtils.hasText(platformField)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < itemFieldMappings.size(); i++) {
|
for (FieldMappingItem im : itemFieldMappings) {
|
||||||
JSONObject im = itemFieldMappings.getJSONObject(i);
|
if (platformField.equals(im.getPlatformField())) {
|
||||||
if (platformField.equals(im.getString("platformField"))) {
|
return im.getIdentifier();
|
||||||
return im.getString("identifier");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String findFirstIdentifier(JSONArray itemFieldMappings) {
|
private String findIdentifierFromItem(List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings, String platformField) {
|
||||||
|
if (itemFieldMappings == null || !StringUtils.hasText(platformField)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (ExtraMappingConfig.ItemFieldMapping im : itemFieldMappings) {
|
||||||
|
if (platformField.equals(im.getPlatformField())) {
|
||||||
|
return im.getIdentifier();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findFirstIdentifier(List<FieldMappingItem> itemFieldMappings) {
|
||||||
if (itemFieldMappings == null || itemFieldMappings.isEmpty()) {
|
if (itemFieldMappings == null || itemFieldMappings.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < itemFieldMappings.size(); i++) {
|
for (FieldMappingItem im : itemFieldMappings) {
|
||||||
String identifier = itemFieldMappings.getJSONObject(i).getString("identifier");
|
if (StringUtils.hasText(im.getIdentifier())) {
|
||||||
if (StringUtils.hasText(identifier)) {
|
return im.getIdentifier();
|
||||||
return identifier;
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findFirstIdentifierFromItem(List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings) {
|
||||||
|
if (itemFieldMappings == null || itemFieldMappings.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (ExtraMappingConfig.ItemFieldMapping im : itemFieldMappings) {
|
||||||
|
if (StringUtils.hasText(im.getIdentifier())) {
|
||||||
|
return im.getIdentifier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -1071,7 +1055,7 @@ public class DcpPlatformAdapter {
|
|||||||
private void pushBatchSubDevicesData(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
private void pushBatchSubDevicesData(PlatformInstance platform, PlatformUserAuth userAuth, PlatformDeviceMapping mapping,
|
||||||
PlatformDeviceSubMapping currentSubMapping, String reportSerialNumber,
|
PlatformDeviceSubMapping currentSubMapping, String reportSerialNumber,
|
||||||
String payload, String pushPath, String interfaceCode,
|
String payload, String pushPath, String interfaceCode,
|
||||||
JSONArray requestSchema) {
|
List<RequestSchemaField> requestSchema) {
|
||||||
try {
|
try {
|
||||||
// 1. 查询所有子设备。批量推送只依赖子映射顺序和推送接口 schema,
|
// 1. 查询所有子设备。批量推送只依赖子映射顺序和推送接口 schema,
|
||||||
// 不再从推送接口 request_schema 读取入网用的 sensorDepths。
|
// 不再从推送接口 request_schema 读取入网用的 sensorDepths。
|
||||||
@ -1104,16 +1088,16 @@ public class DcpPlatformAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 准备公共参数(复用已有 fieldMapping + requestSchema)
|
// 3. 准备公共参数(复用已有 fieldMapping + requestSchema)
|
||||||
JSONArray fieldMappings = parseJsonArray(mapping.getFieldMapping());
|
List<FieldMappingItem> fieldMappings = mapping.getFieldMappingParsed();
|
||||||
String fieldName = resolveArrayFieldName(requestSchema);
|
String fieldName = resolveArrayFieldName(requestSchema);
|
||||||
JSONObject extra = null;
|
List<ExtraMappingConfig.ItemFieldMapping> itemFieldMappings = null;
|
||||||
if (StringUtils.hasText(mapping.getExtraMapping())) {
|
ExtraMappingConfig extra = mapping.getExtraMappingParsed();
|
||||||
extra = JSON.parseObject(mapping.getExtraMapping());
|
if (extra != null) {
|
||||||
if (StringUtils.hasText(extra.getString("fieldName"))) {
|
if (StringUtils.hasText(extra.getFieldName())) {
|
||||||
fieldName = extra.getString("fieldName");
|
fieldName = extra.getFieldName();
|
||||||
}
|
}
|
||||||
|
itemFieldMappings = extra.getItemFieldMappings();
|
||||||
}
|
}
|
||||||
JSONArray itemFieldMappings = extra != null ? extra.getJSONArray("itemFieldMappings") : null;
|
|
||||||
|
|
||||||
// 解析当前上报子设备的 payload
|
// 解析当前上报子设备的 payload
|
||||||
JSONObject currentReportData = parsePayloadToMap(payload);
|
JSONObject currentReportData = parsePayloadToMap(payload);
|
||||||
@ -1137,7 +1121,7 @@ public class DcpPlatformAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String sensorId = resolveSubDeviceSensorId(sub);
|
String sensorId = resolveSubDeviceSensorId(sub);
|
||||||
JSONObject sensorDataItem = buildArrayItem(platform, mapping, requestSchema, reportData, fieldName, itemFieldMappings, sensorId);
|
JSONObject sensorDataItem = buildArrayItem(userAuth, mapping, requestSchema, reportData, fieldName, itemFieldMappings, sensorId);
|
||||||
if (sensorDataItem == null || sensorDataItem.isEmpty()) {
|
if (sensorDataItem == null || sensorDataItem.isEmpty()) {
|
||||||
log.warn("[DCP] 子设备 {} 数据映射为空,跳过其 sensorData", subSn);
|
log.warn("[DCP] 子设备 {} 数据映射为空,跳过其 sensorData", subSn);
|
||||||
continue;
|
continue;
|
||||||
@ -1253,16 +1237,9 @@ public class DcpPlatformAdapter {
|
|||||||
* 优先从 onboard_config 中取 sensorId,否则使用子设备序列号。
|
* 优先从 onboard_config 中取 sensorId,否则使用子设备序列号。
|
||||||
*/
|
*/
|
||||||
private String resolveSubDeviceSensorId(PlatformDeviceSubMapping subMapping) {
|
private String resolveSubDeviceSensorId(PlatformDeviceSubMapping subMapping) {
|
||||||
if (StringUtils.hasText(subMapping.getOnboardConfig())) {
|
OnboardConfig config = subMapping.getOnboardConfigParsed();
|
||||||
try {
|
if (config != null && StringUtils.hasText(config.getSensorId())) {
|
||||||
JSONObject config = JSON.parseObject(subMapping.getOnboardConfig());
|
return config.getSensorId();
|
||||||
String sensorId = config.getString("sensorId");
|
|
||||||
if (StringUtils.hasText(sensorId)) {
|
|
||||||
return sensorId;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.debug("[DCP] 解析 onboardConfig 失败 subSn={}", subMapping.getSubSerialNumber());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return subMapping.getSubSerialNumber();
|
return subMapping.getSubSerialNumber();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,22 @@
|
|||||||
package com.fastbee.iot.platform.domain;
|
package com.fastbee.iot.platform.domain;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fastbee.iot.platform.model.json.ExtraMappingConfig;
|
||||||
|
import com.fastbee.iot.platform.model.json.FieldMappingItem;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 平台设备绑定关系
|
* 平台设备绑定关系
|
||||||
@ -71,6 +77,40 @@ public class PlatformDeviceMapping implements Serializable {
|
|||||||
@ApiModelProperty("扩展映射配置,如静力水准子设备编号与DCP sensorId映射")
|
@ApiModelProperty("扩展映射配置,如静力水准子设备编号与DCP sensorId映射")
|
||||||
private String extraMapping;
|
private String extraMapping;
|
||||||
|
|
||||||
|
/** fieldMapping 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient List<FieldMappingItem> fieldMappingParsed;
|
||||||
|
|
||||||
|
/** extraMapping 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient ExtraMappingConfig extraMappingParsed;
|
||||||
|
|
||||||
|
public List<FieldMappingItem> getFieldMappingParsed() {
|
||||||
|
if (fieldMappingParsed == null && StringUtils.hasText(this.fieldMapping)) {
|
||||||
|
this.fieldMappingParsed = JSON.parseArray(this.fieldMapping, FieldMappingItem.class);
|
||||||
|
}
|
||||||
|
return fieldMappingParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFieldMappingParsed(List<FieldMappingItem> parsed) {
|
||||||
|
this.fieldMappingParsed = parsed;
|
||||||
|
this.fieldMapping = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtraMappingConfig getExtraMappingParsed() {
|
||||||
|
if (extraMappingParsed == null && StringUtils.hasText(this.extraMapping)) {
|
||||||
|
this.extraMappingParsed = JSON.parseObject(this.extraMapping, ExtraMappingConfig.class);
|
||||||
|
}
|
||||||
|
return extraMappingParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtraMappingParsed(ExtraMappingConfig parsed) {
|
||||||
|
this.extraMappingParsed = parsed;
|
||||||
|
this.extraMapping = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiModelProperty("入网状态(0=未入网,1=已入网)")
|
@ApiModelProperty("入网状态(0=未入网,1=已入网)")
|
||||||
private Integer netStatus;
|
private Integer netStatus;
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
package com.fastbee.iot.platform.domain;
|
package com.fastbee.iot.platform.domain;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fastbee.iot.platform.model.json.OnboardConfig;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -45,6 +50,23 @@ public class PlatformDeviceSubMapping implements Serializable {
|
|||||||
@ApiModelProperty("入网时传给平台的标识参数(平台相关)")
|
@ApiModelProperty("入网时传给平台的标识参数(平台相关)")
|
||||||
private String onboardConfig;
|
private String onboardConfig;
|
||||||
|
|
||||||
|
/** onboardConfig 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient OnboardConfig onboardConfigParsed;
|
||||||
|
|
||||||
|
public OnboardConfig getOnboardConfigParsed() {
|
||||||
|
if (onboardConfigParsed == null && StringUtils.hasText(this.onboardConfig)) {
|
||||||
|
this.onboardConfigParsed = JSON.parseObject(this.onboardConfig, OnboardConfig.class);
|
||||||
|
}
|
||||||
|
return onboardConfigParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnboardConfigParsed(OnboardConfig parsed) {
|
||||||
|
this.onboardConfigParsed = parsed;
|
||||||
|
this.onboardConfig = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiModelProperty("入网状态(0=未入网,1=已入网)")
|
@ApiModelProperty("入网状态(0=未入网,1=已入网)")
|
||||||
private Integer netStatus;
|
private Integer netStatus;
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,22 @@
|
|||||||
package com.fastbee.iot.platform.domain;
|
package com.fastbee.iot.platform.domain;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fastbee.iot.platform.model.json.ParamOverrideConfig;
|
||||||
|
import com.fastbee.iot.platform.model.json.ResultSaveField;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程步骤
|
* 流程步骤
|
||||||
@ -40,6 +49,41 @@ public class PlatformFlowStep implements Serializable {
|
|||||||
@ApiModelProperty("需持久化的出参字段 [{field,saveTo}]")
|
@ApiModelProperty("需持久化的出参字段 [{field,saveTo}]")
|
||||||
private String resultSave;
|
private String resultSave;
|
||||||
|
|
||||||
|
/** paramMapping 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient Map<String, ParamOverrideConfig> paramMappingParsed;
|
||||||
|
|
||||||
|
/** resultSave 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient List<ResultSaveField> resultSaveParsed;
|
||||||
|
|
||||||
|
public Map<String, ParamOverrideConfig> getParamMappingParsed() {
|
||||||
|
if (paramMappingParsed == null && StringUtils.hasText(this.paramMapping)) {
|
||||||
|
this.paramMappingParsed = JSON.parseObject(this.paramMapping,
|
||||||
|
new TypeReference<Map<String,ParamOverrideConfig>>(){}.getType());
|
||||||
|
}
|
||||||
|
return paramMappingParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParamMappingParsed(Map<String, ParamOverrideConfig> parsed) {
|
||||||
|
this.paramMappingParsed = parsed;
|
||||||
|
this.paramMapping = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ResultSaveField> getResultSaveParsed() {
|
||||||
|
if (resultSaveParsed == null && StringUtils.hasText(this.resultSave)) {
|
||||||
|
this.resultSaveParsed = JSON.parseArray(this.resultSave, ResultSaveField.class);
|
||||||
|
}
|
||||||
|
return resultSaveParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSaveParsed(List<ResultSaveField> parsed) {
|
||||||
|
this.resultSaveParsed = parsed;
|
||||||
|
this.resultSave = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiModelProperty("备注")
|
@ApiModelProperty("备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
package com.fastbee.iot.platform.domain;
|
package com.fastbee.iot.platform.domain;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -36,6 +41,7 @@ public class PlatformInstance implements Serializable {
|
|||||||
@ApiModelProperty("认证类型(1=密码Token,2=ApiKey,3=OAuth2)")
|
@ApiModelProperty("认证类型(1=密码Token,2=ApiKey,3=OAuth2)")
|
||||||
private Integer authType;
|
private Integer authType;
|
||||||
|
|
||||||
|
// ========================= 已弃用 =========================
|
||||||
@ApiModelProperty("认证配置模板(新增用户时复制){userName,password,clientId,scope}")
|
@ApiModelProperty("认证配置模板(新增用户时复制){userName,password,clientId,scope}")
|
||||||
private String authConfig;
|
private String authConfig;
|
||||||
|
|
||||||
@ -51,6 +57,7 @@ public class PlatformInstance implements Serializable {
|
|||||||
|
|
||||||
@ApiModelProperty("初始化状态(0=未初始化,1=已初始化)")
|
@ApiModelProperty("初始化状态(0=未初始化,1=已初始化)")
|
||||||
private Integer initStatus;
|
private Integer initStatus;
|
||||||
|
// ========================= 已弃用 =========================
|
||||||
|
|
||||||
@ApiModelProperty("是否启用(0=禁用,1=启用)")
|
@ApiModelProperty("是否启用(0=禁用,1=启用)")
|
||||||
private String enable;
|
private String enable;
|
||||||
|
|||||||
@ -1,15 +1,22 @@
|
|||||||
package com.fastbee.iot.platform.domain;
|
package com.fastbee.iot.platform.domain;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fastbee.iot.platform.model.json.ResponseSchemaField;
|
||||||
|
import com.fastbee.iot.platform.model.json.RequestSchemaField;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 平台接口定义
|
* 平台接口定义
|
||||||
@ -48,6 +55,40 @@ public class PlatformInterface implements Serializable {
|
|||||||
@ApiModelProperty("出参字段定义 JSON")
|
@ApiModelProperty("出参字段定义 JSON")
|
||||||
private String responseSchema;
|
private String responseSchema;
|
||||||
|
|
||||||
|
/** requestSchema 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient List<RequestSchemaField> requestSchemaParsed;
|
||||||
|
|
||||||
|
/** responseSchema 类型安全解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient List<ResponseSchemaField> responseSchemaParsed;
|
||||||
|
|
||||||
|
public List<RequestSchemaField> getRequestSchemaParsed() {
|
||||||
|
if (requestSchemaParsed == null && StringUtils.hasText(this.requestSchema)) {
|
||||||
|
this.requestSchemaParsed = JSON.parseArray(this.requestSchema, RequestSchemaField.class);
|
||||||
|
}
|
||||||
|
return requestSchemaParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestSchemaParsed(List<RequestSchemaField> parsed) {
|
||||||
|
this.requestSchemaParsed = parsed;
|
||||||
|
this.requestSchema = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ResponseSchemaField> getResponseSchemaParsed() {
|
||||||
|
if (responseSchemaParsed == null && StringUtils.hasText(this.responseSchema)) {
|
||||||
|
this.responseSchemaParsed = JSON.parseArray(this.responseSchema, ResponseSchemaField.class);
|
||||||
|
}
|
||||||
|
return responseSchemaParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseSchemaParsed(List<ResponseSchemaField> parsed) {
|
||||||
|
this.responseSchemaParsed = parsed;
|
||||||
|
this.responseSchema = parsed == null ? null : JSON.toJSONString(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiModelProperty("排序")
|
@ApiModelProperty("排序")
|
||||||
private Integer sortOrder;
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
package com.fastbee.iot.platform.domain;
|
package com.fastbee.iot.platform.domain;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -50,6 +55,40 @@ public class PlatformUserAuth implements Serializable {
|
|||||||
@ApiModelProperty("用户级配置 {projectId,projectName,...}")
|
@ApiModelProperty("用户级配置 {projectId,projectName,...}")
|
||||||
private String extraConfig;
|
private String extraConfig;
|
||||||
|
|
||||||
|
/** authConfig 惰性解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient JSONObject authConfigParsed;
|
||||||
|
|
||||||
|
/** extraConfig 惰性解析 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonIgnore
|
||||||
|
private transient JSONObject extraConfigParsed;
|
||||||
|
|
||||||
|
public JSONObject getAuthConfigParsed() {
|
||||||
|
if (authConfigParsed == null && StringUtils.hasText(this.authConfig)) {
|
||||||
|
this.authConfigParsed = JSON.parseObject(this.authConfig);
|
||||||
|
}
|
||||||
|
return authConfigParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthConfigParsed(JSONObject parsed) {
|
||||||
|
this.authConfigParsed = parsed;
|
||||||
|
this.authConfig = parsed == null ? null : parsed.toJSONString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getExtraConfigParsed() {
|
||||||
|
if (extraConfigParsed == null && StringUtils.hasText(this.extraConfig)) {
|
||||||
|
this.extraConfigParsed = JSON.parseObject(this.extraConfig);
|
||||||
|
}
|
||||||
|
return extraConfigParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtraConfigParsed(JSONObject parsed) {
|
||||||
|
this.extraConfigParsed = parsed;
|
||||||
|
this.extraConfig = parsed == null ? null : parsed.toJSONString();
|
||||||
|
}
|
||||||
|
|
||||||
@ApiModelProperty("是否启用(0=禁用,1=启用)")
|
@ApiModelProperty("是否启用(0=禁用,1=启用)")
|
||||||
private String enable;
|
private String enable;
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import com.fastbee.iot.mapper.DeviceMapper;
|
|||||||
import com.fastbee.iot.mapper.SubGatewayMapper;
|
import com.fastbee.iot.mapper.SubGatewayMapper;
|
||||||
import com.fastbee.iot.platform.domain.*;
|
import com.fastbee.iot.platform.domain.*;
|
||||||
import com.fastbee.iot.platform.mapper.*;
|
import com.fastbee.iot.platform.mapper.*;
|
||||||
|
import com.fastbee.iot.platform.model.json.*;
|
||||||
import com.fastbee.iot.platform.service.IPlatformPushLogService;
|
import com.fastbee.iot.platform.service.IPlatformPushLogService;
|
||||||
import com.dtflys.forest.http.ForestRequestType;
|
import com.dtflys.forest.http.ForestRequestType;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -227,78 +228,91 @@ public class PlatformFlowExecutor {
|
|||||||
* 解析步骤入参
|
* 解析步骤入参
|
||||||
* source 枚举: fixed / auth / extra / context / device / thingsModel / ts
|
* source 枚举: fixed / auth / extra / context / device / thingsModel / ts
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private Map<String, Object> resolveParams(PlatformInterface iface, PlatformFlowStep step, FlowContext ctx) {
|
private Map<String, Object> resolveParams(PlatformInterface iface, PlatformFlowStep step, FlowContext ctx) {
|
||||||
Map<String, Object> result = new LinkedHashMap<>();
|
Map<String, Object> result = new LinkedHashMap<>();
|
||||||
if (!StringUtils.hasText(iface.getRequestSchema())) {
|
List<RequestSchemaField> schema = iface.getRequestSchemaParsed();
|
||||||
|
if (schema == null || schema.isEmpty()) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并接口默认 schema 和步骤覆盖 mapping
|
// 合并接口默认 schema 和步骤覆盖 mapping
|
||||||
JSONArray schema = JSON.parseArray(iface.getRequestSchema());
|
Map<String, ParamOverrideConfig> overrides = step.getParamMappingParsed();
|
||||||
Map<String, Object> overrides = StringUtils.hasText(step.getParamMapping())
|
if (overrides == null) {
|
||||||
? JSON.parseObject(step.getParamMapping(), Map.class)
|
overrides = Collections.emptyMap();
|
||||||
: Collections.emptyMap();
|
}
|
||||||
|
|
||||||
// 优先从 userAuth 获取 authConfig,fallback 到 platform.authTemplate
|
// 获取 userAuth authConfig
|
||||||
JSONObject authConfig = new JSONObject();
|
JSONObject authConfig = new JSONObject();
|
||||||
if (ctx.getPlatformUserAuth() != null && StringUtils.hasText(ctx.getPlatformUserAuth().getAuthConfig())) {
|
if (ctx.getPlatformUserAuth() != null) {
|
||||||
authConfig = JSON.parseObject(ctx.getPlatformUserAuth().getAuthConfig());
|
JSONObject parsed = ctx.getPlatformUserAuth().getAuthConfigParsed();
|
||||||
} else if (StringUtils.hasText(ctx.getPlatform().getAuthConfig())) {
|
if (parsed != null) {
|
||||||
authConfig = JSON.parseObject(ctx.getPlatform().getAuthConfig());
|
authConfig = parsed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优先从 userAuth 获取 extraConfig,fallback 到 platform.extraConfig
|
// 获取 userAuth extraConfig
|
||||||
JSONObject extraConfig = new JSONObject();
|
JSONObject extraConfig = new JSONObject();
|
||||||
if (ctx.getPlatformUserAuth() != null && StringUtils.hasText(ctx.getPlatformUserAuth().getExtraConfig())) {
|
if (ctx.getPlatformUserAuth() != null) {
|
||||||
extraConfig = JSON.parseObject(ctx.getPlatformUserAuth().getExtraConfig());
|
JSONObject parsed = ctx.getPlatformUserAuth().getExtraConfigParsed();
|
||||||
} else if (StringUtils.hasText(ctx.getPlatform().getExtraConfig())) {
|
if (parsed != null) {
|
||||||
extraConfig = JSON.parseObject(ctx.getPlatform().getExtraConfig());
|
extraConfig = parsed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < schema.size(); i++) {
|
for (RequestSchemaField field : schema) {
|
||||||
JSONObject field = schema.getJSONObject(i);
|
String name = field.getName();
|
||||||
String name = field.getString("name");
|
if (name == null) continue;
|
||||||
|
|
||||||
// 步骤覆盖优先
|
// 步骤覆盖优先
|
||||||
if (overrides.containsKey(name)) {
|
if (overrides.containsKey(name)) {
|
||||||
Object override = overrides.get(name);
|
ParamOverrideConfig override = overrides.get(name);
|
||||||
if (override instanceof Map) {
|
if (override != null) {
|
||||||
Map<String, Object> ov = (Map<String, Object>) override;
|
String src = override.getSource() != null ? override.getSource() : field.getSource();
|
||||||
String src = (String) ov.get("source");
|
String type = override.getType() != null ? override.getType() : field.getType();
|
||||||
String type = ov.get("type") != null ? String.valueOf(ov.get("type")) : field.getString("type");
|
result.put(name, normalizeValueByType(type,
|
||||||
result.put(name, normalizeValueByType(type, resolveValue(src, ov, authConfig, extraConfig, ctx)));
|
resolveValue(src, mergeOverride(field, override), authConfig, extraConfig, ctx)));
|
||||||
} else {
|
} else {
|
||||||
result.put(name, normalizeValueByType(field.getString("type"), override));
|
result.put(name, normalizeValueByType(field.getType(), null));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String source = field.getString("source");
|
result.put(name, normalizeValueByType(field.getType(),
|
||||||
result.put(name, normalizeValueByType(field.getString("type"), resolveValue(source, field, authConfig, extraConfig, ctx)));
|
resolveValue(field.getSource(), field, authConfig, extraConfig, ctx)));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveValue(String source, Object fieldDef, JSONObject authConfig,
|
private RequestSchemaField mergeOverride(RequestSchemaField schemaField, ParamOverrideConfig override) {
|
||||||
|
if (override == null) return schemaField;
|
||||||
|
RequestSchemaField merged = new RequestSchemaField();
|
||||||
|
merged.setName(schemaField.getName());
|
||||||
|
merged.setSource(override.getSource() != null ? override.getSource() : schemaField.getSource());
|
||||||
|
merged.setType(override.getType() != null ? override.getType() : schemaField.getType());
|
||||||
|
merged.setValue(override.getValue() != null ? override.getValue() : schemaField.getValue());
|
||||||
|
merged.setField(override.getField() != null ? override.getField() : schemaField.getField());
|
||||||
|
merged.setContextKey(override.getContextKey() != null ? override.getContextKey() : schemaField.getContextKey());
|
||||||
|
merged.setIdentifier(override.getIdentifier() != null ? override.getIdentifier() : schemaField.getIdentifier());
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object resolveValue(String source, RequestSchemaField fieldDef, JSONObject authConfig,
|
||||||
JSONObject extraConfig, FlowContext ctx) {
|
JSONObject extraConfig, FlowContext ctx) {
|
||||||
if (source == null) return null;
|
if (source == null) return null;
|
||||||
JSONObject fd = fieldDef instanceof JSONObject ? (JSONObject) fieldDef
|
|
||||||
: JSON.parseObject(JSON.toJSONString(fieldDef));
|
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case "fixed":
|
case "fixed":
|
||||||
return fd.get("value");
|
return fieldDef.getValue();
|
||||||
case "uuid":
|
case "uuid":
|
||||||
return newGeneratedId();
|
return newGeneratedId();
|
||||||
case "auth":
|
case "auth":
|
||||||
return authConfig.get(fd.getString("field"));
|
return authConfig.get(fieldDef.getField());
|
||||||
case "extra":
|
case "extra":
|
||||||
return extraConfig.get(fd.getString("field"));
|
return extraConfig.get(fieldDef.getField());
|
||||||
case "context":
|
case "context":
|
||||||
return ctx.getFromContext(fd.getString("contextKey"));
|
return ctx.getFromContext(fieldDef.getContextKey());
|
||||||
case "device":
|
case "device":
|
||||||
if (ctx.getDeviceMapping() == null) return null;
|
if (ctx.getDeviceMapping() == null) return null;
|
||||||
String df = fd.getString("field");
|
String df = fieldDef.getField();
|
||||||
if ("platform_device_id".equals(df)) return ctx.getDeviceMapping().getPlatformDeviceId();
|
if ("platform_device_id".equals(df)) return ctx.getDeviceMapping().getPlatformDeviceId();
|
||||||
if ("platform_point_id".equals(df)) return ctx.getDeviceMapping().getPlatformPointId();
|
if ("platform_point_id".equals(df)) return ctx.getDeviceMapping().getPlatformPointId();
|
||||||
// 支持从设备绑定表读取项目信息
|
// 支持从设备绑定表读取项目信息
|
||||||
@ -310,7 +324,7 @@ public class PlatformFlowExecutor {
|
|||||||
if (StringUtils.hasText(ctx.getCurrentMonitorSerialNumber())) {
|
if (StringUtils.hasText(ctx.getCurrentMonitorSerialNumber())) {
|
||||||
return ctx.getCurrentMonitorSerialNumber();
|
return ctx.getCurrentMonitorSerialNumber();
|
||||||
}
|
}
|
||||||
return normalizeValueByType(fd.getString("type"), resolveGatewaySerialNumber(ctx.getDeviceMapping()));
|
return normalizeValueByType(fieldDef.getType(), resolveGatewaySerialNumber(ctx.getDeviceMapping()));
|
||||||
}
|
}
|
||||||
if ("device_name".equals(df)) {
|
if ("device_name".equals(df)) {
|
||||||
return resolveDeviceName(ctx);
|
return resolveDeviceName(ctx);
|
||||||
@ -323,11 +337,11 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case "thingsModel":
|
case "thingsModel":
|
||||||
return resolveThingsModelValue(ctx, fd);
|
return resolveThingsModelValue(ctx, fieldDef);
|
||||||
case "ts":
|
case "ts":
|
||||||
return resolveThingsModelTs(ctx, fd);
|
return resolveThingsModelTs(ctx, fieldDef);
|
||||||
case "onboard_config":
|
case "onboard_config":
|
||||||
return resolveOnboardConfigValue(ctx, fd);
|
return resolveOnboardConfigValue(ctx, fieldDef);
|
||||||
case "subDeviceSensorIds":
|
case "subDeviceSensorIds":
|
||||||
return collectSubDeviceSensorIds(ctx);
|
return collectSubDeviceSensorIds(ctx);
|
||||||
case "cascadedSubDeviceSensorIds":
|
case "cascadedSubDeviceSensorIds":
|
||||||
@ -341,7 +355,7 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveThingsModelValue(FlowContext ctx, JSONObject fieldDef) {
|
private Object resolveThingsModelValue(FlowContext ctx, RequestSchemaField fieldDef) {
|
||||||
JSONObject payload = parsePayloadToObject(ctx.getPayload());
|
JSONObject payload = parsePayloadToObject(ctx.getPayload());
|
||||||
if (payload == null) {
|
if (payload == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -350,7 +364,7 @@ public class PlatformFlowExecutor {
|
|||||||
return StringUtils.hasText(identifier) ? payload.get(identifier) : null;
|
return StringUtils.hasText(identifier) ? payload.get(identifier) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveThingsModelTs(FlowContext ctx, JSONObject fieldDef) {
|
private Object resolveThingsModelTs(FlowContext ctx, RequestSchemaField fieldDef) {
|
||||||
JSONObject payload = parsePayloadToObject(ctx.getPayload());
|
JSONObject payload = parsePayloadToObject(ctx.getPayload());
|
||||||
if (payload == null) {
|
if (payload == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -366,13 +380,13 @@ public class PlatformFlowExecutor {
|
|||||||
return ts != null ? ts : payload.get("timestamp");
|
return ts != null ? ts : payload.get("timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveThingsModelIdentifier(JSONObject fieldDef) {
|
private String resolveThingsModelIdentifier(RequestSchemaField fieldDef) {
|
||||||
String identifier = fieldDef.getString("identifier");
|
String identifier = fieldDef.getIdentifier();
|
||||||
if (StringUtils.hasText(identifier)) {
|
if (StringUtils.hasText(identifier)) {
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
String field = fieldDef.getString("field");
|
String field = fieldDef.getField();
|
||||||
return StringUtils.hasText(field) ? field : fieldDef.getString("contextKey");
|
return StringUtils.hasText(field) ? field : fieldDef.getContextKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject parsePayloadToObject(String payload) {
|
private JSONObject parsePayloadToObject(String payload) {
|
||||||
@ -413,15 +427,18 @@ public class PlatformFlowExecutor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object resolveOnboardConfigValue(FlowContext ctx, JSONObject fieldDef) {
|
private Object resolveOnboardConfigValue(FlowContext ctx, RequestSchemaField fieldDef) {
|
||||||
String name = fieldDef.getString("name");
|
String name = fieldDef.getName();
|
||||||
List<PlatformDeviceSubMapping> monitorSubMappings = ctx.getMonitorSubMappings();
|
List<PlatformDeviceSubMapping> monitorSubMappings = ctx.getMonitorSubMappings();
|
||||||
if (ctx.getCurrentMonitorIndex() != null && CollectionUtils.isNotEmpty(monitorSubMappings)) {
|
if (ctx.getCurrentMonitorIndex() != null && CollectionUtils.isNotEmpty(monitorSubMappings)) {
|
||||||
int index = ctx.getCurrentMonitorIndex();
|
int index = ctx.getCurrentMonitorIndex();
|
||||||
PlatformDeviceSubMapping platformDeviceSubMapping = monitorSubMappings.get(index);
|
PlatformDeviceSubMapping platformDeviceSubMapping = monitorSubMappings.get(index);
|
||||||
JSONObject authConfig = StringUtils.hasText(platformDeviceSubMapping.getOnboardConfig())
|
OnboardConfig config = platformDeviceSubMapping.getOnboardConfigParsed();
|
||||||
? JSON.parseObject(platformDeviceSubMapping.getOnboardConfig()) : new JSONObject();
|
if (config == null) {
|
||||||
String value = authConfig.getString(name);
|
throw new RuntimeException("入网失败,子设备" + platformDeviceSubMapping.getSubDeviceName() + "未配置值:" + name);
|
||||||
|
}
|
||||||
|
// 从 OnboardConfig 按字段名反射获取值(支持 sensorId/sensorDepth/refSerialNumber/refSensorId)
|
||||||
|
String value = resolveOnboardConfigField(config, name);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new RuntimeException("入网失败,子设备" + platformDeviceSubMapping.getSubDeviceName() + "未配置值:" + name);
|
throw new RuntimeException("入网失败,子设备" + platformDeviceSubMapping.getSubDeviceName() + "未配置值:" + name);
|
||||||
}
|
}
|
||||||
@ -500,21 +517,24 @@ public class PlatformFlowExecutor {
|
|||||||
private Set<String> resolveGeneratedFieldNames(PlatformInterface iface, PlatformFlowStep step) {
|
private Set<String> resolveGeneratedFieldNames(PlatformInterface iface, PlatformFlowStep step) {
|
||||||
LinkedHashMap<String, String> sources = new LinkedHashMap<>();
|
LinkedHashMap<String, String> sources = new LinkedHashMap<>();
|
||||||
try {
|
try {
|
||||||
if (iface != null && StringUtils.hasText(iface.getRequestSchema())) {
|
if (iface != null) {
|
||||||
JSONArray schema = JSON.parseArray(iface.getRequestSchema());
|
List<RequestSchemaField> schema = iface.getRequestSchemaParsed();
|
||||||
for (int i = 0; i < schema.size(); i++) {
|
if (schema != null) {
|
||||||
JSONObject field = schema.getJSONObject(i);
|
for (RequestSchemaField field : schema) {
|
||||||
if (field != null && StringUtils.hasText(field.getString("name"))) {
|
if (field != null && StringUtils.hasText(field.getName())) {
|
||||||
sources.put(field.getString("name"), field.getString("source"));
|
sources.put(field.getName(), field.getSource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (step != null && StringUtils.hasText(step.getParamMapping())) {
|
}
|
||||||
JSONObject overrides = JSON.parseObject(step.getParamMapping());
|
if (step != null) {
|
||||||
for (String fieldName : overrides.keySet()) {
|
Map<String, ParamOverrideConfig> overrides = step.getParamMappingParsed();
|
||||||
JSONObject override = overrides.getJSONObject(fieldName);
|
if (overrides != null) {
|
||||||
if (override != null && StringUtils.hasText(override.getString("source"))) {
|
for (Map.Entry<String, ParamOverrideConfig> entry : overrides.entrySet()) {
|
||||||
sources.put(fieldName, override.getString("source"));
|
ParamOverrideConfig override = entry.getValue();
|
||||||
|
if (override != null && StringUtils.hasText(override.getSource())) {
|
||||||
|
sources.put(entry.getKey(), override.getSource());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,10 +551,8 @@ public class PlatformFlowExecutor {
|
|||||||
private List<String> collectSubDeviceSensorIds(FlowContext ctx) {
|
private List<String> collectSubDeviceSensorIds(FlowContext ctx) {
|
||||||
if (StringUtils.hasText(ctx.getCurrentMonitorSerialNumber())
|
if (StringUtils.hasText(ctx.getCurrentMonitorSerialNumber())
|
||||||
&& StringUtils.hasText(ctx.getCurrentReferenceSerialNumber())) {
|
&& StringUtils.hasText(ctx.getCurrentReferenceSerialNumber())) {
|
||||||
String refSensorId = resolveOnboardSensorId(
|
String refSensorId = resolveOnboardSensorIdByCtx(ctx, true);
|
||||||
ctx.getReferenceSubMappingOnboardConfig(), ctx.getCurrentReferenceSerialNumber());
|
String monitorSensorId = resolveOnboardSensorIdByCtx(ctx, false);
|
||||||
String monitorSensorId = resolveOnboardSensorId(
|
|
||||||
ctx.getSubMappingOnboardConfig(), ctx.getCurrentMonitorSerialNumber());
|
|
||||||
List<String> ids = new ArrayList<>();
|
List<String> ids = new ArrayList<>();
|
||||||
if (StringUtils.hasText(refSensorId)) ids.add(refSensorId);
|
if (StringUtils.hasText(refSensorId)) ids.add(refSensorId);
|
||||||
if (StringUtils.hasText(monitorSensorId)) ids.add(monitorSensorId);
|
if (StringUtils.hasText(monitorSensorId)) ids.add(monitorSensorId);
|
||||||
@ -544,16 +562,14 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 网关入网时,从子表 onboard_config 获取 sensorId
|
// 网关入网时,从子表 onboard_config 获取 sensorId
|
||||||
if (StringUtils.hasText(ctx.getSubMappingOnboardConfig())) {
|
OnboardConfig currentConfig = resolveCurrentOnboardConfig(ctx);
|
||||||
try {
|
if (currentConfig != null) {
|
||||||
JSONObject config = JSON.parseObject(ctx.getSubMappingOnboardConfig());
|
|
||||||
List<String> ids = new ArrayList<>();
|
List<String> ids = new ArrayList<>();
|
||||||
String sensorId = config.getString("sensorId");
|
String sensorId = currentConfig.getSensorId();
|
||||||
String refSensorId = config.getString("refSensorId");
|
String refSensorId = currentConfig.getRefSensorId();
|
||||||
if (StringUtils.hasText(refSensorId)) ids.add(refSensorId);
|
if (StringUtils.hasText(refSensorId)) ids.add(refSensorId);
|
||||||
if (StringUtils.hasText(sensorId)) ids.add(sensorId);
|
if (StringUtils.hasText(sensorId)) ids.add(sensorId);
|
||||||
if (!ids.isEmpty()) return ids;
|
if (!ids.isEmpty()) return ids;
|
||||||
} catch (Exception ignored) {}
|
|
||||||
}
|
}
|
||||||
// 回退到从 extra_mapping 解析(直连设备等场景)
|
// 回退到从 extra_mapping 解析(直连设备等场景)
|
||||||
return collectSubDeviceSensorBindings(ctx.getDeviceMapping()).stream()
|
return collectSubDeviceSensorBindings(ctx.getDeviceMapping()).stream()
|
||||||
@ -567,7 +583,13 @@ public class PlatformFlowExecutor {
|
|||||||
List<PlatformDeviceSubMapping> suffix = collectCascadedSubDeviceSuffix(ctx);
|
List<PlatformDeviceSubMapping> suffix = collectCascadedSubDeviceSuffix(ctx);
|
||||||
Collections.reverse(suffix);
|
Collections.reverse(suffix);
|
||||||
List<String> sensorIds = suffix.stream()
|
List<String> sensorIds = suffix.stream()
|
||||||
.map(sub -> resolveOnboardSensorId(sub.getOnboardConfig(), sub.getSubSerialNumber()))
|
.map(sub -> {
|
||||||
|
OnboardConfig cfg = sub.getOnboardConfigParsed();
|
||||||
|
if (cfg != null && StringUtils.hasText(cfg.getSensorId())) {
|
||||||
|
return cfg.getSensorId();
|
||||||
|
}
|
||||||
|
return normalizeText(sub.getSubSerialNumber());
|
||||||
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (sensorIds.stream().anyMatch(id -> !StringUtils.hasText(id))) {
|
if (sensorIds.stream().anyMatch(id -> !StringUtils.hasText(id))) {
|
||||||
throw new RuntimeException("深部位移子设备缺少 sensorId");
|
throw new RuntimeException("深部位移子设备缺少 sensorId");
|
||||||
@ -634,14 +656,14 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object readSensorDepth(PlatformDeviceSubMapping mapping) {
|
private Object readSensorDepth(PlatformDeviceSubMapping mapping) {
|
||||||
if (mapping == null || !StringUtils.hasText(mapping.getOnboardConfig())) {
|
if (mapping == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
OnboardConfig config = mapping.getOnboardConfigParsed();
|
||||||
return JSON.parseObject(mapping.getOnboardConfig()).get("sensorDepth");
|
if (config == null) {
|
||||||
} catch (Exception e) {
|
return null;
|
||||||
throw new RuntimeException("子设备 " + mapping.getSubSerialNumber() + " 入网参数不是有效JSON");
|
|
||||||
}
|
}
|
||||||
|
return config.getSensorDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -650,12 +672,13 @@ public class PlatformFlowExecutor {
|
|||||||
*/
|
*/
|
||||||
private List<List<String>> collectReferenceSubDeviceSensorIdPairs(FlowContext ctx) {
|
private List<List<String>> collectReferenceSubDeviceSensorIdPairs(FlowContext ctx) {
|
||||||
if (StringUtils.hasText(ctx.getCurrentMonitorSerialNumber())) {
|
if (StringUtils.hasText(ctx.getCurrentMonitorSerialNumber())) {
|
||||||
String sensorId = resolveOnboardSensorId(
|
String sensorId = resolveOnboardSensorIdByCtx(ctx, false);
|
||||||
ctx.getSubMappingOnboardConfig(), ctx.getCurrentMonitorSerialNumber());
|
String refSensorId = resolveOnboardSensorIdByCtx(ctx, true);
|
||||||
String refSensorId = resolveOnboardSensorId(
|
|
||||||
ctx.getReferenceSubMappingOnboardConfig(), ctx.getCurrentReferenceSerialNumber());
|
|
||||||
if (!StringUtils.hasText(refSensorId)) {
|
if (!StringUtils.hasText(refSensorId)) {
|
||||||
refSensorId = resolveOnboardConfigText(ctx.getSubMappingOnboardConfig(), "refSensorId");
|
OnboardConfig currentConfig = resolveCurrentOnboardConfig(ctx);
|
||||||
|
if (currentConfig != null) {
|
||||||
|
refSensorId = currentConfig.getRefSensorId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (StringUtils.hasText(sensorId) && StringUtils.hasText(refSensorId)) {
|
if (StringUtils.hasText(sensorId) && StringUtils.hasText(refSensorId)) {
|
||||||
if (sameText(refSensorId, sensorId)) {
|
if (sameText(refSensorId, sensorId)) {
|
||||||
@ -672,17 +695,15 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 网关入网:onboardConfig 已指定当前监测点
|
// 网关入网:onboardConfig 已指定当前监测点
|
||||||
if (StringUtils.hasText(ctx.getSubMappingOnboardConfig())) {
|
OnboardConfig currentConfig = resolveCurrentOnboardConfig(ctx);
|
||||||
try {
|
if (currentConfig != null) {
|
||||||
JSONObject config = JSON.parseObject(ctx.getSubMappingOnboardConfig());
|
String sensorId = currentConfig.getSensorId();
|
||||||
String sensorId = config.getString("sensorId");
|
String refSensorId = currentConfig.getRefSensorId();
|
||||||
String refSensorId = config.getString("refSensorId");
|
|
||||||
if (StringUtils.hasText(sensorId) && StringUtils.hasText(refSensorId)) {
|
if (StringUtils.hasText(sensorId) && StringUtils.hasText(refSensorId)) {
|
||||||
List<List<String>> pairs = new ArrayList<>();
|
List<List<String>> pairs = new ArrayList<>();
|
||||||
pairs.add(Arrays.asList(refSensorId, sensorId));
|
pairs.add(Arrays.asList(refSensorId, sensorId));
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {}
|
|
||||||
}
|
}
|
||||||
// 回退:从 extra_mapping 解析(兼容直连设备场景)
|
// 回退:从 extra_mapping 解析(兼容直连设备场景)
|
||||||
PlatformDeviceMapping mapping = ctx.getDeviceMapping();
|
PlatformDeviceMapping mapping = ctx.getDeviceMapping();
|
||||||
@ -711,20 +732,52 @@ public class PlatformFlowExecutor {
|
|||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveOnboardSensorId(String onboardConfig, String fallbackSerialNumber) {
|
/** 获取当前监测点子设备的 OnboardConfig POJO */
|
||||||
String sensorId = resolveOnboardConfigText(onboardConfig, "sensorId");
|
private OnboardConfig resolveCurrentOnboardConfig(FlowContext ctx) {
|
||||||
return StringUtils.hasText(sensorId) ? sensorId : normalizeText(fallbackSerialNumber);
|
if (ctx.getCurrentMonitorIndex() != null && CollectionUtils.isNotEmpty(ctx.getMonitorSubMappings())) {
|
||||||
|
int index = ctx.getCurrentMonitorIndex();
|
||||||
|
return ctx.getMonitorSubMappings().get(index).getOnboardConfigParsed();
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(ctx.getSubMappingOnboardConfig())) {
|
||||||
|
return JSON.parseObject(ctx.getSubMappingOnboardConfig(), OnboardConfig.class);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveOnboardConfigText(String onboardConfig, String field) {
|
/**
|
||||||
if (!StringUtils.hasText(onboardConfig) || !StringUtils.hasText(field)) {
|
* 解析 sensorId:优先从子映射 OnboardConfig 获取,否则返回序列号
|
||||||
return null;
|
* @param ctx 上下文
|
||||||
|
* @param isReference true=基准点, false=监测点
|
||||||
|
*/
|
||||||
|
private String resolveOnboardSensorIdByCtx(FlowContext ctx, boolean isReference) {
|
||||||
|
String configStr = isReference ? ctx.getReferenceSubMappingOnboardConfig() : ctx.getSubMappingOnboardConfig();
|
||||||
|
String fallbackSn = isReference ? ctx.getCurrentReferenceSerialNumber() : ctx.getCurrentMonitorSerialNumber();
|
||||||
|
|
||||||
|
if (StringUtils.hasText(configStr)) {
|
||||||
|
OnboardConfig config = JSON.parseObject(configStr, OnboardConfig.class);
|
||||||
|
if (config != null && StringUtils.hasText(config.getSensorId())) {
|
||||||
|
return config.getSensorId();
|
||||||
}
|
}
|
||||||
try {
|
} else if (!isReference && ctx.getCurrentMonitorIndex() != null
|
||||||
JSONObject config = JSON.parseObject(onboardConfig);
|
&& CollectionUtils.isNotEmpty(ctx.getMonitorSubMappings())) {
|
||||||
return normalizeText(config.getString(field));
|
int index = ctx.getCurrentMonitorIndex();
|
||||||
} catch (Exception ignored) {
|
OnboardConfig config = ctx.getMonitorSubMappings().get(index).getOnboardConfigParsed();
|
||||||
return null;
|
if (config != null && StringUtils.hasText(config.getSensorId())) {
|
||||||
|
return config.getSensorId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return normalizeText(fallbackSn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 从 OnboardConfig POJO 按字段名取值 */
|
||||||
|
private String resolveOnboardConfigField(OnboardConfig config, String field) {
|
||||||
|
if (config == null || !StringUtils.hasText(field)) return null;
|
||||||
|
switch (field) {
|
||||||
|
case "sensorId": return config.getSensorId();
|
||||||
|
case "sensorDepth": return config.getSensorDepth();
|
||||||
|
case "refSerialNumber": return config.getRefSerialNumber();
|
||||||
|
case "refSensorId": return config.getRefSensorId();
|
||||||
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,28 +804,35 @@ public class PlatformFlowExecutor {
|
|||||||
|
|
||||||
private String appendConfiguredSubDeviceBindings(LinkedHashMap<String, SubDeviceSensorBinding> bindings,
|
private String appendConfiguredSubDeviceBindings(LinkedHashMap<String, SubDeviceSensorBinding> bindings,
|
||||||
PlatformDeviceMapping mapping) {
|
PlatformDeviceMapping mapping) {
|
||||||
if (!StringUtils.hasText(mapping.getExtraMapping())) {
|
ExtraMappingConfig extra = mapping.getExtraMappingParsed();
|
||||||
|
if (extra == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
JSONObject extra = JSON.parseObject(mapping.getExtraMapping());
|
|
||||||
String referenceSerialNumber = null;
|
String referenceSerialNumber = null;
|
||||||
|
|
||||||
JSONArray arrayFields = extra.getJSONArray("arrayFields");
|
List<ExtraMappingConfig.ArrayFieldConfig> arrayFields = extra.getArrayFields();
|
||||||
if (arrayFields != null) {
|
if (arrayFields != null) {
|
||||||
for (int i = 0; i < arrayFields.size(); i++) {
|
for (ExtraMappingConfig.ArrayFieldConfig arrayField : arrayFields) {
|
||||||
JSONObject arrayField = arrayFields.getJSONObject(i);
|
|
||||||
referenceSerialNumber = appendConfiguredMappingRows(bindings,
|
referenceSerialNumber = appendConfiguredMappingRows(bindings,
|
||||||
arrayField == null ? null : arrayField.getJSONArray("subDeviceMappings"),
|
arrayField == null ? null : arrayField.getSubDeviceMappings(),
|
||||||
referenceSerialNumber);
|
referenceSerialNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject staticLevel = extra.getJSONObject("staticLevel");
|
ExtraMappingConfig.StaticLevelConfig staticLevel = extra.getStaticLevel();
|
||||||
if (staticLevel != null) {
|
if (staticLevel != null) {
|
||||||
referenceSerialNumber = normalizeText(staticLevel.getString("referenceSerialNumber"));
|
referenceSerialNumber = normalizeText(staticLevel.getReferenceSerialNumber());
|
||||||
referenceSerialNumber = appendConfiguredMappingRows(
|
List<ExtraMappingConfig.SensorIdMapping> sensorIdMappings = staticLevel.getSensorIdMappings();
|
||||||
bindings, staticLevel.getJSONArray("sensorIdMappings"), referenceSerialNumber);
|
if (sensorIdMappings != null) {
|
||||||
|
for (ExtraMappingConfig.SensorIdMapping item : sensorIdMappings) {
|
||||||
|
if (item == null) continue;
|
||||||
|
String sn = normalizeText(item.getSerialNumber());
|
||||||
|
if (!StringUtils.hasText(sn)) continue;
|
||||||
|
String sid = normalizeText(item.getSensorId());
|
||||||
|
upsertSubDeviceBinding(bindings, sn, StringUtils.hasText(sid) ? sid : sn);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return referenceSerialNumber;
|
return referenceSerialNumber;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -783,24 +843,20 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String appendConfiguredMappingRows(LinkedHashMap<String, SubDeviceSensorBinding> bindings,
|
private String appendConfiguredMappingRows(LinkedHashMap<String, SubDeviceSensorBinding> bindings,
|
||||||
JSONArray mappings, String referenceSerialNumber) {
|
List<ExtraMappingConfig.SubDeviceMapping> mappings,
|
||||||
|
String referenceSerialNumber) {
|
||||||
if (mappings == null || mappings.isEmpty()) {
|
if (mappings == null || mappings.isEmpty()) {
|
||||||
return referenceSerialNumber;
|
return referenceSerialNumber;
|
||||||
}
|
}
|
||||||
String ref = referenceSerialNumber;
|
String ref = referenceSerialNumber;
|
||||||
for (int i = 0; i < mappings.size(); i++) {
|
for (ExtraMappingConfig.SubDeviceMapping item : mappings) {
|
||||||
JSONObject item = mappings.getJSONObject(i);
|
if (item == null) continue;
|
||||||
if (item == null) {
|
String serialNumber = normalizeText(item.getSerialNumber());
|
||||||
continue;
|
if (!StringUtils.hasText(serialNumber)) continue;
|
||||||
}
|
String sensorId = normalizeText(item.getSensorId());
|
||||||
String serialNumber = normalizeText(item.getString("serialNumber"));
|
|
||||||
if (!StringUtils.hasText(serialNumber)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String sensorId = normalizeText(item.getString("sensorId"));
|
|
||||||
upsertSubDeviceBinding(bindings, serialNumber,
|
upsertSubDeviceBinding(bindings, serialNumber,
|
||||||
StringUtils.hasText(sensorId) ? sensorId : serialNumber);
|
StringUtils.hasText(sensorId) ? sensorId : serialNumber);
|
||||||
if (Boolean.TRUE.equals(item.getBoolean("isReference"))) {
|
if (Boolean.TRUE.equals(item.getIsReference())) {
|
||||||
ref = serialNumber;
|
ref = serialNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -925,13 +981,7 @@ public class PlatformFlowExecutor {
|
|||||||
|
|
||||||
/** 移除已替换到路径中的变量,避免重复放入 body */
|
/** 移除已替换到路径中的变量,避免重复放入 body */
|
||||||
private void removePathVars(Map<String, Object> params, String path) {
|
private void removePathVars(Map<String, Object> params, String path) {
|
||||||
Iterator<Map.Entry<String, Object>> it = params.entrySet().iterator();
|
params.entrySet().removeIf(e -> path.contains("{" + e.getKey() + "}"));
|
||||||
while (it.hasNext()) {
|
|
||||||
Map.Entry<String, Object> e = it.next();
|
|
||||||
if (path.contains("{" + e.getKey() + "}")) {
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object buildResponseData(PlatformInterface iface, String responseBody) {
|
private Object buildResponseData(PlatformInterface iface, String responseBody) {
|
||||||
@ -973,19 +1023,18 @@ public class PlatformFlowExecutor {
|
|||||||
|
|
||||||
private JSONObject extractResponseBySchema(PlatformInterface iface, Object parsedResponse) {
|
private JSONObject extractResponseBySchema(PlatformInterface iface, Object parsedResponse) {
|
||||||
JSONObject extracted = new JSONObject();
|
JSONObject extracted = new JSONObject();
|
||||||
if (iface == null || !StringUtils.hasText(iface.getResponseSchema()) || parsedResponse == null) {
|
List<ResponseSchemaField> schema = iface.getResponseSchemaParsed();
|
||||||
|
if (schema == null || schema.isEmpty() || parsedResponse == null) {
|
||||||
return extracted;
|
return extracted;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
JSONArray schema = JSON.parseArray(iface.getResponseSchema());
|
for (ResponseSchemaField field : schema) {
|
||||||
for (int i = 0; i < schema.size(); i++) {
|
if (field == null || !StringUtils.hasText(field.getName())) {
|
||||||
JSONObject field = schema.getJSONObject(i);
|
|
||||||
if (field == null || !StringUtils.hasText(field.getString("name"))) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Object value = readPathValue(parsedResponse, field.getString("path"));
|
Object value = readPathValue(parsedResponse, field.getPath());
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
extracted.put(field.getString("name"), value);
|
extracted.put(field.getName(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1101,14 +1150,15 @@ public class PlatformFlowExecutor {
|
|||||||
*/
|
*/
|
||||||
private void persistResultSave(PlatformFlowStep step, Object responseData, FlowContext context) {
|
private void persistResultSave(PlatformFlowStep step, Object responseData, FlowContext context) {
|
||||||
try {
|
try {
|
||||||
JSONArray saves = JSON.parseArray(step.getResultSave());
|
List<ResultSaveField> saves = step.getResultSaveParsed();
|
||||||
|
if (saves == null || saves.isEmpty()) return;
|
||||||
JSONObject response = toJsonObject(responseData);
|
JSONObject response = toJsonObject(responseData);
|
||||||
if (response == null) return;
|
if (response == null) return;
|
||||||
//PlatformInstance platform = context.getPlatform();
|
|
||||||
PlatformUserAuth userAuth = context.getPlatformUserAuth();
|
PlatformUserAuth userAuth = context.getPlatformUserAuth();
|
||||||
|
|
||||||
JSONObject extra = StringUtils.hasText(userAuth.getExtraConfig())
|
JSONObject extra = userAuth.getExtraConfigParsed();
|
||||||
? JSON.parseObject(userAuth.getExtraConfig()) : new JSONObject();
|
if (extra == null) extra = new JSONObject();
|
||||||
boolean extraChanged = false;
|
boolean extraChanged = false;
|
||||||
boolean userAuthFieldChanged = false;
|
boolean userAuthFieldChanged = false;
|
||||||
// 平台用户授权信息(token、userId)
|
// 平台用户授权信息(token、userId)
|
||||||
@ -1119,10 +1169,9 @@ public class PlatformFlowExecutor {
|
|||||||
// 保存平台映射关系(测点ID、设备ID)
|
// 保存平台映射关系(测点ID、设备ID)
|
||||||
PlatformDeviceMapping mappingUpdate = new PlatformDeviceMapping();
|
PlatformDeviceMapping mappingUpdate = new PlatformDeviceMapping();
|
||||||
|
|
||||||
for (int i = 0; i < saves.size(); i++) {
|
for (ResultSaveField save : saves) {
|
||||||
JSONObject save = saves.getJSONObject(i);
|
String field = save.getField();
|
||||||
String field = save.getString("field");
|
String saveTo = save.getSaveTo();
|
||||||
String saveTo = save.getString("saveTo");
|
|
||||||
Object value = response.get(field);
|
Object value = response.get(field);
|
||||||
if (value == null || saveTo == null) continue;
|
if (value == null || saveTo == null) continue;
|
||||||
|
|
||||||
@ -1185,6 +1234,7 @@ public class PlatformFlowExecutor {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("[PlatformFlow] persistResultSave 失败: {}", e.getMessage());
|
log.warn("[PlatformFlow] persistResultSave 失败: {}", e.getMessage());
|
||||||
|
throw new RuntimeException("执行流程❌,保存数据失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,62 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformDeviceMapping;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformDeviceMapping#extraMapping POJO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ExtraMappingConfig implements Serializable {
|
||||||
|
|
||||||
|
/** 覆盖推送接口中的数组字段名 */
|
||||||
|
private String fieldName;
|
||||||
|
|
||||||
|
/** 数组模式:single / reference_pair */
|
||||||
|
private String arrayMode;
|
||||||
|
|
||||||
|
/** 静力水准缓存超时秒数 */
|
||||||
|
private Integer reportIntervalSec;
|
||||||
|
|
||||||
|
/** 数组项字段映射 */
|
||||||
|
private List<ItemFieldMapping> itemFieldMappings;
|
||||||
|
|
||||||
|
/** 批量推送数组字段子设备映射配置 */
|
||||||
|
private List<ArrayFieldConfig> arrayFields;
|
||||||
|
|
||||||
|
/** 静力水准配置 */
|
||||||
|
private StaticLevelConfig staticLevel;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ItemFieldMapping implements Serializable {
|
||||||
|
private String identifier;
|
||||||
|
private String platformField;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ArrayFieldConfig implements Serializable {
|
||||||
|
private List<SubDeviceMapping> subDeviceMappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class SubDeviceMapping implements Serializable {
|
||||||
|
private String serialNumber;
|
||||||
|
private String sensorId;
|
||||||
|
private Boolean isReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class StaticLevelConfig implements Serializable {
|
||||||
|
private String referenceSerialNumber;
|
||||||
|
private List<SensorIdMapping> sensorIdMappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class SensorIdMapping implements Serializable {
|
||||||
|
private String serialNumber;
|
||||||
|
private String sensorId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformDeviceMapping;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformDeviceMapping.fieldMapping 字段定义 POJO:{identifier, platformField, transform}
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class FieldMappingItem implements Serializable {
|
||||||
|
|
||||||
|
/** 物模型标识符 */
|
||||||
|
private String identifier;
|
||||||
|
|
||||||
|
/** 平台侧字段名 */
|
||||||
|
private String platformField;
|
||||||
|
|
||||||
|
/** 转换方式(可选) */
|
||||||
|
private String transform;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformDeviceSubMapping;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformDeviceSubMapping.onboardConfig POJO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OnboardConfig implements Serializable {
|
||||||
|
|
||||||
|
/** 平台传感器 ID */
|
||||||
|
private String sensorId;
|
||||||
|
|
||||||
|
/** 传感器深度 */
|
||||||
|
private String sensorDepth;
|
||||||
|
|
||||||
|
/** 基准点序列号 */
|
||||||
|
private String refSerialNumber;
|
||||||
|
|
||||||
|
/** 基准点传感器 ID */
|
||||||
|
private String refSensorId;
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformFlowStep;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformFlowStep.paramMapping POJO
|
||||||
|
* <p>
|
||||||
|
* JSON 结构为 Map,key 为字段名,value 为参数覆盖定义:
|
||||||
|
* { "grant_type": {"source": "fixed", "value": "password"}, ... }
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ParamOverrideConfig implements Serializable {
|
||||||
|
|
||||||
|
/** 值来源:fixed/auth/extra/context 等 */
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
/** 类型:string/number 等 */
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/** source=auth/extra 时的子字段名 */
|
||||||
|
private String field;
|
||||||
|
|
||||||
|
/** source=fixed 时的固定值 */
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
/** source=context 时的上下文 key */
|
||||||
|
private String contextKey;
|
||||||
|
|
||||||
|
/** source=thingsModel 时的物模型标识符 */
|
||||||
|
private String identifier;
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformInterface;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformInterface.requestSchema 字段定义 POJO
|
||||||
|
* 支持 14 种 source 类型和递归嵌套的 itemSchema
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RequestSchemaField implements Serializable {
|
||||||
|
|
||||||
|
/** 字段名(出参 key) */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 值来源:fixed/auth/extra/device/thingsModel/ts/context/uuid/onboard_config/等 */
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
/** 字段类型:string/number/boolean/array */
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/** source=fixed 时的固定值 */
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
/** source=auth/extra/device 时的子字段名 */
|
||||||
|
private String field;
|
||||||
|
|
||||||
|
/** source=context 时的上下文 key */
|
||||||
|
private String contextKey;
|
||||||
|
|
||||||
|
/** source=thingsModel 时的物模型标识符 */
|
||||||
|
private String identifier;
|
||||||
|
|
||||||
|
/** type=array 时的数组成员 schema */
|
||||||
|
@JSONField(name = "itemSchema")
|
||||||
|
private List<RequestSchemaField> itemSchema;
|
||||||
|
|
||||||
|
/** type=array 时的数组模式:single/reference_pair */
|
||||||
|
private String arrayMode;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformInterface;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformInterface.responseSchema 字段定义 POJO:{name, path}
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ResponseSchemaField implements Serializable {
|
||||||
|
|
||||||
|
/** 存储到 FlowContext 的 key 名 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** JSON path 表达式,如 $.data.id、data[0].deviceId */
|
||||||
|
private String path;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.fastbee.iot.platform.model.json;
|
||||||
|
|
||||||
|
import com.fastbee.iot.platform.domain.PlatformFlowStep;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PlatformFlowStep.resultSave 字段定义 POJO:{field, saveTo}
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ResultSaveField implements Serializable {
|
||||||
|
|
||||||
|
/** 响应中的字段名 */
|
||||||
|
private String field;
|
||||||
|
|
||||||
|
/** 保存目标,如 platform_user_auth.access_token、device_mapping.platform_device_id、extra_config.projectId */
|
||||||
|
private String saveTo;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user