diff --git a/common/src/main/java/com/groupshell/enumeration/ReimburseStatusEnum.java b/common/src/main/java/com/groupshell/enumeration/ReimburseStatusEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..9747fb95bb1689c2710611d3ebd9afaf5b2f835b
--- /dev/null
+++ b/common/src/main/java/com/groupshell/enumeration/ReimburseStatusEnum.java
@@ -0,0 +1,9 @@
+package com.groupshell.enumeration;
+
+public enum ReimburseStatusEnum {
+
+ NO_NEED, // 无需报销
+ PENDING, // 待报销
+ IN_PROCESS, // 报销中
+ REIMBURSED // 已报销
+}
diff --git a/pojo/pom.xml b/pojo/pom.xml
index 7b45bb2da16be7dad874c7a5a48468c8aa95e23b..ee66ef91d9d4ea0cf330b67f86715c1cc098e18c 100644
--- a/pojo/pom.xml
+++ b/pojo/pom.xml
@@ -27,6 +27,11 @@
lombok
provided
+
+ com.unfbx
+ chatgpt-java
+ 1.0.14-beta1
+
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 115fd0a77ead5c3c974afc5515d7a7fc425bfd5c..5a78e8f5bc72a043b796f6b4fc6448acc1a01c64 100644
--- a/pojo/src/main/java/com/groupshell/entity/Invoice.java
+++ b/pojo/src/main/java/com/groupshell/entity/Invoice.java
@@ -1,15 +1,13 @@
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;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
-import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@@ -23,39 +21,57 @@ import java.time.LocalDateTime;
@ToString
@NoArgsConstructor
@AllArgsConstructor
-@TableName("invoice")
-public class Invoice implements Serializable
-{
+public class Invoice {
/**
* 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;
/**
* 非空
*/
+
/**
* The description of the invoice.
*/
- private String description;
+ private String description; //TODO:description数据库字段类型改为TEXT?
+
/**
* 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 Integer userId; //账单创建人
+
+ private String payMethod; //支付方式
+
+ private ReimburseStatusEnum reimburseStatus;
+
+ private LocalDateTime reimburseRequestTime; // 报销申请时间
+
+ private LocalDateTime reimburseCompleteTime; // 报销完成时间
+
+ private Integer approverId; // 审批者ID
+
+ private String reimburseNotes; // 报销备注
+
}
\ No newline at end of file
diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/KeyRandomStrategy.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/KeyRandomStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..f17fc57c1f86292d66f1f050b59c856f1367d7f9
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/KeyRandomStrategy.java
@@ -0,0 +1,20 @@
+package com.groupshell.entity.chatgpt;
+
+import cn.hutool.core.util.RandomUtil;
+import com.unfbx.chatgpt.function.KeyStrategyFunction;
+
+import java.util.List;
+
+/**
+ * 描述:随机策略
+ *
+ * @author https:www.unfbx.com
+ * @since 2023-04-03
+ */
+public class KeyRandomStrategy implements KeyStrategyFunction, String> {
+
+ @Override
+ public String apply(List apiKeys) {
+ return RandomUtil.randomEle(apiKeys);
+ }
+}
\ No newline at end of file
diff --git a/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java
new file mode 100644
index 0000000000000000000000000000000000000000..277a83c283e11d6d985adf166e60cf7ef2a0a6c7
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt4.java
@@ -0,0 +1,72 @@
+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/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt5.java b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt5.java
new file mode 100644
index 0000000000000000000000000000000000000000..9fb0dc3ceba56cf5a8676adfeea6fbc272a9e606
--- /dev/null
+++ b/pojo/src/main/java/com/groupshell/entity/chatgpt/TestChatGpt5.java
@@ -0,0 +1,72 @@
+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 TestChatGpt5 {
+ 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/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java
index eb055aaf5c92de9b3a1b5e89057444be5f4a75a8..7de561ce0ce9c0734e3b29d7278fb576259014d0 100644
--- a/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java
+++ b/server/src/main/java/com/groupshell/controller/InvoiceCtrl.java
@@ -1,7 +1,10 @@
package com.groupshell.controller;
import com.groupshell.entity.Invoice;
+import com.groupshell.enumeration.ReimburseStatusEnum;
+import com.groupshell.result.Result;
import com.groupshell.service.InvoiceService;
+import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -12,60 +15,98 @@ import java.util.Map;
@RestController
@RequestMapping("/api/invoice")
-public class InvoiceCtrl
-{
- private final InvoiceService invoiceService;
- public InvoiceCtrl(InvoiceService invoiceService) {this.invoiceService=invoiceService;}
+public class InvoiceCtrl {
+
+ @Autowired
+ private InvoiceService invoiceService;
+
@PostMapping
- public Invoice addInvoice(@RequestBody Invoice record)
- {
- return invoiceService.addInvoice(record);
+ public Result addInvoice(@RequestBody Invoice record) {
+ invoiceService.addInvoice(record);
+ return Result.success(Boolean.TRUE);
}
+
// 根据ID获取发票信息
@GetMapping("/{id}")
- public Invoice getInvoiceById(@PathVariable Integer id)
- {
- return invoiceService.getInvoiceById(id);
+ public Result getInvoiceById(@PathVariable Integer id) {
+ Invoice invoice = invoiceService.getInvoiceById(id);
+ return Result.success(invoice);
}
+
@GetMapping
- public List getAllInvoices()
- {
- return invoiceService.getAllInvoices();
+ public Result> getAllInvoices() {
+ List invoices = invoiceService.getAllInvoices();
+ return Result.success(invoices);
}
+
@PutMapping("/{id}")
- public Invoice updateInvoice(@PathVariable Integer id,@RequestBody Invoice record)
- {
- record.setId(id);
- return invoiceService.updateInvoice(record);
+ public Result updateInvoice(@PathVariable Integer id, @RequestBody Invoice record) {
+ //record.setId(id); //TODO:这里的逻辑是不是有问题
+ invoiceService.updateInvoice(record);
+ return Result.success(Boolean.TRUE);
}
+
@DeleteMapping("/{id}")
- public String deleteInvoice(@PathVariable Integer id)
- {
- return invoiceService.deleteInvoice(id);
+ public Result deleteInvoice(@PathVariable Integer id) {
+ invoiceService.deleteInvoice(id);
+ return Result.success(Boolean.TRUE);
}
+
// 获取指定时间段内的总支出
@GetMapping("/expenses")
- public BigDecimal getExpensesByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end)
- {
- return invoiceService.getExpensesByTime(start,end);
+ public Result getExpensesByTime(@RequestParam LocalDateTime start, @RequestParam LocalDateTime end) {
+ BigDecimal expense = invoiceService.getExpensesByTime(start, end);
+ return Result.success(expense);
}
+
// 获取指定时间段内的总收入
@GetMapping("/incomes")
- public BigDecimal getIncomesByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end)
- {
- return invoiceService.getIncomesByTime(start,end);
+ public Result getIncomesByTime(@RequestParam LocalDateTime start, @RequestParam LocalDateTime end) {
+ BigDecimal income = invoiceService.getIncomesByTime(start, end);
+ return Result.success(income);
}
+
// 获取指定时间段内的净收入
@GetMapping("/netIncome")
- public BigDecimal getNetIncomeByTime(@RequestParam LocalDateTime start,@RequestParam LocalDateTime end)
- {
- return invoiceService.getNetIncomeByTime(start,end);
+ public Result getNetIncomeByTime(@RequestParam LocalDateTime start, @RequestParam LocalDateTime end) {
+ BigDecimal netIncome = invoiceService.getNetIncomeByTime(start, end);
+ return Result.success(netIncome);
}
+
// 获取指定类别和时间段内的支出汇总
@GetMapping("/expensesByCategory")
- public Map getExpensesByCategory(@RequestParam String category,
- @RequestParam LocalDateTime start,@RequestParam LocalDateTime end)
- {
- return invoiceService.getExpensesByCategory(category,start,end);
+ public Result