From b345b26f3e06fbb3f2ce523db8a9fb90ab8622b1 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Tue, 23 Apr 2024 00:25:16 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9Task=E4=B8=8EInvoice?= =?UTF-8?q?=E7=B1=BB=EF=BC=8C=E5=8A=A0=E5=85=A5baomidou=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E3=80=82=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89GPT=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/chatgpt/ChatGPTConfig.java | 75 +++++++++++++++++++ .../entity/chatgpt/CustomChatGPT.java | 54 +++++++++++++ .../entity/chatgpt/TestChatGPT6.java | 9 +++ .../groupshell/controller/ChatGPTCtrl.java | 5 ++ .../com/groupshell/mapper/InvoiceMapper.java | 5 +- .../com/groupshell/mapper/TaskMapper.java | 3 +- .../groupshell/service/ChatGPTService.java | 7 ++ .../groupshell/service/InvoiceService.java | 5 +- .../com/groupshell/service/TaskService.java | 3 +- .../service/impl/ChatGPTServiceImpl.java | 7 ++ .../service/impl/InvoiceServiceImpl.java | 5 +- .../service/impl/TaskServiceImpl.java | 3 +- 12 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java create mode 100644 server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java create mode 100644 server/src/main/java/com/groupshell/service/ChatGPTService.java create mode 100644 server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java new file mode 100644 index 0000000..29457ef --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java @@ -0,0 +1,75 @@ +package com.groupshell.entity.chatgpt; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.unfbx.chatgpt.OpenAiStreamClient; +import com.unfbx.chatgpt.entity.chat.ChatCompletion; +import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; +import com.unfbx.chatgpt.entity.chat.Message; +import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; +import lombok.*; + +import java.util.Arrays; +import java.util.concurrent.CountDownLatch; + +@Data +@ToString +@AllArgsConstructor +@Builder +public class ChatGPTConfig { + + private OpenAiStreamClient openAiStreamClient; + private ConsoleEventSourceListener consoleEventSourceListener; + private ChatCompletion chatCompletion; + private ChatCompletion.Model model; + private Message message; + private static final String DEFAULT_OPENAI_KEY = "sk-OA8YqWsVOIIPeGWlD86eB41a9284495085Ab17A08c514b1e"; + private static final String DEFAULT_CHAT_MESSAGE = "你好!请问你是chatGPT吗?"; + private static final String GPT3_OPENAI_API_URL = "https://one.aiskt.com/"; + private static final String GPT4_OPENAI_API_URL = "https://pro.aiskt.com/"; + + + public ChatGPTConfig() throws InterruptedException { + initOpenAiStreamClient(); //初始化流式客户端 + initConsoleEventSourceListener(new ConsoleEventSourceListener()); //初始化事件侦听器 + setChatCompletion(); + setChatCompletion(DEFAULT_CHAT_MESSAGE); //初始化模型与会话 + } + + public void initOpenAiStreamClient() { + this.openAiStreamClient = OpenAiStreamClient.builder() + .apiKey(Arrays.asList(DEFAULT_OPENAI_KEY)) + .apiHost(GPT4_OPENAI_API_URL) //支持GPT4 + .build(); + } + + public void initConsoleEventSourceListener(ConsoleEventSourceListener consoleEventSourceListener) { + + this.consoleEventSourceListener = consoleEventSourceListener; + } + + public void setChatCompletion(String chat) { + + } + + public void setMessage(String chatMessage) { + this.message = Message.builder().role(Message.Role.USER).content(chatMessage).build(); + } + public void setChatCompletion(String chatMessage) { + setMessage(chatMessage); + this.chatCompletion = ChatCompletion.builder().messages(Arrays.asList(message)).build(); + //setChatCompletion(); + chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); + //streamClient.streamChatCompletion(chatCompletion, eventSourceListener); //TODO:这句代码是什么意思 + } + public void setChatCompletion(ChatCompletion chatCompletion) { + this.chatCompletion = chatCompletion; + } + + //设置模型model + public void setChatCompletion(ChatCompletion.Model model) { + //this.setModel(model.getName()); + this.chatCompletion.setModel(model.getName()); + //streamClient.streamChatCompletion(chatCompletion, eventSourceListener); + } + +} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java new file mode 100644 index 0000000..5d22ff5 --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java @@ -0,0 +1,54 @@ +package com.groupshell.entity.chatgpt; + +import com.unfbx.chatgpt.entity.chat.Message; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.ToString; + +import java.util.List; +import java.util.concurrent.CountDownLatch; + +@Data +@ToString +@AllArgsConstructor +@Builder +public class CustomChatGPT { + + private List messages; + private ChatGPTConfig chatGPTConfig; + + public CustomChatGPT() throws InterruptedException { + chatGPTConfig = new ChatGPTConfig(); + } + + public void runCustomChatGPT() throws InterruptedException { + chatGPTConfig.getOpenAiStreamClient().streamChatCompletion( + chatGPTConfig.getChatCompletion(), + chatGPTConfig.getConsoleEventSourceListener()); + + CountDownLatch countDownLatch = new CountDownLatch(1); + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + private void sendMessageToChatGPT(String message) throws InterruptedException { + //chatGPTConfig.setMessage(message); + chatGPTConfig.setChatCompletion(message); + chatGPTConfig.getOpenAiStreamClient().streamChatCompletion( + chatGPTConfig.getChatCompletion(), + chatGPTConfig.getConsoleEventSourceListener()); + + CountDownLatch countDownLatch = new CountDownLatch(1); + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + Thread.currentThread().interrupt(); // 保留中断状态 + } + } +} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java new file mode 100644 index 0000000..aae3391 --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java @@ -0,0 +1,9 @@ +package com.groupshell.entity.chatgpt; + +public class TestChatGPT6 { + public static void main(String[] args) throws InterruptedException { + CustomChatGPT customChatGPT = new CustomChatGPT(); + customChatGPT.runCustomChatGPT(); + customChatGPT.setChatGPTConfig(); + } +} diff --git a/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java new file mode 100644 index 0000000..4674089 --- /dev/null +++ b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java @@ -0,0 +1,5 @@ +package com.groupshell.controller; + +public class ChatGPTCtrl { + +} diff --git a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java index d27d24b..95b3912 100644 --- a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java +++ b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java @@ -1,5 +1,6 @@ package com.groupshell.mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.groupshell.entity.Invoice; import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; @@ -12,8 +13,8 @@ import java.time.LocalTime; import java.util.List; @Mapper -public interface InvoiceMapper { - Invoice insert(Invoice record); +public interface InvoiceMapper extends BaseMapper { + //Invoice insert(Invoice record); Invoice findById(@Param("id") Integer id); diff --git a/server/src/main/java/com/groupshell/mapper/TaskMapper.java b/server/src/main/java/com/groupshell/mapper/TaskMapper.java index 6f3ae2b..ff6df35 100644 --- a/server/src/main/java/com/groupshell/mapper/TaskMapper.java +++ b/server/src/main/java/com/groupshell/mapper/TaskMapper.java @@ -1,5 +1,6 @@ package com.groupshell.mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.groupshell.entity.Task; import com.groupshell.enumeration.TaskStatusEnum; import org.apache.ibatis.annotations.Mapper; @@ -8,7 +9,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; @Mapper -public interface TaskMapper +public interface TaskMapper extends BaseMapper { int insertTask(Task task); diff --git a/server/src/main/java/com/groupshell/service/ChatGPTService.java b/server/src/main/java/com/groupshell/service/ChatGPTService.java new file mode 100644 index 0000000..870e89b --- /dev/null +++ b/server/src/main/java/com/groupshell/service/ChatGPTService.java @@ -0,0 +1,7 @@ +package com.groupshell.service; + +public interface ChatGPTService { + + + +} diff --git a/server/src/main/java/com/groupshell/service/InvoiceService.java b/server/src/main/java/com/groupshell/service/InvoiceService.java index 2ce95e0..5ae5066 100644 --- a/server/src/main/java/com/groupshell/service/InvoiceService.java +++ b/server/src/main/java/com/groupshell/service/InvoiceService.java @@ -1,5 +1,6 @@ package com.groupshell.service; +import com.baomidou.mybatisplus.extension.service.IService; import com.groupshell.entity.Invoice; import com.groupshell.enumeration.ReimburseStatusEnum; import org.springframework.stereotype.Service; @@ -10,9 +11,9 @@ import java.util.List; import java.util.Map; @Service -public interface InvoiceService { +public interface InvoiceService extends IService { - public Invoice addInvoice(Invoice record); + public int addInvoice(Invoice record); public Invoice getInvoiceById(Integer id); diff --git a/server/src/main/java/com/groupshell/service/TaskService.java b/server/src/main/java/com/groupshell/service/TaskService.java index c1a5c77..1d2cf16 100644 --- a/server/src/main/java/com/groupshell/service/TaskService.java +++ b/server/src/main/java/com/groupshell/service/TaskService.java @@ -1,11 +1,12 @@ package com.groupshell.service; +import com.baomidou.mybatisplus.extension.service.IService; import com.groupshell.entity.Task; import com.groupshell.enumeration.TaskStatusEnum; import java.util.List; -public interface TaskService +public interface TaskService extends IService { Task createTask(Task task); diff --git a/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java new file mode 100644 index 0000000..c9e7012 --- /dev/null +++ b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java @@ -0,0 +1,7 @@ +package com.groupshell.service.impl; + +import com.groupshell.service.ChatGPTService; + +public class ChatGPTServiceImpl implements ChatGPTService { + +} diff --git a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java index f43f8de..28d1ddc 100644 --- a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java @@ -1,5 +1,6 @@ package com.groupshell.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.groupshell.entity.Invoice; import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; @@ -15,13 +16,13 @@ import java.util.Map; import java.util.stream.Collectors; @Service -public class InvoiceServiceImpl implements InvoiceService { +public class InvoiceServiceImpl extends ServiceImpl implements InvoiceService { @Autowired private InvoiceMapper invoiceMapper; @Override - public Invoice addInvoice(Invoice record) { + public int addInvoice(Invoice record) { return invoiceMapper.insert(record); } diff --git a/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java index 7b33165..3549b62 100644 --- a/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java @@ -1,5 +1,6 @@ package com.groupshell.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.groupshell.entity.Task; import com.groupshell.enumeration.TaskStatusEnum; import com.groupshell.mapper.TaskMapper; @@ -11,7 +12,7 @@ import java.time.LocalDateTime; import java.util.List; @Service -public class TaskServiceImpl implements TaskService +public class TaskServiceImpl extends ServiceImpl implements TaskService { private final TaskMapper taskMapper; public TaskServiceImpl(TaskMapper taskMapper) {this.taskMapper=taskMapper;} -- Gitee From bd15e16fcb7b8ea20184288c98a456e92b2499f1 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Tue, 23 Apr 2024 15:36:04 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89chatGPT=E7=B1=BB=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pojo/pom.xml | 5 + .../java/com/groupshell/entity/Invoice.java | 5 + .../entity/chatgpt/ChatGPTConfig.java | 117 ++++++++++++++---- .../entity/chatgpt/ChatGPTHistory.java | 38 ++++++ .../entity/chatgpt/CustomChatGPT.java | 58 +++++++-- .../chatgpt/CustomEventSourceListener.java | 49 ++++++++ .../entity/chatgpt/TestChatGPT6.java | 7 +- .../groupshell/controller/ChatGPTCtrl.java | 30 +++++ .../com/groupshell/mapper/ChatGPTMapper.java | 13 ++ .../groupshell/service/ChatGPTService.java | 10 +- .../service/impl/ChatGPTServiceImpl.java | 22 ++++ 11 files changed, 318 insertions(+), 36 deletions(-) create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTHistory.java create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java create mode 100644 server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java diff --git a/pojo/pom.xml b/pojo/pom.xml index ee66ef9..49e2a84 100644 --- a/pojo/pom.xml +++ b/pojo/pom.xml @@ -32,6 +32,11 @@ chatgpt-java 1.0.14-beta1 + + com.alibaba + fastjson + 2.0.27 + com.groupshell common diff --git a/pojo/src/main/java/com/groupshell/entity/Invoice.java b/pojo/src/main/java/com/groupshell/entity/Invoice.java index 5a78e8f..fc78500 100644 --- a/pojo/src/main/java/com/groupshell/entity/Invoice.java +++ b/pojo/src/main/java/com/groupshell/entity/Invoice.java @@ -1,6 +1,9 @@ package com.groupshell.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; import lombok.AllArgsConstructor; @@ -21,11 +24,13 @@ import java.time.LocalDateTime; @ToString @NoArgsConstructor @AllArgsConstructor +@TableName("invoice") public class Invoice { /** * The unique identifier for the invoice. * 主键,自增 */ + @TableId(value="id", type= IdType.AUTO) private Integer id; /** diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java index 29457ef..6b68381 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java @@ -5,11 +5,19 @@ import com.unfbx.chatgpt.OpenAiStreamClient; import com.unfbx.chatgpt.entity.chat.ChatCompletion; import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; import com.unfbx.chatgpt.entity.chat.Message; +import com.unfbx.chatgpt.interceptor.OpenAILogger; import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; import lombok.*; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; @Data @ToString @@ -17,11 +25,17 @@ import java.util.concurrent.CountDownLatch; @Builder public class ChatGPTConfig { + private OkHttpClient okHttpClient; private OpenAiStreamClient openAiStreamClient; - private ConsoleEventSourceListener consoleEventSourceListener; +// private ConsoleEventSourceListener consoleEventSourceListener; + private CustomEventSourceListener eventSourceListener; private ChatCompletion chatCompletion; private ChatCompletion.Model model; - private Message message; + private List messages; + private ChatCompletionResponse response; + private HttpLoggingInterceptor httpLoggingInterceptor; + + private static final String DEFAULT_OPENAI_KEY = "sk-OA8YqWsVOIIPeGWlD86eB41a9284495085Ab17A08c514b1e"; private static final String DEFAULT_CHAT_MESSAGE = "你好!请问你是chatGPT吗?"; private static final String GPT3_OPENAI_API_URL = "https://one.aiskt.com/"; @@ -29,47 +43,98 @@ public class ChatGPTConfig { public ChatGPTConfig() throws InterruptedException { + initHttpLoggingInterceptor(); + initOkHttpClient(); initOpenAiStreamClient(); //初始化流式客户端 - initConsoleEventSourceListener(new ConsoleEventSourceListener()); //初始化事件侦听器 - setChatCompletion(); - setChatCompletion(DEFAULT_CHAT_MESSAGE); //初始化模型与会话 +// initConsoleEventSourceListener(new ConsoleEventSourceListener()); //初始化事件侦听器 + initCustomEventSourceListener(new CustomEventSourceListener()); //初始化事件侦听器 + initChatCompletion(); + //setChatCompletion(DEFAULT_CHAT_MESSAGE); //初始化模型与会话 + //不用加下面那句代码,在CustomChatGPT类中的runCustomChatGPT实现以下功能 + //openAiStreamClient.streamChatCompletion(chatCompletion, consoleEventSourceListener); //把对话信息发送给GPT并让它回复 + } + + public void initHttpLoggingInterceptor() { + //日志拦截器 + this.httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger()); + //!!!!千万别再生产或者测试环境打开BODY级别日志!!!! + //!!!生产或者测试环境建议设置为这三种级别:NONE,BASIC,HEADERS,!!! + this.httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); //除了BODY,只有HEADERS才会返回带有会话信息的内容 + } + + public void initOkHttpClient() { + OkHttpClient okHttpClient = new OkHttpClient.Builder() + .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890))) // 设置代理 + .addInterceptor(httpLoggingInterceptor) + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .build(); } public void initOpenAiStreamClient() { this.openAiStreamClient = OpenAiStreamClient.builder() .apiKey(Arrays.asList(DEFAULT_OPENAI_KEY)) .apiHost(GPT4_OPENAI_API_URL) //支持GPT4 + .keyStrategy(new KeyRandomStrategy()) + .okHttpClient(okHttpClient) .build(); } - public void initConsoleEventSourceListener(ConsoleEventSourceListener consoleEventSourceListener) { +// public void initConsoleEventSourceListener(ConsoleEventSourceListener consoleEventSourceListener) { +// this.consoleEventSourceListener = consoleEventSourceListener; +// } - this.consoleEventSourceListener = consoleEventSourceListener; + public void initCustomEventSourceListener(CustomEventSourceListener eventSourceListener) { + this.eventSourceListener = eventSourceListener; } - public void setChatCompletion(String chat) { - + public void initChatCompletion() { + this.messages = new ArrayList(); +// setMessage(DEFAULT_CHAT_MESSAGE); + this.chatCompletion = ChatCompletion.builder() + .messages(this.messages) + .stream(true) + .build(); //这里必须设置发送给gpt的初始信息(提问) + chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); //TODO:实际使用的是gpt-35-turbo +// chatCompletion.setModel(ChatCompletion.Model.GPT_4_32K.getName()); //实际使用的是gpt-35-turbo } - public void setMessage(String chatMessage) { - this.message = Message.builder().role(Message.Role.USER).content(chatMessage).build(); - } - public void setChatCompletion(String chatMessage) { - setMessage(chatMessage); - this.chatCompletion = ChatCompletion.builder().messages(Arrays.asList(message)).build(); - //setChatCompletion(); - chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); - //streamClient.streamChatCompletion(chatCompletion, eventSourceListener); //TODO:这句代码是什么意思 - } - public void setChatCompletion(ChatCompletion chatCompletion) { - this.chatCompletion = chatCompletion; + /** + * 设置聊天完成的配置,根据不同参数类型执行不同逻辑。 + * + * @param parameter 可以是 String, ChatCompletion 或 ChatCompletion.Model 类型的对象 + */ + public void setChatCompletion(Object parameter) { + if (parameter instanceof String) { //传入用户的对话信息 + String chatMessage = (String) parameter; + addMessage(chatMessage); + this.chatCompletion = ChatCompletion.builder().messages(messages).build(); + //chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); + + } else if (parameter instanceof ChatCompletion) { + this.chatCompletion = (ChatCompletion) parameter; + + } else if (parameter instanceof ChatCompletion.Model) { //更换模型 + ChatCompletion.Model model = (ChatCompletion.Model) parameter; + if (this.chatCompletion == null) { + this.chatCompletion = new ChatCompletion(); + } + this.chatCompletion.setModel(model.getName()); + + } else { + throw new IllegalArgumentException("不支持的参数类型: " + parameter.getClass().getSimpleName()); + } } - //设置模型model - public void setChatCompletion(ChatCompletion.Model model) { - //this.setModel(model.getName()); - this.chatCompletion.setModel(model.getName()); - //streamClient.streamChatCompletion(chatCompletion, eventSourceListener); +// public void setMessage(String chatMessage) { +// this.message = Message.builder().role(Message.Role.USER).content(chatMessage).build(); +// } + + public void addMessage(String chatMessage) { + this.messages.add(Message.builder().role(Message.Role.USER).content(chatMessage).build()); } + + } diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTHistory.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTHistory.java new file mode 100644 index 0000000..1e9a65f --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTHistory.java @@ -0,0 +1,38 @@ +package com.groupshell.entity.chatgpt; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.models.security.SecurityScheme; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.Map; + +@Data +@ToString +//@NoArgsConstructor +@AllArgsConstructor +@Builder +@TableName("chatgpt_history") +public class ChatGPTHistory { + @TableId(type = IdType.AUTO) + private Integer id; + private Integer userId; + private String title; //对话的标题 + private Map userAsk; //用户询问语句:对话id与对话内容 + private Map chatgptAnswer; //chatgpt回答 + private LocalDateTime createdTime; + private LocalDateTime updatedTime; + + // 构造器中自动设置时间 + public ChatGPTHistory() { + this.createdTime = LocalDateTime.now(); + this.updatedTime = LocalDateTime.now(); + } + + // 更新时刷新时间戳 + public void refreshUpdatedTime() { + this.updatedTime = LocalDateTime.now(); + } +} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java index 5d22ff5..c64578a 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java @@ -1,12 +1,16 @@ package com.groupshell.entity.chatgpt; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.unfbx.chatgpt.entity.chat.Message; +import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.ToString; import java.util.List; +import java.util.Scanner; import java.util.concurrent.CountDownLatch; @Data @@ -15,17 +19,22 @@ import java.util.concurrent.CountDownLatch; @Builder public class CustomChatGPT { - private List messages; + private List messages; //TODO:保存临时会话信息?? private ChatGPTConfig chatGPTConfig; public CustomChatGPT() throws InterruptedException { chatGPTConfig = new ChatGPTConfig(); } - public void runCustomChatGPT() throws InterruptedException { + public CustomChatGPT(ChatGPTConfig chatGPTConfig) throws InterruptedException { + this.chatGPTConfig = chatGPTConfig; + } + + //把对话信息发送给GPT并让它回复 + public void callCustomChatGPT() throws InterruptedException { chatGPTConfig.getOpenAiStreamClient().streamChatCompletion( chatGPTConfig.getChatCompletion(), - chatGPTConfig.getConsoleEventSourceListener()); + new ConsoleEventSourceListener()); //new一个ConsoleEventSourceListener CountDownLatch countDownLatch = new CountDownLatch(1); try { @@ -37,11 +46,8 @@ public class CustomChatGPT { } private void sendMessageToChatGPT(String message) throws InterruptedException { - //chatGPTConfig.setMessage(message); chatGPTConfig.setChatCompletion(message); - chatGPTConfig.getOpenAiStreamClient().streamChatCompletion( - chatGPTConfig.getChatCompletion(), - chatGPTConfig.getConsoleEventSourceListener()); + callCustomChatGPT(); CountDownLatch countDownLatch = new CountDownLatch(1); try { @@ -51,4 +57,42 @@ public class CustomChatGPT { Thread.currentThread().interrupt(); // 保留中断状态 } } + + public void startChattingWithConsole() throws InterruptedException { + Scanner scanner = new Scanner(System.in); + System.out.println("你好,开始与 ChatGPT 聊天吧!(输入 'exit' 退出)"); + + while (true) { + System.out.print("我: "); + String input = scanner.nextLine(); + if ("exit".equalsIgnoreCase(input)) { + System.out.println("聊天结束。"); + break; + } + sendMessageToChatGPT(input); + } + scanner.close(); + } + + + public String chatGPTResponseHandler(List jsonResponses) { + StringBuilder fullSentence = new StringBuilder(); + for (String jsonResponse : jsonResponses) { + JSONObject jsonObject = new JSONObject(Boolean.parseBoolean(jsonResponse)); //TODO:无法把jsonResponse转换为JSONObject + JSONArray choices = jsonObject.getJSONArray("choices"); + if (choices != null && choices.size() > 0) { + JSONObject choice = choices.getJSONObject(0); + JSONObject delta = choice.getJSONObject("delta"); + if (delta != null) { + String content = delta.getString("content"); + fullSentence.append(content); + } + } + } + + //System.out.println(fullSentence.toString()); // 输出完整句子到控制台 + return fullSentence.toString(); + } + + } diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java new file mode 100644 index 0000000..f909fb1 --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java @@ -0,0 +1,49 @@ +package com.groupshell.entity.chatgpt; + +import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.sse.EventSource; + +import java.util.Objects; + +@Slf4j +public class CustomEventSourceListener extends ConsoleEventSourceListener { + @Override + public void onOpen(EventSource eventSource, Response response) { + log.info("OpenAI建立sse连接..."); + } + + @Override + public void onEvent(EventSource eventSource, String id, String type, String data) { + log.info("OpenAI返回数据:{}", data); + if (data.equals("[DONE]")) { + log.info("OpenAI返回数据结束了"); + return; + } + } + + @Override + public void onClosed(EventSource eventSource) { + log.info("OpenAI关闭sse连接..."); + } + + @SneakyThrows + @Override + public void onFailure(EventSource eventSource, Throwable t, Response response) { + if(Objects.isNull(response)){ + log.error("OpenAI sse连接异常:{}", t); + eventSource.cancel(); + return; + } + ResponseBody body = response.body(); + if (Objects.nonNull(body)) { + log.error("OpenAI sse连接异常data:{},异常:{}", body.string(), t); + } else { + log.error("OpenAI sse连接异常data:{},异常:{}", response, t); + } + eventSource.cancel(); + } +} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java index aae3391..b2314f5 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java @@ -3,7 +3,10 @@ package com.groupshell.entity.chatgpt; public class TestChatGPT6 { public static void main(String[] args) throws InterruptedException { CustomChatGPT customChatGPT = new CustomChatGPT(); - customChatGPT.runCustomChatGPT(); - customChatGPT.setChatGPTConfig(); + customChatGPT.startChattingWithConsole(); + + //customChatGPT.runCustomChatGPT(); + //customChatGPT.startChattingWithConsole(); + //customChatGPT.setChatGPTConfig(); } } diff --git a/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java index 4674089..f9fe4b1 100644 --- a/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java +++ b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java @@ -1,5 +1,35 @@ package com.groupshell.controller; + +import com.groupshell.service.ChatGPTService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("api/chatgpt") public class ChatGPTCtrl { + @Autowired + private ChatGPTService chatGPTService; + +// @Autowired +// public ChatGPTCtrl(ChatGPTService chatGPTService) { +// this.chatGPTService = chatGPTService; +// } + + + @PostMapping("/ask") + public ResponseEntity getResponse(@RequestBody String userInput) { + try { + String response = chatGPTService.getResponseFromOpenAi(userInput); + return ResponseEntity.ok(response); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error processing your request"); + } + } } diff --git a/server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java b/server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java new file mode 100644 index 0000000..d5d0785 --- /dev/null +++ b/server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java @@ -0,0 +1,13 @@ +package com.groupshell.mapper; + + +import com.groupshell.entity.chatgpt.ChatGPTHistory; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface ChatGPTHistoryMapper { + void insertChatHistory(ChatGPTHistory chatHistory); + List findAllChatHistories(); +} diff --git a/server/src/main/java/com/groupshell/service/ChatGPTService.java b/server/src/main/java/com/groupshell/service/ChatGPTService.java index 870e89b..5f9a31d 100644 --- a/server/src/main/java/com/groupshell/service/ChatGPTService.java +++ b/server/src/main/java/com/groupshell/service/ChatGPTService.java @@ -1,7 +1,15 @@ package com.groupshell.service; -public interface ChatGPTService { +import com.baomidou.mybatisplus.extension.service.IService; +import com.groupshell.entity.chatgpt.CustomChatGPT; +import org.springframework.stereotype.Service; + +import java.io.IOException; +//extends IService +@Service +public interface ChatGPTService { + public String getResponseFromOpenAi(String userInput) throws IOException; } diff --git a/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java index c9e7012..6606d28 100644 --- a/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java @@ -1,7 +1,29 @@ package com.groupshell.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.groupshell.entity.Invoice; +import com.groupshell.entity.chatgpt.CustomChatGPT; +import com.groupshell.mapper.InvoiceMapper; import com.groupshell.service.ChatGPTService; +import com.unfbx.chatgpt.entity.chat.ChatCompletion; +import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; +import com.unfbx.chatgpt.entity.chat.Message; +import org.springframework.beans.factory.annotation.Autowired; +import java.io.IOException; +import java.util.Collections; + +//extends ServiceImpl<...Mapper, ...> public class ChatGPTServiceImpl implements ChatGPTService { + @Autowired + private CustomChatGPT customChatGPT; + @Override + public String getResponseFromOpenAi(String userInput) throws IOException { + ChatCompletion chatCompletion = ChatCompletion.builder() + .messages(Collections.singletonList(Message.builder().content(userInput).build())) + .build(); + ChatCompletionResponse response = customChatGPT.getChatGPTConfig().getChatCompletion(); + return response.getChoices().get(0).getMessage().getContent(); + } } -- Gitee From eb5de99aad7d06c6e0b8e6c0eac947952f3e6032 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Tue, 23 Apr 2024 20:05:33 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E5=9C=A8=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E8=BE=93=E5=87=BAchatGPT=E7=9A=84=E5=9B=9E=E5=A4=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../groupshell/constant/ChatGPTConstants.java | 11 ++ .../entity/chatgpt/ChatGPTConfig.java | 110 +++++++++++------- .../entity/chatgpt/ChatGPTMessageHandler.java | 68 +++++++++++ .../entity/chatgpt/CustomChatGPT.java | 78 +++++++++---- .../chatgpt/CustomEventSourceListener.java | 10 +- .../entity/chatgpt/TestChatGPT6.java | 7 +- 6 files changed, 221 insertions(+), 63 deletions(-) create mode 100644 common/src/main/java/com/groupshell/constant/ChatGPTConstants.java create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java diff --git a/common/src/main/java/com/groupshell/constant/ChatGPTConstants.java b/common/src/main/java/com/groupshell/constant/ChatGPTConstants.java new file mode 100644 index 0000000..31013fb --- /dev/null +++ b/common/src/main/java/com/groupshell/constant/ChatGPTConstants.java @@ -0,0 +1,11 @@ +package com.groupshell.constant; + +public interface ChatGPTConstants { + String DEFAULT_OPENAI_KEY = "sk-OA8YqWsVOIIPeGWlD86eB41a9284495085Ab17A08c514b1e"; + String DEFAULT_CHAT_MESSAGE = "你好!请问你是chatGPT吗?"; + String GPT3_OPENAI_API_URL = "https://one.aiskt.com/"; + String GPT4_OPENAI_API_URL = "https://pro.aiskt.com/"; + String OPENAI_CLIENT = "OpenAiClient"; + String OPENAI_STREAM_CLIENT = "OpenAiStreamClient"; + String CHATGPT_DONE = "[DONE]"; +} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java index 6b68381..9c5aea9 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java @@ -1,6 +1,7 @@ package com.groupshell.entity.chatgpt; import com.baomidou.mybatisplus.annotation.TableName; +import com.unfbx.chatgpt.OpenAiClient; import com.unfbx.chatgpt.OpenAiStreamClient; import com.unfbx.chatgpt.entity.chat.ChatCompletion; import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; @@ -19,6 +20,8 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static com.groupshell.constant.ChatGPTConstants.*; + @Data @ToString @AllArgsConstructor @@ -26,33 +29,42 @@ import java.util.concurrent.TimeUnit; public class ChatGPTConfig { private OkHttpClient okHttpClient; - private OpenAiStreamClient openAiStreamClient; -// private ConsoleEventSourceListener consoleEventSourceListener; + private OpenAiClient openAiClient; //阻塞 + private OpenAiStreamClient openAiStreamClient; //非阻塞 private CustomEventSourceListener eventSourceListener; private ChatCompletion chatCompletion; private ChatCompletion.Model model; private List messages; - private ChatCompletionResponse response; + private ChatCompletionResponse chatCompletionResponse; //暂时没用 private HttpLoggingInterceptor httpLoggingInterceptor; + public ChatGPTConfig(String customization) throws InterruptedException { + if (customization == OPENAI_CLIENT) { + initHttpLoggingInterceptor(); + initOkHttpClient(); + initOpenAiClient(); //初始化阻塞式客户端 + initCustomEventSourceListener(new CustomEventSourceListener()); //初始化事件侦听器 + initChatCompletion(customization); - private static final String DEFAULT_OPENAI_KEY = "sk-OA8YqWsVOIIPeGWlD86eB41a9284495085Ab17A08c514b1e"; - private static final String DEFAULT_CHAT_MESSAGE = "你好!请问你是chatGPT吗?"; - private static final String GPT3_OPENAI_API_URL = "https://one.aiskt.com/"; - private static final String GPT4_OPENAI_API_URL = "https://pro.aiskt.com/"; - - - public ChatGPTConfig() throws InterruptedException { - initHttpLoggingInterceptor(); - initOkHttpClient(); - initOpenAiStreamClient(); //初始化流式客户端 -// initConsoleEventSourceListener(new ConsoleEventSourceListener()); //初始化事件侦听器 - initCustomEventSourceListener(new CustomEventSourceListener()); //初始化事件侦听器 - initChatCompletion(); - //setChatCompletion(DEFAULT_CHAT_MESSAGE); //初始化模型与会话 - //不用加下面那句代码,在CustomChatGPT类中的runCustomChatGPT实现以下功能 - //openAiStreamClient.streamChatCompletion(chatCompletion, consoleEventSourceListener); //把对话信息发送给GPT并让它回复 + //initChatCompletionResponse(); + } + else if (customization == OPENAI_STREAM_CLIENT) { + initHttpLoggingInterceptor(); + initOkHttpClient(); + initOpenAiStreamClient(); //初始化流式客户端 + initCustomEventSourceListener(new CustomEventSourceListener()); //初始化事件侦听器 + initChatCompletion(customization); + } + else { + initHttpLoggingInterceptor(); + initOkHttpClient(); + initOpenAiClient(); //初始化阻塞式客户端 + initCustomEventSourceListener(new CustomEventSourceListener()); //初始化事件侦听器 + initChatCompletion(customization); + //initChatCompletionResponse(); + } } + public void initHttpLoggingInterceptor() { //日志拦截器 @@ -63,7 +75,7 @@ public class ChatGPTConfig { } public void initOkHttpClient() { - OkHttpClient okHttpClient = new OkHttpClient.Builder() + this.okHttpClient = new OkHttpClient.Builder() .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890))) // 设置代理 .addInterceptor(httpLoggingInterceptor) .connectTimeout(15, TimeUnit.SECONDS) @@ -72,6 +84,15 @@ public class ChatGPTConfig { .build(); } + public void initOpenAiClient() { + this.openAiClient = OpenAiClient.builder() + .apiKey(Arrays.asList(DEFAULT_OPENAI_KEY)) + .apiHost(GPT4_OPENAI_API_URL) //支持GPT4 + .keyStrategy(new KeyRandomStrategy()) + .okHttpClient(okHttpClient) + .build(); + } + public void initOpenAiStreamClient() { this.openAiStreamClient = OpenAiStreamClient.builder() .apiKey(Arrays.asList(DEFAULT_OPENAI_KEY)) @@ -81,25 +102,41 @@ public class ChatGPTConfig { .build(); } -// public void initConsoleEventSourceListener(ConsoleEventSourceListener consoleEventSourceListener) { -// this.consoleEventSourceListener = consoleEventSourceListener; -// } public void initCustomEventSourceListener(CustomEventSourceListener eventSourceListener) { this.eventSourceListener = eventSourceListener; } - public void initChatCompletion() { - this.messages = new ArrayList(); -// setMessage(DEFAULT_CHAT_MESSAGE); - this.chatCompletion = ChatCompletion.builder() - .messages(this.messages) - .stream(true) - .build(); //这里必须设置发送给gpt的初始信息(提问) - chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); //TODO:实际使用的是gpt-35-turbo -// chatCompletion.setModel(ChatCompletion.Model.GPT_4_32K.getName()); //实际使用的是gpt-35-turbo + public void initChatCompletion(String customization) { + if (customization == OPENAI_CLIENT) { + this.messages = new ArrayList(); + this.chatCompletion = ChatCompletion.builder() + .messages(this.messages) + .build(); //这里必须设置发送给gpt的初始信息(提问) + chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); //实际使用的是gpt-35-turbo + } + else if (customization == OPENAI_STREAM_CLIENT) { + this.messages = new ArrayList(); + this.chatCompletion = ChatCompletion.builder() + .messages(this.messages) + .stream(true) //流式输出 + .build(); //这里必须设置发送给gpt的初始信息(提问) + chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); //实际使用的是gpt-35-turbo + } + else { + this.messages = new ArrayList(); + this.chatCompletion = ChatCompletion.builder() + .messages(this.messages) + .build(); //这里必须设置发送给gpt的初始信息(提问) + chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); //实际使用的是gpt-35-turbo + } } + public void setChatCompletionResponse() { + this.chatCompletionResponse = openAiClient.chatCompletion(chatCompletion); + } + + /** * 设置聊天完成的配置,根据不同参数类型执行不同逻辑。 * @@ -110,7 +147,6 @@ public class ChatGPTConfig { String chatMessage = (String) parameter; addMessage(chatMessage); this.chatCompletion = ChatCompletion.builder().messages(messages).build(); - //chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); } else if (parameter instanceof ChatCompletion) { this.chatCompletion = (ChatCompletion) parameter; @@ -127,14 +163,10 @@ public class ChatGPTConfig { } } -// public void setMessage(String chatMessage) { -// this.message = Message.builder().role(Message.Role.USER).content(chatMessage).build(); -// } - public void addMessage(String chatMessage) { this.messages.add(Message.builder().role(Message.Role.USER).content(chatMessage).build()); + System.out.println("调用addMessage"); + System.out.println(messages); } - - } diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java new file mode 100644 index 0000000..92cb62b --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java @@ -0,0 +1,68 @@ +package com.groupshell.entity.chatgpt; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; + + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static com.groupshell.constant.ChatGPTConstants.CHATGPT_DONE; + +public class ChatGPTMessageHandler { + +// public String singleResponse; + public List responses = new ArrayList(); + + + public String responseHandler(String jsonResponse) { +// // 使用 Fastjson 解析 JSON 数据 +// JSONObject jsonObject = JSON.parseObject(jsonResponse); +// +// // 提取 choices 数组中第一个元素的 delta 对象下的 content 字段 +// String content = jsonObject.getJSONArray("choices").getJSONObject(1) +// .getJSONObject("delta").getString("content"); +// //System.out.println(fullSentence.toString()); // 输出完整句子到控制台 +// return content; + if (Objects.equals(jsonResponse, CHATGPT_DONE)) { + return null; + } + JSONObject jsonObject = JSON.parseObject(jsonResponse); + JSONArray choices = jsonObject.getJSONArray("choices"); + + if (choices != null && !choices.isEmpty()) { + for (int i = 0; i < choices.size(); i++) { + JSONObject choice = choices.getJSONObject(i); + JSONObject delta = choice.getJSONObject("delta"); + if (delta != null && delta.containsKey("content")) { + String content = delta.getString("content"); + if (content != null && !content.isEmpty()) { + System.out.println(content); + return content; + //responses.add(content); + } else { + System.out.println("Content is empty or not available."); + } + } else { + System.out.println("Delta is null or does not contain 'content'."); + } + } + } else { + System.out.println("Choices array is empty."); + } + return null; + } + + public void printResponses() { + // 遍历responses数组并打印每个元素 + for (String response : responses) { + if (response != null) { + System.out.println(response); + } + } + responses.clear(); + } + +} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java index c64578a..538fe88 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java @@ -2,6 +2,10 @@ package com.groupshell.entity.chatgpt; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.unfbx.chatgpt.OpenAiClient; +import com.unfbx.chatgpt.OpenAiStreamClient; +import com.unfbx.chatgpt.entity.chat.ChatCompletion; +import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; import com.unfbx.chatgpt.entity.chat.Message; import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; import lombok.AllArgsConstructor; @@ -9,10 +13,15 @@ import lombok.Builder; import lombok.Data; import lombok.ToString; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Scanner; import java.util.concurrent.CountDownLatch; +import static com.groupshell.constant.ChatGPTConstants.OPENAI_CLIENT; +import static com.groupshell.constant.ChatGPTConstants.OPENAI_STREAM_CLIENT; + @Data @ToString @AllArgsConstructor @@ -21,41 +30,57 @@ public class CustomChatGPT { private List messages; //TODO:保存临时会话信息?? private ChatGPTConfig chatGPTConfig; + private String openAiClientType; //OpenAiClient或OpenAiStreamClient - public CustomChatGPT() throws InterruptedException { - chatGPTConfig = new ChatGPTConfig(); + //阻塞 + public CustomChatGPT(String customization) throws InterruptedException { + chatGPTConfig = new ChatGPTConfig(customization); + openAiClientType = customization; } - public CustomChatGPT(ChatGPTConfig chatGPTConfig) throws InterruptedException { - this.chatGPTConfig = chatGPTConfig; - } //把对话信息发送给GPT并让它回复 public void callCustomChatGPT() throws InterruptedException { - chatGPTConfig.getOpenAiStreamClient().streamChatCompletion( - chatGPTConfig.getChatCompletion(), - new ConsoleEventSourceListener()); //new一个ConsoleEventSourceListener - - CountDownLatch countDownLatch = new CountDownLatch(1); - try { - countDownLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); + if (openAiClientType == OPENAI_CLIENT) { + return; } - + else if (openAiClientType == OPENAI_STREAM_CLIENT){ + chatGPTConfig.getOpenAiStreamClient().streamChatCompletion( + chatGPTConfig.getChatCompletion(), + chatGPTConfig.getEventSourceListener()); //new一个ConsoleEventSourceListener? + } + else { + return; + } +// CountDownLatch countDownLatch = new CountDownLatch(1); +// try { +// countDownLatch.await(); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } } private void sendMessageToChatGPT(String message) throws InterruptedException { + /* + //这里直接新建了一个ChatCompletion,看看能不能持续对话 + chatGPTConfig.addMessage(message); + ChatCompletion chatCompletion = ChatCompletion.builder() + .messages(chatGPTConfig.getMessages()) + .stream(true) + .build(); + chatGPTConfig.setChatCompletion(chatCompletion); + */ + //chatGPTConfig.initOkHttpClient(); chatGPTConfig.setChatCompletion(message); callCustomChatGPT(); - CountDownLatch countDownLatch = new CountDownLatch(1); - try { - countDownLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - Thread.currentThread().interrupt(); // 保留中断状态 - } +// CountDownLatch countDownLatch = new CountDownLatch(1); +// try { +// countDownLatch.await(); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// //Thread.currentThread().interrupt(); // 保留中断状态 +// } } public void startChattingWithConsole() throws InterruptedException { @@ -70,6 +95,15 @@ public class CustomChatGPT { break; } sendMessageToChatGPT(input); + System.out.println("打印ChatCompletion的Messages"); + System.out.println(chatGPTConfig.getChatCompletion().getMessages()); + +// chatGPTConfig.getOpenAiStreamClient(); +// chatGPTConfig.getChatCompletion() +// chatGPTConfig.setChatCompletionResponse(); //TODO:ChatCompletionResponse会有Unrecognized field的问题 +// chatGPTConfig.getChatCompletionResponse().getChoices().forEach(e -> { +// System.out.println(e.getMessage()); +// }); } scanner.close(); } diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java index f909fb1..920ffa2 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java @@ -9,8 +9,12 @@ import okhttp3.sse.EventSource; import java.util.Objects; +import static com.groupshell.constant.ChatGPTConstants.CHATGPT_DONE; + @Slf4j public class CustomEventSourceListener extends ConsoleEventSourceListener { + ChatGPTMessageHandler messageHandler = new ChatGPTMessageHandler(); + @Override public void onOpen(EventSource eventSource, Response response) { log.info("OpenAI建立sse连接..."); @@ -19,8 +23,12 @@ public class CustomEventSourceListener extends ConsoleEventSourceListener { @Override public void onEvent(EventSource eventSource, String id, String type, String data) { log.info("OpenAI返回数据:{}", data); - if (data.equals("[DONE]")) { + String response = messageHandler.responseHandler(data); + messageHandler.responses.add(response); + if (data.equals(CHATGPT_DONE)) { log.info("OpenAI返回数据结束了"); + messageHandler.printResponses(); + //eventSource.request(); return; } } diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java index b2314f5..75bde11 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java @@ -1,8 +1,13 @@ package com.groupshell.entity.chatgpt; +import com.unfbx.chatgpt.OpenAiClient; + +import static com.groupshell.constant.ChatGPTConstants.OPENAI_CLIENT; +import static com.groupshell.constant.ChatGPTConstants.OPENAI_STREAM_CLIENT; + public class TestChatGPT6 { public static void main(String[] args) throws InterruptedException { - CustomChatGPT customChatGPT = new CustomChatGPT(); + CustomChatGPT customChatGPT = new CustomChatGPT(OPENAI_STREAM_CLIENT); customChatGPT.startChattingWithConsole(); //customChatGPT.runCustomChatGPT(); -- Gitee From c9a86b25bdc95fa2e2a35b8578654ad7b0811ba2 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Thu, 25 Apr 2024 20:24:56 +0800 Subject: [PATCH 04/10] =?UTF-8?q?commit=E6=9C=80=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/chatgpt/ChatGPTMessageHandler.java | 21 ++++-- .../entity/chatgpt/CustomChatGPT.java | 3 +- .../chatgpt/CustomEventSourceListener.java | 2 +- .../entity/chatgpt/CustomOpenAiClient.java | 15 ++++ .../entity/chatgpt/IOpenAiClient.java | 5 ++ .../entity/chatgpt/TestChatGPT6.java | 1 + .../entity/chatgpt/TestChatGpt4.java | 72 ------------------- 7 files changed, 41 insertions(+), 78 deletions(-) create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java create mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java delete mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java index 92cb62b..05f473a 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java @@ -15,6 +15,9 @@ public class ChatGPTMessageHandler { // public String singleResponse; public List responses = new ArrayList(); + public String responsesFomatted; + + public String responseHandler(String jsonResponse) { @@ -43,25 +46,35 @@ public class ChatGPTMessageHandler { return content; //responses.add(content); } else { - System.out.println("Content is empty or not available."); + //System.out.println("Content is empty or not available."); } } else { - System.out.println("Delta is null or does not contain 'content'."); + //System.out.println("Delta is null or does not contain 'content'."); } } } else { - System.out.println("Choices array is empty."); + //System.out.println("Choices array is empty."); } return null; } + public String responseFormat(List responses) { + StringBuilder fullSentence = new StringBuilder(); + for (String word : responses) { + fullSentence = fullSentence.append(word); + } + this.responsesFomatted = fullSentence.toString(); + return fullSentence.toString(); + } + public void printResponses() { // 遍历responses数组并打印每个元素 for (String response : responses) { if (response != null) { - System.out.println(response); + System.out.print(response); } } + System.out.println(); responses.clear(); } diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java index 538fe88..03b1888 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java @@ -88,7 +88,7 @@ public class CustomChatGPT { System.out.println("你好,开始与 ChatGPT 聊天吧!(输入 'exit' 退出)"); while (true) { - System.out.print("我: "); + System.out.print("我: "); //非阻塞会把这句话打印在前面 String input = scanner.nextLine(); if ("exit".equalsIgnoreCase(input)) { System.out.println("聊天结束。"); @@ -98,6 +98,7 @@ public class CustomChatGPT { System.out.println("打印ChatCompletion的Messages"); System.out.println(chatGPTConfig.getChatCompletion().getMessages()); + // chatGPTConfig.getOpenAiStreamClient(); // chatGPTConfig.getChatCompletion() // chatGPTConfig.setChatCompletionResponse(); //TODO:ChatCompletionResponse会有Unrecognized field的问题 diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java index 920ffa2..2247a4f 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java @@ -22,7 +22,7 @@ public class CustomEventSourceListener extends ConsoleEventSourceListener { @Override public void onEvent(EventSource eventSource, String id, String type, String data) { - log.info("OpenAI返回数据:{}", data); + //log.info("OpenAI返回数据:{}", data); String response = messageHandler.responseHandler(data); messageHandler.responses.add(response); if (data.equals(CHATGPT_DONE)) { diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java new file mode 100644 index 0000000..1b3be11 --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java @@ -0,0 +1,15 @@ +//package com.groupshell.entity.chatgpt; +// +//import com.unfbx.chatgpt.OpenAiClient; +//import lombok.AllArgsConstructor; +//import lombok.Builder; +//import lombok.Data; +//import lombok.ToString; +// +// +//public class CustomOpenAiClient extends OpenAiClient implements IOpenAiClient { +// public CustomOpenAiClient(Builder builder) { +// +// super(OpenAiClient.builder()); +// } +//} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java new file mode 100644 index 0000000..dc07c7c --- /dev/null +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java @@ -0,0 +1,5 @@ +//package com.groupshell.entity.chatgpt; +// +//public interface IOpenAiClient { +// +//} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java index 75bde11..29537f5 100644 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java +++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java @@ -10,6 +10,7 @@ public class TestChatGPT6 { CustomChatGPT customChatGPT = new CustomChatGPT(OPENAI_STREAM_CLIENT); customChatGPT.startChattingWithConsole(); + //customChatGPT.runCustomChatGPT(); //customChatGPT.startChattingWithConsole(); //customChatGPT.setChatGPTConfig(); diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java deleted file mode 100644 index 277a83c..0000000 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.groupshell.entity.chatgpt; - -import com.unfbx.chatgpt.OpenAiStreamClient; -import com.unfbx.chatgpt.entity.chat.ChatCompletion; -import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; -import com.unfbx.chatgpt.entity.chat.Message; -import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; - -import java.util.Arrays; -import java.util.concurrent.CountDownLatch; - -public class TestChatGpt4 { - public static void main(String[] args) { -// //日志拦截器 -// HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger()); -// //!!!!千万别再生产或者测试环境打开BODY级别日志!!!! -// //!!!生产或者测试环境建议设置为这三种级别:NONE,BASIC,HEADERS,!!! -// httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); -// -// OkHttpClient okHttpClient = new OkHttpClient.Builder() -//// .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080))) // 设置代理 -// .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890))) // 设置代理 -// .addInterceptor(httpLoggingInterceptor) -// .connectTimeout(15, TimeUnit.SECONDS) -// .writeTimeout(15, TimeUnit.SECONDS) -// .readTimeout(15, TimeUnit.SECONDS) -// .build(); -// -// OpenAiClient client = OpenAiClient.builder() -// .apiKey(Arrays.asList("sk-OA8YqWsVOIIPeGWlD86eB41a9284495085Ab17A08c514b1e")) -// .keyStrategy(new KeyRandomStrategy()) -// .okHttpClient(okHttpClient) -//// .apiHost("https://pro.aiskt.com/") -//// .apiHost("https://one.aiskt.com") -// .apiHost("https://key.aiskt.com") -// .build(); -// -// -// List messages = new ArrayList<>(); -// messages.add(Message.builder().role(Message.Role.USER).content("您好,我想了解更多关于您的服务。").build()); -// -// ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).build(); -// ChatCompletionResponse response = client.chatCompletion(chatCompletion); -// -// System.out.println("响应:" + response.getChoices().get(0).getMessage().getContent()); - - - OpenAiStreamClient streamClient = OpenAiStreamClient.builder() - .apiKey(Arrays.asList("sk-OA8YqWsVOIIPeGWlD86eB41a9284495085Ab17A08c514b1e")) -// .apiKey(Arrays.asList("sk-pBE3MEC3Q6g0KcrpF043815cAe494f2682Ac180032C33bB5")) - .apiHost("https://pro.aiskt.com/") //支持GPT4 -// .apiHost("https://one.aiskt.com/") //不支持GPT4 - .build(); - //聊天模型:gpt-3.5 - ConsoleEventSourceListener eventSourceListener = new ConsoleEventSourceListener(); - Message message = Message.builder().role(Message.Role.USER).content("你好,你是谁?").build(); -// Message message = Message.builder().role(Message.Role.USER).content("你是GPT4吗?").build(); - ChatCompletion chatCompletion = ChatCompletion.builder().messages(Arrays.asList(message)).build(); - chatCompletion.setModel(ChatCompletion.Model.GPT_4.getName()); - streamClient.streamChatCompletion(chatCompletion, eventSourceListener); - - ChatCompletionResponse chatCompletionResponse = new ChatCompletionResponse(); - - CountDownLatch countDownLatch = new CountDownLatch(1); - - try { - countDownLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } -} -- Gitee From 84d694481ec6ed82a0f039f4e76a93795491f3f7 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Thu, 25 Apr 2024 20:27:11 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/chatgpt/CustomOpenAiClient.java | 15 --------------- .../groupshell/entity/chatgpt/IOpenAiClient.java | 5 ----- 2 files changed, 20 deletions(-) delete mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java delete mode 100644 pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java deleted file mode 100644 index 1b3be11..0000000 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomOpenAiClient.java +++ /dev/null @@ -1,15 +0,0 @@ -//package com.groupshell.entity.chatgpt; -// -//import com.unfbx.chatgpt.OpenAiClient; -//import lombok.AllArgsConstructor; -//import lombok.Builder; -//import lombok.Data; -//import lombok.ToString; -// -// -//public class CustomOpenAiClient extends OpenAiClient implements IOpenAiClient { -// public CustomOpenAiClient(Builder builder) { -// -// super(OpenAiClient.builder()); -// } -//} diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java deleted file mode 100644 index dc07c7c..0000000 --- a/pojo/src/main/java/com/groupshell/entity/chatgpt/IOpenAiClient.java +++ /dev/null @@ -1,5 +0,0 @@ -//package com.groupshell.entity.chatgpt; -// -//public interface IOpenAiClient { -// -//} -- Gitee From 362f4b47bc006290a90e2afb71a75b4c678c5fd5 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Fri, 26 Apr 2024 09:34:27 +0800 Subject: [PATCH 06/10] =?UTF-8?q?Invoice=E7=B1=BB=E7=9A=84MyBatisPlus?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=87=BA=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/groupshell/entity/Invoice.java | 3 +- .../main/java/com/groupshell/entity/Task.java | 2 + .../groupshell/controller/ChatGPTCtrl.java | 66 ++--- .../groupshell/controller/InvoiceCtrl.java | 8 +- .../com/groupshell/controller/TaskCtrl.java | 7 + .../mapper/ChatGPTHistoryMapper.java | 13 + .../com/groupshell/mapper/ChatGPTMapper.java | 13 - .../com/groupshell/mapper/InvoiceMapper.java | 1 + .../com/groupshell/mapper/TaskMapper.java | 2 + .../groupshell/service/ChatGPTService.java | 30 +-- .../groupshell/service/InvoiceService.java | 53 ++-- .../com/groupshell/service/TaskService.java | 2 + .../service/impl/ChatGPTServiceImpl.java | 63 ++--- .../service/impl/InvoiceServiceImpl.java | 171 +++++++------ .../service/impl/TaskServiceImpl.java | 10 +- .../main/resources/mapper/InvoiceMapper.xml | 239 +++++++++--------- .../src/main/resources/mapper/TaskMapper.xml | 7 + 17 files changed, 374 insertions(+), 316 deletions(-) create mode 100644 server/src/main/java/com/groupshell/mapper/ChatGPTHistoryMapper.java delete mode 100644 server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java diff --git a/pojo/src/main/java/com/groupshell/entity/Invoice.java b/pojo/src/main/java/com/groupshell/entity/Invoice.java index 0a60742..107eee1 100644 --- a/pojo/src/main/java/com/groupshell/entity/Invoice.java +++ b/pojo/src/main/java/com/groupshell/entity/Invoice.java @@ -8,6 +8,7 @@ import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; import lombok.*; +import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -23,7 +24,7 @@ import java.time.LocalDateTime; @AllArgsConstructor @Builder @TableName("invoice") -public class Invoice { +public class Invoice implements Serializable { /** * The unique identifier for the invoice. * 主键,自增 diff --git a/pojo/src/main/java/com/groupshell/entity/Task.java b/pojo/src/main/java/com/groupshell/entity/Task.java index 68515dc..e3745b3 100644 --- a/pojo/src/main/java/com/groupshell/entity/Task.java +++ b/pojo/src/main/java/com/groupshell/entity/Task.java @@ -68,4 +68,6 @@ public class Task implements Serializable * The status of the task. */ private TaskStatusEnum status; + + private Integer groupId; } \ No newline at end of file diff --git a/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java index f9fe4b1..e1499db 100644 --- a/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java +++ b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java @@ -1,35 +1,35 @@ -package com.groupshell.controller; - - -import com.groupshell.service.ChatGPTService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("api/chatgpt") -public class ChatGPTCtrl { - - @Autowired - private ChatGPTService chatGPTService; - +//package com.groupshell.controller; +// +// +//import com.groupshell.service.ChatGPTService; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.PostMapping; +//import org.springframework.web.bind.annotation.RequestBody; +//import org.springframework.web.bind.annotation.RequestMapping; +//import org.springframework.web.bind.annotation.RestController; +// +//@RestController +//@RequestMapping("api/chatgpt") +//public class ChatGPTCtrl { +// // @Autowired -// public ChatGPTCtrl(ChatGPTService chatGPTService) { -// this.chatGPTService = chatGPTService; +// private ChatGPTService chatGPTService; +// +//// @Autowired +//// public ChatGPTCtrl(ChatGPTService chatGPTService) { +//// this.chatGPTService = chatGPTService; +//// } +// +// +// @PostMapping("/ask") +// public ResponseEntity getResponse(@RequestBody String userInput) { +// try { +// String response = chatGPTService.getResponseFromOpenAi(userInput); +// return ResponseEntity.ok(response); +// } catch (Exception e) { +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error processing your request"); +// } // } - - - @PostMapping("/ask") - public ResponseEntity getResponse(@RequestBody String userInput) { - try { - String response = chatGPTService.getResponseFromOpenAi(userInput); - return ResponseEntity.ok(response); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error processing your request"); - } - } -} +//} diff --git a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java index 41424d3..a1a6838 100644 --- a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java +++ b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java @@ -5,6 +5,7 @@ import com.groupshell.enumeration.ReimburseStatusEnum; import com.groupshell.result.Result; import com.groupshell.service.InvoiceService; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; @@ -19,8 +20,11 @@ import java.util.Map; @RequestMapping("/api/invoice") public class InvoiceCtrl { - private final InvoiceService invoiceService; - public InvoiceCtrl(InvoiceService invoiceService) {this.invoiceService=invoiceService;} + @Autowired + private InvoiceService invoiceService; +// public InvoiceCtrl(InvoiceService invoiceService) { +// this.invoiceService=invoiceService; +// } @PostMapping public Result addInvoice(@RequestBody Invoice record) { diff --git a/server/src/main/java/com/groupshell/controller/TaskCtrl.java b/server/src/main/java/com/groupshell/controller/TaskCtrl.java index 5857a66..db837eb 100644 --- a/server/src/main/java/com/groupshell/controller/TaskCtrl.java +++ b/server/src/main/java/com/groupshell/controller/TaskCtrl.java @@ -58,4 +58,11 @@ public class TaskCtrl { List tasks = taskService.listTasksByStatus(status); return Result.success(tasks); } + + + @GetMapping("/group/{groupId}") + public Result> listTasksByGroup(@PathVariable Integer groupId) { + List tasks = taskService.listTasksByGroup(groupId); + return Result.success(tasks); + } } diff --git a/server/src/main/java/com/groupshell/mapper/ChatGPTHistoryMapper.java b/server/src/main/java/com/groupshell/mapper/ChatGPTHistoryMapper.java new file mode 100644 index 0000000..61d32f6 --- /dev/null +++ b/server/src/main/java/com/groupshell/mapper/ChatGPTHistoryMapper.java @@ -0,0 +1,13 @@ +//package com.groupshell.mapper; +// +// +//import com.groupshell.entity.chatgpt.ChatGPTHistory; +//import org.apache.ibatis.annotations.Mapper; +// +//import java.util.List; +// +//@Mapper +//public interface ChatGPTHistoryMapper { +// void insertChatHistory(ChatGPTHistory chatHistory); +// List findAllChatHistories(); +//} diff --git a/server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java b/server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java deleted file mode 100644 index d5d0785..0000000 --- a/server/src/main/java/com/groupshell/mapper/ChatGPTMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.groupshell.mapper; - - -import com.groupshell.entity.chatgpt.ChatGPTHistory; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface ChatGPTHistoryMapper { - void insertChatHistory(ChatGPTHistory chatHistory); - List findAllChatHistories(); -} diff --git a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java index 95b3912..190e7cf 100644 --- a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java +++ b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java @@ -17,6 +17,7 @@ public interface InvoiceMapper extends BaseMapper { //Invoice insert(Invoice record); Invoice findById(@Param("id") Integer id); + Invoice findByUserId(@Param("userId") Integer userId); List findAllInvoice(); diff --git a/server/src/main/java/com/groupshell/mapper/TaskMapper.java b/server/src/main/java/com/groupshell/mapper/TaskMapper.java index 6c3a37e..7746662 100644 --- a/server/src/main/java/com/groupshell/mapper/TaskMapper.java +++ b/server/src/main/java/com/groupshell/mapper/TaskMapper.java @@ -22,4 +22,6 @@ public interface TaskMapper extends BaseMapper List findTasksByCreatorId(@Param("creatorId") Integer creatorId); List findTasksByStatus(@Param("status") TaskStatusEnum status); + + List findTasksByGroupId(@Param("groupId") Integer groupId); } \ No newline at end of file diff --git a/server/src/main/java/com/groupshell/service/ChatGPTService.java b/server/src/main/java/com/groupshell/service/ChatGPTService.java index 5f9a31d..28154aa 100644 --- a/server/src/main/java/com/groupshell/service/ChatGPTService.java +++ b/server/src/main/java/com/groupshell/service/ChatGPTService.java @@ -1,15 +1,15 @@ -package com.groupshell.service; - -import com.baomidou.mybatisplus.extension.service.IService; -import com.groupshell.entity.chatgpt.CustomChatGPT; -import org.springframework.stereotype.Service; - -import java.io.IOException; - -//extends IService -@Service -public interface ChatGPTService { - - public String getResponseFromOpenAi(String userInput) throws IOException; - -} +//package com.groupshell.service; +// +//import com.baomidou.mybatisplus.extension.service.IService; +//import com.groupshell.entity.chatgpt.CustomChatGPT; +//import org.springframework.stereotype.Service; +// +//import java.io.IOException; +// +////extends IService +//@Service +//public interface ChatGPTService { +// +// public String getResponseFromOpenAi(String userInput) throws IOException; +// +//} diff --git a/server/src/main/java/com/groupshell/service/InvoiceService.java b/server/src/main/java/com/groupshell/service/InvoiceService.java index bab77af..ac86d6a 100644 --- a/server/src/main/java/com/groupshell/service/InvoiceService.java +++ b/server/src/main/java/com/groupshell/service/InvoiceService.java @@ -11,34 +11,35 @@ import java.time.LocalDateTime; import java.util.List; import java.util.Map; -@Service -public interface InvoiceService extends IService { - - public int addInvoice(Invoice record); - - public Invoice getInvoiceById(Integer id); - - public List getAllInvoices(); - - public Invoice updateInvoice(Invoice record); - - public String deleteInvoice(Integer id); - - public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end); - BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end); - - BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end); - - Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end); - - Invoice updateReimburseStatus(Integer id, ReimburseStatusEnum status); - - List findInvoicesByReimburseStatus(ReimburseStatusEnum status); - - BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end); +public interface InvoiceService extends IService { - List findReimburseByUserId(Integer userId); + //public int addInvoice(Invoice record); + + //public Invoice getInvoiceById(Integer id); +// public Invoice getInvoiceByUserId(Integer userId); +// +// public List getAllInvoices(); +// +// public Invoice updateInvoice(Invoice record); +// +// public String deleteInvoice(Integer id); + +// public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end); +// +// BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end); +// +// BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end); +// +// Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end); +// +// Invoice updateReimburseStatus(Integer id, ReimburseStatusEnum status); +// +// List findInvoicesByReimburseStatus(ReimburseStatusEnum status); +// +// BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end); +// +// List findReimburseByUserId(Integer userId); void exportInvoiceData(HttpServletResponse response); } diff --git a/server/src/main/java/com/groupshell/service/TaskService.java b/server/src/main/java/com/groupshell/service/TaskService.java index 1d2cf16..c8a8730 100644 --- a/server/src/main/java/com/groupshell/service/TaskService.java +++ b/server/src/main/java/com/groupshell/service/TaskService.java @@ -19,4 +19,6 @@ public interface TaskService extends IService List listTasksByAssignee(Integer assigneeId); List listTasksByStatus(TaskStatusEnum status); + + List listTasksByGroup(Integer groupId); } diff --git a/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java index 6606d28..5a0a479 100644 --- a/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java @@ -1,29 +1,34 @@ -package com.groupshell.service.impl; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.groupshell.entity.Invoice; -import com.groupshell.entity.chatgpt.CustomChatGPT; -import com.groupshell.mapper.InvoiceMapper; -import com.groupshell.service.ChatGPTService; -import com.unfbx.chatgpt.entity.chat.ChatCompletion; -import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; -import com.unfbx.chatgpt.entity.chat.Message; -import org.springframework.beans.factory.annotation.Autowired; - -import java.io.IOException; -import java.util.Collections; - -//extends ServiceImpl<...Mapper, ...> -public class ChatGPTServiceImpl implements ChatGPTService { - - @Autowired - private CustomChatGPT customChatGPT; - @Override - public String getResponseFromOpenAi(String userInput) throws IOException { - ChatCompletion chatCompletion = ChatCompletion.builder() - .messages(Collections.singletonList(Message.builder().content(userInput).build())) - .build(); - ChatCompletionResponse response = customChatGPT.getChatGPTConfig().getChatCompletion(); - return response.getChoices().get(0).getMessage().getContent(); - } -} +//package com.groupshell.service.impl; +// +//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +//import com.groupshell.entity.Invoice; +//import com.groupshell.entity.chatgpt.CustomChatGPT; +//import com.groupshell.mapper.InvoiceMapper; +//import com.groupshell.service.ChatGPTService; +//import com.unfbx.chatgpt.entity.chat.ChatCompletion; +//import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse; +//import com.unfbx.chatgpt.entity.chat.Message; +//import org.springframework.beans.factory.annotation.Autowired; +// +//import java.io.IOException; +//import java.util.Collections; +// +////extends ServiceImpl<...Mapper, ...> +//public class ChatGPTServiceImpl implements ChatGPTService { +// +// @Autowired +// private CustomChatGPT customChatGPT; +// +// @Override +// public String getResponseFromOpenAi(String userInput) throws IOException { +// return null; +// } +//// @Override +//// public String getResponseFromOpenAi(String userInput) throws IOException { +//// ChatCompletion chatCompletion = ChatCompletion.builder() +//// .messages(Collections.singletonList(Message.builder().content(userInput).build())) +//// .build(); +//// ChatCompletionResponse response = customChatGPT.getChatGPTConfig().getChatCompletion(); +//// return response.getChoices().get(0).getMessage().getContent(); +//// } +//} diff --git a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java index 08f1526..9e7e022 100644 --- a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java @@ -1,10 +1,13 @@ package com.groupshell.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.groupshell.entity.Group; import com.groupshell.entity.Invoice; import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; +import com.groupshell.mapper.GroupMapper; import com.groupshell.mapper.InvoiceMapper; +import com.groupshell.mapper.TaskMapper; import com.groupshell.service.InvoiceService; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; @@ -27,86 +30,94 @@ import java.util.stream.Collectors; @Service public class InvoiceServiceImpl extends ServiceImpl implements InvoiceService { - @Autowired - private InvoiceMapper invoiceMapper; - - @Override - public int addInvoice(Invoice record) { - return invoiceMapper.insert(record); - } - - @Override - public Invoice getInvoiceById(Integer id) { - return invoiceMapper.findById(id); - } - - @Override - public List getAllInvoices() { - return invoiceMapper.findAllInvoice(); - } - - @Override - public Invoice updateInvoice(Invoice record) { - return invoiceMapper.updateInvoiceById(record); - } - - @Override - public String deleteInvoice(Integer id) { - invoiceMapper.deleteById(id); - return "Record deleted successfully!"; - } - - //TODO:实现Controller类的函数 - @Override - public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end) { - return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); - } - - @Override - public BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end) { - return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); - } - - @Override - public BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end) { - BigDecimal income = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); - BigDecimal expenses = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); - return income.subtract(expenses); - } - - - //从数据库查询特定类别和时间范围内的发票,然后计算每个类别的总金额,并以Map形式返回结果 - @Override - public Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end) { - List records = invoiceMapper.findByCategoryAndDate(category, start, end); - return records.stream().collect(Collectors.groupingBy(Invoice::getCategory, - Collectors.reducing(BigDecimal.ZERO, Invoice::getAmount, BigDecimal::add))); - } - - // 新增方法:更新报销状态 - public Invoice updateReimburseStatus(Integer invoiceId, ReimburseStatusEnum status) { - Invoice invoice = invoiceMapper.findById(invoiceId); - if (invoice != null) { - invoice.setReimburseStatus(status); - invoiceMapper.updateInvoiceById(invoice); - } - return invoice; - } - - // 新增方法:查询特定报销状态的账单 - public List findInvoicesByReimburseStatus(ReimburseStatusEnum status) { - return invoiceMapper.findByReimburseStatus(status); - } - - // 新增方法:统计特定时间段内的报销金额 - public BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end) { - return invoiceMapper.sumReimburseAmountByDate(start, end); - } - - // 新增方法:查询特定用户的报销历史 - public List findReimburseByUserId(Integer userId) { - return invoiceMapper.findReimbursementsByUserId(userId); - } +// @Autowired +// private final InvoiceMapper invoiceMapper; +// public InvoiceServiceImpl(InvoiceMapper invoiceMapper) { +// this.invoiceMapper=invoiceMapper; +// } + +// @Override +// public int addInvoice(Invoice record) { +// return invoiceMapper.insert(record); +// } + +// @Override +// public Invoice getInvoiceById(Integer id) { +// return invoiceMapper.findById(id); +// } + +// @Override +// public Invoice getInvoiceByUserId(Integer userId) { +// return invoiceMapper.findByUserId(userId); +// } +// +// @Override +// public List getAllInvoices() { +// return invoiceMapper.findAllInvoice(); +// } +// +// @Override +// public Invoice updateInvoice(Invoice record) { +// return invoiceMapper.updateInvoiceById(record); +// } +// +// @Override +// public String deleteInvoice(Integer id) { +// invoiceMapper.deleteById(id); +// return "Record deleted successfully!"; +// } + +// //TODO:实现Controller类的函数 +// @Override +// public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end) { +// return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); +// } +// +// @Override +// public BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end) { +// return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); +// } +// +// @Override +// public BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end) { +// BigDecimal income = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); +// BigDecimal expenses = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); +// return income.subtract(expenses); +// } +// +// +// //从数据库查询特定类别和时间范围内的发票,然后计算每个类别的总金额,并以Map形式返回结果 +// @Override +// public Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end) { +// List records = invoiceMapper.findByCategoryAndDate(category, start, end); +// return records.stream().collect(Collectors.groupingBy(Invoice::getCategory, +// Collectors.reducing(BigDecimal.ZERO, Invoice::getAmount, BigDecimal::add))); +// } +// +// // 新增方法:更新报销状态 +// public Invoice updateReimburseStatus(Integer invoiceId, ReimburseStatusEnum status) { +// Invoice invoice = invoiceMapper.findById(invoiceId); +// if (invoice != null) { +// invoice.setReimburseStatus(status); +// invoiceMapper.updateInvoiceById(invoice); +// } +// return invoice; +// } +// +// // 新增方法:查询特定报销状态的账单 +// public List findInvoicesByReimburseStatus(ReimburseStatusEnum status) { +// return invoiceMapper.findByReimburseStatus(status); +// } +// +// // 新增方法:统计特定时间段内的报销金额 +// public BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end) { +// return invoiceMapper.sumReimburseAmountByDate(start, end); +// } +// +// // 新增方法:查询特定用户的报销历史 +// public List findReimburseByUserId(Integer userId) { +// return invoiceMapper.findReimbursementsByUserId(userId); +// } //todo 导出某团队的账单数据 @Override public void exportInvoiceData(HttpServletResponse response) diff --git a/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java index 3549b62..320eda4 100644 --- a/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/TaskServiceImpl.java @@ -15,7 +15,9 @@ import java.util.List; public class TaskServiceImpl extends ServiceImpl implements TaskService { private final TaskMapper taskMapper; - public TaskServiceImpl(TaskMapper taskMapper) {this.taskMapper=taskMapper;} + public TaskServiceImpl(TaskMapper taskMapper) { + this.taskMapper=taskMapper; + } @Override public Task createTask(Task task) { @@ -51,4 +53,10 @@ public class TaskServiceImpl extends ServiceImpl implements Tas { return taskMapper.findTasksByStatus(status); } + + @Override + public List listTasksByGroup(Integer groupId) + { + return taskMapper.findTasksByGroupId(groupId); + } } diff --git a/server/src/main/resources/mapper/InvoiceMapper.xml b/server/src/main/resources/mapper/InvoiceMapper.xml index 2f95c44..a1c28eb 100644 --- a/server/src/main/resources/mapper/InvoiceMapper.xml +++ b/server/src/main/resources/mapper/InvoiceMapper.xml @@ -1,130 +1,137 @@ - + - - id, amount, type, description, category, created_time, user_id, pay_method, - reimburse_status, reimburse_request_time, reimburse_complete_time, - approver_id, reimburse_notes - - - #{id}, - #{amount}, - #{type}, - #{description}, - #{category}, - #{createdTime}, - #{userId}, - #{payMethod}, - #{reimburseStatus}, - #{reimburseRequestTime}, - #{reimburseCompleteTime}, - #{approverId}, - #{reimburseNotes} - + + + + + + + + + + + + + + + + + + + + + - - INSERT INTO invoice () - VALUES () - + + + + - + + + + + - + + + + + - - UPDATE invoice - - - amount = #{amount}, - - - type = #{type}, - - - description = #{description}, - - - category = #{category}, - - - created_time = #{createdTime}, - - - user_id = #{userId}, - - - pay_method = #{payMethod}, - - - reimburse_status = #{reimburseStatus}, - - - reimburse_request_time = #{reimburseRequestTime}, - - - reimburse_complete_time = #{reimburseCompleteTime}, - - - approver_id = #{approverId}, - - - reimburse_notes = #{reimburseNotes}, - - - WHERE id = #{id} - + + + + - - DELETE - FROM invoice - WHERE id = #{id} - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + - + + + + + + - - + + + + + + - - + + + + + + + - - + + + + + + + - + + + + + + + + + + diff --git a/server/src/main/resources/mapper/TaskMapper.xml b/server/src/main/resources/mapper/TaskMapper.xml index d45423e..ea77819 100644 --- a/server/src/main/resources/mapper/TaskMapper.xml +++ b/server/src/main/resources/mapper/TaskMapper.xml @@ -104,4 +104,11 @@ WHERE status = #{status} + + + -- Gitee From 65e98bde2b5186be518111bf790e1f3fea7cef70 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Fri, 26 Apr 2024 14:07:14 +0800 Subject: [PATCH 07/10] =?UTF-8?q?Invoice=E7=B1=BB=E7=9A=84MyBatisPlus?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=87=BA=E9=94=99=5F2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../groupshell/controller/InvoiceCtrl.java | 10 +- .../com/groupshell/mapper/InvoiceMapper.java | 9 +- .../groupshell/service/InvoiceService.java | 46 ++-- .../service/impl/InvoiceServiceImpl.java | 125 +++++----- .../main/resources/mapper/InvoiceMapper.xml | 231 +++++++++--------- 5 files changed, 214 insertions(+), 207 deletions(-) diff --git a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java index a1a6838..d9d99a4 100644 --- a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java +++ b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java @@ -28,33 +28,33 @@ public class InvoiceCtrl @PostMapping public Result addInvoice(@RequestBody Invoice record) { - invoiceService.addInvoice(record); + invoiceService.save(record); return Result.success(); } // 根据ID获取发票信息 @GetMapping("/{id}") public Result getInvoiceById(@PathVariable Integer id) { - Invoice invoice=invoiceService.getInvoiceById(id); + Invoice invoice=invoiceService.getById(id); return Result.success(invoice); } @GetMapping public Result> getAllInvoices() { - List invoices=invoiceService.getAllInvoices(); + List invoices=invoiceService.listObjs(); return Result.success(invoices); } //没必要另传id,id直接写在record的id字段里面 @PutMapping public Result updateInvoice(@RequestBody Invoice record) { - invoiceService.updateInvoice(record); + invoiceService.updateById(record); return Result.success(); } @DeleteMapping("/{id}") public Result deleteInvoice(@PathVariable Integer id) { - invoiceService.deleteInvoice(id); + invoiceService.removeById(id); return Result.success(); } // 获取指定时间段内的总支出 diff --git a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java index 190e7cf..91acdba 100644 --- a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java +++ b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java @@ -16,14 +16,14 @@ import java.util.List; public interface InvoiceMapper extends BaseMapper { //Invoice insert(Invoice record); - Invoice findById(@Param("id") Integer id); + //Invoice findById(@Param("id") Integer id); Invoice findByUserId(@Param("userId") Integer userId); - List findAllInvoice(); + //List findAllInvoice(); - Invoice updateInvoiceById(Invoice record); + //Invoice updateInvoiceById(Invoice record); - String deleteById(@Param("id") Integer id); + //String deleteById(@Param("id") Integer id); BigDecimal sumAmountByDate(@Param("type") InvoiceTypeEnum type, @Param("start") LocalDateTime start, @@ -39,4 +39,5 @@ public interface InvoiceMapper extends BaseMapper { BigDecimal sumReimburseAmountByDate(LocalDateTime start, LocalDateTime end); List findReimbursementsByUserId(Integer userId); + List findReimbursementsByGroupId(Integer groupId); } diff --git a/server/src/main/java/com/groupshell/service/InvoiceService.java b/server/src/main/java/com/groupshell/service/InvoiceService.java index ac86d6a..6c154a3 100644 --- a/server/src/main/java/com/groupshell/service/InvoiceService.java +++ b/server/src/main/java/com/groupshell/service/InvoiceService.java @@ -17,29 +17,29 @@ public interface InvoiceService extends IService { //public int addInvoice(Invoice record); //public Invoice getInvoiceById(Integer id); -// public Invoice getInvoiceByUserId(Integer userId); -// -// public List getAllInvoices(); -// -// public Invoice updateInvoice(Invoice record); -// -// public String deleteInvoice(Integer id); - -// public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end); -// -// BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end); -// -// BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end); -// -// Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end); -// -// Invoice updateReimburseStatus(Integer id, ReimburseStatusEnum status); -// -// List findInvoicesByReimburseStatus(ReimburseStatusEnum status); -// -// BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end); -// -// List findReimburseByUserId(Integer userId); + public Invoice getInvoiceByUserId(Integer userId); + + //public List getAllInvoices(); + + //public Invoice updateInvoice(Invoice record); + + //public String deleteInvoice(Integer id); + + public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end); + + BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end); + + BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end); + + Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end); + + Invoice updateReimburseStatus(Integer id, ReimburseStatusEnum status); + + List findInvoicesByReimburseStatus(ReimburseStatusEnum status); + + BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end); + + List findReimburseByUserId(Integer userId); void exportInvoiceData(HttpServletResponse response); } diff --git a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java index 9e7e022..f91d569 100644 --- a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java @@ -1,13 +1,10 @@ package com.groupshell.service.impl; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.groupshell.entity.Group; import com.groupshell.entity.Invoice; import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; -import com.groupshell.mapper.GroupMapper; import com.groupshell.mapper.InvoiceMapper; -import com.groupshell.mapper.TaskMapper; import com.groupshell.service.InvoiceService; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; @@ -30,11 +27,11 @@ import java.util.stream.Collectors; @Service public class InvoiceServiceImpl extends ServiceImpl implements InvoiceService { -// @Autowired -// private final InvoiceMapper invoiceMapper; -// public InvoiceServiceImpl(InvoiceMapper invoiceMapper) { -// this.invoiceMapper=invoiceMapper; -// } + //@Autowired + private final InvoiceMapper invoiceMapper; + public InvoiceServiceImpl(InvoiceMapper invoiceMapper) { + this.invoiceMapper=invoiceMapper; + } // @Override // public int addInvoice(Invoice record) { @@ -46,11 +43,11 @@ public class InvoiceServiceImpl extends ServiceImpl impl // return invoiceMapper.findById(id); // } -// @Override -// public Invoice getInvoiceByUserId(Integer userId) { -// return invoiceMapper.findByUserId(userId); -// } -// + @Override + public Invoice getInvoiceByUserId(Integer userId) { + return invoiceMapper.findByUserId(userId); + } + // @Override // public List getAllInvoices() { // return invoiceMapper.findAllInvoice(); @@ -67,57 +64,57 @@ public class InvoiceServiceImpl extends ServiceImpl impl // return "Record deleted successfully!"; // } -// //TODO:实现Controller类的函数 -// @Override -// public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end) { -// return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); -// } -// -// @Override -// public BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end) { -// return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); -// } -// -// @Override -// public BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end) { -// BigDecimal income = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); -// BigDecimal expenses = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); -// return income.subtract(expenses); -// } -// -// -// //从数据库查询特定类别和时间范围内的发票,然后计算每个类别的总金额,并以Map形式返回结果 -// @Override -// public Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end) { -// List records = invoiceMapper.findByCategoryAndDate(category, start, end); -// return records.stream().collect(Collectors.groupingBy(Invoice::getCategory, -// Collectors.reducing(BigDecimal.ZERO, Invoice::getAmount, BigDecimal::add))); -// } -// -// // 新增方法:更新报销状态 -// public Invoice updateReimburseStatus(Integer invoiceId, ReimburseStatusEnum status) { -// Invoice invoice = invoiceMapper.findById(invoiceId); -// if (invoice != null) { -// invoice.setReimburseStatus(status); -// invoiceMapper.updateInvoiceById(invoice); -// } -// return invoice; -// } -// -// // 新增方法:查询特定报销状态的账单 -// public List findInvoicesByReimburseStatus(ReimburseStatusEnum status) { -// return invoiceMapper.findByReimburseStatus(status); -// } -// -// // 新增方法:统计特定时间段内的报销金额 -// public BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end) { -// return invoiceMapper.sumReimburseAmountByDate(start, end); -// } -// -// // 新增方法:查询特定用户的报销历史 -// public List findReimburseByUserId(Integer userId) { -// return invoiceMapper.findReimbursementsByUserId(userId); -// } + //TODO:实现Controller类的函数 + @Override + public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end) { + return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); + } + + @Override + public BigDecimal getIncomesByTime(LocalDateTime start, LocalDateTime end) { + return invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); + } + + @Override + public BigDecimal getNetIncomeByTime(LocalDateTime start, LocalDateTime end) { + BigDecimal income = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.INCOME, start, end); + BigDecimal expenses = invoiceMapper.sumAmountByDate(InvoiceTypeEnum.EXPENSE, start, end); + return income.subtract(expenses); + } + + + //从数据库查询特定类别和时间范围内的发票,然后计算每个类别的总金额,并以Map形式返回结果 + @Override + public Map getExpensesByCategory(String category, LocalDateTime start, LocalDateTime end) { + List records = invoiceMapper.findByCategoryAndDate(category, start, end); + return records.stream().collect(Collectors.groupingBy(Invoice::getCategory, + Collectors.reducing(BigDecimal.ZERO, Invoice::getAmount, BigDecimal::add))); + } + + // 新增方法:更新报销状态 + public Invoice updateReimburseStatus(Integer invoiceId, ReimburseStatusEnum status) { + Invoice invoice = invoiceMapper.findById(invoiceId); + if (invoice != null) { + invoice.setReimburseStatus(status); + invoiceMapper.updateInvoiceById(invoice); + } + return invoice; + } + + // 新增方法:查询特定报销状态的账单 + public List findInvoicesByReimburseStatus(ReimburseStatusEnum status) { + return invoiceMapper.findByReimburseStatus(status); + } + + // 新增方法:统计特定时间段内的报销金额 + public BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end) { + return invoiceMapper.sumReimburseAmountByDate(start, end); + } + + // 新增方法:查询特定用户的报销历史 + public List findReimburseByUserId(Integer userId) { + return invoiceMapper.findReimbursementsByUserId(userId); + } //todo 导出某团队的账单数据 @Override public void exportInvoiceData(HttpServletResponse response) diff --git a/server/src/main/resources/mapper/InvoiceMapper.xml b/server/src/main/resources/mapper/InvoiceMapper.xml index a1c28eb..eb29361 100644 --- a/server/src/main/resources/mapper/InvoiceMapper.xml +++ b/server/src/main/resources/mapper/InvoiceMapper.xml @@ -2,32 +2,32 @@ - - - - - - - - - - - - - - - - - - - - - + + id, amount, type, description, category, created_time, user_id, pay_method, + reimburse_status, reimburse_request_time, reimburse_complete_time, + approver_id, reimburse_notes, group_id + + + #{id}, + #{amount}, + #{type}, + #{description}, + #{category}, + #{createdTime}, + #{userId}, + #{payMethod}, + #{reimburseStatus}, + #{reimburseRequestTime}, + #{reimburseCompleteTime}, + #{approverId}, + #{reimburseNotes} + #{groupId} + - - - - + + + + @@ -35,103 +35,112 @@ - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + UPDATE invoice + + + amount = #{amount}, + + + type = #{type}, + + + description = #{description}, + + + category = #{category}, + + + created_time = #{createdTime}, + + + user_id = #{userId}, + + + pay_method = #{payMethod}, + + + reimburse_status = #{reimburseStatus}, + + + reimburse_request_time = #{reimburseRequestTime}, + + + reimburse_complete_time = #{reimburseCompleteTime}, + + + approver_id = #{approverId}, + + + reimburse_notes = #{reimburseNotes}, + + + WHERE id = #{id} + + + + + - + - - - - - + - - - - - - + - - - - - - + + - - - - - - - + + - - - - - - - + + - - - - - - - - + + - + -- Gitee From 47c475039287483e9a2fdee2655fd4586bc0053e Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Mon, 29 Apr 2024 15:19:12 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DTaskMapper=E7=9A=84Bug?= =?UTF-8?q?=EF=BC=8Ccreate->created=EF=BC=8Cupdate->updated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/mapper/TaskMapper.xml | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/server/src/main/resources/mapper/TaskMapper.xml b/server/src/main/resources/mapper/TaskMapper.xml index ea77819..97d78db 100644 --- a/server/src/main/resources/mapper/TaskMapper.xml +++ b/server/src/main/resources/mapper/TaskMapper.xml @@ -3,7 +3,7 @@ - id, title, description,create_time, update_time,start_time, deadline, assignee_id, creator_id, priority, status + id, title, description,created_time, updated_time,start_time, deadline, assignee_id, creator_id, priority, status, group_id id, title, description, - create_time, - update_time, + created_time, + updated_time, start_time, deadline, assignee_id, creator_id, priority, status, + group_id, #{id}, #{title}, #{description}, - #{createdTime}, - #{updatedTime}, + #{createdTime}, + #{updatedTime}, #{startTime}, #{deadline}, #{assigneeId}, #{creatorId}, #{priority}, #{status}, + #{groupId}, @@ -47,17 +49,16 @@ description = #{description}, - - create_time = #{createdTime}, + + created_time = #{createdTime}, - - update_time = #{updatedTime}, + + updated_time = #{updatedTime}, start_time = #{startTime}, - deadline = #{deadline}, @@ -72,6 +73,9 @@ status = #{status}, + + group_id = #{groupId}, + WHERE id = #{id} -- Gitee From 6bbd0050431927948bef623f93ae5aacbe4fb572 Mon Sep 17 00:00:00 2001 From: EricCheng <12955029+ericchengscut@user.noreply.gitee.com> Date: Mon, 29 Apr 2024 16:20:02 +0800 Subject: [PATCH 09/10] =?UTF-8?q?Invoice=E7=9B=B8=E5=85=B3=E7=B1=BB?= =?UTF-8?q?=E8=A7=A3=E9=99=A4MyBatisPlus=E7=9B=B8=E5=85=B3=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- server/pom.xml | 8 +- .../groupshell/controller/InvoiceCtrl.java | 200 +++++++++--------- .../com/groupshell/mapper/InvoiceMapper.java | 12 +- .../groupshell/service/InvoiceService.java | 13 +- .../service/impl/InvoiceServiceImpl.java | 51 ++--- .../main/resources/mapper/InvoiceMapper.xml | 36 ++-- 7 files changed, 164 insertions(+), 158 deletions(-) diff --git a/pom.xml b/pom.xml index 23bc68d..5fdaf51 100644 --- a/pom.xml +++ b/pom.xml @@ -35,4 +35,4 @@ - + \ No newline at end of file diff --git a/server/pom.xml b/server/pom.xml index 6f80198..742baab 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -32,6 +32,12 @@ mybatis-plus-spring-boot3-starter 3.5.5 + + + com.baomidou + mybatis-plus-boot-starter + 3.1.0 + org.springframework.boot @@ -128,4 +134,4 @@ - + \ No newline at end of file diff --git a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java index d9d99a4..105cdfd 100644 --- a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java +++ b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java @@ -20,106 +20,106 @@ import java.util.Map; @RequestMapping("/api/invoice") public class InvoiceCtrl { - @Autowired - private InvoiceService invoiceService; -// public InvoiceCtrl(InvoiceService invoiceService) { + @Autowired + private InvoiceService invoiceService; + // public InvoiceCtrl(InvoiceService invoiceService) { // this.invoiceService=invoiceService; // } - @PostMapping - public Result addInvoice(@RequestBody Invoice record) - { - invoiceService.save(record); - return Result.success(); - } - // 根据ID获取发票信息 - @GetMapping("/{id}") - public Result getInvoiceById(@PathVariable Integer id) - { - Invoice invoice=invoiceService.getById(id); - return Result.success(invoice); - } - @GetMapping - public Result> getAllInvoices() - { - List invoices=invoiceService.listObjs(); - return Result.success(invoices); - } - //没必要另传id,id直接写在record的id字段里面 - @PutMapping - public Result updateInvoice(@RequestBody Invoice record) - { - invoiceService.updateById(record); - return Result.success(); - } - @DeleteMapping("/{id}") - public Result deleteInvoice(@PathVariable Integer id) - { - invoiceService.removeById(id); - return Result.success(); - } - // 获取指定时间段内的总支出 - @GetMapping("/expenses") - public Result getExpensesByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) - { - BigDecimal expense=invoiceService.getExpensesByTime(start,end); - return Result.success(expense); - } - // 获取指定时间段内的总收入 - @GetMapping("/incomes") - public Result getIncomesByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) - { - BigDecimal income=invoiceService.getIncomesByTime(start,end); - return Result.success(income); - } - // 获取指定时间段内的净收入 - @GetMapping("/netIncome") - public Result getNetIncomeByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) - { - BigDecimal netIncome=invoiceService.getNetIncomeByTime(start,end); - return Result.success(netIncome); - } - // 获取指定类别和时间段内的支出汇总 - @GetMapping("/expensesByCategory") - public Result> getExpensesByCategory(@RequestParam String category, - @RequestParam LocalDateTime start,@RequestParam LocalDateTime end) - { - Map expense=invoiceService.getExpensesByCategory(category,start,end); - return Result.success(expense); - } - // 更新发票的报销状态 - @PutMapping("/{id}/reimburse") - public Result updateReimburseStatus(@PathVariable Integer id,@RequestParam ReimburseStatusEnum status) - { - invoiceService.updateReimburseStatus(id,status); - return Result.success(Boolean.TRUE); - } - // 根据报销状态查询发票 - @GetMapping("/reimburseStatus/{status}") - public Result> findInvoicesByReimbursementStatus(@PathVariable ReimburseStatusEnum status) - { - List invoices=invoiceService.findInvoicesByReimburseStatus(status); - return Result.success(invoices); - } - // 统计指定时间段内的报销金额 - @GetMapping("/reimburse/sum") - public Result sumReimbursementAmount(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) - { - BigDecimal amount=invoiceService.sumReimburseAmount(start,end); - return Result.success(amount); - } - // 查询特定用户的报销历史 - @GetMapping("/reimburse/user/{userId}") - public Result> findReimbursementsByUserId(@PathVariable Integer userId) - { - List invoices=invoiceService.findReimburseByUserId(userId); - return Result.success(invoices); - } - /** - * 导出运营数据报表 - */ - @GetMapping("/export") - public void export(HttpServletResponse response) - { - invoiceService.exportInvoiceData(response); - } + @PostMapping + public Result addInvoice(@RequestBody Invoice record) + { + invoiceService.addInvoice(record); + return Result.success(); + } + // 根据ID获取发票信息 + @GetMapping("/{id}") + public Result getInvoiceById(@PathVariable Integer id) + { + Invoice invoice=invoiceService.getInvoiceById(id); + return Result.success(invoice); + } + @GetMapping + public Result> getAllInvoices() + { + List invoices=invoiceService.getAllInvoices(); + return Result.success(invoices); + } + //没必要另传id,id直接写在record的id字段里面 + @PutMapping + public Result updateInvoice(@RequestBody Invoice record) + { + invoiceService.updateInvoice(record); + return Result.success(); + } + @DeleteMapping("/{id}") + public Result deleteInvoice(@PathVariable Integer id) + { + invoiceService.deleteInvoice(id); + return Result.success(); + } + // 获取指定时间段内的总支出 + @GetMapping("/expenses") + public Result getExpensesByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) + { + BigDecimal expense=invoiceService.getExpensesByTime(start,end); + return Result.success(expense); + } + // 获取指定时间段内的总收入 + @GetMapping("/incomes") + public Result getIncomesByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) + { + BigDecimal income=invoiceService.getIncomesByTime(start,end); + return Result.success(income); + } + // 获取指定时间段内的净收入 + @GetMapping("/netIncome") + public Result getNetIncomeByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) + { + BigDecimal netIncome=invoiceService.getNetIncomeByTime(start,end); + return Result.success(netIncome); + } + // 获取指定类别和时间段内的支出汇总 + @GetMapping("/expensesByCategory") + public Result> getExpensesByCategory(@RequestParam String category, + @RequestParam LocalDateTime start,@RequestParam LocalDateTime end) + { + Map expense=invoiceService.getExpensesByCategory(category,start,end); + return Result.success(expense); + } + // 更新发票的报销状态 + @PutMapping("/{id}/reimburse") + public Result updateReimburseStatus(@PathVariable Integer id,@RequestParam ReimburseStatusEnum status) + { + invoiceService.updateReimburseStatus(id,status); + return Result.success(Boolean.TRUE); + } + // 根据报销状态查询发票 + @GetMapping("/reimburseStatus/{status}") + public Result> findInvoicesByReimbursementStatus(@PathVariable ReimburseStatusEnum status) + { + List invoices=invoiceService.findInvoicesByReimburseStatus(status); + return Result.success(invoices); + } + // 统计指定时间段内的报销金额 + @GetMapping("/reimburse/sum") + public Result sumReimbursementAmount(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end) + { + BigDecimal amount=invoiceService.sumReimburseAmount(start,end); + return Result.success(amount); + } + // 查询特定用户的报销历史 + @GetMapping("/reimburse/user/{userId}") + public Result> findReimbursementsByUserId(@PathVariable Integer userId) + { + List invoices=invoiceService.findReimburseByUserId(userId); + return Result.success(invoices); + } + /** + * 导出运营数据报表 + */ + @GetMapping("/export") + public void export(HttpServletResponse response) + { + invoiceService.exportInvoiceData(response); + } } diff --git a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java index 91acdba..0f241f0 100644 --- a/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java +++ b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java @@ -13,17 +13,17 @@ import java.time.LocalTime; import java.util.List; @Mapper -public interface InvoiceMapper extends BaseMapper { - //Invoice insert(Invoice record); +public interface InvoiceMapper { + Invoice insert(Invoice record); - //Invoice findById(@Param("id") Integer id); + Invoice findById(@Param("id") Integer id); Invoice findByUserId(@Param("userId") Integer userId); - //List findAllInvoice(); + List findAllInvoice(); - //Invoice updateInvoiceById(Invoice record); + Invoice updateInvoiceById(Invoice record); - //String deleteById(@Param("id") Integer id); + String deleteById(@Param("id") Integer id); BigDecimal sumAmountByDate(@Param("type") InvoiceTypeEnum type, @Param("start") LocalDateTime start, diff --git a/server/src/main/java/com/groupshell/service/InvoiceService.java b/server/src/main/java/com/groupshell/service/InvoiceService.java index 6c154a3..292a831 100644 --- a/server/src/main/java/com/groupshell/service/InvoiceService.java +++ b/server/src/main/java/com/groupshell/service/InvoiceService.java @@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.groupshell.entity.Invoice; import com.groupshell.enumeration.ReimburseStatusEnum; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -12,18 +11,18 @@ import java.util.List; import java.util.Map; -public interface InvoiceService extends IService { +public interface InvoiceService { - //public int addInvoice(Invoice record); + public int addInvoice(Invoice record); - //public Invoice getInvoiceById(Integer id); + public Invoice getInvoiceById(Integer id); public Invoice getInvoiceByUserId(Integer userId); - //public List getAllInvoices(); + public List getAllInvoices(); - //public Invoice updateInvoice(Invoice record); + public Invoice updateInvoice(Invoice record); - //public String deleteInvoice(Integer id); + public String deleteInvoice(Integer id); public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end); diff --git a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java index f91d569..42e4d6e 100644 --- a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java +++ b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java @@ -1,10 +1,11 @@ package com.groupshell.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.groupshell.entity.Group; import com.groupshell.entity.Invoice; +import com.groupshell.mapper.InvoiceMapper; import com.groupshell.enumeration.InvoiceTypeEnum; import com.groupshell.enumeration.ReimburseStatusEnum; -import com.groupshell.mapper.InvoiceMapper; import com.groupshell.service.InvoiceService; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; @@ -25,7 +26,7 @@ import java.util.Map; import java.util.stream.Collectors; @Service -public class InvoiceServiceImpl extends ServiceImpl implements InvoiceService { +public class InvoiceServiceImpl implements InvoiceService { //@Autowired private final InvoiceMapper invoiceMapper; @@ -33,36 +34,36 @@ public class InvoiceServiceImpl extends ServiceImpl impl this.invoiceMapper=invoiceMapper; } -// @Override -// public int addInvoice(Invoice record) { -// return invoiceMapper.insert(record); -// } + @Override + public int addInvoice(Invoice record) { + return invoiceMapper.insert(record); + } -// @Override -// public Invoice getInvoiceById(Integer id) { -// return invoiceMapper.findById(id); -// } + @Override + public Invoice getInvoiceById(Integer id) { + return invoiceMapper.findById(id); + } @Override public Invoice getInvoiceByUserId(Integer userId) { return invoiceMapper.findByUserId(userId); } -// @Override -// public List getAllInvoices() { -// return invoiceMapper.findAllInvoice(); -// } -// -// @Override -// public Invoice updateInvoice(Invoice record) { -// return invoiceMapper.updateInvoiceById(record); -// } -// -// @Override -// public String deleteInvoice(Integer id) { -// invoiceMapper.deleteById(id); -// return "Record deleted successfully!"; -// } + @Override + public List getAllInvoices() { + return invoiceMapper.findAllInvoice(); + } + + @Override + public Invoice updateInvoice(Invoice record) { + return invoiceMapper.updateInvoiceById(record); + } + + @Override + public String deleteInvoice(Integer id) { + invoiceMapper.deleteById(id); + return "Record deleted successfully!"; + } //TODO:实现Controller类的函数 @Override diff --git a/server/src/main/resources/mapper/InvoiceMapper.xml b/server/src/main/resources/mapper/InvoiceMapper.xml index eb29361..23e4fdb 100644 --- a/server/src/main/resources/mapper/InvoiceMapper.xml +++ b/server/src/main/resources/mapper/InvoiceMapper.xml @@ -24,16 +24,16 @@ #{groupId} - - - - + + INSERT INTO invoice () + VALUES () + - - - - - + - - - - + UPDATE invoice @@ -89,11 +89,11 @@ WHERE id = #{id} - - - - - + + DELETE + FROM invoice + WHERE id = #{id} + - SELECT * - FROM invoice - WHERE id = #{id} - + + + + + - + + + + UPDATE invoice @@ -85,15 +85,18 @@ reimburse_notes = #{reimburseNotes}, + + group_id = #{groupId}, + WHERE id = #{id} - - DELETE - FROM invoice - WHERE id = #{id} - + + + + +