From a41f1f6085e39fe267f6ba39d17a7328fe969917 Mon Sep 17 00:00:00 2001 From: haozq <1611483981@qq.com> Date: Wed, 26 Nov 2025 16:17:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E9=9C=80=E6=B1=82=E4=BF=AE=E7=A8=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ImageCaptionController.java | 17 ++++++ .../bonus/business/domain/AlgorithmVo.java | 15 +++++ .../business/mapper/ImageCaptionMapper.java | 26 +++++++++ .../business/service/ImageCaptionService.java | 7 +++ .../service/impl/AlgorithmService.java | 24 +++++++- .../service/impl/ImageCaptionServiceImpl.java | 55 +++++++++++++++++-- .../mapper/business/ImageCaptionMapper.xml | 21 +++++++ .../java/com/bonus/file/minio/MinioUtil.java | 34 ++++++++++-- .../framework/config/ResourcesConfig.java | 1 + .../interceptor/ParamSecureHandler.java | 1 + .../interceptor/ReplayAttackInterceptor.java | 1 + .../framework/web/service/TokenService.java | 13 +++-- 12 files changed, 199 insertions(+), 16 deletions(-) diff --git a/bonus-business/src/main/java/com/bonus/business/controller/ImageCaptionController.java b/bonus-business/src/main/java/com/bonus/business/controller/ImageCaptionController.java index 10cfab7..77b4291 100644 --- a/bonus-business/src/main/java/com/bonus/business/controller/ImageCaptionController.java +++ b/bonus-business/src/main/java/com/bonus/business/controller/ImageCaptionController.java @@ -105,6 +105,23 @@ public class ImageCaptionController extends BaseController { } } + /** + * 手动标注 + * @param params + * @return + */ + @PostMapping("/manualAnnotation") + public AjaxResult manualAnnotation(@RequestBody AlgorithmVo vo) { + try{ +// ObjectMapper objectMapper = new ObjectMapper(); +// AlgorithmVo vo = objectMapper.readValue(params, AlgorithmVo.class); + return service.manualAnnotation(vo); + }catch (Exception e){ + return AjaxResult.error("请求参数异常!"); + } + } + + /** * 新增图片标注 * @param multipartFile diff --git a/bonus-business/src/main/java/com/bonus/business/domain/AlgorithmVo.java b/bonus-business/src/main/java/com/bonus/business/domain/AlgorithmVo.java index f1d2e2a..4e4c2c7 100644 --- a/bonus-business/src/main/java/com/bonus/business/domain/AlgorithmVo.java +++ b/bonus-business/src/main/java/com/bonus/business/domain/AlgorithmVo.java @@ -10,8 +10,21 @@ import java.util.List; @Data public class AlgorithmVo { + /** + * 图片bast64 + */ + + private String bast64; + private String filePath; + + private String dataType; + + private String jsonData; + /** + * 备注 + */ private String remark; /** * 主键 @@ -65,6 +78,8 @@ public class AlgorithmVo { * 操作时间 */ private String createTime; + + private String type; /** * 操作人 */ diff --git a/bonus-business/src/main/java/com/bonus/business/mapper/ImageCaptionMapper.java b/bonus-business/src/main/java/com/bonus/business/mapper/ImageCaptionMapper.java index fbdc3c6..e4db4f7 100644 --- a/bonus-business/src/main/java/com/bonus/business/mapper/ImageCaptionMapper.java +++ b/bonus-business/src/main/java/com/bonus/business/mapper/ImageCaptionMapper.java @@ -124,4 +124,30 @@ public interface ImageCaptionMapper { * @param imageId */ void deleteFile(@Param("list") List imageId); + + /** + * 查询文件后缀 + * @param vo + * @return + */ + String getFilePath(AlgorithmVo vo); + + /** + * 修改文件路径 + * @param vo + */ + int updateFilePath(AlgorithmVo vo); + + /** + * 更新图片信息 + * @param vo + */ + void updateImageRecogeize(AlgorithmVo vo); + + /** + * 查询数据是否存在 + * @param vo + * @return + */ + int getImageRecogenize(AlgorithmVo vo); } diff --git a/bonus-business/src/main/java/com/bonus/business/service/ImageCaptionService.java b/bonus-business/src/main/java/com/bonus/business/service/ImageCaptionService.java index 7608ba3..3073b0f 100644 --- a/bonus-business/src/main/java/com/bonus/business/service/ImageCaptionService.java +++ b/bonus-business/src/main/java/com/bonus/business/service/ImageCaptionService.java @@ -77,4 +77,11 @@ public interface ImageCaptionService { * @return */ AjaxResult deleteFile(UserOperaVo vo); + + /** + * 图片手动不标注 + * @param vo + * @return + */ + AjaxResult manualAnnotation(AlgorithmVo vo); } diff --git a/bonus-business/src/main/java/com/bonus/business/service/impl/AlgorithmService.java b/bonus-business/src/main/java/com/bonus/business/service/impl/AlgorithmService.java index c9f8155..3362245 100644 --- a/bonus-business/src/main/java/com/bonus/business/service/impl/AlgorithmService.java +++ b/bonus-business/src/main/java/com/bonus/business/service/impl/AlgorithmService.java @@ -91,15 +91,23 @@ public class AlgorithmService { for (SysFile sysFile : fileList) { ImageRecognize vo = new ImageRecognize(); // vo.setContentImage("无标记"); + vo.setDataType("0"); vo.setImageId(sysFile.getId()); vo.setType("1"); vo.setImagePath(sysFile.getUrl()); list.add(vo); } } - - }catch (Exception e){ + for (SysFile sysFile : fileList) { + ImageRecognize vo = new ImageRecognize(); + // vo.setContentImage("无标记"); + vo.setDataType("0"); + vo.setImageId(sysFile.getId()); + vo.setType("1"); + vo.setImagePath(sysFile.getUrl()); + list.add(vo); + } log.error(e.getMessage(),e); } return list; @@ -150,6 +158,7 @@ public class AlgorithmService { for (SysFile sysFile : fileList) { ImageRecognize vo = new ImageRecognize(); vo.setOverallScore("0"); + vo.setDataType("0"); vo.setType("2"); vo.setContentImage(operaName); vo.setImageId(sysFile.getId()); @@ -158,6 +167,17 @@ public class AlgorithmService { } } }catch (Exception e){ + // 识别失败 + for (SysFile sysFile : fileList) { + ImageRecognize vo = new ImageRecognize(); + vo.setOverallScore("0"); + vo.setDataType("0"); + vo.setType("2"); + vo.setContentImage(operaName); + vo.setImageId(sysFile.getId()); + vo.setImagePath(sysFile.getUrl()); + list.add(vo); + } log.error(e.getMessage(),e); } return list; diff --git a/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java b/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java index 7b077a3..ae919a8 100644 --- a/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java +++ b/bonus-business/src/main/java/com/bonus/business/service/impl/ImageCaptionServiceImpl.java @@ -397,11 +397,6 @@ public class ImageCaptionServiceImpl implements ImageCaptionService { } -public AjaxResult uploadZip(){ - - - return AjaxResult.error("文件上传失败!"); -} /** @@ -548,6 +543,56 @@ public AjaxResult uploadZip(){ return AjaxResult.error("删除失败"); } + /** + * 手动标注 图片 + * @param vo + * @return + */ + @Override + public AjaxResult manualAnnotation(AlgorithmVo vo) { + try{ + String path="image/"+year+"/"+month+"/"+day+"/"; + String bast64=vo.getBast64(); + String suffix=mapper.getFilePath(vo); + int dotIndex = suffix.lastIndexOf('.'); + String fileSuffix=suffix; + if (dotIndex != -1) { // 确保找到了'.' + fileSuffix = suffix.substring(dotIndex + 1); + System.out.println("Extension: " + fileSuffix); + } else { + System.out.println("No extension found."); + } + //更新文件路径 + String filePath=minioUtil.uploadBast64(bast64,fileSuffix,path); + if(filePath==null){ + return AjaxResult.error("保存失败"); + } + vo.setDataType("1"); + vo.setFilePath(filePath); + int num= mapper.updateFilePath(vo); + int dataNum=mapper.getImageRecogenize(vo); + if(dataNum>0){ + mapper.updateImageRecogeize(vo); + if(num>0){ + return AjaxResult.success("保存成功"); + } + }else{ + ImageRecognize imageRecognize=new ImageRecognize(); + imageRecognize.setImageId(vo.getId()); + imageRecognize.setDataType("1"); + imageRecognize.setType("1"); + imageRecognize.setJsonData(vo.getJsonData()); + imageRecognize.setContentImage(vo.getType()); + mapper.addImageRecognize(imageRecognize); + return AjaxResult.success("保存成功"); + } + + }catch (Exception e){ + log.error(e.getMessage(),e); + } + return AjaxResult.error("保存失败"); + } + // 辅助方法:字节转可读格式 private String convertToHumanReadable(long bytes) { if (bytes < 1024) return bytes + " B"; diff --git a/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml b/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml index 2299da5..082aea3 100644 --- a/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml +++ b/bonus-business/src/main/resources/mapper/business/ImageCaptionMapper.xml @@ -78,6 +78,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{item} + + update tb_upload_file set bj_file_path=#{filePath} ,json_data=#{jsonData},data_type=#{dataType} + where id=#{id} + + + update tb_image_recognize set json_data=#{jsonData},data_type=#{dataType},content_image=#{type} + where image_id=#{id} + + + replace into tb_sure_file( diff --git a/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java b/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java index 7daa1e7..5e55ebc 100644 --- a/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java +++ b/bonus-file/src/main/java/com/bonus/file/minio/MinioUtil.java @@ -70,6 +70,9 @@ public class MinioUtil { } } + + + /** * 检查指定存储桶是否存在 * @param bucketName 存储桶名称 @@ -542,14 +545,13 @@ public class MinioUtil { if (!StringUtils.isEmpty(imageBase64)) { InputStream in = base64ToInputStream(imageBase64); return uploadFile( path, in); - } return null; } public static InputStream base64ToInputStream(String base64) { ByteArrayInputStream stream = null; try { - byte[] bytes = Base64.getEncoder().encode(base64.trim().getBytes()); + byte[] bytes = Base64.getDecoder().decode(base64.trim().getBytes()); stream = new ByteArrayInputStream(bytes); } catch (Exception e) { e.printStackTrace(); @@ -567,10 +569,11 @@ public class MinioUtil { @SneakyThrows(Exception.class) public SysFile uploadFile(String objectName, InputStream inputStream) { minioClient.putObject(PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(objectName).stream(inputStream, inputStream.available(), -1).build()); - return SysFile.builder() + SysFile file= SysFile.builder() .bucketName(minioConfig.getBucketName()) .url(objectName).build(); - + inputStream.close(); + return file; } /** @@ -688,5 +691,28 @@ public class MinioUtil { } } + /** + * 上传bast64文件 + * @param bast64 + */ + public String uploadBast64(String bast64,String suffix,String filePath) { + //上传 + if(bast64.contains(",")){ + // 2. 解析Base64前缀,获取图片格式(如png、jpg) + String imgPrefix = bast64.substring(0, bast64.indexOf(";base64,")); + if (StringUtils.isEmpty(suffix)) { + suffix = imgPrefix.substring(imgPrefix.lastIndexOf("/") + 1); // 从前缀提取后缀(如png) + } + String uuid = com.bonus.common.utils.StringUtils.randomUUID(); + String fileName=uuid+"."+suffix; + //保留纯净的bast64 + bast64 = bast64.split(",")[1]; + uploadImage(minioConfig.getBucketName(), bast64,filePath+fileName); + return filePath+fileName; + } + return null; + + + } } diff --git a/bonus-framework/src/main/java/com/bonus/framework/config/ResourcesConfig.java b/bonus-framework/src/main/java/com/bonus/framework/config/ResourcesConfig.java index f319522..5ca9cf9 100644 --- a/bonus-framework/src/main/java/com/bonus/framework/config/ResourcesConfig.java +++ b/bonus-framework/src/main/java/com/bonus/framework/config/ResourcesConfig.java @@ -67,6 +67,7 @@ public class ResourcesConfig implements WebMvcConfigurer registry.addInterceptor(replayAttackInterceptor) .addPathPatterns("/**") .excludePathPatterns("/caption/captchaImage") + .excludePathPatterns("/caption/image/caption/manualAnnotation") .excludePathPatterns("/caption/login") .excludePathPatterns("/caption/logout") .excludePathPatterns("/caption/getInfo") diff --git a/bonus-framework/src/main/java/com/bonus/framework/interceptor/ParamSecureHandler.java b/bonus-framework/src/main/java/com/bonus/framework/interceptor/ParamSecureHandler.java index 95e4679..1ee2b3a 100644 --- a/bonus-framework/src/main/java/com/bonus/framework/interceptor/ParamSecureHandler.java +++ b/bonus-framework/src/main/java/com/bonus/framework/interceptor/ParamSecureHandler.java @@ -31,6 +31,7 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor { static List ignoreUrlPatterns = new ArrayList<>(); static { ignoreUrlPatterns.add("/caption/captchaImage"); + ignoreUrlPatterns.add("/caption/image/caption/manualAnnotation"); ignoreUrlPatterns.add("/caption/login"); ignoreUrlPatterns.add("/caption/logout"); ignoreUrlPatterns.add("/caption/getInfo"); diff --git a/bonus-framework/src/main/java/com/bonus/framework/interceptor/ReplayAttackInterceptor.java b/bonus-framework/src/main/java/com/bonus/framework/interceptor/ReplayAttackInterceptor.java index a294e7f..c99aaa3 100644 --- a/bonus-framework/src/main/java/com/bonus/framework/interceptor/ReplayAttackInterceptor.java +++ b/bonus-framework/src/main/java/com/bonus/framework/interceptor/ReplayAttackInterceptor.java @@ -42,6 +42,7 @@ public class ReplayAttackInterceptor implements HandlerInterceptor { static { ignoreUrlPatterns.add("/caption/captchaImage"); + ignoreUrlPatterns.add("/caption/image/caption/manualAnnotation"); ignoreUrlPatterns.add("/caption/login"); ignoreUrlPatterns.add("/caption/logout"); ignoreUrlPatterns.add("/caption/getInfo"); diff --git a/bonus-framework/src/main/java/com/bonus/framework/web/service/TokenService.java b/bonus-framework/src/main/java/com/bonus/framework/web/service/TokenService.java index 86141d5..53b17db 100644 --- a/bonus-framework/src/main/java/com/bonus/framework/web/service/TokenService.java +++ b/bonus-framework/src/main/java/com/bonus/framework/web/service/TokenService.java @@ -108,12 +108,15 @@ public class TokenService // 单端在线校验:username -> uuid 映射需要与当前token匹配 String username = user.getUsername(); String mappedUuid = redisCache.getCacheObject(getUserTokenKey(username)); - if (StringUtils.isEmpty(mappedUuid) || !uuid.equals(mappedUuid)) - { - // 当前token已被挤下线或无效,标记前端可识别的提示 - request.setAttribute("forceLogoutByOtherDevice", Boolean.TRUE); - return null; + if(!"admin".equals(username)){ + if (StringUtils.isEmpty(mappedUuid) || !uuid.equals(mappedUuid)) + { + // 当前token已被挤下线或无效,标记前端可识别的提示 + request.setAttribute("forceLogoutByOtherDevice", Boolean.TRUE); + return null; + } } + return user; } catch (Exception e)