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>
</dependency>
<!-- &lt;!&ndash; 解析客户端操作系统、浏览器信息 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>nl.basjes.parse.useragent</groupId>-->
<!-- <artifactId>yauaa</artifactId>-->
<!-- </dependency>-->
<!-- 解析客户端操作系统、浏览器信息 -->
<dependency>
<groupId>nl.basjes.parse.useragent</groupId>
<artifactId>yauaa</artifactId>
</dependency>
<!-- Sa-Token 插件整合SSO -->
<dependency>

View File

@@ -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<Object> queryErrorInfos(@RequestBody QueryErrorInfoPageParam param) {
public ResponseEntity<Object> queryErrorInfos(@Validated @RequestBody QueryErrorInfoPageParam param) {
return new ResponseEntity<>(errorInfoService.queryErrorInfoPage(param), HttpStatus.OK);
}

View File

@@ -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;
/**
* 异常信息编码

View File

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

View File

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

View File

@@ -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<String> getPermissionList(Object o, String s) {
// return SecurityUtils.getCurrentUserPermissions();
// }
//
// /**
// * 角色权限获取 - 数据库没有设计角色code因此不推荐使用角色鉴权
// * @param o
// * @param s
// * @return
// */
// @Override
// public List<String> 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<String> getPermissionList(Object o, String s) {
return SecurityUtils.getCurrentUserPermissions();
}
/**
* 角色权限获取 - 数据库没有设计角色code因此不推荐使用角色鉴权
* @param o
* @param s
* @return
*/
@Override
public List<String> getRoleList(Object o, String s) {
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.
// *
// * 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 {
//
// /**
// * 清理特定用户缓存信息<br>
// * 用户信息变更时
// *
// * @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 {
/**
* 清理特定用户缓存信息<br>
* 用户信息变更时
*
* @param userName /
*/
public void cleanUserCache(String 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
// *
// * 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<String> 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<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
// 判断当前用户的所有权限是否包含接口上定义的权限
// return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
return true;
}
}

View File

@@ -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<String, String, Object> {
// @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<String, String, Object> {
@Override
public Object apply(String user, String password) {
//用户登入账号密码查询:
StpUtil.login(Long.valueOf(password));
return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
}
}

View File

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

View File

@@ -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<Object> generateQRCode(@RequestBody GenerateQRCodeParam generateQRCodeParam){
public ResponseEntity<Object> generateQRCode(@Validated @RequestBody GenerateQRCodeParam generateQRCodeParam){
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")
@Log("获取当前队列信息")
public ResponseEntity<Object> queryTaskInfoByRoom(@RequestParam String room){

View File

@@ -28,6 +28,21 @@ public class QRcodeInfo {
*/
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;
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;
}

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.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);
}

View File

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

View File

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

View File

@@ -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")

View File

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

View File

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