|  | @@ -1,12 +1,14 @@
 | 
	
		
			
				|  |  |  package com.yonge.cooleshow.biz.dal.service.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  | +import com.alipay.api.domain.NextUrl;
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.core.metadata.IPage;
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 | 
	
		
			
				|  |  |  import com.google.common.collect.Lists;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.Student;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.SysUser;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
 | 
	
	
		
			
				|  | @@ -14,17 +16,20 @@ import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.UserTenantAlbumRecord;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.enums.im.EImSendStatus;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.mapper.TenantActivationCodeMapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumPurchaseMapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.mapper.UserTenantAlbumRecordMapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.common.enums.EActivationCode;
 | 
	
		
			
				|  |  |  import com.yonge.toolset.base.exception.BizException;
 | 
	
		
			
				|  |  | +import com.yonge.toolset.mybatis.support.PageUtil;
 | 
	
		
			
				|  |  |  import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 | 
	
		
			
				|  |  |  import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  import org.apache.commons.collections.CollectionUtils;
 | 
	
	
		
			
				|  | @@ -34,14 +39,11 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -import java.util.ArrayList;
 | 
	
		
			
				|  |  | -import java.util.Calendar;
 | 
	
		
			
				|  |  | -import java.util.Comparator;
 | 
	
		
			
				|  |  | -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.regex.Pattern;
 | 
	
		
			
				|  |  |  import java.util.stream.Collectors;
 | 
	
		
			
				|  |  | +import java.util.stream.Stream;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * 机构激活码
 | 
	
	
		
			
				|  | @@ -66,6 +68,8 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private TenantAlbumService tenantAlbumService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private static final String PHONE_REG = "^1\\d{10}$";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 查询详情
 | 
	
		
			
				|  |  |       *
 | 
	
	
		
			
				|  | @@ -323,84 +327,94 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        List<String> errMsg = new ArrayList<>();
 | 
	
		
			
				|  |  | +        List<TenantActivationCodeWrapper.ImportTemplate> importTemplates = dataList.stream().map(ExcelDataReaderProperty::getClazz).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        List<String> codeList = importTemplates.stream().map(TenantActivationCodeWrapper.ImportTemplate::getCode).
 | 
	
		
			
				|  |  | +                filter(StringUtils::isNotEmpty).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        if(codeList.isEmpty()){
 | 
	
		
			
				|  |  | +            throw new BizException("未指定激活码");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<String> phoneList = importTemplates.stream().map(TenantActivationCodeWrapper.ImportTemplate::getPhone)
 | 
	
		
			
				|  |  | +                        .filter(StringUtils::isNotEmpty).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        if(phoneList.isEmpty()){
 | 
	
		
			
				|  |  | +            throw new BizException("未指定手机号");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<TenantActivationCode> activationCodes = this.lambdaQuery()
 | 
	
		
			
				|  |  | +                .eq(TenantActivationCode::getTenantId, tenantId)
 | 
	
		
			
				|  |  | +                .eq(TenantActivationCode::getTenantAlbumPurchaseId, tenantAlbumPurchaseId)
 | 
	
		
			
				|  |  | +                .in(TenantActivationCode::getActivationCode, codeList).list();
 | 
	
		
			
				|  |  | +        Map<String, TenantActivationCode> mapByCode = activationCodes.stream().collect(Collectors.toMap(TenantActivationCode::getActivationCode, Function.identity()));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        StudentSearch studentSearch = new StudentSearch();
 | 
	
		
			
				|  |  | +        studentSearch.setRows(9999);
 | 
	
		
			
				|  |  | +        studentSearch.setPage(1);
 | 
	
		
			
				|  |  | +        studentSearch.setPhoneList(phoneList);
 | 
	
		
			
				|  |  | +        List<StudentVo> studentVos = studentDao.selectPage(PageUtil.getPage(studentSearch), studentSearch);
 | 
	
		
			
				|  |  | +        Map<String, StudentVo> mapStudentByPhone = studentVos.stream().collect(Collectors.toMap(StudentVo::getPhone, Function.identity()));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Map<Integer,List<String>> errMsgMap = new LinkedHashMap<>();
 | 
	
		
			
				|  |  |          Map<String, Integer> codeRowMap = new HashMap<>();
 | 
	
		
			
				|  |  | -        Map<String, String> codePhoneMap = new HashMap<>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          String errTemplate = "第%s行%s";
 | 
	
		
			
				|  |  | -        // 校验数据格式是否错误
 | 
	
		
			
				|  |  | -        int rowIndex = 0;
 | 
	
		
			
				|  |  | -        for (ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate> next : dataList) {
 | 
	
		
			
				|  |  | +        int rowIndex = 1;
 | 
	
		
			
				|  |  | +        // 校验数据格式是否错误 第二行开始取数据
 | 
	
		
			
				|  |  | +        for (TenantActivationCodeWrapper.ImportTemplate template : importTemplates) {
 | 
	
		
			
				|  |  |              rowIndex++;
 | 
	
		
			
				|  |  | -            TenantActivationCodeWrapper.ImportTemplate code = next.getClazz();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            String acCode = code.getCode();
 | 
	
		
			
				|  |  | +            String acCode = template.getCode();
 | 
	
		
			
				|  |  |              if (StringUtils.isEmpty(acCode)) {
 | 
	
		
			
				|  |  |                  continue;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              int msgRowNo = rowIndex;
 | 
	
		
			
				|  |  | -            code.checkIsIllegal().forEach(err -> errMsg.add(String.format(errTemplate, msgRowNo, err)));
 | 
	
		
			
				|  |  | -            if (codeRowMap.containsKey(code.getCode())) {
 | 
	
		
			
				|  |  | -                errMsg.add(String.format(errTemplate, msgRowNo, "激活码重复"));
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            codeRowMap.put(acCode, msgRowNo);
 | 
	
		
			
				|  |  | -            if (StringUtils.isNotEmpty(code.getPhone())) {
 | 
	
		
			
				|  |  | -                codePhoneMap.put(acCode.trim(), code.getPhone().trim());
 | 
	
		
			
				|  |  | +            List<String> errList = errMsgMap.getOrDefault(msgRowNo, new ArrayList<>());
 | 
	
		
			
				|  |  | +            String code = template.getCode();
 | 
	
		
			
				|  |  | +            if (codeRowMap.containsKey(code)) {
 | 
	
		
			
				|  |  | +                errList.add(String.format(errTemplate, msgRowNo, "激活码重复"));
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                codeRowMap.put(acCode, msgRowNo);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if (errMsg.size() > 100) {
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | +            if (!mapByCode.containsKey(code)) {
 | 
	
		
			
				|  |  | +                errList.add(String.format(errTemplate, msgRowNo, "激活码不存在"));
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                TenantActivationCode tenantActivationCode = mapByCode.get(code);
 | 
	
		
			
				|  |  | +                if (tenantActivationCode.getActivationStatus() || EActivationCode.SEND.equals(tenantActivationCode.getSendStatus())) {
 | 
	
		
			
				|  |  | +                    errList.add(String.format(errTemplate, msgRowNo, "激活码已被发放/激活"));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        if (codePhoneMap.isEmpty()) {
 | 
	
		
			
				|  |  | -            throw new BizException("请指定手机号码激活");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        if (!errMsg.isEmpty()) {
 | 
	
		
			
				|  |  | -            throw new BizException(String.join(",", errMsg));
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        // 校验激活码是否被使用
 | 
	
		
			
				|  |  | -        List<List<String>> codePartition = Lists.partition(new ArrayList<>(codeRowMap.keySet()), 50);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        List<TenantActivationCode> tenantActivationCodes = new ArrayList<>();
 | 
	
		
			
				|  |  | -        for (List<String> codes : codePartition) {
 | 
	
		
			
				|  |  | -            List<TenantActivationCode> activationCodes = this.lambdaQuery()
 | 
	
		
			
				|  |  | -                    .eq(TenantActivationCode::getTenantId, tenantId)
 | 
	
		
			
				|  |  | -                    .eq(TenantActivationCode::getTenantAlbumPurchaseId, tenantAlbumPurchaseId)
 | 
	
		
			
				|  |  | -                    .in(TenantActivationCode::getActivationCode, codes).list();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            // 存在无效码或者已经使用过的码
 | 
	
		
			
				|  |  | -            if (codes.size() != activationCodes.size() ||
 | 
	
		
			
				|  |  | -                    activationCodes.stream().anyMatch(TenantActivationCode::getActivationStatus)) {
 | 
	
		
			
				|  |  | -                Map<String, Boolean> codeStatusMap = activationCodes.stream()
 | 
	
		
			
				|  |  | -                        .collect(Collectors.toMap(TenantActivationCode::getActivationCode,
 | 
	
		
			
				|  |  | -                                TenantActivationCode::getActivationStatus));
 | 
	
		
			
				|  |  | -                for (String code : codes) {
 | 
	
		
			
				|  |  | -                    if (!codeStatusMap.containsKey(code)) {
 | 
	
		
			
				|  |  | -                        errMsg.add(String.format(errTemplate, codeRowMap.get(code), "激活码无效"));
 | 
	
		
			
				|  |  | -                    } else if (Boolean.TRUE.equals(codeStatusMap.get(code))) {
 | 
	
		
			
				|  |  | -                        errMsg.add(String.format(errTemplate, codeRowMap.get(code), "激活码已经激活"));
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | +            String phone = template.getPhone();
 | 
	
		
			
				|  |  | +            if (StringUtils.isNotEmpty(phone)) {
 | 
	
		
			
				|  |  | +                if (!Pattern.matches(PHONE_REG, phone.trim()) ||
 | 
	
		
			
				|  |  | +                        (mapStudentByPhone.containsKey(phone) && !mapStudentByPhone.get(phone).getTenantId().equals(tenantId))) {
 | 
	
		
			
				|  |  | +                    errList.add(String.format(errTemplate, msgRowNo, "手机号错误或已注册成为其他机构学员"));
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            List<TenantActivationCode> updateDataList = activationCodes.stream().map(next -> {
 | 
	
		
			
				|  |  | -                TenantActivationCode tenantActivationCode = new TenantActivationCode();
 | 
	
		
			
				|  |  | -                tenantActivationCode.setId(next.getId());
 | 
	
		
			
				|  |  | -                tenantActivationCode.setActivationPhone(codePhoneMap.get(next.getActivationCode()));
 | 
	
		
			
				|  |  | -                tenantActivationCode.setSendStatus(EActivationCode.SEND);
 | 
	
		
			
				|  |  | -                return tenantActivationCode;
 | 
	
		
			
				|  |  | -            }).collect(Collectors.toList());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            tenantActivationCodes.addAll(updateDataList);
 | 
	
		
			
				|  |  | +            errMsgMap.put(msgRowNo, errList);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<String> errMsg = errMsgMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
 | 
	
		
			
				|  |  |          if (!errMsg.isEmpty()) {
 | 
	
		
			
				|  |  | +            String errLines = errMsgMap.entrySet().stream().filter(next -> CollectionUtils.isNotEmpty(next.getValue()))
 | 
	
		
			
				|  |  | +                    .map(next -> String.valueOf(next.getKey())).collect(Collectors.joining("、"));
 | 
	
		
			
				|  |  | +            errMsg.add(0, "第" + errLines + "行存在错误");
 | 
	
		
			
				|  |  |              throw new BizException(String.join(",", errMsg));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        if (!tenantActivationCodes.isEmpty()) {
 | 
	
		
			
				|  |  | -            this.updateBatchById(tenantActivationCodes, 50);
 | 
	
		
			
				|  |  | +        List<TenantActivationCode> tenantActivationCodes = importTemplates.stream()
 | 
	
		
			
				|  |  | +                .filter(next -> StringUtils.isNotEmpty(next.getCode()) && StringUtils.isNotBlank(next.getPhone()))
 | 
	
		
			
				|  |  | +                .map(next -> {
 | 
	
		
			
				|  |  | +                    TenantActivationCode record = mapByCode.get(next.getCode());
 | 
	
		
			
				|  |  | +                    TenantActivationCode tenantActivationCode = new TenantActivationCode();
 | 
	
		
			
				|  |  | +                    tenantActivationCode.setId(record.getId());
 | 
	
		
			
				|  |  | +                    tenantActivationCode.setActivationPhone(next.getPhone());
 | 
	
		
			
				|  |  | +                    tenantActivationCode.setSendStatus(EActivationCode.SEND);
 | 
	
		
			
				|  |  | +                    return tenantActivationCode;
 | 
	
		
			
				|  |  | +                }).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        if (tenantActivationCodes.isEmpty()) {
 | 
	
		
			
				|  |  | +            throw new BizException("没有合法的导入数据");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        this.updateBatchById(tenantActivationCodes, 50);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private void addUserTenantAlbumRecord(Long studentId, TenantAlbumPurchase purchase,
 |