|  | @@ -1,36 +1,44 @@
 | 
											
												
													
														|  |  package com.ym.mec.biz.service.impl;
 |  |  package com.ym.mec.biz.service.impl;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  import com.google.common.collect.Lists;
 |  |  import com.google.common.collect.Lists;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.auth.api.entity.SysUser;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dao.CourseScheduleDao;
 |  |  import com.ym.mec.biz.dal.dao.CourseScheduleDao;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
 |  |  import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dao.CourseShareDao;
 |  |  import com.ym.mec.biz.dal.dao.CourseShareDao;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.biz.dal.dao.OrganizationDao;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dao.StudentDao;
 |  |  import com.ym.mec.biz.dal.dao.StudentDao;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dao.StudentManageDao;
 |  |  import com.ym.mec.biz.dal.dao.StudentManageDao;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.biz.dal.dao.SubjectDao;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dto.CourseShareDto;
 |  |  import com.ym.mec.biz.dal.dto.CourseShareDto;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.dto.StudentManageListDto;
 |  |  import com.ym.mec.biz.dal.dto.StudentManageListDto;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.entity.CourseSchedule;
 |  |  import com.ym.mec.biz.dal.entity.CourseSchedule;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment;
 |  |  import com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.entity.CourseShare;
 |  |  import com.ym.mec.biz.dal.entity.CourseShare;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.biz.dal.entity.Organization;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.entity.Student;
 |  |  import com.ym.mec.biz.dal.entity.Student;
 | 
											
												
													
														|  |  import com.ym.mec.biz.dal.enums.JoinCourseType;
 |  |  import com.ym.mec.biz.dal.enums.JoinCourseType;
 | 
											
												
													
														|  | -import com.ym.mec.biz.dal.enums.ShareModeEnum;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.biz.dal.page.CourseShareQueryInfo;
 | 
											
												
													
														|  |  import com.ym.mec.biz.service.CourseShareService;
 |  |  import com.ym.mec.biz.service.CourseShareService;
 | 
											
												
													
														|  |  import com.ym.mec.biz.service.SysUserService;
 |  |  import com.ym.mec.biz.service.SysUserService;
 | 
											
												
													
														|  |  import com.ym.mec.common.dal.BaseDAO;
 |  |  import com.ym.mec.common.dal.BaseDAO;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.common.exception.BizException;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.common.filters.TenantIdThreadLocal;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.common.page.PageInfo;
 | 
											
												
													
														|  |  import com.ym.mec.common.service.impl.BaseServiceImpl;
 |  |  import com.ym.mec.common.service.impl.BaseServiceImpl;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.util.collection.MapUtil;
 | 
											
												
													
														|  | 
 |  | +import com.ym.mec.util.excel.POIUtil;
 | 
											
												
													
														|  |  import org.apache.commons.collections.CollectionUtils;
 |  |  import org.apache.commons.collections.CollectionUtils;
 | 
											
												
													
														|  | -import org.springframework.beans.BeanUtils;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import org.slf4j.Logger;
 | 
											
												
													
														|  | 
 |  | +import org.slf4j.LoggerFactory;
 | 
											
												
													
														|  |  import org.springframework.beans.factory.annotation.Autowired;
 |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
											
												
													
														|  |  import org.springframework.stereotype.Service;
 |  |  import org.springframework.stereotype.Service;
 | 
											
												
													
														|  |  import org.springframework.transaction.annotation.Transactional;
 |  |  import org.springframework.transaction.annotation.Transactional;
 | 
											
												
													
														|  | 
 |  | +import org.springframework.web.multipart.MultipartFile;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +import java.io.ByteArrayInputStream;
 | 
											
												
													
														|  |  import java.math.BigDecimal;
 |  |  import java.math.BigDecimal;
 | 
											
												
													
														|  | -import java.util.ArrayList;
 |  | 
 | 
											
												
													
														|  | -import java.util.Collections;
 |  | 
 | 
											
												
													
														|  | -import java.util.Date;
 |  | 
 | 
											
												
													
														|  | -import java.util.HashMap;
 |  | 
 | 
											
												
													
														|  | -import java.util.List;
 |  | 
 | 
											
												
													
														|  | -import java.util.Map;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import java.util.*;
 | 
											
												
													
														|  | 
 |  | +import java.util.function.Function;
 | 
											
												
													
														|  |  import java.util.stream.Collectors;
 |  |  import java.util.stream.Collectors;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -41,11 +49,17 @@ import java.util.stream.Collectors;
 | 
											
												
													
														|  |  @Service
 |  |  @Service
 | 
											
												
													
														|  |  public class CourseShareServiceImpl extends BaseServiceImpl<Integer, CourseShare> implements CourseShareService {
 |  |  public class CourseShareServiceImpl extends BaseServiceImpl<Integer, CourseShare> implements CourseShareService {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    private static final Logger LOG = LoggerFactory.getLogger(CourseShareServiceImpl.class);
 | 
											
												
													
														|  |      /**
 |  |      /**
 | 
											
												
													
														|  |       * 批量操作,分批数据最大限制
 |  |       * 批量操作,分批数据最大限制
 | 
											
												
													
														|  |       */
 |  |       */
 | 
											
												
													
														|  |      private static final int BATCH_OPE_MAX_SIZE = 500;
 |  |      private static final int BATCH_OPE_MAX_SIZE = 500;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 导入数据错误信息最大长度
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private static final int IMPORT_ERR_MSG_MAX_LEN = 1000;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      private static final String TENANT_ID = "tenantId";
 |  |      private static final String TENANT_ID = "tenantId";
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Autowired
 |  |      @Autowired
 | 
											
										
											
												
													
														|  | @@ -66,6 +80,11 @@ public class CourseShareServiceImpl extends BaseServiceImpl<Integer, CourseShare
 | 
											
												
													
														|  |      @Autowired
 |  |      @Autowired
 | 
											
												
													
														|  |      private CourseScheduleDao courseScheduleDao;
 |  |      private CourseScheduleDao courseScheduleDao;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    @Autowired
 | 
											
												
													
														|  | 
 |  | +    private OrganizationDao organizationDao;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    private static final List<String> STUDENT_TEMPLATE_FIELDS = Arrays.asList("分部", "学生姓名", "手机号");
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  |      public BaseDAO<Integer, CourseShare> getDAO() {
 |  |      public BaseDAO<Integer, CourseShare> getDAO() {
 | 
											
												
													
														|  |          return courseShareDao;
 |  |          return courseShareDao;
 | 
											
										
											
												
													
														|  | @@ -73,88 +92,73 @@ public class CourseShareServiceImpl extends BaseServiceImpl<Integer, CourseShare
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Transactional(rollbackFor = Exception.class)
 |  |      @Transactional(rollbackFor = Exception.class)
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  | -    public List<CourseShare> create(Integer tenantId, CourseShareDto courseShareDto) {
 |  | 
 | 
											
												
													
														|  | -        List<CourseShare> courseShares = new ArrayList<>();
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public List<CourseShare> saveCourseShare(CourseShareDto courseShareDto) {
 | 
											
												
													
														|  | 
 |  | +        CourseSchedule courseSchedule = getCourseScheduleById(courseShareDto.getCourseId());
 | 
											
												
													
														|  |          Integer userId = userService.getUserId();
 |  |          Integer userId = userService.getUserId();
 | 
											
												
													
														|  | -        if (ShareModeEnum.PRIVATE.equals(courseShareDto.getShareMode())) {
 |  | 
 | 
											
												
													
														|  | -            if (CollectionUtils.isEmpty(courseShareDto.getUserIds())) {
 |  | 
 | 
											
												
													
														|  | -                // 不分享,清理数据并返回
 |  | 
 | 
											
												
													
														|  | -                courseShareDao.deleteByCourseId(courseShareDto.getCourseId());
 |  | 
 | 
											
												
													
														|  | -                return new ArrayList<>();
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -            List<Student> students = studentDao.findByStudentIds(courseShareDto.getUserIds());
 |  | 
 | 
											
												
													
														|  | -            courseShares = students.stream().map(next -> {
 |  | 
 | 
											
												
													
														|  | -                CourseShare courseShare = new CourseShare();
 |  | 
 | 
											
												
													
														|  | -                BeanUtils.copyProperties(courseShareDto, courseShare);
 |  | 
 | 
											
												
													
														|  | -                courseShare.setUserId(next.getUserId());
 |  | 
 | 
											
												
													
														|  | -                courseShare.setTenantId(tenantId);
 |  | 
 | 
											
												
													
														|  | -                courseShare.setCreateTime(new Date());
 |  | 
 | 
											
												
													
														|  | -                courseShare.setCreateBy(userId);
 |  | 
 | 
											
												
													
														|  | -                return courseShare;
 |  | 
 | 
											
												
													
														|  | -            }).collect(Collectors.toList());
 |  | 
 | 
											
												
													
														|  | -        } else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(courseShareDto.getUserIds())) {
 | 
											
												
													
														|  | 
 |  | +            // 不分享,清理数据并返回
 | 
											
												
													
														|  | 
 |  | +            courseShareDao.deleteByCourseId(courseShareDto.getCourseId());
 | 
											
												
													
														|  | 
 |  | +            return new ArrayList<>();
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        List<Student> students = studentDao.findByStudentIds(courseShareDto.getUserIds());
 | 
											
												
													
														|  | 
 |  | +        List<CourseShare> courseShares = students.stream().map(next -> {
 | 
											
												
													
														|  |              CourseShare courseShare = new CourseShare();
 |  |              CourseShare courseShare = new CourseShare();
 | 
											
												
													
														|  | -            BeanUtils.copyProperties(courseShareDto, courseShare);
 |  | 
 | 
											
												
													
														|  | -            courseShare.setTenantId(tenantId);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            courseShare.setCourseId(courseShareDto.getCourseId());
 | 
											
												
													
														|  | 
 |  | +            courseShare.setTenantId(courseSchedule.getTenantId());
 | 
											
												
													
														|  | 
 |  | +            courseShare.setUserId(next.getUserId());
 | 
											
												
													
														|  |              courseShare.setCreateTime(new Date());
 |  |              courseShare.setCreateTime(new Date());
 | 
											
												
													
														|  |              courseShare.setCreateBy(userId);
 |  |              courseShare.setCreateBy(userId);
 | 
											
												
													
														|  | -            courseShares.add(courseShare);
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | 
 |  | +            return courseShare;
 | 
											
												
													
														|  | 
 |  | +        }).collect(Collectors.toList());
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          // 处理已经分享过的数据
 |  |          // 处理已经分享过的数据
 | 
											
												
													
														|  |          List<CourseShare> existShares = courseShareDao.selectByCourseId(courseShareDto.getCourseId());
 |  |          List<CourseShare> existShares = courseShareDao.selectByCourseId(courseShareDto.getCourseId());
 | 
											
												
													
														|  | -        if (CollectionUtils.isNotEmpty(existShares) && (courseShareDto.getShareMode().equals(ShareModeEnum.PRIVATE))) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isNotEmpty(existShares)) {
 | 
											
												
													
														|  |              // 私有分享,删除历史数据
 |  |              // 私有分享,删除历史数据
 | 
											
												
													
														|  |              List<Integer> sharedHistoryRecords = existShares.stream()
 |  |              List<Integer> sharedHistoryRecords = existShares.stream()
 | 
											
												
													
														|  |                      .map(CourseShare::getId)
 |  |                      .map(CourseShare::getId)
 | 
											
												
													
														|  |                      .collect(Collectors.toList());
 |  |                      .collect(Collectors.toList());
 | 
											
												
													
														|  | -            if (CollectionUtils.isNotEmpty(sharedHistoryRecords)) {
 |  | 
 | 
											
												
													
														|  | -                courseShareDao.deleteByIds(sharedHistoryRecords);
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | 
 |  | +            courseShareDao.deleteByIds(sharedHistoryRecords);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          // 数据入库
 |  |          // 数据入库
 | 
											
												
													
														|  | -        List<List<CourseShare>> groupList = Lists.partition(courseShares, BATCH_OPE_MAX_SIZE);
 |  | 
 | 
											
												
													
														|  | -        for (List<CourseShare> shares : groupList) {
 |  | 
 | 
											
												
													
														|  | -            courseShareDao.batchInsert(shares);
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | 
 |  | +        batchInsert(courseShares);
 | 
											
												
													
														|  |          return courseShareDao.selectByCourseId(courseShareDto.getCourseId());
 |  |          return courseShareDao.selectByCourseId(courseShareDto.getCourseId());
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  | -    public List<StudentManageListDto> queryCourseSharedStudent(Integer tenantId, Integer courseId) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public PageInfo<StudentManageListDto> queryCourseSharedStudent(CourseShareQueryInfo shareQueryInfo) {
 | 
											
												
													
														|  | 
 |  | +        CourseSchedule courseSchedule = getCourseScheduleById(shareQueryInfo.getCourseId());
 | 
											
												
													
														|  | 
 |  | +        PageInfo<StudentManageListDto> pageInfo = new PageInfo<>(shareQueryInfo.getPage(), shareQueryInfo.getRows());
 | 
											
												
													
														|  |          // 查询该课程已经分享的学生列表
 |  |          // 查询该课程已经分享的学生列表
 | 
											
												
													
														|  |          Map<String, Object> courseParam = new HashMap<>(2);
 |  |          Map<String, Object> courseParam = new HashMap<>(2);
 | 
											
												
													
														|  | -        courseParam.put("courseId", courseId);
 |  | 
 | 
											
												
													
														|  | -        courseParam.put(TENANT_ID, tenantId);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        courseParam.put("courseId", shareQueryInfo.getCourseId());
 | 
											
												
													
														|  | 
 |  | +        courseParam.put(TENANT_ID, courseSchedule.getTenantId());
 | 
											
												
													
														|  |          List<CourseShare> courseShareRecords = courseShareDao.findAll(courseParam);
 |  |          List<CourseShare> courseShareRecords = courseShareDao.findAll(courseParam);
 | 
											
												
													
														|  |          if (CollectionUtils.isEmpty(courseShareRecords)) {
 |  |          if (CollectionUtils.isEmpty(courseShareRecords)) {
 | 
											
												
													
														|  | -            return new ArrayList<>();
 |  | 
 | 
											
												
													
														|  | 
 |  | +            pageInfo.setTotal(0);
 | 
											
												
													
														|  | 
 |  | +            pageInfo.setRows(new ArrayList<>());
 | 
											
												
													
														|  | 
 |  | +            return pageInfo;
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          // 查询学生列表
 |  |          // 查询学生列表
 | 
											
												
													
														|  |          Map<String, Object> param = new HashMap<>(2);
 |  |          Map<String, Object> param = new HashMap<>(2);
 | 
											
												
													
														|  | -        param.put(TENANT_ID, tenantId);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        param.put(TENANT_ID, courseSchedule.getTenantId());
 | 
											
												
													
														|  | 
 |  | +        MapUtil.populateMap(param, shareQueryInfo);
 | 
											
												
													
														|  |          param.put("userIds", courseShareRecords.stream().map(CourseShare::getUserId).toArray());
 |  |          param.put("userIds", courseShareRecords.stream().map(CourseShare::getUserId).toArray());
 | 
											
												
													
														|  | -        return studentManageDao.findStudentsByOrganId(param);
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    @Override
 |  | 
 | 
											
												
													
														|  | -    public List<StudentManageListDto> queryStudentList(Integer tenantId, Integer organId, Integer subjectId) {
 |  | 
 | 
											
												
													
														|  | -        Map<String, Object> param = new HashMap<>(2);
 |  | 
 | 
											
												
													
														|  | -        if (organId != null) {
 |  | 
 | 
											
												
													
														|  | -            param.put("organIds", new int[]{organId});
 |  | 
 | 
											
												
													
														|  | 
 |  | +        int count = studentManageDao.countStudentAttendances(param);
 | 
											
												
													
														|  | 
 |  | +        pageInfo.setTotal(count);
 | 
											
												
													
														|  | 
 |  | +        if (count > 0) {
 | 
											
												
													
														|  | 
 |  | +            param.put("offset", pageInfo.getOffset());
 | 
											
												
													
														|  | 
 |  | +            pageInfo.setRows(studentManageDao.findStudentsByOrganId(param));
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        if (subjectId != null) {
 |  | 
 | 
											
												
													
														|  | -            param.put("subjectId", subjectId);
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -        param.put(TENANT_ID, tenantId);
 |  | 
 | 
											
												
													
														|  | -        // 查询指定分部和声部对应的学生列表
 |  | 
 | 
											
												
													
														|  | -        return studentManageDao.findStudentsByOrganId(param);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        return pageInfo;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Transactional(rollbackFor = Exception.class)
 |  |      @Transactional(rollbackFor = Exception.class)
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  | -    public boolean createPaymentRecord(Integer tenantId, Long courseId, Integer userId) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public boolean createPaymentRecord(Long courseId, Integer userId) {
 | 
											
												
													
														|  | 
 |  | +        CourseSchedule courseSchedule = getCourseScheduleById(courseId);
 | 
											
												
													
														|  |          // 查询是否已经进入直播间,进入即表示存在记录,不需要重复插入数据
 |  |          // 查询是否已经进入直播间,进入即表示存在记录,不需要重复插入数据
 | 
											
												
													
														|  |          int haveCourse = courseScheduleStudentPaymentDao.checkStudentHaveCourse(courseId, userId);
 |  |          int haveCourse = courseScheduleStudentPaymentDao.checkStudentHaveCourse(courseId, userId);
 | 
											
												
													
														|  |          if (haveCourse == 0) {
 |  |          if (haveCourse == 0) {
 | 
											
										
											
												
													
														|  | @@ -173,7 +177,7 @@ public class CourseShareServiceImpl extends BaseServiceImpl<Integer, CourseShare
 | 
											
												
													
														|  |              payment.setExpectPriceBak(sharePrice);
 |  |              payment.setExpectPriceBak(sharePrice);
 | 
											
												
													
														|  |              payment.setActualPriceBak(sharePrice);
 |  |              payment.setActualPriceBak(sharePrice);
 | 
											
												
													
														|  |              payment.setCreateTime(new Date());
 |  |              payment.setCreateTime(new Date());
 | 
											
												
													
														|  | -            payment.setTenantId(tenantId);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            payment.setTenantId(courseSchedule.getTenantId());
 | 
											
												
													
														|  |              payment.setClassGroupId(schedule.getClassGroupId());
 |  |              payment.setClassGroupId(schedule.getClassGroupId());
 | 
											
												
													
														|  |              payment.setJoinCourseType(JoinCourseType.SHARE);
 |  |              payment.setJoinCourseType(JoinCourseType.SHARE);
 | 
											
												
													
														|  |              courseScheduleStudentPaymentDao.insert(payment);
 |  |              courseScheduleStudentPaymentDao.insert(payment);
 | 
											
										
											
												
													
														|  | @@ -181,4 +185,160 @@ public class CourseShareServiceImpl extends BaseServiceImpl<Integer, CourseShare
 | 
											
												
													
														|  |          return true;
 |  |          return true;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    @Transactional(rollbackFor = Exception.class)
 | 
											
												
													
														|  | 
 |  | +    @Override
 | 
											
												
													
														|  | 
 |  | +    public String importStudent(MultipartFile file, Long courseId) {
 | 
											
												
													
														|  | 
 |  | +        CourseSchedule courseSchedule = getCourseScheduleById(courseId);
 | 
											
												
													
														|  | 
 |  | +        Map<String, List<Map<String, Object>>> sheetsListMap;
 | 
											
												
													
														|  | 
 |  | +        try {
 | 
											
												
													
														|  | 
 |  | +            sheetsListMap = POIUtil.importExcel(
 | 
											
												
													
														|  | 
 |  | +                    new ByteArrayInputStream(file.getBytes()), 0, file.getOriginalFilename());
 | 
											
												
													
														|  | 
 |  | +        } catch (Exception e) {
 | 
											
												
													
														|  | 
 |  | +            LOG.error("导入课程分享学员数据失败", e);
 | 
											
												
													
														|  | 
 |  | +            throw new BizException("文件读取失败");
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        List<Map<String, Object>> students = sheetsListMap.get("student");
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(students)) {
 | 
											
												
													
														|  | 
 |  | +            throw new BizException("文件格式错误,无法获取[student]页签数据");
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        if (!students.get(0).keySet().containsAll(STUDENT_TEMPLATE_FIELDS)) {
 | 
											
												
													
														|  | 
 |  | +            throw new BizException("页签必须包含[分部/学生姓名/手机号]");
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        List<Organization> allOrgans = organizationDao.findAllOrgans(courseSchedule.getTenantId());
 | 
											
												
													
														|  | 
 |  | +        Set<String> orgNames = allOrgans.stream().map(Organization::getName).collect(Collectors.toSet());
 | 
											
												
													
														|  | 
 |  | +        StringBuilder sb = new StringBuilder();
 | 
											
												
													
														|  | 
 |  | +        List<Student> studentList = new ArrayList<>();
 | 
											
												
													
														|  | 
 |  | +        Set<String> phoneNos = new HashSet<>();
 | 
											
												
													
														|  | 
 |  | +        for (int index = 0; index < students.size(); index++) {
 | 
											
												
													
														|  | 
 |  | +            Map<String, Object> row = students.get(index);
 | 
											
												
													
														|  | 
 |  | +            Student student = checkExcelData(sb, orgNames, phoneNos, index, row);
 | 
											
												
													
														|  | 
 |  | +            if (student == null) {
 | 
											
												
													
														|  | 
 |  | +                // 空行过滤
 | 
											
												
													
														|  | 
 |  | +                continue;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            // 避免导入数据存在大量错误数据,出现长时间等待
 | 
											
												
													
														|  | 
 |  | +            if (sb.length() > IMPORT_ERR_MSG_MAX_LEN) {
 | 
											
												
													
														|  | 
 |  | +                break;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            studentList.add(student);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        if (sb.length() > 0) {
 | 
											
												
													
														|  | 
 |  | +            throw new BizException(sb.toString());
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        // 判断导入的学生数据是否在库中匹配到,过滤非法的学生数据
 | 
											
												
													
														|  | 
 |  | +        SysUser sysUser = userService.getUser();
 | 
											
												
													
														|  | 
 |  | +        Map<Integer, String> orgIdNameMap = allOrgans.stream()
 | 
											
												
													
														|  | 
 |  | +                .collect(Collectors.toMap(Organization::getId, Organization::getName));
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        Map<String, List<Student>> studentGroupByOrg = studentList.stream()
 | 
											
												
													
														|  | 
 |  | +                .collect(Collectors.groupingBy(Student::getOrganName));
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        // 按分部分批处理,避免大量加载数据库数据
 | 
											
												
													
														|  | 
 |  | +        Map<String, Object> params = new HashMap<>();
 | 
											
												
													
														|  | 
 |  | +        params.put(TENANT_ID, courseSchedule.getTenantId());
 | 
											
												
													
														|  | 
 |  | +        for (Map.Entry<String, List<Student>> entry : studentGroupByOrg.entrySet()) {
 | 
											
												
													
														|  | 
 |  | +            Optional<Map.Entry<Integer, String>> orgIdName = orgIdNameMap.entrySet()
 | 
											
												
													
														|  | 
 |  | +                    .stream().filter(next -> next.getValue().equals(entry.getKey())).findFirst();
 | 
											
												
													
														|  | 
 |  | +            if (!orgIdName.isPresent()) {
 | 
											
												
													
														|  | 
 |  | +                // 不会发生
 | 
											
												
													
														|  | 
 |  | +                continue;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            Integer orgId = orgIdName.get().getKey();
 | 
											
												
													
														|  | 
 |  | +            params.put("organIds", new int[]{orgId});
 | 
											
												
													
														|  | 
 |  | +            List<StudentManageListDto> manageListDtos = studentManageDao.findStudentsByOrganId(params);
 | 
											
												
													
														|  | 
 |  | +            // 判断学生的姓名和手机号是否匹配上,不匹配的数据过滤掉
 | 
											
												
													
														|  | 
 |  | +            Map<String, StudentManageListDto> legalStudentMap = manageListDtos.stream()
 | 
											
												
													
														|  | 
 |  | +                    .collect(Collectors.toMap(next -> (next.getUsername() + "_" + next.getParentsPhone()),
 | 
											
												
													
														|  | 
 |  | +                            Function.identity()));
 | 
											
												
													
														|  | 
 |  | +            Set<String> legalKeys = legalStudentMap.keySet();
 | 
											
												
													
														|  | 
 |  | +            entry.getValue().removeIf(next -> {
 | 
											
												
													
														|  | 
 |  | +                String key = next.getUsername() + "_" + next.getPhone();
 | 
											
												
													
														|  | 
 |  | +                if (legalKeys.contains(key)) {
 | 
											
												
													
														|  | 
 |  | +                    next.setUserId(legalStudentMap.get(key).getUserId());
 | 
											
												
													
														|  | 
 |  | +                    return false;
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +                return true;
 | 
											
												
													
														|  | 
 |  | +            });
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        List<Student> legalStudents = studentGroupByOrg.values().stream()
 | 
											
												
													
														|  | 
 |  | +                .flatMap(Collection::stream).collect(Collectors.toList());
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(legalStudents)) {
 | 
											
												
													
														|  | 
 |  | +            throw new BizException("未解析到合法的学生");
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        // 处理导入数据中存在已经分享的数据再次入库
 | 
											
												
													
														|  | 
 |  | +        List<CourseShare> existShares = courseShareDao.selectByCourseId(courseId);
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isNotEmpty(existShares)) {
 | 
											
												
													
														|  | 
 |  | +            Set<String> existShareKeys = existShares.stream()
 | 
											
												
													
														|  | 
 |  | +                    .map(next -> (next.getCourseId() + "_" + next.getUserId())).collect(Collectors.toSet());
 | 
											
												
													
														|  | 
 |  | +            legalStudents.removeIf(next -> existShareKeys.contains(courseId + "_" + next.getUserId()));
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        List<CourseShare> courseShares = legalStudents.stream().map(next -> {
 | 
											
												
													
														|  | 
 |  | +            CourseShare courseShare = new CourseShare();
 | 
											
												
													
														|  | 
 |  | +            courseShare.setUserId(next.getUserId());
 | 
											
												
													
														|  | 
 |  | +            courseShare.setTenantId(TenantIdThreadLocal.get());
 | 
											
												
													
														|  | 
 |  | +            courseShare.setCourseId(courseId);
 | 
											
												
													
														|  | 
 |  | +            courseShare.setCreateTime(new Date());
 | 
											
												
													
														|  | 
 |  | +            courseShare.setCreateBy(sysUser.getId());
 | 
											
												
													
														|  | 
 |  | +            return courseShare;
 | 
											
												
													
														|  | 
 |  | +        }).collect(Collectors.toList());
 | 
											
												
													
														|  | 
 |  | +        batchInsert(courseShares);
 | 
											
												
													
														|  | 
 |  | +        return String.format("成功导入%s条数据", courseShares.size());
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    @Override
 | 
											
												
													
														|  | 
 |  | +    public boolean deleteStudent(CourseShareDto courseShareDto) {
 | 
											
												
													
														|  | 
 |  | +        courseShareDao.deleteByCourseAndUserIds(courseShareDto.getCourseId(), courseShareDto.getUserIds());
 | 
											
												
													
														|  | 
 |  | +        return true;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    private Student checkExcelData(StringBuilder sb, Set<String> orgNames, Set<String> phoneNos, int i, Map<String,
 | 
											
												
													
														|  | 
 |  | +            Object> row) {
 | 
											
												
													
														|  | 
 |  | +        Student student = new Student();
 | 
											
												
													
														|  | 
 |  | +        if (row.size() == 0) {
 | 
											
												
													
														|  | 
 |  | +            return null;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        Object orgName = row.get(STUDENT_TEMPLATE_FIELDS.get(0));
 | 
											
												
													
														|  | 
 |  | +        if (Objects.isNull(orgName) || !orgNames.contains(orgName.toString().trim())) {
 | 
											
												
													
														|  | 
 |  | +            sb.append(String.format("第%s行分部数据格式错误或者所属分部不存在%n", (i + 2)));
 | 
											
												
													
														|  | 
 |  | +        } else {
 | 
											
												
													
														|  | 
 |  | +            student.setOrganName(orgName.toString().trim());
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        Object studentName = row.get(STUDENT_TEMPLATE_FIELDS.get(1));
 | 
											
												
													
														|  | 
 |  | +        if (Objects.nonNull(studentName)) {
 | 
											
												
													
														|  | 
 |  | +            student.setUsername(studentName.toString().trim());
 | 
											
												
													
														|  | 
 |  | +        } else {
 | 
											
												
													
														|  | 
 |  | +            sb.append(String.format("第%s行学生姓名数据格式错误%n", (i + 2)));
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        Object phoneNo = row.get(STUDENT_TEMPLATE_FIELDS.get(2));
 | 
											
												
													
														|  | 
 |  | +        if (Objects.nonNull(phoneNo)) {
 | 
											
												
													
														|  | 
 |  | +            String phone = phoneNo.toString().trim();
 | 
											
												
													
														|  | 
 |  | +            if (phoneNos.contains(phone)) {
 | 
											
												
													
														|  | 
 |  | +                sb.append(String.format("第%s行手机号重复%n", (i + 2)));
 | 
											
												
													
														|  | 
 |  | +                return null;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            student.setPhone(phone);
 | 
											
												
													
														|  | 
 |  | +            phoneNos.add(phone);
 | 
											
												
													
														|  | 
 |  | +        } else {
 | 
											
												
													
														|  | 
 |  | +            sb.append(String.format("第%s行手机号数据格式错误%n", (i + 2)));
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        return student;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    private void batchInsert(List<CourseShare> courseShares) {
 | 
											
												
													
														|  | 
 |  | +        List<List<CourseShare>> groupList = Lists.partition(courseShares, BATCH_OPE_MAX_SIZE);
 | 
											
												
													
														|  | 
 |  | +        for (List<CourseShare> shares : groupList) {
 | 
											
												
													
														|  | 
 |  | +            courseShareDao.batchInsert(shares);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    private CourseSchedule getCourseScheduleById(Long courseId) {
 | 
											
												
													
														|  | 
 |  | +        CourseSchedule courseSchedule = courseScheduleDao.get(courseId);
 | 
											
												
													
														|  | 
 |  | +        if (courseSchedule == null) {
 | 
											
												
													
														|  | 
 |  | +            throw new BizException("课程不存在");
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        return courseSchedule;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  }
 |  |  }
 |