package com.kcim.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.enums.DateStyleEnum;
import com.kcim.common.enums.ErrorCodeEnum;
import com.kcim.common.exception.CostException;
import com.kcim.common.file.MinioConfig;
import com.kcim.common.file.MinioFileUtil;
import com.kcim.common.util.*;
import com.kcim.dao.mapper.CostIncomeGroupMapper;
import com.kcim.dao.model.*;
import com.kcim.service.*;
import com.kcim.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Slf4j
@Service("costIncomeGroupService")
public class CostIncomeGroupServiceImpl extends ServiceImpl<CostIncomeGroupMapper, CostIncomeGroup> implements CostIncomeGroupService {

//    @Value("${file.serverPath}")
//    private String fileTempPath;
//
//    @Value("${file.serverUrl}")
//    private String FILE_PATH;

    private final DepartmentService departmentService;

    private final ResponsibilityService responsibilityService;

    private final ProductService productService;

    private final AccountingService accountingService;

    private final ResponsibilityDepartmentService responsibilityDepartmentService;

    private final AccountingProductService accountingProductService;

    private final CostIncomeFileService costIncomeFileService;

    private final CostIncomeGroupSetService costIncomeGroupSetService;

    private final MinioConfig minioConfig;

    private final MinioFileUtil minioFileUtil;

    public CostIncomeGroupServiceImpl(DepartmentService departmentService, ResponsibilityService responsibilityService, ProductService productService, AccountingService accountingService, ResponsibilityDepartmentService responsibilityDepartmentService, AccountingProductService accountingProductService, CostIncomeFileService costIncomeFileService, CostIncomeGroupSetService costIncomeGroupSetService, MinioConfig minioConfig, MinioFileUtil minioFileUtil) {
        this.departmentService = departmentService;
        this.responsibilityService = responsibilityService;
        this.productService = productService;
        this.accountingService = accountingService;
        this.responsibilityDepartmentService = responsibilityDepartmentService;
        this.accountingProductService = accountingProductService;
        this.costIncomeFileService = costIncomeFileService;
        this.costIncomeGroupSetService = costIncomeGroupSetService;
        this.minioConfig = minioConfig;
        this.minioFileUtil = minioFileUtil;
    }

    /**
     * 分页查询收入归集前的数据
     *
     * @param current            当前页
     * @param pageSize           当前页大小
     * @param dateTime           年月
     * @param responsibilityCode 责任中心代码
     * @param productCode        会计科目的Code
     * @param hospId             医院Id
     * @param type               科室类型 1 开单科室 2执行科室
     * @param filter             收入项目名称/代码
     * @param departmentCode     科室代码
     * @return
     */
    @Override
    public PageUtils queryList(Integer current, Integer pageSize, String dateTime, String responsibilityCode, String productCode, Long hospId, Integer type, String filter, String departmentCode) {
//       return getDeptIncomeList(current, pageSize, dateTime, responsibilityCode, productCode, hospId, type, filter, departmentCode);
        return getDeptProductList(current, pageSize, dateTime, departmentCode, productCode, hospId, type, filter);
    }


    public PageUtils getDeptIncomeList(Integer current, Integer pageSize, String dateTime, String responsibilityCode, String productCode, Long hospId, Integer type, String filter, String departmentCode) {
        // 先检验当前年月是否存在数据
        int year = 0;
        int month = 0;
        Date date = DateUtils.StringToDate(dateTime, DateStyleEnum.YYYY_MM);
        if (StrUtil.isNotBlank(dateTime)) {
            year = DateUtil.year(date);
            month = DateUtil.month(date) + 1;
        }
        Page<CostIncomeGroup> costIncomeGroupPage = new Page<>(current, pageSize);
        Page<CostIncomeGroup> pages = new Page<>();
        if(type.equals(NumberConstant.ONE)){
            pages = this.page(costIncomeGroupPage, new QueryWrapper<CostIncomeGroup>().lambda()
                    .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                    .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                    .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month)
                    .eq(CostIncomeGroup::getOpenDepartmentCode,departmentCode)
                    .and(StrUtil.isNotBlank(responsibilityCode), i -> i.like(CostIncomeGroup::getOpenResponsibilityCode, responsibilityCode)
                            .or().like(CostIncomeGroup::getStartResponsibilityCode, responsibilityCode))
                    .like(StrUtil.isNotBlank(productCode), CostIncomeGroup::getProductCode, productCode)
                    .and(StrUtil.isNotBlank(filter),i->i.like(CostIncomeGroup::getProductCode,filter).or().like(CostIncomeGroup::getProductName,filter)));
        }else {
            pages = this.page(costIncomeGroupPage, new QueryWrapper<CostIncomeGroup>().lambda()
                    .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                    .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                    .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month)
                    .eq(CostIncomeGroup::getStartDepartmentCode,departmentCode)
                    .and(StrUtil.isNotBlank(responsibilityCode), i -> i.like(CostIncomeGroup::getOpenResponsibilityCode, responsibilityCode)
                            .or().like(CostIncomeGroup::getStartResponsibilityCode, responsibilityCode))
                    .like(StrUtil.isNotBlank(productCode), CostIncomeGroup::getProductCode, productCode)
                    .and(StrUtil.isNotBlank(filter),i->i.like(CostIncomeGroup::getProductCode,filter).or().like(CostIncomeGroup::getProductName,filter)));
        }

        List<CostIncomeGroup> records = pages.getRecords();
        List<CostIncomeGroupBeforeVO> costIncomeGroupBeforeVOList = BeanUtil.convertList(records, CostIncomeGroupBeforeVO.class);
        if (CollectionUtils.isEmpty(costIncomeGroupBeforeVOList)) {
            PageUtils pageUtils = new PageUtils(pages);
            pageUtils.setList(null);
            pageUtils.setTotalAmount(new BigDecimal("0.0000"));
            return pageUtils;
        }
        List<CostIncomeGroup> list = new ArrayList<>();
        if(type.equals(NumberConstant.ONE)) {
            list = this.list(new QueryWrapper<CostIncomeGroup>().lambda()
                    .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                    .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                    .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month)
                    .eq(CostIncomeGroup::getOpenDepartmentCode,departmentCode)
                    .and(StrUtil.isNotBlank(responsibilityCode), i -> i.like(CostIncomeGroup::getOpenResponsibilityCode, responsibilityCode)
                            .or().like(CostIncomeGroup::getStartResponsibilityCode, responsibilityCode))
                    .like(StrUtil.isNotBlank(productCode), CostIncomeGroup::getProductCode, productCode)
                    .and(StrUtil.isNotBlank(filter),i->i.like(CostIncomeGroup::getProductCode,filter).or().like(CostIncomeGroup::getProductName,filter)));
        }else {
            list = this.list(new QueryWrapper<CostIncomeGroup>().lambda()
                    .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                    .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                    .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month)
                    .eq(CostIncomeGroup::getStartDepartmentCode,departmentCode)

                    .and(StrUtil.isNotBlank(responsibilityCode), i -> i.like(CostIncomeGroup::getOpenResponsibilityCode, responsibilityCode)
                            .or().like(CostIncomeGroup::getStartResponsibilityCode, responsibilityCode))
                    .like(StrUtil.isNotBlank(productCode), CostIncomeGroup::getProductCode, productCode)
                    .and(StrUtil.isNotBlank(filter),i->i.like(CostIncomeGroup::getProductCode,filter).or().like(CostIncomeGroup::getProductName,filter)));
        }
        List<CostIncomeGroup> totalList = this.list(new QueryWrapper<CostIncomeGroup>().lambda()
                .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month));

        // 进行金额合并
        List<CostIncomeGroupBeforeVO> costIncomeGroupBeforeVOList1 = BeanUtil.convertList(list, CostIncomeGroupBeforeVO.class);
        List<Long> idList = costIncomeGroupBeforeVOList1.stream().map(CostIncomeGroupBeforeVO::getId).collect(Collectors.toList());
        List<CostIncomeGroupAllAmountVO> costIncomeGroupAllAmountVoS = baseMapper.countMoney(idList);
        //计算所有数据
        List<Long> totalIds = totalList.stream().map(CostIncomeGroup::getId).collect(Collectors.toList());
        List<CostIncomeGroupAllAmountVO> totalAmountList = baseMapper.countMoney(totalIds);

        // 查询所有的责任中心 科室 会计科目  成本项目的数据  处理名字
        setCodeName(costIncomeGroupAllAmountVoS);
        //  对,的金额进行合并
        AtomicReference<BigDecimal> departmentAmount =setAmount(costIncomeGroupAllAmountVoS);
        AtomicReference<BigDecimal> totalAmount =setAmount(totalAmountList);

        PageUtils pageUtils = new PageUtils(pages);
        pageUtils.setList(costIncomeGroupAllAmountVoS);
        pageUtils.setTotalAmount(totalAmount.get());
        pageUtils.setDepartmentAmount(departmentAmount.get());
        return pageUtils;
    }


    public PageUtils getDeptProductList(Integer current, Integer pageSize, String computeDate, String departmentCode, String productCode, Long hospId, Integer type, String filter) {
        Integer year = ComputeDateUtils.getComputeYear(computeDate);
        Integer month = ComputeDateUtils.getComputeMonth(computeDate);

        Page<PatientInfoVo> page = new Page<>(current,pageSize);
        List<CostIncomeGroup> orderDeptProductList;
        //按开单科室查询
        if(NumberConstant.ONE.equals( type)){
            orderDeptProductList = this.baseMapper.getOrderDeptProductList(page, year, month, departmentCode, hospId, filter);
        }else{
            orderDeptProductList = this.baseMapper.getExecDeptProductList(page, year, month, departmentCode, hospId, filter);
        }
        BigDecimal totalAmount=this.baseMapper.getTotalAmount(year, month, departmentCode, hospId);
        BigDecimal departmentAmount=this.baseMapper.getDeptTotalAmount(year, month, departmentCode, hospId);
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(orderDeptProductList);
        pageUtils.setTotalAmount(totalAmount);
        pageUtils.setDepartmentAmount(departmentAmount);
        return pageUtils;
    }
    private static AtomicReference<BigDecimal> setAmount(List<CostIncomeGroupAllAmountVO> costIncomeGroupAllAmountVoS) {
        AtomicReference<BigDecimal> totalAmount = new AtomicReference<>(new BigDecimal("0.0000"));
        costIncomeGroupAllAmountVoS.forEach(i -> {
            String allMoney = i.getAllMoney();
            if (StrUtil.isNotBlank(allMoney) && allMoney.contains(StrUtil.COMMA)) {
                // 存在，在进行求和
                BigDecimal sum;
                List<BigDecimal> bigDecimals = new ArrayList<>();
                for (String s : allMoney.split(StrUtil.COMMA)) {
                    if(StringUtils.isEmpty(s)){
                        System.out.println("暂停");
                    }
                    if(s == null){
                        System.out.println("暂停");
                    }
                    System.out.println("【"+allMoney+"-{"+s+"}】");
                    BigDecimal bigDecimal = new BigDecimal(s);
                    bigDecimals.add(bigDecimal);
                }
                sum = bigDecimals.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
                i.setAmount(sum);
            }
            totalAmount.updateAndGet(v -> v.add(i.getAmount()));
        });
        return totalAmount;
    }

    /**
     * 批量导入收入数据
     *
     * @param list 输入的文件
     * @param file
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result importIncomeGroup(List<List<Object>> list, MultipartFile file, String dateTime, Integer fileType) {
        // 先检验当前年月是否存在数据
        int year = 0;
        int month = 0;
        Date date = DateUtils.StringToDate(dateTime, DateStyleEnum.YYYY_MM);
        if (StrUtil.isNotBlank(dateTime)) {
            year = DateUtil.year(date);
            month = DateUtil.month(date) + 1;
        }
        Long hospId = UserContext.getHospId();
//        List<CostIncomeGroup> groups = this.list(new QueryWrapper<CostIncomeGroup>().lambda().eq(CostIncomeGroup::getHospId, hospId)
//                .eq(CostIncomeGroup::getDateYear, year).eq(CostIncomeGroup::getDateMonth, month));
//        if (!CollectionUtils.isEmpty(groups)) {
//            throw new CostException(500, year + "年" + month + "月数据已存在");
//        }
        // 移除前几行的抬头内容  list的大小对应的就是行数的大小
        removeTitle(list);
        log.info("读取的数据为：{}", list);
        List<IncomeErrorMessage> incomeErrorMessageList = new ArrayList<>();
        //获取所有的科室 成本项目 责任中心 会计科目
        //
        Map<String, Department> departmentMap = getDepartmentByCodeNameMap(hospId);
        Map<String, Product> productMap = getProductByCodeNameMap(hospId);
        Map<Long, Responsibility> responsibilityMap = getResponsibilityIdResponsibilityMap(hospId);
        Map<Long, Accounting> accountingMap = getAccountIdAccountingMap(hospId);
        List<ResponsibilityDepartment> responsibilityDepartmentList = getResponsibilityDepartments(hospId);
        if (CollectionUtils.isEmpty(responsibilityDepartmentList)) {
            throw new CostException(500, "没有科室责任中心对照数据");
        }
        List<AccountingProduct> accountingProductList = accountingProductService.list(new QueryWrapper<AccountingProduct>().lambda().eq(AccountingProduct::getHospId, hospId));
        if (CollectionUtils.isEmpty(accountingProductList)) {
            throw new CostException(500, "没有成本会计对照数据");
        }
        Map<Long, Long> responsibilityDepMap = getDepartmentIdResponsibilityIdMap(responsibilityDepartmentList);
        Map<Long, Long> accountProMap = getProductIdAccountIdMap(accountingProductList);
        List<CostIncomeGroup> costIncomeGroupArrayList = new ArrayList<>();
        // 检验数据
        checkImportData(list, incomeErrorMessageList, costIncomeGroupArrayList, departmentMap, productMap, responsibilityMap, accountingMap, responsibilityDepMap, accountProMap, hospId, year, month);

        // 文件上传
        String uploadFile = uploadFile(file);
        // 上传记录保存
        if (StrUtil.isBlank(uploadFile)) {
            throw new CostException(500, "文件上传异常");
        }
        // 记录文件上传记录
        CostIncomeFile costIncomeFile = costIncomeFileService.saveCostIncomeFile(list, file, hospId, incomeErrorMessageList, uploadFile, fileType, year, month);
        Long id = costIncomeFile.getId();
        costIncomeGroupArrayList.forEach(i -> {
            // 设置文件Id
            i.setFileId(id);
        });
        if (CollectionUtils.isEmpty(incomeErrorMessageList)) {
            this.saveBatch(costIncomeGroupArrayList);
            return Result.build(200, "数据导入成功", null);
        } else {
            return Result.build(200, "数据未成功导入", null);
        }
    }

    private void removeTitle(List<List<Object>> list) {
        for (int i = list.size() - 1; i >= 0; i--) {
            if (i == NumberConstant.ZERO || i == NumberConstant.ONE || i == NumberConstant.TWO || i == NumberConstant.THREE) {
                list.remove(list.get(i));
            }
        }
    }

    /**
     * 返回成本会计对照数据  Key 成本项目Id   Value 会计科目Id
     *
     * @param accountingProductList
     * @return
     */
    public Map<Long, Long> getProductIdAccountIdMap(List<AccountingProduct> accountingProductList) {
        return accountingProductList.stream().collect(Collectors.toMap(AccountingProduct::getProductId, AccountingProduct::getAccountingId));
    }

    /**
     * Map类型
     * Key DepartmentId
     * Value ResponsibilityId
     *
     * @param responsibilityDepartmentList
     * @return
     */
    public Map<Long, Long> getDepartmentIdResponsibilityIdMap(List<ResponsibilityDepartment> responsibilityDepartmentList) {
        return responsibilityDepartmentList.stream().collect(Collectors.toMap(ResponsibilityDepartment::getDepartmentId, ResponsibilityDepartment::getResponsibilityId));
    }

    public List<ResponsibilityDepartment> getResponsibilityDepartments(Long hospId) {
        return responsibilityDepartmentService.list(new QueryWrapper<ResponsibilityDepartment>().lambda()
                .eq(ResponsibilityDepartment::getHospId, hospId));
    }

    /**
     * Key AccountId
     * Value Accounting对象
     *
     * @param hospId
     * @return
     */
    public Map<Long, Accounting> getAccountIdAccountingMap(Long hospId) {
        return accountingService.list(new QueryWrapper<Accounting>().lambda().eq(Accounting::getHospId, hospId)).stream().collect(Collectors.toMap(Accounting::getId, synOe -> synOe));
    }

    /**
     * Key responsibilityId 责任中心Id
     * Value Responsibility对象
     *
     * @param hospId
     * @return
     */
    public Map<Long, Responsibility> getResponsibilityIdResponsibilityMap(Long hospId) {
        return responsibilityService.list(new QueryWrapper<Responsibility>().lambda().eq(Responsibility::getHospId, hospId)).stream().collect(Collectors.toMap(Responsibility::getId, synOe -> synOe));
    }

    /**
     * Key 成本项目Code+Name
     * Value 成本项目对象
     *
     * @param hospId
     * @return
     */
    public Map<String, Product> getProductByCodeNameMap(Long hospId) {
        return productService.list(new QueryWrapper<Product>().lambda().eq(Product::getHospId, hospId)).stream().collect(Collectors.toMap(k -> k.getProductCode() + k.getProductName(), synOe -> synOe));
    }

    /**
     * Key 科室项目Code+Name
     * Value 科室对象
     *
     * @param hospId
     * @return
     */
    public Map<String, Department> getDepartmentByCodeNameMap(Long hospId) {
        List<Department> departments = departmentService.getDepartments();
       return departments.stream().collect(Collectors.toMap(k -> k.getDepartmentCode() + k.getDepartmentName(), synOe -> synOe)) ;
//        return departmentService.list(new QueryWrapper<Department>().lambda().eq(Department::getHospId, hospId)).stream().collect(Collectors.toMap(k -> k.getDepartmentCode() + k.getDepartmentName(), synOe -> synOe));
    }

    /**
     * 导入收入数据
     *
     * @param read  读取到的初始数据
     * @param user  当前登录用户
     * @param file  导入的文件
     * @param year  年
     * @param month 月
     * @return {@link Result}
     */
    @Override
    public Result importDataByIncomeData(List<List<Object>> read, User user, MultipartFile file, Integer year, Integer month) {
        // 去头
        this.removeTitle(read);
        return null;
    }

    /**
     * 删除收入归集的数据
     *
     * @param asList
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteByIds(List<Long> asList) {
        this.removeByIds(asList);
    }

    @Override
    public List<CommonDepartVo> getDepartment(Integer type, String computeDate, String departmentName) {
        int year = 0;
        int month = 0;
        Date date = DateUtils.StringToDate(computeDate, DateStyleEnum.YYYY_MM);
        if (StrUtil.isNotBlank(computeDate)) {
            year = DateUtil.year(date);
            month = DateUtil.month(date) + 1;
        }
        if(type.equals(NumberConstant.ONE)){
            return  baseMapper.getOpenDepartment(year,month,UserContext.getHospId(),departmentName);
        }else if(type.equals(NumberConstant.TWO)){
            return  baseMapper.getStartDepartment(year,month,UserContext.getHospId(),departmentName);

        }
        return  new ArrayList<>();
    }

    @Override
    public void removeIncome(String computeDate) {
        int year = 0;
        int month = 0;
        Date date = DateUtils.StringToDate(computeDate, DateStyleEnum.YYYY_MM);
        if (StrUtil.isNotBlank(computeDate)) {
            year = DateUtil.year(date);
            month = DateUtil.month(date) + 1;
        }
        LambdaQueryWrapper<CostIncomeGroup> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year);
        queryWrapper.eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month);

        queryWrapper.eq( CostIncomeGroup::getHospId, UserContext.getHospId());
        List<CostIncomeGroup> list = this.list(queryWrapper);
        if(!CollectionUtils.isEmpty(list)){
            List<Long> collect = list.stream().map(CostIncomeGroup::getId).collect(Collectors.toList());
            this.removeByIds(collect);
        }
        //撤销文件记录当月收入数据


    }


    /**
     * 检验数据
     *
     * @param list                     表单数据
     * @param incomeErrorMessageList   存储错误信息的集合
     * @param costIncomeGroupArrayList
     * @param departmentMap            科室Map
     * @param productMap               成本项目map
     * @param responsibilityMap        责任中心Map
     * @param accountingMap            会计科目Map
     * @param responsibilityDepMap     责任中心科室对照Map
     * @param accountProMap            责任中心Map
     * @param hospId
     */
    private void checkImportData(List<List<Object>> list, List<IncomeErrorMessage> incomeErrorMessageList, List<CostIncomeGroup> costIncomeGroupArrayList, Map<String, Department> departmentMap, Map<String, Product> productMap, Map<Long, Responsibility> responsibilityMap, Map<Long, Accounting> accountingMap, Map<Long, Long> responsibilityDepMap, Map<Long, Long> accountProMap, Long hospId, Integer year, Integer month) {
        for (int i = 0; i < list.size(); i++) {
            int row = i + 5;
            CostIncomeGroup costIncomeGroup = new CostIncomeGroup();
            AfterIncomeGroup afterIncomegroup = new AfterIncomeGroup();
            // 用来检验数据合理性的循环
            List<Object> data = list.get(i);
            log.info("用户输入的数据是{}", data);
            // 成本项目的代码和名称
            if (Objects.isNull(data.get(0)) || Objects.isNull(data.get(1))){
                continue;
            }
            String productCode = data.get(0).toString().trim();
            String productName = data.get(1).toString().trim();
            // 开单科室 执行科室的代码和名称
            String openDepartmentName = data.get(2).toString();
            String openDepartmentCode = data.get(3).toString();
            String startDepartmentName = data.get(4).toString();
            String startDepartmentCode = data.get(5).toString();
            if (StrUtil.isBlank(openDepartmentCode) && StrUtil.isBlank(openDepartmentName) && StrUtil.isBlank(startDepartmentCode) && StrUtil.isBlank(startDepartmentName)) {
                continue;
            }
            BigDecimal beforeMoney = BigDecimal.valueOf(Double.parseDouble(("0".equals(data.get(15).toString()) || StrUtil.isBlank(data.get(15).toString())) ? "0.00" : data.get(15).toString()));
            boolean checkNull = StrUtil.isNotBlank(data.get(15).toString());
            boolean checkOne = "0".equals(data.get(15).toString());
            // TODO 为0的时候这一行是否可以输入空的
            if (checkNull || checkOne) {
                // 不为空要求这一行全部输入  前6列数据不能为空
                for (int j = 0; j < NumberConstant.SIX; j++) {
                    if (StrUtil.isBlank(data.get(j).toString())) {
                        IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                        incomeErrorMessage.setTotal(row);
                        int column = j + 1;
                        incomeErrorMessage.setErrMessage("第{" + row + "}行第{" + column + "}列数据为空");
                        incomeErrorMessageList.add(incomeErrorMessage);
                    }
                }
            }
            // 检验收入成本项目数据是否存在
            Product product = productMap.get(productCode.trim() + productName.trim());
            Department department = departmentMap.get(openDepartmentCode.trim() + openDepartmentName.trim());
            Department department1 = departmentMap.get(startDepartmentCode.trim() + startDepartmentName.trim());
            if (StrUtil.isNotBlank(productCode) && StrUtil.isNotBlank(productName)) {
                if (Objects.isNull(product)) {
                    IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                    incomeErrorMessage.setTotal(row);
                    incomeErrorMessage.setErrMessage("成本项目代码:" + productCode + " 名称:" + productName + "不存在");
                    incomeErrorMessageList.add(incomeErrorMessage);

                } else {
                    // 检验对应的会计科目是否存在
                    Long id = product.getId();
                    Long accountId = accountProMap.get(id);
                    if (Objects.isNull(accountingMap.get(accountId))) {
                        IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                        incomeErrorMessage.setTotal(row);
                        incomeErrorMessage.setErrMessage("成本项目代码:" + productCode + " 名称:" + productName + "对应的会计科目不存在");
                        incomeErrorMessageList.add(incomeErrorMessage);
                    } else {
                        costIncomeGroup.setProductCode(productCode);
                        costIncomeGroup.setProductName(productName);
                        costIncomeGroup.setAccountCode(accountingMap.get(accountId).getAccountingCode());
                        costIncomeGroup.setAccountName(accountingMap.get(accountId).getAccountingName());
                    }
                }
            } else {
                costIncomeGroup.setProductCode(null);
                costIncomeGroup.setProductName(null);
                costIncomeGroup.setAccountCode(null);
                costIncomeGroup.setAccountName(null);
            }
            // 检验开单科室
            if (StrUtil.isNotBlank(openDepartmentCode) && StrUtil.isNotBlank(openDepartmentName)) {
                // 开单科室
                if (Objects.isNull(department)) {
                    IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                    incomeErrorMessage.setTotal(row);
                    incomeErrorMessage.setErrMessage("开单科室代码:" + openDepartmentCode + " 科室名称:" + openDepartmentName + "不存在");
                    incomeErrorMessageList.add(incomeErrorMessage);
                } else {
                    Long id = department.getId();
                    Long responsibilityId = responsibilityDepMap.get(id);
                    if (Objects.isNull(responsibilityMap.get(responsibilityId))) {
                        IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                        incomeErrorMessage.setTotal(row);
                        incomeErrorMessage.setErrMessage("开单科室代码代码:" + openDepartmentCode + " 科室名称:" + openDepartmentName + "对应的责任中心不存在");
                        incomeErrorMessageList.add(incomeErrorMessage);
                    } else {
                        Responsibility responsibility = responsibilityMap.get(responsibilityId);
                        costIncomeGroup.setOpenDepartmentCode(openDepartmentCode);
                        costIncomeGroup.setOpenDepartmentName(openDepartmentName);
                        costIncomeGroup.setOpenResponsibilityCode(responsibility.getResponsibilityCode());
                        costIncomeGroup.setOpenResponsibilityName(responsibility.getResponsibilityName());
                        afterIncomegroup.setOpenDepartmentCode(openDepartmentCode);
                        afterIncomegroup.setOpenDepartmentName(openDepartmentName);
                        afterIncomegroup.setOpenDepartmentStatus(responsibility.getResponsibilityType());
                        afterIncomegroup.setOpenResponsibilityCode(responsibility.getResponsibilityCode());
                        afterIncomegroup.setOpenResponsibilityName(responsibility.getResponsibilityName());
                    }
                }
            } else {
                costIncomeGroup.setOpenDepartmentCode(null);
                costIncomeGroup.setOpenDepartmentName(null);
                costIncomeGroup.setOpenResponsibilityCode(null);
                costIncomeGroup.setOpenResponsibilityName(null);
            }
            // 检验执行科室
            if (StrUtil.isNotBlank(startDepartmentCode) && StrUtil.isNotBlank(startDepartmentName)) {
                //执行科室
                if (Objects.isNull(department1)) {
                    IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                    incomeErrorMessage.setTotal(row);
                    incomeErrorMessage.setErrMessage("执行科室代码:" + startDepartmentCode + " 科室名称:" + startDepartmentName + "科室不存在");
                    incomeErrorMessageList.add(incomeErrorMessage);
                } else {
                    Long id = department1.getId();
                    Long responsibilityId = responsibilityDepMap.get(id);
                    if (Objects.isNull(responsibilityMap.get(responsibilityId))) {
                        IncomeErrorMessage incomeErrorMessage = new IncomeErrorMessage();
                        incomeErrorMessage.setTotal(row);
                        incomeErrorMessage.setErrMessage("执行科室代码:" + startDepartmentCode + " 名称:" + startDepartmentCode + "对应的责任中心不存在");
                        incomeErrorMessageList.add(incomeErrorMessage);
                    } else {
                        Responsibility responsibility = responsibilityMap.get(responsibilityId);
                        costIncomeGroup.setStartDepartmentCode(startDepartmentCode);
                        costIncomeGroup.setStartDepartmentName(startDepartmentName);
                        costIncomeGroup.setStartResponsibilityCode(responsibility.getResponsibilityCode());
                        costIncomeGroup.setStartResponsibilityName(responsibility.getResponsibilityName());
                        afterIncomegroup.setStartDepartmentCode(startDepartmentCode);
                        afterIncomegroup.setStartDepartmentName(startDepartmentName);
                        afterIncomegroup.setStartDepartmentStatus(responsibility.getResponsibilityType());
                        afterIncomegroup.setStartResponsibilityCode(responsibility.getResponsibilityCode());
                        afterIncomegroup.setStartResponsibilityName(responsibility.getResponsibilityName());
                    }
                }
            } else {
                costIncomeGroup.setStartDepartmentCode(null);
                costIncomeGroup.setStartDepartmentName(null);
                costIncomeGroup.setStartResponsibilityCode(null);
                costIncomeGroup.setStartResponsibilityName(null);
            }
            costIncomeGroup.setDoctorNumber(StrUtil.isBlank(data.get(6).toString()) ? null : Long.parseLong(data.get(6).toString()))
                    .setDoctorName(data.get(7).toString())
                    .setPatientId(StrUtil.isBlank(data.get(8).toString()) ? null : Long.parseLong(data.get(8).toString()))
                    .setOutpatientId(StrUtil.isBlank(data.get(9).toString()) ? null : Long.parseLong(data.get(9).toString()))
                    .setPatientName(data.get(10).toString())
                    .setPatientFee(data.get(11).toString())
                    .setReceiptFee(data.get(12).toString())
                    .setTotalNumber(StrUtil.isBlank(data.get(13).toString()) ? null : new BigDecimal(data.get(13).toString()))
                    .setUnit(data.get(14).toString())
                    .setFeeDatetime(StrUtil.isBlank(data.get(16).toString()) ? null : DateUtils.StringToDate(data.get(16).toString(), DateStyleEnum.YYYY_MM_DD_HH_MM_SS));
            costIncomeGroup.setHospId(hospId);
            costIncomeGroup.setCreateTime(System.currentTimeMillis());
            costIncomeGroup.setDateYear(year);
            costIncomeGroup.setDateMonth(month);
            costIncomeGroup.setAmount(beforeMoney);
            // 检验数据
            getAfterData(hospId, costIncomeGroup, afterIncomegroup, beforeMoney);
            costIncomeGroupArrayList.add(costIncomeGroup);
        }
    }

    /**
     * 封装需要的数据
     *
     * @param hospId
     * @param costIncomeGroup
     * @param afterIncomegroup
     * @param beforeMoney
     */
    private void getAfterData(Long hospId, CostIncomeGroup costIncomeGroup, AfterIncomeGroup afterIncomegroup, BigDecimal beforeMoney) {
        Integer openDepartmentStatus = afterIncomegroup.getOpenDepartmentStatus();
        Integer startDepartmentStatus = afterIncomegroup.getStartDepartmentStatus();
        if (Objects.nonNull(openDepartmentStatus) && Objects.nonNull(startDepartmentStatus)) {
            Map<String, CostIncomeGroupSet> incomeGroupSetMap = costIncomeGroupSetService.list(new QueryWrapper<CostIncomeGroupSet>().lambda().eq(CostIncomeGroupSet::getHospId, hospId)).stream().collect(Collectors.toMap(k -> k.getOpenDepartmentStatus().toString() + k.getStartDepartmentStatus().toString(), synOe -> synOe));
            CostIncomeGroupSet costIncomeGroupSet = incomeGroupSetMap.get(openDepartmentStatus.toString() + startDepartmentStatus.toString());
            if (Objects.nonNull(costIncomeGroupSet)) {
                Map<String, Responsibility> map = responsibilityService.list(new QueryWrapper<Responsibility>().lambda().eq(Responsibility::getHospId, hospId)).stream().collect(Collectors.toMap(Responsibility::getResponsibilityCode, synOe -> synOe));
                // 开单科室比例
                BigDecimal openDepartmentProportion = new BigDecimal(costIncomeGroupSet.getOpenDepartmentProportion().toString());
                // 执行科室比例
                BigDecimal startDepartmentProportion = new BigDecimal(costIncomeGroupSet.getStartDepartmentProportion().toString());
                // beforeMoney
                afterIncomegroup.setOpenDepartmentDecimal(beforeMoney.multiply(openDepartmentProportion).divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP));
                afterIncomegroup.setStartDepartmentDecimal(beforeMoney.multiply(startDepartmentProportion).divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP));
                String responsibilityCodes = costIncomeGroupSet.getResponsibilityCodes();
                if (NumberConstant.TWO.equals(costIncomeGroupSet.getOpenDepartmentStatus()) && NumberConstant.TWO.equals(costIncomeGroupSet.getStartDepartmentStatus()) && StrUtil.isNotBlank(responsibilityCodes)) {
                    // /拼接的
                    afterIncomegroup.setDirectStatus(NumberConstant.TWO);
                    String responsibilityCode = responsibilityCodes.split(StrUtil.SLASH)[responsibilityCodes.split(StrUtil.SLASH).length - 1];
                    Responsibility responsibility = map.get(responsibilityCode);
                    if (Objects.nonNull(responsibility)) {
                        afterIncomegroup.setResponsibilityCode(responsibility.getResponsibilityCode());
                        afterIncomegroup.setResponsibilityName(responsibility.getResponsibilityName());
                        afterIncomegroup.setOtherResponsibilityDecimal(beforeMoney);
                    }
                }
                costIncomeGroup.setAfterIncomeGroup(JacksonUtil.obj2Str(afterIncomegroup));
            }
        }
    }

    /**
     * 设置相关名称
     *
     * @param costIncomeGroupAllAmountVOList
     */
    private void setCodeName(List<CostIncomeGroupAllAmountVO> costIncomeGroupAllAmountVOList) {
        costIncomeGroupAllAmountVOList.forEach(i -> {
            // 以为这里的数据导入的  在导入的时候进行数据校验
            // 设置开单科室名称 执行科室名称  开单责任中心名称  执行责任中心名称 成本项目的名称 会计科目名称
            i.setOpenDepartmentCodeName("[" + i.getOpenDepartmentCode() + "]" + i.getOpenDepartmentName());
            i.setOpenResponsibilityCodeName("[" + i.getOpenResponsibilityCode() + "]" + i.getOpenResponsibilityName());
            i.setStartDepartmentCodeName("[" + i.getStartDepartmentCode() + "]" + i.getStartDepartmentName());
            i.setStartResponsibilityCodeName("[" + i.getStartResponsibilityCode() + "]" + i.getStartResponsibilityName());
            i.setProductCodeName("[" + i.getProductCode() + "]" + i.getProductName());
            i.setAccountCodeName("[" + i.getAccountCode() + "]" + i.getAccountName());
        });
    }

    /**
     * 文件上传
     */
    public String uploadFile(MultipartFile file) {
        Long hospId = UserContext.getCurrentLoginHospId();
        String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")) + System.currentTimeMillis() + ".xls";
        log.info(fileName);

        DateTime date = DateUtil.date();
        int month = DateUtil.month(date) + 1;
        int year = DateUtil.year(date);
        int day = DateUtil.dayOfMonth(date);
        String fileUrl="";
        try {
//            file.transferTo(new File(localFilePath));
            String format = DateUtil.format(date, DatePattern.PURE_DATETIME_PATTERN);
            String originalFilename = format + fileName;

            String dataDirectory = minioConfig.getBucketName();
            String uploadFileName = "file"+"/"+hospId + "/" + year + "/" + month + "/" + day + "/" + originalFilename;


            InputStream inputStream = file.getInputStream();

            minioFileUtil.putObject(dataDirectory, uploadFileName, inputStream);
            fileUrl = minioFileUtil.getObjectUrl(dataDirectory, uploadFileName);

        } catch (IOException e) {
            log.error("【文件上传至服务器】失败，绝对路径：{}", e.getMessage());
            throw new CostException(ErrorCodeEnum.FILE_UPLOAD_ERROR);
        }
        return fileUrl;
    }


}