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/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/java/com/corewing/app/modules/app/AppFirmwareController.java b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java index dac0c92..4bbb9ec 100644 --- a/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java +++ b/src/main/java/com/corewing/app/modules/app/AppFirmwareController.java @@ -1,31 +1,41 @@ 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; import io.swagger.annotations.ApiOperation; 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; + /** * 固件 Controller */ @Api(tags = "固件接口") @RestController @RequestMapping("/firmware") +@Validated public class AppFirmwareController { - private final FirmwareService firmwareService; + @Resource + private FirmwareService firmwareService; - public AppFirmwareController(FirmwareService firmwareService) { - this.firmwareService = firmwareService; - } + @Resource + private BizDeviceCategoryService bizDeviceCategoryService; /** * 根据ID查询固件 @@ -84,20 +94,20 @@ 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); } /** - * 根据类型查询固件版本 + * 根据类型查询固件版本 【兼容旧版APP】 * * @param firmwareType 固件类型 */ @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 +117,49 @@ public class AppFirmwareController { // 按版本号或创建时间倒序排列,最新版本在前 wrapper.orderByDesc("create_time"); - java.util.List list = firmwareService.list(wrapper); + List list = firmwareService.list(wrapper); return Result.success(list); } + + /** + * 根据类型查询固件版本 【兼容新版APP】 + * + * @param firmwareType 固件类型 + */ + @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")); + } + + 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.ge(Firmware::getVersionId, softwareVersion); + // 按版本号或创建时间倒序排列,最新版本在前 + wrapper.orderByDesc(Firmware::getCreateTime); + + 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 访问端口 diff --git a/src/main/resources/i18n/messages_en_US.properties b/src/main/resources/i18n/messages_en_US.properties index 7e7ff3d..13c1821 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 @@ -143,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 eedf7cf..16f2ef2 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工具类 @@ -143,3 +144,5 @@ firmware.update.success=固件更新成功 firmware.update.failed=固件更新失败 firmware.not.found=固件不存在 firmware.type.required=固件类型不能为空 +firmware.type.or.model.required=固件类型或型号不能为空 +firmware.device.not.found=设备不存在