This commit is contained in:
kerwincui
2024-03-17 14:59:23 +08:00
parent 3d44f4674c
commit 5539c1b6af
999 changed files with 115642 additions and 10757 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,37 @@
package com.fastbee.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* OTA升级状态
* @author gsb
* @date 2022/10/24 17:29
*/
@AllArgsConstructor
@Getter
public enum OTAUpgrade {
AWAIT(0, "等待升级","未推送固件到设备"),
SEND(1, "已发送","已发送设备"),
REPLY(2, "升级中","设备OTA升级中"),
SUCCESS(3, "成功","升级成功"),
FAILED(4, "失败","升级失败"),
STOP(5, "停止","设备离线停止推送"),
UNKNOWN(404, "未知","未知错误码");
Integer status;
String subMsg;
String des;
public static OTAUpgrade parse(Integer code){
for (OTAUpgrade item: OTAUpgrade.values()){
if(item.status.equals(code)){
return item;
}
}
return UNKNOWN;
}
}

View File

@@ -0,0 +1,24 @@
package com.fastbee.common.enums;
/**
* 操作人类别
*
* @author ruoyi
*/
public enum OperatorType
{
/**
* 其它
*/
OTHER,
/**
* 后台用户
*/
MANAGE,
/**
* 手机端用户
*/
MOBILE
}

View File

@@ -0,0 +1,37 @@
package com.fastbee.common.enums;
import com.fastbee.common.constant.HttpStatus;
import lombok.AllArgsConstructor;
/**
* API返回对象
*/
@AllArgsConstructor
public enum ResultCode implements IErrorCode {
SUCCESS(HttpStatus.SUCCESS,"请求成功"),
FAILED(HttpStatus.ERROR,"系统内部错误"),
ACCEPTED(HttpStatus.ACCEPTED,"请求已接收"),
REDIRECT(HttpStatus.SEE_OTHER,"重定向"),
UNAUTHORIZED(HttpStatus.UNAUTHORIZED,"暂未登录或token过期"),
FORBIDDEN(HttpStatus.FORBIDDEN,"没有相关权限或授权过期"),
NOT_FOUND(HttpStatus.NOT_FOUND,"资源未找到"),
PARSE_MSG_EXCEPTION(4018, "解析协议异常"),
TIMEOUT(502, "响应超时!"),
FIRMWARE_VERSION_UNIQUE_ERROR(4022, "产品下已存在该版本固件"),
FIRMWARE_SEQ_UNIQUE_ERROR(4023, "产品下已存在该升级序列号"),
FIRMWARE_TASK_UNIQUE_ERROR(4024, "任务名已存在"),
REPLY_TIMEOUT(4001, "超时未回执"),
INVALID_USER_APP(4002, "用户信息不存在"),
INVALID_MQTT_USER(1003, "内部mqtt服务用户异常"),
DECODE_PROTOCOL_EXCEPTION(1000, "解析协议异常"),
MQTT_TOPIC_INVALID(1001, "MQTT订阅topic格式非法");
private int code;
private String message;
public int getCode(){return code;}
public String getMessage(){return message;}
}

View File

@@ -0,0 +1,36 @@
package com.fastbee.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author gsb
* @date 2022/9/15 9:10
*/
@Getter
@AllArgsConstructor
public enum ServerType {
MQTT(1, "MQTT","MQTT-BROKER"),
COAP(2, "COAP","COAP-SERVER"),
TCP(3, "TCP","TCP-SERVER"),
UDP(4, "UDP","UDP-SERVER"),
WEBSOCKET(5,"WEBSOCKET","WEBSOCKET-SERVER"),
GB28181(6,"GB28181","SIP-SERVER"),
OTHER(999,"WEBSOCKET","MQTT-BROKER");
private int type;
private String code;
private String des;
public static ServerType explain(String code) {
for (ServerType value : ServerType.values()) {
if (value.code.equals(code)) {
return value;
}
}
return ServerType.MQTT;
}
}

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