parent
fee64cb1ac
commit
6ea7454973
@ -0,0 +1,21 @@
|
||||
package cn.teammodel.dao;
|
||||
|
||||
import cn.teammodel.model.entity.ai.ChatSession;
|
||||
import com.azure.spring.data.cosmos.repository.CosmosRepository;
|
||||
import com.azure.spring.data.cosmos.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-11-28 17:39
|
||||
*/
|
||||
@Repository
|
||||
public interface ChatSessionRepository extends CosmosRepository<ChatSession, String> {
|
||||
@Query("select c.id, c.code, c.title, c.userId, c.createTime from c where c.code = 'ChatSession' and c.sessionId = @sessionId")
|
||||
List<ChatSession> findBySessionId(String sessionId);
|
||||
|
||||
@Query("select c.id, c.code, c.title, c.userId, c.createTime from c where c.code = 'ChatSession' and c.userId = @userId")
|
||||
List<ChatSession> findByUserId(String userId);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.teammodel.model.dto.ai;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-19 15:42
|
||||
*/
|
||||
@Data
|
||||
public class UpdateSessionDto {
|
||||
@ApiModelProperty(value = "session id", required = true)
|
||||
@NotBlank
|
||||
private String id;
|
||||
private String title;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package cn.teammodel.model.entity.ai;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.teammodel.model.entity.BaseItem;
|
||||
import com.azure.spring.data.cosmos.core.mapping.Container;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 聊天会话,绑定 teacherId(userId), 主键id: sessionId
|
||||
* @author winter
|
||||
* @create 2023-12-19 15:09
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Container(containerName = "Teacher")
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ChatSession extends BaseItem {
|
||||
/**
|
||||
* 会话名称
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 用户 id
|
||||
*/
|
||||
private String userId;
|
||||
private Long createTime;
|
||||
/**
|
||||
* 产生对话即更新时间,按更新时间排序
|
||||
*/
|
||||
private Long updateTime;
|
||||
private List<Message> history;
|
||||
|
||||
@Data
|
||||
public static class Message {
|
||||
private String id;
|
||||
private String userText;
|
||||
private String gptText;
|
||||
/**
|
||||
* 消耗的 point
|
||||
*/
|
||||
private Integer cost;
|
||||
private Long createTime;
|
||||
|
||||
public static Message ofUserText(String userText) {
|
||||
Message message = new Message();
|
||||
message.setId(UUID.randomUUID().toString());
|
||||
message.setCost(0);
|
||||
message.setUserText(userText);
|
||||
message.setCreateTime(Instant.now().toEpochMilli());
|
||||
return message;
|
||||
}
|
||||
|
||||
public static Message ofGptText(String gptText) {
|
||||
Message message = new Message();
|
||||
message.setId(UUID.randomUUID().toString());
|
||||
message.setCost(0);
|
||||
message.setGptText(gptText);
|
||||
message.setCreateTime(Instant.now().toEpochMilli());
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.teammodel.service;
|
||||
|
||||
import cn.teammodel.model.dto.ai.UpdateSessionDto;
|
||||
import cn.teammodel.model.entity.ai.ChatSession;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-19 15:30
|
||||
*/
|
||||
public interface ChatSessionService {
|
||||
|
||||
void createSession();
|
||||
|
||||
List<ChatSession> listMySession();
|
||||
|
||||
ChatSession updateSession(UpdateSessionDto updateSessionDto);
|
||||
|
||||
void deleteSession(String id);
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package cn.teammodel.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.teammodel.common.ErrorCode;
|
||||
import cn.teammodel.common.PK;
|
||||
import cn.teammodel.config.exception.ServiceException;
|
||||
import cn.teammodel.dao.ChatSessionRepository;
|
||||
import cn.teammodel.model.dto.ai.UpdateSessionDto;
|
||||
import cn.teammodel.model.entity.User;
|
||||
import cn.teammodel.model.entity.ai.ChatSession;
|
||||
import cn.teammodel.model.entity.ai.ChatSession.Message;
|
||||
import cn.teammodel.security.utils.SecurityUtil;
|
||||
import cn.teammodel.service.ChatSessionService;
|
||||
import cn.teammodel.utils.RepositoryUtil;
|
||||
import com.azure.cosmos.models.CosmosPatchOperations;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author winter
|
||||
* @create 2023-12-19 15:31
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ChatSessionServiceImpl implements ChatSessionService {
|
||||
@Resource
|
||||
private ChatSessionRepository chatSessionRepository;
|
||||
|
||||
@Override
|
||||
public void createSession() {
|
||||
User user = SecurityUtil.getLoginUser();
|
||||
String userId = user.getId();
|
||||
// 初始化欢迎语
|
||||
Message message = Message.ofGptText("你好 " + user.getName() + " ,我是你的私人 AI 助手小豆,你可以问我任何包括但不仅限于教育的问题,我会尽力为您解答!");
|
||||
List<Message> history = Collections.singletonList(message);
|
||||
ChatSession chatSession = new ChatSession();
|
||||
chatSession.setId(UUID.randomUUID().toString());
|
||||
chatSession.setCode(PK.CHAT_SESSION);
|
||||
chatSession.setTitle("新对话");
|
||||
chatSession.setUserId(userId);
|
||||
chatSession.setCreateTime(Instant.now().toEpochMilli());
|
||||
chatSession.setUpdateTime(Instant.now().toEpochMilli());
|
||||
chatSession.setHistory(history);
|
||||
chatSessionRepository.save(chatSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatSession> listMySession() {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
List<ChatSession> sessions = chatSessionRepository.findByUserId(userId);
|
||||
// 按更新时间排序
|
||||
sessions = sessions.stream().sorted(Comparator.comparing(ChatSession::getUpdateTime)).collect(Collectors.toList());
|
||||
return sessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatSession updateSession(UpdateSessionDto updateSessionDto) {
|
||||
String id = updateSessionDto.getId();
|
||||
String title = updateSessionDto.getTitle();
|
||||
User user = SecurityUtil.getLoginUser();
|
||||
String userId = user.getId();
|
||||
|
||||
ChatSession session = RepositoryUtil.findOne(chatSessionRepository.findBySessionId(id), "");
|
||||
if (!session.getUserId().equals(userId)) {
|
||||
throw new ServiceException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
CosmosPatchOperations options = CosmosPatchOperations.create()
|
||||
.replace("/title", title);
|
||||
chatSessionRepository.save(id, PK.of(PK.CHAT_SESSION),ChatSession.class, options);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSession(String id) {
|
||||
User user = SecurityUtil.getLoginUser();
|
||||
String userId = user.getId();
|
||||
ChatSession session = RepositoryUtil.findOne(chatSessionRepository.findBySessionId(id), "该会话不存在");
|
||||
// 鉴权
|
||||
if (!session.getUserId().equals(userId)) {
|
||||
throw new ServiceException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
chatSessionRepository.deleteById(id, PK.of(PK.CHAT_SESSION));
|
||||
}
|
||||
}
|
Loading…
Reference in new issue