Merge branch 'dev-ruoyi-5.8.9'

This commit is contained in:
zhuangpeng.li
2025-04-28 10:44:57 +08:00
191 changed files with 26465 additions and 3057 deletions

View File

@@ -46,12 +46,7 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<!-- oauth2-->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
@@ -125,6 +120,29 @@
<artifactId>fastbee-ruleEngine</artifactId>
</dependency>
<!--引入DM8驱动-->
<dependency>
<groupId>com.dameng</groupId>
<artifactId>Dm8JdbcDriver18</artifactId>
<version>8.1.1.49</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.4.1.jre8</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.0</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,119 +0,0 @@
package com.fastbee.iot.oauth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import javax.sql.DataSource;
/**
* 授权服务器配置配置客户端id密钥和令牌的过期时间
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
/**
* 用来配置令牌端点(Token Endpoint)的安全约束
* @param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients()
.authenticationEntryPoint(new OAuth2AuthenticationEntryPoint());
}
/**
* 用来配置客户端详情服务
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(getClientDetailsService());
}
/**
* 用来配置授权authorization以及令牌token的访问端点和令牌服务(token services)。
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 查询用户、授权、分组,可以被重写
endpoints.userDetailsService(userDetailsService)
// 审批客户端的授权
.userApprovalHandler(userApprovalHandler())
// 授权审批
.approvalStore(approvalStore())
// 获取授权码
.authorizationCodeServices(new JdbcAuthorizationCodeServices(dataSource))
// 验证token
.authenticationManager(authenticationManager)
// 查询、保存、刷新token
.tokenStore(this.getJdbcTokenStore());
}
@Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(dataSource);
}
@Bean
public UserApprovalHandler userApprovalHandler() {
return new SpeakerApprovalHandler(getClientDetailsService(), approvalStore(), oAuth2RequestFactory());
}
@Bean
public JdbcClientDetailsService getClientDetailsService() {
JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
jdbcClientDetailsService.setPasswordEncoder(passwordEncoder());
return jdbcClientDetailsService;
}
@Bean
public OAuth2RequestFactory oAuth2RequestFactory() {
return new DefaultOAuth2RequestFactory(getClientDetailsService());
}
@Bean
public TokenStore getJdbcTokenStore(){
TokenStore tokenStore = new JdbcTokenStore(dataSource);
return tokenStore;
}
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}

View File

@@ -1,50 +0,0 @@
package com.fastbee.iot.oauth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import javax.sql.DataSource;
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
TokenStore tokenStore = jdbcTokenStore();
OAuth2AuthenticationManager auth2AuthenticationManager= new OAuth2AuthenticationManager();
resources.authenticationManager(auth2AuthenticationManager);
resources.resourceId("speaker-service").tokenStore(tokenStore).stateless(true);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// 限制资源服务器只接管匹配的资源
http.requestMatchers().antMatchers("/oauth/speaker/**")
.and()
//授权的请求
.authorizeRequests()
.anyRequest().authenticated()
//关闭跨站请求防护
.and()
.csrf().disable();
}
public TokenStore jdbcTokenStore(){
TokenStore tokenStore = new JdbcTokenStore(dataSource);
return tokenStore;
}
}

View File

@@ -1,83 +0,0 @@
package com.fastbee.iot.oauth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.approval.Approval;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.ApprovalStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import java.util.*;
/**
* kerwincui
*/
public class SpeakerApprovalHandler extends ApprovalStoreUserApprovalHandler {
private int approvalExpirySeconds = -1;
@Autowired
private ApprovalStore approvalStore;
public SpeakerApprovalHandler(JdbcClientDetailsService clientDetailsService, ApprovalStore approvalStore, OAuth2RequestFactory oAuth2RequestFactory) {
this.setApprovalStore(approvalStore);
this.setClientDetailsService(clientDetailsService);
this.setRequestFactory(oAuth2RequestFactory);
}
@Override
public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) {
// 获取授权过的范围
Set<String> requestedScopes = authorizationRequest.getScope();
Set<String> approvedScopes = new HashSet<String>();
Set<Approval> approvals = new HashSet<Approval>();
Date expiry = computeExpiry();
// 存储授权或拒绝的范围
Map<String, String> approvalParameters = authorizationRequest.getApprovalParameters();
for (String requestedScope : requestedScopes) {
String approvalParameter = OAuth2Utils.SCOPE_PREFIX + requestedScope;
String value = approvalParameters.get(approvalParameter);
value = value == null ? "" : value.toLowerCase();
if ("true".equals(value) || value.startsWith("approve")||value.equals("on")) {
approvedScopes.add(requestedScope);
approvals.add(new Approval(userAuthentication.getName(), authorizationRequest.getClientId(),
requestedScope, expiry, Approval.ApprovalStatus.APPROVED));
}
else {
approvals.add(new Approval(userAuthentication.getName(), authorizationRequest.getClientId(),
requestedScope, expiry, Approval.ApprovalStatus.DENIED));
}
}
approvalStore.addApprovals(approvals);
boolean approved;
authorizationRequest.setScope(approvedScopes);
if (approvedScopes.isEmpty() && !requestedScopes.isEmpty()) {
approved = false;
}
else {
approved = true;
}
authorizationRequest.setApproved(approved);
return authorizationRequest;
}
private Date computeExpiry() {
Calendar expiresAt = Calendar.getInstance();
// 默认一个月
if (approvalExpirySeconds == -1) {
expiresAt.add(Calendar.MONTH, 1);
}
else {
expiresAt.add(Calendar.SECOND, approvalExpirySeconds);
}
return expiresAt.getTime();
}
}

View File

@@ -1,49 +0,0 @@
package com.fastbee.iot.oauth.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.approval.Approval;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import java.security.Principal;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* kerwincui
*/
@Controller
@SessionAttributes("authorizationRequest")
public class ConfirmAccessController {
@Autowired
private JdbcClientDetailsService clientDetailsService;
@Autowired
private ApprovalStore approvalStore;
@RequestMapping("/oauth/confirm_access")
public String getAccessConfirmation(Map<String, Object> model, Principal principal ) {
AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest");
ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());
Map<String, String> scopes = new LinkedHashMap<String, String>();
for (String scope : clientAuth.getScope()) {
scopes.put(OAuth2Utils.SCOPE_PREFIX + scope, "false");
}
for (Approval approval : approvalStore.getApprovals(principal.getName(), client.getClientId())) {
if (clientAuth.getScope().contains(approval.getScope())) {
scopes.put(OAuth2Utils.SCOPE_PREFIX + approval.getScope(),
approval.getStatus() == Approval.ApprovalStatus.APPROVED ? "true" : "false");
}
}
model.put("auth_request", clientAuth);
model.put("client", client);
model.put("scopes", scopes);
return "oauth/access_confirmation";
}
}

View File

@@ -1,55 +0,0 @@
package com.fastbee.iot.oauth.api;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.domain.model.LoginBody;
import com.fastbee.common.utils.SecurityUtils;
import com.fastbee.framework.web.service.SysLoginService;
import com.fastbee.framework.web.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Controller
public class LoginController {
@Autowired
private TokenStore tokenStore;
@Autowired
private SysLoginService loginService;
@Autowired
private TokenService tokenService;
@RequestMapping("/oauth/login")
public String login() {
return "oauth/login";
}
@RequestMapping("/oauth/index")
public String index() {
return "oauth/index";
}
@GetMapping("/oauth/logout")
@ResponseBody
public String logout(@RequestHeader String Authorization) {
if (!Authorization.isEmpty()){
String token=Authorization.split(" ")[1];
OAuth2AccessToken auth2AccessToken = tokenStore.readAccessToken(token);
tokenStore.removeAccessToken(auth2AccessToken);
return "SUCCESS";
}else{
return "FAIL";
}
}
}

View File

@@ -1,33 +0,0 @@
package com.fastbee.iot.oauth.api;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* kerwincui
*/
@RestController
public class SpeakerController {
@GetMapping("/oauth/speaker/get")
public JSONObject getSpeaker() {
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
JSONObject Json = new JSONObject();
Json.put("1", "1");
Json.put("2", "2");
Json.put("3", "3");
System.out.println("调用了接口get");
return Json;
}
@PostMapping("/oauth/speaker/post")
public JSONObject postSpeaker() {
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
JSONObject bookJson = new JSONObject();
bookJson.put("1", "1");
System.out.println("调用了接口post");
return bookJson;
}
}

View File

@@ -144,10 +144,10 @@ public class ToolServiceImpl implements IToolService
{
msg = "密码长度必须在5到20个字符之间";
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser)))
else if (userService.checkUserNameUnique(sysUser))
{
msg = "保存用户'" + username + "'失败,注册账号已存在";
}else if (UserConstants.NOT_UNIQUE.equals(checkPhoneUnique(phonenumber)))
}else if (checkPhoneUnique(phonenumber))
{
msg = "保存用户'" + username + "'失败,注册手机号码已存在";
}
@@ -203,10 +203,10 @@ public class ToolServiceImpl implements IToolService
{
msg = "密码长度必须在5到20个字符之间";
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser)))
else if (userService.checkUserNameUnique(sysUser))
{
msg = "保存用户'" + username + "'失败,注册账号已存在";
}else if (UserConstants.NOT_UNIQUE.equals(checkPhoneUnique(phonenumber)))
}else if (checkPhoneUnique(phonenumber))
{
msg = "保存用户'" + username + "'失败,注册手机号码已存在";
}
@@ -252,7 +252,7 @@ public class ToolServiceImpl implements IToolService
* @param phonenumber 手机号码
* @return
*/
public String checkPhoneUnique(String phonenumber)
public boolean checkPhoneUnique(String phonenumber)
{
SysUser info = userMapper.checkPhoneUnique(phonenumber);
if (StringUtils.isNotNull(info))

View File

@@ -16,7 +16,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="deviceId" column="device_id" />
<result property="deviceName" column="device_name" />
<result property="serialNumber" column="serial_number" />
<result property="identity" column="identity" />
<result property="identity" column="identify" />
<result property="createBy" column="create_by" />
<result property="isMonitor" column="is_monitor" />
<result property="mode" column="mode" />
@@ -31,18 +31,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.fastbee.iot.model.HistoryModel" id="HistoryResult">
<result property="value" column="log_value" />
<result property="time" column="create_time" />
<result property="identity" column="identity" />
<result property="identity" column="identify" />
</resultMap>
<sql id="selectDeviceLogVo">
select log_id, log_type, log_value, device_id, device_name,serial_number, identity, create_by, is_monitor,mode, user_id, user_name, tenant_id, tenant_name, create_time, remark from iot_device_log
select log_id, log_type, log_value, device_id, device_name,serial_number, identify, create_by, is_monitor,mode, user_id, user_name, tenant_id, tenant_name, create_time, remark from iot_device_log
</sql>
<select id="selectMonitorList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="MonitorResult">
select log_value, create_time from iot_device_log
<where>
<if test="1==1"> and is_monitor=1</if>
<if test="identity != null and identity != ''"> and identity = #{identity}</if>
<if test="identity != null and identity != ''"> and identify = #{identity}</if>
<if test="deviceId != null and deviceId !=0"> and device_id = #{deviceId}</if>
<if test="serialNumber != null and serialNumber !=''"> and serial_number = #{serialNumber}</if>
<if test="beginTime != null and beginTime != '' and endTime != null and endTime != ''"> and create_time between #{beginTime} and #{endTime}</if>
@@ -91,12 +91,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="tenantId != null and tenantId != 0"> and tenant_id = #{tenantId}</if>
</where>
) as monitorCount
limit 1
</select>
<insert id="saveBatch" parameterType="com.fastbee.iot.domain.DeviceLog">
insert into iot_device_log (log_type,log_value,device_id,device_name,serial_number,identity,create_by,
insert into iot_device_log (log_type,log_value,device_id,device_name,serial_number,identify,create_by,
is_monitor,mode,create_time,remark,user_id,user_name,tenant_id,tenant_name,model_name)
values
<foreach collection="list" item="item" index="index" separator=",">
@@ -114,7 +114,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deviceId != null">device_id = #{deviceId},</if>
<if test="deviceName != null and deviceName != ''">device_name = #{deviceName},</if>
<if test="serialNumber != null and serialNumber != ''">serial_number = #{serialNumber},</if>
<if test="identity != null">identity = #{identity},</if>
<if test="identity != null">identify = #{identity},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="isMonitor != null">is_monitor = #{isMonitor},</if>
<if test="mode != null">mode = #{mode},</if>

View File

@@ -297,7 +297,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectDeviceProductAlertCount" parameterType="com.fastbee.iot.domain.Device" resultType="com.fastbee.iot.model.DeviceStatistic">
select
<!--设备数量-->
(select count(distinct d.device_id,d.user_id)
(select count(distinct concat(d.device_id, '|', d.tenant_id))
from iot_device d
inner join iot_device_user u on u.device_id = d.device_id
<where>
@@ -307,7 +307,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
) as deviceCount,
<!--在线设备数量-->
(select count(distinct d.device_id,d.user_id)
(select count(distinct concat(d.device_id, '|', d.tenant_id))
from iot_device d
inner join iot_device_user u on u.device_id = d.device_id
<where>
@@ -320,7 +320,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
(
<!--普通用户查询设备中的产品数量-->
<if test="userId != null and userId != 0">
select count(distinct product_id)
select count(product_id)
from iot_device
where user_id = #{userId}
</if>

View File

@@ -6,7 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.fastbee.iot.domain.EventLog" id="EventLogResult">
<result property="logId" column="log_id" />
<result property="identity" column="identity" />
<result property="identity" column="identify" />
<result property="modelName" column="model_name" />
<result property="logType" column="log_type" />
<result property="logValue" column="log_value" />
@@ -25,13 +25,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectEventLogVo">
select log_id, identity, model_name, log_type, log_value, device_id, device_name, serial_number, is_monitor, mode, user_id, user_name, tenant_id, tenant_name, create_by, create_time, remark from iot_event_log
select log_id, identify, model_name, log_type, log_value, device_id, device_name, serial_number, is_monitor, mode, user_id, user_name, tenant_id, tenant_name, create_by, create_time, remark from iot_event_log
</sql>
<select id="selectEventLogList" parameterType="com.fastbee.iot.domain.EventLog" resultMap="EventLogResult">
<include refid="selectEventLogVo"/>
<where>
<if test="identity != null and identity != ''"> and identity = #{identity}</if>
<if test="identity != null and identity != ''"> and identify = #{identity}</if>
<if test="modelName != null and modelName != ''"> and model_name like concat('%', #{modelName}, '%')</if>
<if test="logType != null "> and log_type = #{logType}</if>
<if test="logValue != null and logValue != ''"> and log_value = #{logValue}</if>
@@ -62,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertEventLog" parameterType="com.fastbee.iot.domain.EventLog" useGeneratedKeys="true" keyProperty="logId">
insert into iot_event_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="identity != null and identity != ''">identity,</if>
<if test="identity != null and identity != ''">identify,</if>
<if test="modelName != null">model_name,</if>
<if test="logType != null">log_type,</if>
<if test="logValue != null and logValue != ''">log_value,</if>
@@ -100,7 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</insert>
<insert id="insertBatch" parameterType="com.fastbee.iot.domain.EventLog">
insert into iot_event_log (identity,model_name,log_type,log_value,device_id,device_name,serial_number,is_monitor,mode,user_id,
insert into iot_event_log (identify,model_name,log_type,log_value,device_id,device_name,serial_number,is_monitor,mode,user_id,
user_name,tenant_id,tenant_name,create_by,create_time,remark)
values
<foreach collection="list" separator="," index="index" item="item">
@@ -112,7 +112,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="updateEventLog" parameterType="com.fastbee.iot.domain.EventLog">
update iot_event_log
<trim prefix="SET" suffixOverrides=",">
<if test="identity != null and identity != ''">identity = #{identity},</if>
<if test="identity != null and identity != ''">identify = #{identity},</if>
<if test="modelName != null">model_name = #{modelName},</if>
<if test="logType != null">log_type = #{logType},</if>
<if test="logValue != null and logValue != ''">log_value = #{logValue},</if>