Prechádzať zdrojové kódy

整合fastbee所有模块

zhangcl 6 mesiacov pred
rodič
commit
9da1becd73
100 zmenil súbory, kde vykonal 8909 pridanie a 2 odobranie
  1. 3 2
      pom.xml
  2. 112 0
      yudao-dependencies/pom.xml
  3. 191 0
      yudao-module-things/fastbee-common/pom.xml
  4. 19 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Anonymous.java
  5. 33 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/DataScope.java
  6. 28 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/DataSource.java
  7. 22 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/DictFormat.java
  8. 187 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Excel.java
  9. 18 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Excels.java
  10. 46 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Log.java
  11. 40 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/RateLimiter.java
  12. 31 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/RepeatSubmit.java
  13. 21 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/SysProtocol.java
  14. 104 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/config/DeviceTask.java
  15. 135 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/config/RuoYiConfig.java
  16. 49 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/CacheConstants.java
  17. 142 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/Constants.java
  18. 258 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/FastBeeConstant.java
  19. 117 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/GenConstants.java
  20. 105 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/HttpStatus.java
  21. 41 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/ProductAuthConstant.java
  22. 50 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/ScheduleConstants.java
  23. 9 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/SipConstants.java
  24. 78 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/UserConstants.java
  25. 216 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/controller/BaseController.java
  26. 214 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/AjaxResult.java
  27. 43 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/BaseDO.java
  28. 126 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/BaseEntity.java
  29. 112 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/CommonResult.java
  30. 25 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/PageParam.java
  31. 42 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/PageResult.java
  32. 115 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/R.java
  33. 56 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/SortingField.java
  34. 20 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/TenantBaseDO.java
  35. 79 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/TreeEntity.java
  36. 77 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/TreeSelect.java
  37. 219 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysDept.java
  38. 189 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysDictData.java
  39. 104 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysDictType.java
  40. 279 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysMenu.java
  41. 257 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysRole.java
  42. 346 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysUser.java
  43. 22 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/BindLoginBody.java
  44. 21 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/BindRegisterBody.java
  45. 82 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginBody.java
  46. 266 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginUser.java
  47. 11 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/RegisterBody.java
  48. 22 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/iot/response/DashDeviceTotalDto.java
  49. 26 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/iot/response/DeCodeBo.java
  50. 70 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/iot/response/IdentityAndName.java
  51. 17 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceReplyBo.java
  52. 104 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceReport.java
  53. 73 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceReportBo.java
  54. 35 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceStatusBo.java
  55. 62 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/InvokeReqDto.java
  56. 51 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/MQSendMessageBo.java
  57. 51 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/MessageReplyBo.java
  58. 49 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceData.java
  59. 69 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceDownMessage.java
  60. 33 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceFunctionMessage.java
  61. 20 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceMessage.java
  62. 20 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/InstructionsMessage.java
  63. 26 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/MqttBo.java
  64. 39 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/PropRead.java
  65. 21 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/ProtocolDto.java
  66. 18 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/SubDeviceMessage.java
  67. 17 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/ota/OtaReplyMessage.java
  68. 46 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/ota/OtaUpgradeBo.java
  69. 54 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/ota/OtaUpgradeDelayTask.java
  70. 101 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/page/PageDomain.java
  71. 85 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/page/TableDataInfo.java
  72. 56 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/page/TableSupport.java
  73. 33 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/protocol/Message.java
  74. 87 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/protocol/modbus/ModbusCode.java
  75. 735 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisCache.java
  76. 99 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisKeyBuilder.java
  77. 113 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisKeyDefine.java
  78. 28 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisKeyRegistry.java
  79. 86 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/CharsetKit.java
  80. 1000 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/Convert.java
  81. 13 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/IntArrayValuable.java
  82. 20 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/KeyValue.java
  83. 92 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/StrFormatter.java
  84. 44 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/NeuronModel.java
  85. 38 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/SceneThingsModelItem.java
  86. 109 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/ThingsModelSimpleItem.java
  87. 76 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/ThingsModelValuesInput.java
  88. 20 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/BusinessStatus.java
  89. 59 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/BusinessType.java
  90. 36 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/CommonStatusEnum.java
  91. 37 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/DataEnum.java
  92. 19 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/DataSourceType.java
  93. 36 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/DeviceStatus.java
  94. 23 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/ExceptionCode.java
  95. 21 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/FunctionReplyStatus.java
  96. 52 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/GlobalErrorCodeConstants.java
  97. 36 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/HttpMethod.java
  98. 14 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/IErrorCode.java
  99. 20 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/LimitType.java
  100. 38 0
      yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/ModbusDataType.java

+ 3 - 2
pom.xml

@@ -16,8 +16,8 @@
         <module>yudao-module-system</module>
         <module>yudao-module-infra</module>
 <!--        <module>yudao-module-member</module>-->
-<!--        <module>yudao-module-bpm</module>-->
-<!--        <module>yudao-module-report</module>-->
+        <module>yudao-module-bpm</module>
+        <module>yudao-module-report</module>
 <!--        <module>yudao-module-mp</module>-->
 <!--        <module>yudao-module-pay</module>-->
 <!--        <module>yudao-module-mall</module>-->
@@ -26,6 +26,7 @@
 <!--        <module>yudao-module-iot</module>-->
         <!-- AI 大模型的开启,请参考 https://doc.iocoder.cn/ai/build/ 文档,对 JDK 版本要要求! -->
 <!--        <module>yudao-module-ai</module>-->
+        <module>yudao-module-things</module>
     </modules>
 
     <name>${project.artifactId}</name>

+ 112 - 0
yudao-dependencies/pom.xml

@@ -76,6 +76,17 @@
         <weixin-java.version>4.6.0</weixin-java.version>
         <!-- 专属于 JDK8 安全漏洞升级 -->
         <logback.version>1.2.13</logback.version> <!-- 无法使用 1.3.X 版本,启动会报错 -->
+        <!-- fastbee 整合新增 -->
+        <fastbee.version>3.8.5</fastbee.version>
+        <jwt.version>0.9.1</jwt.version>
+        <fastjson2.version>2.0.20</fastjson2.version>
+        <oshi.version>6.1.6</oshi.version>
+        <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
+        <commons.fileupload.version>1.4</commons.fileupload.version>
+        <poi.version>4.1.2</poi.version>
+        <bitwalker.version>1.21</bitwalker.version>
+        <easyexcel-core.version>3.3.1</easyexcel-core.version>
+        <kaptcha.version>2.3.3</kaptcha.version>
     </properties>
 
     <dependencyManagement>
@@ -638,6 +649,107 @@
                 <artifactId>logback-classic</artifactId>
                 <version>${logback.version}</version>
             </dependency>
+
+            <!-- fastbee 整合新增 -->
+            <!-- Token生成与解析-->
+            <dependency>
+                <groupId>io.jsonwebtoken</groupId>
+                <artifactId>jjwt</artifactId>
+                <version>${jwt.version}</version>
+            </dependency>
+
+            <!-- 阿里JSON解析器 -->
+            <dependency>
+                <groupId>com.alibaba.fastjson2</groupId>
+                <artifactId>fastjson2</artifactId>
+                <version>${fastjson2.version}</version>
+            </dependency>
+
+            <!-- 获取系统信息 -->
+            <dependency>
+                <groupId>com.github.oshi</groupId>
+                <artifactId>oshi-core</artifactId>
+                <version>${oshi.version}</version>
+            </dependency>
+
+            <!-- pagehelper 分页插件 -->
+            <dependency>
+                <groupId>com.github.pagehelper</groupId>
+                <artifactId>pagehelper-spring-boot-starter</artifactId>
+                <version>${pagehelper.boot.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>org.mybatis</groupId>
+                        <artifactId>mybatis</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <!-- 文件上传工具类 -->
+            <dependency>
+                <groupId>commons-fileupload</groupId>
+                <artifactId>commons-fileupload</artifactId>
+                <version>${commons.fileupload.version}</version>
+            </dependency>
+
+            <!-- excel工具 -->
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml</artifactId>
+                <version>${poi.version}</version>
+            </dependency>
+
+            <!-- 解析客户端操作系统、浏览器等 -->
+            <dependency>
+                <groupId>eu.bitwalker</groupId>
+                <artifactId>UserAgentUtils</artifactId>
+                <version>${bitwalker.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>easyexcel-core</artifactId>
+                <version>${easyexcel-core.version}</version>
+            </dependency>
+            <!-- 验证码 -->
+            <dependency>
+                <groupId>pro.fessional</groupId>
+                <artifactId>kaptcha</artifactId>
+                <version>${kaptcha.version}</version>
+            </dependency>
+            <!--基于netty的MqttBroker-->
+            <dependency>
+                <groupId>com.fastbee</groupId>
+                <artifactId>mqtt-broker</artifactId>
+                <version>${fastbee.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fastbee</groupId>
+                <artifactId>sip-server</artifactId>
+                <version>${fastbee.version}</version>
+            </dependency>
+            <!-- 核心模块-->
+            <dependency>
+                <groupId>com.fastbee</groupId>
+                <artifactId>fastbee-framework</artifactId>
+                <version>${fastbee.version}</version>
+            </dependency>
+            <!-- 通用工具-->
+            <dependency>
+                <groupId>com.fastbee</groupId>
+                <artifactId>fastbee-common</artifactId>
+                <version>${fastbee.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fastbee</groupId>
+                <artifactId>fastbee-iot-service</artifactId>
+                <version>${fastbee.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fastbee</groupId>
+                <artifactId>fastbee-system-service</artifactId>
+                <version>${fastbee.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 191 - 0
yudao-module-things/fastbee-common/pom.xml

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>cn.iocoder.boot</groupId>
+        <artifactId>yudao-module-things</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>fastbee-common</artifactId>
+
+    <description>
+        common通用工具
+    </description>
+
+    <dependencies>
+
+        <!-- Spring框架基本的核心工具 -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+
+        <!-- SpringWeb模块 -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+
+        <!-- spring security 安全认证 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!-- mybatis-plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+        </dependency>
+
+        <!-- pagehelper 分页插件 -->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+
+        <!-- 自定义验证注解 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+
+        <!--常用工具类 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+        <!-- JSON工具类 -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+
+        <!-- 动态数据源 -->
+		<dependency>
+			<groupId>com.baomidou</groupId>
+			<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+			<version>3.5.2</version>
+		</dependency>
+
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+        </dependency>
+
+        <!-- io常用工具类 -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- 文件上传工具类 -->
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>
+
+        <!-- excel工具 -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+        </dependency>
+
+        <!-- yml解析器 -->
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+        </dependency>
+
+        <!-- Token生成与解析-->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+        </dependency>
+
+        <!-- Jaxb -->
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+        </dependency>
+
+        <!-- redis 缓存操作 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <!-- pool 对象池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+
+        <!-- 解析客户端操作系统、浏览器等 -->
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+        </dependency>
+
+        <!-- servlet包 -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.6.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.paho</groupId>
+            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+            <version>1.2.5</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.paho</groupId>
+            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+            <version>1.2.5</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+        </dependency>
+
+        <!-- 工具类相关 -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel-core</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>

+ 19 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Anonymous.java

@@ -0,0 +1,19 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 匿名访问不鉴权注解
+ * 
+ * @author ruoyi
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Anonymous
+{
+}

+ 33 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/DataScope.java

@@ -0,0 +1,33 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 数据权限过滤注解
+ * 
+ * @author ruoyi
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataScope
+{
+    /**
+     * 部门表的别名
+     */
+    public String deptAlias() default "";
+
+    /**
+     * 用户表的别名
+     */
+    public String userAlias() default "";
+
+    /**
+     * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
+     */
+    public String permission() default "";
+}

+ 28 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/DataSource.java

@@ -0,0 +1,28 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import com.fastbee.common.enums.DataSourceType;
+
+/**
+ * 自定义多数据源切换注解
+ *
+ * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
+ *
+ * @author ruoyi
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface DataSource
+{
+    /**
+     * 切换数据源名称
+     */
+    public DataSourceType value() default DataSourceType.MASTER;
+}

+ 22 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/DictFormat.java

@@ -0,0 +1,22 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 字典格式化
+ *
+ * 实现将字典数据的值,格式化成字典数据的标签
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface DictFormat {
+
+    /**
+     * 例如说,SysDictTypeConstants、InfDictTypeConstants
+     *
+     * @return 字典类型
+     */
+    String value();
+
+}

+ 187 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Excel.java

@@ -0,0 +1,187 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.math.BigDecimal;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import com.fastbee.common.utils.poi.ExcelHandlerAdapter;
+
+/**
+ * 自定义导出Excel数据注解
+ * 
+ * @author ruoyi
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Excel
+{
+    /**
+     * 导出时在excel中排序
+     */
+    public int sort() default Integer.MAX_VALUE;
+
+    /**
+     * 导出到Excel中的名字.
+     */
+    public String name() default "";
+
+    /**
+     * 日期格式, 如: yyyy-MM-dd
+     */
+    public String dateFormat() default "";
+
+    /**
+     * 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
+     */
+    public String dictType() default "";
+
+    /**
+     * 读取内容转表达式 (如: 0=男,1=女,2=未知)
+     */
+    public String readConverterExp() default "";
+
+    /**
+     * 分隔符,读取字符串组内容
+     */
+    public String separator() default ",";
+
+    /**
+     * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
+     */
+    public int scale() default -1;
+
+    /**
+     * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
+     */
+    public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
+
+    /**
+     * 导出时在excel中每个列的高度 单位为字符
+     */
+    public double height() default 14;
+
+    /**
+     * 导出时在excel中每个列的宽 单位为字符
+     */
+    public double width() default 16;
+
+    /**
+     * 文字后缀,如% 90 变成90%
+     */
+    public String suffix() default "";
+
+    /**
+     * 当值为空时,字段的默认值
+     */
+    public String defaultValue() default "";
+
+    /**
+     * 提示信息
+     */
+    public String prompt() default "";
+
+    /**
+     * 设置只能选择不能输入的列内容.
+     */
+    public String[] combo() default {};
+
+    /**
+     * 是否需要纵向合并单元格,应对需求:含有list集合单元格)
+     */
+    public boolean needMerge() default false;
+
+    /**
+     * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
+     */
+    public boolean isExport() default true;
+
+    /**
+     * 另一个类中的属性名称,支持多级获取,以小数点隔开
+     */
+    public String targetAttr() default "";
+
+    /**
+     * 是否自动统计数据,在最后追加一行统计数据总和
+     */
+    public boolean isStatistics() default false;
+
+    /**
+     * 导出类型(0数字 1字符串 2图片)
+     */
+    public ColumnType cellType() default ColumnType.STRING;
+
+    /**
+     * 导出列头背景色
+     */
+    public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
+
+    /**
+     * 导出列头字体颜色
+     */
+    public IndexedColors headerColor() default IndexedColors.WHITE;
+
+    /**
+     * 导出单元格背景色
+     */
+    public IndexedColors backgroundColor() default IndexedColors.WHITE;
+
+    /**
+     * 导出单元格字体颜色
+     */
+    public IndexedColors color() default IndexedColors.BLACK;
+
+    /**
+     * 导出字段对齐方式
+     */
+    public HorizontalAlignment align() default HorizontalAlignment.CENTER;
+
+    /**
+     * 自定义数据处理器
+     */
+    public Class<?> handler() default ExcelHandlerAdapter.class;
+
+    /**
+     * 自定义数据处理器参数
+     */
+    public String[] args() default {};
+
+    /**
+     * 字段类型(0:导出导入;1:仅导出;2:仅导入)
+     */
+    Type type() default Type.ALL;
+
+    public enum Type
+    {
+        ALL(0), EXPORT(1), IMPORT(2);
+        private final int value;
+
+        Type(int value)
+        {
+            this.value = value;
+        }
+
+        public int value()
+        {
+            return this.value;
+        }
+    }
+
+    public enum ColumnType
+    {
+        NUMERIC(0), STRING(1), IMAGE(2);
+        private final int value;
+
+        ColumnType(int value)
+        {
+            this.value = value;
+        }
+
+        public int value()
+        {
+            return this.value;
+        }
+    }
+}

+ 18 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Excels.java

@@ -0,0 +1,18 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Excel注解集
+ * 
+ * @author ruoyi
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Excels
+{
+    public Excel[] value();
+}

+ 46 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/Log.java

@@ -0,0 +1,46 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import com.fastbee.common.enums.BusinessType;
+import com.fastbee.common.enums.OperatorType;
+
+/**
+ * 自定义操作日志记录注解
+ * 
+ * @author ruoyi
+ *
+ */
+@Target({ ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Log
+{
+    /**
+     * 模块 
+     */
+    public String title() default "";
+
+    /**
+     * 功能
+     */
+    public BusinessType businessType() default BusinessType.OTHER;
+
+    /**
+     * 操作人类别
+     */
+    public OperatorType operatorType() default OperatorType.MANAGE;
+
+    /**
+     * 是否保存请求的参数
+     */
+    public boolean isSaveRequestData() default true;
+
+    /**
+     * 是否保存响应的参数
+     */
+    public boolean isSaveResponseData() default true;
+}

+ 40 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/RateLimiter.java

@@ -0,0 +1,40 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import com.fastbee.common.constant.CacheConstants;
+import com.fastbee.common.enums.LimitType;
+
+/**
+ * 限流注解
+ * 
+ * @author ruoyi
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RateLimiter
+{
+    /**
+     * 限流key
+     */
+    public String key() default CacheConstants.RATE_LIMIT_KEY;
+
+    /**
+     * 限流时间,单位秒
+     */
+    public int time() default 60;
+
+    /**
+     * 限流次数
+     */
+    public int count() default 100;
+
+    /**
+     * 限流类型
+     */
+    public LimitType limitType() default LimitType.DEFAULT;
+}

+ 31 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/RepeatSubmit.java

@@ -0,0 +1,31 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 自定义注解防止表单重复提交
+ * 
+ * @author ruoyi
+ *
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RepeatSubmit
+{
+    /**
+     * 间隔时间(ms),小于此时间视为重复提交
+     */
+    public int interval() default 5000;
+
+    /**
+     * 提示消息
+     */
+    public String message() default "不允许重复提交,请稍候再试";
+}

+ 21 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/annotation/SysProtocol.java

@@ -0,0 +1,21 @@
+package com.fastbee.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 表示系统内部协议解析器
+ * @author gsb
+ * @date 2022/10/24 10:33
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface SysProtocol {
+
+    /*协议名*/
+    String name() default "";
+    /*协议编码*/
+    String protocolCode() default "";
+    //协议描述
+    String description() default "";
+}

+ 104 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/config/DeviceTask.java

@@ -0,0 +1,104 @@
+package com.fastbee.common.config;
+
+import com.fastbee.common.constant.FastBeeConstant;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * 设备报文处理线程池
+ * @author bill
+ */
+@Configuration
+@EnableAsync
+@ConfigurationProperties(prefix = "spring.task.execution.pool")
+@Data
+public class DeviceTask {
+
+    private int coreSize;
+
+    private int maxSize;
+
+    private int queueCapacity;
+
+    private int  keepAlive;
+
+    /*设备状态池*/
+    @Bean(FastBeeConstant.TASK.DEVICE_STATUS_TASK)
+    public Executor deviceStatusTaskExecutor() {
+      return builder(FastBeeConstant.TASK.DEVICE_STATUS_TASK);
+    }
+
+    /*平台自动获取线程池(例如定时获取设备信息)*/
+    @Bean(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK)
+    public Executor deviceFetchTaskExecutor() {
+        return builder(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK);
+    }
+
+    /*设备回调信息(下发指令(服务)设备应答信息)*/
+    @Bean(FastBeeConstant.TASK.DEVICE_REPLY_MESSAGE_TASK)
+    public Executor deviceReplyTaskExecutor() {
+        return builder(FastBeeConstant.TASK.DEVICE_REPLY_MESSAGE_TASK);
+    }
+
+    /*设备主动上报(设备数据有变化主动上报)*/
+    @Bean(FastBeeConstant.TASK.DEVICE_UP_MESSAGE_TASK)
+    public Executor deviceUpMessageTaskExecutor() {
+        return builder(FastBeeConstant.TASK.DEVICE_UP_MESSAGE_TASK);
+    }
+
+    /*指令下发(服务下发)*/
+    @Bean(FastBeeConstant.TASK.FUNCTION_INVOKE_TASK)
+    public Executor functionInvokeTaskExecutor() {
+        return builder(FastBeeConstant.TASK.FUNCTION_INVOKE_TASK);
+    }
+
+    /*内部消费线程*/
+    @Bean(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK)
+    public Executor messageConsumeTaskExecutor() {
+        return builder(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK);
+    }
+
+    @Bean(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK_PUB)
+    public Executor messageConsumePubTaskExecutor(){
+        return builder(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK_PUB);
+    }
+
+    @Bean(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK_FETCH)
+    public Executor messageConsumeFetchTaskExecutor(){
+        return builder(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK_FETCH);
+    }
+
+    @Bean(FastBeeConstant.TASK.DELAY_UPGRADE_TASK)
+    public Executor delayedTaskExecutor(){
+        return builder(FastBeeConstant.TASK.DELAY_UPGRADE_TASK);
+    }
+
+    /*设备其他消息处理*/
+    @Bean(FastBeeConstant.TASK.DEVICE_OTHER_TASK)
+    public Executor deviceOtherTaskExecutor(){
+        return builder(FastBeeConstant.TASK.DEVICE_OTHER_TASK);
+    }
+
+    /*组装线程池*/
+    private ThreadPoolTaskExecutor builder(String threadNamePrefix){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(coreSize);
+        executor.setMaxPoolSize(maxSize);
+        executor.setKeepAliveSeconds(keepAlive);
+        executor.setQueueCapacity(queueCapacity);
+        // 线程池对拒绝任务的处理策略
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
+        //线程池名的前缀
+        executor.setThreadNamePrefix(threadNamePrefix);
+        executor.initialize();
+        return executor;
+    }
+
+}

+ 135 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/config/RuoYiConfig.java

@@ -0,0 +1,135 @@
+package com.fastbee.common.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 读取项目相关配置
+ * 
+ * @author ruoyi
+ */
+@Component
+@ConfigurationProperties(prefix = "fastbee")
+public class RuoYiConfig
+{
+    /** 项目名称 */
+    private String name;
+
+    /** 版本 */
+    private String version;
+
+    /** 版权年份 */
+    private String copyrightYear;
+
+    /** 实例演示开关 */
+    private boolean demoEnabled;
+
+    /** 上传路径 */
+    private static String profile;
+
+    /** 获取地址开关 */
+    private static boolean addressEnabled;
+
+    /** 验证码类型 */
+    private static String captchaType;
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public String getVersion()
+    {
+        return version;
+    }
+
+    public void setVersion(String version)
+    {
+        this.version = version;
+    }
+
+    public String getCopyrightYear()
+    {
+        return copyrightYear;
+    }
+
+    public void setCopyrightYear(String copyrightYear)
+    {
+        this.copyrightYear = copyrightYear;
+    }
+
+    public boolean isDemoEnabled()
+    {
+        return demoEnabled;
+    }
+
+    public void setDemoEnabled(boolean demoEnabled)
+    {
+        this.demoEnabled = demoEnabled;
+    }
+
+    public static String getProfile()
+    {
+        return profile;
+    }
+
+    public void setProfile(String profile)
+    {
+        RuoYiConfig.profile = profile;
+    }
+
+    public static boolean isAddressEnabled()
+    {
+        return addressEnabled;
+    }
+
+    public void setAddressEnabled(boolean addressEnabled)
+    {
+        RuoYiConfig.addressEnabled = addressEnabled;
+    }
+
+    public static String getCaptchaType() {
+        return captchaType;
+    }
+
+    public void setCaptchaType(String captchaType) {
+        RuoYiConfig.captchaType = captchaType;
+    }
+
+    /**
+     * 获取导入上传路径
+     */
+    public static String getImportPath()
+    {
+        return getProfile() + "/import";
+    }
+
+    /**
+     * 获取头像上传路径
+     */
+    public static String getAvatarPath()
+    {
+        return getProfile() + "/avatar";
+    }
+
+    /**
+     * 获取下载路径
+     */
+    public static String getDownloadPath()
+    {
+        return getProfile() + "/download/";
+    }
+
+    /**
+     * 获取上传路径
+     */
+    public static String getUploadPath()
+    {
+        return getProfile() + "/upload";
+    }
+}

+ 49 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/CacheConstants.java

@@ -0,0 +1,49 @@
+package com.fastbee.common.constant;
+
+/**
+ * 缓存的key 常量
+ *
+ * @author ruoyi
+ */
+public class CacheConstants
+{
+    /**
+     * 登录用户 redis key
+     */
+    public static final String LOGIN_TOKEN_KEY = "login_tokens:";
+
+    /**
+     * 登录用户 redis key
+     */
+    public static final String LOGIN_USERID_KEY = "login_userId:";
+
+    /**
+     * 验证码 redis key
+     */
+    public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
+
+    /**
+     * 参数管理 cache key
+     */
+    public static final String SYS_CONFIG_KEY = "sys_config:";
+
+    /**
+     * 字典管理 cache key
+     */
+    public static final String SYS_DICT_KEY = "sys_dict:";
+
+    /**
+     * 防重提交 redis key
+     */
+    public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
+
+    /**
+     * 限流 redis key
+     */
+    public static final String RATE_LIMIT_KEY = "rate_limit:";
+
+    /**
+     * 登录账户密码错误次数 redis key
+     */
+    public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
+}

+ 142 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/Constants.java

@@ -0,0 +1,142 @@
+package com.fastbee.common.constant;
+
+import io.jsonwebtoken.Claims;
+
+/**
+ * 通用常量信息
+ * 
+ * @author ruoyi
+ */
+public class Constants
+{
+    /**
+     * UTF-8 字符集
+     */
+    public static final String UTF8 = "UTF-8";
+
+    /**
+     * GBK 字符集
+     */
+    public static final String GBK = "GBK";
+
+    /**
+     * www主域
+     */
+    public static final String WWW = "www.";
+
+    /**
+     * http请求
+     */
+    public static final String HTTP = "http://";
+
+    /**
+     * https请求
+     */
+    public static final String HTTPS = "https://";
+
+    /**
+     * 通用成功标识
+     */
+    public static final String SUCCESS = "0";
+
+    /**
+     * 通用失败标识
+     */
+    public static final String FAIL = "1";
+
+    /**
+     * 登录成功
+     */
+    public static final String LOGIN_SUCCESS = "Success";
+
+    /**
+     * 注销
+     */
+    public static final String LOGOUT = "Logout";
+
+    /**
+     * 注册
+     */
+    public static final String REGISTER = "Register";
+
+    /**
+     * 登录失败
+     */
+    public static final String LOGIN_FAIL = "Error";
+ 
+    /**
+     * 验证码有效期(分钟)
+     */
+    public static final Integer CAPTCHA_EXPIRATION = 2;
+
+    /**
+     * 令牌
+     */
+    public static final String TOKEN = "token";
+
+    /**
+     * 令牌前缀
+     */
+    public static final String TOKEN_PREFIX = "Bearer ";
+
+    /**
+     * 令牌前缀
+     */
+    public static final String LOGIN_USER_KEY = "login_user_key";
+
+    /**
+     * 用户ID
+     */
+    public static final String JWT_USERID = "userid";
+
+    /**
+     * 用户名称
+     */
+    public static final String JWT_USERNAME = Claims.SUBJECT;
+
+    /**
+     * 用户头像
+     */
+    public static final String JWT_AVATAR = "avatar";
+
+    /**
+     * 创建时间
+     */
+    public static final String JWT_CREATED = "created";
+
+    /**
+     * 用户权限
+     */
+    public static final String JWT_AUTHORITIES = "authorities";
+
+    /**
+     * 资源映射路径 前缀
+     */
+    public static final String RESOURCE_PREFIX = "/profile";
+
+    /**
+     * RMI 远程方法调用
+     */
+    public static final String LOOKUP_RMI = "rmi:";
+
+    /**
+     * LDAP 远程方法调用
+     */
+    public static final String LOOKUP_LDAP = "ldap:";
+
+    /**
+     * LDAPS 远程方法调用
+     */
+    public static final String LOOKUP_LDAPS = "ldaps:";
+
+    /**
+     * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
+     */
+    public static final String[] JOB_WHITELIST_STR = { "com.fastbee" };
+
+    /**
+     * 定时任务违规的字符
+     */
+    public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
+            "org.springframework", "org.apache", "com.fastbee.common.utils.file", "com.fastbee.common.config" };
+}

+ 258 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/FastBeeConstant.java

@@ -0,0 +1,258 @@
+package com.fastbee.common.constant;
+
+/**
+ * 常量
+ * @author bill
+ */
+public interface FastBeeConstant {
+
+    interface SERVER{
+        String UFT8 = "UTF-8";
+        String GB2312 = "GB2312";
+
+
+        String MQTT = "mqtt";
+        String PORT = "port";
+        String ADAPTER = "adapter";
+        String FRAMEDECODER ="frameDecoder";
+        String DISPATCHER = "dispatcher";
+        String DECODER = "decoder";
+        String ENCODER = "encoder";
+        String MAXFRAMELENGTH = "maxFrameLength";
+        String SLICER = "slicer";
+        String DELIMITERS = "delimiters";
+        String IDLE = "idle";
+        String WS_PREFIX = "web-";
+        String WM_PREFIX = "server-";
+        String FAST_PHONE = "phone-";
+
+        /*MQTT平台判定离线时间 keepAlive*1.5 */
+        Long DEVICE_PING_EXPIRED = 90000L;
+    }
+
+    interface CLIENT{
+        //加盐
+        String TOKEN = "fastbee-smart!@#$123";
+    }
+
+    /*webSocket配置*/
+    interface WS{
+        String HEART_BEAT = "heartbeat";
+        String HTTP_SERVER_CODEC = "httpServerCodec";
+        String AGGREGATOR = "aggregator";
+        String COMPRESSOR = "compressor";
+        String PROTOCOL = "protocol";
+        String MQTT_WEBSOCKET = "mqttWebsocket";
+        String DECODER = "decoder";
+        String ENCODER = "encoder";
+        String BROKER_HANDLER = "brokerHandler";
+
+    }
+
+    interface TASK{
+        /**设备上下线任务*/
+        String DEVICE_STATUS_TASK = "deviceStatusTask";
+        /**设备主动上报任务*/
+        String DEVICE_UP_MESSAGE_TASK = "deviceUpMessageTask";
+        /**设备回调任务*/
+        String DEVICE_REPLY_MESSAGE_TASK = "deviceReplyMessageTask";
+        /**设备下行任务*/
+        String DEVICE_DOWN_MESSAGE_TASK = "deviceDownMessageTask";
+        /**服务调用(指令下发)任务*/
+        String FUNCTION_INVOKE_TASK = "functionInvokeTask";
+        /**属性读取任务,区分服务调用*/
+        String DEVICE_FETCH_PROP_TASK = "deviceFetchPropTask";
+        /**
+         * 设备其他消息处理
+         */
+        String DEVICE_OTHER_TASK = "deviceOtherMsgTask";
+        /**消息消费线程*/
+        String MESSAGE_CONSUME_TASK = "messageConsumeTask";
+        /*内部消费线程publish*/
+        String MESSAGE_CONSUME_TASK_PUB = "messageConsumeTaskPub";
+        /*内部消费线程Fetch*/
+        String MESSAGE_CONSUME_TASK_FETCH = "messageConsumeTaskFetch";
+        /*OTA升级延迟队列*/
+        String DELAY_UPGRADE_TASK = "delayUpgradeTask";
+
+    }
+
+    interface MQTT{
+       //*上报平台前缀*//*
+        String UP_TOPIC_SUFFIX = "post";
+        //*下发设备前缀*//*
+        String DOWN_TOPIC_SUFFIX = "get";
+
+        /*模拟设备后缀*/
+        String PROPERTY_GET_SIMULATE = "simulate";
+
+        String PREDIX = "/+/+";
+
+        String DUP = "dup";
+        String QOS = "qos";
+        String RETAIN = "retain";
+        String CLEAN_SESSION = "cleanSession";
+
+        /*集群方式*/
+        String REDIS_CHANNEL = "redis";
+        String ROCKET_MQ = "rocketmq";
+    }
+
+    /*集群,全局发布的消息类型*/
+    interface CHANNEL {
+        /*设备状态*/
+        String DEVICE_STATUS   = "device_status";
+        /*平台读取属性*/
+        String PROP_READ       = "prop_read";
+        /*推送消息*/
+        String PUBLISH         = "publish";
+        /*服务下发*/
+        String FUNCTION_INVOKE = "function_invoke";
+        /*事件*/
+        String EVENT = "event";
+        /*other*/
+        String OTHER = "other";
+        /*Qos1 推送应答*/
+        String PUBLISH_ACK     = "publish_ack";
+        /*Qos2 发布消息收到*/
+        String PUB_REC         = "pub_rec";
+        /*Qos 发布消息释放*/
+        String PUB_REL = "pub_rel";
+        /*Qos2 发布消息完成*/
+        String PUB_COMP = "pub_comp";
+
+        String UPGRADE  = "upgrade";
+
+        /*-------------------------ROCKETMQ-------------------------*/
+        String SUFFIX = "group";
+        /*设备状态*/
+        String DEVICE_STATUS_GROUP   = DEVICE_STATUS +SUFFIX;
+        String PROP_READ_GROUP        = PROP_READ + SUFFIX;
+        /*服务下发*/
+        String FUNCTION_INVOKE_GROUP = FUNCTION_INVOKE + SUFFIX;
+        /*推送消息*/
+        String PUBLISH_GROUP         = PUBLISH + SUFFIX;
+        /*Qos1 推送应答*/
+        String PUBLISH_ACK_GROUP     = PUBLISH_ACK +SUFFIX;
+        /*Qos2 发布消息收到*/
+        String PUB_REC_GROUP         = PUB_REC + SUFFIX;
+        /*Qos 发布消息释放*/
+        String PUB_REL_GROUP         = PUB_REL + SUFFIX;
+        /*Qos2 发布消息完成*/
+        String PUB_COMP_GROUP        = PUB_COMP + SUFFIX;
+        /*OTA升级*/
+        String UPGRADE_GROUP         = UPGRADE + SUFFIX;
+    }
+
+
+
+    /**redisKey 定义*/
+    interface REDIS{
+        /*redis全局前缀*/
+        String GLOBAL_PREFIX_KEY = "fastbee:";
+        /*设备在线状态*/
+        String DEVICE_STATUS_KEY =  "device:status";
+        /*在线设备列表*/
+        String DEVICE_ONLINE_LIST = "device:online:list";
+        /*设备实时状态key*/
+        String DEVICE_RUNTIME_DATA = "device:runtime:";
+        /*通讯协议参数*/
+        String DEVICE_PROTOCOL_PARAM = "device:param:";
+        /**设备消息id缓存key*/
+        String DEVICE_MESSAGE_ID = "device:messageid";
+        /**固件版本key*/
+        String FIRMWARE_VERSION = "device:firmware:";
+
+        /**
+         * 设备信息
+         */
+        String DEVICE_MSG = "device:msg:";
+
+        /**采集点变更记录缓存key*/
+        String COLLECT_POINT_CHANGE = "collect:point:change:";
+        /**属性下发回调*/
+        String PROP_READ_STORE = "prop:read:store:";
+        /**sip*/
+        String RECORDINFO_KEY = "sip:recordinfo:";
+        String DEVICEID_KEY = "sip:deviceid:";
+        String STREAM_KEY = "sip:stream:";
+        String INVITE_KEY = "sip:invite:";
+        String SIP_CSEQ_PREFIX = "sip:CSEQ:";
+        String DEFAULT_SIP_CONFIG = "sip:config";
+        String DEFAULT_MEDIA_CONFIG = "sip:mediaconfig";
+
+
+        /**当前连接数*/
+        String MESSAGE_CONNECT_COUNT = "messages:connect:count";
+        /**总保留消息*/
+        String MESSAGE_RETAIN_TOTAL = "message:retain:total";
+
+        /**主题数*/
+        String MESSAGE_TOPIC_TOTAL = "message:topic:total";
+        /*发送消息数*/
+        String MESSAGE_SEND_TOTAL = "message:send:total";
+        /*接收消息数*/
+        String MESSAGE_RECEIVE_TOTAL = "message:receive:total";
+        /*连接次数*/
+        String MESSAGE_CONNECT_TOTAL = "message:connect:total";
+        /**认证次数*/
+        String MESSAGE_AUTH_TOTAL = "message:auth:total";
+        /**订阅次数*/
+        String MESSAGE_SUBSCRIBE_TOTAL = "message:subscribe:total";
+
+        /**今日接收消息*/
+        String MESSAGE_RECEIVE_TODAY = "message:receive:today";
+        /**今日发送消息*/
+        String MESSAGE_SEND_TODAY = "message:send:today";
+
+
+        // 物模型值命名空间:Key:TSLV:{productId}_{deviceNumber}   HKey:{identity#V/identity#S/identity#M/identity#N}
+        /**
+         * v-值
+         * s-影子值
+         * m-是否为检测值
+         * n-名称
+         */
+         String DEVICE_PRE_KEY = "TSLV:";
+
+        // 物模型命名空间:Key:TSL:{productId}
+         String TSL_PRE_KEY ="TSL:";
+
+         /**modbus缓存指令*/
+         String POLL_MODBUS_KEY = "poll:modbus";
+
+
+    }
+
+    interface TOPIC{
+        /*属性上报*/
+        String PROP = "properties";
+        //事件
+        String EVENT = "events";
+        //功能
+        String FUNCTION = "functions";
+        /*非OTA消息回复*/
+        String MSG_REPLY = "message/reply";
+        /*OTA升级回复*/
+        String UPGRADE_REPLY = "upgrade/reply";
+        String SUB_UPGRADE_REPLY = "sub/upgrade/reply";
+        /*网关子设备结尾*/
+        String SUB = "/sub";
+    }
+
+    interface PROTOCOL {
+        String ModbusRtu = "MODBUS-RTU";
+        String YinErDa = "YinErDa";
+        String JsonObject = "JSONOBJECT";
+        String JsonArray = "JSON";
+        String ModbusRtuPak = "MODBUS-RTU-PAK";
+        String FlowMeter = "FlowMeter";
+        String RJ45 = "RJ45";
+        String ModbusToJson = "MODBUS-JSON";
+        String ModbusToJsonFY = "MODBUS-JSON-FY";
+        String JsonObject_ChenYi = "JSONOBJECT-CHENYI";
+
+
+    }
+
+}

+ 117 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/GenConstants.java

@@ -0,0 +1,117 @@
+package com.fastbee.common.constant;
+
+/**
+ * 代码生成通用常量
+ * 
+ * @author ruoyi
+ */
+public class GenConstants
+{
+    /** 单表(增删改查) */
+    public static final String TPL_CRUD = "crud";
+
+    /** 树表(增删改查) */
+    public static final String TPL_TREE = "tree";
+
+    /** 主子表(增删改查) */
+    public static final String TPL_SUB = "sub";
+
+    /** 树编码字段 */
+    public static final String TREE_CODE = "treeCode";
+
+    /** 树父编码字段 */
+    public static final String TREE_PARENT_CODE = "treeParentCode";
+
+    /** 树名称字段 */
+    public static final String TREE_NAME = "treeName";
+
+    /** 上级菜单ID字段 */
+    public static final String PARENT_MENU_ID = "parentMenuId";
+
+    /** 上级菜单名称字段 */
+    public static final String PARENT_MENU_NAME = "parentMenuName";
+
+    /** 数据库字符串类型 */
+    public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
+
+    /** 数据库文本类型 */
+    public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
+
+    /** 数据库时间类型 */
+    public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
+
+    /** 数据库数字类型 */
+    public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
+            "bit", "bigint", "float", "double", "decimal" };
+
+    /** 页面不需要编辑字段 */
+    public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
+
+    /** 页面不需要显示的列表字段 */
+    public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
+            "update_time" };
+
+    /** 页面不需要查询字段 */
+    public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
+            "update_time", "remark" };
+
+    /** Entity基类字段 */
+    public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
+
+    /** Tree基类字段 */
+    public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
+
+    /** 文本框 */
+    public static final String HTML_INPUT = "input";
+
+    /** 文本域 */
+    public static final String HTML_TEXTAREA = "textarea";
+
+    /** 下拉框 */
+    public static final String HTML_SELECT = "select";
+
+    /** 单选框 */
+    public static final String HTML_RADIO = "radio";
+
+    /** 复选框 */
+    public static final String HTML_CHECKBOX = "checkbox";
+
+    /** 日期控件 */
+    public static final String HTML_DATETIME = "datetime";
+
+    /** 图片上传控件 */
+    public static final String HTML_IMAGE_UPLOAD = "imageUpload";
+
+    /** 文件上传控件 */
+    public static final String HTML_FILE_UPLOAD = "fileUpload";
+
+    /** 富文本控件 */
+    public static final String HTML_EDITOR = "editor";
+
+    /** 字符串类型 */
+    public static final String TYPE_STRING = "String";
+
+    /** 整型 */
+    public static final String TYPE_INTEGER = "Integer";
+
+    /** 长整型 */
+    public static final String TYPE_LONG = "Long";
+
+    /** 浮点型 */
+    public static final String TYPE_DOUBLE = "Double";
+
+    /** 高精度计算类型 */
+    public static final String TYPE_BIGDECIMAL = "BigDecimal";
+
+    /** 时间类型 */
+    public static final String TYPE_DATE = "Date";
+
+    /** 模糊查询 */
+    public static final String QUERY_LIKE = "LIKE";
+
+    /** 相等查询 */
+    public static final String QUERY_EQ = "EQ";
+
+    /** 需要 */
+    public static final String REQUIRE = "1";
+}

+ 105 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/HttpStatus.java

@@ -0,0 +1,105 @@
+package com.fastbee.common.constant;
+
+/**
+ * 返回状态码
+ *
+ * @author ruoyi
+ */
+public class HttpStatus
+{
+    /**
+     * 操作成功
+     */
+    public static final int SUCCESS = 200;
+
+    /**
+     * 对象创建成功
+     */
+    public static final int CREATED = 201;
+
+    /**
+     * 请求已经被接受
+     */
+    public static final int ACCEPTED = 202;
+
+    /**
+     * 操作已经执行成功,但是没有返回数据
+     */
+    public static final int NO_CONTENT = 204;
+
+    /**
+     * 资源已被移除
+     */
+    public static final int MOVED_PERM = 301;
+
+    /**
+     * 重定向
+     */
+    public static final int SEE_OTHER = 303;
+
+    /**
+     * 资源没有被修改
+     */
+    public static final int NOT_MODIFIED = 304;
+
+    /**
+     * 参数列表错误(缺少,格式不匹配)
+     */
+    public static final int BAD_REQUEST = 400;
+
+    /**
+     * 未授权
+     */
+    public static final int UNAUTHORIZED = 401;
+
+    /**
+     * 访问受限,授权过期
+     */
+    public static final int FORBIDDEN = 403;
+
+    /**
+     * 资源,服务未找到
+     */
+    public static final int NOT_FOUND = 404;
+
+    /**
+     * 不允许的http方法
+     */
+    public static final int BAD_METHOD = 405;
+
+    /**
+     * 资源冲突,或者资源被锁
+     */
+    public static final int CONFLICT = 409;
+
+    /**
+     * 不支持的数据,媒体类型
+     */
+    public static final int UNSUPPORTED_TYPE = 415;
+
+    /**
+     * 用户不存在
+     */
+    public static final int USER_NO_EXIST = 450;
+
+    /**
+     * 系统内部错误
+     */
+    public static final int ERROR = 500;
+
+    /**
+     * 接口未实现
+     */
+    public static final int NOT_IMPLEMENTED = 501;
+
+    /**
+     * 不弹窗显示
+     */
+    public static final int NO_MESSAGE_ALERT = 502;
+
+
+    /**
+     * 系统警告消息
+     */
+    public static final int WARN = 601;
+}

+ 41 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/ProductAuthConstant.java

@@ -0,0 +1,41 @@
+package com.fastbee.common.constant;
+
+/**
+ *
+ * @author fastb
+ * @date 2023-08-03 10:20
+ */
+public class ProductAuthConstant {
+
+    /**
+     * 产品设备认证方式-简单认证
+     */
+    public static final Integer AUTH_WAY_SIMPLE = 1;
+    /**
+     * 产品设备认证方式-简单认证
+     */
+    public static final Integer AUTH_WAY_ENCRYPT = 2;
+    /**
+     * 产品设备认证方式-简单认证
+     */
+    public static final Integer AUTH_WAY_SIMPLE_AND_ENCRYPT = 3;
+
+    /**
+     * 产品设备客户端ID认证类型-简单认证
+     */
+    public static final String CLIENT_ID_AUTH_TYPE_SIMPLE = "S";
+
+    /**
+     * 产品设备客户端ID认证类型-简单认证
+     */
+    public static final String CLIENT_ID_AUTH_TYPE_ENCRYPT = "E";
+    /**
+     * 设备授权
+     */
+    public static final Integer AUTHORIZE = 1;
+    /**
+     * 设备没有授权
+     */
+    public static final Integer NO_AUTHORIZE = 1;
+
+}

+ 50 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/ScheduleConstants.java

@@ -0,0 +1,50 @@
+package com.fastbee.common.constant;
+
+/**
+ * 任务调度通用常量
+ * 
+ * @author ruoyi
+ */
+public class ScheduleConstants
+{
+    public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
+
+    /** 执行目标key */
+    public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
+
+    /** 默认 */
+    public static final String MISFIRE_DEFAULT = "0";
+
+    /** 立即触发执行 */
+    public static final String MISFIRE_IGNORE_MISFIRES = "1";
+
+    /** 触发一次执行 */
+    public static final String MISFIRE_FIRE_AND_PROCEED = "2";
+
+    /** 不触发立即执行 */
+    public static final String MISFIRE_DO_NOTHING = "3";
+
+    public enum Status
+    {
+        /**
+         * 正常
+         */
+        NORMAL("0"),
+        /**
+         * 暂停
+         */
+        PAUSE("1");
+
+        private String value;
+
+        private Status(String value)
+        {
+            this.value = value;
+        }
+
+        public String getValue()
+        {
+            return value;
+        }
+    }
+}

+ 9 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/SipConstants.java

@@ -0,0 +1,9 @@
+package com.fastbee.common.constant;
+
+public class SipConstants {
+    public static final String MESSAGE_CATALOG = "Catalog";
+    public static final String MESSAGE_KEEP_ALIVE = "Keepalive";
+    public static final String MESSAGE_DEVICE_INFO = "DeviceInfo";
+    public static final String MESSAGE_RECORD_INFO = "RecordInfo";
+    public static final String MESSAGE_MEDIA_STATUS = "MediaStatus";
+}

+ 78 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/constant/UserConstants.java

@@ -0,0 +1,78 @@
+package com.fastbee.common.constant;
+
+/**
+ * 用户常量信息
+ * 
+ * @author ruoyi
+ */
+public class UserConstants
+{
+    /**
+     * 平台内系统用户的唯一标志
+     */
+    public static final String SYS_USER = "SYS_USER";
+
+    /** 正常状态 */
+    public static final String NORMAL = "0";
+
+    /** 异常状态 */
+    public static final String EXCEPTION = "1";
+
+    /** 用户封禁状态 */
+    public static final String USER_DISABLE = "1";
+
+    /** 角色封禁状态 */
+    public static final String ROLE_DISABLE = "1";
+
+    /** 部门正常状态 */
+    public static final String DEPT_NORMAL = "0";
+
+    /** 部门停用状态 */
+    public static final String DEPT_DISABLE = "1";
+
+    /** 字典正常状态 */
+    public static final String DICT_NORMAL = "0";
+
+    /** 是否为系统默认(是) */
+    public static final String YES = "Y";
+
+    /** 是否菜单外链(是) */
+    public static final String YES_FRAME = "0";
+
+    /** 是否菜单外链(否) */
+    public static final String NO_FRAME = "1";
+
+    /** 菜单类型(目录) */
+    public static final String TYPE_DIR = "M";
+
+    /** 菜单类型(菜单) */
+    public static final String TYPE_MENU = "C";
+
+    /** 菜单类型(按钮) */
+    public static final String TYPE_BUTTON = "F";
+
+    /** Layout组件标识 */
+    public final static String LAYOUT = "Layout";
+    
+    /** ParentView组件标识 */
+    public final static String PARENT_VIEW = "ParentView";
+
+    /** InnerLink组件标识 */
+    public final static String INNER_LINK = "InnerLink";
+
+    /** 校验返回结果码 */
+    public final static String UNIQUE = "0";
+    public final static String NOT_UNIQUE = "1";
+
+    /**
+     * 用户名长度限制
+     */
+    public static final int USERNAME_MIN_LENGTH = 2;
+    public static final int USERNAME_MAX_LENGTH = 20;
+
+    /**
+     * 密码长度限制
+     */
+    public static final int PASSWORD_MIN_LENGTH = 5;
+    public static final int PASSWORD_MAX_LENGTH = 20;
+}

+ 216 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/controller/BaseController.java

@@ -0,0 +1,216 @@
+package com.fastbee.common.core.controller;
+
+import com.fastbee.common.constant.CacheConstants;
+import com.fastbee.common.constant.HttpStatus;
+import com.fastbee.common.core.domain.AjaxResult;
+import com.fastbee.common.core.domain.model.LoginUser;
+import com.fastbee.common.core.page.PageDomain;
+import com.fastbee.common.core.page.TableDataInfo;
+import com.fastbee.common.core.page.TableSupport;
+import com.fastbee.common.core.redis.RedisCache;
+import com.fastbee.common.utils.DateUtils;
+import com.fastbee.common.utils.PageUtils;
+import com.fastbee.common.utils.SecurityUtils;
+import com.fastbee.common.utils.StringUtils;
+import com.fastbee.common.utils.sql.SqlUtil;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+
+import javax.annotation.Resource;
+import java.beans.PropertyEditorSupport;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * web层通用数据处理
+ *
+ * @author ruoyi
+ */
+public class BaseController
+{
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Resource
+    private RedisCache redisCache;
+
+    /**
+     * 将前台传递过来的日期格式的字符串,自动转化为Date类型
+     */
+    @InitBinder
+    public void initBinder(WebDataBinder binder)
+    {
+        // Date 类型转换
+        binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
+        {
+            @Override
+            public void setAsText(String text)
+            {
+                setValue(DateUtils.parseDate(text));
+            }
+        });
+    }
+
+    /**
+     * 设置请求分页数据
+     */
+    protected void startPage()
+    {
+        PageUtils.startPage();
+    }
+
+    /**
+     * 设置请求排序数据
+     */
+    protected void startOrderBy()
+    {
+        PageDomain pageDomain = TableSupport.buildPageRequest();
+        if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
+        {
+            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
+            PageHelper.orderBy(orderBy);
+        }
+    }
+
+    /**
+     * 清理分页的线程变量
+     */
+    protected void clearPage()
+    {
+        PageUtils.clearPage();
+    }
+
+    /**
+     * 响应请求分页数据
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected TableDataInfo getDataTable(List<?> list)
+    {
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(HttpStatus.SUCCESS);
+        rspData.setMsg("查询成功");
+        rspData.setRows(list);
+        rspData.setTotal(new PageInfo(list).getTotal());
+        return rspData;
+    }
+
+    /**
+     * 返回成功
+     */
+    public AjaxResult success()
+    {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 返回失败消息
+     */
+    public AjaxResult error()
+    {
+        return AjaxResult.error();
+    }
+
+    /**
+     * 返回成功消息
+     */
+    public AjaxResult success(String message)
+    {
+        return AjaxResult.success(message);
+    }
+
+    /**
+     * 返回成功消息
+     */
+    public AjaxResult success(Object data)
+    {
+        return AjaxResult.success(data);
+    }
+
+    /**
+     * 返回失败消息
+     */
+    public AjaxResult error(String message)
+    {
+        return AjaxResult.error(message);
+    }
+
+    /**
+     * 返回警告消息
+     */
+    public AjaxResult warn(String message)
+    {
+        return AjaxResult.warn(message);
+    }
+
+    /**
+     * 响应返回结果
+     *
+     * @param rows 影响行数
+     * @return 操作结果
+     */
+    protected AjaxResult toAjax(int rows)
+    {
+        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
+    }
+
+    /**
+     * 响应返回结果
+     *
+     * @param result 结果
+     * @return 操作结果
+     */
+    protected AjaxResult toAjax(boolean result)
+    {
+        return result ? success() : error();
+    }
+
+    /**
+     * 页面跳转
+     */
+    public String redirect(String url)
+    {
+        return StringUtils.format("redirect:{}", url);
+    }
+
+    /**
+     * 获取用户缓存信息
+     * 由于不同端不能获取最新用户信息,所以优先以用户id缓存key获取用户信息
+     */
+    public LoginUser getLoginUser()
+    {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        Long userId = loginUser.getUserId();
+        if (userId != null) {
+            String userKey = CacheConstants.LOGIN_USERID_KEY + userId;
+            return redisCache.getCacheObject(userKey);
+        }
+        return loginUser;
+    }
+
+    /**
+     * 获取登录用户id
+     */
+    public Long getUserId()
+    {
+        return getLoginUser().getUserId();
+    }
+
+    /**
+     * 获取登录部门id
+     */
+    public Long getDeptId()
+    {
+        return getLoginUser().getDeptId();
+    }
+
+    /**
+     * 获取登录用户名
+     */
+    public String getUsername()
+    {
+        return getLoginUser().getUsername();
+    }
+}

+ 214 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/AjaxResult.java

@@ -0,0 +1,214 @@
+package com.fastbee.common.core.domain;
+
+import java.util.HashMap;
+import com.fastbee.common.constant.HttpStatus;
+import com.fastbee.common.utils.StringUtils;
+
+/**
+ * 操作消息提醒
+ * 
+ * @author ruoyi
+ */
+public class AjaxResult extends HashMap<String, Object>
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 状态码 */
+    public static final String CODE_TAG = "code";
+
+    /** 返回内容 */
+    public static final String MSG_TAG = "msg";
+
+    /** 数据对象 */
+    public static final String DATA_TAG = "data";
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
+     */
+    public AjaxResult()
+    {
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象
+     * 
+     * @param code 状态码
+     * @param msg 返回内容
+     */
+    public AjaxResult(int code, String msg)
+    {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象
+     * 
+     * @param code 状态码
+     * @param msg 返回内容
+     * @param data 数据对象
+     */
+    public AjaxResult(int code, String msg, Object data)
+    {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+        if (StringUtils.isNotNull(data))
+        {
+            super.put(DATA_TAG, data);
+        }
+    }
+
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象
+     *
+     * @param code 状态码
+     * @param msg 返回内容
+     * @param data 数据对象
+     */
+    public AjaxResult(int code, String msg, Object data,int total)
+    {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+        if (StringUtils.isNotNull(data))
+        {
+            super.put(DATA_TAG, data);
+        }
+        super.put("total",total);
+    }
+
+    /**
+     * 返回成功消息
+     * 
+     * @return 成功消息
+     */
+    public static AjaxResult success()
+    {
+        return AjaxResult.success("操作成功");
+    }
+
+    /**
+     * 返回成功数据
+     * 
+     * @return 成功消息
+     */
+    public static AjaxResult success(Object data)
+    {
+        return AjaxResult.success("操作成功", data);
+    }
+
+    /**
+     * 返回成功数据
+     *
+     * @return 成功消息
+     */
+    public static AjaxResult success(Object data,int total)
+    {
+        return new AjaxResult(HttpStatus.SUCCESS, "操作成功", data,total);
+    }
+
+    /**
+     * 返回成功消息
+     * 
+     * @param msg 返回内容
+     * @return 成功消息
+     */
+    public static AjaxResult success(String msg)
+    {
+        return AjaxResult.success(msg, null);
+    }
+
+    /**
+     * 返回成功消息
+     * 
+     * @param msg 返回内容
+     * @param data 数据对象
+     * @return 成功消息
+     */
+    public static AjaxResult success(String msg, Object data)
+    {
+        return new AjaxResult(HttpStatus.SUCCESS, msg, data);
+    }
+
+    /**
+     * 返回警告消息
+     *
+     * @param msg 返回内容
+     * @return 警告消息
+     */
+    public static AjaxResult warn(String msg)
+    {
+        return AjaxResult.warn(msg, null);
+    }
+
+    /**
+     * 返回警告消息
+     *
+     * @param msg 返回内容
+     * @param data 数据对象
+     * @return 警告消息
+     */
+    public static AjaxResult warn(String msg, Object data)
+    {
+        return new AjaxResult(HttpStatus.WARN, msg, data);
+    }
+
+    /**
+     * 返回错误消息
+     * 
+     * @return 错误消息
+     */
+    public static AjaxResult error()
+    {
+        return AjaxResult.error("操作失败");
+    }
+
+    /**
+     * 返回错误消息
+     * 
+     * @param msg 返回内容
+     * @return 错误消息
+     */
+    public static AjaxResult error(String msg)
+    {
+        return AjaxResult.error(msg, null);
+    }
+
+    /**
+     * 返回错误消息
+     * 
+     * @param msg 返回内容
+     * @param data 数据对象
+     * @return 错误消息
+     */
+    public static AjaxResult error(String msg, Object data)
+    {
+        return new AjaxResult(HttpStatus.ERROR, msg, data);
+    }
+
+    /**
+     * 返回错误消息
+     * 
+     * @param code 状态码
+     * @param msg 返回内容
+     * @return 错误消息
+     */
+    public static AjaxResult error(int code, String msg)
+    {
+        return new AjaxResult(code, msg, null);
+    }
+
+    /**
+     * 方便链式调用
+     *
+     * @param key 键
+     * @param value 值
+     * @return 数据对象
+     */
+    @Override
+    public AjaxResult put(String key, Object value)
+    {
+        super.put(key, value);
+        return this;
+    }
+}

+ 43 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/BaseDO.java

@@ -0,0 +1,43 @@
+package com.fastbee.common.core.domain;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 基类,时间类型改为LocalDateTime
+ * @author fastb
+ * @date 2023-08-22 9:11
+ */
+@Data
+public class BaseDO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /** 创建者 */
+    @ApiModelProperty("创建者")
+    private String createBy;
+
+    /** 创建时间 */
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /** 更新者 */
+    @ApiModelProperty("更新者")
+    private String updateBy;
+
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /** 逻辑删除 */
+    @ApiModelProperty("逻辑删除")
+    @TableLogic
+    private Boolean delFlag;
+
+}

+ 126 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/BaseEntity.java

@@ -0,0 +1,126 @@
+package com.fastbee.common.core.domain;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Entity基类
+ * 
+ * @author ruoyi
+ */
+public class BaseEntity implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 搜索值 */
+    @ApiModelProperty("搜索值")
+    @JsonIgnore
+    private String searchValue;
+
+    /** 创建者 */
+    @ApiModelProperty("创建者")
+    private String createBy;
+
+    /** 创建时间 */
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /** 更新者 */
+    @ApiModelProperty("更新者")
+    private String updateBy;
+
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /** 备注 */
+    @ApiModelProperty("备注")
+    private String remark;
+
+    /** 请求参数 */
+    @ApiModelProperty("请求参数")
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private Map<String, Object> params;
+
+    public String getSearchValue()
+    {
+        return searchValue;
+    }
+
+    public void setSearchValue(String searchValue)
+    {
+        this.searchValue = searchValue;
+    }
+
+    public String getCreateBy()
+    {
+        return createBy;
+    }
+
+    public void setCreateBy(String createBy)
+    {
+        this.createBy = createBy;
+    }
+
+    public Date getCreateTime()
+    {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime)
+    {
+        this.createTime = createTime;
+    }
+
+    public String getUpdateBy()
+    {
+        return updateBy;
+    }
+
+    public void setUpdateBy(String updateBy)
+    {
+        this.updateBy = updateBy;
+    }
+
+    public Date getUpdateTime()
+    {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime)
+    {
+        this.updateTime = updateTime;
+    }
+
+    public String getRemark()
+    {
+        return remark;
+    }
+
+    public void setRemark(String remark)
+    {
+        this.remark = remark;
+    }
+
+    public Map<String, Object> getParams()
+    {
+        if (params == null)
+        {
+            params = new HashMap<>();
+        }
+        return params;
+    }
+
+    public void setParams(Map<String, Object> params)
+    {
+        this.params = params;
+    }
+}

+ 112 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/CommonResult.java

@@ -0,0 +1,112 @@
+package com.fastbee.common.core.domain;
+
+import com.fastbee.common.enums.GlobalErrorCodeConstants;
+import com.fastbee.common.exception.ErrorCode;
+import com.fastbee.common.exception.ServiceException;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.springframework.util.Assert;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * 通用返回
+ *
+ * @param <T> 数据泛型
+ */
+@Data
+public class CommonResult<T> implements Serializable {
+
+    /**
+     * 错误码
+     *
+     * @see ErrorCode#getCode()
+     */
+    private Integer code;
+    /**
+     * 返回数据
+     */
+    private T data;
+    /**
+     * 错误提示,用户可阅读
+     *
+     * @see ErrorCode#getMsg() ()
+     */
+    private String msg;
+
+    /**
+     * 将传入的 result 对象,转换成另外一个泛型结果的对象
+     *
+     * 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。
+     *
+     * @param result 传入的 result 对象
+     * @param <T> 返回的泛型
+     * @return 新的 CommonResult 对象
+     */
+    public static <T> CommonResult<T> error(CommonResult<?> result) {
+        return error(result.getCode(), result.getMsg());
+    }
+
+    public static <T> CommonResult<T> error(Integer code, String message) {
+        Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
+        CommonResult<T> result = new CommonResult<>();
+        result.code = code;
+        result.msg = message;
+        return result;
+    }
+
+    public static <T> CommonResult<T> error(ErrorCode errorCode) {
+        return error(errorCode.getCode(), errorCode.getMsg());
+    }
+
+    public static <T> CommonResult<T> success(T data) {
+        CommonResult<T> result = new CommonResult<>();
+        result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
+        result.data = data;
+        result.msg = "";
+        return result;
+    }
+
+    public static boolean isSuccess(Integer code) {
+        return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
+    }
+
+    @JsonIgnore // 避免 jackson 序列化
+    public boolean isSuccess() {
+        return isSuccess(code);
+    }
+
+    @JsonIgnore // 避免 jackson 序列化
+    public boolean isError() {
+        return !isSuccess();
+    }
+
+    // ========= 和 Exception 异常体系集成 =========
+
+    /**
+     * 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
+     */
+    public void checkError() throws ServiceException {
+        if (isSuccess()) {
+            return;
+        }
+        // 业务异常
+        throw new ServiceException(code, msg);
+    }
+
+    /**
+     * 判断是否有异常。如果有,则抛出 {@link ServiceException} 异常
+     * 如果没有,则返回 {@link #data} 数据
+     */
+    @JsonIgnore // 避免 jackson 序列化
+    public T getCheckedData() {
+        checkError();
+        return data;
+    }
+
+    public static <T> CommonResult<T> error(ServiceException serviceException) {
+        return error(serviceException.getCode(), serviceException.getMessage());
+    }
+
+}

+ 25 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/PageParam.java

@@ -0,0 +1,25 @@
+package com.fastbee.common.core.domain;
+
+import lombok.Data;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class PageParam implements Serializable {
+
+    private static final Integer PAGE_NO = 1;
+    private static final Integer PAGE_SIZE = 10;
+
+    @NotNull(message = "页码不能为空")
+    @Min(value = 1, message = "页码最小值为 1")
+    private Integer pageNo = PAGE_NO;
+
+    @NotNull(message = "每页条数不能为空")
+    @Min(value = 1, message = "每页条数最小值为 1")
+    @Max(value = 100, message = "每页条数最大值为 100")
+    private Integer pageSize = PAGE_SIZE;
+
+}

+ 42 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/PageResult.java

@@ -0,0 +1,42 @@
+package com.fastbee.common.core.domain;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Api(tags = "分页结果")
+@Data
+public final class PageResult<T> implements Serializable {
+
+    @ApiModelProperty(value = "数据", required = true)
+    private List<T> list;
+
+    @ApiModelProperty(value = "总量", required = true)
+    private Long total;
+
+    public PageResult() {
+    }
+
+    public PageResult(List<T> list, Long total) {
+        this.list = list;
+        this.total = total;
+    }
+
+    public PageResult(Long total) {
+        this.list = new ArrayList<>();
+        this.total = total;
+    }
+
+    public static <T> PageResult<T> empty() {
+        return new PageResult<>(0L);
+    }
+
+    public static <T> PageResult<T> empty(Long total) {
+        return new PageResult<>(total);
+    }
+
+}

+ 115 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/R.java

@@ -0,0 +1,115 @@
+package com.fastbee.common.core.domain;
+
+import java.io.Serializable;
+import com.fastbee.common.constant.HttpStatus;
+
+/**
+ * 响应信息主体
+ *
+ * @author ruoyi
+ */
+public class R<T> implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 成功 */
+    public static final int SUCCESS = HttpStatus.SUCCESS;
+
+    /** 失败 */
+    public static final int FAIL = HttpStatus.ERROR;
+
+    private int code;
+
+    private String msg;
+
+    private T data;
+
+    public static <T> R<T> ok()
+    {
+        return restResult(null, SUCCESS, "操作成功");
+    }
+
+    public static <T> R<T> ok(T data)
+    {
+        return restResult(data, SUCCESS, "操作成功");
+    }
+
+    public static <T> R<T> ok(T data, String msg)
+    {
+        return restResult(data, SUCCESS, msg);
+    }
+
+    public static <T> R<T> fail()
+    {
+        return restResult(null, FAIL, "操作失败");
+    }
+
+    public static <T> R<T> fail(String msg)
+    {
+        return restResult(null, FAIL, msg);
+    }
+
+    public static <T> R<T> fail(T data)
+    {
+        return restResult(data, FAIL, "操作失败");
+    }
+
+    public static <T> R<T> fail(T data, String msg)
+    {
+        return restResult(data, FAIL, msg);
+    }
+
+    public static <T> R<T> fail(int code, String msg)
+    {
+        return restResult(null, code, msg);
+    }
+
+    private static <T> R<T> restResult(T data, int code, String msg)
+    {
+        R<T> apiResult = new R<>();
+        apiResult.setCode(code);
+        apiResult.setData(data);
+        apiResult.setMsg(msg);
+        return apiResult;
+    }
+
+    public int getCode()
+    {
+        return code;
+    }
+
+    public void setCode(int code)
+    {
+        this.code = code;
+    }
+
+    public String getMsg()
+    {
+        return msg;
+    }
+
+    public void setMsg(String msg)
+    {
+        this.msg = msg;
+    }
+
+    public T getData()
+    {
+        return data;
+    }
+
+    public void setData(T data)
+    {
+        this.data = data;
+    }
+
+    public static <T> Boolean isError(R<T> ret)
+    {
+        return !isSuccess(ret);
+    }
+
+    public static <T> Boolean isSuccess(R<T> ret)
+    {
+        return R.SUCCESS == ret.getCode();
+    }
+}

+ 56 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/SortingField.java

@@ -0,0 +1,56 @@
+package com.fastbee.common.core.domain;
+
+import java.io.Serializable;
+
+/**
+ * 排序字段 DTO
+ *
+ * 类名加了 ing 的原因是,避免和 ES SortField 重名。
+ */
+public class SortingField implements Serializable {
+
+    /**
+     * 顺序 - 升序
+     */
+    public static final String ORDER_ASC = "asc";
+    /**
+     * 顺序 - 降序
+     */
+    public static final String ORDER_DESC = "desc";
+
+    /**
+     * 字段
+     */
+    private String field;
+    /**
+     * 顺序
+     */
+    private String order;
+
+    // 空构造方法,解决反序列化
+    public SortingField() {
+    }
+
+    public SortingField(String field, String order) {
+        this.field = field;
+        this.order = order;
+    }
+
+    public String getField() {
+        return field;
+    }
+
+    public SortingField setField(String field) {
+        this.field = field;
+        return this;
+    }
+
+    public String getOrder() {
+        return order;
+    }
+
+    public SortingField setOrder(String order) {
+        this.order = order;
+        return this;
+    }
+}

+ 20 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/TenantBaseDO.java

@@ -0,0 +1,20 @@
+package com.fastbee.common.core.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 拓展多租户的 BaseDO 基类
+ *
+ * @author fastbee
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public abstract class TenantBaseDO extends BaseDO {
+
+    /**
+     * 多租户编号
+     */
+    private Long tenantId;
+
+}

+ 79 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/TreeEntity.java

@@ -0,0 +1,79 @@
+package com.fastbee.common.core.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tree基类
+ * 
+ * @author ruoyi
+ */
+public class TreeEntity extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 父菜单名称 */
+    private String parentName;
+
+    /** 父菜单ID */
+    private Long parentId;
+
+    /** 显示顺序 */
+    private Integer orderNum;
+
+    /** 祖级列表 */
+    private String ancestors;
+
+    /** 子部门 */
+    private List<?> children = new ArrayList<>();
+
+    public String getParentName()
+    {
+        return parentName;
+    }
+
+    public void setParentName(String parentName)
+    {
+        this.parentName = parentName;
+    }
+
+    public Long getParentId()
+    {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId)
+    {
+        this.parentId = parentId;
+    }
+
+    public Integer getOrderNum()
+    {
+        return orderNum;
+    }
+
+    public void setOrderNum(Integer orderNum)
+    {
+        this.orderNum = orderNum;
+    }
+
+    public String getAncestors()
+    {
+        return ancestors;
+    }
+
+    public void setAncestors(String ancestors)
+    {
+        this.ancestors = ancestors;
+    }
+
+    public List<?> getChildren()
+    {
+        return children;
+    }
+
+    public void setChildren(List<?> children)
+    {
+        this.children = children;
+    }
+}

+ 77 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/TreeSelect.java

@@ -0,0 +1,77 @@
+package com.fastbee.common.core.domain;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.stream.Collectors;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fastbee.common.core.domain.entity.SysDept;
+import com.fastbee.common.core.domain.entity.SysMenu;
+
+/**
+ * Treeselect树结构实体类
+ * 
+ * @author ruoyi
+ */
+public class TreeSelect implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 节点ID */
+    private Long id;
+
+    /** 节点名称 */
+    private String label;
+
+    /** 子节点 */
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private List<TreeSelect> children;
+
+    public TreeSelect()
+    {
+
+    }
+
+    public TreeSelect(SysDept dept)
+    {
+        this.id = dept.getDeptId();
+        this.label = dept.getDeptName();
+        this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
+    }
+
+    public TreeSelect(SysMenu menu)
+    {
+        this.id = menu.getMenuId();
+        this.label = menu.getMenuName();
+        this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public void setLabel(String label)
+    {
+        this.label = label;
+    }
+
+    public List<TreeSelect> getChildren()
+    {
+        return children;
+    }
+
+    public void setChildren(List<TreeSelect> children)
+    {
+        this.children = children;
+    }
+}

+ 219 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysDept.java

@@ -0,0 +1,219 @@
+package com.fastbee.common.core.domain.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fastbee.common.core.domain.BaseEntity;
+
+/**
+ * 部门表 sys_dept
+ * 
+ * @author ruoyi
+ */
+@ApiModel(value = "SysDept", description = "部门表 sys_dept")
+public class SysDept extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 部门ID */
+    @ApiModelProperty("部门ID")
+    private Long deptId;
+
+    /** 父部门ID */
+    @ApiModelProperty("父部门ID")
+    private Long parentId;
+
+    /** 祖级列表 */
+    @ApiModelProperty("祖级列表")
+    private String ancestors;
+
+    /** 部门名称 */
+    @ApiModelProperty("部门名称")
+    private String deptName;
+
+    /** 显示顺序 */
+    @ApiModelProperty("显示顺序")
+    private Integer orderNum;
+
+    /** 负责人 */
+    @ApiModelProperty("负责人")
+    private String leader;
+
+    /** 联系电话 */
+    @ApiModelProperty("联系电话")
+    private String phone;
+
+    /** 邮箱 */
+    @ApiModelProperty("邮箱")
+    private String email;
+
+    /** 部门状态:0正常,1停用 */
+    @ApiModelProperty("部门状态:0正常,1停用")
+    private String status;
+
+    /** 删除标志(0代表存在 2代表删除) */
+    @ApiModelProperty("删除标志(0代表存在 2代表删除)")
+    private String delFlag;
+
+    /** 父部门名称 */
+    @ApiModelProperty("父部门名称")
+    private String parentName;
+    
+    /** 子部门 */
+    @ApiModelProperty("子部门")
+    private List<SysDept> children = new ArrayList<SysDept>();
+
+    public Long getDeptId()
+    {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId)
+    {
+        this.deptId = deptId;
+    }
+
+    public Long getParentId()
+    {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId)
+    {
+        this.parentId = parentId;
+    }
+
+    public String getAncestors()
+    {
+        return ancestors;
+    }
+
+    public void setAncestors(String ancestors)
+    {
+        this.ancestors = ancestors;
+    }
+
+    @NotBlank(message = "部门名称不能为空")
+    @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
+    public String getDeptName()
+    {
+        return deptName;
+    }
+
+    public void setDeptName(String deptName)
+    {
+        this.deptName = deptName;
+    }
+
+    @NotNull(message = "显示顺序不能为空")
+    public Integer getOrderNum()
+    {
+        return orderNum;
+    }
+
+    public void setOrderNum(Integer orderNum)
+    {
+        this.orderNum = orderNum;
+    }
+
+    public String getLeader()
+    {
+        return leader;
+    }
+
+    public void setLeader(String leader)
+    {
+        this.leader = leader;
+    }
+
+    @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+    }
+
+    @Email(message = "邮箱格式不正确")
+    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getParentName()
+    {
+        return parentName;
+    }
+
+    public void setParentName(String parentName)
+    {
+        this.parentName = parentName;
+    }
+
+    public List<SysDept> getChildren()
+    {
+        return children;
+    }
+
+    public void setChildren(List<SysDept> children)
+    {
+        this.children = children;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("deptId", getDeptId())
+            .append("parentId", getParentId())
+            .append("ancestors", getAncestors())
+            .append("deptName", getDeptName())
+            .append("orderNum", getOrderNum())
+            .append("leader", getLeader())
+            .append("phone", getPhone())
+            .append("email", getEmail())
+            .append("status", getStatus())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 189 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysDictData.java

@@ -0,0 +1,189 @@
+package com.fastbee.common.core.domain.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fastbee.common.annotation.Excel;
+import com.fastbee.common.annotation.Excel.ColumnType;
+import com.fastbee.common.constant.UserConstants;
+import com.fastbee.common.core.domain.BaseEntity;
+
+/**
+ * 字典数据表 sys_dict_data
+ * 
+ * @author ruoyi
+ */
+@ApiModel(value = "SysDictData", description = "字典数据表 sys_dict_data")
+public class SysDictData extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 字典编码 */
+    @ApiModelProperty("字典编码")
+    @Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
+    private Long dictCode;
+
+    /** 字典排序 */
+    @ApiModelProperty("字典排序")
+    @Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
+    private Long dictSort;
+
+    /** 字典标签 */
+    @ApiModelProperty("字典标签")
+    @Excel(name = "字典标签")
+    private String dictLabel;
+
+    /** 字典键值 */
+    @ApiModelProperty("字典键值")
+    @Excel(name = "字典键值")
+    private String dictValue;
+
+    /** 字典类型 */
+    @ApiModelProperty("字典类型")
+    @Excel(name = "字典类型")
+    private String dictType;
+
+    /** 样式属性(其他样式扩展) */
+    @ApiModelProperty("样式属性(其他样式扩展)")
+    private String cssClass;
+
+    /** 表格字典样式 */
+    @ApiModelProperty("表格字典样式")
+    private String listClass;
+
+    /** 是否默认(Y是 N否) */
+    @ApiModelProperty("是否默认(Y是 N否)")
+    @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
+    private String isDefault;
+
+    /** 状态(0正常 1停用) */
+    @ApiModelProperty("状态(0正常 1停用)")
+    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    public Long getDictCode()
+    {
+        return dictCode;
+    }
+
+    public void setDictCode(Long dictCode)
+    {
+        this.dictCode = dictCode;
+    }
+
+    public Long getDictSort()
+    {
+        return dictSort;
+    }
+
+    public void setDictSort(Long dictSort)
+    {
+        this.dictSort = dictSort;
+    }
+
+    @NotBlank(message = "字典标签不能为空")
+    @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
+    public String getDictLabel()
+    {
+        return dictLabel;
+    }
+
+    public void setDictLabel(String dictLabel)
+    {
+        this.dictLabel = dictLabel;
+    }
+
+    @NotBlank(message = "字典键值不能为空")
+    @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
+    public String getDictValue()
+    {
+        return dictValue;
+    }
+
+    public void setDictValue(String dictValue)
+    {
+        this.dictValue = dictValue;
+    }
+
+    @NotBlank(message = "字典类型不能为空")
+    @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
+    public String getDictType()
+    {
+        return dictType;
+    }
+
+    public void setDictType(String dictType)
+    {
+        this.dictType = dictType;
+    }
+
+    @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
+    public String getCssClass()
+    {
+        return cssClass;
+    }
+
+    public void setCssClass(String cssClass)
+    {
+        this.cssClass = cssClass;
+    }
+
+    public String getListClass()
+    {
+        return listClass;
+    }
+
+    public void setListClass(String listClass)
+    {
+        this.listClass = listClass;
+    }
+
+    public boolean getDefault()
+    {
+        return UserConstants.YES.equals(this.isDefault);
+    }
+
+    public String getIsDefault()
+    {
+        return isDefault;
+    }
+
+    public void setIsDefault(String isDefault)
+    {
+        this.isDefault = isDefault;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+    
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("dictCode", getDictCode())
+            .append("dictSort", getDictSort())
+            .append("dictLabel", getDictLabel())
+            .append("dictValue", getDictValue())
+            .append("dictType", getDictType())
+            .append("cssClass", getCssClass())
+            .append("listClass", getListClass())
+            .append("isDefault", getIsDefault())
+            .append("status", getStatus())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 104 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysDictType.java

@@ -0,0 +1,104 @@
+package com.fastbee.common.core.domain.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fastbee.common.annotation.Excel;
+import com.fastbee.common.annotation.Excel.ColumnType;
+import com.fastbee.common.core.domain.BaseEntity;
+
+/**
+ * 字典类型表 sys_dict_type
+ * 
+ * @author ruoyi
+ */
+@ApiModel(value = "SysDictType", description = "字典类型表 sys_dict_type")
+public class SysDictType extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 字典主键 */
+    @ApiModelProperty("字典主键")
+    @Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
+    private Long dictId;
+
+    /** 字典名称 */
+    @ApiModelProperty("字典名称")
+    @Excel(name = "字典名称")
+    private String dictName;
+
+    /** 字典类型 */
+    @ApiModelProperty("字典类型")
+    @Excel(name = "字典类型")
+    private String dictType;
+
+    /** 状态(0正常 1停用) */
+    @ApiModelProperty("状态(0正常 1停用)")
+    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    public Long getDictId()
+    {
+        return dictId;
+    }
+
+    public void setDictId(Long dictId)
+    {
+        this.dictId = dictId;
+    }
+
+    @NotBlank(message = "字典名称不能为空")
+    @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
+    public String getDictName()
+    {
+        return dictName;
+    }
+
+    public void setDictName(String dictName)
+    {
+        this.dictName = dictName;
+    }
+
+    @NotBlank(message = "字典类型不能为空")
+    @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
+    @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
+    public String getDictType()
+    {
+        return dictType;
+    }
+
+    public void setDictType(String dictType)
+    {
+        this.dictType = dictType;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+    
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("dictId", getDictId())
+            .append("dictName", getDictName())
+            .append("dictType", getDictType())
+            .append("status", getStatus())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 279 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysMenu.java

@@ -0,0 +1,279 @@
+package com.fastbee.common.core.domain.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fastbee.common.core.domain.BaseEntity;
+
+/**
+ * 菜单权限表 sys_menu
+ * 
+ * @author ruoyi
+ */
+@ApiModel(value = "SysMenu", description = "菜单权限表 sys_menu")
+public class SysMenu extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 菜单ID */
+    @ApiModelProperty("菜单ID")
+    private Long menuId;
+
+    /** 菜单名称 */
+    @ApiModelProperty("菜单名称")
+    private String menuName;
+
+    /** 父菜单名称 */
+    @ApiModelProperty("父菜单名称")
+    private String parentName;
+
+    /** 父菜单ID */
+    @ApiModelProperty("父菜单ID")
+    private Long parentId;
+
+    /** 显示顺序 */
+    @ApiModelProperty("显示顺序")
+    private Integer orderNum;
+
+    /** 路由地址 */
+    @ApiModelProperty("路由地址")
+    private String path;
+
+    /** 组件路径 */
+    @ApiModelProperty("组件路径")
+    private String component;
+
+    /** 路由参数 */
+    @ApiModelProperty("路由参数")
+    private String query;
+
+    /** 是否为外链(0是 1否) */
+    @ApiModelProperty("是否为外链(0是 1否)")
+    private String isFrame;
+
+    /** 是否缓存(0缓存 1不缓存) */
+    @ApiModelProperty("是否缓存(0缓存 1不缓存)")
+    private String isCache;
+
+    /** 类型(M目录 C菜单 F按钮) */
+    @ApiModelProperty("类型(M目录 C菜单 F按钮)")
+    private String menuType;
+
+    /** 显示状态(0显示 1隐藏) */
+    @ApiModelProperty("显示状态(0显示 1隐藏)")
+    private String visible;
+    
+    /** 菜单状态(0正常 1停用) */
+    @ApiModelProperty("菜单状态(0正常 1停用)")
+    private String status;
+
+    /** 权限字符串 */
+    @ApiModelProperty("权限字符串")
+    private String perms;
+
+    /** 菜单图标 */
+    @ApiModelProperty("菜单图标")
+    private String icon;
+
+    /** 子菜单 */
+    @ApiModelProperty("子菜单")
+    private List<SysMenu> children = new ArrayList<SysMenu>();
+
+    public Long getMenuId()
+    {
+        return menuId;
+    }
+
+    public void setMenuId(Long menuId)
+    {
+        this.menuId = menuId;
+    }
+
+    @NotBlank(message = "菜单名称不能为空")
+    @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
+    public String getMenuName()
+    {
+        return menuName;
+    }
+
+    public void setMenuName(String menuName)
+    {
+        this.menuName = menuName;
+    }
+
+    public String getParentName()
+    {
+        return parentName;
+    }
+
+    public void setParentName(String parentName)
+    {
+        this.parentName = parentName;
+    }
+
+    public Long getParentId()
+    {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId)
+    {
+        this.parentId = parentId;
+    }
+
+    @NotNull(message = "显示顺序不能为空")
+    public Integer getOrderNum()
+    {
+        return orderNum;
+    }
+
+    public void setOrderNum(Integer orderNum)
+    {
+        this.orderNum = orderNum;
+    }
+
+    @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
+    public String getPath()
+    {
+        return path;
+    }
+
+    public void setPath(String path)
+    {
+        this.path = path;
+    }
+
+    @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
+    public String getComponent()
+    {
+        return component;
+    }
+
+    public void setComponent(String component)
+    {
+        this.component = component;
+    }
+
+    public String getQuery()
+    {
+        return query;
+    }
+
+    public void setQuery(String query)
+    {
+        this.query = query;
+    }
+
+    public String getIsFrame()
+    {
+        return isFrame;
+    }
+
+    public void setIsFrame(String isFrame)
+    {
+        this.isFrame = isFrame;
+    }
+
+    public String getIsCache()
+    {
+        return isCache;
+    }
+
+    public void setIsCache(String isCache)
+    {
+        this.isCache = isCache;
+    }
+
+    @NotBlank(message = "菜单类型不能为空")
+    public String getMenuType()
+    {
+        return menuType;
+    }
+
+    public void setMenuType(String menuType)
+    {
+        this.menuType = menuType;
+    }
+
+    public String getVisible()
+    {
+        return visible;
+    }
+
+    public void setVisible(String visible)
+    {
+        this.visible = visible;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
+    public String getPerms()
+    {
+        return perms;
+    }
+
+    public void setPerms(String perms)
+    {
+        this.perms = perms;
+    }
+
+    public String getIcon()
+    {
+        return icon;
+    }
+
+    public void setIcon(String icon)
+    {
+        this.icon = icon;
+    }
+
+    public List<SysMenu> getChildren()
+    {
+        return children;
+    }
+
+    public void setChildren(List<SysMenu> children)
+    {
+        this.children = children;
+    }
+    
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("menuId", getMenuId())
+            .append("menuName", getMenuName())
+            .append("parentId", getParentId())
+            .append("orderNum", getOrderNum())
+            .append("path", getPath())
+            .append("component", getComponent())
+            .append("isFrame", getIsFrame())
+            .append("IsCache", getIsCache())
+            .append("menuType", getMenuType())
+            .append("visible", getVisible())
+            .append("status ", getStatus())
+            .append("perms", getPerms())
+            .append("icon", getIcon())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 257 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysRole.java

@@ -0,0 +1,257 @@
+package com.fastbee.common.core.domain.entity;
+
+import java.util.Set;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fastbee.common.annotation.Excel;
+import com.fastbee.common.annotation.Excel.ColumnType;
+import com.fastbee.common.core.domain.BaseEntity;
+
+/**
+ * 角色表 sys_role
+ * 
+ * @author ruoyi
+ */
+@ApiModel(value = "SysRole", description = "角色表 sys_role")
+public class SysRole extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 角色ID */
+    @ApiModelProperty("角色ID")
+    @Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
+    private Long roleId;
+
+    /** 角色名称 */
+    @ApiModelProperty("角色名称")
+    @Excel(name = "角色名称")
+    private String roleName;
+
+    /** 角色权限 */
+    @ApiModelProperty("角色权限")
+    @Excel(name = "角色权限")
+    private String roleKey;
+
+    /** 角色排序 */
+    @ApiModelProperty("角色排序")
+    @Excel(name = "角色排序")
+    private Integer roleSort;
+
+    /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
+    @ApiModelProperty(value = "数据范围", notes = "(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)")
+    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
+    private String dataScope;
+
+    /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
+    @ApiModelProperty(value = "菜单树选择项是否关联显示", notes = "( 0:父子不互相关联显示 1:父子互相关联显示)")
+    private boolean menuCheckStrictly;
+
+    /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
+    @ApiModelProperty(value = "部门树选择项是否关联显示", notes = "(0:父子不互相关联显示 1:父子互相关联显示 )")
+    private boolean deptCheckStrictly;
+
+    /** 角色状态(0正常 1停用) */
+    @ApiModelProperty("角色状态(0正常 1停用)")
+    @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /** 删除标志(0代表存在 2代表删除) */
+    @ApiModelProperty("删除标志")
+    private String delFlag;
+
+    /** 用户是否存在此角色标识 默认不存在 */
+    private boolean flag = false;
+
+    /** 菜单组 */
+    @ApiModelProperty("菜单组")
+    private Long[] menuIds;
+
+    /** 部门组(数据权限) */
+    @ApiModelProperty("部门组")
+    private Long[] deptIds;
+
+    /** 角色菜单权限 */
+    @ApiModelProperty("角色菜单权限")
+    private Set<String> permissions;
+
+    public SysRole()
+    {
+
+    }
+
+    public SysRole(Long roleId)
+    {
+        this.roleId = roleId;
+    }
+
+    public Long getRoleId()
+    {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId)
+    {
+        this.roleId = roleId;
+    }
+
+    public boolean isAdmin()
+    {
+        return isAdmin(this.roleId);
+    }
+
+    public static boolean isAdmin(Long roleId)
+    {
+        return roleId != null && 1L == roleId;
+    }
+
+    @NotBlank(message = "角色名称不能为空")
+    @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
+    public String getRoleName()
+    {
+        return roleName;
+    }
+
+    public void setRoleName(String roleName)
+    {
+        this.roleName = roleName;
+    }
+
+    @NotBlank(message = "权限字符不能为空")
+    @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
+    public String getRoleKey()
+    {
+        return roleKey;
+    }
+
+    public void setRoleKey(String roleKey)
+    {
+        this.roleKey = roleKey;
+    }
+
+    @NotNull(message = "显示顺序不能为空")
+    public Integer getRoleSort()
+    {
+        return roleSort;
+    }
+
+    public void setRoleSort(Integer roleSort)
+    {
+        this.roleSort = roleSort;
+    }
+
+    public String getDataScope()
+    {
+        return dataScope;
+    }
+
+    public void setDataScope(String dataScope)
+    {
+        this.dataScope = dataScope;
+    }
+
+    public boolean isMenuCheckStrictly()
+    {
+        return menuCheckStrictly;
+    }
+
+    public void setMenuCheckStrictly(boolean menuCheckStrictly)
+    {
+        this.menuCheckStrictly = menuCheckStrictly;
+    }
+
+    public boolean isDeptCheckStrictly()
+    {
+        return deptCheckStrictly;
+    }
+
+    public void setDeptCheckStrictly(boolean deptCheckStrictly)
+    {
+        this.deptCheckStrictly = deptCheckStrictly;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public boolean isFlag()
+    {
+        return flag;
+    }
+
+    public void setFlag(boolean flag)
+    {
+        this.flag = flag;
+    }
+
+    public Long[] getMenuIds()
+    {
+        return menuIds;
+    }
+
+    public void setMenuIds(Long[] menuIds)
+    {
+        this.menuIds = menuIds;
+    }
+
+    public Long[] getDeptIds()
+    {
+        return deptIds;
+    }
+
+    public void setDeptIds(Long[] deptIds)
+    {
+        this.deptIds = deptIds;
+    }
+
+    public Set<String> getPermissions()
+    {
+        return permissions;
+    }
+
+    public void setPermissions(Set<String> permissions)
+    {
+        this.permissions = permissions;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("roleId", getRoleId())
+            .append("roleName", getRoleName())
+            .append("roleKey", getRoleKey())
+            .append("roleSort", getRoleSort())
+            .append("dataScope", getDataScope())
+            .append("menuCheckStrictly", isMenuCheckStrictly())
+            .append("deptCheckStrictly", isDeptCheckStrictly())
+            .append("status", getStatus())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 346 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysUser.java

@@ -0,0 +1,346 @@
+package com.fastbee.common.core.domain.entity;
+
+import java.util.Date;
+import java.util.List;
+import javax.validation.constraints.*;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fastbee.common.annotation.Excel;
+import com.fastbee.common.annotation.Excel.ColumnType;
+import com.fastbee.common.annotation.Excel.Type;
+import com.fastbee.common.annotation.Excels;
+import com.fastbee.common.core.domain.BaseEntity;
+import com.fastbee.common.xss.Xss;
+
+/**
+ * 用户对象 sys_user
+ * 
+ * @author ruoyi
+ */
+@ApiModel(value = "SysUser", description = "用户对象 sys_user")
+public class SysUser extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 用户ID */
+    @ApiModelProperty("用户ID")
+    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
+    private Long userId;
+
+    /** 部门ID */
+    @ApiModelProperty("部门ID")
+    @Excel(name = "部门编号", type = Type.IMPORT)
+    private Long deptId;
+
+    /** 用户账号 */
+    @ApiModelProperty("用户账号")
+    @Excel(name = "登录名称")
+    private String userName;
+
+    /** 用户昵称 */
+    @ApiModelProperty("用户昵称")
+    @Excel(name = "用户名称")
+    private String nickName;
+
+    /** 用户邮箱 */
+    @ApiModelProperty("用户邮箱")
+    @Excel(name = "用户邮箱")
+    private String email;
+
+    /** 手机号码 */
+    @ApiModelProperty("手机号码")
+    @Excel(name = "手机号码")
+    private String phonenumber;
+
+    /** 用户性别 */
+    @ApiModelProperty("用户性别")
+    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
+    private String sex;
+
+    /** 用户头像 */
+    @ApiModelProperty("用户头像")
+    private String avatar;
+
+    /** 密码 */
+    @ApiModelProperty("密码")
+    private String password;
+
+    /** 帐号状态(0正常 1停用) */
+    @ApiModelProperty("帐号状态(0正常 1停用)")
+    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /** 删除标志(0代表存在 2代表删除) */
+    @ApiModelProperty("删除标志")
+    private String delFlag;
+
+    /** 最后登录IP */
+    @ApiModelProperty("最后登录IP")
+    @Excel(name = "最后登录IP", type = Type.EXPORT)
+    private String loginIp;
+
+    /** 最后登录时间 */
+    @ApiModelProperty("最后登录时间")
+    @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
+    private Date loginDate;
+
+    /** 部门对象 */
+    @ApiModelProperty("部门对象")
+    @Excels({
+        @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
+        @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
+    })
+    private SysDept dept;
+
+    /** 角色对象 */
+    @ApiModelProperty("角色对象")
+    private List<SysRole> roles;
+
+    /** 角色组 */
+    @ApiModelProperty("角色组")
+    private Long[] roleIds;
+
+    /** 岗位组 */
+    @ApiModelProperty("岗位组")
+    private Long[] postIds;
+
+    /** 角色ID */
+    @ApiModelProperty("角色ID")
+    private Long roleId;
+
+    public SysUser()
+    {
+
+    }
+
+    public SysUser(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public boolean isAdmin()
+    {
+        return isAdmin(this.userId);
+    }
+
+    public static boolean isAdmin(Long userId)
+    {
+        return userId != null && 1L == userId;
+    }
+
+    public Long getDeptId()
+    {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId)
+    {
+        this.deptId = deptId;
+    }
+
+    @Xss(message = "用户昵称不能包含脚本字符")
+    @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
+    public String getNickName()
+    {
+        return nickName;
+    }
+
+    public void setNickName(String nickName)
+    {
+        this.nickName = nickName;
+    }
+
+    @Xss(message = "用户账号不能包含脚本字符")
+    @NotBlank(message = "用户账号不能为空")
+    @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
+    public String getUserName()
+    {
+        return userName;
+    }
+
+    public void setUserName(String userName)
+    {
+        this.userName = userName;
+    }
+
+    @Email(message = "邮箱格式不正确")
+    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
+    public String getPhonenumber()
+    {
+        return phonenumber;
+    }
+
+    public void setPhonenumber(String phonenumber)
+    {
+        this.phonenumber = phonenumber;
+    }
+
+    public String getSex()
+    {
+        return sex;
+    }
+
+    public void setSex(String sex)
+    {
+        this.sex = sex;
+    }
+
+    public String getAvatar()
+    {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar)
+    {
+        this.avatar = avatar;
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        this.password = password;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getLoginIp()
+    {
+        return loginIp;
+    }
+
+    public void setLoginIp(String loginIp)
+    {
+        this.loginIp = loginIp;
+    }
+
+    public Date getLoginDate()
+    {
+        return loginDate;
+    }
+
+    public void setLoginDate(Date loginDate)
+    {
+        this.loginDate = loginDate;
+    }
+
+    public SysDept getDept()
+    {
+        return dept;
+    }
+
+    public void setDept(SysDept dept)
+    {
+        this.dept = dept;
+    }
+
+    public List<SysRole> getRoles()
+    {
+        return roles;
+    }
+
+    public void setRoles(List<SysRole> roles)
+    {
+        this.roles = roles;
+    }
+
+    public Long[] getRoleIds()
+    {
+        return roleIds;
+    }
+
+    public void setRoleIds(Long[] roleIds)
+    {
+        this.roleIds = roleIds;
+    }
+
+    public Long[] getPostIds()
+    {
+        return postIds;
+    }
+
+    public void setPostIds(Long[] postIds)
+    {
+        this.postIds = postIds;
+    }
+
+    public Long getRoleId()
+    {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId)
+    {
+        this.roleId = roleId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("userId", getUserId())
+            .append("deptId", getDeptId())
+            .append("userName", getUserName())
+            .append("nickName", getNickName())
+            .append("email", getEmail())
+            .append("phonenumber", getPhonenumber())
+            .append("sex", getSex())
+            .append("avatar", getAvatar())
+            .append("password", getPassword())
+            .append("status", getStatus())
+            .append("delFlag", getDelFlag())
+            .append("loginIp", getLoginIp())
+            .append("loginDate", getLoginDate())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .append("dept", getDept())
+            .toString();
+    }
+}

+ 22 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/BindLoginBody.java

@@ -0,0 +1,22 @@
+package com.fastbee.common.core.domain.model;
+
+/**
+ * 用户登录对象
+ * 
+ * @author ruoyi
+ */
+public class BindLoginBody extends LoginBody
+{
+    /**
+     * 绑定id
+     */
+   private String bindId;
+
+    public String getBindId() {
+        return bindId;
+    }
+
+    public void setBindId(String bindId) {
+        this.bindId = bindId;
+    }
+}

+ 21 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/BindRegisterBody.java

@@ -0,0 +1,21 @@
+package com.fastbee.common.core.domain.model;
+
+/**
+ * 用户注册对象
+ *
+ * @author ruoyi
+ */
+public class BindRegisterBody extends RegisterBody {
+    /**
+     * 绑定id
+     */
+    private String bindId;
+
+    public String getBindId() {
+        return bindId;
+    }
+
+    public void setBindId(String bindId) {
+        this.bindId = bindId;
+    }
+}

+ 82 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginBody.java

@@ -0,0 +1,82 @@
+package com.fastbee.common.core.domain.model;
+
+/**
+ * 用户登录对象
+ *
+ * @author ruoyi
+ */
+public class LoginBody
+{
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 用户密码
+     */
+    private String password;
+
+    /**
+     * 验证码
+     */
+    private String code;
+
+    /**
+     * 唯一标识
+     */
+    private String uuid;
+
+    /**
+     * 手机号
+     */
+    private String phonenumber;
+
+    public String getPhonenumber() {
+        return phonenumber;
+    }
+
+    public void setPhonenumber(String phonenumber) {
+        this.phonenumber = phonenumber;
+    }
+
+    public String getUsername()
+    {
+        return username;
+    }
+
+    public void setUsername(String username)
+    {
+        this.username = username;
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        this.password = password;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(String code)
+    {
+        this.code = code;
+    }
+
+    public String getUuid()
+    {
+        return uuid;
+    }
+
+    public void setUuid(String uuid)
+    {
+        this.uuid = uuid;
+    }
+}

+ 266 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginUser.java

@@ -0,0 +1,266 @@
+package com.fastbee.common.core.domain.model;
+
+import java.util.Collection;
+import java.util.Set;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.fastbee.common.core.domain.entity.SysUser;
+
+/**
+ * 登录用户身份权限
+ * 
+ * @author ruoyi
+ */
+public class LoginUser implements UserDetails
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 用户唯一标识
+     */
+    private String token;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+
+    /**
+     * 过期时间
+     */
+    private Long expireTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+    /**
+     * 权限列表
+     */
+    private Set<String> permissions;
+
+    /**
+     * 用户信息
+     */
+    private SysUser user;
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getDeptId()
+    {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId)
+    {
+        this.deptId = deptId;
+    }
+
+    public String getToken()
+    {
+        return token;
+    }
+
+    public void setToken(String token)
+    {
+        this.token = token;
+    }
+
+    public LoginUser()
+    {
+    }
+
+    public LoginUser(SysUser user, Set<String> permissions)
+    {
+        this.user = user;
+        this.permissions = permissions;
+    }
+
+    public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
+    {
+        this.userId = userId;
+        this.deptId = deptId;
+        this.user = user;
+        this.permissions = permissions;
+    }
+
+    @JSONField(serialize = false)
+    @Override
+    public String getPassword()
+    {
+        return user.getPassword();
+    }
+
+    @Override
+    public String getUsername()
+    {
+        return user.getUserName();
+    }
+
+    /**
+     * 账户是否未过期,过期无法验证
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isAccountNonExpired()
+    {
+        return true;
+    }
+
+    /**
+     * 指定用户是否解锁,锁定的用户无法进行身份验证
+     * 
+     * @return
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isAccountNonLocked()
+    {
+        return true;
+    }
+
+    /**
+     * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
+     * 
+     * @return
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isCredentialsNonExpired()
+    {
+        return true;
+    }
+
+    /**
+     * 是否可用 ,禁用的用户不能身份验证
+     * 
+     * @return
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isEnabled()
+    {
+        return true;
+    }
+
+    public Long getLoginTime()
+    {
+        return loginTime;
+    }
+
+    public void setLoginTime(Long loginTime)
+    {
+        this.loginTime = loginTime;
+    }
+
+    public String getIpaddr()
+    {
+        return ipaddr;
+    }
+
+    public void setIpaddr(String ipaddr)
+    {
+        this.ipaddr = ipaddr;
+    }
+
+    public String getLoginLocation()
+    {
+        return loginLocation;
+    }
+
+    public void setLoginLocation(String loginLocation)
+    {
+        this.loginLocation = loginLocation;
+    }
+
+    public String getBrowser()
+    {
+        return browser;
+    }
+
+    public void setBrowser(String browser)
+    {
+        this.browser = browser;
+    }
+
+    public String getOs()
+    {
+        return os;
+    }
+
+    public void setOs(String os)
+    {
+        this.os = os;
+    }
+
+    public Long getExpireTime()
+    {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime)
+    {
+        this.expireTime = expireTime;
+    }
+
+    public Set<String> getPermissions()
+    {
+        return permissions;
+    }
+
+    public void setPermissions(Set<String> permissions)
+    {
+        this.permissions = permissions;
+    }
+
+    public SysUser getUser()
+    {
+        return user;
+    }
+
+    public void setUser(SysUser user)
+    {
+        this.user = user;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities()
+    {
+        return null;
+    }
+}

+ 11 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/RegisterBody.java

@@ -0,0 +1,11 @@
+package com.fastbee.common.core.domain.model;
+
+/**
+ * 用户注册对象
+ * 
+ * @author ruoyi
+ */
+public class RegisterBody extends LoginBody
+{
+
+}

+ 22 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/iot/response/DashDeviceTotalDto.java

@@ -0,0 +1,22 @@
+package com.fastbee.common.core.iot.response;
+
+import lombok.Data;
+
+/**
+ * 大屏设备总览数据
+ * @author bill
+ */
+@Data
+public class DashDeviceTotalDto {
+
+    /*设备总数*/
+    private Integer total;
+    /*在线设备总数*/
+    private Integer onlineCount;
+    /*离线设备总数*/
+    private Integer OfflineCount;
+    /*未激活设备数*/
+    private Integer unActiveCount;
+
+
+}

+ 26 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/iot/response/DeCodeBo.java

@@ -0,0 +1,26 @@
+package com.fastbee.common.core.iot.response;
+
+import lombok.Data;
+
+/**
+ * @author gsb
+ * @date 2023/4/8 15:43
+ */
+@Data
+public class DeCodeBo {
+
+    /**原始报文*/
+    private String payload;
+    /**从机编号*/
+    private Integer slaveId;
+    /**寄存器地址*/
+    private Integer address;
+    /**功能码*/
+    private Integer code;
+    /**读取个数*/
+    private Integer count;
+    /**写入值*/
+    private Integer writeData;
+    /**读写类型  1-解析 2-读指令 3-写指令 */
+    private Integer type;
+}

+ 70 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/iot/response/IdentityAndName.java

@@ -0,0 +1,70 @@
+package com.fastbee.common.core.iot.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 物模型值的项
+ *
+ * @author kerwincui
+ * @date 2021-12-16
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class IdentityAndName
+{
+
+    public IdentityAndName(String id,String value){
+        this.id=id;
+        this.value=value;
+    }
+
+    public IdentityAndName(String id,Integer isHistory){
+        this.id=id;
+        this.isHistory=isHistory;
+    }
+
+    public IdentityAndName(String id, Integer isHistory, String specs, String name, Integer type){
+        this.id = id;
+        this.isHistory = isHistory;
+        this.dataType = specs;
+        this.name = name;
+        this.type = type;
+    }
+
+    /** 物模型唯一标识符 */
+    private String id;
+    /** 物模型值 */
+    private Object value;
+
+    private Integer isChart;
+
+    /**是否监控*/
+    private Integer isHistory;
+    /**
+     * 数据定义
+     */
+    private String dataType;
+    /**物模型名称*/
+    private String name;
+    /**
+     * 物模型类型
+     */
+    private Integer type;
+    /**
+     * 是否是参数
+     */
+    private Integer isParams;
+
+    private String formula;
+
+    private Integer slaveId;
+
+    private Integer tempSlaveId;
+
+    private Integer quantity;
+
+    private String code;
+}

+ 17 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceReplyBo.java

@@ -0,0 +1,17 @@
+package com.fastbee.common.core.mq;
+
+import lombok.Data;
+
+/**
+ * @author bill
+ */
+@Data
+public class DeviceReplyBo {
+
+    /*设备下发消息id*/
+    private String messageId;
+    /*标识符*/
+    private String id;
+    /**下发值*/
+    private String value;
+}

+ 104 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceReport.java

@@ -0,0 +1,104 @@
+package com.fastbee.common.core.mq;
+
+import com.fastbee.common.core.mq.message.SubDeviceMessage;
+import com.fastbee.common.core.protocol.Message;
+import com.fastbee.common.core.thingsModel.ThingsModelValuesInput;
+import com.fastbee.common.enums.FunctionReplyStatus;
+import com.fastbee.common.enums.ServerType;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 设备上行数据model
+ *
+ * @author bill
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class DeviceReport extends Message {
+
+    /**
+     * 设备编号
+     */
+    private String serialNumber;
+    /**
+     * 产品ID
+     */
+    private Long productId;
+    /**
+     * 平台时间
+     */
+    private Date platformDate;
+    /**
+     * 寄存器地址
+     */
+    private String hexAddress;
+    /**
+     * 物模型标识符
+     */
+    private String identifier;
+    /**
+     * 消息id
+     */
+    private String messageId;
+    /**
+     * 设备主动上报的消息体
+     * key 物模型Identifier
+     * value 物模型设备对应值
+     */
+    private ThingsModelValuesInput valuesInput;
+    /**
+     * 消息id或 消息流水号
+     */
+    private String serNo;
+    /**
+     * 值是否监控,如果监控表示需要历史存储,该值来自物模型
+     */
+    private Integer isMonitor;
+    /** ================网关子设备====================*/
+    /**
+     * 网关子设备编号
+     */
+    private List<String> subDeviceCodes;
+    /**
+     * 网关子设备消息
+     */
+    private List<SubDeviceMessage> subDeviceMessages;
+    /** ================回调数据====================*/
+
+    /**
+     * 是否设备回复数据
+     */
+    private Boolean isReply = false;
+
+    /**
+     * 设备回复消息
+     */
+    private String replyMessage;
+    /**
+     * 设备回复状态
+     */
+    private FunctionReplyStatus status;
+    /**
+     * 从机编号
+     */
+    private Integer slaveId;
+    /**
+     * 服务器类型
+     */
+    private ServerType serverType;
+    /**
+     * 寄存器地址
+     */
+    private int address;
+
+    private String protocolCode;
+
+    private Long userId;
+    private String userName;
+    private String deviceName;
+}

+ 73 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceReportBo.java

@@ -0,0 +1,73 @@
+package com.fastbee.common.core.mq;
+
+import com.fastbee.common.core.mq.message.PropRead;
+import com.fastbee.common.core.thingsModel.ThingsModelValuesInput;
+import com.fastbee.common.enums.FunctionReplyStatus;
+import com.fastbee.common.enums.ServerType;
+import com.fastbee.common.enums.ThingsModelType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 设备上报
+ * @author bill
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceReportBo {
+
+    /*设备编号或IMEI号*/
+    private String serialNumber;
+    /*产品ID*/
+    private Long productId;
+    /*4G物联网卡CCID*/
+    private String ccId;
+    /*topic*/
+    private String topicName;
+    /*mqtt消息中的packetId*/
+    private Long packetId;
+    /*上报时间*/
+    private Date platformDate;
+    /*物模型类型 1=-属性,2-功能,3-事件 */
+    private ThingsModelType type;
+    /*上报数据*/
+    private byte[] data;
+    /*1-设备数据上报 2- 下发指令给设备,设备应答数据*/
+    private Integer reportType;
+    /*消息id*/
+    private String messageId;
+    /* modbus协议消息回调,记录数据*/
+    private PropRead prop;
+    /*解析后组装好的数据*/
+    private ThingsModelValuesInput valuesInput;
+    /*处理的消息服务类型*/
+    private ServerType serverType;
+    private Integer slaveId;
+
+    /**
+     * 是否设备回复数据
+     */
+    private Boolean isReply = false;
+
+    /**
+     * 设备回复消息
+     */
+    private String replyMessage;
+    /**
+     * 设备回复状态
+     */
+    private FunctionReplyStatus status;
+    /**
+     * 寄存器地址
+     */
+    private int address;
+
+    private String protocolCode;
+
+}

+ 35 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/DeviceStatusBo.java

@@ -0,0 +1,35 @@
+package com.fastbee.common.core.mq;
+
+import com.fastbee.common.enums.DeviceStatus;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 设备状态
+ * @author bill
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@Builder
+public class DeviceStatusBo {
+    /**
+     * 设备客户端id
+     */
+    private String serialNumber;
+    /**是否活跃*/
+    private DeviceStatus status;
+    /**消息时间*/
+    private Date timestamp;
+    /*host*/
+    private String hostName;
+    /*port*/
+    private Integer port;
+
+    private String ip;
+
+}

+ 62 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/InvokeReqDto.java

@@ -0,0 +1,62 @@
+package com.fastbee.common.core.mq;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fastbee.common.utils.DateUtils;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @author gsb
+ * @date 2022/12/5 11:26
+ */
+@Data
+public class InvokeReqDto {
+
+    @NotNull(message = "设备编号不能为空")
+    @ApiModelProperty(value = "设备编号")
+    private String serialNumber;
+
+    @NotNull(message = "标识符不能为空")
+    @ApiModelProperty(value = "标识符")
+    private String identifier;
+    /**消息体*/
+    @ApiModelProperty(value = "消息体")
+    private JSONObject value;
+    /**远程消息体*/
+    @ApiModelProperty(value = "远程调用消息体")
+    private Map<String,Object> remoteCommand;
+    /**设备超时时间*/
+    @ApiModelProperty(value = "设备超时响应时间,默认10s")
+    private Integer timeOut = 10;
+
+    @ApiModelProperty(value = "下发物模型类型")
+    @NotNull
+    private Integer type;
+
+    @ApiModelProperty(value = "是否是影子模式")
+    @NotNull
+    private Boolean isShadow;
+
+    private String dataType;
+
+    @NotNull(message = "产品id不能为空")
+    @ApiModelProperty(value = "产品id")
+    private Long productId;
+    /**从机编号*/
+    private Integer slaveId;
+    /**
+     * 显示的值
+     */
+    private String showValue;
+
+    /**
+     * 物模型名称
+     */
+    private String modelName;
+
+    private Date timestamp = DateUtils.getNowDate();
+}

+ 51 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/MQSendMessageBo.java

@@ -0,0 +1,51 @@
+package com.fastbee.common.core.mq;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fastbee.common.core.protocol.modbus.ModbusCode;
+import com.fastbee.common.enums.ThingsModelType;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 服务(指令)下发对象
+ *
+ * @author bill
+ */
+@Data
+@NoArgsConstructor
+public class MQSendMessageBo {
+
+    /*设备编号*/
+    private String serialNumber;
+    /*下发属性标识符*/
+    private String identifier;
+    /*寄存器地址 10进制*/
+    private String hexAddress;
+    /*topic*/
+    private JSONObject  command;
+    private String topicName;
+    /*产品ID*/
+    private Long productId;
+    /*物模型类型 1=-属性,2-功能,3-事件,4-属性和功能*/
+    private ThingsModelType type;
+    /*下发的数据*/
+    private JSONObject value;
+    /*协议编号 例如:modbus-rtu*/
+    private String protocolCode;
+    /*messageId生成放到调用接口的时候生成*/
+    private String messageId;
+    /*流水号,针对某些协议没有消息流水号无法区分下发的消息和上报的消息是否对应*/
+    private String serialNo;
+    /*从机id*/
+    private Integer slaveId;
+    /**显示值*/
+    private String showValue;
+    private String modelName;
+    private ModbusCode code;
+    /*是否是影子模式*/
+    private Boolean isShadow;
+    /*传输协议*/
+    private String transport;
+
+
+}

+ 51 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/MessageReplyBo.java

@@ -0,0 +1,51 @@
+package com.fastbee.common.core.mq;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 设备消息回调或者下发指令值
+ *
+ * @author gsb
+ * @date 2022/5/11 9:27
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MessageReplyBo {
+
+
+    private String id;
+    /**
+     * 消息回执的messageId,和下行消息呼应
+     */
+    private String messageId;
+    /**
+     * 设备处理消息的状态
+     */
+    private Integer status;
+    /**
+     * 抵达服务器时间
+     */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date timestamp;
+    /**
+     * 设备上报的时间
+     */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date deviceTimestamp;
+    /**
+     * 回执消息内容
+     */
+    private String body;
+    /*产品编号*/
+    private Long productId;
+    /*设备编号*/
+    private String serialNumber;
+}

+ 49 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceData.java

@@ -0,0 +1,49 @@
+package com.fastbee.common.core.mq.message;
+
+import com.fastbee.common.core.protocol.Message;
+import com.fastbee.common.core.protocol.modbus.ModbusCode;
+import io.netty.buffer.ByteBuf;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 消息解析model
+ * @author gsb
+ * @date 2022/10/10 15:53
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+public class DeviceData extends Message {
+
+    /*topic*/
+    private String topicName;
+
+    /*设备编号*/
+    private String serialNumber;
+
+    /*原数据*/
+    private byte[] data;
+
+    private ByteBuf buf;
+
+    /*消息类型 1.设备上报数据 2.设备回调数据*/
+    private int messageType;
+
+    /*下发数据model*/
+    private DeviceDownMessage downMessage;
+
+    private Object body;
+    /*MQTT OR 其他*/
+    private int type;
+
+    /*Modbus*/
+    private ModbusCode code;
+
+    private PropRead prop;
+    /*是否使用modbus客户端模拟测试*/
+    private boolean isEnabledTest;
+    /**产品id*/
+    private Long productId;
+}

+ 69 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceDownMessage.java

@@ -0,0 +1,69 @@
+package com.fastbee.common.core.mq.message;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fastbee.common.core.protocol.modbus.ModbusCode;
+import com.fastbee.common.enums.ServerType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 设备下发指令model
+ *
+ * @author gsb
+ * @date 2022/10/10 16:18
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceDownMessage {
+
+    private String messageId;
+    /**
+     * 时间戳,单位毫秒
+     */
+    private Long timestamp;
+    /**
+     * 消息体
+     */
+    private Object body;
+    /*下发的指令,服务调用的时候就是服务标识符*/
+    private String identifier;
+    /*产品id*/
+    private Long productId;
+    /**
+     * 设备编码
+     */
+    private String serialNumber;
+    /*网关设备编码*/
+    String subSerialNumber;
+    /**
+     * true: 表示是一条发往网关子设备的指令
+     * 默认是false
+     */
+    Boolean subFlag = false;
+    /**
+     * 从机编号
+     */
+    private Integer slaveId;
+    private ModbusCode code;
+    private int count;
+    private int address;
+    private String protocolCode;
+
+    private List<PropRead> values;
+    private String topic;
+    private String subCode;
+    private ServerType serverType;
+
+    public DeviceDownMessage(List<PropRead> values, String topic, String subCode,String transport) {
+        this.values = values;
+        this.topic = topic;
+        this.subCode = subCode;
+        this.serverType = ServerType.explain(transport);
+    }
+}

+ 33 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceFunctionMessage.java

@@ -0,0 +1,33 @@
+package com.fastbee.common.core.mq.message;
+
+import lombok.Data;
+
+/**
+ * 平台下发指令数据model
+ * @author bill
+ */
+@Data
+public class DeviceFunctionMessage {
+
+    /*流水号,兼容modbus标准协议没有消息流水号*/
+    private String seqNo;
+    /*平台时间*/
+    private Long pfTimestamp;
+    /*下发的消息体*/
+    private Object body;
+    /*下发的指令物模型标识符*/
+    private String identifier;
+    /*下发的数据寄存器地址*/
+    private String hexAddress;
+    /*产品ID*/
+    private Long productId;
+    /*设备编号*/
+    private String serialNumber;
+    /*网关设备编号*/
+    private String protocolCode;
+
+    /*是否有子设备 0-否,1-是*/
+    private Integer hasSub;
+    /*子设备从机编号 例如 02 编号从机。通过主机集控下发的指定从机编号*/
+    private String subDeviceCode;
+}

+ 20 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/DeviceMessage.java

@@ -0,0 +1,20 @@
+package com.fastbee.common.core.mq.message;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 集群消息
+ * @author bill
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DeviceMessage<T> {
+
+    /*数据*/
+    private T data;
+
+    private int nodeId;
+}

+ 20 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/InstructionsMessage.java

@@ -0,0 +1,20 @@
+package com.fastbee.common.core.mq.message;
+
+import lombok.Data;
+
+/**
+ * 指令下发组将的model
+ * @author bill
+ */
+@Data
+public class InstructionsMessage {
+
+    /*下发的数据*/
+    private byte[] message;
+
+    /*MQTt-下发的topic*/
+    private String topicName;
+
+    /*设备编号*/
+    private String serialNumber;
+}

+ 26 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/MqttBo.java

@@ -0,0 +1,26 @@
+package com.fastbee.common.core.mq.message;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author bill
+ */
+@Data
+public class MqttBo {
+
+    /*主题*/
+    private String topic;
+    /*数据*/
+    private String data;
+    /*消息质量*/
+    private int qos = 1;
+    /*发送方向*/
+    private String direction;
+    /*时间*/
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date ts;
+}
+

+ 39 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/PropRead.java

@@ -0,0 +1,39 @@
+package com.fastbee.common.core.mq.message;
+
+import com.fastbee.common.core.protocol.modbus.ModbusCode;
+import lombok.Data;
+
+/**
+ * @author gsb
+ * @date 2022/12/9 10:15
+ */
+@Data
+public class PropRead {
+
+    /**设备编号*/
+    private String serialNumber;
+    /**寄存器起始地址*/
+    private int address;
+    /**
+     * 读取寄存器个数
+     */
+    private int count;
+    /**数据结果长度计算值*/
+    private int length;
+    /**
+     * 从机地址
+     */
+    private int slaveId;
+    /**
+     * 读取个数
+     */
+    private int quantity;
+    /**
+     * 数据
+     */
+    private String data;
+    /**
+     * 功能码
+     */
+    private ModbusCode code;
+}

+ 21 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/ProtocolDto.java

@@ -0,0 +1,21 @@
+package com.fastbee.common.core.mq.message;
+
+import lombok.Data;
+
+/**
+ * 协议bean
+ * @author gsb
+ * @date 2022/10/25 14:54
+ */
+@Data
+public class ProtocolDto {
+
+    /**协议编号*/
+    private String code;
+    private String name;
+    /*外部协议url*/
+    private String protocolUrl;
+    private String description;
+    /**协议类型 协议类型 0:系统协议 1:jar,2.js,3.c*/
+    private Integer protocolType;
+}

+ 18 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/message/SubDeviceMessage.java

@@ -0,0 +1,18 @@
+package com.fastbee.common.core.mq.message;
+
+import lombok.Data;
+
+/**
+ * 网关子设备model
+ * @author gsb
+ * @date 2022/10/10 10:18
+ */
+@Data
+public class SubDeviceMessage {
+    /*子设备编号或编码*/
+    private String serialNumber;
+    /*数据*/
+    private byte[] data;
+    /*消息id*/
+    private String messageId;
+}

+ 17 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/ota/OtaReplyMessage.java

@@ -0,0 +1,17 @@
+package com.fastbee.common.core.mq.ota;
+
+import lombok.Data;
+
+/**
+ * OTA升级回复model
+ * @author gsb
+ * @date 2022/10/24 17:20
+ */
+@Data
+public class OtaReplyMessage {
+
+    private String messageId;
+    // 200成功 其他。。
+    private int code;
+    private String msg;
+}

+ 46 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/ota/OtaUpgradeBo.java

@@ -0,0 +1,46 @@
+package com.fastbee.common.core.mq.ota;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Builder;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * OTA远程升级
+ * @author gsb
+ * @date 2022/10/10 10:22
+ */
+@Data
+@Builder
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public class OtaUpgradeBo {
+
+    /**OTAId*/
+    private Long otaId;
+    @NotNull(message = "上传地址为空")
+    private String otaUrl;
+    @NotNull(message = "固件版本号不能为空")
+    private String firmwareVersion;
+    private String firmwareName;
+    @NotNull(message = "流水号不能为空")
+    private String seqNo;
+    @NotNull(message = "产品ID不能为空")
+    private Long productId;
+    private String signType = "16md5";
+    @NotNull(message = "签名不能为空")
+    private String signCode;
+    /*产品名称*/
+    private String productName;
+    private String fileBase64;
+    private Integer pushType;
+    /*设备编码,逐个升级*/
+    private String serialNumber;
+    private String deviceName;
+    /*任务ID*/
+    private Long taskId;
+    /*消息id*/
+    private String messageId;
+    /*平台描述消息*/
+    private String msg;
+}

+ 54 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/mq/ota/OtaUpgradeDelayTask.java

@@ -0,0 +1,54 @@
+package com.fastbee.common.core.mq.ota;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fastbee.common.utils.DateUtils;
+import lombok.Data;
+import org.springframework.lang.NonNull;
+
+import java.lang.reflect.Member;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ota升级发送,实现Delayed延时接口
+ *
+ * @author bill
+ */
+@Data
+public class OtaUpgradeDelayTask implements Delayed {
+
+    /*固件id*/
+    private Long firmwareId;
+    private List<String> devices;
+    /*任务id*/
+    private Long taskId;
+    /*开始升级时间*/
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date startTime;
+
+
+    /**
+     * 设置延迟执行时间 开始升级时间 -当前时间
+     *
+     * @param unit
+     * @return
+     */
+    @Override
+    public long getDelay(TimeUnit unit) {
+        return startTime.getTime() - DateUtils.getTimestamp();
+    }
+
+    @Override
+    public int compareTo(Delayed o) {
+        OtaUpgradeDelayTask delayTask = (OtaUpgradeDelayTask) o;
+        //比较
+        long diff = this.startTime.getTime() - delayTask.startTime.getTime();
+        if (diff <= 0) {
+            return -1;
+        } else {
+            return 1;
+        }
+    }
+}

+ 101 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/page/PageDomain.java

@@ -0,0 +1,101 @@
+package com.fastbee.common.core.page;
+
+import com.fastbee.common.utils.StringUtils;
+
+/**
+ * 分页数据
+ * 
+ * @author ruoyi
+ */
+public class PageDomain
+{
+    /** 当前记录起始索引 */
+    private Integer pageNum;
+
+    /** 每页显示记录数 */
+    private Integer pageSize;
+
+    /** 排序列 */
+    private String orderByColumn;
+
+    /** 排序的方向desc或者asc */
+    private String isAsc = "asc";
+
+    /** 分页参数合理化 */
+    private Boolean reasonable = true;
+
+    public String getOrderBy()
+    {
+        if (StringUtils.isEmpty(orderByColumn))
+        {
+            return "";
+        }
+        return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
+    }
+
+    public Integer getPageNum()
+    {
+        return pageNum;
+    }
+
+    public void setPageNum(Integer pageNum)
+    {
+        this.pageNum = pageNum;
+    }
+
+    public Integer getPageSize()
+    {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize)
+    {
+        this.pageSize = pageSize;
+    }
+
+    public String getOrderByColumn()
+    {
+        return orderByColumn;
+    }
+
+    public void setOrderByColumn(String orderByColumn)
+    {
+        this.orderByColumn = orderByColumn;
+    }
+
+    public String getIsAsc()
+    {
+        return isAsc;
+    }
+
+    public void setIsAsc(String isAsc)
+    {
+        if (StringUtils.isNotEmpty(isAsc))
+        {
+            // 兼容前端排序类型
+            if ("ascending".equals(isAsc))
+            {
+                isAsc = "asc";
+            }
+            else if ("descending".equals(isAsc))
+            {
+                isAsc = "desc";
+            }
+            this.isAsc = isAsc;
+        }
+    }
+
+    public Boolean getReasonable()
+    {
+        if (StringUtils.isNull(reasonable))
+        {
+            return Boolean.TRUE;
+        }
+        return reasonable;
+    }
+
+    public void setReasonable(Boolean reasonable)
+    {
+        this.reasonable = reasonable;
+    }
+}

+ 85 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/page/TableDataInfo.java

@@ -0,0 +1,85 @@
+package com.fastbee.common.core.page;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 表格分页数据对象
+ * 
+ * @author ruoyi
+ */
+public class TableDataInfo implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 总记录数 */
+    private long total;
+
+    /** 列表数据 */
+    private List<?> rows;
+
+    /** 消息状态码 */
+    private int code;
+
+    /** 消息内容 */
+    private String msg;
+
+    /**
+     * 表格数据对象
+     */
+    public TableDataInfo()
+    {
+    }
+
+    /**
+     * 分页
+     * 
+     * @param list 列表数据
+     * @param total 总记录数
+     */
+    public TableDataInfo(List<?> list, int total)
+    {
+        this.rows = list;
+        this.total = total;
+    }
+
+    public long getTotal()
+    {
+        return total;
+    }
+
+    public void setTotal(long total)
+    {
+        this.total = total;
+    }
+
+    public List<?> getRows()
+    {
+        return rows;
+    }
+
+    public void setRows(List<?> rows)
+    {
+        this.rows = rows;
+    }
+
+    public int getCode()
+    {
+        return code;
+    }
+
+    public void setCode(int code)
+    {
+        this.code = code;
+    }
+
+    public String getMsg()
+    {
+        return msg;
+    }
+
+    public void setMsg(String msg)
+    {
+        this.msg = msg;
+    }
+}

+ 56 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/page/TableSupport.java

@@ -0,0 +1,56 @@
+package com.fastbee.common.core.page;
+
+import com.fastbee.common.core.text.Convert;
+import com.fastbee.common.utils.ServletUtils;
+
+/**
+ * 表格数据处理
+ * 
+ * @author ruoyi
+ */
+public class TableSupport
+{
+    /**
+     * 当前记录起始索引
+     */
+    public static final String PAGE_NUM = "pageNum";
+
+    /**
+     * 每页显示记录数
+     */
+    public static final String PAGE_SIZE = "pageSize";
+
+    /**
+     * 排序列
+     */
+    public static final String ORDER_BY_COLUMN = "orderByColumn";
+
+    /**
+     * 排序的方向 "desc" 或者 "asc".
+     */
+    public static final String IS_ASC = "isAsc";
+
+    /**
+     * 分页参数合理化
+     */
+    public static final String REASONABLE = "reasonable";
+
+    /**
+     * 封装分页对象
+     */
+    public static PageDomain getPageDomain()
+    {
+        PageDomain pageDomain = new PageDomain();
+        pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
+        pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
+        pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
+        pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
+        pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
+        return pageDomain;
+    }
+
+    public static PageDomain buildPageRequest()
+    {
+        return getPageDomain();
+    }
+}

+ 33 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/protocol/Message.java

@@ -0,0 +1,33 @@
+package com.fastbee.common.core.protocol;
+
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 基础消息
+ *
+ * @author bill
+ */
+@Data
+public class Message implements Serializable {
+
+    /*获取客户端id*/
+   public String clientId;
+    /*消息类型*/
+    public String messageId;
+    /*消息流水号*/
+    public String serNo;
+    /**消息通道id*/
+    public String channelId;
+
+    public ByteBuf payload;
+
+    /**
+     * 是否数据和注册包都封装到一起
+     */
+    private Boolean isPackage = false;
+
+    private Object body;
+}

+ 87 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/protocol/modbus/ModbusCode.java

@@ -0,0 +1,87 @@
+package com.fastbee.common.core.protocol.modbus;
+
+import com.fastbee.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Modbus功能码
+ * @author bill
+ *
+ * {bit 位操作}
+ * 线圈寄存器:   bit对应一个信号的开关状态。功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01  0x05  0x0f
+ * 离散输入寄存器:离散输入寄存器就 是 只读线圈寄存器,每个bit表示一个开关量,是不能够写的。 功能码: 0x02
+ *
+ * {byte 字节操作}
+ * 保持寄存器:  两个byte,可读写的 写也分为单个写和多个写对应的三个:0x03 0x06 0x10
+ * 输入寄存器:  和保持寄存器类似,只支持读而不能写,一般是读取各种实时数据。一个寄存器也是占据两个byte的空间。对应的功能码: 0x04
+ *
+ */
+@Getter
+@AllArgsConstructor
+public enum ModbusCode {
+
+    Read01("读线圈",(byte) 0x01), // 读线圈(读写位模式)
+    Read02("读离散量输入",(byte) 0x02), // 读离散量输入(位只读模式)
+    Read03("读保持寄存器",(byte) 0x03), // 读保持寄存器(字节读写模式)
+    Read04("读输入寄存器",(byte) 0x04), // 读输入寄存器(字节只读模式)
+
+    Write05("写单个线圈(读写位模式)",(byte) 0x05), // 写单个线圈(读写位模式)
+    Write06("写多个线圈",(byte) 0x06), // 写单个保持寄存器
+    Write0F("写多个线圈",(byte) 0x0F), // 写多个线圈
+    Write10("写多个保持寄存器",(byte) 0x10) // 写多个保持寄存器
+    ;
+
+    private String desc;
+    private byte code;
+
+    public static ModbusCode getInstance(int code) {
+        switch ((byte)code) {
+            case 0x01:
+                return Read01;
+            case 0x02:
+                return Read02;
+            case 0x03:
+                return Read03;
+            case 0x04:
+                return Read04;
+
+            case 0x05:
+                return Write05;
+            case 0x06:
+                return Write06;
+            case 0x0F:
+                return Write0F;
+            case 0x10:
+                return Write10;
+
+            default:
+                throw new ServiceException("功能码[" + code + "],未定义");
+        }
+    }
+
+    public static String getDes(int code){
+        switch ((byte)code) {
+            case 0x01:
+                return Read01.desc;
+            case 0x02:
+                return Read02.desc;
+            case 0x03:
+                return Read03.desc;
+            case 0x04:
+                return Read04.desc;
+            case 0x05:
+                return Write05.desc;
+            case 0x06:
+                return Write06.desc;
+            case 0x0F:
+                return Write0F.desc;
+            case 0x10:
+                return Write10.desc;
+
+            default:
+                return "UNKOWN";
+        }
+    }
+
+}

+ 735 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisCache.java

@@ -0,0 +1,735 @@
+package com.fastbee.common.core.redis;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.Cursor;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.data.redis.support.atomic.RedisAtomicLong;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.util.regex.Pattern.compile;
+
+/**
+ * spring redis 工具类
+ *
+ * @author ruoyi
+ **/
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
+@Component
+public class RedisCache {
+    @Autowired
+    public RedisTemplate redisTemplate;
+
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key   缓存的键值
+     * @param value 缓存的值
+     */
+    public <T> void setCacheObject(final String key, final T value) {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key      缓存的键值
+     * @param value    缓存的值
+     * @param timeout  时间
+     * @param timeUnit 时间颗粒度
+     */
+    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key     Redis键
+     * @param timeout 超时时间
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout) {
+        return expire(key, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key     Redis键
+     * @param timeout 超时时间
+     * @param unit    时间单位
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
+        return redisTemplate.expire(key, timeout, unit);
+    }
+
+    /**
+     * 获取有效时间
+     *
+     * @param key Redis键
+     * @return 有效时间
+     */
+    public long getExpire(final String key) {
+        return redisTemplate.getExpire(key);
+    }
+
+    /**
+     * 判断 key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public Boolean hasKey(String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T getCacheObject(final String key) {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 删除单个对象
+     *
+     * @param key
+     */
+    public boolean deleteObject(final String key) {
+        return redisTemplate.delete(key);
+    }
+
+    /**
+     * 删除集合对象
+     *
+     * @param collection 多个对象
+     * @return
+     */
+    public boolean deleteObject(final Collection collection) {
+        return redisTemplate.delete(collection) > 0;
+    }
+
+    /**
+     * 缓存List数据
+     *
+     * @param key      缓存的键值
+     * @param dataList 待缓存的List数据
+     * @return 缓存的对象
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList) {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 获得缓存的list对象
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> List<T> getCacheList(final String key) {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缓存Set
+     *
+     * @param key     缓存键值
+     * @param dataSet 缓存的数据
+     * @return 缓存数据的对象
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        Iterator<T> it = dataSet.iterator();
+        while (it.hasNext()) {
+            setOperation.add(it.next());
+        }
+        return setOperation;
+    }
+
+    /**
+     * 获得缓存的set
+     *
+     * @param key
+     * @return
+     */
+    public <T> Set<T> getCacheSet(final String key) {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 缓存Map
+     *
+     * @param key
+     * @param dataMap
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     * 获得缓存的Map
+     *
+     * @param key
+     * @return
+     */
+    public <T> Map<String, T> getCacheMap(final String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key   Redis键
+     * @param hKey  Hash键
+     * @param value 值
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key  Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey) {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+    /**
+     * 获取多个Hash中的数据
+     *
+     * @param key   Redis键
+     * @param hKeys Hash键集合
+     * @return Hash对象集合
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+    /**
+     * 删除Hash中的某条数据
+     *
+     * @param key  Redis键
+     * @param hKey Hash键
+     * @return 是否成功
+     */
+    public boolean deleteCacheMapValue(final String key, final String hKey) {
+        return redisTemplate.opsForHash().delete(key, hKey) > 0;
+    }
+
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param pattern 字符串前缀
+     * @return 对象列表
+     */
+    public Collection<String> keys(final String pattern) {
+        return redisTemplate.keys(pattern);
+    }
+
+    /**
+     * 是否存在key
+     *
+     * @param key 缓存key
+     * @return true:存在key ;false:key不存在或者已过期
+     */
+    public boolean containsKey(String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+
+    /**
+     * 递增
+     *
+     * @param key   键
+     * @param delta 要增加几(大于0)
+     * @return
+     */
+    public long incr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递增因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+
+    /**
+     * redis 计数器自增
+     *
+     * @param key      key
+     * @param liveTime 过期时间,null不设置过期时间
+     * @return 自增数
+     */
+    public Long incr2(String key, long liveTime) {
+        RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
+        Long increment = entityIdCounter.getAndIncrement();
+
+        if (increment == 0 && liveTime > 0) {//初始设置过期时间
+            entityIdCounter.expire(liveTime, TimeUnit.HOURS);
+        }
+
+        return increment;
+    }
+
+    /**
+     * 将数据放入set缓存
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sAdd(String key, Object... values) {
+        try {
+            return redisTemplate.opsForSet().add(key, values);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 将set数据放入缓存
+     *
+     * @param key    键
+     * @param time   时间(秒)
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSetAndTime(String key, long time, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().add(key, values);
+            if (time > 0) expire(key, time);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 移除set集合值为value的
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 移除的个数
+     */
+    public long setRemove(String key, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().remove(key, values);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 添加一个元素, zset与set最大的区别就是每个元素都有一个score,因此有个排序的辅助功能;  zadd
+     *
+     * @param key   键
+     * @param value 值
+     * @param score 分数
+     */
+    public boolean zSetAdd(String key, String value, double score) {
+        try {
+            Boolean aBoolean = stringRedisTemplate.opsForZSet().add(key, value, score);
+            return BooleanUtils.isTrue(aBoolean);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 移除一个zset有序集合的key的一个或者多个值
+     * zrem key member [member ...] :移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。当 key 存在但不是有序集类型时,返回一个错误。
+     *
+     * @param key    集合的键key
+     * @param values 需要移除的value
+     * @return
+     */
+    public boolean zRem(String key, Object... values) {
+        try {
+            Long aLong = stringRedisTemplate.opsForZSet().remove(key, values);
+            return aLong != null ? true : false;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。
+     *
+     * @param key   String
+     * @param start double 最小score
+     * @param end   double 最大score
+     */
+    public Long zRemBySocre(String key, double start, double end) {
+        try {
+            return stringRedisTemplate.opsForZSet().removeRangeByScore(key, start, end);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 判断value在zset中的排名  zrank命令
+     *
+     * @param key   键
+     * @param value 值
+     * @return score 越小排名越高;
+     */
+    public Long zRank(String key, String value) {
+        try {
+            return stringRedisTemplate.opsForZSet().rank(key, value);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 查询zSet集合中指定顺序的值, 0 -1 表示获取全部的集合内容  zrange
+     *
+     * @param key   键
+     * @param start 开始
+     * @param end   结束
+     * @return 返回有序的集合,score小的在前面
+     */
+    public Set<String> zRange(String key, int start, int end) {
+        try {
+            return stringRedisTemplate.opsForZSet().range(key, start, end);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。
+     * 有序集成员按 score 值递增(从小到大)次序排列。
+     *
+     * @param key   String
+     * @param start double 最小score
+     * @param end   double 最大score
+     */
+    public Set<String> zRangeByScore(String key, double start, double end) {
+        try {
+            return stringRedisTemplate.opsForZSet().rangeByScore(key, start, end);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 返回set集合的长度
+     *
+     * @param key
+     * @return
+     */
+    public Long zSize(String key) {
+        try {
+            return stringRedisTemplate.opsForZSet().zCard(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 根据前缀获取所有的key
+     * 例如:pro_*
+     */
+    public Set<String> getListKeyByPrefix(String prefix) {
+        Set<String> keys = redisTemplate.keys(prefix.concat("*"));
+        return keys;
+    }
+
+    /**
+     * 匹配获取键值对,ScanOptions.NONE为获取全部键对
+     *
+     * @param key
+     * @param options
+     * @return
+     */
+    public Cursor<Map.Entry<Object, Object>> hashScan(String key, ScanOptions options) {
+        return redisTemplate.opsForHash().scan(key, options);
+    }
+
+    /**
+     * 获取所有键值对集合
+     *
+     * @param key
+     */
+    public Map hashEntity(String key) {
+        return redisTemplate.boundHashOps(key).entries();
+    }
+
+    /**
+     * 以map集合的形式添加键值对
+     *
+     * @param key
+     * @param maps
+     */
+    public void hashPutAll(String key, Map<String, String> maps) {
+        redisTemplate.opsForHash().putAll(key, maps);
+    }
+
+    /**
+     * 以map集合的形式添加键值对
+     *
+     * @param key
+     * @param maps
+     */
+    public void hashPutAllObj(String key, Map<String, Object> maps) {
+        redisTemplate.opsForHash().putAll(key, maps);
+    }
+
+    /**
+     * 批量获取设备物模型值
+     *
+     * @param keys          键的集合
+     * @param hkeyCondition 筛选字段
+     * @return
+     */
+    public Map<String, Map> hashGetAllByKeys(Set<String> keys, String hkeyCondition) {
+        return (Map<String, Map>) redisTemplate.execute((RedisCallback) con -> {
+            Iterator<String> it = keys.iterator();
+            Map<String, Map> mapList = new HashMap<>();
+            while (it.hasNext()) {
+                String key = it.next();
+                Map<byte[], byte[]> result = con.hGetAll(key.getBytes());
+                Map ans;
+                if (CollectionUtils.isEmpty(result)) {
+                    return new HashMap<>(0);
+                }
+                ans = new HashMap<>(result.size());
+                for (Map.Entry entry : result.entrySet()) {
+                    String field = new String((byte[]) entry.getKey());
+                    if (!"".equals(hkeyCondition)) {
+                        if (field.endsWith(hkeyCondition)) {
+                            ans.put(new String((byte[]) entry.getKey()), new String((byte[]) entry.getValue()));
+                        }
+                    } else {
+                        ans.put(new String((byte[]) entry.getKey()), new String((byte[]) entry.getValue()));
+                    }
+                }
+                mapList.put(key, ans);
+            }
+            return mapList;
+        });
+    }
+
+    /**
+     * 批量获取匹配触发器的物模型值(定时告警使用)
+     *
+     * @param keys         键的集合
+     * @param operator     操作符
+     * @param triggerValue 触发的值
+     * @return
+     */
+    public Map<String, String> hashGetAllMatchByKeys(Set<String> keys, String operator, String id, String triggerValue) {
+        return (Map<String, String>) redisTemplate.execute((RedisCallback) con -> {
+            Iterator<String> it = keys.iterator();
+            Map<String, String> mapList = new HashMap<>();
+            while (it.hasNext()) {
+                String key = it.next();
+                Map<byte[], byte[]> result = con.hGetAll(key.getBytes());
+                if (CollectionUtils.isEmpty(result)) {
+                    return new HashMap<>(0);
+                }
+                for (Map.Entry entry : result.entrySet()) {
+                    String field = new String((byte[]) entry.getKey());
+                    // 获取物模型值并且匹配规则,获取值的类型和匹配规则后续还要仔细测了然后优化
+                    if (field.equals(id) || field.equals(id + "#V")) {
+                        String valueStr = new String((byte[]) entry.getValue());
+                        JSONObject jsonObject = JSONObject.parseObject((String) JSON.parse(valueStr));
+                        String value = (String) jsonObject.get("value");
+                        if (ruleResult(operator, value, triggerValue)) {
+                            mapList.put(key, value);
+                        }
+                    }
+                }
+            }
+            return mapList;
+        });
+    }
+
+    /**
+     * 根据key集合获取字符串
+     *
+     * @param keys 键的集合
+     * @return
+     */
+    public Map<String, String> getStringAllByKeys(Set<String> keys) {
+        return (Map<String, String>) redisTemplate.execute((RedisCallback) con -> {
+            Iterator<String> it = keys.iterator();
+            Map<String, String> mapList = new HashMap<>();
+            while (it.hasNext()) {
+                String key = it.next();
+                byte[] result = con.get(key.getBytes());
+                if (result == null) {
+                    return new HashMap<>(0);
+                }
+                String ans = new String((byte[]) result);
+                mapList.put(key, ans);
+            }
+            return mapList;
+        });
+    }
+
+    /**
+     * 根据条件返回所有键
+     *
+     * @param query
+     * @return
+     */
+    public List<Object> scan(String query) {
+        Set<String> keys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
+            Set<String> keysTmp = new HashSet<>();
+            Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(query).count(1000).build());
+            while (cursor.hasNext()) {
+                keysTmp.add(new String(cursor.next()));
+            }
+            return keysTmp;
+        });
+        return new ArrayList<>(keys);
+    }
+
+    /**
+     * 规则匹配结果
+     *
+     * @param operator     操作符
+     * @param value        上报的值
+     * @param triggerValue 触发器的值
+     * @return
+     */
+    private boolean ruleResult(String operator, String value, String triggerValue) {
+        boolean result = false;
+        if ("".equals(value)) {
+            return result;
+        }
+        // 操作符比较
+        switch (operator) {
+            case "=":
+                result = value.equals(triggerValue);
+                break;
+            case "!=":
+                result = !value.equals(triggerValue);
+                break;
+            case ">":
+                if (isNumeric(value) && isNumeric(triggerValue)) {
+                    result = Double.parseDouble(value) > Double.parseDouble(triggerValue);
+                }
+                break;
+            case "<":
+                if (isNumeric(value) && isNumeric(triggerValue)) {
+                    result = Double.parseDouble(value) < Double.parseDouble(triggerValue);
+                }
+                break;
+            case ">=":
+                if (isNumeric(value) && isNumeric(triggerValue)) {
+                    result = Double.parseDouble(value) >= Double.parseDouble(triggerValue);
+                }
+                break;
+            case "<=":
+                if (isNumeric(value) && isNumeric(triggerValue)) {
+                    result = Double.parseDouble(value) <= Double.parseDouble(triggerValue);
+                }
+                break;
+            case "contain":
+                result = value.contains(triggerValue);
+                break;
+            case "notcontain":
+                result = !value.contains(triggerValue);
+                break;
+            default:
+                break;
+        }
+        return result;
+    }
+
+    /**
+     * 判断字符串是否为整数或小数
+     */
+    private boolean isNumeric(String str) {
+        Pattern pattern = compile("[0-9]*\\.?[0-9]+");
+        Matcher isNum = pattern.matcher(str);
+        if (!isNum.matches()) {
+            return false;
+        }
+        return true;
+    }
+
+    public void publish(Object message, String channel) {
+        try {
+            redisTemplate.convertAndSend(channel, message);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key   Redis键
+     * @param hKey  Hash键
+     * @param value 值
+     */
+    public <T> void setHashValue(final String key, final String hKey, final T value) {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+
+    /**
+     * 删除Hash中的数据
+     *
+     * @param key
+     * @param hkey
+     */
+    public void delHashValue(final String key, final String hkey) {
+        HashOperations hashOperations = redisTemplate.opsForHash();
+        hashOperations.delete(key, hkey);
+    }
+
+}

+ 99 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisKeyBuilder.java

@@ -0,0 +1,99 @@
+package com.fastbee.common.core.redis;
+
+import com.fastbee.common.constant.FastBeeConstant;
+
+/**
+ * 缓存key生成器
+ *
+ * @author bill
+ */
+public class RedisKeyBuilder {
+
+    /**设备在线列表缓存key*/
+    public static String buildDeviceOnlineListKey(){
+       return FastBeeConstant.REDIS.DEVICE_ONLINE_LIST;
+    }
+
+    /**设备实时数据key*/
+    public static String buildDeviceRtCacheKey(String serialNumber){
+        return FastBeeConstant.REDIS.DEVICE_RUNTIME_DATA + serialNumber;
+    }
+
+    /**
+     * 设备通讯协议参数
+     */
+    public static String buildDeviceRtParamsKey(String serialNumber){
+        return FastBeeConstant.REDIS.DEVICE_PROTOCOL_PARAM + serialNumber;
+    }
+
+    /**固件版本缓存key*/
+    public static String buildFirmwareCachedKey(Long firmwareId){
+       return FastBeeConstant.REDIS.FIRMWARE_VERSION + firmwareId;
+    }
+
+    /**属性读取回调缓存key*/
+    public static String buildPropReadCacheKey(String serialNumber){
+        return FastBeeConstant.REDIS.PROP_READ_STORE + serialNumber;
+    }
+
+    /**
+     * 物模型值命名缓存key
+     * Key:TSLV:{productId}_{deviceNumber}   HKey:{identity#V/identity#S/identity#M/identity#N}
+     */
+    public static String buildTSLVCacheKey(Long productId,String serialNumber){
+        return FastBeeConstant.REDIS.DEVICE_PRE_KEY + productId + "_" + serialNumber.toUpperCase();
+    }
+
+    /**
+     * 物模型缓存key
+     * 物模型命名空间:Key:TSL:{productId}  hkey: identity  value: thingsModel
+     */
+    public static String buildTSLCacheKey(Long productId){
+        return FastBeeConstant.REDIS.TSL_PRE_KEY + productId;
+    }
+
+    /**录像缓存key*/
+    public static String buildSipRecordinfoCacheKey(String recordKey){
+        return FastBeeConstant.REDIS.RECORDINFO_KEY + recordKey;
+    }
+
+    /**设备id缓存key*/
+    public static String buildSipDeviceidCacheKey(String id){
+        return FastBeeConstant.REDIS.DEVICEID_KEY + id;
+    }
+    /**ipCSEQ缓存key*/
+    public static String buildStreamCacheKey(String steamId){
+        return FastBeeConstant.REDIS.STREAM_KEY + steamId;
+    }
+
+    public static String buildStreamCacheKey(String deviceId, String channelId, String stream, String ssrc){
+        return FastBeeConstant.REDIS.STREAM_KEY + deviceId + ":" + channelId + ":" + stream + ":" + ssrc;
+    }
+
+    public static String buildInviteCacheKey(String type, String deviceId, String channelId, String stream, String ssrc){
+        return FastBeeConstant.REDIS.INVITE_KEY + type + ":"+ deviceId + ":" + channelId + ":" + stream + ":" + ssrc;
+    }
+
+    /**ipCSEQ缓存key*/
+    public static String buildSipCSEQCacheKey(String CSEQ){
+        return FastBeeConstant.REDIS.SIP_CSEQ_PREFIX + CSEQ;
+    }
+
+    /**modbus指令缓存可以*/
+    public static String buildModbusCacheKey(Long productId){
+        return FastBeeConstant.REDIS.POLL_MODBUS_KEY + productId;
+    }
+
+    /*缓存设备下发指令消息ID*/
+    public static String buildDownMessageIdCacheKey(String serialNumber){
+        return FastBeeConstant.REDIS.DEVICE_MESSAGE_ID;
+    }
+
+    /**
+     * 缓存产品id,设备编号,协议编号
+     */
+    public static String buildDeviceMsgCacheKey(String serialNumber){
+        return FastBeeConstant.REDIS.DEVICE_MSG + serialNumber;
+    }
+
+}

+ 113 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisKeyDefine.java

@@ -0,0 +1,113 @@
+package com.fastbee.common.core.redis;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+import java.time.Duration;
+
+/**
+ * Redis Key 定义类
+ *
+ * @author fastbee
+ */
+@Data
+public class RedisKeyDefine {
+
+    @Getter
+    @AllArgsConstructor
+    public enum KeyTypeEnum {
+
+        STRING("String"),
+        LIST("List"),
+        HASH("Hash"),
+        SET("Set"),
+        ZSET("Sorted Set"),
+        STREAM("Stream"),
+        PUBSUB("Pub/Sub");
+
+        /**
+         * 类型
+         */
+        @JsonValue
+        private final String type;
+
+    }
+
+    @Getter
+    @AllArgsConstructor
+    public enum TimeoutTypeEnum {
+
+        FOREVER(1), // 永不超时
+        DYNAMIC(2), // 动态超时
+        FIXED(3); // 固定超时
+
+        /**
+         * 类型
+         */
+        @JsonValue
+        private final Integer type;
+
+    }
+
+    /**
+     * Key 模板
+     */
+    private final String keyTemplate;
+    /**
+     * Key 类型的枚举
+     */
+    private final KeyTypeEnum keyType;
+    /**
+     * Value 类型
+     *
+     * 如果是使用分布式锁,设置为 {@link java.util.concurrent.locks.Lock} 类型
+     */
+    private final Class<?> valueType;
+    /**
+     * 超时类型
+     */
+    private final TimeoutTypeEnum timeoutType;
+    /**
+     * 过期时间
+     */
+    private final Duration timeout;
+    /**
+     * 备注
+     */
+    private final String memo;
+
+    private RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType,
+                           TimeoutTypeEnum timeoutType, Duration timeout) {
+        this.memo = memo;
+        this.keyTemplate = keyTemplate;
+        this.keyType = keyType;
+        this.valueType = valueType;
+        this.timeout = timeout;
+        this.timeoutType = timeoutType;
+        // 添加注册表
+        RedisKeyRegistry.add(this);
+    }
+
+    public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
+        this(memo, keyTemplate, keyType, valueType, TimeoutTypeEnum.FIXED, timeout);
+    }
+
+    public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
+        this(memo, keyTemplate, keyType, valueType, timeoutType, Duration.ZERO);
+    }
+
+    /**
+     * 格式化 Key
+     *
+     * 注意,内部采用 {@link String#format(String, Object...)} 实现
+     *
+     * @param args 格式化的参数
+     * @return Key
+     */
+    public String formatKey(Object... args) {
+        return String.format(keyTemplate, args);
+    }
+
+}

+ 28 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/redis/RedisKeyRegistry.java

@@ -0,0 +1,28 @@
+package com.fastbee.common.core.redis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link RedisKeyDefine} 注册表
+ */
+public class RedisKeyRegistry {
+
+    /**
+     * Redis RedisKeyDefine 数组
+     */
+    private static final List<RedisKeyDefine> DEFINES = new ArrayList<>();
+
+    public static void add(RedisKeyDefine define) {
+        DEFINES.add(define);
+    }
+
+    public static List<RedisKeyDefine> list() {
+        return DEFINES;
+    }
+
+    public static int size() {
+        return DEFINES.size();
+    }
+
+}

+ 86 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/CharsetKit.java

@@ -0,0 +1,86 @@
+package com.fastbee.common.core.text;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import com.fastbee.common.utils.StringUtils;
+
+/**
+ * 字符集工具类
+ * 
+ * @author ruoyi
+ */
+public class CharsetKit
+{
+    /** ISO-8859-1 */
+    public static final String ISO_8859_1 = "ISO-8859-1";
+    /** UTF-8 */
+    public static final String UTF_8 = "UTF-8";
+    /** GBK */
+    public static final String GBK = "GBK";
+
+    /** ISO-8859-1 */
+    public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
+    /** UTF-8 */
+    public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
+    /** GBK */
+    public static final Charset CHARSET_GBK = Charset.forName(GBK);
+
+    /**
+     * 转换为Charset对象
+     * 
+     * @param charset 字符集,为空则返回默认字符集
+     * @return Charset
+     */
+    public static Charset charset(String charset)
+    {
+        return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
+    }
+
+    /**
+     * 转换字符串的字符集编码
+     * 
+     * @param source 字符串
+     * @param srcCharset 源字符集,默认ISO-8859-1
+     * @param destCharset 目标字符集,默认UTF-8
+     * @return 转换后的字符集
+     */
+    public static String convert(String source, String srcCharset, String destCharset)
+    {
+        return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
+    }
+
+    /**
+     * 转换字符串的字符集编码
+     * 
+     * @param source 字符串
+     * @param srcCharset 源字符集,默认ISO-8859-1
+     * @param destCharset 目标字符集,默认UTF-8
+     * @return 转换后的字符集
+     */
+    public static String convert(String source, Charset srcCharset, Charset destCharset)
+    {
+        if (null == srcCharset)
+        {
+            srcCharset = StandardCharsets.ISO_8859_1;
+        }
+
+        if (null == destCharset)
+        {
+            destCharset = StandardCharsets.UTF_8;
+        }
+
+        if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
+        {
+            return source;
+        }
+        return new String(source.getBytes(srcCharset), destCharset);
+    }
+
+    /**
+     * @return 系统字符集编码
+     */
+    public static String systemCharset()
+    {
+        return Charset.defaultCharset().name();
+    }
+}

+ 1000 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/Convert.java

@@ -0,0 +1,1000 @@
+package com.fastbee.common.core.text;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.text.NumberFormat;
+import java.util.Set;
+import com.fastbee.common.utils.StringUtils;
+import org.apache.commons.lang3.ArrayUtils;
+
+/**
+ * 类型转换器
+ *
+ * @author ruoyi
+ */
+public class Convert
+{
+    /**
+     * 转换为字符串<br>
+     * 如果给定的值为null,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static String toStr(Object value, String defaultValue)
+    {
+        if (null == value)
+        {
+            return defaultValue;
+        }
+        if (value instanceof String)
+        {
+            return (String) value;
+        }
+        return value.toString();
+    }
+
+    /**
+     * 转换为字符串<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static String toStr(Object value)
+    {
+        return toStr(value, null);
+    }
+
+    /**
+     * 转换为字符<br>
+     * 如果给定的值为null,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Character toChar(Object value, Character defaultValue)
+    {
+        if (null == value)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Character)
+        {
+            return (Character) value;
+        }
+
+        final String valueStr = toStr(value, null);
+        return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
+    }
+
+    /**
+     * 转换为字符<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Character toChar(Object value)
+    {
+        return toChar(value, null);
+    }
+
+    /**
+     * 转换为byte<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Byte toByte(Object value, Byte defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Byte)
+        {
+            return (Byte) value;
+        }
+        if (value instanceof Number)
+        {
+            return ((Number) value).byteValue();
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return Byte.parseByte(valueStr);
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为byte<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Byte toByte(Object value)
+    {
+        return toByte(value, null);
+    }
+
+    /**
+     * 转换为Short<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Short toShort(Object value, Short defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Short)
+        {
+            return (Short) value;
+        }
+        if (value instanceof Number)
+        {
+            return ((Number) value).shortValue();
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return Short.parseShort(valueStr.trim());
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为Short<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Short toShort(Object value)
+    {
+        return toShort(value, null);
+    }
+
+    /**
+     * 转换为Number<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Number toNumber(Object value, Number defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Number)
+        {
+            return (Number) value;
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return NumberFormat.getInstance().parse(valueStr);
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为Number<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Number toNumber(Object value)
+    {
+        return toNumber(value, null);
+    }
+
+    /**
+     * 转换为int<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Integer toInt(Object value, Integer defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Integer)
+        {
+            return (Integer) value;
+        }
+        if (value instanceof Number)
+        {
+            return ((Number) value).intValue();
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return Integer.parseInt(valueStr.trim());
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为int<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Integer toInt(Object value)
+    {
+        return toInt(value, null);
+    }
+
+    /**
+     * 转换为Integer数组<br>
+     *
+     * @param str 被转换的值
+     * @return 结果
+     */
+    public static Integer[] toIntArray(String str)
+    {
+        return toIntArray(",", str);
+    }
+
+    /**
+     * 转换为Long数组<br>
+     *
+     * @param str 被转换的值
+     * @return 结果
+     */
+    public static Long[] toLongArray(String str)
+    {
+        return toLongArray(",", str);
+    }
+
+    /**
+     * 转换为Integer数组<br>
+     *
+     * @param split 分隔符
+     * @param split 被转换的值
+     * @return 结果
+     */
+    public static Integer[] toIntArray(String split, String str)
+    {
+        if (StringUtils.isEmpty(str))
+        {
+            return new Integer[] {};
+        }
+        String[] arr = str.split(split);
+        final Integer[] ints = new Integer[arr.length];
+        for (int i = 0; i < arr.length; i++)
+        {
+            final Integer v = toInt(arr[i], 0);
+            ints[i] = v;
+        }
+        return ints;
+    }
+
+    /**
+     * 转换为Long数组<br>
+     *
+     * @param split 分隔符
+     * @param str 被转换的值
+     * @return 结果
+     */
+    public static Long[] toLongArray(String split, String str)
+    {
+        if (StringUtils.isEmpty(str))
+        {
+            return new Long[] {};
+        }
+        String[] arr = str.split(split);
+        final Long[] longs = new Long[arr.length];
+        for (int i = 0; i < arr.length; i++)
+        {
+            final Long v = toLong(arr[i], null);
+            longs[i] = v;
+        }
+        return longs;
+    }
+
+    /**
+     * 转换为String数组<br>
+     *
+     * @param str 被转换的值
+     * @return 结果
+     */
+    public static String[] toStrArray(String str)
+    {
+        return toStrArray(",", str);
+    }
+
+    /**
+     * 转换为String数组<br>
+     *
+     * @param split 分隔符
+     * @param split 被转换的值
+     * @return 结果
+     */
+    public static String[] toStrArray(String split, String str)
+    {
+        return str.split(split);
+    }
+
+    /**
+     * 转换为long<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Long toLong(Object value, Long defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Long)
+        {
+            return (Long) value;
+        }
+        if (value instanceof Number)
+        {
+            return ((Number) value).longValue();
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            // 支持科学计数法
+            return new BigDecimal(valueStr.trim()).longValue();
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为long<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Long toLong(Object value)
+    {
+        return toLong(value, null);
+    }
+
+    /**
+     * 转换为double<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Double toDouble(Object value, Double defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Double)
+        {
+            return (Double) value;
+        }
+        if (value instanceof Number)
+        {
+            return ((Number) value).doubleValue();
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            // 支持科学计数法
+            return new BigDecimal(valueStr.trim()).doubleValue();
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为double<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Double toDouble(Object value)
+    {
+        return toDouble(value, null);
+    }
+
+    /**
+     * 转换为Float<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Float toFloat(Object value, Float defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Float)
+        {
+            return (Float) value;
+        }
+        if (value instanceof Number)
+        {
+            return ((Number) value).floatValue();
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return Float.parseFloat(valueStr.trim());
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为Float<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Float toFloat(Object value)
+    {
+        return toFloat(value, null);
+    }
+
+    /**
+     * 转换为boolean<br>
+     * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static Boolean toBool(Object value, Boolean defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof Boolean)
+        {
+            return (Boolean) value;
+        }
+        String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        valueStr = valueStr.trim().toLowerCase();
+        switch (valueStr)
+        {
+            case "true":
+            case "yes":
+            case "ok":
+            case "1":
+                return true;
+            case "false":
+            case "no":
+            case "0":
+                return false;
+            default:
+                return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为boolean<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static Boolean toBool(Object value)
+    {
+        return toBool(value, null);
+    }
+
+    /**
+     * 转换为Enum对象<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     *
+     * @param clazz Enum的Class
+     * @param value 值
+     * @param defaultValue 默认值
+     * @return Enum
+     */
+    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (clazz.isAssignableFrom(value.getClass()))
+        {
+            @SuppressWarnings("unchecked")
+            E myE = (E) value;
+            return myE;
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return Enum.valueOf(clazz, valueStr);
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为Enum对象<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
+     *
+     * @param clazz Enum的Class
+     * @param value 值
+     * @return Enum
+     */
+    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value)
+    {
+        return toEnum(clazz, value, null);
+    }
+
+    /**
+     * 转换为BigInteger<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof BigInteger)
+        {
+            return (BigInteger) value;
+        }
+        if (value instanceof Long)
+        {
+            return BigInteger.valueOf((Long) value);
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return new BigInteger(valueStr);
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为BigInteger<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static BigInteger toBigInteger(Object value)
+    {
+        return toBigInteger(value, null);
+    }
+
+    /**
+     * 转换为BigDecimal<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        if (value instanceof BigDecimal)
+        {
+            return (BigDecimal) value;
+        }
+        if (value instanceof Long)
+        {
+            return new BigDecimal((Long) value);
+        }
+        if (value instanceof Double)
+        {
+            return BigDecimal.valueOf((Double) value);
+        }
+        if (value instanceof Integer)
+        {
+            return new BigDecimal((Integer) value);
+        }
+        final String valueStr = toStr(value, null);
+        if (StringUtils.isEmpty(valueStr))
+        {
+            return defaultValue;
+        }
+        try
+        {
+            return new BigDecimal(valueStr);
+        }
+        catch (Exception e)
+        {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * 转换为BigDecimal<br>
+     * 如果给定的值为空,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static BigDecimal toBigDecimal(Object value)
+    {
+        return toBigDecimal(value, null);
+    }
+
+    /**
+     * 将对象转为字符串<br>
+     * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
+     *
+     * @param obj 对象
+     * @return 字符串
+     */
+    public static String utf8Str(Object obj)
+    {
+        return str(obj, CharsetKit.CHARSET_UTF_8);
+    }
+
+    /**
+     * 将对象转为字符串<br>
+     * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
+     *
+     * @param obj 对象
+     * @param charsetName 字符集
+     * @return 字符串
+     */
+    public static String str(Object obj, String charsetName)
+    {
+        return str(obj, Charset.forName(charsetName));
+    }
+
+    /**
+     * 将对象转为字符串<br>
+     * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
+     *
+     * @param obj 对象
+     * @param charset 字符集
+     * @return 字符串
+     */
+    public static String str(Object obj, Charset charset)
+    {
+        if (null == obj)
+        {
+            return null;
+        }
+
+        if (obj instanceof String)
+        {
+            return (String) obj;
+        }
+        else if (obj instanceof byte[])
+        {
+            return str((byte[]) obj, charset);
+        }
+        else if (obj instanceof Byte[])
+        {
+            byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj);
+            return str(bytes, charset);
+        }
+        else if (obj instanceof ByteBuffer)
+        {
+            return str((ByteBuffer) obj, charset);
+        }
+        return obj.toString();
+    }
+
+    /**
+     * 将byte数组转为字符串
+     *
+     * @param bytes byte数组
+     * @param charset 字符集
+     * @return 字符串
+     */
+    public static String str(byte[] bytes, String charset)
+    {
+        return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
+    }
+
+    /**
+     * 解码字节码
+     *
+     * @param data 字符串
+     * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+     * @return 解码后的字符串
+     */
+    public static String str(byte[] data, Charset charset)
+    {
+        if (data == null)
+        {
+            return null;
+        }
+
+        if (null == charset)
+        {
+            return new String(data);
+        }
+        return new String(data, charset);
+    }
+
+    /**
+     * 将编码的byteBuffer数据转换为字符串
+     *
+     * @param data 数据
+     * @param charset 字符集,如果为空使用当前系统字符集
+     * @return 字符串
+     */
+    public static String str(ByteBuffer data, String charset)
+    {
+        if (data == null)
+        {
+            return null;
+        }
+
+        return str(data, Charset.forName(charset));
+    }
+
+    /**
+     * 将编码的byteBuffer数据转换为字符串
+     *
+     * @param data 数据
+     * @param charset 字符集,如果为空使用当前系统字符集
+     * @return 字符串
+     */
+    public static String str(ByteBuffer data, Charset charset)
+    {
+        if (null == charset)
+        {
+            charset = Charset.defaultCharset();
+        }
+        return charset.decode(data).toString();
+    }
+
+    // ----------------------------------------------------------------------- 全角半角转换
+    /**
+     * 半角转全角
+     *
+     * @param input String.
+     * @return 全角字符串.
+     */
+    public static String toSBC(String input)
+    {
+        return toSBC(input, null);
+    }
+
+    /**
+     * 半角转全角
+     *
+     * @param input String
+     * @param notConvertSet 不替换的字符集合
+     * @return 全角字符串.
+     */
+    public static String toSBC(String input, Set<Character> notConvertSet)
+    {
+        char[] c = input.toCharArray();
+        for (int i = 0; i < c.length; i++)
+        {
+            if (null != notConvertSet && notConvertSet.contains(c[i]))
+            {
+                // 跳过不替换的字符
+                continue;
+            }
+
+            if (c[i] == ' ')
+            {
+                c[i] = '\u3000';
+            }
+            else if (c[i] < '\177')
+            {
+                c[i] = (char) (c[i] + 65248);
+
+            }
+        }
+        return new String(c);
+    }
+
+    /**
+     * 全角转半角
+     *
+     * @param input String.
+     * @return 半角字符串
+     */
+    public static String toDBC(String input)
+    {
+        return toDBC(input, null);
+    }
+
+    /**
+     * 替换全角为半角
+     *
+     * @param text 文本
+     * @param notConvertSet 不替换的字符集合
+     * @return 替换后的字符
+     */
+    public static String toDBC(String text, Set<Character> notConvertSet)
+    {
+        char[] c = text.toCharArray();
+        for (int i = 0; i < c.length; i++)
+        {
+            if (null != notConvertSet && notConvertSet.contains(c[i]))
+            {
+                // 跳过不替换的字符
+                continue;
+            }
+
+            if (c[i] == '\u3000')
+            {
+                c[i] = ' ';
+            }
+            else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
+            {
+                c[i] = (char) (c[i] - 65248);
+            }
+        }
+        String returnString = new String(c);
+
+        return returnString;
+    }
+
+    /**
+     * 数字金额大写转换 先写个完整的然后将如零拾替换成零
+     *
+     * @param n 数字
+     * @return 中文大写数字
+     */
+    public static String digitUppercase(double n)
+    {
+        String[] fraction = { "角", "分" };
+        String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
+        String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };
+
+        String head = n < 0 ? "负" : "";
+        n = Math.abs(n);
+
+        String s = "";
+        for (int i = 0; i < fraction.length; i++)
+        {
+            s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
+        }
+        if (s.length() < 1)
+        {
+            s = "整";
+        }
+        int integerPart = (int) Math.floor(n);
+
+        for (int i = 0; i < unit[0].length && integerPart > 0; i++)
+        {
+            String p = "";
+            for (int j = 0; j < unit[1].length && n > 0; j++)
+            {
+                p = digit[integerPart % 10] + unit[1][j] + p;
+                integerPart = integerPart / 10;
+            }
+            s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
+        }
+        return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
+    }
+}

+ 13 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/IntArrayValuable.java

@@ -0,0 +1,13 @@
+package com.fastbee.common.core.text;
+
+/**
+ * 可生成 Int 数组的接口
+ */
+public interface IntArrayValuable {
+
+    /**
+     * @return int 数组
+     */
+    int[] array();
+
+}

+ 20 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/KeyValue.java

@@ -0,0 +1,20 @@
+package com.fastbee.common.core.text;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Key Value 的键值对
+ *
+ * @author 芋道源码
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class KeyValue<K, V> {
+
+    private K key;
+    private V value;
+
+}

+ 92 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/text/StrFormatter.java

@@ -0,0 +1,92 @@
+package com.fastbee.common.core.text;
+
+import com.fastbee.common.utils.StringUtils;
+
+/**
+ * 字符串格式化
+ * 
+ * @author ruoyi
+ */
+public class StrFormatter
+{
+    public static final String EMPTY_JSON = "{}";
+    public static final char C_BACKSLASH = '\\';
+    public static final char C_DELIM_START = '{';
+    public static final char C_DELIM_END = '}';
+
+    /**
+     * 格式化字符串<br>
+     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
+     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
+     * 例:<br>
+     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
+     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
+     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
+     * 
+     * @param strPattern 字符串模板
+     * @param argArray 参数列表
+     * @return 结果
+     */
+    public static String format(final String strPattern, final Object... argArray)
+    {
+        if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
+        {
+            return strPattern;
+        }
+        final int strPatternLength = strPattern.length();
+
+        // 初始化定义好的长度以获得更好的性能
+        StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
+
+        int handledPosition = 0;
+        int delimIndex;// 占位符所在位置
+        for (int argIndex = 0; argIndex < argArray.length; argIndex++)
+        {
+            delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
+            if (delimIndex == -1)
+            {
+                if (handledPosition == 0)
+                {
+                    return strPattern;
+                }
+                else
+                { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
+                    sbuf.append(strPattern, handledPosition, strPatternLength);
+                    return sbuf.toString();
+                }
+            }
+            else
+            {
+                if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
+                {
+                    if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
+                    {
+                        // 转义符之前还有一个转义符,占位符依旧有效
+                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
+                        sbuf.append(Convert.utf8Str(argArray[argIndex]));
+                        handledPosition = delimIndex + 2;
+                    }
+                    else
+                    {
+                        // 占位符被转义
+                        argIndex--;
+                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
+                        sbuf.append(C_DELIM_START);
+                        handledPosition = delimIndex + 1;
+                    }
+                }
+                else
+                {
+                    // 正常占位符
+                    sbuf.append(strPattern, handledPosition, delimIndex);
+                    sbuf.append(Convert.utf8Str(argArray[argIndex]));
+                    handledPosition = delimIndex + 2;
+                }
+            }
+        }
+        // 加入最后一个占位符后所有的字符
+        sbuf.append(strPattern, handledPosition, strPattern.length());
+
+        return sbuf.toString();
+    }
+}

+ 44 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/NeuronModel.java

@@ -0,0 +1,44 @@
+package com.fastbee.common.core.thingsModel;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Neuron-JSON格式协议
+ * @author gsb
+ * @date 2023/5/31 16:36
+ */
+@Data
+public class NeuronModel {
+
+    /**
+     * 产品节点
+     */
+    private String node;
+
+    /**
+     * 网关编号
+     */
+    private String group;
+    /**
+     * 上报时间
+     */
+    private Date timestamp;
+
+    /**
+     * 上报JSON
+     */
+    private JSONObject values;
+    /**
+     * 错误集合
+     */
+    private JSONObject errors;
+    /**
+     * 上报属性值集合
+     */
+    private List<ThingsModelSimpleItem> items;
+
+}

+ 38 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/SceneThingsModelItem.java

@@ -0,0 +1,38 @@
+package com.fastbee.common.core.thingsModel;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 物模型值的项
+ *
+ * @author kerwincui
+ * @date 2021-12-16
+ */
+@AllArgsConstructor
+@Builder
+@Data
+public class SceneThingsModelItem
+{
+    /** 物模型唯一标识符 */
+    private String id;
+
+    /** 物模型值 */
+    private String value;
+
+    /** 类型:1=属性, 2=功能,3=事件, 4=设备升级,5=设备上线,6=设备下线 ,*/
+    private int type;
+
+    /** 脚本ID */
+    private String stripId;
+
+    /** 场景ID*/
+    private Long sceneId;
+
+    /** 产品ID */
+    private Long productId;
+
+    /** 设备编号 */
+    private String DeviceNumber;
+}

+ 109 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/ThingsModelSimpleItem.java

@@ -0,0 +1,109 @@
+package com.fastbee.common.core.thingsModel;
+
+import com.fastbee.common.utils.DateUtils;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 物模型值的项
+ *
+ * @author kerwincui
+ * @date 2021-12-16
+ */
+@AllArgsConstructor
+public class ThingsModelSimpleItem
+{
+    /** 物模型唯一标识符 */
+    private String id;
+
+    /** 物模型值 */
+    private String value;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date ts;
+
+    private Integer slaveId;
+
+    /** 备注 **/
+    private String remark;
+
+    private String timestamp;
+
+    private boolean isBit = false;
+
+    public ThingsModelSimpleItem(String id, String value , String remark){
+        this.id=id;
+        this.value=value;
+        this.remark=remark;
+    }
+
+    public ThingsModelSimpleItem(String id, String value ,Integer slaveId, String remark){
+        this.id=id;
+        this.value=value;
+        this.slaveId = slaveId;
+        this.remark=remark;
+    }
+
+    public boolean isBit() {
+        return isBit;
+    }
+
+    public void setBit(boolean bit) {
+        isBit = bit;
+    }
+
+    public Integer getSlaveId() {
+        return slaveId;
+    }
+
+    public void setSlaveId(Integer slaveId) {
+        this.slaveId = slaveId;
+    }
+
+    public Date getTs() {
+        return ts;
+    }
+
+    public void setTs(Date ts) {
+        this.ts = ts  != null ? ts : DateUtils.getNowDate();
+    }
+
+    public ThingsModelSimpleItem(){}
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+}

+ 76 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/core/thingsModel/ThingsModelValuesInput.java

@@ -0,0 +1,76 @@
+package com.fastbee.common.core.thingsModel;
+
+import java.util.List;
+
+/**
+ * 设备输入物模型值参数
+ *
+ * @author kerwincui
+ * @date 2021-12-16
+ */
+public class ThingsModelValuesInput
+{
+    /** 产品ID **/
+    private Long productId;
+
+    private Long deviceId;
+
+    /** 设备ID **/
+    private String deviceNumber;
+
+    /** 设备物模型值的字符串格式 **/
+    private String stringValue;
+
+    /** 设备物模型值的集合 **/
+    private List<ThingsModelSimpleItem> thingsModelSimpleItem;
+
+    private Integer slaveId;
+
+    public Integer getSlaveId() {
+        return slaveId;
+    }
+
+    public void setSlaveId(Integer slaveId) {
+        this.slaveId = slaveId;
+    }
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(Long deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public Long getProductId() {
+        return productId;
+    }
+
+    public void setProductId(Long productId) {
+        this.productId = productId;
+    }
+
+    public String getStringValue() {
+        return stringValue;
+    }
+
+    public void setStringValue(String stringValue) {
+        this.stringValue = stringValue;
+    }
+
+    public String getDeviceNumber() {
+        return deviceNumber;
+    }
+
+    public void setDeviceNumber(String deviceNumber) {
+        this.deviceNumber = deviceNumber;
+    }
+
+    public List<ThingsModelSimpleItem> getThingsModelValueRemarkItem() {
+        return thingsModelSimpleItem;
+    }
+
+    public void setThingsModelValueRemarkItem(List<ThingsModelSimpleItem> thingsModelSimpleItem) {
+        this.thingsModelSimpleItem = thingsModelSimpleItem;
+    }
+}

+ 20 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/BusinessStatus.java

@@ -0,0 +1,20 @@
+package com.fastbee.common.enums;
+
+/**
+ * 操作状态
+ * 
+ * @author ruoyi
+ *
+ */
+public enum BusinessStatus
+{
+    /**
+     * 成功
+     */
+    SUCCESS,
+
+    /**
+     * 失败
+     */
+    FAIL,
+}

+ 59 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/BusinessType.java

@@ -0,0 +1,59 @@
+package com.fastbee.common.enums;
+
+/**
+ * 业务操作类型
+ * 
+ * @author ruoyi
+ */
+public enum BusinessType
+{
+    /**
+     * 其它
+     */
+    OTHER,
+
+    /**
+     * 新增
+     */
+    INSERT,
+
+    /**
+     * 修改
+     */
+    UPDATE,
+
+    /**
+     * 删除
+     */
+    DELETE,
+
+    /**
+     * 授权
+     */
+    GRANT,
+
+    /**
+     * 导出
+     */
+    EXPORT,
+
+    /**
+     * 导入
+     */
+    IMPORT,
+
+    /**
+     * 强退
+     */
+    FORCE,
+
+    /**
+     * 生成代码
+     */
+    GENCODE,
+    
+    /**
+     * 清空数据
+     */
+    CLEAN,
+}

+ 36 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/CommonStatusEnum.java

@@ -0,0 +1,36 @@
+package com.fastbee.common.enums;
+
+import com.fastbee.common.core.text.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 通用状态枚举
+
+ */
+@Getter
+@AllArgsConstructor
+public enum CommonStatusEnum implements IntArrayValuable {
+
+    ENABLE(0, "开启"),
+    DISABLE(1, "关闭");
+
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CommonStatusEnum::getStatus).toArray();
+
+    /**
+     * 状态值
+     */
+    private final Integer status;
+    /**
+     * 状态名
+     */
+    private final String name;
+
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
+
+}

+ 37 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/DataEnum.java

@@ -0,0 +1,37 @@
+package com.fastbee.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author gsb
+ * @date 2023/6/3 14:09
+ */
+@Getter
+@AllArgsConstructor
+public enum DataEnum {
+
+    DECIMAL("decimal", "十进制"),
+    DOUBLE("double", "双精度"),
+    ENUM("enum","枚举"),
+    BOOLEAN("boolean","布尔类型"),
+    INTEGER("integer","整形"),
+    OBJECT("object", "对象"),
+    STRING("string","字符串"),
+    ARRAY("array","数组");
+
+    String type;
+    String msg;
+
+    public static DataEnum convert(String type){
+        for (DataEnum value : DataEnum.values()) {
+            if (Objects.equals(value.type, type)){
+                return value;
+            }
+        }
+        return DataEnum.STRING;
+    }
+
+}

+ 19 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/DataSourceType.java

@@ -0,0 +1,19 @@
+package com.fastbee.common.enums;
+
+/**
+ * 数据源
+ * 
+ * @author ruoyi
+ */
+public enum DataSourceType
+{
+    /**
+     * 主库
+     */
+    MASTER,
+
+    /**
+     * 从库
+     */
+    SLAVE
+}

+ 36 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/DeviceStatus.java

@@ -0,0 +1,36 @@
+package com.fastbee.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum DeviceStatus {
+
+    UNACTIVATED(1,"NOTACTIVE","未激活"),
+    FORBIDDEN(2,"DISABLE","禁用"),
+    ONLINE(3,"ONLINE","在线"),
+    OFFLINE(4,"OFFLINE","离线");
+
+    private int type;
+    private String code;
+    private String description;
+
+    public static DeviceStatus convert(int type){
+        for (DeviceStatus value : DeviceStatus.values()) {
+            if (value.type == type){
+                return value;
+            }
+        }
+        return null;
+    }
+
+    public static DeviceStatus convert(String code){
+        for (DeviceStatus value : DeviceStatus.values()) {
+            if (value.code.equals(code)){
+                return value;
+            }
+        }
+        return null;
+    }
+}

+ 23 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/ExceptionCode.java

@@ -0,0 +1,23 @@
+package com.fastbee.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+/**
+ * @author gsb
+ * @date 2022/11/3 11:05
+ */
+@Getter
+@AllArgsConstructor
+public enum ExceptionCode {
+
+    SUCCESS(200,"成功"),
+    TIMEOUT(400,"超时"),
+    OFFLINE(404,"设备断线"),
+    FAIL(500,"失败");
+    ;
+
+    public int code;
+    public String desc;
+}

+ 21 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/FunctionReplyStatus.java

@@ -0,0 +1,21 @@
+package com.fastbee.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 设备回调状态
+ * @author bill
+ */
+@Getter
+@AllArgsConstructor
+public enum FunctionReplyStatus {
+    SUCCESS(200,"设备执行成功"),
+    FAIl(201,"指令执行失败"),
+    UNKNOWN(204,"设备超时未回复"),
+    NORELY(203, "指令下发成功");
+
+    int code;
+    String message;
+
+}

+ 52 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/GlobalErrorCodeConstants.java

@@ -0,0 +1,52 @@
+package com.fastbee.common.enums;
+
+
+import com.fastbee.common.exception.ErrorCode;
+
+/**
+ * 全局错误码枚举
+ * 0-999 系统异常编码保留
+ *
+ * 一般情况下,使用 HTTP 响应状态码 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
+ * 虽然说,HTTP 响应状态码作为业务使用表达能力偏弱,但是使用在系统层面还是非常不错的
+ * 比较特殊的是,因为之前一直使用 0 作为成功,就不使用 200 啦。
+ *
+ * @author fastbee
+ */
+public interface GlobalErrorCodeConstants {
+
+    ErrorCode SUCCESS = new ErrorCode(0, "成功");
+
+    // ========== 客户端错误段 ==========
+
+    ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
+    ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
+    ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
+    ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
+    ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
+    ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
+    ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
+
+    // ========== 服务端错误段 ==========
+
+    ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
+    ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
+
+    // ========== 自定义错误段 ==========
+    ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
+    ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
+
+    ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
+
+    /**
+     * 是否为服务端错误,参考 HTTP 5XX 错误码段
+     *
+     * @param code 错误码
+     * @return 是否
+     */
+   static boolean isServerErrorCode(Integer code) {
+       return code != null
+               && code >= INTERNAL_SERVER_ERROR.getCode() && code <= INTERNAL_SERVER_ERROR.getCode() + 99;
+   }
+
+}

+ 36 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/HttpMethod.java

@@ -0,0 +1,36 @@
+package com.fastbee.common.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.lang.Nullable;
+
+/**
+ * 请求方式
+ *
+ * @author ruoyi
+ */
+public enum HttpMethod
+{
+    GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+
+    private static final Map<String, HttpMethod> mappings = new HashMap<>(16);
+
+    static
+    {
+        for (HttpMethod httpMethod : values())
+        {
+            mappings.put(httpMethod.name(), httpMethod);
+        }
+    }
+
+    @Nullable
+    public static HttpMethod resolve(@Nullable String method)
+    {
+        return (method != null ? mappings.get(method) : null);
+    }
+
+    public boolean matches(String method)
+    {
+        return (this == resolve(method));
+    }
+}

+ 14 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/IErrorCode.java

@@ -0,0 +1,14 @@
+package com.fastbee.common.enums;
+
+/**
+ * 常用API返回对象接口
+ */
+public interface IErrorCode {
+
+    /**返回码*/
+    int getCode();
+
+    /**返回信息*/
+    String getMessage();
+
+}

+ 20 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/LimitType.java

@@ -0,0 +1,20 @@
+package com.fastbee.common.enums;
+
+/**
+ * 限流类型
+ *
+ * @author ruoyi
+ */
+
+public enum LimitType
+{
+    /**
+     * 默认策略全局限流
+     */
+    DEFAULT,
+
+    /**
+     * 根据请求者IP进行限流
+     */
+    IP
+}

+ 38 - 0
yudao-module-things/fastbee-common/src/main/java/com/fastbee/common/enums/ModbusDataType.java

@@ -0,0 +1,38 @@
+package com.fastbee.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Objects;
+
+/**
+ * @author gsb
+ * @date 2023/9/4 14:46
+ */
+@Getter
+@AllArgsConstructor
+public enum ModbusDataType {
+
+
+    U_SHORT("ushort","16位 无符号"),
+    SHORT("short","16位 有符号"),
+    LONG_ABCD("long-ABCD","32位 有符号(ABCD)"),
+    LONG_CDAB("long-CDAB","32位 有符号(CDAB)"),
+    U_LONG_ABCD("ulong-ABCD","32位 无符号(ABCD)"),
+    U_LONG_CDAB("ulong-CDAB","32位 无符号(CDAB)"),
+    FLOAT_ABCD("float-ABCD","32位 浮点数(ABCD)"),
+    FLOAT_CDAB("float-CDAB","32位 浮点数(CDAB)"),
+    BIT("bit","位");
+
+    String type;
+    String msg;
+
+    public static ModbusDataType convert(String type){
+        for (ModbusDataType value : ModbusDataType.values()) {
+            if (Objects.equals(value.type,type)){
+                return value;
+            }
+        }
+        return ModbusDataType.U_SHORT;
+    }
+}

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov