2.6.获取缩略图预览地址接口 getIconUrl()
2.6.1参数分析:用户(userId)、图片尺寸(iconCode)、文件id(fileId)
因为这个接口是每个用户自己的缩略图,所以需要一个userId确定是哪个用户的缩略图,同时如果要找到缩略图的话需要storageObjectId和iconCode唯一确定,而storageObjectId是原图的,要拿到这个可以根据fileId和userId来唯一确定对应的那张图片。用一个fileResizeIconBo封装
2.6.2先在FileResizeIconController里写一个/image/getIconUrl方法,然后具体业务在service层实现。首先根据fileId在UserFile表获得userFile,然后通过auditStatus看审核状态如果审核失败的就调用getAuditFailIconUrl()审核通过的则拿到storageObjectId就通过getFileResizeIcon()先去查看是否有缩略图,如果没有就需要调用downloadImage()方法,而里面又需要传入containerId和objectId,因此就需要通过getStorageObjectById()方法拿到里面的storageObject。然后最后再将
最终的 containerId和objectId赋值然后再调用getDownloadUrl()方法生成缩略图下载地址。
/** * 获得缩略图生成地址 * @param userId * @param fileId * @param iconCode * @return */ @Override public String getIconUrl(String userId, String fileId, String iconCode){ //根据fileId先把userFile拿出来,为了拿到里面的storageObjectId UserFileBo userFile = cloud2TransService.getUserFileById(fileId); String storageObjectId = userFile.getStorageObjectId(); String fileName = userFile.getFileName(); String suffixName = fileName.substring(fileName.lastIndexOf(".")); //查看审核状态 if(userFile.getAuditStatus().equals(CommonConstant.FILE_AUDIT_FAIL)){ return getAuditFailIconUrl(); } //查询缩略图是否存在 FileResizeIcon fileResizeIcon = iFileResizeIconService.getFileResizeIcon(storageObjectId, iconCode); //不存在则要生成缩略图的时候需要containerId和objectId,所以根据storageObject拿到storageObject取出里面的元素 StorageObjectBo storageObject = cloud2TransService.getStorageObjectById(storageObjectId); String containerId; String objectId ; //不存在则生成缩略图 //1.下载原图 if(fileResizeIcon == null){ String srcFileName = iFileResizeIconService.downloadImage(storageObject.getContainerId(),storageObject.getObjectId(),suffixName); //原图下载失败 if(StringUtils.isBlank(suffixName)){ log.error("downloadResult error!"); return null; } //生成缩略图 FileResizeIcon newFileResizeIcon = iFileResizeIconService.imageThumbnailSave(iconCode, suffixName, srcFileName, storageObjectId, fileName); //文件为空或者文件生成失败 if(newFileResizeIcon == null){ log.error("imageThumbnailSave() error!"); return null; } objectId = newFileResizeIcon.getObjectId(); containerId = newFileResizeIcon.getContainerId(); }else{ //存在则直接生成缩略图下载地址 objectId = fileResizeIcon.getObjectId(); containerId = fileResizeIcon.getContainerId(); } ResultBody iconUrlResponse = cloud2TransService.getDownloadUrl(containerId, objectId); return iconUrlResponse.getData().toString(); }
2.7getAuditFailIconUrl() 获取审核失败的缩略图地址
2.7.1参数分析:无
2.7.2首先从常量池CommonConstant获取一个ICON_STORAGE_OBJECT_ID的审核不通过的常量id,先去查询是否存在这个storageObject
- 如果没有,则先下载已经准备好的缩略图然后uploadIcon()方法进行上传然后取出containerId和objectId去获得下载的地址
- 如果有则直接取出containerId和objectId去获得下载的地址
/** * 获取审核失败的照片图 * @return */ @Override public String getAuditFailIconUrl() { //查询默认图是否存在存储池 String iconStorageObjectId = CommonConstant.ICON_STORAGE_OBJECT_ID; StorageObjectBo iconStorageObject = cloud2TransService.getStorageObjectById(iconStorageObjectId); String containerId = ""; String objectId = ""; String srcFileName = ""; //不存在则从文件中获取违规图上传到存储池 if(iconStorageObject == null){ File file = null; try{ file = ResourceUtils.getFile("classpath:static/auditFail.jpg"); } catch (FileNotFoundException e) { e.printStackTrace(); } FileResizeIcon newFileResizeIcon = iFileResizeIconService.uploadIcon(null, iconStorageObjectId, "200_200", file, "auditFail.jpg"); containerId = newFileResizeIcon.getContainerId(); objectId = newFileResizeIcon.getObjectId(); }else{ containerId = iconStorageObject.getContainerId(); objectId = iconStorageObject.getObjectId(); } //生成缩略图下载地址 ResultBody iconUrlResponse = cloud2TransService.getDownloadUrl(containerId,objectId); return iconUrlResponse.getData().toString(); }
审核功能
流程图
数据库
开发流程
1.基础配置
1.1新生成一个audit的项目,配置application,修改名字,端口为9001,
1.2pom文件导入
<dependencies> <dependency> <groupId>org.example</groupId> <artifactId>cloud-photo-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> </dependencies>
1.3用代码生成工具根据tb_file_audit表生成基本类
1.4配置启动类,加上注解,实体表的主键上也加上@TableId(type = IdType.ASSIGN_UUID)
@EnableDiscoveryClient @SpringBootApplication @EnableFeignClients(basePackages = {"com.cloud.photo"}) @MapperScan(basePackages = {"com.cloud.photo.audit.mapper"}) @ComponentScan({"com.cloud.photo"})
2.接口开发
2.1.kfkaf消费审核列表
因为是从kfkaf里拿消息所以肯定是先创建一个AuditConsumer类负责消费审核列表的消息,再进行业务逻辑处理。在类上注解配上@Component
先拿出file_audit_topic主题里的审核消息,取出userFileId、fileMd5、fileName、fileSize、storageObjectId属性,相同文件只需要判断一次,因此根据md5判断是否审核过
- 如果没审核则组装一下然后入库加入人工审核列表,管理员则通过待审核列表去更新审核列表
- 如果已经过了审核则不需要做什么
- 如果没有过审核的则需要在userFile里修改审核状态然后执行updateUserFile()方法
/** * @Author:kkoneone11 * @name:AuditConsumer * @Date:2023/7/23 10:51 */ @Component public class AuditConsumer { @Autowired IFileAuditService iFileAuditService; @Autowired Cloud2TransService cloud2TransService; @KafkaListener(topics = {"file_audit_topic"}) public void onMessage(ConsumerRecord<String,Object> record){ // 消费的哪个topic、partition的消息,打印出消息内容 System.out.println("消费:"+record.topic()+"-"+record.partition()+"-"+record.value()); //组装一下需要的信息 Object value = record.value(); JSONObject jsonObject = JSONObject.parseObject(value.toString()); String userFileId = jsonObject.getString("userFileId"); String fileMd5 = jsonObject.getString("fileMd5"); String fileName = jsonObject.getString("fileName"); Integer fileSize = jsonObject.getInteger("fileSize"); String storageObjectId = jsonObject.getString("storageObjectId"); //根据md5查询是否在审核数据库里 FileAudit fileAudit = iFileAuditService.getOne(new QueryWrapper<FileAudit>().eq("md5", fileMd5), false); //1.未审核,不存在数据库中则入库 if(fileAudit == null){ //插入审核列表 FileAudit newFileAudit =new FileAudit(); newFileAudit.setAuditStatus(CommonConstant.FILE_AUDIT); newFileAudit.setFileName(fileName); newFileAudit.setMd5(fileMd5); newFileAudit.setFileSize(fileSize); newFileAudit.setCreateTime(LocalDateTime.now()); newFileAudit.setUserFileId(userFileId); newFileAudit.setStorageObjectId(storageObjectId); iFileAuditService.save(newFileAudit); //2.已经审核过了 }else if(fileAudit.getFileAuditId().equals(CommonConstant.FILE_AUDIT_ACCESS)){ //3.审核过且不通过,则修改状态并更新到数据库中 }else if(fileAudit.getAuditStatus().equals(CommonConstant.FILE_AUDIT_FAIL)){ //组装 UserFileBo userFileBo = new UserFileBo(); userFileBo.setUserFileId(userFileId); userFileBo.setAuditStatus(CommonConstant.FILE_AUDIT_FAIL); List<UserFileBo> userFileList = new ArrayList<>(); userFileList.add(userFileBo); cloud2TransService.updateUserFile(userFileList); } } }
2.2获得审核列表 /audit/getAuditLis Post
2.2.1参数分析:查询列表当然需要(current、pageSize),然后要需要展现一个待审核的列表(AuditStatusList)。
2.2.2因为未处理的审核列表和已经处理的审核列表用的都是同一个方法,因此先看pageBo里的AuditStatusList是否为空
- 如果不为空则表明要查询的是已经审核的列表,设置的查询为in
- 如果为空则表明要查询的是待审核的,返回查询待审核的列表即可,设置查询为eq
最后面设置page然后进行查询即可
2.3.更新审核状态 /audit/updateAuditStatus Post
2.3.1参数分析:待更改的对象列表idsList、要更改的状态auditStatus
2.3.2写一个updateAuditStatus()方法,然后具体处理业务放在service里,先从pageBo类拿出auditStatus和idsList。然后通过idsList查出fileAuditList列表,通过一个for循环给里面的fileAud对象标记上已审核的标记,然后再组装一个userFileBo。再后面对fileAuditList和userFileBoList进行更新。
** * <p> * 文件审核列表 服务实现类 * </p> * * @author kkoneone11 * @since 2023-07-23 */ @Service public class FileAuditServiceImpl extends ServiceImpl<FileAuditMapper, FileAudit> implements IFileAuditService { @Autowired private IFileAuditService iFileAuditService; @Autowired private Cloud2TransService cloud2TransService; @Override public Boolean updateAuditStatus(AuditPageBo auditPageBo) { Integer auditStatus = auditPageBo.getAuditStatus(); List<String> idsList = auditPageBo.getFileAuditIds(); List<UserFileBo> userFileBoList = new ArrayList<>(); List<FileAudit> fileAuditList = iFileAuditService.listByIds(idsList); for(FileAudit fileAudit : fileAuditList){ fileAudit.setAuditStatus(auditStatus); //组装UserFileBo去更新状态 UserFileBo userFileBo = new UserFileBo(); userFileBo.setAuditStatus(auditStatus); userFileBo.setStorageObjectId(fileAudit.getStorageObjectId()); userFileBoList.add(userFileBo); } Boolean updateResult = iFileAuditService.updateBatchById(fileAuditList); //审核不通过的才去更新更新文件列表审核状态 if(auditStatus.equals(CommonConstant.FILE_AUDIT_FAIL)){ updateResult = cloud2TransService.updateUserFile(userFileBoList); } return updateResult; } }