feat: 重构

This commit is contained in:
2026-07-07 09:58:42 +08:00
parent a5fe28e536
commit 3eeb5bbd51
58 changed files with 122 additions and 285 deletions

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.sse; package com.webgame.webgamebackend.adapter.sse;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.webgame.webgamebackend.common.event.SseEvent; import com.webgame.webgamebackend.common.event.SseEvent;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.sse; package com.webgame.webgamebackend.adapter.sse;
import com.webgame.webgamebackend.common.event.SseEvent; import com.webgame.webgamebackend.common.event.SseEvent;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.sse; package com.webgame.webgamebackend.adapter.sse;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider; import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import com.webgame.webgamebackend.common.dto.ApiResponse; import com.webgame.webgamebackend.common.dto.ApiResponse;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.ws; package com.webgame.webgamebackend.adapter.ws;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@@ -1,17 +1,17 @@
package com.webgame.webgamebackend.ws; package com.webgame.webgamebackend.adapter.ws;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider; import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.webgame.webgamebackend.entities.GameRoomEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameRoomEntity;
import com.webgame.webgamebackend.repository.GameRoomRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.GameRoomRepository;
import com.webgame.webgamebackend.service.RoomManager; import com.webgame.webgamebackend.domain.room.RoomManager;
import com.webgame.webgamebackend.service.engine.GameEngine; import com.webgame.webgamebackend.domain.engine.GameEngine;
import com.webgame.webgamebackend.service.engine.GameEngineRegistry; import com.webgame.webgamebackend.domain.engine.GameEngineRegistry;
import com.webgame.webgamebackend.service.engine.RoomContext; import com.webgame.webgamebackend.domain.engine.RoomContext;
import com.webgame.webgamebackend.ws.dto.WsInboundMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsInboundMessage;
import com.webgame.webgamebackend.ws.dto.WsMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsMessage;
import com.webgame.webgamebackend.ws.dto.WsOutboundMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsOutboundMessage;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.ws; package com.webgame.webgamebackend.adapter.ws;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.ws; package com.webgame.webgamebackend.adapter.ws;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.ws.dto; package com.webgame.webgamebackend.adapter.ws.dto;
/** /**
* 客户端服务端 WebSocket 消息类型 * 客户端服务端 WebSocket 消息类型

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.ws.dto; package com.webgame.webgamebackend.adapter.ws.dto;
/** /**
* WebSocket 消息通用封装 * WebSocket 消息通用封装

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.ws.dto; package com.webgame.webgamebackend.adapter.ws.dto;
/** /**
* 服务端客户端 WebSocket 消息类型 * 服务端客户端 WebSocket 消息类型

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.controller; package com.webgame.webgamebackend.api;
import com.webgame.webgamebackend.common.dto.ApiResponse; import com.webgame.webgamebackend.common.dto.ApiResponse;
import com.webgame.webgamebackend.common.dto.account.LoginRequest; import com.webgame.webgamebackend.common.dto.account.LoginRequest;
@@ -6,7 +6,7 @@ import com.webgame.webgamebackend.common.dto.account.LoginResponse;
import com.webgame.webgamebackend.common.dto.account.LogoutRequest; import com.webgame.webgamebackend.common.dto.account.LogoutRequest;
import com.webgame.webgamebackend.common.dto.account.RefreshTokenRequest; import com.webgame.webgamebackend.common.dto.account.RefreshTokenRequest;
import com.webgame.webgamebackend.common.dto.account.RegisterRequest; import com.webgame.webgamebackend.common.dto.account.RegisterRequest;
import com.webgame.webgamebackend.service.AccountService; import com.webgame.webgamebackend.domain.account.AccountService;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;

View File

@@ -1,8 +1,8 @@
package com.webgame.webgamebackend.controller; package com.webgame.webgamebackend.api;
import com.webgame.webgamebackend.common.dto.ApiResponse; import com.webgame.webgamebackend.common.dto.ApiResponse;
import com.webgame.webgamebackend.common.dto.game.GameListResponse; import com.webgame.webgamebackend.common.dto.game.GameListResponse;
import com.webgame.webgamebackend.service.GameService; import com.webgame.webgamebackend.domain.game.GameService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;

View File

@@ -1,9 +1,9 @@
package com.webgame.webgamebackend.controller; package com.webgame.webgamebackend.api;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider; import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import com.webgame.webgamebackend.common.dto.ApiResponse; import com.webgame.webgamebackend.common.dto.ApiResponse;
import com.webgame.webgamebackend.common.dto.game.*; import com.webgame.webgamebackend.common.dto.game.*;
import com.webgame.webgamebackend.service.RoomManager; import com.webgame.webgamebackend.domain.room.RoomManager;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;

View File

@@ -1,11 +1,11 @@
package com.webgame.webgamebackend.controller; package com.webgame.webgamebackend.api;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider; import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import com.webgame.webgamebackend.common.dto.ApiResponse; import com.webgame.webgamebackend.common.dto.ApiResponse;
import com.webgame.webgamebackend.common.dto.user.UpdateStatusRequest; import com.webgame.webgamebackend.common.dto.user.UpdateStatusRequest;
import com.webgame.webgamebackend.common.dto.user.UpdateUserInfoRequest; import com.webgame.webgamebackend.common.dto.user.UpdateUserInfoRequest;
import com.webgame.webgamebackend.common.dto.user.UserInfoResponse; import com.webgame.webgamebackend.common.dto.user.UserInfoResponse;
import com.webgame.webgamebackend.service.UserService; import com.webgame.webgamebackend.domain.user.UserService;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;

View File

@@ -1,7 +1,7 @@
package com.webgame.webgamebackend.common.dto.game; package com.webgame.webgamebackend.common.dto.game;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.webgame.webgamebackend.entities.GameConfigEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameConfigEntity;
import java.util.List; import java.util.List;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.common.dto.game; package com.webgame.webgamebackend.common.dto.game;
import com.webgame.webgamebackend.entities.GameRoomEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameRoomEntity;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.common.dto.user; package com.webgame.webgamebackend.common.dto.user;
import com.webgame.webgamebackend.entities.UserEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UserEntity;
import java.time.LocalDate; import java.time.LocalDate;

View File

@@ -3,7 +3,7 @@ package com.webgame.webgamebackend.common.event;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.webgame.webgamebackend.common.exception.BusinessException; import com.webgame.webgamebackend.common.exception.BusinessException;
import com.webgame.webgamebackend.common.exception.ErrorCode; import com.webgame.webgamebackend.common.exception.ErrorCode;
import com.webgame.webgamebackend.sse.SseConnectionManager; import com.webgame.webgamebackend.adapter.sse.SseConnectionManager;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service.impl; package com.webgame.webgamebackend.domain.account;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider; import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import com.webgame.webgamebackend.common.constants.UserConstants; import com.webgame.webgamebackend.common.constants.UserConstants;
@@ -7,12 +7,12 @@ import com.webgame.webgamebackend.common.dto.account.LoginResponse;
import com.webgame.webgamebackend.common.dto.account.RegisterRequest; import com.webgame.webgamebackend.common.dto.account.RegisterRequest;
import com.webgame.webgamebackend.common.exception.BusinessException; import com.webgame.webgamebackend.common.exception.BusinessException;
import com.webgame.webgamebackend.common.exception.ErrorCode; import com.webgame.webgamebackend.common.exception.ErrorCode;
import com.webgame.webgamebackend.entities.AccountEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.AccountEntity;
import com.webgame.webgamebackend.entities.UserEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UserEntity;
import com.webgame.webgamebackend.repository.AccountRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.AccountRepository;
import com.webgame.webgamebackend.repository.UserRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.UserRepository;
import com.webgame.webgamebackend.service.AccountService; import com.webgame.webgamebackend.domain.account.AccountService;
import com.webgame.webgamebackend.service.RefreshTokenService; import com.webgame.webgamebackend.domain.token.RefreshTokenService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -27,7 +27,7 @@ import java.util.concurrent.ThreadLocalRandom;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class AccountServiceImpl implements AccountService { public class AccountService {
private final AccountRepository accountRepository; private final AccountRepository accountRepository;
private final UserRepository userRepository; private final UserRepository userRepository;
@@ -35,7 +35,6 @@ public class AccountServiceImpl implements AccountService {
private final RefreshTokenService refreshTokenService; private final RefreshTokenService refreshTokenService;
private final AuthenticationProvider authProvider; private final AuthenticationProvider authProvider;
@Override
public LoginResponse login(LoginRequest request) { public LoginResponse login(LoginRequest request) {
AccountEntity account = accountRepository.findByUsername(request.username()) AccountEntity account = accountRepository.findByUsername(request.username())
.orElseThrow(() -> new BusinessException(ErrorCode.BAD_CREDENTIALS)); .orElseThrow(() -> new BusinessException(ErrorCode.BAD_CREDENTIALS));
@@ -50,7 +49,6 @@ public class AccountServiceImpl implements AccountService {
return new LoginResponse(accessToken, refreshToken); return new LoginResponse(accessToken, refreshToken);
} }
@Override
@Transactional @Transactional
public LoginResponse register(RegisterRequest request) { public LoginResponse register(RegisterRequest request) {
// 检查用户名是否已存在 // 检查用户名是否已存在
@@ -80,7 +78,6 @@ public class AccountServiceImpl implements AccountService {
return new LoginResponse(accessToken, refreshToken); return new LoginResponse(accessToken, refreshToken);
} }
@Override
public LoginResponse refresh(String refreshToken) { public LoginResponse refresh(String refreshToken) {
// 校验 refresh token有效则用它签发新的 access token // 校验 refresh token有效则用它签发新的 access token
String userId = refreshTokenService.validate(refreshToken); String userId = refreshTokenService.validate(refreshToken);
@@ -90,7 +87,6 @@ public class AccountServiceImpl implements AccountService {
return new LoginResponse(accessToken, refreshToken); return new LoginResponse(accessToken, refreshToken);
} }
@Override
public void logout(String refreshToken) { public void logout(String refreshToken) {
// 获取当前登录用户ID用于日志 // 获取当前登录用户ID用于日志
String loginId = authProvider.getCurrentUserId(); String loginId = authProvider.getCurrentUserId();

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service.engine; package com.webgame.webgamebackend.domain.engine;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service.engine; package com.webgame.webgamebackend.domain.engine;
/** /**
* 游戏引擎工厂接口 * 游戏引擎工厂接口

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service.engine; package com.webgame.webgamebackend.domain.engine;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service.engine; package com.webgame.webgamebackend.domain.engine;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;

View File

@@ -1,13 +1,13 @@
package com.webgame.webgamebackend.service.engine; package com.webgame.webgamebackend.domain.engine;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.webgame.webgamebackend.common.exception.BusinessException; import com.webgame.webgamebackend.common.exception.BusinessException;
import com.webgame.webgamebackend.common.exception.ErrorCode; import com.webgame.webgamebackend.common.exception.ErrorCode;
import com.webgame.webgamebackend.entities.GameMoveEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameMoveEntity;
import com.webgame.webgamebackend.repository.GameMoveRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.GameMoveRepository;
import com.webgame.webgamebackend.ws.dto.WsMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsMessage;
import com.webgame.webgamebackend.ws.dto.WsOutboundMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsOutboundMessage;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.service.engine; package com.webgame.webgamebackend.domain.engine;
import com.webgame.webgamebackend.ws.dto.WsMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsMessage;
import lombok.Getter; import lombok.Getter;
import java.util.List; import java.util.List;

View File

@@ -1,10 +1,10 @@
package com.webgame.webgamebackend.service.impl; package com.webgame.webgamebackend.domain.game;
import com.webgame.webgamebackend.common.dto.game.GameItemResponse; import com.webgame.webgamebackend.common.dto.game.GameItemResponse;
import com.webgame.webgamebackend.common.dto.game.GameListResponse; import com.webgame.webgamebackend.common.dto.game.GameListResponse;
import com.webgame.webgamebackend.entities.GameConfigEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameConfigEntity;
import com.webgame.webgamebackend.repository.GameConfigRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.GameConfigRepository;
import com.webgame.webgamebackend.service.GameService; import com.webgame.webgamebackend.domain.game.GameService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -19,11 +19,10 @@ import java.util.List;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class GameServiceImpl implements GameService { public class GameService {
private final GameConfigRepository gameConfigRepository; private final GameConfigRepository gameConfigRepository;
@Override
public GameListResponse getGameList() { public GameListResponse getGameList() {
List<GameConfigEntity> configs = gameConfigRepository.findByEnabledTrueOrderBySortOrderAsc(); List<GameConfigEntity> configs = gameConfigRepository.findByEnabledTrueOrderBySortOrderAsc();
List<GameItemResponse> list = configs.stream() List<GameItemResponse> list = configs.stream()

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service; package com.webgame.webgamebackend.domain.room;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.webgame.webgamebackend.common.dto.game.*; import com.webgame.webgamebackend.common.dto.game.*;
@@ -8,12 +8,12 @@ import com.webgame.webgamebackend.common.event.SseEventPublisher;
import com.webgame.webgamebackend.common.event.SseEventType; import com.webgame.webgamebackend.common.event.SseEventType;
import com.webgame.webgamebackend.common.exception.BusinessException; import com.webgame.webgamebackend.common.exception.BusinessException;
import com.webgame.webgamebackend.common.exception.ErrorCode; import com.webgame.webgamebackend.common.exception.ErrorCode;
import com.webgame.webgamebackend.entities.*; import com.webgame.webgamebackend.infrastructure.persistence.entity.*;
import com.webgame.webgamebackend.repository.*; import com.webgame.webgamebackend.infrastructure.persistence.repository.*;
import com.webgame.webgamebackend.service.engine.*; import com.webgame.webgamebackend.domain.engine.*;
import com.webgame.webgamebackend.ws.RoomSessionManager; import com.webgame.webgamebackend.adapter.ws.RoomSessionManager;
import com.webgame.webgamebackend.ws.dto.WsMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsMessage;
import com.webgame.webgamebackend.ws.dto.WsOutboundMessage; import com.webgame.webgamebackend.adapter.ws.dto.WsOutboundMessage;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;

View File

@@ -1,8 +1,8 @@
package com.webgame.webgamebackend.service.impl; package com.webgame.webgamebackend.domain.token;
import com.webgame.webgamebackend.common.exception.BusinessException; import com.webgame.webgamebackend.common.exception.BusinessException;
import com.webgame.webgamebackend.common.exception.ErrorCode; import com.webgame.webgamebackend.common.exception.ErrorCode;
import com.webgame.webgamebackend.service.RefreshTokenService; import com.webgame.webgamebackend.domain.token.RefreshTokenService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
@@ -27,7 +27,7 @@ import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class RefreshTokenServiceImpl implements RefreshTokenService { public class RefreshTokenService {
/** Redis key 前缀 */ /** Redis key 前缀 */
private static final String KEY_PREFIX = "xzg:refresh:"; private static final String KEY_PREFIX = "xzg:refresh:";
@@ -43,7 +43,6 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
private final StringRedisTemplate stringRedisTemplate; private final StringRedisTemplate stringRedisTemplate;
@Override
public String create(String userId) { public String create(String userId) {
if (userId == null || userId.isBlank()) { if (userId == null || userId.isBlank()) {
throw new BusinessException(ErrorCode.BAD_REQUEST, "用户ID不能为空"); throw new BusinessException(ErrorCode.BAD_REQUEST, "用户ID不能为空");
@@ -64,7 +63,6 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
return token; return token;
} }
@Override
public String validate(String token) { public String validate(String token) {
if (token == null || token.isBlank()) { if (token == null || token.isBlank()) {
throw new BusinessException(ErrorCode.REFRESH_TOKEN_MISSING); throw new BusinessException(ErrorCode.REFRESH_TOKEN_MISSING);
@@ -76,7 +74,6 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
return userId; return userId;
} }
@Override
public String rotate(String oldToken) { public String rotate(String oldToken) {
String userId = validate(oldToken); String userId = validate(oldToken);
// 先删反向映射再删正向映射 // 先删反向映射再删正向映射
@@ -88,7 +85,6 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
return create(userId); return create(userId);
} }
@Override
public void revoke(String token) { public void revoke(String token) {
if (token == null || token.isBlank()) { if (token == null || token.isBlank()) {
return; return;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.service.impl; package com.webgame.webgamebackend.domain.user;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider; import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import com.webgame.webgamebackend.common.dto.user.UpdateStatusRequest; import com.webgame.webgamebackend.common.dto.user.UpdateStatusRequest;
@@ -6,9 +6,9 @@ import com.webgame.webgamebackend.common.dto.user.UpdateUserInfoRequest;
import com.webgame.webgamebackend.common.dto.user.UserInfoResponse; import com.webgame.webgamebackend.common.dto.user.UserInfoResponse;
import com.webgame.webgamebackend.common.exception.BusinessException; import com.webgame.webgamebackend.common.exception.BusinessException;
import com.webgame.webgamebackend.common.exception.ErrorCode; import com.webgame.webgamebackend.common.exception.ErrorCode;
import com.webgame.webgamebackend.entities.UserEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UserEntity;
import com.webgame.webgamebackend.repository.UserRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.UserRepository;
import com.webgame.webgamebackend.service.UserService; import com.webgame.webgamebackend.domain.user.UserService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -27,7 +27,7 @@ import java.util.Set;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class UserServiceImpl implements UserService { public class UserService {
/** 头像存储目录(相对于项目工作目录) */ /** 头像存储目录(相对于项目工作目录) */
private static final String AVATAR_DIR = "uploads/avatars"; private static final String AVATAR_DIR = "uploads/avatars";
@@ -50,7 +50,6 @@ public class UserServiceImpl implements UserService {
private final UserRepository userRepository; private final UserRepository userRepository;
private final AuthenticationProvider authProvider; private final AuthenticationProvider authProvider;
@Override
public UserInfoResponse getCurrentUserInfo() { public UserInfoResponse getCurrentUserInfo() {
String accountId = authProvider.getCurrentUserId(); String accountId = authProvider.getCurrentUserId();
log.info("[用户服务] 获取当前登录用户信息, accountId: {}", accountId); log.info("[用户服务] 获取当前登录用户信息, accountId: {}", accountId);
@@ -59,7 +58,6 @@ public class UserServiceImpl implements UserService {
return UserInfoResponse.from(user); return UserInfoResponse.from(user);
} }
@Override
@Transactional @Transactional
public UserInfoResponse updateUserInfo(String accountId, UpdateUserInfoRequest request) { public UserInfoResponse updateUserInfo(String accountId, UpdateUserInfoRequest request) {
UserEntity user = userRepository.findByAccountId(accountId) UserEntity user = userRepository.findByAccountId(accountId)
@@ -90,7 +88,6 @@ public class UserServiceImpl implements UserService {
return UserInfoResponse.from(user); return UserInfoResponse.from(user);
} }
@Override
@Transactional @Transactional
public void updateStatus(String accountId, UpdateStatusRequest request) { public void updateStatus(String accountId, UpdateStatusRequest request) {
UserEntity user = userRepository.findByAccountId(accountId) UserEntity user = userRepository.findByAccountId(accountId)
@@ -101,7 +98,6 @@ public class UserServiceImpl implements UserService {
log.info("[用户服务] 更新在线状态, accountId={}, status={}", accountId, request.status()); log.info("[用户服务] 更新在线状态, accountId={}, status={}", accountId, request.status());
} }
@Override
@Transactional @Transactional
public UserInfoResponse uploadAvatar(String accountId, MultipartFile file) { public UserInfoResponse uploadAvatar(String accountId, MultipartFile file) {
// 校验文件类型 // 校验文件类型
@@ -144,7 +140,6 @@ public class UserServiceImpl implements UserService {
} }
} }
@Override
@Transactional @Transactional
public UserInfoResponse deleteAvatar(String accountId) { public UserInfoResponse deleteAvatar(String accountId) {
UserEntity user = userRepository.findByAccountId(accountId) UserEntity user = userRepository.findByAccountId(accountId)

View File

@@ -1,8 +1,8 @@
package com.webgame.webgamebackend.config; package com.webgame.webgamebackend.infrastructure.config;
import com.webgame.webgamebackend.repository.GameMoveRepository; import com.webgame.webgamebackend.infrastructure.persistence.repository.GameMoveRepository;
import com.webgame.webgamebackend.service.engine.GameEngineRegistry; import com.webgame.webgamebackend.domain.engine.GameEngineRegistry;
import com.webgame.webgamebackend.service.engine.GomokuEngine; import com.webgame.webgamebackend.domain.engine.GomokuEngine;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.common.config; package com.webgame.webgamebackend.infrastructure.config;
import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.Info;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.common.config; package com.webgame.webgamebackend.infrastructure.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.common.config; package com.webgame.webgamebackend.infrastructure.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.common.config; package com.webgame.webgamebackend.infrastructure.config;
import cn.dev33.satoken.fun.strategy.SaCorsHandleFunction; import cn.dev33.satoken.fun.strategy.SaCorsHandleFunction;
import cn.dev33.satoken.router.SaHttpMethod; import cn.dev33.satoken.router.SaHttpMethod;

View File

@@ -1,7 +1,7 @@
package com.webgame.webgamebackend.config; package com.webgame.webgamebackend.infrastructure.config;
import com.webgame.webgamebackend.common.event.SseEventPublisher; import com.webgame.webgamebackend.common.event.SseEventPublisher;
import com.webgame.webgamebackend.sse.RedisSseListener; import com.webgame.webgamebackend.adapter.sse.RedisSseListener;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.common.config; package com.webgame.webgamebackend.infrastructure.config;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.config; package com.webgame.webgamebackend.infrastructure.config;
import com.webgame.webgamebackend.ws.RoomWebSocketHandler; import com.webgame.webgamebackend.adapter.ws.RoomWebSocketHandler;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.EnableWebSocket;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.entities.base; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;

View File

@@ -1,4 +1,4 @@
package com.webgame.webgamebackend.entities.base; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.entities; package com.webgame.webgamebackend.infrastructure.persistence.entity;
import com.webgame.webgamebackend.entities.base.UUIDBaseEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UUIDBaseEntity;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.AccountEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.AccountEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional; import java.util.Optional;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.GameConfigEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameConfigEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.GameMoveEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameMoveEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.GameRecordEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameRecordEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional; import java.util.Optional;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.GameRoomEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.GameRoomEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.RoomPlayerEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.RoomPlayerEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.repository; package com.webgame.webgamebackend.infrastructure.persistence.repository;
import com.webgame.webgamebackend.entities.UserEntity; import com.webgame.webgamebackend.infrastructure.persistence.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; import java.util.List;

View File

@@ -1,42 +0,0 @@
package com.webgame.webgamebackend.service;
import com.webgame.webgamebackend.common.dto.account.LoginRequest;
import com.webgame.webgamebackend.common.dto.account.LoginResponse;
import com.webgame.webgamebackend.common.dto.account.RegisterRequest;
/**
* 账号服务接口
*/
public interface AccountService {
/**
* 登录
*
* @param request 登录请求
* @return 登录结果(含 token
*/
LoginResponse login(LoginRequest request);
/**
* 注册
*
* @param request 注册请求
* @return 注册结果(含双 token注册后自动登录
*/
LoginResponse register(RegisterRequest request);
/**
* 刷新令牌
*
* @param refreshToken 刷新令牌
* @return 新的双 tokenaccessToken + refreshToken
*/
LoginResponse refresh(String refreshToken);
/**
* 登出,使 access token 和 refresh token 失效
*
* @param refreshToken 刷新令牌
*/
void logout(String refreshToken);
}

View File

@@ -1,19 +0,0 @@
package com.webgame.webgamebackend.service;
import com.webgame.webgamebackend.common.dto.game.GameListResponse;
/**
* 游戏服务接口
*
* 管理游戏配置相关的查询。
* 房间管理已迁移到 {@link RoomManager}。
*/
public interface GameService {
/**
* 获取游戏列表
*
* @return 所有启用的游戏信息
*/
GameListResponse getGameList();
}

View File

@@ -1,40 +0,0 @@
package com.webgame.webgamebackend.service;
/**
* 刷新令牌服务接口,管理 refresh token 的生命周期
*/
public interface RefreshTokenService {
/**
* 为用户创建新的刷新令牌,存入 RedisTTL 30 天
*
* @param userId 用户ID
* @return 生成的 refresh token 字符串
*/
String create(String userId);
/**
* 校验刷新令牌是否有效
*
* @param token 刷新令牌
* @return 对应的用户ID
* @throws com.webgame.webgamebackend.common.exception.BusinessException 令牌无效时抛出
*/
String validate(String token);
/**
* 轮换刷新令牌:删除旧 token生成新 token防重放
*
* @param oldToken 旧的刷新令牌
* @return 新的刷新令牌
* @throws com.webgame.webgamebackend.common.exception.BusinessException 旧令牌无效时抛出
*/
String rotate(String oldToken);
/**
* 撤销刷新令牌(登出时调用)
*
* @param token 要撤销的刷新令牌
*/
void revoke(String token);
}

View File

@@ -1,57 +0,0 @@
package com.webgame.webgamebackend.service;
import com.webgame.webgamebackend.common.dto.user.UpdateStatusRequest;
import com.webgame.webgamebackend.common.dto.user.UpdateUserInfoRequest;
import com.webgame.webgamebackend.common.dto.user.UserInfoResponse;
import org.springframework.web.multipart.MultipartFile;
/**
* 用户服务接口
*/
public interface UserService {
/**
* 获取当前登录用户的资料
*
* @return 用户信息
*/
UserInfoResponse getCurrentUserInfo();
/**
* 更新当前登录用户的资料
*
* @param accountId 账号 ID
* @param request 更新请求(所有字段可选)
* @return 更新后的用户信息
*/
UserInfoResponse updateUserInfo(String accountId, UpdateUserInfoRequest request);
/**
* 更新当前登录用户的在线状态
*
* @param accountId 账号 ID
* @param request 状态更新请求
*/
void updateStatus(String accountId, UpdateStatusRequest request);
/**
* 上传并更新当前登录用户的头像
*
* 文件会被保存到 uploads/avatars/{accountId}.jpg并更新 DB 中的 avatar 字段。
*
* @param accountId 账号 ID
* @param file 头像文件(前端已裁剪为 200×200 JPEG
* @return 更新后的用户信息
*/
UserInfoResponse uploadAvatar(String accountId, MultipartFile file);
/**
* 删除当前登录用户的头像
*
* 删除磁盘文件,并将 DB 中 avatar 置为 null前端会回退显示默认头像
*
* @param accountId 账号 ID
* @return 更新后的用户信息
*/
UserInfoResponse deleteAvatar(String accountId);
}

View File

@@ -74,6 +74,15 @@ logging:
# #如果是true则用的是https而不是http,默认值是true # #如果是true则用的是https而不是http,默认值是true
# secure: false # secure: false
############## 游戏配置 ##############
game:
# 断线重连超时时间(秒)
disconnect-timeout-seconds: 60
# 聊天消息最大长度
chat-max-length: 500
# 五子棋棋盘大小
board-size: 15
############## Sa-Token 配置 (文档: https://sa-token.cc) ############## ############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
sa-token: sa-token:
# token 名称(同时也是 cookie 名称) # token 名称(同时也是 cookie 名称)