From a6f7d83ecb85d4e4039517d91347c5945b0e97f1 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Wed, 12 Mar 2025 15:07:12 +0800 Subject: [PATCH] =?UTF-8?q?3.12=20=E4=BB=8Ebing=E7=88=AC=E8=99=AB=EF=BC=8C?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E4=BC=A0=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 ++ .../controller/PictureController.java | 13 +++ .../picture/PictureUploadByBatchRequest.java | 29 +++++++ .../dto/picture/PictureUploadRequest.java | 5 ++ .../service/PictureService.java | 21 ++++- .../service/impl/PictureServiceImpl.java | 83 +++++++++++++++++-- 6 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadByBatchRequest.java diff --git a/pom.xml b/pom.xml index 0ac29a8..7468a95 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,12 @@ cos_api 5.6.227 + + + org.jsoup + jsoup + 1.15.3 + com.mysql mysql-connector-j diff --git a/src/main/java/edu/whut/smilepicturebackend/controller/PictureController.java b/src/main/java/edu/whut/smilepicturebackend/controller/PictureController.java index 7a831fa..714ec0f 100644 --- a/src/main/java/edu/whut/smilepicturebackend/controller/PictureController.java +++ b/src/main/java/edu/whut/smilepicturebackend/controller/PictureController.java @@ -223,4 +223,17 @@ public class PictureController { pictureService.doPictureReview(pictureReviewRequest, loginUser); return ResultUtils.success(true); } + + /** + * 批量抓取并创建图片 + */ + @PostMapping("/upload/batch") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse uploadPictureByBatch(@RequestBody PictureUploadByBatchRequest pictureUploadByBatchRequest, + HttpServletRequest request) { + ThrowUtils.throwIf(pictureUploadByBatchRequest == null, ErrorCode.PARAMS_ERROR); + User loginUser = userService.getLoginUser(request); + int uploadCount = pictureService.uploadPictureByBatch(pictureUploadByBatchRequest, loginUser); + return ResultUtils.success(uploadCount); + } } diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadByBatchRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadByBatchRequest.java new file mode 100644 index 0000000..679ce6f --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadByBatchRequest.java @@ -0,0 +1,29 @@ +package edu.whut.smilepicturebackend.model.dto.picture; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 批量导入图片请求 + */ +@Data +public class PictureUploadByBatchRequest implements Serializable { + + /** + * 搜索词 + */ + private String searchText; + + /** + * 抓取数量 + */ + private Integer count = 20; + + /** + * 图片名称前缀 + */ + private String namePrefix; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadRequest.java index 1172c90..43bce23 100644 --- a/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadRequest.java +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/picture/PictureUploadRequest.java @@ -22,5 +22,10 @@ public class PictureUploadRequest implements Serializable { */ private String fileUrl; + /** + * 图片名称 + */ + private String picName; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/service/PictureService.java b/src/main/java/edu/whut/smilepicturebackend/service/PictureService.java index 95d78de..e600e8a 100644 --- a/src/main/java/edu/whut/smilepicturebackend/service/PictureService.java +++ b/src/main/java/edu/whut/smilepicturebackend/service/PictureService.java @@ -4,10 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import edu.whut.smilepicturebackend.model.dto.picture.PictureEditRequest; -import edu.whut.smilepicturebackend.model.dto.picture.PictureQueryRequest; -import edu.whut.smilepicturebackend.model.dto.picture.PictureReviewRequest; -import edu.whut.smilepicturebackend.model.dto.picture.PictureUploadRequest; +import edu.whut.smilepicturebackend.model.dto.picture.*; import edu.whut.smilepicturebackend.model.entity.Picture; import edu.whut.smilepicturebackend.model.entity.User; import edu.whut.smilepicturebackend.model.vo.PictureVO; @@ -80,5 +77,21 @@ public interface PictureService extends IService { */ void doPictureReview(PictureReviewRequest pictureReviewRequest, User loginUser); + /** + * 填充审核参数 + * + * @param picture + * @param loginUser + */ void fillReviewParams(Picture picture, User loginUser); + + /** + * 批量抓取和创建图片 + * + * @param pictureUploadByBatchRequest + * @param loginUser + * @return 成功创建的图片数 + */ + Integer uploadPictureByBatch(PictureUploadByBatchRequest pictureUploadByBatchRequest, + User loginUser); } diff --git a/src/main/java/edu/whut/smilepicturebackend/service/impl/PictureServiceImpl.java b/src/main/java/edu/whut/smilepicturebackend/service/impl/PictureServiceImpl.java index ce4d7bb..afe24da 100644 --- a/src/main/java/edu/whut/smilepicturebackend/service/impl/PictureServiceImpl.java +++ b/src/main/java/edu/whut/smilepicturebackend/service/impl/PictureServiceImpl.java @@ -17,10 +17,7 @@ import edu.whut.smilepicturebackend.manager.upload.FilePictureUpload; import edu.whut.smilepicturebackend.manager.upload.PictureUploadTemplate; import edu.whut.smilepicturebackend.manager.upload.UrlPictureUpload; import edu.whut.smilepicturebackend.mapper.PictureMapper; -import edu.whut.smilepicturebackend.model.dto.picture.PictureEditRequest; -import edu.whut.smilepicturebackend.model.dto.picture.PictureQueryRequest; -import edu.whut.smilepicturebackend.model.dto.picture.PictureReviewRequest; -import edu.whut.smilepicturebackend.model.dto.picture.PictureUploadRequest; +import edu.whut.smilepicturebackend.model.dto.picture.*; import edu.whut.smilepicturebackend.model.entity.Picture; import edu.whut.smilepicturebackend.model.entity.User; import edu.whut.smilepicturebackend.model.enums.PictureReviewStatusEnum; @@ -30,11 +27,17 @@ import edu.whut.smilepicturebackend.model.vo.UserVO; import edu.whut.smilepicturebackend.service.PictureService; import edu.whut.smilepicturebackend.service.UserService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; + import javax.servlet.http.HttpServletRequest; +import java.io.IOException; import java.util.Date; import java.util.List; import java.util.Map; @@ -46,6 +49,7 @@ import java.util.stream.Collectors; * @description 针对表【picture(图片)】的数据库操作Service实现 * @createDate 2025-06-11 11:23:11 */ +@Slf4j @Service @RequiredArgsConstructor public class PictureServiceImpl extends ServiceImpl @@ -105,6 +109,13 @@ public class PictureServiceImpl extends ServiceImpl Picture picture = new Picture(); // 复制同名属性(url、name、picSize、picWidth、picHeight、picScale、picFormat) BeanUtils.copyProperties(uploadPictureResult, picture); + // 支持外层pictureUploadRequest传递图片名称 + picture.setName( + StrUtil.blankToDefault( + pictureUploadRequest == null ? null : pictureUploadRequest.getPicName(), + uploadPictureResult.getName() + ) + ); picture.setUserId(loginUser.getId()); // 补充审核参数 this.fillReviewParams(picture, loginUser); @@ -292,6 +303,68 @@ public class PictureServiceImpl extends ServiceImpl picture.setReviewStatus(PictureReviewStatusEnum.REVIEWING.getValue()); } } + + //爬取网落图片,可以用ai分析标签 + @Override + public Integer uploadPictureByBatch(PictureUploadByBatchRequest pictureUploadByBatchRequest, User loginUser) { + // 校验参数 + String searchText = pictureUploadByBatchRequest.getSearchText(); + Integer count = pictureUploadByBatchRequest.getCount(); + ThrowUtils.throwIf(count > 30, ErrorCode.PARAMS_ERROR, "最多 30 条"); + // 名称前缀默认等于搜索关键词 + String namePrefix = pictureUploadByBatchRequest.getNamePrefix(); + if (StrUtil.isBlank(namePrefix)) { + namePrefix = searchText; + } + // 抓取内容 + String fetchUrl = String.format("https://cn.bing.com/images/async?q=%s&mmasync=1", searchText); + //最全的html文档 + Document document; + try { + document = Jsoup.connect(fetchUrl).get(); + } catch (IOException e) { + log.error("获取页面失败", e); + throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取页面失败"); + } + // 解析内容 + Element div = document.getElementsByClass("dgControl").first(); + if (ObjUtil.isEmpty(div)) { + throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取元素失败"); + } + Elements imgElementList = div.select("img.mimg"); + // 遍历元素,依次处理上传图片 + int uploadCount = 0; + for (Element imgElement : imgElementList) { + String fileUrl = imgElement.attr("src"); + if (StrUtil.isBlank(fileUrl)) { + //并不是所有图片链接都是正确的 + log.info("当前链接为空,已跳过:{}", fileUrl); + continue; + } + // 处理图片的地址,防止转义或者和对象存储冲突的问题 + // codefather.cn?yupi=dog,应该只保留 codefather.cn + int questionMarkIndex = fileUrl.indexOf("?"); + if (questionMarkIndex > -1) { + fileUrl = fileUrl.substring(0, questionMarkIndex); + } + // 上传图片 + PictureUploadRequest pictureUploadRequest = new PictureUploadRequest(); + pictureUploadRequest.setFileUrl(fileUrl); + pictureUploadRequest.setPicName(namePrefix + (uploadCount + 1)); + try { + PictureVO pictureVO = this.uploadPicture(fileUrl, pictureUploadRequest, loginUser); + log.info("图片上传成功,id = {}", pictureVO.getId()); + uploadCount++; + } catch (Exception e) { + log.error("图片上传失败", e); + continue; + } + if (uploadCount >= count) { + break; + } + } + return uploadCount; + } }