package com.doumee.service.business.impl; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.annotation.excel.ExcelImporter; import com.doumee.core.constants.Constants; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.model.PageData; import com.doumee.core.model.PageWrap; import com.doumee.core.utils.DateUtil; import com.doumee.core.utils.tyyun.TyyZosUtil; import com.doumee.dao.business.CasesMapper; import com.doumee.dao.business.CategoryMapper; import com.doumee.dao.business.MemberMapper; import com.doumee.dao.business.dto.CasesImport; import com.doumee.dao.business.dto.MemberImport; import com.doumee.dao.business.model.Cases; import com.doumee.dao.business.model.Category; import com.doumee.dao.business.model.ImportRecord; import com.doumee.core.utils.Utils; import com.doumee.dao.business.ImportRecordMapper; import com.doumee.dao.business.model.Member; import com.doumee.dao.system.model.SystemUser; import com.doumee.service.business.ImportRecordService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.sun.xml.internal.messaging.saaj.util.ByteInputStream; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.xssf.usermodel.XSSFPictureData; import org.apache.shiro.SecurityUtils; import org.checkerframework.checker.units.qual.A; import org.checkerframework.checker.units.qual.C; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.TimeUnit; /** * 分类信息表Service实现 * @author doumee * @date 2026-01-27 16:02:37 */ @Service @Slf4j public class ImportRecordServiceImpl implements ImportRecordService { @Autowired private ImportRecordMapper importRecordMapper; @Autowired private CategoryMapper categoryMapper; @Autowired private MemberMapper memberMapper; @Autowired private CasesMapper casesMapper; @Resource private RedisTemplate redisTemplate; @Resource private SystemDictDataBiz systemDictDataBiz; @Override public Integer create(ImportRecord importRecord) { if(StringUtils.isBlank(importRecord.getImgurl())){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal(); importRecord.setDeleted(Constants.ZERO); importRecord.setStatus(Constants.ZERO); importRecord.setCreateTime(new Date()); importRecord.setCreateUser(loginUserInfo.getId()); importRecord.setUpdateTime(new Date()); importRecord.setUpdateUser(loginUserInfo.getId()); importRecordMapper.insert(importRecord); return importRecord.getId(); } @Override public void deleteById(Integer id) { importRecordMapper.deleteById(id); } @Override public void delete(ImportRecord importRecord) { UpdateWrapper deleteWrapper = new UpdateWrapper<>(importRecord); importRecordMapper.delete(deleteWrapper); } @Override public void deleteByIdInBatch(List ids) { if (CollectionUtils.isEmpty(ids)) { return; } importRecordMapper.deleteBatchIds(ids); } @Override public void updateById(ImportRecord importRecord) { importRecordMapper.updateById(importRecord); } @Override public void updateByIdInBatch(List importRecords) { if (CollectionUtils.isEmpty(importRecords)) { return; } for (ImportRecord importRecord: importRecords) { this.updateById(importRecord); } } @Override public ImportRecord findById(Integer id) { return importRecordMapper.selectById(id); } @Override public ImportRecord findOne(ImportRecord importRecord) { QueryWrapper wrapper = new QueryWrapper<>(importRecord).last("limit 1"); return importRecordMapper.selectOne(wrapper); } @Override public List findList(ImportRecord importRecord) { QueryWrapper wrapper = new QueryWrapper<>(importRecord); return importRecordMapper.selectList(wrapper); } @Override public PageData findPage(PageWrap pageWrap) { IPage page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); MPJLambdaWrapper queryWrapper = new MPJLambdaWrapper<>(); Utils.MP.blankToNull(pageWrap.getModel()); queryWrapper.selectAll(ImportRecord.class ) .selectAs(SystemUser::getRealname,ImportRecord::getUpdateUserName) .leftJoin(SystemUser.class,SystemUser::getId,ImportRecord::getUpdateUser); queryWrapper.eq(pageWrap.getModel().getId() != null,ImportRecord::getId, pageWrap.getModel().getId()); queryWrapper.eq(pageWrap.getModel().getDeleted() != null,ImportRecord::getDeleted, pageWrap.getModel().getDeleted()); queryWrapper.eq(pageWrap.getModel().getCreateUser() != null,ImportRecord::getCreateUser, pageWrap.getModel().getCreateUser()); queryWrapper.eq(pageWrap.getModel().getUpdateUser() != null,ImportRecord::getUpdateUser, pageWrap.getModel().getUpdateUser()); queryWrapper.eq(pageWrap.getModel().getRemark() != null,ImportRecord::getRemark, pageWrap.getModel().getRemark()); queryWrapper.eq(pageWrap.getModel().getStatus() != null,ImportRecord::getStatus, pageWrap.getModel().getStatus()); queryWrapper.eq(pageWrap.getModel().getTitle() != null,ImportRecord::getTitle, pageWrap.getModel().getTitle()); queryWrapper.eq(pageWrap.getModel().getTotalNum() != null,ImportRecord::getTotalNum, pageWrap.getModel().getTotalNum()); queryWrapper.eq(pageWrap.getModel().getDetail() != null,ImportRecord::getDetail, pageWrap.getModel().getDetail()); queryWrapper.eq(pageWrap.getModel().getImgurl() != null,ImportRecord::getImgurl, pageWrap.getModel().getImgurl()); queryWrapper.eq(pageWrap.getModel().getSortnum() != null,ImportRecord::getSortnum, pageWrap.getModel().getSortnum()); queryWrapper.eq(pageWrap.getModel().getType() != null,ImportRecord::getType, pageWrap.getModel().getType()); queryWrapper.eq(pageWrap.getModel().getDoneNum() != null,ImportRecord::getDoneNum, pageWrap.getModel().getDoneNum()); queryWrapper.eq(pageWrap.getModel().getErrorNum() != null,ImportRecord::getErrorNum, pageWrap.getModel().getErrorNum()); queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getUpdateUserName()),SystemUser::getRealname, pageWrap.getModel().getUpdateUserName()); queryWrapper.ge(pageWrap.getModel().getEndtime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getEndtime()); queryWrapper.ne(pageWrap.getModel().getStarttime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getStarttime()); queryWrapper.orderByDesc(ImportRecord::getId); return PageData.from(importRecordMapper.selectPage(page, queryWrapper)); } @Override public long count(ImportRecord importRecord) { QueryWrapper wrapper = new QueryWrapper<>(importRecord); return importRecordMapper.selectCount(wrapper); } @Override public ImportRecord importBatch(MultipartFile file,int type ){ Boolean importing = (Boolean) redisTemplate.opsForValue().get(Constants.RedisKeys.IMPORTING_RECORD); if(importing!=null && importing){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,已存在导入任务正在执行中,请稍后再试!"); } redisTemplate.opsForValue().set(Constants.RedisKeys.IMPORTING_RECORD,true,30, TimeUnit.MINUTES); try { List categoryList = null; if(type == 0){ categoryList = categoryMapper.selectList(new QueryWrapper().lambda().eq(Category::getDeleted,Constants.ZERO)); if(categoryList == null || categoryList.size()==0){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起, 读取老师基数数据配置出错,请先配置基础数据信息!"); } } ImportRecord model = new ImportRecord(); LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal(); model.setDeleted(Constants.ZERO); model.setStatus(Constants.ONE);//异步处理中 model.setCreateTime(new Date()); model.setCreateUser(loginUserInfo.getId()); model.setUpdateTime(model.getCreateTime()); model.setUpdateUser(loginUserInfo.getId()); model.setType(type); model.setTitle((type==1?"案例信息批量导入":"老师信息批量导入,")+"文件:"+file.getOriginalFilename()); model.setTotalNum(0); ExcelImporter ie= new ExcelImporter(file,0,0, CellType.STRING); // 确保单元格类型为字符串); Map pics = ie.getExcelPictures(); if(type == 1) { List importList = (ie.getDataList(CasesImport.class,null)); if(importList==null || importList.size()==0){ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"导入文件案例信息内容为空!"); } model.setTotalNum(model.getCaseList().size()); }else{ List importList = (ie.getDataList(MemberImport.class,null)); model.setMemberList(isvalidImpartMemberParam(loginUserInfo,categoryList,pics,importList)); model.setTotalNum(model.getMemberList().size()); } importRecordMapper.insert(model); return model; }catch (BusinessException e){ redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD); throw e; }catch (Exception e){ redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD); throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"文件信息读取失败,请检查文件内容后重试!"); }finally { // redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD); } } private List isvalidImpartMemberParam(LoginUserInfo user, List categoryList ,Map pics, List memberList) { if(memberList ==null || memberList.size()==0){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,未读取到有效数据"); } if(pics ==null || pics.size()==0){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,未读取到任何职业照图片数据"); } List insertMember = new ArrayList<>(); List allList = memberMapper.selectList(new QueryWrapper().lambda() .eq(Member::getDeleted,Constants.ZERO)); allList=allList==null?new ArrayList<>():allList; if(categoryList == null || categoryList.size()==0){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起, 读取老师基数数据配置出错,请先配置基础数据信息!"); } Date date = new Date(); int index = 1; for(MemberImport param :memberList){ index ++; if(StringUtils.isBlank(param.getImgurl()) ||StringUtils.isBlank(param.getFee()) ||StringUtils.isBlank(param.getName()) ||StringUtils.isBlank(param.getInfo()) ||StringUtils.isBlank(param.getJobYear()) ||StringUtils.isBlank(param.getPosition()) ||StringUtils.isBlank(param.getFieldNames()) ||StringUtils.isBlank(param.getSex()) ||StringUtils.isBlank(param.getCode()) ||StringUtils.isBlank(param.getZqNames()) ||StringUtils.isBlank(param.getLevelName()) ||StringUtils.isBlank(param.getServeNum()) ||StringUtils.isBlank(param.getTypeNames())){ continue; } Member member = new Member(); if(StringUtils.isBlank(param.getCode())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 工号信息不能为空"); } for(Member m : allList){ if(StringUtils.equals(param.getCode(),m.getCode())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 工号【"+param.getCode()+"】信息已存在,请确认不要重复录入"); } } for(Member m : insertMember){ if(StringUtils.equals(param.getCode(),m.getCode())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 工号【"+param.getCode()+"】在文档中重复出现"); } } if(StringUtils.isBlank(param.getName())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 姓名信息不能为空"); } if(StringUtils.isBlank(param.getLevelName())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 等级信息不能为空"); } if(StringUtils.isBlank(param.getJobYear())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 从业年份信息不能为空"); } Integer year ; try { year = Integer.parseInt(param.getJobYear()); }catch (Exception e){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 从业年份信息不正确"); } if(StringUtils.isBlank(param.getZqNames())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 服务战区信息不能为空"); } if(StringUtils.isBlank(param.getTypeNames())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 商业化类型信息不能为空"); } if(StringUtils.isBlank(param.getFee())){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 费用标准信息不能为空"); } if(pics!=null && StringUtils.isNotBlank(param.getImgurl())){ log.info("===================="+param.getImgurl()); int start = param.getImgurl().indexOf("(\"")+2; int end = param.getImgurl().indexOf("\","); if(start>=0&& end>=1 && end>start){ String picId = param.getImgurl().substring(start,end); log.info("====================PICID:"+param.getImgurl()); XSSFPictureData data = pics.get(picId); if(data!= null && data.getData() != null){ member.setImgurlData(data.getData()); } } } if(member.getImgurlData() ==null || member.getImgurlData().length==0){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行【"+param.getName()+"】数据, 未读取到任何职业照图片数据"); } //类型:0=战区;1=商业化;2=擅长领域;3=讲师等级;" List list0 = isValidCategoryParam(param.getZqNames(),Constants.ZERO,categoryList,index );//战区 List list1 = isValidCategoryParam(param.getTypeNames(),Constants.ONE,categoryList,index);//商业化 List list2 = isValidCategoryParam(param.getFieldNames(),Constants.TWO,categoryList,index);//擅长领域 Category levelCate = getCategoryModelByName(param.getLevelName(),Constants.THREE,categoryList);//讲师等级 if(levelCate == null){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, 等级信息【"+param.getLevelName()+"】尚未配置"); } member.setCreateTime(date); member.setUpdateTime(date); member.setCreateUser(user.getId()); member.setUpdateUser(user.getId()); member.setAddType(Constants.ONE); member.setDeleted(Constants.ZERO); member.setStatus(Constants.ZERO); member.setName(param.getName()); member.setContent(param.getInfo()); member.setJobYear(year); member.setCode(param.getCode()); member.setPositon(param.getPosition()); try { member.setServeNum(Integer.parseInt(param.getServeNum())); }catch (Exception e){ } try { member.setFee(new BigDecimal(param.getFee())); }catch (Exception e){ } member.setSex(StringUtils.equals(param.getSex(),"男")?Constants.ZERO:(StringUtils.equals(param.getSex(),"女")?Constants.ZERO:null)); member.setZhanquIds(getIdStrListByList(list0)); member.setBustypeIds(getIdStrListByList(list1)); member.setFieldIds(getIdStrListByList(list2)); member.setLevelId(levelCate.getId()); insertMember.add(member); } if(insertMember ==null || insertMember.size()==0){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,未读取到有效数据"); } return insertMember; } private String getIdStrListByList(List categoryList) { String[] idList = new String[categoryList.size()]; for (int i = 0; i isValidCategoryParam(String zqNames, int type, List categoryList,int index) { if(StringUtils.isBlank(zqNames)){ return null; } //获客类|市场类|培训类 List list = new ArrayList<>(); String names[] = zqNames.split("/"); String title = type==0?"服务战区":( type==1?"商业化类型":"擅长领域"); for(String str : names){ if(StringUtils.isBlank(str)){ continue; } Category cate = getCategoryModelByName(str,type,categoryList); if(cate == null){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据,"+title+"中【"+str+"】尚未配置"); } list.add(cate); } if(list == null || list.size() ==0){ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据,"+title+"未查询到有效配置"); } return list; } private Category getCategoryModelByName(String levelName, int type, List categoryList) { for(Category c : categoryList){ if(Constants.equalsInteger(c.getType(),type) && StringUtils.equals(levelName.trim(),StringUtils.defaultString(c.getName(),"").trim())){ return c; } } return null; } /** * 异步执行文件任务 * @param importRecord */ @Override @Async public void dealImporTask(ImportRecord importRecord){ int success = 0; if(Constants.equalsInteger(importRecord.getType(),0)){ dealUserImportBiz(importRecord); }else{ dealCaseImportBiz(importRecord); } importRecord.setStatus(Constants.TWO); importRecord.setUpdateTime(new Date()); importRecordMapper.updateById(importRecord); } /** * 处理案例导入任务 * @param importRecord */ private int dealCaseImportBiz(ImportRecord importRecord) { int success=0; String msg =""; try { for(Cases param:importRecord.getCaseList()){ } }catch (Exception e){ } importRecord.setDoneNum(success); importRecord.setErrorNum(importRecord.getTotalNum() - success); return success; } /** * 处理人员导入记录 * @param importRecord */ private int dealUserImportBiz(ImportRecord importRecord) { int success=0; String msg = ""; String nowDate =DateUtil.getNowShortDate(); try { String bucket =systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.BUCKETNAME).getCode(); String folder =systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.MEMBER_FILES).getCode(); TyyZosUtil obs = new TyyZosUtil(systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.ENDPOINT).getCode(), systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.ACCESS_ID).getCode(), systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.ACCESS_KEY).getCode()); for(Member param: importRecord.getMemberList()){ success += dealMemberInsert(obs,param,folder,nowDate,bucket); } obs.shutDown(); }catch (Exception e){ log.error("处理人员信息发生异常{}",e.getMessage()); } importRecord.setDoneNum(success); importRecord.setErrorNum(importRecord.getTotalNum() - success); importRecord.setDetail(msg); redisTemplate.delete(Constants.RedisKeys.IMPORTING_RECORD); return success; } private int dealMemberInsert( TyyZosUtil obs,Member param,String folder,String nowDate,String bucketName) { int success =0; try { String fileName = UUID.randomUUID() + ".png"; String tempFileName = nowDate + "/" + fileName; String key = folder + tempFileName;// 文件名 if (obs.uploadInputstreamObjectNoShutdown(new ByteArrayInputStream(param.getImgurlData() ) ,bucketName, key)) { param.setImgurl(tempFileName);//证件照地址 log.error("处理人员信息证件照成功=================={}",key ); success= memberMapper.insert(param); } }catch (Exception e){ log.error("处理人员信息{}==发生异常{}",param.getName(),e.getMessage()); } return success; } }