From da144b7c6a4fd17ff14df7d490411fc5bf6d8a60 Mon Sep 17 00:00:00 2001 From: MichaelWin Date: Fri, 6 Mar 2026 11:28:15 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E3=80=90=E6=94=B9=E8=BF=9B=E3=80=91?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E5=BC=82=E5=B8=B8=E6=8D=95=E8=8E=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/handler/GlobalExceptionHandler.java | 37 +++++++++++++++++-- .../resources/i18n/messages_en_US.properties | 1 + .../resources/i18n/messages_zh_CN.properties | 1 + 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/corewing/app/handler/GlobalExceptionHandler.java b/src/main/java/com/corewing/app/handler/GlobalExceptionHandler.java index fa4f34f..9a63431 100644 --- a/src/main/java/com/corewing/app/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/corewing/app/handler/GlobalExceptionHandler.java @@ -5,10 +5,16 @@ import com.corewing.app.common.Result; import com.corewing.app.util.I18nUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import java.util.stream.Collectors; + /** * 全局异常处理器 */ @@ -46,14 +52,39 @@ public class GlobalExceptionHandler { return Result.error(HttpStatus.UNAUTHORIZED.value(), message); } + /** + * 处理 @Valid 参数校验异常(RequestBody 参数) + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + // 获取第一个错误信息 + String errorMessage = e.getBindingResult().getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining("; ")); + return Result.error(HttpStatus.BAD_REQUEST.value(), errorMessage); + } + + /** + * 处理 @Validated 参数校验异常(RequestParam/PathVariable 参数) + */ + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleConstraintViolationException(ConstraintViolationException e) { + // 获取第一个错误信息 + String errorMessage = e.getConstraintViolations().stream() + .map(ConstraintViolation::getMessage) + .collect(Collectors.joining("; ")); + return Result.error(HttpStatus.BAD_REQUEST.value(), errorMessage); + } + /** * 处理其他异常 */ @ExceptionHandler(Exception.class) -// @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public Result handleException(Exception e) { - log.error(e.getMessage()); + log.error("系统异常: ", e); return Result.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), - e.getMessage()); + I18nUtil.getMessage("error.system")); } } diff --git a/src/main/resources/i18n/messages_en_US.properties b/src/main/resources/i18n/messages_en_US.properties index 7e7ff3d..55ec8c1 100644 --- a/src/main/resources/i18n/messages_en_US.properties +++ b/src/main/resources/i18n/messages_en_US.properties @@ -64,6 +64,7 @@ error.token.replaced=Account has been logged in elsewhere error.token.kicked.out=Account has been kicked offline error.not.login=Not logged in, please login first error.server.internal=Internal server error: {0} +error.system=System error, please try again later # ==================== Utility Classes ==================== # Redis Utility diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties index eedf7cf..ff4bab7 100644 --- a/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -64,6 +64,7 @@ error.token.replaced=账号已在其他地方登录 error.token.kicked.out=账号已被踢下线 error.not.login=未登录,请先登录 error.server.internal=服务器内部错误:{0} +error.system=系统错误,请稍后重试 # ==================== 工具类 ==================== # Redis工具类 From 84594dda48c6504e0a74bfd6b6faae06a6a21b84 Mon Sep 17 00:00:00 2001 From: MichaelWin Date: Fri, 6 Mar 2026 11:28:40 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91?= =?UTF-8?q?=E5=9B=BA=E4=BB=B6=E7=89=88=E6=9C=AC=E5=8D=87=E7=BA=A7=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/dto/FirmwareVersionRequest.java | 23 +++++++++++++ .../com/corewing/app/entity/Firmware.java | 15 +++++++++ .../modules/app/AppFirmwareController.java | 26 ++++++++++++--- .../corewing/app/service/FirmwareService.java | 8 +++++ .../app/service/impl/FirmwareServiceImpl.java | 32 +++++++++++++++++++ src/main/resources/application.properties | 4 +-- 6 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/corewing/app/dto/FirmwareVersionRequest.java diff --git a/src/main/java/com/corewing/app/dto/FirmwareVersionRequest.java b/src/main/java/com/corewing/app/dto/FirmwareVersionRequest.java new file mode 100644 index 0000000..dc16d48 --- /dev/null +++ b/src/main/java/com/corewing/app/dto/FirmwareVersionRequest.java @@ -0,0 +1,23 @@ +package com.corewing.app.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class FirmwareVersionRequest { + + @ApiModelProperty(value = "型号id", required = true) + @NotNull(message = "型号不能为空") + private Integer modelId; + + @ApiModelProperty(value = "版本号", required = true) + @NotNull(message = "版本号不能为空") + private String version; + + @ApiModelProperty(value = "固件类型", required = true) + @NotNull(message = "固件类型不能为空") + private Integer firmwareType; + +} diff --git a/src/main/java/com/corewing/app/entity/Firmware.java b/src/main/java/com/corewing/app/entity/Firmware.java index 4dda9be..3de81f5 100644 --- a/src/main/java/com/corewing/app/entity/Firmware.java +++ b/src/main/java/com/corewing/app/entity/Firmware.java @@ -45,6 +45,21 @@ public class Firmware implements Serializable { */ private Integer firmwareType; + /** + * 模型id + */ + private String modelId; + + /** + * 版本校验id + */ + private Integer versionId; + + /** + * 版本号 + */ + private String version; + /** * 固件下载地址 */ diff --git a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java index dac0c92..638a455 100644 --- a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java +++ b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java @@ -5,20 +5,26 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.corewing.app.common.Result; import com.corewing.app.common.annotation.CommonLog; +import com.corewing.app.dto.FirmwareVersionRequest; import com.corewing.app.entity.Firmware; import com.corewing.app.service.FirmwareService; import com.corewing.app.util.I18nUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.util.StringUtils; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.validation.Valid; +import java.util.List; + /** * 固件 Controller */ @Api(tags = "固件接口") @RestController @RequestMapping("/firmware") +@Validated public class AppFirmwareController { private final FirmwareService firmwareService; @@ -84,8 +90,8 @@ public class AppFirmwareController { @CommonLog("查询所有固件集合") @ApiOperation("查询所有固件集合") @GetMapping("/list") - public Result> list() { - java.util.List list = firmwareService.list(); + public Result> list() { + List list = firmwareService.list(); return Result.success(list); } @@ -97,7 +103,7 @@ public class AppFirmwareController { @CommonLog("根据类型查询固件版本") @ApiOperation("根据类型查询固件版本") @GetMapping("/type/{firmwareType}") - public Result> listByType(@PathVariable Integer firmwareType) { + public Result> listByType(@PathVariable Integer firmwareType) { if (firmwareType == null) { return Result.error(I18nUtil.getMessage("firmware.type.required")); } @@ -107,7 +113,19 @@ public class AppFirmwareController { // 按版本号或创建时间倒序排列,最新版本在前 wrapper.orderByDesc("create_time"); - java.util.List list = firmwareService.list(wrapper); + List list = firmwareService.list(wrapper); return Result.success(list); } + + + /** + * 校验是否存在新固件 + * @return + */ + @CommonLog("校验是否存在新固件") + @ApiOperation("校验是否存在新固件") + @PostMapping("/checkVersion") + public Result checkVersion(@RequestBody @Valid FirmwareVersionRequest firmwareVersionRequest) { + return Result.success(firmwareService.checkVersion(firmwareVersionRequest)); + } } diff --git a/src/main/java/com/corewing/app/service/FirmwareService.java b/src/main/java/com/corewing/app/service/FirmwareService.java index bb57718..2945aba 100644 --- a/src/main/java/com/corewing/app/service/FirmwareService.java +++ b/src/main/java/com/corewing/app/service/FirmwareService.java @@ -3,6 +3,7 @@ package com.corewing.app.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.corewing.app.common.Result; +import com.corewing.app.dto.FirmwareVersionRequest; import com.corewing.app.entity.Firmware; import org.springframework.web.multipart.MultipartFile; @@ -40,4 +41,11 @@ public interface FirmwareService extends IService { * @return */ boolean removeData(Long id); + + /** + * 校验固件是否有新固件 + * @param firmwareVersionRequest + * @return + */ + Firmware checkVersion(FirmwareVersionRequest firmwareVersionRequest); } diff --git a/src/main/java/com/corewing/app/service/impl/FirmwareServiceImpl.java b/src/main/java/com/corewing/app/service/impl/FirmwareServiceImpl.java index c3ae948..c34d9a1 100644 --- a/src/main/java/com/corewing/app/service/impl/FirmwareServiceImpl.java +++ b/src/main/java/com/corewing/app/service/impl/FirmwareServiceImpl.java @@ -4,8 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.corewing.app.common.page.PageContext; +import com.corewing.app.dto.FirmwareVersionRequest; +import com.corewing.app.entity.BizDeviceCategory; import com.corewing.app.entity.Firmware; import com.corewing.app.mapper.FirmwareMapper; +import com.corewing.app.service.BizDeviceCategoryService; import com.corewing.app.service.FirmwareService; import com.corewing.app.util.OSSUploadUtil; import org.springframework.stereotype.Service; @@ -13,7 +16,9 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; import java.io.IOException; +import java.util.Objects; /** * 固件 Service 实现类 @@ -21,6 +26,9 @@ import java.io.IOException; @Service public class FirmwareServiceImpl extends ServiceImpl implements FirmwareService { + @Resource + private BizDeviceCategoryService bizDeviceCategoryService; + @Override public Page page(Firmware firmware) { Page page = PageContext.getDefaultPage(Firmware.class); @@ -63,6 +71,30 @@ public class FirmwareServiceImpl extends ServiceImpl i return false; } + @Override + public Firmware checkVersion(FirmwareVersionRequest firmwareVersionRequest) { + + // 根据型号id搜索到设备分类id + LambdaQueryWrapper categoryLambdaQueryWrapper = new LambdaQueryWrapper<>(); + categoryLambdaQueryWrapper.eq(BizDeviceCategory::getModelId, firmwareVersionRequest.getModelId()); + BizDeviceCategory deviceCategory = bizDeviceCategoryService.getOne(categoryLambdaQueryWrapper); + if(Objects.isNull(deviceCategory)){ + throw new RuntimeException("该设备型号不存在设备"); + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.ge(Firmware::getVersionId, firmwareVersionRequest.getVersion()); + wrapper.eq(Firmware::getModelId, deviceCategory.getId()); + wrapper.eq(Firmware::getFirmwareType, firmwareVersionRequest.getFirmwareType()); + wrapper.orderByDesc(Firmware::getVersionId); + wrapper.last("LIMIT 1"); + Firmware firmware = this.getOne(wrapper); + if (firmware == null) { + throw new RuntimeException("未找到匹配的固件版本"); + } + return firmware; + } + /** * 获取 URL 路径的最后一节(忽略查询参数 ? 和锚点 #) * @param urlStr URL字符串 diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eebba98..76c4960 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,9 +1,9 @@ # spring profiles configuration ######################################### -#spring.profiles.active=local +spring.profiles.active=local #spring.profiles.active=test -spring.profiles.active=prod +#spring.profiles.active=prod ######################################### # 应用服务 WEB 访问端口 From c0896c199d606aaa7e412c9a147d2973883660db Mon Sep 17 00:00:00 2001 From: MichaelWin Date: Fri, 6 Mar 2026 14:08:11 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E7=B1=BB=E5=9E=8B=EF=BC=8C=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=9B=BA=E4=BB=B6=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/app/AppFirmwareController.java | 43 ++++++++++++++++--- .../resources/i18n/messages_en_US.properties | 2 + .../resources/i18n/messages_zh_CN.properties | 2 + 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java index 638a455..4aad458 100644 --- a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java +++ b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java @@ -1,12 +1,15 @@ package com.corewing.app.modules.app; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.corewing.app.common.Result; import com.corewing.app.common.annotation.CommonLog; import com.corewing.app.dto.FirmwareVersionRequest; +import com.corewing.app.entity.BizDeviceCategory; import com.corewing.app.entity.Firmware; +import com.corewing.app.service.BizDeviceCategoryService; import com.corewing.app.service.FirmwareService; import com.corewing.app.util.I18nUtil; import io.swagger.annotations.Api; @@ -15,6 +18,7 @@ import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; @@ -27,11 +31,11 @@ import java.util.List; @Validated public class AppFirmwareController { - private final FirmwareService firmwareService; + @Resource + private FirmwareService firmwareService; - public AppFirmwareController(FirmwareService firmwareService) { - this.firmwareService = firmwareService; - } + @Resource + private BizDeviceCategoryService bizDeviceCategoryService; /** * 根据ID查询固件 @@ -96,7 +100,7 @@ public class AppFirmwareController { } /** - * 根据类型查询固件版本 + * 根据类型查询固件版本 【兼容旧版APP】 * * @param firmwareType 固件类型 */ @@ -117,6 +121,35 @@ public class AppFirmwareController { return Result.success(list); } + /** + * 根据类型查询固件版本 【兼容新版APP】 + * + * @param firmwareType 固件类型 + */ + @CommonLog("根据类型,型号查询固件版本") + @ApiOperation("根据类型,型号查询固件版本") + @GetMapping("/type/{firmwareType}/{modelId}") + public Result> listByType(@PathVariable Integer firmwareType, @PathVariable Integer modelId) { + if (firmwareType == null && modelId == null) { + return Result.error(I18nUtil.getMessage("firmware.type.or.model.required")); + } + + LambdaQueryWrapper categoryQueryWrapper = new LambdaQueryWrapper<>(); + categoryQueryWrapper.eq(BizDeviceCategory::getModelId, modelId); + BizDeviceCategory bizDeviceCategory = bizDeviceCategoryService.getOne(categoryQueryWrapper); + if(bizDeviceCategory == null) { + return Result.error(I18nUtil.getMessage("firmware.device.not.found")); + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(Firmware::getFirmwareType, firmwareType); + wrapper.eq(Firmware::getModelId, bizDeviceCategory.getId()); + // 按版本号或创建时间倒序排列,最新版本在前 + wrapper.orderByDesc(Firmware::getCreateTime); + + List list = firmwareService.list(wrapper); + return Result.success(list); + } /** * 校验是否存在新固件 diff --git a/src/main/resources/i18n/messages_en_US.properties b/src/main/resources/i18n/messages_en_US.properties index 55ec8c1..13c1821 100644 --- a/src/main/resources/i18n/messages_en_US.properties +++ b/src/main/resources/i18n/messages_en_US.properties @@ -144,3 +144,5 @@ firmware.update.success=Firmware updated successfully firmware.update.failed=Failed to update firmware firmware.not.found=Firmware not found firmware.type.required=Firmware type is required +firmware.type.or.model.required=Firmware type or model is required +firmware.device.not.found=Device not found diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties index ff4bab7..16f2ef2 100644 --- a/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -144,3 +144,5 @@ firmware.update.success=固件更新成功 firmware.update.failed=固件更新失败 firmware.not.found=固件不存在 firmware.type.required=固件类型不能为空 +firmware.type.or.model.required=固件类型或型号不能为空 +firmware.device.not.found=设备不存在 From e472a3207f9f25098c82fc289c0471470756fba2 Mon Sep 17 00:00:00 2001 From: MichaelWin Date: Fri, 6 Mar 2026 14:58:52 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E3=80=90=E6=94=B9=E8=BF=9B=E3=80=91?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=9B=BA=E4=BB=B6=E7=89=88=E6=9C=AC=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=BD=93=E5=89=8D=E7=89=88=E6=9C=AC=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../corewing/app/modules/app/AppFirmwareController.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java index 4aad458..4bbb9ec 100644 --- a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java +++ b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java @@ -126,10 +126,10 @@ public class AppFirmwareController { * * @param firmwareType 固件类型 */ - @CommonLog("根据类型,型号查询固件版本") - @ApiOperation("根据类型,型号查询固件版本") - @GetMapping("/type/{firmwareType}/{modelId}") - public Result> listByType(@PathVariable Integer firmwareType, @PathVariable Integer modelId) { + @CommonLog("根据类型,型号,当前版本查询固件版本") + @ApiOperation("根据类型,当前版本查询固件版本") + @GetMapping("/type/{firmwareType}/{modelId}/{softwareVersion}") + public Result> listByType(@PathVariable Integer firmwareType, @PathVariable Integer modelId, @PathVariable Integer softwareVersion) { if (firmwareType == null && modelId == null) { return Result.error(I18nUtil.getMessage("firmware.type.or.model.required")); } @@ -144,6 +144,7 @@ public class AppFirmwareController { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Firmware::getFirmwareType, firmwareType); wrapper.eq(Firmware::getModelId, bizDeviceCategory.getId()); + wrapper.ge(Firmware::getVersionId, softwareVersion); // 按版本号或创建时间倒序排列,最新版本在前 wrapper.orderByDesc(Firmware::getCreateTime);