From c7cf779d83edac3fe5f6f408d3bf77f6b633f6b1 Mon Sep 17 00:00:00 2001 From: violet-77-0826 <2570312936@qq.com> Date: Wed, 10 Sep 2025 14:42:50 +0800 Subject: [PATCH 01/23] =?UTF-8?q?qa-service-application=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/gradle.xml | 1 + qa-service/qa-service-application/pom.xml | 61 +++++++++++++++++++ .../application/command/CreateQaCommand.java | 11 ++++ .../application/command/UpdateQaCommand.java | 10 +++ .../application/port/in/CreateQaUseCase.java | 8 +++ .../application/port/in/DeleteQaUseCase.java | 5 ++ .../application/port/in/GetQaByIdUseCase.java | 7 +++ .../application/port/in/GetQaListUseCase.java | 9 +++ .../application/port/in/UpdateQaUseCase.java | 8 +++ .../application/service/CreateQaService.java | 30 +++++++++ .../application/service/DeleteQaService.java | 15 +++++ .../application/service/GetQaByIdService.java | 18 ++++++ .../application/service/GetQaListService.java | 21 +++++++ .../application/service/UpdateQaService.java | 28 +++++++++ 14 files changed, 232 insertions(+) create mode 100644 qa-service/qa-service-application/pom.xml create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java diff --git a/.idea/gradle.xml b/.idea/gradle.xml index c4be5fb..514d7a6 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,5 +1,6 @@ + diff --git a/qa-service/qa-service-application/pom.xml b/qa-service/qa-service-application/pom.xml new file mode 100644 index 0000000..78ac32d --- /dev/null +++ b/qa-service/qa-service-application/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + com.example + user-service-application + 0.0.1-SNAPSHOT + user-service-application + user-service-application + + + com.example + user-service + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + provided + + + + com.example + user-service-domain + 0.0.1-SNAPSHOT + + + org.projectlombok + lombok + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java new file mode 100644 index 0000000..8b93e4e --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java @@ -0,0 +1,11 @@ +package com.example.qa.service.application.command; + +import lombok.Builder; + +@Builder +public record CreateQaCommand( + Long id, + String name, + Integer age, + String email +){} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java new file mode 100644 index 0000000..add3235 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java @@ -0,0 +1,10 @@ +package com.example.qa.service.application.command; + +import lombok.Builder; + +@Builder +public record UpdateQaCommand(Long id, + String name, + Integer age, + String email) { +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java new file mode 100644 index 0000000..84c2ccb --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java @@ -0,0 +1,8 @@ +package com.example.qa.service.application.port.in; + +import com.example.user.service.application.command.CreateUserCommand; +import com.example.user.service.domain.User; + +public interface CreateQaUseCase { + User createUser(CreateQaCommand qaCommand); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java new file mode 100644 index 0000000..5d28dae --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java @@ -0,0 +1,5 @@ +package com.example.qa.service.application.port.in; + +public interface DeleteQaUseCase { + void deleteQa(Long id); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java new file mode 100644 index 0000000..6157b12 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java @@ -0,0 +1,7 @@ +package com.example.qa.service.application.port.in; + +import com.example.user.service.domain.User; + +public interface GetQaByIdUseCase { + User getQaById(Long id); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java new file mode 100644 index 0000000..c6b2100 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java @@ -0,0 +1,9 @@ +package com.example.qa.service.application.port.in; + +import com.example.user.service.domain.User; + +import java.util.List; + +public interface GetQaListUseCase { + List getQas(); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java new file mode 100644 index 0000000..d548bd9 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java @@ -0,0 +1,8 @@ +package com.example.qa.service.application.port.in; + +import com.example.user.service.application.command.UpdateUserCommand; +import com.example.user.service.domain.User; + +public interface UpdateQaUseCase { + User updateUser(UpdateQaCommand command); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java new file mode 100644 index 0000000..4146079 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java @@ -0,0 +1,30 @@ +package com.example.qa.service.application.service; + +import com.example.qa.service.application.command.CreateQaCommand; +import com.example.qa.service.application.port.in.CreateQaUseCase; +import com.example.qa.service.domain.User; +import com.example.qa.service.domain.port.CreateUserPort; +import com.example.qa.service.domain.valueobject.Email; +import com.example.qa.service.domain.valueobject.UserAge; +import com.example.qa.service.domain.valueobject.UserName; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class CreateQaService implements CreateQaUseCase { + @Resource + private CreateQaPort createUserPort; + @Override + public Qa createUser(CreateQaCommand createUserCommand) { + //command -> domain + Qa qa=new Qa( + new UserName(createQaCommand.name()), + new UserAge(createQaCommand.age()), + new Email(createQaCommand.email()) + ); + log.info("qa:{}",qa); + return createUserPort.createQa(qa); + } +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java new file mode 100644 index 0000000..64150e6 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java @@ -0,0 +1,15 @@ +package com.example.qa.service.application.service; + +import com.example.qa.service.application.port.in.DeleteQaUseCase; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +@Service +public class DeleteQaService implements DeleteQaUseCase { + @Resource + private DeleteQaPort deleteQaPort; + @Override + public void deleteUser(Long id) { + deleteQaPort.deleteQa(id); + } +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java new file mode 100644 index 0000000..6a1dde9 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java @@ -0,0 +1,18 @@ +package com.example.qa.service.application.service; + +import com.example.user.service.application.port.in.GetUserByIdUseCase; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserByIdPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +@Service +public class GetQaByIdService implements GetUserByIdUseCase { + + @Resource + private GetUserByIdPort getUserByIdPort; + @Override + public User getUserById(Long id) { + return getUserByIdPort.getUserById(id); + } +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java new file mode 100644 index 0000000..004a5b3 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java @@ -0,0 +1,21 @@ +package com.example.qa.service.application.service; + +import com.example.user.service.application.port.in.GetUserListUseCase; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserListPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class GetQaListService implements GetUserListUseCase { + + @Resource + GetUserListPort getUserListPort; + @Override + public List getUsers() { + List users = User.getUsers(getUserListPort); + return users; + } +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java new file mode 100644 index 0000000..dfb889e --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java @@ -0,0 +1,28 @@ +package com.example.qa.service.application.service; + +import com.example.user.service.application.command.UpdateUserCommand; +import com.example.user.service.application.port.in.UpdateUserUseCase; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.UpdateUserPort; +import com.example.user.service.domain.valueobject.Email; +import com.example.user.service.domain.valueobject.UserAge; +import com.example.user.service.domain.valueobject.UserId; +import com.example.user.service.domain.valueobject.UserName; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +@Service +public class UpdateQaService implements UpdateUserUseCase { + @Resource + private UpdateUserPort updateUserPort; + + @Override + public User updateUser(UpdateUserCommand command) { + User user = new User( + new UserId(command.id()), + new UserName(command.name()), + new UserAge(command.age()), + new Email(command.email())); + return updateUserPort.updateUser(user); + } +} -- Gitee From bfe36d8ad68c3abe2be6ae5b05d0aff43265470f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Wed, 10 Sep 2025 15:32:52 +0800 Subject: [PATCH 02/23] =?UTF-8?q?=E7=9B=AE=E5=89=8D=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=9E=B6=E6=9E=84=EF=BC=8C=E5=87=86=E5=A4=87?= =?UTF-8?q?=E6=8C=89=E7=85=A7=E5=88=86=E5=B7=A5=E5=BC=80=E5=A7=8B=E5=86=99?= =?UTF-8?q?=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 13 +++++ .idea/encodings.xml | 4 +- .idea/misc.xml | 14 +++++ qa-service/pom.xml | 6 +- qa-service/{ => qa-service-domain}/.gitignore | 0 qa-service/qa-service-domain/pom.xml | 57 +++++++++++++++++++ .../com/example/user/service/domain/User.java | 48 ++++++++++++++++ .../service/domain/port/CreateUserPort.java | 7 +++ .../service/domain/port/DeleteUserPort.java | 5 ++ .../service/domain/port/GetUserByIdPort.java | 7 +++ .../service/domain/port/GetUserListPort.java | 9 +++ .../service/domain/port/UpdateUserPort.java | 7 +++ .../service/domain/valueobject/Email.java | 7 +++ .../service/domain/valueobject/UserAge.java | 7 +++ .../service/domain/valueobject/UserId.java | 9 +++ .../service/domain/valueobject/UserName.java | 7 +++ 16 files changed, 203 insertions(+), 4 deletions(-) rename qa-service/{ => qa-service-domain}/.gitignore (100%) create mode 100644 qa-service/qa-service-domain/pom.xml create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index a1757ae..1dbe11b 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -3,6 +3,19 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml index da0415a..7b5b33a 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,4 +1,6 @@ - + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 7280f00..fdcfc8b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,4 +3,18 @@ + + + + + + \ No newline at end of file diff --git a/qa-service/pom.xml b/qa-service/pom.xml index 0b70349..476ca31 100644 --- a/qa-service/pom.xml +++ b/qa-service/pom.xml @@ -8,7 +8,7 @@ qa-service qa-service - 17 + 21 UTF-8 UTF-8 3.0.2 @@ -44,8 +44,8 @@ maven-compiler-plugin 3.8.1 - 17 - 17 + 21 + 21 UTF-8 diff --git a/qa-service/.gitignore b/qa-service/qa-service-domain/.gitignore similarity index 100% rename from qa-service/.gitignore rename to qa-service/qa-service-domain/.gitignore diff --git a/qa-service/qa-service-domain/pom.xml b/qa-service/qa-service-domain/pom.xml new file mode 100644 index 0000000..a561c5e --- /dev/null +++ b/qa-service/qa-service-domain/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + com.example + qa-service-domain + 0.0.1-SNAPSHOT + qa-service-domain + qa-service-domain + + + com.example + qa-service + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + provided + + + + com.example + qa-service-common + 0.0.1-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + + diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java new file mode 100644 index 0000000..f3ee515 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -0,0 +1,48 @@ +package com.example.user.service.domain; + +import com.example.user.service.common.IdWorker; +import com.example.user.service.domain.port.GetUserListPort; +import com.example.user.service.domain.valueobject.Email; +import com.example.user.service.domain.valueobject.UserAge; +import com.example.user.service.domain.valueobject.UserId; +import com.example.user.service.domain.valueobject.UserName; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@ToString +public class User { + private UserId id; + private UserName name; + private UserAge age; + private Email email; + + public User() { + } + + public User(UserId id, UserName name, UserAge age, Email email) { + this.id = id; + this.name = name; + this.age = age; + this.email = email; + } + + public User( UserName name, UserAge age, Email email) { + this.id= genId() ; + this.name = name; + this.age = age; + this.email = email; + } + + public static List getUsers(GetUserListPort getUserListPort){ + return getUserListPort.getUsers(); + } + + public UserId genId(){ + return new UserId(new IdWorker().nextId()); + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java new file mode 100644 index 0000000..77a2a96 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java @@ -0,0 +1,7 @@ +package com.example.user.service.domain.port; + +import com.example.user.service.domain.User; + +public interface CreateUserPort { + User createUser(User user); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java new file mode 100644 index 0000000..a7d10a1 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java @@ -0,0 +1,5 @@ +package com.example.user.service.domain.port; + +public interface DeleteUserPort { + void deleteUser(Long id); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java new file mode 100644 index 0000000..7163ec8 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java @@ -0,0 +1,7 @@ +package com.example.user.service.domain.port; + +import com.example.user.service.domain.User; + +public interface GetUserByIdPort { + User getUserById(Long id); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java new file mode 100644 index 0000000..2ad8e17 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java @@ -0,0 +1,9 @@ +package com.example.user.service.domain.port; + +import com.example.user.service.domain.User; + +import java.util.List; + +public interface GetUserListPort { + List getUsers(); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java new file mode 100644 index 0000000..9a7ffd0 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java @@ -0,0 +1,7 @@ +package com.example.user.service.domain.port; + +import com.example.user.service.domain.User; + +public interface UpdateUserPort { + User updateUser(User user); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java new file mode 100644 index 0000000..f83b243 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java @@ -0,0 +1,7 @@ +package com.example.user.service.domain.valueobject; + +public record Email(String email) { + public String getValue() { + return email; + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java new file mode 100644 index 0000000..38ef937 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java @@ -0,0 +1,7 @@ +package com.example.user.service.domain.valueobject; + +public record UserAge(int age) { + public int getValue() { + return age; + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java new file mode 100644 index 0000000..bf3ce0b --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java @@ -0,0 +1,9 @@ +package com.example.user.service.domain.valueobject; + +public record UserId(long id) { + + public long getValue(){ + return id; + } + +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java new file mode 100644 index 0000000..0c11a15 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java @@ -0,0 +1,7 @@ +package com.example.user.service.domain.valueobject; + +public record UserName(String username) { + public String getValue() { + return username; + } +} -- Gitee From 60abdea3187ab7119b6c1c4ab29c325f6993f786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Wed, 10 Sep 2025 16:03:10 +0800 Subject: [PATCH 03/23] =?UTF-8?q?=E7=9B=AE=E5=89=8D=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=9E=B6=E6=9E=84=EF=BC=8C=E5=87=86=E5=A4=87?= =?UTF-8?q?=E6=8C=89=E7=85=A7=E5=88=86=E5=B7=A5=E5=BC=80=E5=A7=8B=E5=86=99?= =?UTF-8?q?=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qa-service/qa-service-adapter/pom.xml | 39 ++++ .../qa-adapter-in/.gitignore | 33 +++ .../qa-service-adapter/qa-adapter-in/pom.xml | 38 ++++ .../qa-adapter-in-web/.gitignore | 33 +++ .../qa-adapter-in/qa-adapter-in-web/pom.xml | 61 ++++++ .../in/web/controller/UserController.java | 86 ++++++++ .../in/web/dto/CreateUserRequestDTO.java | 8 + .../in/web/dto/UpdateUserRequestDTO.java | 7 + .../adapter/in/web/dto/UserResponseDTO.java | 15 ++ .../qa-service-adapter/qa-adapter-out/pom.xml | 38 ++++ .../qa-adapter-out-persistence/.gitignore | 33 +++ .../qa-adapter-out-persistence/pom.xml | 57 +++++ .../persistence/bridge/CreateUserBridge.java | 26 +++ .../persistence/bridge/DeleteUserBridge.java | 19 ++ .../persistence/bridge/GetUserByIdBridge.java | 22 ++ .../persistence/bridge/GetUserListBridge.java | 32 +++ .../persistence/bridge/UpdateUserBridge.java | 23 ++ .../persistence/convertor/UserConvertor.java | 29 +++ .../out/persistence/entity/UserEntity.java | 20 ++ .../out/persistence/mapper/UserMapper.java | 7 + qa-service/qa-service-bootstrap/pom.xml | 92 ++++++++ .../QaServiceBootstrapApplication.java | 15 ++ .../src/main/resources/application.properties | 27 +++ qa-service/qa-service-common/.gitignore | 33 +++ qa-service/qa-service-common/pom.xml | 72 +++++++ .../example/qr/service/common/IdWorker.java | 199 ++++++++++++++++++ 26 files changed, 1064 insertions(+) create mode 100644 qa-service/qa-service-adapter/pom.xml create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/.gitignore create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/pom.xml create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/.gitignore create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/pom.xml create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/.gitignore create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java create mode 100644 qa-service/qa-service-bootstrap/pom.xml create mode 100644 qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java create mode 100644 qa-service/qa-service-bootstrap/src/main/resources/application.properties create mode 100644 qa-service/qa-service-common/.gitignore create mode 100644 qa-service/qa-service-common/pom.xml create mode 100644 qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java diff --git a/qa-service/qa-service-adapter/pom.xml b/qa-service/qa-service-adapter/pom.xml new file mode 100644 index 0000000..3b61e10 --- /dev/null +++ b/qa-service/qa-service-adapter/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + com.example + user-service-adapter + 0.0.1-SNAPSHOT + user-service-adapter + user-service-adapter + + pom + + + com.example + user-service + 0.0.1-SNAPSHOT + + + + user-adapter-in + user-adapter-out + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + diff --git a/qa-service/qa-service-adapter/qa-adapter-in/.gitignore b/qa-service/qa-service-adapter/qa-adapter-in/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/qa-service/qa-service-adapter/qa-adapter-in/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/pom.xml new file mode 100644 index 0000000..cf0b3a2 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + com.example + user-adapter-in + 0.0.1-SNAPSHOT + user-adapter-in + user-adapter-in + + pom + + + com.example + user-service-adapter + 0.0.1-SNAPSHOT + + + + user-adapter-in-web + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/.gitignore b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml new file mode 100644 index 0000000..753f60d --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + com.example + user-adapter-in-web + 0.0.1-SNAPSHOT + user-adapter-in-web + user-adapter-in-web + + + com.example + user-adapter-in + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + provided + + + org.projectlombok + lombok + + + + com.example + user-service-application + 0.0.1-SNAPSHOT + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java new file mode 100644 index 0000000..0d111b2 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -0,0 +1,86 @@ +package com.example.user.adapter.in.web.controller; + +import com.example.user.adapter.in.web.dto.CreateUserRequestDTO; +import com.example.user.adapter.in.web.dto.UpdateUserRequestDTO; +import com.example.user.adapter.in.web.dto.UserResponseDTO; +import com.example.user.service.application.command.CreateUserCommand; +import com.example.user.service.application.command.UpdateUserCommand; +import com.example.user.service.application.port.in.*; +import com.example.user.service.domain.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Slf4j +@RequestMapping("/users") +@RestController +@RequiredArgsConstructor +public class UserController { + + private final GetUserListUseCase getUserListUseCase; + private final CreateUserUseCase createUserUseCase; + private final DeleteUserUseCase deleteUserUseCase; + private final UpdateUserUseCase updateUserUseCase; + private final GetUserByIdUseCase getUserByIdUseCase; + + @GetMapping("") + public List getUsers() { + log.info("getUsers"); + return getUserListUseCase.getUsers(); + } + + @PostMapping() + public User createUser(@RequestBody CreateUserRequestDTO createUserRequestDTO){ + + CreateUserCommand command=CreateUserCommand.builder() + .name(createUserRequestDTO.name()) + .age(createUserRequestDTO.age()) + .email(createUserRequestDTO.email()) + .build(); + + return createUserUseCase.createUser(command); + } + + + @DeleteMapping("{id}") + public String deleteUser(@PathVariable("id") Long id){ + deleteUserUseCase.deleteUser(id); + return "success"; + } + + /** + * @author liuxin + * @param updateUserRequestDTO + * @return + */ + @PutMapping("") + public User updateUser(@RequestBody UpdateUserRequestDTO updateUserRequestDTO){ + UpdateUserCommand command=UpdateUserCommand.builder() + .id(updateUserRequestDTO.id()) + .name(updateUserRequestDTO.name()) + .age(updateUserRequestDTO.age()) + .email(updateUserRequestDTO.email()) + .build(); + User user = updateUserUseCase.updateUser(command); + return user; + } + + + /** + * @author dengli + * @param id + * @return + */ + @GetMapping("{id}") + public UserResponseDTO getUserById(@PathVariable("id") Long id){ + User user = getUserByIdUseCase.getUserById(id); + UserResponseDTO userResponseDTO = new UserResponseDTO( + user.getId().id(), + user.getName().username(), + user.getAge().age(), + user.getEmail().email()); + return userResponseDTO; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java new file mode 100644 index 0000000..386262a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java @@ -0,0 +1,8 @@ +package com.example.user.adapter.in.web.dto; + +public record CreateUserRequestDTO( + String name, + Integer age, + String email) { + +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java new file mode 100644 index 0000000..d42ae55 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java @@ -0,0 +1,7 @@ +package com.example.user.adapter.in.web.dto; + +public record UpdateUserRequestDTO(Long id, + String name, + Integer age, + String email) { +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java new file mode 100644 index 0000000..ea9048e --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java @@ -0,0 +1,15 @@ +package com.example.user.adapter.in.web.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserResponseDTO { + private long id; + private String name; + private int age; + private String email; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/pom.xml b/qa-service/qa-service-adapter/qa-adapter-out/pom.xml new file mode 100644 index 0000000..c6af622 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + com.example + user-adapter-out + 0.0.1-SNAPSHOT + user-adapter-out + user-adapter-out + + pom + + + com.example + user-service-adapter + 0.0.1-SNAPSHOT + + + + user-adapter-out-persistence + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/.gitignore b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml new file mode 100644 index 0000000..812d59d --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + com.example + user-adapter-out-persistence + 0.0.1-SNAPSHOT + user-adapter-out-persistence + user-adapter-out-persistence + + com.example + user-adapter-out + 0.0.1-SNAPSHOT + + + + + org.projectlombok + lombok + provided + + + + com.example + user-service-domain + 0.0.1-SNAPSHOT + + + + com.baomidou + mybatis-plus-spring-boot3-starter + + + + com.mysql + mysql-connector-j + runtime + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + + + diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java new file mode 100644 index 0000000..bec96ab --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java @@ -0,0 +1,26 @@ +package com.example.user.adapter.out.persistence.bridge; + +import com.example.user.adapter.out.persistence.convertor.UserConvertor; +import com.example.user.adapter.out.persistence.entity.UserEntity; +import com.example.user.adapter.out.persistence.mapper.UserMapper; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.CreateUserPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class CreateUserBridge implements CreateUserPort { + @Resource + private UserMapper userMapper; + + @Override + public User createUser(User user) { + UserEntity userEntity = UserConvertor.toEntity(user); + int result = userMapper.insert(userEntity); + //result 指受影响行数 + log.info("result:{}",result); + return user; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java new file mode 100644 index 0000000..acf2985 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java @@ -0,0 +1,19 @@ +package com.example.user.adapter.out.persistence.bridge; + +import com.example.user.adapter.out.persistence.mapper.UserMapper; +import com.example.user.service.domain.port.DeleteUserPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class DeleteUserBridge implements DeleteUserPort { + @Resource + private UserMapper userMapper; + @Override + public void deleteUser(Long id) { + int result = userMapper.deleteById(id); + log.info("result:{}",result); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java new file mode 100644 index 0000000..ea3bd70 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java @@ -0,0 +1,22 @@ +package com.example.user.adapter.out.persistence.bridge; + +import com.example.user.adapter.out.persistence.convertor.UserConvertor; +import com.example.user.adapter.out.persistence.entity.UserEntity; +import com.example.user.adapter.out.persistence.mapper.UserMapper; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserByIdPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class GetUserByIdBridge implements GetUserByIdPort { + @Resource + private UserMapper userMapper; + @Override + public User getUserById(Long id) { + UserEntity userEntity = userMapper.selectById(id); + return UserConvertor.toDomain(userEntity); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java new file mode 100644 index 0000000..bda787d --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java @@ -0,0 +1,32 @@ +package com.example.user.adapter.out.persistence.bridge; + +import com.example.user.adapter.out.persistence.convertor.UserConvertor; +import com.example.user.adapter.out.persistence.entity.UserEntity; +import com.example.user.adapter.out.persistence.mapper.UserMapper; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserListPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class GetUserListBridge implements GetUserListPort { + + @Resource + private UserMapper userMapper; + + @Override + public List getUsers() { + List entities = userMapper.selectList(null); + + ArrayList list = new ArrayList<>(); + + entities.forEach(userEntity -> { + User user = UserConvertor.toDomain(userEntity); + list.add(user); + }); + return list; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java new file mode 100644 index 0000000..231cd5a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java @@ -0,0 +1,23 @@ +package com.example.user.adapter.out.persistence.bridge; + +import com.example.user.adapter.out.persistence.convertor.UserConvertor; +import com.example.user.adapter.out.persistence.mapper.UserMapper; +import com.example.user.service.domain.User; +import com.example.user.service.domain.port.UpdateUserPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class UpdateUserBridge implements UpdateUserPort { + @Resource + private UserMapper userMapper; + + @Override + public User updateUser(User user) { + int result = userMapper.updateById(UserConvertor.toEntity(user)); + log.info("result:{}",result); + return user; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java new file mode 100644 index 0000000..a11e9b0 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java @@ -0,0 +1,29 @@ +package com.example.user.adapter.out.persistence.convertor; + +import com.example.user.adapter.out.persistence.entity.UserEntity; +import com.example.user.service.domain.User; +import com.example.user.service.domain.valueobject.Email; +import com.example.user.service.domain.valueobject.UserAge; +import com.example.user.service.domain.valueobject.UserId; +import com.example.user.service.domain.valueobject.UserName; + +public class UserConvertor { + + public static User toDomain(UserEntity userEntity) { + return new User( + new UserId(userEntity.getId()), + new UserName(userEntity.getName()), + new UserAge(userEntity.getAge()), + new Email(userEntity.getEmail()) + ); + } + + public static UserEntity toEntity(User user) { + return new UserEntity( + user.getId().getValue(), + user.getName().getValue(), + user.getAge().getValue(), + user.getEmail().getValue() + ); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java new file mode 100644 index 0000000..1114abc --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java @@ -0,0 +1,20 @@ +package com.example.user.adapter.out.persistence.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName("user") +public class UserEntity { + @TableId(type= IdType.ASSIGN_ID) + private long id; + private String name; + private Integer age; + private String email; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java new file mode 100644 index 0000000..92125d3 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java @@ -0,0 +1,7 @@ +package com.example.user.adapter.out.persistence.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.example.user.adapter.out.persistence.entity.UserEntity; + +public interface UserMapper extends BaseMapper { +} diff --git a/qa-service/qa-service-bootstrap/pom.xml b/qa-service/qa-service-bootstrap/pom.xml new file mode 100644 index 0000000..1e684fc --- /dev/null +++ b/qa-service/qa-service-bootstrap/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + com.example + qa-service-bootstrap + 0.0.1-SNAPSHOT + qa-service-bootstrap + qa-service-bootstrap + + + com.example + qa-service + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.example + qa-adapter-in-web + 0.0.1-SNAPSHOT + + + + com.example + qa-adapter-out-persistence + 0.0.1-SNAPSHOT + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + org.mybatis + mybatis-spring + 3.0.5 + compile + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.example.qa.service.bootstrap.qaServiceBootstrapApplication + false + + + + repackage + + repackage + + + + + + + + diff --git a/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java b/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java new file mode 100644 index 0000000..1b9be1f --- /dev/null +++ b/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java @@ -0,0 +1,15 @@ +package com.example.qa.service.bootstrap; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.example") +@MapperScan("com.example.Qa.adapter.out.persistence.mapper") +public class QaServiceBootstrapApplication { + + public static void main(String[] args) { + SpringApplication.run(QaServiceBootstrapApplication.class, args); + } + +} diff --git a/qa-service/qa-service-bootstrap/src/main/resources/application.properties b/qa-service/qa-service-bootstrap/src/main/resources/application.properties new file mode 100644 index 0000000..f9592d1 --- /dev/null +++ b/qa-service/qa-service-bootstrap/src/main/resources/application.properties @@ -0,0 +1,27 @@ +server.port=28080 + +spring.application.name=qa-service + + +# Nacos认证信息 +spring.cloud.nacos.discovery.username=nacos +spring.cloud.nacos.discovery.password=nacos +# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 +spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 +# 注册到 nacos 的指定 namespace,默认为 public +spring.cloud.nacos.discovery.namespace=public + +# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html +# Nacos认证信息 +spring.cloud.nacos.config.username=nacos +spring.cloud.nacos.config.password=nacos +spring.cloud.nacos.config.contextPath=/nacos +# 设置配置中心服务端地址 +spring.cloud.nacos.config.server-addr=192.168.168.128::8848 +# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 +# spring.cloud.nacos.config.namespace= +spring.config.import=nacos:${spring.application.name}.properties?refresh=true + + + + diff --git a/qa-service/qa-service-common/.gitignore b/qa-service/qa-service-common/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/qa-service/qa-service-common/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/qa-service/qa-service-common/pom.xml b/qa-service/qa-service-common/pom.xml new file mode 100644 index 0000000..489b70f --- /dev/null +++ b/qa-service/qa-service-common/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + com.example + qr-service-common + 0.0.1-SNAPSHOT + qr-service-common + qr-service-common + + 21 + UTF-8 + UTF-8 + 3.0.2 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 17 + 17 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.example.qr.service.common.QrServiceCommonApplication + true + + + + repackage + + repackage + + + + + + + + diff --git a/qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java b/qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java new file mode 100644 index 0000000..2cb84b3 --- /dev/null +++ b/qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java @@ -0,0 +1,199 @@ +package com.example.qr.service.common; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.NetworkInterface; + +/** + * @author wuyunbin + *

名称:IdWorker.java

+ *

描述:分布式自增长ID

+ *
+ *     Twitter的 Snowflake JAVA实现方案
+ * 
+ * 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用: + * 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000 + * 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间, + * 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识), + * 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。 + * 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分), + * 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。 + *

+ * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)) + * @author Polim + */ +public class IdWorker { + /** + * 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) + */ + private final static long TWEPOCH = 1288834974657L; + + /** + * 机器标识位数 + */ + private final static long WORKER_ID_BITS = 5L; + + /** + * 数据中心标识位数 + */ + private final static long DATA_CENTER_ID_BITS = 5L; + + /** + * 机器ID最大值 + */ + private final static long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS); + + /** + * 数据中心ID最大值 + */ + private final static long MAX_DATACENTER_ID = -1L ^ (-1L << DATA_CENTER_ID_BITS); + + /** + * 毫秒内自增位 + */ + private final static long SEQUENCE_BITS = 12L; + + /** + * 机器ID偏左移12位 + */ + private final static long WORKER_ID_SHIFT = SEQUENCE_BITS; + + /** + * 数据中心ID左移17位 + */ + private final static long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; + + /** + * 时间毫秒左移22位 + */ + private final static long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS; + + private final static long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); + + /** + * 上次生产id时间戳 + */ + private static long lastTimestamp = -1L; + + /** + * 0,并发控制 + */ + private long sequence = 0L; + + private final long workerId; + + /** + * 数据标识id部分 + */ + private final long datacenterId; + + public IdWorker() { + this.datacenterId = getDatacenterId(); + this.workerId = getMaxWorkerId(datacenterId); + } + + /** + * @param workerId 工作机器ID + * @param datacenterId 序列号 + */ + public IdWorker(long workerId, long datacenterId) { + if (workerId > MAX_WORKER_ID || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID)); + } + if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", MAX_DATACENTER_ID)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + /** + * 获取下一个ID + * + * @return + */ + public synchronized long nextId() { + long timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (lastTimestamp == timestamp) { + // 当前毫秒内,则+1 + sequence = (sequence + 1) & SEQUENCE_MASK; + if (sequence == 0) { + // 当前毫秒内计数满了,则等待下一秒 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0L; + } + lastTimestamp = timestamp; + // ID偏移组合生成最终的ID,并返回ID + + return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) + | (datacenterId << DATACENTER_ID_SHIFT) + | (workerId << WORKER_ID_SHIFT) | sequence; + } + + private long tilNextMillis(final long lastTimestamp) { + long timestamp = this.timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = this.timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + /** + *

+ * 获取 MAX_WORKER_ID + *

+ */ + protected static long getMaxWorkerId(long datacenterId) { + StringBuilder mpid = new StringBuilder(); + mpid.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (!name.isEmpty()) { + /* + * GET jvmPid + */ + mpid.append(name.split("@")[0]); + } + /* + * MAC + PID 的 hashcode 获取16个低位 + */ + return (mpid.toString().hashCode() & 0xffff) % (IdWorker.MAX_WORKER_ID + 1); + } + + /** + *

+ * 数据标识id部分 + *

+ */ + protected static long getDatacenterId() { + long id = 0L; + try { + InetAddress ip = InetAddress.getLocalHost(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + id = 1L; + } else { + byte[] mac = network.getHardwareAddress(); + id = ((0x000000FF & (long) mac[mac.length - 1]) + | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; + id = id % (IdWorker.MAX_DATACENTER_ID + 1); + } + } catch (Exception e) { + System.out.println(" getDatacenterId: " + e.getMessage()); + } + return id; + } + + + + +} -- Gitee From 3d312efeadebd5356b97ec47d3d40b3a469bfad5 Mon Sep 17 00:00:00 2001 From: zqy <2287881924@qq.com> Date: Wed, 10 Sep 2025 16:42:18 +0800 Subject: [PATCH 04/23] =?UTF-8?q?feat=E6=B7=BB=E5=8A=A0=E4=BA=86qa?= =?UTF-8?q?=E7=9A=84=E6=9F=A5=E6=89=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加所有有关qa查找功能的文件 --- .../persistence/bridge/GetQaByIdBridge.java | 26 ++++++++++++++ .../persistence/bridge/GetQaListBridge.java | 36 +++++++++++++++++++ .../persistence/bridge/GetUserByIdBridge.java | 22 ------------ .../persistence/bridge/GetUserListBridge.java | 32 ----------------- 4 files changed, 62 insertions(+), 54 deletions(-) create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaByIdBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaListBridge.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaByIdBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaByIdBridge.java new file mode 100644 index 0000000..5b4fa5f --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaByIdBridge.java @@ -0,0 +1,26 @@ +package com.example.qa.adapter.out.persistence.bridge; + +/* + author: ZhangQianyu + 2210705220 + */ + +import com.example.qa.adapter.out.persistence.convertor.QaConvertor; +import com.example.qa.adapter.out.persistence.entity.QaEntity; +import com.example.qa.adapter.out.persistence.mapper.QaMapper; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.GetQaByIdPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class GetQaByIdBridge implements GetQaByIdPort { + @Resource + private QaMapper qaMapper; + @Override + public Qa getQaById(Long id) { + QaEntity qaEntity = qaMapper.selectById(id); + return QaConvertor.toDomain(qaEntity); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaListBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaListBridge.java new file mode 100644 index 0000000..d5b2378 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaListBridge.java @@ -0,0 +1,36 @@ +package com.example.qa.adapter.out.persistence.bridge; + +/* + author: ZhangQianyu + 2210705220 + */ + +import com.example.qa.adapter.out.persistence.convertor.QaConvertor; +import com.example.qa.adapter.out.persistence.entity.QaEntity; +import com.example.qa.adapter.out.persistence.mapper.QaMapper; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.GetQaListPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class GetQaListBridge implements GetQaListPort { + + @Resource + private QaMapper qaMapper; + + @Override + public List getQas() { + List entities = qaMapper.selectList(null); + + ArrayList list = new ArrayList<>(); + + entities.forEach(qaEntity -> { + Qa qa = QaConvertor.toDomain(qaEntity); + list.add(qa); + }); + return list; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java deleted file mode 100644 index ea3bd70..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserByIdBridge.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.example.user.adapter.out.persistence.bridge; - -import com.example.user.adapter.out.persistence.convertor.UserConvertor; -import com.example.user.adapter.out.persistence.entity.UserEntity; -import com.example.user.adapter.out.persistence.mapper.UserMapper; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.GetUserByIdPort; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class GetUserByIdBridge implements GetUserByIdPort { - @Resource - private UserMapper userMapper; - @Override - public User getUserById(Long id) { - UserEntity userEntity = userMapper.selectById(id); - return UserConvertor.toDomain(userEntity); - } -} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java deleted file mode 100644 index bda787d..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetUserListBridge.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.user.adapter.out.persistence.bridge; - -import com.example.user.adapter.out.persistence.convertor.UserConvertor; -import com.example.user.adapter.out.persistence.entity.UserEntity; -import com.example.user.adapter.out.persistence.mapper.UserMapper; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.GetUserListPort; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; - -@Component -public class GetUserListBridge implements GetUserListPort { - - @Resource - private UserMapper userMapper; - - @Override - public List getUsers() { - List entities = userMapper.selectList(null); - - ArrayList list = new ArrayList<>(); - - entities.forEach(userEntity -> { - User user = UserConvertor.toDomain(userEntity); - list.add(user); - }); - return list; - } -} -- Gitee From 1d6835c7df56aecaeebc9cd963e305422e5b5295 Mon Sep 17 00:00:00 2001 From: Zyc <1577767405@qq.com> Date: Wed, 10 Sep 2025 16:46:46 +0800 Subject: [PATCH 05/23] =?UTF-8?q?feat(qa-service-domain,qa-service-common.?= =?UTF-8?q?qa-service-adaptor):=20=E4=BF=AE=E6=94=B9=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E5=8F=98=E9=87=8F=EF=BC=8C=E6=9C=89=E5=8F=82=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/convertor/QaConvertor.java | 29 +++++++++++ .../persistence/convertor/UserConvertor.java | 29 ----------- .../entity/{UserEntity.java => QaEntity.java} | 14 +++--- .../out/persistence/mapper/QaMapper.java | 10 ++++ .../out/persistence/mapper/UserMapper.java | 7 --- qa-service/qa-service-common/pom.xml | 6 +-- .../{qr => qa}/service/common/IdWorker.java | 2 +- .../com/example/qa/service/domain/Qa.java | 48 +++++++++++++++++++ .../qa/service/domain/port/CreateQaPort.java | 10 ++++ .../qa/service/domain/port/DeleteQaPort.java | 8 ++++ .../qa/service/domain/port/GetQaByIdPort.java | 10 ++++ .../qa/service/domain/port/GetQaListPort.java | 12 +++++ .../qa/service/domain/port/UpdateQaPort.java | 10 ++++ .../qa/service/domain/valueobject/Answer.java | 10 ++++ .../service/domain/valueobject/QaId.java} | 7 ++- .../service/domain/valueobject/Question.java | 7 +++ .../com/example/user/service/domain/User.java | 48 ------------------- .../service/domain/port/CreateUserPort.java | 7 --- .../service/domain/port/DeleteUserPort.java | 5 -- .../service/domain/port/GetUserByIdPort.java | 7 --- .../service/domain/port/GetUserListPort.java | 9 ---- .../service/domain/port/UpdateUserPort.java | 7 --- .../service/domain/valueobject/Email.java | 7 --- .../service/domain/valueobject/UserAge.java | 7 --- .../service/domain/valueobject/UserName.java | 7 --- 25 files changed, 171 insertions(+), 152 deletions(-) create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/QaConvertor.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/{UserEntity.java => QaEntity.java} (65%) create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/QaMapper.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java rename qa-service/qa-service-common/src/main/java/com/example/{qr => qa}/service/common/IdWorker.java (99%) create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQaPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQaPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaByIdPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaListPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQaPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java rename qa-service/qa-service-domain/src/main/java/com/example/{user/service/domain/valueobject/UserId.java => qa/service/domain/valueobject/QaId.java} (34%) create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/QaConvertor.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/QaConvertor.java new file mode 100644 index 0000000..7a9bbd5 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/QaConvertor.java @@ -0,0 +1,29 @@ +package com.example.qa.adapter.out.persistence.convertor; + +import com.example.qa.adapter.out.persistence.entity.QaEntity; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.valueobject.Answer; +import com.example.qa.service.domain.valueobject.Question; +import com.example.qa.service.domain.valueobject.QaId; + +/* + author: zhangyucheng + */ +public class QaConvertor { + + public static Qa toDomain(QaEntity qaEntity) { + return new Qa( + new QaId(qaEntity.getId()), + new Question(qaEntity.getQuestion()), + new Answer(qaEntity.getAnswer()) + ); + } + + public static QaEntity toEntity(Qa qa) { + return new QaEntity( + qa.getId().getValue(), + qa.getQuestion().getValue(), + qa.getAnswer().getValue() + ); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java deleted file mode 100644 index a11e9b0..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.user.adapter.out.persistence.convertor; - -import com.example.user.adapter.out.persistence.entity.UserEntity; -import com.example.user.service.domain.User; -import com.example.user.service.domain.valueobject.Email; -import com.example.user.service.domain.valueobject.UserAge; -import com.example.user.service.domain.valueobject.UserId; -import com.example.user.service.domain.valueobject.UserName; - -public class UserConvertor { - - public static User toDomain(UserEntity userEntity) { - return new User( - new UserId(userEntity.getId()), - new UserName(userEntity.getName()), - new UserAge(userEntity.getAge()), - new Email(userEntity.getEmail()) - ); - } - - public static UserEntity toEntity(User user) { - return new UserEntity( - user.getId().getValue(), - user.getName().getValue(), - user.getAge().getValue(), - user.getEmail().getValue() - ); - } -} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/QaEntity.java similarity index 65% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/QaEntity.java index 1114abc..fa70580 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/QaEntity.java @@ -1,4 +1,4 @@ -package com.example.user.adapter.out.persistence.entity; +package com.example.qa.adapter.out.persistence.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -7,14 +7,16 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +/* + author: zhangyucheng + */ @Data @AllArgsConstructor @NoArgsConstructor -@TableName("user") -public class UserEntity { +@TableName("qa") +public class QaEntity { @TableId(type= IdType.ASSIGN_ID) private long id; - private String name; - private Integer age; - private String email; + private String question; + private String answer; } diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/QaMapper.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/QaMapper.java new file mode 100644 index 0000000..937e69a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/QaMapper.java @@ -0,0 +1,10 @@ +package com.example.qa.adapter.out.persistence.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.example.qa.adapter.out.persistence.entity.QaEntity; + +/* + author: zhangyucheng + */ +public interface QaMapper extends BaseMapper { +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java deleted file mode 100644 index 92125d3..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/UserMapper.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.adapter.out.persistence.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.example.user.adapter.out.persistence.entity.UserEntity; - -public interface UserMapper extends BaseMapper { -} diff --git a/qa-service/qa-service-common/pom.xml b/qa-service/qa-service-common/pom.xml index 489b70f..2b45a38 100644 --- a/qa-service/qa-service-common/pom.xml +++ b/qa-service/qa-service-common/pom.xml @@ -3,10 +3,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - qr-service-common + qa-service 0.0.1-SNAPSHOT - qr-service-common - qr-service-common + qa-service-common + qa-service-common 21 UTF-8 diff --git a/qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java b/qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java similarity index 99% rename from qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java rename to qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java index 2cb84b3..ac96e23 100644 --- a/qa-service/qa-service-common/src/main/java/com/example/qr/service/common/IdWorker.java +++ b/qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java @@ -1,4 +1,4 @@ -package com.example.qr.service.common; +package com.example.qa.service.common; import java.lang.management.ManagementFactory; import java.net.InetAddress; diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java new file mode 100644 index 0000000..33d6531 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java @@ -0,0 +1,48 @@ +package com.example.qa.service.domain; + +import com.example.qa.service.common.IdWorker; +import com.example.qa.service.domain.port.GetQaListPort; +import com.example.qa.service.domain.valueobject.Email; +import com.example.qa.service.domain.valueobject.QaAge; +import com.example.qa.service.domain.valueobject.QaId; +import com.example.qa.service.domain.valueobject.QaName; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@ToString +/* + author: zhangyucheng + */ +public class Qa { + private QaId id; + private Question question; + private Answer answer; + + public Qa() { + } + + public Qa(QaId id, Question question, Answer answer) { + this.id = id; + this.question = question; + this.answer = answer; + } + + public Qa( Question question, Answer answer) { + this.id= genId() ; + this.question = question; + this.answer = answer; + } + + public static List getQas(GetQaListPort getQaListPort){ + return getQaListPort.getQas(); + } + + public QaId genId(){ + return new QaId(new IdWorker().nextId()); + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQaPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQaPort.java new file mode 100644 index 0000000..5812a35 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQaPort.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.Qa; + +/* + author: zhangyucheng + */ +public interface CreateQaPort { + Qa createQa(Qa qa); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQaPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQaPort.java new file mode 100644 index 0000000..16549fb --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQaPort.java @@ -0,0 +1,8 @@ +package com.example.qa.service.domain.port; + +/* + author: zhangyucheng + */ +public interface DeleteQaPort { + void deleteQa(Long id); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaByIdPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaByIdPort.java new file mode 100644 index 0000000..b985a2b --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaByIdPort.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.Qa; + +/* + author: zhangyucheng + */ +public interface GetQaByIdPort { + Qa getQaById(Long id); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaListPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaListPort.java new file mode 100644 index 0000000..b93c6f6 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQaListPort.java @@ -0,0 +1,12 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.Qa; + +import java.util.List; + +/* + author: zhangyucheng + */ +public interface GetQaListPort { + List getQas(); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQaPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQaPort.java new file mode 100644 index 0000000..bbd8c44 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQaPort.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.Qa; + +/* + author: zhangyucheng + */ +public interface UpdateQaPort { + Qa updateQa(Qa qa); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java new file mode 100644 index 0000000..2cf2488 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.valueobject; + +/* + author: zhangyucheng + */ +public record Answer(String answer) { + public String getValue() { + return answer; + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QaId.java similarity index 34% rename from qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java rename to qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QaId.java index bf3ce0b..75f02de 100644 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserId.java +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QaId.java @@ -1,6 +1,9 @@ -package com.example.user.service.domain.valueobject; +package com.example.qa.service.domain.valueobject; -public record UserId(long id) { +/* + author: zhangyucheng + */ +public record QaId(long id) { public long getValue(){ return id; diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java new file mode 100644 index 0000000..52814d7 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java @@ -0,0 +1,7 @@ +package com.example.qa.service.domain.valueobject; + +public record Question(String question) { + public String getValue() { + return question; + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java deleted file mode 100644 index f3ee515..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/User.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.example.user.service.domain; - -import com.example.user.service.common.IdWorker; -import com.example.user.service.domain.port.GetUserListPort; -import com.example.user.service.domain.valueobject.Email; -import com.example.user.service.domain.valueobject.UserAge; -import com.example.user.service.domain.valueobject.UserId; -import com.example.user.service.domain.valueobject.UserName; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -import java.util.List; - -@Setter -@Getter -@ToString -public class User { - private UserId id; - private UserName name; - private UserAge age; - private Email email; - - public User() { - } - - public User(UserId id, UserName name, UserAge age, Email email) { - this.id = id; - this.name = name; - this.age = age; - this.email = email; - } - - public User( UserName name, UserAge age, Email email) { - this.id= genId() ; - this.name = name; - this.age = age; - this.email = email; - } - - public static List getUsers(GetUserListPort getUserListPort){ - return getUserListPort.getUsers(); - } - - public UserId genId(){ - return new UserId(new IdWorker().nextId()); - } -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java deleted file mode 100644 index 77a2a96..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/CreateUserPort.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.port; - -import com.example.user.service.domain.User; - -public interface CreateUserPort { - User createUser(User user); -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java deleted file mode 100644 index a7d10a1..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.user.service.domain.port; - -public interface DeleteUserPort { - void deleteUser(Long id); -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java deleted file mode 100644 index 7163ec8..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserByIdPort.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.port; - -import com.example.user.service.domain.User; - -public interface GetUserByIdPort { - User getUserById(Long id); -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java deleted file mode 100644 index 2ad8e17..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/GetUserListPort.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.example.user.service.domain.port; - -import com.example.user.service.domain.User; - -import java.util.List; - -public interface GetUserListPort { - List getUsers(); -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java deleted file mode 100644 index 9a7ffd0..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/UpdateUserPort.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.port; - -import com.example.user.service.domain.User; - -public interface UpdateUserPort { - User updateUser(User user); -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java deleted file mode 100644 index f83b243..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.valueobject; - -public record Email(String email) { - public String getValue() { - return email; - } -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java deleted file mode 100644 index 38ef937..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.valueobject; - -public record UserAge(int age) { - public int getValue() { - return age; - } -} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java deleted file mode 100644 index 0c11a15..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.valueobject; - -public record UserName(String username) { - public String getValue() { - return username; - } -} -- Gitee From 5b0f9115b93b52849762728d61b173354e5a4815 Mon Sep 17 00:00:00 2001 From: violet-77-0826 <2570312936@qq.com> Date: Wed, 10 Sep 2025 16:49:05 +0800 Subject: [PATCH 06/23] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 12 ------------ .../persistence/bridge/DeleteUserBridge.java | 19 ++++++++++++------- .../application/port/in/DeleteQaUseCase.java | 5 +++++ .../application/service/DeleteQaService.java | 7 ++++++- .../service/domain/port/DeleteUserPort.java | 11 ++++++++--- 5 files changed, 31 insertions(+), 23 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index fdcfc8b..b317a6b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,17 +4,5 @@
- - - - \ No newline at end of file diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java index acf2985..a58a725 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java @@ -1,19 +1,24 @@ -package com.example.user.adapter.out.persistence.bridge; +package com.example.qa.adapter.out.persistence.bridge; -import com.example.user.adapter.out.persistence.mapper.UserMapper; -import com.example.user.service.domain.port.DeleteUserPort; +import com.example.qa.adapter.out.persistence.mapper.QaMapper; +import com.example.qa.service.domain.port.DeleteQaPort; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +/** + * @author liaoqi + * @param + * @return + */ @Slf4j @Component -public class DeleteUserBridge implements DeleteUserPort { +public class DeleteQaBridge implements DeleteQaPort { @Resource - private UserMapper userMapper; + private QaMapper qaMapper; @Override - public void deleteUser(Long id) { - int result = userMapper.deleteById(id); + public void deleteQa(Long id) { + int result = qaMapper.deleteById(id); log.info("result:{}",result); } } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java index 5d28dae..ccb1675 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/DeleteQaUseCase.java @@ -1,5 +1,10 @@ package com.example.qa.service.application.port.in; +/** + * @author liaoqi + * @param + * @return + */ public interface DeleteQaUseCase { void deleteQa(Long id); } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java index 64150e6..d2af9f0 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java @@ -4,12 +4,17 @@ import com.example.qa.service.application.port.in.DeleteQaUseCase; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; +/** + * @author liaoqi + * @param + * @return + */ @Service public class DeleteQaService implements DeleteQaUseCase { @Resource private DeleteQaPort deleteQaPort; @Override - public void deleteUser(Long id) { + public void deleteQa(Long id) { deleteQaPort.deleteQa(id); } } diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java index a7d10a1..4f4e65a 100644 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java +++ b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java @@ -1,5 +1,10 @@ -package com.example.user.service.domain.port; +package com.example.qa.service.domain.port; -public interface DeleteUserPort { - void deleteUser(Long id); +/** + * @author liaoqi + * @param + * @return + */ +public interface DeleteQaPort { + void deleteQa(Long id); } -- Gitee From dafded77aed7472b0b01a693bc37a2e89b08659f Mon Sep 17 00:00:00 2001 From: zqy <2287881924@qq.com> Date: Wed, 10 Sep 2025 17:39:02 +0800 Subject: [PATCH 07/23] =?UTF-8?q?feat=E6=B7=BB=E5=8A=A0qa=E7=9A=84?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/port/in/GetQaByIdUseCase.java | 8 ++++++-- .../application/port/in/GetQaListUseCase.java | 6 +++++- .../application/service/GetQaByIdService.java | 18 ++++++++++------- .../application/service/GetQaListService.java | 20 +++++++++++-------- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java index 6157b12..ad20cea 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaByIdUseCase.java @@ -1,7 +1,11 @@ package com.example.qa.service.application.port.in; -import com.example.user.service.domain.User; +/* + author: ZhangQianyu + 2210705220 + */ + +import com.example.qa.service.domain.Qa; public interface GetQaByIdUseCase { - User getQaById(Long id); + Qa getQaById(Long id); } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java index c6b2100..c8ddb7c 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/GetQaListUseCase.java @@ -1,6 +1,10 @@ package com.example.qa.service.application.port.in; -import com.example.user.service.domain.User; +/* + author: ZhangQianyu + 2210705220 + */ + +import com.example.qa.service.domain.Qa; import java.util.List; diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java index 6a1dde9..5e4ea05 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaByIdService.java @@ -1,18 +1,22 @@ package com.example.qa.service.application.service; -import com.example.user.service.application.port.in.GetUserByIdUseCase; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.GetUserByIdPort; +/* + author: ZhangQianyu + 2210705220 + */ + +import com.example.qa.service.application.port.in.GetQaByIdUseCase; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.GetQaByIdPort; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @Service -public class GetQaByIdService implements GetUserByIdUseCase { +public class GetQaByIdService implements GetQaByIdUseCase { @Resource - private GetUserByIdPort getUserByIdPort; + private GetQaByIdPort getQaByIdPort; @Override - public User getUserById(Long id) { - return getUserByIdPort.getUserById(id); + public Qa getQaById(Long id) { + return getQaByIdPort.getQaById(id); } } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java index 004a5b3..5acc87b 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/GetQaListService.java @@ -1,21 +1,25 @@ package com.example.qa.service.application.service; -import com.example.user.service.application.port.in.GetUserListUseCase; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.GetUserListPort; +/* + author: ZhangQianyu + 2210705220 + */ + +import com.example.qa.service.application.port.in.GetQaListUseCase; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.GetQaListPort; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.List; @Service -public class GetQaListService implements GetUserListUseCase { +public class GetQaListService implements GetQaListUseCase { @Resource - GetUserListPort getUserListPort; + GetQaListPort getQaListPort; @Override - public List getUsers() { - List users = User.getUsers(getUserListPort); - return users; + public List getQas() { + List qas = Qa.getQas(getQaListPort); + return qas; } } -- Gitee From 2b0a6f0a38254d5977bb0ff9b7101cfd83db9b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Wed, 10 Sep 2025 18:15:43 +0800 Subject: [PATCH 08/23] =?UTF-8?q?feat=E6=B7=BB=E5=8A=A0=E4=BA=86qa?= =?UTF-8?q?=E7=9A=84=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...serResponseDTO.java => QaResponseDTO.java} | 15 +++++--- .../in/web/dto/UpdateQaRequestDTO.java | 10 +++++ .../in/web/dto/UpdateUserRequestDTO.java | 7 ---- .../persistence/bridge/UpdateQaBridge.java | 27 +++++++++++++ .../persistence/bridge/UpdateUserBridge.java | 23 ----------- .../application/command/CreateQaCommand.java | 14 ++++--- .../application/command/UpdateQaCommand.java | 11 ++++-- .../application/port/in/UpdateQaUseCase.java | 12 ++++-- .../application/service/UpdateQaService.java | 38 ++++++++++--------- .../service/domain/port/DeleteUserPort.java | 10 ----- 10 files changed, 91 insertions(+), 76 deletions(-) rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/{UserResponseDTO.java => QaResponseDTO.java} (46%) create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateQaRequestDTO.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateQaBridge.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java delete mode 100644 qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/QaResponseDTO.java similarity index 46% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/QaResponseDTO.java index ea9048e..ff5501f 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UserResponseDTO.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/QaResponseDTO.java @@ -1,15 +1,18 @@ -package com.example.user.adapter.in.web.dto; +package com.example.qa.adapter.in.web.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; - +/** + * @author zhujunjie + * @param + * @return + */ @Data @AllArgsConstructor @NoArgsConstructor -public class UserResponseDTO { +public class QaResponseDTO { private long id; - private String name; - private int age; - private String email; + private String question; + private String answer; } diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateQaRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateQaRequestDTO.java new file mode 100644 index 0000000..5ef5b88 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateQaRequestDTO.java @@ -0,0 +1,10 @@ +package com.example.qa.adapter.in.web.dto; +/** + * @author zhujunjie + * @param + * @return + */ +public record UpdateQaRequestDTO(Long id, + String question, + String answer,) { +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java deleted file mode 100644 index d42ae55..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.adapter.in.web.dto; - -public record UpdateUserRequestDTO(Long id, - String name, - Integer age, - String email) { -} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateQaBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateQaBridge.java new file mode 100644 index 0000000..cf6edd9 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateQaBridge.java @@ -0,0 +1,27 @@ +package com.example.Qa.adapter.out.persistence.bridge; +import com.example.Qa.adapter.out.persistence.convertor.QaConvertor; +import com.example.Qa.adapter.out.persistence.mapper.QaMapper; +import com.example.Qa.service.domain.Qa; +import com.example.Qa.service.domain.port.UpdateQaPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @author zhujunjie + * @param + * @return + */ +@Slf4j +@Component +public class UpdateQaBridge implements UpdateQaPort { + @Resource + private QaMapper QaMapper; + + @Override + public Qa updateQa(Qa qa) { + int result = QaMapper.updateById(QaConvertor.toEntity(qa)); + log.info("result:{}",result); + return qa; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java deleted file mode 100644 index 231cd5a..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateUserBridge.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.user.adapter.out.persistence.bridge; - -import com.example.user.adapter.out.persistence.convertor.UserConvertor; -import com.example.user.adapter.out.persistence.mapper.UserMapper; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.UpdateUserPort; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class UpdateUserBridge implements UpdateUserPort { - @Resource - private UserMapper userMapper; - - @Override - public User updateUser(User user) { - int result = userMapper.updateById(UserConvertor.toEntity(user)); - log.info("result:{}",result); - return user; - } -} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java index 8b93e4e..e2c2350 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java @@ -1,11 +1,15 @@ package com.example.qa.service.application.command; - +/** + * @author zhujunjie + * @param + * @return + */ import lombok.Builder; @Builder public record CreateQaCommand( Long id, - String name, - Integer age, - String email -){} + String question, + String answer +) { +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java index add3235..15c4c85 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/UpdateQaCommand.java @@ -1,10 +1,13 @@ package com.example.qa.service.application.command; import lombok.Builder; - +/** + * @author zhujunjie + * @param + * @return + */ @Builder public record UpdateQaCommand(Long id, - String name, - Integer age, - String email) { + String question, + String answer) { } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java index d548bd9..6799e18 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java @@ -1,8 +1,12 @@ package com.example.qa.service.application.port.in; - -import com.example.user.service.application.command.UpdateUserCommand; -import com.example.user.service.domain.User; +/** + * @author zhujunjie + * @param + * @return + */ +import com.example.ua.service.application.command.UpdateQaCommand; +import com.example.ua.service.domain.Qa; public interface UpdateQaUseCase { - User updateUser(UpdateQaCommand command); + Qa updateQa(UpdateQaCommand command); } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java index dfb889e..f5430b4 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java @@ -1,28 +1,32 @@ package com.example.qa.service.application.service; - -import com.example.user.service.application.command.UpdateUserCommand; -import com.example.user.service.application.port.in.UpdateUserUseCase; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.UpdateUserPort; -import com.example.user.service.domain.valueobject.Email; -import com.example.user.service.domain.valueobject.UserAge; -import com.example.user.service.domain.valueobject.UserId; -import com.example.user.service.domain.valueobject.UserName; +/** + * @author zhujunjie + * @param + * @return + */ +import com.example.qa.service.application.command.UpdateQaCommand; +import com.example.qa.service.application.port.in.UpdateQaUseCase; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.UpdateQaPort; +import com.example.qa.service.domain.valueobject.Email; +import com.example.qa.service.domain.valueobject.QaAge; +import com.example.qa.service.domain.valueobject.QaId; +import com.example.qa.service.domain.valueobject.QaName; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @Service -public class UpdateQaService implements UpdateUserUseCase { +public class UpdateQaService implements UpdateQaUseCase { @Resource - private UpdateUserPort updateUserPort; + private UpdateQaPort updateQaPort; @Override - public User updateUser(UpdateUserCommand command) { - User user = new User( - new UserId(command.id()), - new UserName(command.name()), - new UserAge(command.age()), + public Qa updateQa(UpdateQaCommand command) { + Qa qa = new Qa( + new QaId(command.id()), + new QaName(command.name()), + new QaAge(command.age()), new Email(command.email())); - return updateUserPort.updateUser(user); + return updateQaPort.updateQa(qa); } } diff --git a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java b/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java deleted file mode 100644 index 4f4e65a..0000000 --- a/qa-service/qa-service-domain/src/main/java/com/example/user/service/domain/port/DeleteUserPort.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.qa.service.domain.port; - -/** - * @author liaoqi - * @param - * @return - */ -public interface DeleteQaPort { - void deleteQa(Long id); -} -- Gitee From 696a61acf8dfbcd041531676c5b73ef8e731a8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Wed, 10 Sep 2025 19:06:41 +0800 Subject: [PATCH 09/23] =?UTF-8?q?=E9=99=A4=E4=BA=86controller=E5=A4=96?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E7=8E=B0=E5=9C=A8=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E7=9B=AE=E5=BD=95=E6=98=AF=E5=90=A6=E5=85=A8?= =?UTF-8?q?=E6=98=AFqa=EF=BC=8Cpom.xml=E6=96=87=E4=BB=B6=E4=B8=AD=E4=B9=9F?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qa-service/qa-service-adapter/pom.xml | 12 ++++---- .../qa-service-adapter/qa-adapter-in/pom.xml | 10 +++---- .../qa-adapter-in/qa-adapter-in-web/pom.xml | 10 +++---- .../in/web/controller/UserController.java | 0 .../in/web/dto/CreateQaRequestDTO.java | 9 ++++++ .../adapter/in/web/dto/QaResponseDTO.java | 0 .../in/web/dto/UpdateQaRequestDTO.java | 0 .../in/web/dto/CreateUserRequestDTO.java | 8 ----- .../qa-service-adapter/qa-adapter-out/pom.xml | 10 +++---- .../qa-adapter-out-persistence/pom.xml | 10 +++---- .../persistence/bridge/CreateQaBridge.java | 30 +++++++++++++++++++ .../persistence/bridge/DeleteQaBridge.java} | 0 .../persistence/bridge/GetQaByIdBridge.java | 0 .../persistence/bridge/GetQaListBridge.java | 0 .../persistence/bridge/UpdateQaBridge.java | 0 .../persistence/convertor/QaConvertor.java | 0 .../out/persistence/entity/QaEntity.java | 0 .../out/persistence/mapper/QaMapper.java | 0 .../persistence/bridge/CreateUserBridge.java | 26 ---------------- .../application/port/in/CreateQaUseCase.java | 10 +++++-- .../application/service/CreateQaService.java | 25 +++++++++------- user-service/user-service-application/pom.xml | 10 +++---- .../UserServiceBootstrapApplication.java | 0 23 files changed, 91 insertions(+), 79 deletions(-) rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/{user => qa}/adapter/in/web/controller/UserController.java (100%) create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/{user => qa}/adapter/in/web/dto/QaResponseDTO.java (100%) rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/{user => qa}/adapter/in/web/dto/UpdateQaRequestDTO.java (100%) delete mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user/adapter/out/persistence/bridge/DeleteUserBridge.java => qa/adapter/out/persistence/bridge/DeleteQaBridge.java} (100%) rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user => qa}/adapter/out/persistence/bridge/GetQaByIdBridge.java (100%) rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user => qa}/adapter/out/persistence/bridge/GetQaListBridge.java (100%) rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user => qa}/adapter/out/persistence/bridge/UpdateQaBridge.java (100%) rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user => qa}/adapter/out/persistence/convertor/QaConvertor.java (100%) rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user => qa}/adapter/out/persistence/entity/QaEntity.java (100%) rename qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/{user => qa}/adapter/out/persistence/mapper/QaMapper.java (100%) delete mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java rename user-service/user-service-bootstrap/src/main/java/com/example/{user => qa}/service/bootstrap/UserServiceBootstrapApplication.java (100%) diff --git a/qa-service/qa-service-adapter/pom.xml b/qa-service/qa-service-adapter/pom.xml index 3b61e10..0074d0c 100644 --- a/qa-service/qa-service-adapter/pom.xml +++ b/qa-service/qa-service-adapter/pom.xml @@ -3,22 +3,22 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-service-adapter + qa-service-adapter 0.0.1-SNAPSHOT - user-service-adapter - user-service-adapter + qa-service-adapter + qa-service-adapter pom com.example - user-service + qa-service 0.0.1-SNAPSHOT - user-adapter-in - user-adapter-out + qa-adapter-in + qa-adapter-out diff --git a/qa-service/qa-service-adapter/qa-adapter-in/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/pom.xml index cf0b3a2..473ef75 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/pom.xml @@ -3,21 +3,21 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-in + qa-adapter-in 0.0.1-SNAPSHOT - user-adapter-in - user-adapter-in + qa-adapter-in + qa-adapter-in pom com.example - user-service-adapter + qa-service-adapter 0.0.1-SNAPSHOT - user-adapter-in-web + qa-adapter-in-web diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml index 753f60d..ba230d1 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-in-web + qa-adapter-in-web 0.0.1-SNAPSHOT - user-adapter-in-web - user-adapter-in-web + qa-adapter-in-web + qa-adapter-in-web com.example - user-adapter-in + qa-adapter-in 0.0.1-SNAPSHOT @@ -37,7 +37,7 @@ com.example - user-service-application + qa-service-application 0.0.1-SNAPSHOT diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/UserController.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/UserController.java diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java new file mode 100644 index 0000000..a399661 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java @@ -0,0 +1,9 @@ +package com.example.qa.adapter.in.web.dto; +/* + author: liyujie + */ +public record CreateQaRequestDTO( + String question, + String answer) { + +} \ No newline at end of file diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/QaResponseDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/QaResponseDTO.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/QaResponseDTO.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/QaResponseDTO.java diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateQaRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQaRequestDTO.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateQaRequestDTO.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQaRequestDTO.java diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java deleted file mode 100644 index 386262a..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.example.user.adapter.in.web.dto; - -public record CreateUserRequestDTO( - String name, - Integer age, - String email) { - -} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/pom.xml b/qa-service/qa-service-adapter/qa-adapter-out/pom.xml index c6af622..dfc017b 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-out/pom.xml @@ -3,21 +3,21 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-out + qa-adapter-out 0.0.1-SNAPSHOT - user-adapter-out - user-adapter-out + qa-adapter-out + qa-adapter-out pom com.example - user-service-adapter + qa-service-adapter 0.0.1-SNAPSHOT - user-adapter-out-persistence + qa-adapter-out-persistence diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml index 812d59d..9d78608 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml @@ -3,13 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-out-persistence + qa-adapter-out-persistence 0.0.1-SNAPSHOT - user-adapter-out-persistence - user-adapter-out-persistence + qa-adapter-out-persistence + qa-adapter-out-persistence com.example - user-adapter-out + qa-adapter-out 0.0.1-SNAPSHOT @@ -22,7 +22,7 @@ com.example - user-service-domain + qa-service-domain 0.0.1-SNAPSHOT diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java new file mode 100644 index 0000000..1591518 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java @@ -0,0 +1,30 @@ +package com.example.qa.adapter.out.persistence.bridge; + +import com.example.qa.adapter.out.persistence.convertor.QaConvertor; +import com.example.qa.adapter.out.persistence.entity.QaEntity; +import com.example.qa.adapter.out.persistence.mapper.QaMapper; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.CreateQaPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/* + author: liyujie + */ + +@Slf4j +@Component +public class CreateQaBridge implements CreateQaPort { + @Resource + private QaMapper qaMapper; + + @Override + public qa createqa(qa qa) { + qaEntity qaEntity = qaConvertor.toEntity(qa); + int result = qaMapper.insert(qaEntity); + //result 指受影响行数 + log.info("result:{}",result); + return qa; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/DeleteQaBridge.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/DeleteUserBridge.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/DeleteQaBridge.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaByIdBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQaByIdBridge.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaByIdBridge.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQaByIdBridge.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaListBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQaListBridge.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/GetQaListBridge.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQaListBridge.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateQaBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQaBridge.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/UpdateQaBridge.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQaBridge.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/QaConvertor.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/convertor/QaConvertor.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/QaConvertor.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/convertor/QaConvertor.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/QaEntity.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/entity/QaEntity.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/QaEntity.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/entity/QaEntity.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/QaMapper.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/mapper/QaMapper.java similarity index 100% rename from qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/mapper/QaMapper.java rename to qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/mapper/QaMapper.java diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java deleted file mode 100644 index bec96ab..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/bridge/CreateUserBridge.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.user.adapter.out.persistence.bridge; - -import com.example.user.adapter.out.persistence.convertor.UserConvertor; -import com.example.user.adapter.out.persistence.entity.UserEntity; -import com.example.user.adapter.out.persistence.mapper.UserMapper; -import com.example.user.service.domain.User; -import com.example.user.service.domain.port.CreateUserPort; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class CreateUserBridge implements CreateUserPort { - @Resource - private UserMapper userMapper; - - @Override - public User createUser(User user) { - UserEntity userEntity = UserConvertor.toEntity(user); - int result = userMapper.insert(userEntity); - //result 指受影响行数 - log.info("result:{}",result); - return user; - } -} diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java index 84c2ccb..9bc7ed2 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java @@ -1,8 +1,12 @@ package com.example.qa.service.application.port.in; -import com.example.user.service.application.command.CreateUserCommand; -import com.example.user.service.domain.User; +import com.example.qa.service.application.command.CreateqaCommand; +import com.example.qa.service.domain.qa; + +/* + author: liyujie + */ public interface CreateQaUseCase { - User createUser(CreateQaCommand qaCommand); + qa createqa(CreateQaCommand qaCommand); } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java index 4146079..6c8c5ac 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java @@ -2,29 +2,32 @@ package com.example.qa.service.application.service; import com.example.qa.service.application.command.CreateQaCommand; import com.example.qa.service.application.port.in.CreateQaUseCase; -import com.example.qa.service.domain.User; -import com.example.qa.service.domain.port.CreateUserPort; -import com.example.qa.service.domain.valueobject.Email; -import com.example.qa.service.domain.valueobject.UserAge; -import com.example.qa.service.domain.valueobject.UserName; +import com.example.qa.service.domain.qa; +import com.example.qa.service.domain.port.CreateqaPort; +import com.example.qa.service.domain.valueobject.Question; +import com.example.qa.service.domain.valueobject.Answer; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +/* + author: zhujunjie + */ + @Slf4j @Service public class CreateQaService implements CreateQaUseCase { @Resource - private CreateQaPort createUserPort; + private CreateQaPort createqaPort; @Override - public Qa createUser(CreateQaCommand createUserCommand) { + public Qa createqa(CreateQaCommand createqaCommand) { //command -> domain Qa qa=new Qa( - new UserName(createQaCommand.name()), - new UserAge(createQaCommand.age()), - new Email(createQaCommand.email()) + new Qaid(createQaCommand.id()), + new Answer(createQaCommand.answer()), + new Question(createQaCommand.question()) ); log.info("qa:{}",qa); - return createUserPort.createQa(qa); + return createqaPort.createQa(qa); } } diff --git a/user-service/user-service-application/pom.xml b/user-service/user-service-application/pom.xml index df05045..8d9eb8b 100644 --- a/user-service/user-service-application/pom.xml +++ b/user-service/user-service-application/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-service-application + qa-service-application 0.0.1-SNAPSHOT - user-service-application - user-service-application + qa-service-application + qa-service-application com.example - user-service + qa-service 0.0.1-SNAPSHOT @@ -33,7 +33,7 @@ com.example - user-service-domain + qa-service-domain 0.0.1-SNAPSHOT diff --git a/user-service/user-service-bootstrap/src/main/java/com/example/user/service/bootstrap/UserServiceBootstrapApplication.java b/user-service/user-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/UserServiceBootstrapApplication.java similarity index 100% rename from user-service/user-service-bootstrap/src/main/java/com/example/user/service/bootstrap/UserServiceBootstrapApplication.java rename to user-service/user-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/UserServiceBootstrapApplication.java -- Gitee From 12c1e9dbf685901b106bfe7f0ceaf7f24173ad1c Mon Sep 17 00:00:00 2001 From: Zyc <1577767405@qq.com> Date: Wed, 10 Sep 2025 19:26:38 +0800 Subject: [PATCH 10/23] =?UTF-8?q?docs(qa-service-application.qa-service-ad?= =?UTF-8?q?aptor):=20=E4=BF=AE=E6=94=B9pom=E6=96=87=E4=BB=B6=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qa-service/qa-service-adapter/pom.xml | 12 ++++++------ qa-service/qa-service-adapter/qa-adapter-in/pom.xml | 10 +++++----- .../qa-adapter-in/qa-adapter-in-web/pom.xml | 10 +++++----- qa-service/qa-service-adapter/qa-adapter-out/pom.xml | 10 +++++----- .../qa-adapter-out-persistence/pom.xml | 10 +++++----- qa-service/qa-service-application/pom.xml | 10 +++++----- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/qa-service/qa-service-adapter/pom.xml b/qa-service/qa-service-adapter/pom.xml index 3b61e10..0074d0c 100644 --- a/qa-service/qa-service-adapter/pom.xml +++ b/qa-service/qa-service-adapter/pom.xml @@ -3,22 +3,22 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-service-adapter + qa-service-adapter 0.0.1-SNAPSHOT - user-service-adapter - user-service-adapter + qa-service-adapter + qa-service-adapter pom com.example - user-service + qa-service 0.0.1-SNAPSHOT - user-adapter-in - user-adapter-out + qa-adapter-in + qa-adapter-out diff --git a/qa-service/qa-service-adapter/qa-adapter-in/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/pom.xml index cf0b3a2..473ef75 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/pom.xml @@ -3,21 +3,21 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-in + qa-adapter-in 0.0.1-SNAPSHOT - user-adapter-in - user-adapter-in + qa-adapter-in + qa-adapter-in pom com.example - user-service-adapter + qa-service-adapter 0.0.1-SNAPSHOT - user-adapter-in-web + qa-adapter-in-web diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml index 753f60d..ba230d1 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-in-web + qa-adapter-in-web 0.0.1-SNAPSHOT - user-adapter-in-web - user-adapter-in-web + qa-adapter-in-web + qa-adapter-in-web com.example - user-adapter-in + qa-adapter-in 0.0.1-SNAPSHOT @@ -37,7 +37,7 @@ com.example - user-service-application + qa-service-application 0.0.1-SNAPSHOT diff --git a/qa-service/qa-service-adapter/qa-adapter-out/pom.xml b/qa-service/qa-service-adapter/qa-adapter-out/pom.xml index c6af622..dfc017b 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-out/pom.xml @@ -3,21 +3,21 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-out + qa-adapter-out 0.0.1-SNAPSHOT - user-adapter-out - user-adapter-out + qa-adapter-out + qa-adapter-out pom com.example - user-service-adapter + qa-service-adapter 0.0.1-SNAPSHOT - user-adapter-out-persistence + qa-adapter-out-persistence diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml index 812d59d..9d78608 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/pom.xml @@ -3,13 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-adapter-out-persistence + qa-adapter-out-persistence 0.0.1-SNAPSHOT - user-adapter-out-persistence - user-adapter-out-persistence + qa-adapter-out-persistence + qa-adapter-out-persistence com.example - user-adapter-out + qa-adapter-out 0.0.1-SNAPSHOT @@ -22,7 +22,7 @@ com.example - user-service-domain + qa-service-domain 0.0.1-SNAPSHOT diff --git a/qa-service/qa-service-application/pom.xml b/qa-service/qa-service-application/pom.xml index 78ac32d..8078a94 100644 --- a/qa-service/qa-service-application/pom.xml +++ b/qa-service/qa-service-application/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - user-service-application + qa-service-application 0.0.1-SNAPSHOT - user-service-application - user-service-application + qa-service-application + qa-service-application com.example - user-service + qa-service 0.0.1-SNAPSHOT @@ -33,7 +33,7 @@ com.example - user-service-domain + qa-service-domain 0.0.1-SNAPSHOT -- Gitee From 6c0d43626ea7108c248fe2314488bab08b40576f Mon Sep 17 00:00:00 2001 From: Zyc <1577767405@qq.com> Date: Wed, 10 Sep 2025 19:57:49 +0800 Subject: [PATCH 11/23] =?UTF-8?q?fix(qa-service-domain):=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9Qa=E5=AE=9E=E4=BD=93=E7=B1=BB=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qa-service/qa-service-common/pom.xml | 6 +++--- qa-service/qa-service-domain/pom.xml | 1 + .../src/main/java/com/example/qa/service/domain/Qa.java | 7 ++++--- .../example/qa/service/domain/valueobject/Question.java | 3 +++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/qa-service/qa-service-common/pom.xml b/qa-service/qa-service-common/pom.xml index 2b45a38..d214d8e 100644 --- a/qa-service/qa-service-common/pom.xml +++ b/qa-service/qa-service-common/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - qa-service + qa-service-common 0.0.1-SNAPSHOT qa-service-common qa-service-common @@ -44,8 +44,8 @@ maven-compiler-plugin 3.8.1 - 17 - 17 + 21 + 21 UTF-8 diff --git a/qa-service/qa-service-domain/pom.xml b/qa-service/qa-service-domain/pom.xml index a561c5e..89f21ef 100644 --- a/qa-service/qa-service-domain/pom.xml +++ b/qa-service/qa-service-domain/pom.xml @@ -36,6 +36,7 @@ qa-service-common 0.0.1-SNAPSHOT + diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java index 33d6531..bddc8f8 100644 --- a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/Qa.java @@ -2,10 +2,9 @@ package com.example.qa.service.domain; import com.example.qa.service.common.IdWorker; import com.example.qa.service.domain.port.GetQaListPort; -import com.example.qa.service.domain.valueobject.Email; -import com.example.qa.service.domain.valueobject.QaAge; +import com.example.qa.service.domain.valueobject.Answer; +import com.example.qa.service.domain.valueobject.Question; import com.example.qa.service.domain.valueobject.QaId; -import com.example.qa.service.domain.valueobject.QaName; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -15,9 +14,11 @@ import java.util.List; @Setter @Getter @ToString + /* author: zhangyucheng */ + public class Qa { private QaId id; private Question question; diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java index 52814d7..5c1b0a4 100644 --- a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java @@ -1,5 +1,8 @@ package com.example.qa.service.domain.valueobject; +/* + author: zhangyucheng + */ public record Question(String question) { public String getValue() { return question; -- Gitee From e31f6f8bd483bfe3253ae060dbec7a75fba11c7e Mon Sep 17 00:00:00 2001 From: Zyc <1577767405@qq.com> Date: Wed, 10 Sep 2025 20:10:20 +0800 Subject: [PATCH 12/23] =?UTF-8?q?fix(qa-service-domain):=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=A8=A1=E5=9D=97=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 11 +++++++++++ .idea/encodings.xml | 8 ++++++++ .idea/misc.xml | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 1dbe11b..a38426b 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -7,10 +7,21 @@ + + + + + + + + + + + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 7b5b33a..375fcef 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -2,5 +2,13 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index b317a6b..65df5df 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,5 +4,17 @@ + + + \ No newline at end of file -- Gitee From b803e778c18caddeaa01dad6e62a0d6fe0e920b5 Mon Sep 17 00:00:00 2001 From: L-xiaojie <2107588160@qq.com> Date: Wed, 10 Sep 2025 20:40:20 +0800 Subject: [PATCH 13/23] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 8 +++----- .idea/encodings.xml | 17 +++++++++++++++++ .idea/misc.xml | 9 +++++---- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index a38426b..8758d01 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -10,6 +10,9 @@ + + + @@ -17,11 +20,6 @@ - - - - - diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 375fcef..ca66ba4 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -4,11 +4,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 65df5df..2816d0c 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -7,12 +7,13 @@ -- Gitee From 6e2dfbfa93fa8595b7b56d5388f026310051de0e Mon Sep 17 00:00:00 2001 From: L-xiaojie <2107588160@qq.com> Date: Wed, 10 Sep 2025 21:18:08 +0800 Subject: [PATCH 14/23] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qa-service/qa-service-adapter/pom.xml | 2 +- .../{UserController.java => QaController.java} | 11 +++++------ .../service/application/command/CreateQaCommand.java | 6 ++---- .../service/application/service/CreateQaService.java | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/{UserController.java => QaController.java} (87%) diff --git a/qa-service/qa-service-adapter/pom.xml b/qa-service/qa-service-adapter/pom.xml index 0074d0c..873a26e 100644 --- a/qa-service/qa-service-adapter/pom.xml +++ b/qa-service/qa-service-adapter/pom.xml @@ -26,7 +26,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.13.0 21 21 diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/UserController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java similarity index 87% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/UserController.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java index 0d111b2..ef932a7 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/UserController.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java @@ -32,15 +32,14 @@ public class UserController { } @PostMapping() - public User createUser(@RequestBody CreateUserRequestDTO createUserRequestDTO){ + public Qa createQa(@RequestBody CreateQaRequestDTO createQaRequestDTO){ - CreateUserCommand command=CreateUserCommand.builder() - .name(createUserRequestDTO.name()) - .age(createUserRequestDTO.age()) - .email(createUserRequestDTO.email()) + CreateQaCommand command=CreateQaCommand.builder() + .question(createQaRequestDTO.question()) + .answer(createQaRequestDTO.answer()) .build(); - return createUserUseCase.createUser(command); + return createQaUseCase.createQa(command); } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java index e2c2350..839adf2 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/command/CreateQaCommand.java @@ -1,8 +1,6 @@ package com.example.qa.service.application.command; -/** - * @author zhujunjie - * @param - * @return +/* + author: liyujie */ import lombok.Builder; diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java index 6c8c5ac..7ebf51e 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java @@ -11,7 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /* - author: zhujunjie + author: liyujie */ @Slf4j -- Gitee From 0986c237d3978f9d92afebf28650f8d600a0bd22 Mon Sep 17 00:00:00 2001 From: Zyc <1577767405@qq.com> Date: Wed, 10 Sep 2025 21:28:54 +0800 Subject: [PATCH 15/23] =?UTF-8?q?docs=E4=BF=AE=E6=94=B9=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qa-adapter-in/qa-adapter-in-web/pom.xml | 1 + .../in/web/controller/QaController.java | 9 +++++++-- .../in/web/dto/CreateQaRequestDTO.java | 19 ++++++++++++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml index ba230d1..1194f9d 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml @@ -53,6 +53,7 @@ 21 21 UTF-8 + --enable-preview diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java index ef932a7..0fc668d 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java @@ -43,9 +43,14 @@ public class UserController { } + /** + * @author liaoqi + * @param + * @return + */ @DeleteMapping("{id}") - public String deleteUser(@PathVariable("id") Long id){ - deleteUserUseCase.deleteUser(id); + public String deleteQa(@PathVariable("id") Long id){ + deleteQaUseCase.deleteQa(id); return "success"; } diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java index a399661..aa60908 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java @@ -1,9 +1,18 @@ package com.example.qa.adapter.in.web.dto; -/* - author: liyujie +/** + * @author liyujie + * @param createQaRequestDTO + * @return */ -public record CreateQaRequestDTO( - String question, - String answer) { + +@PostMapping() +public Qa createQa(@RequestBody CreateQaRequestDTO createQaRequestDTO){ + + CreateQaCommand command=CreateQaCommand.builder() + .question(createQaRequestDTO.question()) + .answer(createQaRequestDTO.answer()) + .build(); + + return createQaUseCase.createQa(command); } \ No newline at end of file -- Gitee From 32aca99aca4636f5ca6b3f7c49f31d7f87106d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Thu, 11 Sep 2025 00:14:32 +0800 Subject: [PATCH 16/23] =?UTF-8?q?feat=E5=AE=8C=E6=88=90qa=E5=A2=9E?= =?UTF-8?q?=E5=88=A0=E6=94=B9=E6=9F=A5=EF=BC=8C=E4=BD=BF=E7=94=A8=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E6=9C=BA=E7=99=BB=E9=99=86=E5=90=8E=E5=8F=91=E7=8E=B0?= =?UTF-8?q?=E8=BF=90=E8=A1=8Cdocker-compose.yml=E5=90=8E=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E8=BF=90=E8=A1=8C=EF=BC=8C=E4=BD=86=E6=98=AF?= =?UTF-8?q?nacos=E6=97=A0=E6=B3=95=E8=AE=BF=E9=97=AE=EF=BC=8C=E5=86=85?= =?UTF-8?q?=E9=83=A8=E4=BE=9D=E7=84=B6curl=E4=B8=8D=E9=80=9A=EF=BC=8C?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 6 +- .idea/encodings.xml | 15 ++ .idea/misc.xml | 1 + qa-service/docker-compose.yml | 250 ++++++++++++++++++ qa-service/nacos_config.sql | 179 +++++++++++++ qa-service/pom.xml | 47 +++- .../qa-adapter-in/qa-adapter-in-web/pom.xml | 6 + .../in/web/controller/QaController.java | 81 +++--- .../in/web/dto/CreateQaRequestDTO.java | 20 +- .../in/web/dto/UpdateQaRequestDTO.java | 2 +- .../persistence/bridge/CreateQaBridge.java | 4 +- .../persistence/bridge/UpdateQaBridge.java | 14 +- .../application/port/in/CreateQaUseCase.java | 6 +- .../application/port/in/UpdateQaUseCase.java | 4 +- .../application/service/CreateQaService.java | 15 +- .../application/service/DeleteQaService.java | 1 + .../application/service/UpdateQaService.java | 10 +- .../src/main/resources/application.properties | 4 +- .../in/web/dto/CreateUserRequestDTO.java | 1 - user-service/user-service-application/pom.xml | 10 +- 20 files changed, 571 insertions(+), 105 deletions(-) create mode 100644 qa-service/docker-compose.yml create mode 100644 qa-service/nacos_config.sql diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 8758d01..b3be308 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -10,9 +10,12 @@ + + - + + @@ -20,6 +23,7 @@ + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index ca66ba4..4e6cc9f 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -2,12 +2,23 @@ + + + + + + + + + + + @@ -23,6 +34,10 @@ + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml index 2816d0c..496ab3d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -14,6 +14,7 @@ diff --git a/qa-service/docker-compose.yml b/qa-service/docker-compose.yml new file mode 100644 index 0000000..b92c130 --- /dev/null +++ b/qa-service/docker-compose.yml @@ -0,0 +1,250 @@ +networks: + app_net: + driver: bridge +services: + # MySQL 主库 + mysql: + image: mysql:8.4 + container_name: mysql + environment: + - MYSQL_ROOT_PASSWORD=root + - TZ=Asia/Shanghai + - MYSQL_CHARSET=utf8mb4 + - MYSQL_COLLATION=utf8mb4_general_ci + - MYSQL_ROOT_HOST=% + - MYSQL_SSL_MODE=REQUIRED + ports: + - "3306:3306" + privileged: true + volumes: + - ./mysql/conf.d:/etc/mysql/conf.d + - ./mysql/data:/var/lib/mysql + healthcheck: + test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] + interval: 10s + timeout: 5s + retries: 5 + networks: + - app_net + restart: always + redis: + container_name: redis + image: redis:latest + ports: + - "6379:6379" + privileged: true + healthcheck: + test: [ "CMD", "redis-cli", "ping" ] + interval: 5s + timeout: 3s + retries: 5 + networks: + - app_net + restart: always + + rabbitmq: + container_name: rabbitmq + image: rabbitmq:4.1.2-management + ports: + - "5672:5672" + - "15672:15672" + privileged: true + healthcheck: + test: [ "CMD", "rabbitmqctl", "status" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + minio: + image: quay.io/minio/minio:latest + container_name: minio + restart: always + ports: + - "9000:9000" # S3 API 端口 + - "9001:9001" # Web 控制台端口 + environment: + MINIO_ROOT_USER: admin + MINIO_ROOT_PASSWORD: admin123456 + volumes: + - ./minio-data:/data + command: server /data --console-address ":9001" + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + # RocketMQ NameServer + rocketmq-namesrv: + image: apache/rocketmq:latest + container_name: rocketmq-namesrv + command: sh mqnamesrv + ports: + - "9876:9876" + environment: + JAVA_OPT_EXT: "-server -Xms128m -Xmx128m -Xmn128m" + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9876" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + + # RocketMQ Broker + rocketmq-broker: + image: apache/rocketmq:latest + container_name: rocketmq-broker + command: sh mqbroker -c /home/rocketmq/rocketmq-5.3.3/conf/broker.conf + ports: + - "10909:10909" + - "10911:10911" + - "10912:10912" + environment: + JAVA_OPT_EXT: "-server -Xms128m -Xmx128m -Xmn128m" + NAMESRV_ADDR: "rocketmq-namesrv:9876" + volumes: + - ./rocketmq/conf/broker.conf:/home/rocketmq/rocketmq-5.3.3/conf/broker.conf + - ./rocketmq/logs:/home/rocketmq/logs + - ./rocketmq/store:/home/rocketmq/store + depends_on: + - rocketmq-namesrv + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:10911" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + + # Elasticsearch + elasticsearch: + image: elasticsearch:7.17.28 + container_name: elasticsearch + environment: + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms512m -Xmx512m + - xpack.security.enabled=false + ports: + - "9200:9200" + - "9300:9300" + volumes: + - ./es/data:/usr/share/elasticsearch/data + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9200" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + + # Nginx + nginx: + image: nginx:latest + container_name: nginx + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/conf.d:/etc/nginx/conf.d + - ./nginx/html:/usr/share/nginx/html + - ./nginx/logs:/var/log/nginx + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + nacos: + container_name: nacos + image: nacos/nacos-server:v3.0.2 + ports: + - "8848:8848" + - "8080:8080" + - "9848:9848" + - "9849:9849" + environment: + - TZ=Asia/Shanghai + - MODE=standalone + - PREFER_HOST_MODE=hostname + - SPRING_DATASOURCE_PLATFORM=mysql + - MYSQL_SERVICE_HOST=mysql + - MYSQL_SERVICE_DB_NAME=nacos_config + - MYSQL_SERVICE_PORT=3306 + - MYSQL_SERVICE_USER=root + - MYSQL_SERVICE_PASSWORD=root + - MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + - NACOS_AUTH_IDENTITY_KEY=2222 + - NACOS_AUTH_IDENTITY_VALUE=2xxx + - NACOS_AUTH_TOKEN=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg= + volumes: + - ./nacos/logs:/home/nacos/logs + depends_on: + mysql: + condition: service_healthy + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + privileged: true + restart: always + # Seata + seata-server: + image: seataio/seata-server:1.6.0 + container_name: seata-server + ports: + - "7091:7091" + - "8091:8091" + networks: + - app_net + restart: always + + # Sentinel + sentinel: + image: bladex/sentinel-dashboard:latest + container_name: sentinel + ports: + - "8858:8858" + environment: + - JAVA_OPTS=-Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8858 -Dproject.name=sentinel-dashboard + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8858" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + leaf-server: + image: registry.cn-hangzhou.aliyuncs.com/itheima/meituan-leaf:1.0.1 + container_name: leaf-server + ports: + - "8090:8080" + environment: + - SPRING_PROFILES_ACTIVE=prod + volumes: + - ./leaf/application.properties:/leaf-server/config/application.properties + networks: + - app_net + + zookeeper: + image: bitnami/zookeeper:latest + container_name: zookeeper + ports: + - "2181:2181" + environment: + - ALLOW_ANONYMOUS_LOGIN=yes + networks: + - app_net + restart: always \ No newline at end of file diff --git a/qa-service/nacos_config.sql b/qa-service/nacos_config.sql new file mode 100644 index 0000000..433a90b --- /dev/null +++ b/qa-service/nacos_config.sql @@ -0,0 +1,179 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/******************************************/ +/* 表名称 = config_info */ +/******************************************/ +CREATE TABLE `config_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) DEFAULT NULL COMMENT 'group_id', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `c_desc` varchar(256) DEFAULT NULL COMMENT 'configuration description', + `c_use` varchar(64) DEFAULT NULL COMMENT 'configuration usage', + `effect` varchar(64) DEFAULT NULL COMMENT '配置生效的描述', + `type` varchar(64) DEFAULT NULL COMMENT '配置的类型', + `c_schema` text COMMENT '配置的模式', + `encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' COMMENT '密钥', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info'; + +/******************************************/ +/* 表名称 = config_info since 2.5.0 */ +/******************************************/ +CREATE TABLE `config_info_gray` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `src_user` text COMMENT 'src_user', + `src_ip` varchar(100) DEFAULT NULL COMMENT 'src_ip', + `gmt_create` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'gmt_create', + `gmt_modified` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'gmt_modified', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `gray_name` varchar(128) NOT NULL COMMENT 'gray_name', + `gray_rule` text NOT NULL COMMENT 'gray_rule', + `encrypted_data_key` varchar(256) NOT NULL DEFAULT '' COMMENT 'encrypted_data_key', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfogray_datagrouptenantgray` (`data_id`,`group_id`,`tenant_id`,`gray_name`), + KEY `idx_dataid_gmt_modified` (`data_id`,`gmt_modified`), + KEY `idx_gmt_modified` (`gmt_modified`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='config_info_gray'; + +/******************************************/ +/* 表名称 = config_tags_relation */ +/******************************************/ +CREATE TABLE `config_tags_relation` ( + `id` bigint(20) NOT NULL COMMENT 'id', + `tag_name` varchar(128) NOT NULL COMMENT 'tag_name', + `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `nid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增长标识', + PRIMARY KEY (`nid`), + UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation'; + +/******************************************/ +/* 表名称 = group_capacity */ +/******************************************/ +CREATE TABLE `group_capacity` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', + `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', + `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', + `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', + `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值', + `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', + `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_group_id` (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表'; + +/******************************************/ +/* 表名称 = his_config_info */ +/******************************************/ +CREATE TABLE `his_config_info` ( + `id` bigint(20) unsigned NOT NULL COMMENT 'id', + `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增标识', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + `op_type` char(10) DEFAULT NULL COMMENT 'operation type', + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' COMMENT '密钥', + `publish_type` varchar(50) DEFAULT 'formal' COMMENT 'publish type gray or formal', + `gray_name` varchar(50) DEFAULT NULL COMMENT 'gray name', + `ext_info` longtext DEFAULT NULL COMMENT 'ext info', + PRIMARY KEY (`nid`), + KEY `idx_gmt_create` (`gmt_create`), + KEY `idx_gmt_modified` (`gmt_modified`), + KEY `idx_did` (`data_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造'; + + +/******************************************/ +/* 表名称 = tenant_capacity */ +/******************************************/ +CREATE TABLE `tenant_capacity` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID', + `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', + `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', + `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', + `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数', + `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', + `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表'; + + +CREATE TABLE `tenant_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `kp` varchar(128) NOT NULL COMMENT 'kp', + `tenant_id` varchar(128) default '' COMMENT 'tenant_id', + `tenant_name` varchar(128) default '' COMMENT 'tenant_name', + `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc', + `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source', + `gmt_create` bigint(20) NOT NULL COMMENT '创建时间', + `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info'; + +CREATE TABLE `users` ( + `username` varchar(50) NOT NULL PRIMARY KEY COMMENT 'username', + `password` varchar(500) NOT NULL COMMENT 'password', + `enabled` boolean NOT NULL COMMENT 'enabled' +); + +CREATE TABLE `roles` ( + `username` varchar(50) NOT NULL COMMENT 'username', + `role` varchar(50) NOT NULL COMMENT 'role', + UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE +); + +CREATE TABLE `permissions` ( + `role` varchar(50) NOT NULL COMMENT 'role', + `resource` varchar(128) NOT NULL COMMENT 'resource', + `action` varchar(8) NOT NULL COMMENT 'action', + UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE +); + diff --git a/qa-service/pom.xml b/qa-service/pom.xml index 476ca31..7ba8bd5 100644 --- a/qa-service/pom.xml +++ b/qa-service/pom.xml @@ -11,22 +11,34 @@ 21 UTF-8 UTF-8 - 3.0.2 + 3.2.4 + 2023.0.1.0 + 2023.0.1 + + pom + + + qa-service-bootstrap + qa-service-adapter + qa-service-application + qa-service-domain + qa-service-common + + + - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + org.springframework.boot spring-boot-dependencies @@ -34,6 +46,19 @@ pom import + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.14 + @@ -54,7 +79,7 @@ spring-boot-maven-plugin ${spring-boot.version} - com.example.qa.service.QaServiceApplication + com.example.qa-service.qa-serviceApplication true diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml index 1194f9d..7cad311 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml @@ -35,10 +35,16 @@ lombok + + com.example + user-service-application + 0.0.1-SNAPSHOT + com.example qa-service-application 0.0.1-SNAPSHOT + compile diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java index 0fc668d..f170078 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java @@ -1,12 +1,11 @@ -package com.example.user.adapter.in.web.controller; +package com.example.qa.adapter.in.web.controller; -import com.example.user.adapter.in.web.dto.CreateUserRequestDTO; -import com.example.user.adapter.in.web.dto.UpdateUserRequestDTO; -import com.example.user.adapter.in.web.dto.UserResponseDTO; -import com.example.user.service.application.command.CreateUserCommand; -import com.example.user.service.application.command.UpdateUserCommand; -import com.example.user.service.application.port.in.*; -import com.example.user.service.domain.User; +import com.example.qa.adapter.in.web.dto.CreateQaRequestDTO; +import com.example.qa.adapter.in.web.dto.QaResponseDTO; +import com.example.qa.adapter.in.web.dto.UpdateQaRequestDTO; +import com.example.qa.service.application.command.*; +import com.example.qa.service.application.port.in.*; +import com.example.qa.service.domain.Qa; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @@ -14,23 +13,30 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @Slf4j -@RequestMapping("/users") +@RequestMapping("/qa") @RestController @RequiredArgsConstructor -public class UserController { +public class QaController { - private final GetUserListUseCase getUserListUseCase; - private final CreateUserUseCase createUserUseCase; - private final DeleteUserUseCase deleteUserUseCase; - private final UpdateUserUseCase updateUserUseCase; - private final GetUserByIdUseCase getUserByIdUseCase; + private final GetQaListUseCase getQaListUseCase; + private final CreateQaUseCase createQaUseCase; + private final DeleteQaUseCase deleteQaUseCase; + private final UpdateQaUseCase updateQaUseCase; + private final GetQaByIdUseCase getQaByIdUseCase; @GetMapping("") - public List getUsers() { - log.info("getUsers"); - return getUserListUseCase.getUsers(); + public List getQas() { + log.info("getQas"); + return getQaListUseCase.getQas(); } + /** + * @author liyujie + * @param + * @return + */ + + @PostMapping() public Qa createQa(@RequestBody CreateQaRequestDTO createQaRequestDTO){ @@ -53,38 +59,33 @@ public class UserController { deleteQaUseCase.deleteQa(id); return "success"; } - /** - * @author liuxin - * @param updateUserRequestDTO + * @author zhujunjie + * @param * @return */ @PutMapping("") - public User updateUser(@RequestBody UpdateUserRequestDTO updateUserRequestDTO){ - UpdateUserCommand command=UpdateUserCommand.builder() - .id(updateUserRequestDTO.id()) - .name(updateUserRequestDTO.name()) - .age(updateUserRequestDTO.age()) - .email(updateUserRequestDTO.email()) + public Qa updateQa(@RequestBody UpdateQaRequestDTO updateQaRequestDTO){ + UpdateQaCommand command=UpdateQaCommand.builder() + .id(updateQaRequestDTO.id()) + .question(updateQaRequestDTO.question()) + .answer(updateQaRequestDTO.answer()) .build(); - User user = updateUserUseCase.updateUser(command); - return user; + Qa qa = updateQaUseCase.updateQa(command); + return qa; } - - /** - * @author dengli + * @author ZhangQianyu + 2210705220 * @param id * @return */ @GetMapping("{id}") - public UserResponseDTO getUserById(@PathVariable("id") Long id){ - User user = getUserByIdUseCase.getUserById(id); - UserResponseDTO userResponseDTO = new UserResponseDTO( - user.getId().id(), - user.getName().username(), - user.getAge().age(), - user.getEmail().email()); - return userResponseDTO; + public QaResponseDTO getQaById(@PathVariable("id") Long id){ + Qa qa = getQaByIdUseCase.getQaById(id); + QaResponseDTO qaResponseDTO = new QaResponseDTO( + qa.getId().id(), + qa.getQuestion().question(), + qa.getAnswer().answer()); + return qaResponseDTO; } } diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java index aa60908..fe642cc 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQaRequestDTO.java @@ -1,18 +1,6 @@ package com.example.qa.adapter.in.web.dto; -/** - * @author liyujie - * @param createQaRequestDTO - * @return - */ - -@PostMapping() -public Qa createQa(@RequestBody CreateQaRequestDTO createQaRequestDTO){ - - CreateQaCommand command=CreateQaCommand.builder() - .question(createQaRequestDTO.question()) - .answer(createQaRequestDTO.answer()) - .build(); - - return createQaUseCase.createQa(command); -} \ No newline at end of file +public record CreateQaRequestDTO( + String question, + String answer){ +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQaRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQaRequestDTO.java index 5ef5b88..4cdfc5d 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQaRequestDTO.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQaRequestDTO.java @@ -6,5 +6,5 @@ package com.example.qa.adapter.in.web.dto; */ public record UpdateQaRequestDTO(Long id, String question, - String answer,) { + String answer) { } diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java index 1591518..0df2a1a 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQaBridge.java @@ -20,8 +20,8 @@ public class CreateQaBridge implements CreateQaPort { private QaMapper qaMapper; @Override - public qa createqa(qa qa) { - qaEntity qaEntity = qaConvertor.toEntity(qa); + public Qa createQa(Qa qa) { + QaEntity qaEntity = QaConvertor.toEntity(qa); int result = qaMapper.insert(qaEntity); //result 指受影响行数 log.info("result:{}",result); diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQaBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQaBridge.java index cf6edd9..b4d3c94 100644 --- a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQaBridge.java +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQaBridge.java @@ -1,8 +1,8 @@ -package com.example.Qa.adapter.out.persistence.bridge; -import com.example.Qa.adapter.out.persistence.convertor.QaConvertor; -import com.example.Qa.adapter.out.persistence.mapper.QaMapper; -import com.example.Qa.service.domain.Qa; -import com.example.Qa.service.domain.port.UpdateQaPort; +package com.example.qa.adapter.out.persistence.bridge; +import com.example.qa.adapter.out.persistence.convertor.QaConvertor; +import com.example.qa.adapter.out.persistence.mapper.QaMapper; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.UpdateQaPort; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -16,11 +16,11 @@ import org.springframework.stereotype.Component; @Component public class UpdateQaBridge implements UpdateQaPort { @Resource - private QaMapper QaMapper; + private QaMapper qaMapper; @Override public Qa updateQa(Qa qa) { - int result = QaMapper.updateById(QaConvertor.toEntity(qa)); + int result = qaMapper.updateById(QaConvertor.toEntity(qa)); log.info("result:{}",result); return qa; } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java index 9bc7ed2..22fb92f 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/CreateQaUseCase.java @@ -1,12 +1,12 @@ package com.example.qa.service.application.port.in; -import com.example.qa.service.application.command.CreateqaCommand; -import com.example.qa.service.domain.qa; +import com.example.qa.service.application.command.CreateQaCommand; +import com.example.qa.service.domain.Qa; /* author: liyujie */ public interface CreateQaUseCase { - qa createqa(CreateQaCommand qaCommand); + Qa createQa(CreateQaCommand command); } diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java index 6799e18..8ff994f 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/port/in/UpdateQaUseCase.java @@ -4,8 +4,8 @@ package com.example.qa.service.application.port.in; * @param * @return */ -import com.example.ua.service.application.command.UpdateQaCommand; -import com.example.ua.service.domain.Qa; +import com.example.qa.service.application.command.UpdateQaCommand; +import com.example.qa.service.domain.Qa; public interface UpdateQaUseCase { Qa updateQa(UpdateQaCommand command); diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java index 7ebf51e..e9bba9c 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java @@ -2,10 +2,11 @@ package com.example.qa.service.application.service; import com.example.qa.service.application.command.CreateQaCommand; import com.example.qa.service.application.port.in.CreateQaUseCase; -import com.example.qa.service.domain.qa; -import com.example.qa.service.domain.port.CreateqaPort; -import com.example.qa.service.domain.valueobject.Question; +import com.example.qa.service.domain.Qa; +import com.example.qa.service.domain.port.CreateQaPort; import com.example.qa.service.domain.valueobject.Answer; +import com.example.qa.service.domain.valueobject.QaId; +import com.example.qa.service.domain.valueobject.Question; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -20,12 +21,12 @@ public class CreateQaService implements CreateQaUseCase { @Resource private CreateQaPort createqaPort; @Override - public Qa createqa(CreateQaCommand createqaCommand) { + public Qa createQa(CreateQaCommand createQaCommand) { //command -> domain Qa qa=new Qa( - new Qaid(createQaCommand.id()), - new Answer(createQaCommand.answer()), - new Question(createQaCommand.question()) + new QaId(createQaCommand.id()), + new Question(createQaCommand.question()), + new Answer(createQaCommand.answer()) ); log.info("qa:{}",qa); return createqaPort.createQa(qa); diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java index d2af9f0..0d2937b 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/DeleteQaService.java @@ -1,6 +1,7 @@ package com.example.qa.service.application.service; import com.example.qa.service.application.port.in.DeleteQaUseCase; +import com.example.qa.service.domain.port.DeleteQaPort; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java index f5430b4..3a40bb6 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/UpdateQaService.java @@ -8,10 +8,7 @@ import com.example.qa.service.application.command.UpdateQaCommand; import com.example.qa.service.application.port.in.UpdateQaUseCase; import com.example.qa.service.domain.Qa; import com.example.qa.service.domain.port.UpdateQaPort; -import com.example.qa.service.domain.valueobject.Email; -import com.example.qa.service.domain.valueobject.QaAge; -import com.example.qa.service.domain.valueobject.QaId; -import com.example.qa.service.domain.valueobject.QaName; +import com.example.qa.service.domain.valueobject.*; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -24,9 +21,8 @@ public class UpdateQaService implements UpdateQaUseCase { public Qa updateQa(UpdateQaCommand command) { Qa qa = new Qa( new QaId(command.id()), - new QaName(command.name()), - new QaAge(command.age()), - new Email(command.email())); + new Question(command.question()), + new Answer(command.answer())); return updateQaPort.updateQa(qa); } } diff --git a/qa-service/qa-service-bootstrap/src/main/resources/application.properties b/qa-service/qa-service-bootstrap/src/main/resources/application.properties index f9592d1..12c9b20 100644 --- a/qa-service/qa-service-bootstrap/src/main/resources/application.properties +++ b/qa-service/qa-service-bootstrap/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.application.name=qa-service # Nacos认证信息 -spring.cloud.nacos.discovery.username=nacos +spring.cloud.nacos.discovery.qaname=nacos spring.cloud.nacos.discovery.password=nacos # Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 @@ -13,7 +13,7 @@ spring.cloud.nacos.discovery.namespace=public # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html # Nacos认证信息 -spring.cloud.nacos.config.username=nacos +spring.cloud.nacos.config.qaname=nacos spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.contextPath=/nacos # 设置配置中心服务端地址 diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java index 386262a..b494b7b 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java @@ -4,5 +4,4 @@ public record CreateUserRequestDTO( String name, Integer age, String email) { - } diff --git a/user-service/user-service-application/pom.xml b/user-service/user-service-application/pom.xml index 8d9eb8b..df05045 100644 --- a/user-service/user-service-application/pom.xml +++ b/user-service/user-service-application/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example - qa-service-application + user-service-application 0.0.1-SNAPSHOT - qa-service-application - qa-service-application + user-service-application + user-service-application com.example - qa-service + user-service 0.0.1-SNAPSHOT @@ -33,7 +33,7 @@ com.example - qa-service-domain + user-service-domain 0.0.1-SNAPSHOT -- Gitee From 7275960d66d2569fcf7aaa022bbe07508965f58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Thu, 11 Sep 2025 15:53:28 +0800 Subject: [PATCH 17/23] =?UTF-8?q?feat=E5=AE=8C=E6=88=90qa=E5=A2=9E?= =?UTF-8?q?=E5=88=A0=E6=94=B9=E6=9F=A5=EF=BC=8C=E4=BD=BF=E7=94=A8=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E6=9C=BA=E7=99=BB=E9=99=86=E5=90=8E=E5=8F=91=E7=8E=B0?= =?UTF-8?q?=E8=BF=90=E8=A1=8Cdocker-compose.yml=E5=90=8E=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E8=BF=90=E8=A1=8C=EF=BC=8C=E4=BD=86=E6=98=AF?= =?UTF-8?q?nacos=E6=97=A0=E6=B3=95=E8=AE=BF=E9=97=AE=EF=BC=8C=E5=86=85?= =?UTF-8?q?=E9=83=A8=E4=BE=9D=E7=84=B6curl=E4=B8=8D=E9=80=9A=EF=BC=8C?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qa-adapter-in/qa-adapter-in-web/pom.xml | 2 +- .../qa/adapter/in/web/controller/QaController.java | 2 +- .../qa/service/application/service/CreateQaService.java | 2 -- .../service/bootstrap/QaServiceBootstrapApplication.java | 4 ++-- .../src/main/resources/application.properties | 8 ++++---- qa-service/qa-service-domain/pom.xml | 1 - .../user-adapter-out/user-adapter-out-persistence/pom.xml | 1 + .../src/main/resources/application.properties | 2 +- 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml index 7cad311..d333edd 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/pom.xml @@ -37,7 +37,7 @@ com.example - user-service-application + qa-service-application 0.0.1-SNAPSHOT diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java index f170078..723c00e 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java @@ -37,7 +37,7 @@ public class QaController { */ - @PostMapping() + @PostMapping("") public Qa createQa(@RequestBody CreateQaRequestDTO createQaRequestDTO){ CreateQaCommand command=CreateQaCommand.builder() diff --git a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java index e9bba9c..9a3c7ac 100644 --- a/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java +++ b/qa-service/qa-service-application/src/main/java/com/example/qa/service/application/service/CreateQaService.java @@ -5,7 +5,6 @@ import com.example.qa.service.application.port.in.CreateQaUseCase; import com.example.qa.service.domain.Qa; import com.example.qa.service.domain.port.CreateQaPort; import com.example.qa.service.domain.valueobject.Answer; -import com.example.qa.service.domain.valueobject.QaId; import com.example.qa.service.domain.valueobject.Question; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -24,7 +23,6 @@ public class CreateQaService implements CreateQaUseCase { public Qa createQa(CreateQaCommand createQaCommand) { //command -> domain Qa qa=new Qa( - new QaId(createQaCommand.id()), new Question(createQaCommand.question()), new Answer(createQaCommand.answer()) ); diff --git a/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java b/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java index 1b9be1f..c7c6759 100644 --- a/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java +++ b/qa-service/qa-service-bootstrap/src/main/java/com/example/qa/service/bootstrap/QaServiceBootstrapApplication.java @@ -4,8 +4,8 @@ import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -@SpringBootApplication(scanBasePackages = "com.example") -@MapperScan("com.example.Qa.adapter.out.persistence.mapper") +@SpringBootApplication(scanBasePackages = "com.example.qa") +@MapperScan("com.example.qa.adapter.out.persistence.mapper") public class QaServiceBootstrapApplication { public static void main(String[] args) { diff --git a/qa-service/qa-service-bootstrap/src/main/resources/application.properties b/qa-service/qa-service-bootstrap/src/main/resources/application.properties index 12c9b20..ed16249 100644 --- a/qa-service/qa-service-bootstrap/src/main/resources/application.properties +++ b/qa-service/qa-service-bootstrap/src/main/resources/application.properties @@ -1,10 +1,10 @@ -server.port=28080 +server.port=28081 spring.application.name=qa-service # Nacos认证信息 -spring.cloud.nacos.discovery.qaname=nacos +spring.cloud.nacos.discovery.username=nacos spring.cloud.nacos.discovery.password=nacos # Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 @@ -13,11 +13,11 @@ spring.cloud.nacos.discovery.namespace=public # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html # Nacos认证信息 -spring.cloud.nacos.config.qaname=nacos +spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.contextPath=/nacos # 设置配置中心服务端地址 -spring.cloud.nacos.config.server-addr=192.168.168.128::8848 +spring.cloud.nacos.config.server-addr=192.168.168.128:8848 # Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:${spring.application.name}.properties?refresh=true diff --git a/qa-service/qa-service-domain/pom.xml b/qa-service/qa-service-domain/pom.xml index 89f21ef..bcd25fe 100644 --- a/qa-service/qa-service-domain/pom.xml +++ b/qa-service/qa-service-domain/pom.xml @@ -2,7 +2,6 @@ 4.0.0 - com.example qa-service-domain 0.0.1-SNAPSHOT qa-service-domain diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/pom.xml b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/pom.xml index 812d59d..eb6838c 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/pom.xml +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/pom.xml @@ -55,3 +55,4 @@ + diff --git a/user-service/user-service-bootstrap/src/main/resources/application.properties b/user-service/user-service-bootstrap/src/main/resources/application.properties index e073491..cd28c71 100644 --- a/user-service/user-service-bootstrap/src/main/resources/application.properties +++ b/user-service/user-service-bootstrap/src/main/resources/application.properties @@ -17,7 +17,7 @@ spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.contextPath=/nacos # 设置配置中心服务端地址 -spring.cloud.nacos.config.server-addr=192.168.168.128::8848 +spring.cloud.nacos.config.server-addr=192.168.168.128:8848 # Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:${spring.application.name}.properties?refresh=true -- Gitee From b9ee154a7b3cea6a099316f9c9be08a8a9f28093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Fri, 12 Sep 2025 16:28:40 +0800 Subject: [PATCH 18/23] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=BA=AFjava=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E5=AE=9E=E7=8E=B0=E7=9A=84jwt=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E5=B8=A6lombok=EF=BC=8C=E5=BC=95=E5=85=A5=E4=BC=9A=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=89=88=E6=9C=AC=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/service/UserLoginService.java | 21 ++--- .../src/main/resources/application.properties | 5 ++ user-service/user-service-common/pom.xml | 18 +++++ .../example/user/service/common/JwtUtil.java | 79 +++++++++++++++++++ .../user/service/common/config/JwtConfig.java | 29 +++++++ 5 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java create mode 100644 user-service/user-service-common/src/main/java/com/example/user/service/common/config/JwtConfig.java diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java index 4240269..9187d83 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java @@ -1,9 +1,11 @@ +// user-service-application/src/main/java/com/example/user/application/service/UserLoginService.java package com.example.user.service.application.service; import com.example.user.service.application.command.UserLoginCommand; import com.example.user.service.application.port.in.UserLoginUseCase; import com.example.user.service.domain.User; import com.example.user.service.domain.port.GetUserByNamePort; +import com.example.user.service.common.JwtUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -15,23 +17,22 @@ public class UserLoginService implements UserLoginUseCase { @Resource private GetUserByNamePort getUserByNamePort; + @Resource + private JwtUtil jwtUtil; + @Override public String login(UserLoginCommand userLoginCommand) { - //验证用户 User user = User.getUserByName(userLoginCommand.name(), getUserByNamePort); log.info("user:{}", user); - if(user==null){ + if(user == null){ throw new RuntimeException("用户不存在"); } - //验证密码 if(!user.validatePassword(userLoginCommand.password())){ throw new RuntimeException("密码错误"); } - //签发token - /* - todo 封装一个JwtUtil实现jwt签发 - token 有效期 5min ,key=123456 ,载荷:{name:user.name,id:user.id,is_super} - */ - return "token"; + return jwtUtil.generateToken( + user.getName().getValue(), + user.getId().getValue()); + } -} +} \ No newline at end of file diff --git a/user-service/user-service-bootstrap/src/main/resources/application.properties b/user-service/user-service-bootstrap/src/main/resources/application.properties index e21f2d5..ef6c11a 100644 --- a/user-service/user-service-bootstrap/src/main/resources/application.properties +++ b/user-service/user-service-bootstrap/src/main/resources/application.properties @@ -22,3 +22,8 @@ spring.cloud.nacos.config.server-addr=192.168.168.128:8848 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:${spring.application.name}.properties?refresh=true +#jwt +# ????????????? +jwt.secret=6f4b4d7a9c2e1b8f3a5d6e7c8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b +jwt.expiration= 300000 + # 5min= 300000 \ No newline at end of file diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index a198ef3..f5b652b 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -24,6 +24,24 @@ spring-boot-starter-test test + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java new file mode 100644 index 0000000..dfe88a2 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java @@ -0,0 +1,79 @@ +// JwtUtil.java - 完全不依赖Lombok +package com.example.user.service.common; + +import com.example.user.service.common.config.JwtConfig; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Component +public class JwtUtil { + + private final JwtConfig jwtConfig; + + // 通过构造函数注入配置 + public JwtUtil(JwtConfig jwtConfig) { + this.jwtConfig = jwtConfig; + } + + public String generateToken(String username, Long userId) { + SecretKey key = Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes()); + + Map claims = new HashMap<>(); + claims.put("name", username); + claims.put("id", userId); + + return Jwts.builder() + .setClaims(claims) + .setSubject(username) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + jwtConfig.getExpiration())) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + } + + // 其他方法保持不变... + public boolean validateToken(String token) { + try { + SecretKey key = Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes()); + Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token); + return true; + } catch (Exception e) { + return false; + } + } + + public String getUsernameFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.getSubject(); + } + + public Long getUserIdFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.get("id", Long.class); + } + + public Boolean getIsSuperFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.get("is_super", Boolean.class); + } + + private Claims getClaimsFromToken(String token) { + SecretKey key = Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes()); + return Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token) + .getBody(); + } +} \ No newline at end of file diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/config/JwtConfig.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/config/JwtConfig.java new file mode 100644 index 0000000..5abf081 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/config/JwtConfig.java @@ -0,0 +1,29 @@ +// JwtConfig.java - 手动实现getter/setter +package com.example.user.service.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "jwt") +public class JwtConfig { + private String secret; + private long expiration; + + // 手动实现getter和setter + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public long getExpiration() { + return expiration; + } + + public void setExpiration(long expiration) { + this.expiration = expiration; + } +} \ No newline at end of file -- Gitee From 5b4ddfee6cd0a74936bb79e5460ad8789890d6a4 Mon Sep 17 00:00:00 2001 From: zqy <2287881924@qq.com> Date: Tue, 16 Sep 2025 15:17:20 +0800 Subject: [PATCH 19/23] =?UTF-8?q?=E5=AF=B9=E5=88=9B=E5=BB=BA=E5=92=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8A=9F=E8=83=BD=E7=9A=84=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/adapter/in/web/controller/UserController.java | 1 - .../user/adapter/in/web/dto/CreateUserRequestDTO.java | 1 - .../user/adapter/in/web/dto/UpdateUserRequestDTO.java | 5 +++-- .../user/service/application/command/UpdateUserCommand.java | 5 +++-- .../user/service/application/service/CreateUserService.java | 1 + .../user/service/application/service/UpdateUserService.java | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index 96820c0..150db7c 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -64,7 +64,6 @@ public class UserController { } CreateUserCommand command=CreateUserCommand.builder() .name(createUserRequestDTO.name()) - .age(createUserRequestDTO.age()) .email(createUserRequestDTO.email()) .password(createUserRequestDTO.password()) .build(); diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java index 574d0e0..918bfc0 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java @@ -2,7 +2,6 @@ package com.example.user.adapter.in.web.dto; public record CreateUserRequestDTO( String name, - Integer age, String email, String password, String rePassword) { diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java index d42ae55..6baa149 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java @@ -2,6 +2,7 @@ package com.example.user.adapter.in.web.dto; public record UpdateUserRequestDTO(Long id, String name, - Integer age, - String email) { + String email, + String phone, + String real_name) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java index 0ef0ed9..8b1aa40 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java @@ -5,6 +5,7 @@ import lombok.Builder; @Builder public record UpdateUserCommand(Long id, String name, - Integer age, - String email) { + String email, + String phone, + String real_name) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java index 931828a..ee0839f 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java @@ -26,6 +26,7 @@ public class CreateUserService implements CreateUserUseCase { new Email(createUserCommand.email()), // new Password( createUserCommand.password()) Password.fromRaw(createUserCommand.password()) + ); log.info("user:{}",user); return createUserPort.createUser(user); diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java index 97da325..1adf521 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java @@ -21,8 +21,8 @@ public class UpdateUserService implements UpdateUserUseCase { User user = new User( new UserId(command.id()), new UserName(command.name()), - new UserAge(command.age()), new Email(command.email())); return updateUserPort.updateUser(user); } } + -- Gitee From 2e907463f183612c20bacb30bbcd3ff22ef4bd8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Tue, 16 Sep 2025 15:18:42 +0800 Subject: [PATCH 20/23] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 9 +- .idea/encodings.xml | 2 + .idea/misc.xml | 5 +- .../user-adapter-in-web/pom.xml | 4 + .../in/web/config/BasicSecurityConfig.java | 179 +++++++++ .../user/adapter/in/web/dto/Result.java | 149 ++++++++ .../web/exception/GlobalExceptionHandler.java | 259 +++++++++++++ .../web/filter/JwtAuthenticationFilter.java | 351 ++++++++++++++++++ .../in/web/filter/TokenBlacklistService.java | 203 ++++++++++ user-service/user-service-common/pom.xml | 23 +- .../example/user/service/common/JwtUtil.java | 345 +++++++++++++++++ user-service/user-service-domain/pom.xml | 6 + .../com/example/user/service/domain/User.java | 50 +-- .../service/domain/valueobject/Email.java | 18 +- .../service/domain/valueobject/Phone.java | 23 ++ .../service/domain/valueobject/RealName.java | 23 ++ .../service/domain/valueobject/UserAge.java | 7 - .../service/domain/valueobject/UserName.java | 27 +- .../service/domain/valueobject/UserRole.java | 36 ++ .../domain/valueobject/UserStatus.java | 34 ++ 20 files changed, 1712 insertions(+), 41 deletions(-) create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/exception/GlobalExceptionHandler.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java create mode 100644 user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/TokenBlacklistService.java create mode 100644 user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java create mode 100644 user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java create mode 100644 user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java delete mode 100644 user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java create mode 100644 user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java create mode 100644 user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index b3be308..cbe6e5f 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -8,17 +8,18 @@ + + + + + - - - - diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 4e6cc9f..6418d5e 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -2,6 +2,8 @@ + + diff --git a/.idea/misc.xml b/.idea/misc.xml index 496ab3d..010e673 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -15,8 +15,11 @@ - + + + \ No newline at end of file diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml index b673bee..6ce88a3 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml @@ -25,6 +25,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-security + org.projectlombok lombok diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java new file mode 100644 index 0000000..7282f3c --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java @@ -0,0 +1,179 @@ +package com.example.user.adapter.in.web.config; + +import com.example.ss.demo.filter.JwtAuthenticationFilter; +import com.example.ss.demo.service.CustomUserDetailsService; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; +import java.util.List; + +/** + * Spring Security 配置类 + * 支持JWT认证和跨域配置 + * + * 这个类负责配置整个应用程序的安全策略,包括: + * 1. 用户认证和授权规则 + * 2. JWT Token验证 + * 3. 跨域资源共享(CORS)配置 + * 4. 会话管理策略 + */ +@Configuration +@EnableWebSecurity +@EnableMethodSecurity(prePostEnabled = true) +@RequiredArgsConstructor +public class BasicSecurityConfig { + + /** + * JWT认证过滤器 + * 用于拦截请求并验证JWT Token的有效性 + */ + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + /** + * 自定义用户详情服务 + * 用于加载用户信息进行认证 + */ + private final CustomUserDetailsService userDetailsService; + + + + /** + * 认证管理器 + * 负责处理用户认证请求 + * + * @param config 认证配置对象,由Spring自动注入 + * @return AuthenticationManager 认证管理器实例 + * @throws Exception 如果配置过程中出现异常 + */ + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); + } + + /** + * CORS配置源 + * 配置跨域资源共享策略,允许前端应用访问后端API + * + * @return CorsConfigurationSource CORS配置源 + */ + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + + // 允许的源(Origin),这里设置为允许所有域名访问 + // 在生产环境中应该设置为具体的域名以提高安全性 + configuration.setAllowedOriginPatterns(List.of("*")); + + // 允许的HTTP方法,包括常用的GET、POST、PUT、DELETE等 + configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); + + // 允许的请求头,这里设置为允许所有请求头 + configuration.setAllowedHeaders(List.of("*")); + + // 允许携带凭证(如Cookie),设置为true表示允许跨域请求携带身份信息 + configuration.setAllowCredentials(true); + + // 预检请求的缓存时间,单位秒,这里设置为1小时 + configuration.setMaxAge(3600L); + + // 暴露给客户端的响应头,允许客户端访问这些响应头 + configuration.setExposedHeaders(Arrays.asList("Authorization", "Content-Type")); + + // 创建基于URL的CORS配置源 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + // 对所有路径应用相同的CORS配置 + source.registerCorsConfiguration("/**", configuration); + return source; + } + + /** + * 安全过滤器链配置 + * 定义HTTP请求的安全处理规则 + * + * @param http HttpSecurity对象,用于配置Web安全 + * @return SecurityFilterChain 安全过滤器链 + * @throws Exception 如果配置过程中出现异常 + */ + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + // 禁用CSRF(跨站请求伪造)保护 + // 前后端分离项目通常禁用,因为使用Token认证而不是Session + .csrf(AbstractHttpConfigurer::disable) + + // 启用CORS(跨域资源共享)并使用上面定义的配置 + .cors(cors -> cors.configurationSource(corsConfigurationSource())) + + // 配置会话管理为无状态 + // 因为使用JWT Token认证,不需要服务器保存会话状态 + .sessionManagement(session -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + ) + + // 配置请求授权规则 + .authorizeHttpRequests(authz -> authz + // 公开接口,无需认证即可访问 + .requestMatchers("/api/auth/login", "/api/auth/register").permitAll() + .requestMatchers("/api/auth/debug/**").permitAll() + // Swagger和knife4j文档接口放行,方便查看API文档 + .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll() + .requestMatchers("/doc.html", "/webjars/**", "/favicon.ico").permitAll() + .requestMatchers("/actuator/**").permitAll() + .requestMatchers("/error").permitAll() + // 其他所有请求都需要认证 + .anyRequest().authenticated() + ) + + // 禁用默认的登录页面 + // 因为使用自定义的登录接口,不需要Spring Security提供的默认登录页面 + .formLogin(AbstractHttpConfigurer::disable) + + // 禁用默认的登出页面 + // 因为使用自定义的登出接口,不需要Spring Security提供的默认登出功能 + .logout(AbstractHttpConfigurer::disable) + + // 禁用HTTP Basic认证 + // 因为使用JWT Token认证,不需要HTTP Basic认证方式 + .httpBasic(AbstractHttpConfigurer::disable) + + // 添加JWT认证过滤器 + // 在用户名密码认证过滤器之前添加JWT认证过滤器 + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) + + // 配置用户详情服务 + // 用于加载用户信息进行认证 + .userDetailsService(userDetailsService) + + // 配置异常处理 + .exceptionHandling(exceptions -> exceptions + // 认证入口点,当未认证用户访问需要认证的资源时调用 + .authenticationEntryPoint((request, response, authException) -> { + response.setStatus(401); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"code\":401,\"message\":\"未授权访问,请先登录\",\"data\":null}"); + }) + // 访问拒绝处理器,当已认证用户访问没有权限的资源时调用 + .accessDeniedHandler((request, response, accessDeniedException) -> { + response.setStatus(403); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"code\":403,\"message\":\"访问被拒绝,权限不足\",\"data\":null}"); + }) + ); + + return http.build(); + } +} diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java new file mode 100644 index 0000000..245d8f6 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/Result.java @@ -0,0 +1,149 @@ +package com.example.user.adapter.in.web.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 通用响应结果类 + * 用于封装所有API接口的响应数据,统一返回格式 + * + * 这样做有以下好处: + * 1. 前端可以统一处理响应格式 + * 2. 便于统一错误处理 + * 3. 提高代码的可维护性 + * + * 使用泛型可以让这个类适用于任何类型的数据 + * + * @Data Lombok注解,自动生成getter、setter、toString等方法 + * @NoArgsConstructor Lombok注解,生成无参构造函数 + * @AllArgsConstructor Lombok注解,生成全参构造函数 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Result { + + /** + * 响应码 + * + * 用于表示请求处理的结果状态 + * 常见的响应码: + * 200 - 成功 + * 400 - 请求参数错误 + * 401 - 未授权 + * 403 - 禁止访问 + * 500 - 服务器内部错误 + */ + private Integer code; + + /** + * 响应消息 + * + * 用于描述请求处理的结果信息 + * 成功时可以是"操作成功" + * 失败时可以是具体的错误信息,如"用户名或密码错误" + */ + private String message; + + /** + * 响应数据 + * + * 用于携带具体的业务数据 + * 可以是任何类型,如用户信息、列表数据等 + * 使用泛型T使得这个字段可以适应不同类型的数据 + */ + private T data; + + /** + * 成功响应静态方法 + * + * 用于创建成功的响应结果 + * + * @param data 响应数据 + * @return Result 成功的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result success(T data) { + return new Result<>(200, "操作成功", data); + } + + /** + * 成功响应静态方法(无数据) + * + * 用于创建不携带数据的成功响应结果 + * + * @return Result 成功的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result success() { + return new Result<>(200, "操作成功", null); + } + + /** + * 成功响应静态方法(自定义消息) + * + * 用于创建携带自定义成功消息的响应结果 + * + * @param message 自定义的成功消息 + * @param data 响应数据 + * @return Result 成功的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result success(String message, T data) { + return new Result<>(200, message, data); + } + + /** + * 失败响应静态方法 + * + * 用于创建失败的响应结果,默认使用500状态码 + * + * @param message 错误消息 + * @return Result 失败的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result error(String message) { + return new Result<>(500, message, null); + } + + /** + * 失败响应静态方法(自定义状态码) + * + * 用于创建携带自定义状态码的失败响应结果 + * + * @param code 自定义状态码 + * @param message 错误消息 + * @return Result 失败的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result error(Integer code, String message) { + return new Result<>(code, message, null); + } + + /** + * 未授权响应静态方法 + * + * 用于创建401未授权的响应结果 + * + * @param message 错误消息 + * @return Result 未授权的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result unauthorized(String message) { + return new Result<>(401, message, null); + } + + /** + * 禁止访问响应静态方法 + * + * 用于创建403禁止访问的响应结果 + * + * @param message 错误消息 + * @return Result 禁止访问的响应结果 + * @param 泛型参数,表示数据的类型 + */ + public static Result forbidden(String message) { + return new Result<>(403, message, null); + } +} \ No newline at end of file diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/exception/GlobalExceptionHandler.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..14605dc --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,259 @@ +package com.example.user.adapter.in.web.exception; + +import com.example.user.adapter.in.web.dto.Result; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.stream.Collectors; + +/** + * 全局异常处理器 + * 统一处理应用中的各种异常,避免异常直接暴露给用户 + * + * @Slf4j Lombok注解,自动生成日志对象log,用于记录异常日志 + * @RestControllerAdvice 组合注解,相当于@ControllerAdvice + @ResponseBody + * 用于定义全局异常处理器,可以捕获控制器层抛出的异常 + */ +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + /** + * 处理认证异常 + * + * 当用户认证失败时(如Token无效、过期等)会抛出AuthenticationException + * + * @ExceptionHandler 注解指定该方法处理哪种异常 + * @ResponseStatus 注解指定返回的HTTP状态码 + * + * @param e 认证异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(AuthenticationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Result handleAuthenticationException(AuthenticationException e) { + log.error("认证异常: {}", e.getMessage()); + return Result.unauthorized("认证失败: " + e.getMessage()); + } + + /** + * 处理凭据错误异常 + * + * 当用户名或密码错误时会抛出BadCredentialsException + * 这是AuthenticationException的一个子类 + * + * @param e 凭据错误异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(BadCredentialsException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Result handleBadCredentialsException(BadCredentialsException e) { + log.error("凭据错误: {}", e.getMessage()); + return Result.unauthorized("用户名或密码错误"); + } + + /** + * 处理访问拒绝异常 + * + * 当已认证用户尝试访问没有权限的资源时会抛出AccessDeniedException + * + * @param e 访问拒绝异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(AccessDeniedException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public Result handleAccessDeniedException(AccessDeniedException e) { + log.error("访问拒绝: {}", e.getMessage()); + return Result.forbidden("访问被拒绝,权限不足"); + } + + /** + * 处理参数校验异常 - @Valid注解 + * + * 当使用@Valid注解验证请求参数失败时会抛出MethodArgumentNotValidException + * 例如LoginRequest中的用户名或密码不符合验证规则 + * + * @param e 参数校验异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + // 收集所有字段的错误信息并拼接成字符串 + String errorMessage = e.getBindingResult().getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining(", ")); + log.error("参数校验失败: {}", errorMessage); + return Result.error("参数校验失败: " + errorMessage); + } + + /** + * 处理参数绑定异常 + * + * 当请求参数绑定到对象时发生错误会抛出BindException + * + * @param e 参数绑定异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(BindException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleBindException(BindException e) { + // 收集所有字段的错误信息并拼接成字符串 + String errorMessage = e.getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining(", ")); + log.error("参数绑定失败: {}", errorMessage); + return Result.error("参数绑定失败: " + errorMessage); + } + + /** + * 处理约束违反异常 + * + * 当使用Bean Validation API验证失败时会抛出ConstraintViolationException + * + * @param e 约束违反异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleConstraintViolationException(ConstraintViolationException e) { + // 收集所有约束违反的错误信息并拼接成字符串 + String errorMessage = e.getConstraintViolations().stream() + .map(ConstraintViolation::getMessage) + .collect(Collectors.joining(", ")); + log.error("约束违反: {}", errorMessage); + return Result.error("参数校验失败: " + errorMessage); + } + + /** + * 处理非法参数异常 + * + * 当传递给方法的参数不合法时会抛出IllegalArgumentException + * + * @param e 非法参数异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleIllegalArgumentException(IllegalArgumentException e) { + log.error("非法参数: {}", e.getMessage()); + return Result.error("参数错误: " + e.getMessage()); + } + + /** + * 处理空指针异常 + * + * 当尝试访问空对象的属性或方法时会抛出NullPointerException + * + * @param e 空指针异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(NullPointerException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public Result handleNullPointerException(NullPointerException e) { + log.error("空指针异常", e); + return Result.error("系统内部错误,请联系管理员"); + } + + /** + * 处理运行时异常 + * + * 当发生未预期的运行时错误时会抛出RuntimeException + * 这是很多异常的父类 + * + * @param e 运行时异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(RuntimeException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public Result handleRuntimeException(RuntimeException e) { + log.error("运行时异常: {}", e.getMessage(), e); + return Result.error("系统异常: " + e.getMessage()); + } + + /** + * 处理其他所有异常 + * + * 作为兜底的异常处理方法,处理所有未被上面方法处理的异常 + * + * @param e 异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public Result handleException(Exception e) { + log.error("未知异常: {}", e.getMessage(), e); + return Result.error("系统内部错误,请联系管理员"); + } + + /** + * 自定义业务异常类 + * + * 用于处理应用程序中特定的业务异常 + * 继承自RuntimeException,是一个受检异常 + */ + public static class BusinessException extends RuntimeException { + /** + * 异常码 + * + * 用于标识异常的类型,便于前端进行不同的处理 + */ + private final int code; + + /** + * 构造函数 - 只有消息 + * + * @param message 异常消息 + */ + public BusinessException(String message) { + super(message); + this.code = 500; + } + + /** + * 构造函数 - 有码和消息 + * + * @param code 异常码 + * @param message 异常消息 + */ + public BusinessException(int code, String message) { + super(message); + this.code = code; + } + + /** + * 获取异常码 + * + * @return int 异常码 + */ + public int getCode() { + return code; + } + } + + /** + * 处理自定义业务异常 + * + * 处理应用程序中抛出的BusinessException + * + * @param e 业务异常对象 + * @return Result 统一响应结果 + */ + @ExceptionHandler(BusinessException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public Result handleBusinessException(BusinessException e) { + log.error("业务异常: {}", e.getMessage()); + return Result.error(e.getCode(), e.getMessage()); + } +} \ No newline at end of file diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java new file mode 100644 index 0000000..055d347 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/JwtAuthenticationFilter.java @@ -0,0 +1,351 @@ +package com.example.user.adapter.in.web.filter; + + +import com.example.user.service.common.JwtUtil; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +/** + * JWT认证过滤器 - Spring Security认证体系的核心组件 + * + * 【什么是过滤器?】 + * 过滤器(Filter)是Java Web开发中的重要组件,它像一个"检查站",在请求到达Controller之前 + * 对每个HTTP请求进行预处理和验证。想象成机场安检,每个乘客(请求)都必须通过安检(过滤器) + * 才能登机(到达Controller)。 + * + * 【JWT认证过滤器的作用】 + * 1. 拦截所有HTTP请求 + * 2. 检查请求头中是否包含有效的JWT Token + * 3. 验证Token的合法性(是否过期、签名是否正确) + * 4. 如果Token有效,将用户信息设置到Spring Security上下文中 + * 5. 如果Token无效或不存在,让请求继续,由其他安全机制处理 + * + * 【为什么继承OncePerRequestFilter?】 + * OncePerRequestFilter确保每个请求只被过滤一次,避免重复验证造成性能问题。 + * 在复杂的Web应用中,一个请求可能会经过多个过滤器,这个基类保证了我们的 + * JWT验证逻辑只执行一次。 + * + * 【Spring Security认证流程】 + * 1. 用户发送请求 → 2. JWT过滤器验证Token → 3. 设置认证上下文 → 4. 后续代码可以获取用户信息 + * + * 【注解说明】 + * @Slf4j: Lombok注解,自动生成日志对象log,用于记录调试和错误信息 + * @Component: Spring注解,将该类注册为Spring容器管理的Bean,可以被自动注入 + */ +@Slf4j +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + /** + * JWT工具类 - Token操作的核心工具 + * + * 【作用说明】 + * 负责JWT Token的生成、解析、验证等所有操作 + * + * 【@Autowired注解】 + * Spring的依赖注入注解,Spring容器会自动找到JwtUtil类型的Bean并注入到这里 + * 这样我们就不需要手动创建JwtUtil对象,Spring帮我们管理对象的生命周期 + */ + @Autowired + private JwtUtil jwtUtil; + + /** + * Token黑名单服务 - 管理已失效的JWT Token + * + * 【作用说明】 + * 用于解决JWT无状态特性导致的logout后token仍然有效的问题 + * 通过维护一个黑名单,记录已经失效的token + * + * 【JWT无状态认证的挑战】 + * JWT设计为无状态,服务器不保存token信息,这带来了扩展性优势 + * 但也带来了问题:无法主动使token失效(如用户logout) + * + * 【黑名单解决方案】 + * 1. 用户logout时,将token加入黑名单 + * 2. 每次验证token时,先检查是否在黑名单中 + * 3. 黑名单中的token被视为无效,拒绝访问 + * + * 【性能考虑】 + * 黑名单检查会增加一定的性能开销,但这是安全性的必要代价 + * 在生产环境中,建议使用Redis等高性能缓存来存储黑名单 + */ + @Autowired + private TokenBlacklistService tokenBlacklistService; + + /** + * Spring应用上下文 - Spring容器的入口 + * + * 【作用说明】 + * ApplicationContext是Spring容器的核心接口,通过它可以获取容器中的任何Bean + * + * 【为什么需要它?】 + * 在某些情况下,我们需要动态获取Bean,而不是通过@Autowired静态注入 + * 特别是在解决循环依赖问题时,这种方式非常有用 + */ + @Autowired + private ApplicationContext applicationContext; + + /** + * 用户详情服务 - 用户信息加载器 + * + * 【设计说明】 + * 注意这里没有使用@Autowired注解,而是通过延迟加载的方式获取 + * 这是为了避免循环依赖问题: + * JwtAuthenticationFilter需要UserDetailsService, + * 而UserDetailsService的实现类可能也需要其他被JwtAuthenticationFilter保护的组件 + * + * 【延迟加载的好处】 + * 只有在真正需要时才获取Bean,避免启动时的循环依赖问题 + */ + private UserDetailsService userDetailsService; + + /** + * 获取用户详情服务实例 - 延迟加载模式的实现 + * + * 【延迟加载模式(Lazy Loading)】 + * 这是一种设计模式,只有在真正需要对象时才创建或获取它 + * 类似于"用时再买"的概念,避免提前准备造成的资源浪费 + * + * 【解决循环依赖的核心方法】 + * 循环依赖问题:A需要B,B需要A,如果同时创建会造成死锁 + * 解决方案:A先创建,需要B时再去获取B,这样打破了循环 + * + * 【实现原理】 + * 1. 第一次调用时,userDetailsService为null,通过ApplicationContext获取Bean + * 2. 后续调用直接返回已获取的实例,提高性能 + * 3. 这种方式叫做"单例模式 + 延迟初始化" + * + * 【为什么不直接用@Autowired?】 + * 如果直接用@Autowired,Spring在启动时就要解决所有依赖关系 + * 可能会遇到循环依赖导致启动失败 + * + * @return UserDetailsService 用户详情服务实例 + */ + private UserDetailsService getUserDetailsService() { + if (userDetailsService == null) { + // 通过Spring容器动态获取Bean,避免循环依赖 + userDetailsService = applicationContext.getBean(UserDetailsService.class); + } + return userDetailsService; + } + + /** + * 过滤器核心方法 - JWT认证的完整流程实现 + * + * 【方法执行时机】 + * 每个HTTP请求到达Controller之前都会执行这个方法 + * 这是Spring Security认证链中的关键环节 + * + * 【完整的JWT认证流程】 + * 1. 提取Token:从HTTP请求头的Authorization字段中提取JWT Token + * 2. 解析Token:使用JWT工具类解析Token,获取用户名 + * 3. 验证Token:检查Token是否过期、签名是否正确 + * 4. 加载用户:从数据库加载用户详细信息 + * 5. 创建认证:创建Spring Security认证对象 + * 6. 设置上下文:将认证信息存储到SecurityContext中 + * 7. 继续处理:调用过滤器链,让请求继续向下传递 + * + * 【Spring Security上下文的作用】 + * SecurityContext就像一个"身份证明",一旦设置成功,后续的所有代码 + * 都可以通过SecurityContextHolder.getContext()获取当前用户信息 + * + * 【异常处理策略】 + * 如果JWT验证失败,不会阻止请求继续执行,而是清除认证上下文 + * 让Spring Security的其他机制(如返回401未授权)来处理 + * + * @param request HTTP请求对象,包含客户端发送的所有信息 + * @param response HTTP响应对象,用于向客户端发送响应 + * @param filterChain 过滤器链,用于调用下一个过滤器或最终的Controller + * @throws ServletException Servlet相关异常 + * @throws IOException 输入输出异常 + */ + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + try { + // 【步骤1:提取JWT Token】 + // 从HTTP请求头的Authorization字段中提取Token + // 标准格式:Authorization: Bearer + String jwt = getJwtFromRequest(request); + + // 【步骤2:检查Token是否存在】 + // StringUtils.hasText()检查字符串是否不为null且不为空字符串 + // 如果没有Token,说明可能是匿名访问或登录请求 + if (StringUtils.hasText(jwt)) { + // 【步骤2.5:检查Token是否在黑名单中】 + // 这是新增的安全检查,解决JWT无状态认证的logout问题 + // 如果token在黑名单中,说明用户已经logout,应该拒绝访问 + if (tokenBlacklistService.isBlacklisted(jwt)) { + log.warn("Token is blacklisted (user has logged out): {}", + jwt.substring(0, Math.min(20, jwt.length())) + "..."); + // 清除认证上下文,确保不会认证成功 + SecurityContextHolder.clearContext(); + // 继续过滤器链,让Spring Security返回401未授权 + filterChain.doFilter(request, response); + return; + } + + // 【步骤3:解析Token获取用户名】 + // 这一步会解析JWT的payload部分,提取用户名信息 + // 如果Token格式错误或签名无效,会抛出异常 + String username = jwtUtil.getUsernameFromToken(jwt); + + // 【步骤4:检查是否需要认证】 + // username != null: 确保成功从Token中提取到用户名 + // SecurityContextHolder.getContext().getAuthentication() == null: 确保当前请求还没有认证信息 + // 这样避免重复认证,提高性能 + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + // 【步骤5:加载用户详细信息】 + // 通过用户名从数据库加载完整的用户信息(包括权限、角色等) + // 这里使用了延迟加载的UserDetailsService,避免循环依赖 + UserDetails userDetails = getUserDetailsService().loadUserByUsername(username); + + // 【步骤6:验证Token的完整性】 + // 不仅要检查Token格式,还要验证: + // 1. Token是否过期 + // 2. 签名是否正确 + // 3. Token中的用户名是否与数据库中的一致 + if (jwtUtil.validateToken(jwt, userDetails.getUsername())) { + // 【步骤7:创建Spring Security认证对象】 + // UsernamePasswordAuthenticationToken是Spring Security的标准认证对象 + // 三个参数的含义: + // 1. principal: 主体,通常是用户详情对象 + // 2. credentials: 凭据,JWT模式下不需要密码,设为null + // 3. authorities: 权限列表,从用户详情中获取 + UsernamePasswordAuthenticationToken authentication = + new UsernamePasswordAuthenticationToken( + userDetails, // 用户详情(包含用户名、权限等) + null, // 凭据(JWT认证不需要密码) + userDetails.getAuthorities() // 用户权限列表 + ); + + // 【步骤8:设置认证详情】 + // 添加额外的认证信息,如IP地址、Session ID等 + // 这些信息在安全审计和日志记录中很有用 + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + + // 【步骤9:设置到Spring Security上下文】 + // 这是最关键的一步!将认证信息存储到SecurityContext中 + // 后续的Controller、Service等都可以通过SecurityContextHolder获取当前用户信息 + // 这就是Spring Security"记住"用户身份的机制 + SecurityContextHolder.getContext().setAuthentication(authentication); + + // 记录成功的认证日志,便于调试和监控 + log.debug("JWT authentication successful for user: {}", username); + } else { + // Token验证失败,记录警告日志 + // 可能的原因:Token过期、签名错误、用户名不匹配等 + log.warn("JWT token validation failed for user: {}", username); + } + } + } + } catch (Exception e) { + // 【异常处理:安全优先原则】 + // 任何异常都不应该影响系统的安全性 + // 记录错误日志,便于排查问题 + log.error("Cannot set user authentication: {}", e.getMessage()); + // 清除认证上下文,确保不会使用错误或不完整的认证信息 + // 这是安全编程的重要原则:出错时选择更安全的状态 + SecurityContextHolder.clearContext(); + } + + // 继续过滤器链,让请求继续向下处理 + filterChain.doFilter(request, response); + } + + /** + * 从请求中提取JWT Token - HTTP标准认证头解析 + * + * 【HTTP Authorization头标准】 + * HTTP协议规定,认证信息应该放在Authorization请求头中 + * JWT认证的标准格式:Authorization: Bearer + * + * 【Bearer认证方案】 + * Bearer是OAuth 2.0规范中定义的认证方案 + * 意思是"持有者",表示谁持有这个Token,谁就有相应的权限 + * 格式:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... + * + * 【为什么要单独提取?】 + * 1. 代码复用:多个地方可能需要提取Token + * 2. 职责分离:Token提取和Token验证是不同的职责 + * 3. 易于测试:可以单独测试Token提取逻辑 + * + * @param request HTTP请求对象,包含所有请求头信息 + * @return JWT Token字符串,如果不存在或格式错误则返回null + */ + private String getJwtFromRequest(HttpServletRequest request) { + // 从请求头中获取Authorization字段的值 + // 例如:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + String bearerToken = request.getHeader("Authorization"); + // 使用JwtUtil工具类提取实际的Token部分(去掉"Bearer "前缀) + return jwtUtil.extractTokenFromHeader(bearerToken); + } + + /** + * 判断是否需要过滤 - 实现白名单机制 + * + * 【白名单机制的重要性】 + * 不是所有的接口都需要JWT认证,有些接口必须是公开的: + * 1. 登录接口:用户还没有Token,怎么能要求提供Token? + * 2. 注册接口:新用户注册时也没有Token + * 3. 文档接口:开发时需要查看API文档 + * + * 【OncePerRequestFilter的设计】 + * OncePerRequestFilter提供了shouldNotFilter方法,让我们可以灵活控制 + * 哪些请求需要过滤,哪些不需要。返回true表示跳过过滤。 + * + * 【安全考虑】 + * 白名单要谨慎设置,只有真正需要公开访问的接口才能加入白名单 + * 过多的白名单会降低系统安全性 + * + * 【路径匹配策略】 + * 使用startsWith进行前缀匹配,这样可以匹配一类接口 + * 例如:/user/login 可以匹配 /user/login、/user/login?username=xxx 等 + * + * @param request HTTP请求对象 + * @return boolean 是否不需要过滤,true表示跳过JWT验证 + * @throws ServletException Servlet异常 + */ + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + // 获取请求的URI路径 + String path = request.getRequestURI(); + + // 【业务接口白名单】 + // /user/login: 用户登录接口,用户通过用户名密码获取Token + // /user/register: 用户注册接口,新用户创建账号 + boolean isBusinessWhitelist = path.startsWith("/user/login") || + path.startsWith("/user/register"); + + // 【文档接口白名单】 + // 这些是Swagger API文档相关的接口,开发阶段需要公开访问 + // /doc.html: Knife4j文档首页 + // /swagger-ui: Swagger UI界面 + // /v3/api-docs: OpenAPI 3.0规范的JSON文档 + // /webjars: 前端资源文件(CSS、JS等) + boolean isDocWhitelist = path.startsWith("/doc.html") || + path.startsWith("/swagger-ui") || + path.startsWith("/v3/api-docs") || + path.startsWith("/webjars"); + + // 返回true表示不需要JWT验证,false表示需要验证 + return isBusinessWhitelist || isDocWhitelist; + } +} \ No newline at end of file diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/TokenBlacklistService.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/TokenBlacklistService.java new file mode 100644 index 0000000..9e21522 --- /dev/null +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/filter/TokenBlacklistService.java @@ -0,0 +1,203 @@ +package com.example.user.adapter.in.web.filter; + +import com.example.user.service.common.JwtUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Token黑名单服务类 - JWT令牌失效管理 + * + * 这个服务类解决了JWT无状态认证中的一个重要问题:如何在用户登出后立即使令牌失效 + * + * JWT的无状态特性说明: + * - JWT令牌是自包含的,包含了所有必要的用户信息 + * - 服务端不需要存储会话状态,每次请求都通过验证令牌签名来确认身份 + * - 这种设计的优点是可扩展性好,但缺点是无法在服务端主动"销毁"令牌 + * - 令牌在过期时间之前始终有效,即使用户已经登出 + * + * 黑名单机制原理: + * 1. 维护一个已失效令牌的黑名单列表 + * 2. 用户登出时,将令牌添加到黑名单 + * 3. 每次验证令牌时,先检查是否在黑名单中 + * 4. 如果在黑名单中,则拒绝访问,即使令牌本身是有效的 + * + * 存储方案选择: + * - 内存存储(ConcurrentHashMap):适合单机部署,性能最好 + * - Redis存储:适合分布式部署,多个服务实例共享黑名单 + * - 数据库存储:适合对数据持久性要求高的场景 + * + * 本实现使用内存存储,具有以下特点: + * - 高性能:内存访问速度快,不涉及网络IO + * - 线程安全:使用ConcurrentHashMap保证并发安全 + * - 自动清理:定时清理过期的黑名单记录,避免内存泄漏 + * - 简单可靠:无外部依赖,部署简单 + * + * 注意事项: + * - 重启服务会丢失黑名单数据,已登出的用户令牌可能重新生效 + * - 多实例部署时,各实例的黑名单不共享 + * - 如需解决以上问题,建议改用Redis等外部存储 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class TokenBlacklistService { + + /** + * JWT工具类,用于解析令牌获取过期时间 + */ + private final JwtUtil jwtUtil; + + /** + * 黑名单存储容器 + * + * 使用ConcurrentHashMap确保线程安全的并发访问 + * Key: JWT令牌字符串 + * Value: 令牌的过期时间,用于定时清理 + * + * 为什么存储过期时间: + * - 避免永久存储已过期的令牌,节省内存空间 + * - 支持定时清理机制,自动移除不再需要的黑名单记录 + * - 提供调试信息,便于排查问题 + */ + private final ConcurrentHashMap blacklistedTokens = new ConcurrentHashMap<>(); + + /** + * 将令牌添加到黑名单 + * + * 当用户登出时调用此方法,将JWT令牌加入黑名单 + * 加入黑名单后,该令牌将无法再用于身份验证 + * + * 实现细节: + * 1. 解析令牌获取过期时间 + * 2. 将令牌和过期时间存入黑名单Map + * 3. 记录操作日志,便于审计和调试 + * + * 异常处理: + * - 如果令牌格式无效,会记录警告日志但不抛出异常 + * - 确保即使个别令牌处理失败,也不影响整体功能 + * + * @param token JWT令牌字符串 + */ + public void addToBlacklist(String token) { + try { + // 解析令牌获取过期时间 + // 这样可以在令牌自然过期后自动清理黑名单记录 + Date expirationTime = jwtUtil.getExpirationDateFromToken(token); + + // 将令牌添加到黑名单 + blacklistedTokens.put(token, expirationTime); + + // 记录操作日志(只记录令牌的前几位,避免泄露完整令牌) + log.info("令牌已添加到黑名单,过期时间: {}, 令牌前缀: {}...", + expirationTime, + token.substring(0, Math.min(token.length(), 10))); + + } catch (Exception e) { + // 如果解析令牌失败,记录警告日志 + log.warn("添加令牌到黑名单时发生错误: {}, 令牌前缀: {}...", + e.getMessage(), + token.substring(0, Math.min(token.length(), 10))); + } + } + + /** + * 检查令牌是否在黑名单中 + * + * 在JWT认证过滤器中调用此方法,检查令牌是否已被列入黑名单 + * 如果令牌在黑名单中,则应拒绝该请求的访问 + * + * 性能考虑: + * - ConcurrentHashMap的containsKey操作时间复杂度为O(1) + * - 即使黑名单中有大量令牌,查询性能也很好 + * - 无需额外的网络请求或磁盘IO + * + * @param token JWT令牌字符串 + * @return boolean true表示令牌在黑名单中(应拒绝访问),false表示不在黑名单中 + */ + public boolean isBlacklisted(String token) { + boolean isBlacklisted = blacklistedTokens.containsKey(token); + + if (isBlacklisted) { + log.debug("检测到黑名单令牌访问尝试,令牌前缀: {}...", + token.substring(0, Math.min(token.length(), 10))); + } + + return isBlacklisted; + } + + /** + * 定时清理过期的黑名单令牌 + * + * 使用Spring的@Scheduled注解实现定时任务 + * 每小时执行一次清理操作,移除已经自然过期的令牌 + * + * 清理的必要性: + * - 避免内存泄漏:长期运行的服务会积累大量过期令牌 + * - 提高性能:减少黑名单大小,提高查询效率 + * - 节省资源:释放不再需要的内存空间 + * + * 清理策略: + * - 只清理已经过期的令牌(当前时间 > 令牌过期时间) + * - 使用迭代器安全地删除元素,避免并发修改异常 + * - 记录清理统计信息,便于监控和调试 + * + * 定时配置说明: + * - fixedRate = 3600000:每3600000毫秒(1小时)执行一次 + * - 可以根据实际需求调整清理频率 + * - 频率过高会增加CPU开销,频率过低会占用更多内存 + */ + @Scheduled(fixedRate = 3600000) // 每小时执行一次 + public void cleanupExpiredTokens() { + Date now = new Date(); + int initialSize = blacklistedTokens.size(); + + // 使用removeIf方法安全地移除过期令牌 + // 这个方法是线程安全的,不会与其他操作产生冲突 + blacklistedTokens.entrySet().removeIf(entry -> { + Date expirationTime = entry.getValue(); + return expirationTime != null && now.after(expirationTime); + }); + + int finalSize = blacklistedTokens.size(); + int cleanedCount = initialSize - finalSize; + + if (cleanedCount > 0) { + log.info("黑名单清理完成,清理了 {} 个过期令牌,当前黑名单大小: {}", cleanedCount, finalSize); + } else { + log.debug("黑名单清理完成,无过期令牌需要清理,当前黑名单大小: {}", finalSize); + } + } + + /** + * 获取当前黑名单大小 + * + * 提供监控和调试功能,可以了解当前黑名单的使用情况 + * + * @return int 黑名单中令牌的数量 + */ + public int getBlacklistSize() { + return blacklistedTokens.size(); + } + + /** + * 清空所有黑名单令牌 + * + * 提供管理功能,在特殊情况下可以清空整个黑名单 + * 注意:此操作会使所有已登出用户的令牌重新生效 + * + * 使用场景: + * - 系统维护时需要重置黑名单状态 + * - 测试环境中需要快速清理数据 + * - 紧急情况下需要恢复所有用户访问 + */ + public void clearBlacklist() { + int size = blacklistedTokens.size(); + blacklistedTokens.clear(); + log.warn("黑名单已被清空,共清理了 {} 个令牌", size); + } +} \ No newline at end of file diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index a198ef3..759d5de 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -18,12 +18,33 @@ org.springframework.boot spring-boot-starter - org.springframework.boot spring-boot-starter-test test + + org.projectlombok + lombok + provided + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + diff --git a/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java new file mode 100644 index 0000000..0229663 --- /dev/null +++ b/user-service/user-service-common/src/main/java/com/example/user/service/common/JwtUtil.java @@ -0,0 +1,345 @@ +package com.example.user.service.common; + +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import java.util.Date; + +/** + * JWT工具类 - JSON Web Token 核心处理工具 + * + * 【什么是JWT?】 + * JWT (JSON Web Token) 是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。 + * 它是一种无状态的认证方式,服务器不需要保存用户的登录状态。 + * + * 【JWT的结构】 + * JWT由三部分组成,用点(.)分隔: + * 1. Header(头部):包含token类型和签名算法,如 {"typ":"JWT","alg":"HS512"} + * 2. Payload(载荷):包含声明信息,如用户名、过期时间等,如 {"sub":"user123","exp":1234567890} + * 3. Signature(签名):用于验证token的完整性,防止篡改 + * 格式:Header.Payload.Signature + * 例如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c + * + * 【为什么使用JWT?】 + * 1. 无状态:服务器不需要存储session,适合分布式系统 + * 2. 跨域:可以在不同域名间传递认证信息 + * 3. 移动友好:适合移动应用的认证方式 + * 4. 性能好:避免了频繁的数据库查询 + * + * 【安全考虑】 + * 1. 密钥安全:签名密钥必须保密,泄露会导致token可被伪造 + * 2. HTTPS传输:token应通过HTTPS传输,防止被截获 + * 3. 过期时间:设置合理的过期时间,平衡安全性和用户体验 + * 4. 敏感信息:不要在payload中存储敏感信息,因为它只是Base64编码,不是加密 + * + * 【注解说明】 + * @Slf4j:Lombok注解,自动生成日志对象log,用于记录调试和错误信息 + * @Component:Spring注解,将该类注册为Spring容器管理的Bean,可以被其他类注入使用 + */ +@Slf4j +@Component +public class JwtUtil { + + /** + * JWT签名密钥 - 用于保证token安全性的核心要素 + * + * 【作用说明】 + * 这个密钥用于对JWT进行签名和验证,确保token的完整性和真实性。 + * 任何人如果没有这个密钥,就无法伪造有效的JWT token。 + * + * 【配置方式】 + * @Value注解从application.properties或application.yml中读取jwt.secret配置 + * 如果配置文件中没有设置,则使用冒号后面的默认值 + * + * 【安全要求】 + * 1. 密钥长度:至少256位(32字节)才能满足HS256算法要求 + * 2. 密钥复杂度:应包含大小写字母、数字,避免使用简单密码 + * 3. 密钥保密:绝对不能泄露给客户端或第三方 + * 4. 生产环境:必须使用环境变量或加密配置文件存储 + * + * 【为什么这样设计?】 + * 使用@Value注解可以灵活配置密钥,不同环境(开发、测试、生产)可以使用不同的密钥 + */ + @Value("${jwt.secret:mySecretKeyForJwtTokenGenerationAndValidation123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789}") + private String secret; + + /** + * JWT token过期时间(毫秒) - 控制token有效期的关键参数 + * + * 【时间设置说明】 + * 默认值86400000毫秒 = 24小时 = 1天 + * 计算方式:24小时 × 60分钟 × 60秒 × 1000毫秒 = 86400000毫秒 + * + * 【为什么需要过期时间?】 + * 1. 安全考虑:限制token的有效期,即使被盗用也会自动失效 + * 2. 减少风险:缩短攻击者可利用stolen token的时间窗口 + * 3. 强制重新认证:定期要求用户重新登录,提高安全性 + * + * 【时间设置策略】 + * - 高安全应用:1-2小时 + * - 一般应用:24小时 + * - 低风险应用:7天 + * - 移动应用:可以设置更长时间,配合refresh token使用 + * + * 【配置灵活性】 + * 通过@Value注解,可以在不同环境中设置不同的过期时间 + */ + @Value("${jwt.expiration:86400000}") + private Long expiration; + + /** + * 生成JWT token - 用户登录成功后创建身份凭证 + * + * 【方法作用】 + * 当用户登录成功后,调用此方法生成一个JWT token作为用户的身份凭证。 + * 用户后续的请求都需要携带这个token来证明自己的身份。 + * + * 【生成流程】 + * 1. 获取当前时间作为token的签发时间 + * 2. 计算token的过期时间(当前时间 + 配置的有效期) + * 3. 使用JJWT库的Builder模式构建token + * 4. 设置token的各个声明(Claims) + * 5. 使用密钥和算法对token进行签名 + * 6. 生成最终的token字符串 + * + * 【参数说明】 + * @param username 用户名,将作为token的主体(subject),用于标识token属于哪个用户 + * + * 【返回值说明】 + * @return String 生成的JWT token,格式为:Header.Payload.Signature + * + * 【使用场景】 + * - 用户登录成功后 + * - 需要为用户创建新的身份凭证时 + * - token刷新时(如果实现了refresh token机制) + */ + public String generateToken(String username) { + // 获取当前时间 - 作为token的签发时间(iat - issued at) + Date now = new Date(); + // 计算过期时间 - 当前时间加上配置的有效期 + // 这样设计可以灵活控制token的生命周期 + Date expiryDate = new Date(now.getTime() + expiration); + + // 使用JJWT库的Builder模式构建JWT Token + // Builder模式的优点:代码清晰、易于理解、支持链式调用 + return Jwts.builder() + .setSubject(username) // 设置主体(sub):标识token的所有者 + .setIssuedAt(now) // 设置签发时间(iat):token的创建时间 + .setExpiration(expiryDate) // 设置过期时间(exp):token的失效时间 + .signWith(getSigningKey(), SignatureAlgorithm.HS512) // 使用HS512算法和密钥进行签名 + .compact(); // 生成紧凑的URL安全字符串格式 + } + + /** + * 从token中获取用户名 - 解析JWT获取用户身份信息 + * + * 【方法作用】 + * 当收到客户端发送的JWT token时,需要从中提取用户名来识别用户身份。 + * 这是JWT认证流程中的关键步骤。 + * + * 【解析过程】 + * 1. 调用getClaimsFromToken()方法解析token + * 2. 从Claims中获取subject字段(用户名) + * 3. 返回用户名供后续业务逻辑使用 + * + * 【为什么这样设计?】 + * JWT的payload部分包含了用户信息,通过解析可以直接获取, + * 无需查询数据库,提高了性能。 + * + * @param token JWT token字符串 + * @return String 用户名,如果token格式错误或解析失败则可能抛出异常 + * + * 【注意事项】 + * - 此方法不验证token是否过期,只负责提取用户名 + * - 如果token被篡改,解析时会抛出签名验证异常 + */ + public String getUsernameFromToken(String token) { + // 解析token获取载荷(Claims) - Claims包含了token中的所有声明信息 + Claims claims = getClaimsFromToken(token); + // 从载荷中获取主体(subject),即用户名 + // subject是JWT标准中用于标识token所有者的字段 + return claims.getSubject(); + } + + /** + * 验证token是否有效 - JWT认证的核心验证逻辑 + * + * 【验证目的】 + * 确保接收到的JWT token是合法、有效且未被篡改的。 + * 这是保护API安全的重要防线。 + * + * 【验证步骤】 + * 1. 从token中提取用户名 + * 2. 比较token中的用户名与期望的用户名是否一致 + * 3. 检查token是否已过期 + * 4. 隐式验证:getClaimsFromToken()会验证签名 + * + * 【为什么需要双重验证?】 + * - 用户名匹配:确保token属于正确的用户 + * - 过期检查:确保token仍在有效期内 + * - 签名验证:确保token未被篡改(在解析过程中自动完成) + * + * @param token JWT token字符串 + * @param username 期望的用户名,通常来自请求上下文 + * @return boolean true表示token有效,false表示无效 + * + * 【异常处理】 + * 使用try-catch捕获所有可能的异常(签名错误、格式错误等), + * 确保方法不会因异常而中断,统一返回false表示验证失败。 + */ + public boolean validateToken(String token, String username) { + try { + // 从token中获取用户名 - 这一步会验证token的签名 + String tokenUsername = getUsernameFromToken(token); + // 验证用户名是否匹配且token未过期 + // 两个条件都必须满足才认为token有效 + return (username.equals(tokenUsername) && !isTokenExpired(token)); + } catch (Exception e) { + // 捕获解析token时的异常(如签名错误、格式错误等) + // 记录错误日志便于调试,但不暴露具体错误信息给客户端 + log.error("Token validation failed: {}", e.getMessage()); + return false; // 任何异常都视为验证失败 + } + } + + /** + * 检查token是否过期 + * + * @param token JWT token + * @return boolean token是否过期 + */ + public boolean isTokenExpired(String token) { + // 获取token的过期时间 + Date expiration = getExpirationDateFromToken(token); + // 比较过期时间是否在当前时间之前 + return expiration.before(new Date()); + } + + /** + * 从token中获取过期时间 + * + * @param token JWT token + * @return Date 过期时间 + */ + public Date getExpirationDateFromToken(String token) { + // 解析token获取载荷(Claims) + Claims claims = getClaimsFromToken(token); + // 从载荷中获取过期时间 + return claims.getExpiration(); + } + + /** + * 从token中解析Claims - JWT解析的核心方法 + * + * 【Claims概念】 + * Claims是JWT的载荷(Payload)部分,包含了关于用户和token的声明信息。 + * 标准声明包括:sub(主体)、exp(过期时间)、iat(签发时间)等。 + * + * 【解析流程】 + * 1. 创建JWT解析器(Parser) + * 2. 设置签名密钥用于验证token完整性 + * 3. 解析token字符串,验证签名 + * 4. 提取并返回Claims对象 + * + * 【安全机制】 + * 解析过程中会自动验证token的签名,如果token被篡改, + * 签名验证会失败并抛出异常,确保了token的安全性。 + * + * 【为什么设计为private?】 + * 这是一个内部工具方法,只供本类的其他方法使用, + * 不需要暴露给外部调用者,符合封装原则。 + * + * @param token JWT token字符串 + * @return Claims 载荷对象,包含token中的所有声明信息 + * @throws JwtException 如果token格式错误、签名无效或已过期 + */ + private Claims getClaimsFromToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) // 设置签名密钥用于验证token完整性 + .build() // 构建解析器 + .parseClaimsJws(token) // 解析JWT token并验证签名 + .getBody(); // 获取载荷部分(Claims) + } + + /** + * 获取签名密钥 - 将配置的字符串密钥转换为加密算法所需的密钥对象 + * + * 【转换目的】 + * JJWT库需要SecretKey对象来进行HMAC签名算法, + * 而我们配置的是字符串,需要转换为合适的密钥格式。 + * + * 【HMAC算法说明】 + * HMAC (Hash-based Message Authentication Code) 是一种基于哈希的消息认证码算法。 + * 它结合了哈希函数和密钥,既能验证数据完整性,又能验证数据来源。 + * + * 【转换过程】 + * 1. 将字符串密钥转换为字节数组 + * 2. 使用Keys.hmacShaKeyFor()方法生成适合HMAC-SHA算法的密钥 + * 3. 返回SecretKey对象供签名和验证使用 + * + * 【安全考虑】 + * - 密钥长度必须足够(至少256位) + * - 密钥应该是随机生成的,不能是简单的字符串 + * - 密钥必须保密,不能泄露给客户端 + * + * @return SecretKey 适用于HMAC-SHA算法的签名密钥 + */ + private SecretKey getSigningKey() { + // 将字符串密钥转换为字节数组 + // 使用UTF-8编码确保字符串到字节的转换一致性 + byte[] keyBytes = secret.getBytes(); + // 使用JJWT提供的工具方法生成HMAC-SHA密钥 + // 该方法会自动选择合适的HMAC算法(HS256、HS384、HS512) + return Keys.hmacShaKeyFor(keyBytes); + } + + /** + * 从请求头中提取token - 解析HTTP Authorization头获取JWT token + * + * 【HTTP Authorization头格式】 + * 根据RFC 6750 (OAuth 2.0 Bearer Token Usage)标准, + * JWT token应该放在HTTP请求头的Authorization字段中, + * 格式为: "Authorization: Bearer " + * + * 【为什么使用Bearer?】 + * Bearer是OAuth 2.0标准中定义的token类型,表示"持有者token", + * 意思是任何持有该token的人都可以使用它,无需额外的身份验证。 + * + * 【提取逻辑】 + * 1. 检查Authorization头是否存在 + * 2. 验证是否以"Bearer "开头(注意Bearer后有一个空格) + * 3. 提取"Bearer "后面的token部分 + * 4. 如果格式不正确,返回null + * + * 【使用场景】 + * 主要在JWT认证过滤器中使用,用于从HTTP请求中提取token, + * 然后进行后续的验证和用户身份识别。 + * + * 【安全考虑】 + * - 只接受标准的Bearer格式,拒绝其他格式 + * - 返回null而不是抛出异常,便于调用者处理 + * - 不对token内容进行验证,只负责提取 + * + * @param authHeader HTTP请求中的Authorization头的值 + * @return String JWT token字符串,如果格式不正确则返回null + * + * 【示例】 + * 输入: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + * 输出: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + */ + public String extractTokenFromHeader(String authHeader) { + // 检查Authorization头是否存在且以"Bearer "开头 + // 注意:"Bearer "后面有一个空格,这是标准格式要求 + if (authHeader != null && authHeader.startsWith("Bearer ")) { + // 提取Bearer后面的token部分 + // substring(7)是因为"Bearer "有7个字符(包括空格) + return authHeader.substring(7); + } + // 如果格式不正确,返回null,让调用者知道没有有效的token + return null; + } +} \ No newline at end of file diff --git a/user-service/user-service-domain/pom.xml b/user-service/user-service-domain/pom.xml index 502cbe0..79ea885 100644 --- a/user-service/user-service-domain/pom.xml +++ b/user-service/user-service-domain/pom.xml @@ -40,6 +40,12 @@ org.springframework.security spring-security-crypto + + org.jetbrains + annotations + 13.0 + compile + diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index 88945ed..c59d808 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -8,6 +8,7 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -17,37 +18,44 @@ import java.util.List; @ToString public class User { private UserId id; - private UserName name; - private UserAge age; + private UserName username; private Email email; private Password password; + private Phone phone; + private RealName realName; + private UserStatus status; + private UserRole role; public User() { } - public User(UserId id, UserName name, UserAge age, Email email, Password password) { + // 私有构造方法 + private User(UserId id, UserName username, Password password, Email email, + Phone phone, RealName realName, UserStatus status, UserRole role) { this.id = id; - this.name = name; - this.age = age; - this.email = email; + this.username = username; this.password = password; - } - - public User( UserName name, UserAge age, Email email, Password password) { - this.id= genId() ; - this.name = name; - this.age = age; this.email = email; - this.password = password; - } - - public User(UserId userId, UserName userName, UserAge userAge, Email email) { - this.id = id; - this.name = name; - this.age = age; - this.email = email; - } + this.phone = phone; + this.realName = realName; + this.status = status; + this.role = role;} + // 一次性更新多个字段的方法 + public User updatePersonalInfo(@Nullable Phone phone, + @Nullable RealName realName, + @Nullable Email email) { + return new User( + this.id, + this.username, + this.password, + email != null ? email : this.email, + phone != null ? phone : this.phone, + realName != null ? realName : this.realName, + this.status, + this.role + ); + } public static List getUsers(GetUserListPort getUserListPort){ return getUserListPort.getUsers(); diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java index f83b243..fb1ef8d 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java @@ -1,7 +1,19 @@ package com.example.user.service.domain.valueobject; -public record Email(String email) { - public String getValue() { - return email; +public record Email(String value) { + public static Email of(String email) { + if (email == null || email.isBlank()) { + throw new RuntimeException("邮箱不能为空"); + } + + if (!email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) { + throw new RuntimeException("邮箱格式不正确"); + } + + return new Email(email); + } + + public boolean isValid() { + return value != null && value.matches("^[A-Za-z0-9+_.-]+@(.+)$"); } } diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java new file mode 100644 index 0000000..ef5e59e --- /dev/null +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java @@ -0,0 +1,23 @@ +package com.example.user.service.domain.valueobject; + +/** + * @Author: zhangyucheng + * @Date: 2025/9/16 14:15 + */ +public record Phone(String value) { + public static Phone of(String phone) { + if (phone == null || phone.isBlank()) { + throw new RuntimeException("手机号不能为空"); + } + + if (!phone.matches("^1[3-9]\\d{9}$")) { + throw new RuntimeException("手机号格式不正确"); + } + + return new Phone(phone); + } + + public boolean isValid() { + return value != null && value.matches("^1[3-9]\\d{9}$"); + } +} \ No newline at end of file diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java new file mode 100644 index 0000000..1e1939a --- /dev/null +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java @@ -0,0 +1,23 @@ +package com.example.user.service.domain.valueobject; + +/** + * @Author: zhangyucheng + * @Date: 2025/9/16 14:15 + */ +public record RealName(String value) { + public static RealName of(String name) { + if (name == null || name.isBlank()) { + throw new RuntimeException("真实姓名不能为空"); + } + + if (name.length() < 2 || name.length() > 20) { + throw new RuntimeException("真实姓名长度必须在2-20个字符之间"); + } + + return new RealName(name.trim()); + } + + public boolean isValid() { + return value != null && value.length() >= 2 && value.length() <= 20; + } +} \ No newline at end of file diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java deleted file mode 100644 index 38ef937..0000000 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserAge.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.user.service.domain.valueobject; - -public record UserAge(int age) { - public int getValue() { - return age; - } -} diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java index 0c11a15..4ba8bbe 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java @@ -1,7 +1,26 @@ package com.example.user.service.domain.valueobject; -public record UserName(String username) { - public String getValue() { - return username; +public record UserName(String value) { + public static UserName of(String username) { + if (username == null || username.isBlank()) { + throw new RuntimeException("用户名不能为空"); + } + + if (username.length() < 3 || username.length() > 20) { + throw new RuntimeException("用户名长度必须在3-20个字符之间"); + } + + if (!username.matches("^[a-zA-Z0-9_]+$")) { + throw new RuntimeException("用户名只能包含字母、数字和下划线"); + } + + return new UserName(username); + } + + public boolean isValid() { + return value != null && + value.length() >= 3 && + value.length() <= 20 && + value.matches("^[a-zA-Z0-9_]+$"); } -} +} \ No newline at end of file diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java new file mode 100644 index 0000000..44a9755 --- /dev/null +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java @@ -0,0 +1,36 @@ +package com.example.user.service.domain.valueobject; + +import java.time.LocalDateTime; + +/** + * @Author: zhangyucheng + * @Date: 2025/9/16 14:15 + */ +public record UserRole(String value) { + public static final String ADMIN = "ADMIN"; + public static final String USER = "USER"; + + public static UserRole of(String role) { + if (role == null || role.isBlank()) { + throw new RuntimeException("用户角色不能为空"); + } + + if (!role.equals(ADMIN) && !role.equals(USER)) { + throw new RuntimeException("用户角色必须是ADMIN或USER"); + } + + return new UserRole(role); + } + + public boolean isAdmin() { + return ADMIN.equals(value); + } + + public boolean isUser() { + return USER.equals(value); + } + + public boolean isValid() { + return value != null && (value.equals(ADMIN) || value.equals(USER)); + } +} \ No newline at end of file diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java new file mode 100644 index 0000000..7c965e0 --- /dev/null +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java @@ -0,0 +1,34 @@ +package com.example.user.service.domain.valueobject; + +/** + * @Author: zhangyucheng + * @Date: 2025/9/16 14:15 + */ +public record UserStatus(Integer value) { + public static final Integer DISABLED = 0; + public static final Integer ENABLED = 1; + + public static UserStatus of(Integer status) { + if (status == null) { + throw new RuntimeException("用户状态不能为空"); + } + + if (!status.equals(DISABLED) && !status.equals(ENABLED)) { + throw new RuntimeException("用户状态必须是0(禁用)或1(启用)"); + } + + return new UserStatus(status); + } + + public boolean isEnabled() { + return ENABLED.equals(value); + } + + public boolean isDisabled() { + return DISABLED.equals(value); + } + + public boolean isValid() { + return value != null && (value.equals(DISABLED) || value.equals(ENABLED)); + } +} \ No newline at end of file -- Gitee From cfade86981225a851b1296ad4d0a79b9754f5e7a Mon Sep 17 00:00:00 2001 From: zqy <2287881924@qq.com> Date: Tue, 16 Sep 2025 15:45:02 +0800 Subject: [PATCH 21/23] =?UTF-8?q?=E4=BF=AE=E6=94=B9controller=E7=9A=84upda?= =?UTF-8?q?te=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/user/adapter/in/web/controller/UserController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index 150db7c..452d6e8 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -84,8 +84,9 @@ public class UserController { UpdateUserCommand command=UpdateUserCommand.builder() .id(updateUserRequestDTO.id()) .name(updateUserRequestDTO.name()) - .age(updateUserRequestDTO.age()) .email(updateUserRequestDTO.email()) + .phone(updateUserRequestDTO.phone()) + .real_name(updateUserRequestDTO.real_name()) .build(); User user = updateUserUseCase.updateUser(command); return user; -- Gitee From da1c2c7efd16ebcb9ecdf5cba190075b698048fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Tue, 16 Sep 2025 20:26:33 +0800 Subject: [PATCH 22/23] =?UTF-8?q?doc=20=E6=96=B0user=E8=A1=A8=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=AE=8C=E6=88=90=EF=BC=8Cdomin=E5=B7=B2=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=8C=E4=B8=94=E5=B7=B2=E7=BB=8F=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=EF=BC=8C=E7=99=BB=E5=BD=95=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E8=BF=94=E5=9B=9Etoken=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E4=BF=A1=E6=81=AF=E7=AD=89=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user-adapter-in-web/pom.xml | 6 + .../in/web/config/BasicSecurityConfig.java | 54 ++++---- .../in/web/controller/UserController.java | 29 ++-- .../in/web/dto/CreateUserRequestDTO.java | 10 +- .../in/web/dto/UpdateUserRequestDTO.java | 5 +- .../persistence/convertor/UserConvertor.java | 19 ++- .../out/persistence/entity/UserEntity.java | 27 +++- .../command/CreateUserCommand.java | 8 +- .../command/UpdateUserCommand.java | 5 +- .../service/CreateUserService.java | 21 ++- .../service/UpdateUserService.java | 22 +-- .../application/service/UserLoginService.java | 11 +- .../src/main/resources/application.properties | 3 + user-service/user-service-common/pom.xml | 2 +- .../com/example/user/service/domain/User.java | 130 +++++++++++++----- .../service/domain/valueobject/Email.java | 5 + .../service/domain/valueobject/Phone.java | 5 + .../service/domain/valueobject/RealName.java | 5 + .../service/domain/valueobject/UserName.java | 4 + .../service/domain/valueobject/UserRole.java | 66 +++++++-- .../domain/valueobject/UserStatus.java | 77 +++++++++-- 21 files changed, 355 insertions(+), 159 deletions(-) diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml index 6ce88a3..1cc92b4 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/pom.xml @@ -50,6 +50,12 @@ knife4j-openapi3-jakarta-spring-boot-starter ${knife4j.version} + + com.example + user-adapter-out-persistence + 0.0.1-SNAPSHOT + compile + diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java index 7282f3c..74d7385 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/config/BasicSecurityConfig.java @@ -1,7 +1,7 @@ package com.example.user.adapter.in.web.config; -import com.example.ss.demo.filter.JwtAuthenticationFilter; -import com.example.ss.demo.service.CustomUserDetailsService; + +import com.example.user.adapter.in.web.filter.JwtAuthenticationFilter; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -24,7 +24,7 @@ import java.util.List; /** * Spring Security 配置类 * 支持JWT认证和跨域配置 - * + * * 这个类负责配置整个应用程序的安全策略,包括: * 1. 用户认证和授权规则 * 2. JWT Token验证 @@ -42,19 +42,18 @@ public class BasicSecurityConfig { * 用于拦截请求并验证JWT Token的有效性 */ private final JwtAuthenticationFilter jwtAuthenticationFilter; - + /** * 自定义用户详情服务 * 用于加载用户信息进行认证 */ - private final CustomUserDetailsService userDetailsService; /** * 认证管理器 * 负责处理用户认证请求 - * + * * @param config 认证配置对象,由Spring自动注入 * @return AuthenticationManager 认证管理器实例 * @throws Exception 如果配置过程中出现异常 @@ -67,32 +66,32 @@ public class BasicSecurityConfig { /** * CORS配置源 * 配置跨域资源共享策略,允许前端应用访问后端API - * + * * @return CorsConfigurationSource CORS配置源 */ @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); - + // 允许的源(Origin),这里设置为允许所有域名访问 // 在生产环境中应该设置为具体的域名以提高安全性 configuration.setAllowedOriginPatterns(List.of("*")); - + // 允许的HTTP方法,包括常用的GET、POST、PUT、DELETE等 configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); - + // 允许的请求头,这里设置为允许所有请求头 configuration.setAllowedHeaders(List.of("*")); - + // 允许携带凭证(如Cookie),设置为true表示允许跨域请求携带身份信息 configuration.setAllowCredentials(true); - + // 预检请求的缓存时间,单位秒,这里设置为1小时 configuration.setMaxAge(3600L); - + // 暴露给客户端的响应头,允许客户端访问这些响应头 configuration.setExposedHeaders(Arrays.asList("Authorization", "Content-Type")); - + // 创建基于URL的CORS配置源 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有路径应用相同的CORS配置 @@ -103,7 +102,7 @@ public class BasicSecurityConfig { /** * 安全过滤器链配置 * 定义HTTP请求的安全处理规则 - * + * * @param http HttpSecurity对象,用于配置Web安全 * @return SecurityFilterChain 安全过滤器链 * @throws Exception 如果配置过程中出现异常 @@ -114,21 +113,21 @@ public class BasicSecurityConfig { // 禁用CSRF(跨站请求伪造)保护 // 前后端分离项目通常禁用,因为使用Token认证而不是Session .csrf(AbstractHttpConfigurer::disable) - + // 启用CORS(跨域资源共享)并使用上面定义的配置 .cors(cors -> cors.configurationSource(corsConfigurationSource())) - + // 配置会话管理为无状态 // 因为使用JWT Token认证,不需要服务器保存会话状态 .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) - + // 配置请求授权规则 .authorizeHttpRequests(authz -> authz // 公开接口,无需认证即可访问 - .requestMatchers("/api/auth/login", "/api/auth/register").permitAll() - .requestMatchers("/api/auth/debug/**").permitAll() + .requestMatchers("/user/login", "/user/register").permitAll() + .requestMatchers("/user/debug/**").permitAll() // Swagger和knife4j文档接口放行,方便查看API文档 .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll() .requestMatchers("/doc.html", "/webjars/**", "/favicon.ico").permitAll() @@ -137,27 +136,24 @@ public class BasicSecurityConfig { // 其他所有请求都需要认证 .anyRequest().authenticated() ) - + // 禁用默认的登录页面 // 因为使用自定义的登录接口,不需要Spring Security提供的默认登录页面 .formLogin(AbstractHttpConfigurer::disable) - + // 禁用默认的登出页面 // 因为使用自定义的登出接口,不需要Spring Security提供的默认登出功能 .logout(AbstractHttpConfigurer::disable) - + // 禁用HTTP Basic认证 // 因为使用JWT Token认证,不需要HTTP Basic认证方式 .httpBasic(AbstractHttpConfigurer::disable) - + // 添加JWT认证过滤器 // 在用户名密码认证过滤器之前添加JWT认证过滤器 .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - - // 配置用户详情服务 - // 用于加载用户信息进行认证 - .userDetailsService(userDetailsService) - + + // 配置异常处理 .exceptionHandling(exceptions -> exceptions // 认证入口点,当未认证用户访问需要认证的资源时调用 diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java index 544dd4c..12f5668 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/controller/UserController.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @Slf4j -@RequestMapping("/users") +@RequestMapping("/user") @RestController @RequiredArgsConstructor public class UserController { @@ -48,14 +48,16 @@ public class UserController { return getUserListUseCase.getUsers(); } - @PostMapping() + @PostMapping("register") public User createUser(@RequestBody CreateUserRequestDTO createUserRequestDTO){ CreateUserCommand command=CreateUserCommand.builder() - .name(createUserRequestDTO.name()) - .age(createUserRequestDTO.age()) + .username(createUserRequestDTO.name()) .email(createUserRequestDTO.email()) + .phone(createUserRequestDTO.phone()) + .realname(createUserRequestDTO.realname()) .password(createUserRequestDTO.password()) + .repassword(createUserRequestDTO.repassword()) .build(); return createUserUseCase.createUser(command); @@ -78,27 +80,12 @@ public class UserController { UpdateUserCommand command=UpdateUserCommand.builder() .id(updateUserRequestDTO.id()) .name(updateUserRequestDTO.name()) - .age(updateUserRequestDTO.age()) .email(updateUserRequestDTO.email()) + .phone(updateUserRequestDTO.phone()) + .real_name(updateUserRequestDTO.real_name()) .build(); User user = updateUserUseCase.updateUser(command); return user; } - - /** - * @author dengli - * @param id - * @return - */ - @GetMapping("{id}") - public UserResponseDTO getUserById(@PathVariable("id") Long id){ - User user = getUserByIdUseCase.getUserById(id); - UserResponseDTO userResponseDTO = new UserResponseDTO( - user.getId().id(), - user.getName().username(), - user.getAge().age(), - user.getEmail().email()); - return userResponseDTO; - } } diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java index b494b7b..6400177 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/CreateUserRequestDTO.java @@ -1,7 +1,11 @@ package com.example.user.adapter.in.web.dto; public record CreateUserRequestDTO( - String name, - Integer age, - String email) { + String name, + String email, + String phone, + String realname, + String password, + String repassword +) { } diff --git a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java index d42ae55..6baa149 100644 --- a/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java +++ b/user-service/user-service-adapter/user-adapter-in/user-adapter-in-web/src/main/java/com/example/user/adapter/in/web/dto/UpdateUserRequestDTO.java @@ -2,6 +2,7 @@ package com.example.user.adapter.in.web.dto; public record UpdateUserRequestDTO(Long id, String name, - Integer age, - String email) { + String email, + String phone, + String real_name) { } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java index 6f79540..808eb01 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/convertor/UserConvertor.java @@ -10,19 +10,28 @@ public class UserConvertor { return new User( new UserId(userEntity.getId()), new UserName(userEntity.getName()), - new UserAge(userEntity.getAge()), + new Password(userEntity.getPassword()), new Email(userEntity.getEmail()), - new Password(userEntity.getPassword()) + new Phone(userEntity.getPhone()), + new RealName(userEntity.getRealName()), + new UserStatus(userEntity.getStatus()), + new UserRole(userEntity.getRole()) ); } public static UserEntity toEntity(User user) { return new UserEntity( user.getId().getValue(), - user.getName().getValue(), - user.getAge().getValue(), + user.getUsername().getValue(), + user.getPassword().encryptedValue(), user.getEmail().getValue(), - user.getPassword().encryptedValue() + user.getPhone().getValue(), + user.getRealName().getValue(), + user.getStatus().getValue(), + user.getRole().getValue(), + user.getCreateTime(), + user.getUpdateTime(), + user.getLastLoginTime() ); } } diff --git a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java index b64228d..d04f201 100644 --- a/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java +++ b/user-service/user-service-adapter/user-adapter-out/user-adapter-out-persistence/src/main/java/com/example/user/adapter/out/persistence/entity/UserEntity.java @@ -7,6 +7,10 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; + @Data @AllArgsConstructor @NoArgsConstructor @@ -15,10 +19,27 @@ public class UserEntity { @TableId(type= IdType.ASSIGN_ID) private long id; private String name; - private Integer age; - private String email; private String password; + private String email; + private String phone; + private String realName; + private int status; + private String role; + private LocalDateTime createTime; + private LocalDateTime updateTime; + private LocalDateTime lastLoginTime; - public UserEntity(long value, String value1, int value2, String value3) { +// public UserEntity(long value, String value1, int value2, String value3) { +// } + public UserEntity(long id, String name, String password, String email, + String phone, String realName, int status, String role) { + this.id = id; + this.name = name; + this.password = password; + this.email = email; + this.phone = phone; + this.realName = realName; + this.status = status; + this.role = role; } } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java index d7f3519..8aca7f9 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/CreateUserCommand.java @@ -5,9 +5,11 @@ import lombok.Builder; @Builder public record CreateUserCommand( Long id, - String name, - Integer age, + String username, String email, - String password + String phone, + String realname, + String password, + String repassword ) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java index 0ef0ed9..8b1aa40 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/command/UpdateUserCommand.java @@ -5,6 +5,7 @@ import lombok.Builder; @Builder public record UpdateUserCommand(Long id, String name, - Integer age, - String email) { + String email, + String phone, + String real_name) { } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java index 931828a..913d1c8 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/CreateUserService.java @@ -4,10 +4,7 @@ import com.example.user.service.application.command.CreateUserCommand; import com.example.user.service.application.port.in.CreateUserUseCase; import com.example.user.service.domain.User; import com.example.user.service.domain.port.CreateUserPort; -import com.example.user.service.domain.valueobject.Email; -import com.example.user.service.domain.valueobject.Password; -import com.example.user.service.domain.valueobject.UserAge; -import com.example.user.service.domain.valueobject.UserName; +import com.example.user.service.domain.valueobject.*; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -17,17 +14,19 @@ import org.springframework.stereotype.Service; public class CreateUserService implements CreateUserUseCase { @Resource private CreateUserPort createUserPort; + @Override public User createUser(CreateUserCommand createUserCommand) { - //command -> domain - User user=new User( - new UserName(createUserCommand.name()), - new UserAge(createUserCommand.age()), + // 创建用户领域对象 + User user = User.createUser( + new UserName(createUserCommand.username()), + Password.fromRaw(createUserCommand.password()), new Email(createUserCommand.email()), -// new Password( createUserCommand.password()) - Password.fromRaw(createUserCommand.password()) + new Phone(createUserCommand.phone()), + new RealName(createUserCommand.realname()), + UserRole.user() // 默认用户角色 ); - log.info("user:{}",user); + log.info("Creating user: {}", user); return createUserPort.createUser(user); } } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java index 97da325..3ece0ce 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UpdateUserService.java @@ -3,11 +3,10 @@ package com.example.user.service.application.service; import com.example.user.service.application.command.UpdateUserCommand; import com.example.user.service.application.port.in.UpdateUserUseCase; import com.example.user.service.domain.User; +import com.example.user.service.domain.port.GetUserByIdPort; import com.example.user.service.domain.port.UpdateUserPort; -import com.example.user.service.domain.valueobject.Email; -import com.example.user.service.domain.valueobject.UserAge; -import com.example.user.service.domain.valueobject.UserId; -import com.example.user.service.domain.valueobject.UserName; +import com.example.user.service.domain.valueobject.*; + import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -15,14 +14,19 @@ import org.springframework.stereotype.Service; public class UpdateUserService implements UpdateUserUseCase { @Resource private UpdateUserPort updateUserPort; + @Resource + private GetUserByIdPort getUserByIdPort; @Override public User updateUser(UpdateUserCommand command) { - User user = new User( - new UserId(command.id()), - new UserName(command.name()), - new UserAge(command.age()), - new Email(command.email())); + User user = getUserByIdPort.getUserById(command.id()); + + user.updateProfile( + new Email(command.email()), + new Phone(command.phone()), + new RealName(command.real_name()) + ); + return updateUserPort.updateUser(user); } } diff --git a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java index 4240269..f0c7ec4 100644 --- a/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java +++ b/user-service/user-service-application/src/main/java/com/example/user/service/application/service/UserLoginService.java @@ -2,10 +2,12 @@ package com.example.user.service.application.service; import com.example.user.service.application.command.UserLoginCommand; import com.example.user.service.application.port.in.UserLoginUseCase; +import com.example.user.service.common.JwtUtil; import com.example.user.service.domain.User; import com.example.user.service.domain.port.GetUserByNamePort; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Slf4j @@ -14,6 +16,8 @@ public class UserLoginService implements UserLoginUseCase { @Resource private GetUserByNamePort getUserByNamePort; + @Autowired + private JwtUtil jwtUtil; @Override public String login(UserLoginCommand userLoginCommand) { @@ -27,11 +31,6 @@ public class UserLoginService implements UserLoginUseCase { if(!user.validatePassword(userLoginCommand.password())){ throw new RuntimeException("密码错误"); } - //签发token - /* - todo 封装一个JwtUtil实现jwt签发 - token 有效期 5min ,key=123456 ,载荷:{name:user.name,id:user.id,is_super} - */ - return "token"; + return jwtUtil.generateToken(userLoginCommand.name()); } } diff --git a/user-service/user-service-bootstrap/src/main/resources/application.properties b/user-service/user-service-bootstrap/src/main/resources/application.properties index e21f2d5..6ed57fa 100644 --- a/user-service/user-service-bootstrap/src/main/resources/application.properties +++ b/user-service/user-service-bootstrap/src/main/resources/application.properties @@ -22,3 +22,6 @@ spring.cloud.nacos.config.server-addr=192.168.168.128:8848 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:${spring.application.name}.properties?refresh=true +springdoc.api-docs.enabled=true +springdoc.swagger-ui.enabled=true +springdoc.swagger-ui.path=/swagger-ui.html \ No newline at end of file diff --git a/user-service/user-service-common/pom.xml b/user-service/user-service-common/pom.xml index 759d5de..4d8b80a 100644 --- a/user-service/user-service-common/pom.xml +++ b/user-service/user-service-common/pom.xml @@ -11,7 +11,7 @@ 21 UTF-8 UTF-8 - 3.0.2 + 3.2.4 diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index c59d808..959897e 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -8,8 +8,8 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.Nullable; +import java.time.LocalDateTime; import java.util.List; @Slf4j @@ -25,13 +25,17 @@ public class User { private RealName realName; private UserStatus status; private UserRole role; + private LocalDateTime createTime; + private LocalDateTime updateTime; + private LocalDateTime lastLoginTime; + // 私有默认构造方法,用于框架反射 public User() { } - // 私有构造方法 - private User(UserId id, UserName username, Password password, Email email, - Phone phone, RealName realName, UserStatus status, UserRole role) { + // 静态工厂方法 - 用于从持久化实体重建领域对象 + public User(UserId id, UserName username, Password password, Email email, + Phone phone, RealName realName, UserStatus status, UserRole role) { this.id = id; this.username = username; this.password = password; @@ -39,52 +43,108 @@ public class User { this.phone = phone; this.realName = realName; this.status = status; - this.role = role;} - - // 一次性更新多个字段的方法 - public User updatePersonalInfo(@Nullable Phone phone, - @Nullable RealName realName, - @Nullable Email email) { - return new User( - this.id, - this.username, - this.password, - email != null ? email : this.email, - phone != null ? phone : this.phone, - realName != null ? realName : this.realName, - this.status, - this.role - ); - } - - public static List getUsers(GetUserListPort getUserListPort){ + this.role = role; + } + + // 静态工厂方法 - 用于创建新用户(注册时使用) + public static User createUser(UserName userName, Password password, Email email, + Phone phone, RealName realName, UserRole role) { + User user = new User(); + user.id = user.genId(); + user.username = userName; + user.password = password; + user.email = email; + user.phone = phone; + user.realName = realName; + user.status = UserStatus.ENABLED; // 默认激活状态 + user.role = role != null ? role : UserRole.USER; // 默认用户角色 + user.createTime = LocalDateTime.now().withNano(0); + user.updateTime = LocalDateTime.now().withNano(0); + user.lastLoginTime = LocalDateTime.now().withNano(0); + return user; + } + + // 静态工厂方法 - 用于从数据库重建用户(查询时使用) + public static User reconstruct(UserId id, UserName username, Email email, Password password, + Phone phone, RealName realName, UserStatus status, UserRole role, + LocalDateTime createTime, LocalDateTime updateTime, LocalDateTime lastLoginTime) { + User user = new User(); + user.id = id; + user.username = username; + user.email = email; + user.password = password; + user.phone = phone; + user.realName = realName; + user.status = status; + user.role = role; + user.createTime = createTime; + user.updateTime = updateTime; + user.lastLoginTime = lastLoginTime; + return user; + } + + // 业务方法 - 更新用户信息 + public void updateProfile(Email email, Phone phone, RealName realName) { + this.email = email; + this.phone = phone; + this.realName = realName; + this.updateTime = LocalDateTime.now(); // 自动更新修改时间 + } + + // 业务方法 - 更新密码 + public void changePassword(Password newPassword) { + this.password = newPassword; + this.updateTime = LocalDateTime.now(); // 自动更新修改时间 + } + + // 业务方法 - 用户登录 + public void login() { + this.lastLoginTime = LocalDateTime.now(); + this.updateTime = LocalDateTime.now(); // 更新最后修改时间 + } + + // 业务方法 - 激活/禁用用户 + public void activate() { + this.status = UserStatus.ENABLED; + this.updateTime = LocalDateTime.now(); + } + + public void deactivate() { + this.status = UserStatus.ENABLED; + this.updateTime = LocalDateTime.now(); + } + + public static List getUsers(GetUserListPort getUserListPort) { return getUserListPort.getUsers(); } /** * 根据用户名查询用户 - * 当需要使用类似GetUserByNamePort这种对象的时候,需要在方法参数注入该对象 - * 因为通过构造方法或者字段注入都会失败,因为方法是静态方法,会早于对象创建,导致对象无法注入 - * @param name 用户名 - * @param getUserByNamePort 查询用户的端口 - * @return 用户模型 */ - public static User getUserByName(String name, GetUserByNamePort getUserByNamePort){ + public static User getUserByName(String name, GetUserByNamePort getUserByNamePort) { User user = getUserByNamePort.getUserByName(name); log.info("user:{}", user); return user; } - public UserId genId(){ + private UserId genId() { return new UserId(new IdWorker().nextId()); } /** * 验证密码 - * @param password 密码 明文还是密文? - * @return 验证结果 */ - public boolean validatePassword(String password){ - return this.password.verify( password); + public boolean validatePassword(String password) { + return this.password.verify(password); + } + + // 验证业务规则的方法 + public boolean isValid() { + return username != null && + password != null && + email != null && + status != null && + role != null && + createTime != null; } -} +} \ No newline at end of file diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java index fb1ef8d..8ca701a 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Email.java @@ -1,5 +1,8 @@ package com.example.user.service.domain.valueobject; +import lombok.extern.slf4j.Slf4j; + +@Slf4j public record Email(String value) { public static Email of(String email) { if (email == null || email.isBlank()) { @@ -13,6 +16,8 @@ public record Email(String value) { return new Email(email); } + public String getValue() {return value;} + public boolean isValid() { return value != null && value.matches("^[A-Za-z0-9+_.-]+@(.+)$"); } diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java index ef5e59e..4634d88 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/Phone.java @@ -1,9 +1,12 @@ package com.example.user.service.domain.valueobject; +import lombok.extern.slf4j.Slf4j; + /** * @Author: zhangyucheng * @Date: 2025/9/16 14:15 */ +@Slf4j public record Phone(String value) { public static Phone of(String phone) { if (phone == null || phone.isBlank()) { @@ -17,6 +20,8 @@ public record Phone(String value) { return new Phone(phone); } + public String getValue() {return value;} + public boolean isValid() { return value != null && value.matches("^1[3-9]\\d{9}$"); } diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java index 1e1939a..0b5884a 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/RealName.java @@ -1,9 +1,12 @@ package com.example.user.service.domain.valueobject; +import lombok.extern.slf4j.Slf4j; + /** * @Author: zhangyucheng * @Date: 2025/9/16 14:15 */ +@Slf4j public record RealName(String value) { public static RealName of(String name) { if (name == null || name.isBlank()) { @@ -17,6 +20,8 @@ public record RealName(String value) { return new RealName(name.trim()); } + public String getValue() {return value;} + public boolean isValid() { return value != null && value.length() >= 2 && value.length() <= 20; } diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java index 4ba8bbe..1841298 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserName.java @@ -1,5 +1,8 @@ package com.example.user.service.domain.valueobject; +import lombok.extern.slf4j.Slf4j; + +@Slf4j public record UserName(String value) { public static UserName of(String username) { if (username == null || username.isBlank()) { @@ -16,6 +19,7 @@ public record UserName(String value) { return new UserName(username); } + public String getValue() {return value;} public boolean isValid() { return value != null && diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java index 44a9755..620b6c7 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserRole.java @@ -1,36 +1,72 @@ package com.example.user.service.domain.valueobject; -import java.time.LocalDateTime; +import lombok.extern.slf4j.Slf4j; /** - * @Author: zhangyucheng - * @Date: 2025/9/16 14:15 + * 用户角色值对象 */ +@Slf4j public record UserRole(String value) { - public static final String ADMIN = "ADMIN"; - public static final String USER = "USER"; + public static final UserRole ADMIN = new UserRole("ADMIN"); + public static final UserRole USER = new UserRole("USER"); - public static UserRole of(String role) { - if (role == null || role.isBlank()) { - throw new RuntimeException("用户角色不能为空"); + public UserRole { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("用户角色不能为空"); + } + // 修改验证逻辑,直接使用字符串比较,不要引用静态字段 + if (!"ADMIN".equals(value) && !"USER".equals(value)) { + throw new IllegalArgumentException("用户角色必须是ADMIN或USER"); + } } - if (!role.equals(ADMIN) && !role.equals(USER)) { - throw new RuntimeException("用户角色必须是ADMIN或USER"); + private static boolean isValidRole(String role) { + // 同样修改这里 + return "ADMIN".equals(role) || "USER".equals(role); } - + // 静态工厂方法 + public static UserRole of(String role) { return new UserRole(role); } + public static UserRole admin() { + return ADMIN; + } + + public static UserRole user() { + return USER; + } + + public String getValue() { + return value; + } + public boolean isAdmin() { - return ADMIN.equals(value); + return ADMIN.value.equals(value); } public boolean isUser() { - return USER.equals(value); + return USER.value.equals(value); + } + + public boolean isValid(String role) { + return ADMIN.value.equals(role) || USER.value.equals(role); + } + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + UserRole userRole = (UserRole) obj; + return value.equals(userRole.value); } - public boolean isValid() { - return value != null && (value.equals(ADMIN) || value.equals(USER)); + @Override + public int hashCode() { + return value.hashCode(); } } \ No newline at end of file diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java index 7c965e0..a893b6a 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/valueobject/UserStatus.java @@ -1,34 +1,83 @@ package com.example.user.service.domain.valueobject; +import lombok.extern.slf4j.Slf4j; + /** - * @Author: zhangyucheng - * @Date: 2025/9/16 14:15 + * 用户状态值对象 */ + +@Slf4j public record UserStatus(Integer value) { - public static final Integer DISABLED = 0; - public static final Integer ENABLED = 1; + public static final UserStatus DISABLED = new UserStatus(0); + public static final UserStatus ENABLED = new UserStatus(1); + public static final UserStatus PENDING = new UserStatus(2); // 可选:添加待激活状态 - public static UserStatus of(Integer status) { - if (status == null) { - throw new RuntimeException("用户状态不能为空"); + public UserStatus { + if (value == null) { + throw new IllegalArgumentException("用户状态不能为空"); } - - if (!status.equals(DISABLED) && !status.equals(ENABLED)) { - throw new RuntimeException("用户状态必须是0(禁用)或1(启用)"); + // 直接使用数字字面量进行比较,不要引用静态字段 + if (value != 0 && value != 1 && value != 2) { + throw new IllegalArgumentException("用户状态必须是0(禁用)、1(启用)或2(待激活)"); } + } + // 静态工厂方法 + public static UserStatus of(Integer status) { return new UserStatus(status); } + public static UserStatus disabled() { + return DISABLED; + } + + public static UserStatus enabled() { + return ENABLED; + } + + public static UserStatus pending() { + return PENDING; + } + public boolean isEnabled() { - return ENABLED.equals(value); + return Integer.valueOf(1).equals(value); } public boolean isDisabled() { - return DISABLED.equals(value); + return Integer.valueOf(0).equals(value); + } + + public boolean isPending() { + return Integer.valueOf(2).equals(value); + } + + private static boolean isValidStatus(Integer status) { + // 同样修改这里,使用字面量 + return Integer.valueOf(0).equals(status) || + Integer.valueOf(1).equals(status) || + Integer.valueOf(2).equals(status); + } + + // 转换方法:从数据库值创建 + public Integer getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + UserStatus that = (UserStatus) obj; + return value.equals(that.value); } - public boolean isValid() { - return value != null && (value.equals(DISABLED) || value.equals(ENABLED)); + @Override + public int hashCode() { + return value.hashCode(); } } \ No newline at end of file -- Gitee From 568e7078d9b4a624e20de159d5f9fd25a7895016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?OK=E4=BA=86?= <2634608480@qq.com> Date: Wed, 17 Sep 2025 20:50:09 +0800 Subject: [PATCH 23/23] =?UTF-8?q?doc=20=E6=B6=88=E6=81=AF=E9=98=9F?= =?UTF-8?q?=E5=88=97=E5=92=8Ckimi=E8=BF=9E=E6=8E=A5=E5=AE=8C=E6=88=90?= =?UTF-8?q?=EF=BC=8C=E6=B6=88=E6=81=AF=E9=98=9F=E5=88=97=E5=9B=9E=E5=A4=8D?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=A4=B1=E8=B4=A5=EF=BC=8C=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=B8=B8=E8=A7=84=E6=A8=A1=E5=BC=8F=EF=BC=8C=E7=BC=BA=E7=82=B9?= =?UTF-8?q?=E6=98=AF=E6=97=A0=E6=B3=95=E7=9B=B4=E6=8E=A5=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC=E4=BC=A0=E9=80=92=E5=9B=9E=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/web/config/MoonShotConfig.java | 19 ++++ .../qa/adapter/in/web/config/RestConfig.java | 18 ++++ .../in/web/controller/QaController.java | 27 ++--- .../in/web/dto/ChatCompletionRequestDTO.java | 12 +++ .../in/web/dto/ChatCompletionResponseDTO.java | 14 +++ .../example/qa/adapter/in/web/dto/Choice.java | 10 ++ .../qa/adapter/in/web/dto/Message.java | 9 ++ .../in/web/listener/Demo3Listener.java | 19 ---- .../persistence}/listener/Demo2Listener.java | 2 +- .../persistence/listener/Demo3Listener.java | 102 ++++++++++++++++++ .../persistence}/listener/DemoListener.java | 2 +- .../src/main/resources/application.properties | 11 +- 12 files changed, 200 insertions(+), 45 deletions(-) create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/MoonShotConfig.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/RestConfig.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionRequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionResponseDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Choice.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Message.java delete mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo3Listener.java rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/{in/web => out/persistence}/listener/Demo2Listener.java (87%) create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo3Listener.java rename qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/{in/web => out/persistence}/listener/DemoListener.java (86%) diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/MoonShotConfig.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/MoonShotConfig.java new file mode 100644 index 0000000..4a84938 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/MoonShotConfig.java @@ -0,0 +1,19 @@ +package com.example.qa.adapter.in.web.config; + + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @Author: zhangyucheng + * @Date: 2025/9/17 17:29 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "moonshot") +public class MoonShotConfig { + private String url; + private String key; + private String model; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/RestConfig.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/RestConfig.java new file mode 100644 index 0000000..a3e0f0f --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/config/RestConfig.java @@ -0,0 +1,18 @@ +package com.example.qa.adapter.in.web.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @Author: zhangyucheng + * @Date: 2025/9/17 17:29 + */ +@Configuration +public class RestConfig { + @Bean + public RestTemplate getRestTemplate(){ + return new RestTemplate(); + } +} \ No newline at end of file diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java index 0f41224..2f3e865 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QaController.java @@ -1,9 +1,7 @@ package com.example.qa.adapter.in.web.controller; import com.alibaba.fastjson2.JSON; -import com.example.qa.adapter.in.web.dto.CreateQaRequestDTO; -import com.example.qa.adapter.in.web.dto.QaResponseDTO; -import com.example.qa.adapter.in.web.dto.UpdateQaRequestDTO; +import com.example.qa.adapter.in.web.dto.*; import com.example.qa.service.application.command.*; import com.example.qa.service.application.port.in.*; import com.example.qa.service.domain.Qa; @@ -12,7 +10,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.web.bind.annotation.*; - import java.util.List; @Slf4j @@ -98,7 +95,7 @@ public class QaController { /** * @param : * @return String - * @author Administrator + * @author zhujunjie * @date 2025/9/17 18:27 */ @GetMapping("send") @@ -110,7 +107,7 @@ public class QaController { /** * @param createQaRequestDTO: * @return String - * @author Administrator + * @author zhujunjie * @date 2025/9/17 19:24 */ @PostMapping("sendObject") @@ -126,20 +123,14 @@ public class QaController { return "success"; } /** - * @param createQaRequestDTO: + * @param : * @return String - * @author Administrator - * @date 2025/9/17 19:24 + * @author zhujunjie + * @date 2025/9/17 20:12 */ - @PostMapping("sendJson") - public String sendJson(@RequestBody CreateQaRequestDTO createQaRequestDTO) { - Qa qa=new Qa(); - CreateQaCommand command=CreateQaCommand.builder() - .question(createQaRequestDTO.question()) - .answer(createQaRequestDTO.answer()) - .build(); - qa=createQaUseCase.createQa(command); - rabbitTemplate.convertAndSend("test3", JSON.toJSONString(qa)); + @GetMapping("sendJson") + public String sendJson(@RequestParam("question") String question) { + rabbitTemplate.convertAndSend("test3", JSON.toJSONString(question)); return "success"; } } diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionRequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionRequestDTO.java new file mode 100644 index 0000000..7ef84a0 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionRequestDTO.java @@ -0,0 +1,12 @@ +package com.example.qa.adapter.in.web.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class ChatCompletionRequestDTO { + private String model; + private List messages; + private double temperature; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionResponseDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionResponseDTO.java new file mode 100644 index 0000000..ef17370 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/ChatCompletionResponseDTO.java @@ -0,0 +1,14 @@ +package com.example.qa.adapter.in.web.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class ChatCompletionResponseDTO { + private String id; + private String object; + private long created; + private String model; + private List choices; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Choice.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Choice.java new file mode 100644 index 0000000..6b135a4 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Choice.java @@ -0,0 +1,10 @@ +package com.example.qa.adapter.in.web.dto; + +import lombok.Data; + +@Data +public class Choice { + private int index; + private Message message; + private String finish_reason; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Message.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Message.java new file mode 100644 index 0000000..e000aac --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/Message.java @@ -0,0 +1,9 @@ +package com.example.qa.adapter.in.web.dto; + +import lombok.Data; + +@Data +public class Message { + private String role; + private String content; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo3Listener.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo3Listener.java deleted file mode 100644 index d6947e6..0000000 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo3Listener.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.qa.adapter.in.web.listener; - - -import com.alibaba.fastjson2.JSON; -import com.example.qa.service.domain.Qa; -import org.springframework.amqp.rabbit.annotation.RabbitHandler; -import org.springframework.amqp.rabbit.annotation.RabbitListener; -import org.springframework.stereotype.Component; - -@Component -@RabbitListener(queues = "test3") -public class Demo3Listener { - @RabbitHandler - public void handler(String QA){ - //json字符串还原会成对象 - Qa qa = JSON.parseObject(QA, Qa.class); - System.out.println("收到的消息是:"+qa); - } -} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo2Listener.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo2Listener.java similarity index 87% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo2Listener.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo2Listener.java index 81b5ce0..a767b0f 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/Demo2Listener.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo2Listener.java @@ -1,4 +1,4 @@ -package com.example.qa.adapter.in.web.listener; +package com.example.qa.adapter.out.persistence.listener; import com.example.qa.service.domain.Qa; diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo3Listener.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo3Listener.java new file mode 100644 index 0000000..8794448 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/Demo3Listener.java @@ -0,0 +1,102 @@ +package com.example.qa.adapter.out.persistence.listener; + + +import com.alibaba.fastjson2.JSON; +import com.example.qa.adapter.in.web.config.MoonShotConfig; +import com.example.qa.adapter.in.web.dto.ChatCompletionRequestDTO; +import com.example.qa.adapter.in.web.dto.ChatCompletionResponseDTO; +import com.example.qa.adapter.in.web.dto.Choice; +import com.example.qa.adapter.in.web.dto.Message; +import com.example.qa.service.application.command.CreateQaCommand; +import com.example.qa.service.application.port.in.CreateQaUseCase; +import com.example.qa.service.domain.Qa; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.Arrays; +@Slf4j +@Component +@RequiredArgsConstructor +@RabbitListener(queues = "test3") +public class Demo3Listener { + @Resource + private MoonShotConfig moonShotConfig; + @Resource + private RestTemplate restTemplate; + private final CreateQaUseCase createQaUseCase; + + @RabbitHandler + public void handler(String question) { + /** + * @author zhangyucheng + * @param + * @return + */ + try { + log.info("收到问题: {}", question); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("Authorization", "Bearer " + moonShotConfig.getKey()); + + ChatCompletionRequestDTO request = new ChatCompletionRequestDTO(); + request.setModel(moonShotConfig.getModel()); + request.setTemperature(0.6); + + Message systemMessage = new Message(); + systemMessage.setRole("system"); + systemMessage.setContent("你是 Kimi,由 Moonshot AI 提供的人工智能助手..."); + + Message userMessage = new Message(); + userMessage.setRole("user"); + userMessage.setContent(question); + + request.setMessages(Arrays.asList(systemMessage, userMessage)); + + HttpEntity requestEntity = new HttpEntity<>(request, headers); + ChatCompletionResponseDTO response = restTemplate.exchange( + moonShotConfig.getUrl(), + HttpMethod.POST, + requestEntity, + ChatCompletionResponseDTO.class + ).getBody(); + + log.info("API响应: {}", response); + + String answer = extractAnswerFromResponse(response); + + CreateQaCommand command = new CreateQaCommand( + null, // id由数据库自动生成 + question, + answer + ); + createQaUseCase.createQa(command); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * @param + * @return + * @author zhangyucheng + */ + private String extractAnswerFromResponse(ChatCompletionResponseDTO response) { + if (response != null && response.getChoices() != null && !response.getChoices().isEmpty()) { + Choice firstChoice = response.getChoices().get(0); + if (firstChoice.getMessage() != null) { + return firstChoice.getMessage().getContent(); + } + } + return "抱歉,无法获取答案"; + } +} + diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/DemoListener.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/DemoListener.java similarity index 86% rename from qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/DemoListener.java rename to qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/DemoListener.java index b9eb263..12f1798 100644 --- a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/listener/DemoListener.java +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/out/persistence/listener/DemoListener.java @@ -1,4 +1,4 @@ -package com.example.qa.adapter.in.web.listener; +package com.example.qa.adapter.out.persistence.listener; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; diff --git a/qa-service/qa-service-bootstrap/src/main/resources/application.properties b/qa-service/qa-service-bootstrap/src/main/resources/application.properties index 21b2d24..1e3baf8 100644 --- a/qa-service/qa-service-bootstrap/src/main/resources/application.properties +++ b/qa-service/qa-service-bootstrap/src/main/resources/application.properties @@ -1,8 +1,5 @@ server.port=28081 - spring.application.name=qa-service - - # Nacos认证信息 spring.cloud.nacos.discovery.username=nacos spring.cloud.nacos.discovery.password=nacos @@ -10,7 +7,6 @@ spring.cloud.nacos.discovery.password=nacos spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 # 注册到 nacos 的指定 namespace,默认为 public spring.cloud.nacos.discovery.namespace=public - # Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html # Nacos认证信息 spring.cloud.nacos.config.username=nacos @@ -21,8 +17,11 @@ spring.cloud.nacos.config.server-addr=192.168.168.128:8848 # Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 # spring.cloud.nacos.config.namespace= spring.config.import=nacos:${spring.application.name}.properties?refresh=true - spring.rabbitmq.addresses=192.168.168.128 spring.rabbitmq.username=guest spring.rabbitmq.password=guest -spring.amqp.deserialization.trust.all = true \ No newline at end of file +spring.amqp.deserialization.trust.all=true + +moonshot.url=https://api.moonshot.cn/v1/chat/completions +moonshot.key=sk-BMEWhXEYHR0sLrixvuIzv25dRSMHD1E5X21UugQk0Tstc6qs +moonshot.model=kimi-k2-0905-preview \ No newline at end of file -- Gitee