yl-backend/src/main/java/com/guwan/backend/controller/CommonController.java

572 lines
18 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.guwan.backend.controller;
import cn.hutool.json.JSONObject;
import com.guwan.backend.annotation.OperationLog;
import com.guwan.backend.client.SimpleTTSClient;
import com.guwan.backend.client.VoiceServiceClient;
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 dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import io.minio.MinioClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
@RestController
@RequestMapping("/api/common")
@RequiredArgsConstructor
public class CommonController {
private final MinioUtil minioUtil;
private final VoiceServiceClient voiceServiceClient;
private final SimpleTTSClient simpleTTSClient;
private final MinioClient minioClient;
//private final BookContentService bookContentService;
private final MongodbUserService mongodbUserService;
private final EveryReadDetailOfMongodbService everyReadDetailOfMongodbService;
private final QwenChatModel qwenChatModel;
private final QwenStreamingChatModel qwenStreamingChatModel;
private final TestDateRepository testDateRepository;
private final TestDateDao testDateDao;
@PostMapping("/uploadFile")
public Result<String> uploadFile(String bucketName, MultipartFile file){
return Result.success(minioUtil.getUrl(minioUtil.getFileUrl
(bucketName, minioUtil.uploadFile(bucketName, file))));
}
// @PostMapping("/addBookComment")
// public Result<String> addBookComment(String url) {
// log.debug(url);
// // "http://localhost:9000/txt/8357cf6b-9637-4354-9ee6-2717141f665a.txt";
// OkHttpClient client = new OkHttpClient();
//
// // 创建一个请求对象
// Request request = new Request.Builder()
// .url(url)
// .build();
//
// // 发起同步请求
// try {
// String content = getTextUsingOkHttp(client, request);
// ArrayList<BookContent> bookContents = processContent(content);
// bookContentService.saveBatch(bookContents);
//
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// return Result.success("ok");
// }
// 通过 OkHttpClient 发起同步请求获取文件内容
public static String getTextUsingOkHttp(OkHttpClient client, Request request) throws IOException {
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
return response.body().string(); // 返回文件内容
} else {
throw new IOException("Unexpected code " + response);
}
}
}
// 处理文件内容,提取卷和节
public static ArrayList<BookContent> processContent(String content) {
// 正则表达式,提取卷和节
String volumePattern = "第([一二三四五六七八九十]+)卷"; // 提取卷
String sectionPattern = "第([一二三四五六七八九十零百]+)节:(.*)"; // 提取节及其节名
// 提取卷
Pattern volumeRegex = Pattern.compile(volumePattern);
Matcher volumeMatcher = volumeRegex.matcher(content);
// 提取节
Pattern sectionRegex = Pattern.compile(sectionPattern);
Matcher sectionMatcher = sectionRegex.matcher(content);
// 列表来存储所有卷和节的内容
List<String> volumes = new ArrayList<>(); // 存储所有卷的标题
List<String> sections = new ArrayList<>(); // 存储所有节的标题
List<String> sectionContents = new ArrayList<>(); // 存储每节的正文内容
// 收集卷的信息
while (volumeMatcher.find()) {
String volume = "" + volumeMatcher.group(1) + "";
volumes.add(volume);
}
// 收集节的信息
while (sectionMatcher.find()) {
String sectionTitle = "" + sectionMatcher.group(1) + "节:" + sectionMatcher.group(2).trim(); // 这里去掉节名前后空格
sections.add(sectionTitle);
// 获取节的正文内容
int start = sectionMatcher.end(); // 获取节标题之后的位置
int end = content.length(); // 默认到文件末尾
// 查找下一个节的位置(即本节内容的结束位置)
Matcher nextSectionMatcher = sectionRegex.matcher(content);
if (nextSectionMatcher.find(start)) {
end = nextSectionMatcher.start();
}
// 获取当前节的正文内容
String sectionContent = content.substring(start, end).trim();
sectionContents.add(sectionContent);
}
// 标记是否是第一次匹配到“第一节”
boolean isFirstSection = true;
ArrayList<BookContent> bookContents = new ArrayList<>();
int sectionId = 1;
// 输出卷和节信息
for (int i = 0; i < volumes.size(); i++) {
// 输出卷的标题
// 输出该卷的每一节标题和正文内容
for (int j = 0; j < sections.size(); j++) {
// System.out.print(volumes.get(i));
String section = sections.get(j);
String sectionContent = sectionContents.get(j);
// 输出节标题
// System.out.println(" " + section);
// 输出节的正文内容
// System.out.println(" 正文: " + sectionContent);
// 如果是“第一节”,并且不是第一次出现,递增卷的索引
if (section.contains("第一节") && !isFirstSection) {
i++; // 不是第一次才递增
}
// 第一次匹配到“第一节”后标记为false
isFirstSection = false;
BookContent bookContent = new BookContent();
bookContent.setBookName("大爱仙尊");
bookContent.setVolume(volumes.get(i));
bookContent.setSection(section);
bookContent.setSectionContent(sectionContent);
bookContent.setSectionId(sectionId++);
System.out.println("bookContent = " + bookContent);
bookContents.add(bookContent);
}
}
return bookContents;
}
// @GetMapping("/getBookComment")
// public Result<String> getBookComment(Long id) {
// BookContent bookContent = bookContentService.getById(id);
// return Result.success(bookContent.getSectionContent());
// }
// @GetMapping("/getBookContent")
// public Result<String> getBookContent(String bookName, Long id) {
// BookContent bookContent = bookContentService.getBookContent(bookName, id);
// return Result.success(bookContent.getSectionContent());
// }
// @GetMapping("/getBookCommentByPath")
// public ResponseEntity<Map<String, Object>> getBookCommentByPath(@RequestParam("id") Long id) {
// // 从数据库中获取评论内容
// //String comments = bookContentService.getById(id).getSectionContent();
//
// BookContent byId = bookContentService.lambdaQuery()
// .eq(BookContent::getBookName, "大爱仙尊")
// .eq(BookContent::getSectionId, id).one();
//
// // 构造返回数据
// Map<String, Object> response = new HashMap<>();
// response.put("data", byId);
//
// return ResponseEntity.ok(response);
//
// }
@GetMapping("/testMongodb")
public Result testMongodb(){
User user = new User();
user.setId("1");
user.setName("1");
user.setAge(1L);
user.setEmail("1");
mongodbUserService.save(user);
return Result.success();
}
@PostMapping("/everyRead")
public Result everyRead(@RequestBody EveryReadDetailOfMongodb everyReadDetailOfMongodb){
everyReadDetailOfMongodbService.save(everyReadDetailOfMongodb);
return Result.success();
}
@GetMapping("/getUserOneTotalTime")
@OperationLog(description = "统计用户某本书的读书时间")
public Result getUserOneTotalTime(@RequestParam Long userId){
//return Result.success();
// everyReadDetailOfMongodbService.getUserOneTotalTime(userId);
return Result.success(everyReadDetailOfMongodbService.getUserOneTotalTime(userId));
}
/**
* model 默认值 /model/faster-whisper-small/
*/
@PostMapping("/convertVoiceToText")
public Result convertVoiceToText(MultipartFile file, String model) {
if (model == null){
model = "/model/faster-whisper-small/";
}
return Result.success(voiceServiceClient.voiceToText(file, model));
}
@PostMapping("/simpleTTS")
public Result simpleTTS(String input, String voiceModel) {
if (voiceModel == null) {
voiceModel = "zh-CN-XiaoxiaoNeural";
}
// 使用 JSONObject 构造JSON
JSONObject jsonObject = new JSONObject();
jsonObject.putOpt("input", input);
jsonObject.putOpt("voice", voiceModel);
String jsonInputString = jsonObject.toString();
System.out.println(jsonInputString);
// jsonInputString = "{\"input\": \"想听个啥123\", \"voice\": \"zh-CN-XiaoxiaoNeural\", \"style\": \"\", \"rate\": 0, \"pitch\": 0}";
String url = minioUtil.getUrl(minioUtil.getFileUrl("temp",
minioUtil.uploadByteArray(
simpleTTSClient.saveAudio(jsonInputString), "mp3")));
return Result.success(url);
}
@PostMapping("/testPart")
public void testPart(@RequestPart(value = "file", required = false) MultipartFile file,
@RequestPart(value = "str1", required = false) String str1,
@RequestPart(value = "f1", required = false) String f1) {
String s = null;
if (file != null) {
s = minioUtil.uploadFile("temp", file);
}
System.out.println("s = " + s);
System.out.println("str1 = " + str1);
System.out.println("f1 = " + f1);
}
@PostMapping("/testPartOfFloat")
public void testPartOfFloat(@RequestPart(value = "file", required = false) MultipartFile file,
@RequestPart(value = "str1", required = false) String str1,
@RequestPart(value = "f1", required = false) Float f1) {
String s = null;
if (file != null) {
s = minioUtil.uploadFile("temp", file);
}
System.out.println("s = " + s);
System.out.println("str1 = " + str1);
System.out.println("f1 = " + f1);
}
@PostMapping("/testParam")
public void testParm(@RequestPart(value = "file", required = false) MultipartFile file,
@RequestParam(value = "str1", required = true) String str1,
@RequestParam(value = "f1", required = false) Float f1) {
String s = null;
if (file != null) {
s = minioUtil.uploadFile("temp", file);
}
System.out.println("s = " + s);
System.out.println("str1 = " + str1);
System.out.println("f1 = " + f1);
}
@GetMapping("/testQwen")
public Result testQwen(@RequestParam(value = "str1", required = false) String message) {
var response = qwenChatModel.chat(message);
System.out.println("response = " + response);
return Result.success(response);
}
@GetMapping(value = "/testQwenStreaming", produces = "text/steam;charset=UTF-8")
public Flux<String> testQwenStreaming(
@RequestParam(value = "message", required = false) String message) {
Flux<String> flux = Flux.create(fluxSink -> {
qwenStreamingChatModel.chat(message, new StreamingChatResponseHandler() {
//每一次流式响应的文本
@Override
public void onPartialResponse(String partialResponse) {
fluxSink.next(partialResponse);
}
//响应结束的文本
@Override
public void onCompleteResponse(ChatResponse chatResponse) {
fluxSink.complete();
}
@Override
public void onError(Throwable throwable) {
fluxSink.error(throwable);
}
});
});
return flux;
}
@GetMapping("/PPTToImageConverter")
public void PPTToImageConverter() throws IOException {
String pptFile = "D:\\00_桌面\\公司简介.pptx"; // PPT 文件路径
String outputDir = "output_images"; // 输出目录
FileInputStream inputStream = new FileInputStream(pptFile);
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);
System.out.println("Saved slide: " + outputFile.getAbsolutePath());
slideNumber++;
}
ppt.close();
}
@GetMapping("/videoDuration")
public void VideoDuration() throws IOException {
String preSignedUrl = "http://localhost:9000/videos/ffffad37-9804-4765-ae18-3f8dcda9bea8.mp4"; // Minio 预签名 URL
// minioClient.getObject()
InputStream stream = minioUtil.getFileInputStream("videos", "ffffad37-9804-4765-ae18-3f8dcda9bea8.mp4");
System.out.println("stream = " + stream);
try {
Metadata metadata = new Metadata();
Parser parser = new AutoDetectParser();
parser.parse(stream, new BodyContentHandler(), metadata, new ParseContext());
String duration = metadata.get("duration");
System.out.println("视频时长(毫秒): " + duration);
} catch (Exception e) {
e.printStackTrace();
}
}
@PostMapping("/testPostUseParam")
//测试公司写法
public void testPostUseParam(@RequestParam("ids") List<String> ids,
@RequestParam("str") String str){
System.out.println("ids = " + ids);
System.out.println("str = " + str);
}
@GetMapping("/testGetParam")
public void testGetParam(@RequestParam("ids") List<String> ids,
@RequestParam("str") String str){
System.out.println("ids = " + ids);
System.out.println("str = " + str);
}
@GetMapping("/testDate")
public void testDate(){
TestDate testDate = new TestDate();
testDate.setId(UUID.randomUUID().toString());
Instant now = Instant.now();
//Instant now = Instant.now();
// 获取当前系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
// 获取今天的 00:00:00
Instant todayStart = LocalDate.now(zoneId)
.atStartOfDay(zoneId)
.toInstant();
// 假设 testDate 有一个 setDate(Instant instant) 方法
testDate.setDate(Date.from(todayStart));
// testDate.setDate(new Date());
testDateRepository.insert(testDate);
}
@GetMapping("/testDateFind")
public void testDateFind(){
TestDate testDate = new TestDate();
testDate.setId(UUID.randomUUID().toString());
Instant now = Instant.now();
//Instant now = Instant.now();
// 获取当前系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
// 获取今天的 00:00:00
Instant todayStart = LocalDate.now(zoneId)
.atStartOfDay(zoneId)
.toInstant();
Date from = Date.from(todayStart);
List<TestDate> byDate = testDateDao.findByDate(from);
System.out.println("byDate = " + byDate);
}
@PostMapping("/sendCode")
public void sendCode(@RequestParam String code){
System.out.println("code = " + code);
}
}