From 523dfa47b6b43525efb5db7f1b9fa2afbe8bf36a Mon Sep 17 00:00:00 2001 From: "zhouj1203@hotmail.com" Date: Tue, 20 Aug 2024 14:40:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A4=84=E7=90=86=E5=B9=B4=E7=BA=A7?= =?UTF-8?q?=E4=B8=8E=E7=8F=AD=E7=BA=A7=E6=95=B0=E6=8D=AE=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/CommonController.java | 35 ++++++++ .../admin/service/CommonService.java | 10 +++ .../admin/service/impl/CommonServiceImpl.java | 83 +++++++++++++++++++ .../model/dto/admin/common/GCDto.java | 9 ++ .../model/entity/school/ClassInfo.java | 1 + .../model/vo/admin/GradeAndClassVo.java | 23 +++++ .../teammodel/repository/ClassRepository.java | 2 + .../utils/MonthToNumberConverter.java | 36 ++++++++ 8 files changed, 199 insertions(+) create mode 100644 src/main/java/cn/teammodel/controller/admin/controller/CommonController.java create mode 100644 src/main/java/cn/teammodel/controller/admin/service/CommonService.java create mode 100644 src/main/java/cn/teammodel/controller/admin/service/impl/CommonServiceImpl.java create mode 100644 src/main/java/cn/teammodel/model/dto/admin/common/GCDto.java create mode 100644 src/main/java/cn/teammodel/model/vo/admin/GradeAndClassVo.java create mode 100644 src/main/java/cn/teammodel/utils/MonthToNumberConverter.java diff --git a/src/main/java/cn/teammodel/controller/admin/controller/CommonController.java b/src/main/java/cn/teammodel/controller/admin/controller/CommonController.java new file mode 100644 index 0000000..672aa1c --- /dev/null +++ b/src/main/java/cn/teammodel/controller/admin/controller/CommonController.java @@ -0,0 +1,35 @@ +package cn.teammodel.controller.admin.controller; + +import cn.teammodel.common.R; +import cn.teammodel.controller.admin.service.ArtService; +import cn.teammodel.controller.admin.service.CommonService; +import cn.teammodel.model.dto.admin.art.ArtFindDto; +import cn.teammodel.model.dto.admin.common.GCDto; +import cn.teammodel.model.vo.admin.ArtElementsVo; +import cn.teammodel.model.vo.admin.GradeAndClassVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("admin/common") +@Api(tags = "管理员端-公共组件") +public class CommonController { + + @Resource + private CommonService commonService ; + @PostMapping("getGradeAndClass") + @ApiOperation("获取当前学校当前学段年级班级信息") + public R> findRecords(@Valid @RequestBody GCDto gcDto) { + List res = commonService.getGradeAndClass(gcDto); + return R.success(res); + } +} diff --git a/src/main/java/cn/teammodel/controller/admin/service/CommonService.java b/src/main/java/cn/teammodel/controller/admin/service/CommonService.java new file mode 100644 index 0000000..5322efa --- /dev/null +++ b/src/main/java/cn/teammodel/controller/admin/service/CommonService.java @@ -0,0 +1,10 @@ +package cn.teammodel.controller.admin.service; + +import cn.teammodel.model.dto.admin.common.GCDto; +import cn.teammodel.model.vo.admin.GradeAndClassVo; +import org.springframework.stereotype.Service; + +import java.util.List; +public interface CommonService { + List getGradeAndClass(GCDto gcDto); +} diff --git a/src/main/java/cn/teammodel/controller/admin/service/impl/CommonServiceImpl.java b/src/main/java/cn/teammodel/controller/admin/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..87f5769 --- /dev/null +++ b/src/main/java/cn/teammodel/controller/admin/service/impl/CommonServiceImpl.java @@ -0,0 +1,83 @@ +package cn.teammodel.controller.admin.service.impl; + +import cn.teammodel.controller.admin.service.CommonService; +import cn.teammodel.model.dto.admin.common.GCDto; +import cn.teammodel.model.entity.school.ClassInfo; +import cn.teammodel.model.entity.school.School; +import cn.teammodel.model.vo.admin.GradeAndClassVo; +import cn.teammodel.repository.ClassRepository; +import cn.teammodel.repository.SchoolRepository; +import cn.teammodel.utils.MonthToNumberConverter; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.Month; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static java.time.LocalDate.now; + +@Service +public class CommonServiceImpl implements CommonService { + @Resource + private SchoolRepository schoolRepository; + @Resource + private ClassRepository classRepository; + + @Override + public List getGradeAndClass(GCDto gcDto) { + List gradeAndClassVos = new ArrayList<>(); + try { + //获取当前学校该学段下详细信息 + List period = schoolRepository.findPeriodById(gcDto.getSchoolId(), gcDto.getPeriodId()); + List classes = classRepository.findClassBySchoolIdAndPeriodId(gcDto.getSchoolId(), gcDto.getPeriodId()); + int year = now().getYear(); + Month month = now().getMonth(); + int mon = MonthToNumberConverter.convertMonthToNumber(month.name()); + int day = now().getDayOfMonth(); + //处理年级ID + for (ClassInfo classInfo : classes) { + if(period.get(0).getId().equalsIgnoreCase(classInfo.getPeriodId())) { + for (School.Semester semester : period.get(0).getSemesters()) { + int time = 0; + if(semester.getStart() == 1) { + if (mon == semester.getMonth()) + { + time = day >= semester.getDay() ? 0 : 1; + } + else + { + time = mon > semester.getMonth() ? 0 : 1; + } + int eYear = year - time; + classInfo.setGrade(eYear- classInfo.getYear()); + } + } + + } + } + List grades = period.get(0).getGrades(); + int index = 0; + for (String grade : grades) { + GradeAndClassVo gradeAndClassVo = new GradeAndClassVo(); + gradeAndClassVo.setGradeId(index); + gradeAndClassVo.setGradeName(grade); + classes.stream().filter(classInfo -> classInfo.getGrade() == gradeAndClassVo.getGradeId()).forEach(classInfo -> { + GradeAndClassVo.CI ci = new GradeAndClassVo.CI(); + ci.setClassId(classInfo.getId()); + ci.setClassName(classInfo.getName()); + gradeAndClassVo.AddClass(ci); + }); + index ++; + gradeAndClassVos.add(gradeAndClassVo); + } + + return gradeAndClassVos; + }catch (Exception e) { + + throw new RuntimeException("获取当前学校当前学段年级班级信息失败"); + } + } +} diff --git a/src/main/java/cn/teammodel/model/dto/admin/common/GCDto.java b/src/main/java/cn/teammodel/model/dto/admin/common/GCDto.java new file mode 100644 index 0000000..d3afa41 --- /dev/null +++ b/src/main/java/cn/teammodel/model/dto/admin/common/GCDto.java @@ -0,0 +1,9 @@ +package cn.teammodel.model.dto.admin.common; + +import lombok.Data; + +@Data +public class GCDto { + private String schoolId; + private String periodId; +} diff --git a/src/main/java/cn/teammodel/model/entity/school/ClassInfo.java b/src/main/java/cn/teammodel/model/entity/school/ClassInfo.java index 277ced8..3ccf33a 100644 --- a/src/main/java/cn/teammodel/model/entity/school/ClassInfo.java +++ b/src/main/java/cn/teammodel/model/entity/school/ClassInfo.java @@ -19,6 +19,7 @@ public class ClassInfo extends BaseItem { private String room; private String school; private Integer graduate; + private Integer grade; private String pk; private Integer ttl; diff --git a/src/main/java/cn/teammodel/model/vo/admin/GradeAndClassVo.java b/src/main/java/cn/teammodel/model/vo/admin/GradeAndClassVo.java new file mode 100644 index 0000000..7ceafc2 --- /dev/null +++ b/src/main/java/cn/teammodel/model/vo/admin/GradeAndClassVo.java @@ -0,0 +1,23 @@ +package cn.teammodel.model.vo.admin; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class GradeAndClassVo { + private int gradeId; + private String gradeName; + private List classes = new ArrayList<>(); + + public void AddClass(CI ci) { + this.classes.add(ci); + } + + @Data + public static class CI { + private String classId; + private String className; + } +} diff --git a/src/main/java/cn/teammodel/repository/ClassRepository.java b/src/main/java/cn/teammodel/repository/ClassRepository.java index 9da6a4b..b69920b 100644 --- a/src/main/java/cn/teammodel/repository/ClassRepository.java +++ b/src/main/java/cn/teammodel/repository/ClassRepository.java @@ -18,4 +18,6 @@ public interface ClassRepository extends CosmosRepository { @Query("select c.id, c.name from School as c where c.code = @code and c.id in (@ids)") List findAllByCodeAndIdIn(String code, Collection ids); + @Query("select c.id, c.name,c.year,c.periodId from School as c where c.school = @school and c.periodId = @periodId and c.pk = 'Class'") + List findClassBySchoolIdAndPeriodId(String school, String periodId); } diff --git a/src/main/java/cn/teammodel/utils/MonthToNumberConverter.java b/src/main/java/cn/teammodel/utils/MonthToNumberConverter.java new file mode 100644 index 0000000..1a3a908 --- /dev/null +++ b/src/main/java/cn/teammodel/utils/MonthToNumberConverter.java @@ -0,0 +1,36 @@ +package cn.teammodel.utils; + +import java.util.HashMap; +import java.util.Map; + +public class MonthToNumberConverter { + + private static final Map monthMap = createMonthMap(); + + private static Map createMonthMap() { + Map map = new HashMap<>(); + map.put("JANUARY", 1); + map.put("FEBRUARY", 2); + map.put("MARCH", 3); + map.put("APRIL", 4); + map.put("MAY", 5); + map.put("JUNE", 6); + map.put("JULY", 7); + map.put("AUGUST", 8); + map.put("SEPTEMBER", 9); + map.put("OCTOBER", 10); + map.put("NOVEMBER", 11); + map.put("DECEMBER", 12); + return map; + } + + public static int convertMonthToNumber(String monthName) { + return monthMap.getOrDefault(monthName, -1); // 如果找不到对应月份,则返回 -1 + } + + /* public static void main(String[] args) { + String month = "August"; + int monthNumber = convertMonthToNumber(month); + System.out.println("The number for " + month + " is: " + monthNumber); + }*/ +} \ No newline at end of file From e8dfcf7f9f463f19b852a20a77175a8770123442 Mon Sep 17 00:00:00 2001 From: PL <774412461@qq.com> Date: Tue, 20 Aug 2024 14:48:02 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E8=81=8A=E5=A4=A9=E8=AF=84=E8=AF=AD?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/frontend/AiController.java | 23 ++++- .../repository/ChatSessionRepository.java | 3 + .../teammodel/service/ChatMessageService.java | 7 ++ .../service/impl/ChatMessageServiceImpl.java | 88 +++++++++++++++++++ 4 files changed, 117 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/teammodel/controller/frontend/AiController.java b/src/main/java/cn/teammodel/controller/frontend/AiController.java index 2a7d2bd..d6b38ef 100644 --- a/src/main/java/cn/teammodel/controller/frontend/AiController.java +++ b/src/main/java/cn/teammodel/controller/frontend/AiController.java @@ -10,9 +10,11 @@ import cn.teammodel.security.utils.SecurityUtil; import cn.teammodel.service.ChatAppService; import cn.teammodel.service.ChatMessageService; import cn.teammodel.service.ChatSessionService; +import io.jsonwebtoken.Claims; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -147,9 +149,22 @@ public class AiController { return R.success("删除应用成功"); } - - - - + @PostMapping("chat/comments") + @ApiOperation("设置评语") + public SseEmitter chatComments(@RequestBody @Valid ChatCompletionReqDto chatCompletionReqDto) { + /* + Authentication user0 = SecurityUtil.getAuthentication(); + Object user01 = SecurityUtil.getAuthentication().getPrincipal(); + TmdUserDetail user02 = (TmdUserDetail) SecurityUtil.getAuthentication().getPrincipal(); + Claims user03 = ((TmdUserDetail) SecurityUtil.getAuthentication().getPrincipal()).getClaims(); + String user04 = ((TmdUserDetail) SecurityUtil.getAuthentication().getPrincipal()).getClaims().getSubject(); + */ + + //String userId = ((TmdUserDetail) SecurityUtil.getAuthentication().getPrincipal()).getClaims().getSubject(); + // 获取getClaims时为空 + String userId = ((TmdUserDetail) SecurityUtil.getAuthentication().getPrincipal()).getUser().getId(); + String userName = ((TmdUserDetail) SecurityUtil.getAuthentication().getPrincipal()).getUser().getName(); + return chatMessageService.chatComments(chatCompletionReqDto, userId, userName); + } } \ No newline at end of file diff --git a/src/main/java/cn/teammodel/repository/ChatSessionRepository.java b/src/main/java/cn/teammodel/repository/ChatSessionRepository.java index 26c82b2..5b117ea 100644 --- a/src/main/java/cn/teammodel/repository/ChatSessionRepository.java +++ b/src/main/java/cn/teammodel/repository/ChatSessionRepository.java @@ -22,4 +22,7 @@ public interface ChatSessionRepository extends CosmosRepository findLatestMessage(String sessionId); + + @Query("select c.id, c.code, c.title, c.userId, c.createTime from c where c.code = 'ChatSession' and c.id = @userId") + List findCommentsById(String userId); } diff --git a/src/main/java/cn/teammodel/service/ChatMessageService.java b/src/main/java/cn/teammodel/service/ChatMessageService.java index 8c68fab..ce0417c 100644 --- a/src/main/java/cn/teammodel/service/ChatMessageService.java +++ b/src/main/java/cn/teammodel/service/ChatMessageService.java @@ -12,4 +12,11 @@ public interface ChatMessageService { * AI 聊天 */ SseEmitter chatCompletion(ChatCompletionReqDto chatCompletionReqDto, String userId); + + /** + * AI 评语聊天 + * @param chatCompletionReqDto + * @return + */ + SseEmitter chatComments(ChatCompletionReqDto chatCompletionReqDto, String userId,String userName); } diff --git a/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java b/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java index c9f3f2e..fef3ea3 100644 --- a/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java +++ b/src/main/java/cn/teammodel/service/impl/ChatMessageServiceImpl.java @@ -1,5 +1,6 @@ package cn.teammodel.service.impl; +import cn.hutool.core.lang.UUID; import cn.teammodel.ai.SparkGptClient; import cn.teammodel.ai.SseHelper; import cn.teammodel.ai.cache.HistoryCache; @@ -27,6 +28,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import javax.annotation.Resource; import java.time.Instant; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -57,6 +59,25 @@ public class ChatMessageServiceImpl implements ChatMessageService { return sseEmitter; } + /** + * 评语调用 聊天模型 + * @param chatCompletionReqDto + * @param userId + * @return + */ + @Override + public SseEmitter chatComments(ChatCompletionReqDto chatCompletionReqDto, String userId,String userName) { + // 目前仅使用讯飞星火大模型 + String appId = chatCompletionReqDto.getAppId(); + SseEmitter sseEmitter; + if (StringUtils.isEmpty(appId)) { + sseEmitter = commentsBySession(chatCompletionReqDto, userId,userName); + } else { + sseEmitter = completionByApp(chatCompletionReqDto, false); + } + return sseEmitter; + } + /** * 面具模式(暂时不存储聊天记录) */ @@ -158,6 +179,73 @@ public class ChatMessageServiceImpl implements ChatMessageService { return sseEmitter; } + /** + * 评语 会话模式 + */ + private SseEmitter commentsBySession(ChatCompletionReqDto chatCompletionReqDto, String userId,String userName) { + String userPrompt = chatCompletionReqDto.getText(); + String sessionId = chatCompletionReqDto.getSessionId(); + + ChatSession session = null; + List sessions = chatSessionRepository.findCommentsById(userId); + if (sessions.size() == 0) { + // 初始化欢迎语 + ChatSession.Message message = ChatSession.Message.of("", "你好" + userName + " ,我是你的私人 AI 助手小豆,你可以问我任何包括但不仅限于教育的问题,我会尽力为您解答!"); + List history = Collections.singletonList(message); + session = new ChatSession(); + session.setId(userId); + session.setCode(PK.CHAT_SESSION); + session.setTitle("评语"); + session.setUserId(userId); + session.setCreateTime(Instant.now().toEpochMilli()); + session.setUpdateTime(Instant.now().toEpochMilli()); + session.setHistory(history); + chatSessionRepository.save(session); + }else { + session = RepositoryUtil.findOne(chatSessionRepository.findBySessionId(userId), "该会话不存在"); + } + + /* + ChatSession session = RepositoryUtil.findOne(chatSessionRepository.findBySessionId(sessionId), "该会话不存在"); + if (!session.getUserId().equals(userId)) { + throw new ServiceException(ErrorCode.NO_AUTH_ERROR.getCode(), "该会话不存在"); + }*/ + + SseEmitter sseEmitter = new SseEmitter(-1L); + SparkGptStreamListener listener = new SparkGptStreamListener(sseEmitter); + // open 回调 + listener.setOnOpen((s) -> { + // 敏感词检查,计费 (设计模型, reducePoints, 或者都可以在完成的回调中做?) + log.info("callback: ws open event emmit"); + }); + // 对话完成的回调 + listener.setOnComplete((s) -> { + log.info("callback: ws complete event emmit"); + SseHelper.send(sseEmitter, "[DONE]"); + // 处理完成后的事件: 保存消息记录, 缓存更改 + ChatSession.Message message = ChatSession.Message.of(userPrompt, s); + HistoryCache.updateContext(sessionId, message); + CosmosPatchOperations options = CosmosPatchOperations.create() + .replace("/updateTime", Instant.now().toEpochMilli()) + .add("/history/-", message); + chatSessionRepository.save(sessionId, PK.of(PK.CHAT_SESSION), ChatSession.class, options); + }); + // 错误的回调 + listener.setOnError((s) -> { + log.error("callback: ws error, info: " + s); + // 返还积分 + }); + List messageList = fetchContext(sessionId, userPrompt); + SparkChatRequestParam requestParam = SparkChatRequestParam + .builder() + .uid(userId) + .chatId(sessionId) + .messageList(messageList) + .build(); + sparkGptClient.streamChatCompletion(requestParam, listener); + return sseEmitter; + } + List fetchContext(String sessionId, String prompt) { List context = HistoryCache.getContext(sessionId); List paramMessages = new ArrayList<>(); From a70efb3c7b93f83ab3afa7736242f82cc9a632b5 Mon Sep 17 00:00:00 2001 From: CrazyIter_Bin Date: Tue, 20 Aug 2024 15:41:17 +0800 Subject: [PATCH 3/3] update --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 549e00a..e7775bf 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ build/ ### VS Code ### .vscode/ +/.vs