package pwc.taxtech.atms.service.impl; import org.apache.commons.lang3.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import pwc.taxtech.atms.common.CommonConstants; import pwc.taxtech.atms.common.CommonUtils; import pwc.taxtech.atms.common.SortUtils; import pwc.taxtech.atms.dao.RegionMapper; import pwc.taxtech.atms.dto.RegionShortDto; import pwc.taxtech.atms.dto.VMRegionDevTreeData; import pwc.taxtech.atms.dto.navtree.DevTreeDto; import pwc.taxtech.atms.dto.navtree.IvhTreeDto; import pwc.taxtech.atms.entity.Area; import pwc.taxtech.atms.entity.AreaExample; import pwc.taxtech.atms.entity.AreaRegion; import pwc.taxtech.atms.entity.AreaRegionExample; import pwc.taxtech.atms.entity.Region; import pwc.taxtech.atms.entity.RegionExample; import pwc.taxtech.atms.exception.ApplicationException; import java.util.ArrayList; import java.util.List; import java.util.Objects; import static java.util.Comparator.*; import static java.util.stream.Collectors.toList; import static pwc.taxtech.atms.common.CommonUtils.copyProperties; import static pwc.taxtech.atms.common.CommonUtils.getUUID; @Service public class RegionServiceImpl extends AbstractService { @Autowired private AreaServiceImpl areaService; @Autowired private AreaRegionServiceImpl areaRegionService; @Autowired private RegionMapper regionMapper; /* * (non-Javadoc) * * @see pwc.taxtech.atms.service.RegionService#getRegionAreaTree() */ public List<DevTreeDto<VMRegionDevTreeData>> getRegionAreaTree() { List<DevTreeDto<VMRegionDevTreeData>> regionAreaTree = new ArrayList<>(); List<Area> topAreas = areaService.findTopAreas(); if (null == topAreas || topAreas.isEmpty()) { return regionAreaTree; } for (Area topArea : topAreas) { DevTreeDto<VMRegionDevTreeData> topNode = new DevTreeDto<>(); topNode.setItems(new ArrayList<>()); VMRegionDevTreeData data = new VMRegionDevTreeData(); data.setLevelType(0); data.setMergerName(topArea.getName()); data.setIsArea(true); data.setIsActive(topArea.getIsActive()); topNode.setId(topArea.getId()); topNode.setCode(""); topNode.setExpanded(true); topNode.setParentId(null); topNode.setRelyOnCodes(""); topNode.setText(topArea.getName()); topNode.setData(data); topNode.setUniqueId(CommonUtils.getUUID()); topNode.setItems(getChildrenAreaTree(topNode)); topNode.getItems().addAll(getRegionTree(topArea)); regionAreaTree.add(topNode); } SortUtils.sortDevTreeDtoByText(regionAreaTree); return regionAreaTree; } /** * Recursively get area tree * * @param current * @return List<DevTreeDto> */ private List<DevTreeDto<VMRegionDevTreeData>> getChildrenAreaTree(DevTreeDto<VMRegionDevTreeData> current) { List<DevTreeDto<VMRegionDevTreeData>> childrenAreaTree = new ArrayList<>(); List<Area> subAreas = areaService.getSubAreaListIngoreActive(current.getId()); if (subAreas == null || subAreas.isEmpty()) { return childrenAreaTree; } for (Area subArea : subAreas) { DevTreeDto<VMRegionDevTreeData> node = new DevTreeDto<>(); node.setItems(new ArrayList<>()); VMRegionDevTreeData data = new VMRegionDevTreeData(); data.setLevelType(current.getData().getLevelType() + 1); data.setMergerName(subArea.getName()); data.setIsArea(true); data.setIsActive(subArea.getIsActive()); node.setId(subArea.getId()); node.setCode(""); node.setExpanded(false); node.setParentId(current.getId()); node.setRelyOnCodes(""); node.setText(subArea.getName()); node.setData(data); node.setUniqueId(CommonUtils.getUUID()); node.setItems(getChildrenAreaTree(node)); node.getItems().addAll(getRegionTree(subArea)); childrenAreaTree.add(node); } SortUtils.sortDevTreeDtoByText(childrenAreaTree); return childrenAreaTree; } /** * Get the region tree under an area * * @param area * @return List<DevTreeDto> */ private List<DevTreeDto<VMRegionDevTreeData>> getRegionTree(Area area) { List<DevTreeDto<VMRegionDevTreeData>> regionTree = new ArrayList<>(); List<AreaRegion> subRegions = areaRegionService.findAreaRegionsByArea(area.getId()); if (subRegions == null || subRegions.isEmpty()) { return regionTree; } int currentLevelType = 9; for (int i = 0; i < subRegions.size(); i++) { DevTreeDto<VMRegionDevTreeData> currentNode = new DevTreeDto<>(); currentNode.setItems(new ArrayList<>()); AreaRegion areaRegion = subRegions.get(i); VMRegionDevTreeData data = new VMRegionDevTreeData(); data.setLevelType(areaRegion.getRegion().getLevelType()); data.setMergerName(areaRegion.getRegion().getMergerName()); data.setIsArea(false); data.setAreaId(areaRegion.getArea().getId()); data.setIsActive(areaRegion.getRegion().getIsActive()); currentNode.setId(areaRegion.getRegion().getId()); currentNode.setCode(""); currentNode.setExpanded(false); currentNode.setParentId(areaRegion.getRegion().getParentId()); currentNode.setRelyOnCodes(""); currentNode.setText(areaRegion.getRegion().getName()); currentNode.setData(data); currentNode.setUniqueId(CommonUtils.getUUID()); if (currentLevelType > currentNode.getData().getLevelType()) { regionTree.add(currentNode); } else { if (null == regionTree.get(regionTree.size() - 1).getItems()) { regionTree.get(regionTree.size() - 1).setItems(new ArrayList<DevTreeDto<VMRegionDevTreeData>>()); } currentNode.setUniqueId(null); regionTree.get(regionTree.size() - 1).getItems().add(currentNode); } currentLevelType = currentNode.getData().getLevelType(); } return regionTree; } /* * (non-Javadoc) * * @see pwc.taxtech.atms.service.RegionService#getProvinceAndCityTreeList() */ public List<DevTreeDto<IvhTreeDto<Region>>> getProvinceAndCityTreeList() { // Find all regions with leveltype 1 RegionExample regionExample = new RegionExample(); regionExample.createCriteria().andLevelTypeEqualTo(CommonConstants.REGION_LEVELTYPE_PROVINCE); regionExample.setOrderByClause("id ASC"); List<Region> regionList = regionMapper.selectByExample(regionExample); List<DevTreeDto<IvhTreeDto<Region>>> devTree = new ArrayList<>(); for (Region region : regionList) { DevTreeDto<IvhTreeDto<Region>> regionNode = new DevTreeDto<>(); regionNode.setItems(new ArrayList<>()); regionNode.setId(region.getId()); regionNode.setCode(null); regionNode.setExpanded(false); regionNode.setParentId(null); regionNode.setRelyOnCodes(null); regionNode.setText(region.getName()); regionNode.setUniqueId(null); regionNode.setItems(new ArrayList<DevTreeDto<IvhTreeDto<Region>>>()); IvhTreeDto<Region> regionData = new IvhTreeDto<>(); regionData.setId(region.getId()); regionData.setLabel(region.getName()); regionData.setValue(region); regionData.setChildren(new ArrayList<IvhTreeDto<Region>>()); // Find cities under region RegionExample cityExample = new RegionExample(); cityExample.createCriteria().andLevelTypeEqualTo(CommonConstants.REGION_LEVELTYPE_CITY) .andParentIdEqualTo(region.getId()); regionExample.setOrderByClause("id ASC"); List<Region> cityList = regionMapper.selectByExample(cityExample); for (Region city : cityList) { DevTreeDto<IvhTreeDto<Region>> cityNode = new DevTreeDto<>(); cityNode.setItems(new ArrayList<>()); cityNode.setId(city.getId()); cityNode.setCode(null); cityNode.setExpanded(false); cityNode.setParentId(null); cityNode.setRelyOnCodes(null); cityNode.setText(city.getName()); cityNode.setUniqueId(null); IvhTreeDto<Region> cityData = new IvhTreeDto<>(); cityData.setChildren(new ArrayList<>()); Region cloneCity = new Region(); try { cloneCity = (Region) (city.clone()); } catch (CloneNotSupportedException e) { } cityData.setId(city.getId()); cityData.setLabel(city.getName()); cityData.setValue(cloneCity); cityNode.setData(cityData); IvhTreeDto<Region> childIvhTreeDto = new IvhTreeDto<>(); childIvhTreeDto.setChildren(new ArrayList<>()); childIvhTreeDto.setId(city.getId()); childIvhTreeDto.setLabel(city.getName()); childIvhTreeDto.setValue(city); regionData.getChildren().add(childIvhTreeDto); regionNode.getItems().add(cityNode); } regionNode.setData(regionData); devTree.add(regionNode); } return devTree; } @SuppressWarnings({"rawtypes", "unchecked"}) public List<DevTreeDto> getAreaRegionTreeByNodeId(String areaId) { Area toNode = areaMapper.selectByPrimaryKey(areaId); Region regionInfo = null; if (toNode == null) { // id 为省市 id regionInfo = regionMapper.selectByPrimaryKey(areaId); if (regionInfo == null) { return new ArrayList<>(); } AreaRegionExample areaRegionExample = new AreaRegionExample(); areaRegionExample.createCriteria().andRegionIdEqualTo(regionInfo.getId()); AreaRegion data = areaRegionMapper.selectByExample(areaRegionExample).stream().findFirst().orElse(null); if (data == null) { return new ArrayList<>(); } toNode = new Area(); toNode.setId(regionInfo.getId()); toNode.setName(regionInfo.getName()); toNode.setParentId(data.getAreaId()); } RegionShortDto topNode = new RegionShortDto(); topNode.setId(toNode.getId()); topNode.setIsActive(BooleanUtils.isTrue(toNode.getIsActive())); topNode.setLevelType(0); topNode.setMergerName(toNode.getName()); topNode.setName(toNode.getName()); topNode.setParentId(toNode.getParentId()); topNode.setSubRegionList(new ArrayList<>()); topNode.setIsArea(regionInfo == null); VMRegionDevTreeData regionDevTreeData = new VMRegionDevTreeData(); regionDevTreeData.setMergerName(topNode.getMergerName()); regionDevTreeData.setLevelType(topNode.getLevelType()); regionDevTreeData.setIsArea(topNode.getIsArea()); regionDevTreeData.setAreaId(topNode.getAreaId()); regionDevTreeData.setIsActive(BooleanUtils.isTrue(toNode.getIsActive())); DevTreeDto tree = new DevTreeDto(); tree.setCode(""); tree.setExpanded(true); tree.setItems(new ArrayList<>()); tree.setParentId(""); tree.setRelyOnCodes(""); tree.setText(toNode.getName()); tree.setId(toNode.getId()); tree.setData(regionDevTreeData); if (regionInfo == null) { List<Area> areaList = areaMapper.selectByExample(new AreaExample()); List<AreaRegion> areaRegionList = areaRegionMapper.selectByExample(new AreaRegionExample()); RegionExample regionExample = new RegionExample(); regionExample.createCriteria().andLevelTypeLessThan(3); List<Region> regionList = regionMapper.selectByExample(regionExample); List<RegionShortDto> relationRegionQuery = new ArrayList<>(); for (AreaRegion ar : areaRegionList) { if (ar == null || ar.getRegionId() == null) { continue; } for (Region r : regionList) { if (ar.getRegionId().equals(r.getId())) { RegionShortDto regionShortDto = new RegionShortDto(); regionShortDto.setAreaId(ar.getAreaId()); regionShortDto.setId(r.getId()); regionShortDto.setIsActive(BooleanUtils.isTrue(r.getIsActive())); regionShortDto.setIsArea(false); regionShortDto.setLevelType(r.getLevelType()); regionShortDto.setMergerName(r.getMergerName()); regionShortDto.setName(r.getName()); regionShortDto.setParentId(r.getParentId()); regionShortDto.setSubRegionList(new ArrayList<>()); relationRegionQuery.add(regionShortDto); } } } tree.setItems(getAreaRegionChildrenList(topNode, areaList, relationRegionQuery)); } else { RegionExample regionExample = new RegionExample(); regionExample.createCriteria().andParentIdEqualTo(topNode.getId()); List<Region> sublist = regionMapper.selectByExample(regionExample); List<RegionShortDto> subRegionShortList = sublist.stream().map(sa -> { RegionShortDto regionShortDto = copyProperties(sa, new RegionShortDto()); regionShortDto.setIsActive(BooleanUtils.isTrue(sa.getIsActive())); return regionShortDto; }).collect(toList()); tree.setItems(getNavTreeDtoList(topNode, subRegionShortList)); } List<DevTreeDto> list = new ArrayList<>(); list.add(tree); return list; } /** * 获取当前节点的子节点(必须是自定义的区域或者是城市及以上的区域) */ @SuppressWarnings({"rawtypes", "unchecked"}) private List<DevTreeDto> getAreaRegionChildrenList(RegionShortDto current, List<Area> areaList, List<RegionShortDto> relationRegionQuery) { List<DevTreeDto> subWarpList = new ArrayList<>(); // 获取区域 List<Area> subList = areaList.stream().filter(sa -> Objects.equals(sa.getParentId(), current.getId())) .collect(toList()); if (subList != null && !subList.isEmpty()) { for (Area area : subList) { RegionShortDto model = new RegionShortDto(); model.setId(area.getId()); model.setIsActive(BooleanUtils.isTrue(area.getIsActive())); model.setIsArea(true); model.setLevelType(current.getLevelType() + 1); model.setMergerName(area.getName()); model.setName(area.getName()); model.setParentId(area.getParentId()); model.setSubRegionList(new ArrayList<>()); VMRegionDevTreeData data = copyProperties(model, new VMRegionDevTreeData()); data.setIsActive(BooleanUtils.isTrue(area.getIsActive())); DevTreeDto tree = new DevTreeDto(); tree.setCode(""); tree.setExpanded(false); tree.setItems(new ArrayList<>()); tree.setParentId(area.getParentId()); tree.setRelyOnCodes(""); tree.setText(area.getName()); tree.setId(area.getId()); tree.setData(data); tree.setUniqueId(getUUID()); tree.setItems(getAreaRegionChildrenList(model, areaList, relationRegionQuery)); tree.getItems().sort(comparing(DevTreeDto<VMRegionDevTreeData>::getText, nullsLast(naturalOrder()))); subWarpList.add(tree); } } List<RegionShortDto> regionList = relationRegionQuery.stream() .filter(sa -> Objects.equals(sa.getAreaId(), current.getId())).collect(toList()); if (regionList != null && !regionList.isEmpty()) { Integer minLevel = regionList.stream().map(RegionShortDto::getLevelType).filter(Objects::nonNull) .min(naturalOrder()).orElseThrow(ApplicationException::new); for (RegionShortDto region : regionList) { if (Objects.equals(region.getLevelType(), minLevel)) { VMRegionDevTreeData data = copyProperties(region, new VMRegionDevTreeData()); DevTreeDto navTree = new DevTreeDto(); navTree.setCode(""); navTree.setExpanded(false); navTree.setItems(new ArrayList<>()); navTree.setParentId(region.getParentId()); navTree.setRelyOnCodes(""); navTree.setText(region.getName()); navTree.setId(region.getId()); navTree.setData(data); navTree.setUniqueId(getUUID()); // 省的parentId为区域Id region.setParentId( BooleanUtils.isTrue(current.getIsArea()) ? current.getId() : current.getParentId()); navTree.setItems(getNavTreeDtoList(region, regionList)); navTree.getItems() .sort(comparing(DevTreeDto<VMRegionDevTreeData>::getText, nullsLast(naturalOrder()))); subWarpList.add(navTree); } } } // TODO 按照拼音排序(所有通过getText进行排序) subWarpList.sort(comparing(DevTreeDto<VMRegionDevTreeData>::getText, nullsLast(naturalOrder()))); return subWarpList; } @SuppressWarnings({"rawtypes", "unchecked"}) private List<DevTreeDto> getNavTreeDtoList(RegionShortDto currentNode, List<RegionShortDto> list) { List<RegionShortDto> subList = list.stream().filter(sa -> Objects.equals(sa.getParentId(), currentNode.getId())) .collect(toList()); List<DevTreeDto> retlist = new ArrayList<>(); for (RegionShortDto item : subList) { VMRegionDevTreeData data = copyProperties(item, new VMRegionDevTreeData()); DevTreeDto model = new DevTreeDto(); model.setCode(""); model.setExpanded(false); model.setItems(new ArrayList<>()); model.setParentId(currentNode.getId()); model.setRelyOnCodes(""); model.setText(item.getName()); model.setId(item.getId()); model.setData(data); model.setItems(getNavTreeDtoList(item, list)); retlist.add(model); } return retlist; } }