From 67653cc2003e7fe16b60efa549cf0f9cee5aacab Mon Sep 17 00:00:00 2001 From: liejiu946 Date: Sun, 1 Feb 2026 18:10:37 +0800 Subject: [PATCH] =?UTF-8?q?opt:1.=E4=BF=AE=E5=A4=8D=E5=BC=95=E5=85=A5EasyC?= =?UTF-8?q?aptchaBoot=E5=AF=BC=E8=87=B4=E7=9A=84web=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E3=80=822.=E6=B7=BB=E5=8A=A0=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E7=AE=A1=E7=90=86=E7=B3=BB=E7=BB=9F=E8=BD=A6=E8=BE=86?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E3=80=81=E4=BA=8C=E7=BB=B4=E7=A0=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nl-business-sys/pom.xml | 10 +- .../controller/AnomalyInfoController.java | 3 +- .../param/QueryErrorInfoPageParam.java | 9 +- .../security/satoken/RedisListenerConfig.java | 44 +++---- .../security/satoken/SaTokenConfigure.java | 56 ++++----- .../security/satoken/StpInterfaceImpl.java | 76 ++++++------- .../security/service/UserCacheClean.java | 67 ++++++----- .../config/ElPermissionConfig.java | 66 +++++------ .../config/saconfig/LoginUserHandler.java | 48 ++++---- .../config/saconfig/SaInitCOnfig.java | 66 +++++------ .../qrcode/controller/QRCodeController.java | 25 +++- .../nl/sys/modular/qrcode/dao/QRcodeInfo.java | 15 +++ .../qrcode/param/GenerateQRCodeParam.java | 9 +- .../qrcode/param/QueryQRCodeParam.java | 29 +++++ .../qrcode/param/UpdateQRCodeParam.java | 51 +++++++++ .../modular/qrcode/service/QRCodeService.java | 31 +++++ .../service/impl/QRCodeServiceImpl.java | 107 ++++++++++++++++-- .../src/main/java/org/nl/util/QRCodeUtil.java | 20 +++- .../src/main/java/org/nl/Application.java | 4 +- .../main/resources/config/application-dev.yml | 2 +- .../src/main/resources/config/application.yml | 6 +- 21 files changed, 505 insertions(+), 239 deletions(-) create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/QueryQRCodeParam.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/UpdateQRCodeParam.java diff --git a/nl-business-sys/pom.xml b/nl-business-sys/pom.xml index c723a3e..f5d5594 100644 --- a/nl-business-sys/pom.xml +++ b/nl-business-sys/pom.xml @@ -45,11 +45,11 @@ captcha-spring-boot-starter - - - - - + + + nl.basjes.parse.useragent + yauaa + diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/controller/AnomalyInfoController.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/controller/AnomalyInfoController.java index 29a6cd4..cb407d7 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/controller/AnomalyInfoController.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/controller/AnomalyInfoController.java @@ -16,6 +16,7 @@ import org.nl.util.FileConstant; import org.nl.util.ParseZip; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -119,7 +120,7 @@ public class AnomalyInfoController { @PostMapping("/queryErrorInfos") @Log("分页查询异常信息") - public ResponseEntity queryErrorInfos(@RequestBody QueryErrorInfoPageParam param) { + public ResponseEntity queryErrorInfos(@Validated @RequestBody QueryErrorInfoPageParam param) { return new ResponseEntity<>(errorInfoService.queryErrorInfoPage(param), HttpStatus.OK); } diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/param/QueryErrorInfoPageParam.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/param/QueryErrorInfoPageParam.java index 818986c..a699cae 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/param/QueryErrorInfoPageParam.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/param/QueryErrorInfoPageParam.java @@ -1,6 +1,7 @@ package org.nl.sys.modular.anomalyInfo.param; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; /** @@ -13,14 +14,14 @@ public class QueryErrorInfoPageParam { /** * 当前页 */ - @NotBlank(message = "当前页不能为空") - private int pageNum; + @NotNull(message = "当前页不能为空") + private Integer pageNum; /** * 页大小 */ - @NotBlank(message = "页大小不能为空") - private int pageSize; + @NotNull(message = "页大小不能为空") + private Integer pageSize; /** * 异常信息编码 diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/RedisListenerConfig.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/RedisListenerConfig.java index 5513f80..3564678 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/RedisListenerConfig.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/RedisListenerConfig.java @@ -1,22 +1,22 @@ -//package org.nl.sys.modular.backgroundmanagement.common.security.satoken; -// -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.data.redis.connection.RedisConnectionFactory; -//import org.springframework.data.redis.listener.RedisMessageListenerContainer; -// -///** -// * @author: lyd -// * @description: redis监听配置 -// * @Date: 2022/10/8 -// */ -//@Configuration -//public class RedisListenerConfig { -// -//// @Bean -//// RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { -//// RedisMessageListenerContainer container = new RedisMessageListenerContainer(); -//// container.setConnectionFactory(connectionFactory); -//// return container; -//// } -//} +package org.nl.sys.modular.backgroundmanagement.common.security.satoken; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; + +/** + * @author: lyd + * @description: redis监听配置 + * @Date: 2022/10/8 + */ +@Configuration +public class RedisListenerConfig { + +// @Bean +// RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { +// RedisMessageListenerContainer container = new RedisMessageListenerContainer(); +// container.setConnectionFactory(connectionFactory); +// return container; +// } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/SaTokenConfigure.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/SaTokenConfigure.java index 2e7bd1c..4330658 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/SaTokenConfigure.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/SaTokenConfigure.java @@ -1,28 +1,28 @@ -//package org.nl.sys.modular.backgroundmanagement.common.security.satoken; -// -//import cn.dev33.satoken.interceptor.SaInterceptor; -//import cn.dev33.satoken.jwt.StpLogicJwtForSimple; -//import cn.dev33.satoken.stp.StpLogic; -//import cn.dev33.satoken.stp.StpUtil; -//import lombok.extern.slf4j.Slf4j; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -// -///** -// * @author: lyd -// * @description: sa-token的配置路由拦截 -// * @Date: 2022-09-20 -// */ -//@Slf4j -//@Configuration -//public class SaTokenConfigure implements WebMvcConfigurer { -// -// // Sa-Token 整合 jwt (Simple 简单模式) -// @Bean -// public StpLogic getStpLogicJwt() { -// return new StpLogicJwtForSimple(); -// } -//} +package org.nl.sys.modular.backgroundmanagement.common.security.satoken; + +import cn.dev33.satoken.interceptor.SaInterceptor; +import cn.dev33.satoken.jwt.StpLogicJwtForSimple; +import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.stp.StpUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @author: lyd + * @description: sa-token的配置路由拦截 + * @Date: 2022-09-20 + */ +@Slf4j +@Configuration +public class SaTokenConfigure implements WebMvcConfigurer { + + // Sa-Token 整合 jwt (Simple 简单模式) + @Bean + public StpLogic getStpLogicJwt() { + return new StpLogicJwtForSimple(); + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/StpInterfaceImpl.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/StpInterfaceImpl.java index 7cacad8..dc418c4 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/StpInterfaceImpl.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/satoken/StpInterfaceImpl.java @@ -1,38 +1,38 @@ -//package org.nl.sys.modular.backgroundmanagement.common.security.satoken; -// -//import cn.dev33.satoken.stp.StpInterface; -//import org.nl.sys.modular.backgroundmanagement.common.util.SecurityUtils; -//import org.springframework.stereotype.Component; -// -//import java.util.List; -// -///** -// * @author: lyd -// * @description: stp接口impl 自定义权限验证接口扩展 保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展 -// * @Date: 2022-09-20 -// */ -//@Component -//public class StpInterfaceImpl implements StpInterface { -// -// /** -// * 用户权限获取 -// * @param o login存入的值,此处存放用户id -// * @param s -// * @return -// */ -// @Override -// public List getPermissionList(Object o, String s) { -// return SecurityUtils.getCurrentUserPermissions(); -// } -// -// /** -// * 角色权限获取 - 数据库没有设计角色code,因此不推荐使用角色鉴权 -// * @param o -// * @param s -// * @return -// */ -// @Override -// public List getRoleList(Object o, String s) { -// return null; -// } -//} +package org.nl.sys.modular.backgroundmanagement.common.security.satoken; + +import cn.dev33.satoken.stp.StpInterface; +import org.nl.sys.modular.backgroundmanagement.common.util.SecurityUtils; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author: lyd + * @description: stp接口impl 自定义权限验证接口扩展 保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展 + * @Date: 2022-09-20 + */ +@Component +public class StpInterfaceImpl implements StpInterface { + + /** + * 用户权限获取 + * @param o login存入的值,此处存放用户id + * @param s + * @return + */ + @Override + public List getPermissionList(Object o, String s) { + return SecurityUtils.getCurrentUserPermissions(); + } + + /** + * 角色权限获取 - 数据库没有设计角色code,因此不推荐使用角色鉴权 + * @param o + * @param s + * @return + */ + @Override + public List getRoleList(Object o, String s) { + return null; + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/service/UserCacheClean.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/service/UserCacheClean.java index 8b3b83e..161daa9 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/service/UserCacheClean.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/common/security/service/UserCacheClean.java @@ -1,4 +1,5 @@ -package org.nl.sys.modular.backgroundmanagement.common.security.service;///* +package org.nl.sys.modular.backgroundmanagement.common.security.service; +//* // * Copyright 2019-2020 the original author or authors. // * // * Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,37 +14,35 @@ package org.nl.sys.modular.backgroundmanagement.common.security.service;///* // * See the License for the specific language governing permissions and // * limitations under the License. // */ -// -//package org.nl.common.security.service; -// -//import cn.hutool.core.util.StrUtil; -//import org.springframework.stereotype.Component; -// -///** -// * @author: liaojinlong -// * @date: 2020/6/11 18:01 -// * @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类 -// */ -//@Component -//public class UserCacheClean { -// -// /** -// * 清理特定用户缓存信息
-// * 用户信息变更时 -// * -// * @param userName / -// */ -// public void cleanUserCache(String userName) { -// if (StrUtil.isNotEmpty(userName)) { -//// UserDetailsServiceImpl.userDtoCache.remove(userName); -// } + +import cn.hutool.core.util.StrUtil; +import org.springframework.stereotype.Component; + +/** + * @author: liaojinlong + * @date: 2020/6/11 18:01 + * @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类 + */ +@Component +public class UserCacheClean { + + /** + * 清理特定用户缓存信息
+ * 用户信息变更时 + * + * @param userName / + */ + public void cleanUserCache(String userName) { + if (StrUtil.isNotEmpty(userName)) { +// UserDetailsServiceImpl.userDtoCache.remove(userName); + } + } + + /** + * 清理所有用户的缓存信息
+ * ,如发生角色授权信息变化,可以简便的全部失效缓存 + */ +// public void cleanAll() { +// UserDetailsServiceImpl.userDtoCache.clear(); // } -// -// /** -// * 清理所有用户的缓存信息
-// * ,如发生角色授权信息变化,可以简便的全部失效缓存 -// */ -//// public void cleanAll() { -//// UserDetailsServiceImpl.userDtoCache.clear(); -//// } -//} +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/ElPermissionConfig.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/ElPermissionConfig.java index 9000dcf..6061d21 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/ElPermissionConfig.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/ElPermissionConfig.java @@ -1,33 +1,33 @@ -///* -// * Copyright 2019-2020 Zheng Jie -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -//package org.nl.sys.modular.backgroundmanagement.config; -// -//import org.springframework.stereotype.Service; -// -///** -// * @author Zheng Jie -// */ -//@Service(value = "el") -//public class ElPermissionConfig { -// -// public Boolean check(String ...permissions){ -// // 获取当前用户的所有权限 -//// List elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); -// // 判断当前用户的所有权限是否包含接口上定义的权限 -//// return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains); -// return true; -// } -//} +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.nl.sys.modular.backgroundmanagement.config; + +import org.springframework.stereotype.Service; + +/** + * @author Zheng Jie + */ +@Service(value = "el") +public class ElPermissionConfig { + + public Boolean check(String ...permissions){ + // 获取当前用户的所有权限 +// List elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); + // 判断当前用户的所有权限是否包含接口上定义的权限 +// return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains); + return true; + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/LoginUserHandler.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/LoginUserHandler.java index 0209e7d..905e347 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/LoginUserHandler.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/LoginUserHandler.java @@ -1,24 +1,24 @@ -//package org.nl.sys.modular.backgroundmanagement.config.saconfig; -// -//import cn.dev33.satoken.stp.StpUtil; -//import cn.dev33.satoken.util.SaResult; -//import org.springframework.stereotype.Component; -// -//import java.util.function.BiFunction; -// -///* -// * @author ZZQ -// * @Date 2022/11/24 3:47 下午 -// */ -//@Component -//public class LoginUserHandler implements BiFunction { -// @Override -// public Object apply(String user, String password) { -// //用户登入账号密码查询: -// StpUtil.login(Long.valueOf(password)); -// -// return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue()); -// -// } -// -//} +package org.nl.sys.modular.backgroundmanagement.config.saconfig; + +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; +import org.springframework.stereotype.Component; + +import java.util.function.BiFunction; + +/* + * @author ZZQ + * @Date 2022/11/24 3:47 下午 + */ +@Component +public class LoginUserHandler implements BiFunction { + @Override + public Object apply(String user, String password) { + //用户登入账号密码查询: + StpUtil.login(Long.valueOf(password)); + + return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue()); + + } + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/SaInitCOnfig.java b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/SaInitCOnfig.java index de44ad2..3609c77 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/SaInitCOnfig.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/backgroundmanagement/config/saconfig/SaInitCOnfig.java @@ -1,33 +1,33 @@ -//package org.nl.sys.modular.backgroundmanagement.config.saconfig; -// -//import cn.dev33.satoken.config.SaSsoConfig; -//import cn.hutool.http.HttpRequest; -//import cn.hutool.http.HttpResponse; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.web.servlet.ModelAndView; -// -///* -// * @author ZZQ -// * @Date 2022/11/28 10:58 上午 -// */ -//@Configuration -//public class SaInitCOnfig { -// -// @Autowired -// LoginUserHandler loginUserHandler; -// -// @Autowired -// public void configSso(SaSsoConfig sso) { -// System.out.println("启动初始化-----SaSsoConfig"); -// // 配置:未登录时返回的View -// sso.setNotLoginView(() -> new ModelAndView("sa-login")); -// // 配置:登录处理函数 -// sso.setDoLoginHandle(loginUserHandler); -// -// sso.setSendHttp(s -> { -// HttpResponse execute = HttpRequest.get(s).execute(); -// return execute.body(); -// }); -// } -//} +package org.nl.sys.modular.backgroundmanagement.config.saconfig; + +import cn.dev33.satoken.config.SaSsoConfig; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ModelAndView; + +/* + * @author ZZQ + * @Date 2022/11/28 10:58 上午 + */ +@Configuration +public class SaInitCOnfig { + + @Autowired + LoginUserHandler loginUserHandler; + + @Autowired + public void configSso(SaSsoConfig sso) { + System.out.println("启动初始化-----SaSsoConfig"); + // 配置:未登录时返回的View + sso.setNotLoginView(() -> new ModelAndView("sa-login")); + // 配置:登录处理函数 + sso.setDoLoginHandle(loginUserHandler); + + sso.setSendHttp(s -> { + HttpResponse execute = HttpRequest.get(s).execute(); + return execute.body(); + }); + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/controller/QRCodeController.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/controller/QRCodeController.java index b374120..3dbd3e6 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/controller/QRCodeController.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/controller/QRCodeController.java @@ -1,12 +1,17 @@ package org.nl.sys.modular.qrcode.controller; +import cn.dev33.satoken.annotation.SaIgnore; import jakarta.annotation.Resource; import org.nl.api.task.core.TaskRequestParam; import org.nl.logging.annotation.Log; +import org.nl.sys.modular.qrcode.dao.QRcodeInfo; import org.nl.sys.modular.qrcode.param.GenerateQRCodeParam; +import org.nl.sys.modular.qrcode.param.QueryQRCodeParam; +import org.nl.sys.modular.qrcode.param.UpdateQRCodeParam; import org.nl.sys.modular.qrcode.service.QRCodeService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; /** @@ -22,10 +27,28 @@ public class QRCodeController { @PostMapping("/generateQRCode") @Log("生成二维码") - public ResponseEntity generateQRCode(@RequestBody GenerateQRCodeParam generateQRCodeParam){ + public ResponseEntity generateQRCode(@Validated @RequestBody GenerateQRCodeParam generateQRCodeParam){ return new ResponseEntity<>(qrCodeService.generateQRCode(generateQRCodeParam), HttpStatus.OK); } + @PostMapping("/queryQRCodeInfoList") + @Log("查询二维码信息列表") + public ResponseEntity queryQRCodeInfoList(@Validated @RequestBody QueryQRCodeParam param){ + return new ResponseEntity<>(qrCodeService.queryQRCodeInfoList(param), HttpStatus.OK); + } + + @PostMapping("/updateQRCodeInfo") + @Log("修改二维码信息") + public ResponseEntity updateQRCodeInfo(@Validated @RequestBody UpdateQRCodeParam param){ + return new ResponseEntity<>(qrCodeService.updateQRCodeInfo(param), HttpStatus.OK); + } + + @PostMapping("/deleteQRCodeInfo") + @Log("删除二维码信息") + public ResponseEntity deleteQRCodeInfo(@RequestBody QRcodeInfo qRcodeInfo){ + return new ResponseEntity<>(qrCodeService.deleteQRCodeInfo(qRcodeInfo), HttpStatus.OK); + } + @GetMapping("/queryTaskInfoByRoom") @Log("获取当前队列信息") public ResponseEntity queryTaskInfoByRoom(@RequestParam String room){ diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/dao/QRcodeInfo.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/dao/QRcodeInfo.java index 896046b..9f358f5 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/dao/QRcodeInfo.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/dao/QRcodeInfo.java @@ -28,6 +28,21 @@ public class QRcodeInfo { */ private String room_code; + /** + * 二维码内容 + */ + private String qrcode_data; + + /** + * 二维码宽度(像素) + */ + private Integer qrcode_width; + + /** + * 二维码高度(像素) + */ + private Integer qrcode_height; + /** * 二维码地址 */ diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/GenerateQRCodeParam.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/GenerateQRCodeParam.java index 7a20750..d5d98d4 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/GenerateQRCodeParam.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/GenerateQRCodeParam.java @@ -1,6 +1,7 @@ package org.nl.sys.modular.qrcode.param; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; /** @@ -25,12 +26,12 @@ public class GenerateQRCodeParam { /** * 二维码宽度(像素) */ - @NotBlank(message = "二维码宽度不能为空") - private int width; + @NotNull(message = "二维码宽度不能为空") + private Integer width; /** * 二维码高度(像素) */ - @NotBlank(message = "二维码高度不能为空") - private int height; + @NotNull(message = "二维码高度不能为空") + private Integer height; } diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/QueryQRCodeParam.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/QueryQRCodeParam.java new file mode 100644 index 0000000..b8387ed --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/QueryQRCodeParam.java @@ -0,0 +1,29 @@ +package org.nl.sys.modular.qrcode.param; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author dsh + * 2026/2/1 + */ +@Data +public class QueryQRCodeParam { + /** + * 当前页 + */ + @NotNull(message = "当前页不能为空") + private Integer pageNum; + + /** + * 页大小 + */ + @NotNull(message = "页大小不能为空") + private Integer pageSize; + + /** + * 房间编号 + */ + private String room_code; +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/UpdateQRCodeParam.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/UpdateQRCodeParam.java new file mode 100644 index 0000000..87c420d --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/param/UpdateQRCodeParam.java @@ -0,0 +1,51 @@ +package org.nl.sys.modular.qrcode.param; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author dsh + * 2026/2/1 + */ +@Data +public class UpdateQRCodeParam { + + /** + * 二维码标识 + */ + @NotBlank(message = "二维码标识不能为空") + private String qrcode_id; + + /** + * 修改之前的房间号 + */ + @NotBlank(message = "修改之前的房间号不能为空") + private String oldRoom; + + /** + * 修改之后的房间号 + */ + @NotBlank(message = "修改之后的房间号不能为空") + private String newRoom; + + /** + * 二维码内容 + */ + @NotBlank(message = "二维码内容不能为空") + private String qrcode_data; + + /** + * 二维码宽度(像素) + */ + @NotNull(message = "二维码宽度不能为空") + private Integer qrcode_width; + + /** + * 二维码高度(像素) + */ + @NotNull(message = "二维码高度不能为空") + private Integer qrcode_height; + + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/QRCodeService.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/QRCodeService.java index a3b5b6c..84867b3 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/QRCodeService.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/QRCodeService.java @@ -2,7 +2,10 @@ package org.nl.sys.modular.qrcode.service; import org.nl.api.task.core.TaskRequestParam; import org.nl.response.WebResponse; +import org.nl.sys.modular.qrcode.dao.QRcodeInfo; import org.nl.sys.modular.qrcode.param.GenerateQRCodeParam; +import org.nl.sys.modular.qrcode.param.QueryQRCodeParam; +import org.nl.sys.modular.qrcode.param.UpdateQRCodeParam; /** * @author dsh @@ -17,6 +20,27 @@ public interface QRCodeService { */ WebResponse generateQRCode(GenerateQRCodeParam generateQRCodeParam); + /** + * 查询二维码信息列表 + * @param queryQRCodeParam + * @return + */ + WebResponse queryQRCodeInfoList(QueryQRCodeParam queryQRCodeParam); + + /** + * 修改二维码信息 + * @param param + * @return + */ + WebResponse updateQRCodeInfo(UpdateQRCodeParam param); + + /** + * 删除二维码信息 + * @param qRcodeInfo + * @return + */ + WebResponse deleteQRCodeInfo(QRcodeInfo qRcodeInfo); + /** * 二维码创建任务 * @param qrCodeTaskRequestParam @@ -43,4 +67,11 @@ public interface QRCodeService { * @return */ WebResponse taskOperationConfirm(String taskCode); + + /** + * 检验该房间是否已经存在二维码 + * @param room + * @return + */ + boolean verifyQRCodeByRoom(String room); } diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/impl/QRCodeServiceImpl.java b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/impl/QRCodeServiceImpl.java index 09e0cd6..204a766 100644 --- a/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/impl/QRCodeServiceImpl.java +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/qrcode/service/impl/QRCodeServiceImpl.java @@ -1,17 +1,24 @@ package org.nl.sys.modular.qrcode.service.impl; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import jakarta.annotation.Resource; import org.nl.api.task.api.TaskAPI; import org.nl.api.task.core.TaskRequestParam; import org.nl.enums.TaskSourceEnum; import org.nl.exception.BadRequestException; import org.nl.response.WebResponse; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; import org.nl.sys.modular.qrcode.dao.QRcodeInfo; import org.nl.sys.modular.qrcode.mapper.QRcodeInfoMapper; import org.nl.sys.modular.qrcode.param.GenerateQRCodeParam; +import org.nl.sys.modular.qrcode.param.QueryQRCodeParam; +import org.nl.sys.modular.qrcode.param.UpdateQRCodeParam; import org.nl.sys.modular.qrcode.service.QRCodeService; import org.nl.util.FileProperties; import org.nl.util.IdUtil; @@ -36,24 +43,38 @@ public class QRCodeServiceImpl implements QRCodeService { @Override public WebResponse generateQRCode(GenerateQRCodeParam param) { + if (StrUtil.isBlank(param.getData())){ + throw new BadRequestException("二维码内容不能为空"); + } + if (StrUtil.isBlank(param.getRoom())){ + throw new BadRequestException("二维码房间号不能为空"); + } + //二维码高宽如果为空 默认150像素 + int qrcodeWidth = ObjectUtil.isNotEmpty(param.getWidth()) ? param.getWidth() : 150; + int qrcodeHeight = ObjectUtil.isNotEmpty(param.getHeight()) ? param.getHeight() : 150; + //本地地址 + String localAddress = fileProperties.getPath().getQrcode(); + //文件名称 + String fileName = param.getRoom() + ".png"; //result 返回文件大小 - String result = QRCodeUtil.generateQRCode(param.getData(), param.getWidth(), - param.getHeight(),fileProperties.getPath().getQrcode(),param.getRoom()+".png"); + String result = QRCodeUtil.generateQRCode(param.getData(), qrcodeWidth, + qrcodeHeight,localAddress,fileName); if (StrUtil.isBlank(result)){ throw new BadRequestException("生成二维码失败"); } - - boolean exists = qrcodeInfoMapper.selectCount(new LambdaQueryWrapper<>(QRcodeInfo.class) - .eq(QRcodeInfo::getRoom_code,param.getRoom()) - )>0; + // 检验该房间是否已经存在二维码 + boolean exists = this.verifyQRCodeByRoom(param.getRoom()); if (exists){ throw new BadRequestException("该房间已存在二维码,无法继续生成"); } QRcodeInfo qrcodeInfo = new QRcodeInfo(); qrcodeInfo.setQrcode_id(IdUtil.getStringId()); - qrcodeInfo.setFile_name(param.getRoom()+".png"); + qrcodeInfo.setFile_name(fileName); qrcodeInfo.setRoom_code(param.getRoom()); - qrcodeInfo.setFile_address("/qrcode/"+param.getRoom()+".png"); + qrcodeInfo.setQrcode_data(param.getData()); + qrcodeInfo.setQrcode_width(qrcodeWidth); + qrcodeInfo.setQrcode_height(qrcodeHeight); + qrcodeInfo.setFile_address("/qrcode/"+fileName); qrcodeInfo.setFile_size(result); qrcodeInfo.setCreate_time(DateUtil.now()); @@ -61,6 +82,66 @@ public class QRCodeServiceImpl implements QRCodeService { return WebResponse.requestOk(); } + @Override + public WebResponse queryQRCodeInfoList(QueryQRCodeParam param) { + Page page = new Page<>(param.getPageNum(), param.getPageSize()); + IPage infoPage = qrcodeInfoMapper.selectPage(page,new LambdaQueryWrapper<>(QRcodeInfo.class) + .like(StrUtil.isNotBlank(param.getRoom_code()),QRcodeInfo::getRoom_code,param.getRoom_code()) + ); + return WebResponse.requestParamOk(infoPage); + } + + @Override + public WebResponse updateQRCodeInfo(UpdateQRCodeParam param) { + //房间号变更后进行校验 + if (!param.getOldRoom().equals(param.getNewRoom())){ + // 检验该房间是否已经存在二维码 + boolean exists = this.verifyQRCodeByRoom(param.getNewRoom()); + if (exists){ + throw new BadRequestException("该房间已存在二维码,无法修改"); + } + } + String fileName = param.getNewRoom() + ".png"; + //result 返回文件大小 + String fileSizeKB = QRCodeUtil.generateQRCode(param.getQrcode_data(), param.getQrcode_width(), + param.getQrcode_height(),fileProperties.getPath().getQrcode(),fileName); + if (StrUtil.isBlank(fileSizeKB)){ + throw new BadRequestException("生成二维码失败"); + } + //更新二维码信息 + boolean result = qrcodeInfoMapper.update(null,new LambdaUpdateWrapper<>(QRcodeInfo.class) + .set(QRcodeInfo::getRoom_code,param.getNewRoom()) + .set(QRcodeInfo::getQrcode_data,param.getQrcode_data()) + .set(QRcodeInfo::getUpdate_time,DateUtil.now()) + .set(QRcodeInfo::getFile_name,fileName) + .set(QRcodeInfo::getFile_size,fileSizeKB) + .set(QRcodeInfo::getFile_address,"/qrcode/"+fileName) + .set(QRcodeInfo::getQrcode_width,param.getQrcode_width()) + .set(QRcodeInfo::getQrcode_height,param.getQrcode_height()) + .eq(QRcodeInfo::getQrcode_id,param.getQrcode_id()) + ) > 0; + if (!result){ + throw new BadRequestException("修改二维码信息失败"); + } + return WebResponse.requestOk(); + } + + @Override + public WebResponse deleteQRCodeInfo(QRcodeInfo qRcodeInfo) { + if (StrUtil.isBlank(qRcodeInfo.getQrcode_id())){ + throw new BadRequestException("二维码标识不能为空"); + } + boolean deleteResult = QRCodeUtil.deleteQRCode(fileProperties.getPath().getQrcode(),qRcodeInfo.getFile_name()); + if (!deleteResult){ + throw new BadRequestException("删除二维码文件失败"); + } + boolean result = qrcodeInfoMapper.deleteById(qRcodeInfo.getQrcode_id())>0; + if (!result){ + throw new BadRequestException("删除二维码失败"); + } + return WebResponse.requestOk(); + } + @Override public WebResponse createTask(TaskRequestParam qrCodeTaskRequestParam) { taskAPI.createTask(qrCodeTaskRequestParam, TaskSourceEnum.QRCODE.getName()); @@ -81,4 +162,14 @@ public class QRCodeServiceImpl implements QRCodeService { public WebResponse taskOperationConfirm(String taskCode) { return taskAPI.taskOperationConfirm(taskCode); } + + @Override + public boolean verifyQRCodeByRoom(String room) { + if (StrUtil.isBlank(room)){ + throw new BadRequestException("房间号不能为空"); + } + return qrcodeInfoMapper.selectCount(new LambdaQueryWrapper<>(QRcodeInfo.class) + .eq(QRcodeInfo::getRoom_code,room) + )>0; + } } diff --git a/nl-common/src/main/java/org/nl/util/QRCodeUtil.java b/nl-common/src/main/java/org/nl/util/QRCodeUtil.java index 08df5a6..f9cab1d 100644 --- a/nl-common/src/main/java/org/nl/util/QRCodeUtil.java +++ b/nl-common/src/main/java/org/nl/util/QRCodeUtil.java @@ -10,7 +10,9 @@ import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; -import java.text.DecimalFormat; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; @@ -75,4 +77,20 @@ public class QRCodeUtil { return null; } } + + public static boolean deleteQRCode(String filePath,String fileName) { + try { + Path path = Paths.get(filePath).resolve(fileName).normalize(); + boolean deleted = Files.deleteIfExists(path); + if (deleted) { + log.info("文件删除成功: {}", fileName); + } else { + log.warn("文件不存在: {}", fileName); + } + return true; + } catch (Exception e) { + log.info("删除二维码文件失败:{}", e.getMessage()); + return false; + } + } } diff --git a/nl-web-app/src/main/java/org/nl/Application.java b/nl-web-app/src/main/java/org/nl/Application.java index 9c543da..6ebb7fc 100644 --- a/nl-web-app/src/main/java/org/nl/Application.java +++ b/nl-web-app/src/main/java/org/nl/Application.java @@ -34,7 +34,9 @@ import org.springframework.web.bind.annotation.RestController; */ @Slf4j @RestController -@SpringBootApplication +@SpringBootApplication(exclude = { + io.github.eternalstone.captcha.autoconfig.EasyCaptchaAutoConfiguration.class +}) @EnableScheduling @EnableTransactionManagement @EnableMethodCache(basePackages = "org.nl") diff --git a/nl-web-app/src/main/resources/config/application-dev.yml b/nl-web-app/src/main/resources/config/application-dev.yml index d96c471..c5a2db6 100644 --- a/nl-web-app/src/main/resources/config/application-dev.yml +++ b/nl-web-app/src/main/resources/config/application-dev.yml @@ -82,7 +82,7 @@ file: qrcode: /home/eladmin/qrcode/ avatar: /home/eladmin/avatar/ windows: - path: C:\eladmin\file\currentMap\ + path: C:\eladmin\file\ qrcode: C:\eladmin\qrcode\ avatar: C:\eladmin\avatar\ # 文件大小 /M diff --git a/nl-web-app/src/main/resources/config/application.yml b/nl-web-app/src/main/resources/config/application.yml index 2bb8f68..172fdc0 100644 --- a/nl-web-app/src/main/resources/config/application.yml +++ b/nl-web-app/src/main/resources/config/application.yml @@ -38,7 +38,11 @@ security: excludes: # 认证 - /auth/login - # apt屏幕操作 + - /auth/code + - /auth/logout + - /sys-user-do/** + # frobot屏幕操作 + - /schedule/vehicle/** - /mapMonitor/** - /api/scheduleTask/** - /setting/**