package com.xjrsoft.module.textbook.service.impl; import cn.dev33.satoken.stp.StpUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.xjrsoft.common.enums.ArchivesStatusEnum; import com.xjrsoft.common.enums.ClaimTypeEnum; import com.xjrsoft.common.enums.DeleteMark; import com.xjrsoft.common.enums.IssueModeEnum; import com.xjrsoft.common.exception.MyException; import com.xjrsoft.common.page.ConventPage; import com.xjrsoft.common.utils.VoToColumnUtil; import com.xjrsoft.module.base.entity.BaseClass; import com.xjrsoft.module.base.entity.BaseSemester; import com.xjrsoft.module.generator.entity.ImportConfig; import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll; import com.xjrsoft.module.system.entity.DictionaryDetail; import com.xjrsoft.module.teacher.entity.XjrUser; import com.xjrsoft.module.teacher.mapper.XjrUserMapper; import com.xjrsoft.module.textbook.dto.*; import com.xjrsoft.module.textbook.entity.*; import com.xjrsoft.module.textbook.mapper.*; import com.xjrsoft.module.textbook.service.IWfTextbookClaimService; import com.xjrsoft.module.textbook.vo.*; import com.xjrsoft.module.veb.util.ImportExcelUtil; import com.xjrsoft.module.workflow.entity.WorkflowFormRelation; import com.xjrsoft.module.workflow.mapper.WorkflowFormRelationMapper; import lombok.AllArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.camunda.bpm.engine.history.HistoricProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; /** * @title: 教材申领 * @Author szs * @Date: 2023-12-26 * @Version 1.0 */ @Service @AllArgsConstructor public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl implements IWfTextbookClaimService { private final WfTextbookClaimMapper wfTextbookClaimWfTextbookClaimMapper; private final WfTextbookClaimItemMapper wfTextbookClaimWfTextbookClaimItemMapper; private final XjrUserMapper xjrUserMapper; private final TextbookIssueRecordMapper textbookIssueRecordMapper; private final TextbookClaimUserMapper textbookClaimUserMapper; private final WorkflowFormRelationMapper workflowFormRelationMapper; private final TextbookWarehouseRecordMapper textbookWarehouseRecordMapper; private final TextbookStudentClaimMapper textbookStudentClaimMapper; @Override public IPage distributePage(DistributePageDto dto) { // 申领主表记录 MPJLambdaWrapper wfTextbookClaimMPJLambdaWrapper = new MPJLambdaWrapper<>(); wfTextbookClaimMPJLambdaWrapper .disableSubLogicDel() .select(WfTextbookClaim::getId) .select(WfTextbookClaim.class, x -> VoToColumnUtil.fieldsToColumns(DistributePageVo.class).contains(x.getProperty())) .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfTextbookClaim::getClaimType, wrapper -> wrapper .selectAs(DictionaryDetail::getName, DistributePageVo::getClaimTypeCn) ) .leftJoin(XjrUser.class, XjrUser::getId, WfTextbookClaim::getApplicantUserId, wrapper -> wrapper .selectAs(XjrUser::getName, DistributePageVo::getApplicantUserIdCn) ) .leftJoin(BaseClass.class, BaseClass::getId, WfTextbookClaim::getClassId, wrapper -> wrapper .selectAs(BaseClass::getName, DistributePageVo::getClassIdCn) ) .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookClaim::getBaseSemesterId, wrapper -> wrapper .selectAs(BaseSemester::getName, DistributePageVo::getBaseSemesterIdCn) ) .leftJoin(XjrUser.class, XjrUser::getId, WfTextbookClaim::getStudentUserId, wrapper -> wrapper .selectAs(XjrUser::getName, DistributePageVo::getStudentUserIdCn) ) .eq(WfTextbookClaim::getBaseSemesterId, dto.getBaseSemesterId()) .eq(StringUtils.isNotEmpty(dto.getClaimType()), WfTextbookClaim::getClaimType, dto.getClaimType()) .and(StringUtils.isNotEmpty(dto.getName()), wrapper -> wrapper .like(XjrUser::getName, dto.getName()) .or() .like(BaseClass::getName, dto.getName()) ) ; // 发放状态(是否有过发放(1:未发放,2:部分发放,3:全部发放,4:有发放)) if (ObjectUtils.isNotEmpty(dto.getDistributeStatus())) { // 有发放,除了未发放其他所有的状态 if (dto.getDistributeStatus() == 4) { wfTextbookClaimMPJLambdaWrapper .ne(WfTextbookClaim::getStatus, 1) ; } else { wfTextbookClaimMPJLambdaWrapper .eq(WfTextbookClaim::getStatus, dto.getDistributeStatus()) ; } } // 流程状态(0:未结束,1:已结束,正常通过,2:已结束,未通过,3:作废) if (ObjectUtils.isNotEmpty(dto.getWorkflowStatus())) { wfTextbookClaimMPJLambdaWrapper .eq(WfTextbookClaim::getWorkflowStatus, dto.getWorkflowStatus()) ; } else { wfTextbookClaimMPJLambdaWrapper .and(wrapper -> wrapper .eq(WfTextbookClaim::getWorkflowStatus, 1) .or() .eq(WfTextbookClaim::getWorkflowStatus, 3) ) ; } IPage page = this.selectJoinListPage(ConventPage.getPage(dto), DistributePageVo.class, wfTextbookClaimMPJLambdaWrapper); // 当申领记录为空 List records = page.getRecords(); if(CollectionUtils.isEmpty(records)){ return page; } List claimIds = records.stream() .map(DistributePageVo::getId) .collect(Collectors.toList()); // 查询统计数据 MPJLambdaWrapper statsWrapper = new MPJLambdaWrapper<>(); statsWrapper .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId) .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber) .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber) .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds) .groupBy(WfTextbookClaimItem::getWfTextbookClaimId); List statsList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, statsWrapper); Map statsMap = statsList.stream() .collect(Collectors.toMap( WfTextbookClaimItem::getWfTextbookClaimId, Function.identity(), (w1, w2) -> w1)); // 可视情况记录冲突日志 // 查询子项数据 MPJLambdaWrapper itemWrapper = new MPJLambdaWrapper<>(); itemWrapper.disableSubLogicDel() .select(WfTextbookClaimItem::getId) .selectAs(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItemVo::getApplicantNumber) .selectAs(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItemVo::getIssueNumber) .select(WfTextbookClaimItem.class, x -> VoToColumnUtil.fieldsToColumns(WfTextbookClaimItemVo.class).contains(x.getProperty())) .leftJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId, w -> w .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn) .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn)) .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds); List itemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItemVo.class, itemWrapper); Map> itemMap = itemList.stream() .collect(Collectors.groupingBy(WfTextbookClaimItemVo::getWfTextbookClaimId)); // 查询发放记录 MPJLambdaWrapper recordWrapper = new MPJLambdaWrapper<>(); recordWrapper.disableSubLogicDel() .selectAs(TextbookIssueRecord::getDataId, DistributeRecordVo::getWfTextbookClaimId) .selectAs(TextbookIssueRecord::getDataItemId, DistributeRecordVo::getWfTextbookClaimItemId) .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate) .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber) .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber) .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark) .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId, w -> w .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn) .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn)) .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId, w -> w .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser)) .in(TextbookIssueRecord::getDataId, claimIds); List recordList = textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, recordWrapper); Map> recordMap = recordList.stream() .collect(Collectors.groupingBy(DistributeRecordVo::getWfTextbookClaimItemId)); // 组装数据 for (DistributePageVo vo : records) { Long claimId = vo.getId(); // 填充统计信息 if (MapUtils.isNotEmpty(statsMap) && statsMap.containsKey(claimId)) { WfTextbookClaimItem stat = statsMap.get(claimId); vo.setApplicantTatolNumber(stat.getApplicantNumber()); vo.setIssueTatolNumber(stat.getIssueNumber()); } // 填充子项及发放记录 if (MapUtils.isNotEmpty(itemMap) && CollectionUtils.isNotEmpty(itemMap.get(claimId))) { List items = itemMap.get(claimId); for (WfTextbookClaimItemVo item : items) { if (recordMap.containsKey(item.getId())) { item.setDistributeRecordVos(recordMap.get(item.getId())); } } vo.setWfTextbookClaimItemVoList(items); } } return page; } @Override @Transactional(rollbackFor = Exception.class) public Boolean add(WfTextbookClaim wfTextbookClaim) { wfTextbookClaimWfTextbookClaimMapper.insert(wfTextbookClaim); for (WfTextbookClaimItem wfTextbookClaimItem : wfTextbookClaim.getWfTextbookClaimItemList()) { wfTextbookClaimItem.setWfTextbookClaimId(wfTextbookClaim.getId()); wfTextbookClaimWfTextbookClaimItemMapper.insert(wfTextbookClaimItem); } return true; } @Override @Transactional(rollbackFor = Exception.class) public Boolean update(WfTextbookClaim wfTextbookClaim) { wfTextbookClaimWfTextbookClaimMapper.updateById(wfTextbookClaim); //********************************* WfTextbookClaimItem 增删改 开始 *******************************************/ { // 查出所有子级的id List wfTextbookClaimItemList = wfTextbookClaimWfTextbookClaimItemMapper.selectList(Wrappers.lambdaQuery(WfTextbookClaimItem.class).eq(WfTextbookClaimItem::getWfTextbookClaimId, wfTextbookClaim.getId()).select(WfTextbookClaimItem::getId)); List wfTextbookClaimItemIds = wfTextbookClaimItemList.stream().map(WfTextbookClaimItem::getId).collect(Collectors.toList()); //原有子表单 没有被删除的主键 List wfTextbookClaimItemOldIds = wfTextbookClaim.getWfTextbookClaimItemList().stream().map(WfTextbookClaimItem::getId).filter(Objects::nonNull).collect(Collectors.toList()); //找到需要删除的id List wfTextbookClaimItemRemoveIds = wfTextbookClaimItemIds.stream().filter(item -> !wfTextbookClaimItemOldIds.contains(item)).collect(Collectors.toList()); for (WfTextbookClaimItem wfTextbookClaimItem : wfTextbookClaim.getWfTextbookClaimItemList()) { //如果不等于空则修改 if (wfTextbookClaimItem.getId() != null) { wfTextbookClaimWfTextbookClaimItemMapper.updateById(wfTextbookClaimItem); } //如果等于空 则新增 else { //已经不存在的id 删除 wfTextbookClaimItem.setWfTextbookClaimId(wfTextbookClaim.getId()); wfTextbookClaimWfTextbookClaimItemMapper.insert(wfTextbookClaimItem); } } //已经不存在的id 删除 if (wfTextbookClaimItemRemoveIds.size() > 0) { wfTextbookClaimWfTextbookClaimItemMapper.deleteBatchIds(wfTextbookClaimItemRemoveIds); } } //********************************* WfTextbookClaimItem 增删改 结束 *******************************************/ return true; } @Override @Transactional(rollbackFor = Exception.class) public Boolean delete(List ids) { wfTextbookClaimWfTextbookClaimMapper.deleteBatchIds(ids); wfTextbookClaimWfTextbookClaimItemMapper.delete(Wrappers.lambdaQuery(WfTextbookClaimItem.class).in(WfTextbookClaimItem::getWfTextbookClaimId, ids)); return true; } @Override public IPage getPage(WfTextbookClaimPageDto dto) { dto.setUserId(StpUtil.getLoginIdAsLong()); IPage page = wfTextbookClaimWfTextbookClaimMapper.getPage(ConventPage.getPage(dto), dto); for (WfTextbookClaimPageVo wfTextbookClaimPageVo : page.getRecords()) { //拆分代领取人 String receiveUserIdStr = wfTextbookClaimPageVo.getReceiveUserId(); if (ObjectUtils.isNotEmpty(receiveUserIdStr) && !receiveUserIdStr.isEmpty()) { String[] receiveUserIdStrs = receiveUserIdStr.split(","); List receiveUserIdList = new ArrayList<>(); for (String str : receiveUserIdStrs) { receiveUserIdList.add(Long.parseLong(str)); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper .in(XjrUser::getId, receiveUserIdList); List xjrUserList = xjrUserMapper.selectList(queryWrapper); if (ObjectUtils.isNotEmpty(xjrUserList) && !xjrUserList.isEmpty()) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < xjrUserList.size(); i++) { if (i == 0) { sb.append(xjrUserList.get(i).getName()); } else { sb.append(",").append(xjrUserList.get(i).getName()); } } wfTextbookClaimPageVo.setReceiveUserIdCN(sb.toString()); } } //加上申领项 List wfTextbookClaimItemVoList = wfTextbookClaimWfTextbookClaimItemMapper.getListByWfTextbookClaimId(Long.parseLong(wfTextbookClaimPageVo.getId())); if (ObjectUtils.isNotEmpty(wfTextbookClaimItemVoList) && !wfTextbookClaimItemVoList.isEmpty()) { wfTextbookClaimPageVo.setWfTextbookClaimItemList(wfTextbookClaimItemVoList); } } return page; } @Override public WfTextbookClaimVo infoDistribute(Long id) { WfTextbookClaimVo wfTextbookClaimVo = wfTextbookClaimWfTextbookClaimMapper.infoDistribute(id); if (ObjectUtils.isNotEmpty(wfTextbookClaimVo)) { //拆分代领人 String receiveUserIdStr = wfTextbookClaimVo.getReceiveUserId(); if (ObjectUtils.isNotEmpty(receiveUserIdStr) && !receiveUserIdStr.isEmpty()) { String[] receiveUserIdStrs = receiveUserIdStr.split(","); List receiveUserIdList = new ArrayList<>(); for (String str : receiveUserIdStrs) { receiveUserIdList.add(Long.parseLong(str)); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper .in(XjrUser::getId, receiveUserIdList); List xjrUserList = xjrUserMapper.selectList(queryWrapper); if (ObjectUtils.isNotEmpty(xjrUserList) && !xjrUserList.isEmpty()) { StringBuilder sb = new StringBuilder(); for (XjrUser xjrUser : xjrUserList) { sb.append(",").append(xjrUser.getName()); } wfTextbookClaimVo.setReceiveUserIdCN(sb.toString()); } } //加上申领项 List wfTextbookClaimItemVoList = wfTextbookClaimWfTextbookClaimItemMapper.getListByWfTextbookClaimId(Long.parseLong(wfTextbookClaimVo.getId())); if (ObjectUtils.isNotEmpty(wfTextbookClaimItemVoList) && !wfTextbookClaimItemVoList.isEmpty()) { wfTextbookClaimVo.setWfTextbookClaimItemList(wfTextbookClaimItemVoList); } } return wfTextbookClaimVo; } @Override public List distributeRecord(Long id) { MPJLambdaWrapper textbookIssueRecordMPJLambdaWrapper = new MPJLambdaWrapper<>(); textbookIssueRecordMPJLambdaWrapper .disableSubLogicDel() .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate) .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber) .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber) .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark) .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId, wrapper -> wrapper .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn) ) .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId, wrapper -> wrapper .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser) ) .eq(TextbookIssueRecord::getDataId, id) ; return textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, textbookIssueRecordMPJLambdaWrapper); } /* @Override @Transactional(rollbackFor = Exception.class) public Boolean confirmDistribute(ConfirmDistributeDto dto) { WfTextbookClaim wfTextbookClaim = this.getByIdDeep(dto.getTextbookClaimId()); List wfTextbookClaimItemList = wfTextbookClaim.getWfTextbookClaimItemList(); int issueTimes = wfTextbookClaim.getIssueTimes() + 1; Date nowDate = new Date(); int claimTotalNum = 0; int issueTotalNum = 0; for (WfTextbookClaimItem wfTextbookClaimItem : wfTextbookClaimItemList) { claimTotalNum += wfTextbookClaimItem.getApplicantNumber(); issueTotalNum += wfTextbookClaimItem.getIssueNumber(); } // 如果是班级申领,获取班级所有学生 List stuList = new ArrayList<>(); if (ClaimTypeEnum.ClaimStudent.getCode().equals(wfTextbookClaim.getClaimType()) && ObjectUtils.isNotEmpty(wfTextbookClaim.getClassId()) ) { MPJLambdaWrapper xjrUserMPJLambdaWrapper = new MPJLambdaWrapper<>(); xjrUserMPJLambdaWrapper .select(XjrUser::getId) .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId) .eq(BaseStudentSchoolRoll::getClassId, wfTextbookClaim.getClassId()) .eq(BaseStudentSchoolRoll::getArchivesStatus, ArchivesStatusEnum.FB2901.getCode()) ; stuList = xjrUserMapper.selectJoinList(XjrUser.class, xjrUserMPJLambdaWrapper); } // 获取所有入库记录 List textbookWarehouseRecordIds = new ArrayList<>(); for (ConfirmDistributeDto.TextbookClaimItem textbookClaimItem : dto.getTextbookClaimItemList()) { for (ConfirmDistributeDto.TextbookWarehouseRecords textbookWarehouseRecords : textbookClaimItem.getTextbookWarehouseRecords()) { textbookWarehouseRecordIds.add(textbookWarehouseRecords.getTextbookWarehouseRecordId()); } } if (ObjectUtils.isEmpty(textbookWarehouseRecordIds)) { throw new MyException("当前发放项来源入库单号无效"); } List textbookWarehouseRecordList = textbookWarehouseRecordMapper.selectList( Wrappers.lambdaQuery(TextbookWarehouseRecord.class) .in(TextbookWarehouseRecord::getId, textbookWarehouseRecordIds) .eq(TextbookWarehouseRecord::getDeleteMark, DeleteMark.NODELETE.getCode()) ); Map textbookWarehouseRecordMap = textbookWarehouseRecordList.stream() .collect(Collectors.toMap(TextbookWarehouseRecord::getId, t -> t, (t1, t2) -> t1)); if (ObjectUtils.isEmpty(wfTextbookClaim) || ObjectUtils.isEmpty(dto.getTextbookClaimItemList()) || dto.getTextbookClaimItemList().isEmpty() || wfTextbookClaimItemList.isEmpty() ) { throw new MyException("未找到申领数据"); } Map wfTextbookClaimItemMap = wfTextbookClaimItemList.stream() .collect(Collectors.toMap(WfTextbookClaimItem::getId, w -> w, (w1, w2) -> w1)); // 根据学期,班级获取学生确认领取记录 LambdaQueryWrapper textbookStudentClaimLambdaQueryWrapper = new LambdaQueryWrapper<>(); textbookStudentClaimLambdaQueryWrapper .eq(TextbookStudentClaim::getBaseSemesterId, wfTextbookClaim.getBaseSemesterId()) .eq(TextbookStudentClaim::getClassId, wfTextbookClaim.getClassId()) ; List textbookStudentClaimList = textbookStudentClaimMapper.selectList(textbookStudentClaimLambdaQueryWrapper); Map byUserIdAndTextbookId = textbookStudentClaimList.stream() .collect(Collectors.toMap(t -> "" + t.getStudentUserId() + t.getTextbookId(), t -> t, (t1, t2) -> t1)); // 处理出库单号 StringBuilder sb = new StringBuilder(); sb.append("CK"); LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String nowStr = now.format(dateTimeFormatter); sb.append(nowStr); int oldOrderInteger = 0; int oldOrderLastInteger = 0; // 操作每一个申领项 WfTextbookClaimItem updateWfTextbookClaimItem; // 学生确认处理 List insertList = new ArrayList<>(); List updateList = new ArrayList<>(); TextbookStudentClaim oldTextbookStudentClaim; TextbookStudentClaim insertTextbookStudentClaim; TextbookStudentClaim updateTextbookStudentClaim; Long loginUserId = StpUtil.getLoginIdAsLong(); for (ConfirmDistributeDto.TextbookClaimItem textbookClaimItem : dto.getTextbookClaimItemList()) { // WfTextbookClaimItem wfTextbookClaimItem = wfTextbookClaimWfTextbookClaimItemMapper.selectById(textbookClaimItem.getTextbookClaimItemId()); WfTextbookClaimItem wfTextbookClaimItem = wfTextbookClaimItemMap.get(textbookClaimItem.getTextbookClaimItemId()); if (ObjectUtils.isEmpty(wfTextbookClaimItem)) { throw new MyException("申领详细数据发生更改,请刷新页面"); } //判断总发放数量是否超出该申请项的申请数量 int issueNumber = ObjectUtils.isEmpty(wfTextbookClaimItem.getIssueNumber()) ? 0 : wfTextbookClaimItem.getIssueNumber();//已发放 int applicantNumber = ObjectUtils.isEmpty(wfTextbookClaimItem.getApplicantNumber()) ? 0 : wfTextbookClaimItem.getApplicantNumber();//申领总数量 int confirmNumber = ObjectUtils.isEmpty(textbookClaimItem.getConfirmTotalNumber()) ? 0 : textbookClaimItem.getConfirmTotalNumber();//本次发放 issueTotalNum += confirmNumber; if (issueNumber + confirmNumber > applicantNumber) { throw new MyException(textbookClaimItem.getTextbookIdCn() + "发放总数量超出申领数量"); } TextbookIssueRecord textbookIssueRecord; // 出库单号前缀 oldOrderInteger += 1; String newOrder = String.format("%03d", oldOrderInteger); // 补零并格式化为三位数 String oldPrex = sb + newOrder + "-"; for (ConfirmDistributeDto.TextbookWarehouseRecords textbookWarehouseRecords : textbookClaimItem.getTextbookWarehouseRecords()) { TextbookWarehouseRecord textbookWarehouseRecord = textbookWarehouseRecordMap.get(textbookWarehouseRecords.getTextbookWarehouseRecordId()); if (ObjectUtils.isEmpty(textbookWarehouseRecord)) { throw new MyException("未找到对应入库详细数据"); } if (textbookWarehouseRecord.getRemainNumber() < textbookWarehouseRecords.getConfirmNumber()) { throw new MyException("发放数量大于库存数量"); } //更新教材入库中的的库存数量 textbookWarehouseRecordMapper.updateById(new TextbookWarehouseRecord() {{ setModifyUserId(StpUtil.getLoginIdAsLong()); setModifyDate(nowDate); setId(textbookWarehouseRecord.getId()); setIssuedNumber(ObjectUtils.isEmpty(textbookWarehouseRecord.getIssuedNumber()) ? 0 : textbookWarehouseRecord.getIssuedNumber() + textbookWarehouseRecords.getConfirmNumber()); setRemainNumber(ObjectUtils.isEmpty(textbookWarehouseRecord.getRemainNumber()) ? 0 : textbookWarehouseRecord.getRemainNumber() - textbookWarehouseRecords.getConfirmNumber() ); }}); //增加出库记录 textbookIssueRecord = new TextbookIssueRecord(); textbookIssueRecord.setBaseSemesterId(wfTextbookClaim.getBaseSemesterId()); // 处理出库单号 // 根据当前申领项主键id和入库主键id查找时候已经有了出库记录 LambdaQueryWrapper maxOrderNumberLambdaQueryWrapper = new LambdaQueryWrapper<>(); maxOrderNumberLambdaQueryWrapper .eq(TextbookIssueRecord::getDataItemId, wfTextbookClaimItem.getId()) .eq(TextbookIssueRecord::getTextbookWarehouseRecordId, textbookWarehouseRecord.getId()) .eq(TextbookIssueRecord::getDeleteMark, DeleteMark.NODELETE.getCode()) .orderByDesc(TextbookIssueRecord::getOrderNumber) .last("limit 1") ; TextbookIssueRecord maxOrderNumber = textbookIssueRecordMapper.selectOne(maxOrderNumberLambdaQueryWrapper); if (ObjectUtils.isNotEmpty(maxOrderNumber) && ObjectUtils.isNotEmpty(maxOrderNumber.getOrderNumber()) ) { String oldOrderNumber = maxOrderNumber.getOrderNumber(); oldPrex = oldOrderNumber.substring(0, oldOrderNumber.length() - 3); oldOrderInteger -= 1; String oldOrder = oldOrderNumber.substring(oldOrderNumber.length() - 3); oldOrderLastInteger = Integer.parseInt(oldOrder); } oldOrderLastInteger += 1; String newLastOrder = String.format("%03d", oldOrderLastInteger); // 补零并格式化为三位数 textbookIssueRecord.setOrderNumber(oldPrex + newLastOrder); if (ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType()) && wfTextbookClaim.getClaimType().equals(ClaimTypeEnum.ClaimStudent.getCode()) ) { textbookIssueRecord.setIssueMode(IssueModeEnum.ImStudent.getCode()); } if (ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType()) && wfTextbookClaim.getClaimType().equals(ClaimTypeEnum.ClaimClass.getCode()) ) { textbookIssueRecord.setIssueMode(IssueModeEnum.ImClass.getCode()); } if (ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType()) && wfTextbookClaim.getClaimType().equals(ClaimTypeEnum.ClaimTeacher.getCode()) ) { textbookIssueRecord.setIssueMode(IssueModeEnum.ImTeacher.getCode()); } textbookIssueRecord.setDataId(wfTextbookClaim.getId()); textbookIssueRecord.setDataItemId(wfTextbookClaimItem.getId()); textbookIssueRecord.setTextbookWarehouseRecordId(textbookWarehouseRecords.getTextbookWarehouseRecordId()); textbookIssueRecord.setTextbookId(wfTextbookClaimItem.getTextbookId()); textbookIssueRecord.setIssueNumber(textbookWarehouseRecords.getConfirmNumber()); textbookIssueRecord.setRecedeNumber(0); textbookIssueRecord.setActualIssueNumber(textbookWarehouseRecords.getConfirmNumber()); textbookIssueRecord.setActualTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(textbookWarehouseRecords.getConfirmNumber()))); if (ObjectUtils.isNotEmpty(dto.getReceiveUserId())) { textbookIssueRecord.setReceiveUserId(dto.getReceiveUserId()); } else { textbookIssueRecord.setReceiveUserId(wfTextbookClaim.getApplicantUserId()); } textbookIssueRecord.setIssueUserId(StpUtil.getLoginIdAsLong()); textbookIssueRecord.setCreateDate(nowDate); textbookIssueRecord.setRemark(dto.getRemark()); textbookIssueRecord.setIssueTimes(issueTimes); textbookIssueRecordMapper.insert(textbookIssueRecord); // 如果申领项是个人申领,发放的时候应该直接帮助学生确认领取 if (ClaimTypeEnum.ClaimStudent.getCode().equals(wfTextbookClaim.getClaimType())) { oldTextbookStudentClaim = byUserIdAndTextbookId.get("" + wfTextbookClaim.getApplicantUserId() + wfTextbookClaimItem.getTextbookId()); if (ObjectUtils.isNotEmpty(oldTextbookStudentClaim) && (ObjectUtils.isEmpty(oldTextbookStudentClaim.getClaimSource()) || oldTextbookStudentClaim.getClaimSource() != 1) ) { updateTextbookStudentClaim = new TextbookStudentClaim(); updateTextbookStudentClaim.setId(oldTextbookStudentClaim.getId()); updateTextbookStudentClaim.setIsClaim(1); updateTextbookStudentClaim.setModifyDate(nowDate); updateTextbookStudentClaim.setModifyUserId(loginUserId); updateTextbookStudentClaim.setTextbookWarehouseRecordId(textbookWarehouseRecord.getId()); updateTextbookStudentClaim.setPrice(textbookWarehouseRecord.getSubtotal()); updateTextbookStudentClaim.setClaimSource(2); updateList.add(updateTextbookStudentClaim); } else { insertTextbookStudentClaim = new TextbookStudentClaim(); insertTextbookStudentClaim.setBaseSemesterId(wfTextbookClaim.getBaseSemesterId()); insertTextbookStudentClaim.setClassId(wfTextbookClaim.getClassId()); insertTextbookStudentClaim.setStudentUserId(wfTextbookClaim.getApplicantUserId()); insertTextbookStudentClaim.setTextbookId(wfTextbookClaimItem.getTextbookId()); insertTextbookStudentClaim.setIsClaim(1); insertTextbookStudentClaim.setCreateDate(nowDate); insertTextbookStudentClaim.setCreateUserId(loginUserId); insertTextbookStudentClaim.setTextbookWarehouseRecordId(textbookWarehouseRecord.getId()); insertTextbookStudentClaim.setPrice(textbookWarehouseRecord.getSubtotal()); insertTextbookStudentClaim.setClaimSource(2); insertList.add(insertTextbookStudentClaim); } } // 如果申领项是班级申领,发放的时候应该直接生成领取记录 if (ClaimTypeEnum.ClaimClass.getCode().equals(wfTextbookClaim.getClaimType())) { for (XjrUser stu : stuList) { oldTextbookStudentClaim = byUserIdAndTextbookId.get("" + stu.getId() + wfTextbookClaimItem.getTextbookId()); if (ObjectUtils.isEmpty(oldTextbookStudentClaim)) { insertTextbookStudentClaim = new TextbookStudentClaim(); insertTextbookStudentClaim.setBaseSemesterId(wfTextbookClaim.getBaseSemesterId()); insertTextbookStudentClaim.setClassId(wfTextbookClaim.getClassId()); insertTextbookStudentClaim.setStudentUserId(stu.getId()); insertTextbookStudentClaim.setTextbookId(wfTextbookClaimItem.getTextbookId()); insertTextbookStudentClaim.setIsClaim(0); insertTextbookStudentClaim.setCreateDate(nowDate); insertTextbookStudentClaim.setCreateUserId(loginUserId); insertTextbookStudentClaim.setTextbookWarehouseRecordId(textbookWarehouseRecord.getId()); insertTextbookStudentClaim.setPrice(textbookWarehouseRecord.getSubtotal()); insertTextbookStudentClaim.setClaimSource(2); insertList.add(insertTextbookStudentClaim); } } } } // 修改征订项发放数量 updateWfTextbookClaimItem = new WfTextbookClaimItem(); updateWfTextbookClaimItem.setId(wfTextbookClaimItem.getId()); updateWfTextbookClaimItem.setIssueNumber( ObjectUtils.isEmpty(wfTextbookClaimItem.getIssueNumber()) ? 0 : wfTextbookClaimItem.getIssueNumber() + textbookClaimItem.getConfirmTotalNumber() ); wfTextbookClaimWfTextbookClaimItemMapper.updateById(updateWfTextbookClaimItem); } if (CollectionUtils.isNotEmpty(insertList)) { for (TextbookStudentClaim insert : insertList) { textbookStudentClaimMapper.insert(insert); } } if (CollectionUtils.isNotEmpty(updateList)) { for (TextbookStudentClaim update : updateList) { textbookStudentClaimMapper.updateById(update); } } // 查询当前申领所有子项是否已经完成, 发放数量大于申领数量 MPJLambdaWrapper wfTextbookClaimItemMPJLambdaWrapper = new MPJLambdaWrapper<>(); wfTextbookClaimItemMPJLambdaWrapper .select(WfTextbookClaimItem::getId) .innerJoin(WfTextbookClaim.class, WfTextbookClaim::getId, WfTextbookClaimItem::getWfTextbookClaimId) .lt(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getApplicantNumber) .eq(WfTextbookClaimItem::getWfTextbookClaimId, wfTextbookClaim.getId()) ; long count = wfTextbookClaimWfTextbookClaimItemMapper.selectCount(wfTextbookClaimItemMPJLambdaWrapper); WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim(); updateWfTextbookClaim.setId(wfTextbookClaim.getId()); if (count > 0) { updateWfTextbookClaim.setStatus(2); } else { updateWfTextbookClaim.setStatus(3); } updateWfTextbookClaim.setIssueTimes(issueTimes); updateWfTextbookClaim.setModifyUserId(StpUtil.getLoginIdAsLong()); updateWfTextbookClaim.setModifyDate(nowDate); //更新申领项中的已经发放数量 wfTextbookClaimWfTextbookClaimMapper.updateById(updateWfTextbookClaim); return true; } */ @Override @Transactional(rollbackFor = Exception.class) public Boolean confirmDistribute(ConfirmDistributeDto dto) { // 1. 参数校验和初始化 validateInput(dto); // 2. 获取基础数据 WfTextbookClaim claim = getClaimData(dto); List students = getRelatedStudents(claim); Map warehouseRecords = getWarehouseRecords(dto); // 3. 处理发放逻辑 processDistribution(claim, dto, warehouseRecords, students); // 4. 更新申领状态 updateClaimStatus(claim); return true; } // 1. 参数校验和初始化 private void validateInput(ConfirmDistributeDto dto) { if (ObjectUtils.isEmpty(dto.getTextbookClaimId())) { throw new MyException("申领ID不能为空"); } if (CollectionUtils.isEmpty(dto.getTextbookClaimItemList())) { throw new MyException("申领项列表不能为空"); } } // 2. 获取申领数据 private WfTextbookClaim getClaimData(ConfirmDistributeDto dto) { WfTextbookClaim claim = this.getByIdDeep(dto.getTextbookClaimId()); if (ObjectUtils.isEmpty(claim) || CollectionUtils.isEmpty(claim.getWfTextbookClaimItemList())) { throw new MyException("未找到申领数据或申领项为空"); } return claim; } // 2. 获取关联学生数据 private List getRelatedStudents(WfTextbookClaim claim) { if (!ClaimTypeEnum.ClaimClass.getCode().equals(claim.getClaimType()) || ObjectUtils.isEmpty(claim.getClassId())) { return Collections.emptyList(); } return xjrUserMapper.selectJoinList(XjrUser.class, new MPJLambdaWrapper() .select(XjrUser::getId) .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId) .eq(BaseStudentSchoolRoll::getClassId, claim.getClassId()) .eq(BaseStudentSchoolRoll::getArchivesStatus, ArchivesStatusEnum.FB2901.getCode())); } // 2. 获取关联的入库单号数据 private Map getWarehouseRecords(ConfirmDistributeDto dto) { List recordIds = dto.getTextbookClaimItemList().stream() .flatMap(item -> item.getTextbookWarehouseRecords().stream() .map(ConfirmDistributeDto.TextbookWarehouseRecords::getTextbookWarehouseRecordId)) .collect(Collectors.toList()); if (CollectionUtils.isEmpty(recordIds)) { throw new MyException("入库单号无效"); } return textbookWarehouseRecordMapper.selectList( Wrappers.lambdaQuery(TextbookWarehouseRecord.class) .in(TextbookWarehouseRecord::getId, recordIds) .eq(TextbookWarehouseRecord::getDeleteMark, DeleteMark.NODELETE.getCode())) .stream() .collect(Collectors.toMap(TextbookWarehouseRecord::getId, Function.identity())); } // 3. 处理发放逻辑 private void processDistribution(WfTextbookClaim claim, ConfirmDistributeDto dto, Map warehouseRecords, List students) { Date now = new Date(); Long userId = StpUtil.getLoginIdAsLong(); int issueTimes = claim.getIssueTimes() + 1; // 获取现有领取记录 Map existingClaims = getExistingStudentClaims(claim); // 处理每个申领项 for (ConfirmDistributeDto.TextbookClaimItem item : dto.getTextbookClaimItemList()) { processClaimItem(dto, claim, item, warehouseRecords, students, existingClaims, now, userId, issueTimes); } } // 获取现有领取记录 private Map getExistingStudentClaims(WfTextbookClaim claim) { return textbookStudentClaimMapper.selectList( Wrappers.lambdaQuery(TextbookStudentClaim.class) .eq(TextbookStudentClaim::getBaseSemesterId, claim.getBaseSemesterId()) .eq(TextbookStudentClaim::getClassId, claim.getClassId())) .stream() .collect(Collectors.toMap( t -> t.getStudentUserId() + "_" + t.getTextbookId(), Function.identity())); } private void processClaimItem(ConfirmDistributeDto dto, WfTextbookClaim claim, ConfirmDistributeDto.TextbookClaimItem item, Map warehouseRecords, List students, Map existingClaims, Date now, Long userId, int issueTimes) { WfTextbookClaimItem claimItem = claim.getWfTextbookClaimItemList().stream() .filter(i -> i.getId().equals(item.getTextbookClaimItemId())) .findFirst() .orElseThrow(() -> new MyException("申领详细数据发生更改")); validateIssueQuantity(claimItem, item); // 处理每个入库记录 for (ConfirmDistributeDto.TextbookWarehouseRecords record : item.getTextbookWarehouseRecords()) { TextbookWarehouseRecord warehouseRecord = warehouseRecords.get(record.getTextbookWarehouseRecordId()); if (warehouseRecord == null) { throw new MyException("未找到对应入库详细数据"); } // 验证发放数量是否合法 validateRemainingQuantity(warehouseRecord, record, item); // 更新库存 updateWarehouseRecord(warehouseRecord, record, now, userId); // 创建出库记录 TextbookIssueRecord issueRecord = createIssueRecord(claim, claimItem, warehouseRecord, dto, record, now, userId, issueTimes); textbookIssueRecordMapper.insert(issueRecord); // 处理学生领取记录 processStudentClaims(claim, claimItem, warehouseRecord, students, existingClaims, now, userId); } // 更新申领项 updateClaimItem(claimItem, item.getConfirmTotalNumber()); } // 验证发放数量是否合法 private void validateIssueQuantity(WfTextbookClaimItem claimItem, ConfirmDistributeDto.TextbookClaimItem item) { int issued = ObjectUtils.defaultIfNull(claimItem.getIssueNumber(), 0); int applied = ObjectUtils.defaultIfNull(claimItem.getApplicantNumber(), 0); int confirming = ObjectUtils.defaultIfNull(item.getConfirmTotalNumber(), 0); if (issued + confirming > applied) { throw new MyException(String.format( "教材[%s]发放总数量(%d)超出申领数量(%d)", item.getTextbookIdCn(), issued + confirming, applied )); } } // 验证库存是否充足 private void validateRemainingQuantity(TextbookWarehouseRecord warehouseRecord, ConfirmDistributeDto.TextbookWarehouseRecords record, ConfirmDistributeDto.TextbookClaimItem item ) { int remaining = ObjectUtils.defaultIfNull(warehouseRecord.getRemainNumber(), 0); int confirming = ObjectUtils.defaultIfNull(record.getConfirmNumber(), 0); if (remaining < confirming) { throw new MyException(String.format( "教材[%s]发放数量(%d)大于库存剩余数量(%d)", item.getTextbookIdCn(), confirming, remaining )); } } // 验证库存是否充足 private void updateWarehouseRecord(TextbookWarehouseRecord record, ConfirmDistributeDto.TextbookWarehouseRecords confirmRecord, Date now, Long userId) { TextbookWarehouseRecord update = new TextbookWarehouseRecord(); update.setId(record.getId()); update.setModifyUserId(userId); update.setModifyDate(now); update.setIssuedNumber(ObjectUtils.defaultIfNull(record.getIssuedNumber(), 0) + confirmRecord.getConfirmNumber()); update.setRemainNumber(ObjectUtils.defaultIfNull(record.getRemainNumber(), 0) - confirmRecord.getConfirmNumber()); textbookWarehouseRecordMapper.updateById(update); } // 创建出库记录 private TextbookIssueRecord createIssueRecord(WfTextbookClaim claim, WfTextbookClaimItem claimItem, TextbookWarehouseRecord warehouseRecord, ConfirmDistributeDto dto, ConfirmDistributeDto.TextbookWarehouseRecords confirmRecord, Date now, Long userId, int issueTimes) { // 生成出库单号 String orderNumber = generateOrderNumber(claimItem.getId(), warehouseRecord.getId()); TextbookIssueRecord record = new TextbookIssueRecord(); record.setBaseSemesterId(claim.getBaseSemesterId()); record.setOrderNumber(orderNumber); record.setIssueMode(getIssueMode(claim.getClaimType())); record.setDataId(claim.getId()); record.setDataItemId(claimItem.getId()); record.setTextbookWarehouseRecordId(warehouseRecord.getId()); record.setTextbookId(claimItem.getTextbookId()); record.setIssueNumber(confirmRecord.getConfirmNumber()); record.setRecedeNumber(0); record.setActualIssueNumber(confirmRecord.getConfirmNumber()); record.setActualTotalPrice( warehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(confirmRecord.getConfirmNumber())) ); if (ObjectUtils.isNotEmpty(dto.getReceiveUserId())) { record.setReceiveUserId(dto.getReceiveUserId()); } else { record.setReceiveUserId(claim.getApplicantUserId()); } record.setIssueUserId(userId); record.setCreateDate(now); record.setRemark(dto.getRemark()); record.setIssueTimes(issueTimes); return record; } // 构造出库单号 private String generateOrderNumber(Long claimItemId, Long warehouseRecordId) { LambdaQueryWrapper query = Wrappers.lambdaQuery(TextbookIssueRecord.class) .eq(TextbookIssueRecord::getDataItemId, claimItemId) .eq(TextbookIssueRecord::getTextbookWarehouseRecordId, warehouseRecordId) .eq(TextbookIssueRecord::getDeleteMark, DeleteMark.NODELETE.getCode()) .orderByDesc(TextbookIssueRecord::getOrderNumber) .last("LIMIT 1"); TextbookIssueRecord lastRecord = textbookIssueRecordMapper.selectOne(query); if (lastRecord != null) { // 已有记录则递增序号 String[] parts = lastRecord.getOrderNumber().split("-"); int seq = Integer.parseInt(parts[parts.length - 1]) + 1; return parts[0] + "-" + String.format("%03d", seq); } else { // 新记录生成初始单号 return "CK" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "-001"; } } // 判定申领类型 private String getIssueMode(String claimType) { if (ClaimTypeEnum.ClaimStudent.getCode().equals(claimType)) { return IssueModeEnum.ImStudent.getCode(); } else if (ClaimTypeEnum.ClaimClass.getCode().equals(claimType)) { return IssueModeEnum.ImClass.getCode(); } else if (ClaimTypeEnum.ClaimTeacher.getCode().equals(claimType)) { return IssueModeEnum.ImTeacher.getCode(); } throw new MyException("未知的申领类型: " + claimType); } // 处理学生领取记录 private void processStudentClaims(WfTextbookClaim claim, WfTextbookClaimItem claimItem, TextbookWarehouseRecord warehouseRecord, List students, Map existingClaims, Date now, Long userId) { List toInsert = new ArrayList<>(); List toUpdate = new ArrayList<>(); if (ClaimTypeEnum.ClaimStudent.getCode().equals(claim.getClaimType())) { // 个人申领直接确认 handleStudentClaim(claim.getApplicantUserId(), claim, claimItem, warehouseRecord, existingClaims, now, userId, toInsert, toUpdate); } else if (ClaimTypeEnum.ClaimClass.getCode().equals(claim.getClaimType())) { // 班级申领为每个学生生成记录 students.forEach(student -> handleStudentClaim(student.getId(), claim, claimItem, warehouseRecord, existingClaims, now, userId, toInsert, toUpdate)); } // 批量操作 if (!toInsert.isEmpty()) { for (TextbookStudentClaim insert : toInsert){ textbookStudentClaimMapper.insert(insert); } } if (!toUpdate.isEmpty()) { for (TextbookStudentClaim update : toUpdate){ textbookStudentClaimMapper.updateById(update); } } } // 新增或修改领取记录 private void handleStudentClaim(Long studentId, WfTextbookClaim claim, WfTextbookClaimItem claimItem, TextbookWarehouseRecord warehouseRecord, Map existingClaims, Date now, Long userId, List toInsert, List toUpdate) { String key = studentId + "_" + claimItem.getTextbookId(); TextbookStudentClaim existing = existingClaims.get(key); if (existing != null) { if ((ClaimTypeEnum.ClaimStudent.getCode().equals(claim.getClaimType())) && !Integer.valueOf(1).equals(existing.getIsClaim()) ) { TextbookStudentClaim update = new TextbookStudentClaim(); update.setId(existing.getId()); update.setIsClaim(1); update.setModifyDate(now); update.setModifyUserId(userId); update.setTextbookWarehouseRecordId(warehouseRecord.getId()); update.setPrice(warehouseRecord.getSubtotal()); update.setClaimSource(2); // 管理员发放 toUpdate.add(update); } } else { TextbookStudentClaim insert = new TextbookStudentClaim(); insert.setBaseSemesterId(claim.getBaseSemesterId()); insert.setClassId(claim.getClassId()); insert.setStudentUserId(studentId); insert.setTextbookId(claimItem.getTextbookId()); insert.setIsClaim(ClaimTypeEnum.ClaimStudent.getCode().equals(claim.getClaimType()) ? 1 : 0); insert.setCreateDate(now); insert.setCreateUserId(userId); insert.setTextbookWarehouseRecordId(warehouseRecord.getId()); insert.setPrice(warehouseRecord.getSubtotal()); insert.setClaimSource(2); // 管理员发放 toInsert.add(insert); } } // 更新申领项 private void updateClaimItem(WfTextbookClaimItem claimItem, int confirmNumber) { WfTextbookClaimItem update = new WfTextbookClaimItem(); update.setId(claimItem.getId()); update.setIssueNumber(ObjectUtils.defaultIfNull(claimItem.getIssueNumber(), 0) + confirmNumber); wfTextbookClaimWfTextbookClaimItemMapper.updateById(update); } // 4. 更新申领状态 private void updateClaimStatus(WfTextbookClaim claim) { long incompleteItems = wfTextbookClaimWfTextbookClaimItemMapper.selectCount( new MPJLambdaWrapper() .select(WfTextbookClaimItem::getId) .innerJoin(WfTextbookClaim.class, WfTextbookClaim::getId, WfTextbookClaimItem::getWfTextbookClaimId) .lt(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getApplicantNumber) .eq(WfTextbookClaimItem::getWfTextbookClaimId, claim.getId())); WfTextbookClaim update = new WfTextbookClaim(); update.setId(claim.getId()); update.setStatus(incompleteItems > 0 ? 2 : 3); update.setIssueTimes(claim.getIssueTimes() + 1); update.setModifyUserId(StpUtil.getLoginIdAsLong()); update.setModifyDate(new Date()); wfTextbookClaimWfTextbookClaimMapper.updateById(update); } @Override @Transactional(rollbackFor = Exception.class) public Boolean nullify(NullifyWfTextbookClaimDto dto) { // 作废申领流程数据,应该移除领取人记录 LambdaUpdateWrapper textbookClaimUserLambdaUpdateWrapper = new LambdaUpdateWrapper<>(); textbookClaimUserLambdaUpdateWrapper .eq(TextbookClaimUser::getWfTextbookClaimId, dto.getId()) ; textbookClaimUserMapper.delete(textbookClaimUserLambdaUpdateWrapper); WfTextbookClaim wfTextbookClaim = new WfTextbookClaim(); wfTextbookClaim.setId(dto.getId()); wfTextbookClaim.setWorkflowStatus(3); wfTextbookClaim.setModifyDate(new Date()); wfTextbookClaim.setModifyUserId(StpUtil.getLoginIdAsLong()); this.updateById(wfTextbookClaim); return true; } @Override @Transactional public Boolean dataHandleAddClaimUserNode(Long id) { WfTextbookClaim wfTextbookClaim = this.getById(id); // 根据数据id找到所在流程得状态 WorkflowFormRelation workflowFormRelation = workflowFormRelationMapper.selectOne( Wrappers.lambdaQuery(WorkflowFormRelation.class) .eq(WorkflowFormRelation::getFormKeyValue, id) ); if (ObjectUtils.isNotEmpty(wfTextbookClaim) && ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimType()) && ObjectUtils.isNotEmpty(workflowFormRelation) && HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState()) ) { //所有需要添加的可领取人ID List textbookClaimUserList = new ArrayList<>(); //申领人自己可以领取 textbookClaimUserList.add(new TextbookClaimUser() {{ setCreateDate(new Date()); setWfTextbookClaimId(wfTextbookClaim.getId()); setUserId(wfTextbookClaim.getApplicantUserId()); if (ClaimTypeEnum.ClaimTeacher.getCode().equals(wfTextbookClaim.getClaimType()) || ClaimTypeEnum.ClaimClass.getCode().equals(wfTextbookClaim.getClaimType()) ) { setUserType(2); } if (ClaimTypeEnum.ClaimStudent.getCode().equals(wfTextbookClaim.getClaimType())) { setUserType(1); } }}); //申领类型是班级申领,学生代表可领取 if (ClaimTypeEnum.ClaimClass.getCode().equals(wfTextbookClaim.getClaimType()) && ObjectUtils.isNotEmpty(wfTextbookClaim.getApplicantUserId()) && ObjectUtils.isNotEmpty(wfTextbookClaim.getStudentUserId()) && !Objects.equals(wfTextbookClaim.getApplicantUserId(), wfTextbookClaim.getStudentUserId()) ) { textbookClaimUserList.add(new TextbookClaimUser() {{ setCreateDate(new Date()); setWfTextbookClaimId(wfTextbookClaim.getId()); setUserId(wfTextbookClaim.getStudentUserId()); setUserType(1); }}); } //申领类型是教师申领,领取人可领取 if (ClaimTypeEnum.ClaimTeacher.getCode().equals(wfTextbookClaim.getClaimType()) && ObjectUtils.isNotEmpty(wfTextbookClaim.getApplicantUserId()) && ObjectUtils.isNotEmpty(wfTextbookClaim.getClaimUserId()) && !Objects.equals(wfTextbookClaim.getApplicantUserId(), wfTextbookClaim.getClaimUserId()) ) { textbookClaimUserList.add(new TextbookClaimUser() {{ setCreateDate(new Date()); setWfTextbookClaimId(wfTextbookClaim.getId()); setUserId(wfTextbookClaim.getClaimUserId()); setUserType(2); }}); } for (TextbookClaimUser textbookClaimUser : textbookClaimUserList) { textbookClaimUserMapper.insert(textbookClaimUser); } // 修改流程结束状态 WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim(); updateWfTextbookClaim.setId(wfTextbookClaim.getId()); updateWfTextbookClaim.setWorkflowStatus(1); this.updateById(updateWfTextbookClaim); } if (ObjectUtils.isNotEmpty(wfTextbookClaim) && ObjectUtils.isNotEmpty(workflowFormRelation) && !HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState()) && !HistoricProcessInstance.STATE_ACTIVE.equals(workflowFormRelation.getCurrentState()) ) { // 修改教材申领流程状态为不正常的结束 WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim(); updateWfTextbookClaim.setId(wfTextbookClaim.getId()); updateWfTextbookClaim.setWorkflowStatus(2); this.updateById(updateWfTextbookClaim); } return true; } @Override public ByteArrayOutputStream claimRecordsExportQuery(ClaimRecordsExportQueryDto dto) throws IOException { MPJLambdaWrapper wfTextbookClaimMPJLambdaWrapper = new MPJLambdaWrapper<>(); wfTextbookClaimMPJLambdaWrapper .disableSubLogicDel() .select(WfTextbookClaim::getId) .select(WfTextbookClaim.class, x -> VoToColumnUtil.fieldsToColumns(ClaimRecordsExportQueryVo.class).contains(x.getProperty())) .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfTextbookClaim::getClaimType, wrapper -> wrapper .selectAs(DictionaryDetail::getName, ClaimRecordsExportQueryVo::getClaimTypeCn) ) .leftJoin(XjrUser.class, XjrUser::getId, WfTextbookClaim::getApplicantUserId, wrapper -> wrapper .selectAs(XjrUser::getName, ClaimRecordsExportQueryVo::getApplicantUserIdCn) ) .leftJoin(BaseClass.class, BaseClass::getId, WfTextbookClaim::getClassId, wrapper -> wrapper .selectAs(BaseClass::getName, ClaimRecordsExportQueryVo::getClassIdCn) ) .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookClaim::getBaseSemesterId, wrapper -> wrapper .selectAs(BaseSemester::getName, ClaimRecordsExportQueryVo::getBaseSemesterIdCn) ) .eq(WfTextbookClaim::getWorkflowStatus, 1) .eq(ObjectUtils.isNotEmpty(dto.getBaseSemesterId()), WfTextbookClaim::getBaseSemesterId, dto.getBaseSemesterId()) ; List dataList = this.selectJoinList(ClaimRecordsExportQueryVo.class, wfTextbookClaimMPJLambdaWrapper); List claimIds = dataList.stream() .map(ClaimRecordsExportQueryVo::getId) .collect(Collectors.toList()); // 查询统计数据 MPJLambdaWrapper statsWrapper = new MPJLambdaWrapper<>(); statsWrapper .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId) .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber) .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber) .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds) .groupBy(WfTextbookClaimItem::getWfTextbookClaimId); List statsList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, statsWrapper); Map statsMap = statsList.stream() .collect(Collectors.toMap( WfTextbookClaimItem::getWfTextbookClaimId, Function.identity(), (w1, w2) -> w1)); // 可视情况记录冲突日志 // 查询子项数据 MPJLambdaWrapper itemWrapper = new MPJLambdaWrapper<>(); itemWrapper.disableSubLogicDel() .select(WfTextbookClaimItem::getId) .selectAs(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItemVo::getApplicantNumber) .selectAs(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItemVo::getIssueNumber) .select(WfTextbookClaimItem.class, x -> VoToColumnUtil.fieldsToColumns(WfTextbookClaimItemVo.class).contains(x.getProperty())) .leftJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId, w -> w .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn) .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn)) .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds); List itemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItemVo.class, itemWrapper); Map> itemMap = itemList.stream() .collect(Collectors.groupingBy(WfTextbookClaimItemVo::getWfTextbookClaimId)); // 查询发放记录 MPJLambdaWrapper recordWrapper = new MPJLambdaWrapper<>(); recordWrapper.disableSubLogicDel() .selectAs(TextbookIssueRecord::getDataId, DistributeRecordVo::getWfTextbookClaimId) .selectAs(TextbookIssueRecord::getDataItemId, DistributeRecordVo::getWfTextbookClaimItemId) .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate) .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber) .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber) .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark) .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId, w -> w .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn) .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn)) .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId, w -> w .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser)) .in(TextbookIssueRecord::getDataId, claimIds); List recordList = textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, recordWrapper); Map> recordMap = recordList.stream() .collect(Collectors.groupingBy(DistributeRecordVo::getWfTextbookClaimItemId)); // 开始写入 Workbook workbook = new XSSFWorkbook(); // 创建一个工作表(sheet) String sheetName = "sheet1"; Sheet sheet = workbook.createSheet(sheetName); // 出参vo字段数量 ClaimRecordsExportQueryVo obj = new ClaimRecordsExportQueryVo(); List importConfigs = ImportExcelUtil.allFields(obj); // 写大标题 int rowNumber = 0; ImportExcelUtil.createBigHead(workbook, sheet, "教材申领情况", rowNumber++, importConfigs.size() - 1); // 表头 ImportExcelUtil.createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), rowNumber++); // 字体内容格式 Font font = workbook.createFont(); font.setBold(false);// 设置为粗体 font.setFontName("宋体"); font.setFontHeightInPoints((short) 12); // 单元格样式 CellStyle cellStyle = workbook.createCellStyle(); cellStyle.setFont(font); // 将字体应用到样式 cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); cellStyle.setAlignment(HorizontalAlignment.CENTER); // 设置边框样式为细线 cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色 cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色 cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色 cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色 // 记录写入 List claimVo; List claimItemVo; List claimItemIssueVo; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); for (ClaimRecordsExportQueryVo vo : dataList) { if (ObjectUtils.isNotEmpty(vo.getClaimType()) && ClaimTypeEnum.ClaimClass.getCode().equals(vo.getClaimType())) { vo.setReceiver(vo.getClassIdCn()); } else { vo.setReceiver(vo.getApplicantUserIdCn()); } // 1:未发放,2:部分发放,3:全部发放) if (vo.getStatus() == 2) { vo.setStatusStr("部分发放"); } else if (vo.getStatus() == 3) { vo.setStatusStr("全部发放"); } else { vo.setStatusStr("未发放"); } Long claimId = vo.getId(); // 填充统计信息 if (MapUtils.isNotEmpty(statsMap) && statsMap.containsKey(claimId)) { WfTextbookClaimItem stat = statsMap.get(claimId); vo.setApplicantTatolNumber(stat.getApplicantNumber()); vo.setIssueTatolNumber(stat.getIssueNumber()); } // 申领总记录 claimVo = new ArrayList<>(); claimVo.add(vo.getBaseSemesterIdCn()); claimVo.add(vo.getClaimTypeCn()); claimVo.add(vo.getReceiver()); if (StringUtils.isNotEmpty(vo.getClassIdCn())) { claimVo.add(vo.getClassIdCn()); } else { claimVo.add("无"); } claimVo.add(vo.getApplicantTatolNumber() + ""); claimVo.add(vo.getStatusStr()); claimVo.add(vo.getIssueTatolNumber() + ""); // 填充子项及发放记录 int mergeClaim = 0; if (MapUtils.isNotEmpty(itemMap) && CollectionUtils.isNotEmpty(itemMap.get(claimId))) { List items = itemMap.get(claimId); for (WfTextbookClaimItemVo item : items) { claimItemVo = new ArrayList<>(claimVo); claimItemVo.add(item.getTextbookIdCN()); claimItemVo.add(item.getIssn()); claimItemVo.add(item.getApplicantNumber() + ""); claimItemVo.add(item.getIssueNumber() + ""); int mergeClaimItem = 0; if (recordMap.containsKey(item.getId())) { List issues = recordMap.get(item.getId()); for (DistributeRecordVo issue : issues) { mergeClaimItem++; mergeClaim++; claimItemIssueVo = new ArrayList<>(claimItemVo); LocalDateTime localDateTime = issue.getIssueDate().toInstant() .atZone(ZoneId.systemDefault()) .toLocalDateTime(); claimItemIssueVo.add(localDateTime.format(formatter)); claimItemIssueVo.add(issue.getIssueUser()); claimItemIssueVo.add(issue.getOrderNumber()); claimItemIssueVo.add(issue.getIssueNumber() + ""); Row dataRow = sheet.createRow(rowNumber++); for (int j = 0; j < claimItemIssueVo.size(); j++) { String content = claimItemIssueVo.get(j); Cell cell = dataRow.createCell(j); cell.setCellValue(content); cell.setCellStyle(cellStyle); } } // 合并申领项 if (mergeClaimItem > 1) { for (int k = 7; k < 11; k++) { sheet.addMergedRegion(new CellRangeAddress(rowNumber - mergeClaimItem, rowNumber - 1, k, k)); } } } else { mergeClaim++; Row dataRow = sheet.createRow(rowNumber++); for (int j = 0; j < claimItemVo.size(); j++) { String content = claimItemVo.get(j); Cell cell = dataRow.createCell(j); cell.setCellValue(content); cell.setCellStyle(cellStyle); } } } // 合并申领 if (mergeClaim > 1) { for (int k = 0; k < 7; k++) { sheet.addMergedRegion(new CellRangeAddress(rowNumber - mergeClaim, rowNumber - 1, k, k)); } } } else { Row dataRow = sheet.createRow(rowNumber++); for (int j = 0; j < claimVo.size(); j++) { String content = claimVo.get(j); Cell cell = dataRow.createCell(j); cell.setCellValue(content); cell.setCellStyle(cellStyle); } } } // 自动列宽 for (int i = 0; i < importConfigs.size(); i++) { sheet.autoSizeColumn(i); } ByteArrayOutputStream bot = new ByteArrayOutputStream(); workbook.write(bot); return bot; } }