From 84cc59ea076c4d4ce87a436ce78be8cc3e94034b Mon Sep 17 00:00:00 2001 From: lqw <1305554895@qq.com> Date: Fri, 7 Jul 2023 12:35:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5AI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/lin/controller/ArticleController.java | 8 +- .../java/com/lin/dao/mapper/AdMapper.java | 1 - .../lin/dao/mapper/OpenaiAnswersMapper.java | 7 + .../java/com/lin/dao/pojo/OpenaiAnswers.java | 12 ++ .../java/com/lin/service/ArticleService.java | 4 +- .../java/com/lin/service/OpenAIService.java | 9 + .../lin/service/impl/ArticleServiceImpl.java | 37 +++- .../lin/service/impl/OpenAIServiceImpl.java | 99 +++++++++ .../src/main/java/com/lin/vo/ArticleVo.java | 4 + .../src/main/java/com/lin/vo/ai/AIAnswer.java | 49 +++++ .../src/main/java/com/lin/vo/ai/Choices.java | 45 +++++ zhiliao-api/zhiliao-api.iml | 190 +----------------- 12 files changed, 266 insertions(+), 199 deletions(-) create mode 100644 zhiliao-api/src/main/java/com/lin/dao/mapper/OpenaiAnswersMapper.java create mode 100644 zhiliao-api/src/main/java/com/lin/dao/pojo/OpenaiAnswers.java create mode 100644 zhiliao-api/src/main/java/com/lin/service/OpenAIService.java create mode 100644 zhiliao-api/src/main/java/com/lin/service/impl/OpenAIServiceImpl.java create mode 100644 zhiliao-api/src/main/java/com/lin/vo/ai/AIAnswer.java create mode 100644 zhiliao-api/src/main/java/com/lin/vo/ai/Choices.java diff --git a/zhiliao-api/src/main/java/com/lin/controller/ArticleController.java b/zhiliao-api/src/main/java/com/lin/controller/ArticleController.java index cce93bd..a5fa9a5 100644 --- a/zhiliao-api/src/main/java/com/lin/controller/ArticleController.java +++ b/zhiliao-api/src/main/java/com/lin/controller/ArticleController.java @@ -14,6 +14,8 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import java.io.IOException; + //json数据进行交互 @RestController @RequestMapping("articles") @@ -26,7 +28,7 @@ public class ArticleController { /** * 限流接口 */ - @RateLimiter(time = 3,count = 1,limitType = LimitType.IP) + @RateLimiter(time = 3, count = 1, limitType = LimitType.IP) @GetMapping("/test/{id}") @LogAnnotation(module = "文章", operator = "test接口") public String test(@PathVariable("id") String id) { @@ -100,9 +102,9 @@ public Result findArticleById(@PathVariable("id") Long articleId) { @PostMapping("publish") @ApiOperation("新增修改文章接口") - @RateLimiter(time = 10,count = 1,limitType = LimitType.IP) + @RateLimiter(time = 10, count = 1, limitType = LimitType.IP) @LogAnnotation(module = "文章", operator = "新增修改文章接口") - public Result publish(@RequestBody ArticleParam articleParam) { + public Result publish(@RequestBody ArticleParam articleParam) throws IOException { return articleService.publish(articleParam); } diff --git a/zhiliao-api/src/main/java/com/lin/dao/mapper/AdMapper.java b/zhiliao-api/src/main/java/com/lin/dao/mapper/AdMapper.java index b3edbe2..ae69478 100644 --- a/zhiliao-api/src/main/java/com/lin/dao/mapper/AdMapper.java +++ b/zhiliao-api/src/main/java/com/lin/dao/mapper/AdMapper.java @@ -5,7 +5,6 @@ import com.lin.dao.pojo.AdType; import org.apache.ibatis.annotations.Param; -import java.util.List; /** * adMapper接口 diff --git a/zhiliao-api/src/main/java/com/lin/dao/mapper/OpenaiAnswersMapper.java b/zhiliao-api/src/main/java/com/lin/dao/mapper/OpenaiAnswersMapper.java new file mode 100644 index 0000000..9b9b3a6 --- /dev/null +++ b/zhiliao-api/src/main/java/com/lin/dao/mapper/OpenaiAnswersMapper.java @@ -0,0 +1,7 @@ +package com.lin.dao.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.lin.dao.pojo.OpenaiAnswers; + +public interface OpenaiAnswersMapper extends BaseMapper { +} diff --git a/zhiliao-api/src/main/java/com/lin/dao/pojo/OpenaiAnswers.java b/zhiliao-api/src/main/java/com/lin/dao/pojo/OpenaiAnswers.java new file mode 100644 index 0000000..f0fe6b4 --- /dev/null +++ b/zhiliao-api/src/main/java/com/lin/dao/pojo/OpenaiAnswers.java @@ -0,0 +1,12 @@ +package com.lin.dao.pojo; + +import lombok.Data; + +@Data +public class OpenaiAnswers { + private Long id; + + private String articleId; + + private String answer; +} diff --git a/zhiliao-api/src/main/java/com/lin/service/ArticleService.java b/zhiliao-api/src/main/java/com/lin/service/ArticleService.java index c01c52a..a38e03f 100644 --- a/zhiliao-api/src/main/java/com/lin/service/ArticleService.java +++ b/zhiliao-api/src/main/java/com/lin/service/ArticleService.java @@ -5,6 +5,8 @@ import com.lin.vo.params.PageParams; import com.lin.vo.params.PageSearchParams; +import java.io.IOException; + public interface ArticleService { /** * 分页查询 文章列表 @@ -59,7 +61,7 @@ public interface ArticleService { * @param articleParam * @return */ - Result publish(ArticleParam articleParam); + Result publish(ArticleParam articleParam) throws IOException; Result delAticleById(Long articleId); diff --git a/zhiliao-api/src/main/java/com/lin/service/OpenAIService.java b/zhiliao-api/src/main/java/com/lin/service/OpenAIService.java new file mode 100644 index 0000000..63bc79f --- /dev/null +++ b/zhiliao-api/src/main/java/com/lin/service/OpenAIService.java @@ -0,0 +1,9 @@ +package com.lin.service; + +import java.io.IOException; + +public interface OpenAIService { + String doChatGPT(String question) throws IOException; + + void generateAnswers(String content, Long id, Boolean isEdit) throws IOException; +} diff --git a/zhiliao-api/src/main/java/com/lin/service/impl/ArticleServiceImpl.java b/zhiliao-api/src/main/java/com/lin/service/impl/ArticleServiceImpl.java index 43d5100..2ff959d 100644 --- a/zhiliao-api/src/main/java/com/lin/service/impl/ArticleServiceImpl.java +++ b/zhiliao-api/src/main/java/com/lin/service/impl/ArticleServiceImpl.java @@ -4,13 +4,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.lin.dao.dos.Archives; -import com.lin.dao.pojo.Article; -import com.lin.dao.pojo.ArticleBody; -import com.lin.dao.pojo.ArticleTag; -import com.lin.dao.pojo.SysUser; +import com.lin.dao.mapper.OpenaiAnswersMapper; +import com.lin.dao.pojo.*; import com.lin.service.*; import com.lin.utils.SensitiveFilter; import com.lin.utils.UserThreadLocal; +import com.lin.utils.text.StringUtils; import com.lin.vo.*; import com.lin.vo.params.ArticleParam; import com.lin.vo.params.PageParams; @@ -22,8 +21,12 @@ import org.joda.time.DateTime; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -150,14 +153,27 @@ public Result findArticleById(Long articleId) { // 更新 增加了此次接口的 耗时 如果一旦更新出问题,不能影响 查看文章的操作 //线程池 可以把更新操作 扔到线程池中去执行,和主线程就不相关了 threadService.updateArticleViewCount(articleMapper, article); + + + //查找ai回答 + LambdaQueryWrapper answersWrapper = new LambdaQueryWrapper<>(); + answersWrapper.eq(OpenaiAnswers::getArticleId,articleId); + OpenaiAnswers openaiAnswers = openaiAnswersMapper.selectOne(answersWrapper); + if(openaiAnswers!=null){ + articleVo.setAnswer(openaiAnswers.getAnswer()); + } + return Result.success(articleVo); } + //敏感词过滤器 @Autowired SensitiveFilter sensitiveFilter; + + @Transactional @Override - public Result publish(ArticleParam articleParam) { + public Result publish(ArticleParam articleParam) throws IOException { //此接口 要加入到登录拦截当中 SysUser sysUser = UserThreadLocal.get(); /** @@ -229,9 +245,20 @@ public Result publish(ArticleParam articleParam) { articleMessage.setArticleId(article.getId()); rocketMQTemplate.convertAndSend("api-update-article:SEND_ARTICLE_MSG", articleMessage); } + + //保存ai回答 + openAIService.generateAnswers(articleParam.getBody().getContent(),article.getId(),isEdit); + return Result.success(map); } + @Autowired + OpenAIService openAIService; + + @Resource + OpenaiAnswersMapper openaiAnswersMapper; + + @Override public Result delAticleById(Long articleId) { boolean b = articleMapper.updateAvailableById(articleId); diff --git a/zhiliao-api/src/main/java/com/lin/service/impl/OpenAIServiceImpl.java b/zhiliao-api/src/main/java/com/lin/service/impl/OpenAIServiceImpl.java new file mode 100644 index 0000000..19a6306 --- /dev/null +++ b/zhiliao-api/src/main/java/com/lin/service/impl/OpenAIServiceImpl.java @@ -0,0 +1,99 @@ +package com.lin.service.impl; + + +import com.alibaba.fastjson.JSON; +import com.lin.dao.mapper.OpenaiAnswersMapper; +import com.lin.dao.pojo.OpenaiAnswers; +import com.lin.service.OpenAIService; +import com.lin.vo.ai.AIAnswer; +import com.lin.vo.ai.Choices; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.List; + +@Service +@Async("taskExecutor") +public class OpenAIServiceImpl implements OpenAIService { + + + @Resource + OpenaiAnswersMapper openaiAnswersMapper; + + private Logger logger = LoggerFactory.getLogger(OpenAIServiceImpl.class); + +// @Value("${chatbot-api.openAiKey}") +// private String openAiKey; + + @Override + public String doChatGPT(String question) throws IOException { + String openAiKey="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"; + + CloseableHttpClient httpClient = HttpClientBuilder.create().build(); + + HttpPost post = new HttpPost("https://api.openai.com/v1/completions"); + post.addHeader("Content-Type", "application/json"); + post.addHeader("Authorization", "Bearer " + openAiKey); + + String paramJson = "{\"model\": \"text-davinci-003\", \"prompt\": \"" + question + "\", \"temperature\": 0, \"max_tokens\": 1024}"; + + StringEntity stringEntity = new StringEntity(paramJson, ContentType.create("text/json", "UTF-8")); + post.setEntity(stringEntity); + + CloseableHttpResponse response = httpClient.execute(post); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + String jsonStr = EntityUtils.toString(response.getEntity()); + AIAnswer aiAnswer = JSON.parseObject(jsonStr, AIAnswer.class); + StringBuilder answers = new StringBuilder(); + List choices = aiAnswer.getChoices(); + for (Choices choice : choices) { + answers.append(choice.getText()); + } + + return answers.toString(); + } else { + logger.error("api.openai.com Err Code is " + response.getStatusLine().getStatusCode()); + return null; + } + } + + /** + * 保存ChatGPT数据 + * @param content 文本 + * @param id 文章id + * @param isEdit 是否修改 + * @throws IOException + */ + + @Override + public void generateAnswers(String content, Long id, Boolean isEdit) throws IOException { + OpenaiAnswers openaiAnswers = new OpenaiAnswers(); + //更新 + if(isEdit){ + OpenaiAnswers openaiAnswersRest = openaiAnswersMapper.selectById(id); + openaiAnswers.setId(openaiAnswersRest.getId()); + } + //新增 + openaiAnswers.setArticleId(String.valueOf(id)); + String s = this.doChatGPT(content); + if(s!=null){ + openaiAnswers.setAnswer(s); + openaiAnswersMapper.insert(openaiAnswers); + } + } + + + +} diff --git a/zhiliao-api/src/main/java/com/lin/vo/ArticleVo.java b/zhiliao-api/src/main/java/com/lin/vo/ArticleVo.java index 37e7883..273e233 100644 --- a/zhiliao-api/src/main/java/com/lin/vo/ArticleVo.java +++ b/zhiliao-api/src/main/java/com/lin/vo/ArticleVo.java @@ -36,4 +36,8 @@ public class ArticleVo { private CategoryVo category; + /** + * ai 放回值 + */ + private String answer; } diff --git a/zhiliao-api/src/main/java/com/lin/vo/ai/AIAnswer.java b/zhiliao-api/src/main/java/com/lin/vo/ai/AIAnswer.java new file mode 100644 index 0000000..c4dd011 --- /dev/null +++ b/zhiliao-api/src/main/java/com/lin/vo/ai/AIAnswer.java @@ -0,0 +1,49 @@ +package com.lin.vo.ai; + + +import java.util.List; + +public class AIAnswer { + + private String id; + + private String object; + + private int created; + + private String model; + + private List choices; + + public void setId(String id){ + this.id = id; + } + public String getId(){ + return this.id; + } + public void setObject(String object){ + this.object = object; + } + public String getObject(){ + return this.object; + } + public void setCreated(int created){ + this.created = created; + } + public int getCreated(){ + return this.created; + } + public void setModel(String model){ + this.model = model; + } + public String getModel(){ + return this.model; + } + public void setChoices(List choices){ + this.choices = choices; + } + public List getChoices(){ + return this.choices; + } + +} diff --git a/zhiliao-api/src/main/java/com/lin/vo/ai/Choices.java b/zhiliao-api/src/main/java/com/lin/vo/ai/Choices.java new file mode 100644 index 0000000..6c1fa49 --- /dev/null +++ b/zhiliao-api/src/main/java/com/lin/vo/ai/Choices.java @@ -0,0 +1,45 @@ +package com.lin.vo.ai; + + +public class Choices { + + private String text; + + private int index; + + private String logprobs; + + private String finish_reason; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String getLogprobs() { + return logprobs; + } + + public void setLogprobs(String logprobs) { + this.logprobs = logprobs; + } + + public String getFinish_reason() { + return finish_reason; + } + + public void setFinish_reason(String finish_reason) { + this.finish_reason = finish_reason; + } +} diff --git a/zhiliao-api/zhiliao-api.iml b/zhiliao-api/zhiliao-api.iml index ac81116..1daccae 100644 --- a/zhiliao-api/zhiliao-api.iml +++ b/zhiliao-api/zhiliao-api.iml @@ -1,196 +1,8 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file