20251224:格式化代码

This commit is contained in:
George 2025-12-24 20:36:15 +08:00
parent 7e612e03eb
commit d89e3b63dc
695 changed files with 19767 additions and 17863 deletions

View File

@ -14,8 +14,7 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{
public @interface DataScope {
/**
* 部门表的别名
*/

View File

@ -11,40 +11,32 @@ import java.net.UnknownHostException;
*
* @author ruoyi
*/
public class IpUtils
{
public class IpUtils {
/**
* 获取客户端IP
*
* @param request 请求对象
* @return IP地址
*/
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
public static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
@ -57,8 +49,7 @@ public class IpUtils
* @param ip IP地址
* @return 结果
*/
public static boolean internalIp(String ip)
{
public static boolean internalIp(String ip) {
byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip);
}
@ -69,10 +60,8 @@ public class IpUtils
* @param addr byte地址
* @return 结果
*/
private static boolean internalIp(byte[] addr)
{
if (StringUtils.isNull(addr) || addr.length < 2)
{
private static boolean internalIp(byte[] addr) {
if (StringUtils.isNull(addr) || addr.length < 2) {
return true;
}
final byte b0 = addr[0];
@ -86,20 +75,16 @@ public class IpUtils
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
switch (b0)
{
switch (b0) {
case SECTION_1:
return true;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4)
{
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
return true;
}
case SECTION_5:
switch (b1)
{
case SECTION_6:
return true;
if (b1 == SECTION_6) {
return true;
}
default:
return false;
@ -112,25 +97,20 @@ public class IpUtils
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text)
{
if (text.length() == 0)
{
public static byte[] textToNumericFormatV4(String text) {
if (text.length() == 0) {
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try
{
try {
long l;
int i;
switch (elements.length)
{
switch (elements.length) {
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L))
{
if ((l < 0L) || (l > 4294967295L)) {
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
@ -140,14 +120,12 @@ public class IpUtils
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L))
{
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L))
{
if ((l < 0L) || (l > 16777215L)) {
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
@ -155,29 +133,24 @@ public class IpUtils
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
for (i = 0; i < 2; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L))
{
if ((l < 0L) || (l > 65535L)) {
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
for (i = 0; i < 4; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
@ -186,9 +159,7 @@ public class IpUtils
default:
return null;
}
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
return null;
}
return bytes;
@ -199,14 +170,10 @@ public class IpUtils
*
* @return 本地IP地址
*/
public static String getHostIp()
{
try
{
public static String getHostIp() {
try {
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException e)
{
} catch (UnknownHostException e) {
}
return "127.0.0.1";
}
@ -216,14 +183,10 @@ public class IpUtils
*
* @return 本地主机名
*/
public static String getHostName()
{
try
{
public static String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
} catch (UnknownHostException e) {
}
return "未知";
}
@ -234,16 +197,12 @@ public class IpUtils
* @param ip 获得的IP地址
* @return 第一个非unknown IP地址
*/
public static String getMultistageReverseProxyIp(String ip)
{
public static String getMultistageReverseProxyIp(String ip) {
// 多级反向代理检测
if (ip != null && ip.indexOf(",") > 0)
{
if (ip != null && ip.indexOf(",") > 0) {
final String[] ips = ip.trim().split(",");
for (String subIp : ips)
{
if (false == isUnknown(subIp))
{
for (String subIp : ips) {
if (false == isUnknown(subIp)) {
ip = subIp;
break;
}
@ -258,8 +217,7 @@ public class IpUtils
* @param checkString 被检测的字符串
* @return 是否未知
*/
public static boolean isUnknown(String checkString)
{
public static boolean isUnknown(String checkString) {
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>fastbee</artifactId>
@ -18,7 +18,7 @@
<dependencies>
<!-- SpringBoot Web容器 -->
<dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

View File

@ -1,16 +1,5 @@
package com.fastbee.framework.aspect;
import com.google.gson.Gson;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
//@Aspect
//@Component
public class WebLogAspect {
@ -48,7 +37,7 @@ public class WebLogAspect {
// @After("webLog()")
// public void doAfter() throws Throwable {
// logger.info("=========================================== End ===========================================");
// 每个请求之间空一行
// 每个请求之间空一行
// logger.info("");
// }
// /**

View File

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

View File

@ -1,6 +1,8 @@
package com.fastbee.framework.aspectj;
import java.util.Objects;
import com.fastbee.common.annotation.DataSource;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.framework.datasource.DynamicDataSourceContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@ -11,9 +13,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.fastbee.common.annotation.DataSource;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.framework.datasource.DynamicDataSourceContextHolder;
import java.util.Objects;
/**
* 多数据源处理
@ -23,33 +24,26 @@ import com.fastbee.framework.datasource.DynamicDataSourceContextHolder;
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{
public class DataSourceAspect {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.fastbee.common.annotation.DataSource)"
+ "|| @within(com.fastbee.common.annotation.DataSource)")
public void dsPointCut()
{
public void dsPointCut() {
}
@Around("dsPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable
{
public Object around(ProceedingJoinPoint point) throws Throwable {
DataSource dataSource = getDataSource(point);
if (StringUtils.isNotNull(dataSource))
{
if (StringUtils.isNotNull(dataSource)) {
DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
}
try
{
try {
return point.proceed();
}
finally
{
} finally {
// 销毁数据源 在执行方法之后
DynamicDataSourceContextHolder.clearDataSourceType();
}
@ -58,12 +52,10 @@ public class DataSourceAspect
/**
* 获取需要切换的数据源
*/
public DataSource getDataSource(ProceedingJoinPoint point)
{
public DataSource getDataSource(ProceedingJoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
if (Objects.nonNull(dataSource))
{
if (Objects.nonNull(dataSource)) {
return dataSource;
}

View File

@ -1,18 +1,5 @@
package com.fastbee.framework.aspectj;
import java.util.Collection;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson2.JSON;
import com.fastbee.common.annotation.Log;
import com.fastbee.common.core.domain.model.LoginUser;
@ -26,6 +13,20 @@ import com.fastbee.common.utils.ip.IpUtils;
import com.fastbee.framework.manager.AsyncManager;
import com.fastbee.framework.manager.factory.AsyncFactory;
import com.fastbee.system.domain.SysOperLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Map;
/**
* 操作日志记录处理
@ -34,21 +35,20 @@ import com.fastbee.system.domain.SysOperLog;
*/
@Aspect
@Component
public class LogAspect
{
public class LogAspect {
/**
* 排除敏感属性字段
*/
public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
/** 排除敏感属性字段 */
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
{
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
handleLog(joinPoint, controllerLog, null, jsonResult);
}
@ -56,18 +56,15 @@ public class LogAspect
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
* @param e 异常
*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
{
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
handleLog(joinPoint, controllerLog, e, null);
}
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult)
{
try
{
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
try {
// 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser();
@ -78,13 +75,11 @@ public class LogAspect
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
if (loginUser != null)
{
if (loginUser != null) {
operLog.setOperName(loginUser.getUsername());
}
if (e != null)
{
if (e != null) {
operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
}
@ -98,9 +93,7 @@ public class LogAspect
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 保存数据库
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
}
catch (Exception exp)
{
} catch (Exception exp) {
// 记录本地异常日志
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
@ -110,12 +103,11 @@ public class LogAspect
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param log 日志
* @param log 日志
* @param operLog 操作日志
* @throws Exception
*/
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception
{
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception {
// 设置action动作
operLog.setBusinessType(log.businessType().ordinal());
// 设置标题
@ -123,14 +115,12 @@ public class LogAspect
// 设置操作人类别
operLog.setOperatorType(log.operatorType().ordinal());
// 是否需要保存request,参数和值
if (log.isSaveRequestData())
{
if (log.isSaveRequestData()) {
// 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, operLog);
}
// 是否需要保存response,参数和值
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
{
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) {
operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
}
}
@ -141,16 +131,12 @@ public class LogAspect
* @param operLog 操作日志
* @throws Exception 异常
*/
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
{
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception {
String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
{
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
}
else
{
} else {
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter()), 0, 2000));
}
@ -159,22 +145,15 @@ public class LogAspect
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray)
{
private String argsArrayToString(Object[] paramsArray) {
String params = "";
if (paramsArray != null && paramsArray.length > 0)
{
for (Object o : paramsArray)
{
if (StringUtils.isNotNull(o) && !isFilterObject(o))
{
try
{
if (paramsArray != null && paramsArray.length > 0) {
for (Object o : paramsArray) {
if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
try {
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter());
params += jsonObj.toString() + " ";
}
catch (Exception e)
{
} catch (Exception e) {
}
}
}
@ -185,8 +164,7 @@ public class LogAspect
/**
* 忽略敏感属性
*/
public PropertyPreExcludeFilter excludePropertyPreFilter()
{
public PropertyPreExcludeFilter excludePropertyPreFilter() {
return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES);
}
@ -197,26 +175,18 @@ public class LogAspect
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
@SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o)
{
public boolean isFilterObject(final Object o) {
Class<?> clazz = o.getClass();
if (clazz.isArray())
{
if (clazz.isArray()) {
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
}
else if (Collection.class.isAssignableFrom(clazz))
{
} else if (Collection.class.isAssignableFrom(clazz)) {
Collection collection = (Collection) o;
for (Object value : collection)
{
for (Object value : collection) {
return value instanceof MultipartFile;
}
}
else if (Map.class.isAssignableFrom(clazz))
{
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) o;
for (Object value : map.entrySet())
{
for (Object value : map.entrySet()) {
Map.Entry entry = (Map.Entry) value;
return entry.getValue() instanceof MultipartFile;
}

View File

@ -1,8 +1,11 @@
package com.fastbee.framework.aspectj;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import com.fastbee.common.annotation.RateLimiter;
import com.fastbee.common.enums.LimitType;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.ServletUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.ip.IpUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@ -13,12 +16,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import com.fastbee.common.annotation.RateLimiter;
import com.fastbee.common.enums.LimitType;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.ServletUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.ip.IpUtils;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
/**
* 限流处理
@ -27,8 +28,7 @@ import com.fastbee.common.utils.ip.IpUtils;
*/
@Aspect
@Component
public class RateLimiterAspect
{
public class RateLimiterAspect {
private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
private RedisTemplate<Object, Object> redisTemplate;
@ -36,49 +36,38 @@ public class RateLimiterAspect
private RedisScript<Long> limitScript;
@Autowired
public void setRedisTemplate1(RedisTemplate<Object, Object> redisTemplate)
{
public void setRedisTemplate1(RedisTemplate<Object, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Autowired
public void setLimitScript(RedisScript<Long> limitScript)
{
public void setLimitScript(RedisScript<Long> limitScript) {
this.limitScript = limitScript;
}
@Before("@annotation(rateLimiter)")
public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable
{
public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {
int time = rateLimiter.time();
int count = rateLimiter.count();
String combineKey = getCombineKey(rateLimiter, point);
List<Object> keys = Collections.singletonList(combineKey);
try
{
try {
Long number = redisTemplate.execute(limitScript, keys, count, time);
if (StringUtils.isNull(number) || number.intValue() > count)
{
if (StringUtils.isNull(number) || number.intValue() > count) {
throw new ServiceException("访问过于频繁,请稍候再试");
}
log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey);
}
catch (ServiceException e)
{
} catch (ServiceException e) {
throw e;
}
catch (Exception e)
{
} catch (Exception e) {
throw new RuntimeException("服务器限流异常,请稍候再试");
}
}
public String getCombineKey(RateLimiter rateLimiter, JoinPoint point)
{
public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
if (rateLimiter.limitType() == LimitType.IP)
{
if (rateLimiter.limitType() == LimitType.IP) {
stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-");
}
MethodSignature signature = (MethodSignature) point.getSignature();

View File

@ -1,11 +1,12 @@
package com.fastbee.framework.config;
import java.util.TimeZone;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import java.util.TimeZone;
/**
* 程序注解配置
*
@ -14,14 +15,12 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
public class ApplicationConfig
{
public class ApplicationConfig {
/**
* 时区配置
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
{
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
}
}

View File

@ -1,10 +1,12 @@
package com.fastbee.framework.config;
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
import static com.google.code.kaptcha.Constants.*;
/**
@ -13,11 +15,9 @@ import static com.google.code.kaptcha.Constants.*;
* @author ruoyi
*/
@Configuration
public class CaptchaConfig
{
public class CaptchaConfig {
@Bean(name = "captchaProducer")
public DefaultKaptcha getKaptchaBean()
{
public DefaultKaptcha getKaptchaBean() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yes,no
@ -44,8 +44,7 @@ public class CaptchaConfig
}
@Bean(name = "captchaProducerMath")
public DefaultKaptcha getKaptchaBeanMath()
{
public DefaultKaptcha getKaptchaBeanMath() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yes,no

View File

@ -31,8 +31,8 @@ public class DataSourceConfig {
private final DataSource shardingSphereDataSource;
public DataSourceConfig(DynamicDataSourceProperties properties,
DefaultDataSourceCreator dataSourceCreator,
@Qualifier("shardingSphereDataSource") DataSource shardingSphereDataSource) {
DefaultDataSourceCreator dataSourceCreator,
@Qualifier("shardingSphereDataSource") DataSource shardingSphereDataSource) {
this.properties = properties;
this.dataSourceCreator = dataSourceCreator;
this.shardingSphereDataSource = shardingSphereDataSource;

View File

@ -15,11 +15,10 @@ public class DruidConfig {
/**
* 去除监控页面底部的广告
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
{
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) {
// 获取web监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取common.js的配置路径
@ -27,16 +26,14 @@ public class DruidConfig {
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
final String filePath = "support/http/resources/js/common.js";
// 创建filter进行过滤
Filter filter = new Filter()
{
Filter filter = new Filter() {
@Override
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
{
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
throws IOException, ServletException {
chain.doFilter(request, response);
// 重置缓冲区,响应头不会被重置
response.resetBuffer();
@ -47,9 +44,9 @@ public class DruidConfig {
text = text.replaceAll("powered.*?shrek.wang</a>", "");
response.getWriter().write(text);
}
@Override
public void destroy()
{
public void destroy() {
}
};
FilterRegistrationBean registrationBean = new FilterRegistrationBean();

View File

@ -1,44 +1,39 @@
package com.fastbee.framework.config;
import java.nio.charset.Charset;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/**
* Redis使用FastJson序列化
*
* @author ruoyi
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
if (t == null)
{
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
if (bytes == null || bytes.length <= 0)
{
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);

View File

@ -1,16 +1,17 @@
package com.fastbee.framework.config;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.DispatcherType;
import com.fastbee.common.filter.RepeatableFilter;
import com.fastbee.common.filter.XssFilter;
import com.fastbee.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fastbee.common.filter.RepeatableFilter;
import com.fastbee.common.filter.XssFilter;
import com.fastbee.common.utils.StringUtils;
import javax.servlet.DispatcherType;
import java.util.HashMap;
import java.util.Map;
/**
* Filter配置
@ -18,19 +19,17 @@ import com.fastbee.common.utils.StringUtils;
* @author ruoyi
*/
@Configuration
public class FilterConfig
{
public class FilterConfig {
@Value("${xss.excludes}")
private String excludes;
@Value("${xss.urlPatterns}")
private String urlPatterns;
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
public FilterRegistrationBean xssFilterRegistration()
{
public FilterRegistrationBean xssFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new XssFilter());
@ -43,10 +42,9 @@ public class FilterConfig
return registration;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
public FilterRegistrationBean someFilterRegistration()
{
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new RepeatableFilter());
registration.addUrlPatterns("/*");

View File

@ -1,61 +1,49 @@
package com.fastbee.framework.config;
import java.util.Random;
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
import java.util.Random;
/**
* 验证码文本生成器
*
* @author ruoyi
*/
public class KaptchaTextCreator extends DefaultTextCreator
{
public class KaptchaTextCreator extends DefaultTextCreator {
private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
@Override
public String getText()
{
public String getText() {
Integer result = 0;
Random random = new Random();
int x = random.nextInt(10);
int y = random.nextInt(10);
StringBuilder suChinese = new StringBuilder();
int randomoperands = random.nextInt(3);
if (randomoperands == 0)
{
if (randomoperands == 0) {
result = x * y;
suChinese.append(CNUMBERS[x]);
suChinese.append("*");
suChinese.append(CNUMBERS[y]);
}
else if (randomoperands == 1)
{
if ((x != 0) && y % x == 0)
{
} else if (randomoperands == 1) {
if ((x != 0) && y % x == 0) {
result = y / x;
suChinese.append(CNUMBERS[y]);
suChinese.append("/");
suChinese.append(CNUMBERS[x]);
}
else
{
} else {
result = x + y;
suChinese.append(CNUMBERS[x]);
suChinese.append("+");
suChinese.append(CNUMBERS[y]);
}
}
else
{
if (x >= y)
{
} else {
if (x >= y) {
result = x - y;
suChinese.append(CNUMBERS[x]);
suChinese.append("-");
suChinese.append(CNUMBERS[y]);
}
else
{
} else {
result = y - x;
suChinese.append(CNUMBERS[y]);
suChinese.append("-");

View File

@ -8,8 +8,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class OtaThreadPoolConfig
{
public class OtaThreadPoolConfig {
// 配置线程池的前缀
private static final String threadNamePrefix = "ota-";
// 核心线程池大小
private int corePoolSize = 10;
// 最大可创建的线程数
@ -18,12 +19,9 @@ public class OtaThreadPoolConfig
private int queueCapacity = 10000;
// 线程池维护线程所允许的空闲时间
private int keepAliveSeconds = 30;
// 配置线程池的前缀
private static final String threadNamePrefix = "ota-";
@Bean(name = FastBeeConstant.TASK.OTA_THREAD_POOL)
public ThreadPoolTaskExecutor threadPoolTaskExecutor()
{
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize);

View File

@ -14,12 +14,10 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
* @author ruoyi
*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport
{
public class RedisConfig extends CachingConfigurerSupport {
@Bean
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
{
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
@ -38,8 +36,7 @@ public class RedisConfig extends CachingConfigurerSupport
}
@Bean
public DefaultRedisScript<Long> limitScript()
{
public DefaultRedisScript<Long> limitScript() {
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(limitScriptText());
redisScript.setResultType(Long.class);
@ -49,8 +46,7 @@ public class RedisConfig extends CachingConfigurerSupport
/**
* 限流脚本
*/
private String limitScriptText()
{
private String limitScriptText() {
return "local key = KEYS[1]\n" +
"local count = tonumber(ARGV[1])\n" +
"local time = tonumber(ARGV[2])\n" +

View File

@ -1,6 +1,8 @@
package com.fastbee.framework.config;
import cn.hutool.core.util.ObjectUtil;
import com.fastbee.framework.config.properties.RedissonProperties;
import com.fastbee.framework.handler.KeyPrefixHandler;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -9,7 +11,6 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import com.fastbee.framework.config.properties.RedissonProperties;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.CompositeCodec;
import org.redisson.codec.TypedJsonJacksonCodec;
@ -18,8 +19,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fastbee.framework.handler.KeyPrefixHandler;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@ -53,39 +52,39 @@ public class RedissonConfig {
// 组合序列化 key 使用 String 内容使用通用 json 格式
CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
config.setThreads(redissonProperties.getThreads())
.setNettyThreads(redissonProperties.getNettyThreads())
// 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
.setUseScriptCache(true)
.setCodec(codec);
.setNettyThreads(redissonProperties.getNettyThreads())
// 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
.setUseScriptCache(true)
.setCodec(codec);
RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
if (ObjectUtil.isNotNull(singleServerConfig)) {
// 使用单机模式
config.useSingleServer()
//设置redis key前缀
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
.setTimeout(singleServerConfig.getTimeout())
.setClientName(singleServerConfig.getClientName())
.setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
.setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
.setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
.setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
//设置redis key前缀
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
.setTimeout(singleServerConfig.getTimeout())
.setClientName(singleServerConfig.getClientName())
.setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
.setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
.setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
.setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
}
// 集群配置方式 参考下方注释
RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
if (ObjectUtil.isNotNull(clusterServersConfig)) {
config.useClusterServers()
//设置redis key前缀
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
.setTimeout(clusterServersConfig.getTimeout())
.setClientName(clusterServersConfig.getClientName())
.setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
.setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
.setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
.setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
.setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
.setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
.setReadMode(clusterServersConfig.getReadMode())
.setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
//设置redis key前缀
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
.setTimeout(clusterServersConfig.getTimeout())
.setClientName(clusterServersConfig.getClientName())
.setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
.setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
.setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
.setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
.setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
.setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
.setReadMode(clusterServersConfig.getReadMode())
.setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
}
log.info("初始化 redis 配置");
};

View File

@ -1,8 +1,9 @@
package com.fastbee.framework.config;
import java.util.concurrent.TimeUnit;
import com.fastbee.common.config.RuoYiConfig;
import com.fastbee.common.constant.Constants;
import com.fastbee.framework.interceptor.LanguageInterceptor;
import com.fastbee.framework.interceptor.RepeatSubmitInterceptor;
import com.fastbee.framework.interceptor.TraceIdInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@ -14,11 +15,9 @@ import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.fastbee.common.config.RuoYiConfig;
import com.fastbee.common.constant.Constants;
import com.fastbee.framework.interceptor.RepeatSubmitInterceptor;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* 通用配置
@ -26,8 +25,7 @@ import javax.annotation.Resource;
* @author ruoyi
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
public class ResourcesConfig implements WebMvcConfigurer {
@Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Resource
@ -36,8 +34,7 @@ public class ResourcesConfig implements WebMvcConfigurer
private TraceIdInterceptor traceIdInterceptor;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
@ -45,15 +42,15 @@ public class ResourcesConfig implements WebMvcConfigurer
/** swagger配置 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());;
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());
;
}
/**
* 自定义拦截规则
*/
@Override
public void addInterceptors(InterceptorRegistry registry)
{
public void addInterceptors(InterceptorRegistry registry) {
// TraceId拦截器放在最前面,确保所有请求都有TraceId
registry.addInterceptor(traceIdInterceptor).addPathPatterns("/**").order(0);
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
@ -66,8 +63,7 @@ public class ResourcesConfig implements WebMvcConfigurer
* 跨域配置
*/
@Bean
public CorsFilter corsFilter()
{
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置访问源地址

View File

@ -1,5 +1,9 @@
package com.fastbee.framework.config;
import com.fastbee.framework.config.properties.PermitAllUrlProperties;
import com.fastbee.framework.security.filter.JwtAuthenticationTokenFilter;
import com.fastbee.framework.security.handle.AuthenticationEntryPointImpl;
import com.fastbee.framework.security.handle.LogoutSuccessHandlerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
@ -15,10 +19,6 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.filter.CorsFilter;
import com.fastbee.framework.config.properties.PermitAllUrlProperties;
import com.fastbee.framework.security.filter.JwtAuthenticationTokenFilter;
import com.fastbee.framework.security.handle.AuthenticationEntryPointImpl;
import com.fastbee.framework.security.handle.LogoutSuccessHandlerImpl;
/**
* spring security配置
@ -27,8 +27,7 @@ import com.fastbee.framework.security.handle.LogoutSuccessHandlerImpl;
*/
//@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 自定义用户认证逻辑
*/
@ -73,8 +72,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@ -94,8 +92,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
* authenticated | 用户登录后可访问
*/
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
protected void configure(HttpSecurity httpSecurity) throws Exception {
// 注解标记允许匿名访问的url
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
@ -113,17 +110,17 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage","/iot/tool/register","/iot/tool/ntp",
"/iot/tool/mqtt/auth","/iot/tool/mqtt/authv5","/iot/tool/mqtt/webhook","/iot/tool/mqtt/webhookv5","/auth/**/**",
.antMatchers("/login", "/register", "/captchaImage", "/iot/tool/register", "/iot/tool/ntp",
"/iot/tool/mqtt/auth", "/iot/tool/mqtt/authv5", "/iot/tool/mqtt/webhook", "/iot/tool/mqtt/webhookv5", "/auth/**/**",
"/wechat/mobileLogin", "/wechat/miniLogin", "/wechat/wxBind/callback").permitAll()
.antMatchers("/zlmhook/**").permitAll()
//.antMatchers("/sip/player/getBigScreenUrl/**").permitAll()
.antMatchers("/ruleengine/rulemanager/**").permitAll()
.antMatchers("/goview/sys/login","/goview/project/getData").permitAll()
.antMatchers("/notify/smsLoginCaptcha","/auth/sms/login", "/notify/weComVerifyUrl"
,"/wechat/publicAccount/callback","/notify/smsRegisterCaptcha").permitAll()
.antMatchers("/goview/sys/login", "/goview/project/getData").permitAll()
.antMatchers("/notify/smsLoginCaptcha", "/auth/sms/login", "/notify/weComVerifyUrl"
, "/wechat/publicAccount/callback", "/notify/smsRegisterCaptcha").permitAll()
.antMatchers("/app/language/list").permitAll()
.antMatchers("/iot/news/bannerList","/iot/news/topList", "/iot/news/getDetail").permitAll()
.antMatchers("/iot/news/bannerList", "/iot/news/topList", "/iot/news/getDetail").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
@ -161,8 +158,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
* 强散列哈希加密实现
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@ -170,8 +166,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
}

View File

@ -1,8 +1,9 @@
package com.fastbee.framework.config;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import com.fastbee.common.utils.ServletUtils;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 服务相关配置
@ -10,23 +11,20 @@ import com.fastbee.common.utils.ServletUtils;
* @author ruoyi
*/
@Component
public class ServerConfig
{
public class ServerConfig {
public static String getDomain(HttpServletRequest request) {
StringBuffer url = request.getRequestURL();
String contextPath = request.getServletContext().getContextPath();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
}
/**
* 获取完整的请求路径,包括:域名,端口,上下文访问路径
*
* @return 服务地址
*/
public String getUrl()
{
public String getUrl() {
HttpServletRequest request = ServletUtils.getRequest();
return getDomain(request);
}
public static String getDomain(HttpServletRequest request)
{
StringBuffer url = request.getRequestURL();
String contextPath = request.getServletContext().getContextPath();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
}
}

View File

@ -20,16 +20,18 @@ import java.util.stream.Collectors;
/**
* 解决Mybatis Plus Order By SQL注入问题
*
* @author admin
*/
@Slf4j
public class SqlFilterArgumentResolver implements HandlerMethodArgumentResolver {
private final static String[] KEYWORDS = { "master", "truncate", "insert", "select", "delete", "update", "declare",
"alter", "drop", "sleep" };
private final static String[] KEYWORDS = {"master", "truncate", "insert", "select", "delete", "update", "declare",
"alter", "drop", "sleep"};
/**
* 判断Controller是否包含page 参数
*
* @param parameter 参数
* @return 是否过滤
*/
@ -39,9 +41,9 @@ public class SqlFilterArgumentResolver implements HandlerMethodArgumentResolver
}
/**
* @param parameter 入参集合
* @param mavContainer model 和 view
* @param webRequest web相关
* @param parameter 入参集合
* @param mavContainer model 和 view
* @param webRequest web相关
* @param binderFactory 入参解析
* @return 检查后新的page对象
* <p>
@ -77,6 +79,7 @@ public class SqlFilterArgumentResolver implements HandlerMethodArgumentResolver
/**
* 判断用户输入里面有没有关键字
*
* @return Predicate
*/
private Predicate<String> sqlInjectPredicate() {

View File

@ -5,6 +5,7 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@ -15,8 +16,7 @@ import java.util.concurrent.ThreadPoolExecutor;
* @author ruoyi
**/
@Configuration
public class ThreadPoolConfig
{
public class ThreadPoolConfig {
// 核心线程池大小
private int corePoolSize = 50;
@ -30,8 +30,7 @@ public class ThreadPoolConfig
private int keepAliveSeconds = 300;
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor()
{
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize);
@ -46,15 +45,12 @@ public class ThreadPoolConfig
* 执行周期性或定时任务
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService()
{
protected ScheduledExecutorService scheduledExecutorService() {
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy())
{
new ThreadPoolExecutor.CallerRunsPolicy()) {
@Override
protected void afterExecute(Runnable r, Throwable t)
{
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Threads.printException(r, t);
}

View File

@ -8,8 +8,7 @@ import org.springframework.context.annotation.Configuration;
* @author ruoyi
*/
@Configuration
public class DruidProperties
{
public class DruidProperties {
// @Value("${spring.datasource.druid.initialSize}")
// private int initialSize;
//

View File

@ -1,10 +1,6 @@
package com.fastbee.framework.config.properties;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import com.fastbee.common.annotation.Anonymous;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
@ -15,7 +11,12 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import com.fastbee.common.annotation.Anonymous;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
/**
* 设置Anonymous注解允许匿名访问的url
@ -23,19 +24,14 @@ import com.fastbee.common.annotation.Anonymous;
* @author ruoyi
*/
@Configuration
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware
{
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware {
private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
public String ASTERISK = "*";
private ApplicationContext applicationContext;
private List<String> urls = new ArrayList<>();
public String ASTERISK = "*";
@Override
public void afterPropertiesSet()
{
public void afterPropertiesSet() {
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
@ -55,18 +51,15 @@ public class PermitAllUrlProperties implements InitializingBean, ApplicationCont
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException
{
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.applicationContext = context;
}
public List<String> getUrls()
{
public List<String> getUrls() {
return urls;
}
public void setUrls(List<String> urls)
{
public void setUrls(List<String> urls) {
this.urls = urls;
}
}

View File

@ -8,7 +8,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Redisson 配置属性
*
*/
@Data
@ConfigurationProperties(prefix = "redisson")

View File

@ -21,15 +21,18 @@ import java.util.stream.Collectors;
/**
* <p> @Title ShardingAlgorithmTool
* <p> @Description 按月分片算法工具
*
*/
@Slf4j
public class ShardingAlgorithmTool {
/** 表分片符号,例:siot_device_log_202201 中,分片符号为 "_" */
/**
* 表分片符号,例:siot_device_log_202201 中,分片符号为 "_"
*/
private static final String TABLE_SPLIT_SYMBOL = "_";
/** 数据库配置 */
/**
* 数据库配置
*/
private static final Environment ENV = SpringUtil.getApplicationContext().getEnvironment();
private static final String DATASOURCE_URL = ENV.getProperty("spring.shardingsphere.datasource.ds0.url");
private static final String DATASOURCE_USERNAME = ENV.getProperty("spring.shardingsphere.datasource.ds0.username");
@ -38,7 +41,8 @@ public class ShardingAlgorithmTool {
/**
* 检查分表获取的表名是否存在,不存在则自动建表
* @param logicTable 逻辑表
*
* @param logicTable 逻辑表
* @param resultTableNames 真实表名,例:iot_device_log_202201
* @return 存在于数据库中的真实表名集合
*/
@ -48,7 +52,8 @@ public class ShardingAlgorithmTool {
/**
* 检查分表获取的表名是否存在,不存在则自动建表
* @param logicTable 逻辑表
*
* @param logicTable 逻辑表
* @param resultTableName 真实表名,例:iot_device_log_202201
* @return 确认存在于数据库中的真实表名
*/
@ -72,6 +77,7 @@ public class ShardingAlgorithmTool {
/**
* 重载指定分表缓存
*
* @param logicTable 逻辑表
*/
public static void tableNameCacheReload(ShardingTableCacheEnum logicTable) {
@ -89,8 +95,9 @@ public class ShardingAlgorithmTool {
/**
* 获取所有表名
* @return 表名集合
*
* @param logicTable 逻辑表
* @return 表名集合
*/
public static List<String> getAllTableNameBySchema(ShardingTableCacheEnum logicTable) {
List<String> tableNames = new ArrayList<>();
@ -102,10 +109,10 @@ public class ShardingAlgorithmTool {
Statement st = conn.createStatement()) {
String logicTableName = logicTable.logicTableName();
try (ResultSet rs = st.executeQuery("show TABLES like '" + logicTableName + TABLE_SPLIT_SYMBOL + "%'")) {
log.info("查询数据库所有表:{}","show TABLES like '" + logicTableName + TABLE_SPLIT_SYMBOL + "%'");
log.info("查询数据库所有表:{}", "show TABLES like '" + logicTableName + TABLE_SPLIT_SYMBOL + "%'");
while (rs.next()) {
String tableName = rs.getString(1);
log.info("分表格式:{}",String.format("^(%s\\d{6})$", logicTableName + TABLE_SPLIT_SYMBOL));
log.info("分表格式:{}", String.format("^(%s\\d{6})$", logicTableName + TABLE_SPLIT_SYMBOL));
// 匹配分表格式 例:^(t\_contract_\d{6})$
if (org.apache.commons.lang3.StringUtils.isNotBlank(tableName) && tableName.matches(String.format("^(%s\\d{6})$", logicTableName + TABLE_SPLIT_SYMBOL))) {
tableNames.add(rs.getString(1));
@ -125,7 +132,7 @@ public class ShardingAlgorithmTool {
* @param logicTableName 逻辑表名
* @param tableNamesCache 真实表名集合
*/
public static void actualDataNodesRefresh(String logicTableName, List<String> tableNamesCache) {
public static void actualDataNodesRefresh(String logicTableName, List<String> tableNamesCache) {
try {
if (CollectionUtils.isEmpty(tableNamesCache)) {
return;
@ -138,7 +145,7 @@ public class ShardingAlgorithmTool {
String newActualDataNodes = tableNamesCache.stream().map(o -> String.format("%s.%s", dbName, o)).collect(Collectors.joining(","));
ShardingSphereDataSource shardingSphereDataSource = SpringUtil.getBean(ShardingSphereDataSource.class);
updateShardRuleActualDataNodes(shardingSphereDataSource, logicTableName, newActualDataNodes);
}catch (Exception e){
} catch (Exception e) {
log.error("初始化 动态表单失败,原因:{}", e.getMessage(), e);
}
}
@ -209,13 +216,14 @@ public class ShardingAlgorithmTool {
/**
* 创建分表
* @param logicTable 逻辑表
*
* @param logicTable 逻辑表
* @param resultTableName 真实表名,例:sys_user_behavior_202201
* @return 创建结果(true创建成功,false未创建)
*/
private static boolean createShardingTable(ShardingTableCacheEnum logicTable, String resultTableName) {
// 根据日期判断,当前月份之后分表不提前创建
String month = resultTableName.replace(logicTable.logicTableName() + TABLE_SPLIT_SYMBOL,"");
String month = resultTableName.replace(logicTable.logicTableName() + TABLE_SPLIT_SYMBOL, "");
YearMonth shardingMonth = YearMonth.parse(month, DateTimeFormatter.ofPattern("yyyyMM"));
if (shardingMonth.isAfter(YearMonth.now())) {
return false;
@ -236,6 +244,7 @@ public class ShardingAlgorithmTool {
/**
* 执行SQL
*
* @param sqlList SQL集合
*/
private static void executeSql(List<String> sqlList) {

View File

@ -7,7 +7,6 @@ import org.springframework.stereotype.Component;
/**
* <p> @Title ShardingTablesLoadRunner
* <p> @Description 项目启动后,读取已有分表,进行缓存
*
*/
@Order(value = 1) // 数字越小,越先执行
@Component

View File

@ -20,7 +20,6 @@ import java.util.function.Function;
/**
* <p> @Title TimeShardingAlgorithm
* <p> @Description 分片算法,按月分片
*
*/
@Slf4j
public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
@ -51,7 +50,8 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
/**
* 精准分片
* @param tableNames 对应分片库中所有分片表的集合
*
* @param tableNames 对应分片库中所有分片表的集合
* @param preciseShardingValue 分片键值,其中 logicTableName 为逻辑表,columnName 分片键,value 为从 SQL 中解析出来的分片键的值
* @return 表名
*/
@ -69,7 +69,7 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
String resultTableName = logicTableName + "_" + TABLE_SHARD_TIME_FORMATTER.format(localDateTime);
// 检查分表获取的表名是否存在,不存在则自动建表
if (!tableNames.contains(resultTableName)){
if (!tableNames.contains(resultTableName)) {
tableNames.add(resultTableName);
}
return ShardingAlgorithmTool.getShardingTableAndCreate(logicTable, resultTableName);
@ -77,13 +77,14 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
/**
* 范围分片
* @param tableNames 对应分片库中所有分片表的集合
*
* @param tableNames 对应分片库中所有分片表的集合
* @param rangeShardingValue 分片范围
* @return 表名集合
*/
@Override
public Collection<String> doSharding(Collection<String> tableNames, RangeShardingValue<Date> rangeShardingValue) {
log.info("开始分表查询开始:{}",System.currentTimeMillis());
log.info("开始分表查询开始:{}", System.currentTimeMillis());
String logicTableName = rangeShardingValue.getLogicTableName();
ShardingTableCacheEnum logicTable = ShardingTableCacheEnum.of(logicTableName);
createAllTable(logicTable, tableNames);
@ -113,7 +114,7 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
calendar.add(Calendar.DAY_OF_MONTH, 1); // 给日期加一天
minDate = calendar.getTime();
}
log.info("开始分表查询结束:{}",System.currentTimeMillis());
log.info("开始分表查询结束:{}", System.currentTimeMillis());
return ShardingAlgorithmTool.getShardingTablesAndCreate(logicTable, resultTableNames);
} catch (Exception e) {
return ShardingAlgorithmTool.getShardingTablesAndCreate(logicTable, logicTable.resultTableNamesCache());
@ -137,6 +138,7 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
/**
* 获取 最小分片值
*
* @param tableNames 表名集合
* @return 最小分片值
*/
@ -156,6 +158,7 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
/**
* 获取 最大分片值
*
* @param tableNames 表名集合
* @return 最大分片值
*/
@ -175,6 +178,7 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
/**
* 根据分片规则获取的表,创建所有的表
*
* @param logicTable
* @param tableNames
*/
@ -184,7 +188,7 @@ public class TimeShardingAlgorithm implements StandardShardingAlgorithm<Date> {
return;
}
//根据分片规则创建表
ShardingAlgorithmTool.getShardingTablesAndCreate(logicTable,tableNames);
ShardingAlgorithmTool.getShardingTablesAndCreate(logicTable, tableNames);
//刷新缓存
ShardingAlgorithmTool.tableNameCacheReload(logicTable);
}

View File

@ -1,6 +1,7 @@
package com.fastbee.framework.config.sharding.enums;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import java.util.*;
import static com.fastbee.framework.config.sharding.ShardingAlgorithmTool.actualDataNodesRefresh;
@ -9,7 +10,6 @@ import static com.fastbee.framework.config.sharding.ShardingAlgorithmTool.actual
/**
* <p> @Title ShardingTableCacheEnum
* <p> @Description 分片表缓存枚举
*
*/
public enum ShardingTableCacheEnum {
@ -18,6 +18,12 @@ public enum ShardingTableCacheEnum {
*/
DEVICE_LOG("iot_device_log", new HashSet<>());
private static Map<String, ShardingTableCacheEnum> valueMap = new HashMap<>();
static {
Arrays.stream(ShardingTableCacheEnum.values()).forEach(o -> valueMap.put(o.logicTableName, o));
}
/**
* 逻辑表名
*/
@ -27,12 +33,6 @@ public enum ShardingTableCacheEnum {
*/
private final Set<String> resultTableNamesCache;
private static Map<String, ShardingTableCacheEnum> valueMap = new HashMap<>();
static {
Arrays.stream(ShardingTableCacheEnum.values()).forEach(o -> valueMap.put(o.logicTableName, o));
}
ShardingTableCacheEnum(String logicTableName, Set<String> resultTableNamesCache) {
this.logicTableName = logicTableName;
this.resultTableNamesCache = resultTableNamesCache;
@ -42,6 +42,10 @@ public enum ShardingTableCacheEnum {
return valueMap.get(value);
}
public static Set<String> logicTableNames() {
return valueMap.keySet();
}
public String logicTableName() {
return logicTableName;
}
@ -69,10 +73,6 @@ public enum ShardingTableCacheEnum {
}
}
public static Set<String> logicTableNames() {
return valueMap.keySet();
}
@Override
public String toString() {
return "ShardingTableCacheEnum{" +

View File

@ -12,18 +12,15 @@ import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
* @author ruoyi
*/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource
{
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
{
public class DynamicDataSource extends AbstractRoutingDataSource {
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey()
{
protected Object determineCurrentLookupKey() {
//log.debug("数据源:" + DynamicDataSourceContextHolder.getDataSourceType());
return DynamicDataSourceContextHolder.getDataSourceType();
}

View File

@ -8,38 +8,34 @@ import org.slf4j.LoggerFactory;
*
* @author ruoyi
*/
public class DynamicDataSourceContextHolder
{
public class DynamicDataSourceContextHolder {
public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
/**
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
*/
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
/**
* 获得数据源的变量
*/
public static String getDataSourceType() {
return CONTEXT_HOLDER.get();
}
/**
* 设置数据源的变量
*/
public static void setDataSourceType(String dsType)
{
public static void setDataSourceType(String dsType) {
log.info("切换到{}数据源", dsType);
CONTEXT_HOLDER.set(dsType);
}
/**
* 获得数据源的变量
*/
public static String getDataSourceType()
{
return CONTEXT_HOLDER.get();
}
/**
* 清空数据源变量
*/
public static void clearDataSourceType()
{
public static void clearDataSourceType() {
CONTEXT_HOLDER.remove();
}
}

View File

@ -27,14 +27,14 @@ public class LanguageInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String language = request.getHeader(LANGUAGE);
if (StringUtils.isEmpty(language) || language.equals("undefined")
|| language.equals("")|| language.equals("null")){
|| language.equals("") || language.equals("null")) {
//针对有些接口没有增加语言字段,先去token获取
language = SecurityUtils.getLanguage();
}else if (!language.contains("-")){
language = Language.matches(language);
} else if (!language.contains("-")) {
language = Language.matches(language);
}
// 前端传递的language必须是zh-CN格式的,中间的-必须要完整,不能只传递zh或en
Locale locale = new Locale(language.split("-")[0],language.split("-")[1]);
Locale locale = new Locale(language.split("-")[0], language.split("-")[1]);
// 这样赋值以后,MessageUtils.message方法就不用修改了
LocaleContextHolder.setLocale(locale);
return true;

View File

@ -3,6 +3,7 @@ package com.fastbee.framework.interceptor;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
@ -17,29 +18,22 @@ import com.fastbee.common.utils.ServletUtils;
* @author ruoyi
*/
@Component
public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
{
public abstract class RepeatSubmitInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
if (handler instanceof HandlerMethod)
{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
if (annotation != null)
{
if (this.isRepeatSubmit(request, annotation))
{
if (annotation != null) {
if (this.isRepeatSubmit(request, annotation)) {
AjaxResult ajaxResult = AjaxResult.error(annotation.message());
ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
return false;
}
}
return true;
}
else
{
} else {
return true;
}
}

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@ -23,8 +24,7 @@ import com.fastbee.framework.interceptor.RepeatSubmitInterceptor;
* @author ruoyi
*/
@Component
public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
{
public class SameUrlDataInterceptor extends RepeatSubmitInterceptor {
public final String REPEAT_PARAMS = "repeatParams";
public final String REPEAT_TIME = "repeatTime";
@ -38,18 +38,15 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
@SuppressWarnings("unchecked")
@Override
public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation)
{
public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) {
String nowParams = "";
if (request instanceof RepeatedlyRequestWrapper)
{
if (request instanceof RepeatedlyRequestWrapper) {
RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
nowParams = HttpHelper.getBodyString(repeatedlyRequest);
}
// body参数为空,获取Parameter的数据
if (StringUtils.isEmpty(nowParams))
{
if (StringUtils.isEmpty(nowParams)) {
nowParams = JSON.toJSONString(request.getParameterMap());
}
Map<String, Object> nowDataMap = new HashMap<String, Object>();
@ -66,14 +63,11 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey;
Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
if (sessionObj != null)
{
if (sessionObj != null) {
Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
if (sessionMap.containsKey(url))
{
if (sessionMap.containsKey(url)) {
Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval()))
{
if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) {
return true;
}
}
@ -87,8 +81,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
/**
* 判断参数是否相同
*/
private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
{
private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) {
String nowParams = (String) nowMap.get(REPEAT_PARAMS);
String preParams = (String) preMap.get(REPEAT_PARAMS);
return nowParams.equals(preParams);
@ -97,12 +90,10 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
/**
* 判断两次间隔时间
*/
private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap, int interval)
{
private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap, int interval) {
long time1 = (Long) nowMap.get(REPEAT_TIME);
long time2 = (Long) preMap.get(REPEAT_TIME);
if ((time1 - time2) < interval)
{
if ((time1 - time2) < interval) {
return true;
}
return false;

View File

@ -1,23 +1,23 @@
package com.fastbee.framework.manager;
import com.fastbee.common.utils.Threads;
import com.fastbee.common.utils.spring.SpringUtils;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.fastbee.common.utils.Threads;
import com.fastbee.common.utils.spring.SpringUtils;
/**
* 异步任务管理器
*
* @author ruoyi
*/
public class AsyncManager
{
public class AsyncManager {
private static AsyncManager me = new AsyncManager();
/**
* 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;
/**
* 异步操作任务调度线程池
*/
@ -26,12 +26,10 @@ public class AsyncManager
/**
* 单例模式
*/
private AsyncManager(){}
private AsyncManager() {
}
private static AsyncManager me = new AsyncManager();
public static AsyncManager me()
{
public static AsyncManager me() {
return me;
}
@ -40,16 +38,14 @@ public class AsyncManager
*
* @param task 任务
*/
public void execute(TimerTask task)
{
public void execute(TimerTask task) {
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
/**
* 停止任务线程池
*/
public void shutdown()
{
public void shutdown() {
Threads.shutdownAndAwaitTermination(executor);
}
}

View File

@ -2,16 +2,16 @@ package com.fastbee.framework.manager;
import org.springframework.cache.Cache;
import com.fastbee.common.utils.spring.SpringUtils;
import java.util.concurrent.Callable;
/**
* Cache 装饰器模式(用于扩展 Caffeine 一级缓存)
*
*/
public class CaffeineCacheDecorator implements Cache {
private static final com.github.benmanes.caffeine.cache.Cache<Object, Object>
CAFFEINE = SpringUtils.getBean("caffeine");
CAFFEINE = SpringUtils.getBean("caffeine");
private final Cache cache;

View File

@ -3,6 +3,7 @@ package com.fastbee.framework.manager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/**
@ -11,28 +12,22 @@ import javax.annotation.PreDestroy;
* @author ruoyi
*/
@Component
public class ShutdownManager
{
public class ShutdownManager {
private static final Logger logger = LoggerFactory.getLogger("sys-user");
@PreDestroy
public void destroy()
{
public void destroy() {
shutdownAsyncManager();
}
/**
* 停止异步执行任务
*/
private void shutdownAsyncManager()
{
try
{
private void shutdownAsyncManager() {
try {
logger.info("====关闭后台任务任务线程池====");
AsyncManager.me().shutdown();
}
catch (Exception e)
{
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}

View File

@ -23,22 +23,16 @@ import java.util.concurrent.ConcurrentMap;
* <p>
* 修改 RedissonSpringCacheManager 源码
* 重写 cacheName 处理方法 支持多参数
*
*
*/
@SuppressWarnings("unchecked")
public class SpringCacheManager implements CacheManager {
private boolean dynamic = true;
private boolean allowNullValues = true;
private boolean transactionAware = true;
private Long ttl;
Map<String, CacheConfig> configMap = new ConcurrentHashMap<>();
ConcurrentMap<String, Cache> instanceMap = new ConcurrentHashMap<>();
private boolean dynamic = true;
private boolean allowNullValues = true;
private boolean transactionAware = true;
private Long ttl;
/**
* Creates CacheManager supplied by Redisson instance
@ -74,25 +68,6 @@ public class SpringCacheManager implements CacheManager {
this.transactionAware = transactionAware;
}
/**
* Defines 'fixed' cache names.
* A new cache instance will not be created in dynamic for non-defined names.
* <p>
* `null` parameter setups dynamic mode
*
* @param names of caches
*/
public void setCacheNames(Collection<String> names) {
if (names != null) {
for (String name : names) {
getCache(name);
}
dynamic = false;
} else {
dynamic = true;
}
}
/**
* Set cache config mapped by cache name
*
@ -182,5 +157,24 @@ public class SpringCacheManager implements CacheManager {
return Collections.unmodifiableSet(configMap.keySet());
}
/**
* Defines 'fixed' cache names.
* A new cache instance will not be created in dynamic for non-defined names.
* <p>
* `null` parameter setups dynamic mode
*
* @param names of caches
*/
public void setCacheNames(Collection<String> names) {
if (names != null) {
for (String name : names) {
getCache(name);
}
dynamic = false;
} else {
dynamic = true;
}
}
}

View File

@ -1,8 +1,5 @@
package com.fastbee.framework.manager.factory;
import java.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.utils.LogUtils;
import com.fastbee.common.utils.ServletUtils;
@ -15,35 +12,35 @@ import com.fastbee.system.domain.SysOperLog;
import com.fastbee.system.service.ISysLogininforService;
import com.fastbee.system.service.ISysOperLogService;
import eu.bitwalker.useragentutils.UserAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.TimerTask;
/**
* 异步工厂(产生任务用)
*
* @author ruoyi
*/
public class AsyncFactory
{
public class AsyncFactory {
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
/**
* 记录登录信息
*
* @param username 用户名
* @param status 状态
* @param message 消息
* @param args 列表
* @param status 状态
* @param message 消息
* @param args 列表
* @return 任务task
*/
public static TimerTask recordLogininfor(final String username, final String status, final String message,
final Object... args)
{
final Object... args) {
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
return new TimerTask()
{
return new TimerTask() {
@Override
public void run()
{
public void run() {
String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder();
s.append(LogUtils.getBlock(ip));
@ -66,12 +63,9 @@ public class AsyncFactory
logininfor.setOs(os);
logininfor.setMsg(message);
// 日志状态
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
{
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
logininfor.setStatus(Constants.SUCCESS);
}
else if (Constants.LOGIN_FAIL.equals(status))
{
} else if (Constants.LOGIN_FAIL.equals(status)) {
logininfor.setStatus(Constants.FAIL);
}
// 插入数据
@ -86,13 +80,10 @@ public class AsyncFactory
* @param operLog 操作日志信息
* @return 任务task
*/
public static TimerTask recordOper(final SysOperLog operLog)
{
return new TimerTask()
{
public static TimerTask recordOper(final SysOperLog operLog) {
return new TimerTask() {
@Override
public void run()
{
public void run() {
// 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);

View File

@ -9,7 +9,7 @@ import java.util.Collection;
/**
* 拓展 MyBatis Plus QueryWrapper 类,主要增加如下功能:
*
* <p>
* 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
*
* @param <T> 数据类型
@ -93,13 +93,13 @@ public class QueryWrapperX<T> extends QueryWrapper<T> {
}
public QueryWrapperX<T> betweenIfPresent(String column, Object[] values) {
if (values!= null && values.length != 0 && values[0] != null && values[1] != null) {
if (values != null && values.length != 0 && values[0] != null && values[1] != null) {
return (QueryWrapperX<T>) super.between(column, values[0], values[1]);
}
if (values!= null && values.length != 0 && values[0] != null) {
if (values != null && values.length != 0 && values[0] != null) {
return (QueryWrapperX<T>) ge(column, values[0]);
}
if (values!= null && values.length != 0 && values[1] != null) {
if (values != null && values.length != 0 && values[1] != null) {
return (QueryWrapperX<T>) le(column, values[1]);
}
return this;

View File

@ -24,6 +24,7 @@ public class MybatisPlusConfig implements WebMvcConfigurer {
/**
* SQL 过滤器避免SQL 注入
*
* @param argumentResolvers
*/
@Override
@ -49,8 +50,10 @@ public class MybatisPlusConfig implements WebMvcConfigurer {
public IdentifierGenerator idGenerator() {
return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
}
/**
* 审计字段自动填充
*
* @return {@link MybatisPlusMetaObjectHandler}
*/
@Bean

View File

@ -19,6 +19,32 @@ import java.util.Date;
@Slf4j
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
/**
* 填充值,先判断是否有手动设置,优先手动设置的值,例如:job必须手动设置
*
* @param fieldName 属性名
* @param fieldVal 属性值
* @param metaObject MetaObject
* @param isCover 是否覆盖原有值,避免更新操作手动入参
*/
private static void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
// 1. 没有 get 方法
if (!metaObject.hasSetter(fieldName)) {
return;
}
// 2. 如果用户有手动设置的值
Object userSetValue = metaObject.getValue(fieldName);
String setValueStr = StrUtil.str(userSetValue, Charset.defaultCharset());
if (StrUtil.isNotBlank(setValueStr) && !isCover) {
return;
}
// 3. field 类型相同时设置
Class<?> getterType = metaObject.getGetterType(fieldName);
if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
metaObject.setValue(fieldName, fieldVal);
}
}
@Override
public void insertFill(MetaObject metaObject) {
log.debug("mybatisPlus插入填充--------------");
@ -38,33 +64,9 @@ public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
}
/**
* 填充值,先判断是否有手动设置,优先手动设置的值,例如:job必须手动设置
* @param fieldName 属性名
* @param fieldVal 属性值
* @param metaObject MetaObject
* @param isCover 是否覆盖原有值,避免更新操作手动入参
*/
private static void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
// 1. 没有 get 方法
if (!metaObject.hasSetter(fieldName)) {
return;
}
// 2. 如果用户有手动设置的值
Object userSetValue = metaObject.getValue(fieldName);
String setValueStr = StrUtil.str(userSetValue, Charset.defaultCharset());
if (StrUtil.isNotBlank(setValueStr) && !isCover) {
return;
}
// 3. field 类型相同时设置
Class<?> getterType = metaObject.getGetterType(fieldName);
if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
metaObject.setValue(fieldName, fieldVal);
}
}
/**
* 获取 spring security 当前的用户名
*
* @return 当前用户名
*/
private String getUserName() {

View File

@ -34,7 +34,7 @@ public class MyBatisUtils {
// 排序字段
if (!CollectionUtil.isEmpty(sortingFields)) {
page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ?
OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField()))
OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField()))
.collect(Collectors.toList()));
}
return page;
@ -45,8 +45,8 @@ public class MyBatisUtils {
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
*
* @param interceptor 链
* @param inner 拦截器
* @param index 位置
* @param inner 拦截器
* @param index 位置
*/
public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner, int index) {
List<InnerInterceptor> inners = new ArrayList<>(interceptor.getInterceptors());
@ -56,7 +56,7 @@ public class MyBatisUtils {
/**
* 获得 Table 对应的表名
*
* <p>
* 兼容 MySQL 转义表名 `t_xxx`
*
* @param table 表
@ -73,9 +73,9 @@ public class MyBatisUtils {
/**
* 构建 Column 对象
*
* @param tableName 表名
* @param tableName 表名
* @param tableAlias 别名
* @param column 字段名
* @param column 字段名
* @return Column 对象
*/
public static Column buildColumn(String tableName, Alias tableAlias, String column) {

View File

@ -7,22 +7,18 @@ import org.springframework.security.core.Authentication;
*
* @author ruoyi
*/
public class AuthenticationContextHolder
{
public class AuthenticationContextHolder {
private static final ThreadLocal<Authentication> contextHolder = new ThreadLocal<>();
public static Authentication getContext()
{
public static Authentication getContext() {
return contextHolder.get();
}
public static void setContext(Authentication context)
{
public static void setContext(Authentication context) {
contextHolder.set(context);
}
public static void clearContext()
{
public static void clearContext() {
contextHolder.remove();
}
}

View File

@ -9,19 +9,16 @@ import com.fastbee.common.core.text.Convert;
*
* @author ruoyi
*/
public class PermissionContextHolder
{
public class PermissionContextHolder {
private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT";
public static void setContext(String permission)
{
RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,
RequestAttributes.SCOPE_REQUEST);
}
public static String getContext()
{
public static String getContext() {
return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES,
RequestAttributes.SCOPE_REQUEST));
}
public static void setContext(String permission) {
RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,
RequestAttributes.SCOPE_REQUEST);
}
}

View File

@ -5,6 +5,7 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
@ -22,18 +23,15 @@ import com.fastbee.framework.web.service.TokenService;
* @author ruoyi
*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private TokenService tokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException
{
throws ServletException, IOException {
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
tokenService.verifyToken(loginUser);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@ -19,26 +20,23 @@ import com.fastbee.common.utils.StringUtils;
* @author ruoyi
*/
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
{
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable {
private static final long serialVersionUID = -8970718410437077606L;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException
{
// if (isAjaxRequest(request)){
int code = HttpStatus.UNAUTHORIZED;
String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
// }else {
// response.sendRedirect("/oauth/login");
// }
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String ajaxFlag = request.getHeader("X-Requested-With");
return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag);
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException {
// if (isAjaxRequest(request)){
int code = HttpStatus.UNAUTHORIZED;
String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
// }else {
// response.sendRedirect("/oauth/login");
// }
}
}

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
@ -24,8 +25,7 @@ import com.fastbee.framework.web.service.TokenService;
* @author ruoyi
*/
@Configuration
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
{
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
@Autowired
private TokenService tokenService;
@ -36,11 +36,9 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
*/
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException
{
throws IOException, ServletException {
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser))
{
if (StringUtils.isNotNull(loginUser)) {
String userName = loginUser.getUsername();
// 删除用户缓存记录
tokenService.delLoginUser(loginUser.getToken());

View File

@ -1,16 +1,8 @@
package com.fastbee.framework.web.domain;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import com.fastbee.common.utils.Arith;
import com.fastbee.common.utils.ip.IpUtils;
import com.fastbee.framework.web.domain.server.Cpu;
import com.fastbee.framework.web.domain.server.Jvm;
import com.fastbee.framework.web.domain.server.Mem;
import com.fastbee.framework.web.domain.server.Sys;
import com.fastbee.framework.web.domain.server.SysFile;
import com.fastbee.framework.web.domain.server.*;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
@ -21,13 +13,17 @@ import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
/**
* 服务器相关信息
*
* @author ruoyi
*/
public class Server
{
public class Server {
private static final int OSHI_WAIT_SECOND = 1000;
/**
@ -55,58 +51,69 @@ public class Server
*/
private List<SysFile> sysFiles = new LinkedList<SysFile>();
public Cpu getCpu()
{
public Cpu getCpu() {
return cpu;
}
public void setCpu(Cpu cpu)
{
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public Mem getMem()
{
public Mem getMem() {
return mem;
}
public void setMem(Mem mem)
{
public void setMem(Mem mem) {
this.mem = mem;
}
public Jvm getJvm()
{
public Jvm getJvm() {
return jvm;
}
public void setJvm(Jvm jvm)
{
public void setJvm(Jvm jvm) {
this.jvm = jvm;
}
public Sys getSys()
{
public Sys getSys() {
return sys;
}
public void setSys(Sys sys)
{
public void setSys(Sys sys) {
this.sys = sys;
}
public List<SysFile> getSysFiles()
{
public List<SysFile> getSysFiles() {
return sysFiles;
}
public void setSysFiles(List<SysFile> sysFiles)
{
public void setSysFiles(List<SysFile> sysFiles) {
this.sysFiles = sysFiles;
}
public void copyTo() throws Exception
{
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os) {
FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray) {
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
sysFiles.add(sysFile);
}
}
public void copyTo() throws Exception {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
@ -124,8 +131,7 @@ public class Server
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor)
{
private void setCpuInfo(CentralProcessor processor) {
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
@ -150,8 +156,7 @@ public class Server
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory)
{
private void setMemInfo(GlobalMemory memory) {
mem.setTotal(memory.getTotal());
mem.setUsed(memory.getTotal() - memory.getAvailable());
mem.setFree(memory.getAvailable());
@ -160,8 +165,7 @@ public class Server
/**
* 设置服务器信息
*/
private void setSysInfo()
{
private void setSysInfo() {
Properties props = System.getProperties();
sys.setComputerName(IpUtils.getHostName());
sys.setComputerIp(IpUtils.getHostIp());
@ -173,8 +177,7 @@ public class Server
/**
* 设置Java虚拟机
*/
private void setJvmInfo() throws UnknownHostException
{
private void setJvmInfo() throws UnknownHostException {
Properties props = System.getProperties();
jvm.setTotal(Runtime.getRuntime().totalMemory());
jvm.setMax(Runtime.getRuntime().maxMemory());
@ -183,57 +186,25 @@ public class Server
jvm.setHome(props.getProperty("java.home"));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os)
{
FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray)
{
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
sysFiles.add(sysFile);
}
}
/**
* 字节转换
*
* @param size 字节大小
* @return 转换后值
*/
public String convertFileSize(long size)
{
public String convertFileSize(long size) {
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb)
{
if (size >= gb) {
return String.format("%.1f GB", (float) size / gb);
}
else if (size >= mb)
{
} else if (size >= mb) {
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
}
else if (size >= kb)
{
} else if (size >= kb) {
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
}
else
{
} else {
return String.format("%d B", size);
}
}

View File

@ -7,8 +7,7 @@ import com.fastbee.common.utils.Arith;
*
* @author ruoyi
*/
public class Cpu
{
public class Cpu {
/**
* 核心数
*/
@ -39,63 +38,51 @@ public class Cpu
*/
private double free;
public int getCpuNum()
{
public int getCpuNum() {
return cpuNum;
}
public void setCpuNum(int cpuNum)
{
public void setCpuNum(int cpuNum) {
this.cpuNum = cpuNum;
}
public double getTotal()
{
public double getTotal() {
return Arith.round(Arith.mul(total, 100), 2);
}
public void setTotal(double total)
{
public void setTotal(double total) {
this.total = total;
}
public double getSys()
{
public double getSys() {
return Arith.round(Arith.mul(sys / total, 100), 2);
}
public void setSys(double sys)
{
public void setSys(double sys) {
this.sys = sys;
}
public double getUsed()
{
public double getUsed() {
return Arith.round(Arith.mul(used / total, 100), 2);
}
public void setUsed(double used)
{
public void setUsed(double used) {
this.used = used;
}
public double getWait()
{
public double getWait() {
return Arith.round(Arith.mul(wait / total, 100), 2);
}
public void setWait(double wait)
{
public void setWait(double wait) {
this.wait = wait;
}
public double getFree()
{
public double getFree() {
return Arith.round(Arith.mul(free / total, 100), 2);
}
public void setFree(double free)
{
public void setFree(double free) {
this.free = free;
}
}

View File

@ -1,16 +1,16 @@
package com.fastbee.framework.web.domain.server;
import java.lang.management.ManagementFactory;
import com.fastbee.common.utils.Arith;
import com.fastbee.common.utils.DateUtils;
import java.lang.management.ManagementFactory;
/**
* JVM相关信息
*
* @author ruoyi
*/
public class Jvm
{
public class Jvm {
/**
* 当前JVM占用的内存总数(M)
*/
@ -36,95 +36,79 @@ public class Jvm
*/
private String home;
public double getTotal()
{
public double getTotal() {
return Arith.div(total, (1024 * 1024), 2);
}
public void setTotal(double total)
{
public void setTotal(double total) {
this.total = total;
}
public double getMax()
{
public double getMax() {
return Arith.div(max, (1024 * 1024), 2);
}
public void setMax(double max)
{
public void setMax(double max) {
this.max = max;
}
public double getFree()
{
public double getFree() {
return Arith.div(free, (1024 * 1024), 2);
}
public void setFree(double free)
{
public void setFree(double free) {
this.free = free;
}
public double getUsed()
{
public double getUsed() {
return Arith.div(total - free, (1024 * 1024), 2);
}
public double getUsage()
{
public double getUsage() {
return Arith.mul(Arith.div(total - free, total, 4), 100);
}
/**
* 获取JDK名称
*/
public String getName()
{
public String getName() {
return ManagementFactory.getRuntimeMXBean().getVmName();
}
public String getVersion()
{
public String getVersion() {
return version;
}
public void setVersion(String version)
{
public void setVersion(String version) {
this.version = version;
}
public String getHome()
{
public String getHome() {
return home;
}
public void setHome(String home)
{
public void setHome(String home) {
this.home = home;
}
/**
* JDK启动时间
*/
public String getStartTime()
{
public String getStartTime() {
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
}
/**
* JDK运行时间
*/
public String getRunTime()
{
public String getRunTime() {
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
}
/**
* 运行参数
*/
public String getInputArgs()
{
public String getInputArgs() {
return ManagementFactory.getRuntimeMXBean().getInputArguments().toString();
}
}

View File

@ -7,8 +7,7 @@ import com.fastbee.common.utils.Arith;
*
* @author ruoyi
*/
public class Mem
{
public class Mem {
/**
* 内存总量
*/
@ -24,38 +23,31 @@ public class Mem
*/
private double free;
public double getTotal()
{
public double getTotal() {
return Arith.div(total, (1024 * 1024 * 1024), 2);
}
public void setTotal(long total)
{
public void setTotal(long total) {
this.total = total;
}
public double getUsed()
{
public double getUsed() {
return Arith.div(used, (1024 * 1024 * 1024), 2);
}
public void setUsed(long used)
{
public void setUsed(long used) {
this.used = used;
}
public double getFree()
{
public double getFree() {
return Arith.div(free, (1024 * 1024 * 1024), 2);
}
public void setFree(long free)
{
public void setFree(long free) {
this.free = free;
}
public double getUsage()
{
public double getUsage() {
return Arith.mul(Arith.div(used, total, 4), 100);
}
}

View File

@ -5,8 +5,7 @@ package com.fastbee.framework.web.domain.server;
*
* @author ruoyi
*/
public class Sys
{
public class Sys {
/**
* 服务器名称
*/
@ -32,53 +31,43 @@ public class Sys
*/
private String osArch;
public String getComputerName()
{
public String getComputerName() {
return computerName;
}
public void setComputerName(String computerName)
{
public void setComputerName(String computerName) {
this.computerName = computerName;
}
public String getComputerIp()
{
public String getComputerIp() {
return computerIp;
}
public void setComputerIp(String computerIp)
{
public void setComputerIp(String computerIp) {
this.computerIp = computerIp;
}
public String getUserDir()
{
public String getUserDir() {
return userDir;
}
public void setUserDir(String userDir)
{
public void setUserDir(String userDir) {
this.userDir = userDir;
}
public String getOsName()
{
public String getOsName() {
return osName;
}
public void setOsName(String osName)
{
public void setOsName(String osName) {
this.osName = osName;
}
public String getOsArch()
{
public String getOsArch() {
return osArch;
}
public void setOsArch(String osArch)
{
public void setOsArch(String osArch) {
this.osArch = osArch;
}
}

View File

@ -5,8 +5,7 @@ package com.fastbee.framework.web.domain.server;
*
* @author ruoyi
*/
public class SysFile
{
public class SysFile {
/**
* 盘符路径
*/
@ -42,73 +41,59 @@ public class SysFile
*/
private double usage;
public String getDirName()
{
public String getDirName() {
return dirName;
}
public void setDirName(String dirName)
{
public void setDirName(String dirName) {
this.dirName = dirName;
}
public String getSysTypeName()
{
public String getSysTypeName() {
return sysTypeName;
}
public void setSysTypeName(String sysTypeName)
{
public void setSysTypeName(String sysTypeName) {
this.sysTypeName = sysTypeName;
}
public String getTypeName()
{
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName)
{
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public String getTotal()
{
public String getTotal() {
return total;
}
public void setTotal(String total)
{
public void setTotal(String total) {
this.total = total;
}
public String getFree()
{
public String getFree() {
return free;
}
public void setFree(String free)
{
public void setFree(String free) {
this.free = free;
}
public String getUsed()
{
public String getUsed() {
return used;
}
public void setUsed(String used)
{
public void setUsed(String used) {
this.used = used;
}
public double getUsage()
{
public double getUsage() {
return usage;
}
public void setUsage(double usage)
{
public void setUsage(double usage) {
this.usage = usage;
}
}

View File

@ -1,6 +1,10 @@
package com.fastbee.framework.web.exception;
import javax.servlet.http.HttpServletRequest;
import com.fastbee.common.constant.HttpStatus;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.exception.DemoModeException;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
@ -9,11 +13,8 @@ import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.fastbee.common.constant.HttpStatus;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.exception.DemoModeException;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.StringUtils;
import javax.servlet.http.HttpServletRequest;
/**
* 全局异常处理器
@ -21,16 +22,14 @@ import com.fastbee.common.utils.StringUtils;
* @author ruoyi
*/
@RestControllerAdvice
public class GlobalExceptionHandler
{
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 权限校验异常
*/
@ExceptionHandler(AccessDeniedException.class)
public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request)
{
public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
@ -41,8 +40,7 @@ public class GlobalExceptionHandler
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
HttpServletRequest request)
{
HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
return AjaxResult.error(e.getMessage());
@ -52,8 +50,7 @@ public class GlobalExceptionHandler
* 业务异常
*/
@ExceptionHandler(ServiceException.class)
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
{
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) {
log.error(e.getMessage(), e);
Integer code = e.getCode();
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
@ -63,8 +60,7 @@ public class GlobalExceptionHandler
* 拦截未知的运行时异常
*/
@ExceptionHandler(RuntimeException.class)
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
{
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生未知异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
@ -74,8 +70,7 @@ public class GlobalExceptionHandler
* 系统异常
*/
@ExceptionHandler(Exception.class)
public AjaxResult handleException(Exception e, HttpServletRequest request)
{
public AjaxResult handleException(Exception e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
@ -85,8 +80,7 @@ public class GlobalExceptionHandler
* 自定义验证异常
*/
@ExceptionHandler(BindException.class)
public AjaxResult handleBindException(BindException e)
{
public AjaxResult handleBindException(BindException e) {
log.error(e.getMessage(), e);
String message = e.getAllErrors().get(0).getDefaultMessage();
return AjaxResult.error(message);
@ -96,8 +90,7 @@ public class GlobalExceptionHandler
* 自定义验证异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
{
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.error(e.getMessage(), e);
String message = e.getBindingResult().getFieldError().getDefaultMessage();
return AjaxResult.error(message);
@ -107,8 +100,7 @@ public class GlobalExceptionHandler
* 演示模式异常
*/
@ExceptionHandler(DemoModeException.class)
public AjaxResult handleDemoModeException(DemoModeException e)
{
public AjaxResult handleDemoModeException(DemoModeException e) {
return AjaxResult.error("演示模式,不允许操作");
}
}

View File

@ -1,13 +1,14 @@
package com.fastbee.framework.web.service;
import java.util.Set;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.fastbee.common.core.domain.entity.SysRole;
import com.fastbee.common.core.domain.model.LoginUser;
import com.fastbee.common.utils.SecurityUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.framework.security.context.PermissionContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Set;
/**
* RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母
@ -15,12 +16,15 @@ import com.fastbee.framework.security.context.PermissionContextHolder;
* @author ruoyi
*/
@Service("ss")
public class PermissionService
{
/** 所有权限标识 */
public class PermissionService {
/**
* 所有权限标识
*/
private static final String ALL_PERMISSION = "*:*:*";
/** 管理员角色权限标识 */
/**
* 管理员角色权限标识
*/
private static final String SUPER_ADMIN = "admin";
private static final String ROLE_DELIMETER = ",";
@ -33,15 +37,12 @@ public class PermissionService
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(String permission)
{
if (StringUtils.isEmpty(permission))
{
public boolean hasPermi(String permission) {
if (StringUtils.isEmpty(permission)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
{
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
return false;
}
PermissionContextHolder.setContext(permission);
@ -54,8 +55,7 @@ public class PermissionService
* @param permission 权限字符串
* @return 用户是否不具备某权限
*/
public boolean lacksPermi(String permission)
{
public boolean lacksPermi(String permission) {
return hasPermi(permission) != true;
}
@ -65,23 +65,18 @@ public class PermissionService
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
* @return 用户是否具有以下任意一个权限
*/
public boolean hasAnyPermi(String permissions)
{
if (StringUtils.isEmpty(permissions))
{
public boolean hasAnyPermi(String permissions) {
if (StringUtils.isEmpty(permissions)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
{
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
return false;
}
PermissionContextHolder.setContext(permissions);
Set<String> authorities = loginUser.getPermissions();
for (String permission : permissions.split(PERMISSION_DELIMETER))
{
if (permission != null && hasPermissions(authorities, permission))
{
for (String permission : permissions.split(PERMISSION_DELIMETER)) {
if (permission != null && hasPermissions(authorities, permission)) {
return true;
}
}
@ -94,22 +89,17 @@ public class PermissionService
* @param role 角色字符串
* @return 用户是否具备某角色
*/
public boolean hasRole(String role)
{
if (StringUtils.isEmpty(role))
{
public boolean hasRole(String role) {
if (StringUtils.isEmpty(role)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
{
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
return false;
}
for (SysRole sysRole : loginUser.getUser().getRoles())
{
for (SysRole sysRole : loginUser.getUser().getRoles()) {
String roleKey = sysRole.getRoleKey();
if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
{
if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) {
return true;
}
}
@ -122,8 +112,7 @@ public class PermissionService
* @param role 角色名称
* @return 用户是否不具备某角色
*/
public boolean lacksRole(String role)
{
public boolean lacksRole(String role) {
return hasRole(role) != true;
}
@ -133,21 +122,16 @@ public class PermissionService
* @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
* @return 用户是否具有以下任意一个角色
*/
public boolean hasAnyRoles(String roles)
{
if (StringUtils.isEmpty(roles))
{
public boolean hasAnyRoles(String roles) {
if (StringUtils.isEmpty(roles)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
{
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
return false;
}
for (String role : roles.split(ROLE_DELIMETER))
{
if (hasRole(role))
{
for (String role : roles.split(ROLE_DELIMETER)) {
if (hasRole(role)) {
return true;
}
}
@ -158,11 +142,10 @@ public class PermissionService
* 判断是否包含权限
*
* @param permissions 权限列表
* @param permission 权限字符串
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
private boolean hasPermissions(Set<String> permissions, String permission)
{
private boolean hasPermissions(Set<String> permissions, String permission) {
return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
}
}

View File

@ -1,10 +1,5 @@
package com.fastbee.framework.web.service;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.fastbee.common.constant.CacheConstants;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.core.domain.entity.SysUser;
@ -16,6 +11,12 @@ import com.fastbee.common.utils.SecurityUtils;
import com.fastbee.framework.manager.AsyncManager;
import com.fastbee.framework.manager.factory.AsyncFactory;
import com.fastbee.framework.security.context.AuthenticationContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 登录密码方法
@ -23,8 +24,7 @@ import com.fastbee.framework.security.context.AuthenticationContextHolder;
* @author ruoyi
*/
@Component
public class SysPasswordService
{
public class SysPasswordService {
@Autowired
private RedisCache redisCache;
@ -40,86 +40,71 @@ public class SysPasswordService
* @param username 用户名
* @return 缓存键key
*/
private String getCacheKey(String username)
{
private String getCacheKey(String username) {
return CacheConstants.PWD_ERR_CNT_KEY + username;
}
public void validate(SysUser user)
{
public void validate(SysUser user) {
Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
String username = usernamePasswordAuthenticationToken.getName();
String password = usernamePasswordAuthenticationToken.getCredentials().toString();
Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
if (retryCount == null)
{
if (retryCount == null) {
retryCount = 0;
}
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{
if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
}
if (!matches(user, password))
{
if (!matches(user, password)) {
retryCount = retryCount + 1;
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.count", retryCount)));
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new UserPasswordNotMatchException();
}
else
{
} else {
clearLoginRecordCache(username);
}
}
public void socialValidate(SysUser user, String encodePwd)
{
public void socialValidate(SysUser user, String encodePwd) {
String username = user.getUserName();
String password = user.getPassword();
Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
if (retryCount == null)
{
if (retryCount == null) {
retryCount = 0;
}
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{
if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
}
if(!password.equals(encodePwd)){
if (!password.equals(encodePwd)) {
retryCount = retryCount + 1;
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.count", retryCount)));
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new UserPasswordNotMatchException();
}
else
{
} else {
clearLoginRecordCache(username);
}
}
public boolean matches(SysUser user, String rawPassword)
{
public boolean matches(SysUser user, String rawPassword) {
return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
}
public void clearLoginRecordCache(String loginName)
{
if (redisCache.hasKey(getCacheKey(loginName)))
{
public void clearLoginRecordCache(String loginName) {
if (redisCache.hasKey(getCacheKey(loginName))) {
redisCache.deleteObject(getCacheKey(loginName));
}
}
@ -130,28 +115,23 @@ public class SysPasswordService
Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
if (retryCount == null)
{
if (retryCount == null) {
retryCount = 0;
}
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{
if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
}
if (!matches(user, encodePwd))
{
if (!matches(user, encodePwd)) {
retryCount = retryCount + 1;
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.count", retryCount)));
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new UserPasswordNotMatchException();
}
else
{
} else {
clearLoginRecordCache(username);
}
}

View File

@ -1,14 +1,15 @@
package com.fastbee.framework.web.service;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fastbee.common.core.domain.entity.SysRole;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.system.service.ISysMenuService;
import com.fastbee.system.service.ISysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 用户权限处理
@ -16,8 +17,7 @@ import com.fastbee.system.service.ISysRoleService;
* @author ruoyi
*/
@Component
public class SysPermissionService
{
public class SysPermissionService {
@Autowired
private ISysRoleService roleService;
@ -30,16 +30,12 @@ public class SysPermissionService
* @param user 用户信息
* @return 角色权限信息
*/
public Set<String> getRolePermission(SysUser user)
{
public Set<String> getRolePermission(SysUser user) {
Set<String> roles = new HashSet<String>();
// 管理员拥有所有权限
if (user.isAdmin())
{
if (user.isAdmin()) {
roles.add("admin");
}
else
{
} else {
roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
}
return roles;
@ -51,26 +47,21 @@ public class SysPermissionService
* @param user 用户信息
* @return 菜单权限信息
*/
public Set<String> getMenuPermission(SysUser user)
{
public Set<String> getMenuPermission(SysUser user) {
Set<String> perms = new HashSet<String>();
// 管理员拥有所有权限
if (user.isAdmin()) {
perms.add("*:*:*");
} else {
List<SysRole> roles = user.getRoles();
if (!roles.isEmpty() && roles.size() > 1)
{
if (!roles.isEmpty() && roles.size() > 1) {
// 多角色设置permissions属性,以便数据权限匹配权限
for (SysRole role : roles)
{
for (SysRole role : roles) {
Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
role.setPermissions(rolePerms);
perms.addAll(rolePerms);
}
}
else
{
} else {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
}
}

View File

@ -1,7 +1,5 @@
package com.fastbee.framework.web.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fastbee.common.constant.CacheConstants;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.constant.UserConstants;
@ -17,6 +15,8 @@ import com.fastbee.framework.manager.AsyncManager;
import com.fastbee.framework.manager.factory.AsyncFactory;
import com.fastbee.system.service.ISysConfigService;
import com.fastbee.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 注册校验方法
@ -24,8 +24,7 @@ import com.fastbee.system.service.ISysUserService;
* @author ruoyi
*/
@Component
public class SysRegisterService
{
public class SysRegisterService {
@Autowired
private ISysUserService userService;
@ -38,52 +37,36 @@ public class SysRegisterService
/**
* 注册
*/
public String register(RegisterBody registerBody)
{
public String register(RegisterBody registerBody) {
String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword();
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
// 验证码开关
boolean captchaEnabled = configService.selectCaptchaEnabled();
if (captchaEnabled)
{
if (captchaEnabled) {
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
}
if (StringUtils.isEmpty(username))
{
if (StringUtils.isEmpty(username)) {
msg = "用户名不能为空";
}
else if (StringUtils.isEmpty(password))
{
} else if (StringUtils.isEmpty(password)) {
msg = "用户密码不能为空";
}
else if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
} else if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH) {
msg = "账户长度必须在2到20个字符之间";
}
else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
} else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
msg = "密码长度必须在5到20个字符之间";
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser)))
{
} else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser))) {
msg = "保存用户'" + username + "'失败,注册账号已存在";
}
else
{
} else {
sysUser.setNickName(username);
sysUser.setPassword(SecurityUtils.encryptPassword(password));
boolean regFlag = userService.registerUser(sysUser);
if (!regFlag)
{
if (!regFlag) {
msg = "注册失败,请联系系统管理人员";
}
else
{
} else {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success")));
}
}
@ -94,21 +77,18 @@ public class SysRegisterService
* 校验验证码
*
* @param username 用户名
* @param code 验证码
* @param uuid 唯一标识
* @param code 验证码
* @param uuid 唯一标识
* @return 结果
*/
public void validateCaptcha(String username, String code, String uuid)
{
public void validateCaptcha(String username, String code, String uuid) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null)
{
if (captcha == null) {
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha))
{
if (!code.equalsIgnoreCase(captcha)) {
throw new CaptchaException();
}
}

View File

@ -35,24 +35,18 @@ import java.util.concurrent.TimeUnit;
*/
@Component
public class TokenService {
protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
// 令牌自定义标识
@Value("${token.header}")
private String header;
// 令牌秘钥
@Value("${token.secret}")
private String secret;
// 令牌有效期(默认30分钟)
@Value("${token.expireTime}")
private int expireTime;
protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
@Autowired
private RedisCache redisCache;

View File

@ -1,5 +1,11 @@
package com.fastbee.framework.web.service;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.common.core.domain.model.LoginUser;
import com.fastbee.common.enums.UserStatus;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -7,12 +13,6 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.common.core.domain.model.LoginUser;
import com.fastbee.common.enums.UserStatus;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.system.service.ISysUserService;
/**
* 用户验证处理
@ -20,8 +20,7 @@ import com.fastbee.system.service.ISysUserService;
* @author ruoyi
*/
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
public class UserDetailsServiceImpl implements UserDetailsService {
private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
@Autowired
@ -34,21 +33,15 @@ public class UserDetailsServiceImpl implements UserDetailsService
private SysPermissionService permissionService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = userService.selectUserByUserName(username);
if (StringUtils.isNull(user))
{
if (StringUtils.isNull(user)) {
log.info("登录用户:{} 不存在.", username);
throw new ServiceException("登录用户:" + username + " 不存在");
}
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
} else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
log.info("登录用户:{} 已被删除.", username);
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
}
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", username);
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
@ -58,8 +51,7 @@ public class UserDetailsServiceImpl implements UserDetailsService
return createLoginUser(user);
}
public UserDetails createLoginUser(SysUser user)
{
public UserDetails createLoginUser(SysUser user) {
return new LoginUser(user.getUserId(), user.getDeptId(), user.getLanguage(), user, permissionService.getMenuPermission(user));
}
}

View File

@ -1,34 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>fastbee</artifactId>
<groupId>com.fastbee</groupId>
<version>3.8.5</version>
</parent>
<artifactId>fastbee-iot-data</artifactId>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>fastbee</artifactId>
<groupId>com.fastbee</groupId>
<version>3.8.5</version>
</parent>
<artifactId>fastbee-iot-data</artifactId>
<dependencies>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>mqtt-broker</artifactId>
</dependency>
<dependencies>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>mqtt-broker</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mq</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mq</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mqtt-client</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mqtt-client</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -65,7 +65,7 @@ public class StartBoot implements ApplicationRunner {
log.info("=>设备监听队列启动成功");
}).start();
} catch (Exception e) {
log.error("=>客户端启动失败:{}", e.getMessage(),e);
log.error("=>客户端启动失败:{}", e.getMessage(), e);
}
}
}

View File

@ -14,11 +14,11 @@ import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.service.IProductService;
import com.fastbee.iot.service.IProductAuthorizeService;
import com.fastbee.iot.domain.ProductAuthorize;
import com.fastbee.iot.domain.Product;
import com.fastbee.iot.domain.ProductAuthorize;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.service.IProductAuthorizeService;
import com.fastbee.iot.service.IProductService;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.mqtt.manager.MqttRemoteManager;
import com.fastbee.mqtt.model.PushMessageBo;
@ -41,7 +41,7 @@ import java.util.Objects;
/**
* 设备调试错误日志AOP切面
* 用于拦截数据解析和指令发送的异常,自动记录错误日志并推送到前端页面
*
* <p>
* 功能:
* 1. 拦截设备数据解析异常(parseReportMsg)
* 2. 拦截指令发送异常(messagePost)
@ -58,13 +58,21 @@ import java.util.Objects;
@Slf4j
public class DeviceDebugLogAspect {
/** 日志值最大长度 */
/**
* 日志值最大长度
*/
private static final int MAX_LOG_VALUE_LENGTH = 64;
/** 备注最大长度 */
/**
* 备注最大长度
*/
private static final int MAX_REMARK_LENGTH = 200;
/** 错误信息显示最大长度 */
/**
* 错误信息显示最大长度
*/
private static final int MAX_ERROR_MSG_DISPLAY_LENGTH = 50;
/** 其他模式 */
/**
* 其他模式
*/
private static final int MODE_OTHER = 3;
@Resource
@ -461,37 +469,9 @@ public class DeviceDebugLogAspect {
}
}
/**
* 错误日志上下文对象
*/
private static class ErrorLogContext {
private final String serialNumber;
private final String sourceData;
private final String errorMsg;
private final Integer logType;
private final String identity;
private final Long productId;
public ErrorLogContext(String serialNumber, String sourceData, String errorMsg,
Integer logType, String identity, Long productId) {
this.serialNumber = serialNumber;
this.sourceData = sourceData;
this.errorMsg = errorMsg;
this.logType = logType;
this.identity = identity;
this.productId = productId;
}
public String getSerialNumber() { return serialNumber; }
public String getSourceData() { return sourceData; }
public String getErrorMsg() { return errorMsg; }
public Integer getLogType() { return logType; }
public String getIdentity() { return identity; }
public Long getProductId() { return productId; }
}
/**
* 将ASCII字符串转换为HEX字符串
*
* @param asciiStr ASCII字符串
* @return HEX字符串(大写,每两个字符一组,用空格分隔)
*/
@ -523,6 +503,7 @@ public class DeviceDebugLogAspect {
/**
* 将16进制字符串转换为ASCII字符串
*
* @param hexStr 16进制字符串(可能包含空格)
* @return ASCII字符串,保留换行符和回车符,其他不可打印字符显示为点号
*/
@ -570,4 +551,50 @@ public class DeviceDebugLogAspect {
return "";
}
}
/**
* 错误日志上下文对象
*/
private static class ErrorLogContext {
private final String serialNumber;
private final String sourceData;
private final String errorMsg;
private final Integer logType;
private final String identity;
private final Long productId;
public ErrorLogContext(String serialNumber, String sourceData, String errorMsg,
Integer logType, String identity, Long productId) {
this.serialNumber = serialNumber;
this.sourceData = sourceData;
this.errorMsg = errorMsg;
this.logType = logType;
this.identity = identity;
this.productId = productId;
}
public String getSerialNumber() {
return serialNumber;
}
public String getSourceData() {
return sourceData;
}
public String getErrorMsg() {
return errorMsg;
}
public Integer getLogType() {
return logType;
}
public String getIdentity() {
return identity;
}
public Long getProductId() {
return productId;
}
}
}

View File

@ -21,12 +21,12 @@ public class DeviceOtherMsgConsumer {
private DeviceOtherMsgHandler otherMsgHandler;
@Async(FastBeeConstant.TASK.DEVICE_OTHER_TASK)
public void consume(DeviceReportBo bo){
public void consume(DeviceReportBo bo) {
try {
//处理emq订阅的非 property/post 属性上报的消息 ,因为其他消息量小,放在一起处理
//处理emq订阅的非 property/post 属性上报的消息 ,因为其他消息量小,放在一起处理
otherMsgHandler.messageHandler(bo);
}catch (Exception e){
log.error("=>设备其他消息处理出错",e);
} catch (Exception e) {
log.error("=>设备其他消息处理出错", e);
}
}

View File

@ -55,6 +55,8 @@ import java.util.stream.Collectors;
public class DevicePropFetchConsumer {
//锁集合
private final ConcurrentHashMap<String, Lock> taskLocks = new ConcurrentHashMap<>();
@Autowired
private PubMqttClient pubMqttClient;
@Autowired
@ -71,11 +73,8 @@ public class DevicePropFetchConsumer {
private ISessionStore sessionStore;
@Resource
private IModbusParamsService modbusParamsService;
@Value("${server.broker.enabled}")
private Boolean enabled;
//锁集合
private final ConcurrentHashMap<String, Lock> taskLocks = new ConcurrentHashMap<>();
@Async(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK)
public void consume(ModbusPollJob job) {
@ -83,7 +82,7 @@ public class DevicePropFetchConsumer {
DeviceJob deviceJob = job.getDeviceJob();
// type 1:手动下发 2:定时任务执行
ModbusPollMsg task = type == 1 ? job.getPollMsg() : getCommandList(deviceJob);
if (CollectionUtils.isEmpty(task.getCommandList()))return;
if (CollectionUtils.isEmpty(task.getCommandList())) return;
String serialNumber = task.getSerialNumber();
//获取一个线程锁
Lock lock = taskLocks.computeIfAbsent(serialNumber, k -> new ReentrantLock());
@ -132,7 +131,7 @@ public class DevicePropFetchConsumer {
modbusJob.setJobId(jobId);
modbusJob.setStatus("0");
List<ModbusJob> modbusJobList = modbusJobService.selectModbusJobList(modbusJob);
if (CollectionUtils.isEmpty(modbusJobList))return modbusPollMsg;
if (CollectionUtils.isEmpty(modbusJobList)) return modbusPollMsg;
//处理子设备情况
handleSubDeviceStatus(modbusJobList);
List<String> commandList = modbusJobList.stream().map(ModbusJob::getCommand).collect(Collectors.toList());
@ -179,8 +178,8 @@ public class DevicePropFetchConsumer {
DeviceStatusVO deviceStatusVO = deviceService.selectDeviceStatusAndTransportStatus(modbusPollMsg.getSerialNumber());
modbusPollMsg.setTransport(deviceStatusVO.getTransport());
Session session = sessionStore.getSession(modbusPollMsg.getSerialNumber());
if (enabled && Objects.isNull(session)){
log.info("设备:[{}],不在线",modbusPollMsg.getSerialNumber());
if (enabled && Objects.isNull(session)) {
log.info("设备:[{}],不在线", modbusPollMsg.getSerialNumber());
return modbusPollMsg;
}
log.info("执行modbus轮询指令:[{}]", JSON.toJSONString(commandList));
@ -190,30 +189,30 @@ public class DevicePropFetchConsumer {
/**
* 处理子设备根据设备数据定时更新状态
*/
public void handleSubDeviceStatus(List<ModbusJob> modbusJobList){
public void handleSubDeviceStatus(List<ModbusJob> modbusJobList) {
for (ModbusJob modbusJob : modbusJobList) {
String subSerialNumber = modbusJob.getSubSerialNumber();
Session session = sessionStore.getSession(subSerialNumber);
if (Objects.isNull(session))continue;
if (Objects.isNull(session)) continue;
//如果是网关子设备,则检测子设备是否在特定时间内有数据上报
if (modbusJob.getDeviceType() == DeviceType.SUB_GATEWAY.getCode()){
if (modbusJob.getDeviceType() == DeviceType.SUB_GATEWAY.getCode()) {
long deterTime = 300L; //这里默认使用5分钟,如果轮询时间大于5分钟,请在配置参数设置更长时间
ModbusParams params = modbusParamsService.getModbusParamsByDeviceId(modbusJob.getSubDeviceId());
if (!Objects.isNull(params)){
if (!Objects.isNull(params)) {
deterTime = Long.parseLong(params.getDeterTimer());
}
long lastAccessTime = session.getLastAccessTime();
//如果现在的时间 - 最后访问时间 > 判断时间则更新为离线
long time = (System.currentTimeMillis() - lastAccessTime - 20) / 1000;
if (time > deterTime){
if (time > deterTime) {
//处理设备离线
DeviceStatusBo statusBo = DeviceStatusBo.builder().status(DeviceStatus.OFFLINE)
.serialNumber(subSerialNumber)
.timestamp(DateUtils.getNowDate()).build();
MessageProducer.sendStatusMsg(statusBo);
sessionStore.cleanSession(subSerialNumber);
log.info("设备[{}],超过:[{}],未上报数据,更新为离线",subSerialNumber,deterTime);
log.info("设备[{}],超过:[{}],未上报数据,更新为离线", subSerialNumber, deterTime);
}
}

View File

@ -63,7 +63,7 @@ public class DeviceStatusConsumer {
try {
List<DeviceStatusBo> list = new ArrayList<>();
List<SubDeviceBo> subDeviceList = subGatewayService.getSubDeviceListByGw(bo.getSerialNumber());
if (!CollectionUtils.isEmpty(subDeviceList) && bo.getStatus()== DeviceStatus.OFFLINE){
if (!CollectionUtils.isEmpty(subDeviceList) && bo.getStatus() == DeviceStatus.OFFLINE) {
for (SubDeviceBo subDeviceBo : subDeviceList) {
DeviceStatusBo deviceStatusBo = new DeviceStatusBo();
BeanUtils.copyProperties(bo, deviceStatusBo);

View File

@ -20,12 +20,12 @@ public class DeviceTestConsumer {
private IDeviceTestService testHandler;
@Async(FastBeeConstant.TASK.DEVICE_TEST_TASK)
public void consume(DeviceTestReportBo bo){
public void consume(DeviceTestReportBo bo) {
try {
//处理emq订阅的非 property/post 属性上报的消息 ,因为其他消息量小,放在一起处理
testHandler.messageHandler(bo);
}catch (Exception e){
log.error("=>设备其他消息处理出错",e);
} catch (Exception e) {
log.error("=>设备其他消息处理出错", e);
}
}
}

View File

@ -64,6 +64,6 @@ public class subscribeCallback implements IMqttMessageListener {
.serverType(ServerType.MQTT)
.build();
/*将mqtt的消息发送至MQ队列处理消息 ,减轻mqtt客户端消息压力*/
emqxMessageSerice.sendEmqxMessage(name,reportBo);
emqxMessageSerice.sendEmqxMessage(name, reportBo);
}
}

View File

@ -4,12 +4,12 @@ import com.fastbee.common.constant.Constants;
import com.fastbee.common.constant.ScheduleConstants;
import com.fastbee.common.utils.ExceptionUtil;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.TraceIdUtils;
import com.fastbee.common.utils.bean.BeanUtils;
import com.fastbee.common.utils.spring.SpringUtils;
import com.fastbee.iot.domain.DeviceJob;
import com.fastbee.quartz.domain.SysJobLog;
import com.fastbee.quartz.service.ISysJobLogService;
import com.fastbee.common.utils.TraceIdUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@ -23,8 +23,7 @@ import java.util.Date;
*
* @author ruoyi
*/
public abstract class DeviceAbstractQuartzJob implements Job
{
public abstract class DeviceAbstractQuartzJob implements Job {
private static final Logger log = LoggerFactory.getLogger(DeviceAbstractQuartzJob.class);
/**
@ -33,21 +32,16 @@ public abstract class DeviceAbstractQuartzJob implements Job
private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException
{
public void execute(JobExecutionContext context) throws JobExecutionException {
DeviceJob deviceJob = new DeviceJob();
BeanUtils.copyBeanProp(deviceJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
try
{
try {
before(context, deviceJob);
if (deviceJob != null)
{
if (deviceJob != null) {
doExecute(context, deviceJob);
}
after(context, deviceJob, null);
}
catch (Exception e)
{
} catch (Exception e) {
log.error("任务执行异常 - :", e);
after(context, deviceJob, e);
}
@ -56,11 +50,10 @@ public abstract class DeviceAbstractQuartzJob implements Job
/**
* 执行前
*
* @param context 工作执行上下文对象
* @param context 工作执行上下文对象
* @param deviceJob 系统计划任务
*/
protected void before(JobExecutionContext context, DeviceJob deviceJob)
{
protected void before(JobExecutionContext context, DeviceJob deviceJob) {
threadLocal.set(new Date());
// 为设备定时任务生成TraceId,使用统一的生成逻辑
@ -72,11 +65,10 @@ public abstract class DeviceAbstractQuartzJob implements Job
/**
* 执行后
*
* @param context 工作执行上下文对象
* @param context 工作执行上下文对象
* @param deviceJob 系统计划任务
*/
protected void after(JobExecutionContext context, DeviceJob deviceJob, Exception e)
{
protected void after(JobExecutionContext context, DeviceJob deviceJob, Exception e) {
Date startTime = threadLocal.get();
threadLocal.remove();
@ -89,8 +81,8 @@ public abstract class DeviceAbstractQuartzJob implements Job
if (StringUtils.isEmpty(invokeTarget)) {
// 如果设备名称为空,使用设备编号或任务名称作为默认值
invokeTarget = StringUtils.isNotEmpty(deviceJob.getSerialNumber())
? deviceJob.getSerialNumber()
: deviceJob.getJobName();
? deviceJob.getSerialNumber()
: deviceJob.getJobName();
}
sysJobLog.setInvokeTarget(invokeTarget);
@ -103,14 +95,11 @@ public abstract class DeviceAbstractQuartzJob implements Job
sysJobLog.setStopTime(stopTime);
long runMs = stopTime.getTime() - startTime.getTime();
sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
if (e != null)
{
if (e != null) {
sysJobLog.setStatus(Constants.FAIL);
String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
sysJobLog.setExceptionInfo(errorMsg);
}
else
{
} else {
sysJobLog.setStatus(Constants.SUCCESS);
}
@ -126,7 +115,7 @@ public abstract class DeviceAbstractQuartzJob implements Job
/**
* 执行方法,由子类重载
*
* @param context 工作执行上下文对象
* @param context 工作执行上下文对象
* @param deviceJob 系统计划任务
* @throws Exception 执行过程中的异常
*/

View File

@ -8,14 +8,11 @@ import org.quartz.JobExecutionContext;
* 定时任务处理(禁止并发执行)
*
* @author ruoyi
*
*/
@DisallowConcurrentExecution
public class DeviceDisallowConcurrentExecution extends DeviceAbstractQuartzJob
{
public class DeviceDisallowConcurrentExecution extends DeviceAbstractQuartzJob {
@Override
protected void doExecute(JobExecutionContext context, DeviceJob deviceJob) throws Exception
{
protected void doExecute(JobExecutionContext context, DeviceJob deviceJob) throws Exception {
DeviceJobInvoke.invokeMethod(deviceJob);
}
}

View File

@ -7,13 +7,10 @@ import org.quartz.JobExecutionContext;
* 定时任务处理(允许并发执行)
*
* @author ruoyi
*
*/
public class DeviceJobExecution extends DeviceAbstractQuartzJob
{
public class DeviceJobExecution extends DeviceAbstractQuartzJob {
@Override
protected void doExecute(JobExecutionContext context, DeviceJob deviceJob) throws Exception
{
protected void doExecute(JobExecutionContext context, DeviceJob deviceJob) throws Exception {
DeviceJobInvoke.invokeMethod(deviceJob);
}
}

View File

@ -36,6 +36,7 @@ public class DeviceJobInvoke {
private static FlowLogExecutor flowExecutor = SpringUtils.getBean(FlowLogExecutor.class);
private static IDataHandler dataHandler = SpringUtils.getBean(IDataHandler.class);
/**
* 执行方法
*

View File

@ -10,18 +10,15 @@ import org.quartz.*;
* 定时任务工具类
*
* @author ruoyi
*
*/
public class DeviceScheduleUtils
{
public class DeviceScheduleUtils {
/**
* 得到quartz任务类
*
* @param deviceJob 执行计划
* @return 具体执行任务类
*/
private static Class<? extends Job> getQuartzJobClass(DeviceJob deviceJob)
{
private static Class<? extends Job> getQuartzJobClass(DeviceJob deviceJob) {
boolean isConcurrent = "0".equals(deviceJob.getConcurrent());
return isConcurrent ? DeviceJobExecution.class : DeviceDisallowConcurrentExecution.class;
}
@ -29,24 +26,21 @@ public class DeviceScheduleUtils
/**
* 构建任务触发对象
*/
public static TriggerKey getTriggerKey(Long jobId, String jobGroup)
{
public static TriggerKey getTriggerKey(Long jobId, String jobGroup) {
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 构建任务键对象
*/
public static JobKey getJobKey(Long jobId, String jobGroup)
{
public static JobKey getJobKey(Long jobId, String jobGroup) {
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 创建定时任务
*/
public static void createScheduleJob(Scheduler scheduler, DeviceJob job) throws SchedulerException, TaskException
{
public static void createScheduleJob(Scheduler scheduler, DeviceJob job) throws SchedulerException, TaskException {
Class<? extends Job> jobClass = getQuartzJobClass(job);
// 1.创建任务
Long jobId = job.getJobId();
@ -65,8 +59,7 @@ public class DeviceScheduleUtils
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
// 判断是否存在
if (scheduler.checkExists(getJobKey(jobId, jobGroup)))
{
if (scheduler.checkExists(getJobKey(jobId, jobGroup))) {
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(getJobKey(jobId, jobGroup));
}
@ -75,8 +68,7 @@ public class DeviceScheduleUtils
scheduler.scheduleJob(jobDetail, trigger);
// 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
{
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) {
scheduler.pauseJob(DeviceScheduleUtils.getJobKey(jobId, jobGroup));
}
}
@ -85,10 +77,8 @@ public class DeviceScheduleUtils
* 设置定时任务策略
*/
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(DeviceJob job, CronScheduleBuilder cb)
throws TaskException
{
switch (job.getMisfirePolicy())
{
throws TaskException {
switch (job.getMisfirePolicy()) {
case ScheduleConstants.MISFIRE_DEFAULT:
return cb;
case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:

View File

@ -17,6 +17,7 @@ import java.util.Objects;
/**
* 定时同步设备状态 -- netty版本mqtt使用
*
* @author gsb
* @date 2024/4/11 10:33
*/
@ -32,8 +33,8 @@ public class SyncDeviceStatusJob {
/**
* 定期同步设备状态
* 1.将异常在线设备变更为离线状态
* 2.将离线设备但实际在线设备变更为在线
* 1.将异常在线设备变更为离线状态
* 2.将离线设备但实际在线设备变更为在线
*/
public void syncDeviceStatus() {
if (enabled) {

View File

@ -22,12 +22,12 @@ public class DeviceOtherListen {
private DeviceOtherMsgConsumer otherMsgConsumer;
@Async(FastBeeConstant.TASK.DEVICE_OTHER_TASK)
public void listen(){
while (true){
public void listen() {
while (true) {
try {
DeviceReportBo reportBo = DeviceOtherQueue.take();
otherMsgConsumer.consume(reportBo);
}catch (Exception e){
} catch (Exception e) {
log.error("=>emq数据转发异常");
}
}

View File

@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
/**
* 设备状态监听
*
* @author bill
*/
@Slf4j

View File

@ -21,13 +21,13 @@ public class DeviceTestListen {
private DeviceTestConsumer deviceTestConsumer;
@Async(FastBeeConstant.TASK.DEVICE_TEST_TASK)
public void listen(){
while (true){
public void listen() {
while (true) {
try {
DeviceTestReportBo take = DeviceTestQueue.take();
deviceTestConsumer.consume(take);
}catch (Exception e){
} catch (Exception e) {
log.error("=>emq数据转发异常");
}
}

View File

@ -22,6 +22,7 @@ import java.util.Date;
/**
* OTA升级监听
*
* @author bill
*/
@Slf4j
@ -41,18 +42,18 @@ public class UpGradeListener implements ApplicationRunner {
@Async(FastBeeConstant.TASK.DELAY_UPGRADE_TASK)
public void listen(){
while (true){
public void listen() {
while (true) {
try {
OtaUpgradeDelayTask task = DelayUpgradeQueue.task();
if (StringUtils.isNotNull(task)){
if (StringUtils.isNotNull(task)) {
Date startTime = task.getStartTime();
otaUpgradeService.upgrade(task);
log.info("=>开始OTA升级时间{}",startTime);
log.info("=>开始OTA升级时间{}", startTime);
}
continue;
}catch (Exception e){
log.error("=>OTA升级监听异常",e);
} catch (Exception e) {
log.error("=>OTA升级监听异常", e);
}
}
}
@ -68,14 +69,14 @@ public class UpGradeListener implements ApplicationRunner {
/**
* 切换菜单中Emqx控制台和netty管理
*/
public void updateMenu(){
public void updateMenu() {
SysMenu sysMenu = new SysMenu();
if (enabled){
if (enabled) {
sysMenu.setMenuId(2104L);
sysMenu.setVisible("1");
menuService.updateMenu(sysMenu);
sysMenu.setMenuId(3031L);
}else {
} else {
sysMenu.setMenuId(3031L);
sysMenu.setVisible("1");
menuService.updateMenu(sysMenu);

View File

@ -45,52 +45,37 @@ import static java.util.regex.Pattern.compile;
@Slf4j
public class SceneContext {
private static Logger scene_logger = LoggerFactory.getLogger("scene");
private static IFunctionInvoke functionInvoke = SpringUtils.getBean(IFunctionInvoke.class);
private static IDeviceService deviceService = SpringUtils.getBean(IDeviceService.class);
private static IAlertService alertService = SpringUtils.getBean(IAlertService.class);
private static NotifySendService notifySendService = SpringUtils.getBean(NotifySendService.class);
private static RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
private static IAlertLogService alertLogService = SpringUtils.getBean(IAlertLogService.class);
private static IDeviceUserService deviceUserService = SpringUtils.getBean(IDeviceUserService.class);
private static ISceneService sceneService = SpringUtils.getBean(ISceneService.class);
private static IRuleEngine ruleService = SpringUtils.getBean(IRuleEngine.class);
private static IDeviceAlertUserService deviceAlertUserService = SpringUtils.getBean(IDeviceAlertUserService.class);
/**
* 上报信息的设备编号
*/
private String deviceNum;
/**
* 上报信息的设备所属产品ID
*/
private Long productId;
/**
* 上报信息的设备信息类型 1=属性, 2=功能,3=事件,4=设备升级,5=设备上线,6=设备下线
*/
private int type;
/**
* 上报的物模型集合
*/
private List<ThingsModelSimpleItem> thingsModelSimpleItems;
/**
* 触发成功的物模型集合,保留给告警记录
*/
private List<SceneThingsModelItem> sceneThingsModelItems;
private static IFunctionInvoke functionInvoke = SpringUtils.getBean(IFunctionInvoke.class);
private static IDeviceService deviceService = SpringUtils.getBean(IDeviceService.class);
private static IAlertService alertService = SpringUtils.getBean(IAlertService.class);
private static NotifySendService notifySendService = SpringUtils.getBean(NotifySendService.class);
private static RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
private static IAlertLogService alertLogService = SpringUtils.getBean(IAlertLogService.class);
private static IDeviceUserService deviceUserService = SpringUtils.getBean(IDeviceUserService.class);
private static ISceneService sceneService = SpringUtils.getBean(ISceneService.class);
private static IRuleEngine ruleService = SpringUtils.getBean(IRuleEngine.class);
private static IDeviceAlertUserService deviceAlertUserService = SpringUtils.getBean(IDeviceAlertUserService.class);
public SceneContext(String deviceNum, Long productId, int type, List<ThingsModelSimpleItem> thingsModelSimpleItems) {
this.deviceNum = deviceNum;
this.productId = productId;

View File

@ -5,6 +5,7 @@ import com.fastbee.common.core.mq.message.ReportDataBo;
/**
* 客户端上报数据处理方法集合
*
* @author bill
*/
public interface IDataHandler {
@ -26,12 +27,14 @@ public interface IDataHandler {
/**
* 上报设备信息
*
* @param bo 上报数据模型
*/
public void reportDevice(ReportDataBo bo);
/**
* 计算场景变量的值
*
* @param id 主键id
* @return java.lang.String
*/
@ -39,6 +42,7 @@ public interface IDataHandler {
/**
* 场景变量指令下发
*
* @param reqDto 下发类
* @return void
*/

View File

@ -21,6 +21,7 @@ public interface IDeviceMessageService {
/**
* 变量读取
*
* @param readVO
*/
public void readVariableValue(VariableReadVO readVO);

View File

@ -6,6 +6,7 @@ import com.fastbee.protocol.base.protocol.IProtocol;
/**
* 处理设备上报数据解析
*
* @author gsb
* @date 2022/10/10 13:48
*/
@ -13,18 +14,21 @@ public interface IDeviceReportMessageService {
/**
* 处理设备主动上报数据
*
* @param bo
*/
public void parseReportMsg(DeviceReportBo bo);
/**
* 处理设备普通消息回调
*
* @param bo
*/
public void parseReplyMsg(DeviceReportBo bo);
/**
* 处理设备OTA升级
*
* @param bo
*/
public void parseOTAUpdateReply(DeviceReportBo bo);
@ -32,6 +36,7 @@ public interface IDeviceReportMessageService {
/**
* 构建消息
*
* @param bo
*/
public DeviceStatusVO buildReport(DeviceReportBo bo);

View File

@ -15,8 +15,7 @@ import java.util.List;
* @author kerwincui
* @date 2024-08-18
*/
public interface IFirmwareTaskDetailService extends IService<FirmwareTaskDetail>
{
public interface IFirmwareTaskDetailService extends IService<FirmwareTaskDetail> {
/**
* 查询固件升级任务详细对象列表
@ -29,6 +28,7 @@ public interface IFirmwareTaskDetailService extends IService<FirmwareTaskDetail>
/**
* 查询固件升级任务详细
*
* @param taskId
* @param serialNumber
* @return
@ -36,9 +36,9 @@ public interface IFirmwareTaskDetailService extends IService<FirmwareTaskDetail>
public FirmwareTaskDetail selectFirmwareTaskDetailByTaskIdAndSerialNumber(Long taskId, String serialNumber);
/**
* 更新升级状态
*
* @param taskId
* @param serialNumber
* @param otaUpgrade

View File

@ -13,8 +13,7 @@ import java.util.List;
* @author kerwincui
* @date 2024-08-18
*/
public interface IFirmwareTaskService extends IService<FirmwareTask>
{
public interface IFirmwareTaskService extends IService<FirmwareTask> {
/**
* 查询固件升级任务对象列表
@ -35,6 +34,7 @@ public interface IFirmwareTaskService extends IService<FirmwareTask>
/**
* OTA升级
*
* @param task
*/
void upgrade(OtaUpgradeDelayTask task);

View File

@ -5,6 +5,7 @@ import com.fastbee.common.core.mq.InvokeReqDto;
/**
* 设备指令下发接口
*
* @author gsb
* @date 2022/12/5 11:03
*/
@ -12,6 +13,7 @@ public interface IFunctionInvoke {
/**
* 服务调用,等待设备响应
*
* @param reqDto 服务下发对象
* @return 数据结果
*/
@ -19,6 +21,7 @@ public interface IFunctionInvoke {
/**
* 服务调用,设备不响应
*
* @param reqDto 服务下发对象
* @return 消息id messageId
*/

View File

@ -2,6 +2,7 @@ package com.fastbee.iot.data.service;
/**
* 设备消息推送mq
*
* @author bill
*/
public interface IMessagePublishService {
@ -9,9 +10,10 @@ public interface IMessagePublishService {
/**
* 发布消息到mq
*
* @param message 设备消息
* @param channel 推送channel
*/
public void publish(Object message,String channel);
public void publish(Object message, String channel);
}

View File

@ -66,7 +66,7 @@ public interface IMqttMessagePublish {
* 推送设备状态
*
* @param device 设备
* @param status 状态
* @param status 状态
*/
public void pushDeviceStatus(Device device, DeviceStatus status);

View File

@ -11,6 +11,7 @@ public interface IOtaTaskUpgradeService {
/**
* 固件升级异步方法
*
* @param taskId
* @param serialNumber
* @param firmware

View File

@ -4,12 +4,14 @@ import com.fastbee.common.core.mq.ota.OtaUpgradeDelayTask;
/**
* OTA升级
*
* @author bill
*/
public interface IOtaUpgradeService {
/**
* OTA延迟升级任务发送
*
* @param task
*/
public void upgrade(OtaUpgradeDelayTask task);

View File

@ -6,6 +6,7 @@ import java.util.concurrent.ScheduledExecutorService;
/**
* 规则引擎处理数据方法集合
*
* @author bill
*/
public interface IRuleEngine {
@ -15,6 +16,8 @@ public interface IRuleEngine {
* @param bo 上报数据模型
*/
public void ruleMatch(ReportDataBo bo);
public void addCheckTask(String key, ScheduledExecutorService task);
public void removeCheckTask(String key);
}

View File

@ -42,6 +42,7 @@ import java.util.*;
/**
* 上报数据处理方法集合
*
* @author bill
*/
@Service
@ -99,7 +100,7 @@ public class DataHandlerImpl implements IDataHandler {
input.setSources(bo.getSources());
List<ThingsModelSimpleItem> result = deviceService.reportDeviceThingsModelValue(input, bo.getType(), bo.isShadow());
// 只有设备上报进入规则引擎流程
if (bo.isRuleEngine() && !bo.getSerialNumber().startsWith("server-")){
if (bo.isRuleEngine() && !bo.getSerialNumber().startsWith("server-")) {
ruleEngine.ruleMatch(bo);
}
//发送至前端
@ -107,11 +108,11 @@ public class DataHandlerImpl implements IDataHandler {
messageBo.setTopic(topicsUtils.buildTopic(bo.getProductId(), bo.getSerialNumber(), TopicType.WS_SERVICE_INVOKE));
JSONObject pushObj = new JSONObject();
pushObj.put("message", result);
pushObj.put("sources",bo.getSources());
pushObj.put("sources", bo.getSources());
messageBo.setMessage(JSON.toJSONString(pushObj));
remoteManager.pushCommon(messageBo);
if (!Objects.isNull(bo.getGwDeviceBo())){
messageBo.setTopic(topicsUtils.buildTopic(bo.getGwDeviceBo().getProductId(),bo.getGwDeviceBo().getSerialNumber(),TopicType.WS_SERVICE_INVOKE));
if (!Objects.isNull(bo.getGwDeviceBo())) {
messageBo.setTopic(topicsUtils.buildTopic(bo.getGwDeviceBo().getProductId(), bo.getGwDeviceBo().getSerialNumber(), TopicType.WS_SERVICE_INVOKE));
remoteManager.pushCommon(messageBo);
}
// 上报属性给小度音箱,接入小度音箱后可放开
@ -122,7 +123,7 @@ public class DataHandlerImpl implements IDataHandler {
// log.error("=>上报属性信息给小度音箱异常", e);
// }
} catch (Exception e) {
log.error("接收属性数据,解析数据时异常 message={}", e.getMessage(),e);
log.error("接收属性数据,解析数据时异常 message={}", e.getMessage(), e);
}
}
@ -160,7 +161,7 @@ public class DataHandlerImpl implements IDataHandler {
//eventLogService.insertEventLog(event);
}
eventLogService.saveBatch(results);
if (bo.isRuleEngine()){
if (bo.isRuleEngine()) {
ruleEngine.ruleMatch(bo);
}
} catch (Exception e) {
@ -255,10 +256,11 @@ public class DataHandlerImpl implements IDataHandler {
/**
* 保存场景变量值
*
* @param sceneModelTag 变量类
* @return void
* @param: value 值
* @param: now 执行时间
* @return void
*/
private void saveSceneModelTagValue(SceneModelTag sceneModelTag, String value, LocalDateTime now) {
// 保存运算型变量值,存缓存

View File

@ -68,9 +68,9 @@ public class DeviceJob {
//更新iot设备状态
Device dev = deviceService.selectDeviceBySerialNumber(item.getDeviceSipId());
if (dev != null && dev.getStatus() == DeviceStatus.ONLINE.getType()) {
log.warn("定时任务:=>设备:{} 已经下线,设备超过{}秒没上线!",item.getDeviceSipId(),timeout);
log.warn("定时任务:=>设备:{} 已经下线,设备超过{}秒没上线!", item.getDeviceSipId(), timeout);
dev.setStatus(DeviceStatus.OFFLINE.getType());
deviceService.updateDeviceStatusAndLocation(dev,"");
deviceService.updateDeviceStatusAndLocation(dev, "");
DeviceStatusBo bo = DeviceStatusBo.builder()
.serialNumber(dev.getSerialNumber())
.status(DeviceStatus.OFFLINE)

View File

@ -29,8 +29,7 @@ import java.util.List;
*/
@Service
@Slf4j
public class DeviceJobServiceImpl implements IDeviceJobService
{
public class DeviceJobServiceImpl implements IDeviceJobService {
@Autowired
private Scheduler scheduler;
@ -45,13 +44,11 @@ public class DeviceJobServiceImpl implements IDeviceJobService
* 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据)
*/
@PostConstruct
public void init() throws SchedulerException, TaskException
{
public void init() throws SchedulerException, TaskException {
scheduler.clear();
// 设备定时任务
List<DeviceJob> jobList = jobMapper.selectJobAll();
for (DeviceJob deviceJob : jobList)
{
for (DeviceJob deviceJob : jobList) {
// 跳过设备上电触发任务,它们不需要加入调度器
if (!isPowerOnTriggerTask(deviceJob) && StringUtils.isNotEmpty(deviceJob.getCronExpression())) {
DeviceScheduleUtils.createScheduleJob(scheduler, deviceJob);
@ -60,8 +57,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
// 系统定时任务
List<SysJob> sysJobList = sysJobMapper.selectJobAll();
for (SysJob job : sysJobList)
{
for (SysJob job : sysJobList) {
com.fastbee.quartz.util.ScheduleUtils.createScheduleJob(scheduler, job);
}
}
@ -73,8 +69,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
* @return
*/
@Override
public List<DeviceJob> selectJobList(DeviceJob job)
{
public List<DeviceJob> selectJobList(DeviceJob job) {
return jobMapper.selectJobList(job);
}
@ -85,8 +80,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
* @return 调度任务对象信息
*/
@Override
public DeviceJob selectJobById(Long jobId)
{
public DeviceJob selectJobById(Long jobId) {
return jobMapper.selectJobById(jobId);
}
@ -97,14 +91,12 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int pauseJob(DeviceJob job) throws SchedulerException
{
public int pauseJob(DeviceJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0)
{
if (rows > 0) {
scheduler.pauseJob(DeviceScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
@ -117,14 +109,12 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int resumeJob(DeviceJob job) throws SchedulerException
{
public int resumeJob(DeviceJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0)
{
if (rows > 0) {
scheduler.resumeJob(DeviceScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
@ -137,13 +127,11 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteJob(DeviceJob job) throws SchedulerException
{
public int deleteJob(DeviceJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
int rows = jobMapper.deleteJobById(jobId);
if (rows > 0)
{
if (rows > 0) {
scheduler.deleteJob(DeviceScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
@ -157,10 +145,8 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Long[] jobIds) throws SchedulerException
{
for (Long jobId : jobIds)
{
public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
for (Long jobId : jobIds) {
DeviceJob job = jobMapper.selectJobById(jobId);
deleteJob(job);
}
@ -174,14 +160,13 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobByDeviceIds(Long[] deviceIds) throws SchedulerException
{
public void deleteJobByDeviceIds(Long[] deviceIds) throws SchedulerException {
// 查出所有job
List<DeviceJob> deviceJobs=jobMapper.selectShortJobListByDeviceIds(deviceIds);
List<DeviceJob> deviceJobs = jobMapper.selectShortJobListByDeviceIds(deviceIds);
// 批量删除job
int rows=jobMapper.deleteJobByDeviceIds(deviceIds);
int rows = jobMapper.deleteJobByDeviceIds(deviceIds);
// 批量删除调度器
for(DeviceJob job:deviceJobs){
for (DeviceJob job : deviceJobs) {
scheduler.deleteJob(DeviceScheduleUtils.getJobKey(job.getJobId(), job.getJobGroup()));
}
}
@ -194,14 +179,13 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobByAlertIds(Long[] alertIds) throws SchedulerException
{
public void deleteJobByAlertIds(Long[] alertIds) throws SchedulerException {
// 查出所有job
List<DeviceJob> deviceJobs=jobMapper.selectShortJobListByAlertIds(alertIds);
List<DeviceJob> deviceJobs = jobMapper.selectShortJobListByAlertIds(alertIds);
// 批量删除job
int rows=jobMapper.deleteJobByAlertIds(alertIds);
int rows = jobMapper.deleteJobByAlertIds(alertIds);
// 批量删除调度器
for(DeviceJob job:deviceJobs){
for (DeviceJob job : deviceJobs) {
scheduler.deleteJob(DeviceScheduleUtils.getJobKey(job.getJobId(), job.getJobGroup()));
}
}
@ -214,14 +198,13 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobBySceneIds(Long[] sceneIds) throws SchedulerException
{
public void deleteJobBySceneIds(Long[] sceneIds) throws SchedulerException {
// 查出所有job
List<DeviceJob> deviceJobs=jobMapper.selectShortJobListBySceneIds(sceneIds);
List<DeviceJob> deviceJobs = jobMapper.selectShortJobListBySceneIds(sceneIds);
// 批量删除job
int rows=jobMapper.deleteJobBySceneIds(sceneIds);
int rows = jobMapper.deleteJobBySceneIds(sceneIds);
// 批量删除调度器
for(DeviceJob job:deviceJobs){
for (DeviceJob job : deviceJobs) {
scheduler.deleteJob(DeviceScheduleUtils.getJobKey(job.getJobId(), job.getJobGroup()));
}
}
@ -233,16 +216,12 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int changeStatus(DeviceJob job) throws SchedulerException
{
public int changeStatus(DeviceJob job) throws SchedulerException {
int rows = 0;
String status = job.getStatus();
if (ScheduleConstants.Status.NORMAL.getValue().equals(status))
{
if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) {
rows = resumeJob(job);
}
else if (ScheduleConstants.Status.PAUSE.getValue().equals(status))
{
} else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) {
rows = pauseJob(job);
}
return rows;
@ -255,8 +234,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void run(DeviceJob job) throws SchedulerException
{
public void run(DeviceJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
DeviceJob properties = selectJobById(job.getJobId());
@ -273,8 +251,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int insertJob(DeviceJob deviceJob) throws SchedulerException, TaskException
{
public int insertJob(DeviceJob deviceJob) throws SchedulerException, TaskException {
int rows = jobMapper.insertJob(deviceJob);
if (rows > 0) {
// 检查是否是设备上电触发任务(通过检查remark或cron表达式)
@ -289,6 +266,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
/**
* 检查是否是设备上电触发任务
*
* @param deviceJob 设备任务
* @return true表示是设备上电触发任务
*/
@ -315,12 +293,10 @@ public class DeviceJobServiceImpl implements IDeviceJobService
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateJob(DeviceJob deviceJob) throws SchedulerException, TaskException
{
public int updateJob(DeviceJob deviceJob) throws SchedulerException, TaskException {
DeviceJob properties = selectJobById(deviceJob.getJobId());
int rows = jobMapper.updateJob(deviceJob);
if (rows > 0)
{
if (rows > 0) {
updateSchedulerJob(deviceJob, properties.getJobGroup());
}
return rows;
@ -330,15 +306,13 @@ public class DeviceJobServiceImpl implements IDeviceJobService
* 更新任务
*
* @param deviceJob 任务对象
* @param jobGroup 任务组名
* @param jobGroup 任务组名
*/
public void updateSchedulerJob(DeviceJob deviceJob, String jobGroup) throws SchedulerException, TaskException
{
public void updateSchedulerJob(DeviceJob deviceJob, String jobGroup) throws SchedulerException, TaskException {
Long jobId = deviceJob.getJobId();
// 判断是否存在
JobKey jobKey = DeviceScheduleUtils.getJobKey(jobId, jobGroup);
if (scheduler.checkExists(jobKey))
{
if (scheduler.checkExists(jobKey)) {
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(jobKey);
}
@ -356,8 +330,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
* @return 结果
*/
@Override
public boolean checkCronExpressionIsValid(String cronExpression)
{
public boolean checkCronExpressionIsValid(String cronExpression) {
return CronUtils.isValid(cronExpression);
}
@ -374,7 +347,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
// 批量删除job
int rows = jobMapper.deleteJobByJobTypeAndDatasourceIds(datasourceIds, jobType);
// 批量删除调度器
for(DeviceJob job:deviceJobs){
for (DeviceJob job : deviceJobs) {
scheduler.deleteJob(DeviceScheduleUtils.getJobKey(job.getJobId(), job.getJobGroup()));
}
}
@ -387,6 +360,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
/**
* 根据条件批量删除定时任务
*
* @param deviceId
* @param jobType
*/
@ -401,7 +375,7 @@ public class DeviceJobServiceImpl implements IDeviceJobService
// 批量删除job
jobMapper.deleteJobByJobTypeAndDeviceId(deviceId, jobType);
// 批量删除调度器
for(DeviceJob job:deviceJobs){
for (DeviceJob job : deviceJobs) {
scheduler.deleteJob(DeviceScheduleUtils.getJobKey(job.getJobId(), job.getJobGroup()));
}
}

View File

@ -87,12 +87,12 @@ public class DeviceMessageServiceImpl implements IDeviceMessageService {
DeviceAndProtocol deviceAndProtocol = deviceService.selectProtocolBySerialNumber(serialNumber);
String transport = deviceAndProtocol.getTransport();
TopicType type = TopicType.getType(topicName);
topicName = topicsUtils.buildTopic(deviceAndProtocol.getProductId(), serialNumber,type);
switch (type){
topicName = topicsUtils.buildTopic(deviceAndProtocol.getProductId(), serialNumber, type);
switch (type) {
case FUNCTION_GET:
if (transport.equals(ServerType.MQTT.getCode())){
if (transport.equals(ServerType.MQTT.getCode())) {
mqttClient.publish(0, false, topicName, deviceMessage.getMessage().toString());
}else if (transport.equals(ServerType.TCP.getCode())){
} else if (transport.equals(ServerType.TCP.getCode())) {
//处理TCP下发
ModbusPollMsg modbusPollMsg = new ModbusPollMsg();
modbusPollMsg.setSerialNumber(serialNumber);
@ -102,8 +102,8 @@ public class DeviceMessageServiceImpl implements IDeviceMessageService {
modbusPollMsg.setCommandList(commandList);
DeviceStatusVO deviceStatusVO = deviceService.selectDeviceStatusAndTransportStatus(modbusPollMsg.getSerialNumber());
modbusPollMsg.setTransport(deviceStatusVO.getTransport());
if (deviceStatusVO.getStatus() != DeviceStatus.ONLINE.getType()){
log.info("设备:[{}],不在线",modbusPollMsg.getSerialNumber());
if (deviceStatusVO.getStatus() != DeviceStatus.ONLINE.getType()) {
log.info("设备:[{}],不在线", modbusPollMsg.getSerialNumber());
return;
}
ModbusPollJob modbusPollJob = new ModbusPollJob();
@ -149,13 +149,13 @@ public class DeviceMessageServiceImpl implements IDeviceMessageService {
out = modbusTcpEncoder.encode(modbusTcp);
} else {
//兼容15、16功能码
if (modbusRtu.getCode() == ModbusCode.Write10.getCode()){
if (modbusRtu.getCode() == ModbusCode.Write10.getCode()) {
//计算:字节数=2*N;N为寄存器个数
modbusRtu.setBitCount(2 * modbusRtu.getCount());
}else if (modbusRtu.getCode() == ModbusCode.Write0F.getCode()){
} else if (modbusRtu.getCode() == ModbusCode.Write0F.getCode()) {
//计算:字节数=N/8 余数为0是 N需要再+1。N是线圈个数
int i = modbusRtu.getCount() / 8;
if (modbusRtu.getCount() % 8!= 0){
if (modbusRtu.getCount() % 8 != 0) {
i++;
}
modbusRtu.setBitCount(i);
@ -192,31 +192,33 @@ public class DeviceMessageServiceImpl implements IDeviceMessageService {
/**
* 变量读取
*
* @param readVO
*/
@Override
public void readVariableValue(VariableReadVO readVO){
public void readVariableValue(VariableReadVO readVO) {
String serialNumber = readVO.getSerialNumber();
assert !Objects.isNull(serialNumber) : "设备编号为空";
DeviceAndProtocol deviceAndProtocol = deviceService.selectProtocolBySerialNumber(serialNumber);
if (!(deviceAndProtocol.getProtocolCode().equals(FastBeeConstant.PROTOCOL.ModbusRtu) ||
deviceAndProtocol.getProtocolCode().equals(FastBeeConstant.PROTOCOL.ModbusTcp))) throw new ServiceException("非modbus协议请先配置主动采集协议");
deviceAndProtocol.getProtocolCode().equals(FastBeeConstant.PROTOCOL.ModbusTcp)))
throw new ServiceException("非modbus协议请先配置主动采集协议");
Long productId = deviceAndProtocol.getProductId();
//如果是子设备,则获取网关子设备的产品id和设备编号
Integer deviceType = deviceAndProtocol.getDeviceType();
if (deviceType == DeviceType.SUB_GATEWAY.getCode()){
if (deviceType == DeviceType.SUB_GATEWAY.getCode()) {
serialNumber = deviceAndProtocol.getGwSerialNumber();
productId = deviceAndProtocol.getGwProductId();
}
Integer type = readVO.getType();
type = Objects.isNull(type) ? 1 : type;
if (type == 1){
if (type == 1) {
//单个变量获取
String identifier = readVO.getIdentifier();
ThingsModelValueItem thingModels = itslCache.getSingleThingModels(deviceAndProtocol.getProductId(), identifier);
ModbusConfig config = thingModels.getConfig();
if (Objects.isNull(config)) throw new ServiceException("未配置modbus点位");
thingModels.getConfig().setModbusCode(ModbusUtils.getReadModbusCode(config.getType(),config.getIsReadonly()));
thingModels.getConfig().setModbusCode(ModbusUtils.getReadModbusCode(config.getType(), config.getIsReadonly()));
MQSendMessageBo messageBo = new MQSendMessageBo();
messageBo.setThingsModel(JSON.toJSONString(thingModels));
messageBo.setSerialNumber(readVO.getSerialNumber());
@ -235,15 +237,15 @@ public class DeviceMessageServiceImpl implements IDeviceMessageService {
modbusPollMsg.setCommandList(commandList);
DeviceStatusVO deviceStatusVO = deviceService.selectDeviceStatusAndTransportStatus(modbusPollMsg.getSerialNumber());
modbusPollMsg.setTransport(deviceStatusVO.getTransport());
if (deviceStatusVO.getStatus() != DeviceStatus.ONLINE.getType()){
log.info("设备:[{}],不在线",modbusPollMsg.getSerialNumber());
if (deviceStatusVO.getStatus() != DeviceStatus.ONLINE.getType()) {
log.info("设备:[{}],不在线", modbusPollMsg.getSerialNumber());
return;
}
ModbusPollJob job = new ModbusPollJob();
job.setPollMsg(modbusPollMsg);
job.setType(1);
MessageProducer.sendPropFetch(job);
}else {
} else {
//读取当前设备的所有变量,这里读取所有的,判断传递的设备是网关设备、网关子设备、直连设备
DeviceType code = DeviceType.transfer(deviceType);
List<ModbusJob> modbusJobList = modbusJobService.selectDevicesJobByDeviceType(code, readVO.getSerialNumber());

View File

@ -22,14 +22,14 @@ import com.fastbee.iot.data.service.IDataHandler;
import com.fastbee.iot.data.service.IDeviceReportMessageService;
import com.fastbee.iot.data.service.IFirmwareTaskDetailService;
import com.fastbee.iot.domain.FunctionLog;
import com.fastbee.iot.domain.Product;
import com.fastbee.iot.domain.ProductAuthorize;
import com.fastbee.iot.enums.DeviceType;
import com.fastbee.iot.model.DeviceStatusVO;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.service.IFunctionLogService;
import com.fastbee.iot.service.IProductService;
import com.fastbee.iot.service.IProductAuthorizeService;
import com.fastbee.iot.domain.ProductAuthorize;
import com.fastbee.iot.domain.Product;
import com.fastbee.iot.service.IProductService;
import com.fastbee.mq.producer.MessageProducer;
import com.fastbee.mqtt.manager.MqttRemoteManager;
import com.fastbee.mqtt.model.PushMessageBo;
@ -108,7 +108,7 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
handlerDeviceReply(reportMessage);
}
serialNumber = reportMessage.getSerialNumber() == null ? serialNumber : reportMessage.getSerialNumber();
productId = reportMessage.getProductId()== null ? productId : reportMessage.getProductId();
productId = reportMessage.getProductId() == null ? productId : reportMessage.getProductId();
reportMessage.setSerialNumber(serialNumber);
reportMessage.setProductId(productId);
reportMessage.setPlatformDate(bo.getPlatformDate());
@ -157,7 +157,6 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
}
/**
* 处理设备回调数据
*/
@ -199,9 +198,9 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
return;
}
int size = 256;
if ((int)data[0] == 1) {
if ((int) data[0] == 1) {
size = 512;
} else if ((int)data[0] == 2) {
} else if ((int) data[0] == 2) {
size = 1024;
}
otaTaskCache.setOtaCacheValue(bo.getSerialNumber(), "packageSize", String.valueOf(size), 5);
@ -299,6 +298,7 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
/**
* 处理设备回调信息,此处按照topic区分 prop上报和设备回调reply,
* 如果模组可订阅的topic有限,不能区分prop上报和reply,自行根据上报数据来区分
*
* @param message
*/
public void handlerDeviceReply(DeviceReport message) {
@ -310,13 +310,13 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
//从redis中获取messageId 流水号,获取下发记录
for (String fun : functionList) {
String[] split = fun.split(":");
if (split[0].equals(sources)){
if (split[0].equals(sources)) {
messageId = split[1];
}
redisCache.zRem(cacheKey,fun);
redisCache.zRem(cacheKey, fun);
}
FunctionLog functionLog = new FunctionLog();
switch (message.getProtocolCode()){
switch (message.getProtocolCode()) {
case FastBeeConstant.PROTOCOL.ModbusRtu:
case FastBeeConstant.PROTOCOL.ModbusToJsonHP:
case FastBeeConstant.PROTOCOL.ModbusRtuPak:
@ -340,13 +340,14 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
/**
* 同步设备状态
*
* @param
*/
private void synchDeviceStatus(String serialNumber){
private void synchDeviceStatus(String serialNumber) {
//如果有数据上报,但是数据库设备状态为离线,则进行同步
DeviceStatusVO deviceStatusVO = deviceService.selectDeviceStatusAndTransportStatus(serialNumber);
if (deviceStatusVO.getStatus() == DeviceStatus.OFFLINE.getType()
|| deviceStatusVO.getStatus() == DeviceStatus.UNACTIVATED.getType()){
|| deviceStatusVO.getStatus() == DeviceStatus.UNACTIVATED.getType()) {
DeviceStatusBo statusBo = new DeviceStatusBo();
statusBo.setStatus(DeviceStatus.ONLINE);
statusBo.setSerialNumber(deviceStatusVO.getSerialNumber());
@ -362,11 +363,11 @@ public class DeviceReportMessageServiceImpl implements IDeviceReportMessageServi
session.setConnected(true);
sessionStore.storeSession(deviceStatusVO.getSerialNumber(), session);
}
}else if (deviceStatusVO.getStatus() == DeviceStatus.ONLINE.getType() ){
if (deviceStatusVO.getDeviceType() == DeviceType.SUB_GATEWAY.getCode()){
} else if (deviceStatusVO.getStatus() == DeviceStatus.ONLINE.getType()) {
if (deviceStatusVO.getDeviceType() == DeviceType.SUB_GATEWAY.getCode()) {
//如果是在线,则更新session在线时间
Session session = sessionStore.getSession(deviceStatusVO.getSerialNumber());
if (session!= null) {
if (session != null) {
session.setLastAccessTime(DateUtils.getTimestamp());
sessionStore.storeSession(deviceStatusVO.getSerialNumber(), session);
}

View File

@ -34,10 +34,11 @@ public class DeviceTestHandler implements IDeviceTestService {
/**
* 处理数据调试信息
*
* @param testReportBo
*/
@Override
public void messageHandler(DeviceTestReportBo testReportBo){
public void messageHandler(DeviceTestReportBo testReportBo) {
boolean isReply = testReportBo.getIsReply();
Long productId = testReportBo.getProductId();
String serialNumber = testReportBo.getSerialNumber();
@ -49,7 +50,7 @@ public class DeviceTestHandler implements IDeviceTestService {
} else {
deviceMessage.setTopicName(TopicType.PROPERTY_POST.getTopicSuffix());
}
if (Objects.isNull(productId)){
if (Objects.isNull(productId)) {
DeviceAndProtocol protocol = deviceService.selectProtocolBySerialNumber(serialNumber);
productId = protocol.getProductId();
}
@ -58,7 +59,7 @@ public class DeviceTestHandler implements IDeviceTestService {
messageBo.setTopic(topicsUtils.buildTopic(productId, serialNumber.toUpperCase(), TopicType.WS_SERVICE_INVOKE));
JSONObject pushObj = new JSONObject();
pushObj.put("message", testReportBo.getThingsModelSimpleItem());
pushObj.put("sources",testReportBo.getSources());
pushObj.put("sources", testReportBo.getSources());
messageBo.setMessage(JSON.toJSONString(pushObj));
mqttRemoteManager.pushCommon(messageBo);
}

View File

@ -28,7 +28,7 @@ import java.util.Objects;
* @date 2024-08-18
*/
@Service
public class FirmwareTaskDetailServiceImpl extends ServiceImpl<FirmwareTaskDetailMapper,FirmwareTaskDetail> implements IFirmwareTaskDetailService {
public class FirmwareTaskDetailServiceImpl extends ServiceImpl<FirmwareTaskDetailMapper, FirmwareTaskDetail> implements IFirmwareTaskDetailService {
@Resource
private FirmwareTaskDetailMapper firmwareTaskDetailMapper;
@ -66,19 +66,21 @@ public class FirmwareTaskDetailServiceImpl extends ServiceImpl<FirmwareTaskDetai
/**
* 查询固件升级任务详细
*
* @param taskId
* @param serialNumber
* @return
*/
public FirmwareTaskDetail selectFirmwareTaskDetailByTaskIdAndSerialNumber(Long taskId, String serialNumber){
public FirmwareTaskDetail selectFirmwareTaskDetailByTaskIdAndSerialNumber(Long taskId, String serialNumber) {
LambdaQueryWrapper<FirmwareTaskDetail> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(FirmwareTaskDetail::getId,taskId);
wrapper.eq(FirmwareTaskDetail::getSerialNumber,serialNumber);
wrapper.eq(FirmwareTaskDetail::getId, taskId);
wrapper.eq(FirmwareTaskDetail::getSerialNumber, serialNumber);
return baseMapper.selectOne(wrapper);
}
/**
* 更新升级状态
*
* @param taskId
* @param serialNumber
* @param otaUpgrade
@ -97,6 +99,7 @@ public class FirmwareTaskDetailServiceImpl extends ServiceImpl<FirmwareTaskDetai
/**
* 根据固件id查询下属设备列表
*
* @param firmwareTaskDetailInput
* @return
*/
@ -108,8 +111,7 @@ public class FirmwareTaskDetailServiceImpl extends ServiceImpl<FirmwareTaskDetai
String statusCache = otaTaskCache.getOtaCacheValue(output.getSerialNumber(), "status");
if (output.getUpgradeStatus() == 1 && StringUtils.isNotEmpty(statusCache)) {
output.setProgress(Integer.parseInt(statusCache));
}
else if (output.getUpgradeStatus() == 2 || output.getUpgradeStatus() == 3) {
} else if (output.getUpgradeStatus() == 2 || output.getUpgradeStatus() == 3) {
output.setProgress(100);
} else {
output.setProgress(0);
@ -120,6 +122,7 @@ public class FirmwareTaskDetailServiceImpl extends ServiceImpl<FirmwareTaskDetai
/**
* 固件升级设备统计
*
* @param firmwareTaskDetailInput
* @return
*/

View File

@ -35,7 +35,7 @@ import java.util.Objects;
* @date 2024-08-18
*/
@Service
public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,FirmwareTask> implements IFirmwareTaskService {
public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper, FirmwareTask> implements IFirmwareTaskService {
@Resource
private FirmwareTaskMapper firmwareTaskMapper;
@ -47,7 +47,6 @@ public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,Firm
private IDeviceService deviceService;
/**
* 查询固件升级任务对象列表
*
@ -86,12 +85,11 @@ public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,Firm
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Long insertFirmwareTask(FirmwareTaskInput firmwareTaskInput)
{
public Long insertFirmwareTask(FirmwareTaskInput firmwareTaskInput) {
//先查询任务是否存在,根据任务名查询
int count = firmwareTaskMapper.selectCountFirmwareTaskByTaskName(firmwareTaskInput.getFirmwareId(), firmwareTaskInput.getTaskName());
if (count >0){
throw new ServiceException("任务:" + firmwareTaskInput.getTaskName() +"已存在");
if (count > 0) {
throw new ServiceException("任务:" + firmwareTaskInput.getTaskName() + "已存在");
}
List<String> deviceList;
if (1 == firmwareTaskInput.getUpgradeType()) {
@ -101,7 +99,7 @@ public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,Firm
deviceList = firmwareTaskInput.getDeviceList();
}
FirmwareTask firmwareTask = new FirmwareTask();
BeanUtils.copyBeanProp(firmwareTask,firmwareTaskInput);
BeanUtils.copyBeanProp(firmwareTask, firmwareTaskInput);
firmwareTask.setCreateTime(DateUtils.getNowDate());
// 插入固件升级任务主表
firmwareTaskMapper.insert(firmwareTask);
@ -118,7 +116,7 @@ public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,Firm
}
// 批量插入明细表
firmwareTaskDetailService.saveBatch(detailList);
if (taskId > 0){
if (taskId > 0) {
OtaUpgradeDelayTask otaTask = new OtaUpgradeDelayTask();
otaTask.setTaskId(taskId);
otaTask.setFirmwareId(firmwareTaskInput.getFirmwareId());
@ -132,13 +130,14 @@ public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,Firm
/**
* OTA升级
*
* @param task
*/
@Override
public void upgrade(OtaUpgradeDelayTask task){
public void upgrade(OtaUpgradeDelayTask task) {
// 判定是否是预定升级时间升级
if (null != task.getStartTime()){
if (DateUtils.getNowDate().after(task.getStartTime())){
if (null != task.getStartTime()) {
if (DateUtils.getNowDate().after(task.getStartTime())) {
throw new ServiceException(MessageUtils.message("firmware.task.upgrade.failed.time.not.valid"));
}
//预定升级的任务放到 延迟任务队列
@ -147,7 +146,7 @@ public class FirmwareTaskServiceImpl extends ServiceImpl<FirmwareTaskMapper,Firm
updatePo.setId(task.getTaskId());
updatePo.setBookTime(task.getStartTime());
baseMapper.updateById(updatePo);
}else {
} else {
otaUpgradeService.upgrade(task);
}
}

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