opt:1.修复引入EasyCaptchaBoot导致的web路径报错。2.添加后台管理系统车辆管理、二维码管理。

This commit is contained in:
2026-02-01 18:10:37 +08:00
parent 778c8de6cd
commit 67653cc200
21 changed files with 505 additions and 239 deletions

View File

@@ -45,11 +45,11 @@
<artifactId>captcha-spring-boot-starter</artifactId> <artifactId>captcha-spring-boot-starter</artifactId>
</dependency> </dependency>
<!-- &lt;!&ndash; 解析客户端操作系统、浏览器信息 &ndash;&gt;--> <!-- 解析客户端操作系统、浏览器信息 -->
<!-- <dependency>--> <dependency>
<!-- <groupId>nl.basjes.parse.useragent</groupId>--> <groupId>nl.basjes.parse.useragent</groupId>
<!-- <artifactId>yauaa</artifactId>--> <artifactId>yauaa</artifactId>
<!-- </dependency>--> </dependency>
<!-- Sa-Token 插件整合SSO --> <!-- Sa-Token 插件整合SSO -->
<dependency> <dependency>

View File

@@ -16,6 +16,7 @@ import org.nl.util.FileConstant;
import org.nl.util.ParseZip; import org.nl.util.ParseZip;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -119,7 +120,7 @@ public class AnomalyInfoController {
@PostMapping("/queryErrorInfos") @PostMapping("/queryErrorInfos")
@Log("分页查询异常信息") @Log("分页查询异常信息")
public ResponseEntity<Object> queryErrorInfos(@RequestBody QueryErrorInfoPageParam param) { public ResponseEntity<Object> queryErrorInfos(@Validated @RequestBody QueryErrorInfoPageParam param) {
return new ResponseEntity<>(errorInfoService.queryErrorInfoPage(param), HttpStatus.OK); return new ResponseEntity<>(errorInfoService.queryErrorInfoPage(param), HttpStatus.OK);
} }

View File

@@ -1,6 +1,7 @@
package org.nl.sys.modular.anomalyInfo.param; package org.nl.sys.modular.anomalyInfo.param;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
/** /**
@@ -13,14 +14,14 @@ public class QueryErrorInfoPageParam {
/** /**
* 当前页 * 当前页
*/ */
@NotBlank(message = "当前页不能为空") @NotNull(message = "当前页不能为空")
private int pageNum; private Integer pageNum;
/** /**
* 页大小 * 页大小
*/ */
@NotBlank(message = "页大小不能为空") @NotNull(message = "页大小不能为空")
private int pageSize; private Integer pageSize;
/** /**
* 异常信息编码 * 异常信息编码

View File

@@ -1,22 +1,22 @@
//package org.nl.sys.modular.backgroundmanagement.common.security.satoken; package org.nl.sys.modular.backgroundmanagement.common.security.satoken;
//
//import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
//import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
//import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.RedisMessageListenerContainer;
//
///** /**
// * @author: lyd * @author: lyd
// * @description: redis监听配置 * @description: redis监听配置
// * @Date: 2022/10/8 * @Date: 2022/10/8
// */ */
//@Configuration @Configuration
//public class RedisListenerConfig { public class RedisListenerConfig {
//
//// @Bean // @Bean
//// RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { // RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
//// RedisMessageListenerContainer container = new RedisMessageListenerContainer(); // RedisMessageListenerContainer container = new RedisMessageListenerContainer();
//// container.setConnectionFactory(connectionFactory); // container.setConnectionFactory(connectionFactory);
//// return container; // return container;
//// } // }
//} }

View File

@@ -1,28 +1,28 @@
//package org.nl.sys.modular.backgroundmanagement.common.security.satoken; package org.nl.sys.modular.backgroundmanagement.common.security.satoken;
//
//import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.interceptor.SaInterceptor;
//import cn.dev33.satoken.jwt.StpLogicJwtForSimple; import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
//import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpLogic;
//import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
//import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
//import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//
///** /**
// * @author: lyd * @author: lyd
// * @description: sa-token的配置路由拦截 * @description: sa-token的配置路由拦截
// * @Date: 2022-09-20 * @Date: 2022-09-20
// */ */
//@Slf4j @Slf4j
//@Configuration @Configuration
//public class SaTokenConfigure implements WebMvcConfigurer { public class SaTokenConfigure implements WebMvcConfigurer {
//
// // Sa-Token 整合 jwt (Simple 简单模式) // Sa-Token 整合 jwt (Simple 简单模式)
// @Bean @Bean
// public StpLogic getStpLogicJwt() { public StpLogic getStpLogicJwt() {
// return new StpLogicJwtForSimple(); return new StpLogicJwtForSimple();
// } }
//} }

View File

@@ -1,38 +1,38 @@
//package org.nl.sys.modular.backgroundmanagement.common.security.satoken; package org.nl.sys.modular.backgroundmanagement.common.security.satoken;
//
//import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpInterface;
//import org.nl.sys.modular.backgroundmanagement.common.util.SecurityUtils; import org.nl.sys.modular.backgroundmanagement.common.util.SecurityUtils;
//import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
//
//import java.util.List; import java.util.List;
//
///** /**
// * @author: lyd * @author: lyd
// * @description: stp接口impl 自定义权限验证接口扩展 保证此类被springboot扫描即可完成sa-token的自定义权限验证扩展 * @description: stp接口impl 自定义权限验证接口扩展 保证此类被springboot扫描即可完成sa-token的自定义权限验证扩展
// * @Date: 2022-09-20 * @Date: 2022-09-20
// */ */
//@Component @Component
//public class StpInterfaceImpl implements StpInterface { public class StpInterfaceImpl implements StpInterface {
//
// /** /**
// * 用户权限获取 * 用户权限获取
// * @param o login存入的值此处存放用户id * @param o login存入的值此处存放用户id
// * @param s * @param s
// * @return * @return
// */ */
// @Override @Override
// public List<String> getPermissionList(Object o, String s) { public List<String> getPermissionList(Object o, String s) {
// return SecurityUtils.getCurrentUserPermissions(); return SecurityUtils.getCurrentUserPermissions();
// } }
//
// /** /**
// * 角色权限获取 - 数据库没有设计角色code因此不推荐使用角色鉴权 * 角色权限获取 - 数据库没有设计角色code因此不推荐使用角色鉴权
// * @param o * @param o
// * @param s * @param s
// * @return * @return
// */ */
// @Override @Override
// public List<String> getRoleList(Object o, String s) { public List<String> getRoleList(Object o, String s) {
// return null; return null;
// } }
//} }

View File

@@ -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. // * Copyright 2019-2020 the original author or authors.
// * // *
// * Licensed under the Apache License, Version 2.0 (the "License"); // * 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 // * See the License for the specific language governing permissions and
// * limitations under the License. // * limitations under the License.
// */ // */
//
//package org.nl.common.security.service; import cn.hutool.core.util.StrUtil;
// import org.springframework.stereotype.Component;
//import cn.hutool.core.util.StrUtil;
//import org.springframework.stereotype.Component; /**
// * @author: liaojinlong
///** * @date: 2020/6/11 18:01
// * @author: liaojinlong * @apiNote: 用于清理 用户登录信息缓存为防止Spring循环依赖与安全考虑 ,单独构成工具类
// * @date: 2020/6/11 18:01 */
// * @apiNote: 用于清理 用户登录信息缓存为防止Spring循环依赖与安全考虑 ,单独构成工具类 @Component
// */ public class UserCacheClean {
//@Component
//public class UserCacheClean { /**
// * 清理特定用户缓存信息<br>
// /** * 用户信息变更时
// * 清理特定用户缓存信息<br> *
// * 用户信息变更时 * @param userName /
// * */
// * @param userName / public void cleanUserCache(String userName) {
// */ if (StrUtil.isNotEmpty(userName)) {
// public void cleanUserCache(String userName) { // UserDetailsServiceImpl.userDtoCache.remove(userName);
// if (StrUtil.isNotEmpty(userName)) { }
//// UserDetailsServiceImpl.userDtoCache.remove(userName); }
// }
/**
* 清理所有用户的缓存信息<br>
* ,如发生角色授权信息变化,可以简便的全部失效缓存
*/
// public void cleanAll() {
// UserDetailsServiceImpl.userDtoCache.clear();
// } // }
// }
// /**
// * 清理所有用户的缓存信息<br>
// * ,如发生角色授权信息变化,可以简便的全部失效缓存
// */
//// public void cleanAll() {
//// UserDetailsServiceImpl.userDtoCache.clear();
//// }
//}

View File

@@ -1,33 +1,33 @@
///* /*
// * Copyright 2019-2020 Zheng Jie * Copyright 2019-2020 Zheng Jie
// * *
// * Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at * You may obtain a copy of the License at
// * *
// * http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
// * *
// * Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
// * limitations under the License. * limitations under the License.
// */ */
//package org.nl.sys.modular.backgroundmanagement.config; package org.nl.sys.modular.backgroundmanagement.config;
//
//import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
//
///** /**
// * @author Zheng Jie * @author Zheng Jie
// */ */
//@Service(value = "el") @Service(value = "el")
//public class ElPermissionConfig { public class ElPermissionConfig {
//
// public Boolean check(String ...permissions){ public Boolean check(String ...permissions){
// // 获取当前用户的所有权限 // 获取当前用户的所有权限
//// List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); // List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
// // 判断当前用户的所有权限是否包含接口上定义的权限 // 判断当前用户的所有权限是否包含接口上定义的权限
//// return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains); // return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
// return true; return true;
// } }
//} }

View File

@@ -1,24 +1,24 @@
//package org.nl.sys.modular.backgroundmanagement.config.saconfig; package org.nl.sys.modular.backgroundmanagement.config.saconfig;
//
//import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
//import cn.dev33.satoken.util.SaResult; import cn.dev33.satoken.util.SaResult;
//import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
//
//import java.util.function.BiFunction; import java.util.function.BiFunction;
//
///* /*
// * @author ZZQ * @author ZZQ
// * @Date 2022/11/24 3:47 下午 * @Date 2022/11/24 3:47 下午
// */ */
//@Component @Component
//public class LoginUserHandler implements BiFunction<String, String, Object> { public class LoginUserHandler implements BiFunction<String, String, Object> {
// @Override @Override
// public Object apply(String user, String password) { public Object apply(String user, String password) {
// //用户登入账号密码查询: //用户登入账号密码查询:
// StpUtil.login(Long.valueOf(password)); StpUtil.login(Long.valueOf(password));
//
// return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue()); return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
//
// } }
//
//} }

View File

@@ -1,33 +1,33 @@
//package org.nl.sys.modular.backgroundmanagement.config.saconfig; package org.nl.sys.modular.backgroundmanagement.config.saconfig;
//
//import cn.dev33.satoken.config.SaSsoConfig; import cn.dev33.satoken.config.SaSsoConfig;
//import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
//import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
//import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
//import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
//
///* /*
// * @author ZZQ * @author ZZQ
// * @Date 2022/11/28 10:58 上午 * @Date 2022/11/28 10:58 上午
// */ */
//@Configuration @Configuration
//public class SaInitCOnfig { public class SaInitCOnfig {
//
// @Autowired @Autowired
// LoginUserHandler loginUserHandler; LoginUserHandler loginUserHandler;
//
// @Autowired @Autowired
// public void configSso(SaSsoConfig sso) { public void configSso(SaSsoConfig sso) {
// System.out.println("启动初始化-----SaSsoConfig"); System.out.println("启动初始化-----SaSsoConfig");
// // 配置未登录时返回的View // 配置未登录时返回的View
// sso.setNotLoginView(() -> new ModelAndView("sa-login")); sso.setNotLoginView(() -> new ModelAndView("sa-login"));
// // 配置:登录处理函数 // 配置:登录处理函数
// sso.setDoLoginHandle(loginUserHandler); sso.setDoLoginHandle(loginUserHandler);
//
// sso.setSendHttp(s -> { sso.setSendHttp(s -> {
// HttpResponse execute = HttpRequest.get(s).execute(); HttpResponse execute = HttpRequest.get(s).execute();
// return execute.body(); return execute.body();
// }); });
// } }
//} }

View File

@@ -1,12 +1,17 @@
package org.nl.sys.modular.qrcode.controller; package org.nl.sys.modular.qrcode.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.nl.api.task.core.TaskRequestParam; import org.nl.api.task.core.TaskRequestParam;
import org.nl.logging.annotation.Log; 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.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.sys.modular.qrcode.service.QRCodeService;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
/** /**
@@ -22,10 +27,28 @@ public class QRCodeController {
@PostMapping("/generateQRCode") @PostMapping("/generateQRCode")
@Log("生成二维码") @Log("生成二维码")
public ResponseEntity<Object> generateQRCode(@RequestBody GenerateQRCodeParam generateQRCodeParam){ public ResponseEntity<Object> generateQRCode(@Validated @RequestBody GenerateQRCodeParam generateQRCodeParam){
return new ResponseEntity<>(qrCodeService.generateQRCode(generateQRCodeParam), HttpStatus.OK); return new ResponseEntity<>(qrCodeService.generateQRCode(generateQRCodeParam), HttpStatus.OK);
} }
@PostMapping("/queryQRCodeInfoList")
@Log("查询二维码信息列表")
public ResponseEntity<Object> queryQRCodeInfoList(@Validated @RequestBody QueryQRCodeParam param){
return new ResponseEntity<>(qrCodeService.queryQRCodeInfoList(param), HttpStatus.OK);
}
@PostMapping("/updateQRCodeInfo")
@Log("修改二维码信息")
public ResponseEntity<Object> updateQRCodeInfo(@Validated @RequestBody UpdateQRCodeParam param){
return new ResponseEntity<>(qrCodeService.updateQRCodeInfo(param), HttpStatus.OK);
}
@PostMapping("/deleteQRCodeInfo")
@Log("删除二维码信息")
public ResponseEntity<Object> deleteQRCodeInfo(@RequestBody QRcodeInfo qRcodeInfo){
return new ResponseEntity<>(qrCodeService.deleteQRCodeInfo(qRcodeInfo), HttpStatus.OK);
}
@GetMapping("/queryTaskInfoByRoom") @GetMapping("/queryTaskInfoByRoom")
@Log("获取当前队列信息") @Log("获取当前队列信息")
public ResponseEntity<Object> queryTaskInfoByRoom(@RequestParam String room){ public ResponseEntity<Object> queryTaskInfoByRoom(@RequestParam String room){

View File

@@ -28,6 +28,21 @@ public class QRcodeInfo {
*/ */
private String room_code; private String room_code;
/**
* 二维码内容
*/
private String qrcode_data;
/**
* 二维码宽度(像素)
*/
private Integer qrcode_width;
/**
* 二维码高度(像素)
*/
private Integer qrcode_height;
/** /**
* 二维码地址 * 二维码地址
*/ */

View File

@@ -1,6 +1,7 @@
package org.nl.sys.modular.qrcode.param; package org.nl.sys.modular.qrcode.param;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
/** /**
@@ -25,12 +26,12 @@ public class GenerateQRCodeParam {
/** /**
* 二维码宽度(像素) * 二维码宽度(像素)
*/ */
@NotBlank(message = "二维码宽度不能为空") @NotNull(message = "二维码宽度不能为空")
private int width; private Integer width;
/** /**
* 二维码高度(像素) * 二维码高度(像素)
*/ */
@NotBlank(message = "二维码高度不能为空") @NotNull(message = "二维码高度不能为空")
private int height; private Integer height;
} }

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -2,7 +2,10 @@ package org.nl.sys.modular.qrcode.service;
import org.nl.api.task.core.TaskRequestParam; import org.nl.api.task.core.TaskRequestParam;
import org.nl.response.WebResponse; 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.GenerateQRCodeParam;
import org.nl.sys.modular.qrcode.param.QueryQRCodeParam;
import org.nl.sys.modular.qrcode.param.UpdateQRCodeParam;
/** /**
* @author dsh * @author dsh
@@ -17,6 +20,27 @@ public interface QRCodeService {
*/ */
WebResponse generateQRCode(GenerateQRCodeParam generateQRCodeParam); 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 * @param qrCodeTaskRequestParam
@@ -43,4 +67,11 @@ public interface QRCodeService {
* @return * @return
*/ */
WebResponse taskOperationConfirm(String taskCode); WebResponse taskOperationConfirm(String taskCode);
/**
* 检验该房间是否已经存在二维码
* @param room
* @return
*/
boolean verifyQRCodeByRoom(String room);
} }

View File

@@ -1,17 +1,24 @@
package org.nl.sys.modular.qrcode.service.impl; package org.nl.sys.modular.qrcode.service.impl;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 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 jakarta.annotation.Resource;
import org.nl.api.task.api.TaskAPI; import org.nl.api.task.api.TaskAPI;
import org.nl.api.task.core.TaskRequestParam; import org.nl.api.task.core.TaskRequestParam;
import org.nl.enums.TaskSourceEnum; import org.nl.enums.TaskSourceEnum;
import org.nl.exception.BadRequestException; import org.nl.exception.BadRequestException;
import org.nl.response.WebResponse; 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.dao.QRcodeInfo;
import org.nl.sys.modular.qrcode.mapper.QRcodeInfoMapper; import org.nl.sys.modular.qrcode.mapper.QRcodeInfoMapper;
import org.nl.sys.modular.qrcode.param.GenerateQRCodeParam; 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.sys.modular.qrcode.service.QRCodeService;
import org.nl.util.FileProperties; import org.nl.util.FileProperties;
import org.nl.util.IdUtil; import org.nl.util.IdUtil;
@@ -36,24 +43,38 @@ public class QRCodeServiceImpl implements QRCodeService {
@Override @Override
public WebResponse generateQRCode(GenerateQRCodeParam param) { 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 返回文件大小 //result 返回文件大小
String result = QRCodeUtil.generateQRCode(param.getData(), param.getWidth(), String result = QRCodeUtil.generateQRCode(param.getData(), qrcodeWidth,
param.getHeight(),fileProperties.getPath().getQrcode(),param.getRoom()+".png"); qrcodeHeight,localAddress,fileName);
if (StrUtil.isBlank(result)){ if (StrUtil.isBlank(result)){
throw new BadRequestException("生成二维码失败"); throw new BadRequestException("生成二维码失败");
} }
// 检验该房间是否已经存在二维码
boolean exists = qrcodeInfoMapper.selectCount(new LambdaQueryWrapper<>(QRcodeInfo.class) boolean exists = this.verifyQRCodeByRoom(param.getRoom());
.eq(QRcodeInfo::getRoom_code,param.getRoom())
)>0;
if (exists){ if (exists){
throw new BadRequestException("该房间已存在二维码,无法继续生成"); throw new BadRequestException("该房间已存在二维码,无法继续生成");
} }
QRcodeInfo qrcodeInfo = new QRcodeInfo(); QRcodeInfo qrcodeInfo = new QRcodeInfo();
qrcodeInfo.setQrcode_id(IdUtil.getStringId()); qrcodeInfo.setQrcode_id(IdUtil.getStringId());
qrcodeInfo.setFile_name(param.getRoom()+".png"); qrcodeInfo.setFile_name(fileName);
qrcodeInfo.setRoom_code(param.getRoom()); 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.setFile_size(result);
qrcodeInfo.setCreate_time(DateUtil.now()); qrcodeInfo.setCreate_time(DateUtil.now());
@@ -61,6 +82,66 @@ public class QRCodeServiceImpl implements QRCodeService {
return WebResponse.requestOk(); return WebResponse.requestOk();
} }
@Override
public WebResponse queryQRCodeInfoList(QueryQRCodeParam param) {
Page<QRcodeInfo> page = new Page<>(param.getPageNum(), param.getPageSize());
IPage<QRcodeInfo> 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 @Override
public WebResponse createTask(TaskRequestParam qrCodeTaskRequestParam) { public WebResponse createTask(TaskRequestParam qrCodeTaskRequestParam) {
taskAPI.createTask(qrCodeTaskRequestParam, TaskSourceEnum.QRCODE.getName()); taskAPI.createTask(qrCodeTaskRequestParam, TaskSourceEnum.QRCODE.getName());
@@ -81,4 +162,14 @@ public class QRCodeServiceImpl implements QRCodeService {
public WebResponse taskOperationConfirm(String taskCode) { public WebResponse taskOperationConfirm(String taskCode) {
return taskAPI.taskOperationConfirm(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;
}
} }

View File

@@ -10,7 +10,9 @@ import javax.imageio.ImageIO;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; 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.HashMap;
import java.util.Map; import java.util.Map;
@@ -75,4 +77,20 @@ public class QRCodeUtil {
return null; 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;
}
}
} }

View File

@@ -34,7 +34,9 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@Slf4j @Slf4j
@RestController @RestController
@SpringBootApplication @SpringBootApplication(exclude = {
io.github.eternalstone.captcha.autoconfig.EasyCaptchaAutoConfiguration.class
})
@EnableScheduling @EnableScheduling
@EnableTransactionManagement @EnableTransactionManagement
@EnableMethodCache(basePackages = "org.nl") @EnableMethodCache(basePackages = "org.nl")

View File

@@ -82,7 +82,7 @@ file:
qrcode: /home/eladmin/qrcode/ qrcode: /home/eladmin/qrcode/
avatar: /home/eladmin/avatar/ avatar: /home/eladmin/avatar/
windows: windows:
path: C:\eladmin\file\currentMap\ path: C:\eladmin\file\
qrcode: C:\eladmin\qrcode\ qrcode: C:\eladmin\qrcode\
avatar: C:\eladmin\avatar\ avatar: C:\eladmin\avatar\
# 文件大小 /M # 文件大小 /M

View File

@@ -38,7 +38,11 @@ security:
excludes: excludes:
# 认证 # 认证
- /auth/login - /auth/login
# apt屏幕操作 - /auth/code
- /auth/logout
- /sys-user-do/**
# frobot屏幕操作
- /schedule/vehicle/**
- /mapMonitor/** - /mapMonitor/**
- /api/scheduleTask/** - /api/scheduleTask/**
- /setting/** - /setting/**