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.core.toolkit.ObjectUtils; 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.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.BaseCourseSubject; import com.xjrsoft.module.base.entity.BaseUserStudent; import com.xjrsoft.module.base.service.IBaseUserStudentService; import com.xjrsoft.module.organization.dto.WeChatSendMessageDto; import com.xjrsoft.module.organization.entity.User; 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.service.IFileService; import com.xjrsoft.module.teacher.dto.AddClassInternshipDynamicDto; import com.xjrsoft.module.teacher.dto.AddClassInternshipDynamicReadDto; import com.xjrsoft.module.teacher.dto.ClassInternshipDynamicPageDto; import com.xjrsoft.module.teacher.dto.ClassInternshipDynamicReadListDto; import com.xjrsoft.module.teacher.entity.*; import com.xjrsoft.module.teacher.mapper.ClassInternshipDynamicClassMapper; import com.xjrsoft.module.teacher.mapper.ClassInternshipDynamicMapper; import com.xjrsoft.module.teacher.mapper.ClassInternshipDynamicReadMapper; import com.xjrsoft.module.teacher.mapper.XjrUserMapper; import com.xjrsoft.module.teacher.service.IClassInternshipDynamicService; import com.xjrsoft.module.teacher.vo.ClassHomeworkPageVo; import com.xjrsoft.module.teacher.vo.ClassHomeworkReadListVo; import com.xjrsoft.module.teacher.vo.ClassInternshipDynamicPageVo; import com.xjrsoft.module.teacher.vo.ClassInternshipDynamicReadListVo; import com.xjrsoft.module.workflow.entity.WorkflowFormRelation; import lombok.AllArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.camunda.bpm.engine.history.HistoricProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; 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 ClassInternshipDynamicServiceImpl extends MPJBaseServiceImpl implements IClassInternshipDynamicService { private final ClassInternshipDynamicClassMapper classInternshipDynamicClassMapper; private final UserMapper userMapper; private final IWeChatService weChatService; private final IBaseStudentSchoolRollService rollService; private final IBaseUserStudentService userStudentService; private final IFileService fileService; private final XjrUserMapper xjrUserMapper; private final ClassInternshipDynamicReadMapper classInternshipDynamicReadMapper; @Override public IPage pageClassInternshipDynamic(ClassInternshipDynamicPageDto dto) { // 需要划分权限 // 教职工看到自己发的所有的,学生和家长看到自己的 List roleList = StpUtil.getRoleList(); long userId = StpUtil.getLoginIdAsLong(); int roleType = 1; List 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 list = userStudentService.list(new QueryWrapper().lambda().eq(BaseUserStudent::getUserId, userId)); for (BaseUserStudent userStudent : list) { classIds.add(rollService.getClassIdByUserId(userStudent.getStudentId())); } } MPJLambdaWrapper queryWrapper = new MPJLambdaWrapper<>(); queryWrapper .select(ClassInternshipDynamic::getId) .select(ClassInternshipDynamic.class,x -> VoToColumnUtil.fieldsToColumns(ClassInternshipDynamicPageVo.class).contains(x.getProperty())) .select("(select\n" + " group_concat(b.name)\n" + " from class_internship_dynamic_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_internship_dynamic_class a\n" + " where a.class_homework_id = t.id\n" + " ) as class_ids") .leftJoin(XjrUser.class, XjrUser::getId, ClassInternshipDynamic::getPublisherId, wrapper -> wrapper .selectAs(XjrUser::getName, ClassInternshipDynamicPageVo::getPublisherIdCn) ) .ge(ObjectUtils.isNotEmpty(dto.getStartDate()), ClassInternshipDynamic::getCreateDate, dto.getStartDate()) .le(ObjectUtils.isNotEmpty(dto.getEndDate()), ClassInternshipDynamic::getCreateDate, dto.getEndDate()) .orderByDesc(ClassInternshipDynamic::getCreateDate) ; if(roleType == 2){ queryWrapper .eq(ClassInternshipDynamic::getPublisherId, userId); } if(roleType == 3){ queryWrapper .innerJoin(ClassInternshipDynamicClass.class, ClassInternshipDynamicClass::getClassInternshipDynamicId, ClassInternshipDynamic::getId) .in(CollectionUtils.isNotEmpty(classIds), ClassInternshipDynamicClass::getClassId, classIds); } IPage page = this.selectJoinListPage(ConventPage.getPage(dto), ClassInternshipDynamicPageVo.class, queryWrapper); for (ClassInternshipDynamicPageVo vo : page.getRecords()){ if(ObjectUtils.isNotEmpty(vo.getFolderId())){ List files = fileService.list(Wrappers.query().lambda().eq(File::getFolderId, vo.getFolderId())); vo.setFiles(files); } } return page; } @Override @Transactional(rollbackFor = Exception.class) public Boolean addClassInternshipDynamic(AddClassInternshipDynamicDto dto) { Long loginId = StpUtil.getLoginIdAsLong(); LocalDateTime nowLocalDateTime = LocalDateTime.now(); ClassInternshipDynamic classInternshipDynamic = BeanUtil.toBean(dto, ClassInternshipDynamic.class); classInternshipDynamic.setCreateUserId(loginId); classInternshipDynamic.setCreateDate(nowLocalDateTime); this.save(classInternshipDynamic); for (Long classid : dto.getClassIds()){ ClassInternshipDynamicClass classInternshipDynamicClass = new ClassInternshipDynamicClass(); classInternshipDynamicClass.setClassInternshipDynamicId(classInternshipDynamic.getId()); classInternshipDynamicClass.setClassId(classid); classInternshipDynamicClass.setCreateUserId(loginId); classInternshipDynamicClass.setCreateDate(nowLocalDateTime); classInternshipDynamicClassMapper.insert(classInternshipDynamicClass); } // 发送通知 List combinedList = new ArrayList<>(); if(ObjectUtils.isNotEmpty(dto.getRoleType()) && dto.getRoleType() == 1){ // 找到班上所有的学生 MPJLambdaWrapper 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 stuList = userMapper.selectJoinList(User.class, stuMPJLambdaWrapper); combinedList.addAll(stuList); } if(ObjectUtils.isNotEmpty(dto.getRoleType()) && dto.getRoleType() == 2){ // 找到班上所有的学生的家长 MPJLambdaWrapper 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 parentList = userMapper.selectJoinList(User.class, parentMPJLambdaWrapper); // 合并两个列表,并根据 User 的 id 去重 combinedList = new ArrayList<>(Stream.concat(combinedList.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", nowLocalDateTime); 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 listClassInternshipDynamic(ClassInternshipDynamicReadListDto dto) { ClassInternshipDynamic classInternshipDynamic = this.getById(dto.getClassInternshipDynamicId()); if (ObjectUtils.isEmpty(classInternshipDynamic)) { throw new MyException("当前作业被修改,请刷新重试"); } // 获取当前所有班级所有的学生 MPJLambdaWrapper xjrUserMPJLambdaWrapper = new MPJLambdaWrapper<>(); xjrUserMPJLambdaWrapper .selectAs(XjrUser::getId, ClassInternshipDynamicReadListVo::getUserId) .selectAs(XjrUser::getName, ClassInternshipDynamicReadListVo::getUserIdCn) .select("0 as is_read") .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId) ; if(ObjectUtils.isEmpty(dto.getClassId())){ LambdaQueryWrapper classLambdaQueryWrapper = new LambdaQueryWrapper<>(); classLambdaQueryWrapper .eq(ClassInternshipDynamicClass::getClassInternshipDynamicId, dto.getClassInternshipDynamicId()) .eq(ClassInternshipDynamicClass::getDeleteMark, DeleteMark.NODELETE.getCode()) ; List classeList = classInternshipDynamicClassMapper.selectList(classLambdaQueryWrapper); if(CollectionUtils.isEmpty(classeList)){ return new ArrayList<>(); } // 提取 classId 并去重 List uniqueClassIds = classeList.stream() .map(ClassInternshipDynamicClass::getClassId) // 提取 classId .distinct() // 去重 .collect(Collectors.toList()); // 收集为 List xjrUserMPJLambdaWrapper .in(BaseStudentSchoolRoll::getClassId, uniqueClassIds); }else { xjrUserMPJLambdaWrapper .eq(BaseStudentSchoolRoll::getClassId, dto.getClassId()); } List list = xjrUserMapper.selectJoinList(ClassInternshipDynamicReadListVo.class, xjrUserMPJLambdaWrapper); // 获取当前作业已经阅读情况 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper .select(ClassInternshipDynamicRead.class, x -> VoToColumnUtil.fieldsToColumns(ClassInternshipDynamicRead.class).contains(x.getProperty())) .eq(ClassInternshipDynamicRead::getClassInternshipDynamicId, dto.getClassInternshipDynamicId()) .orderByDesc(ClassInternshipDynamicRead::getId) ; List readList = classInternshipDynamicReadMapper.selectList(queryWrapper); Map readMap = readList.stream() .collect(Collectors.toMap(ClassInternshipDynamicRead::getUserId, ClassInternshipDynamicRead::getCreateDate, (l1, l2) -> l2)); if (MapUtils.isNotEmpty(readMap)) { for (ClassInternshipDynamicReadListVo vo : list) { if (readMap.containsKey(vo.getUserId())) { vo.setCreateDate(readMap.get(vo.getUserId())); vo.setIsRead(1); } } } List result = new ArrayList<>(); if(ObjectUtils.isNotEmpty(dto.getIsRead())){ for (ClassInternshipDynamicReadListVo vo : list) { if(Objects.equals(vo.getIsRead(), dto.getIsRead())){ result.add(vo); } } }else { return list; } return result; } @Override @Transactional(rollbackFor = Exception.class) public Boolean readClassInternshipDynamic(AddClassInternshipDynamicReadDto dto) { Long loginId = StpUtil.getLoginIdAsLong(); // 查询用户是否已经阅读当前作业 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper .select(ClassInternshipDynamicRead.class,x -> VoToColumnUtil.fieldsToColumns(ClassInternshipDynamicRead.class).contains(x.getProperty())) .eq(ClassInternshipDynamicRead::getClassInternshipDynamicId, dto.getClassInternshipDynamicId()) .eq(ClassInternshipDynamicRead::getUserId, loginId) ; ClassInternshipDynamicRead classInternshipDynamicRead = classInternshipDynamicReadMapper.selectOne(queryWrapper); if(ObjectUtils.isEmpty(classInternshipDynamicRead)){ ClassInternshipDynamicRead insert = BeanUtil.toBean(dto, ClassInternshipDynamicRead.class); insert.setUserId(loginId); insert.setCreateDate(LocalDateTime.now()); insert.setCreateUserId(loginId); classInternshipDynamicReadMapper.insert(insert); } return true; } }