赞
踩
目录
我们在登录chatgpt官网进行对话是不收费的,但需要魔法。在调用官网的API时,在代码层面上使用,通过API KEY进行对话是收费的,不过刚注册的小伙伴有免费5美金的体验额度,在不调用绘画模型,只是做为简单的问答,个人使用是没问题的。
Gpt35TurboVO
- import lombok.Data;
-
- @Data
- public class Gpt35TurboVO {
- private String role; // 角色一般为 user
- private String content; // 询问内容
- }
Controller
- @GetMapping(value = "/test", produces = "text/event-stream;charset=UTF-8")
- public String test(@RequestParam String message) {
- //回复用户
- String apikey = "sk-****";
- //请求ChatGPT的URL
- String url = "https://api.openai.com/v1/chat/completions";
-
- Gpt35TurboVO gpt35TurboVO = new Gpt35TurboVO();
- gpt35TurboVO.setRole("user");
- gpt35TurboVO.setContent(message);
- List<Gpt35TurboVO> objects = new ArrayList<>();
- objects.add(gpt35TurboVO);
- Map<Object, Object> objectObjectHashMap = new HashMap<>();
- objectObjectHashMap.put("model", "gpt-3.5-turbo"); //使用的模型
- objectObjectHashMap.put("messages", objects); //提问信息
- objectObjectHashMap.put("stream", false); //流
- objectObjectHashMap.put("temperature", 0); //GPT回答温度(随机因子)
- objectObjectHashMap.put("frequency_penalty", 0); //重复度惩罚因子
- objectObjectHashMap.put("presence_penalty", 0.6); //控制主题的重复度
- String postData = JSONUtil.toJsonStr(objectObjectHashMap);
-
- String result2 = HttpRequest.post(url)
- .header("Authorization", "Bearer " + apikey)//头信息,多个头信息多次调用此方法即可
- .header("Content-Type", "application/json")
- .body(postData)//表单内容
- .timeout(200000)//超时,毫秒
- .execute().body();
-
- System.out.println(result2);
-
- return result2;
-
- }
返回结果
ChatBotSingleQuestionVO
- import lombok.Data;
-
- /**
- * 应用管理-单次提问-VO
- * @author lf
- * @date 2023/8/18
- */
- @Data
- public class ChatBotSingleQuestionVO {
-
- /**
- * 用户输入的询问内容
- */
- private String prompt;
-
- /**
- * 角色扮演ID
- */
- private Integer rolePlayId;
-
- }
Redis锁工具类
- import org.redisson.api.RLock;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
-
- import java.util.concurrent.TimeUnit;
-
- /**
- * redis锁工具类
- *
- * @author ruoyi
- */
- @Component
- public class RedisLock {
- @Autowired
- private RedissonClient redissonClient;
-
- /**
- * 获取锁
- *
- * @param lockKey 锁实例key
- * @return 锁信息
- */
- public RLock getRLock(String lockKey) {
- return redissonClient.getLock(lockKey);
- }
-
- /**
- * 加锁
- *
- * @param lockKey 锁实例key
- * @return 锁信息
- */
- public RLock lock(String lockKey) {
- RLock lock = getRLock(lockKey);
- lock.lock();
- return lock;
- }
-
- /**
- * 加锁
- *
- * @param lockKey 锁实例key
- * @param leaseTime 上锁后自动释放锁时间
- * @return true=成功;false=失败
- */
- public Boolean tryLock(String lockKey, long leaseTime) {
- return tryLock(lockKey, 0, leaseTime, TimeUnit.SECONDS);
- }
-
- /**
- * 加锁
- *
- * @param lockKey 锁实例key
- * @param leaseTime 上锁后自动释放锁时间
- * @param unit 时间颗粒度
- * @return true=加锁成功;false=加锁失败
- */
- public Boolean tryLock(String lockKey, long leaseTime, TimeUnit unit) {
- return tryLock(lockKey, 0, leaseTime, unit);
- }
-
- /**
- * 加锁
- *
- * @param lockKey 锁实例key
- * @param waitTime 最多等待时间
- * @param leaseTime 上锁后自动释放锁时间
- * @param unit 时间颗粒度
- * @return true=加锁成功;false=加锁失败
- */
- public Boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
- RLock rLock = getRLock(lockKey);
- boolean tryLock = false;
- try {
- tryLock = rLock.tryLock(waitTime, leaseTime, unit);
- } catch (InterruptedException e) {
- return false;
- }
- return tryLock;
- }
-
- /**
- * 释放锁
- *
- * @param lockKey 锁实例key
- */
- public void unlock(String lockKey) {
- RLock lock = getRLock(lockKey);
- lock.unlock();
- }
-
- /**
- * 释放锁
- *
- * @param lock 锁信息
- */
- public void unlock(RLock lock) {
- lock.unlock();
- }
- }
Controller
- @PostMapping("/chatBotSingleQuestion/api")
- public AjaxResult chatBotSingleQuestion(@RequestBody ChatBotSingleQuestionVO chatBotSingleQuestionVO) {
- String answerContent = iChatBotSingleQuestionService.chatBotSingleQuestion(chatBotSingleQuestionVO);
- return success("success", answerContent);
- }
Impl
- /**
- * 应用管理-用户单次提问-不支持续问对话
- * @param chatBotSingleQuestionVO
- * @return
- */
- @Override
- @Transactional
- public String chatBotSingleQuestion(ChatBotSingleQuestionVO chatBotSingleQuestionVO) {
-
- if (Objects.isNull(chatBotSingleQuestionVO.getRolePlayId())){
- throw new RuntimeException("参数不可为空");
- }
-
-
- String lockName = "QA_" + SecurityUtils.getUserId();
-
- //回答的内容
- String answerContent = "";
-
- try{
- RLock rLock = redisLock.getRLock(lockName);
- boolean locked = rLock.isLocked();
-
- if (locked) {
- throw new RuntimeException("正在回复中...");
- }
-
- //对同一用户访问加锁
- redisLock.lock(lockName);
- this.chatBefore(chatBotSingleQuestionVO);
- InputStream is = this.sendRequestBeforeChat(chatBotSingleQuestionVO);
- String line = "";
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- while ((line = reader.readLine()) != null) {
- //首先对行数据进行处理
- if (StrUtil.isNotBlank(line) &&
- !StrUtil.equals(line, "event: answer") &&
- !StrUtil.equals(line, "event: chatResponse") &&
- !StrUtil.contains(line, "data: {\"quoteLen\"")) {
- line = CollectionUtil.removeEmpty(StrUtil.split(line, "data: ")).get(0);
- if (!StrUtil.contains(line, "[DONE]")) {
- String oneWord = catchTextGpt(line);
- if (StrUtil.isNotBlank(oneWord)) {
- answerContent = answerContent + oneWord;
- }
- }
- WebSocketService.sendInfo(line, SecurityUtils.getUserId() + "");
- TimeUnit.MILLISECONDS.sleep(50);
- }
- }
- //处理完了后将次条聊天记录进行记录
- if (StrUtil.isNotBlank(answerContent)) {
- //保存聊天记录
- this.saveDialogueProcess(chatBotSingleQuestionVO, answerContent);
- //更新提问次数
- this.upddateAppModel(chatBotSingleQuestionVO);
- }
- is.close();
- reader.close();
-
-
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage());
- }finally {
- redisLock.unlock(lockName);
- }
- return answerContent;
- }
sendRequestBeforeChat方法
- /**
- * 这块为问询,不包含对话模式
- *
- * @param chatBotSingleQuestionVO
- * @return
- * @throws Exception
- */
- @Transactional
- public InputStream sendRequestBeforeChat(ChatBotSingleQuestionVO chatBotSingleQuestionVO) throws Exception {
- InputStream in = null;
- // 通知内容添加文本铭感词汇过滤
- //其余错误见返回码说明
- //正常返回0
- //违禁词检测
- this.disableWordCheck(chatBotSingleQuestionVO.getPrompt());
- String apikeyRefresh = getOpenAiKey();
- if (StrUtil.isBlank(apikeyRefresh)) {
- throw new RuntimeException("无可用key");
- }
- List<Gpt35TurboVO> chatContext = this.getChatContext(chatBotSingleQuestionVO);
- String requestUrl = iTbKeyManagerService.getproxyUrl();
- Map<Object, Object> objectObjectHashMap = new HashMap<>();
- objectObjectHashMap.put("model", "gpt-3.5-turbo");
- objectObjectHashMap.put("messages", chatContext);
- objectObjectHashMap.put("stream", true);
- objectObjectHashMap.put("temperature", 0);
- objectObjectHashMap.put("frequency_penalty", 0);
- objectObjectHashMap.put("presence_penalty", 0.6);
- String bodyJson = JSONUtil.toJsonStr(objectObjectHashMap);
- URL url = new URL(requestUrl); // 接口地址
- HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setDoOutput(true);
- urlConnection.setDoInput(true);
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("Connection", "Keep-Alive");
- urlConnection.setRequestProperty("Charset", "UTF-8");
- urlConnection.setRequestProperty("Authorization", "Bearer " + apikeyRefresh);
- urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
- byte[] dataBytes = bodyJson.getBytes();
- urlConnection.setRequestProperty("Content-Length", String.valueOf(dataBytes.length));
- OutputStream os = urlConnection.getOutputStream();
- os.write(dataBytes);
- in = new BufferedInputStream(urlConnection.getInputStream());
- os.flush();
- os.close();
- return in;
-
- }
catchTextGpt方法
- /**
- * 处理单独打印的文字
- *
- * @param str
- * @return
- */
- public String catchTextGpt(String str) {
- String choices = JsonUtil.parseMiddleData(str, "choices");
- JSONArray jsonArray = JSONUtil.parseArray(choices);
- String string = jsonArray.getByPath("[0].delta").toString();
- String content = JsonUtil.parseMiddleData(string, "content");
- return content;
- }
getChatContext方法
- /**
- * 角色扮演
- * @param chatBotSingleQuestionVO
- * @return 结果
- */
- public List<Gpt35TurboVO> getChatContext(ChatBotSingleQuestionVO chatBotSingleQuestionVO) {
-
- List<Gpt35TurboVO> messages = new ArrayList<>();
-
- //首先获取角色,设置默认角色
- String default_role_content = iconfigService.selectConfigByKey("default_role");
- if (StrUtil.isBlank(default_role_content)) {
- default_role_content = "我是一个全能机器人,可以回答你任何问题";
- }
-
- TbAppModel tbAppModel = iTbAppModelService.selectTbAppModelById(Long.valueOf(chatBotSingleQuestionVO.getRolePlayId()));
- if (!Objects.isNull(tbAppModel)){
- default_role_content = tbAppModel.getAppModelContent();
- }
- //小程序专用
- //是否通过微信小程序审核的设定语
- String is_open_pass_wx_promt = iconfigService.selectConfigByKey("is_open_pass_wx_promt");
- if (StrUtil.isNotBlank(is_open_pass_wx_promt) && !StrUtil.equals(is_open_pass_wx_promt, "0")) {
- String pass_wx_promt = iconfigService.selectConfigByKey("pass_wx_promt");
- default_role_content = default_role_content + "。并且你必须遵循:" + pass_wx_promt;
- }
-
- //设定系统所扮演的角色
- Gpt35TurboVO gpt35TurboVOSys = new Gpt35TurboVO();
- gpt35TurboVOSys.setRole("system");
- gpt35TurboVOSys.setContent(default_role_content);
- messages.add(gpt35TurboVOSys);
-
-
- //最后查询用户最新询问的问题
- Gpt35TurboVO gpt35TurboUser = new Gpt35TurboVO();
- gpt35TurboUser.setRole("user");
- gpt35TurboUser.setContent(chatBotSingleQuestionVO.getPrompt());
- messages.add(gpt35TurboUser);
- return messages;
- }
getOpenAiKey方法
- /**
- * 查询key是否可用
- * @return 结果
- */
- public String getOpenAiKey() {
- //模仿查到的key集合
- TbKeyManager tbKeyManager = new TbKeyManager();
- tbKeyManager.setIsUse(1);
- //可用的key
- List<TbKeyManager> tbKeyManagers = iTbKeyManagerService.selectTbKeyManagerList(tbKeyManager);
- //判断是否key额度用完
- if (CollectionUtil.isEmpty(tbKeyManagers) || tbKeyManagers.size() <= 0) {
- throw new RuntimeException("key额度耗尽");
- }
- //获取第一个key,然后将第一个key存入缓存
- String key = tbKeyManagers.get(0).getSecretKey();
- redisTemplate.opsForValue().set("apikey", key);
- //检查key
- changeKey(tbKeyManagers.get(0));
- return key;
- }
Controller
- @PostMapping(value = "/chatBotNoId/api")
- public AjaxResult continuousDialogue(@RequestBody StreamParametersVO streamParametersVO) {
- String answerContent = iChatGtpService.continuousDialogueSocketStream(streamParametersVO);
- return success("success", answerContent);
- }
Impl
- /**
- * 用户直接发起连续对话,系统同意创建对话主题,用户不用手动新建主题
- *
- * @param streamParametersVO
- */
- @Override
- public String continuousDialogueSocketStream(StreamParametersVO streamParametersVO) {
-
- //判断是否isNewOpen填写参数,表示是否先开对话
- if (Objects.isNull(streamParametersVO.getIsNewOpen())) {
- throw new RuntimeException("isNewOpen参数未填");
- }
-
- if (streamParametersVO.getIsNewOpen()) {
- //新开对话,创建新的对话主题
- tbModelTable = new TbModelTable();
- //主题名称
- tbModelTable.setModelName("Dialogue_" + SecurityUtils.getUserId() + "_" + DateTime.now());
- //设置模板角色
- if (Objects.nonNull(streamParametersVO.getDialogueRoleId())) {
- tbModelTable.setId(Long.valueOf(streamParametersVO.getDialogueRoleId()));
- } else {
- tbModelTable.setId(1L);
- }
- tbDialogueMain = tbDialogueMainService.creatNewDig(tbModelTable);
- } else {
- //非新开对话,查询本次的对话主题
- TbDialogueMain tbDialogueMainParam = new TbDialogueMain();
- //设置模板角色
- if (Objects.nonNull(streamParametersVO.getDialogueRoleId())) {
- tbDialogueMainParam.setDialogueRoleId(Long.valueOf(streamParametersVO.getDialogueRoleId()));
- } else {
- tbDialogueMainParam.setDialogueRoleId(1L);
- }
-
- tbDialogueMainParam.setUserId(SecurityUtils.getUserId());
- List<TbDialogueMain> tbDialogueMains = iTbDialogueMainService.selectTbDialogueMainList(tbDialogueMainParam);
-
- if (CollectionUtil.isEmpty(tbDialogueMains)) {
- //创建新的对话主题
- tbModelTable = new TbModelTable();
- //主题名称
- tbModelTable.setModelName("Dialogue_" + SecurityUtils.getUserId() + "_" + DateTime.now());
- //设置模板角色
- tbModelTable.setId(Long.valueOf(streamParametersVO.getDialogueRoleId()));
- tbDialogueMain = tbDialogueMainService.creatNewDig(tbModelTable);
- } else {
- tbDialogueMain = tbDialogueMains.get(0);
- }
-
- }
-
- //设置对话ID
- streamParametersVO.setDialogueId(tbDialogueMain.getId());
-
- String lockName = "chat_" + SecurityUtils.getUserId();
- //回答的内容
- String answerContent = "";
- try {
-
- RLock rLock = redisLock.getRLock(lockName);
- boolean locked = rLock.isLocked();
-
- if (locked) {
- throw new RuntimeException("正在回复中...");
- }
-
- //对同一用户访问加锁
- redisLock.lock(lockName);
-
- //进来做校验
- TbDialogueMain tbDialogueMain = this.paramVerify(streamParametersVO);
-
- String userId = SecurityUtils.getUserId() + "";
-
- //将提问数据封装为流,并请求OpenAI的接口
- InputStream inputStream = this.sendRequestBefore(streamParametersVO, tbDialogueMain);
-
- String line = null;
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
-
- while ((line = reader.readLine()) != null) {
-
- //首先对行数据进行处理
- if (StrUtil.isNotBlank(line) &&
- !StrUtil.equals(line, "event: answer") &&
- !StrUtil.equals(line, "event: chatResponse") &&
- !StrUtil.contains(line, "data: {\"quoteLen\"")) {
-
- line = CollectionUtil.removeEmpty(StrUtil.split(line, "data: ")).get(0);
-
- if (StrUtil.contains(line, "[DONE]")) {
- } else {
-
- String oneWord = catchTextGpt(line);
- if (StrUtil.isNotBlank(oneWord)) {
- answerContent = answerContent + oneWord;
- }
- }
-
- WebSocketService.sendInfo(line, userId);
- TimeUnit.MILLISECONDS.sleep(50);
-
- }
- }
-
- //处理完了后,将此条聊天记录进行保存
- if (StrUtil.isNotBlank(answerContent)) {
- //保存聊天记录
- this.saveDig(streamParametersVO, answerContent);
- }
- inputStream.close();
- reader.close();
-
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage());
- } finally {
- //解锁
- redisLock.unlock(lockName);
- //清除正在问话的标识
- redisTemplate.delete(SecurityUtils.getUserId() + "");
- }
-
- return answerContent;
- }
sendRequestBefore方法
- /**
- * 这块为 - 流对话模式的封装
- *
- * @param streamParametersVO
- * @param tbDialogueMain
- * @return
- * @throws Exception
- */
- @Transactional
- public InputStream sendRequestBefore(StreamParametersVO streamParametersVO, TbDialogueMain tbDialogueMain) throws Exception {
-
- InputStream in = null;
- //提问内容
- String prompt = streamParametersVO.getPrompt();
-
- // 获取当前的用户
- String userId = SecurityUtils.getUserId() + "";
- Object o = redisTemplate.opsForValue().get(userId);
-
- if (!Objects.isNull(o)) {
- throw new RuntimeException("正在回复");
- }
-
- redisTemplate.opsForValue().set(userId, true, 30, TimeUnit.SECONDS);
-
- if (StrUtil.isBlank(prompt)) {
- throw new RuntimeException("输入内容为空");
- }
-
- // 通知内容添加文本铭感词汇过滤
- // 其余错误见返回码说明
- // 违禁词检测 正常返回0
- this.disableWordCheck(prompt);
-
- String apikeyRefresh = getOpenAiKey();
- if (StrUtil.isBlank(apikeyRefresh)) {
- throw new RuntimeException("无可用key");
- }
-
- //处理提问内容(指定系统角色+对话上下文+最新的提问内容)
- List<Gpt35TurboVO> chatContext = this.getChatDigContext(streamParametersVO, tbDialogueMain);
-
- String requestUrl = iTbKeyManagerService.getproxyUrl();
- Map<Object, Object> objectObjectHashMap = new HashMap<>();
- objectObjectHashMap.put("model", "gpt-3.5-turbo");
- objectObjectHashMap.put("messages", chatContext);
- objectObjectHashMap.put("stream", true);
- objectObjectHashMap.put("temperature", 0);
- objectObjectHashMap.put("frequency_penalty", 0);
- objectObjectHashMap.put("presence_penalty", 0.6);
- String bodyJson = JSONUtil.toJsonStr(objectObjectHashMap);
- URL url = new URL(requestUrl); // 接口地址
- HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setDoOutput(true);
- urlConnection.setDoInput(true);
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("Connection", "Keep-Alive");
- urlConnection.setRequestProperty("Charset", "UTF-8");
- urlConnection.setRequestProperty("Authorization", "Bearer " + apikeyRefresh);
- urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
- byte[] dataBytes = bodyJson.getBytes();
- urlConnection.setRequestProperty("Content-Length", String.valueOf(dataBytes.length));
- OutputStream os = urlConnection.getOutputStream();
- os.write(dataBytes);
- in = new BufferedInputStream(urlConnection.getInputStream());
- os.flush();
- os.close();
- return in;
-
- }
getChatDigContext方法
- /**
- * 获取对话上下文
- *
- * @param streamParametersVO
- * @return
- */
- public List<Gpt35TurboVO> getChatDigContext(StreamParametersVO streamParametersVO, TbDialogueMain tbDialogueMain) {
-
- List<Gpt35TurboVO> messages = new ArrayList<>();
-
- //首先获取角色,默认角色
- String default_role_content = iconfigService.selectConfigByKey("default_role");
- if (StrUtil.isBlank(default_role_content)) {
- default_role_content = "我是一个全能机器人,可以回答你任何问题";
- }
-
- //根据用户传递过来的Id查询角色模型数据
- TbModelTable tbModelTable = iTbModelTableService.selectTbModelTableById(tbDialogueMain.getDialogueRoleId());
- if (!Objects.isNull(tbModelTable)) {
- default_role_content = tbModelTable.getModelContent();
- }
-
- //小程序专用
- //是否通过微信小程序审核的设定语
- String is_open_pass_wx_promt = iconfigService.selectConfigByKey("is_open_pass_wx_promt");
- if (StrUtil.isNotBlank(is_open_pass_wx_promt) && !StrUtil.equals(is_open_pass_wx_promt, "0")) {
- String pass_wx_promt = iconfigService.selectConfigByKey("pass_wx_promt");
- default_role_content = default_role_content + "。并且你必须遵循:" + pass_wx_promt;
- }
-
- //设定系统所扮演的角色
- Gpt35TurboVO gpt35TurboVOSys = new Gpt35TurboVO();
- gpt35TurboVOSys.setRole("system");
- gpt35TurboVOSys.setContent(default_role_content);
- messages.add(gpt35TurboVOSys);
-
- //然后查询当前对话的上下文数据TbDialogueProcess
- TbDialogueProcess tbDialogueProcess = new TbDialogueProcess();
- tbDialogueProcess.setSessionId(streamParametersVO.getDialogueId());
- tbDialogueProcess.setUserId(SecurityUtils.getUserId());
- String default_context_num = iconfigService.selectConfigByKey("default_context_num");
- if (StrUtil.isBlank(default_context_num) || !NumberUtil.isNumber(default_context_num)) {
- default_context_num = "10";
- }
- tbDialogueProcess.setLimitNum(Integer.valueOf(default_context_num));
-
- //根据对话ID和用户ID查询到对话列表-根据时间倒叙获取后几条设定的数据
- List<TbDialogueProcess> tbDialogueProcessesDesc = iTbDialogueProcessService
- .selectTbDialogueProcessListByLimitDesc(tbDialogueProcess);
-
- if (CollectionUtil.isNotEmpty(tbDialogueProcessesDesc)) {
- //获取到倒数10条数据后将数据正序配好
- List<TbDialogueProcess> tbDialogueProcesses = tbDialogueProcessesDesc
- .stream()
- .sorted(Comparator.comparing(TbDialogueProcess::getCreateTime))
- .collect(Collectors.toList());
-
- for (TbDialogueProcess tbDialogueProcessfor : tbDialogueProcesses) {
- Gpt35TurboVO gpt35TurboUser = new Gpt35TurboVO();
- //用户询问的问题
- gpt35TurboUser.setRole("user");
- gpt35TurboUser.setContent(tbDialogueProcessfor.getAskContent());
- messages.add(gpt35TurboUser);
- //机器人回答的问题
- Gpt35TurboVO gpt35TurAssistant = new Gpt35TurboVO();
- gpt35TurAssistant.setRole("assistant");
- gpt35TurAssistant.setContent(tbDialogueProcessfor.getAnswerContent());
- messages.add(gpt35TurAssistant);
- }
-
- }
-
- //最后查询用户最新询问的问题
- Gpt35TurboVO gpt35TurboUser = new Gpt35TurboVO();
- gpt35TurboUser.setRole("user");
- gpt35TurboUser.setContent(streamParametersVO.getPrompt());
- messages.add(gpt35TurboUser);
-
- return messages;
- }
Controller
- @PostMapping("/image/api")
- public AjaxResult imageApi(@RequestBody StreamImageParametersVO streamImageParametersVO) {
- String answerContent = iChatGptImageService.imageSocketStream(streamImageParametersVO);
- return success("success",answerContent);
- }
Impl
- @Override
- public String imageSocketStream(StreamImageParametersVO imageParametersVO) {
-
- String lockName = "image_" + SecurityUtils.getUserId();
-
- String answerContent = "";
-
- try{
- RLock rLock = redisLock.getRLock(lockName);
- boolean locked = rLock.isLocked();
- if (locked){
- throw new RuntimeException("回复中");
- }
- //对同一用户访问加锁
- redisLock.lock(lockName);
- //校验是否输入内容,次数扣减
- this.imageBefore(imageParametersVO);
- String userId = SecurityUtils.getUserId() + "";
- InputStream is = this.sendRequestBeforeImage(imageParametersVO);
- String line = null;
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- while((line = reader.readLine()) != null){
- //数据处理
- if (StrUtil.isNotBlank(line) &&
- !StrUtil.equals(line, "event: answer") &&
- !StrUtil.equals(line, "event: chatResponse") &&
- !StrUtil.contains(line, "data: {\"quoteLen\"")) {
- line = CollectionUtil.removeEmpty(StrUtil.split(line, "data: ")).get(0);
- if (StrUtil.contains(line, "[DONE]")){
-
- }else{
- String oneWord = catchUrlImage(line);
- if (StrUtil.isNotBlank(oneWord)){
- answerContent = answerContent + oneWord;
- }
- }
- WebSocketService.sendInfo(line,userId);
- TimeUnit.MILLISECONDS.sleep(50);
- }
- }
- //处理完之后将次条聊天记录进行记录
- if (StrUtil.isNotBlank(answerContent)){
- //保存聊天记录
- this.saveDialogueLog(imageParametersVO, answerContent);
- }
- is.close();
- reader.close();
-
- }catch (Exception e){
- throw new RuntimeException(e.getMessage());
- }finally {
- //解锁
- redisLock.unlock(lockName);
- redisTemplate.delete(SecurityUtils.getUserId() + "");
- }
-
- return saveImageUrl(jsonImageUrl(answerContent));
- }
sendRequestBeforeImage方法
- /**
- * 问询,不包含对话模式
- */
- @Transactional
- public InputStream sendRequestBeforeImage(StreamImageParametersVO imageParametersVO) throws Exception{
- InputStream in = null;
- //通知内容添加文本敏感词汇过滤
- //其余错误见返回码说明
- //正常返回0
- //违禁词检测
- this.disbleWordImageCheck(imageParametersVO.getPrompt());
- String apikeyRefresh = getOpenAiKey();
- if (StrUtil.isBlank(apikeyRefresh)){
- throw new RuntimeException("无可用key");
- }
-
- // List<Gpt35TurboVO> imageContext = this.getImageContext(imageParametersVO);
- String requestImageUrl = iTbKeyManagerService.getImageProxyUrl();
- Map<Object, Object> objectObjecHashtMap = new HashMap<>();
- objectObjecHashtMap.put("prompt", imageParametersVO.getPrompt());
- objectObjecHashtMap.put("n", 1);
- objectObjecHashtMap.put("size", "1024x1024");
- String bodyJson = JSONUtil.toJsonStr(objectObjecHashtMap);
- URL url = new URL(requestImageUrl); //接口地址
- HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setDoOutput(true);
- urlConnection.setDoInput(true);
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("Connection", "Keep-Alive");
- urlConnection.setRequestProperty("Charset", "UTF-8");
- urlConnection.setRequestProperty("Authorization", "Bearer " + apikeyRefresh);
- urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
- byte[] dataBytes = bodyJson.getBytes();
- urlConnection.setRequestProperty("Content-Length", String.valueOf(dataBytes.length));
- OutputStream os = urlConnection.getOutputStream();
- os.write(dataBytes);
- in = new BufferedInputStream(urlConnection.getInputStream());
- os.flush();
- os.close();
- return in;
-
- }
catchUrlImage方法
- /**
- * 对链接地址处理
- */
- public String catchUrlImage(String str){
-
- return str;
-
- }
图片处理,chatgpt返回的图片有效期是五分钟,我们需要将图片下载至本地或服务器。
- /**
- * 保存图片返回的结果
- */
- public String saveImageUrl(String jsonUrl){
-
- String imageURL = uploadFileImageAi(jsonUrl);
-
- // 找到下划线的索引位置
- int underscoreIndex = imageURL.indexOf('_');
-
- String result = "";
-
- if (underscoreIndex != -1) {
- // 截取从下划线的位置开始到字符串的末尾
- result = imageURL.substring(underscoreIndex - 9);
- } else {
- throw new RuntimeException("图片链接截取失败");
- }
-
- return TomcatConfig.getImageAiUrl() + "/" + result;
- }
-
- /**
- * 图片处理
- * @param imageUrl
- * @return
- */
- public String uploadFileImageAi(String imageUrl){
-
- // //服务器文件上传路径
- String path = TomcatConfig.setUploadImageAiUrl() + Constants.DRAW_PREFIX + "_" + Seq.getId(Seq.uploadSeqType) + ".png";
- // 本地文件上传路径
- // String path = "D:\\BaiduNetdiskDownload\\image-use\\" + Constants.DRAW_PREFIX + "_" + Seq.getId(Seq.uploadSeqType) + ".png";
-
- try{
- URL url = new URL(imageUrl);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- int responseCode = connection.getResponseCode();
- if (responseCode == HttpURLConnection.HTTP_OK) {
- InputStream inputStream = connection.getInputStream();
- OutputStream outputStream = new FileOutputStream(path);
-
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- outputStream.write(buffer, 0, bytesRead);
- }
-
- outputStream.close();
- inputStream.close();
- } else {
- throw new RuntimeException("文件无法下载");
- }
- }catch (IOException e){
- e.printStackTrace();
- }
- return path;
- }
-
- /**
- * JSON数据处理
- * @param imageContent
- * @return
- */
- public String jsonImageUrl(String imageContent){
-
- //解析json字符串
- JSONObject obj = JSON.parseObject(imageContent);
-
- //获取 "data"字段相应的JSON数组
- JSONArray dataArray = obj.getJSONArray("data");
-
- //获取第一个元素路径地址
- JSONObject dataObject = dataArray.getJSONObject(0);
-
- // 返回"url"字段的值
- return dataObject.getString("url");
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。