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 0000000000000000000000000000000000000000..31013fba02c8062916e668e1461a5b20faa23bb7
--- /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/pom.xml b/pojo/pom.xml
index ee66ef91d9d4ea0cf330b67f86715c1cc098e18c..49e2a84b01b9d6875a28953efde667f012efa888 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 26b166b2b59080b7b9e90edeeff0ebf8ed39f832..107eee1fd84f6022bfddf8e30430a2c070840009 100644
--- a/pojo/src/main/java/com/groupshell/entity/Invoice.java
+++ b/pojo/src/main/java/com/groupshell/entity/Invoice.java
@@ -1,9 +1,14 @@
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.*;
+import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@@ -18,20 +23,60 @@ import java.time.LocalDateTime;
@NoArgsConstructor
@AllArgsConstructor
@Builder
-public class Invoice
-{
+@TableName("invoice")
+public class Invoice implements Serializable {
+ /**
+ * The unique identifier for the invoice.
+ * 主键,自增
+ */
+ @TableId(value="id", type= IdType.AUTO)
private Integer id;
+
+ /**
+ * The amount of the invoice.
+ * 使用BigDecimal进行与财务相关的计算,避免出现浮点数运算误差
+ */
private BigDecimal amount;
- private InvoiceTypeEnum type;//EXPENSE,INCOME
+
+
+ private InvoiceTypeEnum type;
+ /**
+ * 非空
+ */
+
+ /**
+ * The description of the invoice.
+ */
private String description;
+
+ /**
+ * The category of the invoice.
+ */
private String category;
+
+ /**
+ * The date and time when the invoice was created.
+ */
private LocalDateTime createdTime;
+
+ //TODO:更新时间,更新人
+ /**
+ * The user ID associated with the invoice.
+ * 外键引用user表的id
+ */
private Integer userId; //账单创建人
+
private String payMethod; //支付方式
+
private ReimburseStatusEnum reimburseStatus;
+
private LocalDateTime reimburseRequestTime; // 报销申请时间
+
private LocalDateTime reimburseCompleteTime; // 报销完成时间
+
private Integer approverId; // 审批者ID
+
private String reimburseNotes; // 报销备注
- private Integer groupId;
+
+ private Integer groupId;
}
\ No newline at end of file
diff --git a/pojo/src/main/java/com/groupshell/entity/Task.java b/pojo/src/main/java/com/groupshell/entity/Task.java
index 68515dc5136fd3ddbe49a852de5155d0625df32b..e3745b3b893e909f5e4ad61654844f2e662d2c52 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/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 0000000000000000000000000000000000000000..9c5aea93ea722e324168b96d22889f08eda17228
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTConfig.java
@@ -0,0 +1,172 @@
+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;
+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;
+
+import static com.groupshell.constant.ChatGPTConstants.*;
+
+@Data
+@ToString
+@AllArgsConstructor
+@Builder
+public class ChatGPTConfig {
+
+ private OkHttpClient okHttpClient;
+ private OpenAiClient openAiClient; //阻塞
+ private OpenAiStreamClient openAiStreamClient; //非阻塞
+ private CustomEventSourceListener eventSourceListener;
+ private ChatCompletion chatCompletion;
+ private ChatCompletion.Model model;
+ private List messages;
+ private ChatCompletionResponse chatCompletionResponse; //暂时没用
+ private HttpLoggingInterceptor httpLoggingInterceptor;
+
+ public ChatGPTConfig(String customization) throws InterruptedException {
+ if (customization == OPENAI_CLIENT) {
+ initHttpLoggingInterceptor();
+ initOkHttpClient();
+ initOpenAiClient(); //初始化阻塞式客户端
+ initCustomEventSourceListener(new CustomEventSourceListener()); //初始化事件侦听器
+ initChatCompletion(customization);
+
+ //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() {
+ //日志拦截器
+ this.httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
+ //!!!!千万别再生产或者测试环境打开BODY级别日志!!!!
+ //!!!生产或者测试环境建议设置为这三种级别:NONE,BASIC,HEADERS,!!!
+ this.httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); //除了BODY,只有HEADERS才会返回带有会话信息的内容
+ }
+
+ public void initOkHttpClient() {
+ this.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 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))
+ .apiHost(GPT4_OPENAI_API_URL) //支持GPT4
+ .keyStrategy(new KeyRandomStrategy())
+ .okHttpClient(okHttpClient)
+ .build();
+ }
+
+
+ public void initCustomEventSourceListener(CustomEventSourceListener eventSourceListener) {
+ this.eventSourceListener = eventSourceListener;
+ }
+
+ 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);
+ }
+
+
+ /**
+ * 设置聊天完成的配置,根据不同参数类型执行不同逻辑。
+ *
+ * @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();
+
+ } 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());
+ }
+ }
+
+ 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/ChatGPTHistory.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTHistory.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e9a65f38941124a12ccba6ffe072affc9a7cf78
--- /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/ChatGPTMessageHandler.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..05f473aeb5d45372522a468cb5bf921cb663b268
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/ChatGPTMessageHandler.java
@@ -0,0 +1,81 @@
+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 responsesFomatted;
+
+
+
+
+ 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 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.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
new file mode 100644
index 0000000000000000000000000000000000000000..03b18880a7ffac531429f45a0820ae92fdc478d3
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomChatGPT.java
@@ -0,0 +1,133 @@
+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;
+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
+@Builder
+public class CustomChatGPT {
+
+ private List messages; //TODO:保存临时会话信息??
+ private ChatGPTConfig chatGPTConfig;
+ private String openAiClientType; //OpenAiClient或OpenAiStreamClient
+
+ //阻塞
+ public CustomChatGPT(String customization) throws InterruptedException {
+ chatGPTConfig = new ChatGPTConfig(customization);
+ openAiClientType = customization;
+ }
+
+
+ //把对话信息发送给GPT并让它回复
+ public void callCustomChatGPT() throws InterruptedException {
+ 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(); // 保留中断状态
+// }
+ }
+
+ 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);
+ 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();
+ }
+
+
+ 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 0000000000000000000000000000000000000000..2247a4fe06fd289c8a79d2b44778a02f5ca457bb
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/CustomEventSourceListener.java
@@ -0,0 +1,57 @@
+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;
+
+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连接...");
+ }
+
+ @Override
+ public void onEvent(EventSource eventSource, String id, String type, String data) {
+ //log.info("OpenAI返回数据:{}", data);
+ String response = messageHandler.responseHandler(data);
+ messageHandler.responses.add(response);
+ if (data.equals(CHATGPT_DONE)) {
+ log.info("OpenAI返回数据结束了");
+ messageHandler.printResponses();
+ //eventSource.request();
+ 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
new file mode 100644
index 0000000000000000000000000000000000000000..29537f52e0d9b4b20babbf7428e835503750b7fe
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGPT6.java
@@ -0,0 +1,18 @@
+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(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 277a83c283e11d6d985adf166e60cf7ef2a0a6c7..0000000000000000000000000000000000000000
--- 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();
- }
- }
-}
diff --git a/pom.xml b/pom.xml
index 23bc68d32167fe9d6590fcf0f023b7c8d071665d..5fdaf516bc31986ad5a2cb880f54a5b6f6735a36 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 6f801980d7f8b91b98c37c80c394b71513168e1e..742baab04ac1e2efe2f53982d3154d96c2b5b6df 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/ChatGPTCtrl.java b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1499db7d6e02b87013f96f37ac861939988d11d
--- /dev/null
+++ b/server/src/main/java/com/groupshell/controller/ChatGPTCtrl.java
@@ -0,0 +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/controller/InvoiceCtrl.java b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java
index 41424d35c64d9c78c72df0da92b2d5985124ab34..d9d99a4ea1cd1fe36fbac8f200cfc96c58491a42 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,38 +20,41 @@ 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)
{
- 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/controller/TaskCtrl.java b/server/src/main/java/com/groupshell/controller/TaskCtrl.java
index 5857a66474bb558beedc3c776bc522409f0b4362..db837eb79d099db5667a608ded17f56f6fe9182e 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 0000000000000000000000000000000000000000..61d32f62dbb5db13a005bfba7cf78efca1e3d046
--- /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/InvoiceMapper.java b/server/src/main/java/com/groupshell/mapper/InvoiceMapper.java
index 46274dbbbf6f4eb1872da2fdd30f1599847b5848..e6abc0adaad724518cce78114258066f2416ab10 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;
@@ -11,27 +12,31 @@ import java.time.LocalDateTime;
import java.util.List;
@Mapper
-public interface InvoiceMapper
-{
- Invoice insert(Invoice record);
-
- Invoice findById(@Param("id") Integer id);
-
- List findAllInvoice();
-
- Invoice updateInvoiceById(Invoice record);
-
- String deleteById(@Param("id") Integer id);
-
- BigDecimal sumAmountByDate(@Param("type") InvoiceTypeEnum type,@Param("start") LocalDateTime start,
- @Param("end") LocalDateTime end);
-
- List findByCategoryAndDate(@Param("category") String category,@Param("start") LocalDateTime start,@Param(
- "end") LocalDateTime end);
-
+public interface InvoiceMapper extends BaseMapper {
+ //Invoice insert(Invoice record);
+
+ //Invoice findById(@Param("id") Integer id);
+ Invoice findByUserId(@Param("userId") Integer userId);
+
+ //List findAllInvoice();
+
+ //Invoice updateInvoiceById(Invoice record);
+
+ //String deleteById(@Param("id") Integer id);
+
+ BigDecimal sumAmountByDate(@Param("type") InvoiceTypeEnum type,
+ @Param("start") LocalDateTime start,
+ @Param("end") LocalDateTime end);
+
+ List findByCategoryAndDate(@Param("category") String category,
+ @Param("start") LocalDateTime start,
+ @Param("end") LocalDateTime end);
+
+
List findByReimburseStatus(ReimburseStatusEnum status);
-
- BigDecimal sumReimburseAmountByDate(LocalDateTime start,LocalDateTime end);
-
+
+ BigDecimal sumReimburseAmountByDate(LocalDateTime start, LocalDateTime end);
+
List findReimbursementsByUserId(Integer userId);
+ List findReimbursementsByGroupId(Integer groupId);
}
diff --git a/server/src/main/java/com/groupshell/mapper/TaskMapper.java b/server/src/main/java/com/groupshell/mapper/TaskMapper.java
index e740ff7ff8cd1f0519ad0734b2bb589fcc03f274..77466623693c85961bf8b2ce5efcffcf09991285 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);
@@ -21,4 +22,6 @@ public interface TaskMapper
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
new file mode 100644
index 0000000000000000000000000000000000000000..28154aa3caab38a1fca28f8928d102c581658d98
--- /dev/null
+++ b/server/src/main/java/com/groupshell/service/ChatGPTService.java
@@ -0,0 +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;
+//
+//}
diff --git a/server/src/main/java/com/groupshell/service/InvoiceService.java b/server/src/main/java/com/groupshell/service/InvoiceService.java
index dfd63b59904fb0c11d8d7588a00f65a8cdc9a1b0..7e73354c7fdc65d3e6ada5ac7b9f54a4dd37a1bf 100644
--- a/server/src/main/java/com/groupshell/service/InvoiceService.java
+++ b/server/src/main/java/com/groupshell/service/InvoiceService.java
@@ -1,27 +1,28 @@
package com.groupshell.service;
+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;
import java.util.List;
import java.util.Map;
-@Service
-public interface InvoiceService {
- public Invoice addInvoice(Invoice record);
+public interface InvoiceService extends IService {
- public Invoice getInvoiceById(Integer id);
+ //public int addInvoice(Invoice record);
- public List getAllInvoices();
+ //public Invoice getInvoiceById(Integer id);
+ public Invoice getInvoiceByUserId(Integer userId);
- public Invoice updateInvoice(Invoice record);
+ //public List getAllInvoices();
- public String deleteInvoice(Integer id);
+ //public Invoice updateInvoice(Invoice record);
+
+ //public String deleteInvoice(Integer id);
public BigDecimal getExpensesByTime(LocalDateTime start, LocalDateTime end);
@@ -38,6 +39,6 @@ public interface InvoiceService {
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 c1a5c7741833b03cee2306446d2af69c23d64e5b..c8a873003c892119eb2e7ab76d64fe4352530b59 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);
@@ -18,4 +19,6 @@ public interface TaskService
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
new file mode 100644
index 0000000000000000000000000000000000000000..5a0a479a4d3ce13065654b8a82dcc1ba9798b6d2
--- /dev/null
+++ b/server/src/main/java/com/groupshell/service/impl/ChatGPTServiceImpl.java
@@ -0,0 +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 {
+// 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 d6007f08275c546639742254dc4e5f520ad04abe..f933139e78d09758abbe48cc10555718ab4fb347 100644
--- a/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java
+++ b/server/src/main/java/com/groupshell/service/impl/InvoiceServiceImpl.java
@@ -1,111 +1,109 @@
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;
import com.groupshell.mapper.InvoiceMapper;
import com.groupshell.service.InvoiceService;
-import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.io.IOException;
-import java.io.InputStream;
import java.math.BigDecimal;
-import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
-public class InvoiceServiceImpl implements InvoiceService
-{
- @Autowired
- private InvoiceMapper invoiceMapper;
- @Override
- public Invoice addInvoice(Invoice record)
- {
- return invoiceMapper.insert(record);
- }
- //TODO:实现Controller类的函数
- @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);
+public class InvoiceServiceImpl extends ServiceImpl implements InvoiceService {
+
+ //@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 String deleteInvoice(Integer id)
- {
- invoiceMapper.deleteById(id);
- return "Record deleted successfully!";
+ 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);
+ 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);
+ 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);
+ 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 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)
- {
+ public Invoice updateReimburseStatus(Integer invoiceId, ReimburseStatusEnum status) {
+ Invoice invoice = invoiceMapper.selectById(invoiceId);
+ if (invoice != null) {
invoice.setReimburseStatus(status);
- invoiceMapper.updateInvoiceById(invoice);
+ invoiceMapper.updateById(invoice);
}
return invoice;
}
+
// 新增方法:查询特定报销状态的账单
- public List findInvoicesByReimburseStatus(ReimburseStatusEnum status)
- {
+ public List findInvoicesByReimburseStatus(ReimburseStatusEnum status) {
return invoiceMapper.findByReimburseStatus(status);
}
+
// 新增方法:统计特定时间段内的报销金额
- public BigDecimal sumReimburseAmount(LocalDateTime start,LocalDateTime end)
- {
- return invoiceMapper.sumReimburseAmountByDate(start,end);
+ public BigDecimal sumReimburseAmount(LocalDateTime start, LocalDateTime end) {
+ return invoiceMapper.sumReimburseAmountByDate(start, end);
}
+
// 新增方法:查询特定用户的报销历史
- public List findReimburseByUserId(Integer userId)
- {
+ public List findReimburseByUserId(Integer userId) {
return invoiceMapper.findReimbursementsByUserId(userId);
}
//todo 导出某团队的账单数据
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 7b33165d6447f85c360ab09eb077288e9d60bdcb..320eda4d9996c11718c7b4d0b8348f3243c13627 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,10 +12,12 @@ 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;}
+ public TaskServiceImpl(TaskMapper taskMapper) {
+ this.taskMapper=taskMapper;
+ }
@Override
public Task createTask(Task task)
{
@@ -50,4 +53,10 @@ public class TaskServiceImpl implements TaskService
{
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 2f95c4400b56adc5d628c00a270b692e85e87be8..12eadefe5978ef579ee4f29b7742d9d496eaea24 100644
--- a/server/src/main/resources/mapper/InvoiceMapper.xml
+++ b/server/src/main/resources/mapper/InvoiceMapper.xml
@@ -1,11 +1,11 @@
-
+
id, amount, type, description, category, created_time, user_id, pay_method,
reimburse_status, reimburse_request_time, reimburse_complete_time,
- approver_id, reimburse_notes
+ approver_id, reimburse_notes, group_id
#{id},
@@ -21,24 +21,31 @@
#{reimburseCompleteTime},
#{approverId},
#{reimburseNotes}
+ #{groupId}
-
- INSERT INTO invoice ()
- VALUES ()
-
+
+
+
+
-
+
+
+
+
+
-
diff --git a/server/src/main/resources/mapper/TaskMapper.xml b/server/src/main/resources/mapper/TaskMapper.xml
index d45423ed2be946282170ce363162064e53b861aa..97d78db259a4db80ac593dd57ba2362931106e9d 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}
@@ -104,4 +108,11 @@
WHERE status = #{status}
+
+
+ SELECT *
+ FROM task
+ WHERE group_id = #{groupId}
+
+