package com.imed.costaccount.service.impl; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.imed.costaccount.common.exception.CostException; import com.imed.costaccount.common.util.PageUtils; import com.imed.costaccount.mapper.CostIncomeGroupMapper; import com.imed.costaccount.mapper.IncomeCollectionMapper; import com.imed.costaccount.model.AfterIncomegroup; import com.imed.costaccount.model.CostIncomeGroup; import com.imed.costaccount.model.IncomeCollection; import com.imed.costaccount.model.dto.CollectDTO; import com.imed.costaccount.model.vo.CollectedVO; import com.imed.costaccount.model.vo.CollectionVO; import com.imed.costaccount.service.IncomeCollectionService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; import static com.imed.costaccount.common.constants.Constant.LIMIT; @Slf4j @Service("incomeCollectionService") public class IncomeCollectionServiceImpl extends ServiceImpl implements IncomeCollectionService { private final CostIncomeGroupMapper incomeGroupMapper; public IncomeCollectionServiceImpl(CostIncomeGroupMapper incomeGroupMapper) { this.incomeGroupMapper = incomeGroupMapper; } /** * 获取收入归集分页列表 * * @param current 当前页 * @param pageSize 页码数据大小 * @param date 日期 yyyy-MM-dd * @param hospId 医院id * @return {@link PageUtils} 分页对象 */ @Override public PageUtils getCollections(Integer current, Integer pageSize, String date, Long hospId) { current = current - 1; Integer startIndex = current * pageSize; List list = incomeGroupMapper.getCollections(startIndex, pageSize, date, hospId); int count = incomeGroupMapper.getCollectionCount(date, hospId); // 设置是否归集字段 list.forEach(i -> { i.setIsCollection(true); IncomeCollection one = this.getOne( new LambdaQueryWrapper().select(IncomeCollection::getId) .eq(IncomeCollection::getYear, i.getYear()) .eq(IncomeCollection::getMonth, i.getMonth()) .last(LIMIT) ); if (Objects.isNull(one)) { i.setIsCollection(false); } }); return new PageUtils(list, count, pageSize, current); } /** * 按年月归集数据 * * @param year 年 数字类型 * @param month 月 数字 * @param hospId 医院id */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void collect(Integer year, Integer month, Long hospId) { // 可能几十万次数据 需要分段异步多线程处理,分布式锁处理, List costIncomeGroups = incomeGroupMapper.selectList( new LambdaQueryWrapper() .eq(CostIncomeGroup::getDateYear, year) .eq(CostIncomeGroup::getDateMonth, month) .eq(CostIncomeGroup::getHospId, hospId) ); if (costIncomeGroups.isEmpty()) { String format = StrUtil.format("{}年{}月数据不存在,请先导入数据", year, month); throw new CostException(format); } // 根据会计科目和成本项目归纳所有数据 Map> collectMap = costIncomeGroups.stream() .collect(Collectors.groupingBy(i -> i.getAccountCode() + "cost" + i.getProductCode())); // 遍历map 组装成List保存 List list = new LinkedList<>(); Set>> entries = collectMap.entrySet(); entries.stream().map(Map.Entry::getValue).flatMap(Collection::stream).forEach(costIncomeGroup -> { IncomeCollection incomeCollection = new IncomeCollection(); incomeCollection.setYear(year); incomeCollection.setMonth(month); incomeCollection.setAccountingCode(costIncomeGroup.getAccountCode()); incomeCollection.setAccountingName(costIncomeGroup.getAccountName()); incomeCollection.setProductName(costIncomeGroup.getProductName()); incomeCollection.setProductCode(costIncomeGroup.getProductCode()); incomeCollection.setAmount(costIncomeGroup.getAmount()); incomeCollection.setHospId(hospId); // todo 来源id暂时不确定 incomeCollection.setFileId(costIncomeGroup.getFileId()); incomeCollection.setCreateTime(System.currentTimeMillis()); String afterIncomeGroupStr = costIncomeGroup.getAfterIncomeGroup(); AfterIncomegroup afterIncomegroup = JSONUtil.toBean(afterIncomeGroupStr, AfterIncomegroup.class); if (Objects.isNull(afterIncomegroup)) { throw new CostException("未能正确归集对应的...."); } // 转换一下其他的 if (afterIncomegroup.getDirectStatus() == 2) { afterIncomegroup.setDirectStatus(0); } incomeCollection.setIsDirectIncome(afterIncomegroup.getDirectStatus()); // 开单中心的数据 incomeCollection.setDepartmentCode(afterIncomegroup.getOpenDepartmentCode()); incomeCollection.setDepartmentName(afterIncomegroup.getOpenDepartmentName()); incomeCollection.setResponsibilityCode(afterIncomegroup.getResponsibilityCode()); incomeCollection.setResponsibilityName(afterIncomegroup.getResponsibilityName()); list.add(incomeCollection); // 执行科室数据 incomeCollection.setDepartmentCode(afterIncomegroup.getStartDepartmentCode()); incomeCollection.setDepartmentName(afterIncomegroup.getStartDepartmentName()); incomeCollection.setResponsibilityCode(afterIncomegroup.getResponsibilityCode()); incomeCollection.setResponsibilityName(afterIncomegroup.getResponsibilityName()); list.add(incomeCollection); }); // TODO: 2021/8/10 几十万条数据如何处理 待测试处理 this.saveBatch(list); } /** * 按年月撤销归集 * * @param year 年 数字类型 * @param month 月 数字 * @param hospId 医院id */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void cancelCollect(Integer year, Integer month, Long hospId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(IncomeCollection::getYear, year) .eq(IncomeCollection::getMonth, month) .eq(IncomeCollection::getHospId, hospId); this.remove(wrapper); } /** * 归集后数据分页列表 * * @param collectDTO {@link CollectDTO} 查询相关参数 * @return {@link PageUtils} */ @Override public PageUtils collectList(CollectDTO collectDTO) { // 分页数据初始化 Integer current = collectDTO.getCurrent(); current = (Objects.isNull(current) || current == 0) ? 0 : current - 1; Integer pageSize = collectDTO.getPageSize(); pageSize = Objects.isNull(pageSize) ? 10 : pageSize; collectDTO.setCurrent(current * pageSize); collectDTO.setPageSize(pageSize); // 查询需要的数据 DB List list = baseMapper.getCollectList(collectDTO); int count = baseMapper.getCollectListCount(collectDTO); BigDecimal totalAmount = baseMapper.getTotalAmount(collectDTO); return new PageUtils(list, count, pageSize, current, totalAmount); } }