RoomService.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. package com.izouma.yags.service;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.izouma.yags.config.Constants;
  5. import com.izouma.yags.domain.*;
  6. import com.izouma.yags.dto.PageQuery;
  7. import com.izouma.yags.dto.RecognitionResult;
  8. import com.izouma.yags.dto.RoomDetail;
  9. import com.izouma.yags.enums.JoinRoomStatus;
  10. import com.izouma.yags.enums.RoomStatus;
  11. import com.izouma.yags.enums.RoomType;
  12. import com.izouma.yags.exception.BusinessException;
  13. import com.izouma.yags.repo.*;
  14. import com.izouma.yags.utils.JpaUtils;
  15. import com.izouma.yags.utils.RecognizeUtil;
  16. import lombok.AllArgsConstructor;
  17. import org.apache.commons.collections.CollectionUtils;
  18. import org.apache.commons.lang3.StringUtils;
  19. import org.springframework.beans.BeanUtils;
  20. import org.springframework.data.domain.Page;
  21. import org.springframework.data.domain.PageImpl;
  22. import org.springframework.data.domain.Pageable;
  23. import org.springframework.data.jpa.domain.Specification;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.web.multipart.MultipartFile;
  26. import javax.imageio.ImageIO;
  27. import javax.persistence.criteria.Predicate;
  28. import java.io.ByteArrayOutputStream;
  29. import java.io.IOException;
  30. import java.math.BigDecimal;
  31. import java.net.URL;
  32. import java.time.LocalDateTime;
  33. import java.util.*;
  34. import java.util.regex.Pattern;
  35. import java.util.stream.Collectors;
  36. @Service
  37. @AllArgsConstructor
  38. public class RoomService {
  39. private RoomRepo roomRepo;
  40. private GameRepo gameRepo;
  41. private GameModeRepo gameModeRepo;
  42. private GameMapRepo gameMapRepo;
  43. private UserTicketRepo userTicketRepo;
  44. private JoinRoomRepo joinRoomRepo;
  45. private UserRepo userRepo;
  46. private UserBalanceService userBalanceService;
  47. private BindGameRepo bindGameRepo;
  48. private TicketConfigRepo ticketConfigRepo;
  49. public Page<Room> all(PageQuery pageQuery) {
  50. return roomRepo.findAll(JpaUtils.toSpecification(pageQuery, Room.class), JpaUtils.toPageRequest(pageQuery));
  51. }
  52. public Room createRoom(Long userId, Long gameId, Long modeId, Long mapId, Long ticketId, String url, String password, String zone) {
  53. if (StringUtils.isBlank(password)) {
  54. password = null;
  55. }
  56. UserTicket ticket = userTicketRepo.findById(ticketId).orElseThrow(new BusinessException("通行证无记录"));
  57. if (ticket.getExpireAt().isBefore(LocalDateTime.now())) {
  58. throw new BusinessException("通行证已过期");
  59. }
  60. if (ticket.isUsed()) {
  61. throw new BusinessException("通行证已使用");
  62. }
  63. TicketConfig ticketConfig = ticketConfigRepo.findByType(ticket.getType()).orElseThrow(new BusinessException("无记录"));
  64. Game game = gameRepo.findById(gameId).orElseThrow(new BusinessException("游戏无记录"));
  65. GameMode mode = gameModeRepo.findById(modeId).orElseThrow(new BusinessException("模式无记录"));
  66. GameMap map = gameMapRepo.findById(mapId).orElseThrow(new BusinessException("地图无记录"));
  67. BindGame bindGame = bindGameRepo.findByUserIdAndGameIdAndZoneAndActive(userId, gameId, zone, true)
  68. .orElseThrow(new BusinessException("请先绑定游戏"));
  69. Room room = Room.builder()
  70. .name(mode.getName() + " " + map.getName())
  71. .status(RoomStatus.WAITING)
  72. .userId(userId)
  73. .gameId(gameId)
  74. .gameModeId(modeId)
  75. .gameMapId(mapId)
  76. .type(RoomType.USER)
  77. .requireTicket(ticket.getType())
  78. .minPlayerNum(Optional.ofNullable(map.getMinPlayerNum()).orElse(mode.getMinPlayerNum()))
  79. .maxPlayerNum(Optional.ofNullable(map.getMaxPlayerNum()).orElse(mode.getMaxPlayerNum()))
  80. .bonus(ticketConfig.getBonus())
  81. .url(url)
  82. .password(password)
  83. .zone(zone)
  84. .needAudit(mode.isNeedAudit())
  85. .build();
  86. room = roomRepo.save(room);
  87. JoinRoom joinRoom = joinRoomRepo.save(JoinRoom.builder()
  88. .userId(userId)
  89. .roomId(room.getId())
  90. .gameId(gameId)
  91. .modeId(modeId)
  92. .mapId(mapId)
  93. .ticketId(ticketId)
  94. .host(true)
  95. .joinAt(LocalDateTime.now())
  96. .status(JoinRoomStatus.WAITING)
  97. .team("host")
  98. // .gameNickname(Optional.ofNullable(bindGame).map(BindGame::getNickname).orElse(null))
  99. .build());
  100. ticket.setUsed(true);
  101. ticket.setUsedAt(LocalDateTime.now());
  102. ticket.setRoomId(room.getId());
  103. userTicketRepo.save(ticket);
  104. return room;
  105. }
  106. public void changeUrl(Long userId, Long roomId, String url) {
  107. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  108. if (!room.getUserId().equals(userId)) {
  109. throw new BusinessException("无权限");
  110. }
  111. room.setUrl(url);
  112. roomRepo.save(room);
  113. }
  114. public JoinRoom joinRoom(Long userId, Long roomId, Long ticketId, String password) {
  115. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  116. UserTicket ticket = userTicketRepo.findById(ticketId).orElseThrow(new BusinessException("通行证无记录"));
  117. if (room.getStatus() != RoomStatus.WAITING) {
  118. throw new BusinessException("报名已结束");
  119. }
  120. if (StringUtils.isNotBlank(room.getPassword()) && !room.getPassword().equals(password)) {
  121. throw new BusinessException("密码错误");
  122. }
  123. if (!ticket.getUserId().equals(userId)) {
  124. throw new BusinessException("通行证无效");
  125. }
  126. if (ticket.getExpireAt().isBefore(LocalDateTime.now())) {
  127. throw new BusinessException("通行证已过期");
  128. }
  129. if (ticket.isUsed()) {
  130. throw new BusinessException("通行证已使用");
  131. }
  132. if (room.getRequireTicket() != ticket.getType()) {
  133. throw new BusinessException("通行证类型不符");
  134. }
  135. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatus(roomId, JoinRoomStatus.WAITING);
  136. if (joinRoomList.size() >= room.getMaxPlayerNum()) {
  137. throw new BusinessException("人数已满");
  138. }
  139. if (joinRoomList.stream().anyMatch(j -> j.getUserId().equals(userId))) {
  140. throw new BusinessException("请勿重加入");
  141. }
  142. Map<String, Long> teamCounting = joinRoomList.stream()
  143. .collect(Collectors.groupingBy(JoinRoom::getTeam, Collectors.counting()));
  144. teamCounting.putIfAbsent("guest", 0L);
  145. String team = teamCounting.entrySet().stream().min(Comparator.comparingLong(Map.Entry::getValue))
  146. .map(Map.Entry::getKey).orElse("host");
  147. JoinRoom joinRoom = joinRoomRepo.save(JoinRoom.builder()
  148. .userId(userId)
  149. .roomId(roomId)
  150. .gameId(room.getGameId())
  151. .modeId(room.getGameModeId())
  152. .mapId(room.getGameMapId())
  153. .ticketId(ticketId)
  154. .host(false)
  155. .joinAt(LocalDateTime.now())
  156. .status(JoinRoomStatus.WAITING)
  157. .team(team)
  158. .build());
  159. ticket.setUsed(true);
  160. ticket.setUsedAt(LocalDateTime.now());
  161. ticket.setRoomId(roomId);
  162. userTicketRepo.save(ticket);
  163. return joinRoom;
  164. }
  165. public void startGame(Long userId, Long roomId) {
  166. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  167. if (!room.getUserId().equals(userId)) {
  168. throw new BusinessException("无权限");
  169. }
  170. if (room.getStatus() != RoomStatus.WAITING) {
  171. throw new BusinessException("游戏已开始");
  172. }
  173. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatus(roomId, JoinRoomStatus.WAITING);
  174. if (room.getMinPlayerNum() > joinRoomList.size()) {
  175. throw new BusinessException("人数不足");
  176. }
  177. Map<String, Long> teamCounting = joinRoomList.stream()
  178. .collect(Collectors.groupingBy(JoinRoom::getTeam, Collectors.counting()));
  179. if (teamCounting.values().stream().distinct().count() != 1) {
  180. throw new BusinessException("团队人数不一致");
  181. }
  182. room.setStatus(RoomStatus.GAMING);
  183. room.setStartAt(LocalDateTime.now());
  184. roomRepo.save(room);
  185. joinRoomList.parallelStream().forEach(j -> {
  186. j.setStatus(JoinRoomStatus.GAMING);
  187. joinRoomRepo.save(j);
  188. });
  189. }
  190. public void quit(Long userId, Long roomId) {
  191. JoinRoom joinRoom = joinRoomRepo.findFirstByRoomIdAndUserId(roomId, userId)
  192. .orElseThrow(new BusinessException("没有报名"));
  193. if (joinRoom.getStatus() != JoinRoomStatus.WAITING) {
  194. throw new BusinessException("当前状态无法退出");
  195. }
  196. joinRoomRepo.delete(joinRoom);
  197. }
  198. public void changeTeam(Long userId, Long roomId, String team) {
  199. JoinRoom joinRoom = joinRoomRepo.findFirstByRoomIdAndUserId(roomId, userId)
  200. .orElseThrow(new BusinessException("没有报名"));
  201. if (joinRoom.getStatus() != JoinRoomStatus.WAITING) {
  202. throw new BusinessException("当前状态无法更改团队");
  203. }
  204. if (joinRoom.getTeam().equals(team)) {
  205. return;
  206. }
  207. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatus(roomId, JoinRoomStatus.WAITING);
  208. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  209. if (room.getMaxPlayerNum() / 2 >= joinRoomList.size()) {
  210. throw new BusinessException("人数已满");
  211. }
  212. joinRoom.setTeam(team);
  213. joinRoomRepo.save(joinRoom);
  214. }
  215. public void cancel(Long userId, Long roomId) {
  216. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  217. if (!room.getUserId().equals(userId)) {
  218. throw new BusinessException("无权限");
  219. }
  220. if (room.getStatus() != RoomStatus.WAITING) {
  221. throw new BusinessException("游戏已开始");
  222. }
  223. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatus(roomId, JoinRoomStatus.WAITING);
  224. joinRoomList.forEach(j -> {
  225. j.setStatus(JoinRoomStatus.CANCELLED);
  226. joinRoomRepo.save(j);
  227. userTicketRepo.findById(j.getTicketId()).ifPresent(t -> {
  228. t.setUsed(false);
  229. t.setUsedAt(null);
  230. t.setRoomId(null);
  231. userTicketRepo.save(t);
  232. });
  233. });
  234. room.setStatus(RoomStatus.CANCELLED);
  235. room.setCancelAt(LocalDateTime.now());
  236. roomRepo.save(room);
  237. }
  238. public void uploadResult(Long userId, Long roomId, String screenShot, MultipartFile file) throws IOException {
  239. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  240. if (LocalDateTime.now().isBefore(room.getStartAt().plusMinutes(10))) {
  241. throw new BusinessException("比赛时间过短:10分钟");
  242. }
  243. if (room.isNeedAudit()) {
  244. if (!(room.getStatus() == RoomStatus.GAMING || room.getStatus() == RoomStatus.AUDIT)) {
  245. throw new BusinessException("当前房间状态无法上传截图");
  246. }
  247. JoinRoom joinRoom = joinRoomRepo.findFirstByRoomIdAndUserId(roomId, userId).orElseThrow(new BusinessException("无记录"));
  248. joinRoom.setScreenShot(screenShot);
  249. joinRoomRepo.save(joinRoom);
  250. room.setStatus(RoomStatus.AUDIT);
  251. roomRepo.save(room);
  252. } else {
  253. GameMode gameMode = gameModeRepo.findById(room.getGameModeId()).orElseThrow(new BusinessException("游戏模式无记录"));
  254. if (room.getStatus() != RoomStatus.GAMING) {
  255. throw new BusinessException("当前房间状态无法上传截图");
  256. }
  257. boolean win = false;
  258. String mode = null;
  259. String format;
  260. if (Pattern.matches(".*\\.(jpg|jpeg)", screenShot.toLowerCase())) {
  261. format = "jpg";
  262. } else if (Pattern.matches(".*\\.png", screenShot.toLowerCase())) {
  263. format = "png";
  264. } else if (Pattern.matches(".*\\.bmp", screenShot.toLowerCase())) {
  265. format = "bmp";
  266. } else {
  267. throw new BusinessException("截图格式不正确");
  268. }
  269. JSONObject res;
  270. try {
  271. ByteArrayOutputStream os = new ByteArrayOutputStream();
  272. ImageIO.write(ImageIO.read(new URL(screenShot)), format, os);
  273. res = RecognizeUtil.recognize1(os.toByteArray());
  274. } catch (Exception e) {
  275. e.printStackTrace();
  276. throw new BusinessException("图片识别失败");
  277. }
  278. JSONArray results = res.getJSONArray("results");
  279. for (int i = 0; i < results.size(); i++) {
  280. JSONObject json = results.getJSONObject(i);
  281. String name = json.getString("label");
  282. double score = json.getDouble("confidence");
  283. if ("胜利".equals(name) && score > 0.8) {
  284. win = true;
  285. }
  286. if (score > 0.8 && ("1v1".equals(name) || "2v2".equals(name) || "3v3".equals(name) || "5v5".equals(name))) {
  287. mode = name;
  288. }
  289. }
  290. if (!win) {
  291. JoinRoom j = joinRoomRepo.findFirstByRoomIdAndUserId(roomId, userId).orElseThrow(new BusinessException("无记录"));
  292. j.setScreenShot(screenShot);
  293. joinRoomRepo.save(j);
  294. return;
  295. // throw new BusinessException("失败方无需上传截图");
  296. }
  297. if (!gameMode.getName().equals(mode)) {
  298. throw new BusinessException("游戏模式不一致");
  299. }
  300. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatus(roomId, JoinRoomStatus.GAMING);
  301. JoinRoom joinRoom = (JoinRoom) CollectionUtils.find(joinRoomList, j -> ((JoinRoom) j).getUserId().equals(userId));
  302. if (joinRoom == null) {
  303. throw new BusinessException("数据错误");
  304. }
  305. joinRoom.setScreenShot(screenShot);
  306. joinRoomList.forEach(j -> {
  307. j.setStatus(j.getTeam().equals(joinRoom.getTeam()) ? JoinRoomStatus.WIN : JoinRoomStatus.LOSE);
  308. j.setFinishAt(LocalDateTime.now());
  309. joinRoomRepo.save(j);
  310. if (j.getTeam().equals(joinRoom.getTeam())) {
  311. userBalanceService.modifyBalance(j.getUserId(), room.getBonus(), Constants.BalanceDesc.BONUS);
  312. }
  313. });
  314. room.setWinTeam(joinRoom.getTeam());
  315. room.setStatus(RoomStatus.FINISH);
  316. room.setFinishAt(LocalDateTime.now());
  317. room.setWinner(joinRoomList.stream().filter(j -> j.getTeam().equals(joinRoom.getTeam()))
  318. .map(JoinRoom::getUserId).collect(Collectors.toList()));
  319. roomRepo.save(room);
  320. }
  321. }
  322. public void uploadResultNew(Long userId, Long roomId, String screenShot) throws Exception {
  323. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  324. if (LocalDateTime.now().isBefore(room.getStartAt().plusMinutes(10))) {
  325. throw new BusinessException("比赛时间过短:10分钟");
  326. }
  327. JoinRoom joinRoom = joinRoomRepo.findFirstByRoomIdAndUserId(roomId, userId).orElseThrow(new BusinessException("无记录"));
  328. if (!(room.getStatus() == RoomStatus.GAMING || room.getStatus() == RoomStatus.AUDIT)) {
  329. throw new BusinessException("当前房间状态无法上传截图");
  330. }
  331. String format;
  332. if (Pattern.matches(".*\\.(jpg|jpeg)", screenShot.toLowerCase())) {
  333. format = "jpg";
  334. } else if (Pattern.matches(".*\\.png", screenShot.toLowerCase())) {
  335. format = "png";
  336. } else if (Pattern.matches(".*\\.bmp", screenShot.toLowerCase())) {
  337. format = "bmp";
  338. } else {
  339. throw new BusinessException("截图格式不正确");
  340. }
  341. ByteArrayOutputStream os = new ByteArrayOutputStream();
  342. ImageIO.write(ImageIO.read(new URL(screenShot)), format, os);
  343. RecognitionResult recognitionResult = RecognizeUtil.recognize2(os.toByteArray());
  344. joinRoom.setScreenShot(screenShot);
  345. joinRoom.setRecognitionResult(recognitionResult);
  346. joinRoomRepo.save(joinRoom);
  347. room.setStatus(RoomStatus.AUDIT);
  348. if (room.getEndAt() == null) {
  349. room.setEndAt(LocalDateTime.now());
  350. }
  351. roomRepo.save(room);
  352. }
  353. public RoomDetail detail(Long id, boolean players) {
  354. Room room = roomRepo.findById(id).orElseThrow(new BusinessException("房间无记录"));
  355. return detail(room, players);
  356. }
  357. public RoomDetail detail(Room room, boolean players) {
  358. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatusNotIn(room.getId(),
  359. Arrays.asList(JoinRoomStatus.KICKED_OUT, JoinRoomStatus.QUIT));
  360. RoomDetail detail = new RoomDetail();
  361. BeanUtils.copyProperties(room, detail);
  362. Arrays.asList(1, 2, 3).parallelStream().forEach(i -> {
  363. switch (i) {
  364. case 1:
  365. detail.setGame(gameRepo.findById(room.getGameId()).orElse(null));
  366. break;
  367. case 2:
  368. detail.setGameMap(gameMapRepo.findById(room.getGameMapId()).orElse(null));
  369. break;
  370. case 3:
  371. detail.setGameMode(gameModeRepo.findById(room.getGameModeId()).orElse(null));
  372. break;
  373. }
  374. });
  375. detail.setHost(userRepo.findById(room.getUserId()).map(user -> {
  376. RoomDetail.Player player = new RoomDetail.Player();
  377. player.setUserId(user.getId());
  378. player.setNickname(user.getNickname());
  379. player.setAvatar(user.getAvatar());
  380. player.setHost(true);
  381. return player;
  382. }).orElse(null));
  383. if (players) {
  384. detail.setPlayers(userRepo.findAllById(joinRoomList.stream()
  385. .map(JoinRoom::getUserId).collect(Collectors.toList()))
  386. .stream().map(user -> {
  387. RoomDetail.Player player = new RoomDetail.Player();
  388. player.setUserId(user.getId());
  389. player.setNickname(user.getNickname());
  390. player.setAvatar(user.getAvatar());
  391. player.setHost(user.getId().equals(room.getUserId()));
  392. JoinRoom joinRoom = (JoinRoom) (CollectionUtils.find(joinRoomList,
  393. j -> ((JoinRoom) j).getUserId().equals(user.getId())));
  394. player.setTeam(joinRoom.getTeam());
  395. player.setScreenShot(joinRoom.getScreenShot());
  396. return player;
  397. }).collect(Collectors.toList()));
  398. }
  399. return detail;
  400. }
  401. public Page<RoomDetail> roomList(Long id, Long gameId, Long modeId, Long mapId, List<RoomStatus> status, String zone, Pageable pageable) {
  402. Page<Room> page = roomRepo.findAll((Specification<Room>) (root, query, criteriaBuilder) -> {
  403. List<Predicate> and = new ArrayList<>();
  404. if (id != null) {
  405. and.add(criteriaBuilder.equal(root.get("id"), id));
  406. }
  407. if (gameId != null) {
  408. and.add(criteriaBuilder.equal(root.get("gameId"), gameId));
  409. }
  410. if (modeId != null) {
  411. and.add(criteriaBuilder.equal(root.get("gameModeId"), modeId));
  412. }
  413. if (mapId != null) {
  414. and.add(criteriaBuilder.equal(root.get("gameMapId"), mapId));
  415. }
  416. if (status != null && !status.isEmpty()) {
  417. and.add(root.get("status").in(status));
  418. }
  419. if (zone != null) {
  420. and.add(criteriaBuilder.equal(root.get("zone"), zone));
  421. }
  422. return criteriaBuilder.and(and.toArray(new Predicate[0]));
  423. }, pageable);
  424. return new PageImpl<>(page.stream().parallel()
  425. .map(room -> detail(room, true))
  426. .collect(Collectors.toList()),
  427. page.getPageable(), page.getTotalElements());
  428. }
  429. public Page<Room> my(Long userId, Pageable pageable) {
  430. return joinRoomRepo.findByUserId(userId, pageable).map(j -> {
  431. Room room = roomRepo.findById(j.getRoomId()).orElse(null);
  432. if (room == null) {
  433. return null;
  434. }
  435. return detail(room, true);
  436. });
  437. }
  438. public void judge(Long roomId, String team) {
  439. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  440. if (room.getStatus() != RoomStatus.AUDIT) {
  441. throw new BusinessException("房间状态不正确");
  442. }
  443. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatusNotIn(room.getId(),
  444. Arrays.asList(JoinRoomStatus.KICKED_OUT, JoinRoomStatus.QUIT));
  445. for (JoinRoom j : joinRoomList) {
  446. j.setFinishAt(LocalDateTime.now());
  447. if (j.getTeam().equals(team)) {
  448. j.setStatus(JoinRoomStatus.WIN);
  449. userBalanceService.modifyBalance(j.getUserId(), room.getBonus(), Constants.BalanceDesc.BONUS);
  450. } else {
  451. j.setStatus(JoinRoomStatus.LOSE);
  452. }
  453. joinRoomRepo.save(j);
  454. }
  455. room.setWinTeam(team);
  456. room.setStatus(RoomStatus.FINISH);
  457. room.setFinishAt(LocalDateTime.now());
  458. room.setWinner(joinRoomList.stream().filter(j -> j.getTeam().equals(team))
  459. .map(JoinRoom::getUserId).collect(Collectors.toList()));
  460. roomRepo.save(room);
  461. }
  462. public void changeJudge(Long roomId, String team) {
  463. Room room = roomRepo.findById(roomId).orElseThrow(new BusinessException("房间无记录"));
  464. if (room.getStatus() != RoomStatus.FINISH) {
  465. throw new BusinessException("房间状态不正确");
  466. }
  467. List<JoinRoom> joinRoomList = joinRoomRepo.findByRoomIdAndStatusNotIn(room.getId(),
  468. Arrays.asList(JoinRoomStatus.KICKED_OUT, JoinRoomStatus.QUIT));
  469. String currentWinTeam = joinRoomList.stream().filter(j -> j.getStatus() == JoinRoomStatus.WIN)
  470. .findAny().map(JoinRoom::getTeam).orElseThrow(new BusinessException("没有胜利的队伍"));
  471. if (currentWinTeam.equals(team)) {
  472. throw new BusinessException("当前队伍已经是胜利的队伍");
  473. }
  474. for (JoinRoom j : joinRoomList) {
  475. j.setFinishAt(LocalDateTime.now());
  476. if (j.getTeam().equals(team)) {
  477. j.setStatus(JoinRoomStatus.WIN);
  478. userBalanceService.modifyBalance(j.getUserId(), room.getBonus(), Constants.BalanceDesc.BONUS);
  479. // userBalanceService.modifyBalance(j.getUserId(), room.getBonus().multiply(new BigDecimal("0.25")),
  480. // Constants.BalanceDesc.COMPENSATION);
  481. } else {
  482. j.setStatus(JoinRoomStatus.LOSE);
  483. userBalanceService.modifyBalance(j.getUserId(), room.getBonus().negate(), Constants.BalanceDesc.RETURN);
  484. userBalanceService.modifyBalance(j.getUserId(), room.getBonus().multiply(new BigDecimal("0.25")).negate(),
  485. Constants.BalanceDesc.PUNISH);
  486. }
  487. joinRoomRepo.save(j);
  488. }
  489. room.setStatus(RoomStatus.FINISH);
  490. room.setFinishAt(LocalDateTime.now());
  491. room.setWinner(joinRoomList.stream().filter(j -> j.getTeam().equals(team))
  492. .map(JoinRoom::getUserId).collect(Collectors.toList()));
  493. roomRepo.save(room);
  494. }
  495. }