From acf269e92a49ae29bd868c6bc929ed7af06dd80e Mon Sep 17 00:00:00 2001 From: liejiu946 Date: Sun, 4 Jan 2026 09:34:07 +0800 Subject: [PATCH] =?UTF-8?q?add:=E7=AC=AC=E4=B8=80=E7=89=88=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=821.F=E6=9C=BA=E5=99=A8=E4=BA=BA=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E4=B8=8A=E6=8A=A5=E5=BC=82=E5=B8=B8=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=8C=E5=90=8E=E7=AB=AF=E5=AD=98=E5=82=A8=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E4=BF=A1=E6=81=AF=E5=92=8C=E5=BC=82=E5=B8=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=BC=82=E5=B8=B8=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=92=8C=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=E6=96=B9?= =?UTF-8?q?=E6=B3=95excel=E5=AF=BC=E5=85=A5=E5=8A=9F=E8=83=BD=E3=80=822.?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=86=E7=A0=81=E6=A0=A1=E9=AA=8C=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/nl/api/setting/api/SettingAPI.java | 4 +- .../api/sys/anomalyInfo/api/ErrorInfoAPI.java | 17 +++ .../schedule/modular/init/ScheduleInit.java | 26 ++++ .../service/impl/ScheduleTaskServiceImpl.java | 2 +- .../modular/vehicle/dto/VehicleInfoDto.java | 15 +- .../service/impl/VehicleServiceImpl.java | 8 +- .../modular/enums/SettingCodeEnum.java | 7 +- .../modular/provider/SettingAPIProvider.java | 4 +- .../service/impl/SettingServiceImpl.java | 9 ++ nl-business-sys/pom.xml | 13 ++ .../controller/AnomalyInfoController.java | 122 +++++++++++++++++ .../anomalyInfo/dao/ErrorHandling.java | 64 +++++++++ .../modular/anomalyInfo/dao/ErrorInfo.java | 76 +++++++++++ .../modular/anomalyInfo/dto/ErrorDataDto.java | 26 ++++ .../listener/ErrorHandlingListener.java | 90 ++++++++++++ .../listener/ErrorInfoListener.java | 91 +++++++++++++ .../mapper/ErrorHandlingMapper.java | 14 ++ .../anomalyInfo/mapper/ErrorInfoMapper.java | 14 ++ .../provider/ErrorInfoAPIProvider.java | 36 +++++ .../service/AnomalyInfoService.java | 17 +++ .../service/ErrorHandlingService.java | 12 ++ .../anomalyInfo/service/ErrorInfoService.java | 11 ++ .../service/impl/AnomalyInfoServiceImpl.java | 47 +++++++ .../impl/ErrorHandlingServiceImpl.java | 15 ++ .../service/impl/ErrorInfoServiceImpl.java | 16 +++ .../controller/SecurityController.java | 30 ++++ .../modular/secutiry/param/SecurityParam.java | 18 +++ .../secutiry/service/SecurityService.java | 12 ++ .../service/impl/SecurityServiceImpl.java | 35 +++++ nl-common/pom.xml | 6 + .../main/java/org/nl/util/FileConstant.java | 23 ++++ .../src/main/java/org/nl/util/ParseZip.java | 128 ++++++++++++++++++ .../src/main/java/org/nl/util/RsaUtils.java | 90 ++++++++++++ 33 files changed, 1089 insertions(+), 9 deletions(-) create mode 100644 nl-business-api/src/main/java/org/nl/api/sys/anomalyInfo/api/ErrorInfoAPI.java create mode 100644 nl-business-schedule/src/main/java/org/nl/schedule/modular/init/ScheduleInit.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/controller/AnomalyInfoController.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorHandling.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorInfo.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dto/ErrorDataDto.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorHandlingListener.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorInfoListener.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorHandlingMapper.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorInfoMapper.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/provider/ErrorInfoAPIProvider.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/AnomalyInfoService.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorHandlingService.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorInfoService.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/AnomalyInfoServiceImpl.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorHandlingServiceImpl.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorInfoServiceImpl.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/controller/SecurityController.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/param/SecurityParam.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/SecurityService.java create mode 100644 nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/impl/SecurityServiceImpl.java create mode 100644 nl-common/src/main/java/org/nl/util/FileConstant.java create mode 100644 nl-common/src/main/java/org/nl/util/ParseZip.java create mode 100644 nl-common/src/main/java/org/nl/util/RsaUtils.java diff --git a/nl-business-api/src/main/java/org/nl/api/setting/api/SettingAPI.java b/nl-business-api/src/main/java/org/nl/api/setting/api/SettingAPI.java index d53b07d..fb833cc 100644 --- a/nl-business-api/src/main/java/org/nl/api/setting/api/SettingAPI.java +++ b/nl-business-api/src/main/java/org/nl/api/setting/api/SettingAPI.java @@ -9,8 +9,8 @@ import com.alibaba.fastjson.JSONObject; public interface SettingAPI { /** - * 根据设置编号查询设置参数是否启用 + * 根据设置编号查询 * @return */ - JSONObject querySttingParamIsActiveByCode(String setting_code); + JSONObject querySettingParamByCode(String setting_code); } diff --git a/nl-business-api/src/main/java/org/nl/api/sys/anomalyInfo/api/ErrorInfoAPI.java b/nl-business-api/src/main/java/org/nl/api/sys/anomalyInfo/api/ErrorInfoAPI.java new file mode 100644 index 0000000..cb51b70 --- /dev/null +++ b/nl-business-api/src/main/java/org/nl/api/sys/anomalyInfo/api/ErrorInfoAPI.java @@ -0,0 +1,17 @@ +package org.nl.api.sys.anomalyInfo.api; + +import com.alibaba.fastjson.JSONObject; + +/** + * @author dsh + * 2025/12/30 + */ +public interface ErrorInfoAPI { + + /** + * 根据异常码查询异常信息 + * @param code + * @return + */ + JSONObject queryErrorInfoByCode(Integer code); +} diff --git a/nl-business-schedule/src/main/java/org/nl/schedule/modular/init/ScheduleInit.java b/nl-business-schedule/src/main/java/org/nl/schedule/modular/init/ScheduleInit.java new file mode 100644 index 0000000..66b4415 --- /dev/null +++ b/nl-business-schedule/src/main/java/org/nl/schedule/modular/init/ScheduleInit.java @@ -0,0 +1,26 @@ +package org.nl.schedule.modular.init; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import org.nl.api.setting.api.SettingAPI; +import org.nl.util.URLConstant; +import org.springframework.stereotype.Component; + +/** + * @author dsh + * 2025/12/29 + */ +@Component +public class ScheduleInit { + + @Resource + private SettingAPI settingAPI; + + @PostConstruct + public void init() { + URLConstant.SCHEDULE_IP_PORT = settingAPI.querySettingParamByCode("schedule_ip") + .getJSONObject("data") + .getString("value"); + } + +} diff --git a/nl-business-schedule/src/main/java/org/nl/schedule/modular/task/service/impl/ScheduleTaskServiceImpl.java b/nl-business-schedule/src/main/java/org/nl/schedule/modular/task/service/impl/ScheduleTaskServiceImpl.java index e488b97..7d5d239 100644 --- a/nl-business-schedule/src/main/java/org/nl/schedule/modular/task/service/impl/ScheduleTaskServiceImpl.java +++ b/nl-business-schedule/src/main/java/org/nl/schedule/modular/task/service/impl/ScheduleTaskServiceImpl.java @@ -55,7 +55,7 @@ public class ScheduleTaskServiceImpl implements ScheduleTaskService { boolean flag = false; // 到达时等待设置参数 - JSONObject jsonObject = settingAPI.querySttingParamIsActiveByCode("call_arrival_waiting_time").getJSONObject("data"); + JSONObject jsonObject = settingAPI.querySettingParamByCode("call_arrival_waiting_time").getJSONObject("data"); String is_active = jsonObject.getString("is_active"); String arrive_waiting_time = jsonObject.getString("value"); if (StrUtil.isNotBlank(is_active) && YesOrNoEnum.YES.getCode().equals(is_active)){ diff --git a/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/dto/VehicleInfoDto.java b/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/dto/VehicleInfoDto.java index fbc90fb..0d19c3f 100644 --- a/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/dto/VehicleInfoDto.java +++ b/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/dto/VehicleInfoDto.java @@ -1,5 +1,6 @@ package org.nl.schedule.modular.vehicle.dto; +import com.alibaba.fastjson.JSONObject; import lombok.Data; import org.nl.schedule.modular.vehicle.entity.Location; @@ -54,9 +55,19 @@ public class VehicleInfoDto{ private int signalStrength; /** - * 异常信息集合 + * 异常信息编码 */ - private List exceptions; + private Integer error_code; + + /** + * 异常信息内容 + */ + private String error_msg; + + /** + * 异常信息 + */ + private JSONObject error_info; /** * 当前位置 diff --git a/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/service/impl/VehicleServiceImpl.java b/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/service/impl/VehicleServiceImpl.java index 7b5e959..e654d61 100644 --- a/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/service/impl/VehicleServiceImpl.java +++ b/nl-business-schedule/src/main/java/org/nl/schedule/modular/vehicle/service/impl/VehicleServiceImpl.java @@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.nl.api.sys.anomalyInfo.api.ErrorInfoAPI; import org.nl.api.task.api.TaskAPI; import org.nl.response.WebResponse; import org.nl.schedule.core.websocket.WebSocketVehicleInfoServer; @@ -38,6 +39,9 @@ public class VehicleServiceImpl implements VehicleService { @Resource private TaskAPI taskAPI; + @Resource + private ErrorInfoAPI errorInfoAPI; + /** * 定时更新车辆信息(每秒执行) */ @@ -52,6 +56,9 @@ public class VehicleServiceImpl implements VehicleService { // 更新缓存 for (VehicleInfoDto vehicle : vehicles) { + if (vehicle.getError_code()!=0) { + vehicle.setError_info(errorInfoAPI.queryErrorInfoByCode(vehicle.getError_code())); + } vehicleCache.put(vehicle.getVehicleNumber(), vehicle); } @@ -78,7 +85,6 @@ public class VehicleServiceImpl implements VehicleService { @Override public List getAllVehicles() { - String url = URLConstant.SCHEDULE_IP_PORT+"/vehicles"; List vehicles = new ArrayList<>(); try { try (HttpResponse response = HttpRequest.get(URLConstant.SCHEDULE_IP_PORT+"/vehicles") diff --git a/nl-business-setting/src/main/java/org/nl/setting/modular/enums/SettingCodeEnum.java b/nl-business-setting/src/main/java/org/nl/setting/modular/enums/SettingCodeEnum.java index 679b09b..03773a7 100644 --- a/nl-business-setting/src/main/java/org/nl/setting/modular/enums/SettingCodeEnum.java +++ b/nl-business-setting/src/main/java/org/nl/setting/modular/enums/SettingCodeEnum.java @@ -37,7 +37,12 @@ public enum SettingCodeEnum { /** * 充电时是否可呼叫 */ - CAN_IT_BE_CALLED_WHILE_CHARGING("6", "can_it_be_called_while_charging", "充电时是否可呼叫"); + CAN_IT_BE_CALLED_WHILE_CHARGING("6", "can_it_be_called_while_charging", "充电时是否可呼叫"), + + /** + * 显示屏密码 + */ + SCREEN_PASSWORD("7", "password", "显示屏密码"); private String code; private String name; diff --git a/nl-business-setting/src/main/java/org/nl/setting/modular/provider/SettingAPIProvider.java b/nl-business-setting/src/main/java/org/nl/setting/modular/provider/SettingAPIProvider.java index 37b299f..efc335d 100644 --- a/nl-business-setting/src/main/java/org/nl/setting/modular/provider/SettingAPIProvider.java +++ b/nl-business-setting/src/main/java/org/nl/setting/modular/provider/SettingAPIProvider.java @@ -26,10 +26,10 @@ public class SettingAPIProvider implements SettingAPI { private SettingService settingService; @Override - public JSONObject querySttingParamIsActiveByCode(String setting_code) { + public JSONObject querySettingParamByCode(String setting_code) { if (StrUtil.isBlank(setting_code)){ log.info("设置编号不能为空"); - throw new BadRequestException("设置编号不能为空"); + return null; } JSONObject result = new JSONObject(); result.put("data",settingService.getOne(new LambdaQueryWrapper<>(Setting.class).eq(Setting::getSetting_code,setting_code))); diff --git a/nl-business-setting/src/main/java/org/nl/setting/modular/service/impl/SettingServiceImpl.java b/nl-business-setting/src/main/java/org/nl/setting/modular/service/impl/SettingServiceImpl.java index a0d7334..e685a80 100644 --- a/nl-business-setting/src/main/java/org/nl/setting/modular/service/impl/SettingServiceImpl.java +++ b/nl-business-setting/src/main/java/org/nl/setting/modular/service/impl/SettingServiceImpl.java @@ -1,5 +1,6 @@ package org.nl.setting.modular.service.impl; +import cn.dev33.satoken.secure.SaSecureUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -20,6 +21,8 @@ import org.nl.setting.modular.enums.SettingCodeEnum; import org.nl.setting.modular.mapper.SettingMapper; import org.nl.setting.modular.param.UpdateSettingParam; import org.nl.setting.modular.service.SettingService; +import org.nl.util.RsaUtils; +import org.nl.util.URLConstant; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -66,6 +69,7 @@ public class SettingServiceImpl extends ServiceImpl impl switch (settingCodeEnum){ case SCHEDULE_IP: log.info("修改调度IP"); + URLConstant.SCHEDULE_IP_PORT = setting_value; break; case DELIVERY_SPEED: log.info("修改配送速度"); @@ -120,6 +124,11 @@ public class SettingServiceImpl extends ServiceImpl impl throw new BadRequestException("设置调度可接任务阈值失败"); } break; + case SCREEN_PASSWORD: + log.info("修改显示屏密码"); + String newPassword = RsaUtils.decryptByPrivateKey(RsaUtils.privateKey,setting_value); + setting_value = SaSecureUtil.md5BySalt(newPassword,"salt"); + break; } settingMapper.update(new LambdaUpdateWrapper<>(Setting.class) diff --git a/nl-business-sys/pom.xml b/nl-business-sys/pom.xml index dae1da1..b16089b 100644 --- a/nl-business-sys/pom.xml +++ b/nl-business-sys/pom.xml @@ -27,6 +27,19 @@ org.nl nl-business-api + + + + com.alibaba + easyexcel + + + + + cn.dev33 + sa-token-spring-boot3-starter + + 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 new file mode 100644 index 0000000..e76300c --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/controller/AnomalyInfoController.java @@ -0,0 +1,122 @@ +package org.nl.sys.modular.anomalyInfo.controller; + +import com.alibaba.excel.EasyExcel; +import jakarta.annotation.Resource; +import org.nl.exception.BadRequestException; +import org.nl.logging.annotation.Log; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; +import org.nl.sys.modular.anomalyInfo.listener.ErrorHandlingListener; +import org.nl.sys.modular.anomalyInfo.listener.ErrorInfoListener; +import org.nl.sys.modular.anomalyInfo.service.AnomalyInfoService; +import org.nl.sys.modular.anomalyInfo.service.ErrorHandlingService; +import org.nl.sys.modular.anomalyInfo.service.ErrorInfoService; +import org.nl.util.FileConstant; +import org.nl.util.ParseZip; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; + +/** + * @author dsh + * 2025/12/29 + */ +@RestController +@RequestMapping("/anomalyInfo") +public class AnomalyInfoController { + + @Resource + private AnomalyInfoService anomalyInfoService; + + @Resource + private ErrorInfoService errorInfoService; + + @Resource + private ErrorHandlingService errorHandlingService; + + @Resource + private ParseZip parseZip; + + @PostMapping("/queryErrorDataByCode") + @Log("根据异常编号查询异常数据") + public ResponseEntity queryErrorDataByCode(@RequestParam("code") String code) { + return new ResponseEntity<>(anomalyInfoService.queryErrorDataByCode(code), HttpStatus.OK); + } + + @PostMapping("/importErrorInfoExcel") + @Log("导入excel异常信息") + public ResponseEntity importErrorInfoExcel(@RequestParam("file") MultipartFile file) throws IOException { + if (file.isEmpty()) { + throw new BadRequestException("请选择文件上传"); + } + + // 创建监听器实例,传入所需的Service + ErrorInfoListener listener = new ErrorInfoListener(errorInfoService); + + // 读取Excel文件 + // withFile(file.getInputStream())... 也可以 + + EasyExcel.read(file.getInputStream(), ErrorInfo.class, listener) + .sheet() // 默认读取第一个sheet + .doRead(); + return new ResponseEntity<>("操作成功",HttpStatus.OK); + } + + @PostMapping("/importErrorHandlingExcel") + @Log("导入excel异常处理信息") + public ResponseEntity importErrorHandlingExcel(@RequestParam("file") MultipartFile file) throws IOException { + if (file.isEmpty()) { + throw new BadRequestException("请选择文件上传"); + } + + // 创建监听器实例,传入所需的Service + ErrorHandlingListener listener = new ErrorHandlingListener(errorHandlingService); + + // 读取Excel文件 + // withFile(file.getInputStream())... 也可以 + + EasyExcel.read(file.getInputStream(), ErrorHandling.class, listener) + .sheet() // 默认读取第一个sheet + .doRead(); + return new ResponseEntity<>("操作成功",HttpStatus.OK); + } + + @PostMapping("/importErrorImage") + @Log("导入异常图片") + public ResponseEntity importErrorImage(@RequestParam("file") MultipartFile file) throws IOException { + if (file.isEmpty()) { + throw new BadRequestException("文件不能为空"); + } + + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null || + (!originalFilename.toLowerCase().endsWith(".zip"))) { + throw new BadRequestException("目前只支持ZIP格式"); + } + + try { + // 创建上传目录 + File uploadDir = new File(FileConstant.ERROR_IMAGE_PATH); + if (!uploadDir.exists()) { + uploadDir.mkdirs(); + } + + // 处理压缩文件 + parseZip.processCompressedFile(file); + + + return new ResponseEntity<>("上传成功!",HttpStatus.OK); + + } catch (Exception e) { + throw new BadRequestException("处理文件失败:{}"+e.getMessage()); + } + } + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorHandling.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorHandling.java new file mode 100644 index 0000000..3a01c14 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorHandling.java @@ -0,0 +1,64 @@ +package org.nl.sys.modular.anomalyInfo.dao; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author dsh + * 2025/12/29 + */ +@Data +@TableName("error_handling") +public class ErrorHandling { + + /** + * 异常处理标识 + */ + @TableId + @ExcelProperty(index = 0,value = "标识") + private String error_handling_id; + + /** + * 异常信息编码 + */ + @ExcelProperty(index = 1,value = "异常编码") + private String error_code; + + /** + * 异常处理类型(1 图文说明 2视频说明) + */ + @ExcelProperty(index = 2,value = "异常处理类型(1图文说明2视频说明)") + private Integer error_handling_type; + + /** + * 异常处理说明 + */ + @ExcelProperty(index = 3,value = "异常处理说明") + private String error_handling_title; + + /** + * 中文异常处理说明 + */ + @ExcelProperty(index = 4,value = "异常处理说明(中文)") + private String zh_error_handling_title; + + /** + * 英文异常处理说明 + */ + @ExcelProperty(index = 5,value = "异常处理说明(英文)") + private String en_error_handling_title; + + /** + * 异常处理排序 + */ + @ExcelProperty(index = 6,value = "异常处理排序") + private Integer error_handling_seq; + + /** + * 异常处理地址(图片 或 视频地址) + */ + @ExcelProperty(index = 7,value = "异常处理地址(图片或视频地址)") + private String error_handling_addre; +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorInfo.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorInfo.java new file mode 100644 index 0000000..cff0ac7 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dao/ErrorInfo.java @@ -0,0 +1,76 @@ +package org.nl.sys.modular.anomalyInfo.dao; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author dsh + * 2025/12/29 + */ +@Data +@TableName("error_info") +public class ErrorInfo { + + /** + * 异常信息标识 + */ + @TableId + @ExcelProperty(index = 0,value = "唯一标识") + private String error_id; + + /** + * 异常信息名称 + */ + @ExcelProperty(index = 1,value = "异常名称") + private String error_name; + + /** + * 中文异常信息名称 + */ + @ExcelProperty(index = 2,value = "异常名称(中文)") + private String zh_error_name; + + /** + * 英文异常信息名称 + */ + @ExcelProperty(index = 3,value = "异常名称(英文)") + private String en_error_name; + + /** + * 异常信息编码 + */ + @ExcelProperty(index = 4,value = "异常编号") + private String error_code; + + /** + * 异常信息类别(1普通故障 2严重故障) + */ + @ExcelProperty(index = 5,value = "异常类别(1普通故障,2严重故障)") + private Integer error_category; + + /** + * 异常说明 + */ + @ExcelProperty(index = 6,value = "异常说明") + private String error_description; + + /** + * 中文异常说明 + */ + @ExcelProperty(index = 7,value = "异常说明(中文)") + private String zh_error_description; + + /** + * 英文异常说明 + */ + @ExcelProperty(index = 8,value = "异常说明(英文)") + private String en_error_description; + + /** + * 异常信息类型(1电气 2导航) + */ + @ExcelProperty(index = 9,value = "异常类型(1电气,2导航)") + private Integer error_type; +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dto/ErrorDataDto.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dto/ErrorDataDto.java new file mode 100644 index 0000000..c0f6911 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/dto/ErrorDataDto.java @@ -0,0 +1,26 @@ +package org.nl.sys.modular.anomalyInfo.dto; + +import lombok.Data; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; + +import java.util.List; + +/** + * @author dsh + * 2025/12/29 + */ +@Data +public class ErrorDataDto extends ErrorInfo { + + /** + * 图文异常处理 + */ + private List graphicDescription; + + /** + * 视频异常处理 + */ + private List videoDescription; + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorHandlingListener.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorHandlingListener.java new file mode 100644 index 0000000..e4b0440 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorHandlingListener.java @@ -0,0 +1,90 @@ +package org.nl.sys.modular.anomalyInfo.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; +import lombok.extern.slf4j.Slf4j; +import org.nl.exception.BadRequestException; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsh + * 2025/12/29 + */ +@Slf4j +public class ErrorHandlingListener extends AnalysisEventListener { + /** + * 每隔 BATCH_COUNT 条存储数据库,然后清理list,方便内存回收 + */ + private static final int BATCH_COUNT = 1000; // 批处理阈值:cite[2]:cite[5] + + private List cachedDataList = new ArrayList<>(BATCH_COUNT); + + /** + * 假设我们需要Service进行批量插入 + * 也可以使用Mapper,但Service层封装批量操作更常见 + */ + private IService service; + + /** + * 通过构造器传入需要的Service或Mapper + */ + public ErrorHandlingListener(IService service) { + this.service = service; + } + + /** + * 每读一行数据,都会调用此方法 + * @param data 一行数据,类型是泛型T + * @param context + */ + @Override + public void invoke(ErrorHandling data, AnalysisContext context) { + cachedDataList.add(data); + // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM + if (cachedDataList.size() >= BATCH_COUNT) { + saveData(); + // 存储完成清理 list + cachedDataList.clear(); + } + } + + /** + * 所有数据解析完成后,会调用此方法 + * @param context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 确保最后一批数据也持久化到数据库 + if (!cachedDataList.isEmpty()) { + saveData(); + cachedDataList.clear(); + } + log.info("所有Excel数据解析并导入完成!"); + } + + /** + * 批量保存数据到数据库 + * 使用MyBatis-Plus的saveBatch方法 + */ + @Transactional(rollbackFor = Exception.class) + public void saveData() { + if (!cachedDataList.isEmpty()) { + // 清除所有异常信息 重新导入 + service.remove(new QueryWrapper()); + // 第二个参数是批次大小 + boolean saveResult = service.saveBatch(cachedDataList, BATCH_COUNT); + if (saveResult) { + log.info("成功批量插入 {} 条数据。", cachedDataList.size()); + } else { + log.error("批量插入数据失败!"); + throw new BadRequestException("操作失败"); + } + } + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorInfoListener.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorInfoListener.java new file mode 100644 index 0000000..8317aa7 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/listener/ErrorInfoListener.java @@ -0,0 +1,91 @@ +package org.nl.sys.modular.anomalyInfo.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; +import lombok.extern.slf4j.Slf4j; +import org.nl.exception.BadRequestException; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dsh + * 2025/12/29 + */ +@Slf4j +public class ErrorInfoListener extends AnalysisEventListener { + + /** + * 每隔 BATCH_COUNT 条存储数据库,然后清理list,方便内存回收 + */ + private static final int BATCH_COUNT = 1000; // 批处理阈值:cite[2]:cite[5] + + private List cachedDataList = new ArrayList<>(BATCH_COUNT); + + /** + * 假设我们需要Service进行批量插入 + * 也可以使用Mapper,但Service层封装批量操作更常见 + */ + private IService service; + + /** + * 通过构造器传入需要的Service或Mapper + */ + public ErrorInfoListener(IService service) { + this.service = service; + } + + /** + * 每读一行数据,都会调用此方法 + * @param data 一行数据,类型是泛型T + * @param context + */ + @Override + public void invoke(ErrorInfo data, AnalysisContext context) { + cachedDataList.add(data); + // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM + if (cachedDataList.size() >= BATCH_COUNT) { + saveData(); + // 存储完成清理 list + cachedDataList.clear(); + } + } + + /** + * 所有数据解析完成后,会调用此方法 + * @param context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 确保最后一批数据也持久化到数据库 + if (!cachedDataList.isEmpty()) { + saveData(); + cachedDataList.clear(); + } + log.info("所有Excel数据解析并导入完成!"); + } + + /** + * 批量保存数据到数据库 + * 使用MyBatis-Plus的saveBatch方法 + */ + @Transactional(rollbackFor = Exception.class) + public void saveData() { + if (!cachedDataList.isEmpty()) { + // 清除所有异常信息 重新导入 + service.remove(new QueryWrapper()); + // 第二个参数是批次大小 + boolean saveResult = service.saveBatch(cachedDataList, BATCH_COUNT); + if (saveResult) { + log.info("成功批量插入 {} 条数据。", cachedDataList.size()); + } else { + log.error("批量插入数据失败!"); + throw new BadRequestException("操作失败"); + } + } + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorHandlingMapper.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorHandlingMapper.java new file mode 100644 index 0000000..b6c7891 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorHandlingMapper.java @@ -0,0 +1,14 @@ +package org.nl.sys.modular.anomalyInfo.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; + +/** + * @author dsh + * 2025/12/29 + */ +@Mapper +public interface ErrorHandlingMapper extends BaseMapper { + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorInfoMapper.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorInfoMapper.java new file mode 100644 index 0000000..10db921 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/mapper/ErrorInfoMapper.java @@ -0,0 +1,14 @@ +package org.nl.sys.modular.anomalyInfo.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; + +/** + * @author dsh + * 2025/12/29 + */ +@Mapper +public interface ErrorInfoMapper extends BaseMapper { + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/provider/ErrorInfoAPIProvider.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/provider/ErrorInfoAPIProvider.java new file mode 100644 index 0000000..836fecf --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/provider/ErrorInfoAPIProvider.java @@ -0,0 +1,36 @@ +package org.nl.sys.modular.anomalyInfo.provider; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.nl.api.sys.anomalyInfo.api.ErrorInfoAPI; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; +import org.nl.sys.modular.anomalyInfo.service.ErrorInfoService; +import org.springframework.stereotype.Service; + +/** + * @author dsh + * 2025/12/30 + */ +@Slf4j +@Service +public class ErrorInfoAPIProvider implements ErrorInfoAPI { + + @Resource + private ErrorInfoService errorInfoService; + + @Override + public JSONObject queryErrorInfoByCode(Integer code) { + if (ObjectUtil.isEmpty(code)){ + log.info("异常码不能为空"); + return null; + } + ErrorInfo errorInfo = errorInfoService.getOne(new LambdaQueryWrapper<>(ErrorInfo.class) + .eq(ErrorInfo::getError_code,code) + ); + return errorInfo == null ? null : JSONObject.parseObject(JSONObject.toJSONString(errorInfo)); + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/AnomalyInfoService.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/AnomalyInfoService.java new file mode 100644 index 0000000..012e536 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/AnomalyInfoService.java @@ -0,0 +1,17 @@ +package org.nl.sys.modular.anomalyInfo.service; + +import org.nl.sys.modular.anomalyInfo.dto.ErrorDataDto; + +/** + * @author dsh + * 2025/12/29 + */ +public interface AnomalyInfoService { + + /** + * 根据异常编码查询处理方法 + * @param code + * @return + */ + ErrorDataDto queryErrorDataByCode(String code); +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorHandlingService.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorHandlingService.java new file mode 100644 index 0000000..359b9dd --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorHandlingService.java @@ -0,0 +1,12 @@ +package org.nl.sys.modular.anomalyInfo.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; + +/** + * @author dsh + * 2025/12/29 + */ +public interface ErrorHandlingService extends IService { + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorInfoService.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorInfoService.java new file mode 100644 index 0000000..928b49b --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/ErrorInfoService.java @@ -0,0 +1,11 @@ +package org.nl.sys.modular.anomalyInfo.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; + +/** + * @author dsh + * 2025/12/29 + */ +public interface ErrorInfoService extends IService { +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/AnomalyInfoServiceImpl.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/AnomalyInfoServiceImpl.java new file mode 100644 index 0000000..7c56358 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/AnomalyInfoServiceImpl.java @@ -0,0 +1,47 @@ +package org.nl.sys.modular.anomalyInfo.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import jakarta.annotation.Resource; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; +import org.nl.sys.modular.anomalyInfo.dto.ErrorDataDto; +import org.nl.sys.modular.anomalyInfo.service.AnomalyInfoService; +import org.nl.sys.modular.anomalyInfo.mapper.ErrorHandlingMapper; +import org.nl.sys.modular.anomalyInfo.mapper.ErrorInfoMapper; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author dsh + * 2025/12/29 + */ +@Service +public class AnomalyInfoServiceImpl implements AnomalyInfoService { + + @Resource + private ErrorHandlingMapper errorHandlingMapper; + + @Resource + private ErrorInfoMapper errorInfoMapper; + + @Override + public ErrorDataDto queryErrorDataByCode(String code) { + + ErrorDataDto errorDataDto = new ErrorDataDto(); + // 异常信息 + ErrorInfo errorInfo = errorInfoMapper.selectOne(new LambdaQueryWrapper<>(ErrorInfo.class).eq(ErrorInfo::getError_code,code)); + BeanUtil.copyProperties(errorInfo,errorDataDto); + // 异常处理 + List errorHandlingList = errorHandlingMapper.selectList(new LambdaQueryWrapper<>(ErrorHandling.class).eq(ErrorHandling::getError_code,code)); + // 图文说明 + List graphicDescription = errorHandlingList.stream().filter(errorHandling -> errorHandling.getError_handling_type() == 1).collect(Collectors.toList()); + // 视频说明 + List videoDescription = errorHandlingList.stream().filter(errorHandling -> errorHandling.getError_handling_type() == 2).collect(Collectors.toList()); + errorDataDto.setGraphicDescription(graphicDescription); + errorDataDto.setVideoDescription(videoDescription); + return errorDataDto; + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorHandlingServiceImpl.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorHandlingServiceImpl.java new file mode 100644 index 0000000..ad57c0d --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorHandlingServiceImpl.java @@ -0,0 +1,15 @@ +package org.nl.sys.modular.anomalyInfo.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.nl.sys.modular.anomalyInfo.dao.ErrorHandling; +import org.nl.sys.modular.anomalyInfo.service.ErrorHandlingService; +import org.nl.sys.modular.anomalyInfo.mapper.ErrorHandlingMapper; +import org.springframework.stereotype.Service; + +/** + * @author dsh + * 2025/12/29 + */ +@Service +public class ErrorHandlingServiceImpl extends ServiceImpl implements ErrorHandlingService { +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorInfoServiceImpl.java b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorInfoServiceImpl.java new file mode 100644 index 0000000..e9a2fed --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/anomalyInfo/service/impl/ErrorInfoServiceImpl.java @@ -0,0 +1,16 @@ +package org.nl.sys.modular.anomalyInfo.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.nl.sys.modular.anomalyInfo.dao.ErrorInfo; +import org.nl.sys.modular.anomalyInfo.service.ErrorInfoService; +import org.nl.sys.modular.anomalyInfo.mapper.ErrorInfoMapper; +import org.springframework.stereotype.Service; + +/** + * @author dsh + * 2025/12/29 + */ +@Service +public class ErrorInfoServiceImpl extends ServiceImpl implements ErrorInfoService { + +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/controller/SecurityController.java b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/controller/SecurityController.java new file mode 100644 index 0000000..0ec21b0 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/controller/SecurityController.java @@ -0,0 +1,30 @@ +package org.nl.sys.modular.secutiry.controller; + +import jakarta.annotation.Resource; +import org.nl.logging.annotation.Log; +import org.nl.sys.modular.secutiry.param.SecurityParam; +import org.nl.sys.modular.secutiry.service.SecurityService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author dsh + * 2025/12/30 + */ +@RestController +@RequestMapping("/security") +public class SecurityController { + + @Resource + private SecurityService securityService; + + @PostMapping("/verifyPasswords") + @Log("校验显示屏密码") + public ResponseEntity verifyPasswords(@RequestBody SecurityParam param){ + return new ResponseEntity<>(securityService.verifyPasswords(param.getPassword()), HttpStatus.OK); + } +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/param/SecurityParam.java b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/param/SecurityParam.java new file mode 100644 index 0000000..5f33173 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/param/SecurityParam.java @@ -0,0 +1,18 @@ +package org.nl.sys.modular.secutiry.param; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author dsh + * 2025/12/30 + */ +@Data +public class SecurityParam { + + /** + * 密码 + */ + @NotBlank(message = "密码不能为空") + private String password; +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/SecurityService.java b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/SecurityService.java new file mode 100644 index 0000000..8a5f87f --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/SecurityService.java @@ -0,0 +1,12 @@ +package org.nl.sys.modular.secutiry.service; + +import org.nl.response.WebResponse; + +/** + * @author dsh + * 2025/12/30 + */ +public interface SecurityService { + + WebResponse verifyPasswords(String password); +} diff --git a/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/impl/SecurityServiceImpl.java b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/impl/SecurityServiceImpl.java new file mode 100644 index 0000000..be290e6 --- /dev/null +++ b/nl-business-sys/src/main/java/org/nl/sys/modular/secutiry/service/impl/SecurityServiceImpl.java @@ -0,0 +1,35 @@ +package org.nl.sys.modular.secutiry.service.impl; + +import cn.dev33.satoken.secure.SaSecureUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import jakarta.annotation.Resource; +import lombok.SneakyThrows; +import org.nl.api.setting.api.SettingAPI; +import org.nl.exception.BadRequestException; +import org.nl.response.WebResponse; +import org.nl.sys.modular.secutiry.service.SecurityService; +import org.nl.util.RsaUtils; +import org.springframework.stereotype.Service; + +/** + * @author dsh + * 2025/12/30 + */ +@Service +public class SecurityServiceImpl implements SecurityService { + + @Resource + private SettingAPI settingAPI; + + @Override + @SneakyThrows + public WebResponse verifyPasswords(String password) { + String new_password = RsaUtils.decryptByPrivateKey(RsaUtils.privateKey,password); + JSONObject setting = settingAPI.querySettingParamByCode("password").getJSONObject("data"); + if (ObjectUtil.isEmpty(setting) || !setting.getString("value").equals(SaSecureUtil.md5BySalt(new_password,"salt"))) { + throw new BadRequestException("密码错误"); + } + return WebResponse.requestOk(); + } +} diff --git a/nl-common/pom.xml b/nl-common/pom.xml index 36f5bb8..473365d 100644 --- a/nl-common/pom.xml +++ b/nl-common/pom.xml @@ -71,5 +71,11 @@ com.google.zxing javase + + + + cn.dev33 + sa-token-spring-boot3-starter + diff --git a/nl-common/src/main/java/org/nl/util/FileConstant.java b/nl-common/src/main/java/org/nl/util/FileConstant.java new file mode 100644 index 0000000..de63394 --- /dev/null +++ b/nl-common/src/main/java/org/nl/util/FileConstant.java @@ -0,0 +1,23 @@ +package org.nl.util; + +import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author dsh + * 2025/12/29 + */ +@Component +public class FileConstant { + + public static String ERROR_IMAGE_PATH = ""; + + @Resource + private FileProperties properties; + + @Value("${customize.errorImage-dir}") + public void setErrorImagePath(String errorImagePath) { + FileConstant.ERROR_IMAGE_PATH = properties.getPath().getPath()+errorImagePath; + } +} diff --git a/nl-common/src/main/java/org/nl/util/ParseZip.java b/nl-common/src/main/java/org/nl/util/ParseZip.java new file mode 100644 index 0000000..a6fd6ef --- /dev/null +++ b/nl-common/src/main/java/org/nl/util/ParseZip.java @@ -0,0 +1,128 @@ +package org.nl.util; + +import lombok.extern.slf4j.Slf4j; +import org.nl.exception.BadRequestException; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * @author dsh + * 2025/12/29 + */ +@Slf4j +@Service +public class ParseZip { + + /** + * 处理上传的异常文件 + * @param file + * @throws IOException + */ + public void processCompressedFile(MultipartFile file) throws IOException { + List skippedFiles = new ArrayList<>(); + + String filename = file.getOriginalFilename(); + String extension = filename.substring(filename.lastIndexOf(".")); + + try (InputStream inputStream = file.getInputStream()) { + if (extension.toLowerCase().equals(".zip")) { + extractZipFile(inputStream, skippedFiles); + } else { + throw new BadRequestException("不支持的压缩格式: " + extension); + } + } + } + + /** + * 解压上传异常图片压缩文件 + * @param inputStream + * @param skippedFiles + * @throws IOException + */ + private void extractZipFile(InputStream inputStream, List skippedFiles) + throws IOException { + int processedCount = 0; + int skippedCount = 0; + + try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) { + ZipEntry entry; + while ((entry = zipInputStream.getNextEntry()) != null) { + if (!entry.isDirectory() && isImageFile(entry.getName())) { + String filename = new File(entry.getName()).getName(); + + if (isFileExists(filename)) { + skippedFiles.add(filename); + skippedCount++; + continue; + } + + if (saveImageFile(zipInputStream, filename)) { + processedCount++; + } + } + zipInputStream.closeEntry(); + } + } + log.info("处理文件数:{},跳过文件数:{},跳过文件名称集合:{}",processedCount,skippedCount,skippedFiles); + } + + /** + * 保存图片文件到目录 + * @param inputStream + * @param filename + * @return + */ + private boolean saveImageFile(InputStream inputStream, String filename) { + try { + File outputFile = new File(FileConstant.ERROR_IMAGE_PATH + "/" + filename); + + // 确保目录存在 + File parentDir = outputFile.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + + Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + return true; + } catch (IOException e) { + log.error("保存文件失败: " + filename, e); + return false; + } + } + + /** + * 判断是否是图片文件或者视频文件 + * @param filename + * @return + */ + private boolean isImageFile(String filename) { + String lowerCaseFilename = filename.toLowerCase(); + return lowerCaseFilename.endsWith(".jpg") || + lowerCaseFilename.endsWith(".jpeg") || + lowerCaseFilename.endsWith(".png") || + lowerCaseFilename.endsWith(".gif") || + lowerCaseFilename.endsWith(".bmp") || + lowerCaseFilename.endsWith(".webp")|| + lowerCaseFilename.endsWith(".mp4"); + } + + /** + * 查看文件名是否有重名 + * @param filename + * @return + */ + private boolean isFileExists(String filename) { + File targetFile = new File(FileConstant.ERROR_IMAGE_PATH+ "/" + filename); + return targetFile.exists(); + } +} diff --git a/nl-common/src/main/java/org/nl/util/RsaUtils.java b/nl-common/src/main/java/org/nl/util/RsaUtils.java new file mode 100644 index 0000000..a7c9a8b --- /dev/null +++ b/nl-common/src/main/java/org/nl/util/RsaUtils.java @@ -0,0 +1,90 @@ +package org.nl.util; + +import org.apache.tomcat.util.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; + +/** + * @author liejiu + */ +@Component +public class RsaUtils { + + public static String privateKey; + + @Value("${rsa.private_key}") + public void setPrivateKey(String privateKey) { + RsaUtils.privateKey = privateKey; + } + + public static void main(String[] args) throws Exception { + System.out.println("\n"); + RsaKeyPair keyPair = generateKeyPair(); + System.out.println("公钥:" + keyPair.getPublicKey()); + System.out.println("私钥:" + keyPair.getPrivateKey()); + } + + /** + * 构建RSA密钥对 + * + * @return / + * @throws NoSuchAlgorithmException / + */ + public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded()); + String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); + return new RsaKeyPair(publicKeyString, privateKeyString); + } + + /** + * RSA密钥对对象 + */ + public static class RsaKeyPair { + + private final String publicKey; + private final String privateKey; + + public RsaKeyPair(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + } + + /** + * 私钥解密 + * + * @param privateKeyText 私钥 + * @param text 待解密的文本 + * @return / + * @throws Exception / + */ + public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] result = cipher.doFinal(Base64.decodeBase64(text)); + return new String(result); + } +}