From 24681c81c09022f584a57006f2534b5f74723414 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 30 六月 2026 09:27:31 +0800
Subject: [PATCH] 初始化项目

---
 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java |  252 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 252 insertions(+), 0 deletions(-)

diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
index 4a8b974..9029960 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
@@ -1,10 +1,16 @@
 package cn.iocoder.yudao.module.iot.service.thingmodel;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO;
 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO;
@@ -12,9 +18,14 @@
 import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert;
 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelBoolOrEnumDataSpecs;
+import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs;
+import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
 import cn.iocoder.yudao.module.iot.dal.mysql.thingmodel.IotThingModelMapper;
 import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum;
+import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField;
 import cn.iocoder.yudao.module.iot.service.device.IotDeviceModbusPointService;
 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
 import jakarta.annotation.Resource;
@@ -26,7 +37,15 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZonedDateTime;
 import java.util.Collection;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -166,6 +185,239 @@
         }
     }
 
+    @Override
+    public Object convertThingModelPropertyValue(IotThingModelDO thingModel, Object value) {
+        if (thingModel == null || thingModel.getProperty() == null || value == null) {
+            return null;
+        }
+        String dataType = thingModel.getProperty().getDataType();
+        if (ObjectUtils.equalsAny(dataType,
+                IotDataSpecsDataTypeEnum.STRUCT.getDataType(), IotDataSpecsDataTypeEnum.ARRAY.getDataType())) {
+            // 鐗规畩锛歋TRUCT 鍜� ARRAY 绫诲瀷锛屽湪 TDengine 閲岋紝娌℃湁瀵瑰簲鏁版嵁绫诲瀷锛屽彧鑳介�氳繃 JSON 鏉ュ瓨鍌�
+            return convertToVarchar(JsonUtils.toJsonString(value), TDengineTableField.LENGTH_VARCHAR);
+        }
+        if (IotDataSpecsDataTypeEnum.INT.getDataType().equals(dataType)) {
+            return convertToInt(value);
+        }
+        if (IotDataSpecsDataTypeEnum.FLOAT.getDataType().equals(dataType)) {
+            return convertToFloat(value);
+        }
+        if (IotDataSpecsDataTypeEnum.DOUBLE.getDataType().equals(dataType)) {
+            return convertToDouble(value);
+        }
+        if (IotDataSpecsDataTypeEnum.ENUM.getDataType().equals(dataType)) {
+            return convertEnumToTinyInt(thingModel, value);
+        }
+        if (IotDataSpecsDataTypeEnum.BOOL.getDataType().equals(dataType)) {
+            return convertBoolToTinyInt(value);
+        }
+        if (IotDataSpecsDataTypeEnum.TEXT.getDataType().equals(dataType)) {
+            return convertToVarchar(Convert.toStr(value), getTextLength(thingModel));
+        }
+        if (IotDataSpecsDataTypeEnum.DATE.getDataType().equals(dataType)) {
+            return convertToTimestamp(value);
+        }
+        return null;
+    }
+
+    private Integer getTextLength(IotThingModelDO thingModel) {
+        ThingModelDataSpecs dataSpecs = thingModel.getProperty().getDataSpecs();
+        if (!(dataSpecs instanceof ThingModelDateOrTextDataSpecs)) {
+            return null;
+        }
+        return ((ThingModelDateOrTextDataSpecs) dataSpecs).getLength();
+    }
+
+    private String convertToVarchar(String value, Integer length) {
+        if (value == null) {
+            return null;
+        }
+        if (length != null && value.getBytes(StandardCharsets.UTF_8).length > length) {
+            return null;
+        }
+        return value;
+    }
+
+    private Integer convertToInt(Object value) {
+        BigDecimal decimal = convertToBigDecimal(value);
+        if (decimal == null) {
+            return null;
+        }
+        try {
+            return decimal.intValueExact();
+        } catch (ArithmeticException e) {
+            return null;
+        }
+    }
+
+    private Float convertToFloat(Object value) {
+        BigDecimal decimal = convertToBigDecimal(value);
+        if (decimal == null) {
+            return null;
+        }
+        float result = decimal.floatValue();
+        return Float.isFinite(result) ? result : null;
+    }
+
+    private Double convertToDouble(Object value) {
+        BigDecimal decimal = convertToBigDecimal(value);
+        if (decimal == null) {
+            return null;
+        }
+        double result = decimal.doubleValue();
+        return Double.isFinite(result) ? result : null;
+    }
+
+    private BigDecimal convertToBigDecimal(Object value) {
+        if (value instanceof Boolean) {
+            return null;
+        }
+        String text = Convert.toStr(value);
+        if (StrUtil.isBlank(text)) {
+            return null;
+        }
+        try {
+            return new BigDecimal(text);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+
+    private Byte convertEnumToTinyInt(IotThingModelDO thingModel, Object value) {
+        Integer intValue = convertToInt(value);
+        if (intValue == null && value instanceof CharSequence) {
+            intValue = getEnumValueByName(thingModel, value.toString());
+        }
+        if (intValue == null || !isTinyInt(intValue)) {
+            return null;
+        }
+        if (CollUtil.isNotEmpty(thingModel.getProperty().getDataSpecsList())
+                && getEnumDataSpecsByValue(thingModel, intValue) == null) {
+            return null;
+        }
+        return intValue.byteValue();
+    }
+
+    private Integer getEnumValueByName(IotThingModelDO thingModel, String name) {
+        ThingModelBoolOrEnumDataSpecs dataSpecs = getEnumDataSpecsByName(thingModel, name);
+        return dataSpecs != null ? dataSpecs.getValue() : null;
+    }
+
+    private ThingModelBoolOrEnumDataSpecs getEnumDataSpecsByName(IotThingModelDO thingModel, String name) {
+        if (CollUtil.isEmpty(thingModel.getProperty().getDataSpecsList())) {
+            return null;
+        }
+        for (ThingModelDataSpecs dataSpecs : thingModel.getProperty().getDataSpecsList()) {
+            if (!(dataSpecs instanceof ThingModelBoolOrEnumDataSpecs)) {
+                continue;
+            }
+            ThingModelBoolOrEnumDataSpecs enumDataSpecs = (ThingModelBoolOrEnumDataSpecs) dataSpecs;
+            if (StrUtil.equals(enumDataSpecs.getName(), name)) {
+                return enumDataSpecs;
+            }
+        }
+        return null;
+    }
+
+    private ThingModelBoolOrEnumDataSpecs getEnumDataSpecsByValue(IotThingModelDO thingModel, Integer value) {
+        if (CollUtil.isEmpty(thingModel.getProperty().getDataSpecsList())) {
+            return null;
+        }
+        for (ThingModelDataSpecs dataSpecs : thingModel.getProperty().getDataSpecsList()) {
+            if (!(dataSpecs instanceof ThingModelBoolOrEnumDataSpecs)) {
+                continue;
+            }
+            ThingModelBoolOrEnumDataSpecs enumDataSpecs = (ThingModelBoolOrEnumDataSpecs) dataSpecs;
+            if (Objects.equals(enumDataSpecs.getValue(), value)) {
+                return enumDataSpecs;
+            }
+        }
+        return null;
+    }
+
+    private Byte convertBoolToTinyInt(Object value) {
+        if (value instanceof Boolean) {
+            return (Boolean) value ? (byte) 1 : (byte) 0;
+        }
+        if (value instanceof CharSequence) {
+            String text = StrUtil.trim(value.toString());
+            if (StrUtil.equalsIgnoreCase(text, "true")) {
+                return (byte) 1;
+            }
+            if (StrUtil.equalsIgnoreCase(text, "false")) {
+                return (byte) 0;
+            }
+        }
+        Integer intValue = convertToInt(value);
+        if (intValue == null || (intValue != 0 && intValue != 1)) {
+            return null;
+        }
+        return intValue.byteValue();
+    }
+
+    private boolean isTinyInt(Integer value) {
+        return value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE;
+    }
+
+    private Long convertToTimestamp(Object value) {
+        if (value instanceof LocalDateTime) {
+            return LocalDateTimeUtil.toEpochMilli((LocalDateTime) value);
+        }
+        if (value instanceof LocalDate) {
+            return LocalDateTimeUtil.toEpochMilli(((LocalDate) value).atStartOfDay());
+        }
+        if (value instanceof Instant) {
+            return ((Instant) value).toEpochMilli();
+        }
+        if (value instanceof OffsetDateTime) {
+            return ((OffsetDateTime) value).toInstant().toEpochMilli();
+        }
+        if (value instanceof ZonedDateTime) {
+            return ((ZonedDateTime) value).toInstant().toEpochMilli();
+        }
+        if (value instanceof Date) {
+            return ((Date) value).getTime();
+        }
+        Long timestamp = convertToLong(value);
+        if (timestamp != null) {
+            return timestamp;
+        }
+        if (!(value instanceof CharSequence)) {
+            return null;
+        }
+        String text = StrUtil.trim(value.toString());
+        if (StrUtil.isBlank(text)) {
+            return null;
+        }
+        try {
+            return OffsetDateTime.parse(text).toInstant().toEpochMilli();
+        } catch (Exception ignored) {
+            // 灏濊瘯鏈湴鏃堕棿鏍煎紡锛屼緥濡� yyyy-MM-dd HH:mm:ss
+        }
+        try {
+            return LocalDateTimeUtil.toEpochMilli(LocalDateTimeUtil.parse(text, DatePattern.NORM_DATETIME_PATTERN));
+        } catch (Exception ignored) {
+            // 灏濊瘯鍏跺畠 Hutool 鏀寔鐨勬湰鍦版椂闂存牸寮�
+        }
+        try {
+            return LocalDateTimeUtil.toEpochMilli(LocalDateTimeUtils.parse(text));
+        } catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    private Long convertToLong(Object value) {
+        BigDecimal decimal = convertToBigDecimal(value);
+        if (decimal == null) {
+            return null;
+        }
+        try {
+            return decimal.longValueExact();
+        } catch (ArithmeticException e) {
+            return null;
+        }
+    }
+
     private void validateProductThingModelMapperExists(Long id) {
         if (thingModelMapper.selectById(id) == null) {
             throw exception(THING_MODEL_NOT_EXISTS);

--
Gitblit v1.9.3