diff --git a/pom.xml b/pom.xml index 0d14a8b..4a05f8a 100644 --- a/pom.xml +++ b/pom.xml @@ -13,19 +13,6 @@ 0.0.1-SNAPSHOT myplayer-backend myplayer-backend - - - - - - - - - - - - - 17 @@ -64,7 +51,7 @@ org.projectlombok lombok - true + provided org.springframework.boot @@ -105,11 +92,21 @@ mybatis-plus-jsqlparser 3.5.11 + + org.mybatis + mybatis-spring + 3.0.4 + io.jsonwebtoken jjwt 0.12.6 + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.8.14 + @@ -122,29 +119,9 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.projectlombok - lombok - - - - org.springframework.boot spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - diff --git a/src/main/java/xin/merlin/myplayerbackend/MyplayerBackendApplication.java b/src/main/java/xin/merlin/myplayerbackend/MyplayerBackendApplication.java index 8bffea1..4e761ce 100644 --- a/src/main/java/xin/merlin/myplayerbackend/MyplayerBackendApplication.java +++ b/src/main/java/xin/merlin/myplayerbackend/MyplayerBackendApplication.java @@ -2,8 +2,11 @@ package xin.merlin.myplayerbackend; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import xin.merlin.myplayerbackend.config.security.JwtProperties; @SpringBootApplication +@EnableConfigurationProperties(JwtProperties.class) public class MyplayerBackendApplication { public static void main(String[] args) { diff --git a/src/main/java/xin/merlin/myplayerbackend/config/security/CustomAuthenticationEntryPoint.java b/src/main/java/xin/merlin/myplayerbackend/config/security/CustomAuthenticationEntryPoint.java new file mode 100644 index 0000000..01d6f7f --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/config/security/CustomAuthenticationEntryPoint.java @@ -0,0 +1,27 @@ +package xin.merlin.myplayerbackend.config.security; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.InsufficientAuthenticationException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Slf4j +@Component +public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { + String message = "认证失败"; + if (exception instanceof InsufficientAuthenticationException) { + message = "未提供认证信息"; + } + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().write(message); + } +} diff --git a/src/main/java/xin/merlin/myplayerbackend/config/security/JWTAuthenticationFilter.java b/src/main/java/xin/merlin/myplayerbackend/config/security/JWTAuthenticationFilter.java index c15b03f..fc84d1a 100644 --- a/src/main/java/xin/merlin/myplayerbackend/config/security/JWTAuthenticationFilter.java +++ b/src/main/java/xin/merlin/myplayerbackend/config/security/JWTAuthenticationFilter.java @@ -35,12 +35,12 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter { try { if (!jwtUtil.isTokenExpired(token)) { - System.out.println(token); - String username = jwtUtil.getUAccount(token); + System.out.println("token expired: " + token); + String account = jwtUtil.getAccount(token); - if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + if (account != null && SecurityContextHolder.getContext().getAuthentication() == null) { UsernamePasswordAuthenticationToken authenticationToken = - new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList()); + new UsernamePasswordAuthenticationToken(account, null, Collections.emptyList()); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); } diff --git a/src/main/java/xin/merlin/myplayerbackend/config/security/SecurityConfig.java b/src/main/java/xin/merlin/myplayerbackend/config/security/SecurityConfig.java index 7e74a2e..db01d1b 100644 --- a/src/main/java/xin/merlin/myplayerbackend/config/security/SecurityConfig.java +++ b/src/main/java/xin/merlin/myplayerbackend/config/security/SecurityConfig.java @@ -1,7 +1,6 @@ package xin.merlin.myplayerbackend.config.security; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -22,21 +21,23 @@ public class SecurityConfig { private final JWTAuthenticationFilter jwtAuthenticationFilter; @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain filterChain(HttpSecurity http,CustomAuthenticationEntryPoint entryPoint) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(authz -> authz .requestMatchers( + "/error", "/login", "/register", "/health", "/code/**", - "/blog/**" + "/v3/api-docs/**" ).permitAll() .anyRequest().authenticated() ) - .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) + .exceptionHandling(ex -> ex.authenticationEntryPoint(entryPoint)); return http.build(); } @@ -48,7 +49,7 @@ public class SecurityConfig { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") - .allowedOriginPatterns("*") // 开发阶段允许所有来源 + .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .exposedHeaders("Authorization") diff --git a/src/main/java/xin/merlin/myplayerbackend/controller/CodeController.java b/src/main/java/xin/merlin/myplayerbackend/controller/CodeController.java new file mode 100644 index 0000000..fa708b9 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/controller/CodeController.java @@ -0,0 +1,51 @@ +package xin.merlin.myplayerbackend.controller; + + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xin.merlin.myplayerbackend.entity.Account; +import xin.merlin.myplayerbackend.entity.http.Code; +import xin.merlin.myplayerbackend.service.CodeService; +import xin.merlin.myplayerbackend.utils.result.Response; +import xin.merlin.myplayerbackend.utils.result.ResultCode; + +/* +* 验证码controller +* 包含发送和验证逻辑*/ + +@Slf4j +@RestController +@RequestMapping("/code") +@RequiredArgsConstructor +public class CodeController { + + private final CodeService codeService; + + //发送验证码 + @PostMapping("/send") + Response send(@RequestBody Account account){ + try { + return codeService.send(account); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Response.fail(ResultCode.SERVER_ERROR); + } + } + + + //验证验证码是否存在、可用、正确 + @PostMapping("/verify") + Response verify(@RequestBody Code code){ + try { + return codeService.verify(code); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Response.fail(ResultCode.SERVER_ERROR); + } + + } +} diff --git a/src/main/java/xin/merlin/myplayerbackend/controller/HealthController.java b/src/main/java/xin/merlin/myplayerbackend/controller/HealthController.java new file mode 100644 index 0000000..0d7ede3 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/controller/HealthController.java @@ -0,0 +1,17 @@ +package xin.merlin.myplayerbackend.controller; + + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import xin.merlin.myplayerbackend.utils.result.Response; +import xin.merlin.myplayerbackend.utils.result.ResultCode; + +@RestController +public class HealthController { + + @GetMapping("/health") + Response health() { + return Response.success(ResultCode.SUCCESS); + } + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/controller/LoginController.java b/src/main/java/xin/merlin/myplayerbackend/controller/LoginController.java new file mode 100644 index 0000000..fc7bf7b --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/controller/LoginController.java @@ -0,0 +1,59 @@ +package xin.merlin.myplayerbackend.controller; + + +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import xin.merlin.myplayerbackend.entity.Account; +import xin.merlin.myplayerbackend.entity.http.Code; +import xin.merlin.myplayerbackend.service.CodeService; +import xin.merlin.myplayerbackend.service.impl.AccountServiceImpl; +import xin.merlin.myplayerbackend.utils.result.Response; +import xin.merlin.myplayerbackend.utils.result.ResultCode; + + +/* +* 登录controller +* 包括:登录和注册逻辑 +* */ +@Slf4j +@RestController +@RequiredArgsConstructor +public class LoginController { + + private final AccountServiceImpl accountService; + + private final CodeService codeService; + + private final HttpServletRequest request; + + //login + @PostMapping("/login") + Response login(@RequestBody Account account){ + + + return Response.success(ResultCode.SUCCESS); + } + + //register + @PostMapping("/register") + Response register(@RequestBody Code code){ + try { + Response response = codeService.verify(code); + if(response.getCode().equals("200")){ + Account account = new Account(); + account.setAccount(code.getAccount()); + account.setIp(request.getRemoteAddr()); + accountService.save(account); + } + return response; + } catch (Exception e) { + log.error(e.getMessage(), e); + return Response.fail(ResultCode.SERVER_ERROR); + } + } + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Account.java b/src/main/java/xin/merlin/myplayerbackend/entity/Account.java new file mode 100644 index 0000000..9904fef --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Account.java @@ -0,0 +1,17 @@ +package xin.merlin.myplayerbackend.entity; + + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("account") +public class Account { + @TableId("id") + private Integer id; + + private String account; + private String password; + private String ip; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Audit.java b/src/main/java/xin/merlin/myplayerbackend/entity/Audit.java new file mode 100644 index 0000000..35756db --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Audit.java @@ -0,0 +1,18 @@ +package xin.merlin.myplayerbackend.entity; + + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("audit") +public class Audit { + @TableId("a_id") + private Integer a_id; + + private Integer type; + private Integer applicant; + private Integer influence; + private String changed; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Friends.java b/src/main/java/xin/merlin/myplayerbackend/entity/Friends.java new file mode 100644 index 0000000..3901c33 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Friends.java @@ -0,0 +1,15 @@ +package xin.merlin.myplayerbackend.entity; + + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("friends") +public class Friends { + private Integer id; + private Integer f_id; + private String nickname; + + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Group.java b/src/main/java/xin/merlin/myplayerbackend/entity/Group.java new file mode 100644 index 0000000..a1ac085 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Group.java @@ -0,0 +1,16 @@ +package xin.merlin.myplayerbackend.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("group") +public class Group { + @TableId("g_id") + private Integer g_id; + + private String g_name; + private String g_introduction; + private String g_avatar; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Groups.java b/src/main/java/xin/merlin/myplayerbackend/entity/Groups.java new file mode 100644 index 0000000..927a413 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Groups.java @@ -0,0 +1,12 @@ +package xin.merlin.myplayerbackend.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("groups") +public class Groups { + private Integer g_id; + private Integer id; + private Integer role; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Inviting.java b/src/main/java/xin/merlin/myplayerbackend/entity/Inviting.java new file mode 100644 index 0000000..1951629 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Inviting.java @@ -0,0 +1,18 @@ +package xin.merlin.myplayerbackend.entity; + + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("inviting") +public class Inviting { + @TableId("i_id") + private Integer i_id; + + private Integer inviter; + private Integer target; + private Integer status; + private Integer room; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Message.java b/src/main/java/xin/merlin/myplayerbackend/entity/Message.java new file mode 100644 index 0000000..1550049 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Message.java @@ -0,0 +1,20 @@ +package xin.merlin.myplayerbackend.entity; + + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("message") +public class Message { + @TableId("m_id") + private Integer m_id; + + private Integer sender; + private Integer receiver; + private String content; + private LocalDateTime time; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Playroom.java b/src/main/java/xin/merlin/myplayerbackend/entity/Playroom.java new file mode 100644 index 0000000..fc57e9f --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Playroom.java @@ -0,0 +1,16 @@ +package xin.merlin.myplayerbackend.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("playroom") +public class Playroom { + @TableId("r_id") + private Integer r_id; + + private String r_name; + private String r_introduction; + private String r_avatar; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/Playrooms.java b/src/main/java/xin/merlin/myplayerbackend/entity/Playrooms.java new file mode 100644 index 0000000..c873315 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/Playrooms.java @@ -0,0 +1,13 @@ +package xin.merlin.myplayerbackend.entity; + + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("playrooms") +public class Playrooms { + private Integer r_id; + private Integer id; + private Integer role; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/User.java b/src/main/java/xin/merlin/myplayerbackend/entity/User.java new file mode 100644 index 0000000..d633146 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/User.java @@ -0,0 +1,17 @@ +package xin.merlin.myplayerbackend.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("user") +public class User { + @TableId("u_id") + private String u_id; + + private Integer id; + private String u_name; + private String u_introduction; + private String u_avatar; +} diff --git a/src/main/java/xin/merlin/myplayerbackend/entity/http/Code.java b/src/main/java/xin/merlin/myplayerbackend/entity/http/Code.java new file mode 100644 index 0000000..ad4739a --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/entity/http/Code.java @@ -0,0 +1,11 @@ +package xin.merlin.myplayerbackend.entity.http; + +import lombok.Data; + +@Data +public class Code { + private String account; + private String c_id; + private String code; + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/AccountMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/AccountMapper.java new file mode 100644 index 0000000..8f53e66 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/AccountMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Account; + +@Mapper +public interface AccountMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/AuditMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/AuditMapper.java new file mode 100644 index 0000000..69db918 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/AuditMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Audit; + +@Mapper +public interface AuditMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/FriendsMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/FriendsMapper.java new file mode 100644 index 0000000..23ff80e --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/FriendsMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Friends; + +@Mapper +public interface FriendsMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/GroupMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/GroupMapper.java new file mode 100644 index 0000000..e02952e --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/GroupMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Group; + +@Mapper +public interface GroupMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/GroupsMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/GroupsMapper.java new file mode 100644 index 0000000..7e70fca --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/GroupsMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Groups; + +@Mapper +public interface GroupsMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/InvitingMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/InvitingMapper.java new file mode 100644 index 0000000..6da0cd0 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/InvitingMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Inviting; + +@Mapper +public interface InvitingMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/MessageMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/MessageMapper.java new file mode 100644 index 0000000..1fb860a --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/MessageMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Message; + +@Mapper +public interface MessageMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/PlayroomMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/PlayroomMapper.java new file mode 100644 index 0000000..b28db99 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/PlayroomMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Playroom; + +@Mapper +public interface PlayroomMapper extends BaseMapper { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/mapper/PlayroomsMapper.java b/src/main/java/xin/merlin/myplayerbackend/mapper/PlayroomsMapper.java new file mode 100644 index 0000000..dbb8e88 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/mapper/PlayroomsMapper.java @@ -0,0 +1,9 @@ +package xin.merlin.myplayerbackend.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import xin.merlin.myplayerbackend.entity.Playrooms; + +@Mapper +public interface PlayroomsMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/xin/merlin/myplayerbackend/service/CodeService.java b/src/main/java/xin/merlin/myplayerbackend/service/CodeService.java new file mode 100644 index 0000000..8290828 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/CodeService.java @@ -0,0 +1,106 @@ +package xin.merlin.myplayerbackend.service; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import xin.merlin.myplayerbackend.entity.Account; +import xin.merlin.myplayerbackend.entity.http.Code; +import xin.merlin.myplayerbackend.utils.result.Response; +import xin.merlin.myplayerbackend.utils.result.ResultCode; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +@RequiredArgsConstructor +public class CodeService { + // 验证码字典 + private static final Cache waitingList = Caffeine.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .build(); + + // 抛出以便登录时访问字典 + public Cache getWaitingList() { + return waitingList; + } + + // 冷却缓存:限制邮箱请求频率 + private static final Cache emailCooldown = Caffeine.newBuilder() + .expireAfterWrite(60, TimeUnit.SECONDS) // 冷却 60 秒 + .build(); + + // 验证码验证次数 + private static final Cache codeFailCount = Caffeine.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .build(); + + private final MailService mailService; + + // 发送验证码 + public Response send(Account account){ + String a = account.getAccount(); + if(a==null) return Response.success(ResultCode.MAIL_ACCOUNT_NOT_PROVIDED); + log.info("sending code to ----->{}", a); + + // 检查是否在冷却中 + if (emailCooldown.getIfPresent(a) != null) { + return Response.success(ResultCode.MAIL_REQUEST_TOO_FAST); + } + String tempId = UUID.randomUUID().toString() + .replace("-", ""); + + try { + // 加入验证码字典 + waitingList.put(tempId, mailService.sendMail(a)); + // 加入验证码冷却 + emailCooldown.put(a, true); + return Response.success(ResultCode.SUCCESS, Map.of("c_id", tempId)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + //验证验证码是否存在、可用、正确 + @Transactional + public Response verify(Code code){ + String c_id = code.getC_id(); + String account = code.getAccount(); + String c = code.getCode(); + if(c_id==null||account==null||c==null) return Response.success(ResultCode.MAIL_INFO_LOST); + Integer count = codeFailCount.getIfPresent(c_id); + + //设置并查看最大尝试次数 + try { + if(count == null){ + codeFailCount.put(c_id, 1); + }else if(count<=5){ + codeFailCount.put(c_id, count+1); + }else { + codeFailCount.invalidate(c_id); + return Response.success(ResultCode.MAIL_VERIFY_FAIL_TOO_MANY); + } + + //执行验证逻辑 + String tempCode = waitingList.getIfPresent(c_id); + log.info("verifying...{},{}--?=--{}", account,code, tempCode); + if (tempCode == null) return Response.success(ResultCode.MAIL_VERIFY_NOT_EXIST); + if (!tempCode.equals(code.getCode())) return Response.success(ResultCode.MAIL_VERIFY_CODE_ERROR); + codeFailCount.invalidate(c_id); + emailCooldown.invalidate(account); + + return Response.success(ResultCode.SUCCESS); + } catch (Exception e) { + throw new RuntimeException(e); + } + + + } + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/LoginService.java b/src/main/java/xin/merlin/myplayerbackend/service/LoginService.java new file mode 100644 index 0000000..413b952 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/LoginService.java @@ -0,0 +1,29 @@ +package xin.merlin.myplayerbackend.service; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Account; +import xin.merlin.myplayerbackend.mapper.AccountMapper; +import xin.merlin.myplayerbackend.utils.result.Response; +import xin.merlin.myplayerbackend.utils.result.ResultCode; + +@Service +@RequiredArgsConstructor +public class LoginService{ + + private final AccountMapper accountMapper; + + public Response login(Account account){ + Account ta = accountMapper.selectOne(new QueryWrapper().eq("account",account.getAccount())); + if(ta == null) return Response.success(ResultCode.USER_NOT_FOUND); + + //TODO:111 + return null; + } + + + + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/MailService.java b/src/main/java/xin/merlin/myplayerbackend/service/MailService.java new file mode 100644 index 0000000..4f0401e --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/MailService.java @@ -0,0 +1,36 @@ +package xin.merlin.myplayerbackend.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.MailException; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class MailService { + + private final JavaMailSender mailSender; + + @Value("${spring.mail.username}") + private String mail; + + public String sendMail(String receiver){ + try { + String code = Double.toString(Math.random()).substring(2,8); + SimpleMailMessage message = new SimpleMailMessage(); + message.setFrom(mail); + message.setTo(receiver); + message.setSubject("Welcome to use Merlin`s product"); + message.setText("欢迎使用Merlin.xin产品! \n"+"您的验证码为:"+code+"\n有效期五分钟,请勿泄露!"); + mailSender.send(message); + return code; + } catch (MailException e) { + log.error("e: ", e); + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/AccountServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/AccountServiceImpl.java new file mode 100644 index 0000000..b390062 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/AccountServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Account; +import xin.merlin.myplayerbackend.mapper.AccountMapper; + +@Service +public class AccountServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/AuditServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/AuditServiceImpl.java new file mode 100644 index 0000000..9aff1e3 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/AuditServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Audit; +import xin.merlin.myplayerbackend.mapper.AuditMapper; + +@Service +public class AuditServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/FriendsServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/FriendsServiceImpl.java new file mode 100644 index 0000000..4059927 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/FriendsServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Friends; +import xin.merlin.myplayerbackend.mapper.FriendsMapper; + +@Service +public class FriendsServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/GroupServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/GroupServiceImpl.java new file mode 100644 index 0000000..97caa6e --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/GroupServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Group; +import xin.merlin.myplayerbackend.mapper.GroupMapper; + +@Service +public class GroupServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/GroupsServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/GroupsServiceImpl.java new file mode 100644 index 0000000..3995404 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/GroupsServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Groups; +import xin.merlin.myplayerbackend.mapper.GroupsMapper; + +@Service +public class GroupsServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/InvitingServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/InvitingServiceImpl.java new file mode 100644 index 0000000..0ba2fa9 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/InvitingServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Inviting; +import xin.merlin.myplayerbackend.mapper.InvitingMapper; + +@Service +public class InvitingServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/MessageServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/MessageServiceImpl.java new file mode 100644 index 0000000..bd489d5 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/MessageServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Message; +import xin.merlin.myplayerbackend.mapper.MessageMapper; + +@Service +public class MessageServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/PlayroomServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/PlayroomServiceImpl.java new file mode 100644 index 0000000..1ec66c9 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/PlayroomServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Playroom; +import xin.merlin.myplayerbackend.mapper.PlayroomMapper; + +@Service +public class PlayroomServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/service/impl/PlayroomsServiceImpl.java b/src/main/java/xin/merlin/myplayerbackend/service/impl/PlayroomsServiceImpl.java new file mode 100644 index 0000000..343325f --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/service/impl/PlayroomsServiceImpl.java @@ -0,0 +1,10 @@ +package xin.merlin.myplayerbackend.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import xin.merlin.myplayerbackend.entity.Playrooms; +import xin.merlin.myplayerbackend.mapper.PlayroomsMapper; + +@Service +public class PlayroomsServiceImpl extends ServiceImpl { +} diff --git a/src/main/java/xin/merlin/myplayerbackend/utils/JwtUtil.java b/src/main/java/xin/merlin/myplayerbackend/utils/JwtUtil.java index b67f8bc..2d26235 100644 --- a/src/main/java/xin/merlin/myplayerbackend/utils/JwtUtil.java +++ b/src/main/java/xin/merlin/myplayerbackend/utils/JwtUtil.java @@ -38,14 +38,14 @@ public class JwtUtil { /** * 生成 JWT Token */ - public String generateToken(String uAccount, Integer uId) { + public String generateToken(String account, Integer id) { Date now = new Date(); Date expireDate = new Date(now.getTime() + jwtProperties.getExpire() * 1000L); return Jwts.builder() - .subject(uAccount) - .claim("id", uId) - .claim("account", uAccount) + .subject(account) + .claim("id", id) + .claim("account", account) .id(UUID.randomUUID().toString()) .issuedAt(now) .expiration(expireDate) @@ -82,7 +82,7 @@ public class JwtUtil { /** * 获取账号 */ - public String getUAccount(String token) { + public String getAccount(String token) { Claims claims = getClaims(token); return claims.getSubject(); } @@ -90,9 +90,9 @@ public class JwtUtil { /** * 获取用户ID */ - public String getUId(String token) { + public Integer getId(String token) { Claims claims = getClaims(token); - return claims.get("id", String.class); + return claims.get("id", Integer.class); } // 自定义异常类 diff --git a/src/main/java/xin/merlin/myplayerbackend/utils/RandomCode.java b/src/main/java/xin/merlin/myplayerbackend/utils/RandomCode.java new file mode 100644 index 0000000..9117463 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/utils/RandomCode.java @@ -0,0 +1,20 @@ +package xin.merlin.myplayerbackend.utils; + + +import java.util.Random; + +public class RandomCode { + + private static final Random rand = new Random(); + + public static String generateID(){ + // 生成一个0到999999999的随机数,然后格式化为9位数字字符串 + return String.format("%09d", rand.nextInt(1000000000)); + } + + public static String generateCode(){ + // 生成一个0到999999的随机数,然后格式化为6位数字字符串 + return String.format("%06d", rand.nextInt(1000000)); + } + +} diff --git a/src/main/java/xin/merlin/myplayerbackend/utils/SecretKeyGenerator.java b/src/main/java/xin/merlin/myplayerbackend/utils/SecretKeyGenerator.java new file mode 100644 index 0000000..e15ccc2 --- /dev/null +++ b/src/main/java/xin/merlin/myplayerbackend/utils/SecretKeyGenerator.java @@ -0,0 +1,15 @@ +package xin.merlin.myplayerbackend.utils; + +import io.jsonwebtoken.security.Keys; + +import javax.crypto.SecretKey; +import java.util.Base64; + +public class SecretKeyGenerator { + public static void main(String[] args) { + SecretKey key = Keys.secretKeyFor(io.jsonwebtoken.SignatureAlgorithm.HS256); + String base64Key = Base64.getEncoder().encodeToString(key.getEncoded()); + System.out.println("Your secure Base64 key:"); + System.out.println(base64Key); + } +} diff --git a/src/main/java/xin/merlin/myplayerbackend/utils/result/Response.java b/src/main/java/xin/merlin/myplayerbackend/utils/result/Response.java index 0d3aab7..f3bbbee 100644 --- a/src/main/java/xin/merlin/myplayerbackend/utils/result/Response.java +++ b/src/main/java/xin/merlin/myplayerbackend/utils/result/Response.java @@ -10,23 +10,23 @@ import java.time.LocalDateTime; @NoArgsConstructor @AllArgsConstructor public class Response { - private int code; + private String code; private String message; private T data; // 请求成功 public static Response success(ResultCode code , T data){ - System.out.println( LocalDateTime.now()+" success : \n"+code); + System.out.println( LocalDateTime.now()+" success : "+code); return new Response(code.getCode(), code.getMessage(), data); } public static Response success(ResultCode code){ - System.out.println( LocalDateTime.now()+" success : \n"+code); + System.out.println( LocalDateTime.now()+" success : "+code); return new Response(code.getCode(), code.getMessage(),null); } // 请求失败 public static Response fail(ResultCode code){ - System.out.println( LocalDateTime.now()+" fail : \n"+code); + System.out.println( LocalDateTime.now()+" fail : "+code); return new Response(code.getCode(),code.getMessage(), null); } diff --git a/src/main/java/xin/merlin/myplayerbackend/utils/result/ResultCode.java b/src/main/java/xin/merlin/myplayerbackend/utils/result/ResultCode.java index d1910f9..c5b3df0 100644 --- a/src/main/java/xin/merlin/myplayerbackend/utils/result/ResultCode.java +++ b/src/main/java/xin/merlin/myplayerbackend/utils/result/ResultCode.java @@ -8,29 +8,42 @@ import lombok.Getter; @Getter public enum ResultCode { - SUCCESS(200, "成功"), - BAD_REQUEST(400, "请求参数错误"), - UNAUTHORIZED(401, "未认证或登录已过期"), - FORBIDDEN(403, "无权限访问"), - NOT_FOUND(404, "资源不存在"), - SERVER_ERROR(500, "服务器内部错误"), + SUCCESS("200", "成功"), + BAD_REQUEST("400", "请求参数错误"), + UNAUTHORIZED("401", "未认证或登录已过期"), + FORBIDDEN("403", "无权限访问"), + NOT_FOUND("404", "资源不存在"), + SERVER_ERROR("500", "服务器内部错误"), // 自定义业务错误码 - USER_BANNED(1000,"用户被封禁"), - USER_NOT_FOUND(1001, "用户不存在"), - USER_EXIST(1003,"用户已存在"), - USER_PASSWORD_ERROR(1004,"用户密码错误"), - USER_VERIFICATION_ERROR(1005,"验证码不存在或错误"), - USER_SEND_TOO_FAST(1006,"用户请求过快"), - USER_SEND_TOO_OFTEN(1007,"请求次数过多,已被限制"), - ORDER_NOT_FOUND(2000, "订单不存在"); + + //账户相关 + ACCOUNT_EXIST("2001","账户已存在"), + + //用户相关 + USER_BANNED("4000","用户被封禁"), + USER_NOT_FOUND("4001", "用户不存在"), + USER_EXIST("4003","用户已存在"), + USER_PASSWORD_ERROR("4004","用户密码错误"), + USER_VERIFICATION_ERROR("4005","验证码不存在或错误"), + USER_SEND_TOO_FAST("4006","用户请求过快"), + USER_SEND_TOO_OFTEN("4007","请求次数过多,已被限制"), + ORDER_NOT_FOUND("4000", "订单不存在"), + + //邮箱相关 + MAIL_ACCOUNT_NOT_PROVIDED("4101","未提供验证码接受账户"), + MAIL_REQUEST_TOO_FAST("4102","验证码请求过于频繁"), + MAIL_INFO_LOST("4103","验证信息丢失"), + MAIL_VERIFY_FAIL_TOO_MANY("4104","验证码错误过多,请重新申请验证码"), + MAIL_VERIFY_NOT_EXIST("4105","验证码元素丢失,请重新申请验证码"), + MAIL_VERIFY_CODE_ERROR("4106","验证码错误,请重新输入"); - private final int code; + private final String code; private final String message; - ResultCode(int code, String message) { + ResultCode(String code, String message) { this.code = code; this.message = message; }