package com.finance.web.controller.lisenter; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.finance.common.core.domain.entity.SysUser; import com.finance.common.enums.UserTypeEnum; import com.finance.common.exception.ServiceException; import com.finance.common.utils.BeanUtils; import com.finance.common.utils.SecurityUtils; import com.finance.common.utils.StringUtils; import com.finance.system.service.ISysUserService; import com.finance.web.controller.excel.DeptExcel; import java.util.List; import lombok.extern.slf4j.Slf4j; /** * @author mitao * @date 2024/3/28 */ @Slf4j public class DeptImportListener implements ReadListener { /** * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 2000; /** * 缓存的数据 */ private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); public ISysUserService sysUserService; public DeptImportListener() { } public DeptImportListener(ISysUserService sysUserService) { this.sysUserService = sysUserService; } @Override public void invoke(DeptExcel data, AnalysisContext context) { log.info("解析到一条数据:{}", JSON.toJSONString(data)); if (StringUtils.isEmpty(data.getAreaName()) || StringUtils.isEmpty(data.getAreaCode()) || StringUtils.isEmpty(data.getAreaLevel()) || StringUtils.isNull(data.getCountyFlag()) || StringUtils.isEmpty(data.getPersonInCharge()) || StringUtils.isEmpty( data.getUserName()) || StringUtils.isEmpty(data.getPhoneNumber()) || StringUtils.isEmpty( data.getPassword())) { throw new ServiceException(String.format("数据校验失败,请检查第%d行内容填写是否完整", cachedDataList.size() + 1)); } boolean flag = sysUserService.lambdaQuery() .eq(SysUser::getUserType, UserTypeEnum.PLATFORM.getCode()) .eq(SysUser::getUserName, data.getUserName()).oneOpt().isPresent(); if (flag) { throw new ServiceException(String.format("数据校验失败,第%d行的登录账号:%s已存在", cachedDataList.size() + 1, data.getUserName())); } flag = cachedDataList.stream() .anyMatch(item -> item.getAreaCode().equals(data.getAreaCode())); if (flag) { throw new ServiceException( String.format("数据校验失败,第%d行区划代码%s重复", cachedDataList.size() + 1, data.getAreaCode())); } flag = cachedDataList.stream() .anyMatch(item -> item.getUserName().equals(data.getUserName())); if (flag) { throw new ServiceException( String.format("数据校验失败,第%d行登录账号%s重复", cachedDataList.size() + 1, data.getAreaCode())); } cachedDataList.add(data); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (cachedDataList.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("所有数据解析完成!"); saveData(); } private void saveData() { log.info("{}条数据,开始存储数据库!", cachedDataList.size()); List sysUsers = BeanUtils.copyList(cachedDataList, SysUser.class); sysUsers.forEach(item -> { item.setPassword(SecurityUtils.encryptPassword(item.getPassword())); item.setNickName(item.getAreaName()); item.setUserType(UserTypeEnum.DEPARTMENT); }); sysUserService.remove(Wrappers.lambdaQuery() .eq(SysUser::getUserType, UserTypeEnum.DEPARTMENT.getCode())); sysUserService.saveBatch(sysUsers); log.info("{}条数据,导入成功!", cachedDataList.size()); } }