package com.izouma.nineth.service; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.excel.util.CollectionUtils; import com.izouma.nineth.config.Constants; import com.izouma.nineth.domain.Asset; import com.izouma.nineth.domain.MetaItem; import com.izouma.nineth.domain.SpaceObjectsInfo; import com.izouma.nineth.dto.BuildingDTO; import com.izouma.nineth.dto.BuildingPosDTO; import com.izouma.nineth.dto.MetaRestResult; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.AssetRepo; import com.izouma.nineth.repo.MetaItemRepo; import com.izouma.nineth.repo.SpaceObjectsInfoRepo; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @Service @AllArgsConstructor public class MetaPlayerInfoService { private SpaceObjectsInfoRepo spaceObjectsInfoRepo; private AssetRepo assetRepo; private MetaItemRepo metaItemRepo; @Transactional public MetaRestResult metaSpaceInfo(Long userId, Long spaceId) { merge(userId); SpaceObjectsInfo spaceObjectsInfo = spaceObjectsInfoRepo.findBySpaceIdAndDel(spaceId, false); if (Objects.isNull(spaceObjectsInfo)) { return MetaRestResult.returnError(String.format("不存在空间id:%S的空间信息", spaceId)); } spaceObjectsInfo.setPersonal(spaceObjectsInfo.getUserId().equals(userId)); // 如果是查询个人空间物品信息,统计用户剩余物品信息 if (spaceObjectsInfo.isPersonal()) { List spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDel(userId, false); spaceObjectsInfo.setBuildingList(buildingList(userId, spaceObjectsInfos)); } return MetaRestResult.returnSuccess(spaceObjectsInfo); } @Transactional public MetaRestResult personalMetaSpaceInfo(Long userId) { merge(userId); SpaceObjectsInfo spaceObjectsInfo = new SpaceObjectsInfo(); List spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDel(userId, false); spaceObjectsInfo.setBuildingList(buildingList(userId, spaceObjectsInfos)); return MetaRestResult.returnSuccess(spaceObjectsInfo); } @Transactional public MetaRestResult updateMetaPersonalSpace(SpaceObjectsInfo spaceObjectsInfo) { if (Objects.isNull(spaceObjectsInfo.getId())) { return MetaRestResult.returnError("参数不合法,缺少空间物品信息记录id"); } SpaceObjectsInfo dbSpaceObjectsInfo = spaceObjectsInfoRepo.findById(spaceObjectsInfo.getId()).orElse(null); if (Objects.isNull(dbSpaceObjectsInfo)) { return MetaRestResult.returnError(String.format("操作失败:不存在id[%S]的空间物品数据", spaceObjectsInfo.getSpaceId())); } merge(dbSpaceObjectsInfo.getUserId()); List buildingPosList = spaceObjectsInfo.getBuildingPosList(); if (CollectionUtil.isEmpty(buildingPosList)) { dbSpaceObjectsInfo.setBuildingPosList(null); return MetaRestResult.returnSuccess(spaceObjectsInfoRepo.save(dbSpaceObjectsInfo)); } Map map = new HashMap<>(); // 统计要修改的个人空间各物品数据 buildingPosList.forEach(buildingPosDTO -> { Long key = buildingPosDTO.getItemId(); if (map.containsKey(key)) { map.put(key, map.get(key) + 1); } else { map.put(key, 1); } }); List spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDelAndIdNot(dbSpaceObjectsInfo.getUserId(), false, dbSpaceObjectsInfo.getId()); List buildingDTOS = buildingList(dbSpaceObjectsInfo.getUserId(), spaceObjectsInfos); // 查询用户所有已经编辑过的物品id Set keys = map.keySet(); // 比较个人空间拥有的各物品最大数量 try { keys.forEach(key -> { buildingDTOS.forEach(buildingDTO -> { if (key.equals(buildingDTO.getItemId())) { if (map.get(key) > buildingDTO.getCount()) { throw new BusinessException("操作失败:当前用户修改该物品数量大于用户持有最大数量"); } } }); }); } catch (Exception e) { return MetaRestResult.returnError(e.getMessage()); } dbSpaceObjectsInfo.setBuildingPosList(spaceObjectsInfo.getBuildingPosList()); return MetaRestResult.returnSuccess("修改成功", spaceObjectsInfoRepo.save(dbSpaceObjectsInfo)); } private List buildingList(Long userId, List spaceObjectsInfos) { List buildingList = countAll(userId); // 如果该该用户没有空间信息直接返回 buildingList if (CollectionUtil.isEmpty(spaceObjectsInfos) || CollectionUtil.isEmpty(buildingList)) { return buildingList; } HashMap map = countEdit(spaceObjectsInfos); // 如过buildingList不为为空,且用户没有编辑过物品,返回buildingList if (CollectionUtil.isEmpty(map)) { return buildingList; } // 查询用户所有已经编辑过的物品id Set keys = map.keySet(); // 查询剩余未编辑物品信息 buildingList.forEach(buildingDTO -> { keys.forEach(key -> { if (buildingDTO.getItemId().equals(key)) { buildingDTO.setCount(buildingDTO.getCount() - map.get(key)); } }); }); // 返回用户剩余物品信息 return buildingList; } @Transactional public void merge(Long userId) { List spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDel(userId, false); // 统计该用户藏品室内所有物品信息 List buildingList = countAll(userId); // 用户空间没有物品编辑信息 直接退出 if (CollectionUtils.isEmpty(spaceObjectsInfos)) { return; } // 所有物品信息为空 删除已经编辑的物品信息 if (CollectionUtil.isEmpty(buildingList)) { spaceObjectsInfoRepo.updateByUserId(userId); return; } // 统计该用户已经编辑过的物品信息 HashMap map = countEdit(spaceObjectsInfos); Set keys = map.keySet(); // 查询用户拥有的所有的物品id List all = buildingList.stream().map(BuildingDTO::getItemId).collect(Collectors.toList()); spaceObjectsInfos.forEach(spaceObjectsInfo -> { List newBuildingPosList = new ArrayList<>(); List buildingPosList = spaceObjectsInfo.getBuildingPosList(); if (CollectionUtil.isNotEmpty(buildingPosList)) { buildingPosList.forEach(buildingPosDTO -> { if (all.contains(buildingPosDTO.getItemId())) { newBuildingPosList.add(buildingPosDTO); } }); } spaceObjectsInfo.setBuildingPosList(newBuildingPosList); }); // 查询剩余未编辑物品信息 buildingList.forEach(buildingDTO -> { keys.forEach(key -> { if (buildingDTO.getItemId().equals(key)) { AtomicInteger newCount = new AtomicInteger(buildingDTO.getCount() - map.get(key)); // 如果用户剩余物品数量为负数,返回失败 if (newCount.get() < 0) { spaceObjectsInfos.forEach(spaceObjectsInfo -> { if (newCount.get() < 0) { List newBuildingPosList = new ArrayList<>(spaceObjectsInfo.getBuildingPosList()); List buildingPosList = spaceObjectsInfo.getBuildingPosList(); if (CollectionUtil.isNotEmpty(buildingPosList)) { buildingPosList.forEach(buildingPosDTO -> { if (newCount.get() < 0) { if (key.equals(buildingDTO.getItemId())) { newBuildingPosList.remove(buildingPosDTO); newCount.set(newCount.get() + 1); } } }); } spaceObjectsInfo.setBuildingPosList(newBuildingPosList); } }); } } }); }); spaceObjectsInfoRepo.saveAll(spaceObjectsInfos); } /** * 统计该用户已经编辑过的物品信息 * * @param spaceObjectsInfos 空间物品信息 * @return 统计后已经编辑过的物品信息 */ private HashMap countEdit(List spaceObjectsInfos) { HashMap map = new HashMap<>(); spaceObjectsInfos.forEach(spaceObjectsInfo -> { if (CollectionUtil.isNotEmpty(spaceObjectsInfo.getBuildingPosList())) { spaceObjectsInfo.getBuildingPosList().forEach(buildingPosDTO -> { Long key = buildingPosDTO.getItemId(); if (map.containsKey(key)) { map.put(key, map.get(key) + 1); } else { map.put(key, 1); } }); } }); return map; } /** * 统计该用户所有物品信息 * * @param userId 用户id * @return 所有物品信息 */ private List countAll(Long userId) { List buildingList = new ArrayList<>(); List metaItems = metaItemRepo.findAllByDel(false); metaItems.forEach(metaItem -> { List assets = assetRepo.findAllByUserIdAndStatusInAndNameLike(userId, Constants.META_NORMAL_STATUS, "%" + metaItem.getName() + "%"); if (CollectionUtil.isNotEmpty(assets)) { buildingList.add(new BuildingDTO(metaItem.getId(), metaItem.getName(), assets.size())); } }); return buildingList; } }