|
|
@@ -0,0 +1,360 @@
|
|
|
+package com.xjrsoft.module.teacher.service.impl;
|
|
|
+
|
|
|
+import cn.dev33.satoken.stp.StpUtil;
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.github.yulichang.base.MPJBaseServiceImpl;
|
|
|
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
+import com.xjrsoft.common.enums.DeleteMark;
|
|
|
+import com.xjrsoft.common.enums.RoleEnum;
|
|
|
+import com.xjrsoft.common.exception.MyException;
|
|
|
+import com.xjrsoft.common.model.result.RT;
|
|
|
+import com.xjrsoft.common.page.ConventPage;
|
|
|
+import com.xjrsoft.common.utils.VoToColumnUtil;
|
|
|
+import com.xjrsoft.module.base.entity.BaseClass;
|
|
|
+import com.xjrsoft.module.base.entity.BaseCourseSubject;
|
|
|
+import com.xjrsoft.module.base.entity.BaseUserStudent;
|
|
|
+import com.xjrsoft.module.base.service.IBaseUserStudentService;
|
|
|
+import com.xjrsoft.module.evaluate.entity.EvaluateExecuter;
|
|
|
+import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
|
|
|
+import com.xjrsoft.module.organization.entity.User;
|
|
|
+import com.xjrsoft.module.organization.entity.UserRoleRelation;
|
|
|
+import com.xjrsoft.module.organization.entity.UserStudent;
|
|
|
+import com.xjrsoft.module.organization.mapper.UserMapper;
|
|
|
+import com.xjrsoft.module.organization.service.IWeChatService;
|
|
|
+import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
|
|
|
+import com.xjrsoft.module.student.service.IBaseStudentSchoolRollService;
|
|
|
+import com.xjrsoft.module.system.entity.File;
|
|
|
+import com.xjrsoft.module.system.mapper.FileMapper;
|
|
|
+import com.xjrsoft.module.system.service.IFileService;
|
|
|
+import com.xjrsoft.module.teacher.dto.AddClassHomeworkDto;
|
|
|
+import com.xjrsoft.module.teacher.dto.AddClassHomeworkReadDto;
|
|
|
+import com.xjrsoft.module.teacher.dto.ClassHomeworkPageDto;
|
|
|
+import com.xjrsoft.module.teacher.dto.ClassHomeworkReadListDto;
|
|
|
+import com.xjrsoft.module.teacher.entity.ClassHomework;
|
|
|
+import com.xjrsoft.module.teacher.entity.ClassHomeworkClass;
|
|
|
+import com.xjrsoft.module.teacher.entity.ClassHomeworkRead;
|
|
|
+import com.xjrsoft.module.teacher.entity.XjrUser;
|
|
|
+import com.xjrsoft.module.teacher.mapper.ClassHomeworkClassMapper;
|
|
|
+import com.xjrsoft.module.teacher.mapper.ClassHomeworkMapper;
|
|
|
+import com.xjrsoft.module.teacher.mapper.ClassHomeworkReadMapper;
|
|
|
+import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
|
|
|
+import com.xjrsoft.module.teacher.service.IClassHomeworkService;
|
|
|
+import com.xjrsoft.module.teacher.vo.ClassHomeworkPageVo;
|
|
|
+import com.xjrsoft.module.teacher.vo.ClassHomeworkReadListVo;
|
|
|
+import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.collections.MapUtils;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.text.ParseException;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @title: 教师为班级布置作业记录表
|
|
|
+ * @Author szs
|
|
|
+ * @Date: 2025-04-27
|
|
|
+ * @Version 1.0
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@AllArgsConstructor
|
|
|
+public class ClassHomeworkServiceImpl extends MPJBaseServiceImpl<ClassHomeworkMapper, ClassHomework> implements IClassHomeworkService {
|
|
|
+
|
|
|
+ private final IWeChatService weChatService;
|
|
|
+ private final UserMapper userMapper;
|
|
|
+ private final IBaseStudentSchoolRollService rollService;
|
|
|
+ private final IBaseUserStudentService userStudentService;
|
|
|
+ private final IFileService fileService;
|
|
|
+ private final XjrUserMapper xjrUserMapper;
|
|
|
+ private final ClassHomeworkReadMapper classHomeworkReadMapper;
|
|
|
+ private final ClassHomeworkClassMapper classHomeworkClassMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<ClassHomeworkPageVo> pageClassHomework(ClassHomeworkPageDto dto) {
|
|
|
+ // 需要划分权限
|
|
|
+ // 教职工看到自己发的所有的,学生和家长看到自己的
|
|
|
+ List<String> roleList = StpUtil.getRoleList();
|
|
|
+ long userId = StpUtil.getLoginIdAsLong();
|
|
|
+
|
|
|
+ int roleType = 1;
|
|
|
+
|
|
|
+ List<Long> classIds = new ArrayList<>();
|
|
|
+
|
|
|
+ if (roleList.contains("TEACHER")) {
|
|
|
+ roleType = 2;
|
|
|
+ }
|
|
|
+ if (roleList.contains("STUDENT")) {
|
|
|
+ roleType = 3;
|
|
|
+ classIds.add(rollService.getClassIdByUserId(userId));
|
|
|
+ }
|
|
|
+ if (roleList.contains("PARENT")) {
|
|
|
+ roleType = 3;
|
|
|
+ List<BaseUserStudent> list = userStudentService.list(new QueryWrapper<BaseUserStudent>().lambda().eq(BaseUserStudent::getUserId, userId));
|
|
|
+ for (BaseUserStudent userStudent : list) {
|
|
|
+ classIds.add(rollService.getClassIdByUserId(userStudent.getStudentId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ MPJLambdaWrapper<ClassHomework> queryWrapper = new MPJLambdaWrapper<>();
|
|
|
+ queryWrapper
|
|
|
+ .disableSubLogicDel()
|
|
|
+ .select(ClassHomework::getId)
|
|
|
+ .select(ClassHomework.class,x -> VoToColumnUtil.fieldsToColumns(ClassHomeworkPageVo.class).contains(x.getProperty()))
|
|
|
+ .select("(select\n" +
|
|
|
+ " group_concat(b.name)\n" +
|
|
|
+ " from class_homework_class a\n" +
|
|
|
+ " inner join base_class b on a.class_id = b.id\n" +
|
|
|
+ " where a.class_homework_id = t.id\n" +
|
|
|
+ " ) as class_id_cns")
|
|
|
+ .select("(select\n" +
|
|
|
+ " group_concat(a.class_id)\n" +
|
|
|
+ " from class_homework_class a\n" +
|
|
|
+ " where a.class_homework_id = t.id\n" +
|
|
|
+ " ) as class_ids")
|
|
|
+ .leftJoin(XjrUser.class, XjrUser::getId, ClassHomework::getTeacherId,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(XjrUser::getName, ClassHomeworkPageVo::getTeacherIdCn)
|
|
|
+ )
|
|
|
+ .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, ClassHomework::getBaseCourseSubjectId,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(BaseCourseSubject::getName, ClassHomeworkPageVo::getBaseCourseSubjectIdCn)
|
|
|
+ )
|
|
|
+ .eq(ObjectUtils.isNotEmpty(dto.getBaseCourseSubjectId()), ClassHomework::getBaseCourseSubjectId, dto.getBaseCourseSubjectId())
|
|
|
+ .ge(ObjectUtils.isNotEmpty(dto.getStartDate()), ClassHomework::getCreateDate, dto.getStartDate())
|
|
|
+ .le(ObjectUtils.isNotEmpty(dto.getEndDate()), ClassHomework::getCreateDate, dto.getEndDate())
|
|
|
+ .orderByDesc(ClassHomework::getCreateDate)
|
|
|
+ ;
|
|
|
+ if(roleType == 2){
|
|
|
+ queryWrapper
|
|
|
+ .eq(ClassHomework::getTeacherId, userId);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(roleType == 3){
|
|
|
+ queryWrapper
|
|
|
+ .innerJoin(ClassHomeworkClass.class, ClassHomeworkClass::getClassHomeworkId, ClassHomework::getId)
|
|
|
+ .in(CollectionUtils.isNotEmpty(classIds), ClassHomeworkClass::getClassId, classIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ IPage<ClassHomeworkPageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), ClassHomeworkPageVo.class, queryWrapper);
|
|
|
+
|
|
|
+ for (ClassHomeworkPageVo vo : page.getRecords()){
|
|
|
+ if(ObjectUtils.isNotEmpty(vo.getFolderId())){
|
|
|
+ List<File> files = fileService.list(Wrappers.<File>query().lambda().eq(File::getFolderId, vo.getFolderId()));
|
|
|
+ vo.setFiles(files);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean addClassHomework(AddClassHomeworkDto dto) {
|
|
|
+ Long loginId = StpUtil.getLoginIdAsLong();
|
|
|
+ LocalDateTime nowLocalDateTime = LocalDateTime.now();
|
|
|
+
|
|
|
+ ClassHomework classHomework = BeanUtil.toBean(dto, ClassHomework.class);
|
|
|
+ classHomework.setTeacherId(loginId);
|
|
|
+
|
|
|
+ classHomework.setCreateUserId(loginId);
|
|
|
+ classHomework.setCreateDate(nowLocalDateTime);
|
|
|
+
|
|
|
+ this.save(classHomework);
|
|
|
+ for (Long classId : dto.getClassIds()){
|
|
|
+ ClassHomeworkClass classHomeworkClass = new ClassHomeworkClass();
|
|
|
+ classHomeworkClass.setClassHomeworkId(classHomework.getId());
|
|
|
+ classHomeworkClass.setClassId(classId);
|
|
|
+
|
|
|
+ classHomeworkClass.setCreateUserId(loginId);
|
|
|
+ classHomeworkClass.setCreateDate(nowLocalDateTime);
|
|
|
+
|
|
|
+ classHomeworkClassMapper.insert(classHomeworkClass);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 发送通知
|
|
|
+ // 找到班上所有的学生
|
|
|
+ MPJLambdaWrapper<User> stuMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ stuMPJLambdaWrapper
|
|
|
+ .distinct()
|
|
|
+ .select(User::getId)
|
|
|
+ .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
|
|
|
+ .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, User::getId)
|
|
|
+ .in(BaseStudentSchoolRoll::getClassId, dto.getClassIds());
|
|
|
+ List<User> stuList = userMapper.selectJoinList(User.class, stuMPJLambdaWrapper);
|
|
|
+
|
|
|
+ // 找到班上所有的学生的家长
|
|
|
+ MPJLambdaWrapper<User> parentMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ parentMPJLambdaWrapper
|
|
|
+ .distinct()
|
|
|
+ .disableSubLogicDel()
|
|
|
+ .select(User::getId).select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
|
|
|
+ .leftJoin(UserStudent.class, UserStudent::getUserId, User::getId)
|
|
|
+ .leftJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, UserStudent::getId)
|
|
|
+ .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, User::getId)
|
|
|
+ .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
|
|
|
+ .in(BaseStudentSchoolRoll::getClassId, dto.getClassIds());
|
|
|
+ List<User> parentList = userMapper.selectJoinList(User.class, parentMPJLambdaWrapper);
|
|
|
+
|
|
|
+ // 合并两个列表,并根据 User 的 id 去重
|
|
|
+ List<User> combinedList = new ArrayList<>(Stream.concat(stuList.stream(), parentList.stream())
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ User::getId, // 键:User 的 id
|
|
|
+ user -> user, // 值:User 对象本身
|
|
|
+ (existing, replacement) -> existing // 如果有重复的键,保留旧值(existing)
|
|
|
+ ))
|
|
|
+ .values());
|
|
|
+
|
|
|
+ // 发布作业的教师
|
|
|
+ User releaseUser = userMapper.selectById(loginId);
|
|
|
+
|
|
|
+ try {
|
|
|
+ for (User user : combinedList) {
|
|
|
+ WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
|
|
|
+ weChatSendMessageDto.setUserId(user.getOpenId());
|
|
|
+ weChatSendMessageDto.setTemplateId("qmpXORPM1Cocqn503Qa4On6BJhR92UZ00eod2-6IcGo");
|
|
|
+ weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
|
|
|
+ JSONObject paramJson = new JSONObject();
|
|
|
+
|
|
|
+ JSONObject thing23 = new JSONObject();
|
|
|
+ thing23.put("value", dto.getTitle());
|
|
|
+ paramJson.put("thing23", thing23);
|
|
|
+
|
|
|
+ JSONObject thing29 = new JSONObject();
|
|
|
+ thing29.put("value", releaseUser.getName());
|
|
|
+ paramJson.put("thing29", thing29);
|
|
|
+
|
|
|
+ JSONObject time17Json = new JSONObject();
|
|
|
+ time17Json.put("value", dto.getCompletionDeadline());
|
|
|
+ paramJson.put("time17", time17Json);
|
|
|
+
|
|
|
+ weChatSendMessageDto.setContent(paramJson);
|
|
|
+ weChatService.sendTemplateMessage(weChatSendMessageDto);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送消息错误,Error processing event data", e);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ClassHomeworkReadListVo> listClassHomeworkRead(ClassHomeworkReadListDto dto) {
|
|
|
+ ClassHomework classHomework = this.getById(dto.getClassHomeworkId());
|
|
|
+ if (ObjectUtils.isEmpty(classHomework)) {
|
|
|
+ throw new MyException("当前作业被修改,请刷新重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前所有班级所有的学生
|
|
|
+ MPJLambdaWrapper<XjrUser> xjrUserMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ xjrUserMPJLambdaWrapper
|
|
|
+ .selectAs(XjrUser::getId, ClassHomeworkReadListVo::getUserId)
|
|
|
+ .selectAs(XjrUser::getName, ClassHomeworkReadListVo::getUserIdCn)
|
|
|
+ .select("0 as is_read")
|
|
|
+ .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId)
|
|
|
+ ;
|
|
|
+
|
|
|
+ if(ObjectUtils.isEmpty(dto.getClassId())){
|
|
|
+ LambdaQueryWrapper<ClassHomeworkClass> classLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ classLambdaQueryWrapper
|
|
|
+ .eq(ClassHomeworkClass::getClassHomeworkId, dto.getClassHomeworkId())
|
|
|
+ .eq(ClassHomeworkClass::getDeleteMark, DeleteMark.NODELETE.getCode())
|
|
|
+ ;
|
|
|
+
|
|
|
+ List<ClassHomeworkClass> classHomeworkClassList = classHomeworkClassMapper.selectList(classLambdaQueryWrapper);
|
|
|
+ if(CollectionUtils.isEmpty(classHomeworkClassList)){
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取 classId 并去重
|
|
|
+ List<Long> uniqueClassIds = classHomeworkClassList.stream()
|
|
|
+ .map(ClassHomeworkClass::getClassId) // 提取 classId
|
|
|
+ .distinct() // 去重
|
|
|
+ .collect(Collectors.toList()); // 收集为 List
|
|
|
+
|
|
|
+ xjrUserMPJLambdaWrapper
|
|
|
+ .in(BaseStudentSchoolRoll::getClassId, uniqueClassIds);
|
|
|
+ }else {
|
|
|
+ xjrUserMPJLambdaWrapper
|
|
|
+ .eq(BaseStudentSchoolRoll::getClassId, dto.getClassId());
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ClassHomeworkReadListVo> list = xjrUserMapper.selectJoinList(ClassHomeworkReadListVo.class, xjrUserMPJLambdaWrapper);
|
|
|
+
|
|
|
+ // 获取当前作业已经阅读情况
|
|
|
+ LambdaQueryWrapper<ClassHomeworkRead> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper
|
|
|
+ .select(ClassHomeworkRead.class, x -> VoToColumnUtil.fieldsToColumns(ClassHomeworkRead.class).contains(x.getProperty()))
|
|
|
+ .eq(ClassHomeworkRead::getClassHomeworkId, dto.getClassHomeworkId())
|
|
|
+ .orderByDesc(ClassHomeworkRead::getId)
|
|
|
+ ;
|
|
|
+
|
|
|
+ List<ClassHomeworkRead> readList = classHomeworkReadMapper.selectList(queryWrapper);
|
|
|
+ Map<Long, LocalDateTime> readMap = readList.stream()
|
|
|
+ .collect(Collectors.toMap(ClassHomeworkRead::getUserId, ClassHomeworkRead::getCreateDate, (l1, l2) -> l2));
|
|
|
+
|
|
|
+ if (MapUtils.isNotEmpty(readMap)) {
|
|
|
+ for (ClassHomeworkReadListVo vo : list) {
|
|
|
+ if (readMap.containsKey(vo.getUserId())) {
|
|
|
+ vo.setCreateDate(readMap.get(vo.getUserId()));
|
|
|
+ vo.setIsRead(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ClassHomeworkReadListVo> result = new ArrayList<>();
|
|
|
+ if(ObjectUtils.isNotEmpty(dto.getIsRead())){
|
|
|
+ for (ClassHomeworkReadListVo vo : list) {
|
|
|
+ if(Objects.equals(vo.getIsRead(), dto.getIsRead())){
|
|
|
+ result.add(vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean readClassHomework(AddClassHomeworkReadDto dto) {
|
|
|
+ Long loginId = StpUtil.getLoginIdAsLong();
|
|
|
+ // 查询用户是否已经阅读当前作业
|
|
|
+ LambdaQueryWrapper<ClassHomeworkRead> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper
|
|
|
+ .select(ClassHomeworkRead.class,x -> VoToColumnUtil.fieldsToColumns(ClassHomeworkRead.class).contains(x.getProperty()))
|
|
|
+ .eq(ClassHomeworkRead::getClassHomeworkId, dto.getClassHomeworkId())
|
|
|
+ .eq(ClassHomeworkRead::getUserId, loginId)
|
|
|
+ ;
|
|
|
+ ClassHomeworkRead classHomeworkRead = classHomeworkReadMapper.selectOne(queryWrapper);
|
|
|
+
|
|
|
+ if(ObjectUtils.isEmpty(classHomeworkRead)){
|
|
|
+ ClassHomeworkRead insert = BeanUtil.toBean(dto, ClassHomeworkRead.class);
|
|
|
+ insert.setUserId(loginId);
|
|
|
+
|
|
|
+ insert.setCreateDate(LocalDateTime.now());
|
|
|
+ insert.setCreateUserId(loginId);
|
|
|
+
|
|
|
+ classHomeworkReadMapper.insert(insert);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|