package com.panzhihua.common.listen; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.fastjson.JSONArray; import com.google.common.collect.Lists; import com.panzhihua.common.constants.Constants; import com.panzhihua.common.exceptions.ServiceException; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.model.vos.community.cluster.admin.ComClusterMemberExcelErrorVO; import com.panzhihua.common.model.vos.community.cluster.admin.ComClusterMemberExcelVO; import com.panzhihua.common.service.community.CommunityService; import com.panzhihua.common.utlis.ListUtils; import com.panzhihua.common.utlis.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * title: 群团组织成员导入监听 * @author : lyq */ @Slf4j public class ComClusterMemberExcelListen extends AnalysisEventListener> { /** * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 3000; private static int headSize = 0; List> list = new ArrayList>(); private CommunityService communityService; private Long communityId; private Long userId; private Map headData; private StringRedisTemplate stringRedisTemplate; public ComClusterMemberExcelListen(CommunityService communityService, Long communityId, Long userId, StringRedisTemplate stringRedisTemplate) { this.communityService = communityService; this.communityId = communityId; this.userId = userId; this.stringRedisTemplate = stringRedisTemplate; } @Override public void invoke(Map data, AnalysisContext context) { list.add(data); if (list.size() >= BATCH_COUNT) { saveData(); list.clear(); } } /** * 这里会一行行的返回头 * * @param headMap * @param context */ @Override public void invokeHeadMap(Map headMap, AnalysisContext context) { headSize = headMap.size(); headData = headMap; } @Override public void doAfterAllAnalysed(AnalysisContext context) { saveData(); log.info("所有数据解析完成!"); } /** * 不是固定的列只能手动处理 */ private void saveData() { log.info("表格总数据:" + list.size()); if (list.size() == 0) { throw new ServiceException("000", "导入数据为空!"); } ValueOperations valueOperations = stringRedisTemplate.opsForValue(); String key = Constants.CLUSTER_MEMBER_ERROR_LIST + communityId; int index = 2; try { ArrayList voList = Lists.newArrayList(); ArrayList mistakes = Lists.newArrayList(); for (Map oneData : list) { ComClusterMemberExcelVO vo = new ComClusterMemberExcelVO(); if (StringUtils.isEmpty(oneData.get(0))) { index++; mistakes.add(setErrorObject(oneData,"名字不可为空,请填写姓名")); continue; }else{ //判断导入的名字的长度是否超过10 if(oneData.get(0).length() > 10){ index++; mistakes.add(setErrorObject(oneData,"名字长度不可超过10,请重新填写姓名")); continue; } } vo.setName(oneData.get(0)); if (StringUtils.isEmpty(oneData.get(1))) { index++; mistakes.add(setErrorObject(oneData,"组织不可为空,请填写组织名称")); continue; } vo.setClusterName(oneData.get(1)); if (StringUtils.isEmpty(oneData.get(2))) { index++; mistakes.add(setErrorObject(oneData,"职务不可为空,请填写职务")); continue; } vo.setJob(oneData.get(2)); if (StringUtils.isEmpty(oneData.get(3))) { index++; mistakes.add(setErrorObject(oneData,"联系电话不可为空,请填写联系电话")); continue; }else{ //验证手机号正则 String regex = "^[1][3,4,5,6,7,8,9][0-9]{9}$"; Pattern pattern = Pattern.compile(regex); Matcher m = pattern.matcher(oneData.get(3)); if(!m.matches()){ index++; mistakes.add(setErrorObject(oneData,"联系电话输入错误,请核对联系电话")); continue; } } vo.setPhone(oneData.get(3)); if (StringUtils.isEmpty(oneData.get(4))) { index++; mistakes.add(setErrorObject(oneData,"民族不可为空,请填写民族")); continue; }else{ if(!oneData.get(4).contains("族")){ index++; mistakes.add(setErrorObject(oneData,"填写的民族有误,请重新填写(民族格式:X族 如:汉族)")); continue; } } vo.setNation(oneData.get(4)); if (StringUtils.isEmpty(oneData.get(5))) { index++; mistakes.add(setErrorObject(oneData,"住址不可为空,请填写住址")); continue; } vo.setAddress(oneData.get(5)); if (StringUtils.isEmpty(oneData.get(6))) { index++; mistakes.add(setErrorObject(oneData,"身份证号不可为空,请填写身份证号码")); continue; } // 判断身份证号码位数 if (oneData.get(6).length() != 18) { index++; mistakes.add(setErrorObject(oneData,"身份证号位数有误,请检查身份证号码是否正确")); continue; } vo.setIdCard(oneData.get(6).toUpperCase()); voList.add(vo); index++; } List newVoList = voList.stream().filter(ListUtils.distinctByKey(ComClusterMemberExcelVO::getIdCard)) .collect(Collectors.toList()); R r = communityService.importClusterMember(newVoList, communityId, userId); if (!R.isOk(r)) { List list = JSONArray.parseArray(JSONArray.toJSONString(r.getData()), ComClusterMemberExcelErrorVO.class); mistakes.addAll(list); valueOperations.set(key, JSONArray.toJSONString(mistakes), 1, TimeUnit.HOURS); throw new ServiceException("500", key); } else { if (!mistakes.isEmpty()) { valueOperations.set(key, JSONArray.toJSONString(mistakes), 1, TimeUnit.HOURS); throw new ServiceException("500", key); } } } catch (NumberFormatException e) { e.printStackTrace(); throw new ServiceException("500", "导入失败"); } } private void setError(Map map, ComClusterMemberExcelErrorVO vo) { vo.setName(map.get(0)); vo.setClusterName(map.get(1)); vo.setJob(map.get(2)); vo.setPhone(map.get(3)); vo.setNation(map.get(4)); vo.setAddress(map.get(5)); vo.setIdCard(map.get(6)); } /** * 组装错误信息 * @param oneData 数据表格对象 * @param error 错误信息 * @return 错误对象 */ private ComClusterMemberExcelErrorVO setErrorObject(Map oneData, String error){ ComClusterMemberExcelErrorVO mistake = new ComClusterMemberExcelErrorVO(); setError(oneData, mistake); mistake.setError(error); return mistake; } }