From 86f1df5e0859ee1d6a44c369a38a77f44e3ff210 Mon Sep 17 00:00:00 2001 From: ovo Date: Sun, 11 May 2025 19:15:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20[=E8=AF=BE=E7=A8=8B=E6=96=B0=E5=A2=9E]?= =?UTF-8?q?=E5=A4=84=E7=90=86ppt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 11 +- .../backend/controller/CommonController.java | 12 ++ .../backend/controller/CourseController.java | 11 +- .../backend/controller/MinioController.java | 10 ++ .../backend/controller/TeacherController.java | 1 - .../backend/factory/SectionVOFactory.java | 6 +- .../com/guwan/backend/pojo/dto/Courses.java | 62 ---------- .../pojo/dto/course/InsertCourseDTO.java | 20 ++++ .../response/courseDetail/BaseSectionVO.java | 1 + .../response/courseDetail/CourseDetailVO.java | 2 + .../response/courseDetail/PdfSectionVO.java | 1 - .../response/courseDetail/PptSectionVO.java | 2 +- .../response/courseDetail/VideoSectionVO.java | 1 - .../service/impl/ChallengesServiceImpl.java | 3 - .../service/impl/CourseServiceImpl.java | 6 +- .../com/guwan/backend/util/MinioUtil.java | 28 ++++- .../java/com/guwan/backend/util/PPTUtil.java | 106 ++++++++++++++++++ 17 files changed, 202 insertions(+), 81 deletions(-) delete mode 100644 src/main/java/com/guwan/backend/pojo/dto/Courses.java create mode 100644 src/main/java/com/guwan/backend/pojo/dto/course/InsertCourseDTO.java create mode 100644 src/main/java/com/guwan/backend/util/PPTUtil.java diff --git a/pom.xml b/pom.xml index 63377ff..fb3534b 100644 --- a/pom.xml +++ b/pom.xml @@ -407,7 +407,7 @@ org.apache.poi poi-ooxml - 5.2.3 + 5.4.1 org.apache.logging.log4j @@ -418,7 +418,7 @@ org.apache.poi poi-scratchpad - 5.2.3 + 5.4.1 org.apache.logging.log4j @@ -426,6 +426,13 @@ + + + org.apache.commons + commons-compress + 1.27.1 + + commons-io diff --git a/src/main/java/com/guwan/backend/controller/CommonController.java b/src/main/java/com/guwan/backend/controller/CommonController.java index 5f9bbc0..43907cc 100644 --- a/src/main/java/com/guwan/backend/controller/CommonController.java +++ b/src/main/java/com/guwan/backend/controller/CommonController.java @@ -8,6 +8,7 @@ import com.guwan.backend.common.Result; import com.guwan.backend.mongodb.*; import com.guwan.backend.pojo.entity.BookContent; import com.guwan.backend.util.MinioUtil; +import com.guwan.backend.util.PPTUtil; import dev.langchain4j.community.model.dashscope.QwenChatModel; import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel; import dev.langchain4j.model.chat.response.ChatResponse; @@ -65,6 +66,7 @@ public class CommonController { private final QwenStreamingChatModel qwenStreamingChatModel; private final TestDateRepository testDateRepository; private final TestDateDao testDateDao; + private final PPTUtil pptUtil; @PostMapping("/uploadFile") public Result uploadFile(String bucketName, MultipartFile file){ @@ -461,6 +463,16 @@ public class CommonController { ppt.close(); } + @GetMapping("/PPTToImageConverterMinio") + public void PPTToImageConverterMinio() throws IOException { + + List list = pptUtil.PPTToImageConverter(); + for (String s : list) { + System.out.println(s); + } + + } + @GetMapping("/videoDuration") public void VideoDuration() throws IOException { diff --git a/src/main/java/com/guwan/backend/controller/CourseController.java b/src/main/java/com/guwan/backend/controller/CourseController.java index 010f4c1..6f24956 100644 --- a/src/main/java/com/guwan/backend/controller/CourseController.java +++ b/src/main/java/com/guwan/backend/controller/CourseController.java @@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.guwan.backend.common.Result; import com.guwan.backend.common.SearchResult; +import com.guwan.backend.mybatis.query.LambdaQueryWrapperX; import com.guwan.backend.pojo.dto.BSCategory; +import com.guwan.backend.pojo.dto.course.InsertCourseDTO; import com.guwan.backend.pojo.entity.Course; import com.guwan.backend.pojo.entity.Teacher; import com.guwan.backend.pojo.response.CourseByAdminVO; @@ -131,7 +133,7 @@ public class CourseController { @RequestParam(required = false) String courseName) { Page page = new Page<>(pageNumber, size); - LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapperX().likeIfPresent(Course::getCategoryName, courseName); Page resultPage = this.courseService.page(page, lambdaQueryWrapper); @@ -159,5 +161,12 @@ public class CourseController { return SearchResult.success(courseByAdminVOS, resultPage.getTotal()); } + @PostMapping("/addCourse") + public Result addCourse(@RequestBody InsertCourseDTO insertCourseDTO) { + System.out.println("insertCourseDTO = " + insertCourseDTO); + return Result.success(); + } + + } diff --git a/src/main/java/com/guwan/backend/controller/MinioController.java b/src/main/java/com/guwan/backend/controller/MinioController.java index 3c3e2e4..75f5970 100644 --- a/src/main/java/com/guwan/backend/controller/MinioController.java +++ b/src/main/java/com/guwan/backend/controller/MinioController.java @@ -31,4 +31,14 @@ public class MinioController { return Result.success(url); } + @PostMapping("/courseSourceUpload") + public Result courseSourceUpload(@RequestPart("file") MultipartFile file) { + String bucketName = "file"; + String folder = "courseSource"; + String fileName = minioUtil.uploadFile(bucketName, file, folder); + String fileUrl = minioUtil.getFileUrl(bucketName, fileName); + String url = minioUtil.getUrl(fileUrl); + return Result.success(url); + } + } diff --git a/src/main/java/com/guwan/backend/controller/TeacherController.java b/src/main/java/com/guwan/backend/controller/TeacherController.java index 07f9a2b..dc54730 100644 --- a/src/main/java/com/guwan/backend/controller/TeacherController.java +++ b/src/main/java/com/guwan/backend/controller/TeacherController.java @@ -1,6 +1,5 @@ package com.guwan.backend.controller; - import com.guwan.backend.common.Result; import com.guwan.backend.pojo.entity.Teacher; import com.guwan.backend.service.TeacherService; diff --git a/src/main/java/com/guwan/backend/factory/SectionVOFactory.java b/src/main/java/com/guwan/backend/factory/SectionVOFactory.java index 889a781..effd9fd 100644 --- a/src/main/java/com/guwan/backend/factory/SectionVOFactory.java +++ b/src/main/java/com/guwan/backend/factory/SectionVOFactory.java @@ -27,13 +27,13 @@ public class SectionVOFactory { BeanUtils.copyProperties(section, video); video.setType("video"); video.setDuration(section.getDuration() + ":00"); - video.setUrl(section.getUrl()); + //video.setUrl(section.getUrl()); return video; case "pdf": PdfSectionVO pdf = new PdfSectionVO(); BeanUtils.copyProperties(section, pdf); pdf.setType("pdf"); - pdf.setUrl(section.getUrl()); + //pdf.setUrl(section.getUrl()); pdf.setDownloadable(true); return pdf; case "ppt": @@ -53,7 +53,7 @@ public class SectionVOFactory { .collect(Collectors.toList()); ppt.setSlides(slideVOS); - ppt.setDownUrl(section.getUrl()); + //ppt.setUrl(section.getUrl()); ppt.setPreViewUrl(KKviewUrlUtil.toKKViewUrl(section.getUrl())); return ppt; default: diff --git a/src/main/java/com/guwan/backend/pojo/dto/Courses.java b/src/main/java/com/guwan/backend/pojo/dto/Courses.java deleted file mode 100644 index 8b6563a..0000000 --- a/src/main/java/com/guwan/backend/pojo/dto/Courses.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.guwan.backend.pojo.dto; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; - -import java.io.Serializable; -import java.math.BigDecimal; - -/** - * 课程表 - * @TableName courses - */ -@TableName(value ="courses") -@Data -public class Courses implements Serializable { - /** - * 课程ID - */ - @TableId(type = IdType.AUTO) - private Integer id; - - /** - * 课程标题 - */ - private String title; - - /** - * 分类编码 - */ - private String categoryId; - - /** - * 分类名称 - */ - private String categoryName; - - /** - * 封面图片URL - */ - private String coverImg; - - /** - * 学习人数 - */ - private Integer studentCount; - - /** - * 评分 - */ - private BigDecimal rating; - - /** - * 价格 - */ - private BigDecimal price; - - @TableField(exist = false) - private static final long serialVersionUID = 1L; -} \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/pojo/dto/course/InsertCourseDTO.java b/src/main/java/com/guwan/backend/pojo/dto/course/InsertCourseDTO.java new file mode 100644 index 0000000..e1a7ab9 --- /dev/null +++ b/src/main/java/com/guwan/backend/pojo/dto/course/InsertCourseDTO.java @@ -0,0 +1,20 @@ +package com.guwan.backend.pojo.dto.course; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.guwan.backend.pojo.response.courseDetail.ChapterVO; +import lombok.Data; + +import java.util.List; + +@Data +public class InsertCourseDTO { + private String title; + private String description; + private String categoryId; + private String levelId; + private String typeId; + private String teacherId; + private String coverImg; + @JsonProperty("chapters") + private List chapterVOS; +} diff --git a/src/main/java/com/guwan/backend/pojo/response/courseDetail/BaseSectionVO.java b/src/main/java/com/guwan/backend/pojo/response/courseDetail/BaseSectionVO.java index 5c7fe99..b4dbef8 100644 --- a/src/main/java/com/guwan/backend/pojo/response/courseDetail/BaseSectionVO.java +++ b/src/main/java/com/guwan/backend/pojo/response/courseDetail/BaseSectionVO.java @@ -7,6 +7,7 @@ public class BaseSectionVO { private String id; private String title; private String type; // video / pdf / ppt + private String url; private boolean isFree; private boolean completed; } diff --git a/src/main/java/com/guwan/backend/pojo/response/courseDetail/CourseDetailVO.java b/src/main/java/com/guwan/backend/pojo/response/courseDetail/CourseDetailVO.java index b97d9b5..dbaa34c 100644 --- a/src/main/java/com/guwan/backend/pojo/response/courseDetail/CourseDetailVO.java +++ b/src/main/java/com/guwan/backend/pojo/response/courseDetail/CourseDetailVO.java @@ -24,6 +24,8 @@ public class CourseDetailVO { private String teacherAvatar; + private String categoryName; + private String levelName; private String typeName; diff --git a/src/main/java/com/guwan/backend/pojo/response/courseDetail/PdfSectionVO.java b/src/main/java/com/guwan/backend/pojo/response/courseDetail/PdfSectionVO.java index c633beb..392152d 100644 --- a/src/main/java/com/guwan/backend/pojo/response/courseDetail/PdfSectionVO.java +++ b/src/main/java/com/guwan/backend/pojo/response/courseDetail/PdfSectionVO.java @@ -9,6 +9,5 @@ import lombok.ToString; @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class PdfSectionVO extends BaseSectionVO { - private String url; private boolean downloadable; } diff --git a/src/main/java/com/guwan/backend/pojo/response/courseDetail/PptSectionVO.java b/src/main/java/com/guwan/backend/pojo/response/courseDetail/PptSectionVO.java index 9ab7a5e..18a2f6f 100644 --- a/src/main/java/com/guwan/backend/pojo/response/courseDetail/PptSectionVO.java +++ b/src/main/java/com/guwan/backend/pojo/response/courseDetail/PptSectionVO.java @@ -10,7 +10,7 @@ import java.util.List; @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class PptSectionVO extends BaseSectionVO { - private String downUrl; + private String url; private String preViewUrl; private List slides; } diff --git a/src/main/java/com/guwan/backend/pojo/response/courseDetail/VideoSectionVO.java b/src/main/java/com/guwan/backend/pojo/response/courseDetail/VideoSectionVO.java index b202485..c21f5de 100644 --- a/src/main/java/com/guwan/backend/pojo/response/courseDetail/VideoSectionVO.java +++ b/src/main/java/com/guwan/backend/pojo/response/courseDetail/VideoSectionVO.java @@ -10,5 +10,4 @@ import lombok.ToString; @EqualsAndHashCode(callSuper = true) public class VideoSectionVO extends BaseSectionVO { private String duration; - private String url; } diff --git a/src/main/java/com/guwan/backend/service/impl/ChallengesServiceImpl.java b/src/main/java/com/guwan/backend/service/impl/ChallengesServiceImpl.java index cf6ef9d..ac9ee2b 100644 --- a/src/main/java/com/guwan/backend/service/impl/ChallengesServiceImpl.java +++ b/src/main/java/com/guwan/backend/service/impl/ChallengesServiceImpl.java @@ -89,8 +89,6 @@ public class ChallengesServiceImpl extends ServiceImpl private final UserMapper userMapper; + private final BSCategoryMapper bsCategoryMapper; + private final CourseLevelMapper courseLevelMapper; private final CourseTypeMapper courseTypeMapper; @@ -66,6 +67,7 @@ public class CourseServiceImpl extends ServiceImpl CourseDetailVO courseDetailVO = new CourseDetailVO(); courseDetailVO.setTitle(course.getTitle()); courseDetailVO.setDescription(course.getDescription()); + courseDetailVO.setCategoryName(bsCategoryMapper.selectById(course.getCategoryId()).getChineseName()); courseDetailVO.setLevelName(courseLevelMapper.selectById(course.getLevelId()).getChineseName()); courseDetailVO.setTypeName(courseTypeMapper.selectById(course.getTypeId()).getChineseName()); @@ -168,12 +170,10 @@ public class CourseServiceImpl extends ServiceImpl courseDetailVO.setReviewVOS(reviewVOList); - courseDetailVO.setRatingDistribution(ratingDistributions.stream().map(RatingDistribution::getCount).collect(Collectors.toList())); System.out.println("courseDetailVO = " + courseDetailVO); return courseDetailVO; - } public int getStudentCount(String courseId) { diff --git a/src/main/java/com/guwan/backend/util/MinioUtil.java b/src/main/java/com/guwan/backend/util/MinioUtil.java index 0dd84b1..0e54a00 100644 --- a/src/main/java/com/guwan/backend/util/MinioUtil.java +++ b/src/main/java/com/guwan/backend/util/MinioUtil.java @@ -12,9 +12,8 @@ import org.apache.commons.io.FilenameUtils; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.nio.file.Files; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; @@ -94,6 +93,29 @@ public class MinioUtil { } } + + public String uploadFile(String bucketName, File file, String folder) { + createBucket(bucketName); + try (FileInputStream inputStream = new FileInputStream(file)) { + String fileName = generateFileName(file.getName()); + fileName = folder + "/" + fileName; + + minioClient.putObject( + PutObjectArgs.builder() + .bucket(bucketName) + .object(fileName) + .stream(inputStream, file.length(), -1) + .contentType(Files.probeContentType(file.toPath())) // 自动获取 contentType + .build() + ); + + return fileName; + } catch (Exception e) { + log.error("上传文件失败", e); + throw new RuntimeException("上传文件失败", e); + } + } + /** * 上传Base64图片 */ diff --git a/src/main/java/com/guwan/backend/util/PPTUtil.java b/src/main/java/com/guwan/backend/util/PPTUtil.java new file mode 100644 index 0000000..f0c3aa9 --- /dev/null +++ b/src/main/java/com/guwan/backend/util/PPTUtil.java @@ -0,0 +1,106 @@ +package com.guwan.backend.util; + +import lombok.RequiredArgsConstructor; +import org.apache.poi.openxml4j.util.ZipSecureFile; +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFSlide; +import org.springframework.stereotype.Component; +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class PPTUtil { + + private final MinioUtil minioUtil; + + public List PPTToImageConverter() throws IOException { + + List slideList = new ArrayList<>(); + + String pptFile = "http://localhost:9000/file/courseSource/748831eb-e145-45e6-a4db-07662b747b1f.pptx"; // PPT 文件路径 + String outputDir = "output_images"; // 输出目录 + + ZipSecureFile.setMinInflateRatio(0); + + // 从网络加载 PPT 文件 + URL url = new URL(pptFile); + URLConnection connection = url.openConnection(); + InputStream inputStream = connection.getInputStream(); + + XMLSlideShow ppt = new XMLSlideShow(inputStream); + inputStream.close(); + + // 创建输出目录 + File dir = new File(outputDir); + if (!dir.exists()) { + dir.mkdirs(); + } + + // 获取幻灯片 + int slideNumber = 1; + for (XSLFSlide slide : ppt.getSlides()) { + Dimension pgsize = ppt.getPageSize(); + BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = img.createGraphics(); + + // 设置背景为白色 + graphics.setPaint(Color.WHITE); + graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height)); + + // 渲染幻灯片 + slide.draw(graphics); + + // 输出为图片 + File outputFile = new File(outputDir + "/slide_" + slideNumber + ".png"); + ImageIO.write(img, "png", outputFile); + String uploadResult = minioUtil.uploadFile("photo", outputFile, "ppt"); + + + System.out.println("Saved slide: " + outputFile.getAbsolutePath()); + + slideNumber++; + // 删除本地文件 + boolean deleted = outputFile.delete(); + if (deleted) { + System.out.println("Deleted file: " + outputFile.getAbsolutePath()); + } else { + System.out.println("Failed to delete file: " + outputFile.getAbsolutePath()); + } + slideList.add(uploadResult); + } + ppt.close(); + deleteDirectory(new File(outputDir)); + return slideList; + } + + private void deleteDirectory(File dir) { + if (dir.isDirectory()) { + // 列出文件夹中的文件 + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + // 递归删除文件或目录 + deleteDirectory(file); + } + } + } + // 删除目录本身 + boolean deleted = dir.delete(); + if (deleted) { + System.out.println("Deleted directory: " + dir.getAbsolutePath()); + } else { + System.out.println("Failed to delete directory: " + dir.getAbsolutePath()); + } + } + +}