From 0aa739db8268b442ab74634289ffed00124a976a Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期五, 18 四月 2025 17:14:30 +0800
Subject: [PATCH] 会话管理、聊天接口(待测试)
---
ai-chat/src/main/java/com/monkeylessey/controller/ChatController.java | 38 +
dev-admin/src/main/resources/application-dev.yml | 7
dev-sys/src/main/java/com/monkeylessey/framework/config/TokenSecurityConfig.java | 1
ai-chat/src/main/java/com/monkeylessey/domain/form/SessionMsgForm.java | 39 +
ai-chat/src/main/java/com/monkeylessey/controller/SessionController.java | 88 +++
ai-chat/src/main/java/com/monkeylessey/domain/entity/SessionMsg.java | 34 +
ai-chat/src/main/java/com/monkeylessey/mapper/SessionMapper.java | 61 ++
ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionCountVO.java | 30 +
ai-chat/src/main/java/com/monkeylessey/controller/SessionMsgController.java | 83 +++
ai-chat/src/main/java/com/monkeylessey/domain/form/SessionForm.java | 77 +++
dev-admin/src/main/resources/application-prod.yml | 6
ai-chat/src/main/java/com/monkeylessey/service/SessionService.java | 72 ++
pom.xml | 7
ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionVO.java | 64 ++
ai-chat/src/main/java/com/monkeylessey/mapper/SessionMsgMapper.java | 33 +
ai-chat/src/main/java/com/monkeylessey/domain/form/ChatForm.java | 69 ++
dev-sys/src/main/java/com/monkeylessey/gen/handler/VoHandler.java | 2
ai-chat/src/main/java/com/monkeylessey/service/ChatService.java | 24
ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionMsgVO.java | 37 +
ai-chat/src/main/java/com/monkeylessey/service/impl/SessionMsgServiceImpl.java | 119 ++++
ai-chat/src/main/resources/mapper/SessionMapper.xml | 86 +++
ai-chat/src/main/java/com/monkeylessey/domain/query/SessionMsgQuery.java | 21
ai-chat/src/main/java/com/monkeylessey/domain/entity/Session.java | 70 ++
ai-chat/pom.xml | 6
dev-sys/src/main/java/com/monkeylessey/gen/utils/GenerateCodeUtil.java | 4
dev-sys/src/main/resources/templates/serviceImpl.java.vm | 3
ai-chat/src/main/java/com/monkeylessey/config/AIConfig.java | 50 ++
ai-chat/src/main/java/com/monkeylessey/service/impl/SessionServiceImpl.java | 146 +++++
ai-chat/src/main/java/com/monkeylessey/service/impl/ChatServiceImpl.java | 84 +++
dev-sys/src/main/java/com/monkeylessey/gen/handler/QueryHandler.java | 2
ai-chat/src/main/java/com/monkeylessey/domain/query/SessionQuery.java | 22
ai-chat/src/main/java/com/monkeylessey/service/SessionMsgService.java | 65 ++
ai-chat/src/main/resources/mapper/SessionMsgMapper.xml | 46 +
33 files changed, 1,491 insertions(+), 5 deletions(-)
diff --git a/ai-chat/pom.xml b/ai-chat/pom.xml
index 49a028c..b375c9a 100644
--- a/ai-chat/pom.xml
+++ b/ai-chat/pom.xml
@@ -17,6 +17,12 @@
</properties>
<dependencies>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-webflux</artifactId>
+ </dependency>
+
<dependency>
<groupId>com.monkeylessey</groupId>
<artifactId>dev-sys</artifactId>
diff --git a/ai-chat/src/main/java/com/monkeylessey/config/AIConfig.java b/ai-chat/src/main/java/com/monkeylessey/config/AIConfig.java
new file mode 100644
index 0000000..d09ea0e
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/config/AIConfig.java
@@ -0,0 +1,50 @@
+package com.monkeylessey.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author锛歺p
+ * @date锛�2025/4/18 14:28
+ */
+@Configuration
+@ConfigurationProperties(prefix = "ai")
+public class AIConfig {
+
+ /**
+ * 鍩熷悕
+ */
+ private String domain;
+
+ /**
+ * 绔彛
+ */
+ private String port;
+
+
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ /**
+ * 鑾峰彇瀹屾暣鐨勫煙
+ *
+ * @return
+ */
+ public String getFullDomain() {
+ return this.domain + ":" + this.port;
+ }
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/controller/ChatController.java b/ai-chat/src/main/java/com/monkeylessey/controller/ChatController.java
new file mode 100644
index 0000000..0ee4efb
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/controller/ChatController.java
@@ -0,0 +1,38 @@
+package com.monkeylessey.controller;
+
+import com.monkeylessey.domain.form.ChatForm;
+import com.monkeylessey.domain.form.SessionForm;
+import com.monkeylessey.group.Add;
+import com.monkeylessey.response.Result;
+import com.monkeylessey.service.ChatService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author锛歺p
+ * @date锛�2025/4/18 13:59
+ */
+@Validated
+@RequiredArgsConstructor
+@Api(value = "chat瀵硅瘽", tags = "chat瀵硅瘽绠$悊")
+@RestController
+@RequestMapping("/chat")
+public class ChatController {
+
+ private final ChatService chatService;
+
+ @PostMapping(value = "/send/msg", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+ @ApiOperation(value = "闂棶棰�/瀵硅瘽", notes = "闂棶棰�/瀵硅瘽")
+ public SseEmitter sendMsg(@RequestBody @Validated ChatForm form) {
+ return chatService.sendMsg(form);
+ }
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/controller/SessionController.java b/ai-chat/src/main/java/com/monkeylessey/controller/SessionController.java
new file mode 100644
index 0000000..b233c69
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/controller/SessionController.java
@@ -0,0 +1,88 @@
+package com.monkeylessey.controller;
+
+import com.monkeylessey.domain.form.SessionForm;
+import com.monkeylessey.domain.query.SessionQuery;
+import com.monkeylessey.group.Update;
+import com.monkeylessey.group.Add;
+import com.monkeylessey.service.SessionService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import lombok.RequiredArgsConstructor;
+import java.util.List;
+import javax.validation.constraints.NotEmpty;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import com.monkeylessey.response.Result;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * chat瀵硅瘽 鍓嶇鎺у埗鍣�
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Validated
+@RequiredArgsConstructor
+@Api(value = "浼氳瘽绠$悊", tags = "浼氳瘽绠$悊")
+@RestController
+@RequestMapping("/session")
+public class SessionController {
+
+ private final SessionService sessionService;
+
+ @PostMapping
+ @ApiOperation(value = "娣诲姞", notes = "娣诲姞")
+// @PreAuthorize("hasAuthority('session:add')")
+ public Result add(@RequestBody @Validated(Add.class) SessionForm form) {
+ return sessionService.add(form);
+ }
+
+ @PutMapping
+ @ApiOperation(value = "淇敼", notes = "淇敼")
+ @PreAuthorize("hasAuthority('session:edit')")
+ public Result update(@RequestBody @Validated(Update.class) SessionForm form) {
+ return sessionService.update(form);
+ }
+
+ @DeleteMapping("/{id}")
+ @ApiOperation(value = "ID鍒犻櫎", notes = "ID鍒犻櫎")
+ @PreAuthorize("hasAuthority('session:del')")
+ public Result removeById(@PathVariable("id") String id) {
+ return sessionService.removeById(id);
+ }
+
+ @DeleteMapping("/batch")
+ @ApiOperation(value = "鎵归噺鍒犻櫎", notes = "鎵归噺鍒犻櫎")
+ @PreAuthorize("hasAuthority('session:del:batch')")
+ public Result remove(@RequestBody @NotEmpty(message = "璇烽�夋嫨鏁版嵁") List<String> ids) {
+ return sessionService.remove(ids);
+ }
+
+ @GetMapping("/page")
+ @ApiOperation(value = "鍒嗛〉", notes = "鍒嗛〉")
+ @PreAuthorize("hasAuthority('session:page')")
+ public Result page(SessionQuery query) {
+ return sessionService.page(query);
+ }
+
+ @GetMapping("/{id}")
+ @ApiOperation(value = "璇︽儏", notes = "璇︽儏")
+// @PreAuthorize("hasAuthority('session:detail')")
+ public Result detail(@PathVariable("id") Integer id) {
+ return sessionService.detail(id);
+ }
+
+ @GetMapping("/list")
+ @PreAuthorize("hasAuthority('session:list')")
+ @ApiOperation(value = "鍒楄〃", notes = "鍒楄〃")
+ public Result list() {
+ return sessionService.all();
+ }
+
+ @GetMapping("/client/list")
+// @PreAuthorize("hasAuthority('session:client:list')")
+ @ApiOperation(value = "瀹㈡埛绔細璇濆垪琛�", notes = "瀹㈡埛绔細璇濆垪琛�")
+ public Result clientList() {
+ return sessionService.clientList();
+ }
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/controller/SessionMsgController.java b/ai-chat/src/main/java/com/monkeylessey/controller/SessionMsgController.java
new file mode 100644
index 0000000..390a431
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/controller/SessionMsgController.java
@@ -0,0 +1,83 @@
+package com.monkeylessey.controller;
+
+import com.monkeylessey.group.Update;
+import com.monkeylessey.group.Add;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import lombok.RequiredArgsConstructor;
+import java.util.List;
+import org.springframework.validation.annotation.Validated;
+import javax.validation.constraints.NotEmpty;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import com.monkeylessey.service.SessionMsgService;
+import com.monkeylessey.response.Result;
+import com.monkeylessey.domain.form.SessionMsgForm;
+import com.monkeylessey.domain.query.SessionMsgQuery;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 浼氳瘽娑堟伅 鍓嶇鎺у埗鍣�
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Validated
+@RequiredArgsConstructor
+@Api(value = "浼氳瘽娑堟伅", tags = "浼氳瘽娑堟伅绠$悊")
+@RestController
+@RequestMapping("/session-msg")
+public class SessionMsgController {
+
+ private final SessionMsgService sessionMsgService;
+
+ @PostMapping
+ @ApiOperation(value = "娣诲姞", notes = "娣诲姞")
+ @PreAuthorize("hasAuthority('sessionMsg:add')")
+ public Result add(@RequestBody @Validated(Add.class) SessionMsgForm form) {
+ return sessionMsgService.add(form);
+ }
+
+ @PutMapping
+ @ApiOperation(value = "淇敼", notes = "淇敼")
+ @PreAuthorize("hasAuthority('sessionMsg:edit')")
+ public Result update(@RequestBody @Validated(Update.class) SessionMsgForm form) {
+ return sessionMsgService.update(form);
+ }
+
+ @DeleteMapping("/{id}")
+ @ApiOperation(value = "ID鍒犻櫎", notes = "ID鍒犻櫎")
+ @PreAuthorize("hasAuthority('sessionMsg:del')")
+ public Result removeById(@PathVariable("id") String id) {
+ return sessionMsgService.removeById(id);
+ }
+
+ @DeleteMapping("/batch")
+ @ApiOperation(value = "鎵归噺鍒犻櫎", notes = "鎵归噺鍒犻櫎")
+ @PreAuthorize("hasAuthority('sessionMsg:del:batch')")
+ public Result remove(@RequestBody @NotEmpty(message = "璇烽�夋嫨鏁版嵁") List<String> ids) {
+ return sessionMsgService.remove(ids);
+ }
+
+ @GetMapping("/page")
+ @ApiOperation(value = "鍒嗛〉", notes = "鍒嗛〉")
+ @PreAuthorize("hasAuthority('sessionMsg:page')")
+ public Result page(SessionMsgQuery query) {
+ return sessionMsgService.page(query);
+ }
+
+ @GetMapping("/{id}")
+ @ApiOperation(value = "璇︽儏", notes = "璇︽儏")
+ @PreAuthorize("hasAuthority('sessionMsg:detail')")
+ public Result detail(@PathVariable("id") Integer id) {
+ return sessionMsgService.detail(id);
+ }
+
+ @GetMapping("/list")
+ @PreAuthorize("hasAuthority('sessionMsg:list')")
+ @ApiOperation(value = "鍒楄〃", notes = "鍒楄〃")
+ public Result list() {
+ return sessionMsgService.all();
+ }
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/entity/Session.java b/ai-chat/src/main/java/com/monkeylessey/domain/entity/Session.java
new file mode 100644
index 0000000..afc7b21
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/entity/Session.java
@@ -0,0 +1,70 @@
+package com.monkeylessey.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.monkeylessey.sys.domain.base.AbsEntity;
+import java.io.Serializable;
+import lombok.Data;
+
+/**
+ * chat瀵硅瘽
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@TableName("ai_session")
+public class Session extends AbsEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ @TableField("session_name")
+ /** 浼氳瘽鍚嶇О */
+ private String sessionName;
+
+ @TableField("mode")
+ /** 浼氳瘽妯″紡 */
+ private String mode;
+
+ @TableField("kb_name")
+ /** 鐭ヨ瘑搴� */
+ private String kbName;
+
+ @TableField("top_k")
+ /** */
+ private String topK;
+
+ @TableField("score_threshold")
+ /** */
+ private String scoreThreshold;
+
+ @TableField("stream")
+ /** */
+ private Integer stream;
+
+ @TableField("model")
+ /** 澶фā鍨� */
+ private String model;
+
+ @TableField("temperature")
+ /** */
+ private String temperature;
+
+ @TableField("max_tokens")
+ /** 鏈�澶у悙瀛楁暟 */
+ private Integer maxTokens;
+
+ @TableField("prompt_name")
+ /** */
+ private String promptName;
+
+ @TableField("return_direct")
+ /** 鏄惁鍙繑鍥炴绱㈢粨鏋滀笉璋冪敤澶фā鍨� */
+ private Integer returnDirect;
+
+ @TableField("user_id")
+ /** */
+ private String userId;
+
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/entity/SessionMsg.java b/ai-chat/src/main/java/com/monkeylessey/domain/entity/SessionMsg.java
new file mode 100644
index 0000000..76bef6f
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/entity/SessionMsg.java
@@ -0,0 +1,34 @@
+package com.monkeylessey.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.monkeylessey.sys.domain.base.AbsEntity;
+import java.io.Serializable;
+import lombok.Data;
+
+/**
+ * 浼氳瘽娑堟伅
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@TableName("ai_session_msg")
+public class SessionMsg extends AbsEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ @TableField("session_id")
+ /** 浼氳瘽id */
+ private String sessionId;
+
+ @TableField("role")
+ /** 瑙掕壊锛歛i銆乽ser */
+ private String role;
+
+ @TableField("content")
+ /** 瀵硅瘽鍐呭 */
+ private String content;
+
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/form/ChatForm.java b/ai-chat/src/main/java/com/monkeylessey/domain/form/ChatForm.java
new file mode 100644
index 0000000..6d83423
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/form/ChatForm.java
@@ -0,0 +1,69 @@
+package com.monkeylessey.domain.form;
+
+import com.monkeylessey.group.Add;
+import com.monkeylessey.group.Update;
+import com.monkeylessey.sys.domain.base.AbsForm;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * chat瀵硅瘽琛ㄥ崟
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "Session琛ㄥ崟", description = "chat瀵硅瘽琛ㄥ崟")
+public class ChatForm extends AbsForm {
+
+// @NotBlank(message = "鏈�夋嫨浼氳瘽")
+ @ApiModelProperty("浼氳瘽id")
+ private String sessionId;
+
+ @NotBlank(message = "璇疯緭鍏ユ偍鐨勯棶棰�")
+ @ApiModelProperty("褰撳墠鐢ㄦ埛鎻愰棶鍐呭")
+ private String query;
+
+ @NotBlank(message = "浼氳瘽妯″紡涓嶈兘涓虹┖")
+ @ApiModelProperty("浼氳瘽妯″紡")
+ private String mode;
+
+ @NotBlank(message = "鐭ヨ瘑搴撲笉鑳戒负绌�")
+ @ApiModelProperty("鐭ヨ瘑搴�")
+ private String kbName;
+
+ @ApiModelProperty("")
+ private String topK;
+
+ @ApiModelProperty("")
+ private String scoreThreshold;
+
+ @ApiModelProperty("娴佸紡鍝嶅簲")
+ private Boolean stream;
+
+ @NotBlank(message = "妯″瀷涓嶈兘涓虹┖")
+ @ApiModelProperty("妯″瀷")
+ private String model;
+
+ @ApiModelProperty("")
+ private String temperature;
+
+ @ApiModelProperty("鏈�澶у悙瀛楁暟")
+ private Integer maxTokens;
+
+ @ApiModelProperty("")
+ private String promptName;
+
+ @ApiModelProperty("鏄惁鍙繑鍥炴绱㈢粨鏋滀笉璋冪敤澶фā鍨�")
+ private Boolean returnDirect;
+
+ @ApiModelProperty("鍘嗗彶娑堟伅")
+ private List<SessionMsgForm> history = new ArrayList<>();
+
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/form/SessionForm.java b/ai-chat/src/main/java/com/monkeylessey/domain/form/SessionForm.java
new file mode 100644
index 0000000..b251af8
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/form/SessionForm.java
@@ -0,0 +1,77 @@
+package com.monkeylessey.domain.form;
+
+import com.monkeylessey.domain.entity.Session;
+import com.monkeylessey.group.Update;
+import com.monkeylessey.group.Add;
+import com.monkeylessey.sys.domain.base.AbsForm;
+import org.springframework.beans.BeanUtils;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import org.springframework.lang.NonNull;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * chat瀵硅瘽琛ㄥ崟
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "Session琛ㄥ崟", description = "chat瀵硅瘽琛ㄥ崟")
+public class SessionForm extends AbsForm {
+
+ @NotBlank(message = "浼氳瘽鍚嶇О涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("浼氳瘽鍚嶇О")
+ private String sessionName;
+
+ @NotBlank(message = "浼氳瘽妯″紡涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("浼氳瘽妯″紡")
+ private String mode;
+
+ @NotBlank(message = "鐭ヨ瘑搴撲笉鑳戒负绌�", groups = {Add.class, Update.class})
+ @ApiModelProperty("鐭ヨ瘑搴�")
+ private String kbName;
+
+ @NotBlank(message = "涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("")
+ private String topK;
+
+ @NotBlank(message = "涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("")
+ private String scoreThreshold;
+
+ @NotNull(message = "涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("")
+ private Integer stream;
+
+ @NotBlank(message = "澶фā鍨嬩笉鑳戒负绌�", groups = {Add.class, Update.class})
+ @ApiModelProperty("澶фā鍨�")
+ private String model;
+
+ @NotBlank(message = "涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("")
+ private String temperature;
+
+ @NotNull(message = "鏈�澶у悙瀛楁暟涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("鏈�澶у悙瀛楁暟")
+ private Integer maxTokens;
+
+ @NotBlank(message = "涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @ApiModelProperty("")
+ private String promptName;
+
+ @NotNull(message = "鏄惁鍙繑鍥炴绱㈢粨鏋滀笉璋冪敤澶фā鍨嬩笉鑳戒负绌�", groups = {Add.class, Update.class})
+ @ApiModelProperty("鏄惁鍙繑鍥炴绱㈢粨鏋滀笉璋冪敤澶фā鍨�")
+ private Integer returnDirect;
+
+ public static Session getEntityByForm(@NonNull SessionForm form, Session entity) {
+ if(entity == null) {
+ entity = new Session();
+ }
+ BeanUtils.copyProperties(form, entity);
+ return entity;
+ }
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/form/SessionMsgForm.java b/ai-chat/src/main/java/com/monkeylessey/domain/form/SessionMsgForm.java
new file mode 100644
index 0000000..f52d96e
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/form/SessionMsgForm.java
@@ -0,0 +1,39 @@
+package com.monkeylessey.domain.form;
+
+import com.monkeylessey.group.Update;
+import com.monkeylessey.group.Add;
+import com.monkeylessey.sys.domain.base.AbsForm;
+import com.monkeylessey.domain.entity.SessionMsg;
+import org.springframework.beans.BeanUtils;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import org.springframework.lang.NonNull;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 浼氳瘽娑堟伅琛ㄥ崟
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "SessionMsg琛ㄥ崟", description = "浼氳瘽娑堟伅琛ㄥ崟")
+public class SessionMsgForm extends AbsForm {
+
+ @ApiModelProperty("瑙掕壊锛歛i銆乽ser")
+ private String role;
+
+ @ApiModelProperty("瀵硅瘽鍐呭")
+ private String content;
+
+ public static SessionMsg getEntityByForm(@NonNull SessionMsgForm form, SessionMsg entity) {
+ if(entity == null) {
+ entity = new SessionMsg();
+ }
+ BeanUtils.copyProperties(form, entity);
+ return entity;
+ }
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/query/SessionMsgQuery.java b/ai-chat/src/main/java/com/monkeylessey/domain/query/SessionMsgQuery.java
new file mode 100644
index 0000000..8a449bf
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/query/SessionMsgQuery.java
@@ -0,0 +1,21 @@
+package com.monkeylessey.domain.query;
+
+import com.monkeylessey.sys.domain.base.AbsQuery;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 浼氳瘽娑堟伅鏌ヨ
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "SessionMsg鏌ヨ鍙傛暟", description = "浼氳瘽娑堟伅鏌ヨ鍙傛暟")
+public class SessionMsgQuery extends AbsQuery {
+
+ @ApiModelProperty("瀵硅瘽鍐呭")
+ private String content;
+}
+
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/query/SessionQuery.java b/ai-chat/src/main/java/com/monkeylessey/domain/query/SessionQuery.java
new file mode 100644
index 0000000..d1dee39
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/query/SessionQuery.java
@@ -0,0 +1,22 @@
+package com.monkeylessey.domain.query;
+
+
+import com.monkeylessey.sys.domain.base.AbsQuery;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * chat瀵硅瘽鏌ヨ
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "Session鏌ヨ鍙傛暟", description = "chat瀵硅瘽鏌ヨ鍙傛暟")
+public class SessionQuery extends AbsQuery {
+
+ @ApiModelProperty("浼氳瘽鍚嶇О")
+ private String sessionName;
+}
+
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionCountVO.java b/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionCountVO.java
new file mode 100644
index 0000000..9201960
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionCountVO.java
@@ -0,0 +1,30 @@
+package com.monkeylessey.domain.vo;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author锛歺p
+ * @date锛�2025/4/18 15:20
+ */
+@Data
+public class SessionCountVO {
+
+ /**
+ * 浠婂ぉ鐨勪細璇�
+ */
+ private List<SessionVO> today = new ArrayList<>();
+
+ /**
+ * 鏄ㄥぉ鐨勪細璇�
+ */
+ private List<SessionVO> yesterday = new ArrayList<>();
+
+ /**
+ * 鏄ㄥぉ浠ュ墠鐨勬墍鏈変細璇�
+ */
+ private List<SessionVO> old = new ArrayList<>();
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionMsgVO.java b/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionMsgVO.java
new file mode 100644
index 0000000..d7b98ef
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionMsgVO.java
@@ -0,0 +1,37 @@
+package com.monkeylessey.domain.vo;
+
+import com.monkeylessey.domain.entity.SessionMsg;
+import com.monkeylessey.sys.domain.base.AbsVo;
+import org.springframework.lang.NonNull;
+import org.springframework.beans.BeanUtils;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+/**
+ * 浼氳瘽娑堟伅灞曠ず
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "浼氳瘽娑堟伅鍝嶅簲鏁版嵁", description = "浼氳瘽娑堟伅鍝嶅簲鏁版嵁")
+public class SessionMsgVO extends AbsVo {
+
+ /** 浼氳瘽id */
+ private String sessionId;
+
+ /** 瑙掕壊锛歛i銆乽ser */
+ private String role;
+
+ /** 瀵硅瘽鍐呭 */
+ private String content;
+
+ public static SessionMsgVO getVoByEntity(@NonNull SessionMsg entity, SessionMsgVO vo) {
+ if(vo == null) {
+ vo = new SessionMsgVO();
+ }
+ BeanUtils.copyProperties(entity, vo);
+ return vo;
+ }
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionVO.java b/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionVO.java
new file mode 100644
index 0000000..e58dd5a
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/domain/vo/SessionVO.java
@@ -0,0 +1,64 @@
+package com.monkeylessey.domain.vo;
+
+import com.monkeylessey.domain.entity.Session;
+import com.monkeylessey.sys.domain.base.AbsVo;
+import org.springframework.lang.NonNull;
+import org.springframework.beans.BeanUtils;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+/**
+ * chat瀵硅瘽灞曠ず
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Data
+@ApiModel(value = "chat瀵硅瘽鍝嶅簲鏁版嵁", description = "chat瀵硅瘽鍝嶅簲鏁版嵁")
+public class SessionVO extends AbsVo {
+
+ /** 浼氳瘽鍚嶇О */
+ private String sessionName;
+
+ /** 浼氳瘽妯″紡 */
+ private String mode;
+
+ /** 鐭ヨ瘑搴� */
+ private String kbName;
+
+ /** */
+ private String topK;
+
+ /** */
+ private String scoreThreshold;
+
+ /** */
+ private Integer stream;
+
+ /** 澶фā鍨� */
+ private String model;
+
+ /** */
+ private String temperature;
+
+ /** 鏈�澶у悙瀛楁暟 */
+ private Integer maxTokens;
+
+ /** */
+ private String promptName;
+
+ /** 鏄惁鍙繑鍥炴绱㈢粨鏋滀笉璋冪敤澶фā鍨� */
+ private Integer returnDirect;
+
+ /** */
+ private String userId;
+
+ public static SessionVO getVoByEntity(@NonNull Session entity, SessionVO vo) {
+ if(vo == null) {
+ vo = new SessionVO();
+ }
+ BeanUtils.copyProperties(entity, vo);
+ return vo;
+ }
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/mapper/SessionMapper.java b/ai-chat/src/main/java/com/monkeylessey/mapper/SessionMapper.java
new file mode 100644
index 0000000..f166a06
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/mapper/SessionMapper.java
@@ -0,0 +1,61 @@
+package com.monkeylessey.mapper;
+
+import com.monkeylessey.domain.entity.Session;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.Date;
+import java.util.List;
+
+import com.monkeylessey.domain.query.SessionQuery;
+import com.monkeylessey.domain.vo.SessionVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * chat瀵硅瘽 Mapper 鎺ュ彛
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Mapper
+public interface SessionMapper extends BaseMapper<Session> {
+
+ /**
+ * id鏌ユ壘chat瀵硅瘽
+ * @param id
+ * @return
+ */
+ SessionVO getById(Integer id);
+
+ /**
+ * 鍒嗛〉
+ */
+ IPage getPage(IPage page, @Param("query") SessionQuery query);
+
+ /**
+ * 浠婂ぉ鐨勪細璇濆垪琛�
+ *
+ * @param dayStart
+ * @param dayEnd
+ * @return
+ */
+ List<SessionVO> getTodaySessionList(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd);
+
+ /**
+ * 鏄ㄥぉ鐨勪細璇�
+ *
+ * @param dayStart
+ * @param dayEnd
+ * @return
+ */
+ List<SessionVO> getYesterdaySessionList(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd);
+
+ /**
+ * 鏄ㄥぉ涔嬪墠鐨勬墍鏈変細璇�
+ *
+ * @param time
+ * @return
+ */
+ List<SessionVO> getOldSessionList(@Param("time") Date time);
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/mapper/SessionMsgMapper.java b/ai-chat/src/main/java/com/monkeylessey/mapper/SessionMsgMapper.java
new file mode 100644
index 0000000..02f144f
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/mapper/SessionMsgMapper.java
@@ -0,0 +1,33 @@
+package com.monkeylessey.mapper;
+
+import com.monkeylessey.domain.entity.SessionMsg;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.monkeylessey.domain.query.SessionMsgQuery;
+import com.monkeylessey.domain.vo.SessionMsgVO;
+import java.util.List;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 浼氳瘽娑堟伅 Mapper 鎺ュ彛
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Mapper
+public interface SessionMsgMapper extends BaseMapper<SessionMsg> {
+
+ /**
+ * id鏌ユ壘浼氳瘽娑堟伅
+ * @param id
+ * @return
+ */
+ SessionMsgVO getById(Integer id);
+
+ /**
+ * 鍒嗛〉
+ */
+ IPage getPage(IPage page, @Param("query") SessionMsgQuery query);
+
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/service/ChatService.java b/ai-chat/src/main/java/com/monkeylessey/service/ChatService.java
new file mode 100644
index 0000000..7ab0b35
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/service/ChatService.java
@@ -0,0 +1,24 @@
+package com.monkeylessey.service;
+
+import com.monkeylessey.domain.form.ChatForm;
+import com.monkeylessey.response.Result;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 瀵硅瘽
+ *
+ * @author锛歺p
+ * @date锛�2025/4/18 14:21
+ */
+public interface ChatService {
+
+
+ /**
+ * 鐢ㄦ埛鎻愰棶
+ *
+ * @param form
+ */
+ SseEmitter sendMsg(ChatForm form);
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/service/SessionMsgService.java b/ai-chat/src/main/java/com/monkeylessey/service/SessionMsgService.java
new file mode 100644
index 0000000..02a08e2
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/service/SessionMsgService.java
@@ -0,0 +1,65 @@
+package com.monkeylessey.service;
+
+import com.monkeylessey.domain.entity.SessionMsg;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.monkeylessey.response.Result;
+import com.monkeylessey.domain.form.SessionMsgForm;
+import com.monkeylessey.domain.query.SessionMsgQuery;
+import java.util.List;
+
+/**
+ * 浼氳瘽娑堟伅 鏈嶅姟绫�
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+public interface SessionMsgService extends IService<SessionMsg> {
+
+ /**
+ * 娣诲姞
+ * @param form
+ * @return
+ */
+ Result add(SessionMsgForm form);
+
+ /**
+ * 淇敼
+ * @param form
+ * @return
+ */
+ Result update(SessionMsgForm form);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ * @param ids
+ * @return
+ */
+ Result remove(List<String> ids);
+
+ /**
+ * id鍒犻櫎
+ * @param id
+ * @return
+ */
+ Result removeById(String id);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ * @param query
+ * @return
+ */
+ Result page(SessionMsgQuery query);
+
+ /**
+ * 鏍规嵁id鏌ユ壘
+ * @param id
+ * @return
+ */
+ Result detail(Integer id);
+
+ /**
+ * 鍒楄〃
+ * @return
+ */
+ Result all();
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/service/SessionService.java b/ai-chat/src/main/java/com/monkeylessey/service/SessionService.java
new file mode 100644
index 0000000..3a1aacd
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/service/SessionService.java
@@ -0,0 +1,72 @@
+package com.monkeylessey.service;
+
+import com.monkeylessey.domain.entity.Session;
+import com.monkeylessey.domain.form.SessionForm;
+import com.monkeylessey.domain.query.SessionQuery;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.monkeylessey.response.Result;
+import java.util.List;
+
+/**
+ * chat瀵硅瘽 鏈嶅姟绫�
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+public interface SessionService extends IService<Session> {
+
+ /**
+ * 娣诲姞
+ * @param form
+ * @return
+ */
+ Result add(SessionForm form);
+
+ /**
+ * 淇敼
+ * @param form
+ * @return
+ */
+ Result update(SessionForm form);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ * @param ids
+ * @return
+ */
+ Result remove(List<String> ids);
+
+ /**
+ * id鍒犻櫎
+ * @param id
+ * @return
+ */
+ Result removeById(String id);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ * @param query
+ * @return
+ */
+ Result page(SessionQuery query);
+
+ /**
+ * 鏍规嵁id鏌ユ壘
+ * @param id
+ * @return
+ */
+ Result detail(Integer id);
+
+ /**
+ * 鍒楄〃
+ * @return
+ */
+ Result all();
+
+ /**
+ * 瀹㈡埛绔細璇濆垪琛�
+ *
+ * @return
+ */
+ Result clientList();
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/service/impl/ChatServiceImpl.java b/ai-chat/src/main/java/com/monkeylessey/service/impl/ChatServiceImpl.java
new file mode 100644
index 0000000..5ee0931
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/service/impl/ChatServiceImpl.java
@@ -0,0 +1,84 @@
+package com.monkeylessey.service.impl;
+
+import cn.hutool.http.HttpUtil;
+import com.monkeylessey.config.AIConfig;
+import com.monkeylessey.domain.form.ChatForm;
+import com.monkeylessey.service.ChatService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * @author锛歺p
+ * @date锛�2025/4/18 14:22
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ChatServiceImpl implements ChatService {
+
+ private final AIConfig aiConfig;
+
+ @Override
+ public SseEmitter sendMsg(ChatForm form) {
+
+ SseEmitter emitter = new SseEmitter(Long.MAX_VALUE); // 璁剧疆鏃犻檺瓒呮椂
+
+ // 1. 鏋勫缓璇锋眰浣�
+ Map<String, Object> body = new HashMap<>();
+ body.put("query", form.getQuery());
+ body.put("mode", form.getMode());
+ body.put("kb_name", form.getKbName());
+ body.put("top_k", form.getTopK());
+ body.put("score_threshold", form.getScoreThreshold());
+ body.put("history", form.getHistory());
+ body.put("stream", form.getStream());
+ body.put("model", form.getModel());
+ body.put("temperature", form.getTemperature());
+ body.put("max_tokens", form.getMaxTokens());
+ body.put("prompt_name", form.getPromptName());
+ body.put("return_direct", form.getReturnDirect());
+
+ // 2. 寮傛澶勭悊SSE杞彂
+ CompletableFuture.runAsync(() -> {
+ try {
+ WebClient client = WebClient.create(aiConfig.getFullDomain());
+ client.post()
+ .uri("/chat/kb_chat")
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.TEXT_EVENT_STREAM) // 澹版槑鎺ュ彈SSE鍝嶅簲
+ .bodyValue(body)
+ .retrieve()
+ .bodyToFlux(String.class) // 浣跨敤Flux鎺ユ敹娴佸紡鍝嶅簲
+ .subscribe(
+ data -> {
+ try {
+ emitter.send(SseEmitter.event().data(data));
+ } catch (IOException e) {
+ log.error("鍙戦�佸け璐�", e.getMessage());
+ }
+ },
+ error -> emitter.completeWithError(error),
+ () -> emitter.complete()
+ );
+ } catch (Exception e) {
+ emitter.completeWithError(e);
+ }
+ });
+
+ // 3. 杩炴帴鐢熷懡鍛ㄦ湡鍥炶皟
+ emitter.onCompletion(() -> log.info("SSE connection completed"));
+ emitter.onTimeout(() -> log.warn("SSE connection timed out"));
+ emitter.onError(ex -> log.error("SSE error: {}", ex.getMessage()));
+ return emitter;
+ }
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/service/impl/SessionMsgServiceImpl.java b/ai-chat/src/main/java/com/monkeylessey/service/impl/SessionMsgServiceImpl.java
new file mode 100644
index 0000000..c3a0a87
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/service/impl/SessionMsgServiceImpl.java
@@ -0,0 +1,119 @@
+package com.monkeylessey.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.monkeylessey.domain.entity.SessionMsg;
+import com.monkeylessey.mapper.SessionMsgMapper;
+import com.monkeylessey.service.SessionMsgService;
+import com.monkeylessey.response.Result;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.monkeylessey.domain.form.SessionMsgForm;
+import com.monkeylessey.domain.vo.SessionMsgVO;
+import com.monkeylessey.domain.query.SessionMsgQuery;
+import org.springframework.stereotype.Service;
+import lombok.RequiredArgsConstructor;
+import com.monkeylessey.utils.PageUtil;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.Assert;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 浼氳瘽娑堟伅 鏈嶅姟瀹炵幇绫�
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Service
+@RequiredArgsConstructor
+public class SessionMsgServiceImpl extends ServiceImpl<SessionMsgMapper, SessionMsg> implements SessionMsgService {
+
+ private final SessionMsgMapper sessionMsgMapper;
+
+ /**
+ * 娣诲姞
+ * @param form
+ * @return
+ */
+ @Override
+ public Result add(SessionMsgForm form) {
+ SessionMsg entity = SessionMsgForm.getEntityByForm(form, null);
+ baseMapper.insert(entity);
+ return Result.ok("娣诲姞鎴愬姛");
+ }
+
+ /**
+ * 淇敼
+ * @param form
+ * @return
+ */
+ @Override
+ public Result update(SessionMsgForm form) {
+ SessionMsg entity = baseMapper.selectById(form.getId());
+
+ // 涓虹┖鎶汭llegalArgumentException锛屽仛鍏ㄥ眬寮傚父澶勭悊
+ Assert.notNull(entity, "璁板綍涓嶅瓨鍦�");
+ BeanUtils.copyProperties(form, entity);
+ baseMapper.updateById(entity);
+ return Result.ok("淇敼鎴愬姛");
+ }
+
+ /**
+ * 鎵归噺鍒犻櫎
+ * @param ids
+ * @return
+ */
+ @Override
+ public Result remove(List<String> ids) {
+ baseMapper.deleteBatchIds(ids);
+ return Result.ok("鍒犻櫎鎴愬姛");
+ }
+
+ /**
+ * id鍒犻櫎
+ * @param id
+ * @return
+ */
+ @Override
+ public Result removeById(String id) {
+ baseMapper.deleteById(id);
+ return Result.ok("鍒犻櫎鎴愬姛");
+ }
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ * @param query
+ * @return
+ */
+ @Override
+ public Result page(SessionMsgQuery query) {
+ IPage<SessionMsgVO> page = PageUtil.getPage(query, SessionMsgVO.class);
+ baseMapper.getPage(page, query);
+ return Result.ok().data(page.getRecords()).total(page.getTotal());
+ }
+
+ /**
+ * 鏍规嵁id鏌ユ壘
+ * @param id
+ * @return
+ */
+ @Override
+ public Result detail(Integer id) {
+ SessionMsgVO vo = baseMapper.getById(id);
+ Assert.notNull(vo, "璁板綍涓嶅瓨鍦�");
+ return Result.ok().data(vo);
+ }
+
+ /**
+ * 鍒楄〃
+ * @return
+ */
+ @Override
+ public Result all() {
+ List<SessionMsg> entities = baseMapper.selectList(null);
+ List<SessionMsgVO> vos = entities.stream()
+ .map(entity -> SessionMsgVO.getVoByEntity(entity, null))
+ .collect(Collectors.toList());
+ return Result.ok().data(vos);
+ }
+}
diff --git a/ai-chat/src/main/java/com/monkeylessey/service/impl/SessionServiceImpl.java b/ai-chat/src/main/java/com/monkeylessey/service/impl/SessionServiceImpl.java
new file mode 100644
index 0000000..4160fb3
--- /dev/null
+++ b/ai-chat/src/main/java/com/monkeylessey/service/impl/SessionServiceImpl.java
@@ -0,0 +1,146 @@
+package com.monkeylessey.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.monkeylessey.domain.entity.Session;
+import com.monkeylessey.domain.form.SessionForm;
+import com.monkeylessey.domain.query.SessionQuery;
+import com.monkeylessey.domain.vo.SessionCountVO;
+import com.monkeylessey.domain.vo.SessionVO;
+import com.monkeylessey.mapper.SessionMapper;
+import com.monkeylessey.service.SessionService;
+import com.monkeylessey.response.Result;
+import com.monkeylessey.utils.DateUtil;
+import com.monkeylessey.utils.PageUtil;
+import org.springframework.stereotype.Service;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.Assert;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * chat瀵硅瘽 鏈嶅姟瀹炵幇绫�
+ *
+ * @author 鍚戝煿
+ * @since 2025-04-18
+ */
+@Service
+@RequiredArgsConstructor
+public class SessionServiceImpl extends ServiceImpl<SessionMapper, Session> implements SessionService {
+
+ private final SessionMapper sessionMapper;
+
+ /**
+ * 娣诲姞
+ * @param form
+ * @return
+ */
+ @Override
+ public Result add(SessionForm form) {
+ Session entity = SessionForm.getEntityByForm(form, null);
+ baseMapper.insert(entity);
+ return Result.ok("娣诲姞鎴愬姛");
+ }
+
+ /**
+ * 淇敼
+ * @param form
+ * @return
+ */
+ @Override
+ public Result update(SessionForm form) {
+ Session entity = baseMapper.selectById(form.getId());
+
+ // 涓虹┖鎶汭llegalArgumentException锛屽仛鍏ㄥ眬寮傚父澶勭悊
+ Assert.notNull(entity, "璁板綍涓嶅瓨鍦�");
+ BeanUtils.copyProperties(form, entity);
+ baseMapper.updateById(entity);
+ return Result.ok("淇敼鎴愬姛");
+ }
+
+ /**
+ * 鎵归噺鍒犻櫎
+ * @param ids
+ * @return
+ */
+ @Override
+ public Result remove(List<String> ids) {
+ baseMapper.deleteBatchIds(ids);
+ return Result.ok("鍒犻櫎鎴愬姛");
+ }
+
+ /**
+ * id鍒犻櫎
+ * @param id
+ * @return
+ */
+ @Override
+ public Result removeById(String id) {
+ baseMapper.deleteById(id);
+ return Result.ok("鍒犻櫎鎴愬姛");
+ }
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ * @param query
+ * @return
+ */
+ @Override
+ public Result page(SessionQuery query) {
+ IPage<SessionVO> page = PageUtil.getPage(query, SessionVO.class);
+ baseMapper.getPage(page, query);
+ return Result.ok().data(page.getRecords()).total(page.getTotal());
+ }
+
+ /**
+ * 鏍规嵁id鏌ユ壘
+ * @param id
+ * @return
+ */
+ @Override
+ public Result detail(Integer id) {
+ SessionVO vo = baseMapper.getById(id);
+ Assert.notNull(vo, "璁板綍涓嶅瓨鍦�");
+ return Result.ok().data(vo);
+ }
+
+ /**
+ * 鍒楄〃
+ * @return
+ */
+ @Override
+ public Result all() {
+ List<Session> entities = baseMapper.selectList(null);
+ List<SessionVO> vos = entities.stream()
+ .map(entity -> SessionVO.getVoByEntity(entity, null))
+ .collect(Collectors.toList());
+ return Result.ok().data(vos);
+ }
+
+
+ @Override
+ public Result clientList() {
+ Date now = new Date();
+ // TODO锛寀serId鏌ヨ
+ // 浠婂ぉ
+ List<SessionVO> todaySession = baseMapper.getTodaySessionList(DateUtil.getDayStart(now), DateUtil.getDayEnd(now));
+ // 鏄ㄥぉ
+ Calendar instance = Calendar.getInstance();
+ instance.setTime(now);
+ instance.add(Calendar.DATE, -1);
+ Date yesterday = instance.getTime();
+ List<SessionVO> yesterdaySession = baseMapper.getYesterdaySessionList(DateUtil.getDayStart(yesterday), DateUtil.getDayEnd(yesterday));
+ // 鏇存棭
+ List<SessionVO> oldSession = baseMapper.getOldSessionList(DateUtil.getDayStart(yesterday));
+
+ SessionCountVO vo = new SessionCountVO();
+ vo.setToday(todaySession);
+ vo.setYesterday(yesterdaySession);
+ vo.setOld(oldSession);
+ return Result.ok().data(vo);
+ }
+}
diff --git a/ai-chat/src/main/resources/mapper/SessionMapper.xml b/ai-chat/src/main/resources/mapper/SessionMapper.xml
new file mode 100644
index 0000000..ad68b14
--- /dev/null
+++ b/ai-chat/src/main/resources/mapper/SessionMapper.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.monkeylessey.mapper.SessionMapper">
+
+ <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+ <resultMap id="BaseResultMap" type="com.monkeylessey.domain.vo.SessionVO">
+ <result column="session_name" property="sessionName" />
+ <result column="mode" property="mode" />
+ <result column="kb_name" property="kbName" />
+ <result column="top_k" property="topK" />
+ <result column="score_threshold" property="scoreThreshold" />
+ <result column="stream" property="stream" />
+ <result column="model" property="model" />
+ <result column="temperature" property="temperature" />
+ <result column="max_tokens" property="maxTokens" />
+ <result column="prompt_name" property="promptName" />
+ <result column="return_direct" property="returnDirect" />
+ <result column="user_id" property="userId" />
+ </resultMap>
+
+
+
+
+
+
+
+ <select id="getById" resultMap="BaseResultMap">
+ SELECT
+ SE.session_name,
+ SE.mode,
+ SE.kb_name,
+ SE.top_k,
+ SE.score_threshold,
+ SE.stream,
+ SE.model,
+ SE.temperature,
+ SE.max_tokens,
+ SE.prompt_name,
+ SE.return_direct,
+ SE.user_id,
+ SE.id
+ FROM
+ ai_session SE
+ WHERE
+ SE.id = #{id} AND SE.deleted = 0
+ </select>
+
+
+ <select id="getPage" resultMap="BaseResultMap">
+ SELECT
+ SE.session_name,
+ SE.mode,
+ SE.kb_name,
+ SE.top_k,
+ SE.score_threshold,
+ SE.stream,
+ SE.model,
+ SE.temperature,
+ SE.max_tokens,
+ SE.prompt_name,
+ SE.return_direct,
+ SE.user_id,
+ SE.id
+ FROM
+ ai_session SE
+ WHERE
+ SE.deleted = 0
+ <if test="query.sessionName != null and query.sessionName != ''">
+ AND SE.session_name = #{query.sessionName}
+ </if>
+ </select>
+
+
+ <select id="getTodaySessionList" resultMap="BaseResultMap">
+ SELECT * FROM ai_session WHERE gmt_create between #{dayStart} and #{dayEnd} AND deleted = 0 ORDER BY gmt_create DESC
+ </select>
+
+
+ <select id="getYesterdaySessionList" resultMap="BaseResultMap">
+ SELECT * FROM ai_session WHERE gmt_create between #{dayStart} and #{dayEnd} AND deleted = 0 ORDER BY gmt_create DESC
+ </select>
+
+ <select id="getOldSessionList" resultMap="BaseResultMap">
+ SELECT * FROM ai_session WHERE gmt_create < #{time} AND deleted = 0 ORDER BY gmt_create DESC
+ </select>
+</mapper>
diff --git a/ai-chat/src/main/resources/mapper/SessionMsgMapper.xml b/ai-chat/src/main/resources/mapper/SessionMsgMapper.xml
new file mode 100644
index 0000000..079d7f6
--- /dev/null
+++ b/ai-chat/src/main/resources/mapper/SessionMsgMapper.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.monkeylessey.mapper.SessionMsgMapper">
+
+ <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+ <resultMap id="BaseResultMap" type="com.monkeylessey.domain.vo.SessionMsgVO">
+ <result column="session_id" property="sessionId" />
+ <result column="role" property="role" />
+ <result column="content" property="content" />
+ </resultMap>
+
+
+
+
+
+
+
+ <select id="getById" resultMap="BaseResultMap">
+ SELECT
+ ASM.session_id,
+ ASM.role,
+ ASM.content,
+ ASM.id
+ FROM
+ ai_session_msg ASM
+ WHERE
+ ASM.id = #{id} AND ASM.deleted = 0
+ </select>
+
+
+ <select id="getPage" resultMap="BaseResultMap">
+ SELECT
+ ASM.session_id,
+ ASM.role,
+ ASM.content,
+ ASM.id
+ FROM
+ ai_session_msg ASM
+ WHERE
+ ASM.deleted = 0
+ <if test="query.content != null and query.content != ''">
+ AND ASM.content = #{query.content}
+ </if>
+ </select>
+
+</mapper>
diff --git a/dev-admin/src/main/resources/application-dev.yml b/dev-admin/src/main/resources/application-dev.yml
index e606970..6199ba4 100644
--- a/dev-admin/src/main/resources/application-dev.yml
+++ b/dev-admin/src/main/resources/application-dev.yml
@@ -53,3 +53,10 @@
domain: http://127.0.0.1:${server.port}/files/
+# 鐭ヨ瘑搴撻厤缃�
+ai:
+ domain: http://i-1.gpushare.com
+ port: 52574
+
+
+
diff --git a/dev-admin/src/main/resources/application-prod.yml b/dev-admin/src/main/resources/application-prod.yml
index b829bf6..afedac2 100644
--- a/dev-admin/src/main/resources/application-prod.yml
+++ b/dev-admin/src/main/resources/application-prod.yml
@@ -48,3 +48,9 @@
# 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
url: E:/ycl/file
domain: http://127.0.0.1:${server.port}/files/
+
+
+# 鐭ヨ瘑搴撻厤缃�
+ai:
+ domain: http://i-1.gpushare.com
+ port: 52574
diff --git a/dev-sys/src/main/java/com/monkeylessey/framework/config/TokenSecurityConfig.java b/dev-sys/src/main/java/com/monkeylessey/framework/config/TokenSecurityConfig.java
index 5e93c84..d407f5c 100644
--- a/dev-sys/src/main/java/com/monkeylessey/framework/config/TokenSecurityConfig.java
+++ b/dev-sys/src/main/java/com/monkeylessey/framework/config/TokenSecurityConfig.java
@@ -65,6 +65,7 @@
.authenticationEntryPoint(authenticationException);
http.authorizeRequests()
+ .antMatchers("/**").permitAll()
.antMatchers(HttpMethod.POST, "/xpstart/login").permitAll()
.antMatchers("/sys-table/columns/**").permitAll()
.antMatchers("/ws/**").permitAll()
diff --git a/dev-sys/src/main/java/com/monkeylessey/gen/handler/QueryHandler.java b/dev-sys/src/main/java/com/monkeylessey/gen/handler/QueryHandler.java
index 62e21ca..c6629be 100644
--- a/dev-sys/src/main/java/com/monkeylessey/gen/handler/QueryHandler.java
+++ b/dev-sys/src/main/java/com/monkeylessey/gen/handler/QueryHandler.java
@@ -37,7 +37,7 @@
queryTemplate.setFields(columnS);
// 璁剧疆query鐨勭埗绫诲悕
queryTemplate.setBaseQueryName("AbsQuery");
- queryTemplate.setBaseQueryPath("com.monkeylessey.base");
+ queryTemplate.setBaseQueryPath("com.monkeylessey.sys.domain.base");
objectMap.put("queryInfo", queryTemplate);
return new VueHandler().handler(objectMap, data);
}
diff --git a/dev-sys/src/main/java/com/monkeylessey/gen/handler/VoHandler.java b/dev-sys/src/main/java/com/monkeylessey/gen/handler/VoHandler.java
index d6d3732..26c1b46 100644
--- a/dev-sys/src/main/java/com/monkeylessey/gen/handler/VoHandler.java
+++ b/dev-sys/src/main/java/com/monkeylessey/gen/handler/VoHandler.java
@@ -42,7 +42,7 @@
voTemplate.setFields(columns);
// 璁剧疆vo鐨勭埗绫诲悕
voTemplate.setBaseVoName("AbsVo");
- voTemplate.setBaseVoPath("com.monkeylessey.base");
+ voTemplate.setBaseVoPath("com.monkeylessey.sys.domain.base");
voTemplate.setTableSimpleName(WordsUtils.extractFirstLetters(tableInfo.getName(), "_"));
diff --git a/dev-sys/src/main/java/com/monkeylessey/gen/utils/GenerateCodeUtil.java b/dev-sys/src/main/java/com/monkeylessey/gen/utils/GenerateCodeUtil.java
index ff60eb0..0efa29f 100644
--- a/dev-sys/src/main/java/com/monkeylessey/gen/utils/GenerateCodeUtil.java
+++ b/dev-sys/src/main/java/com/monkeylessey/gen/utils/GenerateCodeUtil.java
@@ -116,12 +116,12 @@
.packageConfig(builder -> {
builder.parent("com.monkeylessey")
//.moduleName("onceCode")
- .entity("sys.domain.entity")
+ .entity("domain.entity")
.service("service")
.serviceImpl("service.impl")
.controller("controller")
.mapper("mapper")
- .other("sys.domain")
+ .other("domain")
.xml("mapper")
.pathInfo(Collections.singletonMap(OutputFile.other, finalOutDir + "\\domain"))
.pathInfo(Collections.singletonMap(OutputFile.xml, finalMapperDir));
diff --git a/dev-sys/src/main/resources/templates/serviceImpl.java.vm b/dev-sys/src/main/resources/templates/serviceImpl.java.vm
index 79c7aa0..b4fc2a5 100644
--- a/dev-sys/src/main/resources/templates/serviceImpl.java.vm
+++ b/dev-sys/src/main/resources/templates/serviceImpl.java.vm
@@ -14,9 +14,10 @@
#if(${entityLombokModel})
import lombok.RequiredArgsConstructor;
#end
-import com.ycl.jxkg.utils.PageUtil;
+import com.monkeylessey.utils.PageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
import java.util.stream.Collectors;
diff --git a/pom.xml b/pom.xml
index a13f860..b7f0825 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,6 +93,13 @@
<version>${version}</version>
</dependency>
+ <!-- 鍏叡妯″潡 -->
+ <dependency>
+ <groupId>com.monkeylessey</groupId>
+ <artifactId>ai-chat</artifactId>
+ <version>${version}</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
--
Gitblit v1.8.0