提交 710303f0 编写于 作者: xiaonannet's avatar xiaonannet

Merge branch 'release/1.0.0' into main

......@@ -62,6 +62,9 @@ com.mqttsnet.thinglinks
│ └── thinglinks-visual-collection // 服务器监控采集服务 [19401]
├──pom.xml // 公共依赖
~~~
## 平台总体架构
![](doc/imgs/overallArchitecture.png)
## 设备集成LINK架构
......
......@@ -115,7 +115,7 @@ smqtt:
username: ${spring.datasource.dynamic.datasource.master.username}
password: ${spring.datasource.dynamic.datasource.master.password}
http: # http相关配置 端口固定60000
enable: false # 开关
enable: true # 开关
accessLog: false # http访问日志
ssl: # ssl配置
enable: false
......@@ -168,7 +168,7 @@ smqtt:
sourceName: rocket_mq
sourceAttributes:
topic: thinglinks-link-mqttMsg
tags: thinglinks-link
tags: thinglinks
namesrvAddr: 127.0.0.1:19876
instanceName: broker-a
producerGroup: thinglinks
......
此差异已折叠。
......@@ -26,8 +26,12 @@ public interface RemotePublishActorService {
/**
* 通知ThingLins MQTT Broker推送消息
* @param params
* topic topic String 是
* qos 服务等级 Integer 是
* retain 保留消息 Boolean 是
* message 消息 String 是
* @return
*/
@PostMapping("/sendMessage")
public R sendMessage(@RequestBody Map<String, String> params);
@PostMapping("/publish/sendMessage")
public R sendMessage(@RequestBody Map<String, Object> params);
}
......@@ -37,7 +37,7 @@ public class RemotePublishActorFallbackFactory implements FallbackFactory<Remote
* @return
*/
@Override
public R sendMessage(Map<String, String> params) {
public R sendMessage(Map<String, Object> params) {
return R.fail("通知ThingLins MQTT Broker推送消息失败:" + throwable.getMessage());
}
};
......
......@@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
......@@ -25,6 +26,7 @@ import lombok.Data;
/**
* 设备管理
*/
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "设备管理")
@Data
public class Device extends BaseEntity implements Serializable{
......@@ -127,24 +129,18 @@ public class Device extends BaseEntity implements Serializable{
private String deviceTags;
/**
* 产品型号
* 产品标识
*/
@Excel(name = "产品型号")
@ApiModelProperty(value = "产品型号")
private String productId;
@Excel(name = "产品标识")
@ApiModelProperty(value = "产品标识")
private String productIdentification;
/**
* 厂商ID
*/
@Excel(name = "厂商ID")
@ApiModelProperty(value = "厂商ID")
private String manufacturerId;
/**
* 产品协议类型 :mqtt || coap || modbus || http
* 协议类型 :mqtt || coap || modbus || http
*/
@Excel(name = "产品协议类型")
@ApiModelProperty(value = "产品协议类型 :mqtt || coap || modbus || http")
@Excel(name = "协议类型")
@ApiModelProperty(value = "协议类型 :mqtt || coap || modbus || http")
private String protocolType;
/**
......
package com.mqttsnet.thinglinks.link.api.domain.device.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Description: java类作用描述
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/4/25$ 12:48$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/4/25$ 12:48$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
/**
* 子设备档案表
*/
@ApiModel(value="子设备档案表")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DeviceInfo implements Serializable {
/**
* 主键
*/
@ApiModelProperty(value="主键")
private Long id;
/**
* 边设备档案主键
*/
@ApiModelProperty(value="边设备档案主键")
private Long dId;
/**
* 应用ID
*/
@ApiModelProperty(value="应用ID")
private String appId;
/**
* 设备自身的唯一标识
*/
@ApiModelProperty(value="设备自身的唯一标识")
private String nodeId;
/**
* 设备名称
*/
@ApiModelProperty(value="设备名称")
private String nodeName;
/**
* 平台生成的设备唯一标识
*/
@ApiModelProperty(value="平台生成的设备唯一标识")
private String deviceId;
/**
* 设备描述
*/
@ApiModelProperty(value="设备描述")
private String description;
/**
* 厂商ID
*/
@ApiModelProperty(value="厂商ID")
private String manufacturerId;
/**
* 设备型号
*/
@ApiModelProperty(value="设备型号")
private String model;
/**
* 子设备连接状态 : 在线:ONLINE || 离线:OFFLINE || 未连接:INIT
*/
@ApiModelProperty(value="子设备连接状态 : 在线:ONLINE || 离线:OFFLINE || 未连接:INIT")
private String connectStatus;
/**
* 是否支持设备影子TRUE:1、FALSE :0
*/
@ApiModelProperty(value="是否支持设备影子TRUE:1、FALSE :0")
private Boolean shadowEnable;
/**
* 设备影子数据表名
*/
@ApiModelProperty(value="设备影子数据表名")
private String shadowTableName;
/**
* 状态(字典值:0启用 1停用)
*/
@ApiModelProperty(value="状态(字典值:0启用 1停用)")
private String status;
/**
* 创建者
*/
@ApiModelProperty(value="创建者")
private String createBy;
/**
* 创建时间
*/
@ApiModelProperty(value="创建时间")
private LocalDateTime createTime;
/**
* 更新者
*/
@ApiModelProperty(value="更新者")
private String updateBy;
/**
* 更新时间
*/
@ApiModelProperty(value="更新时间")
private LocalDateTime updateTime;
/**
* 备注
*/
@ApiModelProperty(value="备注")
private String remark;
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
package com.mqttsnet.thinglinks.link.api.domain.device.entity.model;
import lombok.Data;
/**
* @Description: 边设备添加子设备详情数据模型
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/4/25$ 12:54$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/4/25$ 12:54$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
@Data
public class DeviceInfos {
private static final long serialVersionUID = 1L;
private String nodeId;
private String name;
private String description;
private String manufacturerId;
private String model;
}
package com.mqttsnet.thinglinks.link.api.domain.device.entity.model;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import java.io.Serializable;
/**
* @Description: Device Entity class model
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/5/4$ 18:57$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/5/4$ 18:57$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
public class DeviceModel extends Device implements Serializable {
private static final long serialVersionUID = 1L;
}
package com.mqttsnet.thinglinks.link.api.domain.device.entity.model;
import lombok.Data;
import java.util.List;
/**
* @Description: 边设备添加子设备数据模型
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/4/25$ 12:52$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/4/25$ 12:52$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
@Data
public class TopoAddDatas {
private static final long serialVersionUID = 1L;
private Integer mid;
private List<DeviceInfos> deviceInfos;
}
......@@ -16,11 +16,16 @@ import java.util.List;
@Data
public class TableDto extends BaseEntity{
/**
* 超级表普通列字段的值
* 值需要与创建超级表时普通列字段的数据类型对应上
*/
private List<Fields> schemaFieldValues;
/**
* 超级表标签字段的值
* 值需要与创建超级表时标签字段的数据类型对应上
*/
@NotEmpty(message = "invalid operation: fieldValues can not be empty")
private List<Fields> tagsFieldValues;
/**
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -1784,4 +1784,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return zoneDateTime1.format(formatter);
}
/**
* 取得当前时间戳(精确到毫秒秒)Long 类型
*
* @return
*/
public static Long millisecondStampL() {
long ts = System.currentTimeMillis();
long thirtySec = 1000 * 30;
return ts + (thirtySec);
}
}
package com.mqttsnet.thinglinks.common.core.utils;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.text.StrFormatter;
import org.springframework.util.AntPathMatcher;
......@@ -508,4 +510,18 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
}
return source;
}
/**
*
* 方法描述:jsonToMap
* @param jsonStr json字符串
* @return Map<String, Object> map对象
*/
@SuppressWarnings({ "unchecked", "rawtypes"})
public static Map<String, Object> jsonToMap(String jsonStr) {
Map<String, Object> paramMap = new HashMap<>();
if (jsonStr != null && !"".equals(jsonStr)) {
paramMap = (Map) JSON.parse(jsonStr);
}
return paramMap;
}
}
\ No newline at end of file
......@@ -16,6 +16,11 @@ import lombok.Data;
@Data
public class ConsumerTopicConstant {
/**
* MQTT设备消息监听主题
*/
public static final String THINGLINKS_LINK_MQTT_MSG = "thinglinks-link-mqttMsg";
/**
* TDengine超级表创键修改动作监听主题
*/
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
package com.mqttsnet.thinglinks.broker.Actors;
import io.github.quickmsg.common.annotation.AllowCors;
import io.github.quickmsg.common.annotation.Header;
import io.github.quickmsg.common.annotation.Router;
import io.github.quickmsg.common.config.Configuration;
import io.github.quickmsg.common.enums.HttpType;
import io.github.quickmsg.common.message.HttpPublishMessage;
import io.github.quickmsg.core.http.AbstractHttpActor;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.web.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import reactor.netty.http.server.HttpServerRequest;
import reactor.netty.http.server.HttpServerResponse;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @Description: Broker推送设备消息
......@@ -26,20 +22,28 @@ import java.nio.charset.StandardCharsets;
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
@Router(value = "/publish", type = HttpType.POST)
@Slf4j
@Header(key = "Content-Type", value = "application/json")
@AllowCors
public class PublishActor extends AbstractHttpActor {
@RestController
@RequestMapping("/publish")
public class PublishActor{
@Override
public Publisher<Void> doRequest(HttpServerRequest request, HttpServerResponse response, Configuration configuration) {
return request
.receive()
.asString()
.map(this.toJson(HttpPublishMessage.class))
.doOnNext(message -> {
//处理request
}).then(response.sendString(Mono.just("success")).then());
/**
* MQTT推送消息接口
* @param params
* @return
*/
@PostMapping("/sendMessage")
public R sendMessage(@RequestBody Map<String, Object> params) {
log.info("MQTT Broker publish {}", params.toString());
JSONObject param = new JSONObject();
param.put("topic", params.get("topic"));
param.put("qos", Integer.valueOf(params.get("qos").toString()));
param.put("retain", Boolean.valueOf(params.get("retain").toString()));
param.put("message", String.valueOf(params.get("message")));
String result = HttpRequest.post("http://127.0.0.1:60000/smqtt/publish")
.header("Content-Type", "application/json;charset=UTF-8")
.body(param.toString())
.execute().body();
return R.ok();
}
}
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -127,6 +127,13 @@
<version>${thinglinks.version}</version>
</dependency>
<!-- thinglinks Api broker -->
<dependency>
<groupId>com.mqttsnet</groupId>
<artifactId>thinglinks-api-broker</artifactId>
<version>${thinglinks.version}</version>
</dependency>
</dependencies>
<build>
......
......@@ -2,6 +2,7 @@ package com.mqttsnet.thinglinks.link.common.rockermq.consumer;
import com.alibaba.fastjson.JSONObject;
import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerGroupConstant;
import com.mqttsnet.thinglinks.common.rocketmq.constant.ConsumerTopicConstant;
import lombok.extern.slf4j.Slf4j;
import com.mqttsnet.thinglinks.link.service.device.DeviceActionService;
import com.mqttsnet.thinglinks.link.service.device.DeviceDatasService;
......@@ -23,7 +24,7 @@ import org.springframework.stereotype.Component;
*/
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_GROUP, topic = "thinglinks-link")
@RocketMQMessageListener(consumerGroup = ConsumerGroupConstant.THINGLINKS_GROUP, topic = ConsumerTopicConstant.THINGLINKS_LINK_MQTT_MSG)
public class DeviceActionMessageConsumer implements RocketMQListener {
@Autowired
private DeviceActionService deviceActionService;
......@@ -35,18 +36,22 @@ public class DeviceActionMessageConsumer implements RocketMQListener {
assert message!=null:"message cannot be empty";
log.info("ThingLinks物联网平台数据消费-->Received message={}", message);
JSONObject thinglinksMessage = JSONObject.parseObject(String.valueOf(message));
/**
* TODO 设备上下线处理
* $event/close 设备断开事件
* $event/connect 设备连接事件
* ${topic} 其他为业务数据自行处理
*/
if("$event/connect".equals(thinglinksMessage.get("topic"))){
deviceActionService.connectEvent(String.valueOf(thinglinksMessage.getString("msg")));
}else if("$event/close".equals(thinglinksMessage.get("topic"))){
deviceActionService.closeEvent(String.valueOf(thinglinksMessage.getString("msg")));
}else {
deviceDatasService.insertBaseDatas(thinglinksMessage);
try {
/**
* TODO 设备上下线处理
* $event/close 设备断开事件
* $event/connect 设备连接事件
* ${topic} 其他为业务数据自行处理
*/
if("$event/connect".equals(thinglinksMessage.get("topic"))){
deviceActionService.connectEvent(String.valueOf(thinglinksMessage.getString("msg")));
}else if("$event/close".equals(thinglinksMessage.get("topic"))){
deviceActionService.closeEvent(String.valueOf(thinglinksMessage.getString("msg")));
}else {
deviceDatasService.insertBaseDatas(thinglinksMessage);
}
}catch (Exception e){
log.error("ThingLinks物联网平台数据消费-->消费失败,失败原因:{}", e.getMessage());
}
}
}
package com.mqttsnet.thinglinks.link.controller.device;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.mqttsnet.thinglinks.common.core.annotation.NoRepeatSubmit;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
import com.mqttsnet.thinglinks.common.core.utils.poi.ExcelUtil;
import com.mqttsnet.thinglinks.common.core.web.controller.BaseController;
......@@ -14,7 +17,13 @@ import com.mqttsnet.thinglinks.common.core.web.page.TableDataInfo;
import com.mqttsnet.thinglinks.common.log.annotation.Log;
import com.mqttsnet.thinglinks.common.log.enums.BusinessType;
import com.mqttsnet.thinglinks.common.security.annotation.PreAuthorize;
import com.mqttsnet.thinglinks.common.security.service.TokenService;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
import com.mqttsnet.thinglinks.link.service.product.ProductService;
import com.mqttsnet.thinglinks.system.api.domain.SysUser;
import com.mqttsnet.thinglinks.system.api.model.LoginUser;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.mqttsnet.thinglinks.link.service.device.DeviceService;
......@@ -30,17 +39,30 @@ import com.mqttsnet.thinglinks.link.service.device.DeviceService;
public class DeviceController extends BaseController {
@Autowired
private DeviceService deviceService;
@Autowired
private ProductService productService;
@Autowired
private TokenService tokenService;
/**
* 查询设备管理列表
*/
@PreAuthorize(hasPermi = "link:device:list")
@GetMapping("/list")
public TableDataInfo list(Device device)
public R<Map<String, Object>> list(Device device)
{
startPage();
final Map<String, Object> results = new HashMap<>();
List<Device> list = deviceService.selectDeviceList(device);
return getDataTable(list);
//查询设备数据
results.put("device", getDataTable(list));
//统计设备在线数量
results.put("onlineCount", deviceService.countDistinctClientIdByConnectStatus(DeviceConnectStatus.ONLINE.getValue()));
//统计设备离线数量
results.put("offlineCount", deviceService.countDistinctClientIdByConnectStatus(DeviceConnectStatus.OFFLINE.getValue()));
//统计设备初始化数量
results.put("initCount", deviceService.countDistinctClientIdByConnectStatus(DeviceConnectStatus.INIT.getValue()));
return R.ok(results);
}
/**
......@@ -60,10 +82,20 @@ public class DeviceController extends BaseController {
* 获取设备管理详细信息
*/
@PreAuthorize(hasPermi = "link:device:query")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
@GetMapping(value = { "/", "/{id}" })
public AjaxResult getInfo(@PathVariable(value = "id", required = false) Long id)
{
return AjaxResult.success(deviceService.selectDeviceById(id));
LoginUser loginUser = tokenService.getLoginUser();
SysUser sysUser = loginUser.getSysUser();
AjaxResult ajax = AjaxResult.success();
if (StringUtils.isNotNull(id))
{
ajax.put(AjaxResult.DATA_TAG,deviceService.selectDeviceById(id));
ajax.put("products", productService.selectProductList(new Product()));
}else {
ajax.put("products", productService.selectProductList(new Product()));
}
return ajax;
}
/**
......
......@@ -51,25 +51,6 @@ public class ProductController extends BaseController {
return productService.selectByPrimaryKey(id);
}
/* *//**
* 新增产品模型
*//*
@PreAuthorize(hasPermi = "link:product:add")
@Log(title = "产品模型", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody JSONObject content) {
JSONObject tokenObj = new JSONObject();
try {
// AjaxResult ajaxResult = productService.insert(content);
return null;
} catch (JSONException e) {
return new AjaxResult(HttpStatus.ERROR, "文件数据的json格式错误", tokenObj);
} catch (Exception e) {
log.error("新增产品模型异常:", e);
return new AjaxResult(HttpStatus.ERROR, "快捷生成失败", tokenObj);
}
}*/
/**
* 导入产品模型json数据
* @param file json文件
......@@ -80,7 +61,7 @@ public class ProductController extends BaseController {
* @return AjaxResult
* @throws Exception
*/
// @PreAuthorize(hasPermi = "link:product:import")
@PreAuthorize(hasPermi = "link:product:import")
@Log(title = "产品管理", businessType = BusinessType.IMPORT)
@PostMapping("/importProductJsonFile")
public AjaxResult importProductJson(MultipartFile file,
......@@ -183,14 +164,15 @@ public class ProductController extends BaseController {
/**
* 初始化生成超级表模型
* @param productId productId==null 初始化所有产品:productId!=null 初始化指定产品
* @param productIds 产品ID集合
* @param initializeOrNot 是否初始化
* @return
* @throws Exception
*/
@GetMapping(value = "/findCreateSuperTableDataModel/{productId}")
public AjaxResult findCreateSuperTableDataModel(@PathVariable("productId") Long productId) throws Exception {
@GetMapping(value = "/findCreateSuperTableDataModel/{productIds}/{initializeOrNot}")
public AjaxResult findCreateSuperTableDataModel(@PathVariable("productIds") Long[] productIds,@PathVariable("initializeOrNot") Boolean initializeOrNot) throws Exception {
try {
final List<SuperTableDto> superTableDataModel = productService.createSuperTableDataModel(productId,false);
final List<SuperTableDto> superTableDataModel = productService.createSuperTableDataModel(productIds,initializeOrNot);
return AjaxResult.success(superTableDataModel);
}catch (Exception e){
log.error(e.getMessage());
......
package com.mqttsnet.thinglinks.link.mapper.device;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.DeviceInfo;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @Description: java类作用描述
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/4/25$ 12:48$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/4/25$ 12:48$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
@Mapper
public interface DeviceInfoMapper {
/**
* delete by primary key
* @param id primaryKey
* @return deleteCount
*/
int deleteByPrimaryKey(Long id);
/**
* insert record to table
* @param record the record
* @return insert count
*/
int insert(DeviceInfo record);
int insertOrUpdate(DeviceInfo record);
int insertOrUpdateSelective(DeviceInfo record);
/**
* insert record to table selective
* @param record the record
* @return insert count
*/
int insertSelective(DeviceInfo record);
/**
* select by primary key
* @param id primary key
* @return object by primary key
*/
DeviceInfo selectByPrimaryKey(Long id);
/**
* update record selective
* @param record the updated record
* @return update count
*/
int updateByPrimaryKeySelective(DeviceInfo record);
/**
* update record
* @param record the updated record
* @return update count
*/
int updateByPrimaryKey(DeviceInfo record);
int updateBatch(List<DeviceInfo> list);
int batchInsert(@Param("list") List<DeviceInfo> list);
int deleteByDeviceId(@Param("deviceId")String deviceId);
DeviceInfo findOneByDeviceId(@Param("deviceId")String deviceId);
}
\ No newline at end of file
......@@ -155,6 +155,8 @@ public interface DeviceMapper {
Device findOneByClientIdOrDeviceIdentification(@Param("clientId")String clientId,@Param("deviceIdentification")String deviceIdentification);
Long countDistinctClientIdByConnectStatus(@Param("connectStatus")String connectStatus);
......
package com.mqttsnet.thinglinks.link.mapper.product;
import java.util.Collection;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
......@@ -140,6 +141,11 @@ public interface ProductMapper {
Product findOneByIdAndStatus(@Param("id")Long id,@Param("status")String status);
Product findOneByProductIdentificationAndProtocolType(@Param("productIdentification")String productIdentification,@Param("protocolType")String protocolType);
List<Product> findAllByIdInAndStatus(@Param("idCollection")Collection<Long> idCollection,@Param("status")String status);
......
......@@ -50,9 +50,33 @@ public interface DeviceDatasService {
*
* @param thinglinksMessage
*/
void insertBaseDatas(JSONObject thinglinksMessage);
void insertBaseDatas(JSONObject thinglinksMessage) throws Exception;
/**
* 处理/topo/add Topic边设备添加子设备
*
* @param deviceIdentification 设备标识
* @param msg 数据
*/
String processingTopoAddTopic(String deviceIdentification,String msg) throws Exception;
/**
* 处理/topo/delete Topic边设备删除子设备
*
* @param deviceIdentification 设备标识
* @param msg 数据
*/
String processingTopoDeleteTopic(String deviceIdentification,String msg) throws Exception;
/**
* 处理/topo/update Topic边设备更新子设备状态
*
* @param deviceIdentification 设备标识
* @param msg 数据
*/
String processingTopoUpdateTopic(String deviceIdentification,String msg) throws Exception;
/**
* 处理datas Topic数据上报
*
......@@ -61,6 +85,14 @@ public interface DeviceDatasService {
*/
void processingDatasTopic(String deviceIdentification,String msg) throws Exception;
/**
* 处理/commandResponse Topic边设备返回给物联网平台的命令响应
*
* @param deviceIdentification 设备标识
* @param msg 数据
*/
void processingTopoCommandResponseTopic(String deviceIdentification,String msg) throws Exception;
}
package com.mqttsnet.thinglinks.link.service.device;
import java.util.List;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.DeviceInfo;
/**
* @Description: java类作用描述
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/4/25$ 12:44$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/4/25$ 12:44$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
public interface DeviceInfoService {
int deleteByPrimaryKey(Long id);
int insert(DeviceInfo record);
int insertOrUpdate(DeviceInfo record);
int insertOrUpdateSelective(DeviceInfo record);
int insertSelective(DeviceInfo record);
DeviceInfo selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(DeviceInfo record);
int updateByPrimaryKey(DeviceInfo record);
int updateBatch(List<DeviceInfo> list);
int batchInsert(List<DeviceInfo> list);
int deleteByDeviceId(String deviceId);
DeviceInfo findOneByDeviceId(String deviceId);
}
......@@ -131,5 +131,10 @@ public interface DeviceService {
* @return
*/
int disconnect(Long[] ids);
Long countDistinctClientIdByConnectStatus(String connectStatus);
}
package com.mqttsnet.thinglinks.link.service.device.impl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import com.mqttsnet.thinglinks.link.mapper.device.DeviceInfoMapper;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.DeviceInfo;
import com.mqttsnet.thinglinks.link.service.device.DeviceInfoService;
/**
* @Description: java类作用描述
* @Author: ShiHuan SUN
* @E-mail: 13733918655@163.com
* @Website: http://thinglinks.mqttsnet.com
* @CreateDate: 2022/4/25$ 12:44$
* @UpdateUser: ShiHuan SUN
* @UpdateDate: 2022/4/25$ 12:44$
* @UpdateRemark: 修改内容
* @Version: V1.0
*/
@Service
public class DeviceInfoServiceImpl implements DeviceInfoService {
@Resource
private DeviceInfoMapper deviceInfoMapper;
@Override
public int deleteByPrimaryKey(Long id) {
return deviceInfoMapper.deleteByPrimaryKey(id);
}
@Override
public int insert(DeviceInfo record) {
return deviceInfoMapper.insert(record);
}
@Override
public int insertOrUpdate(DeviceInfo record) {
return deviceInfoMapper.insertOrUpdate(record);
}
@Override
public int insertOrUpdateSelective(DeviceInfo record) {
return deviceInfoMapper.insertOrUpdateSelective(record);
}
@Override
public int insertSelective(DeviceInfo record) {
return deviceInfoMapper.insertSelective(record);
}
@Override
public DeviceInfo selectByPrimaryKey(Long id) {
return deviceInfoMapper.selectByPrimaryKey(id);
}
@Override
public int updateByPrimaryKeySelective(DeviceInfo record) {
return deviceInfoMapper.updateByPrimaryKeySelective(record);
}
@Override
public int updateByPrimaryKey(DeviceInfo record) {
return deviceInfoMapper.updateByPrimaryKey(record);
}
@Override
public int updateBatch(List<DeviceInfo> list) {
return deviceInfoMapper.updateBatch(list);
}
@Override
public int batchInsert(List<DeviceInfo> list) {
return deviceInfoMapper.batchInsert(list);
}
@Override
public int deleteByDeviceId(String deviceId){
return deviceInfoMapper.deleteByDeviceId(deviceId);
}
@Override
public DeviceInfo findOneByDeviceId(String deviceId){
return deviceInfoMapper.findOneByDeviceId(deviceId);
}
}
package com.mqttsnet.thinglinks.link.service.device.impl;
import com.alibaba.fastjson.JSON;
import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.enums.DeviceConnectStatus;
import com.mqttsnet.thinglinks.common.core.utils.DateUtils;
import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
import com.mqttsnet.thinglinks.common.log.annotation.Log;
import com.mqttsnet.thinglinks.common.redis.service.RedisService;
import com.mqttsnet.thinglinks.common.security.service.TokenService;
import com.mqttsnet.thinglinks.link.api.domain.device.entity.Device;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
......@@ -52,17 +54,8 @@ public class DeviceServiceImpl implements DeviceService {
private DeviceMapper deviceMapper;
@Autowired
private TokenService tokenService;
@Resource
private RemoteTdEngineService remoteTdEngineService;
@Autowired
private ProductService productService;
@Autowired
private ProductServicesService productServicesService;
/**
* 数据库名称
*/
@Value("${spring.datasource.dynamic.datasource.master.dbName:thinglinks}")
private String dataBaseName;
private RedisService redisService;
@Override
public int deleteByPrimaryKey(Long id) {
......@@ -217,33 +210,6 @@ public class DeviceServiceImpl implements DeviceService {
device.setCreateBy(sysUser.getUserName());
device.setCreateTime(DateUtils.getNowDate());
final int insertDeviceCount = deviceMapper.insertDevice(device);
Product product = productService.findOneByManufacturerIdAndModelAndProtocolTypeAndStatus(device.getManufacturerId(), device.getProductId(), device.getProtocolType(),"0");
if (StringUtils.isNull(product)) {
new Throwable("The side device reports data processing, but the product does not exist,DeviceIdentification:" + device.getDeviceIdentification() + ",Msg:" + JSON.toJSONString(device));
}
// 新增设备管理成功后,创建TD普通表
List<ProductServices> allByProductIdAndStatus = productServicesService.findAllByProductIdAndStatus(product.getId(), "0");
TableDto tableDto;
for (ProductServices productServices : allByProductIdAndStatus) {
tableDto = new TableDto();
tableDto.setDataBaseName(dataBaseName);
//超级表名称命名规则:产品类型_产品标识_服务名称_设备标识(非ClientId)
String superTableName = product.getProductType()+"_"+product.getProductIdentification()+"_"+productServices.getServiceName();
tableDto.setSuperTableName(superTableName);
tableDto.setTableName(superTableName+"_"+device.getDeviceIdentification());
//Tag的处理
List<Fields> tagsFieldValues = new ArrayList<>();
Fields fields = new Fields();
fields.setFieldValue(device.getDeviceIdentification());
tagsFieldValues.add(fields);
tableDto.setTagsFieldValues(tagsFieldValues);
final R<?> ctResult = remoteTdEngineService.createTable(tableDto);
if (ctResult.getCode() != 200) {
log.error("Create SuperTable Exception: " + ctResult.getMsg());
}else {
log.info("Create SuperTable Success: " + ctResult.getMsg());
}
}
return insertDeviceCount;
}
......@@ -320,6 +286,17 @@ public class DeviceServiceImpl implements DeviceService {
@Override
public Boolean cacheInvalidation(String clientId) {
Device oneByClientId = deviceMapper.findOneByClientId(clientId);
//设备信息缓存失效 删除缓存 更新数据库设备状态
if(StringUtils.isNotNull(oneByClientId)){
//删除缓存
redisService.delete(Constants.DEVICE_RECORD_KEY+clientId);
//更新数据库设备状态
Device device = new Device();
device.setId(oneByClientId.getId());
device.setConnectStatus(DeviceConnectStatus.INIT.getValue());
device.setUpdateTime(DateUtils.getNowDate());
deviceMapper.updateByPrimaryKeySelective(device);
}
log.info(oneByClientId.toString());
return null;
}
......@@ -338,5 +315,13 @@ public class DeviceServiceImpl implements DeviceService {
return 0;
}
@Override
public Long countDistinctClientIdByConnectStatus(String connectStatus){
return deviceMapper.countDistinctClientIdByConnectStatus(connectStatus);
}
}
......@@ -7,6 +7,7 @@ import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDto;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
import java.util.List;
/**
......@@ -137,12 +138,12 @@ public interface ProductService{
/**
* 初始化生成超级表模型
* @param productId productId==null 初始化所有产品:productId!=null 初始化指定产品
* @param productIds 产品ID集合 productIds==null 初始化所有产品:productIds!=null 初始化指定产品
* @param InitializeOrNot 是否初始化
* @return
* @throws Exception
*/
List<SuperTableDto> createSuperTableDataModel(Long productId,Boolean InitializeOrNot)throws Exception;
List<SuperTableDto> createSuperTableDataModel(Long[] productIds,Boolean InitializeOrNot)throws Exception;
......@@ -154,4 +155,9 @@ public interface ProductService{
Product findOneByProductIdentificationAndProtocolType(String productIdentification,String protocolType);
List<Product> findAllByIdInAndStatus(Collection<Long> idCollection,String status);
}
......@@ -10,10 +10,8 @@ import com.mqttsnet.thinglinks.common.core.constant.Constants;
import com.mqttsnet.thinglinks.common.core.domain.R;
import com.mqttsnet.thinglinks.common.core.enums.DataTypeEnum;
import com.mqttsnet.thinglinks.common.core.text.CharsetKit;
import com.mqttsnet.thinglinks.common.core.text.Convert;
import com.mqttsnet.thinglinks.common.core.text.UUID;
import com.mqttsnet.thinglinks.common.core.utils.DateUtils;
import com.mqttsnet.thinglinks.common.core.utils.SpringUtils;
import com.mqttsnet.thinglinks.common.core.utils.StringUtils;
import com.mqttsnet.thinglinks.common.core.web.domain.AjaxResult;
import com.mqttsnet.thinglinks.common.redis.service.RedisService;
......@@ -23,23 +21,17 @@ import com.mqttsnet.thinglinks.common.security.service.TokenService;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.Product;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.ProductProperties;
import com.mqttsnet.thinglinks.link.api.domain.product.entity.ProductServices;
import com.mqttsnet.thinglinks.link.api.domain.product.model.Commands;
import com.mqttsnet.thinglinks.link.api.domain.product.model.Properties;
import com.mqttsnet.thinglinks.link.api.domain.product.model.Services;
import com.mqttsnet.thinglinks.link.mapper.product.ProductMapper;
import com.mqttsnet.thinglinks.link.mapper.product.ProductPropertiesMapper;
import com.mqttsnet.thinglinks.link.mapper.product.ProductServicesMapper;
import com.mqttsnet.thinglinks.link.service.product.ProductPropertiesService;
import com.mqttsnet.thinglinks.link.service.product.ProductService;
import com.mqttsnet.thinglinks.link.service.product.ProductServicesService;
import com.mqttsnet.thinglinks.system.api.domain.SysDictData;
import com.mqttsnet.thinglinks.system.api.domain.SysUser;
import com.mqttsnet.thinglinks.system.api.model.LoginUser;
import com.mqttsnet.thinglinks.tdengine.api.RemoteTdEngineService;
import com.mqttsnet.thinglinks.tdengine.api.domain.Fields;
import com.mqttsnet.thinglinks.tdengine.api.domain.SuperTableDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -57,13 +49,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static cn.hutool.json.XMLTokener.entity;
/**
......@@ -390,15 +376,20 @@ public class ProductServiceImpl implements ProductService{
JSONArray properties = service.getJSONArray("properties");
//如果服务下属性值为空,没必要为该服务创建超级表,跳过该循环,进入下个服务
if (properties.isEmpty()) {
continue loop;
continue;
}
//构建超级表的表结构字段列表
List<Fields> schemaFields = new ArrayList<>();
//超级表第一个字段数据类型必须为时间戳
Fields firstColumn = new Fields();
firstColumn.setFieldName("ts");
firstColumn.setDataType(DataTypeEnum.TIMESTAMP);
schemaFields.add(firstColumn);
//超级表第一个字段数据类型必须为时间戳,默认Ts为当前系统时间
Fields tsColumn = new Fields();
tsColumn.setFieldName("ts");
tsColumn.setDataType(DataTypeEnum.TIMESTAMP);
schemaFields.add(tsColumn);
//超级表第二个字段为事件发生时间数据类型必须为时间戳
Fields eventTimeColumn = new Fields();
eventTimeColumn.setFieldName("event_time");
eventTimeColumn.setDataType(DataTypeEnum.TIMESTAMP);
schemaFields.add(eventTimeColumn);
//根据属性对象列表循环构建超级表表结构
for (int j = 0; j < properties.size(); j++) {
JSONObject propertie = properties.getJSONObject(j);
......@@ -417,7 +408,7 @@ public class ProductServiceImpl implements ProductService{
// 1:设备标识:deviceIdentification
List<Fields> tagsFields = new ArrayList<>();
Fields tags = new Fields();
tags.setFieldName("deviceIdentification");
tags.setFieldName("device_identification");
tags.setDataType(DataTypeEnum.BINARY);
tags.setSize(64);
tagsFields.add(tags);
......@@ -438,7 +429,7 @@ public class ProductServiceImpl implements ProductService{
redisService.deleteObject(Constants.TDENGINE_SUPERTABLEFILELDS+superTableName);
}
//在redis里存入新的超级表对的表结构信息
redisService.setCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName, JSON.toJSONString(superTableDto));
redisService.setCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName, superTableDto);
log.info("缓存超级表数据模型:{}",JSON.toJSONString(superTableDto));
}
}catch (Exception e){
......@@ -555,29 +546,27 @@ public class ProductServiceImpl implements ProductService{
/**
* 初始化生成超级表模型
* @param productId productId==null 初始化所有产品:productId!=null 初始化指定产品
* @param productIds 产品ID集合 productIds==null 初始化所有产品:productIds!=null 初始化指定产品
* @param InitializeOrNot 是否初始化
* @return
* @throws Exception
*/
@Async
@Override
public List<SuperTableDto> createSuperTableDataModel(Long productId,Boolean InitializeOrNot)throws Exception{
public List<SuperTableDto> createSuperTableDataModel(Long[] productIds,Boolean InitializeOrNot)throws Exception{
List<SuperTableDto> superTableDtoList = new ArrayList<>();
List<Product> allByStatus = null;
if (productId == null) {
allByStatus = this.findAllByStatus("0");
List<Product> productList = new ArrayList<>();
if (null==productIds) {
productList = this.findAllByStatus("0");
}else {
allByStatus = new ArrayList<>();
Product product = this.findOneByIdAndStatus(productId,"0");
allByStatus.add(product);
productList = this.findAllByIdInAndStatus(Arrays.asList(productIds),"0");
}
SuperTableDto superTableDto;
loop:
for (Product product : allByStatus) {
for (Product product : productList) {
List<ProductServices> allByProductIdAndStatus = productServicesService.findAllByProductIdAndStatus(product.getId(), "0");
if(StringUtils.isEmpty(allByProductIdAndStatus)){
continue loop;
continue;
}
for (ProductServices productServices : allByProductIdAndStatus) {
superTableDto = new SuperTableDto();
......@@ -597,11 +586,16 @@ public class ProductServiceImpl implements ProductService{
}
//构建超级表的表结构字段列表
List<Fields> schemaFields = new ArrayList<>();
//超级表第一个字段数据类型必须为时间戳
Fields firstColumn = new Fields();
firstColumn.setFieldName("ts");
firstColumn.setDataType(DataTypeEnum.TIMESTAMP);
schemaFields.add(firstColumn);
//超级表第一个字段数据类型必须为时间戳,默认Ts为当前系统时间
Fields tsColumn = new Fields();
tsColumn.setFieldName("ts");
tsColumn.setDataType(DataTypeEnum.TIMESTAMP);
schemaFields.add(tsColumn);
//超级表第二个字段为事件发生时间数据类型必须为时间戳
Fields eventTimeColumn = new Fields();
eventTimeColumn.setFieldName("event_time");
eventTimeColumn.setDataType(DataTypeEnum.TIMESTAMP);
schemaFields.add(eventTimeColumn);
//根据属性对象列表循环构建超级表表结构
for (ProductProperties productProperties : allByServiceId) {
//获取字段名称
......@@ -619,7 +613,7 @@ public class ProductServiceImpl implements ProductService{
// 1:设备标识:deviceIdentification
List<Fields> tagsFields = new ArrayList<>();
Fields tags = new Fields();
tags.setFieldName("deviceIdentification");
tags.setFieldName("device_identification");
tags.setDataType(DataTypeEnum.BINARY);
tags.setSize(64);
tagsFields.add(tags);
......@@ -633,7 +627,7 @@ public class ProductServiceImpl implements ProductService{
redisService.deleteObject(Constants.TDENGINE_SUPERTABLEFILELDS+superTableName);
}
//在redis里存入新的超级表对的表结构信息
redisService.setCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName, JSON.toJSONString(superTableDto));
redisService.setCacheObject(Constants.TDENGINE_SUPERTABLEFILELDS + superTableName, superTableDto);
log.info("缓存超级表数据模型:{}",JSON.toJSONString(superTableDto));
superTableDtoList.add(superTableDto);
if (InitializeOrNot){
......@@ -661,6 +655,22 @@ public class ProductServiceImpl implements ProductService{
return productMapper.findOneByIdAndStatus(id,status);
}
@Override
public Product findOneByProductIdentificationAndProtocolType(String productIdentification,String protocolType){
return productMapper.findOneByProductIdentificationAndProtocolType(productIdentification,protocolType);
}
@Override
public List<Product> findAllByIdInAndStatus(Collection<Long> idCollection, String status){
return productMapper.findAllByIdInAndStatus(idCollection,status);
}
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -18,8 +18,7 @@
<result column="connect_status" jdbcType="VARCHAR" property="connectStatus" />
<result column="is_will" jdbcType="VARCHAR" property="isWill" />
<result column="device_tags" jdbcType="VARCHAR" property="deviceTags" />
<result column="product_id" jdbcType="VARCHAR" property="productId" />
<result column="manufacturer_id" jdbcType="VARCHAR" property="manufacturerId" />
<result column="product_identification" jdbcType="VARCHAR" property="productIdentification" />
<result column="protocol_type" jdbcType="VARCHAR" property="protocolType" />
<result column="device_type" jdbcType="VARCHAR" property="deviceType" />
<result column="create_by" jdbcType="VARCHAR" property="createBy" />
......@@ -43,8 +42,7 @@
<result property="connectStatus" column="connect_status" />
<result property="isWill" column="is_will" />
<result property="deviceTags" column="device_tags" />
<result property="productId" column="product_id" />
<result property="manufacturerId" column="manufacturer_id" />
<result property="productIdentification" column="product_identification" />
<result property="protocolType" column="protocol_type" />
<result property="deviceType" column="device_type" />
<result property="createBy" column="create_by" />
......@@ -57,9 +55,12 @@
<!--@mbg.generated-->
id, client_id, user_name, `password`, app_id, auth_mode, device_identification, device_name,
connector, device_description, device_status, connect_status, is_will, device_tags,
product_id, manufacturer_id, protocol_type, device_type, create_by, create_time,
product_identification, protocol_type, device_type, create_by, create_time,
update_by, update_time, remark
</sql>
<sql id="OrderByCreateTimeDesc">
order by create_time desc
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
<!--@mbg.generated-->
select
......@@ -78,7 +79,7 @@
app_id, auth_mode, device_identification,
device_name, connector, device_description,
device_status, connect_status, is_will,
device_tags, product_id, manufacturer_id,
device_tags, product_identification,
protocol_type, device_type, create_by,
create_time, update_by, update_time,
remark)
......@@ -86,7 +87,7 @@
#{app_id,jdbcType=VARCHAR}, #{auth_mode,jdbcType=VARCHAR}, #{device_identification,jdbcType=VARCHAR},
#{device_name,jdbcType=VARCHAR}, #{connector,jdbcType=VARCHAR}, #{device_description,jdbcType=VARCHAR},
#{device_status,jdbcType=VARCHAR}, #{connect_status,jdbcType=VARCHAR}, #{is_will,jdbcType=VARCHAR},
#{device_tags,jdbcType=VARCHAR}, #{product_id,jdbcType=VARCHAR}, #{manufacturer_id,jdbcType=VARCHAR},
#{device_tags,jdbcType=VARCHAR}, #{product_identification,jdbcType=VARCHAR},
#{protocol_type,jdbcType=VARCHAR}, #{device_type,jdbcType=VARCHAR}, #{create_by,jdbcType=VARCHAR},
#{create_time,jdbcType=TIMESTAMP}, #{update_by,jdbcType=VARCHAR}, #{update_time,jdbcType=TIMESTAMP},
#{remark,jdbcType=VARCHAR})
......@@ -134,11 +135,8 @@
<if test="device_tags != null and device_tags != ''">
device_tags,
</if>
<if test="product_id != null and product_id != ''">
product_id,
</if>
<if test="manufacturer_id != null and manufacturer_id != ''">
manufacturer_id,
<if test="product_identification != null and product_identification != ''">
product_identification,
</if>
<if test="protocol_type != null and protocol_type != ''">
protocol_type,
......@@ -202,11 +200,8 @@
<if test="device_tags != null and device_tags != ''">
#{device_tags,jdbcType=VARCHAR},
</if>
<if test="product_id != null and product_id != ''">
#{product_id,jdbcType=VARCHAR},
</if>
<if test="manufacturer_id != null and manufacturer_id != ''">
#{manufacturer_id,jdbcType=VARCHAR},
<if test="product_identification != null and product_identification != ''">
#{product_identification,jdbcType=VARCHAR},
</if>
<if test="protocol_type != null and protocol_type != ''">
#{protocol_type,jdbcType=VARCHAR},
......@@ -274,11 +269,8 @@
<if test="device_tags != null and device_tags != ''">
device_tags = #{device_tags,jdbcType=VARCHAR},
</if>
<if test="product_id != null and product_id != ''">
product_id = #{product_id,jdbcType=VARCHAR},
</if>
<if test="manufacturer_id != null and manufacturer_id != ''">
manufacturer_id = #{manufacturer_id,jdbcType=VARCHAR},
<if test="product_identification != null and product_identification != ''">
product_identification = #{product_identification,jdbcType=VARCHAR},
</if>
<if test="protocol_type != null and protocol_type != ''">
protocol_type = #{protocol_type,jdbcType=VARCHAR},
......@@ -320,8 +312,7 @@
connect_status = #{connect_status,jdbcType=VARCHAR},
is_will = #{is_will,jdbcType=VARCHAR},
device_tags = #{device_tags,jdbcType=VARCHAR},
product_id = #{product_id,jdbcType=VARCHAR},
manufacturer_id = #{manufacturer_id,jdbcType=VARCHAR},
product_identification = #{product_identification,jdbcType=VARCHAR},
protocol_type = #{protocol_type,jdbcType=VARCHAR},
device_type = #{device_type,jdbcType=VARCHAR},
create_by = #{create_by,jdbcType=VARCHAR},
......@@ -400,14 +391,9 @@
when id = #{item.id,jdbcType=BIGINT} then #{item.device_tags,jdbcType=VARCHAR}
</foreach>
</trim>
<trim prefix="product_id = case" suffix="end,">
<trim prefix="product_identification = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when id = #{item.id,jdbcType=BIGINT} then #{item.product_id,jdbcType=VARCHAR}
</foreach>
</trim>
<trim prefix="manufacturer_id = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when id = #{item.id,jdbcType=BIGINT} then #{item.manufacturer_id,jdbcType=VARCHAR}
when id = #{item.id,jdbcType=BIGINT} then #{item.product_identification,jdbcType=VARCHAR}
</foreach>
</trim>
<trim prefix="protocol_type = case" suffix="end,">
......@@ -546,17 +532,10 @@
</if>
</foreach>
</trim>
<trim prefix="product_id = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.product_id != null">
when id = #{item.id,jdbcType=BIGINT} then #{item.product_id,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
<trim prefix="manufacturer_id = case" suffix="end,">
<trim prefix="product_identification = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.manufacturer_id != null">
when id = #{item.id,jdbcType=BIGINT} then #{item.manufacturer_id,jdbcType=VARCHAR}
<if test="item.product_identification != null">
when id = #{item.id,jdbcType=BIGINT} then #{item.product_identification,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
......@@ -620,7 +599,7 @@
insert into device
(client_id, user_name, `password`, app_id, auth_mode, device_identification, device_name,
connector, device_description, device_status, connect_status, is_will, device_tags,
product_id, manufacturer_id, protocol_type, device_type, create_by, create_time,
product_identification, protocol_type, device_type, create_by, create_time,
update_by, update_time, remark)
values
<foreach collection="list" item="item" separator=",">
......@@ -628,8 +607,8 @@
#{item.app_id,jdbcType=VARCHAR}, #{item.auth_mode,jdbcType=VARCHAR}, #{item.device_identification,jdbcType=VARCHAR},
#{item.device_name,jdbcType=VARCHAR}, #{item.connector,jdbcType=VARCHAR}, #{item.device_description,jdbcType=VARCHAR},
#{item.device_status,jdbcType=VARCHAR}, #{item.connect_status,jdbcType=VARCHAR},
#{item.is_will,jdbcType=VARCHAR}, #{item.device_tags,jdbcType=VARCHAR}, #{item.product_id,jdbcType=VARCHAR},
#{item.manufacturer_id,jdbcType=VARCHAR}, #{item.protocol_type,jdbcType=VARCHAR},
#{item.is_will,jdbcType=VARCHAR}, #{item.device_tags,jdbcType=VARCHAR}, #{item.product_identification,jdbcType=VARCHAR},
#{item.protocol_type,jdbcType=VARCHAR},
#{item.device_type,jdbcType=VARCHAR}, #{item.create_by,jdbcType=VARCHAR}, #{item.create_time,jdbcType=TIMESTAMP},
#{item.update_by,jdbcType=VARCHAR}, #{item.update_time,jdbcType=TIMESTAMP}, #{item.remark,jdbcType=VARCHAR}
)
......@@ -655,8 +634,7 @@
connect_status,
is_will,
device_tags,
product_id,
manufacturer_id,
product_identification,
protocol_type,
device_type,
create_by,
......@@ -683,8 +661,7 @@
#{connect_status,jdbcType=VARCHAR},
#{is_will,jdbcType=VARCHAR},
#{device_tags,jdbcType=VARCHAR},
#{product_id,jdbcType=VARCHAR},
#{manufacturer_id,jdbcType=VARCHAR},
#{product_identification,jdbcType=VARCHAR},
#{protocol_type,jdbcType=VARCHAR},
#{device_type,jdbcType=VARCHAR},
#{create_by,jdbcType=VARCHAR},
......@@ -711,8 +688,7 @@
connect_status = #{connect_status,jdbcType=VARCHAR},
is_will = #{is_will,jdbcType=VARCHAR},
device_tags = #{device_tags,jdbcType=VARCHAR},
product_id = #{product_id,jdbcType=VARCHAR},
manufacturer_id = #{manufacturer_id,jdbcType=VARCHAR},
product_identification = #{product_identification,jdbcType=VARCHAR},
protocol_type = #{protocol_type,jdbcType=VARCHAR},
device_type = #{device_type,jdbcType=VARCHAR},
create_by = #{create_by,jdbcType=VARCHAR},
......@@ -768,11 +744,8 @@
<if test="device_tags != null and device_tags != ''">
device_tags,
</if>
<if test="product_id != null and product_id != ''">
product_id,
</if>
<if test="manufacturer_id != null and manufacturer_id != ''">
manufacturer_id,
<if test="product_identification != null and product_identification != ''">
product_identification,
</if>
<if test="protocol_type != null and protocol_type != ''">
protocol_type,
......@@ -840,11 +813,8 @@
<if test="device_tags != null and device_tags != ''">
#{device_tags,jdbcType=VARCHAR},
</if>
<if test="product_id != null and product_id != ''">
#{product_id,jdbcType=VARCHAR},
</if>
<if test="manufacturer_id != null and manufacturer_id != ''">
#{manufacturer_id,jdbcType=VARCHAR},
<if test="product_identification != null and product_identification != ''">
#{product_identification,jdbcType=VARCHAR},
</if>
<if test="protocol_type != null and protocol_type != ''">
#{protocol_type,jdbcType=VARCHAR},
......@@ -912,11 +882,8 @@
<if test="device_tags != null and device_tags != ''">
device_tags = #{device_tags,jdbcType=VARCHAR},
</if>
<if test="product_id != null and product_id != ''">
product_id = #{product_id,jdbcType=VARCHAR},
</if>
<if test="manufacturer_id != null and manufacturer_id != ''">
manufacturer_id = #{manufacturer_id,jdbcType=VARCHAR},
<if test="product_identification != null and product_identification != ''">
product_identification = #{product_identification,jdbcType=VARCHAR},
</if>
<if test="protocol_type != null and protocol_type != ''">
protocol_type = #{protocol_type,jdbcType=VARCHAR},
......@@ -1061,11 +1028,8 @@
<if test="deviceTags != null and deviceTags != ''">
and device_tags=#{deviceTags,jdbcType=VARCHAR}
</if>
<if test="productId != null and productId != ''">
and product_id=#{productId,jdbcType=VARCHAR}
</if>
<if test="manufacturerId != null and manufacturerId != ''">
and manufacturer_id=#{manufacturerId,jdbcType=VARCHAR}
<if test="productIdentification != null and productIdentification != ''">
and product_identification=#{productIdentification,jdbcType=VARCHAR}
</if>
<if test="protocolType != null and protocolType != ''">
and protocol_type=#{protocolType,jdbcType=VARCHAR}
......@@ -1109,10 +1073,10 @@
</where>
</select>
<sql id="selectDeviceVo">
select id, client_id, user_name, password, app_id, auth_mode, device_identification, device_name, connector, device_description, device_status, connect_status, is_will, device_tags, product_id, manufacturer_id, protocol_type, device_type, create_by, create_time, update_by, update_time, remark from device
select id, client_id, user_name, password, app_id, auth_mode, device_identification, device_name, connector, device_description, device_status, connect_status, is_will, device_tags, product_identification, protocol_type, device_type, create_by, create_time, update_by, update_time, remark from device
</sql>
<select id="selectDeviceList" parameterType="Device" resultMap="DeviceResult">
<select id="selectDeviceList" parameterType="com.mqttsnet.thinglinks.link.api.domain.device.entity.Device" resultMap="DeviceResult">
<include refid="selectDeviceVo"/>
<where>
<if test="clientId != null and clientId != ''"> and client_id like concat('%', #{clientId}, '%')</if>
......@@ -1123,12 +1087,12 @@
<if test="connectStatus != null and connectStatus != ''"> and connect_status = #{connectStatus}</if>
<if test="isWill != null and isWill != ''"> and is_will = #{isWill}</if>
<if test="deviceTags != null and deviceTags != ''"> and device_tags = #{deviceTags}</if>
<if test="productId != null and productId != ''"> and product_id = #{productId}</if>
<if test="manufacturerId != null and manufacturerId != ''"> and manufacturer_id = #{manufacturerId}</if>
<if test="productIdentification != null and productIdentification != ''"> and product_identification = #{productIdentification}</if>
<if test="protocolType != null and protocolType != ''"> and protocol_type = #{protocolType}</if>
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
<if test="createTime != null "> and create_time = #{createTime}</if>
</where>
<include refid="OrderByCreateTimeDesc"/>
</select>
<select id="selectDeviceById" parameterType="Long" resultMap="DeviceResult">
......@@ -1136,7 +1100,7 @@
where id = #{id}
</select>
<insert id="insertDevice" parameterType="Device" useGeneratedKeys="true" keyProperty="id">
<insert id="insertDevice" parameterType="com.mqttsnet.thinglinks.link.api.domain.device.entity.Device" useGeneratedKeys="true" keyProperty="id">
insert into device
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="clientId != null and clientId != ''">client_id,</if>
......@@ -1152,8 +1116,7 @@
<if test="connectStatus != null and connectStatus != ''">connect_status,</if>
<if test="isWill != null">is_will,</if>
<if test="deviceTags != null and deviceTags != ''">device_tags,</if>
<if test="productId != null and productId != ''">product_id,</if>
<if test="manufacturerId != null and manufacturerId != ''">manufacturer_id,</if>
<if test="productIdentification != null and productIdentification != ''">product_identification,</if>
<if test="protocolType != null and protocolType != ''">protocol_type,</if>
<if test="deviceType != null and deviceType != ''">device_type,</if>
<if test="createBy != null">create_by,</if>
......@@ -1176,8 +1139,7 @@
<if test="connectStatus != null and connectStatus != ''">#{connectStatus},</if>
<if test="isWill != null">#{isWill},</if>
<if test="deviceTags != null and deviceTags != ''">#{deviceTags},</if>
<if test="productId != null and productId != ''">#{productId},</if>
<if test="manufacturerId != null and manufacturerId != ''">#{manufacturerId},</if>
<if test="productIdentification != null and productIdentification != ''">#{productIdentification},</if>
<if test="protocolType != null and protocolType != ''">#{protocolType},</if>
<if test="deviceType != null and deviceType != ''">#{deviceType},</if>
<if test="createBy != null">#{createBy},</if>
......@@ -1188,7 +1150,7 @@
</trim>
</insert>
<update id="updateDevice" parameterType="Device">
<update id="updateDevice" parameterType="com.mqttsnet.thinglinks.link.api.domain.device.entity.Device">
update device
<trim prefix="SET" suffixOverrides=",">
<if test="clientId != null and clientId != ''">client_id = #{clientId},</if>
......@@ -1204,8 +1166,7 @@
<if test="connectStatus != null and connectStatus != ''">connect_status = #{connectStatus},</if>
<if test="isWill != null">is_will = #{isWill},</if>
<if test="deviceTags != null and deviceTags != ''">device_tags = #{deviceTags},</if>
<if test="productId != null and productId != ''">product_id = #{productId},</if>
<if test="manufacturerId != null and manufacturerId != ''">manufacturer_id = #{manufacturerId},</if>
<if test="productIdentification != null and productIdentification != ''">product_identification = #{productIdentification},</if>
<if test="protocolType != null and protocolType != ''">protocol_type = #{protocolType},</if>
<if test="deviceType != null and deviceType != ''">device_type = #{deviceType},</if>
<if test="createBy != null">create_by = #{createBy},</if>
......@@ -1294,4 +1255,15 @@
</if>
</where>
</select>
<!--Author By ShiHuan Sun E-mail: 13733918655@163.com on 2022-05-04-->
<select id="countDistinctClientIdByConnectStatus" resultType="java.lang.Long">
select count(distinct(client_id))
from device
<where>
<if test="connectStatus != null">
and connect_status=#{connectStatus}
</if>
</where>
</select>
</mapper>
\ No newline at end of file
......@@ -29,6 +29,9 @@
manufacturer_name, model, data_format, device_type, protocol_type, `status`, remark,
create_by, create_time, update_by, update_time
</sql>
<sql id="OrderByCreateTimeDesc">
order by create_time desc
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
<!--@mbg.generated-->
select
......@@ -744,6 +747,7 @@
<if test="manufacturerName != null and manufacturerName != ''"> and manufacturer_name like concat('%', #{manufacturerName}, '%')</if>
<if test="model != null and model != ''"> and model = #{model}</if>
</where>
<include refid="OrderByCreateTimeDesc" />
</select>
<select id="selectProductById" parameterType="Long" resultMap="BaseResultMap">
......@@ -925,4 +929,38 @@
</if>
</where>
</select>
<!--Author By ShiHuan Sun E-mail: 13733918655@163.com on 2022-04-27-->
<select id="findOneByProductIdentificationAndProtocolType" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from product
<where>
<if test="productIdentification != null">
and product_identification=#{productIdentification,jdbcType=VARCHAR}
</if>
<if test="protocolType != null">
and protocol_type=#{protocolType,jdbcType=VARCHAR}
</if>
</where>
</select>
<!--Author By ShiHuan Sun E-mail: 13733918655@163.com on 2022-04-27-->
<select id="findAllByIdInAndStatus" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from product
<where>
<if test="idCollection != null and idCollection.size() > 0">
and id in
<foreach item="item" index="index" collection="idCollection"
open="(" separator="," close=")">
#{item,jdbcType=BIGINT}
</foreach>
</if>
<if test="status != null">
and `status`=#{status,jdbcType=VARCHAR}
</if>
</where>
</select>
</mapper>
\ No newline at end of file
......@@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
## TDengine SpringBoot + Mybatis Demo
## 超级表设计概念:每个设备一张表,每类设备一个超级表 ;
## 超级表命名规则 : 产品类型_产品标识_服务名称
## 子表命名规则 : 产品类型_产品标识_服务名称_设备标识(非ClientId
## 子表命名规则 : 产品类型_产品标识_服务名称_设备标识(设备唯一标识
## TDengine 服务端版本及搭建
......
......@@ -41,7 +41,7 @@ public class ProductCreateSuperTableMessageConsumer implements RocketMQListener
return;
}
JSONObject stableMessage = JSONObject.parseObject(String.valueOf(message));
log.info("TDengine消费{}超级表消息:{}"+stableMessage.get("type")+stableMessage.get("msg"));
log.info("TDengine消费{}超级表消息:{}",stableMessage.get("type"),stableMessage.get("msg"));
if("create".equals(stableMessage.get("type"))){
try {
productSuperTableCreateOrUpdateService.createProductSuperTable(String.valueOf(stableMessage.get("msg")));
......
......@@ -100,8 +100,8 @@ public class TdEngineServiceImpl implements TdEngineService {
Integer count = tdEngineMapper.checkTableExists(dataBaseName, tableName);
return count == 1;
} catch (Exception e) {
log.error("检测{}表失败", e.getMessage());
return true;
log.error("数据库表不否存在");
return false;
}
}
......
package com.mqttsnet.thinglinks.tdengine.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Description 时间工具类
* @author mqtts.net
* @Email 13733918655@163.com
* @Date 2019/12/9 20:45
* @Version 1.0
*/
public class DateUntils {
public static Date getCurrentDate() {
return new Date();
}
public static String getDateString(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static String getDateStrings(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static String getDateStampString(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static Date getDateString(String date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = null;
try {
date1 = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return date1;
}
public static String strToDateFormat(String date) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
formatter.setLenient(false);
Date newDate = formatter.parse(date);
formatter = new SimpleDateFormat("yyyy-MM-dd");
return formatter.format(newDate);
}
public static String getDateFormatString(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static String getDateFormatTostr(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static String getCurrentDateWithZero(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static String getCurrentDateWithNight(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
String previousDate = dateFormat.format(date);
return previousDate;
}
public static String getPreviousDateWithZero(Date date) {
Date prevDate = new Date(date.getTime() - (24 * 3600000));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
String previousDate = dateFormat.format(prevDate);
return previousDate;
}
public static Date getFomatDate(String str) {
//创建SimpleDateFormat对象实例并定义好转换格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
// 注意格式需要与上面一致,不然会出现异常
date = sdf.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
/**
* 将时间戳转换为日期
*
* @param stamp 时间戳
* @return 时间,返回格式为 yyyy-MM-dd-HH-mm-ss
*/
public static String Stamp2Date(Long stamp) {
String result = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(stamp);
return result;
}
/**
* 取得当前时间戳(精确到秒)
*
* @return
*/
public static String timeStamp() {
long time = System.currentTimeMillis();
String t = String.valueOf(time / 1000);
return t;
}
/**
* 取得当前时间戳(精确到秒)Long 类型
*
* @return
*/
public static Long timeStampL() {
long time = System.currentTimeMillis();
return time / 1000;
}
/**
* 获取指定url中的某个参数
*
* @param url
* @param name
* @return
*/
public static String getParamByUrl(String url, String name) {
url += "&";
String pattern = "(\\?|&){1}#{0,1}" + name + "=[a-zA-Z0-9]*(&{1})";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(url);
if (m.find()) {
System.out.println(m.group(0));
return m.group(0).split("=")[1].replace("&", "");
} else {
return null;
}
}
public static void main(String[] args) throws ParseException {
String sTime = "2019-05-17 00:00:00";
String eTime = "2019-05-19 16:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = getFomatDate(sTime);
Date d2 = getFomatDate(eTime);
List<String> times = getTimes(d1,d2,3600000L);
for (String str:times) {
System.out.println("得到的时间集合=:"+str);
}
List<String> times1 = getTimes(getFomatDate("2021-09-22 00:00:00"), getFomatDate("2021-09-30 00:00:00"), 86400000);
System.out.println(times1);
}
//获取时间段内,时间间隔的所以时间点集合
public static List<String> getTimes(Date startTime, Date endTime,long ll) throws ParseException {
List<String> times = new ArrayList<>();
Calendar calendar = Calendar.getInstance();
calendar.setTime(startTime);
long startTimeStamp = calendar.getTimeInMillis();//起始的毫秒数
calendar.setTime(endTime);
long endTimeStamp = calendar.getTimeInMillis();//截止时间毫秒数
while (true){
long temp = startTimeStamp + ll;
if(temp <= endTimeStamp){
startTimeStamp = temp;
Calendar _calendar = Calendar.getInstance();
_calendar.setTimeInMillis(temp);
int year = _calendar.get(Calendar.YEAR);
int month = _calendar.get(Calendar.MONTH);
int day = _calendar.get(Calendar.DAY_OF_MONTH);
int hour = _calendar.get(Calendar.HOUR_OF_DAY);//24小时制
//int hour = calendar.get(Calendar.HOUR);//12小时制
int minute = _calendar.get(Calendar.MINUTE);
int second = _calendar.get(Calendar.SECOND);
String time = year + "-" + (month + 1) + "-" + day + " " + hour + ":" + minute + ":" + second;
//时间格式处理
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(time);
long ts = date.getTime();
long lt = new Long(String.valueOf(ts));
Date date1 = new Date(lt);
res = simpleDateFormat.format(date1);
times.add(res);
}else {
break;
}
}
return times;
}
/*
* 将时间转换为时间戳
*/
public static String dateToStamp(String s) throws ParseException {
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(s);
long ts = date.getTime();
res = String.valueOf(ts);
return res;
}
/*
* 将时间戳转换为时间
*/
public static String stampToDate(String s){
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long lt = new Long(s);
Date date = new Date(lt);
res = simpleDateFormat.format(date);
return res;
}
}
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -117,15 +117,21 @@
<insert id="insertData">
insert into #{dataBaseName}.#{tableName}
<foreach item="item" collection="tagsFieldValues" separator=","
<foreach item="item" collection="schemaFieldValues" separator=","
open="(" close=")" index="">
#{item.fieldName}
</foreach>
values
using #{dataBaseName}.#{superTableName}
tags
<foreach item="item" collection="tagsFieldValues" separator=","
open="(" close=")" index="">
#{item.fieldValue}
</foreach>
values
<foreach item="item" collection="schemaFieldValues" separator=","
open="(" close=")" index="">
#{item.fieldValue}
</foreach>
</insert>
<select id="selectByTimestamp" parameterType="com.mqttsnet.thinglinks.tdengine.api.domain.SelectDto"
......
import request from '@/utils/request'
import { praseStrEmpty } from "@/utils/thinglinks";
// 查询设备管理列表
export function listDevice(query) {
......@@ -12,7 +13,7 @@ export function listDevice(query) {
// 查询设备管理详细
export function getDevice(id) {
return request({
url: '/link/device/' + id,
url: '/link/device/' + praseStrEmpty(id),
method: 'get'
})
}
......
import request from '@/utils/request'
import { praseStrEmpty } from "@/utils/ruoyi";
import { praseStrEmpty } from "@/utils/thinglinks";
// 查询用户列表
export function listUser(query) {
......
import request from '@/utils/request'
import { praseStrEmpty } from "@/utils/thinglinks";
export function proOptions() {
return request({
url: '/api/tdengine/shadow/proOptions',
method: 'get',
})
}
export function dataList(query) {
return request({
url: '/api/tdengine/shadow/dataList',
method: 'get',
params: query
})
}
export function dataCharts() {
return request({
url: '/api/tdengine/shadow/dataCharts',
method: 'get',
})
}
......@@ -18,7 +18,7 @@ import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/thinglinks";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
......
import Vue from 'vue'
import { mergeRecursive } from "@/utils/ruoyi";
import { mergeRecursive } from "@/utils/thinglinks";
import DictMeta from './DictMeta'
import DictData from './DictData'
......
import { mergeRecursive } from "@/utils/ruoyi";
import { mergeRecursive } from "@/utils/thinglinks";
import DictOptions from './DictOptions'
/**
......
import { mergeRecursive } from "@/utils/ruoyi";
import { mergeRecursive } from "@/utils/thinglinks";
import dictConverter from './DictConverter'
export const options = {
......
import { parseTime } from './ruoyi'
import { parseTime } from './thinglinks'
/**
* 表格时间格式化
*/
export function formatDate(cellValue) {
if (cellValue == null || cellValue == "") return "";
var date = new Date(cellValue)
var date = new Date(cellValue)
var year = date.getFullYear()
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
......@@ -330,7 +330,7 @@ export function makeMap(str, expectsLowerCase) {
? val => map[val.toLowerCase()]
: val => map[val]
}
export const exportDefault = 'export default '
export const beautifierConf = {
......@@ -387,4 +387,4 @@ export function camelCase(str) {
export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}
......@@ -3,7 +3,7 @@ import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import { tansParams, blobValidate } from "@/utils/thinglinks";
import { saveAs } from 'file-saver'
let downloadLoadingInstance;
......
<template>
<div :class="$style['app-content']">
<div>
<el-button type="text">
<i class="el-icon-d-arrow-left" style="font-size: 20px" @click="goBack"></i>
</el-button>
<span style="font-size: 20px; font-weight: bold">
{{
topicName
}}
</span>
&nbsp;&nbsp;&nbsp;
<!-- <el-tag v-if="baseInfo.onlineStatus == 0" type="success" :hit="false" size="small">在线</el-tag>
<el-tag v-if="baseInfo.onlineStatus == 1" type="danger" :hit="false" size="small">离线</el-tag>
<el-tag v-if="baseInfo.onlineStatus == 2" type="warning" size="small" :hit="false">未连接</el-tag>-->
</div>
<!-- <el-table border highlight-current-row :data="tableData">
<el-table-column align="center" prop="dataKey" label="指标" show-overflow-tooltip></el-table-column>
<el-table-column align="center" prop="dataValue" label="指标值" show-overflow-tooltip></el-table-column>
</el-table>-->
<table :class="$style['device-table']" border="1">
<tr>
<th>指标</th>
<th>指标值</th>
<th>指标</th>
<th>指标值</th>
</tr>
<tr v-for="(item,index) in tableNewData" :key="index">
<template v-for="items in item">
<td>{{items.dataKey}}</td>
<td>{{items.dataValue}}</td>
</template>
</tr>
</table>
</div>
</template>
<script>
import { dataList } from "@/api/tdengine/shadow";
export default {
data() {
return {
tableData: [],
tableNewData: [],
topicName: ""
};
},
mounted() {
this.getList();
this.topicName = this.$route.query.row.topicName;
},
beforeDestroy() {
//清理工作 避免内存泄漏
//销毁监听事件
},
methods: {
getList() {
let params = {
clientId: this.$route.query.clientId,
eventTime: this.$route.query.row.eventTime
};
dataList(params).then(res => {
if (res.code == 200) {
this.tableData = res.data;
this.getData();
}
});
},
getData() {
const arr = [];
let minarr = [];
this.tableData.forEach(cate => {
if (minarr.length === 2) {
minarr = [];
}
if (minarr.length == 0) {
arr.push(minarr);
}
minarr.push(cate);
});
this.tableNewData = arr;
},
goBack() {
this.$router.push({
path: "/shadow/Terminal",
query: {
activeNameBack: this.$route.query.activeName,
clientIdBack: this.$route.query.clientId,
startTime: this.$route.query.startTime,
endTime: this.$route.query.endTime
}
});
}
}
};
</script>
<style lang="scss" module>
.app-content {
padding: 20px;
}
.device-table {
table-layout: fixed;
width: 100%;
margin-top: 15px;
margin-bottom: 15px;
border-collapse: collapse;
border: 1px solid #cfdbe6;
// border: none;
font-size: 14px;
td:nth-child(odd) {
width: 30%;
overflow: hidden;
padding: 10px 15px;
// background: #f8f8f9;
}
td:nth-child(even) {
width: 10%;
text-overflow: ellipsis;
white-space: nowrap;
word-break: keep-all;
overflow: hidden;
padding: 10px 15px;
}
th {
height: 40px;
background: rgb(230, 245, 243);
}
th:nth-child(odd) {
width: 20%;
}
th:nth-child(even) {
width: 10%;
}
}
.device-table1 {
table-layout: fixed;
width: 100%;
margin-top: 15px;
margin-bottom: 15px;
border-collapse: collapse;
border: 1px solid #dfe6ec;
// border: none;
font-size: 14px;
// min-height: 300px;
th {
height: 40px !important;
background: rgb(230, 245, 243);
}
.tdClass {
width: 10%;
overflow: hidden;
padding: 10px 15px;
text-align: center;
// background: #f8f8f9;
}
.tdStatus {
width: 19%;
overflow: hidden;
padding: 10px 15px;
// background: #f8f8f9;
}
.tdZB {
width: 40%;
// text-overflow: ellipsis;
// white-space: nowrap;
// word-break: keep-all;
overflow: hidden;
padding: 10px 15px;
}
.tdZB1 {
width: 40%;
// text-overflow: ellipsis;
// white-space: nowrap;
// word-break: keep-all;
// background: #f8f8f9;
overflow: hidden;
padding: 10px 15px;
}
}
.greencircle {
display: inline-block;
vertical-align: middle;
width: 24px;
height: 24px;
background: url("/assets/images/common/green_point.png") no-repeat
50% 50%;
background-size: 100%;
margin-left: 8px;
}
.redcircle {
display: inline-block;
vertical-align: middle;
width: 24px;
height: 24px;
background: url("/assets/images/common/red_point.png") no-repeat 50%
50%;
background-size: 100%;
margin-left: 8px;
}
.tdZB1:hover {
color: #56b4b0;
}
</style>
<style scoped>
.el-form-item {
margin-bottom: 0px !important;
}
</style>
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -33,7 +33,8 @@ module.exports = {
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:19100`,
// target: `http://localhost:19100`,
target: `http://frp1.xiaonannet.com:6901`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
......@@ -11,6 +11,7 @@ spring:
# 环境配置
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册