This commit is contained in:
1 2025-06-06 06:10:57 +08:00
commit 0388d0b2bb
1785 changed files with 274905 additions and 0 deletions

49
.gitignore vendored Normal file
View File

@ -0,0 +1,49 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
../.idea
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
fastbee-common/
fastbee-framework/
own-*
!*/build/*.java
!*/build/*.html
!*/build/*.xml

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

86
README.md Normal file
View File

@ -0,0 +1,86 @@
## 平台简介
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 前端采用Vue、Element UI。
* 后端采用Spring Boot、Spring Security、Redis & Jwt。
* 权限认证使用Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast)Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 特别鸣谢:[element](https://github.com/ElemeFE/element)[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)[eladmin-web](https://github.com/elunez/eladmin-web)。
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)  
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)  
## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存信息查询,命令统计等。
17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://vue.ruoyi.vip
文档地址http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr>
</table>
## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) 点击按钮入群。

12
bin/clean.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause

12
bin/package.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 打包Web工程生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause

14
bin/run.bat Normal file
View File

@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Web<65><62><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../fastbee-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% fastbee-admin.jar
cd bin
pause

177
fastbee-admin/pom.xml Normal file
View File

@ -0,0 +1,177 @@
<?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>
<artifactId>fastbee</artifactId>
<groupId>com.fastbee</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>fastbee-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <optional>true</optional> &lt;!&ndash; 表示依赖不会传递 &ndash;&gt;-->
<!-- </dependency>-->
<!-- swagger3-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
<!-- 防止进入swagger页面报类型转换错误排除3.0.0中的引用手动增加1.6.2版本 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.2</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-framework</artifactId>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-generator</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-oss</artifactId>
</dependency>
<!-- controller API模块-->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-open-api</artifactId>
</dependency>
<!--服务集成启动模块-->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>boot-strap</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>http-server</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>sip-server</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-http</artifactId>
</dependency>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-core</artifactId>
<version>${liteflow.version}</version>
</dependency>
<!-- 通知配置模块 -->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-notify-web</artifactId>
</dependency>
<!-- 通知api模块 -->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-notify-core</artifactId>
</dependency>
<!-- oauth2.0 -->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-oauth</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- &lt;!&ndash; 小度音箱 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.fastbee</groupId>-->
<!-- <artifactId>fastbee-link-dueros</artifactId>-->
<!-- </dependency>-->
<!-- 组态模块 -->
<!-- <dependency>-->
<!-- <groupId>com.fastbee</groupId>-->
<!-- <artifactId>fastbee-scada</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.fastbee</groupId>-->
<!-- <artifactId>fastbee-common</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-common-extend</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

View File

@ -0,0 +1,21 @@
package com.fastbee;
import com.dtflys.forest.springboot.annotation.ForestScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动程序
*
* @author ruoyi
*/
@SpringBootApplication
@ForestScan(basePackages = "com.fastbee")
public class FastBeeApplication
{
public static void main(String[] args)
{
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(FastBeeApplication.class, args);
}
}

View File

@ -0,0 +1,18 @@
package com.fastbee;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web容器中进行部署
*
* @author ruoyi
*/
public class FastBeeServletInitializer extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(FastBeeApplication.class);
}
}

View File

@ -0,0 +1,101 @@
package com.fastbee.web.controller.common;
import com.fastbee.common.config.RuoYiConfig;
import com.fastbee.common.constant.CacheConstants;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.utils.sign.Base64;
import com.fastbee.common.utils.uuid.IdUtils;
import com.fastbee.system.service.ISysConfigService;
import com.google.code.kaptcha.Producer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* 验证码操作处理
*
* @author ruoyi
*/
@Api(tags = "验证码操作")
@RestController
public class CaptchaController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
@Autowired
private RedisCache redisCache;
@Autowired
private ISysConfigService configService;
/**
* 生成验证码
*/
@ApiOperation("获取验证码")
@GetMapping("/captchaImage")
public AjaxResult getCode(HttpServletResponse response,Boolean showCode) throws IOException
{
AjaxResult ajax = AjaxResult.success();
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled)
{
return ajax;
}
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null;
BufferedImage image = null;
// 生成验证码
String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(captchaType))
{
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
}
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try
{
ImageIO.write(image, "jpg", os);
}
catch (IOException e)
{
return AjaxResult.error(e.getMessage());
}
if (Boolean.TRUE.equals(showCode)) {
ajax.put("resultCode", code);
}
ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(os.toByteArray()));
return ajax;
}
}

View File

@ -0,0 +1,259 @@
package com.fastbee.web.controller.common;
import com.fastbee.common.config.RuoYiConfig;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.utils.MessageUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.file.FileUploadUtils;
import com.fastbee.common.utils.file.FileUtils;
import com.fastbee.common.utils.file.QRCodeUtils;
import com.fastbee.framework.config.ServerConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
* 通用请求处理
*
* @author ruoyi
*/
@Api(tags = "通用请求处理")
@RestController
@RequestMapping("/common")
public class CommonController
{
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
@Autowired
private ServerConfig serverConfig;
private static final String FILE_DELIMETER = ",";
/**
* 通用下载请求
*
* @param fileName 文件名称
* @param delete 是否删除
*/
@ApiOperation("文件下载")
@GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{
try
{
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format(MessageUtils.message("download.filename.not.valid"), fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete)
{
FileUtils.deleteFile(filePath);
}
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
/**
* 通用上传请求单个
*/
@ApiOperation("单个文件上传")
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
* 通用上传请求多个
*/
@ApiOperation("多个文件上传")
@PostMapping("/uploads")
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>();
List<String> newFileNames = new ArrayList<String>();
List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files)
{
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
urls.add(url);
fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename());
}
AjaxResult ajax = AjaxResult.success();
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
* 本地资源通用下载
*/
@GetMapping("/download/resource")
@ApiOperation("本地资源通用下载")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
try
{
if (!FileUtils.checkAllowDownload(resource))
{
throw new Exception(StringUtils.format(MessageUtils.message("download.resource.not.valid"), resource));
}
// 本地资源路径
String localPath = RuoYiConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
/**
* 生成二维码
* @param url url
* */
@GetMapping(value = "/createQrCode")
@ApiOperation("根据url生成二维码")
public void getCode(String url, HttpServletResponse response) throws IOException {
// 设置响应流信息
response.setContentType("image/jpg");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
OutputStream stream = response.getOutputStream();
//获取一个二维码图片
BitMatrix bitMatrix = QRCodeUtils.createCode(url);
//以流的形式输出到前端
MatrixToImageWriter.writeToStream(bitMatrix , "jpg" , stream);
}
@ApiOperation("音频文件上传")
@PostMapping("/upload/audio")
public AjaxResult uploadAudioFile(@RequestParam("file") MultipartFile file) throws Exception {
try {
log.info("音频文件上传开始");
// 1. 校验文件是否为空
if (file.isEmpty()) {
return AjaxResult.error("上传文件不能为空");
}
// 2. 校验文件名
String originalFilename = file.getOriginalFilename();
if (originalFilename == null) {
return AjaxResult.error("无法获取文件名");
}
// 3. 创建存储目录确保路径无重复
String audioDir = RuoYiConfig.getProfile() + "/audios"; // 实际存储路径/data/upload/audios/
File dir = new File(audioDir);
if (!dir.exists() && !dir.mkdirs()) {
log.error("目录创建失败:{}", audioDir);
return AjaxResult.error("服务器目录创建失败");
}
// 4. 生成唯一文件名
String extension = StringUtils.substringAfterLast(originalFilename, ".");
String uuidFileName = UUID.randomUUID() + "." + extension;
File dest = new File(dir, uuidFileName);
// 5. 保存文件
try {
file.transferTo(dest);
} catch (IOException e) {
log.error("文件保存失败:{}", dest.getAbsolutePath());
return AjaxResult.error("文件保存失败:" + e.getMessage());
}
// 6. 构造返回数据兼容下载接口
String relativePath = Constants.RESOURCE_PREFIX + "/audios/" + uuidFileName; // 格式/profile/audios/xxx.mp3
String url = serverConfig.getUrl() + relativePath;
AjaxResult ajax = AjaxResult.success("音频上传成功");
ajax.put("url", url); // 完整访问URL http://domain/profile/audios/xxx.mp3
ajax.put("resourcePath", relativePath); // 下载接口参数 /profile/audios/xxx.mp3
ajax.put("fileName", uuidFileName); // 新文件名带扩展名
ajax.put("originalFilename", originalFilename); // 原始文件名
ajax.put("fileSize", file.getSize()); // 文件大小字节
ajax.put("fileType", file.getContentType()); // MIME类型 audio/mpeg
log.info("音频文件上传成功,存储路径:{}", dest.getAbsolutePath());
return ajax;
} catch (Exception e) {
log.error("音频文件上传失败", e);
return AjaxResult.error("音频上传失败: " + e.getMessage());
}
}
}

View File

@ -0,0 +1,121 @@
package com.fastbee.web.controller.monitor;
import com.fastbee.common.constant.CacheConstants;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.system.domain.SysCache;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 缓存监控
*
* @author ruoyi
*/
@Api(tags = "缓存监控")
@RestController
@RequestMapping("/monitor/cache")
public class CacheController
{
@Autowired
private RedisTemplate<String, String> redisTemplate;
private final static List<SysCache> caches = new ArrayList<SysCache>();
{
caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
}
@ApiOperation("获取缓存信息")
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping()
public AjaxResult getInfo() throws Exception
{
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return AjaxResult.success(result);
}
@ApiOperation("缓存列表")
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getNames")
public AjaxResult cache()
{
return AjaxResult.success(caches);
}
@ApiOperation("键名列表")
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getKeys/{cacheName}")
public AjaxResult getCacheKeys(@PathVariable String cacheName)
{
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(cacheKeys);
}
@ApiOperation("缓存内容")
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getValue/{cacheName}/{cacheKey}")
public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
{
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
return AjaxResult.success(sysCache);
}
@ApiOperation("清理缓存名称")
@PreAuthorize("@ss.hasPermi('monitor:cache:remove')")
@DeleteMapping("/clearCacheName/{cacheName}")
public AjaxResult clearCacheName(@PathVariable String cacheName)
{
Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
@ApiOperation("清理缓存键名")
@PreAuthorize("@ss.hasPermi('monitor:cache:remove')")
@DeleteMapping("/clearCacheKey/{cacheKey}")
public AjaxResult clearCacheKey(@PathVariable String cacheKey)
{
redisTemplate.delete(cacheKey);
return AjaxResult.success();
}
@ApiOperation("清理所有缓存内容")
@PreAuthorize("@ss.hasPermi('monitor:cache:remove')")
@DeleteMapping("/clearCacheAll")
public AjaxResult clearCacheAll()
{
Collection<String> cacheKeys = redisTemplate.keys("*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
}

View File

@ -0,0 +1,32 @@
package com.fastbee.web.controller.monitor;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.system.domain.Server;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 服务器监控
*
* @author ruoyi
*/
@Api(tags = "服务器监控")
@RestController
@RequestMapping("/monitor/server")
public class ServerController
{
@ApiOperation("获取服务器信息")
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
@GetMapping()
public AjaxResult getInfo() throws Exception
{
Server server = new Server();
server.copyTo();
return AjaxResult.success(server);
}
}

View File

@ -0,0 +1,94 @@
package com.fastbee.web.controller.monitor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fastbee.common.annotation.Log;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.enums.BusinessType;
import com.fastbee.common.extend.core.controller.BaseController;
import com.fastbee.common.extend.utils.poi.ExcelUtil;
import com.fastbee.system.domain.SysLogininfor;
import com.fastbee.system.domain.vo.SysLogininforVO;
import com.fastbee.system.service.ISysLogininforService;
import com.fastbee.system.service.sys.SysPasswordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
/**
* 系统访问记录
*
* @author ruoyi
*/
@Api(tags = "日志管理:登录日志")
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
@Resource
private ISysLogininforService logininforService;
@Resource
private SysPasswordService passwordService;
@ApiOperation("获取列表登录信息")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor)
{
Page<SysLogininforVO> voPage = logininforService.pageSysLogininforVO(logininfor);
return getDataTable(voPage.getRecords(), voPage.getTotal());
}
@ApiOperation("导出登录日志列表")
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysLogininfor logininfor)
{
Page<SysLogininforVO> voPage = logininforService.pageSysLogininforVO(logininfor);
ExcelUtil<SysLogininforVO> util = new ExcelUtil<SysLogininforVO>(SysLogininforVO.class);
util.exportExcel(response, voPage.getRecords(), "系统访问记录数据");
}
@ApiOperation("批量删除登录日志")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public AjaxResult remove(@PathVariable Long[] infoIds)
{
return toAjax(logininforService.deleteLogininforByIds(infoIds));
}
@ApiOperation("清空登录日志信息")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public AjaxResult clean()
{
logininforService.cleanLogininfor();
return success();
}
@ApiOperation("账户解锁")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName)
{
passwordService.clearLoginRecordCache(userName);
return success();
}
@ApiOperation("获取一周内每天用户统计")
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/userCount")
public AjaxResult userCount()
{
return toAjax(logininforService.getUserCount());
}
}

View File

@ -0,0 +1,71 @@
package com.fastbee.web.controller.monitor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fastbee.common.annotation.Log;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.enums.BusinessType;
import com.fastbee.common.extend.core.controller.BaseController;
import com.fastbee.common.extend.utils.poi.ExcelUtil;
import com.fastbee.system.domain.vo.SysOperLogVO;
import com.fastbee.system.service.ISysOperLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
/**
* 操作日志记录
*
* @author ruoyi
*/
@Api(tags = "日志管理:操作日志")
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
@Resource
private ISysOperLogService operLogService;
@ApiOperation("获取操作日志列表")
@PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
@GetMapping("/list")
public TableDataInfo list(SysOperLogVO operLog)
{
Page<SysOperLogVO> voPage = operLogService.pageSysOperLogVO(operLog);
return getDataTable(voPage.getRecords(), voPage.getTotal());
}
@ApiOperation("导出操作日志")
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysOperLogVO operLog)
{
Page<SysOperLogVO> voPage = operLogService.pageSysOperLogVO(operLog);
ExcelUtil<SysOperLogVO> util = new ExcelUtil<SysOperLogVO>(SysOperLogVO.class);
util.exportExcel(response, voPage.getRecords(), "操作日志记录数据");
}
@ApiOperation("批量删除操作日志")
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/{operIds}")
public AjaxResult remove(@PathVariable Long[] operIds)
{
return toAjax(operLogService.deleteOperLogByIds(operIds));
}
@ApiOperation("清空操作日志")
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/clean")
public AjaxResult clean()
{
operLogService.cleanOperLog();
return success();
}
}

View File

@ -0,0 +1,96 @@
package com.fastbee.web.controller.monitor;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fastbee.common.annotation.Log;
import com.fastbee.common.constant.CacheConstants;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.enums.BusinessType;
import com.fastbee.common.extend.core.controller.BaseController;
import com.fastbee.common.extend.core.domin.model.LoginUser;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.system.domain.SysUserOnline;
import com.fastbee.system.service.ISysUserOnlineService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* 在线用户监控
*
* @author ruoyi
*/
@Api(tags = "在线用户监控")
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController
{
@Autowired
private ISysUserOnlineService userOnlineService;
@Autowired
private RedisCache redisCache;
@ApiOperation("获取在线用户列表")
@PreAuthorize("@ss.hasPermi('monitor:online:list')")
@GetMapping("/list")
public TableDataInfo list(String ipaddr, String userName)
{
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
for (String key : keys)
{
LoginUser user = JSONObject.parseObject(JSON.toJSONString(redisCache.getCacheObject(key)), LoginUser.class);
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
{
if (StringUtils.containsIgnoreCase(user.getIpaddr(), ipaddr) && StringUtils.containsIgnoreCase(user.getUsername(), userName))
{
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
}
}
else if (StringUtils.isNotEmpty(ipaddr))
{
if (StringUtils.containsIgnoreCase(user.getIpaddr(), ipaddr))
{
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
}
}
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
{
if (StringUtils.containsIgnoreCase(user.getUsername(), userName))
{
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
}
}
else
{
userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
}
}
Collections.reverse(userOnlineList);
userOnlineList.removeAll(Collections.singleton(null));
return getDataTable(userOnlineList);
}
/**
* 强退用户
*/
@ApiOperation("强制退出在线用户")
@PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@DeleteMapping("/{tokenId}")
public AjaxResult forceLogout(@PathVariable String tokenId)
{
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
return success();
}
}

View File

@ -0,0 +1,24 @@
package com.fastbee.web.controller.tool;
import com.fastbee.common.extend.core.controller.BaseController;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* swagger 接口
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/swagger")
public class SwaggerController extends BaseController
{
@PreAuthorize("@ss.hasPermi('tool:swagger:view')")
@GetMapping()
public String index()
{
return redirect("/swagger-ui.html");
}
}

View File

@ -0,0 +1,172 @@
package com.fastbee.web.controller.tool;
import com.fastbee.common.core.domain.R;
import com.fastbee.common.extend.core.controller.BaseController;
import com.fastbee.common.utils.StringUtils;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* swagger 用户测试方法
*
* @author ruoyi
*/
@Api("swagger 用户测试方法")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
{
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
}
@ApiOperation("获取用户列表")
@GetMapping("/list")
public R<List<UserEntity>> userList()
{
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
return R.ok(userList);
}
@ApiOperation("获取用户详细")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@GetMapping("/{userId}")
public R<UserEntity> getUser(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
return R.ok(users.get(userId));
}
else
{
return R.fail("用户不存在");
}
}
@ApiOperation("新增用户")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
@ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
})
@PostMapping("/save")
public R<String> save(UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
users.put(user.getUserId(), user);
return R.ok();
}
@ApiOperation("更新用户")
@PutMapping("/update")
public R<String> update(@RequestBody UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
if (users.isEmpty() || !users.containsKey(user.getUserId()))
{
return R.fail("用户不存在");
}
users.remove(user.getUserId());
users.put(user.getUserId(), user);
return R.ok();
}
@ApiOperation("删除用户信息")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@DeleteMapping("/{userId}")
public R<String> delete(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
users.remove(userId);
return R.ok();
}
else
{
return R.fail("用户不存在");
}
}
}
@ApiModel(value = "UserEntity", description = "用户实体")
class UserEntity
{
@ApiModelProperty("用户ID")
private Integer userId;
@ApiModelProperty("用户名称")
private String username;
@ApiModelProperty("用户密码")
private String password;
@ApiModelProperty("用户手机")
private String mobile;
public UserEntity()
{
}
public UserEntity(Integer userId, String username, String password, String mobile)
{
this.userId = userId;
this.username = username;
this.password = password;
this.mobile = mobile;
}
public Integer getUserId()
{
return userId;
}
public void setUserId(Integer userId)
{
this.userId = userId;
}
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 getMobile()
{
return mobile;
}
public void setMobile(String mobile)
{
this.mobile = mobile;
}
}

View File

@ -0,0 +1,216 @@
package com.fastbee.web.controller.tool;
import com.alibaba.fastjson2.JSON;
import com.fastbee.common.annotation.Anonymous;
import com.fastbee.common.core.domain.ImportExcelVO;
import com.fastbee.common.core.domain.OutputExcelVO;
import com.fastbee.common.extend.utils.poi.ExcelUtil;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.iot.domain.AlertLog;
import com.fastbee.iot.domain.DeviceJob;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.mapper.AlertLogMapper;
import com.fastbee.iot.mapper.DeviceJobMapper;
import com.fastbee.iot.mapper.DeviceLogMapper;
import com.fastbee.iot.mapper.DeviceMapper;
import com.fastbee.iot.model.vo.DeviceRelateAlertLogVO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 测试类
* @author fastb
* @date 2023-09-13 11:42
*/
@Anonymous
@RestController
@RequestMapping("/test2")
public class TestController2 {
@Resource
private AlertLogMapper alertLogMapper;
@Resource
private DeviceMapper deviceMapper;
@Resource
private DeviceJobMapper deviceJobMapper;
@Resource
private DeviceLogMapper deviceLogMapper;
@GetMapping("/add")
public void add()
{
Set<String> deviceNumbers = new HashSet<>();
deviceNumbers.add("D1PGLPG58K88");
deviceNumbers.add("D1F0L7P84D8Z");
deviceNumbers.add("D1F0L7P84D8Z_2");
List<DeviceRelateAlertLogVO> deviceRelateAlertLogVOList = deviceMapper.selectDeviceBySerialNumbers(deviceNumbers);
Map<String, DeviceRelateAlertLogVO> deviceRelateAlertLogVOMap = deviceRelateAlertLogVOList.stream().collect(Collectors.toMap(DeviceRelateAlertLogVO::getSerialNumber, Function.identity()));
ArrayList<AlertLog> alertLogList = new ArrayList<>();
for (String deviceNumber : deviceNumbers) {
AlertLog alertLog = new AlertLog();
alertLog.setSerialNumber(deviceNumber);
alertLog.setAlertName("温度告警测试");
alertLog.setAlertLevel(1L);
alertLog.setStatus(1);
alertLog.setProductId(1L);
alertLog.setDetail("111");
alertLog.setCreateTime(new Date());
// 添加设备关联信息
if (deviceRelateAlertLogVOMap.containsKey(deviceNumber)) {
DeviceRelateAlertLogVO deviceRelateAlertLogVO = deviceRelateAlertLogVOMap.get(deviceNumber);
alertLog.setDeviceName(deviceRelateAlertLogVO.getDeviceName());
alertLog.setUserId(deviceRelateAlertLogVO.getUserId());
}
alertLogList.add(alertLog);
}
// 批量插入告警日志
alertLogMapper.insertBatch(alertLogList);
}
@PostMapping("/handleExcel")
public String handleExcel(@RequestParam("file") MultipartFile file) throws Exception
{
if (null == file) {
return "导入失败,请先上传文件!";
}
ExcelUtil<ImportExcelVO> util = new ExcelUtil<>(ImportExcelVO.class);
List<ImportExcelVO> importExcelVOList = util.importExcel(file.getInputStream());
if (CollectionUtils.isEmpty(importExcelVOList)) {
return "导入失败,模板数据不能为空!";
}
System.out.println(importExcelVOList.size());
List<String> oneCityName = new ArrayList<>();
List<String> twoCityName = new ArrayList<>();
List<String> threeCityName = new ArrayList<>();
List<OutputExcelVO> oneCityList = new ArrayList<>();
Map<String, List<OutputExcelVO>> twoCityMap = new HashMap<>(2);
Map<String, List<OutputExcelVO>> threeCityMap = new HashMap<>(2);
for (ImportExcelVO vo : importExcelVOList) {
String city = vo.getCity();
List<String> cityNameList = StringUtils.str2List(city, "/", true, true);
int size = cityNameList.size();
if (1 == size) {
String name = cityNameList.get(0);
if (!oneCityName.contains(name)) {
oneCityName.add(name);
OutputExcelVO outputExcelVO = new OutputExcelVO();
outputExcelVO.setName(name);
outputExcelVO.setCode(vo.getCode());
outputExcelVO.setLat(vo.getLat());
outputExcelVO.setLon(vo.getLon());
oneCityList.add(outputExcelVO);
twoCityMap.put(name, new ArrayList<>());
}
} else if (2 == size) {
String oneName = cityNameList.get(0);
if (!oneCityName.contains(oneName)) {
oneCityName.add(oneName);
OutputExcelVO outputExcelVO = new OutputExcelVO();
outputExcelVO.setName(oneName);
oneCityList.add(outputExcelVO);
twoCityMap.put(oneName, new ArrayList<>());
}
String twoName = cityNameList.get(1);
OutputExcelVO outputExcelVO = new OutputExcelVO();
outputExcelVO.setName(twoName);
outputExcelVO.setCode(vo.getCode());
outputExcelVO.setLat(vo.getLat());
outputExcelVO.setLon(vo.getLon());
if (!twoCityName.contains(twoName)) {
twoCityName.add(twoName);
List<OutputExcelVO> twoList = twoCityMap.get(oneName);
twoList.add(outputExcelVO);
twoCityMap.put(oneName, twoList);
threeCityMap.put(twoName, new ArrayList<>());
}
} else if (3 == size) {
String oneName = cityNameList.get(0);
if (!oneCityName.contains(oneName)) {
oneCityName.add(oneName);
OutputExcelVO outputExcelVO = new OutputExcelVO();
outputExcelVO.setName(oneName);
oneCityList.add(outputExcelVO);
twoCityMap.put(oneName, new ArrayList<>());
}
String twoName = cityNameList.get(1);
if (!twoCityName.contains(twoName)) {
twoCityName.add(twoName);
OutputExcelVO outputExcelVO = new OutputExcelVO();
outputExcelVO.setName(twoName);
List<OutputExcelVO> twoList = twoCityMap.get(oneName);
twoList.add(outputExcelVO);
twoCityMap.put(oneName, twoList);
threeCityMap.put(twoName, new ArrayList<>());
}
String threeName = cityNameList.get(2);
if (!threeCityName.contains(threeName)) {
threeCityName.add(threeName);
OutputExcelVO outputExcelVO = new OutputExcelVO();
outputExcelVO.setName(threeName);
outputExcelVO.setCode(vo.getCode());
outputExcelVO.setLat(vo.getLat());
outputExcelVO.setLon(vo.getLon());
List<OutputExcelVO> twoList = threeCityMap.get(twoName);
twoList.add(outputExcelVO);
threeCityMap.put(twoName, twoList);
}
}
}
int total = 0;
total = total + oneCityList.size();
for (OutputExcelVO outputExcelVO : oneCityList) {
List<OutputExcelVO> voList = twoCityMap.get(outputExcelVO.getName());
if (CollectionUtils.isNotEmpty(voList)) {
total = total + voList.size();
outputExcelVO.setChildren(voList);
for (OutputExcelVO excelVO : voList) {
List<OutputExcelVO> voList1 = threeCityMap.get(excelVO.getName());
if (CollectionUtils.isNotEmpty(voList1)) {
total = total + voList1.size();
excelVO.setChildren(voList1);
}
}
}
}
System.out.println(total);
return JSON.toJSONString(oneCityList);
}
/**
* 计算场景运算型变量的值
* @param id
* @return java.lang.String
*/
@GetMapping("/getJobList")
public String getJobList() {
Long[] ids = {1L, 2L};
List<DeviceJob> deviceJobList = deviceJobMapper.selectListByJobTypeAndDatasourceIds(ids, 3);
return JSON.toJSONString(deviceJobList);
}
@GetMapping("/getStatsValue")
public String getStatsValue() {
DeviceLog deviceLog = new DeviceLog();
deviceLog.setLogType(1);
deviceLog.setIdentify("k1");
deviceLog.setSerialNumber("D10I741UL2P3_1");
deviceLog.setBeginTime("2024-05-17 00:00:00");
deviceLog.setEndTime("2024-05-17 23:59:59");
// deviceLog.setOperation(5);
List<String> list = deviceLogMapper.selectStatsValue(deviceLog);
return JSON.toJSONString(list);
}
}

View File

@ -0,0 +1,121 @@
package com.fastbee.web.core.config;
import com.fastbee.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.ArrayList;
import java.util.List;
/**
* Swagger2的接口配置
*
* @author ruoyi
*/
@Configuration
public class SwaggerConfig
{
/** 系统基础配置 */
@Autowired
private RuoYiConfig ruoyiConfig;
/** 是否开启swagger */
@Value("${swagger.enabled}")
private boolean enabled;
/** 设置请求的统一前缀 */
@Value("${swagger.pathMapping}")
private String pathMapping;
/**
* 创建API
*/
@Bean
public Docket createRestApi()
{
return new Docket(DocumentationType.OAS_30)
// 是否启用Swagger
.enable(enabled)
// 用来创建该API的基本信息展示在文档的页面中自定义展示的信息
.apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
// .apis(RequestHandlerSelectors.basePackage("com.fastbee.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
/* 设置安全模式swagger可以设置访问token */
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.pathMapping(pathMapping);
}
/**
* 安全模式这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的安全上引用
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("FastBee物联网平台接口文档")
// 描述
.description("描述FastBee物联网平台")
// 作者信息
.contact(new Contact(ruoyiConfig.getName(), null, null))
// 版本
.version("版本号:" + ruoyiConfig.getVersion())
.build();
}
}

View File

@ -0,0 +1 @@
restart.include.json=/com.alibaba.fastjson2.*.jar

View File

@ -0,0 +1,107 @@
# 数据源配置
spring:
datasource:
dynamic:
druid:
initial-size: 5
min-idle: 10
max-wait: 60000
max-active: 20
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000 # 配置一个连接在池中最大生存的时间,单位是毫秒
validation-query: 'SELECT 1'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/xazn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: admin123
druid:
filters: stat,wall
stat:
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
none-base-statement-allow: true
taos: # 配置 taos 数据源
enabled: false
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.taosdata.jdbc.TSDBDriver
url: jdbc:TAOS://fastbee:6030/fastbee_log?timezone=UTC-8&charset=utf-8
username: root
password: taosdata
dbName: fastbee_log
# slave:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/fastbee1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: root
# password: fastbee
shardingsphere:
enabled: false
# redis 配置
redis:
host: localhost # 地址
port: 6379 # 端口默认为6379
database: 0 # 数据库索引
password: admin123 # 密码
timeout: 10s # 连接超时时间
lettuce:
pool:
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
max-active: 8 # 连接池的最大数据库连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# mqtt 配置
mqtt:
username: fastbee # 账号
password: fastbee # 密码
host-url: tcp://localhost:1883 # mqtt连接tcp地址
client-id: ${random.int} # 客户端Id不能相同采用随机数 ${random.value}
default-topic: test # 默认主题
timeout: 30 # 超时时间
keepalive: 30 # 保持连接
clearSession: true # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息)
# sip 配置
sip:
enabled: false # 是否启用视频监控SIPtrue为启用
## 本地调试时绑定网卡局域网IP设备在同一局域网设备接入IP填写绑定IP
## 部署服务端时默认绑定容器IP设备接入IP填写服务器公网IP
ip: 177.7.0.13
port: 5061 # SIP端口(保持默认)
domain: 3402000000 # 由省级、市级、区级、基层编号组成
id: 34020000002000000001 # 同上,另外增加编号,(可保持默认)
password: 12345678 # 监控设备接入的密码
log: true
zlmRecordPath: /opt/media/bin/www
mp4_max_second: 30 # 视频录像时长,单位秒
# 日志配置
logging:
level:
com.fastbee: debug
com.yomahub: debug
org.dromara: warn
org.springframework: warn
com.baomidou: debug
# Swagger配置
swagger:
enabled: true # 是否开启swagger
pathMapping: /dev-api # 请求前缀
license:
publicAlias: FastbeePublicKey
storePass: fastbee_store_password666
licensePath: classpath:license.lic
publicKeysStorePath: classpath:publicCerts.keystore

View File

@ -0,0 +1,107 @@
# 数据源配置
spring:
datasource:
dynamic:
druid:
initial-size: 5
min-idle: 10
max-wait: 60000
max-active: 20
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000 # 配置一个连接在池中最大生存的时间,单位是毫秒
validation-query: 'SELECT 1'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://177.7.0.11:3306/fastbee?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: admin123
druid:
filters: stat,wall
stat:
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
none-base-statement-allow: true
taos: # 配置 taos 数据源
enabled: false
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.taosdata.jdbc.TSDBDriver
url: jdbc:TAOS://fastbee:6030/fastbee_log?timezone=UTC-8&charset=utf-8
username: root
password: taosdata
dbName: fastbee_log
# slave:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/fastbee1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: root
# password: fastbee
shardingsphere:
enabled: false
# redis 配置
redis:
host: 177.7.0.10 # 地址
port: 6379 # 端口默认为6379
database: 0 # 数据库索引
password: admin123 # 密码
timeout: 10s # 连接超时时间
lettuce:
pool:
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
max-active: 8 # 连接池的最大数据库连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# mqtt 配置
mqtt:
username: fastbee # 账号(仅用于后端自认证)
password: fastbee # 密码(仅用于后端自认证)
host-url: tcp://177.7.0.12:1883 # 连接 Emqx 消息服务器地址
# host-url: tcp://177.7.0.13:1883 # 内置netty mqtt broker地址
client-id: ${random.int} # 客户端Id不能相同采用随机数 ${random.value}
default-topic: test # 默认主题
timeout: 30 # 超时时间
keepalive: 30 # 保持连接
clearSession: true # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息)
# sip 配置
sip:
enabled: false # 是否启用视频监控SIPtrue为启用
## 本地调试时绑定网卡局域网IP设备在同一局域网设备接入IP填写绑定IP
## 部署服务端时默认绑定容器IP设备接入IP填写服务器公网IP
ip: 177.7.0.13
port: 5061 # SIP端口(保持默认)
domain: 3402000000 # 由省级、市级、区级、基层编号组成
id: 34020000002000000001 # 同上,另外增加编号,(可保持默认)
password: 12345678 # 监控设备接入的密码
log: false
zlmRecordPath: /opt/media/bin/www
mp4MaxSecond: 30 # 视频录像时长,单位秒
# 日志配置
logging:
level:
com.fastbee: debug
com.yomahub: warn
org.dromara: warn
org.springframework: warn
com.baomidou: info
# Swagger配置
swagger:
enabled: true # 是否开启swagger
pathMapping: /prod-api # 请求前缀
license:
publicAlias: FastbeePublicKey
storePass: fastbee_store_password666
licensePath: /license/license.lic
publicKeysStorePath: /license/publicCerts.keystore

View File

@ -0,0 +1,183 @@
# 数据源配置
spring:
datasource:
dynamic:
druid:
initial-size: 5
min-idle: 10
max-wait: 60000
max-active: 20
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000 # 配置一个连接在池中最大生存的时间,单位是毫秒
validation-query: 'SELECT 1'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/xazn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: admin123
druid:
filters: stat,wall
stat:
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
none-base-statement-allow: true
taos: # 配置 taos 数据源
enabled: true
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.taosdata.jdbc.TSDBDriver
url: jdbc:TAOS://fastbee:6030/fastbee_log?timezone=UTC-8&charset=utf-8
username: root
password: taosdata
dbName: fastbee_log
# sqlServer: # 配置 SQLServer 数据源
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;databaseName=fastbee
# username: sa
# password: fastbee@123
# postgres: # 配置 postgres 数据源
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: org.postgresql.Driver
# url: jdbc:postgresql://101.33.237.12:5432/fastbee?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root
# password: fastbee@123
# dameng: # 配置达梦数据源
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://192.168.5.28:5236/fastbee&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
# username: root
# password: fastbee@123
# druid:
# filters: stat
# oracle: # 配置 oracle 数据源
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: oracle.jdbc.driver.OracleDriver
# url: jdbc:oracle:thin:@101.33.237.12:1521:fastbee
# username: root
# password: fastbee@123
# druid:
# validation-query: 'SELECT 1 FROM DUAL'
# slave:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/fastbee1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: root
# password: fastbee
shardingsphere:
enabled: false
# props:
# # 是否显示 ShardingSpher 的sql用于Debug
# sql-show: false
# datasource:
# # 配置真实数据源
# names: ds0
# ds0: # 配置 mysql 数据源
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/fastbee?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: root
# password: fastbee
# filters: stat,wall
# filter:
# stat:
# enabled: true
# # 慢SQL记录
# log-slow-sql: true
# slow-sql-millis: 1000
# merge-sql: true
# wall:
# config:
# multi-statement-allow: true
#
# rules: # 配置表规则
# sharding:
# # 表策略配置
# tables:
# # iot_device_log 是逻辑表
# iot_device_log:
# actualDataNodes: ds0.iot_device_log_$->{2024..2030}0$->{1..9},ds0.iot_device_log_$->{2024..2030}1$->{0..2}
# tableStrategy:
# # 使用标准分片策略
# standard:
# # 配置分片字段
# shardingColumn: create_time
# # 分片算法名称,不支持大写字母和下划线,否则启动就会报错
# shardingAlgorithmName: time-sharding-algorithm
# # 分片算法配置
# shardingAlgorithms:
# # 分片算法名称,不支持大写字母和下划线,否则启动就会报错
# time-sharding-algorithm:
# # 类型:自定义策略
# type: CLASS_BASED
# props:
# # 分片策略
# strategy: standard
# # 分片算法类
# algorithmClassName: com.fastbee.framework.config.sharding.TimeShardingAlgorithm
# redis 配置
redis:
host: localhost # 地址
port: 6379 # 端口默认为6379
database: 3 # 数据库索引
password: admin123 # 密码
timeout: 10s # 连接超时时间
lettuce:
pool:
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
max-active: 8 # 连接池的最大数据库连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# mqtt 配置
mqtt:
username: fastbee # 账号
password: fastbee # 密码
host-url: tcp://localhost:1883 # mqtt连接tcp地址
client-id: ${random.int} # 客户端Id不能相同采用随机数 ${random.value}
default-topic: test # 默认主题
timeout: 30 # 超时时间
keepalive: 30 # 保持连接
clearSession: true # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息)
# sip 配置
sip:
enabled: true # 是否启用视频监控SIPtrue为启用
## 默认为容器IPIDE启动可以写本地网卡内网IP或者127.0.0.1
## 本地调试需保持设备与服务器在同一局域网
ip: 192.168.31.166
port: 5061 # SIP端口(保持默认)
domain: 3402000000 # 由省级、市级、区级、基层编号组成
id: 34020000002000000001 # 同上,另外增加编号,(可保持默认)
password: 12345678 # 监控设备接入的密码
log: true
zlmRecordPath: /opt/media/bin/www
# 日志配置
logging:
level:
com.fastbee: debug
com.yomahub: debug
org.dromara: warn
org.springframework: warn
com.baomidou: debug
# Swagger配置
swagger:
enabled: true # 是否开启swagger
pathMapping: /dev-api # 请求前缀
license:
publicAlias: FastbeePublicKey
storePass: fastbee_store_password666
licensePath: classpath:license.lic
publicKeysStorePath: classpath:publicCerts.keystore

View File

@ -0,0 +1,210 @@
# 项目相关配置
fastbee:
name: fastbee # 名称
version: 2.6.0 # 版本
copyrightYear: 2023 # 版权年份
demoEnabled: true # 实例演示开关
# 文件路径以uploadPath结尾 示例( Windows配置 D:/uploadPathLinux配置 /uploadPath
profile: /uploadPath
addressEnabled: true # 获取ip地址开关
captchaType: math # 验证码类型 math 数组计算 char 字符验证
# 开发环境配置
server:
port: 8080 # 服务器的HTTP端口默认为8080
servlet:
context-path: / # 应用的访问路径
tomcat:
uri-encoding: UTF-8 # tomcat的URI编码
accept-count: 1000 # 连接数满后的排队数默认为100
threads:
max: 800 # tomcat最大线程数默认为200
min-spare: 100 # Tomcat启动初始化的线程数默认值10
# 基于netty的服务器
broker:
enabled: false # mqttBroker类型选择, true: 基于netty的mqttBroker和webSocket false: emq的mqttBroker
port: 1883
websocket-port: 8083
websocket-path: /mqtt
keep-alive: 70 # 默认的全部客户端心跳上传时间
#TCP服务端口
tcp:
enabled: true # 控制tcp端口是否开启
port: 8888
keep-alive: 70
delimiter: 0x7e
udp:
enabled: false # 控制udp端口是否开启
port: 8889
read-idle: 300 # udp保活时间 默认5分钟
http:
enabled: true
port: 8081
auth:
type: Digest # 支持BasicDigest
username: fastbee
password: fastbee
coap:
enabled: true
port: 5683
# Spring配置
spring:
# 环境配置dev=开发环境prod=生产环境
profiles:
active: dev # 环境配置dev=开发环境prod=生产环境
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages
# 文件上传
servlet:
multipart:
max-file-size: 10MB # 单个文件大小
max-request-size: 20MB # 设置总上传的文件大小
# 服务模块
devtools:
restart:
enabled: true # 热部署开关
task:
execution:
pool:
core-size: 20 # 最小连接数
max-size: 200 # 最大连接数
queue-capacity: 3000 # 最大容量
keep-alive: 60
# 缓存配置
cache:
enable: false
type: none # none=不使用缓存 redis=使用redis缓存
ttl: 1800 # 缓存过期时间默认60秒
datasource:
druid:
webStatFilter:
enabled: true
stat-view-servlet:
enabled: true
allow:
url-pattern: /druid/*
loginUsername: fastbee
loginPassword: fastbee
dynamic:
primary: master
strict: false
lazy: true
# 用户配置
user:
password:
maxRetryCount: 5 # 密码最大错误次数
lockTime: 10 # 密码锁定时间默认10分钟
# token配置
token:
header: Authorization # 令牌自定义标识
secret: abcdefghijklfastbeesmartrstuvwxyz # 令牌密钥
expireTime: 1440 # 令牌有效期默认30分钟1440为一天
# MyBatis配置
#mybatis:
# typeAliasesPackage: com.fastbee.**.domain # 搜索指定包别名
# mapperLocations: classpath*:mapper/**/*Mapper.xml # 配置mapper的扫描找到所有的mapper.xml映射文件
# configLocation: classpath:mybatis/mybatis-config.xml # 加载全局的配置文件
# mybatis-plus配置
mybatis-plus:
typeAliasesPackage: com.fastbee.**.domain # 搜索指定包别名
mapperLocations: classpath*:mapper/**/*Mapper.xml # 配置mapper的扫描找到所有的mapper.xml映射文件
configLocation: classpath:mybatis/mybatis-config.xml # 加载全局的配置文件
global-config:
db-config:
id-type: AUTO # 自增 ID
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
# 防止XSS攻击
xss:
enabled: true # 过滤开关
excludes: /system/notice # 排除链接(多个用逗号分隔)
urlPatterns: /system/*,/monitor/*,/tool/* # 匹配链接
# EMQX API配置需要在运行emqx之后去EMQX管理后台手动创建API Key和Secret并配置到application.yml中
emqx:
host: localhost # EMQX服务器地址
port: 18083
ApiKey: ApiKey # EMQX API Key
ApiSecret: ApiSecret # EMQX API Secret
# redisson 配置
redisson:
# redis key前缀
keyPrefix: sql_cache
# 线程池数量
threads: 16
# Netty线程池数量
nettyThreads: 32
# 单节点配置
singleServerConfig:
# 客户端名称
clientName: ${fastbee.name}
# 最小空闲连接数
connectionMinimumIdleSize: 32
# 连接池大小
connectionPoolSize: 64
# 连接空闲超时,单位:毫秒
idleConnectionTimeout: 10000
# 命令等待超时,单位:毫秒
timeout: 3000
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
forest: # Forest配置 版本为1.5.36
backend: okhttp3 # 后端HTTP框架默认为 okhttp3
max-connections: 1000 # 连接池最大连接数(默认为 500
max-route-connections: 500 # 每个路由的最大连接数(默认为 500
max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小
max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数
max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小
connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout
read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout
max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试)
ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议默认为 TLS
log-enabled: true # 打开或关闭日志(默认为 true
log-request: true # 打开/关闭Forest请求日志默认为 true
log-response-status: true # 打开/关闭Forest响应状态日志默认为 true
log-response-content: true # 打开/关闭Forest响应内容日志默认为 false
async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform
liteflow:
#FlowExecutor的execute2Future的线程数默认为64
main-executor-works: 64
#FlowExecutor的execute2Future的自定义线程池Builder
main-executor-class: com.fastbee.ruleEngine.config.MainExecutorBuilder
#并行节点的线程池Builder
thread-executor-class: com.fastbee.ruleEngine.config.WhenExecutorBuilder
rule-source-ext-data-map:
# 应用名称,规则链和脚本组件名称需要一致,不要修改
applicationName: fastbee
#是否开启SQL日志
sqlLogEnabled: true
# 规则多时,启用快速加载模式
fast-load: false
#是否开启SQL数据轮询自动刷新机制 默认不开启
pollingEnabled: false
pollingIntervalSeconds: 60
pollingStartSeconds: 60
#以下是chain表的配置
chainTableName: iot_scene
chainApplicationNameField: application_name
chainNameField: chain_name
elDataField: el_data
chainEnableField: enable
#以下是script表的配置
scriptTableName: iot_script
scriptApplicationNameField: application_name
scriptIdField: script_id
scriptNameField: script_name
scriptDataField: script_data
scriptTypeField: script_type
scriptLanguageField: script_language
scriptEnableField: enable

View File

@ -0,0 +1,2 @@
Application Version: ${fastbee.version}
Spring Boot Version: ${spring-boot.version}

View File

@ -0,0 +1,398 @@
#\u9519\u8BEF\u6D88\u606F
not.null=\u5FC5\u987B\u586B\u5199
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
user.jcaptcha.expire=\u9A8C\u8BC1\u7801\u5DF2\u5931\u6548
user.not.exists=\u7528\u6237\u4E0D\u5B58\u5728/\u5BC6\u7801\u9519\u8BEF
user.password.not.match=\u7528\u6237\u4E0D\u5B58\u5728/\u5BC6\u7801\u9519\u8BEF
user.password.retry.limit.count=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21
user.password.retry.limit.exceed=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21\uFF0C\u5E10\u6237\u9501\u5B9A{1}\u5206\u949F
user.password.delete=\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u7684\u8D26\u53F7\u5DF2\u88AB\u5220\u9664
user.blocked=\u7528\u6237\u5DF2\u5C01\u7981\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
role.blocked=\u89D2\u8272\u5DF2\u5C01\u7981\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.logout.success=\u9000\u51FA\u6210\u529F
length.not.valid=\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4
user.username.not.valid=2\u523020\u4E2A\u6C49\u5B57\u3001\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u4E0B\u5212\u7EBF\u7EC4\u6210\uFF0C\u4E14\u5FC5\u987B\u4EE5\u975E\u6570\u5B57\u5F00\u5934
user.password.not.valid=5-50\u4E2A\u5B57\u7B26
user.email.not.valid=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF
user.mobile.phone.number.not.valid=\u624B\u673A\u53F7\u683C\u5F0F\u9519\u8BEF
user.login.success=\u767B\u5F55\u6210\u529F
user.register.success=\u6CE8\u518C\u6210\u529F
user.notfound=\u8BF7\u91CD\u65B0\u767B\u5F55
user.forcelogout=\u7BA1\u7406\u5458\u5F3A\u5236\u9000\u51FA\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55
user.unknown.error=\u672A\u77E5\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55
##\u6743\u9650
no.permission=\u60A8\u6CA1\u6709\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.create.permission=\u60A8\u6CA1\u6709\u521B\u5EFA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.update.permission=\u60A8\u6CA1\u6709\u4FEE\u6539\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.delete.permission=\u60A8\u6CA1\u6709\u5220\u9664\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.export.permission=\u60A8\u6CA1\u6709\u5BFC\u51FA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.view.permission=\u60A8\u6CA1\u6709\u67E5\u770B\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
##\u6587\u4EF6\u4E0A\u4F20\u6D88\u606F
upload.exceed.maxSize=\u4E0A\u4F20\u7684\u6587\u4EF6\u5927\u5C0F\u8D85\u51FA\u9650\u5236\u7684\u6587\u4EF6\u5927\u5C0F\uFF01<br/>\u5141\u8BB8\u7684\u6587\u4EF6\u6700\u5927\u5927\u5C0F\u662F\uFF1A{0}MB\uFF01
upload.filename.exceed.length=\u4E0A\u4F20\u7684\u6587\u4EF6\u540D\u6700\u957F{0}\u4E2A\u5B57\u7B26
upload.success=\u4E0A\u4F20\u6210\u529F
##\u6587\u4EF6\u4E0B\u8F7D\u6D88\u606F
download.filename.not.valid=\u6587\u4EF6\u540D\u79F0[{}]\u975E\u6CD5\uFF0C\u4E0D\u5141\u8BB8\u4E0B\u8F7D
download.file.failed=\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25
download.resource.not.valid=\u8D44\u6E90\u6587\u4EF6[{}]\u975E\u6CD5\uFF0C\u4E0D\u5141\u8BB8\u4E0B\u8F7D
##Dept
dept.add.failed.name.exists=\u65B0\u589E\u673A\u6784[{}]\u5931\u8D25\uFF0C\u673A\u6784\u540D\u79F0\u5DF2\u5B58\u5728
dept.update.failed.name.exists=\u4FEE\u6539\u673A\u6784[{}]\u5931\u8D25\uFF0C\u673A\u6784\u540D\u79F0\u5DF2\u5B58\u5728
dept.update.failed.parent.not.valid=\u4FEE\u6539\u673A\u6784[{}]\u5931\u8D25\uFF0C\u4E0A\u7EA7\u673A\u6784\u4E0D\u80FD\u662F\u81EA\u5DF1
dept.update.failed.child.not.valid=\u8BE5\u673A\u6784\u5305\u542B\u672A\u505C\u7528\u7684\u5B50\u673A\u6784\uFF01
dept.delete.failed.child.exists=\u5B58\u5728\u4E0B\u7EA7\u673A\u6784\uFF0C\u4E0D\u5141\u8BB8\u5220\u9664
dept.delete.failed.user.exists=\u673A\u6784\u5B58\u5728\u7528\u6237\uFF0C\u4E0D\u5141\u8BB8\u5220\u9664
##Dict
dict.add.failed.type.exists=\u65B0\u589E\u5B57\u5178[{}]\u5931\u8D25\uFF0C\u5B57\u5178\u7C7B\u578B\u5DF2\u5B58\u5728
dict.update.failed.type.exists=\u65B0\u589E\u5B57\u5178[{}]\u5931\u8D25\uFF0C\u5B57\u5178\u7C7B\u578B\u5DF2\u5B58\u5728
##Index
index.welcome.message=\u6B22\u8FCE\u4F7F\u7528{}\u540E\u53F0\u7BA1\u7406\u6846\u67B6\uFF0C\u5F53\u524D\u7248\u672C\uFF1Av{}\uFF0C\u8BF7\u901A\u8FC7\u524D\u7AEF\u5730\u5740\u8BBF\u95EE\u3002
##Menu
menu.add.failed.name.exists=\u65B0\u589E\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u83DC\u5355\u540D\u79F0\u5DF2\u5B58\u5728
menu.add.failed.path.not.valid=\u65B0\u589E\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u5730\u5740\u5FC5\u987B\u4EE5http(s)://\u5F00\u5934
menu.update.failed.name.exists=\u4FEE\u6539\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u83DC\u5355\u540D\u79F0\u5DF2\u5B58\u5728
menu.update.failed.path.not.valid=\u4FEE\u6539\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u5730\u5740\u5FC5\u987B\u4EE5http(s)://\u5F00\u5934
menu.update.failed.parent.not.valid=\u4FEE\u6539\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u4E0A\u7EA7\u83DC\u5355\u4E0D\u80FD\u9009\u62E9\u81EA\u5DF1
menu.delete.failed.child.exists=\u5B58\u5728\u5B50\u83DC\u5355,\u4E0D\u5141\u8BB8\u5220\u9664
menu.delete.failed.role.exists=\u83DC\u5355\u5DF2\u5206\u914D,\u4E0D\u5141\u8BB8\u5220\u9664
##Post
post.add.failed.name.exists=\u65B0\u589E\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u540D\u79F0\u5DF2\u5B58\u5728
post.add.failed.code.exists=\u65B0\u589E\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u7F16\u7801\u5DF2\u5B58\u5728
post.update.failed.name.exists=\u4FEE\u6539\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u540D\u79F0\u5DF2\u5B58\u5728
post.update.failed.code.exists=\u4FEE\u6539\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u7F16\u7801\u5DF2\u5B58\u5728
##User
user.username.exists=\u7CFB\u7EDF\u8D26\u53F7\u540D\u79F0\u5DF2\u5B58\u5728\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u8BD5
user.password.differ=\u4E24\u6B21\u5BC6\u7801\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165
user.add.failed.name.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u767B\u5F55\u8D26\u53F7\u5DF2\u5B58\u5728
user.add.failed.phone.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u624B\u673A\u53F7\u7801\u5DF2\u5B58\u5728
user.add.failed.email.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u90AE\u7BB1\u8D26\u53F7\u5DF2\u5B58\u5728
user.update.failed.password.wrong=\u4FEE\u6539\u5BC6\u7801\u5931\u8D25\uFF0C\u65E7\u5BC6\u7801\u9519\u8BEF
user.update.failed.password.repeat=\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E0E\u65E7\u5BC6\u7801\u76F8\u540C
user.update.password.failed=\u4FEE\u6539\u5BC6\u7801\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.update.failed.name.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u767B\u5F55\u8D26\u53F7\u5DF2\u5B58\u5728
user.update.failed.phone.exists=\u4FEE\u6539\u7528\u6237[{}]\u5931\u8D25\uFF0C\u624B\u673A\u53F7\u7801\u5DF2\u5B58\u5728
user.update.failed.email.exists=\u4FEE\u6539\u7528\u6237[{}]\u5931\u8D25\uFF0C\u90AE\u7BB1\u8D26\u53F7\u5DF2\u5B58\u5728
user.update.failed=\u4FEE\u6539\u4E2A\u4EBA\u4FE1\u606F\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.delete.failed=\u5F53\u524D\u7528\u6237\u4E0D\u80FD\u5220\u9664
user.upload.avatar.failed=\u4E0A\u4F20\u56FE\u7247\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.not.login=\u8BF7\u767B\u5F55\u540E\u91CD\u8BD5
user.access.denied=\u7528\u6237\u62D2\u7EDD\u8BBF\u95EE
##Role
role.add.manager.failed=\u4E0D\u5141\u8BB8\u8BBE\u7F6E\u7BA1\u7406\u5458\u89D2\u8272\u6807\u8BC6
role.add.failed.name.exists=\u65B0\u589E\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u540D\u79F0\u5DF2\u5B58\u5728
role.add.failed.key.exists=\u65B0\u589E\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u6743\u9650\u5DF2\u5B58\u5728
role.update.failed.name.exists=\u4FEE\u6539\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u540D\u79F0\u5DF2\u5B58\u5728
role.update.failed.key.exists=\u4FEE\u6539\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u6743\u9650\u5DF2\u5B58\u5728
role.update.failed=\u4FEE\u6539\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
##Import
import.failed.file.null=\u5BFC\u5165\u5931\u8D25\uFF0C\u8BF7\u5148\u4E0A\u4F20\u6587\u4EF6\uFF01
import.failed.data.null=\u5BFC\u5165\u5931\u8D25\uFF0C\u5BFC\u5165\u6570\u636E\u4E3A\u7A7A\uFF01
import.failed.device.name.null=\u5BFC\u5165\u5931\u8D25\uFF0C\u6A21\u677F\u91CC\u8BBE\u5907\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A\uFF01
import.success=\u5BFC\u5165\u6210\u529F
import.fail=\u5bfc\u5165\u5931\u8d25
##General
success=\u6210\u529F
fail=\u5931\u8D25
query.success=\u67E5\u8BE2\u6210\u529F
operate.success=\u64CD\u4F5C\u6210\u529F
operate.fail=\u64cd\u4f5c\u5931\u8d25
create.success=\u521B\u5EFA\u6210\u529F
create.failed=\u521B\u5EFA\u5931\u8D25
save.success=\u4FDD\u5B58\u6210\u529F
save.failed=\u4FDD\u5B58\u5931\u8D25
authorization.success=\u6388\u6743\u6210\u529F
delete.success=\u5220\u9664\u6210\u529f
delete.fail=\u5220\u9664\u5931\u8d25
bind.success=\u7ed1\u5b9a\u6210\u529f
bind.fail=\u7ed1\u5b9a\u5931\u8d25
unbind.success=\u89e3\u7ed1\u6210\u529f
unbind.fail=\u89e3\u7ed1\u5931\u8d25
captcha.fail=\u9a8c\u8bc1\u7801\u9519\u8bef
import.fail.[{}]=\u5bfc\u5165\u5931\u8d25\uff1a[{}]
only.allow.tenant.config=\u53ea\u5141\u8bb8\u79df\u6237\u914d\u7f6e
password.fail=\u5bc6\u7801\u9519\u8bef
login.success=\u767b\u5f55\u6210\u529f
##Email
email.format.error=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF
email.verification.code.send=\u90AE\u7BB1\u9A8C\u8BC1\u7801\u5DF2\u53D1\u9001
##Firmware
firmware.task.upgrade.failed.time.not.valid=\u9884\u5B9A\u5347\u7EA7\u65F6\u95F4\u5E94\u5927\u4E8E\u5F53\u524D\u65F6\u95F4
##Media
media.record.query.failed=\u8FDE\u63A5\u8D85\u65F6\u6216\u53D1\u751F\u9519\u8BEF\uFF0C\u672A\u83B7\u53D6\u5230\u6570\u636E
##Modbus
modbus.type.null=\u7C7B\u578B\u4E3A\u7A7A
modbus.crc.check.abnormal=crc\u6821\u9a8c\u5f02\u5e38
##Netty
netty.client.not.exists=\u5BA2\u6237\u7AEF\u4E0D\u5B58\u5728
##Runtime
runtime.message.id.null=\u6D88\u606Fid\u4E3A\u7A7A
##Wechat
wechat.verify.type.null=\u8BF7\u4F20\u5165\u9A8C\u8BC1\u65B9\u5F0F
wechat.bind.message.id.null=\u8BF7\u4F20\u5165\u7ED1\u5B9A\u4FE1\u606FID
wechat.please.config.open.platform=\u8bf7\u5148\u914d\u7f6e\u5fae\u4fe1\u5f00\u653e\u5e73\u53f0\u79fb\u52a8\u5e94\u7528\u4fe1\u606f
wechat.user.certificate.gain.fail=\u7528\u6237\u51ed\u8bc1\u83b7\u53d6\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.please.config.open.platform.mini=\u8bf7\u5148\u914d\u7f6e\u5fae\u4fe1\u516c\u4f17\u5e73\u53f0\u5c0f\u7a0b\u5e8f\u4fe1\u606f\uff01
wechat.user.phone.certificate.gain.fail=\u7528\u6237\u624b\u673a\u53f7\u51ed\u8bc1\u83b7\u53d6\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.gain.user.call.certificate.fail=\u83b7\u53d6\u7528\u6237\u8c03\u7528\u51ed\u636e\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.gain.user.phone.fail=\u83b7\u53d6\u7528\u6237\u624b\u673a\u53f7\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.please.login=\u8bf7\u5148\u767b\u5f55\u540e\u91cd\u8bd5
wechat.please.enter.user.password=\u8bf7\u4f20\u5165\u7528\u6237\u5bc6\u7801
wechat.cancelBind.password.fail=\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165
wechat.please.enter.wechat.user.info=\u8bf7\u4f20\u5165\u5fae\u4fe1\u7528\u6237\u4fe1\u606f
wechat.please.enter.user.certificate=\u8bf7\u4f20\u5165\u7528\u6237\u51ed\u8bc1
wechat.gain.wechat.info.fail=\u83b7\u53d6\u5fae\u4fe1\u4fe1\u606f\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\uff01
wechat.your.wechat.already.bind.other.account=\u60a8\u7684\u5fae\u4fe1\u5df2\u7ed1\u5b9a\u5176\u4ed6\u8d26\u53f7\uff0c\u8bf7\u5148\u4f7f\u7528\u5fae\u4fe1\u767b\u5f55\u89e3\u7ed1\u540e\u91cd\u8bd5
wechat.this.wechat.already.bind.other.account=\u8be5\u5fae\u4fe1\u5df2\u7ed1\u5b9a\u5176\u4ed6\u8d26\u53f7\uff0c\u8bf7\u5148\u4f7f\u7528\u5fae\u4fe1\u767b\u5f55\u89e3\u7ed1\u540e\u91cd\u8bd5\uff01
wechat.please.config.open.platform.web.application.personal.bind.info=\u8bf7\u5148\u914d\u7f6e\u5fae\u4fe1\u5f00\u653e\u5e73\u53f0\u7f51\u7ad9\u5e94\u7528\u4e2a\u4eba\u4e2d\u5fc3\u7ed1\u5b9a\u4fe1\u606f
wechat.you.cancel.or.not.gain.authorization.info=\u60a8\u5df2\u53d6\u6d88\u6388\u6743\u6216\u672a\u83b7\u53d6\u5230\u6388\u6743\u4fe1\u606f
wechat.the.qr.code.has.expired=\u4e8c\u7ef4\u7801\u5df2\u5931\u6548\uff0c\u8bf7\u91cd\u65b0\u70b9\u51fb\u7ed1\u5b9a
wechat.your.account.already.bind.wechat=\u60a8\u7684\u8d26\u53f7\u5df2\u7ed1\u5b9a\u5fae\u4fe1\uff0c\u8bf7\u5148\u89e3\u7ed1
##AuthResource
auth.resource.product.query.success=\u67E5\u8BE2\u4EA7\u54C1\u5217\u8868\u6210\u529F
##Device
device.user.id.null=\u7528\u6237ID\u4E0D\u80FD\u4E3A\u7A7A
device.product.id.null=\u8BBE\u5907\u7F16\u53F7\u548C\u4EA7\u54C1ID\u4E0D\u80FD\u4E3A\u7A7A
device.dept.id.null=\u8BF7\u9009\u62E9\u5206\u914D\u673A\u6784
device.id.null=\u8BF7\u9009\u62E9\u8BBE\u5907
device.not.select=\u8bf7\u9009\u62e9\u8bbe\u5907
device.serialNumber.not.empty=\u8bbe\u5907\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
device.delete.fail.please.delete.device.scene=\u8bbe\u5907\u7f16\u53f7\u4e3a[{}]\u7684\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u8bbe\u5907\u4e0b\u7684\u573a\u666f\u8054\u52a8
device.tenant.can.not.bind.exist.device=\u79df\u6237\u4e0d\u5141\u8bb8\u7ed1\u5b9a\u5df2\u5b58\u5728\u7684\u8bbe\u5907\uff0c\u8bbe\u5907\u7f16\u53f7\uff1a[{}]
now.user.belong.device.can.not.repeat.share=\u5f53\u524d\u7528\u6237\u5df2\u62e5\u6709\u8be5\u8bbe\u5907\uff0c\u65e0\u6cd5\u91cd\u590d\u5206\u914d\uff0c\u8bbe\u5907\u7f16\u53f7\uff1a[{}]
device.share.other.user.can.not.share=\u8be5\u8bbe\u5907\u5df2\u88ab\u5206\u914d\u5230\u5176\u4ed6\u7528\u6237\uff0c\u65e0\u6cd5\u91cd\u590d\u5206\u914d\uff0c\u8bbe\u5907\u7f16\u53f7\uff1a[{}]
device.not.exist.add.fail.please.check.product.id.is.correct=\u8bbe\u5907\u4e0d\u5b58\u5728\uff0c\u81ea\u52a8\u6dfb\u52a0\u8bbe\u5907\u65f6\u5931\u8d25\uff0c\u8bf7\u68c0\u67e5\u4ea7\u54c1\u7f16\u53f7\u662f\u5426\u6b63\u786e
device.add.success=\u6dfb\u52a0\u8bbe\u5907\u6210\u529f
device.assignment.fail.dept.not.exist=\u673a\u6784\u4e0d\u5b58\u5728\u6216\u672a\u7ed1\u5b9a\u7ba1\u7406\u5458\uff0c\u8bf7\u8c03\u6574\u540e\u91cd\u8bd5\uff01
device.assignment.fail.dept.admin.not.exist=\u673a\u6784\u7ba1\u7406\u5458\u4e0d\u5b58\u5728
device.assignment.success=\u5206\u914d\u8bbe\u5907\u6210\u529f
device.assignment.fail=\u5206\u914d\u8bbe\u5907\u5931\u8d25
device.recovery.fail.dept.not.exist=\u673a\u6784\u4e0d\u5b58\u5728\u6216\u672a\u7ed1\u5b9a\u7ba1\u7406\u5458\uff0c\u8bf7\u8c03\u6574\u540e\u91cd\u8bd5\uff01
device.recovery.fail.dept.admin.not.exist=\u673a\u6784\u7ba1\u7406\u5458\u4e0d\u5b58\u5728
device.recovery.success=\u56de\u6536\u8bbe\u5907\u6210\u529f
device.recovery.fail=\u56de\u6536\u8bbe\u5907\u5931\u8d25
device.not.exist=\u8bbe\u5907\u4e0d\u5b58\u5728
device.serialNumber.allow.generate.max.number=\u6700\u591a\u53ea\u80fd\u751f\u6210200\u4e2a\uff01
device.insert.fail.device.number.already.exist=\u8bbe\u5907\u7f16\u53f7\uff1a[{}] \u5df2\u7ecf\u5b58\u5728\uff0c\u65b0\u589e\u5931\u8d25
device.get.mqtt.connection.param.fail=\u83b7\u53d6\u8bbe\u5907mqtt\u8fde\u63a5\u53c2\u6570\u5931\u8d25
device.get.authorization.fail.please.config=\u4ea7\u54c1\u5df2\u542f\u7528\u6388\u6743\uff0c\u83b7\u53d6\u8bbe\u5907\u6388\u6743\u7801\u5931\u8d25\uff0c\u8bf7\u5148\u914d\u7f6e\u6388\u6743\u7801
##DeviceJob
job.add.failed.cron.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0CCron\u8868\u8FBE\u5F0F\u4E0D\u6B63\u786E
job.add.failed.rmi.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'rmi'\u8C03\u7528
job.add.failed.ldap.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'ldap(s)'\u8C03\u7528
job.add.failed.http.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'http(s)'\u8C03\u7528
job.add.failed.string.error=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u5B58\u5728\u8FDD\u89C4
job.add.failed.string.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5728\u767D\u540D\u5355\u5185
job.add.failed.product.not.modbus.config=\u65b0\u589e\u4efb\u52a1[{}]\u5931\u8d25\uff0c\u8bf7\u5148\u53bb\u4ea7\u54c1\u8fdb\u884cmodbus\u914d\u7f6e
job.update.failed.cron.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0CCron\u8868\u8FBE\u5F0F\u4E0D\u6B63\u786E
job.update.failed.rmi.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'rmi'\u8C03\u7528
job.update.failed.ldap.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'ldap(s)'\u8C03\u7528
job.update.failed.http.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'http(s)'\u8C03\u7528
job.update.failed.string.error=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u5B58\u5728\u8FDD\u89C4
job.update.failed.string.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5728\u767D\u540D\u5355\u5185
job.update.failed.product.not.modbus.config=\u66f4\u65b0\u4efb\u52a1[{}]\u5931\u8d25\uff0c\u8bf7\u5148\u53bb\u4ea7\u54c1\u8fdb\u884cmodbus\u914d\u7f6e
job.not.exists=\u4EFB\u52A1\u4E0D\u5B58\u5728\u6216\u5DF2\u8FC7\u671F
##DeviceUser
device.user.delete.failed.user.not.valid=\u8BBE\u5907\u6240\u6709\u8005\u4E0D\u80FD\u5220\u9664
##GoviewProject
goview.project.data.save.failed.id.null=\u6CA1\u6709\u8BE5\u9879\u76EEID
goview.project.data.execute.sql.failed=\u8BF7\u7F16\u5199sql\u8BED\u53E5
##ThingsModel
things.model.identifier.repeat=\u4EA7\u54C1\u4E0B\u7684\u6807\u8BC6\u7B26\u4E0D\u80FD\u91CD\u590D
things.model.import.failed.identifier.repeat=[{}]\u6761\u6570\u636E\u672A\u5BFC\u5165\uFF0C\u6807\u8BC6\u7B26\u91CD\u590D
things.model.update.fail.quote.the.scene.variable.formula.please.delete=\u5f53\u524d\u7269\u6a21\u578b\u88ab\u5f15\u7528\u5230\u573a\u666f\u8fd0\u7b97\u578b\u53d8\u91cf\u7684\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8bf7\u5148\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u4fee\u6539\u64cd\u4f5c\uff01
things.model.delete.fail.quote.the.scene.variable.formula.please.delete=\u5f53\u524d\u7269\u6a21\u578b\u88ab\u5f15\u7528\u5230\u573a\u666f\u8fd0\u7b97\u578b\u53d8\u91cf\u7684\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u5220\u9664\uff0c\u8bf7\u5148\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff01
things.model.import.data.exception=\u5bfc\u5165\u6570\u636e\u5f02\u5e38
things.model.register.address.repeat=\u540c\u4e00\u4e2a\u91c7\u96c6\u70b9\u6a21\u677f\u4e0b,\u5bc4\u5b58\u5668\u5730\u5740\u91cd\u590d,\u8bf7\u68c0\u67e5\u5bfc\u5165\u53d8\u91cf\u5bc4\u5b58\u5668\u5730\u5740
##MQTT
mqtt.unauthorized=mqtt\u8D26\u53F7\u548C\u5BC6\u7801\u4E0E\u8BA4\u8BC1\u670D\u52A1\u5668\u914D\u7F6E\u4E0D\u5339\u914D
##Oauth
oauth.response.type.not.valid=response_type\u53C2\u6570\u503C\u53EA\u5141\u8BB8code\u548Ctoken
oauth.grant.type.null=\u672A\u77E5\u6388\u6743\u7C7B\u578B
oauth.grant.type.implicit.not.support=Token\u63A5\u53E3\u4E0D\u652F\u6301implicit\u6388\u6743\u6A21\u5F0F
oauth.access.token.null=\u8BBF\u95EE\u4EE4\u724C\u4E0D\u80FD\u4E3A\u7A7A
obtain.basic.authorization.failed=client_id\u6216client_secret\u672A\u6B63\u786E\u4F20\u9012
##Record
record.app.null=app\u4E0D\u80FD\u4E3A\u7A7A
record.stream.null=stream\u4E0D\u80FD\u4E3A\u7A7A
record.time.not.valid=\u9519\u8BEF\u7684\u5F00\u59CB\u65F6\u95F4\u6216\u7ED3\u675F\u65F6\u95F4
record.file.null=\u672A\u627E\u5230\u89C6\u9891\u6587\u4EF6
##ErrorCodeConstants
app.not.found=App \u4E0D\u5B58\u5728
app.is.disable=App \u5DF2\u7ECF\u88AB\u7981\u7528
app.exist.order.cant.delete=\u652F\u4ED8\u5E94\u7528\u5B58\u5728\u652F\u4ED8\u8BA2\u5355\uFF0C\u65E0\u6CD5\u5220\u9664
app.exist.refund.cant.delete=\u652F\u4ED8\u5E94\u7528\u5B58\u5728\u9000\u6B3E\u8BA2\u5355\uFF0C\u65E0\u6CD5\u5220\u9664
channel.not.found=\u652F\u4ED8\u6E20\u9053\u7684\u914D\u7F6E\u4E0D\u5B58\u5728
channel.is.disable=\u652F\u4ED8\u6E20\u9053\u5DF2\u7ECF\u7981\u7528
channel.exists.same.channel.error=\u5DF2\u5B58\u5728\u76F8\u540C\u7684\u6E20\u9053
order.not.found=\u652F\u4ED8\u8BA2\u5355\u4E0D\u5B58\u5728
order.status.is.not.waiting=\u652F\u4ED8\u8BA2\u5355\u4E0D\u5904\u4E8E\u5F85\u652F\u4ED8
order.status.is.success=\u8BA2\u5355\u5DF2\u652F\u4ED8\uFF0C\u8BF7\u5237\u65B0\u9875\u9762
order.is.expired=\u652F\u4ED8\u8BA2\u5355\u5DF2\u7ECF\u8FC7\u671F
order.submit.channel.error=\u53D1\u8D77\u652F\u4ED8\u62A5\u9519\uFF0C\u9519\u8BEF\u7801\uFF1A{}\uFF0C\u9519\u8BEF\u63D0\u793A\uFF1A{}
order.refund.fail.status.error=\u652F\u4ED8\u8BA2\u5355\u9000\u6B3E\u5931\u8D25\uFF0C\u539F\u56E0\uFF1A\u72B6\u6001\u4E0D\u662F\u5DF2\u652F\u4ED8\u6216\u5DF2\u9000\u6B3E
order.extension.not.found=\u652F\u4ED8\u4EA4\u6613\u62D3\u5C55\u5355\u4E0D\u5B58\u5728
order.extension.status.is.not.waiting=\u652F\u4ED8\u4EA4\u6613\u62D3\u5C55\u5355\u4E0D\u5904\u4E8E\u5F85\u652F\u4ED8
order.extension.is.paid=\u8BA2\u5355\u5DF2\u652F\u4ED8\uFF0C\u8BF7\u7B49\u5F85\u652F\u4ED8\u7ED3\u679C
refund.price.exceed=\u9000\u6B3E\u91D1\u989D\u8D85\u8FC7\u8BA2\u5355\u53EF\u9000\u6B3E\u91D1\u989D
refund.has.refunding=\u5DF2\u7ECF\u6709\u9000\u6B3E\u5728\u5904\u7406\u4E2D
refund.exists=\u5DF2\u7ECF\u5B58\u5728\u9000\u6B3E\u5355
refund.not.found=\u652F\u4ED8\u9000\u6B3E\u5355\u4E0D\u5B58\u5728
refund.statue.is.not.waiting=\u652F\u4ED8\u9000\u6B3E\u5355\u4E0D\u5904\u4E8E\u5F85\u9000\u6B3E
demo.order.not.found=\u793A\u4F8B\u8BA2\u5355\u4E0D\u5B58\u5728
demo.order.update.paid.status.not.unpaid=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u8BA2\u5355\u4E0D\u662F\u3010\u672A\u652F\u4ED8\u3011\u72B6\u6001
demo.order.update.paid.fail.pay.order.id.error=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u652F\u4ED8\u5355\u7F16\u53F7\u4E0D\u5339\u914D
demo.order.update.paid.fail.pay.order.status.not.success=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u652F\u4ED8\u5355\u72B6\u6001\u4E0D\u662F\u3010\u652F\u4ED8\u6210\u529F\u3011\u72B6\u6001
demo.order.update.paid.fail.pay.price.not.match=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u652F\u4ED8\u5355\u91D1\u989D\u4E0D\u5339\u914D
demo.order.refund.fail.not.paid=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u793A\u4F8B\u8BA2\u5355\u672A\u652F\u4ED8
demo.order.refund.fail.refunded=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u793A\u4F8B\u8BA2\u5355\u5DF2\u9000\u6B3E
demo.order.refund.fail.refund.not.found=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u8BA2\u5355\u4E0D\u5B58\u5728
demo.order.refund.fail.refund.not.success=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u8BA2\u5355\u672A\u9000\u6B3E\u6210\u529F
demo.order.refund.fail.refund.order.id.error=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u5355\u7F16\u53F7\u4E0D\u5339\u914D
demo.order.refund.fail.refund.price.not.match=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u5355\u91D1\u989D\u4E0D\u5339\u914D
device.order.control.no.permission=\u6682\u65e0\u6743\u9650\u64cd\u4f5c\uff0c\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u5206\u914d\u6307\u4ee4\u6743\u9650\uff01
##sysConfig
sysConfig.add.param.fail.name.exist=\u65b0\u589e\u53c2\u6570[{}]\u5931\u8d25\uff0c\u53c2\u6570\u952e\u540d\u5df2\u5b58\u5728
sysConfig.update.param.fail.name.exist=\u4fee\u6539\u53c2\u6570[{}]\u5931\u8d25\uff0c\u53c2\u6570\u952e\u540d\u5df2\u5b58\u5728
##sysRegister
sysRegister.fail.not.enable.register=\u5f53\u524d\u7cfb\u7edf\u6ca1\u6709\u5f00\u542f\u6ce8\u518c\u529f\u80fd\uff01
##ossDetail
ossDetail.fail.file.not.empty=\u4e0a\u4f20\u6587\u4ef6\u4e0d\u80fd\u4e3a\u7a7a
##notify
sms.send.fail.contact.admin=\u77ed\u4fe1\u53d1\u9001\u5931\u8d25\uff0c\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\uff01
captcha.has.sent.please.try.again.later=\u9a8c\u8bc1\u7801\u5df2\u53d1\u9001\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5\uff01
not.find.enable.notify.template=\u67e5\u8be2\u4e0d\u5230\u542f\u7528\u7684\u901a\u77e5\u6a21\u677f
not.find.notify.channel=\u67e5\u8be2\u4e0d\u5230\u901a\u77e5\u6e20\u9053
##dataCenter
please.select.device=\u8bf7\u9009\u62e9\u8bbe\u5907
please.incoming.serialNumber=\u8bf7\u4f20\u5165\u8bbe\u5907\u7f16\u53f7
##license
certificate.install.success=\u8bc1\u4e66\u5b89\u88c5\u6210\u529f
certificate.install.fail=\u8bc1\u4e66\u5b89\u88c5\u5931\u8d25:[{}]
certificate.incoming.success=\u8bc1\u4e66\u4e0a\u4f20\u6210\u529f
certificate.incoming.fail=\u8bc1\u4e66\u4e0a\u4f20\u5931\u8d25
certificate.upload.success=\u8bc1\u4e66\u4e0a\u4f20\u6210\u529f
certificate.upload.fail=\u8bc1\u4e66\u4e0a\u4f20\u5931\u8d25:[{}]
##sceneModel
please.incoming.scene.id=\u8bf7\u4f20\u5165\u573a\u666fid
please.incoming.device.config.number=\u8bf7\u4f20\u5165\u5173\u8054\u8bbe\u5907\u914d\u7f6e\u7684\u5e8f\u53f7
sceneModel.please.introduced.id=\u8bf7\u4f20\u5165\u573a\u666f\u7ba1\u7406id
sceneModel.current.variable.quote.operate.variable.formula.please.delete=\u5f53\u524d\u53d8\u91cf\u88ab\u5f15\u7528\u5230\u573a\u666f\u8fd0\u7b97\u578b\u53d8\u91cf\u7684\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u5220\u9664\uff0c\u8bf7\u5148\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff01
sceneModel.scene.already.bind.device=\u573a\u666f\u5df2\u7ed1\u5b9a\u8be5\u8bbe\u5907\uff0c\u8bf7\u91cd\u65b0\u9009\u62e9\uff01
sceneModel.update.fail.device.variable.has.quote.scene.variable.please.delete=\u5f53\u524d\u8bbe\u5907\u4e0b\u5b58\u5728\u53d8\u91cf\u88ab\u5f15\u7528\u5230\u8fd0\u7b97\u578b\u53d8\u91cf\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8bf7\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u4fee\u6539\u64cd\u4f5c\uff01
sceneModel.delete.fail.device.variable.has.quote.scene.variable.please.delete=\u5f53\u524d\u8bbe\u5907\u4e0b\u5b58\u5728\u53d8\u91cf\u88ab\u5f15\u7528\u5230\u8fd0\u7b97\u578b\u53d8\u91cf\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u5220\u9664\uff0c\u8bf7\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff01
sceneModel.formula.cannot.empty=\u8ba1\u7b97\u516c\u5f0f\u4e0d\u80fd\u4e3a\u7a7a\uff01
sceneModel.variable.cannot.empty=\u53d8\u91cf\u4e0d\u80fd\u4e3a\u7a7a\uff01
sceneModel.formula.and.variable.number.inconsistent=\u8ba1\u7b97\u516c\u5f0f\u548c\u53d8\u91cf\u4e2a\u6570\u4e0d\u4e00\u81f4\uff0c\u8bf7\u68c0\u67e5\u540e\u91cd\u8bd5
sceneModel.update.fail.variable.name.exist=\u53d8\u91cf\u540d\u79f0\u5df2\u5b58\u5728\uff0c\u8bf7\u4fee\u6539\u540e\u91cd\u8bd5\uff01
##oauthClientDetail
add.fail.same.client.can.config.one=\u540c\u4e00\u4e2a\u6388\u6743\u5e73\u53f0\u53ea\u80fd\u914d\u7f6e\u4e00\u6761\u4fe1\u606f\uff0c\u8bf7\u52ff\u91cd\u590d\u914d\u7f6e
client.id.is.exist=\u5ba2\u6237\u7aefid\uff1a[{}]\u5df2\u5b58\u5728\u6216\u5df2\u88ab\u5176\u4ed6\u79df\u6237\u4f7f\u7528
oauthClientDetail.client.not.exist=oauth2 \u5ba2\u6237\u7aef\u4e0d\u5b58\u5728
oauthClientDetail.client.disabled=oauth2 \u5ba2\u6237\u7aef\u5df2\u7981\u7528
oauthClientDetail.invalid.client.set=\u65e0\u6548 client_secret
oauthClientDetail.invalid.redirects=\u65e0\u6548 redirect_uri\uff1a[{}]
##category
delete.fail.please.delete.category.product=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u5206\u7c7b\u4e0b\u7684\u4ea7\u54c1
##goviewProjectData
only.allow.select.operate=\u53ea\u5141\u8bb8select\u64cd\u4f5c\uff0c\u7981\u6b62update\u3001delete\u3001insert\u64cd\u4f5c
##newsCategory
newsCategory.delete.fail.please.delete.category.info=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u5206\u7c7b\u4e0b\u7684\u65b0\u95fb\u8d44\u8baf
##product
delete.fail.please.delete.firmware=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u4ea7\u54c1\u4e0b\u7684\u56fa\u4ef6
delete.fail.please.delete.product.device=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u4ea7\u54c1\u4e0b\u7684\u8bbe\u5907
delete.fail.please.delete.product.scene=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u4fee\u6539\u6216\u5220\u9664\u5bf9\u5e94\u4ea7\u54c1\u4e0b\u7684\u573a\u666f\u8054\u52a8\uff1a[{}]
product.status.update.fail.value.fail=\u72b6\u6001\u66f4\u65b0\u5931\u8d25,\u72b6\u6001\u503c\u6709\u8bef
product.status.update.fail=\u72b6\u6001\u66f4\u65b0\u5931\u8d25
##socialLogin
bind.account.not.exist=\u7ed1\u5b9a\u8d26\u6237\u4e0d\u5b58\u5728
socialLogin.verify.has.expired=\u9a8c\u8bc1\u7801\u5df2\u5931\u6548\uff0c\u8bf7\u91cd\u65b0\u83b7\u53d6
socialLogin.platform.type.fail=\u9519\u8bef\u5e73\u53f0\u7c7b\u578b
user.account.and.bind.account.not.match=\u7528\u6237\u8d26\u6237\u548c\u7ed1\u5b9a\u8d26\u6237\u4e0d\u5339\u914d
socialLogin.user.not.exist=\u7528\u6237\u4e0d\u5b58\u5728
socialLogin.bind.end.user.cannot.login.web=\u8bf7\u52ff\u7ed1\u5b9a\u7ec8\u7aef\u7528\u6237\uff0c\u7ed1\u5b9a\u7ec8\u7aef\u7528\u6237\u540e\u4e0d\u53ef\u767b\u5f55web\u7aef
socialLogin.account.already.bind.other.wechat.please.unbind=\u8be5\u8d26\u53f7\u5df2\u7ecf\u7ed1\u5b9a\u5176\u4ed6\u5fae\u4fe1\uff0c\u8bf7\u5148\u89e3\u7ed1\u540e\u91cd\u8bd5\uff01
socialLogin.register.fail.please.check.role.exist=\u6ce8\u518c\u5931\u8d25,\u8bf7\u8054\u7cfb\u7ba1\u7406\u4eba\u5458\u68c0\u67e5\u673a\u6784\u89d2\u8272\u662f\u5426\u5b58\u5728
socialLogin.web.not.allow.end.user.login=web\u7aef\u4e0d\u5141\u8bb8\u7ec8\u7aef\u7528\u6237\u767b\u5f55
##alert
alert.push.fail.device.not.exist=\u544a\u8b66\u63a8\u9001\uff0c\u8bbe\u5907\u4e0d\u5b58\u5728\uff1a[{}]
##modbus
not.modbus.protocol.please.config.collect.protocol=\u975emodbus\u534f\u8bae\u8bf7\u5148\u914d\u7f6e\u4e3b\u52a8\u91c7\u96c6\u534f\u8bae
modbus.point.not.config=\u672a\u914d\u7f6emodbus\u70b9\u4f4d
##ota
firmwareTask.add.fail.FirmwareTask.exist=\u4efb\u52a1\uff1a[{}]\u5df2\u5b58\u5728
firmware.version.not.exist=\u56fa\u4ef6\u7248\u672c\u4e0d\u5b58\u5728%21
##mqttMessage
mqtt.service.send.device.not.exist=\u670d\u52a1\u4e0b\u53d1\u7684\u8bbe\u5907\uff1a[{}]\u4e0d\u5b58\u5728
mqtt.disconnect.occur.fail=\u65ad\u5f00mqtt\u8fde\u63a5\u53d1\u751f\u9519\u8bef\uff1a[{}]
##genTable
genTable.template.rendering.fail=\u5bfc\u5165\u5931\u8d25\uff1a[{}]
genTable.data.sync.fail.original.table.not.exist=\u540c\u6b65\u6570\u636e\u5931\u8d25\uff0c\u539f\u8868\u7ed3\u6784\u4e0d\u5b58\u5728
genTable.tree.code.field.cannot.empty=\u6811\u7f16\u7801\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a
genTable.tree.parent.code.field.cannot.empty=\u6811\u7236\u7f16\u7801\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a
genTable.tree.name.field.cannot.empty=\u6811\u540d\u79f0\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a
genTable.relate.child.table.name.cannot.empty=\u5173\u8054\u5b50\u8868\u7684\u8868\u540d\u4e0d\u80fd\u4e3a\u7a7a
genTable.child.table.relate.foreign.key.name.cannot.empty=\u5b50\u8868\u5173\u8054\u7684\u5916\u952e\u540d\u4e0d\u80fd\u4e3a\u7a7a
##oauthCode
oauthCode.code.not.exist=code \u4e0d\u5b58\u5728
##protocol
protocol.input.content.is.empty=\u8f93\u5165\u5185\u5bb9\u4e3a\u7a7a
protocol.data.parse.error=\u6570\u636e\u89e3\u6790\u51fa\u9519[{}]
protocol.data.parse.exception=\u6570\u636e\u89e3\u6790\u5f02\u5e38[{}]
protocol.instruction.number.exception=\u6307\u4ee4\u7f16\u53f7\u5f02\u5e38\uff1a[{}]
##modbusJob
modbusJob.add.fail.please.bind.gateway=\u8bf7\u5148\u7ed1\u5b9a\u7f51\u5173
thingsModel.array.or.object.no.need.update=\u6682\u65e0\u9700\u8981\u66f4\u65b0\u7684\u6570\u7ec4\u3001\u5bf9\u8c61\u7c7b\u7269\u6a21\u578b
sync.fail.please.try.again=\u540c\u6b65\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\uff01
sync.success=\u540c\u6b65\u6210\u529f
## scada
scada.product.id.is.null=\u4ea7\u54c1id\u4e3a\u7a7a
scada.scene.id.is.null=\u573a\u666fid\u4e3a\u7a7a
scada.guid.cannot.empty=guid\u4e0d\u80fd\u4e3a\u7a7a
scada.base64.change.image.exception=\u7ec4\u6001base64\u8f6c\u56fe\u7247\u5f02\u5e38:[{}]
scada.please.select.device=\u8bf7\u9009\u62e9\u8bbe\u5907
scada.please.enter.password=\u8bf7\u8f93\u5165\u5bc6\u7801\uff01
scada.please.login=\u672a\u767b\u5f55\uff0c\u8bf7\u767b\u5f55\u540e\u91cd\u8bd5
scada.password.fail.please.reload.enter=\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165\uff01
scada.product.has.relate.please.select.again=\u8be5\u4ea7\u54c1\u5df2\u7ecf\u5173\u8054\u7ec4\u6001\uff0c\u8bf7\u91cd\u65b0\u9009\u62e9\uff01
scada.scene.has.relate.please.select.again=\u8be5\u573a\u666f\u5df2\u7ecf\u5173\u8054\u7ec4\u6001\uff0c\u8bf7\u91cd\u65b0\u9009\u62e9\uff01
scada.not.allow.view.other.tenant.config=\u4e0d\u5141\u8bb8\u67e5\u770b\u5176\u4ed6\u79df\u6237\u7684\u7ec4\u6001\uff01
scada.upload.gallery.file.fail=\u4e0a\u4f20\u56fe\u5e93\u6587\u4ef6\u5f02\u5e38\uff0c[{}]
scada.upload.fail=\u4e0a\u4f20\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\uff01
scada.invalid.profile=\u65e0\u6548\u7684\u914d\u7f6e\u6587\u4ef6
scada.import.success.need.replace.variable=\u5bfc\u5165\u6210\u529f\uff0c\u5f53\u524d\u9875\u9762\u9700\u8981\u91cd\u65b0\u66ff\u6362\u7ed1\u5b9a\u7ec4\u4ef6\u7684\u53d8\u91cf\uff01
## speaker
speaker.product.has.relate=\u8be5\u4ea7\u54c1\u5df2\u5173\u8054\uff0c\u8bf7\u52ff\u91cd\u590d\u5173\u8054
speaker.product.relate.add.fail=\u65b0\u589e\u5931\u8d25
speaker.not.found.product.relate=\u672a\u67e5\u8be2\u5230\u4ea7\u54c1\u5173\u8054\u4fe1\u606f
##file
file.content.is.empty=\u6587\u4ef6\u5185\u5bb9\u4e3a\u7a7a
file.is.invalid=\u65e0\u6548\u7684\u6587\u4ef6

View File

@ -0,0 +1,398 @@
#\u9519\u8BEF\u6D88\u606F
not.null=Required
user.jcaptcha.error=The verification code is incorrect
user.jcaptcha.expire=The verification code has expired
user.not.exists=User does not exist/password is incorrect
user.password.not.match=User does not exist/password is incorrect
user.password.retry.limit.count=The password was entered incorrectly {0} times
user.password.retry.limit.exceed=The password was entered incorrectly {0} times and the account was locked for {1} minutes
user.password.delete=Sorry, your account has been deleted
user.blocked=The user has been blocked, please contact the administrator
role.blocked=The role has been banned, contact the administrator
user.logout.success=The exit was successful
length.not.valid=The length must be between {min} and {max} characters
user.username.not.valid=Consists of 2 to 20 characters, letters, numbers, or underscores and must start with a non-number
user.password.not.valid=5-50 characters
user.email.not.valid=The mailbox is malformed
user.mobile.phone.number.not.valid=The phone number is in the wrong format
user.login.success=Login successful
user.register.success=Registration is successful
user.notfound=Please log in again
user.forcelogout=The administrator forcibly logs out, please log back in
user.unknown.error=Unknown error, please log back in
##\u6743\u9650
no.permission=You don't have permissions for data, contact your administrator to add permissions [{0}]
no.create.permission=You do not have permission to create data, please contact your administrator to add permission [{0}]
no.update.permission=You do not have permission to modify the data, please contact the administrator to add permission [{0}]
no.delete.permission=You do not have permission to delete data, please contact your administrator to add permission [{0}]
no.export.permission=You do not have permission to export data, please contact your administrator to add permission [{0}]
no.view.permission=You do not have permission to view the data, please contact your administrator to add permission [{0}]
##\u6587\u4EF6\u4E0A\u4F20\u6D88\u606F
upload.exceed.maxSize=The uploaded file size exceeds the limit file size! <br/>The maximum file size allowed is: {0}MB!
upload.filename.exceed.length=The uploaded file name can be up to {0} characters
upload.success=The upload is successful
##\u6587\u4EF6\u4E0B\u8F7D\u6D88\u606F
download.filename.not.valid=The file name [{}] is illegal and is not allowed to be downloaded
download.file.failed=Failed to download the file
download.resource.not.valid=The resource file [{}] is illegal and is not allowed to be downloaded
##Dept
dept.add.failed.name.exists=Failed to add organization [{}], and the organization name already exists
dept.update.failed.name.exists=Failed to modify organization [{}], and the organization name already exists
dept.update.failed.parent.not.valid=If the modification of the organization [{}] fails, the parent organization cannot be itself
dept.update.failed.child.not.valid=The agency contains sub-institutions that are not deactivated!
dept.delete.failed.child.exists=There are subordinate organizations and deletion is not allowed
dept.delete.failed.user.exists=If there are users in the organization, you cannot delete them
##Dict
dict.add.failed.type.exists=Failed to add dictionary [{}], the dictionary type already exists
dict.update.failed.type.exists=Failed to modify dictionary [{}], the dictionary type already exists
##Index
index.welcome.message=Welcome to the {} backend management framework, the current version: v{}, please access it through the front-end address.
##Menu
menu.add.failed.name.exists=Failed to add a new menu [{}], the menu name already exists
menu.add.failed.path.not.valid=Failed to add a new menu [{}] with an address starting with http(s)://
menu.update.failed.name.exists=Failed to modify menu [{}], menu name already exists
menu.update.failed.path.not.valid=Failed to modify menu [{}] with address starting with http(s)://
menu.update.failed.parent.not.valid=Failed to modify the menu [{}], the parent menu cannot select itself
menu.delete.failed.child.exists=A submenu exists and cannot be deleted
menu.delete.failed.role.exists=Menu is assigned and is not allowed to be deleted
##Post
post.add.failed.name.exists=Failed to add a new post [{}], and the job name already exists
post.add.failed.code.exists=Failed to add a new post [{}], and the post code already exists
post.update.failed.name.exists=Failed to modify the post [{}], the post name already exists
post.update.failed.code.exists=Failed to modify post [{}], the post code already exists
##User
user.username.exists=The system account name already exists, please modify it and try again
user.password.differ=The password is inconsistent twice, please re-enter it
user.add.failed.name.exists=The new user [{}] failed, and the login account already exists
user.add.failed.phone.exists=Failed to add user [{}], and the mobile phone number already exists
user.add.failed.email.exists=Failed to add user [{}], the email account already exists
user.update.failed.password.wrong=Failed to change the password, the old password is incorrect
user.update.failed.password.repeat=The new password cannot be the same as the old password
user.update.password.failed=If the password is abnormal, contact the administrator
user.update.failed.name.exists=The new user [{}] failed, and the login account already exists
user.update.failed.phone.exists=Failed to modify user [{}], mobile phone number already exists
user.update.failed.email.exists=Failed to modify user [{}], and the email account already exists
user.update.failed=If the personal information is abnormal, contact the administrator
user.delete.failed=The current user cannot be deleted
user.upload.avatar.failed=If the uploaded image is abnormal, contact the administrator
user.not.login=Please log in and try again
user.access.denied=Access denied by the user
##Role
role.add.manager.failed=Administrator role identity is not allowed
role.add.failed.name.exists=Failed to add a role [{}], the name of the role already exists
role.add.failed.key.exists=Failed to add a role [{}], and the role permissions already exist
role.update.failed.name.exists=Failed to modify the role [{}], the role name already exists
role.update.failed.key.exists=Failed to modify the role [{}], and the role permissions already exist
role.update.failed=Failed to modify the role [{}], contact the administrator
##Import
import.failed.file.null=Failed to import, please upload the file first!
import.failed.data.null=Failed to import, imported data is empty!
import.failed.device.name.null=Failed to import, the device name in the template cannot be empty!
import.success=The import is successful
import.fail=The import failed
##General
success=success
fail=failed
query.success=The query succeeds
operate.success=The operation succeeded
operate.fail=The operation failed
create.success=The creation is successful
create.failed=Failed to create
save.success=Save successfully
save.failed=Failed to save
authorization.success=Authorization succeeded
delete.success=Delete successfully
delete.fail=Delete failed
bind.success=Binding successful
bind.fail=Binding failed
unbind.success=Unbind successfully
unbind.fail=Unbinding failed
captcha.fail=Verification code error
import.fail.[{}]=Import failed: [{}]
only.allow.tenant.config=Only allow tenant configuration
password.fail=Password error
login.success=Login succeeded
##Email
email.format.error=The email address is malformed
email.verification.code.send=Email verification code sent
##Firmware
firmware.task.upgrade.failed.time.not.valid=The scheduled upgrade time should be greater than the current time
##Media
media.record.query.failed=The connection timed out or an error occurred and no data was obtained
##Modbus
modbus.type.null=type is empty
modbus.crc.check.abnormal=CRC check abnormal
##Netty
netty.client.not.exists=The client does not exist
##Runtime
runtime.message.id.null=The message id is empty
##Wechat
wechat.verify.type.null=Please specify the verification method
wechat.bind.message.id.null=Please pass in the binding information ID
wechat.please.config.open.platform=Please configure WeChat Open Platform mobile application information first
wechat.user.certificate.gain.fail=Failed to obtain user credentials, please log in again!
wechat.please.config.open.platform.mini=Please configure WeChat public platform mini program information first!
wechat.user.phone.certificate.gain.fail=Failed to obtain user's mobile phone number credentials, please log in again!
wechat.gain.user.call.certificate.fail=Failed to obtain user call credentials, please log in again!
wechat.gain.user.phone.fail=Failed to obtain user phone number, please log in again!
wechat.please.login=Please log in first and try again
wechat.please.enter.user.password=Please enter the user password
wechat.cancelBind.password.fail=Password error, please re-enter
wechat.please.enter.wechat.user.info=Please provide WeChat user information
wechat.please.enter.user.certificate=Please provide user credentials
wechat.gain.wechat.info.fail=Failed to obtain WeChat information, please try again!
wechat.your.wechat.already.bind.other.account=Your WeChat account has already been linked to another account. Please log in and unbind it using WeChat first, and then try again
wechat.this.wechat.already.bind.other.account=This WeChat account has already been linked to another account. Please log in and unbind it using WeChat first, and then try again!
wechat.please.config.open.platform.web.application.personal.bind.info=Please first configure the WeChat Open Platform website application personal center binding information
wechat.you.cancel.or.not.gain.authorization.info=You have cancelled authorization or have not obtained authorization information
wechat.the.qr.code.has.expired=The QR code has expired, please click bind again
wechat.your.account.already.bind.wechat=Your account has been linked to WeChat, please unbind it first
##AuthResource
auth.resource.product.query.success=The product list was queried
##Device
device.user.id.null=User ID cannot be empty
device.product.id.null=Device number and product ID cannot be empty
device.dept.id.null=Select Allocation Authority
device.id.null=Select a device
device.not.select=Please select a device
device.serialNumber.not.empty=The device number cannot be empty
device.delete.fail.please.delete.device.scene=If the device ID [{}] fails, delete the scene linkage under the corresponding device
device.tenant.can.not.bind.exist.device=Tenants are not allowed to bind existing devices, device number: [{}]
now.user.belong.device.can.not.repeat.share=The current user already owns the device and cannot be reassigned. Device ID: [{}]
device.share.other.user.can.not.share=This device has already been assigned to another user and cannot be duplicated. Device ID: [{}]
device.not.exist.add.fail.please.check.product.id.is.correct=The device does not exist, automatic device addition failed, please check if the product number is correct
device.add.success=Device added successfully
device.assignment.fail.dept.not.exist=The institution does not exist or is not bound to an administrator. Please adjust and try again!
device.assignment.fail.dept.admin.not.exist=Institution administrator does not exist
device.assignment.success=Equipment allocation successful
device.assignment.fail=Equipment allocation failed
device.recovery.fail.dept.not.exist=The institution does not exist or is not bound to an administrator. Please adjust and try again!
device.recovery.fail.dept.admin.not.exist=Institution administrator does not exist
device.recovery.success=Successful recycling of equipment
device.recovery.fail=Recycling device failed
device.not.exist=The device does not exist
device.serialNumber.allow.generate.max.number=Only up to 200 can be generated!
device.insert.fail.device.number.already.exist=Device number: [{}] already exists, adding failed
device.get.mqtt.connection.param.fail=Failed to retrieve device MQTT connection parameters
device.get.authorization.fail.please.config=The product has enabled authorization, but obtaining the device authorization code has failed. Please configure the authorization code first
##DeviceJob
job.add.failed.cron.not.valid=Failed to add task [{}] with incorrect Cron expression
job.add.failed.rmi.not.valid=The new task [{}] failed, and 'rmi' is not allowed to be called on the target string
job.add.failed.ldap.not.valid=The new task [{}] failed, and 'ldap(s)' cannot be called as the target string
job.add.failed.http.not.valid=The new task [{}] failed, and the target string does not allow 'http(s)' to be called
job.add.failed.string.error=The new task [{}] has failed, and the target string has been violated
job.add.failed.string.not.valid=The new task [{}] failed, and the destination string is not in the whitelist
job.add.failed.product.not.modbus.config=Failed to add task [{}], please go to the product to configure modbus first
job.update.failed.cron.not.valid=Task [{}] failed to be modified, and the Cron expression is incorrect
job.update.failed.rmi.not.valid=Task [{}] failed, and 'rmi' is not allowed to be called by the target string
job.update.failed.ldap.not.valid=Modify task [{}] failed, and 'ldap(s)' is not allowed to be called as the target string
job.update.failed.http.not.valid=Modify task [{}] failed, and 'http(s)' is not allowed to be called to the target string
job.update.failed.string.error=Task [{}] has failed to be modified, and the target string has been violated
job.update.failed.string.not.valid=Task [{}] has failed to be modified, and the destination string is not in the whitelist
job.update.failed.product.not.modbus.config=Update task [{}] failed, please go to the product to configure modbus
job.not.exists=The task does not exist or has expired
##DeviceUser
device.user.delete.failed.user.not.valid=Device owner cannot be deleted
##GoviewProject
goview.project.data.save.failed.id.null=There is no project ID
goview.project.data.execute.sql.failed=Write an SQL statement
##ThingsModel
things.model.identifier.repeat=The identifier under the product cannot be repeated
things.model.import.failed.identifier.repeat=[{}] data is not imported, and the identifier is duplicated
things.model.update.fail.quote.the.scene.variable.formula.please.delete=The current object model is referenced to the calculation formula of the scene operation variable and cannot be modified. Please delete the reference relationship before performing the modification operation!
things.model.delete.fail.quote.the.scene.variable.formula.please.delete=The current object model is referenced to the calculation formula of the scene operation variable and cannot be deleted. Please delete the reference relationship before performing the deletion operation!
things.model.import.data.exception=Import data exception
things.model.register.address.repeat=Under the same collection point template, there are duplicate register addresses. Please check the imported variable register addresses
##MQTT
mqtt.unauthorized=mqtt account and password do not match the configuration of the authentication server
##Oauth
oauth.response.type.not.valid=response_type parameter values allow only code and token
oauth.grant.type.null=Unknown grant type
The oauth.grant.type.implicit.not.support=Token operation does not support implicit authorization mode
oauth.access.token.null=Access token cannot be empty
obtain.basic.authorization.failed=client_id or client_secret is not delivered correctly
##Record
record.app.null=app cannot be empty
record.stream.null=stream cannot be empty
record.time.not.valid=Wrong start time or end time
record.file.null=No video file found
##ErrorCodeConstants
app.not.found=App does not exist
app.is.disable=App has been disabled
app.exist.order.cant.delete=A payment order exists in the payment application and cannot be deleted
app.exist.refund.cant.delete=A refund order exists in the payment app and cannot be deleted
channel.not.found=The configuration of the payment channel does not exist
channel.is.disable=Payment channel is disabled
channel.exists.same.channel.error=The same channel already exists
order.not.found=The payment order does not exist
order.status.is.not.waiting=The paid order is not pending payment
order.status.is.success=Order has been paid, please refresh the page
order.is.expired=The payment order has expired
order.submit.channel.error=Error message is reported for initiating payment, error code: {}, error message: {}
order.refund.fail.status.error=Failed to refund the paid order due to the fact that the status is not Paid or Refunded
order.extension.not.found=The payment transaction extension does not exist
order.extension.status.is.not.waiting=The payment transaction extension order is not pending payment
order.extension.is.paid=The order has been paid, please wait for the payment result
refund.price.exceed=The amount refunded exceeds the amount of the order that can be refunded
refund.has.refunding=A refund is already being processed
refund.exists=A refund ticket already exists
refund.not.found=Payment Refund Form Does Not Exist
refund.statue.is.not.waiting=Payment of a refund receipt is not pending refund
demo.order.not.found=The sample order does not exist
demo.order.update.paid.status.not.unpaid=Example: Failed to update payment status of order, order is not in unpaid status
demo.order.update.paid.fail.pay.order.id.error=Failed to update the payment status of the sample order, and the payment slip number does not match
demo.order.update.paid.fail.pay.order.status.not.success=Example: Failed to update the payment status of the order, and the status of the payment slip is not [Payment Successful].
demo.order.update.paid.fail.pay.price.not.match=Failed to update the payment status of the sample order, and the payment order amount does not match
demo.order.refund.fail.not.paid=Failed to initiate a refund, but the sample order has not been paid
demo.order.refund.fail.refunded=Failed to initiate a refund, the sample order has been refunded
demo.order.refund.fail.refund.not.found=Failed to initiate a refund, but the refund order does not exist
demo.order.refund.fail.refund.not.success=Failed to initiate a refund, but the order was not refunded
demo.order.refund.fail.refund.order.id.error=Failed to initiate a refund, and the refund order number does not match
demo.order.refund.fail.refund.price.not.match=Failed to initiate a refund, and the amount of the refund order does not match
device.order.control.no.permission=There is no permission to operate, please contact the administrator to assign command permissions!
##sysConfig
sysConfig.add.param.fail.name.exist=Failed to add parameter [{}], the parameter key name already exists
sysConfig.update.param.fail.name.exist=Parameter [{}] failed, and the parameter key name already exists
##sysRegister
sysRegister.fail.not.enable.register=The current system does not have the registration function enabled!
##ossDetail
ossDetail.fail.file.not.empty=The uploaded file cannot be empty
##notify
sms.send.fail.contact.admin=SMS sending failed, please contact the administrator!
captcha.has.sent.please.try.again.later=The verification code has been sent, please try again later!
not.find.enable.notify.template=Unable to find enabled notification templates
not.find.notify.channel=Unable to find notification channel
##dataCenter
please.select.device=Please select a device
please.incoming.serialNumber=Please pass in the device number
##license
certificate.install.success=The certificate is successfully installed
certificate.install.fail=Certificate installation failed:[{}]
certificate.incoming.success=The certificate is successfully uploaded
certificate.incoming.fail=The certificate upload failed
certificate.upload.success=The certificate is successfully uploaded
certificate.upload.fail=Certificate upload failed:[{}]
##sceneModel
please.incoming.scene.id=Please pass in the scene ID
please.incoming.device.config.number=Enter the serial number of the associated device configuration
sceneModel.please.introduced.id=Please enter the scene management ID
sceneModel.current.variable.quote.operate.variable.formula.please.delete=The current variable is referenced to the calculation formula of the scene operation variable and cannot be deleted. Please delete the reference relationship before performing the deletion operation!
sceneModel.scene.already.bind.device=The scene has already been bound to this device, please select again!
sceneModel.update.fail.device.variable.has.quote.scene.variable.please.delete=There are variables in the current device that are referenced to the calculation formula of operational variables and cannot be modified. Please delete the reference relationship before performing the modification operation!
sceneModel.delete.fail.device.variable.has.quote.scene.variable.please.delete=There are variables under the current device that are referenced to the calculation formula of operational variables and cannot be deleted. Please delete the reference relationship before performing the deletion operation!
sceneModel.formula.cannot.empty=The calculation formula cannot be empty!
sceneModel.variable.cannot.empty=The variable cannot be empty!
sceneModel.formula.and.variable.number.inconsistent=The calculation formula and the number of variables are inconsistent. Please check and try again
sceneModel.update.fail.variable.name.exist=The variable name already exists, please modify it and try again!
##oauthClientDetail
add.fail.same.client.can.config.one=Only one piece of information can be configured on the same authorization platform, please do not configure it again
client.id.is.exist=Client ID: [{}] Already exists or is already in use by another tenant
oauthClientDetail.client.not.exist=OAuth2 client does not exist
oauthClientDetail.client.disabled=OAuth2 client disabled
oauthClientDetail.invalid.client.set=Invalid client set
oauthClientDetail.invalid.redirects=Invalid redirects: [{}]
##category
delete.fail.please.delete.category.product=Delete failed, please delete the products under the corresponding category first
##goviewProjectData
only.allow.select.operate=Only allow select operation, prohibit update, delete, insert operation
##newsCategory
newsCategory.delete.fail.please.delete.category.info=Delete failed, please delete the news information under the corresponding category first
##product
delete.fail.please.delete.firmware=Delete failed, please delete the firmware under the corresponding product first
delete.fail.please.delete.product.device=Delete failed, please delete the device under the corresponding product first
delete.fail.please.delete.product.scene=Delete failed, please modify or delete the scene linkage under the corresponding product first: [{}]
product.status.update.fail.value.fail=Status update failed, incorrect status value
product.status.update.fail=Status update failed
##socialLogin
bind.account.not.exist=The bound account does not exist
socialLogin.verify.has.expired=The verification code has expired, please obtain it again
socialLogin.platform.type.fail=Wrong platform type
user.account.and.bind.account.not.match=User account and bound account do not match
socialLogin.user.not.exist=user does not exist
socialLogin.bind.end.user.cannot.login.web=Do not bind end users, after binding end users, you cannot log in to the web end
socialLogin.account.already.bind.other.wechat.please.unbind=This account has already been linked to another WeChat account. Please unbind it first and try again!
socialLogin.register.fail.please.check.role.exist=Registration failed, please contact the management personnel to check if the institutional role exists
socialLogin.web.not.allow.end.user.login=The web end does not allow end users to log in
##alert
alert.push.fail.device.not.exist=Alarm push, device does not exist: [{}]
##modbus
not.modbus.protocol.please.config.collect.protocol=Please configure the active collection protocol first for non Modbus protocols
modbus.point.not.config=Modbus point not configured
##ota
firmwareTask.add.fail.FirmwareTask.exist=Task: [{}] already exists
firmware.version.not.exist=The firmware version does not exist!
##mqttMessage
mqtt.service.send.device.not.exist=The device issued by the service: [{}] does not exist
mqtt.disconnect.occur.fail=Error occurred while disconnecting MQTT connection: [{}]
##genTable
genTable.template.rendering.fail=Template rendering failed, table name: [{}]
genTable.data.sync.fail.original.table.not.exist=Data synchronization failed, original table structure does not exist
genTable.tree.code.field.cannot.empty=The tree code field cannot be empty
genTable.tree.parent.code.field.cannot.empty=The tree parent code field cannot be empty
genTable.tree.name.field.cannot.empty=The tree name field cannot be empty
genTable.relate.child.table.name.cannot.empty=The table name of the associated sub table cannot be empty
genTable.child.table.relate.foreign.key.name.cannot.empty=The foreign key name associated with a sub table cannot be empty
##oauthCode
oauthCode.code.not.exist=Code does not exist
##protocol
protocol.input.content.is.empty=The input content is empty
protocol.data.parse.error=Data parsing error [{}]
protocol.data.parse.exception=Data parsing exception [{}]
protocol.instruction.number.exception=Instruction number exception: [{}]
##modbusJob
modbusJob.add.fail.please.bind.gateway=Please bind the gateway first
thingsModel.array.or.object.no.need.update=There are no arrays or objects that need to be updated
sync.fail.please.try.again=Sync failed, please try again!
sync.success=Synchronization succeeded
## scada
scada.product.id.is.null=The product ID is empty
scada.scene.id.is.null=The scene ID is empty
scada.guid.cannot.empty=The guid cannot be empty
scada.base64.change.image.exception=Configuration base64 to image abnormal:[{}]
scada.please.select.device=Please select a device
scada.please.enter.password=Please enter your password!
scada.please.login=If you are not logged in, please log in and try again
scada.password.fail.please.reload.enter=The password is incorrect, please re-enter it!
scada.product.has.relate.please.select.again=The product has been associated with the configuration, please select it again!
scada.scene.has.relate.please.select.again=This scene has been associated with the configuration, please select it again!
scada.not.allow.view.other.tenant.config=It is not allowed to view the configuration of other tenants!
scada.upload.gallery.file.fail=The upload of the gallery file is abnormal,[{}]
scada.upload.fail=Upload failed, please try again!
scada.invalid.profile=Invalid profile
scada.import.success.need.replace.variable=The import is successful, and the current page needs to replace the variables of the bound component again!
## speaker
speaker.product.has.relate=The product is already linked, please do not associate it repeatedly
speaker.product.relate.add.fail=Failed to add a new feature
speaker.not.found.product.relate=No product related information was found
##file
file.content.is.empty=The file content is empty
file.is.invalid=Invalid file

View File

@ -0,0 +1,399 @@
#\u9519\u8BEF\u6D88\u606F
not.null=\u5FC5\u987B\u586B\u5199
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
user.jcaptcha.expire=\u9A8C\u8BC1\u7801\u5DF2\u5931\u6548
user.not.exists=\u7528\u6237\u4E0D\u5B58\u5728/\u5BC6\u7801\u9519\u8BEF
user.password.not.match=\u7528\u6237\u4E0D\u5B58\u5728/\u5BC6\u7801\u9519\u8BEF
user.password.retry.limit.count=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21
user.password.retry.limit.exceed=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21\uFF0C\u5E10\u6237\u9501\u5B9A{1}\u5206\u949F
user.password.delete=\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u7684\u8D26\u53F7\u5DF2\u88AB\u5220\u9664
user.blocked=\u7528\u6237\u5DF2\u5C01\u7981\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
role.blocked=\u89D2\u8272\u5DF2\u5C01\u7981\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.logout.success=\u9000\u51FA\u6210\u529F
length.not.valid=\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4
user.username.not.valid=2\u523020\u4E2A\u6C49\u5B57\u3001\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u4E0B\u5212\u7EBF\u7EC4\u6210\uFF0C\u4E14\u5FC5\u987B\u4EE5\u975E\u6570\u5B57\u5F00\u5934
user.password.not.valid=5-50\u4E2A\u5B57\u7B26
user.email.not.valid=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF
user.mobile.phone.number.not.valid=\u624B\u673A\u53F7\u683C\u5F0F\u9519\u8BEF
user.login.success=\u767B\u5F55\u6210\u529F
user.register.success=\u6CE8\u518C\u6210\u529F
user.notfound=\u8BF7\u91CD\u65B0\u767B\u5F55
user.forcelogout=\u7BA1\u7406\u5458\u5F3A\u5236\u9000\u51FA\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55
user.unknown.error=\u672A\u77E5\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55
##\u6743\u9650
no.permission=\u60A8\u6CA1\u6709\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.create.permission=\u60A8\u6CA1\u6709\u521B\u5EFA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.update.permission=\u60A8\u6CA1\u6709\u4FEE\u6539\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.delete.permission=\u60A8\u6CA1\u6709\u5220\u9664\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.export.permission=\u60A8\u6CA1\u6709\u5BFC\u51FA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
no.view.permission=\u60A8\u6CA1\u6709\u67E5\u770B\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}]
##\u6587\u4EF6\u4E0A\u4F20\u6D88\u606F
upload.exceed.maxSize=\u4E0A\u4F20\u7684\u6587\u4EF6\u5927\u5C0F\u8D85\u51FA\u9650\u5236\u7684\u6587\u4EF6\u5927\u5C0F\uFF01<br/>\u5141\u8BB8\u7684\u6587\u4EF6\u6700\u5927\u5927\u5C0F\u662F\uFF1A{0}MB\uFF01
upload.filename.exceed.length=\u4E0A\u4F20\u7684\u6587\u4EF6\u540D\u6700\u957F{0}\u4E2A\u5B57\u7B26
upload.success=\u4E0A\u4F20\u6210\u529F
##\u6587\u4EF6\u4E0B\u8F7D\u6D88\u606F
download.filename.not.valid=\u6587\u4EF6\u540D\u79F0[{}]\u975E\u6CD5\uFF0C\u4E0D\u5141\u8BB8\u4E0B\u8F7D
download.file.failed=\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25
download.resource.not.valid=\u8D44\u6E90\u6587\u4EF6[{}]\u975E\u6CD5\uFF0C\u4E0D\u5141\u8BB8\u4E0B\u8F7D
##Dept
dept.add.failed.name.exists=\u65B0\u589E\u673A\u6784[{}]\u5931\u8D25\uFF0C\u673A\u6784\u540D\u79F0\u5DF2\u5B58\u5728
dept.update.failed.name.exists=\u4FEE\u6539\u673A\u6784[{}]\u5931\u8D25\uFF0C\u673A\u6784\u540D\u79F0\u5DF2\u5B58\u5728
dept.update.failed.parent.not.valid=\u4FEE\u6539\u673A\u6784[{}]\u5931\u8D25\uFF0C\u4E0A\u7EA7\u673A\u6784\u4E0D\u80FD\u662F\u81EA\u5DF1
dept.update.failed.child.not.valid=\u8BE5\u673A\u6784\u5305\u542B\u672A\u505C\u7528\u7684\u5B50\u673A\u6784\uFF01
dept.delete.failed.child.exists=\u5B58\u5728\u4E0B\u7EA7\u673A\u6784\uFF0C\u4E0D\u5141\u8BB8\u5220\u9664
dept.delete.failed.user.exists=\u673A\u6784\u5B58\u5728\u7528\u6237\uFF0C\u4E0D\u5141\u8BB8\u5220\u9664
##Dict
dict.add.failed.type.exists=\u65B0\u589E\u5B57\u5178[{}]\u5931\u8D25\uFF0C\u5B57\u5178\u7C7B\u578B\u5DF2\u5B58\u5728
dict.update.failed.type.exists=\u4fee\u6539\u5b57\u5178[{}]\u5931\u8d25\uff0c\u5b57\u5178\u7c7b\u578b\u5df2\u5b58\u5728
##Index
index.welcome.message=\u6B22\u8FCE\u4F7F\u7528{}\u540E\u53F0\u7BA1\u7406\u6846\u67B6\uFF0C\u5F53\u524D\u7248\u672C\uFF1Av{}\uFF0C\u8BF7\u901A\u8FC7\u524D\u7AEF\u5730\u5740\u8BBF\u95EE\u3002
##Menu
menu.add.failed.name.exists=\u65B0\u589E\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u83DC\u5355\u540D\u79F0\u5DF2\u5B58\u5728
menu.add.failed.path.not.valid=\u65B0\u589E\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u5730\u5740\u5FC5\u987B\u4EE5http(s)://\u5F00\u5934
menu.update.failed.name.exists=\u4FEE\u6539\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u83DC\u5355\u540D\u79F0\u5DF2\u5B58\u5728
menu.update.failed.path.not.valid=\u4FEE\u6539\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u5730\u5740\u5FC5\u987B\u4EE5http(s)://\u5F00\u5934
menu.update.failed.parent.not.valid=\u4FEE\u6539\u83DC\u5355[{}]\u5931\u8D25\uFF0C\u4E0A\u7EA7\u83DC\u5355\u4E0D\u80FD\u9009\u62E9\u81EA\u5DF1
menu.delete.failed.child.exists=\u5B58\u5728\u5B50\u83DC\u5355,\u4E0D\u5141\u8BB8\u5220\u9664
menu.delete.failed.role.exists=\u83DC\u5355\u5DF2\u5206\u914D,\u4E0D\u5141\u8BB8\u5220\u9664
##Post
post.add.failed.name.exists=\u65B0\u589E\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u540D\u79F0\u5DF2\u5B58\u5728
post.add.failed.code.exists=\u65B0\u589E\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u7F16\u7801\u5DF2\u5B58\u5728
post.update.failed.name.exists=\u4FEE\u6539\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u540D\u79F0\u5DF2\u5B58\u5728
post.update.failed.code.exists=\u4FEE\u6539\u5C97\u4F4D[{}]\u5931\u8D25\uFF0C\u5C97\u4F4D\u7F16\u7801\u5DF2\u5B58\u5728
##User
user.username.exists=\u7CFB\u7EDF\u8D26\u53F7\u540D\u79F0\u5DF2\u5B58\u5728\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u8BD5
user.password.differ=\u4E24\u6B21\u5BC6\u7801\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165
user.add.failed.name.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u767B\u5F55\u8D26\u53F7\u5DF2\u5B58\u5728
user.add.failed.phone.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u624B\u673A\u53F7\u7801\u5DF2\u5B58\u5728
user.add.failed.email.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u90AE\u7BB1\u8D26\u53F7\u5DF2\u5B58\u5728
user.update.failed.password.wrong=\u4FEE\u6539\u5BC6\u7801\u5931\u8D25\uFF0C\u65E7\u5BC6\u7801\u9519\u8BEF
user.update.failed.password.repeat=\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E0E\u65E7\u5BC6\u7801\u76F8\u540C
user.update.password.failed=\u4FEE\u6539\u5BC6\u7801\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.update.failed.name.exists=\u65B0\u589E\u7528\u6237[{}]\u5931\u8D25\uFF0C\u767B\u5F55\u8D26\u53F7\u5DF2\u5B58\u5728
user.update.failed.phone.exists=\u4FEE\u6539\u7528\u6237[{}]\u5931\u8D25\uFF0C\u624B\u673A\u53F7\u7801\u5DF2\u5B58\u5728
user.update.failed.email.exists=\u4FEE\u6539\u7528\u6237[{}]\u5931\u8D25\uFF0C\u90AE\u7BB1\u8D26\u53F7\u5DF2\u5B58\u5728
user.update.failed=\u4FEE\u6539\u4E2A\u4EBA\u4FE1\u606F\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.delete.failed=\u5F53\u524D\u7528\u6237\u4E0D\u80FD\u5220\u9664
user.upload.avatar.failed=\u4E0A\u4F20\u56FE\u7247\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
user.not.login=\u8BF7\u767B\u5F55\u540E\u91CD\u8BD5
user.access.denied=\u7528\u6237\u62D2\u7EDD\u8BBF\u95EE
##Role
role.add.manager.failed=\u4E0D\u5141\u8BB8\u8BBE\u7F6E\u7BA1\u7406\u5458\u89D2\u8272\u6807\u8BC6
role.add.failed.name.exists=\u65B0\u589E\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u540D\u79F0\u5DF2\u5B58\u5728
role.add.failed.key.exists=\u65B0\u589E\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u6743\u9650\u5DF2\u5B58\u5728
role.update.failed.name.exists=\u4FEE\u6539\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u540D\u79F0\u5DF2\u5B58\u5728
role.update.failed.key.exists=\u4FEE\u6539\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u89D2\u8272\u6743\u9650\u5DF2\u5B58\u5728
role.update.failed=\u4FEE\u6539\u89D2\u8272[{}]\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458
##Import
import.failed.file.null=\u5BFC\u5165\u5931\u8D25\uFF0C\u8BF7\u5148\u4E0A\u4F20\u6587\u4EF6\uFF01
import.failed.data.null=\u5BFC\u5165\u5931\u8D25\uFF0C\u5BFC\u5165\u6570\u636E\u4E3A\u7A7A\uFF01
import.failed.device.name.null=\u5BFC\u5165\u5931\u8D25\uFF0C\u6A21\u677F\u91CC\u8BBE\u5907\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A\uFF01
import.success=\u5BFC\u5165\u6210\u529F
import.fail=\u5bfc\u5165\u5931\u8d25
##General
success=\u6210\u529F
fail=\u5931\u8D25
query.success=\u67E5\u8BE2\u6210\u529F
operate.success=\u64CD\u4F5C\u6210\u529F
operate.fail=\u64cd\u4f5c\u5931\u8d25
create.success=\u521B\u5EFA\u6210\u529F
create.failed=\u521B\u5EFA\u5931\u8D25
save.success=\u4FDD\u5B58\u6210\u529F
save.failed=\u4FDD\u5B58\u5931\u8D25
authorization.success=\u6388\u6743\u6210\u529F
delete.success=\u5220\u9664\u6210\u529f
delete.fail=\u5220\u9664\u5931\u8d25
bind.success=\u7ed1\u5b9a\u6210\u529f
bind.fail=\u7ed1\u5b9a\u5931\u8d25
unbind.success=\u89e3\u7ed1\u6210\u529f
unbind.fail=\u89e3\u7ed1\u5931\u8d25
captcha.fail=\u9a8c\u8bc1\u7801\u9519\u8bef
import.fail.[{}]=\u5bfc\u5165\u5931\u8d25\uff1a[{}]
only.allow.tenant.config=\u53ea\u5141\u8bb8\u79df\u6237\u914d\u7f6e
password.fail=\u5bc6\u7801\u9519\u8bef
login.success=\u767b\u5f55\u6210\u529f
##Email
email.format.error=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF
email.verification.code.send=\u90AE\u7BB1\u9A8C\u8BC1\u7801\u5DF2\u53D1\u9001
##Firmware
firmware.task.upgrade.failed.time.not.valid=\u9884\u5B9A\u5347\u7EA7\u65F6\u95F4\u5E94\u5927\u4E8E\u5F53\u524D\u65F6\u95F4
##Media
media.record.query.failed=\u8FDE\u63A5\u8D85\u65F6\u6216\u53D1\u751F\u9519\u8BEF\uFF0C\u672A\u83B7\u53D6\u5230\u6570\u636E
##Modbus
modbus.type.null=\u7C7B\u578B\u4E3A\u7A7A
modbus.crc.check.abnormal=crc\u6821\u9a8c\u5f02\u5e38
##Netty
netty.client.not.exists=\u5BA2\u6237\u7AEF\u4E0D\u5B58\u5728
##Runtime
runtime.message.id.null=\u6D88\u606Fid\u4E3A\u7A7A
##Wechat
wechat.verify.type.null=\u8BF7\u4F20\u5165\u9A8C\u8BC1\u65B9\u5F0F
wechat.bind.message.id.null=\u8BF7\u4F20\u5165\u7ED1\u5B9A\u4FE1\u606FID
wechat.please.config.open.platform=\u8bf7\u5148\u914d\u7f6e\u5fae\u4fe1\u5f00\u653e\u5e73\u53f0\u79fb\u52a8\u5e94\u7528\u4fe1\u606f
wechat.user.certificate.gain.fail=\u7528\u6237\u51ed\u8bc1\u83b7\u53d6\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.please.config.open.platform.mini=\u8bf7\u5148\u914d\u7f6e\u5fae\u4fe1\u516c\u4f17\u5e73\u53f0\u5c0f\u7a0b\u5e8f\u4fe1\u606f\uff01
wechat.user.phone.certificate.gain.fail=\u7528\u6237\u624b\u673a\u53f7\u51ed\u8bc1\u83b7\u53d6\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.gain.user.call.certificate.fail=\u83b7\u53d6\u7528\u6237\u8c03\u7528\u51ed\u636e\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.gain.user.phone.fail=\u83b7\u53d6\u7528\u6237\u624b\u673a\u53f7\u5931\u8d25\uff0c\u8bf7\u91cd\u65b0\u767b\u5f55\uff01
wechat.please.login=\u8bf7\u5148\u767b\u5f55\u540e\u91cd\u8bd5
wechat.please.enter.user.password=\u8bf7\u4f20\u5165\u7528\u6237\u5bc6\u7801
wechat.cancelBind.password.fail=\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165
wechat.please.enter.wechat.user.info=\u8bf7\u4f20\u5165\u5fae\u4fe1\u7528\u6237\u4fe1\u606f
wechat.please.enter.user.certificate=\u8bf7\u4f20\u5165\u7528\u6237\u51ed\u8bc1
wechat.gain.wechat.info.fail=\u83b7\u53d6\u5fae\u4fe1\u4fe1\u606f\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\uff01
wechat.your.wechat.already.bind.other.account=\u60a8\u7684\u5fae\u4fe1\u5df2\u7ed1\u5b9a\u5176\u4ed6\u8d26\u53f7\uff0c\u8bf7\u5148\u4f7f\u7528\u5fae\u4fe1\u767b\u5f55\u89e3\u7ed1\u540e\u91cd\u8bd5
wechat.this.wechat.already.bind.other.account=\u8be5\u5fae\u4fe1\u5df2\u7ed1\u5b9a\u5176\u4ed6\u8d26\u53f7\uff0c\u8bf7\u5148\u4f7f\u7528\u5fae\u4fe1\u767b\u5f55\u89e3\u7ed1\u540e\u91cd\u8bd5\uff01
wechat.please.config.open.platform.web.application.personal.bind.info=\u8bf7\u5148\u914d\u7f6e\u5fae\u4fe1\u5f00\u653e\u5e73\u53f0\u7f51\u7ad9\u5e94\u7528\u4e2a\u4eba\u4e2d\u5fc3\u7ed1\u5b9a\u4fe1\u606f
wechat.you.cancel.or.not.gain.authorization.info=\u60a8\u5df2\u53d6\u6d88\u6388\u6743\u6216\u672a\u83b7\u53d6\u5230\u6388\u6743\u4fe1\u606f
wechat.the.qr.code.has.expired=\u4e8c\u7ef4\u7801\u5df2\u5931\u6548\uff0c\u8bf7\u91cd\u65b0\u70b9\u51fb\u7ed1\u5b9a
wechat.your.account.already.bind.wechat=\u60a8\u7684\u8d26\u53f7\u5df2\u7ed1\u5b9a\u5fae\u4fe1\uff0c\u8bf7\u5148\u89e3\u7ed1
##AuthResource
auth.resource.product.query.success=\u67E5\u8BE2\u4EA7\u54C1\u5217\u8868\u6210\u529F
##Device
device.user.id.null=\u7528\u6237ID\u4E0D\u80FD\u4E3A\u7A7A
device.product.id.null=\u8BBE\u5907\u7F16\u53F7\u548C\u4EA7\u54C1ID\u4E0D\u80FD\u4E3A\u7A7A
device.dept.id.null=\u8BF7\u9009\u62E9\u5206\u914D\u673A\u6784
device.id.null=\u8BF7\u9009\u62E9\u8BBE\u5907
device.not.select=\u8bf7\u9009\u62e9\u8bbe\u5907
device.serialNumber.not.empty=\u8bbe\u5907\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
device.delete.fail.please.delete.device.scene=\u8bbe\u5907\u7f16\u53f7\u4e3a[{}]\u7684\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u8bbe\u5907\u4e0b\u7684\u573a\u666f\u8054\u52a8
device.tenant.can.not.bind.exist.device=\u79df\u6237\u4e0d\u5141\u8bb8\u7ed1\u5b9a\u5df2\u5b58\u5728\u7684\u8bbe\u5907\uff0c\u8bbe\u5907\u7f16\u53f7\uff1a[{}]
now.user.belong.device.can.not.repeat.share=\u5f53\u524d\u7528\u6237\u5df2\u62e5\u6709\u8be5\u8bbe\u5907\uff0c\u65e0\u6cd5\u91cd\u590d\u5206\u914d\uff0c\u8bbe\u5907\u7f16\u53f7\uff1a[{}]
device.share.other.user.can.not.share=\u8be5\u8bbe\u5907\u5df2\u88ab\u5206\u914d\u5230\u5176\u4ed6\u7528\u6237\uff0c\u65e0\u6cd5\u91cd\u590d\u5206\u914d\uff0c\u8bbe\u5907\u7f16\u53f7\uff1a[{}]
device.not.exist.add.fail.please.check.product.id.is.correct=\u8bbe\u5907\u4e0d\u5b58\u5728\uff0c\u81ea\u52a8\u6dfb\u52a0\u8bbe\u5907\u65f6\u5931\u8d25\uff0c\u8bf7\u68c0\u67e5\u4ea7\u54c1\u7f16\u53f7\u662f\u5426\u6b63\u786e
device.add.success=\u6dfb\u52a0\u8bbe\u5907\u6210\u529f
device.assignment.fail.dept.not.exist=\u673a\u6784\u4e0d\u5b58\u5728\u6216\u672a\u7ed1\u5b9a\u7ba1\u7406\u5458\uff0c\u8bf7\u8c03\u6574\u540e\u91cd\u8bd5\uff01
device.assignment.fail.dept.admin.not.exist=\u673a\u6784\u7ba1\u7406\u5458\u4e0d\u5b58\u5728
device.assignment.success=\u5206\u914d\u8bbe\u5907\u6210\u529f
device.assignment.fail=\u5206\u914d\u8bbe\u5907\u5931\u8d25
device.recovery.fail.dept.not.exist=\u673a\u6784\u4e0d\u5b58\u5728\u6216\u672a\u7ed1\u5b9a\u7ba1\u7406\u5458\uff0c\u8bf7\u8c03\u6574\u540e\u91cd\u8bd5\uff01
device.recovery.fail.dept.admin.not.exist=\u673a\u6784\u7ba1\u7406\u5458\u4e0d\u5b58\u5728
device.recovery.success=\u56de\u6536\u8bbe\u5907\u6210\u529f
device.recovery.fail=\u56de\u6536\u8bbe\u5907\u5931\u8d25
device.not.exist=\u8bbe\u5907\u4e0d\u5b58\u5728
device.serialNumber.allow.generate.max.number=\u6700\u591a\u53ea\u80fd\u751f\u6210200\u4e2a\uff01
device.insert.fail.device.number.already.exist=\u8bbe\u5907\u7f16\u53f7\uff1a[{}] \u5df2\u7ecf\u5b58\u5728\uff0c\u65b0\u589e\u5931\u8d25
device.get.mqtt.connection.param.fail=\u83b7\u53d6\u8bbe\u5907mqtt\u8fde\u63a5\u53c2\u6570\u5931\u8d25
device.get.authorization.fail.please.config=\u4ea7\u54c1\u5df2\u542f\u7528\u6388\u6743\uff0c\u83b7\u53d6\u8bbe\u5907\u6388\u6743\u7801\u5931\u8d25\uff0c\u8bf7\u5148\u914d\u7f6e\u6388\u6743\u7801
##DeviceJob
job.add.failed.cron.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0CCron\u8868\u8FBE\u5F0F\u4E0D\u6B63\u786E
job.add.failed.rmi.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'rmi'\u8C03\u7528
job.add.failed.ldap.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'ldap(s)'\u8C03\u7528
job.add.failed.http.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'http(s)'\u8C03\u7528
job.add.failed.string.error=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u5B58\u5728\u8FDD\u89C4
job.add.failed.string.not.valid=\u65B0\u589E\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5728\u767D\u540D\u5355\u5185
job.add.failed.product.not.modbus.config=\u65b0\u589e\u4efb\u52a1[{}]\u5931\u8d25\uff0c\u8bf7\u5148\u53bb\u4ea7\u54c1\u8fdb\u884cmodbus\u914d\u7f6e
job.update.failed.cron.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0CCron\u8868\u8FBE\u5F0F\u4E0D\u6B63\u786E
job.update.failed.rmi.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'rmi'\u8C03\u7528
job.update.failed.ldap.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'ldap(s)'\u8C03\u7528
job.update.failed.http.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5141\u8BB8'http(s)'\u8C03\u7528
job.update.failed.string.error=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u5B58\u5728\u8FDD\u89C4
job.update.failed.string.not.valid=\u4FEE\u6539\u4EFB\u52A1[{}]\u5931\u8D25\uFF0C\u76EE\u6807\u5B57\u7B26\u4E32\u4E0D\u5728\u767D\u540D\u5355\u5185
job.update.failed.product.not.modbus.config=\u66f4\u65b0\u4efb\u52a1[{}]\u5931\u8d25\uff0c\u8bf7\u5148\u53bb\u4ea7\u54c1\u8fdb\u884cmodbus\u914d\u7f6e
job.not.exists=\u4EFB\u52A1\u4E0D\u5B58\u5728\u6216\u5DF2\u8FC7\u671F
##DeviceUser
device.user.delete.failed.user.not.valid=\u8BBE\u5907\u6240\u6709\u8005\u4E0D\u80FD\u5220\u9664
##GoviewProject
goview.project.data.save.failed.id.null=\u6CA1\u6709\u8BE5\u9879\u76EEID
goview.project.data.execute.sql.failed=\u8BF7\u7F16\u5199sql\u8BED\u53E5
##ThingsModel
things.model.identifier.repeat=\u4EA7\u54C1\u4E0B\u7684\u6807\u8BC6\u7B26\u4E0D\u80FD\u91CD\u590D
things.model.import.failed.identifier.repeat=[{}]\u6761\u6570\u636E\u672A\u5BFC\u5165\uFF0C\u6807\u8BC6\u7B26\u91CD\u590D
things.model.update.fail.quote.the.scene.variable.formula.please.delete=\u5f53\u524d\u7269\u6a21\u578b\u88ab\u5f15\u7528\u5230\u573a\u666f\u8fd0\u7b97\u578b\u53d8\u91cf\u7684\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8bf7\u5148\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u4fee\u6539\u64cd\u4f5c\uff01
things.model.delete.fail.quote.the.scene.variable.formula.please.delete=\u5f53\u524d\u7269\u6a21\u578b\u88ab\u5f15\u7528\u5230\u573a\u666f\u8fd0\u7b97\u578b\u53d8\u91cf\u7684\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u5220\u9664\uff0c\u8bf7\u5148\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff01
things.model.import.data.exception=\u5bfc\u5165\u6570\u636e\u5f02\u5e38
things.model.register.address.repeat=\u540c\u4e00\u4e2a\u91c7\u96c6\u70b9\u6a21\u677f\u4e0b,\u5bc4\u5b58\u5668\u5730\u5740\u91cd\u590d,\u8bf7\u68c0\u67e5\u5bfc\u5165\u53d8\u91cf\u5bc4\u5b58\u5668\u5730\u5740
##MQTT
mqtt.unauthorized=mqtt\u8D26\u53F7\u548C\u5BC6\u7801\u4E0E\u8BA4\u8BC1\u670D\u52A1\u5668\u914D\u7F6E\u4E0D\u5339\u914D
##Oauth
oauth.response.type.not.valid=response_type\u53C2\u6570\u503C\u53EA\u5141\u8BB8code\u548Ctoken
oauth.grant.type.null=\u672A\u77E5\u6388\u6743\u7C7B\u578B
oauth.grant.type.implicit.not.support=Token\u63A5\u53E3\u4E0D\u652F\u6301implicit\u6388\u6743\u6A21\u5F0F
oauth.access.token.null=\u8BBF\u95EE\u4EE4\u724C\u4E0D\u80FD\u4E3A\u7A7A
obtain.basic.authorization.failed=client_id\u6216client_secret\u672A\u6B63\u786E\u4F20\u9012
##Record
record.app.null=app\u4E0D\u80FD\u4E3A\u7A7A
record.stream.null=stream\u4E0D\u80FD\u4E3A\u7A7A
record.time.not.valid=\u9519\u8BEF\u7684\u5F00\u59CB\u65F6\u95F4\u6216\u7ED3\u675F\u65F6\u95F4
record.file.null=\u672A\u627E\u5230\u89C6\u9891\u6587\u4EF6
##ErrorCodeConstants
app.not.found=App \u4E0D\u5B58\u5728
app.is.disable=App \u5DF2\u7ECF\u88AB\u7981\u7528
app.exist.order.cant.delete=\u652F\u4ED8\u5E94\u7528\u5B58\u5728\u652F\u4ED8\u8BA2\u5355\uFF0C\u65E0\u6CD5\u5220\u9664
app.exist.refund.cant.delete=\u652F\u4ED8\u5E94\u7528\u5B58\u5728\u9000\u6B3E\u8BA2\u5355\uFF0C\u65E0\u6CD5\u5220\u9664
channel.not.found=\u652F\u4ED8\u6E20\u9053\u7684\u914D\u7F6E\u4E0D\u5B58\u5728
channel.is.disable=\u652F\u4ED8\u6E20\u9053\u5DF2\u7ECF\u7981\u7528
channel.exists.same.channel.error=\u5DF2\u5B58\u5728\u76F8\u540C\u7684\u6E20\u9053
order.not.found=\u652F\u4ED8\u8BA2\u5355\u4E0D\u5B58\u5728
order.status.is.not.waiting=\u652F\u4ED8\u8BA2\u5355\u4E0D\u5904\u4E8E\u5F85\u652F\u4ED8
order.status.is.success=\u8BA2\u5355\u5DF2\u652F\u4ED8\uFF0C\u8BF7\u5237\u65B0\u9875\u9762
order.is.expired=\u652F\u4ED8\u8BA2\u5355\u5DF2\u7ECF\u8FC7\u671F
order.submit.channel.error=\u53D1\u8D77\u652F\u4ED8\u62A5\u9519\uFF0C\u9519\u8BEF\u7801\uFF1A{}\uFF0C\u9519\u8BEF\u63D0\u793A\uFF1A{}
order.refund.fail.status.error=\u652F\u4ED8\u8BA2\u5355\u9000\u6B3E\u5931\u8D25\uFF0C\u539F\u56E0\uFF1A\u72B6\u6001\u4E0D\u662F\u5DF2\u652F\u4ED8\u6216\u5DF2\u9000\u6B3E
order.extension.not.found=\u652F\u4ED8\u4EA4\u6613\u62D3\u5C55\u5355\u4E0D\u5B58\u5728
order.extension.status.is.not.waiting=\u652F\u4ED8\u4EA4\u6613\u62D3\u5C55\u5355\u4E0D\u5904\u4E8E\u5F85\u652F\u4ED8
order.extension.is.paid=\u8BA2\u5355\u5DF2\u652F\u4ED8\uFF0C\u8BF7\u7B49\u5F85\u652F\u4ED8\u7ED3\u679C
refund.price.exceed=\u9000\u6B3E\u91D1\u989D\u8D85\u8FC7\u8BA2\u5355\u53EF\u9000\u6B3E\u91D1\u989D
refund.has.refunding=\u5DF2\u7ECF\u6709\u9000\u6B3E\u5728\u5904\u7406\u4E2D
refund.exists=\u5DF2\u7ECF\u5B58\u5728\u9000\u6B3E\u5355
refund.not.found=\u652F\u4ED8\u9000\u6B3E\u5355\u4E0D\u5B58\u5728
refund.statue.is.not.waiting=\u652F\u4ED8\u9000\u6B3E\u5355\u4E0D\u5904\u4E8E\u5F85\u9000\u6B3E
demo.order.not.found=\u793A\u4F8B\u8BA2\u5355\u4E0D\u5B58\u5728
demo.order.update.paid.status.not.unpaid=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u8BA2\u5355\u4E0D\u662F\u3010\u672A\u652F\u4ED8\u3011\u72B6\u6001
demo.order.update.paid.fail.pay.order.id.error=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u652F\u4ED8\u5355\u7F16\u53F7\u4E0D\u5339\u914D
demo.order.update.paid.fail.pay.order.status.not.success=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u652F\u4ED8\u5355\u72B6\u6001\u4E0D\u662F\u3010\u652F\u4ED8\u6210\u529F\u3011\u72B6\u6001
demo.order.update.paid.fail.pay.price.not.match=\u793A\u4F8B\u8BA2\u5355\u66F4\u65B0\u652F\u4ED8\u72B6\u6001\u5931\u8D25\uFF0C\u652F\u4ED8\u5355\u91D1\u989D\u4E0D\u5339\u914D
demo.order.refund.fail.not.paid=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u793A\u4F8B\u8BA2\u5355\u672A\u652F\u4ED8
demo.order.refund.fail.refunded=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u793A\u4F8B\u8BA2\u5355\u5DF2\u9000\u6B3E
demo.order.refund.fail.refund.not.found=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u8BA2\u5355\u4E0D\u5B58\u5728
demo.order.refund.fail.refund.not.success=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u8BA2\u5355\u672A\u9000\u6B3E\u6210\u529F
demo.order.refund.fail.refund.order.id.error=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u5355\u7F16\u53F7\u4E0D\u5339\u914D
demo.order.refund.fail.refund.price.not.match=\u53D1\u8D77\u9000\u6B3E\u5931\u8D25\uFF0C\u9000\u6B3E\u5355\u91D1\u989D\u4E0D\u5339\u914D
device.order.control.no.permission=\u6682\u65e0\u6743\u9650\u64cd\u4f5c\uff0c\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u5206\u914d\u6307\u4ee4\u6743\u9650\uff01
##sysConfig
sysConfig.add.param.fail.name.exist=\u65b0\u589e\u53c2\u6570[{}]\u5931\u8d25\uff0c\u53c2\u6570\u952e\u540d\u5df2\u5b58\u5728
sysConfig.update.param.fail.name.exist=\u4fee\u6539\u53c2\u6570[{}]\u5931\u8d25\uff0c\u53c2\u6570\u952e\u540d\u5df2\u5b58\u5728
##sysRegister
sysRegister.fail.not.enable.register=\u5f53\u524d\u7cfb\u7edf\u6ca1\u6709\u5f00\u542f\u6ce8\u518c\u529f\u80fd\uff01
##ossDetail
ossDetail.fail.file.not.empty=\u4e0a\u4f20\u6587\u4ef6\u4e0d\u80fd\u4e3a\u7a7a
##notify
sms.send.fail.contact.admin=\u77ed\u4fe1\u53d1\u9001\u5931\u8d25\uff0c\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\uff01
captcha.has.sent.please.try.again.later=\u9a8c\u8bc1\u7801\u5df2\u53d1\u9001\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5\uff01
not.find.enable.notify.template=\u67e5\u8be2\u4e0d\u5230\u542f\u7528\u7684\u901a\u77e5\u6a21\u677f
not.find.notify.channel=\u67e5\u8be2\u4e0d\u5230\u901a\u77e5\u6e20\u9053
##dataCenter
please.select.device=\u8bf7\u9009\u62e9\u8bbe\u5907
please.incoming.serialNumber=\u8bf7\u4f20\u5165\u8bbe\u5907\u7f16\u53f7
##license
certificate.install.success=\u8bc1\u4e66\u5b89\u88c5\u6210\u529f
certificate.install.fail=\u8bc1\u4e66\u5b89\u88c5\u5931\u8d25:[{}]
certificate.incoming.success=\u8bc1\u4e66\u4e0a\u4f20\u6210\u529f
certificate.incoming.fail=\u8bc1\u4e66\u4e0a\u4f20\u5931\u8d25
certificate.upload.success=\u8bc1\u4e66\u4e0a\u4f20\u6210\u529f
certificate.upload.fail=\u8bc1\u4e66\u4e0a\u4f20\u5931\u8d25:[{}]
##sceneModel
please.incoming.scene.id=\u8bf7\u4f20\u5165\u573a\u666fid
please.incoming.device.config.number=\u8bf7\u4f20\u5165\u5173\u8054\u8bbe\u5907\u914d\u7f6e\u7684\u5e8f\u53f7
sceneModel.please.introduced.id=\u8bf7\u4f20\u5165\u573a\u666f\u7ba1\u7406id
sceneModel.current.variable.quote.operate.variable.formula.please.delete=\u5f53\u524d\u53d8\u91cf\u88ab\u5f15\u7528\u5230\u573a\u666f\u8fd0\u7b97\u578b\u53d8\u91cf\u7684\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u5220\u9664\uff0c\u8bf7\u5148\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff01
sceneModel.scene.already.bind.device=\u573a\u666f\u5df2\u7ed1\u5b9a\u8be5\u8bbe\u5907\uff0c\u8bf7\u91cd\u65b0\u9009\u62e9\uff01
sceneModel.update.fail.device.variable.has.quote.scene.variable.please.delete=\u5f53\u524d\u8bbe\u5907\u4e0b\u5b58\u5728\u53d8\u91cf\u88ab\u5f15\u7528\u5230\u8fd0\u7b97\u578b\u53d8\u91cf\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8bf7\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u4fee\u6539\u64cd\u4f5c\uff01
sceneModel.delete.fail.device.variable.has.quote.scene.variable.please.delete=\u5f53\u524d\u8bbe\u5907\u4e0b\u5b58\u5728\u53d8\u91cf\u88ab\u5f15\u7528\u5230\u8fd0\u7b97\u578b\u53d8\u91cf\u8ba1\u7b97\u516c\u5f0f\u4e2d\uff0c\u65e0\u6cd5\u5220\u9664\uff0c\u8bf7\u5220\u9664\u5f15\u7528\u5173\u7cfb\u540e\u518d\u6267\u884c\u5220\u9664\u64cd\u4f5c\uff01
sceneModel.formula.cannot.empty=\u8ba1\u7b97\u516c\u5f0f\u4e0d\u80fd\u4e3a\u7a7a\uff01
sceneModel.variable.cannot.empty=\u53d8\u91cf\u4e0d\u80fd\u4e3a\u7a7a\uff01
sceneModel.formula.and.variable.number.inconsistent=\u8ba1\u7b97\u516c\u5f0f\u548c\u53d8\u91cf\u4e2a\u6570\u4e0d\u4e00\u81f4\uff0c\u8bf7\u68c0\u67e5\u540e\u91cd\u8bd5
sceneModel.update.fail.variable.name.exist=\u53d8\u91cf\u540d\u79f0\u5df2\u5b58\u5728\uff0c\u8bf7\u4fee\u6539\u540e\u91cd\u8bd5\uff01
##oauthClientDetail
add.fail.same.client.can.config.one=\u540c\u4e00\u4e2a\u6388\u6743\u5e73\u53f0\u53ea\u80fd\u914d\u7f6e\u4e00\u6761\u4fe1\u606f\uff0c\u8bf7\u52ff\u91cd\u590d\u914d\u7f6e
client.id.is.exist=\u5ba2\u6237\u7aefid\uff1a[{}]\u5df2\u5b58\u5728\u6216\u5df2\u88ab\u5176\u4ed6\u79df\u6237\u4f7f\u7528
oauthClientDetail.client.not.exist=oauth2 \u5ba2\u6237\u7aef\u4e0d\u5b58\u5728
oauthClientDetail.client.disabled=oauth2 \u5ba2\u6237\u7aef\u5df2\u7981\u7528
oauthClientDetail.invalid.client.set=\u65e0\u6548 client_secret
oauthClientDetail.invalid.redirects=\u65e0\u6548 redirect_uri\uff1a[{}]
##category
delete.fail.please.delete.category.product=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u5206\u7c7b\u4e0b\u7684\u4ea7\u54c1
##goviewProjectData
only.allow.select.operate=\u53ea\u5141\u8bb8select\u64cd\u4f5c\uff0c\u7981\u6b62update\u3001delete\u3001insert\u64cd\u4f5c
##newsCategory
newsCategory.delete.fail.please.delete.category.info=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u5206\u7c7b\u4e0b\u7684\u65b0\u95fb\u8d44\u8baf
##product
delete.fail.please.delete.firmware=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u4ea7\u54c1\u4e0b\u7684\u56fa\u4ef6
delete.fail.please.delete.product.device=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u5220\u9664\u5bf9\u5e94\u4ea7\u54c1\u4e0b\u7684\u8bbe\u5907
delete.fail.please.delete.product.scene=\u5220\u9664\u5931\u8d25\uff0c\u8bf7\u5148\u4fee\u6539\u6216\u5220\u9664\u5bf9\u5e94\u4ea7\u54c1\u4e0b\u7684\u573a\u666f\u8054\u52a8\uff1a[{}]
product.status.update.fail.value.fail=\u72b6\u6001\u66f4\u65b0\u5931\u8d25,\u72b6\u6001\u503c\u6709\u8bef
product.status.update.fail=\u72b6\u6001\u66f4\u65b0\u5931\u8d25
##socialLogin
bind.account.not.exist=\u7ed1\u5b9a\u8d26\u6237\u4e0d\u5b58\u5728
socialLogin.verify.has.expired=\u9a8c\u8bc1\u7801\u5df2\u5931\u6548\uff0c\u8bf7\u91cd\u65b0\u83b7\u53d6
socialLogin.platform.type.fail=\u9519\u8bef\u5e73\u53f0\u7c7b\u578b
user.account.and.bind.account.not.match=\u7528\u6237\u8d26\u6237\u548c\u7ed1\u5b9a\u8d26\u6237\u4e0d\u5339\u914d
socialLogin.user.not.exist=\u7528\u6237\u4e0d\u5b58\u5728
socialLogin.bind.end.user.cannot.login.web=\u8bf7\u52ff\u7ed1\u5b9a\u7ec8\u7aef\u7528\u6237\uff0c\u7ed1\u5b9a\u7ec8\u7aef\u7528\u6237\u540e\u4e0d\u53ef\u767b\u5f55web\u7aef
socialLogin.account.already.bind.other.wechat.please.unbind=\u8be5\u8d26\u53f7\u5df2\u7ecf\u7ed1\u5b9a\u5176\u4ed6\u5fae\u4fe1\uff0c\u8bf7\u5148\u89e3\u7ed1\u540e\u91cd\u8bd5\uff01
socialLogin.register.fail.please.check.role.exist=\u6ce8\u518c\u5931\u8d25,\u8bf7\u8054\u7cfb\u7ba1\u7406\u4eba\u5458\u68c0\u67e5\u673a\u6784\u89d2\u8272\u662f\u5426\u5b58\u5728
socialLogin.web.not.allow.end.user.login=web\u7aef\u4e0d\u5141\u8bb8\u7ec8\u7aef\u7528\u6237\u767b\u5f55
##alert
alert.push.fail.device.not.exist=\u544a\u8b66\u63a8\u9001\uff0c\u8bbe\u5907\u4e0d\u5b58\u5728\uff1a[{}]
##modbus
not.modbus.protocol.please.config.collect.protocol=\u975emodbus\u534f\u8bae\u8bf7\u5148\u914d\u7f6e\u4e3b\u52a8\u91c7\u96c6\u534f\u8bae
modbus.point.not.config=\u672a\u914d\u7f6emodbus\u70b9\u4f4d
##ota
firmwareTask.add.fail.FirmwareTask.exist=\u4efb\u52a1\uff1a[{}]\u5df2\u5b58\u5728
firmware.version.not.exist=\u56fa\u4ef6\u7248\u672c\u4e0d\u5b58\u5728%21
##mqttMessage
mqtt.service.send.device.not.exist=\u670d\u52a1\u4e0b\u53d1\u7684\u8bbe\u5907\uff1a[{}]\u4e0d\u5b58\u5728
mqtt.disconnect.occur.fail=\u65ad\u5f00mqtt\u8fde\u63a5\u53d1\u751f\u9519\u8bef\uff1a[{}]
##genTable
genTable.template.rendering.fail=\u5bfc\u5165\u5931\u8d25\uff1a[{}]
genTable.data.sync.fail.original.table.not.exist=\u540c\u6b65\u6570\u636e\u5931\u8d25\uff0c\u539f\u8868\u7ed3\u6784\u4e0d\u5b58\u5728
genTable.tree.code.field.cannot.empty=\u6811\u7f16\u7801\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a
genTable.tree.parent.code.field.cannot.empty=\u6811\u7236\u7f16\u7801\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a
genTable.tree.name.field.cannot.empty=\u6811\u540d\u79f0\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a
genTable.relate.child.table.name.cannot.empty=\u5173\u8054\u5b50\u8868\u7684\u8868\u540d\u4e0d\u80fd\u4e3a\u7a7a
genTable.child.table.relate.foreign.key.name.cannot.empty=\u5b50\u8868\u5173\u8054\u7684\u5916\u952e\u540d\u4e0d\u80fd\u4e3a\u7a7a
##oauthCode
oauthCode.code.not.exist=code \u4e0d\u5b58\u5728
##protocol
protocol.input.content.is.empty=\u8f93\u5165\u5185\u5bb9\u4e3a\u7a7a
protocol.data.parse.error=\u6570\u636e\u89e3\u6790\u51fa\u9519[{}]
protocol.data.parse.exception=\u6570\u636e\u89e3\u6790\u5f02\u5e38[{}]
protocol.instruction.number.exception=\u6307\u4ee4\u7f16\u53f7\u5f02\u5e38\uff1a[{}]
##modbusJob
modbusJob.add.fail.please.bind.gateway=\u8bf7\u5148\u7ed1\u5b9a\u7f51\u5173
thingsModel.array.or.object.no.need.update=\u6682\u65e0\u9700\u8981\u66f4\u65b0\u7684\u6570\u7ec4\u3001\u5bf9\u8c61\u7c7b\u7269\u6a21\u578b
sync.fail.please.try.again=\u540c\u6b65\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\uff01
sync.success=\u540c\u6b65\u6210\u529f
## scada
scada.product.id.is.null=\u4ea7\u54c1id\u4e3a\u7a7a
scada.scene.id.is.null=\u573a\u666fid\u4e3a\u7a7a
scada.guid.cannot.empty=guid\u4e0d\u80fd\u4e3a\u7a7a
scada.base64.change.image.exception=\u7ec4\u6001base64\u8f6c\u56fe\u7247\u5f02\u5e38:[{}]
scada.please.select.device=\u8bf7\u9009\u62e9\u8bbe\u5907
scada.please.enter.password=\u8bf7\u8f93\u5165\u5bc6\u7801\uff01
scada.please.login=\u672a\u767b\u5f55\uff0c\u8bf7\u767b\u5f55\u540e\u91cd\u8bd5
scada.password.fail.please.reload.enter=\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165\uff01
scada.product.has.relate.please.select.again=\u8be5\u4ea7\u54c1\u5df2\u7ecf\u5173\u8054\u7ec4\u6001\uff0c\u8bf7\u91cd\u65b0\u9009\u62e9\uff01
scada.scene.has.relate.please.select.again=\u8be5\u573a\u666f\u5df2\u7ecf\u5173\u8054\u7ec4\u6001\uff0c\u8bf7\u91cd\u65b0\u9009\u62e9\uff01
scada.not.allow.view.other.tenant.config=\u4e0d\u5141\u8bb8\u67e5\u770b\u5176\u4ed6\u79df\u6237\u7684\u7ec4\u6001\uff01
scada.upload.gallery.file.fail=\u4e0a\u4f20\u56fe\u5e93\u6587\u4ef6\u5f02\u5e38\uff0c[{}]
scada.upload.fail=\u4e0a\u4f20\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\uff01
scada.invalid.profile=\u65e0\u6548\u7684\u914d\u7f6e\u6587\u4ef6
scada.import.success.need.replace.variable=\u5bfc\u5165\u6210\u529f\uff0c\u5f53\u524d\u9875\u9762\u9700\u8981\u91cd\u65b0\u66ff\u6362\u7ed1\u5b9a\u7ec4\u4ef6\u7684\u53d8\u91cf\uff01
## speaker
speaker.product.has.relate=\u8be5\u4ea7\u54c1\u5df2\u5173\u8054\uff0c\u8bf7\u52ff\u91cd\u590d\u5173\u8054
speaker.product.relate.add.fail=\u65b0\u589e\u5931\u8d25
speaker.not.found.product.relate=\u672a\u67e5\u8be2\u5230\u4ea7\u54c1\u5173\u8054\u4fe1\u606f
##file
file.content.is.empty=\u6587\u4ef6\u5185\u5bb9\u4e3a\u7a7a
file.is.invalid=\u65e0\u6548\u7684\u6587\u4ef6

Binary file not shown.

View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property name="log.path" scope="context" value="/logs" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-debug.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-debug.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 10天 -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 DEBUG-->
<level>DEBUG</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 10天 -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-warn.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-warn.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 10天 -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>WARN</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 10天 -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 10天 -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 规则引擎日志输出 -->
<appender name="script" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/rule/script.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/rule/script.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 3天 -->
<maxHistory>3</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%method,%line] - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<appender name="scene" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/rule/scene.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/rule/scene.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 3天 -->
<maxHistory>3</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%method,%line] - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.fastbee" level="debug" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_debug"/>
<appender-ref ref="file_info" />
<appender-ref ref="file_warn" />
<appender-ref ref="file_error" />
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
<!--规则引擎日志-->
<logger name="script" level="info">
<appender-ref ref="script"/>
</logger>
<logger name="scene" level="info">
<appender-ref ref="scene"/>
</logger>
</configuration>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="autoMappingBehavior" value="FULL"/>
<setting name="autoMappingUnknownColumnBehavior" value="NONE"/>
</settings>
</configuration>

Binary file not shown.

View File

@ -0,0 +1,21 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fastbee</groupId>
<artifactId>fastbee</artifactId>
<version>${revision}</version>
</parent>
<artifactId>fastbee-common-extend</artifactId>
<dependencies>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-framework</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,168 @@
package com.fastbee.common.extend.aspectj;
import com.fastbee.common.annotation.DataScope;
import com.fastbee.common.core.domain.BaseEntity;
import com.fastbee.common.core.text.Convert;
import com.fastbee.common.extend.core.domin.model.LoginUser;
import com.fastbee.common.extend.core.domin.entity.SysRole;
import com.fastbee.common.extend.core.domin.entity.SysUser;
import com.fastbee.common.extend.utils.SecurityUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.framework.security.context.PermissionContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 数据过滤处理
*
* @author ruoyi
*/
@Aspect
@Component
public class DataScopeAspect
{
/**
* 全部数据权限
*/
public static final String DATA_SCOPE_ALL = "1";
/**
* 自定数据权限
*/
public static final String DATA_SCOPE_CUSTOM = "2";
/**
* 部门数据权限
*/
public static final String DATA_SCOPE_DEPT = "3";
/**
* 部门及以下数据权限
*/
public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
/**
* 仅本人数据权限
*/
public static final String DATA_SCOPE_SELF = "5";
/**
* 数据权限过滤关键字
*/
public static final String DATA_SCOPE = "dataScope";
@Before("@annotation(controllerDataScope)")
public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
{
clearDataScope(point);
handleDataScope(point, controllerDataScope);
}
protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
{
// 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNotNull(loginUser))
{
SysUser currentUser = loginUser.getUser();
// 如果是超级管理员则不过滤数据
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
{
String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
controllerDataScope.userAlias(), permission);
}
}
}
/**
* 数据范围过滤
*
* @param joinPoint 切点
* @param user 用户
* @param deptAlias 部门别名
* @param userAlias 用户别名
* @param permission 权限字符
*/
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)
{
StringBuilder sqlString = new StringBuilder();
List<String> conditions = new ArrayList<String>();
for (SysRole role : user.getRoles())
{
String dataScope = role.getDataScope();
if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope))
{
continue;
}
if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{
continue;
}
if (DATA_SCOPE_ALL.equals(dataScope))
{
sqlString = new StringBuilder();
break;
}
else if (DATA_SCOPE_CUSTOM.equals(dataScope))
{
sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
role.getRoleId()));
}
else if (DATA_SCOPE_DEPT.equals(dataScope))
{
sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
}
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
{
sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
deptAlias, user.getDeptId(), user.getDeptId()));
}
else if (DATA_SCOPE_SELF.equals(dataScope))
{
if (StringUtils.isNotBlank(userAlias))
{
sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
}
else
{
// 数据权限为仅本人且没有userAlias别名不查询任何数据
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
}
}
conditions.add(dataScope);
}
if (StringUtils.isNotBlank(sqlString.toString()))
{
Object params = joinPoint.getArgs()[0];
if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
{
BaseEntity baseEntity = (BaseEntity) params;
baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
}
}
}
/**
* 拼接权限sql前先清空params.dataScope参数防止注入
*/
private void clearDataScope(final JoinPoint joinPoint)
{
Object params = joinPoint.getArgs()[0];
if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
{
BaseEntity baseEntity = (BaseEntity) params;
baseEntity.getParams().put(DATA_SCOPE, "");
}
}
}

View File

@ -0,0 +1,15 @@
package com.fastbee.common.extend.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "server.http.auth")
@Data
public class HttpAuthConfig {
private String type;
private String username;
private String password;
}

View File

@ -0,0 +1,88 @@
package com.fastbee.common.extend.config;
import com.fastbee.common.config.RuoYiConfig;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.extend.interceptor.LanguageInterceptor;
import com.fastbee.framework.interceptor.RepeatSubmitInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* 通用配置
*
* @author ruoyi
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
@Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Resource
private LanguageInterceptor languageInterceptor;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
/** swagger配置 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());;
// 新增音频文件映射
String audioPath = RuoYiConfig.getProfile() + "/upload/audios/";
registry.addResourceHandler("/audios/**")
.addResourceLocations("file:" + audioPath)
.setCachePeriod(0);
}
/**
* 自定义拦截规则
*/
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
//这里配置国际化拦截器的白名单
registry.addInterceptor(languageInterceptor).addPathPatterns("/**").excludePathPatterns("/v2/api-docs",
"/tool/gen/**");
}
/**
* 跨域配置
*/
@Bean
public CorsFilter corsFilter()
{
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置访问源地址
config.addAllowedOriginPattern("*");
// 设置访问源请求头
config.addAllowedHeader("*");
// 设置访问源请求方法
config.addAllowedMethod("*");
// 有效期 1800秒
config.setMaxAge(1800L);
// 添加映射路径拦截一切请求
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
return new CorsFilter(source);
}
}

View File

@ -0,0 +1,191 @@
package com.fastbee.common.extend.core.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fastbee.common.constant.CacheConstants;
import com.fastbee.common.constant.HttpStatus;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.extend.core.domin.model.LoginUser;
import com.fastbee.common.extend.utils.SecurityUtils;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
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 TableDataInfo getDataTable(List<?> list, Long total)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
rspData.setRows(list);
rspData.setTotal(total);
return rspData;
}
/**
* 根据分页对象构建表格分页数据对象
*/
public static TableDataInfo getDataTable(IPage<?> page) {
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(cn.hutool.http.HttpStatus.HTTP_OK);
rspData.setMsg("查询成功");
rspData.setRows(page.getRecords());
rspData.setTotal(page.getTotal());
return rspData;
}
/**
* 根据数据列表构建表格分页数据对象
*/
public static TableDataInfo getDataTable(List<?> list) {
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(cn.hutool.http.HttpStatus.HTTP_OK);
rspData.setMsg("查询成功");
rspData.setRows(list);
rspData.setTotal(list.size());
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();
}
protected AjaxResult toAjax(Object result) {
return result != null ? success(result) : 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();
}
}

View File

@ -0,0 +1,28 @@
package com.fastbee.common.extend.core.controller;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.utils.license.LicenseManagerHolder;
import de.schlichtherle.license.LicenseManager;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhuangpengli
*/
@Api(tags = "公共模块")
@RestController
@RequestMapping("/commons")
public class CommonsController extends BaseController {
@GetMapping(value = "/getInfo")
public AjaxResult getInfo() {
LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
try {
return AjaxResult.success(licenseManager.verify());
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error();
}
}
}

View File

@ -0,0 +1,164 @@
package com.fastbee.common.extend.core.domin.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fastbee.common.core.domain.PageEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import java.io.Serializable;
import java.util.*;
/**
* 机构对象 sys_dept
*
* @author zhuangpeng.li
* @date 2024-12-25
*/
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SysDept", description = "机构 sys_dept")
@Data
@TableName("sys_dept" )
public class SysDept extends PageEntity implements Serializable{
private static final long serialVersionUID=1L;
/** 机构id */
@TableId(value = "dept_id", type = IdType.AUTO)
@ApiModelProperty("机构id")
private Long deptId;
/** 机构系统账号ID */
@ApiModelProperty("机构系统账号ID")
private Long deptUserId;
/** 上级机构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;
/** 机构状态0正常 1停用 */
@ApiModelProperty("机构状态")
private Integer status;
/** 删除标志0代表存在 2代表删除 */
@ApiModelProperty("删除标志")
@TableLogic
private String delFlag;
/** 创建者 */
@ApiModelProperty("创建者")
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("创建时间")
private Date createTime;
/** 更新者 */
@ApiModelProperty("更新者")
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("更新时间")
private Date updateTime;
/** 邮箱 */
@ApiModelProperty("邮箱")
private String email;
/** 机构类型 */
@ApiModelProperty("机构类型")
private Integer deptType;
/**
* 机构logo
*/
@ApiModelProperty("机构logo")
private String deptLogo;
/**
* logo名称
*/
@ApiModelProperty("logo名称")
private String logoName;
/** 父部门名称 */
@TableField(exist = false)
@ApiModelProperty("父部门名称")
private String parentName;
/**
* 管理员姓名
*/
@TableField(exist = false)
private String deptUserName;
/** 子部门 */
@TableField(exist = false)
@ApiModelProperty("子部门")
private List<SysDept> children = new ArrayList<SysDept>();
/**
* 是否显示自己
*/
@TableField(exist = false)
private Boolean showOwner;
/**
* 系统账号名称
*/
@TableField(exist = false)
private String userName;
/**
* 系统账号密码
*/
@TableField(exist = false)
private String password;
/**
* 确认密码
*/
@TableField(exist = false)
private String confirmPassword;
@Setter
@TableField(exist = false)
@ApiModelProperty("请求参数")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
public Map<String, Object> getParams(){
if (params == null){
params = new HashMap<>();
}
return params;
}
}

View File

@ -0,0 +1,89 @@
package com.fastbee.common.extend.core.domin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fastbee.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 字典数据对象 sys_dict_data
*
* @author gx_ma
* @date 2024-12-26
*/
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SysDictData", description = "字典数据 sys_dict_data")
@Data
@TableName("sys_dict_data" )
public class SysDictData extends BaseEntity {
private static final long serialVersionUID=1L;
/** 字典编码 */
@TableId(value = "dict_code", type = IdType.AUTO)
@ApiModelProperty("字典编码")
private Long dictCode;
/** 字典排序 */
@ApiModelProperty("字典排序")
private Long dictSort;
/** 字典标签 */
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
@ApiModelProperty("字典标签")
private String dictLabel;
/** 字典键值 */
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
@ApiModelProperty("字典键值")
private String dictValue;
/** 字典类型 */
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
@ApiModelProperty("字典类型")
private String dictType;
/** 样式属性(其他样式扩展) */
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
@ApiModelProperty("样式属性")
private String cssClass;
/** 表格回显样式 */
@ApiModelProperty("表格回显样式")
private String listClass;
/** 是否默认Y是 N否 */
@ApiModelProperty("是否默认")
private String isDefault;
/** 状态0正常 1停用 */
@ApiModelProperty("状态")
private Integer status;
/** 字典标签 */
@TableField(exist = false)
@ApiModelProperty("中文字典标签")
private String dictLabel_zh_CN;
/** 字典标签 */
@TableField(exist = false)
@ApiModelProperty("英文字典标签")
private String dictLabel_en_US;
@TableField(exist = false)
@Deprecated
private String language;
}

View File

@ -0,0 +1,188 @@
package com.fastbee.common.extend.core.domin.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fastbee.common.annotation.Excel;
import com.fastbee.common.core.domain.PageEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 角色表 sys_role
*
* @author ruoyi
*/
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SysRole", description = "角色信息 sys_role")
@Data
@TableName("sys_role")
public class SysRole extends PageEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@TableId(value = "role_id", type = IdType.AUTO)
@ApiModelProperty("角色ID")
private Long roleId;
/**
* 角色名称
*/
@ApiModelProperty("角色名称")
private String roleName;
/**
* 角色权限字符串
*/
@ApiModelProperty("角色权限字符串")
private String roleKey;
/**
* 显示顺序
*/
@ApiModelProperty("显示顺序")
private Integer roleSort;
/**
* 数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限
*/
@ApiModelProperty("数据范围")
private String dataScope;
/**
* 菜单树选择项是否关联显示
*/
@ApiModelProperty("菜单树选择项是否关联显示")
private Integer menuCheckStrictly;
/**
* 部门树选择项是否关联显示
*/
@ApiModelProperty("部门树选择项是否关联显示")
private Integer deptCheckStrictly;
/**
* 角色状态0正常 1停用
*/
@ApiModelProperty("角色状态")
private Integer status;
/**
* 删除标志0代表存在 2代表删除
*/
@ApiModelProperty("删除标志")
@TableLogic
private String delFlag;
/**
* 创建者
*/
@ApiModelProperty("创建者")
private String createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("创建时间")
private Date createTime;
/**
* 更新者
*/
@ApiModelProperty("更新者")
private String updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("更新时间")
private Date updateTime;
/**
* 备注
*/
@ApiModelProperty("备注")
private String remark;
private boolean flag = false;
@Excel(name = "菜单组")
@ApiModelProperty("菜单组")
private Long[] menuIds;
@Excel(name = "部门组")
@ApiModelProperty("部门组")
private Long[] deptIds;
@Excel(name = "角色菜单权限")
@ApiModelProperty("角色菜单权限")
private Set<String> permissions;
private Long deptId;
private String deptName;
private Boolean showChild;
private Boolean canEditRole;
private Boolean manager;
@Setter
@TableField(exist = false)
@ApiModelProperty("请求参数")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
public SysRole() {
}
@JsonGetter("menuCheckStrictly")
public Boolean getMenuCheckStrictlyJson() {
return this.menuCheckStrictly != null && this.menuCheckStrictly == 1;
}
@JsonGetter("deptCheckStrictly")
public Boolean getDeptCheckStrictlyJson() {
return this.deptCheckStrictly != null && this.deptCheckStrictly == 1;
}
@JsonProperty("menuCheckStrictly")
public void setMenuCheckStrictlyJson(Boolean value) {
this.menuCheckStrictly = (value != null && value) ? 1 : 0;
}
@JsonProperty("deptCheckStrictly")
public void setDeptCheckStrictlyJson(Boolean value) {
this.deptCheckStrictly = (value != null && value) ? 1 : 0;
}
public SysRole(Long roleId) {
this.roleId = roleId;
}
public boolean isAdmin() {
return isAdmin(this.roleId);
}
public static boolean isAdmin(Long roleId) {
return roleId != null && 1L == roleId;
}
}

View File

@ -0,0 +1,238 @@
package com.fastbee.common.extend.core.domin.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fastbee.common.annotation.Excel;
import com.fastbee.common.core.domain.PageEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 用户对象 sys_user
*
* @author ruoyi
*/
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SysUser", description = "用户信息 sys_user")
@Data
@TableName("sys_user")
public class SysUser extends PageEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@TableId(value = "user_id", type = IdType.AUTO)
@ApiModelProperty("用户ID")
@Excel(name = "用户ID")
private Long userId;
/**
* 部门ID
*/
@ApiModelProperty("部门ID")
@Excel(name = "部门ID")
private Long deptId;
/**
* 用户账号
*/
@ApiModelProperty("用户账号")
@Excel(name = "用户账号")
private String userName;
/**
* 用户昵称
*/
@ApiModelProperty("用户昵称")
@Excel(name = "用户昵称")
private String nickName;
/**
* 用户类型00系统用户
*/
@ApiModelProperty("用户类型")
@Excel(name = "用户类型")
private String userType;
/**
* 用户邮箱
*/
@ApiModelProperty("用户邮箱")
@Excel(name = "用户邮箱")
private String email;
/**
* 手机号码
*/
@ApiModelProperty("手机号码")
@Excel(name = "手机号码")
private String phonenumber;
/**
* 用户性别0男 1女 2未知
*/
@ApiModelProperty("用户性别")
@Excel(name = "用户性别")
private String sex;
/**
* 头像地址
*/
@ApiModelProperty("头像地址")
@Excel(name = "头像地址")
private String avatar;
/**
* 密码
*/
@ApiModelProperty("密码")
@Excel(name = "密码")
private String password;
/**
* 帐号状态0正常 1停用
*/
@ApiModelProperty("帐号状态")
@Excel(name = "帐号状态")
private Integer status;
/**
* 删除标志0代表存在 1代表删除
*/
@ApiModelProperty("删除标志")
@Excel(name = "删除标志")
@TableLogic
private Integer delFlag;
/**
* 最后登录IP
*/
@ApiModelProperty("最后登录IP")
@Excel(name = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("最后登录时间")
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date loginDate;
/**
* 创建者
*/
@ApiModelProperty("创建者")
@Excel(name = "创建者")
private String createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("创建时间")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
@ApiModelProperty("更新者")
@Excel(name = "更新者")
private String updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("更新时间")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 备注
*/
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@Setter
@TableField(exist = false)
@ApiModelProperty("请求参数")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
@TableField(exist = false)
@ApiModelProperty("部门对象")
private SysDept dept;
/**
* 角色对象
*/
@TableField(exist = false)
@ApiModelProperty("角色对象")
private List<SysRole> roles;
/**
* 角色组
*/
@TableField(exist = false)
@ApiModelProperty("角色组")
private Long[] roleIds;
/**
* 岗位组
*/
@TableField(exist = false)
@ApiModelProperty("岗位组")
private Long[] postIds;
/**
* 角色ID
*/
@TableField(exist = false)
@ApiModelProperty("角色ID")
private Long roleId;
@TableField(exist = false)
private Boolean showChild;
@TableField(exist = false)
private Boolean manager;
@TableField(exist = false)
private String language;
@TableField(exist = false)
private String timeZone;
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
public SysUser() {
}
public SysUser(Long userId) {
this.userId = userId;
}
public boolean isAdmin() {
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId) {
return userId != null && 1L == userId;
}
}

View File

@ -0,0 +1,23 @@
package com.fastbee.common.extend.core.domin.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;
}
}

View File

@ -0,0 +1,22 @@
package com.fastbee.common.extend.core.domin.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;
}
}

View File

@ -0,0 +1,109 @@
package com.fastbee.common.extend.core.domin.model;
/**
* 用户登录对象
*
* @author ruoyi
*/
public class LoginBody
{
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
/**
* 验证码
*/
private String code;
/**
* 唯一标识
*/
private String uuid;
/**
* 手机号
*/
private String phonenumber;
/**
* 登录平台 1-web端2-移动端3-小程序
*/
private Integer sourceType;
/**
* 短信验证码
*/
private String smsCode;
public String getSmsCode() {
return smsCode;
}
public void setSmsCode(String smsCode) {
this.smsCode = smsCode;
}
public Integer getSourceType() {
return sourceType;
}
public void setSourceType(Integer sourceType) {
this.sourceType = sourceType;
}
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;
}
}

View File

@ -0,0 +1,309 @@
package com.fastbee.common.extend.core.domin.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fastbee.common.extend.core.domin.entity.SysUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Set;
/**
* 登录用户身份权限
*
* @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 String requestToken;
/**
* 登录时间
*/
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;
private String language;
private Long deptUserId;
private Boolean neverExpire = Boolean.FALSE;
public Boolean getNeverExpire() {
return neverExpire;
}
public void setNeverExpire(Boolean neverExpire) {
this.neverExpire = neverExpire;
}
public String getLanguage() {
return language;
}
public Long getDeptUserId() {
return deptUserId;
}
public void setDeptUserId(Long deptUserId) {
this.deptUserId = deptUserId;
}
public void setLanguage(String language) {
this.language = language;
}
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 String getRequestToken() {
return requestToken;
}
public void setRequestToken(String requestToken) {
this.requestToken = requestToken;
}
public LoginUser()
{
}
public LoginUser(SysUser user, Set<String> permissions)
{
this.user = user;
this.permissions = permissions;
}
public LoginUser(Long userId, Long deptId, String language, SysUser user, Set<String> permissions)
{
this.userId = userId;
this.deptId = deptId;
this.user = user;
this.language = language;
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;
}
}

View File

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

View File

@ -0,0 +1,66 @@
package com.fastbee.common.extend.core.domin.model.device;
import lombok.Data;
/**
* @author gsb
* @date 2024/6/14 9:25
*/
@Data
public class DeviceAndProtocol {
/**
* 子设备编号
*/
private Long deviceId;
/**
* 设备编号
*/
private String serialNumber;
/**
* 协议编号
*/
private String protocolCode;
/**
* 产品id
*/
private Long productId;
private String transport;
/**
* 设备类型
*/
private Integer deviceType;
/**
* 子设备地址
*/
private Integer slaveId;
/**
* 网关绑定的子设备地址
*/
private Integer proSlaveId;
/**
* 网关设备id
*/
private Long gwDeviceId;
/**
* 网关设备产品id
*/
private Long gwProductId;
/**
* 网关设备编号
*/
private String gwSerialNumber;
/**
* 网关设备名
*/
private String gwDeviceName;
/**
* 网关产品名
*/
private String gwProductName;
private Long tenantId;
}

View File

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

View File

@ -0,0 +1,78 @@
package com.fastbee.common.extend.core.domin.mq;
import com.fastbee.common.enums.FunctionReplyStatus;
import com.fastbee.common.enums.ServerType;
import com.fastbee.common.extend.core.domin.thingsModel.ThingsModelSimpleItem;
import com.fastbee.common.extend.core.protocol.Message;
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;
/**
* 消息id
*/
private String messageId;
/** 设备物模型值的集合 **/
private List<ThingsModelSimpleItem> thingsModelSimpleItem;
/**
* 是否设备回复数据
*/
private Boolean isReply = false;
/**
* 原数据报文
*/
private String sources;
/**
* 设备回复消息
*/
private String replyMessage;
/**
* 设备回复状态
*/
private FunctionReplyStatus status;
/**
* 从机编号
*/
private Integer slaveId;
/**
* 服务器类型
*/
private ServerType serverType;
private String protocolCode;
private Long userId;
private String userName;
private String deviceName;
private SubDeviceBo subDeviceBo;
private GwDeviceBo gwDeviceBo;
}

View File

@ -0,0 +1,80 @@
package com.fastbee.common.extend.core.domin.mq;
import com.fastbee.common.enums.FunctionReplyStatus;
import com.fastbee.common.enums.ServerType;
import com.fastbee.common.enums.ThingsModelType;
import com.fastbee.common.extend.core.domin.mq.message.PropRead;
import com.fastbee.common.extend.core.domin.thingsModel.ThingsModelSimpleItem;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
/**
* 设备上报
* @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 List<ThingsModelSimpleItem> thingsModelSimpleItem;
/*处理的消息服务类型*/
private ServerType serverType;
private Integer slaveId;
private String topic;
private String datatype;
/**
* 是否设备回复数据
*/
private Boolean isReply = false;
/**
* 设备回复消息
*/
private String replyMessage;
/**
* 设备回复状态
*/
private FunctionReplyStatus status;
/**
* 寄存器地址
*/
private int address;
private String protocolCode;
private String sources;
}

View File

@ -0,0 +1,35 @@
package com.fastbee.common.extend.core.domin.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;
}

View File

@ -0,0 +1,32 @@
package com.fastbee.common.extend.core.domin.mq;
import com.fastbee.common.extend.core.domin.thingsModel.ThingsModelSimpleItem;
import lombok.Data;
import java.util.List;
/**
* @author bill
*/
@Data
public class DeviceTestReportBo {
private Long productId;
/**
* 设备编号
*/
private String serialNumber;
/**
* 是否是回复数据
*/
private Boolean isReply;
/**
* 设备物模型值的集合
*/
private List<ThingsModelSimpleItem> thingsModelSimpleItem;
/**
* 原报文
*/
private Object sources;
}

View File

@ -0,0 +1,16 @@
package com.fastbee.common.extend.core.domin.mq;
import lombok.Data;
/**
* @author gsb
* @date 2024/9/4 10:49
*/
@Data
public class GwDeviceBo {
private Long productId;
private String serialNumber;
}

View File

@ -0,0 +1,63 @@
package com.fastbee.common.extend.core.domin.mq;
import com.alibaba.fastjson2.JSONObject;
import com.fastbee.common.enums.ThingsModelType;
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 {
@ApiModelProperty(value = "设备编号")
private String serialNumber;
@NotNull(message = "标识符不能为空")
@ApiModelProperty(value = "标识符")
private String identifier;
/**消息体*/
@ApiModelProperty(value = "消息体")
private JSONObject params;
/**远程消息体*/
@ApiModelProperty(value = "远程调用消息体")
private Map<String,Object> remoteCommand;
/**设备超时时间*/
@ApiModelProperty(value = "设备超时响应时间默认10s")
private Integer timeOut = 10;
@ApiModelProperty(value = "下发物模型类型")
private Integer type = ThingsModelType.SERVICE.getCode();
@ApiModelProperty(value = "是否是影子模式")
private String isShadow ;
@ApiModelProperty(value = "产品id")
private Long productId;
/**
* 物模型名称
*/
private String modelName;
private Date timestamp = DateUtils.getNowDate();
/**
* 场景id
*/
private Long sceneModelId;
/**
* 场景变量类型
*/
private Integer variableType;
private Long userId;
}

View File

@ -0,0 +1,61 @@
package com.fastbee.common.extend.core.domin.mq;
import com.alibaba.fastjson2.JSONObject;
import com.fastbee.common.extend.core.domin.model.device.DeviceAndProtocol;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 服务(指令)下发对象
*
* @author bill
*/
@Data
@NoArgsConstructor
public class MQSendMessageBo {
/**
* 设备编号
*/
private String serialNumber;
/**
* 下发属性标识符
*/
private String identifier;
/**
* 下发参数
*/
private JSONObject params;
/**
* 下发的值
*/
private String value;
/**
* messageId生成放到调用接口的时候生成
*/
private String messageId;
/**
* 协议产品相关信息
*/
private DeviceAndProtocol dp;
/**
* 物模型
*/
private String thingsModel;
/**
* 主题
*/
private String topicName;
public Boolean isShadow;
public Long userId;
public Long delay;
private String parentSerialNumber;
}

View File

@ -0,0 +1,51 @@
package com.fastbee.common.extend.core.domin.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;
}

View File

@ -0,0 +1,35 @@
package com.fastbee.common.extend.core.domin.mq;
import lombok.Data;
/**
* @author bill
*/
@Data
public class SubDeviceBo {
/**
* 网关设备id
*/
private Long gwDeviceId;
/**
* 子设备id
*/
private Long subDeviceId;
/**
* 从机地址
*/
private Integer slaveId;
/**
* 子设备名称
*/
private String subDeviceName;
/**
* 子设备编号
*/
private String subDeviceNo;
private Long subProductId;
}

View File

@ -0,0 +1,43 @@
package com.fastbee.common.extend.core.domin.mq.message;
import com.fastbee.common.extend.core.domin.ota.OtaPackageCode;
import com.fastbee.common.extend.core.protocol.Message;
import com.fastbee.common.extend.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;
private Object body;
/*MQTT OR 其他*/
private int type;
/*Modbus*/
private ModbusCode code;
/**产品id*/
private Long productId;
private OtaPackageCode netModbusCode;
private int bitCount;
}

View File

@ -0,0 +1,59 @@
package com.fastbee.common.extend.core.domin.mq.message;
import com.fastbee.common.enums.ServerType;
import com.fastbee.common.extend.core.protocol.modbus.ModbusCode;
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;
/**
* 从机编号
*/
private Integer slaveId;
private ModbusCode code;
private String protocolCode;
private List<com.fastbee.common.extend.core.domin.mq.message.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);
}
}

View File

@ -0,0 +1,33 @@
package com.fastbee.common.extend.core.domin.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;
}

View File

@ -0,0 +1,31 @@
package com.fastbee.common.extend.core.domin.mq.message;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.Date;
/**
* 设备消息
* @author bill
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DeviceMessage {
/** 下发的数据*/
private Object message;
/** 下发的topic*/
private String topicName;
/** 设备编号*/
private String serialNumber;
private String dataType;
/** 时间 */
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss:SSS")
private Date time;
}

View File

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

View File

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

View File

@ -0,0 +1,32 @@
package com.fastbee.common.extend.core.domin.mq.message;
import lombok.Data;
import java.util.List;
/**
* @author gsb
* @date 2024/6/20 10:53
*/
@Data
public class ModbusPollMsg {
/**
* 下发指令
*/
private List<String> commandList;
/**
* 服务端类型
*/
private Integer serverType;
/**
* 产品id
*/
private Long productId;
/**
* 设备编码
*/
private String serialNumber;
private String transport;
}

View File

@ -0,0 +1,26 @@
package com.fastbee.common.extend.core.domin.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;
}

View File

@ -0,0 +1,39 @@
package com.fastbee.common.extend.core.domin.mq.message;
import com.fastbee.common.extend.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;
}

View File

@ -0,0 +1,21 @@
package com.fastbee.common.extend.core.domin.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:jar2.js,3.c*/
private Integer protocolType;
}

View File

@ -0,0 +1,48 @@
package com.fastbee.common.extend.core.domin.mq.message;
import com.fastbee.common.extend.core.domin.mq.GwDeviceBo;
import com.fastbee.common.extend.core.domin.thingsModel.ThingsModelSimpleItem;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* 上报数据模型bo
* @author bill
*/
@Data
@Accessors(chain = true)
public class ReportDataBo {
/**产品id*/
private Long productId;
/**设备编号*/
private String serialNumber;
/**上报消息*/
private String message;
/**上报的数据*/
private List<ThingsModelSimpleItem> dataList;
/**设备影子*/
private boolean isShadow;
/**
* 物模型类型
* 1=属性2=功能3=事件4=设备升级5=设备上线6=设备下线
*/
private int type;
/**是否执行规则引擎*/
private boolean isRuleEngine;
/**从机编号*/
private Integer slaveId;
/**
* 上报原数据包
*/
private Object sources;
private GwDeviceBo gwDeviceBo;
private Long userId;
private String userName;
private String deviceName;
}

View File

@ -0,0 +1,18 @@
package com.fastbee.common.extend.core.domin.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;
}

View File

@ -0,0 +1,21 @@
package com.fastbee.common.extend.core.domin.mq.ota;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.math.BigDecimal;
/**
* OTA升级回复model
* @author gsb
* @date 2022/10/24 17:20
*/
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class OtaReplyMessage {
private Long taskId;
private BigDecimal version;
private int status;
private int progress;
}

View File

@ -0,0 +1,40 @@
package com.fastbee.common.extend.core.domin.mq.ota;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
/**
* OTA远程升级
* @author gsb
* @date 2022/10/10 10:22
*/
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class OtaUpgradeBo {
// 设备编码
private String serialNumber;
// 升级任务ID
private Long taskId;
// 消息内容
private byte[] msg;
// 设备状态
private int status;
// topic
private String topicName;
// 固件包版本
private BigDecimal version;
// 固件包http地址
private String url;
// 固件包分包传输大小
private int packageSize;
// 固件包传输偏移量
private int offset;
// 升级进度
private int progress;
}

View File

@ -0,0 +1,63 @@
package com.fastbee.common.extend.core.domin.mq.ota;
import com.fastbee.common.utils.DateUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
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;
/**
* 1:指定产品 2:指定设备
*/
private Long upgradeType;
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;
}
}
}

View File

@ -0,0 +1,58 @@
package com.fastbee.common.extend.core.domin.notify;
import lombok.Data;
import java.util.Set;
/**
* @author fastb
* @version 1.0
* @description: TODO
* @date 2023-12-26 11:03
*/
@Data
public class AlertPushParams {
/**
* 通知模版id
*/
private Long notifyTemplateId;
/**
* 告警时间
*/
private String alertTime;
/**
* 设备名称
*/
private String deviceName;
/**
* 设备编号
*/
private String serialNumber;
/**
* 告警发生地点
*/
private String address;
/**
* 告警名称
*/
private String alertName;
/**
* 告警推送手机号
*/
private Set<String> userPhoneSet;
/**
* 告警推送用户id
*/
private Set<Long> userIdSet;
/**
* 当前值
*/
private String value;
/**
* 报警限值
*/
private String matchValue;
}

View File

@ -0,0 +1,33 @@
package com.fastbee.common.extend.core.domin.notify;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.sms4j.provider.config.BaseConfig;
/**
* 个推参数配置
* @author gsb
* @date 2023/12/11 17:14
*/
@Data
@Accessors(chain = true)
public class AppGeTuiParams extends BaseConfig {
@ApiModelProperty("appId")
private String appId;
@ApiModelProperty("appKey")
private String appKey;
@ApiModelProperty("秘钥")
private String masterSecret;
@ApiModelProperty("模板参数")
private String params;
@Override
public String getSupplier() {
return null;
}
}

View File

@ -0,0 +1,35 @@
package com.fastbee.common.extend.core.domin.notify;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.sms4j.provider.config.BaseConfig;
/**
* 企业微信(应用消息)
* @author gsb
* @date 2023/12/11 17:25
*/
@Data
@Accessors(chain = true)
public class EnterpriseWeChatAPPParams extends BaseConfig {
@ApiModelProperty("企业ID")
private String corpId;
@ApiModelProperty("企业应用私钥OA")
private String corpSecret;
@ApiModelProperty("企业应用的id")
private Integer agentId;
//@ApiModelProperty("token")
//private String token;
//@ApiModelProperty("aes秘钥")
//private String aesKey;
@ApiModelProperty("模板参数")
private String params;
@Override
public String getSupplier() {
return null;
}
}

View File

@ -0,0 +1,37 @@
package com.fastbee.common.extend.core.domin.notify;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author fastb
* @version 1.0
* @description: 通知配置参数属性VO类
* @date 2024-01-09 14:01
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class NotifyConfigVO {
/**
* 配置属性
*/
private String attribute;
/**
* 配置属性名称
*/
private String name;
/**
* 配置属性样式 string-字符串text-富文本file-文件boolean-启用int-整数
*/
private String type;
/**
*
*/
private String value;
}

View File

@ -0,0 +1,33 @@
package com.fastbee.common.extend.core.domin.notify;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 通知发送响应类
* @date 2024-01-11 16:06
*/
@Data
public class NotifySendResponse {
/**
* 发送结果 1-成功0-失败
*/
private Integer status = 0;
/**
* 返回结果内容
*/
private String resultContent = "";
/**
* 发送内容变量替换后的
*/
private String sendContent = "";
/**
* 不是使用sendAccount账号发送而是像钉钉这种发送所有人或部门记录这个
*/
private String otherSendAccount = "";
}

View File

@ -0,0 +1,31 @@
package com.fastbee.common.extend.core.domin.notify;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 微信服务号推送参数
* @author gsb
* @date 2023/12/11 17:11
*/
@Data
@Accessors(chain = true)
public class WeChatServerParams {
@ApiModelProperty("appId")
private String appId;
@ApiModelProperty("app秘钥")
private String secret;
@ApiModelProperty("模板ID")
private String templateId;
@ApiModelProperty("跳转地址")
private String page;
@ApiModelProperty("模板参数")
private String params;
}

View File

@ -0,0 +1,28 @@
package com.fastbee.common.extend.core.domin.notify.alertPush;
import lombok.Data;
/**
* 推送项item
* @author bill
*/
@Data
public class AlertPushItem {
/**
* 告警时间
*/
private String alertTime;
/**
* 设备编号
*/
private String serialNumber;
/**
* 告警发生地点
*/
private String address;
/**
* 告警名称
*/
private String alertName;
}

View File

@ -0,0 +1,32 @@
package com.fastbee.common.extend.core.domin.notify.alertPush;
import lombok.Data;
import java.util.List;
/**
* 推送配置信息
* @author bill
*/
@Data
public class PushMsg {
/**
* 用户Id
*/
private Long userId;
/**
* 设备id
*/
private Long deviceId;
/**
* 告警id
*/
private Long alertId;
/**
* 推送内容值
*/
private AlertPushItem item;
private List<String> values;
}

View File

@ -0,0 +1,21 @@
package com.fastbee.common.extend.core.domin.notify.config;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 钉钉渠道应用配置类
* @date 2024-01-12 17:50
*/
@Data
public class DingTalkConfigParams {
private String appKey;
private String appSecret;
private String agentId;
private String webHook;
}

View File

@ -0,0 +1,48 @@
package com.fastbee.common.extend.core.domin.notify.config;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 邮箱配置参数
* @author gsb
* @date 2023/12/11 17:17
*/
@Data
public class EmailConfigParams {
@ApiModelProperty("服务器地址")
private String smtpServer;
@ApiModelProperty("端口号")
private String port;
@ApiModelProperty("账号(发件人地址)")
private String username;
@ApiModelProperty("密码")
private String password;
/**
* 是否开启ssl 默认开启 QQ之类的邮箱默认都需要ssl
*/
@ApiModelProperty("是否启动ssl")
private Boolean sslEnable;
/**
* 是否开启验证 默认开启
*/
@ApiModelProperty("启动ttl")
private Boolean authEnable;
/**
* 重试间隔单位默认为5秒
*/
private Integer retryInterval = 5;
/**
* 重试次数默认为1次
*/
private Integer maxRetries = 1;
}

View File

@ -0,0 +1,15 @@
package com.fastbee.common.extend.core.domin.notify.config;
import lombok.Data;
/**
* @author admin
* @version 1.0
* @description: MQTT推送
* @date 2024-12-30 10:38
*/
@Data
public class MqttConfigParams {
// private String topic = "/notify/alert/web/push";
}

View File

@ -0,0 +1,23 @@
package com.fastbee.common.extend.core.domin.notify.config;
import lombok.Data;
/**
* 语音配置
* @author fastb
* @date 2023-12-09 17:32
*/
@Data
public class VoiceConfigParams {
/**
* 您的AccessKey ID
*/
private String accessKeyId;
/**
* 您的AccessKey Secret
*/
private String accessKeySecret;
}

View File

@ -0,0 +1,25 @@
package com.fastbee.common.extend.core.domin.notify.config;
import lombok.Data;
/**
* 微信推送配置参数
* @author gsb
* @date 2023/12/11 17:11
*/
@Data
public class WeChatConfigParams {
private String appId;
private String appSecret;
private String corpId;
private String corpSecret;
private String agentId;
private String webHook;
}

View File

@ -0,0 +1,53 @@
package com.fastbee.common.extend.core.domin.notify.msg;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 钉钉模版配置参数类
* @date 2024-01-12 17:51
*/
@Data
public class DingTalkMsgParams {
/**
* 发送账号
*/
private String sendAccount;
/**
* 是否发送所有人
*/
private String sendAllEnable;
/**
* 发送什么类型的文本
*/
private String msgType;
/**
* 消息内容
*/
private String content;
/**
* 消息标题
*/
private String title;
/**
* 消息链接
*/
private String messageUrl;
/**
* 图片链接
*/
private String picUrl;
/**
* 所属部门id
*/
private String deptId;
}

View File

@ -0,0 +1,33 @@
package com.fastbee.common.extend.core.domin.notify.msg;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 邮箱模板消息参数
* @date 2023-12-22 10:47
*/
@Data
public class EmailMsgParams {
/**
* 发送账号
*/
private String sendAccount;
/**
* 标题
*/
private String title;
/**
* 内容
*/
private String content;
/**
* 附件
*/
private String attachment;
}

View File

@ -0,0 +1,17 @@
package com.fastbee.common.extend.core.domin.notify.msg;
import lombok.Data;
/**
* @author admin
* @version 1.0
* @description: MQTT推送参数
* @date 2024-12-30 10:41
*/
@Data
public class MqttMsgParams {
// private String title;
private String content;
}

View File

@ -0,0 +1,49 @@
package com.fastbee.common.extend.core.domin.notify.msg;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 语音消息模板参数
* @date 2023-12-22 10:54
*/
@Data
public class VoiceMsgParams {
/**
* 发送账号
*/
private String sendAccount;
/**
* 模板ID
*/
private String templateId;
/**
* 内容
*/
private String content;
/**
* 应用ID
*/
private String sdkAppId;
/**
* 播放次数 1~3
*/
private String playTimes = "1";
/**
* 播放音量 0-100
*/
private String volume = "50";
/**
* 语速控制 -500-500
*/
private String speed = "0";
}

View File

@ -0,0 +1,43 @@
package com.fastbee.common.extend.core.domin.notify.msg;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 企业微信消息模板参数
* @date 2023-12-22 10:57
*/
@Data
public class WeComMsgParams {
/**
* 发送账号
*/
private String sendAccount;
/**
* 消息类型
*/
private String msgType;
/**
* 消息内容
*/
private String content;
/**
* 消息标题
*/
private String title;
/**
* 消息描述
*/
private String description;
/**
* 跳转链接
*/
private String url;
/**
* 图片链接
*/
private String picUrl;
}

View File

@ -0,0 +1,43 @@
package com.fastbee.common.extend.core.domin.notify.msg;
import lombok.Data;
/**
* @author fastb
* @version 1.0
* @description: 微信消息模板参数
* @date 2023-12-22 10:57
*/
@Data
public class WechatMsgParams {
/**
* 发送账号
*/
private String sendAccount;
/**
* 模版id
*/
private String templateId;
/**
* 内容
*/
private String content;
/**
* 跳转链接
*/
private String redirectUrl;
/**
* 跳转小程序appid
*/
private String appid;
/**
* 小程序跳转路径
*/
private String pagePath;
}

View File

@ -0,0 +1,45 @@
package com.fastbee.common.extend.core.domin.ota;
import com.fastbee.common.exception.ServiceException;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum OtaPackageCode {
OTA_01("查询产品工装号",(byte) 0x01),
OTA_0A("OTA升级启动",(byte) 0x0A),
OTA_0B("OTA升级包传输",(byte) 0x0B)
;
private String desc;
private byte code;
public static OtaPackageCode getInstance(int code) {
switch ((byte)code) {
case 0x01:
return OTA_01;
case 0x0A:
return OTA_0A;
case 0x0B:
return OTA_0B;
default:
throw new ServiceException("功能码[" + code + "],未定义");
}
}
public static String getDes(int code){
switch ((byte)code) {
case 0x01:
return OTA_01.desc;
case 0x0A:
return OTA_0A.desc;
case 0x0B:
return OTA_0B.desc;
default:
return "UNKOWN";
}
}
}

View File

@ -0,0 +1,44 @@
package com.fastbee.common.extend.core.domin.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;
}

View File

@ -0,0 +1,53 @@
package com.fastbee.common.extend.core.domin.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;
/**
* 备注
*/
private String remark;
/**
* 名称
*/
private String name;
/**
* 被匹配值
*/
private String matchValue;
}

View File

@ -0,0 +1,29 @@
package com.fastbee.common.extend.core.domin.thingsModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Builder;
import lombok.Data;
import java.util.Date;
@Data
@Builder
public class ThingsModelRuleItem {
/** 物模型唯一标识符 */
private String id;
/** 物模型值 */
private String value;
private String operator;
private String triggerValue;
/**
* 更新时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date ts;
/** 备注 **/
private String remark;
private String timestamp;
}

View File

@ -0,0 +1,94 @@
package com.fastbee.common.extend.core.domin.thingsModel;
import com.fastbee.common.utils.DateUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import java.util.Date;
/**
* 物模型值的项
*
* @author kerwincui
* @date 2021-12-16
*/
@AllArgsConstructor
@Builder
public class ThingsModelSimpleItem
{
/** 物模型唯一标识符 */
private String id;
/** 物模型值 */
private String value;
private String name;
/**
* 更新时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date ts;
/** 备注 **/
private String remark;
private String reportTime;
public ThingsModelSimpleItem(String id, String value , String remark){
this.id=id;
this.value=value;
this.remark=remark;
}
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getReportTime() {
return reportTime;
}
public void setReportTime(String reportTime) {
this.reportTime = reportTime;
}
}

View File

@ -0,0 +1,57 @@
package com.fastbee.common.extend.core.domin.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 Integer deviceType;
/** 设备物模型值的集合 **/
private List<ThingsModelSimpleItem> thingsModelSimpleItem;
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 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;
}
}

View File

@ -0,0 +1,33 @@
package com.fastbee.common.extend.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;
}

Some files were not shown because too many files have changed in this diff Show More