TRX 1 год назад
Родитель
Сommit
5a418a5de4
22 измененных файлов с 637 добавлено и 74 удалено
  1. 46 0
      OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplate2DeviceModel.java
  2. 27 0
      OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplate2DeviceParam.java
  3. 29 0
      OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplate2DeviceSearch.java
  4. 7 1
      OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplateModel.java
  5. 4 0
      OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/mqtt/DeviceInfoAddParam.java
  6. 28 3
      OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/mqtt/DeviceInfoModel.java
  7. 58 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/controller/iot/IotTemplate2DeviceController.java
  8. 1 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/base/BaseImpl.java
  9. 21 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/IotTemplate2DeviceDao.java
  10. 17 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/extend/IotTemplate2DeviceDaoExtend.java
  11. 75 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/impl/IotTemplate2DeviceDaoImpl.java
  12. 5 2
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/IotMain.java
  13. 4 1
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/IotTemplate.java
  14. 48 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/IotTemplate2Device.java
  15. 7 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/DeviceInfo.java
  16. 3 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/GateWayInfo.java
  17. 3 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/Mqtt2User.java
  18. 46 17
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/iot/IotServiceImpl.java
  19. 145 0
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/iot/IotTemplate2DeviceService.java
  20. 4 3
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/mqtt/DeviceInfoService.java
  21. 0 2
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/sync/DeviceSyncFullCardService.java
  22. 59 45
      OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/util/test/Test153AddUser.java

+ 46 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplate2DeviceModel.java

@@ -0,0 +1,46 @@
+package com.zhongshu.iot.client.model.iot;
+
+import com.github.microservice.models.type.DeviceType;
+import com.zhongshu.iot.client.model.baseParam.SuperModel;
+import com.zhongshu.iot.client.model.mqtt.DeviceInfoModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author TRX
+ * @date 2025/1/8
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class IotTemplate2DeviceModel extends SuperModel {
+
+    @Schema(description = "物模型ID")
+    private String templateId;
+
+    @Schema(description = "物模型名称")
+    private String templateName;
+
+    @Schema(description = "物模型所属模版ID,就是管理设备时绑定的模版")
+    private String iotTemplateId;
+
+    @Schema(description = "设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备分类")
+    private DeviceType deviceType;
+
+    private String deviceTypeStr;
+
+    public String getDeviceTypeStr() {
+        if (deviceType != null) {
+            return deviceType.getRemark();
+        }
+        return "";
+    }
+
+    @Schema(description = "设备信息")
+    private DeviceInfoModel deviceInfo;
+}

+ 27 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplate2DeviceParam.java

@@ -0,0 +1,27 @@
+package com.zhongshu.iot.client.model.iot;
+
+import com.zhongshu.iot.client.model.baseParam.SuperParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author TRX
+ * @date 2025/1/8
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class IotTemplate2DeviceParam extends SuperParam {
+
+    @Schema(description = "模版id")
+    private String iotTemplateId;
+
+    @Schema(description = "设备ID结合")
+    private List<String> deviceIds = new ArrayList<>();
+
+}

+ 29 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplate2DeviceSearch.java

@@ -0,0 +1,29 @@
+package com.zhongshu.iot.client.model.iot;
+
+import com.github.microservice.models.type.DeviceType;
+import com.zhongshu.iot.client.model.baseParam.SuperSearchParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author TRX
+ * @date 2025/1/8
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class IotTemplate2DeviceSearch extends SuperSearchParam {
+
+    @Schema(description = "模版id")
+    private String iotTemplateId;
+
+    @Schema(description = "设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备分类")
+    private DeviceType deviceType;
+
+
+}

+ 7 - 1
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotTemplateModel.java

@@ -8,6 +8,9 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @author TRX
  * @date 2024/6/20
@@ -15,7 +18,7 @@ import lombok.NoArgsConstructor;
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
-public class IotTemplateModel  extends SuperModel {
+public class IotTemplateModel extends SuperModel {
     @Schema(description = "模版名称")
     private String name;
 
@@ -28,6 +31,9 @@ public class IotTemplateModel  extends SuperModel {
     @Schema(description = "关联的设备")
     private String deviceId;
 
+    @Schema(description = "关联的设备")
+    private List<String> deviceIds = new ArrayList<>();
+
     @Schema(description = "所属分组code")
     private String projectCode;
 

+ 4 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/mqtt/DeviceInfoAddParam.java

@@ -1,6 +1,7 @@
 package com.zhongshu.iot.client.model.mqtt;
 
 import cn.hutool.json.JSONObject;
+import com.github.microservice.models.type.DeviceModel;
 import com.github.microservice.models.type.DeviceType;
 import com.zhongshu.iot.client.model.baseParam.SuperParam;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -22,6 +23,9 @@ public class DeviceInfoAddParam extends SuperParam {
     @Schema(description = "设备类型:消费机 闸机")
     private DeviceType deviceType;
 
+    @Schema(description = "设备型号")
+    private DeviceModel deviceModel;
+
     @Schema(description = "ip地址")
     private String ip;
 

+ 28 - 3
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/mqtt/DeviceInfoModel.java

@@ -1,9 +1,10 @@
 package com.zhongshu.iot.client.model.mqtt;
 
 import cn.hutool.json.JSONObject;
+import com.github.microservice.models.type.DeviceModel;
+import com.github.microservice.models.type.DeviceType;
 import com.github.microservice.models.type.OnLineState;
 import com.zhongshu.iot.client.model.baseParam.SuperModel;
-import com.zhongshu.iot.client.model.iot.IotTemplateModel;
 import com.zhongshu.iot.client.type.DataState;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -33,6 +34,30 @@ public class DeviceInfoModel extends SuperModel {
         return "";
     }
 
+    @Schema(description = "设备型号")
+    private DeviceModel deviceModel;
+
+    private String deviceModelStr;
+
+    public String getDeviceModelStr() {
+        if (deviceModel != null) {
+            return deviceModel.getRemark();
+        }
+        return "";
+    }
+
+    @Schema(description = "设备类型:消费机 闸机")
+    private DeviceType deviceType;
+
+    private String deviceTypeStr;
+
+    public String getDeviceTypeStr() {
+        if (deviceType != null) {
+            return deviceType.getRemark();
+        }
+        return "";
+    }
+
     @Schema(description = "数据状态")
     private DataState state;
 
@@ -72,6 +97,6 @@ public class DeviceInfoModel extends SuperModel {
     @Schema(description = "设备本地日志上报")
     private Boolean isReportLogs = Boolean.TRUE;
 
-    @Schema(description = "物联网模版信息")
-    private IotTemplateModel iotTemplate;
+//    @Schema(description = "物联网模版信息")
+//    private IotTemplateModel iotTemplate;
 }

+ 58 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/controller/iot/IotTemplate2DeviceController.java

@@ -0,0 +1,58 @@
+package com.zhongshu.iot.server.core.controller.iot;
+
+import com.github.microservice.auth.security.annotations.ResourceAuth;
+import com.github.microservice.auth.security.type.AuthType;
+import com.github.microservice.net.ResultContent;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceModel;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceParam;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceSearch;
+import com.zhongshu.iot.server.core.service.iot.IotTemplate2DeviceService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 模版绑定的 设备管理
+ *
+ * @author TRX
+ * @date 2024/3/21
+ */
+@RequestMapping("/iotTemplate2Device")
+@RestController
+@Validated
+@Tag(name = "模版-绑定设备管理")
+public class IotTemplate2DeviceController {
+
+    @Autowired
+    private IotTemplate2DeviceService iotTemplate2DeviceService;
+
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "模版绑定设备")
+    @RequestMapping(value = "templateBindDevices", method = {RequestMethod.POST})
+    public ResultContent templateBindDevices(@RequestBody IotTemplate2DeviceParam param) {
+        return iotTemplate2DeviceService.templateBindDevices(param);
+    }
+
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "模版设备列表-分页查询")
+    @RequestMapping(value = {"page"}, method = {RequestMethod.POST})
+    public ResultContent<Page<IotTemplate2DeviceModel>> pageTemplate(
+            @Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+            @Parameter(required = false) IotTemplate2DeviceSearch param) {
+        return iotTemplate2DeviceService.page(pageable, param);
+    }
+
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "删除模版绑定设备")
+    @RequestMapping(value = "delete", method = {RequestMethod.GET})
+    public ResultContent delete(@RequestParam(name = "id") @Parameter(name = "id", description = "数据id") String id) {
+        return iotTemplate2DeviceService.delete(id);
+    }
+
+}

+ 1 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/base/BaseImpl.java

@@ -27,6 +27,7 @@ public abstract class BaseImpl {
     public Criteria buildCriteriaAboutTime(SuperSearchParam param) {
         Criteria criteria = new Criteria();
         criteria.and("isDelete").ne(Boolean.TRUE);
+
         if (!CommonUtil.longIsEmpty(param.getStartTime()) && !CommonUtil.longIsEmpty(param.getEndTime())) {
             criteria.and("createTime").gte(param.getStartTime()).lte(param.getEndTime());
         } else if (!CommonUtil.longIsEmpty(param.getStartTime()) && CommonUtil.longIsEmpty(param.getEndTime())) {

+ 21 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/IotTemplate2DeviceDao.java

@@ -0,0 +1,21 @@
+package com.zhongshu.iot.server.core.dao.iot;
+
+import com.zhongshu.iot.server.core.dao.iot.extend.IotTemplate2DeviceDaoExtend;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate2Device;
+import com.zhongshu.iot.server.core.domain.iot.mqtt.DeviceInfo;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+/**
+ * @author TRX
+ * @date 2024/3/21
+ */
+public interface IotTemplate2DeviceDao extends IotTemplate2DeviceDaoExtend, MongoRepository<IotTemplate2Device, String> {
+
+    IotTemplate2Device findTopById(String id);
+
+    IotTemplate2Device findTopByTemplateIdAndDeviceId(String templateId, String deviceId);
+
+    IotTemplate2Device findTopByIotTemplateAndDeviceInfo(IotTemplate iotTemplate, DeviceInfo deviceInfo);
+
+}

+ 17 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/extend/IotTemplate2DeviceDaoExtend.java

@@ -0,0 +1,17 @@
+package com.zhongshu.iot.server.core.dao.iot.extend;
+
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceSearch;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate2Device;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+/**
+ * @Author TRX
+ * @CreateDate: 2023/7/7
+ * @Version: 1.0
+ */
+public interface IotTemplate2DeviceDaoExtend {
+
+    Page<IotTemplate2Device> page(Pageable pageable, IotTemplate2DeviceSearch param);
+
+}

+ 75 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/impl/IotTemplate2DeviceDaoImpl.java

@@ -0,0 +1,75 @@
+package com.zhongshu.iot.server.core.dao.iot.impl;
+
+import com.github.microservice.components.data.mongo.mongo.helper.DBHelper;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceSearch;
+import com.zhongshu.iot.server.core.dao.base.BaseImpl;
+import com.zhongshu.iot.server.core.dao.iot.extend.IotTemplate2DeviceDaoExtend;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate2Device;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * @Author TRX
+ * @CreateDate: 2023/4/12
+ * @Version: 1.0
+ */
+@Slf4j
+public class IotTemplate2DeviceDaoImpl extends BaseImpl implements IotTemplate2DeviceDaoExtend {
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    @Autowired
+    private DBHelper dbHelper;
+
+    @Override
+    public Page<IotTemplate2Device> page(Pageable pageable, IotTemplate2DeviceSearch param) {
+        Criteria criteria = buildCriteriaAboutTime(param);
+
+        if (StringUtils.isNotEmpty(param.getIotTemplateId())) {
+            criteria.and("iotTemplateId").is(param.getIotTemplateId());
+        }
+
+        if (param.getDeviceType() != null) {
+            criteria.and("deviceType").is(param.getDeviceType());
+        }
+
+        // 模糊搜索
+        List<Criteria> criterias = new ArrayList<>();
+        if (StringUtils.isNotEmpty(param.getDeviceId())) {
+            Pattern pattern = Pattern.compile("^.*" + param.getDeviceId() + ".*$");
+            criterias.add(Criteria.where("deviceId").is(pattern));
+        }
+        if (!CollectionUtils.isEmpty(criterias)) {
+            criteria.andOperator(criterias.toArray(new Criteria[]{}));
+        }
+
+        // 关键字搜索
+//        if (StringUtils.isNotEmpty(param.getKeyWord())) {
+//            Pattern pattern = Pattern.compile("^.*" + param.getKeyWord() + ".*$");
+//            criteria.orOperator(
+//                    Criteria.where("name").regex(pattern),
+//                    Criteria.where("identifier").regex(pattern),
+//                    Criteria.where("iotTopic").regex(pattern)
+//            );
+//        }
+
+        Sort sort = buildSort(param);
+        Query query = Query.query(criteria);
+        query.with(sort);
+        return dbHelper.pages(query, pageable, IotTemplate2Device.class);
+    }
+
+}

+ 5 - 2
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/IotMain.java

@@ -1,10 +1,10 @@
 package com.zhongshu.iot.server.core.domain.iot;
 
+import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.model.iot.IotAttribute;
 import com.zhongshu.iot.client.model.iot.IotDict;
 import com.zhongshu.iot.client.type.DataType;
 import com.zhongshu.iot.client.type.EventType;
-import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.type.IotDataType;
 import com.zhongshu.iot.server.core.domain.base.SuperEntity;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -29,6 +29,9 @@ import java.util.List;
 @AllArgsConstructor
 public class IotMain extends SuperEntity {
 
+    @Schema(description = "模版id")
+    private String iotMainTemplateId;
+
     // ------------------------iotMain 基础字段 start-----------------------
 
     @Schema(description = "功能类型,属性 事件 服务")
@@ -49,7 +52,7 @@ public class IotMain extends SuperEntity {
     @Schema(description = "真实的topic")
     private String realIotTopic;
 
-    @Schema(description = "所属模版")
+    @Schema(description = "所属模版、物模型")
     @DBRef(lazy = true)
     private IotTemplate iotTemplate;
 

+ 4 - 1
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/IotTemplate.java

@@ -9,8 +9,11 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.springframework.data.mongodb.core.mapping.Document;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
- * 物模型 模版
+ * 物模型 模版 或  物模型 数据
  *
  * @author TRX
  * @date 2024/6/20

+ 48 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/IotTemplate2Device.java

@@ -0,0 +1,48 @@
+package com.zhongshu.iot.server.core.domain.iot;
+
+import com.github.microservice.models.type.DeviceType;
+import com.zhongshu.iot.server.core.domain.base.SuperEntity;
+import com.zhongshu.iot.server.core.domain.iot.mqtt.DeviceInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+/**
+ * 物模型 和 设备的关系
+ *
+ * @author TRX
+ * @date 2024/6/20
+ */
+@Data
+@Document
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotTemplate2Device extends SuperEntity {
+
+    @Schema(description = "物模型ID")
+    private String templateId;
+
+    @Schema(description = "物模型名称")
+    private String templateName;
+
+    @DBRef(lazy = true)
+    @Schema(description = "所属物模型")
+    private IotTemplate iotTemplate;
+
+    @Schema(description = "物模型所属模版ID,就是管理设备时绑定的模版")
+    private String iotTemplateId;
+
+    @Schema(description = "设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备分类")
+    private DeviceType deviceType;
+
+    @DBRef(lazy = true)
+    @Schema(description = "所属设备信息")
+    private DeviceInfo deviceInfo;
+
+}

+ 7 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/DeviceInfo.java

@@ -1,6 +1,7 @@
 package com.zhongshu.iot.server.core.domain.iot.mqtt;
 
 import cn.hutool.json.JSONObject;
+import com.github.microservice.models.type.DeviceModel;
 import com.github.microservice.models.type.DeviceType;
 import com.github.microservice.models.type.OnLineState;
 import com.zhongshu.iot.client.type.DataState;
@@ -25,6 +26,9 @@ import org.springframework.data.mongodb.core.mapping.Document;
 @AllArgsConstructor
 public class DeviceInfo extends SuperEntity {
 
+    @Schema(description = "mqtt账号名称")
+    private String mqttUserName;
+
     @Schema(description = "设备ID")
     private String deviceId;
 
@@ -34,6 +38,9 @@ public class DeviceInfo extends SuperEntity {
     @Schema(description = "设备类型:消费机 闸机")
     private DeviceType deviceType;
 
+    @Schema(description = "设备型号")
+    private DeviceModel deviceModel;
+
     @Schema(description = "在线状态")
     private OnLineState onLineState;
 

+ 3 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/GateWayInfo.java

@@ -21,6 +21,9 @@ import org.springframework.data.mongodb.core.mapping.Document;
 @AllArgsConstructor
 public class GateWayInfo extends SuperEntity {
 
+    @Schema(description = "mqtt账号名称")
+    private String mqttUserName;
+
     @Schema(description = "网关ID")
     private String gateWayId;
 

+ 3 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/Mqtt2User.java

@@ -44,4 +44,7 @@ public class Mqtt2User extends SuperEntity {
     private String syncTimeStr;
 
     private String msg = "";
+
+    @Schema(description = "设备数量(网关也算一个设备)")
+    private Long number = 0L;
 }

+ 46 - 17
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/iot/IotServiceImpl.java

@@ -1,8 +1,9 @@
 package com.zhongshu.iot.server.core.service.iot;
 
+import com.github.microservice.net.ResultContent;
+import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.model.baseParam.NameModel;
 import com.zhongshu.iot.client.model.iot.*;
-import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.type.IotDataType;
 import com.zhongshu.iot.server.core.dao.UserDao;
 import com.zhongshu.iot.server.core.dao.iot.IotDeviceDataDao;
@@ -22,7 +23,6 @@ import com.zhongshu.iot.server.core.service.base.CommonService;
 import com.zhongshu.iot.server.core.service.base.SuperService;
 import com.zhongshu.iot.server.core.util.bean.BeanUtils;
 import com.zhongshu.iot.server.core.util.page.PageEntityUtil;
-import com.github.microservice.net.ResultContent;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -36,7 +36,6 @@ import org.springframework.util.Assert;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -58,19 +57,22 @@ public class IotServiceImpl extends SuperService {
     private IotTopicDao iotTopicDao;
 
     @Autowired
-    UserDao userDao;
+    private UserDao userDao;
 
     @Autowired
-    DeviceInfoDao deviceInfoDao;
+    private DeviceInfoDao deviceInfoDao;
 
     @Autowired
     private GateWay2DeviceDao gateWay2DeviceDao;
 
     @Autowired
-    IotDeviceDataDao iotDeviceDataDao;
+    private IotDeviceDataDao iotDeviceDataDao;
 
     @Autowired
-    CommonService commonService;
+    private CommonService commonService;
+
+    @Autowired
+    private IotTemplate2DeviceService iotTemplate2DeviceService;
 
     //----------------------------- 模版 start----------------------------
 
@@ -190,10 +192,7 @@ public class IotServiceImpl extends SuperService {
             }
         } else if (template.getIotDataType() == IotDataType.Device) {
             // 物模型
-            IotTemplate temp = iotTemplateDao.findTopByNameAndDeviceIdAndIotDataType(
-                    param.getName(),
-                    template.getDeviceId(),
-                    IotDataType.Device);
+            IotTemplate temp = iotTemplateDao.findTopByNameAndDeviceIdAndIotDataType(param.getName(), template.getDeviceId(), IotDataType.Device);
             if (ObjectUtils.isNotEmpty(temp) && !temp.getId().equals(template.getId())) {
                 return ResultContent.buildFail(String.format(ResultMessage.NAME_EXIT, param.getName()));
             }
@@ -288,15 +287,20 @@ public class IotServiceImpl extends SuperService {
         if (ObjectUtils.isEmpty(iotTemplate)) {
             return ResultContent.buildFail(String.format("模版ID不存在", param.getTemplateId()));
         }
+
         // 判断该设备是否已绑定该模版
-        IotTemplate temp = iotTemplateDao.findTopByDeviceIdAndIotTemplateIdAndIotDataType(param.getDeviceId(),
-                iotTemplate.getId(),
-                IotDataType.Device);
+        IotTemplate temp = iotTemplateDao.findTopByDeviceIdAndIotTemplateIdAndIotDataType(param.getDeviceId(), iotTemplate.getId(), IotDataType.Device);
+//        if (ObjectUtils.isNotEmpty(temp)) {
+//            return ResultContent.buildFail(String.format("设备【%s】已绑定模版%s", deviceInfo.getDeviceName(), iotTemplate.getName()));
+//        }
+
+        IotTemplate newIotTemplate = null;
         if (ObjectUtils.isNotEmpty(temp)) {
-            return ResultContent.buildFail(String.format("设备【%s】已绑定模版%s", deviceInfo.getDeviceName(), iotTemplate.getName()));
+            newIotTemplate = temp;
+        } else {
+            newIotTemplate = new IotTemplate();
         }
 
-        IotTemplate newIotTemplate = new IotTemplate();
         BeanUtils.copyProperties(iotTemplate, newIotTemplate, "id", "createTime", "updateTime");
         newIotTemplate.setIotDataType(IotDataType.Device);
         newIotTemplate.setIotTemplateId(param.getTemplateId());
@@ -304,14 +308,34 @@ public class IotServiceImpl extends SuperService {
         newIotTemplate.setProjectCode(deviceInfo.getProjectInfoCode());
         iotTemplateDao.save(newIotTemplate);
 
+        // 绑定 物模型 和 设备的关系
+        iotTemplate2DeviceService.bind(iotTemplate, deviceInfo);
+
         // 属性等数据
         List<IotMain> saveList = new ArrayList<>();
+        // 模版对应的数据
         List<IotMain> list = iotMainDao.findByIotTemplateOrderByCreateTimeAsc(iotTemplate);
+        // 以前绑定的数据
+        List<IotMain> oldList = iotMainDao.findByIotTemplateOrderByCreateTimeAsc(newIotTemplate);
+        HashMap<String, String> map = new HashMap<>();
+        if (ObjectUtils.isNotEmpty(oldList)) {
+            oldList.stream().forEach(it -> {
+                map.put(it.getIotMainTemplateId(), it.getId());
+            });
+        }
         if (list != null) {
+            IotTemplate finalNewIotTemplate = newIotTemplate;
             list.stream().forEach(it -> {
                 IotMain main = new IotMain();
                 BeanUtils.copyProperties(it, main, "id", "createTime", "updateTime");
-                main.setIotTemplate(newIotTemplate);
+                if (oldList.contains(it.getId())) {
+                    main.setId(map.get(it.getId()));
+                    map.remove(it.getId());
+                }
+                main.setIotTemplate(finalNewIotTemplate);
+                // 所属模版内容数据ID
+                main.setIotMainTemplateId(it.getId());
+
                 main.setIotDataType(IotDataType.Device);
                 main.setDeviceId(deviceInfo.getDeviceId());
                 main.setProjectCode(deviceInfo.getProjectInfoCode());
@@ -321,6 +345,11 @@ public class IotServiceImpl extends SuperService {
             });
         }
         iotMainDao.saveAll(saveList);
+        if (!map.isEmpty()) {
+            List<String> ids = new ArrayList<>(map.keySet());
+            iotMainDao.deleteAllById(ids);
+        }
+        // 更新权限数据
         return ResultContent.buildSuccess();
     }
 

+ 145 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/iot/IotTemplate2DeviceService.java

@@ -0,0 +1,145 @@
+package com.zhongshu.iot.server.core.service.iot;
+
+import com.github.microservice.net.ResultContent;
+import com.zhongshu.iot.client.model.iot.DeviceBindIotTemplate;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceModel;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceParam;
+import com.zhongshu.iot.client.model.iot.IotTemplate2DeviceSearch;
+import com.zhongshu.iot.server.core.dao.iot.IotTemplate2DeviceDao;
+import com.zhongshu.iot.server.core.dao.iot.IotTemplateDao;
+import com.zhongshu.iot.server.core.dao.mqtt.DeviceInfoDao;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate2Device;
+import com.zhongshu.iot.server.core.domain.iot.mqtt.DeviceInfo;
+import com.zhongshu.iot.server.core.service.mqtt.DeviceInfoService;
+import com.zhongshu.iot.server.core.util.bean.BeanUtils;
+import com.zhongshu.iot.server.core.util.page.PageEntityUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author TRX
+ * @date 2025/1/8
+ */
+@Slf4j
+@Service
+public class IotTemplate2DeviceService {
+
+    @Autowired
+    private IotTemplate2DeviceDao iotTemplate2DeviceDao;
+
+    @Autowired
+    private DeviceInfoService deviceInfoService;
+
+    @Autowired
+    private IotServiceImpl iotService;
+
+    @Autowired
+    private IotTemplateDao iotTemplateDao;
+
+    @Autowired
+    private DeviceInfoDao deviceInfoDao;
+
+    /**
+     * 绑定 物模型和设备的关系
+     *
+     * @param iotTemplate
+     * @param deviceInfo
+     * @return
+     */
+    public ResultContent bind(IotTemplate iotTemplate, DeviceInfo deviceInfo) {
+        if (ObjectUtils.isNotEmpty(iotTemplate) && ObjectUtils.isNotEmpty(deviceInfo)) {
+            IotTemplate2Device iotTemplate2Device = iotTemplate2DeviceDao.findTopByIotTemplateAndDeviceInfo(iotTemplate, deviceInfo);
+            if (ObjectUtils.isEmpty(iotTemplate2Device)) {
+                iotTemplate2Device = new IotTemplate2Device();
+            }
+            iotTemplate2Device.setIotTemplate(iotTemplate);
+            iotTemplate2Device.setTemplateId(iotTemplate.getId());
+            iotTemplate2Device.setTemplateName(iotTemplate.getName());
+            // 所属模版ID
+            iotTemplate2Device.setIotTemplateId(iotTemplate.getIotTemplateId());
+
+            iotTemplate2Device.setDeviceId(deviceInfo.getDeviceId());
+            iotTemplate2Device.setDeviceInfo(deviceInfo);
+            iotTemplate2Device.setDeviceType(deviceInfo.getDeviceType());
+
+            iotTemplate2DeviceDao.save(iotTemplate2Device);
+        }
+        return ResultContent.buildSuccess();
+    }
+
+    public ResultContent<Page<IotTemplate2DeviceModel>> page(Pageable pageable, IotTemplate2DeviceSearch param) {
+        Page<IotTemplate2Device> page = iotTemplate2DeviceDao.page(pageable, param);
+        return ResultContent.buildSuccess(PageEntityUtil.toPageModel(page, this::toModel));
+    }
+
+    /**
+     * 模版绑定 设备
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent templateBindDevices(IotTemplate2DeviceParam param) {
+        if (StringUtils.isEmpty(param.getIotTemplateId())) {
+            return ResultContent.buildFail("iotTemplateId不能为空");
+        }
+        if (ObjectUtils.isEmpty(param.getDeviceIds())) {
+            return ResultContent.buildFail("deviceIds 不能为空");
+        }
+        IotTemplate iotTemplate = iotTemplateDao.findTopById(param.getIotTemplateId());
+        if (ObjectUtils.isEmpty(iotTemplate)) {
+            return ResultContent.buildFail("模版数据不存在");
+        }
+        List<DeviceInfo> deviceInfos = deviceInfoDao.findByDeviceIdIn(param.getDeviceIds());
+        if (ObjectUtils.isEmpty(deviceInfos)) {
+            return ResultContent.buildFail("设备不存在");
+        }
+        deviceInfos.stream().forEach(deviceInfo -> {
+            // 绑定设备
+            DeviceBindIotTemplate temp = new DeviceBindIotTemplate();
+            temp.setTemplateId(iotTemplate.getId());
+            temp.setDeviceId(deviceInfo.getDeviceId());
+            temp.setProjectInfoCode(deviceInfo.getProjectInfoCode());
+            iotService.deviceBindIotTemplate(temp);
+        });
+        return ResultContent.buildSuccess();
+    }
+
+    /**
+     * 删除设备和物模型的绑定
+     *
+     * @param id
+     * @return
+     */
+    public ResultContent delete(String id) {
+        IotTemplate2Device iotTemplate2Device = iotTemplate2DeviceDao.findTopById(id);
+        if (ObjectUtils.isEmpty(iotTemplate2Device)) {
+            return ResultContent.buildFail("数据不存在");
+        }
+        iotTemplate2DeviceDao.delete(iotTemplate2Device);
+
+        IotTemplate iotTemplate = iotTemplate2Device.getIotTemplate();
+        // 删除物模型
+        if (ObjectUtils.isNotEmpty(iotTemplate)) {
+            iotService.deleteTemplate(iotTemplate.getId());
+        }
+        return ResultContent.buildSuccess();
+    }
+
+    public IotTemplate2DeviceModel toModel(IotTemplate2Device entity) {
+        IotTemplate2DeviceModel model = new IotTemplate2DeviceModel();
+        if (ObjectUtils.isNotEmpty(entity)) {
+            BeanUtils.copyProperties(entity, model);
+            model.setDeviceInfo(deviceInfoService.toModel(entity.getDeviceInfo()));
+        }
+        return model;
+    }
+
+}

+ 4 - 3
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/mqtt/DeviceInfoService.java

@@ -2,12 +2,13 @@ package com.zhongshu.iot.server.core.service.mqtt;
 
 import com.github.microservice.models.type.DeviceType;
 import com.github.microservice.models.type.OnLineState;
+import com.github.microservice.net.ResultContent;
+import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.model.iot.IotMainModel;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoAddParam;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoModel;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoSearchParam;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoUpdateRemark;
-import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.type.type.LogsLevel;
 import com.zhongshu.iot.server.core.dao.iot.IotTemplateDao;
 import com.zhongshu.iot.server.core.dao.mqtt.DeviceInfoDao;
@@ -22,7 +23,6 @@ import com.zhongshu.iot.server.core.service.user.OperationLogsService;
 import com.zhongshu.iot.server.core.util.CommonUtil;
 import com.zhongshu.iot.server.core.util.bean.BeanUtils;
 import com.zhongshu.iot.server.core.util.page.PageEntityUtil;
-import com.github.microservice.net.ResultContent;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,6 +39,7 @@ import java.util.List;
  */
 @Service
 public class DeviceInfoService {
+
     @Autowired
     DeviceInfoDao deviceInfoDao;
 
@@ -266,7 +267,7 @@ public class DeviceInfoService {
         DeviceInfoModel deviceInfoModel = new DeviceInfoModel();
         if (ObjectUtils.isNotEmpty(deviceInfo)) {
             BeanUtils.copyProperties(deviceInfo, deviceInfoModel);
-            deviceInfoModel.setIotTemplate(iotService.toModel(deviceInfo.getIotTemplate()));
+//            deviceInfoModel.setIotTemplate(iotService.toModel(deviceInfo.getIotTemplate()));
             deviceInfoModel.setProjectInfo(projectInfoService.toModel(deviceInfo.getProjectInfo()));
         }
         return deviceInfoModel;

+ 0 - 2
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/sync/DeviceSyncFullCardService.java

@@ -128,8 +128,6 @@ public class DeviceSyncFullCardService extends SuperService {
                 BeanUtils.copyProperties(it, syncParam);
                 // 设备绑定的网关
                 List<GateWay2Device> gateWay2Devices = new ArrayList<>();
-                // 多个
-//                gateWay2Devices = gateWay2DeviceDao.findByDeviceInfo(it);
 
                 // 最新的
                 GateWay2Device gateWay2Device = gateWay2DeviceDao.findTopByDeviceInfoOrderByUpdateTimeDesc(it);

+ 59 - 45
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/util/test/Test153AddUser.java

@@ -1,7 +1,7 @@
 package com.zhongshu.iot.server.core.util.test;
 
+import com.zhongshu.iot.server.core.util.JMXUtil;
 import com.zhongshu.iot.server.core.util.mqtt.MqttTopicUtils;
-import lombok.Cleanup;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
 import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
@@ -14,6 +14,7 @@ import javax.management.ObjectName;
 import javax.management.remote.JMXConnector;
 import javax.management.remote.JMXConnectorFactory;
 import javax.management.remote.JMXServiceURL;
+import java.util.Random;
 
 /**
  * @author TRX
@@ -25,63 +26,76 @@ public class Test153AddUser {
     public static void main(String[] args) {
         try {
             log.info("-------------------- 开始 --------------------------");
-            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://172.24.50.53:1098/jmxrmi");
-            @Cleanup JMXConnector connector = JMXConnectorFactory.connect(url, null);
-            connector.connect();
-            System.out.println("连接成功..............");
-            MBeanServerConnection connection = connector.getMBeanServerConnection();
+//            ActiveMQServerControl addressControl = getAddressControl(
+//                    "192.168.32.113", "mq1");
 
-            ObjectName addressObjectName = ObjectNameBuilder.create("org.apache.activemq.artemis", "broke1").getActiveMQServerObjectName();
+            ActiveMQServerControl addressControl = getAddressControl(
+                    "192.168.32.107", "broke1");
 
-            ActiveMQServerControl addressControl = MBeanServerInvocationHandler.newProxyInstance(connection, addressObjectName, ActiveMQServerControl.class, false);
-
-
-            // 查询用户 可以筛选特定的名称
-            String userListStr = addressControl.listUser("device2");
-            log.info("userListStr: {}", userListStr);
-            if (StringUtils.isNotEmpty(userListStr)) {
-                // 如果不存在用户会报错
-//                addressControl.removeUser("device1");
-            }
             StopWatch stopWatch = new StopWatch();
-
             stopWatch.start("开始添加用户");
-            for (int i = 0; i < 10; i++) {
-                String name = "mqttUser" + i;
-                try {
-                    addressControl.removeUser(name);
-                } catch (Exception e) {
-                }
-//                String passWord = CommonUtil.generateRandomString(16);
-                String roleName = name;
-
-                String passWord = name;
-//                String roleName = "amq";
-                addressControl.addUser(name, passWord, roleName, true);
 
-                String addressMatch = MqttTopicUtils.buildDeviceAllTopic(name);
-//                addressControl.removeSecuritySettings(MqttTopicUtils.buildDeviceAllTopic(name));
-                addressControl.removeSecuritySettings(addressMatch);
+            Random random = new Random();
+            Runnable runnable = () -> {
+                for (int i = 0; i < 10; i++) {
+                    int num = random.nextInt(1000);
+                    log.info("添加用户----------------------- {} {}", i, num);
+                    String name = "mqttUser" + i;
+                    try {
+                        String str = addressControl.listUser(name);
+                        if (JMXUtil.mqttUserIsExit(str)) {
+                            addressControl.removeUser(name);
+                        }
+                    } catch (Exception e) {
+                        log.error("{}", e.getMessage());
+                    }
+//                    String roleName = "amq";
+                    String roleName = name;
+                    String passWord = name;
+                    try {
+                        addressControl.addUser(name, passWord, roleName, true);
+                        String addressMatch = MqttTopicUtils.buildDeviceAllTopic(name);
+//                        addressMatch = "/#";
+//                        addressControl.removeSecuritySettings(addressMatch);
+                        log.info("addUser: {} {} ", name, addressMatch);
+                        addressControl.addSecuritySettings(addressMatch, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName);
+                    } catch (Exception e) {
+                        log.error("出错: {}", e.getMessage());
+                    }
+                }
+            };
 
-                log.info("addUser: {} {} ", name, addressMatch);
-                addressControl.addSecuritySettings(
-                        addressMatch,
-                        roleName, roleName, roleName, roleName, roleName, roleName, roleName,
-                        roleName, roleName, roleName);
+            for (int j = 0; j < 1; j++) {
+                Thread thread = new Thread(runnable);
+                thread.start();
             }
+
             stopWatch.stop();
             log.info("耗时:{}", stopWatch.prettyPrint());
-
-//            // 添加用户 如果存在会报错
-//            addressControl.addUser("device2", "trx", "trx", false);
-//            // 删除用户 如果不存在会报错
-////            addressControl.removeUser("device1");
-//            log.info("添加用户成功1....");
-//            log.info("users: {}", addressControl.listUser(null));
             log.info("-------------------- 结束 --------------------------");
         } catch (Exception e) {
             e.printStackTrace();
         }
+    }
+
+    public static ActiveMQServerControl getAddressControl(String url, String broker) {
+        if (StringUtils.isEmpty(broker)) {
+            broker = "broke1";
+        }
+        try {
+            JMXServiceURL serviceURL = new JMXServiceURL(String.format("service:jmx:rmi:///jndi/rmi://%s:1098/jmxrmi", url));
+            JMXConnector connector = JMXConnectorFactory.connect(serviceURL, null);
+            connector.connect();
+            System.out.println("连接成功..............");
+            MBeanServerConnection connection = connector.getMBeanServerConnection();
 
+            ObjectName addressObjectName = ObjectNameBuilder.create("org.apache.activemq.artemis", broker).getActiveMQServerObjectName();
+            ActiveMQServerControl addressControl = MBeanServerInvocationHandler.newProxyInstance(connection, addressObjectName, ActiveMQServerControl.class, false);
+            return addressControl;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
     }
+
 }