content: package com.java2nb.novel.controller;
  
  import io.github.xxyopen.model.page.PageBean;
  
  import com.java2nb.novel.core.bean.UserDetails;
  import com.java2nb.novel.core.enums.ResponseStatus;
  import io.github.xxyopen.model.resp.RestResult;
  import io.github.xxyopen.web.exception.BusinessException;
  import com.java2nb.novel.entity.Author;
  import com.java2nb.novel.entity.AuthorIncome;
  import com.java2nb.novel.entity.AuthorIncomeDetail;
  import com.java2nb.novel.entity.Book;
  import com.java2nb.novel.service.AuthorService;
  import com.java2nb.novel.service.BookService;
  import io.swagger.v3.oas.annotations.Operation;
  import jakarta.servlet.http.HttpServletRequest;
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.ai.chat.client.ChatClient;
  import org.springframework.ai.chat.messages.UserMessage;
  import org.springframework.ai.chat.model.ChatModel;
  import org.springframework.ai.chat.model.ChatResponse;
  import org.springframework.ai.chat.prompt.Prompt;
  import org.springframework.ai.openai.OpenAiChatModel;
  import org.springframework.http.MediaType;
  import org.springframework.web.bind.annotation.*;
  import reactor.core.publisher.Flux;
  
  import java.util.Date;
  
  /**
   * @author 11797
   */
  @RequestMapping("author")
  @RestController
  @Slf4j
  @RequiredArgsConstructor
  public class AuthorController extends BaseController {
  
      private final AuthorService authorService;
  
      private final BookService bookService;
  
      private final ChatClient chatClient;
  
      private final OpenAiChatModel chatModel;
  
      /**
       * 校验笔名是否存在
       */
      @GetMapping("checkPenName")
      public RestResult<Boolean> checkPenName(String penName) {
  
          return RestResult.ok(authorService.checkPenName(penName));
      }
  
      /**
       * 作家发布小说分页列表查询
       */
      @GetMapping("listBookByPage")
      public RestResult<PageBean<Book>> listBookByPage(@RequestParam(value = "curr", defaultValue = "1") int page,
          @RequestParam(value = "limit", defaultValue = "10") int pageSize, HttpServletRequest request) {
  
          return RestResult.ok(bookService.listBookPageByUserId(getUserDetails(request).getId(), page, pageSize));
      }
  
      /**
       * 发布小说
       */
      @PostMapping("addBook")
      public RestResult<Void> addBook(@RequestParam("bookDesc") String bookDesc, Book book, HttpServletRequest request) {
  
          Author author = checkAuthor(request);
  
          //bookDesc不能使用book对象来接收，否则会自动去掉前面的空格
          book.setBookDesc(bookDesc
              .replaceAll("\\n", "<br>")
              .replaceAll("\\s", "&nbsp;"));
          //发布小说
          bookService.addBook(book, author.getId(), author.getPenName());
  
          return RestResult.ok();
      }
  
      /**
       * 更新小说状态,上架或下架
       */
      @PostMapping("updateBookStatus")
      public RestResult<Void> updateBookStatus(Long bookId, Byte status, HttpServletRequest request) {
          Author author = checkAuthor(request);
  
          //更新小说状态,上架或下架
          bookService.updateBookStatus(bookId, status, author.getId());
  
          return RestResult.ok();
      }
  
  
      /**
       * 删除章节
       */
      @DeleteMapping("deleteIndex/{indexId}")
      public RestResult<Void> deleteIndex(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
  
          Author author = checkAuthor(request);
  
          //删除章节
          bookService.deleteIndex(indexId, author.getId());
  
          return RestResult.ok();
      }
  
  
      /**
       * 发布章节内容
       */
      @PostMapping("addBookContent")
      public RestResult<Void> addBookContent(Long bookId, String indexName, String content, Byte isVip,
          HttpServletRequest request) {
          Author author = checkAuthor(request);
  
          content = content.replaceAll("\\n", "<br>")
              .replaceAll("\\s", "&nbsp;");
          //发布章节内容
          bookService.addBookContent(bookId, indexName, content, isVip, author.getId());
  
          return RestResult.ok();
      }
  
      /**
       * 查询章节内容
       */
      @GetMapping("queryIndexContent/{indexId}")
      public RestResult<String> queryIndexContent(@PathVariable("indexId") Long indexId, HttpServletRequest request) {
  
          Author author = checkAuthor(request);
  
          String content = bookService.queryIndexContent(indexId, author.getId());
  
          content = content.replaceAll("<br>", "\n")
              .replaceAll("&nbsp;", " ");
  
          return RestResult.ok(content);
      }
  
      /**
       * 更新章节内容
       */
      @PostMapping("updateBookContent")
      public RestResult<Void> updateBookContent(Long indexId, String indexName, String content,
          HttpServletRequest request) {
          Author author = checkAuthor(request);
  
          content = content.replaceAll("\\n", "<br>")
              .replaceAll("\\s", "&nbsp;");
          //更新章节内容
          bookService.updateBookContent(indexId, indexName, content, author.getId());
  
          return RestResult.ok();
      }
  
      /**
       * 修改小说封面
       */
      @PostMapping("updateBookPic")
      public RestResult<Void> updateBookPic(@RequestParam("bookId") Long bookId, @RequestParam("bookPic") String bookPic,
          HttpServletRequest request) {
          Author author = checkAuthor(request);
          bookService.updateBookPic(bookId, bookPic, author.getId());
          return RestResult.ok();
      }
  
  
      /**
       * 作家日收入统计数据分页列表查询
       */
      @GetMapping("listIncomeDailyByPage")
      public RestResult<PageBean<AuthorIncomeDetail>> listIncomeDailyByPage(
          @RequestParam(value = "curr", defaultValue = "1") int page,
          @RequestParam(value = "limit", defaultValue = "10") int pageSize,
          @RequestParam(value = "bookId", defaultValue = "0") Long bookId,
          @RequestParam(value = "startTime", defaultValue = "2020-05-01") Date startTime,
          @RequestParam(value = "endTime", defaultValue = "2030-01-01") Date endTime,
          HttpServletRequest request) {
  
          return RestResult.ok(
              authorService.listIncomeDailyByPage(page, pageSize, getUserDetails(request).getId(), bookId, startTime,
                  endTime));
      }
  
  
      /**
       * 作家月收入统计数据分页列表查询
       */
      @GetMapping("listIncomeMonthByPage")
      public RestResult<PageBean<AuthorIncome>> listIncomeMonthByPage(
          @RequestParam(value = "curr", defaultValue = "1") int page,
          @RequestParam(value = "limit", defaultValue = "10") int pageSize,
          @RequestParam(value = "bookId", defaultValue = "0") Long bookId,
          HttpServletRequest request) {
  
          return RestResult.ok(
              authorService.listIncomeMonthByPage(page, pageSize, getUserDetails(request).getId(), bookId));
      }
  
      private Author checkAuthor(HttpServletRequest request) {
  
          UserDetails userDetails = getUserDetails(request);
          if (userDetails == null) {
              throw new BusinessException(ResponseStatus.NO_LOGIN);
          }
  
          //查询作家信息
          Author author = authorService.queryAuthor(userDetails.getId());
  
          //判断作者状态是否正常
          if (author.getStatus() == 1) {
              //封禁状态，不能发布小说
              throw new BusinessException(ResponseStatus.AUTHOR_STATUS_FORBIDDEN);
          }
  
          return author;
  
  
      }
  
      /**
       * 查询AI生成图片
       */
      @GetMapping("queryAiGenPic")
      public RestResult<String> queryAiGenPic(@RequestParam("bookId") Long bookId) {
          return RestResult.ok(bookService.queryAiGenPic(bookId));
      }
  
      /**
       * AI扩写
       */
      @PostMapping("ai/expand")
      public RestResult<String> expandText(@RequestParam("text") String text, @RequestParam("ratio") Double ratio) {
          String prompt = "请将以下文本扩写为原长度的" + ratio / 100 + "倍：" + text;
          return RestResult.ok(chatClient.prompt()
              .user(prompt)
              .call()
              .content());
      }
  
      /**
       * AI缩写
       */
      @PostMapping("ai/condense")
      public RestResult<String> condenseText(@RequestParam("text") String text, @RequestParam("ratio") Integer ratio) {
          String prompt = "请将以下文本缩写为原长度的" + 100 / ratio + "分之一：" + text;
          return RestResult.ok(chatClient.prompt()
              .user(prompt)
              .call()
              .content());
      }
  
      /**
       * AI续写
       */
      @PostMapping("ai/continue")
      public RestResult<String> continueText(@RequestParam("text") String text, @RequestParam("length") Integer length) {
          String prompt = "请续写以下文本，续写长度约为" + length + "字：" + text;
          return RestResult.ok(chatClient.prompt()
              .user(prompt)
              .call()
              .content());
      }
  
      /**
       * AI润色
       */
      @PostMapping("ai/polish")
      public RestResult<String> polishText(@RequestParam("text") String text) {
          String prompt = "请润色优化以下文本，保持原意：" + text;
          return RestResult.ok(chatClient.prompt()
              .user(prompt)
              .call()
              .content());
      }
  
      /**
       * AI扩写
       */
      @GetMapping(value = "ai/stream/expand", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
      public Flux<String> streamExpandText(@RequestParam("text") String text, @RequestParam("ratio") Double ratio) {
          String prompt = "请将以下文本扩写为原长度的" + ratio / 100 + "倍：" + text;
          return chatClient.prompt()
              .user(prompt)
              .stream()
              .content();
      }
  
      /**
       * AI缩写
       */
      @GetMapping(value = "ai/stream/condense", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
      public Flux<String> streamCondenseText(@RequestParam("text") String text, @RequestParam("ratio") Integer ratio) {
          String prompt = "请将以下文本缩写为原长度的" + 100 / ratio + "分之一：" + text;
          return chatClient.prompt()
              .user(prompt)
              .stream()
              .content();
      }
  
      /**
       * AI续写
       */
      @GetMapping(value = "ai/stream/continue", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
      public Flux<String> streamContinueText(@RequestParam("text") String text, @RequestParam("length") Integer length) {
          String prompt = "请续写以下文本，续写长度约为" + length + "字：" + text;
          return chatClient.prompt()
              .user(prompt)
              .stream()
              .content();
      }
  
      /**
       * AI润色
       */
      @GetMapping(value = "/ai/stream/polish", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
      public Flux<String> streamPolishText(@RequestParam("text") String text) {
          String prompt = "请润色优化以下文本，保持原意：" + text;
          return chatClient.prompt()
              .user(prompt)
              .stream()
              .content();
      }
  
  }
  