feat: 接入聊天历史界面与外链会话恢复
- 新增管理端与用户端聊天历史接口和页面 - 外链聊天支持访问令牌登录、身份保活与当前会话恢复 - 聊天执行链路切到统一 runtime 与 chatlog 查询接口
This commit is contained in:
@@ -16,6 +16,10 @@
|
||||
<groupId>tech.easyflow</groupId>
|
||||
<artifactId>easyflow-module-ai</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tech.easyflow</groupId>
|
||||
<artifactId>easyflow-module-chatlog</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tech.easyflow</groupId>
|
||||
<artifactId>easyflow-module-auth</artifactId>
|
||||
@@ -29,4 +33,4 @@
|
||||
<artifactId>easyflow-common-captcha</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -22,11 +22,15 @@ import tech.easyflow.ai.service.*;
|
||||
import tech.easyflow.ai.service.impl.BotServiceImpl;
|
||||
import tech.easyflow.common.audio.core.AudioServiceManager;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.common.web.controller.BaseCurdController;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
import tech.easyflow.common.web.jsonbody.JsonBody;
|
||||
import tech.easyflow.core.chat.protocol.sse.ChatSseEmitter;
|
||||
import tech.easyflow.core.chat.protocol.sse.ChatSseUtil;
|
||||
import tech.easyflow.core.runtime.ChatChannel;
|
||||
import tech.easyflow.core.runtime.ChatRuntimeContext;
|
||||
import tech.easyflow.system.entity.vo.RoleCategoryAccessSnapshot;
|
||||
import tech.easyflow.system.service.CategoryPermissionService;
|
||||
|
||||
@@ -158,7 +162,15 @@ public class BotController extends BaseCurdController<BotService, Bot> {
|
||||
if (errorEmitter != null) {
|
||||
return errorEmitter;
|
||||
}
|
||||
return botService.startChat(botId, prompt, conversationId, messages, chatCheckResult, attachments);
|
||||
return botService.startChat(
|
||||
botId,
|
||||
prompt,
|
||||
conversationId,
|
||||
messages,
|
||||
chatCheckResult,
|
||||
attachments,
|
||||
buildRuntimeContext(chatCheckResult.getAiBot(), conversationId, prompt, attachments)
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("updateLlmId")
|
||||
@@ -319,6 +331,24 @@ public class BotController extends BaseCurdController<BotService, Bot> {
|
||||
return result;
|
||||
}
|
||||
|
||||
private ChatRuntimeContext buildRuntimeContext(Bot bot, BigInteger conversationId, String prompt, List<String> attachments) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
ChatRuntimeContext context = new ChatRuntimeContext();
|
||||
context.setChannel(ChatChannel.ADMIN);
|
||||
context.setSessionId(conversationId);
|
||||
context.setTenantId(account == null ? BigInteger.ZERO : account.getTenantId());
|
||||
context.setDeptId(account == null ? BigInteger.ZERO : account.getDeptId());
|
||||
context.setUserId(account == null ? BigInteger.ZERO : account.getId());
|
||||
context.setUserAccount(account == null ? "admin" : account.getLoginName());
|
||||
context.setUserName(account == null ? "管理员" : (StringUtils.hasText(account.getNickname()) ? account.getNickname() : account.getLoginName()));
|
||||
context.setAssistantId(bot == null ? BigInteger.ZERO : bot.getId());
|
||||
context.setAssistantCode(bot == null ? null : bot.getAlias());
|
||||
context.setAssistantName(bot == null ? null : bot.getTitle());
|
||||
context.setSessionTitle(prompt.length() > 200 ? prompt.substring(0, 200) : prompt);
|
||||
context.setAttachments(attachments);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result<?> onRemoveBefore(Collection<Serializable> ids) {
|
||||
QueryWrapper queryWrapperKnowledge = QueryWrapper.create().in(BotDocumentCollection::getBotId, ids);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package tech.easyflow.admin.controller.ai;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatHistoryPage;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatSessionPage;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatSessionSummary;
|
||||
import tech.easyflow.chatlog.domain.query.ChatPageQuery;
|
||||
import tech.easyflow.chatlog.domain.query.ChatSessionFilterQuery;
|
||||
import tech.easyflow.chatlog.service.ChatHistoryManageService;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/chatHistory")
|
||||
public class ChatHistoryController {
|
||||
|
||||
private final ChatHistoryManageService chatHistoryManageService;
|
||||
|
||||
public ChatHistoryController(ChatHistoryManageService chatHistoryManageService) {
|
||||
this.chatHistoryManageService = chatHistoryManageService;
|
||||
}
|
||||
|
||||
@GetMapping("/sessions")
|
||||
public Result<ChatSessionPage> listSessions(ChatSessionFilterQuery query) {
|
||||
return Result.ok(chatHistoryManageService.queryAdminSessions(query));
|
||||
}
|
||||
|
||||
@GetMapping("/sessions/{sessionId}")
|
||||
public Result<ChatSessionSummary> getSession(@PathVariable BigInteger sessionId) {
|
||||
return Result.ok(chatHistoryManageService.getAdminSession(sessionId));
|
||||
}
|
||||
|
||||
@GetMapping("/sessions/{sessionId}/messages")
|
||||
public Result<ChatHistoryPage> queryMessages(@PathVariable BigInteger sessionId, ChatPageQuery query) {
|
||||
return Result.ok(chatHistoryManageService.queryAdminMessages(sessionId, query));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package tech.easyflow.admin.controller.ai;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.chatlog.domain.dto.PublicChatSessionRestoreResult;
|
||||
import tech.easyflow.chatlog.service.PublicChatSessionRestoreService;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/public-chat")
|
||||
public class PublicChatSessionController {
|
||||
|
||||
private final PublicChatSessionRestoreService publicChatSessionRestoreService;
|
||||
|
||||
public PublicChatSessionController(PublicChatSessionRestoreService publicChatSessionRestoreService) {
|
||||
this.publicChatSessionRestoreService = publicChatSessionRestoreService;
|
||||
}
|
||||
|
||||
@GetMapping("/session/restore")
|
||||
public Result<PublicChatSessionRestoreResult> restoreSession(BigInteger botId,
|
||||
BigInteger conversationId,
|
||||
Integer limit) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
BigInteger userId = account == null ? null : account.getId();
|
||||
PublicChatSessionRestoreResult result = publicChatSessionRestoreService.restoreSession(
|
||||
userId,
|
||||
botId,
|
||||
conversationId,
|
||||
limit
|
||||
);
|
||||
return Result.ok(result);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
package tech.easyflow.admin.controller.auth;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.auth.entity.LoginDTO;
|
||||
import tech.easyflow.auth.entity.LoginVO;
|
||||
import tech.easyflow.auth.service.AuthService;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.web.jsonbody.JsonBody;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
@@ -27,6 +28,12 @@ public class AuthController {
|
||||
return Result.ok(res);
|
||||
}
|
||||
|
||||
@PostMapping("loginByApiKey")
|
||||
@SaIgnore
|
||||
public Result<LoginVO> loginByApiKey(@JsonBody(value = "apiKey", required = true) String apiKey) {
|
||||
return Result.ok(authService.loginByApiKey(apiKey));
|
||||
}
|
||||
|
||||
@PostMapping("logout")
|
||||
public Result<Void> logout() {
|
||||
StpUtil.logout();
|
||||
|
||||
@@ -13,10 +13,13 @@ import tech.easyflow.ai.service.BotService;
|
||||
import tech.easyflow.ai.service.impl.BotServiceImpl;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.core.chat.protocol.sse.ChatSseUtil;
|
||||
import tech.easyflow.core.runtime.ChatChannel;
|
||||
import tech.easyflow.core.runtime.ChatRuntimeContext;
|
||||
import tech.easyflow.system.entity.SysApiKey;
|
||||
import tech.easyflow.system.service.SysApiKeyService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* bot 接口
|
||||
@@ -51,6 +54,7 @@ public class PublicBotController {
|
||||
return ChatSseUtil.sendSystemError(null, "Apikey不能为空!");
|
||||
}
|
||||
sysApiKeyService.checkApikeyPermission(apikey, requestURI);
|
||||
SysApiKey sysApiKey = sysApiKeyService.getSysApiKey(apikey);
|
||||
BotServiceImpl.ChatCheckResult chatCheckResult = new BotServiceImpl.ChatCheckResult();
|
||||
int size = chatRequestParams.getMessages().size();
|
||||
String prompt = null;
|
||||
@@ -62,7 +66,30 @@ public class PublicBotController {
|
||||
if (errorEmitter != null) {
|
||||
return errorEmitter;
|
||||
}
|
||||
return botService.startPublicChat(chatRequestParams.getBotId(), prompt, chatRequestParams.getMessages(), chatCheckResult);
|
||||
return botService.startPublicChat(
|
||||
chatRequestParams.getBotId(),
|
||||
prompt,
|
||||
chatRequestParams.getMessages(),
|
||||
chatCheckResult,
|
||||
buildRuntimeContext(chatCheckResult.getAiBot(), chatRequestParams.getConversationId(), prompt, sysApiKey)
|
||||
);
|
||||
}
|
||||
|
||||
private ChatRuntimeContext buildRuntimeContext(Bot bot, String conversationId, String prompt, SysApiKey sysApiKey) {
|
||||
ChatRuntimeContext context = new ChatRuntimeContext();
|
||||
context.setChannel(ChatChannel.PUBLIC_API);
|
||||
context.setSessionId(new BigInteger(conversationId));
|
||||
context.setTenantId(BigInteger.ZERO);
|
||||
context.setDeptId(BigInteger.ZERO);
|
||||
context.setUserId(BigInteger.ZERO);
|
||||
context.setUserAccount("apikey:" + sysApiKey.getId());
|
||||
context.setUserName("API 调用方");
|
||||
context.setAssistantId(bot == null ? BigInteger.ZERO : bot.getId());
|
||||
context.setAssistantCode(bot == null ? null : bot.getAlias());
|
||||
context.setAssistantName(bot == null ? null : bot.getTitle());
|
||||
context.setSessionTitle(prompt != null && prompt.length() > 200 ? prompt.substring(0, 200) : prompt);
|
||||
context.setAnonymous(true);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,10 +20,14 @@
|
||||
<groupId>tech.easyflow</groupId>
|
||||
<artifactId>easyflow-module-ai</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tech.easyflow</groupId>
|
||||
<artifactId>easyflow-module-chatlog</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tech.easyflow</groupId>
|
||||
<artifactId>easyflow-common-captcha</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -23,10 +23,13 @@ import tech.easyflow.ai.service.impl.BotServiceImpl;
|
||||
import tech.easyflow.common.annotation.UsePermission;
|
||||
import tech.easyflow.common.audio.core.AudioServiceManager;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.common.web.controller.BaseCurdController;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
import tech.easyflow.common.web.jsonbody.JsonBody;
|
||||
import tech.easyflow.core.runtime.ChatChannel;
|
||||
import tech.easyflow.core.runtime.ChatRuntimeContext;
|
||||
import tech.easyflow.system.entity.vo.RoleCategoryAccessSnapshot;
|
||||
import tech.easyflow.system.service.CategoryPermissionService;
|
||||
|
||||
@@ -75,8 +78,6 @@ public class UcBotController extends BaseCurdController<BotService, Bot> {
|
||||
@Resource
|
||||
private BotPluginService botPluginService;
|
||||
@Resource
|
||||
private BotConversationService conversationMessageService;
|
||||
@Resource
|
||||
private CategoryPermissionService categoryPermissionService;
|
||||
|
||||
@GetMapping("/generateConversationId")
|
||||
@@ -161,27 +162,16 @@ public class UcBotController extends BaseCurdController<BotService, Bot> {
|
||||
if (errorEmitter != null) {
|
||||
return errorEmitter;
|
||||
}
|
||||
BotConversation conversation = conversationMessageService.getById(conversationId);
|
||||
if (conversation == null) {
|
||||
conversation = new BotConversation();
|
||||
conversation.setId(conversationId);
|
||||
if (prompt.length() > 200) {
|
||||
conversation.setTitle(prompt.substring(0, 200));
|
||||
} else {
|
||||
conversation.setTitle(prompt);
|
||||
}
|
||||
conversation.setBotId(botId);
|
||||
conversation.setAccountId(SaTokenUtil.getLoginAccount().getId());
|
||||
commonFiled(conversation, SaTokenUtil.getLoginAccount().getId(), SaTokenUtil.getLoginAccount().getTenantId(), SaTokenUtil.getLoginAccount().getDeptId());
|
||||
try {
|
||||
conversationMessageService.save(conversation);
|
||||
} catch (DuplicateKeyException e) {
|
||||
// 并发重试场景下允许重复创建请求,唯一主键冲突按已创建处理。
|
||||
log.debug("conversation already exists, conversationId={}", conversationId, e);
|
||||
}
|
||||
}
|
||||
|
||||
return botService.startChat(botId, prompt, conversationId, messages, chatCheckResult, attachments);
|
||||
return botService.startChat(
|
||||
botId,
|
||||
prompt,
|
||||
conversationId,
|
||||
messages,
|
||||
chatCheckResult,
|
||||
attachments,
|
||||
buildRuntimeContext(chatCheckResult.getAiBot(), conversationId, prompt, attachments)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -296,6 +286,25 @@ public class UcBotController extends BaseCurdController<BotService, Bot> {
|
||||
return super.onSaveOrUpdateBefore(entity, isSave);
|
||||
}
|
||||
|
||||
private ChatRuntimeContext buildRuntimeContext(Bot bot, BigInteger conversationId, String prompt, List<String> attachments) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
ChatRuntimeContext context = new ChatRuntimeContext();
|
||||
context.setChannel(ChatChannel.USER_CENTER);
|
||||
context.setSessionId(conversationId);
|
||||
context.setTenantId(account == null ? BigInteger.ZERO : account.getTenantId());
|
||||
context.setDeptId(account == null ? BigInteger.ZERO : account.getDeptId());
|
||||
context.setUserId(account == null ? BigInteger.ZERO : account.getId());
|
||||
context.setUserAccount(account == null ? "anonymous" : account.getLoginName());
|
||||
context.setUserName(account == null ? "匿名用户" : (StringUtils.hasText(account.getNickname()) ? account.getNickname() : account.getLoginName()));
|
||||
context.setAssistantId(bot == null ? BigInteger.ZERO : bot.getId());
|
||||
context.setAssistantCode(bot == null ? null : bot.getAlias());
|
||||
context.setAssistantName(bot == null ? null : bot.getTitle());
|
||||
context.setSessionTitle(prompt.length() > 200 ? prompt.substring(0, 200) : prompt);
|
||||
context.setAnonymous(account == null || BigInteger.ZERO.equals(account.getId()));
|
||||
context.setAttachments(attachments);
|
||||
return context;
|
||||
}
|
||||
|
||||
private Map<String, Object> getDefaultLlmOptions() {
|
||||
Map<String, Object> defaultLlmOptions = new HashMap<>();
|
||||
defaultLlmOptions.put("temperature", 0.7);
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
package tech.easyflow.usercenter.controller.ai;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.ai.entity.BotConversation;
|
||||
import tech.easyflow.ai.service.BotConversationService;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.common.web.controller.BaseCurdController;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/userCenter/botConversation")
|
||||
@SaIgnore
|
||||
public class UcBotConversationController extends BaseCurdController<BotConversationService, BotConversation> {
|
||||
|
||||
@Resource
|
||||
private BotConversationService conversationMessageService;
|
||||
|
||||
public UcBotConversationController(BotConversationService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定会话
|
||||
*/
|
||||
@GetMapping("/deleteConversation")
|
||||
public Result<Void> deleteConversation(String botId, String conversationId) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
conversationMessageService.deleteConversation(botId, conversationId, account.getId());
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新会话标题
|
||||
*/
|
||||
@GetMapping("/updateConversation")
|
||||
public Result<Void> updateConversation(String botId, String conversationId, String title) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
conversationMessageService.updateConversation(botId, conversationId, title, account.getId());
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<BotConversation>> list(BotConversation entity, Boolean asTree, String sortKey, String sortType) {
|
||||
entity.setAccountId(SaTokenUtil.getLoginAccount().getId());
|
||||
sortKey = "created";
|
||||
sortType = "desc";
|
||||
return super.list(entity, asTree, sortKey, sortType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result<?> onSaveOrUpdateBefore(BotConversation entity, boolean isSave) {
|
||||
entity.setAccountId(SaTokenUtil.getLoginAccount().getId());
|
||||
entity.setCreated(new Date());
|
||||
return super.onSaveOrUpdateBefore(entity, isSave);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询会话列表
|
||||
*
|
||||
* @param request 查询数据
|
||||
* @param sortKey 排序字段
|
||||
* @param sortType 排序方式 asc | desc
|
||||
* @param pageNumber 当前页码
|
||||
* @param pageSize 每页的数据量
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("pageList")
|
||||
public Result<Page<BotConversation>> page(HttpServletRequest request, String sortKey, String sortType, Long pageNumber, Long pageSize) {
|
||||
if (pageNumber == null || pageNumber < 1) {
|
||||
pageNumber = 1L;
|
||||
}
|
||||
if (pageSize == null || pageSize < 1) {
|
||||
pageSize = 10L;
|
||||
}
|
||||
|
||||
QueryWrapper queryWrapper = buildQueryWrapper(request);
|
||||
queryWrapper.orderBy(buildOrderBy(sortKey, sortType, getDefaultOrderBy()));
|
||||
Page<BotConversation> botConversationPage = service.getMapper().paginateWithRelations(pageNumber, pageSize, queryWrapper);
|
||||
return Result.ok(botConversationPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表主键查询数据详情。
|
||||
*
|
||||
* @param id 主键值
|
||||
* @return 内容详情
|
||||
*/
|
||||
@GetMapping("detail")
|
||||
@SaIgnore
|
||||
public Result<BotConversation> detail(String id) {
|
||||
if (tech.easyflow.common.util.StringUtil.noText(id)) {
|
||||
throw new BusinessException("id must not be null");
|
||||
}
|
||||
return Result.ok(service.getMapper().selectOneWithRelationsById(id));
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package tech.easyflow.usercenter.controller.ai;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.ai.entity.BotMessage;
|
||||
import tech.easyflow.ai.service.BotMessageService;
|
||||
import tech.easyflow.ai.vo.ChatMessageVO;
|
||||
import tech.easyflow.common.annotation.UsePermission;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.common.web.controller.BaseCurdController;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Bot 消息记录表 控制层。
|
||||
*
|
||||
* @author michael
|
||||
* @since 2024-11-04
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/userCenter/botMessage")
|
||||
@UsePermission(moduleName = "/api/v1/bot")
|
||||
public class UcBotMessageController extends BaseCurdController<BotMessageService, BotMessage> {
|
||||
private final BotMessageService botMessageService;
|
||||
|
||||
public UcBotMessageController(BotMessageService service, BotMessageService botMessageService) {
|
||||
super(service);
|
||||
this.botMessageService = botMessageService;
|
||||
}
|
||||
|
||||
@GetMapping("/getMessages")
|
||||
@SaIgnore
|
||||
public Result<List<ChatMessageVO>> getMessages(BigInteger botId, BigInteger conversationId) {
|
||||
List<ChatMessageVO> res = new ArrayList<>();
|
||||
QueryWrapper w = QueryWrapper.create();
|
||||
w.eq(BotMessage::getBotId, botId);
|
||||
w.eq(BotMessage::getConversationId, conversationId);
|
||||
List<BotMessage> list = botMessageService.list(w);
|
||||
if (CollectionUtil.isNotEmpty(list)) {
|
||||
for (BotMessage message : list) {
|
||||
ChatMessageVO vo = new ChatMessageVO();
|
||||
vo.setKey(message.getId().toString());
|
||||
vo.setRole(message.getRole());
|
||||
vo.setContent(JSON.parseObject(message.getContent()).getString("textContent"));
|
||||
vo.setPlacement("user".equals(message.getRole()) ? "end" : "start");
|
||||
vo.setCreated(message.getCreated());
|
||||
res.add(vo);
|
||||
}
|
||||
}
|
||||
return Result.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package tech.easyflow.usercenter.controller.ai;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatHistoryPage;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatSessionPage;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatSessionSummary;
|
||||
import tech.easyflow.chatlog.domain.query.ChatPageQuery;
|
||||
import tech.easyflow.chatlog.service.ChatHistoryManageService;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.common.web.jsonbody.JsonBody;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/userCenter/chatHistory")
|
||||
@SaIgnore
|
||||
public class UcChatHistoryController {
|
||||
|
||||
private final ChatHistoryManageService chatHistoryManageService;
|
||||
|
||||
public UcChatHistoryController(ChatHistoryManageService chatHistoryManageService) {
|
||||
this.chatHistoryManageService = chatHistoryManageService;
|
||||
}
|
||||
|
||||
@GetMapping("/sessions")
|
||||
public Result<ChatSessionPage> listSessions(BigInteger assistantId, ChatPageQuery query) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(chatHistoryManageService.queryUserSessions(account.getId(), assistantId, query));
|
||||
}
|
||||
|
||||
@GetMapping("/sessions/{sessionId}")
|
||||
public Result<ChatSessionSummary> getSession(@PathVariable BigInteger sessionId) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(chatHistoryManageService.getUserSession(account.getId(), sessionId));
|
||||
}
|
||||
|
||||
@GetMapping("/sessions/{sessionId}/messages")
|
||||
public Result<ChatHistoryPage> queryMessages(@PathVariable BigInteger sessionId, ChatPageQuery query) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
return Result.ok(chatHistoryManageService.queryUserMessages(account.getId(), sessionId, query));
|
||||
}
|
||||
|
||||
@PostMapping("/sessions/{sessionId}/rename")
|
||||
public Result<Void> renameSession(@PathVariable BigInteger sessionId,
|
||||
@JsonBody(value = "title", required = true) String title) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
chatHistoryManageService.renameUserSession(account.getId(), sessionId, title, account.getId());
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/sessions/{sessionId}/delete")
|
||||
public Result<Void> deleteSession(@PathVariable BigInteger sessionId) {
|
||||
LoginAccount account = SaTokenUtil.getLoginAccount();
|
||||
chatHistoryManageService.deleteUserSession(account.getId(), sessionId, account.getId());
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user