作者 钟来

修改bug

@@ -80,6 +80,16 @@ @@ -80,6 +80,16 @@
80 <artifactId>okhttp</artifactId> 80 <artifactId>okhttp</artifactId>
81 <version>4.10.0</version> 81 <version>4.10.0</version>
82 </dependency> 82 </dependency>
  83 +
  84 + <dependency>
  85 + <groupId>com.zhonglai.luhui</groupId>
  86 + <artifactId>ruoyi-system</artifactId>
  87 + </dependency>
  88 +
  89 + <dependency>
  90 + <groupId>cn.hutool</groupId>
  91 + <artifactId>hutool-all</artifactId>
  92 + </dependency>
83 </dependencies> 93 </dependencies>
84 94
85 <build> 95 <build>
1 package com.zhonglai.luhui.openai.controller; 1 package com.zhonglai.luhui.openai.controller;
2 2
  3 +import cn.hutool.http.HttpUtil;
  4 +import com.alibaba.fastjson.JSONObject;
3 import com.ruoyi.common.core.controller.BaseController; 5 import com.ruoyi.common.core.controller.BaseController;
4 import com.ruoyi.common.core.domain.AjaxResult; 6 import com.ruoyi.common.core.domain.AjaxResult;
5 import com.ruoyi.common.core.domain.Message; 7 import com.ruoyi.common.core.domain.Message;
6 import com.ruoyi.common.core.domain.MessageCode; 8 import com.ruoyi.common.core.domain.MessageCode;
  9 +import com.ruoyi.common.utils.Arith;
  10 +import com.ruoyi.common.utils.DateUtils;
7 import com.ruoyi.common.utils.SecurityUtils; 11 import com.ruoyi.common.utils.SecurityUtils;
  12 +import com.ruoyi.common.utils.StringUtils;
  13 +import com.ruoyi.common.utils.bean.BeanUtils;
  14 +import com.ruoyi.common.utils.html.HttpUtils;
  15 +import com.ruoyi.common.utils.http.OkHttpUtils;
  16 +import com.ruoyi.system.login.dto.OpenAiLoginUser;
  17 +import com.ruoyi.system.login.dto.OpenAiUserInfo;
8 import com.ruoyi.system.service.PublicService; 18 import com.ruoyi.system.service.PublicService;
  19 +import com.theokanning.openai.Usage;
9 import com.theokanning.openai.completion.CompletionChoice; 20 import com.theokanning.openai.completion.CompletionChoice;
  21 +import com.theokanning.openai.completion.CompletionResult;
  22 +import com.zhonglai.luhui.openai.dto.*;
10 import com.zhonglai.luhui.openai.utils.OpenAiUtils; 23 import com.zhonglai.luhui.openai.utils.OpenAiUtils;
  24 +import com.zhonglai.luhui.openai.utils.SysConfigKeyType;
11 import io.swagger.annotations.Api; 25 import io.swagger.annotations.Api;
12 import io.swagger.annotations.ApiOperation; 26 import io.swagger.annotations.ApiOperation;
  27 +import okhttp3.Request;
  28 +import okhttp3.Response;
  29 +import org.apache.commons.io.input.ReaderInputStream;
13 import org.springframework.beans.factory.annotation.Autowired; 30 import org.springframework.beans.factory.annotation.Autowired;
  31 +import org.springframework.transaction.annotation.Transactional;
14 import org.springframework.web.bind.annotation.*; 32 import org.springframework.web.bind.annotation.*;
15 33
16 import javax.servlet.http.HttpServletRequest; 34 import javax.servlet.http.HttpServletRequest;
  35 +import javax.servlet.http.HttpServletResponse;
17 import javax.servlet.http.HttpSession; 36 import javax.servlet.http.HttpSession;
  37 +import java.io.ByteArrayOutputStream;
  38 +import java.io.IOException;
  39 +import java.io.InputStream;
  40 +import java.math.BigDecimal;
  41 +import java.util.ArrayList;
18 import java.util.List; 42 import java.util.List;
  43 +import java.util.Map;
  44 +import java.util.Optional;
  45 +import java.util.stream.Collectors;
19 46
20 @Api(tags = "chatGPT接口") 47 @Api(tags = "chatGPT接口")
21 @RestController 48 @RestController
@@ -45,4 +72,148 @@ public class ChatGPTController extends BaseController { @@ -45,4 +72,148 @@ public class ChatGPTController extends BaseController {
45 return new Message(MessageCode.DEFAULT_SUCCESS_CODE,list); 72 return new Message(MessageCode.DEFAULT_SUCCESS_CODE,list);
46 } 73 }
47 74
  75 + private ChatRoomMessages mapToChatRoomMessages(Map<String,Object> src)
  76 + {
  77 + ChatRoomMessages chatRoomMessages = new ChatRoomMessages();
  78 + BeanUtils.copyBeanProp(chatRoomMessages,src);
  79 + return chatRoomMessages;
  80 + }
  81 +
  82 + @ApiOperation("chatgpt3.5")
  83 + @Transactional
  84 + @RequestMapping(value = "/chatgptV3_5",method = RequestMethod.POST)
  85 + public Message chatgptV3_5(HttpServletRequest httpServletRequest, @RequestBody String data)
  86 + {
  87 + OpenAiLoginUser userInfo = (OpenAiLoginUser) getLoginUser();
  88 + Integer user_id= userInfo.getUserId().intValue();
  89 + OpenAiUserInfo openAiUserInfo = (OpenAiUserInfo) userInfo.getUser();
  90 + if(openAiUserInfo.getFlow_packet_remain()<=0)
  91 + {
  92 + return new Message(MessageCode.DEFAULT_FAIL_CODE,"余量不足");
  93 + }
  94 +
  95 + List<Map<String,Object>> unitpriceList = publicService.getObjectListBySQL("select `key`,`value` from `lk_openai`.`sys_config` where `key_type`='"+SysConfigKeyType.gpt_3_5_unitprice+"'");
  96 + BigDecimal openaiUnitprice = new BigDecimal(0);
  97 + BigDecimal realityUnitprice = new BigDecimal(0);
  98 + if(null != unitpriceList && unitpriceList.size() !=0)
  99 + {
  100 + for(Map<String,Object> map:unitpriceList)
  101 + {
  102 + if("openai".equals(map.get("key")))
  103 + {
  104 + openaiUnitprice = new BigDecimal(map.get("value").toString());
  105 + }else if("reality".equals(map.get("key")))
  106 + {
  107 + realityUnitprice = new BigDecimal(map.get("value").toString());
  108 + }
  109 + }
  110 + }
  111 + if(openaiUnitprice.intValue()==0 || realityUnitprice.intValue()==0)
  112 + {
  113 + return new Message(MessageCode.DEFAULT_FAIL_CODE,"系统未配置流量单价,请联系管理员");
  114 + }
  115 +
  116 + String room_id = String.valueOf(user_id);
  117 + logger.info("{}生成聊天会话:",room_id);
  118 +
  119 + List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT send_role role,send_content content FROM `lk_openai`.`gpt_message` WHERE room_id='"+room_id+"' AND user_id="+user_id+" order by create_time asc limit 5");
  120 +
  121 + List<ChatRoomMessages> messageList = Optional.ofNullable(list).orElse(new ArrayList<>()).stream().map(item->mapToChatRoomMessages(item)).collect(Collectors.toList());
  122 +
  123 + ChatRoomMessages chatRoomMessages = new ChatRoomMessages();
  124 + chatRoomMessages.setRole("user");
  125 + chatRoomMessages.setContent(data);
  126 + messageList.add(chatRoomMessages);
  127 +
  128 + //获取返回参数
  129 + CompletionResult3_5 completionResult3_5 = sendGPTAi(messageList);
  130 + Usage usage = completionResult3_5.getUsage();
  131 +
  132 + List<CompletionChoice3_5> list3_5 = completionResult3_5.getChoices();
  133 + List<CompletionChoiceMessage3_5> rlist = new ArrayList<>();
  134 +
  135 + if(null != list3_5 && list3_5.size() !=0 )
  136 + {
  137 + List<GptMessage> insertGptMessages = new ArrayList<>();
  138 + int i=0;
  139 + for (CompletionChoice3_5 completionChoice:list3_5)
  140 + {
  141 + GptMessage gptMessage = new GptMessage();
  142 + gptMessage.setRoom_id(room_id);
  143 + gptMessage.setUser_id(user_id);
  144 + gptMessage.setCreate_time(DateUtils.getNowTimeMilly());
  145 + gptMessage.setSend_role(chatRoomMessages.getRole());
  146 + gptMessage.setSend_content(chatRoomMessages.getContent());
  147 + if(insertGptMessages.size()==0) //第一次计数后面不计数
  148 + {
  149 + gptMessage.setSend_size(gptMessage.getSend_content().length());
  150 + //统计代币
  151 + gptMessage.setCompletion_tokens(usage.getCompletionTokens());
  152 + gptMessage.setPrompt_tokens(usage.getPromptTokens());
  153 + }else{
  154 + gptMessage.setSend_size(0);
  155 + }
  156 +
  157 + if(null != completionChoice.getMessage())
  158 + {
  159 + rlist.add(completionChoice.getMessage());
  160 +
  161 + gptMessage.setMessage_role(completionChoice.getMessage().getRole());
  162 + gptMessage.setMessage_content(completionChoice.getMessage().getContent());
  163 + }
  164 + gptMessage.setMessage_size(0);
  165 + if(null != gptMessage.getMessage_content())
  166 + {
  167 + gptMessage.setMessage_size(gptMessage.getMessage_content().length());
  168 + }
  169 + i+=gptMessage.getMessage_content().length();
  170 +
  171 + insertGptMessages.add(gptMessage);
  172 + }
  173 +
  174 + logger.info("{} 请求的流量:{},回复的流量:{}",room_id,messageList.get(messageList.size()-1).getContent().length(),i);
  175 +
  176 + if(null != insertGptMessages && insertGptMessages.size() !=0 )
  177 + {
  178 + publicService.insertAllToTable(insertGptMessages,"`lk_openai`.`gpt_message`");
  179 + }
  180 +
  181 + publicService.updateBySql("UPDATE `user_info` SET flow_packet_remain=flow_packet_remain-"+usage.getTotalTokens()+" WHERE id="+openAiUserInfo.getId());
  182 +
  183 + UserFlowPacketRemainLog userFlowPacketRemainLog = new UserFlowPacketRemainLog();
  184 + userFlowPacketRemainLog.setCreate_time(DateUtils.getNowTimeMilly());
  185 + userFlowPacketRemainLog.setUser_id(openAiUserInfo.getId());
  186 + userFlowPacketRemainLog.setRoom_id(room_id);
  187 + userFlowPacketRemainLog.setPrompt_tokens(usage.getPromptTokens());
  188 + userFlowPacketRemainLog.setCompletion_tokens(usage.getCompletionTokens());
  189 + userFlowPacketRemainLog.setTotal_tokens(usage.getTotalTokens());
  190 + userFlowPacketRemainLog.setOpenai_money(openaiUnitprice.multiply(new BigDecimal(usage.getTotalTokens())).divide(new BigDecimal(1000),6));
  191 + userFlowPacketRemainLog.setReality_money(realityUnitprice.multiply(new BigDecimal(usage.getTotalTokens())).divide(new BigDecimal(1000),6));
  192 + publicService.insertToTable(userFlowPacketRemainLog,"`lk_openai`.`user_flow_packet_remain_log`");
  193 + }
  194 + return new Message(MessageCode.DEFAULT_FAIL_CODE,rlist);
  195 + }
  196 +
  197 +
  198 + private CompletionResult3_5 sendGPTAi(List<ChatRoomMessages> messageList)
  199 + {
  200 + JSONObject jsonObject = new JSONObject();
  201 + jsonObject.put("model","gpt-3.5-turbo-0301");
  202 + jsonObject.put("messages",messageList);
  203 + String str = HttpUtil.post("https://chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString());
  204 + CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class);
  205 + return completionResult;
  206 + }
  207 +
  208 + public static byte[] readInputStream(InputStream inputStream) throws IOException {
  209 + byte[] buffer = new byte[1024];
  210 + int len = 0;
  211 + ByteArrayOutputStream bos = new ByteArrayOutputStream();
  212 + while((len = inputStream.read(buffer)) != -1) {
  213 + bos.write(buffer, 0, len);
  214 + }
  215 + bos.close();
  216 + return bos.toByteArray();
  217 + }
  218 +
48 } 219 }
  1 +package com.zhonglai.luhui.openai.controller;
  2 +
  3 +import cn.hutool.http.HttpUtil;
  4 +import com.alibaba.fastjson.JSON;
  5 +import com.ruoyi.common.constant.Constants;
  6 +import com.ruoyi.common.core.controller.BaseController;
  7 +import com.ruoyi.common.core.domain.Message;
  8 +import com.ruoyi.common.core.domain.MessageCode;
  9 +import com.ruoyi.system.login.service.LoginService;
  10 +import io.swagger.annotations.Api;
  11 +import io.swagger.annotations.ApiImplicitParam;
  12 +import io.swagger.annotations.ApiImplicitParams;
  13 +import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.web.bind.annotation.PostMapping;
  16 +import org.springframework.web.bind.annotation.RequestMapping;
  17 +import org.springframework.web.bind.annotation.RestController;
  18 +
  19 +import java.util.HashMap;
  20 +import java.util.Map;
  21 +
  22 +@Api(tags = "登陆")
  23 +@RestController
  24 +@RequestMapping("/openAiUserLogin")
  25 +public class OpenAiUserLoginController extends BaseController {
  26 + private static String user_pass = "123456";
  27 + @Autowired
  28 + private LoginService loginService;
  29 + @ApiOperation("手机验证码登陆")
  30 + @ApiImplicitParams({
  31 + @ApiImplicitParam(value = "手机号",name = "phone"),
  32 + @ApiImplicitParam(value = "验证码",name = "code"),
  33 + })
  34 + @PostMapping("/userpassLogin")
  35 + public Message userpassLogin(String phone, String code,String key)
  36 + {
  37 + //验证验证码
  38 + String str = HttpUtil.get("http://ly.userlogin.yu2le.com/userLogin/verificationCode?key="+key+"&code="+code);
  39 + Message message = JSON.parseObject(str,Message.class);
  40 + if(message.getCode()!=MessageCode.DEFAULT_SUCCESS_CODE.code)
  41 + {
  42 + return message;
  43 + }
  44 + //生成令牌
  45 + String token = loginService.openaiLoginByPass(phone,user_pass);
  46 + Map<String,Object> map = new HashMap<>();
  47 + map.put(Constants.TOKEN, token);
  48 + return new Message(MessageCode.DEFAULT_SUCCESS_CODE,map);
  49 + }
  50 +
  51 +
  52 + @ApiOperation("发送验证码")
  53 + @ApiImplicitParams({
  54 + @ApiImplicitParam(value = "手机号",name = "phone"),
  55 + })
  56 + @PostMapping("/sendPhoneCode")
  57 + public Message sendPhoneCode(String phone)
  58 + {
  59 + //生成令牌
  60 + String str = HttpUtil.get("http://ly.userlogin.yu2le.com/userLogin/getPhoneCode/1/"+phone);
  61 + return JSON.parseObject(str,Message.class);
  62 + }
  63 +
  64 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +/**
  4 + * 聊天室消息
  5 + */
  6 +public class ChatRoomMessages {
  7 + private String role; //角色(system “系统”、user “用户”、assistant “助手”)
  8 + private String content; //内容(消息的内容)
  9 +
  10 + public String getRole() {
  11 + return role;
  12 + }
  13 +
  14 + public void setRole(String role) {
  15 + this.role = role;
  16 + }
  17 +
  18 + public String getContent() {
  19 + return content;
  20 + }
  21 +
  22 + public void setContent(String content) {
  23 + this.content = content;
  24 + }
  25 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +public class CompletionChoice3_5 {
  4 + private CompletionChoiceMessage3_5 message;
  5 + private String finish_reason;
  6 + private Integer index;
  7 +
  8 + public CompletionChoiceMessage3_5 getMessage() {
  9 + return message;
  10 + }
  11 +
  12 + public void setMessage(CompletionChoiceMessage3_5 message) {
  13 + this.message = message;
  14 + }
  15 +
  16 + public String getFinish_reason() {
  17 + return finish_reason;
  18 + }
  19 +
  20 + public void setFinish_reason(String finish_reason) {
  21 + this.finish_reason = finish_reason;
  22 + }
  23 +
  24 + public Integer getIndex() {
  25 + return index;
  26 + }
  27 +
  28 + public void setIndex(Integer index) {
  29 + this.index = index;
  30 + }
  31 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +public class CompletionChoiceMessage3_5 {
  4 + private String role;
  5 + private String content;
  6 +
  7 + public String getRole() {
  8 + return role;
  9 + }
  10 +
  11 + public void setRole(String role) {
  12 + this.role = role;
  13 + }
  14 +
  15 + public String getContent() {
  16 + return content;
  17 + }
  18 +
  19 + public void setContent(String content) {
  20 + this.content = content;
  21 + }
  22 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +import com.theokanning.openai.Usage;
  4 +import com.theokanning.openai.completion.CompletionChoice;
  5 +
  6 +import java.util.List;
  7 +
  8 +public class CompletionResult3_5 {
  9 + private String id;
  10 + private String object;
  11 + private Long created;
  12 + private String model;
  13 + private List<CompletionChoice3_5> choices;
  14 + private Usage usage;
  15 +
  16 + public String getId() {
  17 + return id;
  18 + }
  19 +
  20 + public void setId(String id) {
  21 + this.id = id;
  22 + }
  23 +
  24 + public String getObject() {
  25 + return object;
  26 + }
  27 +
  28 + public void setObject(String object) {
  29 + this.object = object;
  30 + }
  31 +
  32 + public Long getCreated() {
  33 + return created;
  34 + }
  35 +
  36 + public void setCreated(Long created) {
  37 + this.created = created;
  38 + }
  39 +
  40 + public String getModel() {
  41 + return model;
  42 + }
  43 +
  44 + public void setModel(String model) {
  45 + this.model = model;
  46 + }
  47 +
  48 + public List<CompletionChoice3_5> getChoices() {
  49 + return choices;
  50 + }
  51 +
  52 + public void setChoices(List<CompletionChoice3_5> choices) {
  53 + this.choices = choices;
  54 + }
  55 +
  56 + public Usage getUsage() {
  57 + return usage;
  58 + }
  59 +
  60 + public void setUsage(Usage usage) {
  61 + this.usage = usage;
  62 + }
  63 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +public class GptMessage {
  4 + private Integer id; //int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  5 + private Integer create_time; //int(11) NOT NULL COMMENT '创建时间',
  6 + private String room_id; //varchar(150) DEFAULT NULL COMMENT '房价id',
  7 + private String send_role; //varchar(15) DEFAULT NULL COMMENT '发送角色',
  8 + private String send_content; //text COMMENT '发送内容',
  9 + private String message_role; //varchar(15) DEFAULT NULL COMMENT '返回消息角色',
  10 + private String message_content; //text COMMENT '返回消息内容',
  11 + private Integer send_size; //int(11) DEFAULT NULL COMMENT '发送大小byte',
  12 + private Integer message_size; //int(11) DEFAULT NULL COMMENT '返回大小byte',
  13 + private Integer user_id; //int(11) DEFAULT NULL COMMENT '用户id',
  14 + private Long prompt_tokens; //输入代币
  15 + private Long completion_tokens; //输出代币
  16 +
  17 + public Long getPrompt_tokens() {
  18 + return prompt_tokens;
  19 + }
  20 +
  21 + public void setPrompt_tokens(Long prompt_tokens) {
  22 + this.prompt_tokens = prompt_tokens;
  23 + }
  24 +
  25 + public Long getCompletion_tokens() {
  26 + return completion_tokens;
  27 + }
  28 +
  29 + public void setCompletion_tokens(Long completion_tokens) {
  30 + this.completion_tokens = completion_tokens;
  31 + }
  32 +
  33 + public Integer getId() {
  34 + return id;
  35 + }
  36 +
  37 + public void setId(Integer id) {
  38 + this.id = id;
  39 + }
  40 +
  41 + public Integer getCreate_time() {
  42 + return create_time;
  43 + }
  44 +
  45 + public void setCreate_time(Integer create_time) {
  46 + this.create_time = create_time;
  47 + }
  48 +
  49 + public String getRoom_id() {
  50 + return room_id;
  51 + }
  52 +
  53 + public void setRoom_id(String room_id) {
  54 + this.room_id = room_id;
  55 + }
  56 +
  57 + public String getSend_role() {
  58 + return send_role;
  59 + }
  60 +
  61 + public void setSend_role(String send_role) {
  62 + this.send_role = send_role;
  63 + }
  64 +
  65 + public String getSend_content() {
  66 + return send_content;
  67 + }
  68 +
  69 + public void setSend_content(String send_content) {
  70 + this.send_content = send_content;
  71 + }
  72 +
  73 + public String getMessage_role() {
  74 + return message_role;
  75 + }
  76 +
  77 + public void setMessage_role(String message_role) {
  78 + this.message_role = message_role;
  79 + }
  80 +
  81 + public String getMessage_content() {
  82 + return message_content;
  83 + }
  84 +
  85 + public void setMessage_content(String message_content) {
  86 + this.message_content = message_content;
  87 + }
  88 +
  89 + public Integer getSend_size() {
  90 + return send_size;
  91 + }
  92 +
  93 + public void setSend_size(Integer send_size) {
  94 + this.send_size = send_size;
  95 + }
  96 +
  97 + public Integer getMessage_size() {
  98 + return message_size;
  99 + }
  100 +
  101 + public void setMessage_size(Integer message_size) {
  102 + this.message_size = message_size;
  103 + }
  104 +
  105 + public Integer getUser_id() {
  106 + return user_id;
  107 + }
  108 +
  109 + public void setUser_id(Integer user_id) {
  110 + this.user_id = user_id;
  111 + }
  112 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +public class SysConfig {
  4 + private String id; //int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  5 + private String key_type; //varchar(50) DEFAULT NULL COMMENT 'key类型',
  6 + private String key; //varchar(50) DEFAULT NULL COMMENT 'key',
  7 + private String value; //varchar(50) DEFAULT NULL COMMENT '值',
  8 + private String sort; //int(11) DEFAULT NULL COMMENT '排序',
  9 +
  10 + public String getId() {
  11 + return id;
  12 + }
  13 +
  14 + public void setId(String id) {
  15 + this.id = id;
  16 + }
  17 +
  18 + public String getKey_type() {
  19 + return key_type;
  20 + }
  21 +
  22 + public void setKey_type(String key_type) {
  23 + this.key_type = key_type;
  24 + }
  25 +
  26 + public String getKey() {
  27 + return key;
  28 + }
  29 +
  30 + public void setKey(String key) {
  31 + this.key = key;
  32 + }
  33 +
  34 + public String getValue() {
  35 + return value;
  36 + }
  37 +
  38 + public void setValue(String value) {
  39 + this.value = value;
  40 + }
  41 +
  42 + public String getSort() {
  43 + return sort;
  44 + }
  45 +
  46 + public void setSort(String sort) {
  47 + this.sort = sort;
  48 + }
  49 +}
  1 +package com.zhonglai.luhui.openai.dto;
  2 +
  3 +import java.math.BigDecimal;
  4 +
  5 +public class UserFlowPacketRemainLog {
  6 + private Integer id; //int(11) DEFAULT NULL COMMENT '主键',
  7 + private Integer user_id; //int(11) DEFAULT NULL COMMENT '用户',
  8 + private String room_id; //varchar(50) DEFAULT NULL COMMENT '房间号',
  9 + private Integer create_time; //int(11) DEFAULT NULL COMMENT '创建时间',
  10 + private Long prompt_tokens; //bigint(20) DEFAULT NULL COMMENT '发起代币',
  11 + private Long completion_tokens; //bigint(20) DEFAULT NULL COMMENT '完成代币',
  12 + private Long total_tokens; //bigint(20) DEFAULT NULL COMMENT '总代币',
  13 + private BigDecimal openai_money; //bigint(20) DEFAULT NULL COMMENT 'openai费用(美元)',
  14 + private BigDecimal reality_money; //bigint(20) DEFAULT NULL COMMENT '实际费用(人民币)'
  15 +
  16 + public Integer getId() {
  17 + return id;
  18 + }
  19 +
  20 + public void setId(Integer id) {
  21 + this.id = id;
  22 + }
  23 +
  24 + public Integer getUser_id() {
  25 + return user_id;
  26 + }
  27 +
  28 + public void setUser_id(Integer user_id) {
  29 + this.user_id = user_id;
  30 + }
  31 +
  32 + public String getRoom_id() {
  33 + return room_id;
  34 + }
  35 +
  36 + public void setRoom_id(String room_id) {
  37 + this.room_id = room_id;
  38 + }
  39 +
  40 + public Integer getCreate_time() {
  41 + return create_time;
  42 + }
  43 +
  44 + public void setCreate_time(Integer create_time) {
  45 + this.create_time = create_time;
  46 + }
  47 +
  48 + public Long getPrompt_tokens() {
  49 + return prompt_tokens;
  50 + }
  51 +
  52 + public void setPrompt_tokens(Long prompt_tokens) {
  53 + this.prompt_tokens = prompt_tokens;
  54 + }
  55 +
  56 + public Long getCompletion_tokens() {
  57 + return completion_tokens;
  58 + }
  59 +
  60 + public void setCompletion_tokens(Long completion_tokens) {
  61 + this.completion_tokens = completion_tokens;
  62 + }
  63 +
  64 + public Long getTotal_tokens() {
  65 + return total_tokens;
  66 + }
  67 +
  68 + public void setTotal_tokens(Long total_tokens) {
  69 + this.total_tokens = total_tokens;
  70 + }
  71 +
  72 + public BigDecimal getOpenai_money() {
  73 + return openai_money;
  74 + }
  75 +
  76 + public void setOpenai_money(BigDecimal openai_money) {
  77 + this.openai_money = openai_money;
  78 + }
  79 +
  80 + public BigDecimal getReality_money() {
  81 + return reality_money;
  82 + }
  83 +
  84 + public void setReality_money(BigDecimal reality_money) {
  85 + this.reality_money = reality_money;
  86 + }
  87 +}
1 package com.zhonglai.luhui.openai.service; 1 package com.zhonglai.luhui.openai.service;
2 2
3 import com.ruoyi.common.exception.ServiceException; 3 import com.ruoyi.common.exception.ServiceException;
  4 +import com.ruoyi.common.utils.DateUtils;
4 import com.ruoyi.common.utils.StringUtils; 5 import com.ruoyi.common.utils.StringUtils;
5 -import com.ruoyi.system.login.dto.ApiLoginUser;  
6 -import com.ruoyi.system.login.dto.Yu2leUserInfo;  
7 -import com.ruoyi.system.login.dto.Yu2leUserLogin; 6 +import com.ruoyi.system.login.dto.*;
8 import com.ruoyi.system.service.PublicService; 7 import com.ruoyi.system.service.PublicService;
9 import org.slf4j.Logger; 8 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory;
@@ -21,18 +20,22 @@ public class ChatgptDetailsServiceImpl implements UserDetailsService { @@ -21,18 +20,22 @@ public class ChatgptDetailsServiceImpl implements UserDetailsService {
21 private PublicService publicService; 20 private PublicService publicService;
22 @Override 21 @Override
23 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 22 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
24 - Yu2leUserLogin yu2leUserLogin = publicService.getObjectForTableName(Yu2leUserLogin.class,"loginName",username,"`liu_yu_le`.`user_login`");  
25 - Yu2leUserInfo yu2leUserInfo = publicService.getObjectForTableName(Yu2leUserInfo.class,"loginName",username,"`liu_yu_le`.`user_info`");;  
26 - if (StringUtils.isNull(yu2leUserLogin) || StringUtils.isNull(yu2leUserInfo)) 23 + OpenAiUserInfo openAiUserInfo = publicService.getObjectForTableName(OpenAiUserInfo.class,"phone",username,"`lk_openai`.`user_info`");
  24 + if (StringUtils.isNull(openAiUserInfo) )
27 { 25 {
28 - log.info("登录用户:{} 不存在.", username);  
29 - throw new ServiceException("登录用户:" + username + " 不存在"); 26 + log.info("未找到用户{},开始新增用户...",username);
  27 + OpenAiUserInfo adduser = new OpenAiUserInfo();
  28 + adduser.setPhone(username);
  29 + adduser.setCreate_time(DateUtils.getNowTimeMilly());
  30 + adduser.setNickname(username);
  31 + adduser.setVip_level(0);
  32 + adduser.setFlow_packet_remain(10000); //默认给1w免费额度
  33 + adduser.setFlow_packet_total(10000);
  34 + adduser.setState(1);
  35 + publicService.insertToTable(adduser,"`lk_openai`.`user_info`");
  36 + log.info("新增用户{},成功",username);
  37 + openAiUserInfo = adduser;
30 } 38 }
31 - else if (1==yu2leUserInfo.getIsInvalid())  
32 - {  
33 - log.info("登录用户:{} 已被停用.", username);  
34 - throw new ServiceException("对不起,您的账号:" + username + " 已停用");  
35 - }  
36 - return new ApiLoginUser(yu2leUserInfo, yu2leUserLogin); 39 + return new OpenAiLoginUser(openAiUserInfo);
37 } 40 }
38 } 41 }
@@ -64,6 +64,8 @@ public class OpenAiUtils { @@ -64,6 +64,8 @@ public class OpenAiUtils {
64 PARMS.put("OpenAi47", new OpenAi("OpenAi47", "点评生成", "依据文本内容自动生成点评", "text-davinci-003", "依据下面内容,进行点评:\n%s\n点评:", 0.5, 1.0, 1.0, 0.0, 0.0, "")); 64 PARMS.put("OpenAi47", new OpenAi("OpenAi47", "点评生成", "依据文本内容自动生成点评", "text-davinci-003", "依据下面内容,进行点评:\n%s\n点评:", 0.5, 1.0, 1.0, 0.0, 0.0, ""));
65 PARMS.put("OpenAi48", new OpenAi("OpenAi48", "知识学习", "可以为学习知识自动解答", "text-davinci-003", "%s", 0.3, 1.0, 1.0, 0.0, 0.0, "")); 65 PARMS.put("OpenAi48", new OpenAi("OpenAi48", "知识学习", "可以为学习知识自动解答", "text-davinci-003", "%s", 0.3, 1.0, 1.0, 0.0, 0.0, ""));
66 PARMS.put("OpenAi49", new OpenAi("OpenAi49", "面试", "生成面试题", "text-davinci-003", "创建10道%s相关的面试题(中文):\n", 0.5, 1.0, 10.0, 0.0, 0.0, "")); 66 PARMS.put("OpenAi49", new OpenAi("OpenAi49", "面试", "生成面试题", "text-davinci-003", "创建10道%s相关的面试题(中文):\n", 0.5, 1.0, 10.0, 0.0, 0.0, ""));
  67 + PARMS.put("OpenAi50", new OpenAi("OpenAi50", "chatgpt3.5", "chatgpt3.5", "gpt-3.5-turbo-0301", "%s", null, null, null, null, null, null));
  68 +
67 } 69 }
68 70
69 public static String OPENAPI_TOKEN = ""; 71 public static String OPENAPI_TOKEN = "";
@@ -686,4 +688,9 @@ public class OpenAiUtils { @@ -686,4 +688,9 @@ public class OpenAiUtils {
686 return getAiResult(openAi, String.format(openAi.getPrompt(), text)); 688 return getAiResult(openAi, String.format(openAi.getPrompt(), text));
687 } 689 }
688 690
  691 + public static List<CompletionChoice> getChatGPT3_5(String text) {
  692 + OpenAi openAi = PARMS.get("OpenAi50");
  693 + System.out.println(String.format(openAi.getPrompt(), text));
  694 + return getAiResult(openAi, String.format(openAi.getPrompt(), text));
  695 + }
689 } 696 }
  1 +package com.zhonglai.luhui.openai.utils;
  2 +
  3 +public class SysConfigKeyType {
  4 + public static String gpt_3_5_unitprice = "GPT_3_5_UNITPRICE"; //$0.002 / 1K tokens
  5 +
  6 +}
1 -# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 获取ip地址开关 addressEnabled: false # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8082 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 # NameServer地址 rocketmq: name-server: 47.115.144.179:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-chat-gpt send-tags: 1 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/chatgpt/aiChatbot chatgpt: token: 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 timeout: 5000  
  1 +# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 获取ip地址开关 addressEnabled: false # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8082 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 # NameServer地址 rocketmq: name-server: 47.115.144.179:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-chat-gpt send-tags: 1 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/chatgpt/aiChatbot,/chatgpt/chatgptV3_5, chatgpt: token: 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 timeout: 5000
  1 +package com.ruoyi.system.login.dto;
  2 +
  3 +import com.ruoyi.common.core.domain.BaseLoginUser;
  4 +import com.ruoyi.system.domain.tool.PublicSQLConfig;
  5 +import org.springframework.security.core.GrantedAuthority;
  6 +
  7 +import java.util.Collection;
  8 +
  9 +public class OpenAiLoginUser extends BaseLoginUser {
  10 + @PublicSQLConfig(isSelect=false)
  11 + private static final long serialVersionUID = 1L;
  12 +
  13 + private OpenAiUserInfo openAiUserInfo;
  14 +
  15 + public OpenAiLoginUser(OpenAiUserInfo openAiUserInfo) {
  16 + this.openAiUserInfo = openAiUserInfo;
  17 + setUserId(new Long(openAiUserInfo.getId()));
  18 + }
  19 +
  20 + @Override
  21 + public Object getUser() {
  22 + return openAiUserInfo;
  23 + }
  24 +
  25 + @Override
  26 + public Collection<? extends GrantedAuthority> getAuthorities() {
  27 + return null;
  28 + }
  29 +
  30 + @Override
  31 + public String getPassword() {
  32 + return "123456";
  33 + }
  34 +
  35 + @Override
  36 + public String getUsername() {
  37 + return openAiUserInfo.getPhone();
  38 + }
  39 +
  40 + @Override
  41 + public boolean isAccountNonExpired() {
  42 + return openAiUserInfo.getState()!=2;
  43 + }
  44 +
  45 + @Override
  46 + public boolean isAccountNonLocked() {
  47 + return openAiUserInfo.getState()!=3;
  48 + }
  49 +
  50 + @Override
  51 + public boolean isCredentialsNonExpired() {
  52 + return true;
  53 + }
  54 +
  55 + @Override
  56 + public boolean isEnabled() {
  57 + return openAiUserInfo.getState()!=0;
  58 + }
  59 +}
  1 +package com.ruoyi.system.login.dto;
  2 +
  3 +
  4 +import com.ruoyi.system.domain.tool.PublicSQLConfig;
  5 +
  6 +import java.io.Serializable;
  7 +
  8 +/**
  9 + * 用户信息
  10 + */
  11 +public class OpenAiUserInfo implements Serializable {
  12 + @PublicSQLConfig(isSelect = false)
  13 + private static final long serialVersionUID = 2442852637823064570L;
  14 + private Integer id; // int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  15 + private String phone; // varchar(50) DEFAULT NULL COMMENT '手机号',
  16 + private String nickname; // varchar(50) DEFAULT NULL COMMENT '昵称',
  17 + private String img_url; // varchar(50) DEFAULT NULL COMMENT '头像地址',
  18 + private Integer vip_level; //vip等级(0试用用户,1vip1,2vip2,3vip3)
  19 + private Integer getVip_level_end_time; //vip到期时间
  20 + private Integer create_time; //创建时间
  21 + private Integer flow_packet_remain; //流量包余额
  22 + private Integer flow_packet_total; //流量包总额
  23 + private Integer state; //状态(0禁用,1正常,2过期,3锁定)
  24 +
  25 + public Integer getState() {
  26 + return state;
  27 + }
  28 +
  29 + public void setState(Integer state) {
  30 + this.state = state;
  31 + }
  32 +
  33 + public Integer getId() {
  34 + return id;
  35 + }
  36 +
  37 + public void setId(Integer id) {
  38 + this.id = id;
  39 + }
  40 +
  41 + public String getPhone() {
  42 + return phone;
  43 + }
  44 +
  45 + public void setPhone(String phone) {
  46 + this.phone = phone;
  47 + }
  48 +
  49 + public String getNickname() {
  50 + return nickname;
  51 + }
  52 +
  53 + public void setNickname(String nickname) {
  54 + this.nickname = nickname;
  55 + }
  56 +
  57 + public String getImg_url() {
  58 + return img_url;
  59 + }
  60 +
  61 + public void setImg_url(String img_url) {
  62 + this.img_url = img_url;
  63 + }
  64 +
  65 + public Integer getVip_level() {
  66 + return vip_level;
  67 + }
  68 +
  69 + public void setVip_level(Integer vip_level) {
  70 + this.vip_level = vip_level;
  71 + }
  72 +
  73 + public Integer getGetVip_level_end_time() {
  74 + return getVip_level_end_time;
  75 + }
  76 +
  77 + public void setGetVip_level_end_time(Integer getVip_level_end_time) {
  78 + this.getVip_level_end_time = getVip_level_end_time;
  79 + }
  80 +
  81 + public Integer getCreate_time() {
  82 + return create_time;
  83 + }
  84 +
  85 + public void setCreate_time(Integer create_time) {
  86 + this.create_time = create_time;
  87 + }
  88 +
  89 + public Integer getFlow_packet_remain() {
  90 + return flow_packet_remain;
  91 + }
  92 +
  93 + public void setFlow_packet_remain(Integer flow_packet_remain) {
  94 + this.flow_packet_remain = flow_packet_remain;
  95 + }
  96 +
  97 + public Integer getFlow_packet_total() {
  98 + return flow_packet_total;
  99 + }
  100 +
  101 + public void setFlow_packet_total(Integer flow_packet_total) {
  102 + this.flow_packet_total = flow_packet_total;
  103 + }
  104 +}
@@ -91,6 +91,20 @@ public class LoginService { @@ -91,6 +91,20 @@ public class LoginService {
91 return tokenService.createToken(loginUser); 91 return tokenService.createToken(loginUser);
92 } 92 }
93 93
  94 + public String openaiLoginByPass(String user,String pass) {
  95 + // 用户验证
  96 + Authentication authentication = userPasswordVerification(user,pass,SysLogininforType.openAi);
  97 + AsyncManager.me().execute(AsyncFactory.recordLogininfor(user, SysLogininforType.openAi, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
  98 + OpenAiLoginUser loginUser = (OpenAiLoginUser) authentication.getPrincipal();
  99 + loginUser.setSysLogininforType(SysLogininforType.openAi);
  100 +// OpenAiUserInfo openAiUserInfo = new OpenAiUserInfo();
  101 +// openAiUserInfo.setId(loginUser.getUserId().intValue());
  102 +// openAiUserInfo.s(IpUtils.getIpAddr(ServletUtils.getRequest()));
  103 +// openAiUserInfo.setLastLoginTime(DateUtils.getNowTimeMilly());
  104 +// publicService.updateObjectByTable(openAiUserInfo,"id","`lk_openai`.`user_info`");
  105 + return tokenService.createToken(loginUser);
  106 + }
  107 +
94 /** 108 /**
95 * 刷新api端token 109 * 刷新api端token
96 * @param token 110 * @param token
@@ -34,7 +34,7 @@ public interface PublicMapper { @@ -34,7 +34,7 @@ public interface PublicMapper {
34 * 指定表名添加对象集合 34 * 指定表名添加对象集合
35 */ 35 */
36 @InsertProvider(type = PublicSQL.class, method = "insertAllToTable") 36 @InsertProvider(type = PublicSQL.class, method = "insertAllToTable")
37 - int insertAllToTable(List<?> list,String tableName); 37 + int insertAllToTable(@Param("list")List<?> list,@Param("tableName")String tableName);
38 38
39 /** 39 /**
40 * 更新对象不为空的属性 40 * 更新对象不为空的属性