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 com.kcim.common.constants.NumberConstant; import com.kcim.common.exception.CostException; import com.kcim.common.util.BeanUtil; import com.kcim.common.util.UserContext; import com.kcim.common.util.excel.ExcelStyleUtil; import com.kcim.common.util.excel.entity.SpaceImportEntity; import com.kcim.dao.model.Equipment; import com.kcim.dao.model.Space; import com.kcim.dao.repository.SpaceRepository; import com.kcim.service.SpaceService; import com.kcim.vo.CodeAndNameVO; 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.math.RoundingMode; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; /** * @program: CostAccount * @description: * @author: Wang.YS * @create: 2023-11-07 20:42 **/ @Service("SpaceService") @Slf4j @AllArgsConstructor public class SpaceServiceImpl implements SpaceService { SpaceRepository repository; /** * 获取空间成本列表 * @param name 空间名称 * @param type 是否停用 0启用 1停用 默认 0 * @return 列表 */ @Override public Object getSpaceCostList(String name, Integer type) { List list = repository.getList(name, type); List parentList = repository.getParentList(); if(CollectionUtils.isEmpty(parentList)){ return new ArrayList<>(); } if(CollectionUtils.isEmpty(list)){ return new ArrayList<>(); } Map> filterCollect = list.stream().collect(Collectors.groupingBy(Space::getParentCode)); List parentCollect = filterCollect.get(NumberConstant.ZERO_S); filterCollect.remove(NumberConstant.ZERO_S); List removeList = new ArrayList<>(); if(!StringUtils.isEmpty(name)){ parentList.forEach(parent -> { if (!CollectionUtils.isEmpty(filterCollect.get(parent.getCode()))) { parent.setChildList(setChildren(filterCollect.get(parent.getCode()),filterCollect)); } else { removeList.add(parent); } }); }else{ for (Space dictKcClass : parentList) { if (!CollectionUtils.isEmpty(filterCollect.get(dictKcClass.getCode()))) { dictKcClass.setChildList(setChildren(filterCollect.get(dictKcClass.getCode()),filterCollect)); } } } if(!CollectionUtils.isEmpty(removeList)){ parentList.removeAll(removeList); } if(!CollectionUtils.isEmpty(parentCollect)){ //检索条件查询的有父类 if(CollectionUtils.isEmpty(parentList)){ //查询条件为空 把父类加回去 parentList.addAll(parentCollect); }else { //查询条件不为空 对比 最上层是否有 costItems 的父类 没有 加回去 有 不添加 Map filterMap = parentCollect.stream().collect(Collectors.toMap(Space::getCode, item -> item, (a, b) -> b)); List filterParent = new ArrayList<>(); for(Space parent:parentList){ Space item = filterMap.get(parent.getCode()); if(Objects.nonNull(item)){ filterParent.add(item); } } //去掉包含的 数据 parentCollect.removeAll(filterParent); //剩下数据加回去 if(!CollectionUtils.isEmpty(parentCollect)){ parentList.addAll(parentCollect); } } } return parentList; } public List setChildren(List spaces,Map> collect){ for(Space space:spaces){ if(!CollectionUtils.isEmpty(collect.get(space.getCode()))){ space.setChildList(setChildren(collect.get(space.getCode()),collect)); } } return spaces; } /** * 新增 空间成本 * @param request 入参 */ @Override public void addSpaceCost(Space request) { List spaces = repository.getByCode(request.getCode()); if(!CollectionUtils.isEmpty(spaces)){ throw new CostException("当前空间成本代码【"+request.getCode()+"】已存在,请修改后再保存"); } request.setHospId(UserContext.getHospId()); request.setCreateTime(new Date()); request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId())); if(request.getCode() != null&& request.getDepreciationYear() != null && request.getDepreciationYear().compareTo(BigDecimal.ZERO) != 0) { //计算每年折旧 每年折旧=建置成本/折旧年限 request.setCostPerYear(calculateCostPerYear(request.getCost(),request.getDepreciationYear())); //每分钟成本=每年折旧/(365*24*60) request.setCostPerMinute(calculateCostPerMinute(request.getCostPerYear())); } if(request.getStatus() != null &&request.getStatus().equals(NumberConstant.ONE)){ Date stopTime = request.getStopTime(); if(stopTime == null){ throw new CostException("当前空间成本停用标志为停用,停用时间必填"); } }else { request.setStatus(NumberConstant.ZERO); } if(StringUtils.isEmpty(request.getParentCode())){ request.setParentCode(NumberConstant.ZERO_S); } if(request.getType().equals(NumberConstant.ONE)){ if(StringUtils.isEmpty(request.getParentCode())){ throw new CostException("当前分类为子类,父类代码必填"); } } repository.save(request); } /** * 编辑空间成本 * @param request 入参 */ @Override public void editSpaceCost(Space request) { Integer id = request.getId(); if(id ==null){ throw new CostException("编辑空间成本时,主键必填"); } Space space = repository.getById(id); Space spaceOne = repository.getOneByCode(request.getCode()); if(Objects.nonNull(space)){ if(Objects.isNull(spaceOne)||spaceOne.getId().equals(id)){ BeanUtil.convertObj(request,space); space.setUpdateTime(new Date()); space.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId())); if(space.getCode() != null&& space.getDepreciationYear() != null && space.getDepreciationYear().compareTo(BigDecimal.ZERO) != 0) { //计算每年折旧 每年折旧=建置成本/折旧年限 space.setCostPerYear(calculateCostPerYear(space.getCost(),space.getDepreciationYear())); //每分钟成本=每年折旧/(365*24*60) space.setCostPerMinute(calculateCostPerMinute(space.getCostPerYear())); } if(space.getStatus() != null &&space.getStatus().equals(NumberConstant.ONE)){ Date stopTime = request.getStopTime(); if(stopTime == null){ throw new CostException("当前空间成本停用标志为停用,停用时间必填"); } }else { space.setStopTime(null); } if(request.getType().equals(NumberConstant.ONE)){ if(StringUtils.isEmpty(request.getParentCode())){ throw new CostException("当前分类为子类,父类代码必填"); } } repository.updateById(space); }else { throw new CostException("当前空间成本代码【"+request.getCode()+"】已存在,请修改后再保存"); } } } /** * 删除空间成本 * @param id 主键 */ @Override public void deleteSpaceCost(Integer id) { repository.deleteSpaceCost(id); } /** * 导出空间成本模版 * @param response 出参 * @return 出参 */ @SneakyThrows @Override public Object exportSpaceCost(HttpServletResponse response) { try { //配置excel 文件信息 ExportParams params = new ExportParams(); params.setTitle("说明:1、为了保证成功导入,请勿修改模板格式\n" + " 2、没有父级时,父级空间编码填0\n" + " 3、停用字段为下拉选择字段,不可填写选项外的内容\n" + " 4、停用字段为是时,必须填写对应的停用时间,格式:yyyy-MM-dd HH:mm:ss"); //设置导出样式 params.setStyle(ExcelStyleUtil.class); //设置sheetName params.setTitleHeight((short) 20); params.setSheetName("空间成本项目"); // FileOutputStream outputStream = new FileOutputStream("E:\\空间成本项目导入模版.xlsx"); Workbook workbook = ExcelExportUtil.exportExcel(params, SpaceImportEntity.class,new ArrayList<>()); 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 文件 */ @Override public void importSpaceCost(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 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); List spaceImportEntities = ExcelImportUtil.importExcel(stream, SpaceImportEntity.class,params); if(!CollectionUtils.isEmpty(spaceImportEntities)){ List saveList = new ArrayList<>(); Space spaceCost =new Space(); spaceCost.setHospId(UserContext.getHospId()); spaceCost.setCreateTime(new Date()); spaceCost.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId())); for (SpaceImportEntity entity : spaceImportEntities) { Space space = BeanUtil.convertObj(spaceCost, Space.class); space.setCode(entity.getCode()); space.setName(entity.getName()); Integer status = entity.getStatus(); if(status == null){ space.setStatus(NumberConstant.ZERO); }else { space.setStatus(entity.getStatus()); } space.setStopTime(entity.getStopTime()); space.setCost(entity.getCost()); space.setParentCode(entity.getParentCode()); space.setType(Integer.valueOf(entity.getType())); space.setVolume(entity.getVolume()); space.setDepreciationYear(entity.getDepreciationYear()); if(space.getCost() != null&& space.getDepreciationYear() != null && space.getDepreciationYear().compareTo(BigDecimal.ZERO) != 0){ //计算每年折旧 每年折旧=采购价格/折旧年限 space.setCostPerYear(calculateCostPerYear(space.getCost(),space.getDepreciationYear())); //每分钟成本=每年折旧/(365*24*60) space.setCostPerMinute(calculateCostPerMinute(space.getCostPerYear())); }else { space.setCostPerYear(BigDecimal.ZERO); space.setCostPerMinute(BigDecimal.ZERO); } saveList.add(space); } if(!CollectionUtils.isEmpty(saveList)){ check(); repository.saveBatch(saveList,50); } } } catch (Exception e) { throw new CostException(e.getMessage()); } } @Override public List getItemDict() { List list = repository.getList(); if(!CollectionUtils.isEmpty(list)){ List returnList = new ArrayList<>(); for (Space type : list) { CodeAndNameVO vo = new CodeAndNameVO(); vo.setCode(type.getCode()); vo.setName(type.getName()); returnList.add(vo); } //添加全部 CodeAndNameVO vo = new CodeAndNameVO(); vo.setCode(NumberConstant.ZERO_S); vo.setName("全部"); returnList.add(vo); return returnList; } return new ArrayList<>(); } private void check() { List list = repository.getList(); if(!CollectionUtils.isEmpty(list)){ repository.removeList(list); } } private BigDecimal calculateCostPerYear(BigDecimal price, BigDecimal depreciationYear){ return price.divide(depreciationYear, 4, RoundingMode.HALF_UP); } private BigDecimal calculateCostPerMinute(BigDecimal costYear){ int minute = 365 * 24 * 60; return costYear.divide(BigDecimal.valueOf(minute), 4, RoundingMode.HALF_UP); } }