作者 钟来

Default Changelist

... ... @@ -7,8 +7,8 @@ import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {
"com.zhonglai.luhui.config",
"com.zhonglai.luhui.controller",
}
)
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class ChatgptApplication {
... ...
package com.zhonglai.luhui.controller;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.dto.ChatGPTApiDto;
import com.zhonglai.luhui.dto.ChatRoomMessages;
import com.zhonglai.luhui.dto.CompletionResult3_5;
import com.zhonglai.luhui.dto.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Api(tags = "chatGPT接口")
@RestController
... ... @@ -28,29 +27,72 @@ public class ChatGPTApiController {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@ApiOperation(value = "测试")
@GetMapping("/sendMessage")
public void sendMessage(HttpServletResponse response, @RequestBody ChatGPTApiDto chatGPTApiDto)
@PostMapping("/sendMessage")
public String sendMessage(HttpServletResponse response, @RequestBody ChatGPTApiDto chatGPTApiDto)
{
int timeout = 3000000;
// 设置响应内容类型和编码
response.setContentType("text/html;charset=UTF-8");
JSONObject jsonObject = new JSONObject();
jsonObject.put("model","gpt-3.5-turbo-0301");
jsonObject.put("messages",chatGPTApiDto.getMessageList());
String str = "";
// String domainName = "api.openai.com";
// String apiDomain = "openai.yu2le.com/api";
String domainName = "chatgpt.njlaikun.com";
String apiDomain = "localhost:8082";
Map<String,String> map = new HashMap<>();
if(chatGPTApiDto.getIsfree())
{
map.put("Authorization","Bearer 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");
}else{
map.put("Authorization","Bearer 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");
}
map.put("Content-Type","application/json");
String str = HttpRequest.post("https://"+domainName+"/v1/chat/completions").setReadTimeout(timeout).timeout(timeout).addHeaders(map).body(jsonObject.toString()).execute().body();
logger.info("返回的数据:{}",str);
if(JSONUtil.isTypeJSONObject(str))
{
CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class);
List<CompletionChoice3_5> list = completionResult.getChoices();
if(null != list && list.size() != 0)
{
StringBuffer stringBuffer = new StringBuffer();
for (CompletionChoice3_5 completionChoice3_5:list)
{
stringBuffer.append(completionChoice3_5.getMessage().getContent());
completionChoice3_5.getMessage().setContent(null);
}
completionResult.setContentLength( stringBuffer.length());
completionResult.setRoom_id(chatGPTApiDto.getRoom_id());
completionResult.setGptMessage_id(chatGPTApiDto.getGptMessage_id());
completionResult.setUser_id(chatGPTApiDto.getUser_id());
//通知更新用户信息
String noticestr = JSONObject.toJSONString(completionResult);
String rstr = HttpUtil.post("http://"+apiDomain+"/chatGPTStream/upUserFlowPacketRemain",noticestr);
logger.info("修改返回的数据:{}",rstr);
//返回结果字符串
return stringBuffer.toString();
// writeMessage(stringBuffer,response);
}
}
return str;
}
private void writeMessage(StringBuffer stringBuffer,HttpServletResponse response)
{
PrintWriter out = null;
try {
out = response.getWriter();
//验证验证码
if(StringUtils.isNotEmpty(str))
if(StringUtils.isNotEmpty(stringBuffer))
{
for(int i=0;i<str.length();i++)
for(int i=0;i<stringBuffer.length();i++)
{
char c = str.charAt(i);
char c = stringBuffer.charAt(i);
out.write(c);
out.flush(); // 立即将字符输出到客户端
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
} catch (IOException e) {
... ... @@ -63,33 +105,4 @@ public class ChatGPTApiController {
}
}
private CompletionResult3_5 sendGPTAi(List<ChatRoomMessages> messageList)
{
logger.info("请求内容:{}",messageList);
JSONObject jsonObject = new JSONObject();
jsonObject.put("model","gpt-3.5-turbo-0301");
jsonObject.put("messages",messageList);
String str = HttpUtil.post("https://chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString());
logger.info("返回的数据:{}",str);
CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class);
return completionResult;
}
/**
* 免费接口
* @param messageList
* @return
*/
private CompletionResult3_5 sendFreeGPTAi(List<ChatRoomMessages> messageList)
{
logger.info("请求内容:{}",messageList);
JSONObject jsonObject = new JSONObject();
jsonObject.put("model","gpt-3.5-turbo-0301");
jsonObject.put("messages",messageList);
String str = HttpUtil.post("https://free.chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString());
logger.info("返回的数据:{}",str);
CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class);
return completionResult;
}
}
... ...
... ... @@ -13,6 +13,24 @@ public class CompletionResult3_5 {
private String room_id;
private Integer gptMessage_id;
private Integer contentLength;
public Integer getContentLength() {
return contentLength;
}
public void setContentLength(Integer contentLength) {
this.contentLength = contentLength;
}
public String getRoom_id() {
return room_id;
}
public void setRoom_id(String room_id) {
this.room_id = room_id;
}
public Integer getGptMessage_id() {
return gptMessage_id;
}
... ...
... ... @@ -25,7 +25,6 @@ import org.springframework.context.annotation.FilterType;
"com.zhonglai.luhui.openai.service",
"com.zhonglai.luhui.openai.controller"
}
)
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class OpenaiApplication {
... ...
... ... @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.html.HttpUtils;
import com.ruoyi.system.login.dto.OpenAiLoginUser;
import com.ruoyi.system.login.dto.OpenAiUserInfo;
import com.ruoyi.system.service.PublicService;
... ... @@ -25,10 +26,11 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
... ... @@ -44,7 +46,6 @@ public class ChatGPTStreamController extends BaseController {
@Autowired
private VipServiceImpl vipService;
@ApiOperation(value = "chatgpt3.5",notes = "上下文关联,要实现上下问关联就需要记录整个聊天的提问记录,目前只支持相同session的上下文关联,就是说,如果聊天页面关闭以后再打开,是没有上下文关联的")
@Transactional
@RequestMapping(value = "/chatgptV3_5",method = RequestMethod.POST)
public void chatgptV3_5(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, @RequestBody ChatgptMessageDto chatgptMessageDto) throws IOException {
//跟进用户信息生成入口参数
... ... @@ -93,35 +94,64 @@ public class ChatGPTStreamController extends BaseController {
gptMessage.setSend_content(chatRoomMessages.getContent());
gptMessage.setCreate_time(DateUtils.getNowTimeMilly());
publicService.insertToTable(gptMessage,"`lk_openai`.`gpt_message`");
//获取返回参数
//获取返回参数
ChatGPTApiDto chatGPTApiDto = new ChatGPTApiDto();
chatGPTApiDto.setGptMessage_id(gptMessage.getId());
chatGPTApiDto.setMessageList(messageList);
chatGPTApiDto.setUser_id(user_id);
chatGPTApiDto.setRoom_id(room_id);
chatGPTApiDto.setIsfree(vipService.isfree(openAiUserInfo.getVip_level()));
HttpUtil.post("https://chatgpt.njlaikun.com/chatGPTApi/sendMessage", JSONObject.toJSONString(chatGPTApiDto));
Request request = new Request.Builder()
.url("https://chatgpt.njlaikun.com/chatGPTApi/sendMessage")
.post(okhttp3.RequestBody.create(JSONObject.toJSONString(chatGPTApiDto), MediaType.parse("application/json;")))
.build();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
PrintWriter pout = null;
BufferedReader in = null;
try {
URL url = new URL("http://localhost:8086/chatGPTApi/sendMessage");
// 打开和URL之间的连接
URLConnection conn = url.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
pout = new PrintWriter(conn.getOutputStream());
// 发送请求参数
pout.print(JSONObject.toJSONString(chatGPTApiDto));
// flush输出流的缓冲
pout.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
int character;
while ((character = in.read()) != -1) {
out.write((char) character);
out.flush();
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
InputStream inputStream = response.body().byteStream();
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (!(out == null)) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
}
@ApiOperation(value = "历史记录",notes = "默认获取最新5条记录")
@ApiOperation(value = "更新消息状态")
@Transactional
@RequestMapping(value = "/upUserFlowPacketRemain",method = RequestMethod.POST)
public AjaxResult upUserFlowPacketRemain(@RequestBody CompletionResult3_5 completionResult3_5 )
... ... @@ -132,14 +162,13 @@ public class ChatGPTStreamController extends BaseController {
if(null != list3_5 && list3_5.size() !=0 )
{
GptMessage gptMessage = new GptMessage();
gptMessage.setSend_size(0);
gptMessage.setPrompt_tokens(0l);
gptMessage.setCompletion_tokens(0l);
gptMessage.setTotal_tokens(0l);
gptMessage.setMessage_size(0);
gptMessage.setSend_size(completionResult3_5.getContentLength());
for (CompletionChoice3_5 completionChoice:list3_5)
{
gptMessage.setSend_size(gptMessage.getSend_size()+gptMessage.getSend_content().length());
//统计代币
gptMessage.setCompletion_tokens(gptMessage.getCompletion_tokens()+usage.getCompletionTokens());
gptMessage.setPrompt_tokens(gptMessage.getPrompt_tokens()+usage.getPromptTokens());
... ...
... ... @@ -16,7 +16,15 @@ public class CompletionResult3_5 {
private Integer user_id;
private String room_id;
private Integer gptMessage_id;
private Integer contentLength;
public Integer getContentLength() {
return contentLength;
}
public void setContentLength(Integer contentLength) {
this.contentLength = contentLength;
}
public Integer getGptMessage_id() {
return gptMessage_id;
}
... ...
... ... @@ -28,7 +28,8 @@ public class ChatgptDetailsServiceImpl implements UserDetailsService {
adduser.setPhone(username);
adduser.setCreate_time(DateUtils.getNowTimeMilly());
adduser.setNickname(username);
adduser.setVip_level(0);
adduser.setVip_level(3);
adduser.setVip_level_end_time(adduser.getCreate_time()+2592000); //30天
adduser.setFlow_packet_remain(10000); //默认给1w免费额度
adduser.setFlow_packet_total(10000);
adduser.setState(1);
... ...
... ... @@ -49,8 +49,8 @@ public class VipServiceImpl {
chargingList.add(0,true);
chargingList.add(1,true);
chargingList.add(2,false);
chargingList.add(3,false);
chargingList.add(2,true);
chargingList.add(3,true);
chargingList.add(4,false);
chargingList.add(5,false);
... ...
# 项目相关配置 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,/openAiUserLogin/* chatgpt: token: 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 timeout: 5000
\ No newline at end of file
# 项目相关配置 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,/openAiUserLogin/*,/chatGPTStream/upUserFlowPacketRemain chatgpt: token: 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 timeout: 5000
\ No newline at end of file
... ...
... ... @@ -137,6 +137,7 @@ public class PublicSQL {
{
Object object = map.get("object");
String tableName = changTableNameFromObject(object);
String primaryKey = (String) map.get("primaryKey");
if(map.containsKey("tableName"))
{
tableName = map.get("tableName").toString();
... ...
... ... @@ -22,7 +22,8 @@ public interface PublicMapper {
* 指定表名添加
*/
@InsertProvider(type = PublicSQL.class, method = "insertToTable")
int insertToTable(@Param("object") Object object,@Param("tableName") String tableName);
@Options(useGeneratedKeys = true, keyProperty = "object.id")
int insertToTable(@Param("object") Object object,@Param("tableName") String tableName,@Param("primaryKey") String primaryKey);
/**
* 添加对象集合
... ...
... ... @@ -15,8 +15,9 @@ public interface PublicService {
/**
* 指定表名添加
*/
int insertToTable(Object object, String tableName);
int insertToTable(Object object, String tableName,String primaryKey);
int insertToTable(Object object, String tableName);
/**
* 添加对象集合
*/
... ...
... ... @@ -30,7 +30,12 @@ public class PublicServiceImpl implements PublicService {
*/
public int insertToTable(Object object, String tableName)
{
return publicMapper.insertToTable(object,tableName);
return publicMapper.insertToTable(object,tableName,"id");
}
public int insertToTable(Object object, String tableName,String primaryKey)
{
return publicMapper.insertToTable(object,tableName,primaryKey);
}
/**
... ...