MetaPlayerInfoService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package com.izouma.nineth.service;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import com.alibaba.excel.util.CollectionUtils;
  4. import com.izouma.nineth.config.Constants;
  5. import com.izouma.nineth.domain.Asset;
  6. import com.izouma.nineth.domain.MetaItem;
  7. import com.izouma.nineth.domain.SpaceObjectsInfo;
  8. import com.izouma.nineth.dto.BuildingDTO;
  9. import com.izouma.nineth.dto.BuildingPosDTO;
  10. import com.izouma.nineth.dto.MetaRestResult;
  11. import com.izouma.nineth.exception.BusinessException;
  12. import com.izouma.nineth.repo.AssetRepo;
  13. import com.izouma.nineth.repo.MetaItemRepo;
  14. import com.izouma.nineth.repo.SpaceObjectsInfoRepo;
  15. import lombok.AllArgsConstructor;
  16. import org.springframework.stereotype.Service;
  17. import javax.transaction.Transactional;
  18. import java.util.*;
  19. import java.util.concurrent.atomic.AtomicInteger;
  20. import java.util.stream.Collectors;
  21. @Service
  22. @AllArgsConstructor
  23. public class MetaPlayerInfoService {
  24. private SpaceObjectsInfoRepo spaceObjectsInfoRepo;
  25. private AssetRepo assetRepo;
  26. private MetaItemRepo metaItemRepo;
  27. @Transactional
  28. public MetaRestResult<SpaceObjectsInfo> metaSpaceInfo(Long userId, Long spaceId) {
  29. merge(userId);
  30. SpaceObjectsInfo spaceObjectsInfo = spaceObjectsInfoRepo.findBySpaceIdAndDel(spaceId, false);
  31. if (Objects.isNull(spaceObjectsInfo)) {
  32. return MetaRestResult.returnError(String.format("不存在空间id:%S的空间信息", spaceId));
  33. }
  34. spaceObjectsInfo.setPersonal(spaceObjectsInfo.getUserId().equals(userId));
  35. // 如果是查询个人空间物品信息,统计用户剩余物品信息
  36. if (spaceObjectsInfo.isPersonal()) {
  37. List<SpaceObjectsInfo> spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDel(userId, false);
  38. spaceObjectsInfo.setBuildingList(buildingList(userId, spaceObjectsInfos));
  39. }
  40. return MetaRestResult.returnSuccess(spaceObjectsInfo);
  41. }
  42. @Transactional
  43. public MetaRestResult<SpaceObjectsInfo> personalMetaSpaceInfo(Long userId) {
  44. merge(userId);
  45. SpaceObjectsInfo spaceObjectsInfo = new SpaceObjectsInfo();
  46. List<SpaceObjectsInfo> spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDel(userId, false);
  47. spaceObjectsInfo.setBuildingList(buildingList(userId, spaceObjectsInfos));
  48. return MetaRestResult.returnSuccess(spaceObjectsInfo);
  49. }
  50. @Transactional
  51. public MetaRestResult<SpaceObjectsInfo> updateMetaPersonalSpace(SpaceObjectsInfo spaceObjectsInfo) {
  52. if (Objects.isNull(spaceObjectsInfo.getId())) {
  53. return MetaRestResult.returnError("参数不合法,缺少空间物品信息记录id");
  54. }
  55. SpaceObjectsInfo dbSpaceObjectsInfo = spaceObjectsInfoRepo.findById(spaceObjectsInfo.getId()).orElse(null);
  56. if (Objects.isNull(dbSpaceObjectsInfo)) {
  57. return MetaRestResult.returnError(String.format("操作失败:不存在id[%S]的空间物品数据", spaceObjectsInfo.getSpaceId()));
  58. }
  59. merge(dbSpaceObjectsInfo.getUserId());
  60. List<BuildingPosDTO> buildingPosList = spaceObjectsInfo.getBuildingPosList();
  61. if (CollectionUtil.isEmpty(buildingPosList)) {
  62. dbSpaceObjectsInfo.setBuildingPosList(null);
  63. return MetaRestResult.returnSuccess(spaceObjectsInfoRepo.save(dbSpaceObjectsInfo));
  64. }
  65. Map<Long, Integer> map = new HashMap<>();
  66. // 统计要修改的个人空间各物品数据
  67. buildingPosList.forEach(buildingPosDTO -> {
  68. Long key = buildingPosDTO.getItemId();
  69. if (map.containsKey(key)) {
  70. map.put(key, map.get(key) + 1);
  71. } else {
  72. map.put(key, 1);
  73. }
  74. });
  75. List<SpaceObjectsInfo> spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDelAndIdNot(dbSpaceObjectsInfo.getUserId(), false, dbSpaceObjectsInfo.getId());
  76. List<BuildingDTO> buildingDTOS = buildingList(dbSpaceObjectsInfo.getUserId(), spaceObjectsInfos);
  77. // 查询用户所有已经编辑过的物品id
  78. Set<Long> keys = map.keySet();
  79. // 比较个人空间拥有的各物品最大数量
  80. try {
  81. keys.forEach(key -> {
  82. buildingDTOS.forEach(buildingDTO -> {
  83. if (key.equals(buildingDTO.getItemId())) {
  84. if (map.get(key) > buildingDTO.getCount()) {
  85. throw new BusinessException("操作失败:当前用户修改该物品数量大于用户持有最大数量");
  86. }
  87. }
  88. });
  89. });
  90. } catch (Exception e) {
  91. return MetaRestResult.returnError(e.getMessage());
  92. }
  93. dbSpaceObjectsInfo.setBuildingPosList(spaceObjectsInfo.getBuildingPosList());
  94. return MetaRestResult.returnSuccess("修改成功", spaceObjectsInfoRepo.save(dbSpaceObjectsInfo));
  95. }
  96. private List<BuildingDTO> buildingList(Long userId, List<SpaceObjectsInfo> spaceObjectsInfos) {
  97. List<BuildingDTO> buildingList = countAll(userId);
  98. // 如果该该用户没有空间信息直接返回 buildingList
  99. if (CollectionUtil.isEmpty(spaceObjectsInfos) || CollectionUtil.isEmpty(buildingList)) {
  100. return buildingList;
  101. }
  102. HashMap<Long, Integer> map = countEdit(spaceObjectsInfos);
  103. // 如过buildingList不为为空,且用户没有编辑过物品,返回buildingList
  104. if (CollectionUtil.isEmpty(map)) {
  105. return buildingList;
  106. }
  107. // 查询用户所有已经编辑过的物品id
  108. Set<Long> keys = map.keySet();
  109. // 查询剩余未编辑物品信息
  110. buildingList.forEach(buildingDTO -> {
  111. keys.forEach(key -> {
  112. if (buildingDTO.getItemId().equals(key)) {
  113. buildingDTO.setCount(buildingDTO.getCount() - map.get(key));
  114. }
  115. });
  116. });
  117. // 返回用户剩余物品信息
  118. return buildingList;
  119. }
  120. @Transactional
  121. public void merge(Long userId) {
  122. List<SpaceObjectsInfo> spaceObjectsInfos = spaceObjectsInfoRepo.findAllByUserIdAndDel(userId, false);
  123. // 统计该用户藏品室内所有物品信息
  124. List<BuildingDTO> buildingList = countAll(userId);
  125. // 用户空间没有物品编辑信息 直接退出
  126. if (CollectionUtils.isEmpty(spaceObjectsInfos)) {
  127. return;
  128. }
  129. // 所有物品信息为空 删除已经编辑的物品信息
  130. if (CollectionUtil.isEmpty(buildingList)) {
  131. spaceObjectsInfoRepo.updateByUserId(userId);
  132. return;
  133. }
  134. // 统计该用户已经编辑过的物品信息
  135. HashMap<Long, Integer> map = countEdit(spaceObjectsInfos);
  136. Set<Long> keys = map.keySet();
  137. // 查询用户拥有的所有的物品id
  138. List<Long> all = buildingList.stream().map(BuildingDTO::getItemId).collect(Collectors.toList());
  139. spaceObjectsInfos.forEach(spaceObjectsInfo -> {
  140. List<BuildingPosDTO> newBuildingPosList = new ArrayList<>();
  141. List<BuildingPosDTO> buildingPosList = spaceObjectsInfo.getBuildingPosList();
  142. if (CollectionUtil.isNotEmpty(buildingPosList)) {
  143. buildingPosList.forEach(buildingPosDTO -> {
  144. if (all.contains(buildingPosDTO.getItemId())) {
  145. newBuildingPosList.add(buildingPosDTO);
  146. }
  147. });
  148. }
  149. spaceObjectsInfo.setBuildingPosList(newBuildingPosList);
  150. });
  151. // 查询剩余未编辑物品信息
  152. buildingList.forEach(buildingDTO -> {
  153. keys.forEach(key -> {
  154. if (buildingDTO.getItemId().equals(key)) {
  155. AtomicInteger newCount = new AtomicInteger(buildingDTO.getCount() - map.get(key));
  156. // 如果用户剩余物品数量为负数,返回失败
  157. if (newCount.get() < 0) {
  158. spaceObjectsInfos.forEach(spaceObjectsInfo -> {
  159. if (newCount.get() < 0) {
  160. List<BuildingPosDTO> newBuildingPosList = new ArrayList<>(spaceObjectsInfo.getBuildingPosList());
  161. List<BuildingPosDTO> buildingPosList = spaceObjectsInfo.getBuildingPosList();
  162. if (CollectionUtil.isNotEmpty(buildingPosList)) {
  163. buildingPosList.forEach(buildingPosDTO -> {
  164. if (newCount.get() < 0) {
  165. if (key.equals(buildingDTO.getItemId())) {
  166. newBuildingPosList.remove(buildingPosDTO);
  167. newCount.set(newCount.get() + 1);
  168. }
  169. }
  170. });
  171. }
  172. spaceObjectsInfo.setBuildingPosList(newBuildingPosList);
  173. }
  174. });
  175. }
  176. }
  177. });
  178. });
  179. spaceObjectsInfoRepo.saveAll(spaceObjectsInfos);
  180. }
  181. /**
  182. * 统计该用户已经编辑过的物品信息
  183. *
  184. * @param spaceObjectsInfos 空间物品信息
  185. * @return 统计后已经编辑过的物品信息
  186. */
  187. private HashMap<Long, Integer> countEdit(List<SpaceObjectsInfo> spaceObjectsInfos) {
  188. HashMap<Long, Integer> map = new HashMap<>();
  189. spaceObjectsInfos.forEach(spaceObjectsInfo -> {
  190. if (CollectionUtil.isNotEmpty(spaceObjectsInfo.getBuildingPosList())) {
  191. spaceObjectsInfo.getBuildingPosList().forEach(buildingPosDTO -> {
  192. Long key = buildingPosDTO.getItemId();
  193. if (map.containsKey(key)) {
  194. map.put(key, map.get(key) + 1);
  195. } else {
  196. map.put(key, 1);
  197. }
  198. });
  199. }
  200. });
  201. return map;
  202. }
  203. /**
  204. * 统计该用户所有物品信息
  205. *
  206. * @param userId 用户id
  207. * @return 所有物品信息
  208. */
  209. private List<BuildingDTO> countAll(Long userId) {
  210. List<BuildingDTO> buildingList = new ArrayList<>();
  211. List<MetaItem> metaItems = metaItemRepo.findAllByDel(false);
  212. metaItems.forEach(metaItem -> {
  213. List<Asset> assets = assetRepo.findAllByUserIdAndStatusInAndNameLike(userId, Constants.META_NORMAL_STATUS, "%" + metaItem.getName() + "%");
  214. if (CollectionUtil.isNotEmpty(assets)) {
  215. buildingList.add(new BuildingDTO(metaItem.getId(), metaItem.getName(), assets.size()));
  216. }
  217. });
  218. return buildingList;
  219. }
  220. }