package com.kcim.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kcim.common.constants.Constant;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.BeanUtil;
import com.kcim.common.util.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.common.util.excel.ExcelStyleUtil;
import com.kcim.common.util.excel.ExcelUtil;
import com.kcim.common.util.excel.entity.StandItemImportEntity;
import com.kcim.common.util.excel.handler.MedServiceItemTypeHandler;
import com.kcim.dao.model.*;
import com.kcim.dao.repository.*;
import com.kcim.service.CenterService;
import com.kcim.service.StandItemService;
import com.kcim.vo.DictDataVo;
import com.kcim.vo.KCClassVo;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: CostAccount
 * @description: 标准项目接口实现类
 * @author: Wang.YS
 * @create: 2023-11-13 11:28
 **/
@Service("StandItemService")
@Slf4j
@AllArgsConstructor
public class StandItemServiceImpl implements StandItemService {
    StandItemRepository repository;
    StandItemEmpMapRepository standItemEmpMapRepository;
    /**
     * 标准项目与设备对照
     */
    StandItemEquipmentMapRepository standItemEquipmentMapRepository;
    /**
     * 标准项目与空间对照
     */
    StandItemSpaceMapRepository standItemSpaceMapRepository;
    CenterService centerService;

    EmpCostTypeRepository empCostTypeRepository;
    EquipmentRepository equipmentRepository;
    SpaceRepository spaceRepository;

    AccountingRepository accountingRepository;
    /**
     * 获取标准项目分页列表
     * @param current 当前页
     * @param pageSize 页容量
     * @param name 名称
     * @param kcClassCode 康程分类
     * @return 列表
     */
    @Override
    public Object getStandItemList(Integer current, Integer pageSize, String name, String kcClassCode) {
        Page<StandItem> page = repository.getPage(current, pageSize, name, kcClassCode);
        List<StandItem> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);
        }
        //标准项目字典人员对照
        List<StandItemEmpMap> empMapList = standItemEmpMapRepository.getList();
        Map<String, List<StandItemEmpMap>>  empMapGroup = new HashMap<>();
        if(!CollectionUtils.isEmpty(empMapList)){
            List<EmpCostType> list = empCostTypeRepository.getList();
            Map<String,String> map = list.stream().collect(Collectors.toMap(EmpCostType::getCostTypeCode, EmpCostType::getCostTypeName, (a, b) -> b));
            empMapList.forEach(standItemEmpMap -> standItemEmpMap.setEmpTypeCodeName(map.get(standItemEmpMap.getEmpTypeCode())));

            empMapGroup = empMapList.stream().collect(Collectors.groupingBy(StandItemEmpMap::getStandItemCode));


        }
        //标准项目字典空间对照
        List<StandItemSpaceMap> spaceMapList = standItemSpaceMapRepository.getList();
        Map<String, List<StandItemSpaceMap>>  spaceMapGroup = new HashMap<>();
        if(!CollectionUtils.isEmpty(spaceMapList)){
            List<Space> list = spaceRepository.getList();
            Map<String,String> map = list.stream().collect(Collectors.toMap(Space::getCode, Space::getName, (a, b) -> b));
            spaceMapList.forEach(spaceMap -> spaceMap.setSpaceCodeName(map.get(spaceMap.getSpaceCode())));

            spaceMapGroup = spaceMapList.stream().collect(Collectors.groupingBy(StandItemSpaceMap::getStandItemCode));
        }
        //标准项目字典设备对照
        List<StandItemEquipmentMap> equipmentMapList = standItemEquipmentMapRepository.getList();
        Map<String, List<StandItemEquipmentMap>>  equipmentMapGroup = new HashMap<>();
        if(!CollectionUtils.isEmpty(equipmentMapList)){
            List<Equipment> list = equipmentRepository.getList();
            Map<String,String> map = list.stream().collect(Collectors.toMap(Equipment::getCode, Equipment::getName, (a, b) -> b));
            equipmentMapList.forEach(equipmentMap -> equipmentMap.setEquipmentCodeName(map.get(equipmentMap.getEquipmentCode())));
            equipmentMapGroup = equipmentMapList.stream().collect(Collectors.groupingBy(StandItemEquipmentMap::getStandItemCode));
        }
//        List<Accounting> accountIncome = accountingRepository.getAccountIncome(null);
//        if(CollectionUtils.isEmpty(accountIncome)){
//            throw new CostException("当前院区未添加会计科目，添先添加会计科目再进行对照");
//        }
//        Map<String,String> accountMap = accountIncome.stream().collect(Collectors.toMap(Accounting::getAccountingName,Accounting::getAccountingCode, (a, b) -> b));

        List<KCClassVo> kcClass = centerService.getKCClass();
        if(CollectionUtils.isEmpty(kcClass)){
            log.error("中台未维护康程分类，请先维护康程分类数据");
            throw new CostException("中台未维护康程分类，请先维护康程分类数据");
        }
        Map<String,String> map = kcClass.stream().collect(Collectors.toMap(KCClassVo::getCode, KCClassVo::getLevelName, (a, b) -> b));

        DictDataVo centerDict = centerService.getCenterDict(Constant.MED_SERVICE_ITEM_TYPE);
        List<DictDataVo> dataVoList = centerDict.getDataVoList();
        Map<String,String> typeNameMap = dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));


        for (StandItem record : records) {
            record.setKcClassLevelName(map.get(record.getKcClassCode()));
            String type = record.getItemType();
            if(!StringUtils.isEmpty(type)){
                record.setItemTypeName(typeNameMap.get(type));
            }
//            record.setAccountName(accountMap.get(record.getAccounts()));
            record.setEmpMaps(empMapGroup.get(record.getCode()));
            record.setEquipmentMaps(equipmentMapGroup.get(record.getCode()));
            record.setSpaceMaps(spaceMapGroup.get(record.getCode()));
        }
        return new PageUtils(records, Math.toIntExact(page.getTotal()),pageSize,current);
    }

    /**
     * 新增标准项目
     * @param request 入参
     */
    @Override
    public void addStandItem(StandItem request) {
        request.setHospId(UserContext.getHospId());
        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        request.setCreateTime(new Date());
        repository.save(request);
    }

    /**
     * 编辑标准项目
     * @param request 入参
     */
    @Override
    public void editStandItem(StandItem request) {
        Integer id = request.getId();
        if(id ==null){
            throw new CostException("编辑时主键必填");
        }
        StandItem item = repository.getById(id);
        StandItem oneByCode = repository.getOneByCode(request.getCode());
        if(Objects.nonNull(item)){
            if(Objects.isNull(oneByCode)||oneByCode.getId().equals(id)){
                BeanUtil.convertObj(request,item);
                item.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
                item.setUpdateTime(new Date());
                repository.updateById(item);
            }else {
                throw new CostException("当前标准项目代码已存在，请修改后再保存");
            }
        }
    }

    /**
     * 删除标准项目
     * @param id 主键
     */
    @Override
    public void deleteStandItem(Integer id) {
        repository.deleteStandItem(id);
    }

    /**
     * 导出标准项目模版
     * @param response 出参
     * @return 模版
     */
    @SneakyThrows
    @Override
    public Object exportStandItem(HttpServletResponse response) {
        try {
            //配置excel 文件信息
            ExportParams params = new ExportParams();
            params.setTitle("说明：1、为了保证成功导入，请勿修改模板格式\n" +
                    "      2、康程分类为下拉选择字段，不可填写选项外的数据\n" +
                    "      3、参与人员、使用设备、使用空间填写格式为：人事分类1*人数1*执行时间1|人事分类2*人数2*执行时间2");
            List<KCClassVo> kcClass = centerService.getKCClass();
            if(CollectionUtils.isEmpty(kcClass)){
                throw new CostException("未维护康程分类");
            }
            String[] strings = kcClass.stream().map(KCClassVo::getLevelName).toArray(String[]::new);

            DictDataVo centerDict = centerService.getCenterDict(Constant.MED_SERVICE_ITEM_TYPE);
            List<DictDataVo> dataVoList = centerDict.getDataVoList();
//            params.setDictHandler(new KcClassTypeHandler(kcClass));
            params.setDictHandler(new MedServiceItemTypeHandler(dataVoList));

            //设置导出样式
            params.setStyle(ExcelStyleUtil.class);
            //设置sheetName
            params.setSheetName("标准项目");
//            FileOutputStream outputStream = new FileOutputStream("E:\\标准项目导入模版.xlsx");
            Workbook workbook = ExcelExportUtil.exportExcel(params, StandItemImportEntity.class,new ArrayList<>());
            ExcelUtil.createDropDownExpandList(workbook,strings,2,65535,4,4);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel");
            String fileName ="标准项目导入模版";
            response.setHeader("Content-Disposition",  URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
//            workbook.write(outputStream);
//            outputStream.close();
            workbook.close();
            log.info("导出文件：{}",fileName);
        } catch (FileNotFoundException e) {
            throw new CostException(e.getMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return response.getOutputStream();
    }

    /**
     * 导入标准项目
     * @param file excel模版
     */
//    @SneakyThrows
    @Override
    public void importStandItem(MultipartFile file) {
        try {
            if (ObjectUtils.isEmpty(file) || file.getSize() == 0){
                throw new CostException("未获取到导入的excel文件内容");
            }
            log.info("接收到文件：{}",file.getOriginalFilename());
            // 参数1：文件流
            InputStream stream = file.getInputStream();
            // 参数2：导入类型
            ImportParams params = new ImportParams();
            //校验Excel 去掉空行
            params.setNeedVerify(true);
            IExcelVerifyHandler<StandItemImportEntity> handler = val ->{
                if(StringUtils.isEmpty(val.getCode())){
                    return new ExcelVerifyHandlerResult(false,"标准项目代码不能为空");
                }
                if(StringUtils.isEmpty(val.getName())){
                    return new ExcelVerifyHandlerResult(false,"标准项目名称不能为空");
                }
                return new ExcelVerifyHandlerResult(true);
            };
            params.setVerifyHandler(handler);
            // 标题占用多少行
            params.setTitleRows(1);
            // 头部属性占用多少行
            params.setHeadRows(1);
            DictDataVo centerDict = centerService.getCenterDict(Constant.MED_SERVICE_ITEM_TYPE);
            List<DictDataVo> dataVoList = centerDict.getDataVoList();
//            params.setDictHandler(new KcClassTypeHandler(kcClass));
            params.setDictHandler(new MedServiceItemTypeHandler(dataVoList));
            List<KCClassVo> kcClass = centerService.getKCClass();
            if(CollectionUtils.isEmpty(kcClass)){
                log.error("中台未维护康程分类，请先维护康程分类数据");
                throw new CostException("中台未维护康程分类，请先维护康程分类数据");
            }


//            params.setDictHandler(new KcClassTypeHandler(kcClass));
            List<StandItemImportEntity> itemImportEntities  = ExcelImportUtil.importExcel(stream, StandItemImportEntity.class,params);
            if(!CollectionUtils.isEmpty(itemImportEntities)){
                //人员类别
                List<EmpCostType> empCostTypes = empCostTypeRepository.getList();
                if(CollectionUtils.isEmpty(empCostTypes)){
                    log.error("未维护人员类别，请先维护人员类别数据");
                    throw new CostException("未维护人员类别，请先维护人员类别数据");
                }
                Map<String,String> empCostMap = empCostTypes.stream().collect(Collectors.toMap(EmpCostType::getCostTypeName, EmpCostType::getCostTypeCode, (a, b) -> b));
                //设备成本
                List<Equipment> equipmentList = equipmentRepository.getList();
                if(CollectionUtils.isEmpty(equipmentList)){
                    log.error("未维护设备成本，请先维护设备成本数据");
                    throw new CostException("未维护设备成本，请先维护设备成本数据");
                }
                Map<String,String> equipmentMap = equipmentList.stream().collect(Collectors.toMap(Equipment::getName, Equipment::getCode, (a, b) -> b));
                //空间成本
                List<Space> spaces = spaceRepository.getList();
                if(CollectionUtils.isEmpty(spaces)){
                    log.error("未维护空间成本字典，请先维护空间成本字典数据");
                    throw new CostException("未维护空间成本字典，请先维护空间成本字典数据");
                }
                Map<String,String> spaceMap = spaces.stream().collect(Collectors.toMap(Space::getName, Space::getCode, (a, b) -> b));

                Map<String,String> map = kcClass.stream().collect(Collectors.toMap(KCClassVo::getCode, KCClassVo::getName, (a, b) -> b));
                Map<String,String> kcMap = kcClass.stream().collect(Collectors.toMap(KCClassVo::getLevelName, KCClassVo::getCode, (a, b) -> b));

                List<StandItem> saveList = new ArrayList<>();
                StandItem standItem =new StandItem();
                standItem.setHospId(UserContext.getHospId());
                standItem.setCreateTime(new Date());
                standItem.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
                List<StandItemEmpMap> empSaveList = new ArrayList<>();
                List<StandItemEquipmentMap> equipmentSaveList = new ArrayList<>();
                List<StandItemSpaceMap> spaceSaveList = new ArrayList<>();
                for (StandItemImportEntity entity : itemImportEntities) {
                    StandItem item = BeanUtil.convertObj(standItem, StandItem.class);
                    item.setCode(entity.getCode());
                    item.setName(entity.getName());
                    item.setNationalCode(entity.getNationalCode());
                    item.setKcClassCode(kcMap.get(entity.getType()));
                    item.setExecuteTime(entity.getExecuteTime());
                    item.setKcClassName(map.get(item.getKcClassCode()));
                    item.setTechnicalDifficulty(entity.getTechnicalDifficulty());
                    item.setRiskDegree(entity.getRiskDegree());
                    item.setItemType(entity.getItemType());
                    String emp = entity.getEmp();
                    if(!StringUtils.isEmpty(emp)){
                        List<StandItemEmpMap> empSplit = getEmpSplit(item.getCode(), emp, empCostMap);
                        empSaveList.addAll(empSplit);
                    }
                    String equipment = entity.getEquipment();
                    if(!StringUtils.isEmpty(equipment)){
                        List<StandItemEquipmentMap> equipmentSplit = getEquipmentSplit(item.getCode(), equipment, equipmentMap);
                        equipmentSaveList.addAll(equipmentSplit);
                    }
                    String space = entity.getSpace();
                    if(!StringUtils.isEmpty(space)){
                        List<StandItemSpaceMap> spaceSplit = getSpaceSplit(item.getCode(), space, spaceMap);
                        spaceSaveList.addAll(spaceSplit);
                    }
                    saveList.add(item);
                }
                //标准项目
                if(!CollectionUtils.isEmpty(saveList)){
                    check();
                    repository.saveBatch(saveList,100);
                    if(!CollectionUtils.isEmpty(empSaveList)){
                        standItemEmpMapRepository.saveBatch(empSaveList);
                    }

                    if(!CollectionUtils.isEmpty(equipmentSaveList)){
                        standItemEquipmentMapRepository.saveBatch(equipmentSaveList);
                    }
                    if(!CollectionUtils.isEmpty(spaceSaveList)){
                        standItemSpaceMapRepository.saveBatch(spaceSaveList);
                    }
                }
            }
        } catch (Exception e) {
            throw new CostException(e.getMessage());
        }
    }

    /**
     * 截取并组装标准项目与参与人员出参
     * @param standCode 标准项目代码
     * @param item 人员类别信息
     * @param empCostMap 人员类别字典
     * @return 标准项目与人员类别对照出参
     */
    private List<StandItemEmpMap> getEmpSplit(String standCode,String item, Map<String,String> empCostMap){
        List<StandItemEmpMap> list = new ArrayList<>();
        if(item.contains("|")){
            //有多个
            List<String> split = StrUtil.split(item, "|");
            for (String s : split) {
                convertEmpItem(standCode, empCostMap, list, s);
            }
        }else {
            //只有一个
            convertEmpItem(standCode, empCostMap, list, item);
        }
        return list;
    }

    private void convertEmpItem(String standCode, Map<String, String> empCostMap, List<StandItemEmpMap> list, String s) {
        List<String> split1 = StrUtil.split(s, "*");
        if (split1.size() < 2) {
            log.error("当前" + standCode + "项目参与人员导入信息有误");
            throw new CostException("当前" + standCode + "项目参与人员导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(0))) {
            throw new CostException("当前" + standCode + "项目参与人员人事分类导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(1))) {
            throw new CostException("当前" + standCode + "项目参与人员人数导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(2))) {
            throw new CostException("当前" + standCode + "项目参与人员执行时间导入信息有误");
        }
        StandItemEmpMap vo = new StandItemEmpMap();
        vo.setEmpTypeCode(empCostMap.get(split1.get(0)));
        vo.setNum(new BigDecimal(split1.get(1)));
        vo.setExecuteTime(new BigDecimal(split1.get(2)));
        vo.setStandItemCode(standCode);
        vo.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        vo.setCreateTime(new Date());
        vo.setHospId(UserContext.getHospId());
        list.add(vo);
    }

    /**
     * 截取并组装标准项目与使用设备出参
     * @param standCode 标准项目代码
     * @param item 设备信息
     * @param equipmentMap 设备字典
     * @return 标准项目与使用设备对照出参
     */
    private List<StandItemEquipmentMap> getEquipmentSplit(String standCode,String item, Map<String,String> equipmentMap){
        List<StandItemEquipmentMap> list = new ArrayList<>();
        if(item.contains("|")){
            //有多个
            List<String> split = StrUtil.split(item, "|");
            for (String s : split) {
                convertEquipment(standCode, equipmentMap, list, s);
            }
        }else {
            //只有一个
            convertEquipment(standCode, equipmentMap, list, item);
        }
        return list;
    }

    private void convertEquipment(String standCode, Map<String, String> equipmentMap, List<StandItemEquipmentMap> list, String s) {
        List<String> split1 = StrUtil.split(s, "*");
        if (split1.size() < 2) {
            log.error("当前" + standCode + "项目使用设备导入信息有误");
            throw new CostException("当前" + standCode + "项目使用设备导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(0))) {
            throw new CostException("当前" + standCode + "项目使用设备设备代码导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(1))) {
            throw new CostException("当前" + standCode + "项目使用设备数量导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(2))) {
            throw new CostException("当前" + standCode + "项目使用设备执行时间导入信息有误");
        }
        StandItemEquipmentMap vo = new StandItemEquipmentMap();
        vo.setEquipmentCode(equipmentMap.get(split1.get(0)));
        vo.setNum(new BigDecimal(split1.get(1)));
        vo.setExecuteTime(new BigDecimal(split1.get(2)));
        vo.setStandItemCode(standCode);
        vo.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        vo.setCreateTime(new Date());
        vo.setHospId(UserContext.getHospId());
        list.add(vo);
    }

    /**
     * 截取并组装标准项目与使用空间出参
     * @param standCode 标准项目代码
     * @param item 使用空间信息
     * @param spaceMap 使用空间字典
     * @return 标准项目与使用空间对照出参
     */
    private List<StandItemSpaceMap> getSpaceSplit(String standCode,String item, Map<String,String> spaceMap){
        List<StandItemSpaceMap> list = new ArrayList<>();
        if(item.contains("|")){
            //有多个
            List<String> split = StrUtil.split(item, "|");
            for (String s : split) {
                convertSpaceItem(standCode, spaceMap, list, s);
            }
        }else {
            //只有一个
            convertSpaceItem(standCode, spaceMap, list, item);
        }
        return list;
    }

    private void convertSpaceItem(String standCode, Map<String, String> spaceMap, List<StandItemSpaceMap> list, String s) {
        List<String> split1 = StrUtil.split(s, "*");
        if (split1.size() < 2) {
            log.error("当前" + standCode + "项目使用空间导入信息有误");
            throw new CostException("当前" + standCode + "项目使用空间导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(0))) {
            throw new CostException("当前" + standCode + "项目使用空间空间编辑导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(1))) {
            throw new CostException("当前" + standCode + "项目使用空间数量导入信息有误");
        }
        if (StringUtils.isEmpty(split1.get(2))) {
            throw new CostException("当前" + standCode + "项目使用空间执行时间导入信息有误");
        }



        StandItemSpaceMap vo = new StandItemSpaceMap();
        vo.setSpaceCode(spaceMap.get(split1.get(0)));
        vo.setNum(new BigDecimal(split1.get(1)));
        vo.setExecuteTime(new BigDecimal(split1.get(2)));
        vo.setStandItemCode(standCode);
        vo.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        vo.setCreateTime(new Date());
        vo.setHospId(UserContext.getHospId());

        list.add(vo);
    }

    /**
     * 校验导入时是否有标准项目及对照历史数据 有作废
     */
    private void check() {
        List<StandItem> list = repository.getList();
        if(!CollectionUtils.isEmpty(list)){
            repository.removeList(list);
            List<String> collect = list.stream().map(StandItem::getCode).collect(Collectors.toList());
            //移除人员
            standItemEmpMapRepository.removeByStandCodes(collect);
            //移除设备
            standItemEquipmentMapRepository.removeByStandCodes(collect);
            //移除空间
            standItemSpaceMapRepository.removeByStandCodes(collect);

        }
    }
    /**
     *对照标准项目与会计科目
     */
    @Override
    public void matchStandItemAndCostAccounting() {
        List<StandItem> list = repository.getList();
        //获取病种字典
        if(CollectionUtils.isEmpty(list)){
            throw new CostException("当前院区未添加标准项目字典，添先添加标准项目再进行对照");
        }
        List<Accounting> accountIncome = accountingRepository.getAccountIncome(null);
        if(CollectionUtils.isEmpty(accountIncome)){
            throw new CostException("当前院区未添加会计科目，添先添加会计科目再进行对照");
        }
        Map<String,Accounting> map = accountIncome.stream().collect(Collectors.toMap(Accounting::getAccountingName, type -> type, (a, b) -> b));
        List<StandItem> collect = list.stream().filter(f -> StringUtils.isEmpty(f.getAccounts())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(collect)){
            for (StandItem item : collect) {
                String kcClassName = item.getKcClassName();
                if(!StringUtils.isEmpty(kcClassName)){
                    Accounting accounting = map.get(kcClassName);
                    if(Objects.nonNull(accounting)){
                        item.setAccounts(accounting.getAccountingCode());

                    }
                }
            }
            repository.updateBatchById(collect);
        }
    }

    /**
     * 获取会计科目收入类型字典
     * @param name 会计科目名称
     * @return 会计科目收入类型字典
     */
    @Override
    public Object getCostAccountingDict(String name) {
        return accountingRepository.getAccountIncome(name);
    }

    /**
     * 获取康程分类
     * @return 中台康程分类
     */
    @Override
    public Object getKcClassDict() {

        List<KCClassVo> kcClass = centerService.getKCClass();
        Map<String, List<KCClassVo>> filterCollect = kcClass.stream().collect(Collectors.groupingBy(KCClassVo::getParentCode));

        List<KCClassVo> parentList = filterCollect.get(NumberConstant.ZERO_S);
        filterCollect.remove(NumberConstant.ZERO_S);
        for (KCClassVo dictKcClass : parentList) {
            if (!CollectionUtils.isEmpty(filterCollect.get(dictKcClass.getCode()))) {
                dictKcClass.setChildList(setChildren(filterCollect.get(dictKcClass.getCode()),filterCollect));
            }
        }
        return  parentList;
    }
    public List<KCClassVo> setChildren(List<KCClassVo> dictKcClasses,Map<String, List<KCClassVo>> collect){
        for(KCClassVo dictKcClass:dictKcClasses){
            if(!CollectionUtils.isEmpty(collect.get(dictKcClass.getCode()))){
                dictKcClass.setChildList(setChildren(collect.get(dictKcClass.getCode()),collect));
            }
        }
        return dictKcClasses;
    }
    /**
     * 获取标准项目与参与人员对照
     * @param standCode 标准项目代码
     * @return 标准项目与参与人员对照
     */
    @Override
    public Object getStandItemEmpMap(String standCode) {
        List<StandItemEmpMap> standItemEmpMaps = standItemEmpMapRepository.getByStandCode(standCode);
        List<EmpCostType> empCostTypes = empCostTypeRepository.getList();
        if(CollectionUtils.isEmpty(empCostTypes)){
            log.error("未维护人员类别，请先维护人员类别数据");
            throw new CostException("未维护人员类别，请先维护人员类别数据");
        }
        Map<String,String> empCostMap = empCostTypes.stream().collect(Collectors.toMap(EmpCostType::getCostTypeCode, EmpCostType::getCostTypeName, (a, b) -> b));
        for (StandItemEmpMap empMap : standItemEmpMaps) {
            empMap.setEmpTypeCodeName(empCostMap.get(empMap.getEmpTypeCode()));
        }
        return standItemEmpMaps;
    }

    /**
     * 新增标准项目与参与人员对照
     * @param request 入参
     */
    @Override
    public void addStandItemEmpMap(StandItemEmpMap request) {
        request.setHospId(UserContext.getHospId());
        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        request.setCreateTime(new Date());
        standItemEmpMapRepository.save(request);
    }

    /**
     * 编辑标准项目与参与人员对照
     * @param request 入参
     */
    @Override
    public void editStandItemEmpMap(StandItemEmpMap request) {
        Integer id = request.getId();
        if(id ==null){
            throw new CostException("编辑时主键必填");
        }
        StandItemEmpMap item = standItemEmpMapRepository.getById(id);
        if(Objects.nonNull(item)){
            BeanUtil.convertObj(request,item);
            item.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            item.setUpdateTime(new Date());
            standItemEmpMapRepository.updateById(item);
        }
    }

    /**
     * 删除标准项目与参与人员对照
     * @param id 主键
     */
    @Override
    public void deleteStandItemEmpMap(Integer id) {
        standItemEmpMapRepository.deleteStandItemEmpMap(id);
    }

    /**
     * 获取标准项目与设备对照
     * @param standCode 标准项目代码
     * @return 标准项目与设备对照
     */
    @Override
    public Object getStandItemEquipmentMap(String standCode) {
        List<StandItemEquipmentMap> standItemEmpMaps = standItemEquipmentMapRepository.getByStandCode(standCode);
        List<Equipment> equipmentList = equipmentRepository.getList();
        if(CollectionUtils.isEmpty(equipmentList)){
            log.error("未维护设备信息，请先设备信息数据");
            throw new CostException("未维护设备信息，请先设备信息数据");
        }
        Map<String,String> equipmentMap = equipmentList.stream().collect(Collectors.toMap(Equipment::getCode, Equipment::getName, (a, b) -> b));
        for (StandItemEquipmentMap empMap : standItemEmpMaps) {
            empMap.setEquipmentCodeName(equipmentMap.get(empMap.getEquipmentCode()));
        }
        return standItemEmpMaps;
    }

    /**
     * 新增标准项目与设备对照
     * @param request 入参
     */
    @Override
    public void addStandItemEquipmentMap(StandItemEquipmentMap request) {
        request.setHospId(UserContext.getHospId());
        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        request.setCreateTime(new Date());
        standItemEquipmentMapRepository.save(request);
    }

    /**
     * 编辑标准项目与设备对照
     * @param request 入参
     */
    @Override
    public void editStandItemEquipmentMap(StandItemEquipmentMap request) {
        Integer id = request.getId();
        if(id ==null){
            throw new CostException("编辑时主键必填");
        }
        StandItemEquipmentMap item = standItemEquipmentMapRepository.getById(id);
        if(Objects.nonNull(item)){
            BeanUtil.convertObj(request,item);
            item.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            item.setUpdateTime(new Date());
            standItemEquipmentMapRepository.updateById(item);
        }
    }

    /**
     * 删除标准项目与设备对照
     * @param id 主键
     */
    @Override
    public void deleteStandItemEquipmentMap(Integer id) {
        standItemEquipmentMapRepository.deleteStandItemEquipmentMap(id);

    }

    /**
     * 获取标准项目与空间成本
     * @param standCode 标准项目代码
     * @return 获取标准项目与空间成本对照
     */
    @Override
    public Object getStandItemSpaceMap(String standCode) {
        List<StandItemSpaceMap> standItemSpaceMaps = standItemSpaceMapRepository.getByStandCode(standCode);
        List<Space> list = spaceRepository.getList();
        if(CollectionUtils.isEmpty(list)){
            log.error("未维空间成本信息，请先维护空间成本信息数据");
            throw new CostException("未维空间成本信息，请先维护空间成本信息数据");
        }
        Map<String,String> equipmentMap = list.stream().collect(Collectors.toMap(Space::getCode, Space::getName, (a, b) -> b));
        for (StandItemSpaceMap map : standItemSpaceMaps) {
            map.setSpaceCodeName(equipmentMap.get(map.getSpaceCode()));
        }
        return standItemSpaceMaps;
    }

    /**
     * 新增标准项目与空间成本
     * @param request 入参
     */
    @Override
    public void addStandItemSpaceMap(StandItemSpaceMap request) {
        request.setHospId(UserContext.getHospId());
        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        request.setCreateTime(new Date());
        standItemSpaceMapRepository.save(request);
    }

    /**
     * 编辑标准项目与空间成本
     * @param request 入参
     */
    @Override
    public void editStandItemSpaceMap(StandItemSpaceMap request) {
        Integer id = request.getId();
        if(id ==null){
            throw new CostException("编辑时主键必填");
        }
        StandItemSpaceMap item = standItemSpaceMapRepository.getById(id);
        if(Objects.nonNull(item)){
            BeanUtil.convertObj(request,item);
            item.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            item.setUpdateTime(new Date());
            standItemSpaceMapRepository.updateById(item);
        }
    }

    /**
     * 删除标准项目与空间成本
     * @param id 主键
     */
    @Override
    public void deleteStandItemSpaceMap(Integer id) {
        standItemSpaceMapRepository.deleteStandItemSpaceMap(id);

    }

    @Override
    public List<StandItem> getStandItemDict() {
        List<StandItem> records = repository.getList();

        //标准项目字典人员对照
        List<StandItemEmpMap> empMapList = standItemEmpMapRepository.getList();
        Map<String, List<StandItemEmpMap>>  empMapGroup = new HashMap<>();
        if(!CollectionUtils.isEmpty(empMapList)){
            List<EmpCostType> list = empCostTypeRepository.getList();
            Map<String,String> map = list.stream().collect(Collectors.toMap(EmpCostType::getCostTypeCode, EmpCostType::getCostTypeName, (a, b) -> b));
            empMapList.forEach(standItemEmpMap -> standItemEmpMap.setEmpTypeCodeName(map.get(standItemEmpMap.getEmpTypeCode())));

            empMapGroup = empMapList.stream().collect(Collectors.groupingBy(StandItemEmpMap::getStandItemCode));


        }
        //标准项目字典空间对照
        List<StandItemSpaceMap> spaceMapList = standItemSpaceMapRepository.getList();
        Map<String, List<StandItemSpaceMap>>  spaceMapGroup = new HashMap<>();
        if(!CollectionUtils.isEmpty(spaceMapList)){
            List<Space> list = spaceRepository.getList();
            Map<String,String> map = list.stream().collect(Collectors.toMap(Space::getCode, Space::getName, (a, b) -> b));
            spaceMapList.forEach(spaceMap -> spaceMap.setSpaceCodeName(map.get(spaceMap.getSpaceCode())));

            spaceMapGroup = spaceMapList.stream().collect(Collectors.groupingBy(StandItemSpaceMap::getStandItemCode));
        }
        //标准项目字典设备对照
        List<StandItemEquipmentMap> equipmentMapList = standItemEquipmentMapRepository.getList();
        Map<String, List<StandItemEquipmentMap>>  equipmentMapGroup = new HashMap<>();
        if(!CollectionUtils.isEmpty(equipmentMapList)){
            List<Equipment> list = equipmentRepository.getList();
            Map<String,String> map = list.stream().collect(Collectors.toMap(Equipment::getCode, Equipment::getName, (a, b) -> b));
            equipmentMapList.forEach(equipmentMap -> equipmentMap.setEquipmentCodeName(map.get(equipmentMap.getEquipmentCode())));
            equipmentMapGroup = equipmentMapList.stream().collect(Collectors.groupingBy(StandItemEquipmentMap::getStandItemCode));
        }

        for (StandItem record : records) {
            record.setEmpMaps(empMapGroup.get(record.getCode()));
            record.setEquipmentMaps(equipmentMapGroup.get(record.getCode()));
            record.setSpaceMaps(spaceMapGroup.get(record.getCode()));
        }
        return records;
    }
}
