Initialize patbond microservice modules
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.patbond.patbond</groupId>
|
||||||
|
<artifactId>patbond-api</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>patbond-auth</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>patbond-auth</name>
|
||||||
|
<description>Authentication service for Patbond</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.patbond.patbond</groupId>
|
||||||
|
<artifactId>patbond-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.patbond.patbond.auth;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
|
||||||
|
@EnableFeignClients
|
||||||
|
@SpringBootApplication
|
||||||
|
public class AuthApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(AuthApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.patbond.patbond.auth.client;
|
||||||
|
|
||||||
|
import com.patbond.patbond.common.response.ApiResponse;
|
||||||
|
import com.patbond.patbond.common.user.CreateUserRequest;
|
||||||
|
import com.patbond.patbond.common.user.UserProfile;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordRequest;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordResponse;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
@FeignClient(name = "patbond-user")
|
||||||
|
public interface UserClient {
|
||||||
|
|
||||||
|
@PostMapping("/internal/users")
|
||||||
|
ApiResponse<UserProfile> createUser(@RequestBody CreateUserRequest request);
|
||||||
|
|
||||||
|
@PostMapping("/internal/users/verify-password")
|
||||||
|
ApiResponse<VerifyPasswordResponse> verifyPassword(@RequestBody VerifyPasswordRequest request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.patbond.patbond.auth.controller;
|
||||||
|
|
||||||
|
import com.patbond.patbond.auth.dto.AuthTokenResponse;
|
||||||
|
import com.patbond.patbond.auth.dto.LoginRequest;
|
||||||
|
import com.patbond.patbond.auth.dto.RegisterRequest;
|
||||||
|
import com.patbond.patbond.auth.service.AuthService;
|
||||||
|
import com.patbond.patbond.common.response.ApiResponse;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/auth")
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final AuthService authService;
|
||||||
|
|
||||||
|
public AuthController(AuthService authService) {
|
||||||
|
this.authService = authService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/register")
|
||||||
|
public ApiResponse<AuthTokenResponse> register(@Valid @RequestBody RegisterRequest request) {
|
||||||
|
return ApiResponse.success(authService.register(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public ApiResponse<AuthTokenResponse> login(@Valid @RequestBody LoginRequest request) {
|
||||||
|
return ApiResponse.success(authService.login(request));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.patbond.patbond.auth.dto;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class AuthTokenResponse {
|
||||||
|
|
||||||
|
private String tokenType;
|
||||||
|
private String accessToken;
|
||||||
|
private LocalDateTime expiresAt;
|
||||||
|
private Long userId;
|
||||||
|
private String username;
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
public AuthTokenResponse(String tokenType, String accessToken, LocalDateTime expiresAt,
|
||||||
|
Long userId, String username, String nickname) {
|
||||||
|
this.tokenType = tokenType;
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
this.expiresAt = expiresAt;
|
||||||
|
this.userId = userId;
|
||||||
|
this.username = username;
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTokenType() {
|
||||||
|
return tokenType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getExpiresAt() {
|
||||||
|
return expiresAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.patbond.patbond.auth.dto;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
public class LoginRequest {
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.patbond.patbond.auth.dto;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
public class RegisterRequest {
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@Size(min = 3, max = 32, message = "用户名长度必须在3到32位之间")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
@Size(min = 6, max = 64, message = "密码长度必须在6到64位之间")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Size(max = 32, message = "昵称长度不能超过32位")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@Size(max = 20, message = "手机号长度不能超过20位")
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickname(String nickname) {
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.patbond.patbond.auth.service;
|
||||||
|
|
||||||
|
import com.patbond.patbond.auth.client.UserClient;
|
||||||
|
import com.patbond.patbond.auth.dto.AuthTokenResponse;
|
||||||
|
import com.patbond.patbond.auth.dto.LoginRequest;
|
||||||
|
import com.patbond.patbond.auth.dto.RegisterRequest;
|
||||||
|
import com.patbond.patbond.common.response.ApiResponse;
|
||||||
|
import com.patbond.patbond.common.user.CreateUserRequest;
|
||||||
|
import com.patbond.patbond.common.user.UserProfile;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordRequest;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordResponse;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AuthService {
|
||||||
|
|
||||||
|
private final UserClient userClient;
|
||||||
|
|
||||||
|
public AuthService(UserClient userClient) {
|
||||||
|
this.userClient = userClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthTokenResponse register(RegisterRequest request) {
|
||||||
|
ApiResponse<UserProfile> response = userClient.createUser(new CreateUserRequest(
|
||||||
|
request.getUsername(),
|
||||||
|
request.getPassword(),
|
||||||
|
request.getNickname(),
|
||||||
|
request.getPhone()
|
||||||
|
));
|
||||||
|
UserProfile user = requireData(response, "注册失败");
|
||||||
|
return buildToken(user.getId(), user.getUsername(), user.getNickname());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthTokenResponse login(LoginRequest request) {
|
||||||
|
ApiResponse<VerifyPasswordResponse> response = userClient.verifyPassword(
|
||||||
|
new VerifyPasswordRequest(request.getUsername(), request.getPassword())
|
||||||
|
);
|
||||||
|
VerifyPasswordResponse user = requireData(response, "登录失败");
|
||||||
|
return buildToken(user.getUserId(), user.getUsername(), user.getNickname());
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthTokenResponse buildToken(Long userId, String username, String nickname) {
|
||||||
|
return new AuthTokenResponse(
|
||||||
|
"Bearer",
|
||||||
|
UUID.randomUUID().toString().replace("-", ""),
|
||||||
|
LocalDateTime.now().plusHours(2),
|
||||||
|
userId,
|
||||||
|
username,
|
||||||
|
nickname
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T requireData(ApiResponse<T> response, String defaultMessage) {
|
||||||
|
if (response == null || !response.isSuccess() || response.getData() == null) {
|
||||||
|
String message = response == null || response.getMessage() == null ? defaultMessage : response.getMessage();
|
||||||
|
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, message);
|
||||||
|
}
|
||||||
|
return response.getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: patbond-auth
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
|
config:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: patbond-auth
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
|
config:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
|||||||
|
com/patbond/patbond/auth/dto/RegisterRequest.class
|
||||||
|
com/patbond/patbond/auth/AuthApplication.class
|
||||||
|
com/patbond/patbond/auth/dto/AuthTokenResponse.class
|
||||||
|
com/patbond/patbond/auth/client/UserClient.class
|
||||||
|
com/patbond/patbond/auth/controller/AuthController.class
|
||||||
|
com/patbond/patbond/auth/dto/LoginRequest.class
|
||||||
|
com/patbond/patbond/auth/service/AuthService.class
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/AuthApplication.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/client/UserClient.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/controller/AuthController.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/dto/AuthTokenResponse.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/dto/LoginRequest.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/dto/RegisterRequest.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/service/AuthService.java
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.patbond.patbond</groupId>
|
||||||
|
<artifactId>patbond-api</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>patbond-common</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>patbond-common</name>
|
||||||
|
<description>Common dependencies and shared code for Patbond services</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Shared code for Patbond microservices.
|
||||||
|
*/
|
||||||
|
package com.patbond.patbond.common;
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.patbond.patbond.common.response;
|
||||||
|
|
||||||
|
public class ApiResponse<T> {
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
private String message;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public ApiResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiResponse(Integer code, String message, T data) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ApiResponse<T> success(T data) {
|
||||||
|
return new ApiResponse<>(0, "success", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ApiResponse<T> failure(Integer code, String message) {
|
||||||
|
return new ApiResponse<>(code, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return Integer.valueOf(0).equals(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(T data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.patbond.patbond.common.user;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
public class CreateUserRequest {
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@Size(min = 3, max = 32, message = "用户名长度必须在3到32位之间")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
@Size(min = 6, max = 64, message = "密码长度必须在6到64位之间")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Size(max = 32, message = "昵称长度不能超过32位")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@Size(max = 20, message = "手机号长度不能超过20位")
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
public CreateUserRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateUserRequest(String username, String password, String nickname, String phone) {
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.nickname = nickname;
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickname(String nickname) {
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.patbond.patbond.common.user;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class UserProfile {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String username;
|
||||||
|
private String nickname;
|
||||||
|
private String phone;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
public UserProfile() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProfile(Long id, String username, String nickname, String phone, LocalDateTime createdAt) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.nickname = nickname;
|
||||||
|
this.phone = phone;
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickname(String nickname) {
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(LocalDateTime createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package com.patbond.patbond.common.user;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
public class VerifyPasswordRequest {
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public VerifyPasswordRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public VerifyPasswordRequest(String username, String password) {
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
package com.patbond.patbond.common.user;
|
||||||
|
|
||||||
|
public class VerifyPasswordResponse {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
private String username;
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
public VerifyPasswordResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public VerifyPasswordResponse(Long userId, String username, String nickname) {
|
||||||
|
this.userId = userId;
|
||||||
|
this.username = username;
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(Long userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickname(String nickname) {
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+6
@@ -0,0 +1,6 @@
|
|||||||
|
com/patbond/patbond/common/user/CreateUserRequest.class
|
||||||
|
com/patbond/patbond/common/user/VerifyPasswordRequest.class
|
||||||
|
com/patbond/patbond/common/package-info.class
|
||||||
|
com/patbond/patbond/common/user/UserProfile.class
|
||||||
|
com/patbond/patbond/common/response/ApiResponse.class
|
||||||
|
com/patbond/patbond/common/user/VerifyPasswordResponse.class
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-common/src/main/java/com/patbond/patbond/common/package-info.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-common/src/main/java/com/patbond/patbond/common/response/ApiResponse.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-common/src/main/java/com/patbond/patbond/common/user/CreateUserRequest.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-common/src/main/java/com/patbond/patbond/common/user/UserProfile.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-common/src/main/java/com/patbond/patbond/common/user/VerifyPasswordRequest.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-common/src/main/java/com/patbond/patbond/common/user/VerifyPasswordResponse.java
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.patbond.patbond</groupId>
|
||||||
|
<artifactId>patbond-api</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>patbond-user</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>patbond-user</name>
|
||||||
|
<description>User service for Patbond</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.patbond.patbond</groupId>
|
||||||
|
<artifactId>patbond-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-crypto</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.patbond.patbond.user;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class UserApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(UserApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.patbond.patbond.user.controller;
|
||||||
|
|
||||||
|
import com.patbond.patbond.common.response.ApiResponse;
|
||||||
|
import com.patbond.patbond.common.user.CreateUserRequest;
|
||||||
|
import com.patbond.patbond.common.user.UserProfile;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordRequest;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordResponse;
|
||||||
|
import com.patbond.patbond.user.service.UserService;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/internal/users")
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
public UserController(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public ApiResponse<UserProfile> createUser(@Valid @RequestBody CreateUserRequest request) {
|
||||||
|
return ApiResponse.success(userService.createUser(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/verify-password")
|
||||||
|
public ApiResponse<VerifyPasswordResponse> verifyPassword(@Valid @RequestBody VerifyPasswordRequest request) {
|
||||||
|
return ApiResponse.success(userService.verifyPassword(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ApiResponse<UserProfile> getById(@PathVariable Long id) {
|
||||||
|
return ApiResponse.success(userService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/by-username/{username}")
|
||||||
|
public ApiResponse<UserProfile> getByUsername(@PathVariable String username) {
|
||||||
|
return ApiResponse.success(userService.getByUsername(username));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package com.patbond.patbond.user.service;
|
||||||
|
|
||||||
|
import com.patbond.patbond.common.user.CreateUserRequest;
|
||||||
|
import com.patbond.patbond.common.user.UserProfile;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordRequest;
|
||||||
|
import com.patbond.patbond.common.user.VerifyPasswordResponse;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
private final AtomicLong idGenerator = new AtomicLong(1);
|
||||||
|
private final Map<Long, UserRecord> usersById = new ConcurrentHashMap<>();
|
||||||
|
private final Map<String, UserRecord> usersByUsername = new ConcurrentHashMap<>();
|
||||||
|
private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||||
|
|
||||||
|
public synchronized UserProfile createUser(CreateUserRequest request) {
|
||||||
|
String username = request.getUsername().trim();
|
||||||
|
if (usersByUsername.containsKey(username)) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.CONFLICT, "用户名已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
UserRecord user = new UserRecord(
|
||||||
|
idGenerator.getAndIncrement(),
|
||||||
|
username,
|
||||||
|
passwordEncoder.encode(request.getPassword()),
|
||||||
|
normalizeBlank(request.getNickname()),
|
||||||
|
normalizeBlank(request.getPhone()),
|
||||||
|
LocalDateTime.now()
|
||||||
|
);
|
||||||
|
usersById.put(user.getId(), user);
|
||||||
|
usersByUsername.put(user.getUsername(), user);
|
||||||
|
return toProfile(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VerifyPasswordResponse verifyPassword(VerifyPasswordRequest request) {
|
||||||
|
UserRecord user = usersByUsername.get(request.getUsername().trim());
|
||||||
|
if (user == null || !passwordEncoder.matches(request.getPassword(), user.getPasswordHash())) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "用户名或密码错误");
|
||||||
|
}
|
||||||
|
return new VerifyPasswordResponse(user.getId(), user.getUsername(), user.getNickname());
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProfile getById(Long id) {
|
||||||
|
UserRecord user = usersById.get(id);
|
||||||
|
if (user == null) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "用户不存在");
|
||||||
|
}
|
||||||
|
return toProfile(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProfile getByUsername(String username) {
|
||||||
|
UserRecord user = usersByUsername.get(username.trim());
|
||||||
|
if (user == null) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "用户不存在");
|
||||||
|
}
|
||||||
|
return toProfile(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserProfile toProfile(UserRecord user) {
|
||||||
|
return new UserProfile(user.getId(), user.getUsername(), user.getNickname(), user.getPhone(), user.getCreatedAt());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String normalizeBlank(String value) {
|
||||||
|
return value == null || value.trim().isEmpty() ? null : value.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UserRecord {
|
||||||
|
|
||||||
|
private final Long id;
|
||||||
|
private final String username;
|
||||||
|
private final String passwordHash;
|
||||||
|
private final String nickname;
|
||||||
|
private final String phone;
|
||||||
|
private final LocalDateTime createdAt;
|
||||||
|
|
||||||
|
private UserRecord(Long id, String username, String passwordHash, String nickname, String phone,
|
||||||
|
LocalDateTime createdAt) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.passwordHash = passwordHash;
|
||||||
|
this.nickname = nickname;
|
||||||
|
this.phone = phone;
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPasswordHash() {
|
||||||
|
return passwordHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
server:
|
||||||
|
port: 8082
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: patbond-user
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
|
config:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
server:
|
||||||
|
port: 8082
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: patbond-user
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
|
config:
|
||||||
|
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
+5
@@ -0,0 +1,5 @@
|
|||||||
|
com/patbond/patbond/user/service/UserService$1.class
|
||||||
|
com/patbond/patbond/user/UserApplication.class
|
||||||
|
com/patbond/patbond/user/service/UserService$UserRecord.class
|
||||||
|
com/patbond/patbond/user/controller/UserController.class
|
||||||
|
com/patbond/patbond/user/service/UserService.class
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-user/src/main/java/com/patbond/patbond/user/UserApplication.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-user/src/main/java/com/patbond/patbond/user/controller/UserController.java
|
||||||
|
/home/zyx/workspace/duoduo/patbond/patbond-api/patbond-user/src/main/java/com/patbond/patbond/user/service/UserService.java
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.patbond.patbond</groupId>
|
||||||
|
<artifactId>patbond-api</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<name>patbond-api</name>
|
||||||
|
<description>Patbond microservice parent project</description>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>patbond-common</module>
|
||||||
|
<module>patbond-user</module>
|
||||||
|
<module>patbond-auth</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
|
<spring-boot.version>2.7.18</spring-boot.version>
|
||||||
|
<spring-cloud.version>2021.0.9</spring-cloud.version>
|
||||||
|
<spring-cloud-alibaba.version>2021.0.6.0</spring-cloud-alibaba.version>
|
||||||
|
<lombok.version>1.18.36</lombok.version>
|
||||||
|
<hutool.version>5.8.35</hutool.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud-alibaba.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
<encoding>${project.build.sourceEncoding}</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
Reference in New Issue
Block a user