Spaces:
Configuration error
Configuration error
Add structure coding
Browse files- pom.xml +25 -14
- src/main/java/com/attendenceSystem/AttendenceSystemApplication.java +2 -0
- src/main/java/com/attendenceSystem/annotation/PasswordMatch.java +23 -0
- src/main/java/com/attendenceSystem/config/TimeConfiguration.java +22 -0
- src/main/java/com/attendenceSystem/config/properties/AppProperties.java +17 -0
- src/main/java/com/attendenceSystem/{controllers → controller}/PageController.java +2 -2
- src/main/java/com/attendenceSystem/user/dto/request/LoginRequest.java +22 -0
- src/main/java/com/attendenceSystem/user/dto/request/RegisterRequest.java +38 -0
- src/main/java/com/attendenceSystem/user/dto/response/UserResponse.java +17 -0
- src/main/java/com/attendenceSystem/user/entity/User.java +27 -0
- src/main/java/com/attendenceSystem/user/entity/converter/RoleConverter.java +15 -0
- src/main/java/com/attendenceSystem/user/entity/enums/Role.java +20 -0
- src/main/java/com/attendenceSystem/user/mapper/request/LoginRequestMapper.java +5 -0
- src/main/java/com/attendenceSystem/user/mapper/request/RegisterRequestMapper.java +5 -0
- src/main/java/com/attendenceSystem/user/mapper/response/UserResponseMapper.java +38 -0
- src/main/java/com/attendenceSystem/user/repository/UserRepository.java +5 -0
- src/main/java/com/attendenceSystem/user/service/UserService.java +15 -0
- src/main/java/com/attendenceSystem/user/service/impl/UserServiceImpl.java +65 -0
- src/main/java/com/attendenceSystem/util/TimeUtil.java +30 -0
- src/main/java/com/attendenceSystem/validator/PasswordMatchValidator.java +35 -0
- src/main/resources/application.properties +4 -1
pom.xml
CHANGED
|
@@ -1,30 +1,31 @@
|
|
| 1 |
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
-
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
| 3 |
-
|
|
|
|
| 4 |
<modelVersion>4.0.0</modelVersion>
|
| 5 |
<parent>
|
| 6 |
<groupId>org.springframework.boot</groupId>
|
| 7 |
<artifactId>spring-boot-starter-parent</artifactId>
|
| 8 |
<version>4.0.6</version>
|
| 9 |
-
<relativePath/> <!-- lookup parent from repository -->
|
| 10 |
</parent>
|
| 11 |
<groupId>com.</groupId>
|
| 12 |
<artifactId>attendenceSystem</artifactId>
|
| 13 |
<version>0.0.1-SNAPSHOT</version>
|
| 14 |
-
<name/>
|
| 15 |
-
<description/>
|
| 16 |
-
<url/>
|
| 17 |
<licenses>
|
| 18 |
-
<license/>
|
| 19 |
</licenses>
|
| 20 |
<developers>
|
| 21 |
-
<developer/>
|
| 22 |
</developers>
|
| 23 |
<scm>
|
| 24 |
-
<connection/>
|
| 25 |
-
<developerConnection/>
|
| 26 |
-
<tag/>
|
| 27 |
-
<url/>
|
| 28 |
</scm>
|
| 29 |
<properties>
|
| 30 |
<java.version>21</java.version>
|
|
@@ -34,6 +35,16 @@
|
|
| 34 |
<groupId>org.springframework.boot</groupId>
|
| 35 |
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
| 36 |
</dependency> -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
<dependency>
|
| 38 |
<groupId>org.springframework.boot</groupId>
|
| 39 |
<artifactId>spring-boot-starter-restclient</artifactId>
|
|
@@ -77,7 +88,7 @@
|
|
| 77 |
<artifactId>spring-boot-starter-restclient-test</artifactId>
|
| 78 |
<scope>test</scope>
|
| 79 |
</dependency>
|
| 80 |
-
|
| 81 |
<dependency>
|
| 82 |
<groupId>org.springframework.boot</groupId>
|
| 83 |
<artifactId>spring-boot-starter-webmvc-test</artifactId>
|
|
@@ -94,4 +105,4 @@
|
|
| 94 |
</plugins>
|
| 95 |
</build>
|
| 96 |
|
| 97 |
-
</project>
|
|
|
|
| 1 |
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
| 3 |
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
| 4 |
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
| 5 |
<modelVersion>4.0.0</modelVersion>
|
| 6 |
<parent>
|
| 7 |
<groupId>org.springframework.boot</groupId>
|
| 8 |
<artifactId>spring-boot-starter-parent</artifactId>
|
| 9 |
<version>4.0.6</version>
|
| 10 |
+
<relativePath /> <!-- lookup parent from repository -->
|
| 11 |
</parent>
|
| 12 |
<groupId>com.</groupId>
|
| 13 |
<artifactId>attendenceSystem</artifactId>
|
| 14 |
<version>0.0.1-SNAPSHOT</version>
|
| 15 |
+
<name />
|
| 16 |
+
<description />
|
| 17 |
+
<url />
|
| 18 |
<licenses>
|
| 19 |
+
<license />
|
| 20 |
</licenses>
|
| 21 |
<developers>
|
| 22 |
+
<developer />
|
| 23 |
</developers>
|
| 24 |
<scm>
|
| 25 |
+
<connection />
|
| 26 |
+
<developerConnection />
|
| 27 |
+
<tag />
|
| 28 |
+
<url />
|
| 29 |
</scm>
|
| 30 |
<properties>
|
| 31 |
<java.version>21</java.version>
|
|
|
|
| 35 |
<groupId>org.springframework.boot</groupId>
|
| 36 |
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
| 37 |
</dependency> -->
|
| 38 |
+
<dependency>
|
| 39 |
+
<groupId>org.springframework.boot</groupId>
|
| 40 |
+
<artifactId>spring-boot-starter-validation</artifactId>
|
| 41 |
+
</dependency>
|
| 42 |
+
<dependency>
|
| 43 |
+
<groupId>org.projectlombok</groupId>
|
| 44 |
+
<artifactId>lombok</artifactId>
|
| 45 |
+
<version>1.18.32</version>
|
| 46 |
+
<optional>true</optional>
|
| 47 |
+
</dependency>
|
| 48 |
<dependency>
|
| 49 |
<groupId>org.springframework.boot</groupId>
|
| 50 |
<artifactId>spring-boot-starter-restclient</artifactId>
|
|
|
|
| 88 |
<artifactId>spring-boot-starter-restclient-test</artifactId>
|
| 89 |
<scope>test</scope>
|
| 90 |
</dependency>
|
| 91 |
+
|
| 92 |
<dependency>
|
| 93 |
<groupId>org.springframework.boot</groupId>
|
| 94 |
<artifactId>spring-boot-starter-webmvc-test</artifactId>
|
|
|
|
| 105 |
</plugins>
|
| 106 |
</build>
|
| 107 |
|
| 108 |
+
</project>
|
src/main/java/com/attendenceSystem/AttendenceSystemApplication.java
CHANGED
|
@@ -2,8 +2,10 @@ package com.attendenceSystem;
|
|
| 2 |
|
| 3 |
import org.springframework.boot.SpringApplication;
|
| 4 |
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
|
|
| 5 |
|
| 6 |
@SpringBootApplication
|
|
|
|
| 7 |
public class AttendenceSystemApplication {
|
| 8 |
|
| 9 |
public static void main(String[] args) {
|
|
|
|
| 2 |
|
| 3 |
import org.springframework.boot.SpringApplication;
|
| 4 |
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
| 5 |
+
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
| 6 |
|
| 7 |
@SpringBootApplication
|
| 8 |
+
@ConfigurationPropertiesScan
|
| 9 |
public class AttendenceSystemApplication {
|
| 10 |
|
| 11 |
public static void main(String[] args) {
|
src/main/java/com/attendenceSystem/annotation/PasswordMatch.java
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.annotation;
|
| 2 |
+
|
| 3 |
+
import java.lang.annotation.ElementType;
|
| 4 |
+
import java.lang.annotation.Retention;
|
| 5 |
+
import java.lang.annotation.RetentionPolicy;
|
| 6 |
+
import java.lang.annotation.Target;
|
| 7 |
+
|
| 8 |
+
import com.attendenceSystem.validator.PasswordMatchValidator;
|
| 9 |
+
|
| 10 |
+
import jakarta.validation.Constraint;
|
| 11 |
+
import jakarta.validation.Payload;
|
| 12 |
+
|
| 13 |
+
@Target(ElementType.TYPE)
|
| 14 |
+
@Retention(RetentionPolicy.RUNTIME)
|
| 15 |
+
@Constraint(validatedBy = PasswordMatchValidator.class)
|
| 16 |
+
public @interface PasswordMatch {
|
| 17 |
+
|
| 18 |
+
String message() default "Mật khẩu xác nhận không khớp";
|
| 19 |
+
|
| 20 |
+
Class<?>[] groups() default {};
|
| 21 |
+
|
| 22 |
+
Class<? extends Payload>[] payload() default {};
|
| 23 |
+
}
|
src/main/java/com/attendenceSystem/config/TimeConfiguration.java
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.config;
|
| 2 |
+
|
| 3 |
+
import java.time.ZoneId;
|
| 4 |
+
|
| 5 |
+
import org.springframework.context.annotation.Bean;
|
| 6 |
+
import org.springframework.context.annotation.Configuration;
|
| 7 |
+
|
| 8 |
+
import com.attendenceSystem.config.properties.AppProperties;
|
| 9 |
+
|
| 10 |
+
import lombok.RequiredArgsConstructor;
|
| 11 |
+
|
| 12 |
+
@Configuration
|
| 13 |
+
@RequiredArgsConstructor
|
| 14 |
+
public class TimeConfiguration {
|
| 15 |
+
|
| 16 |
+
private final AppProperties appProperties;
|
| 17 |
+
|
| 18 |
+
@Bean
|
| 19 |
+
public ZoneId applicationZoneId() {
|
| 20 |
+
return ZoneId.of(appProperties.getTimezone());
|
| 21 |
+
}
|
| 22 |
+
}
|
src/main/java/com/attendenceSystem/config/properties/AppProperties.java
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
Đọc file config từ application.properties
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
package com.attendenceSystem.config.properties;
|
| 6 |
+
|
| 7 |
+
import org.springframework.boot.context.properties.ConfigurationProperties;
|
| 8 |
+
|
| 9 |
+
import lombok.Getter;
|
| 10 |
+
import lombok.Setter;
|
| 11 |
+
|
| 12 |
+
@ConfigurationProperties(prefix = "app")
|
| 13 |
+
@Getter
|
| 14 |
+
@Setter
|
| 15 |
+
public class AppProperties {
|
| 16 |
+
private String timezone;
|
| 17 |
+
}
|
src/main/java/com/attendenceSystem/{controllers → controller}/PageController.java
RENAMED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
package com.attendenceSystem.
|
| 2 |
|
| 3 |
import org.springframework.stereotype.Controller;
|
| 4 |
import org.springframework.web.bind.annotation.GetMapping;
|
|
@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|
| 9 |
@RequestMapping("/")
|
| 10 |
public class PageController {
|
| 11 |
|
| 12 |
-
@GetMapping("home")
|
| 13 |
public String home() {
|
| 14 |
return "home";
|
| 15 |
}
|
|
|
|
| 1 |
+
package com.attendenceSystem.controller;
|
| 2 |
|
| 3 |
import org.springframework.stereotype.Controller;
|
| 4 |
import org.springframework.web.bind.annotation.GetMapping;
|
|
|
|
| 9 |
@RequestMapping("/")
|
| 10 |
public class PageController {
|
| 11 |
|
| 12 |
+
@GetMapping({"home",""})
|
| 13 |
public String home() {
|
| 14 |
return "home";
|
| 15 |
}
|
src/main/java/com/attendenceSystem/user/dto/request/LoginRequest.java
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.dto.request;
|
| 2 |
+
|
| 3 |
+
import com.attendenceSystem.user.entity.User;
|
| 4 |
+
|
| 5 |
+
import jakarta.validation.constraints.Email;
|
| 6 |
+
import jakarta.validation.constraints.NotBlank;
|
| 7 |
+
import jakarta.validation.constraints.Size;
|
| 8 |
+
import lombok.Data;
|
| 9 |
+
import lombok.NonNull;
|
| 10 |
+
|
| 11 |
+
@Data
|
| 12 |
+
public class LoginRequest {
|
| 13 |
+
@NotBlank(message = "Email không được để trống")
|
| 14 |
+
@Size(max = 255, message = "Email không được vượt quá 255 ký tự")
|
| 15 |
+
@Email(message = "Email không đúng định dạng")
|
| 16 |
+
private String email;
|
| 17 |
+
@NotBlank(message = "Mật khẩu không được để trống")
|
| 18 |
+
@Size(min = 8, message = "Mật khẩu phải chứa ít nhất 8 kí tự")
|
| 19 |
+
private String password;
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
}
|
src/main/java/com/attendenceSystem/user/dto/request/RegisterRequest.java
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.dto.request;
|
| 2 |
+
|
| 3 |
+
import com.attendenceSystem.annotation.PasswordMatch;
|
| 4 |
+
import com.attendenceSystem.user.entity.User;
|
| 5 |
+
import com.fasterxml.jackson.annotation.JsonProperty;
|
| 6 |
+
|
| 7 |
+
import jakarta.validation.constraints.Email;
|
| 8 |
+
import jakarta.validation.constraints.NotBlank;
|
| 9 |
+
import jakarta.validation.constraints.Size;
|
| 10 |
+
import lombok.Data;
|
| 11 |
+
import lombok.NonNull;
|
| 12 |
+
|
| 13 |
+
@Data
|
| 14 |
+
@PasswordMatch
|
| 15 |
+
public class RegisterRequest {
|
| 16 |
+
@NotBlank(message = "Email không được để trống")
|
| 17 |
+
@Size(max = 255, message = "Email không được vượt quá 255 ký tự")
|
| 18 |
+
@Email(message = "Email không đúng định dạng")
|
| 19 |
+
private String email;
|
| 20 |
+
@NotBlank(message = "Mật khẩu không được để trống")
|
| 21 |
+
@Size(min = 8, message = "Mật khẩu phải chứa ít nhất 8 kí tự")
|
| 22 |
+
private String password;
|
| 23 |
+
@NotBlank(message = "Mật khẩu xác nhận không được để trống")
|
| 24 |
+
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
| 25 |
+
private String rePassword;
|
| 26 |
+
@NotBlank(message = "Họ tên không được để trống")
|
| 27 |
+
@Size(max = 255, message = "Họ tên không được vượt quá 255 ký tự")
|
| 28 |
+
private String fullName;
|
| 29 |
+
|
| 30 |
+
@NonNull
|
| 31 |
+
public User toEntity(String hashPassword) {
|
| 32 |
+
return User.builder()
|
| 33 |
+
.email(this.email)
|
| 34 |
+
.password(hashPassword)
|
| 35 |
+
.fullName(this.fullName)
|
| 36 |
+
.build();
|
| 37 |
+
}
|
| 38 |
+
}
|
src/main/java/com/attendenceSystem/user/dto/response/UserResponse.java
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.dto.response;
|
| 2 |
+
|
| 3 |
+
import lombok.Builder;
|
| 4 |
+
import lombok.Data;
|
| 5 |
+
|
| 6 |
+
@Data
|
| 7 |
+
@Builder
|
| 8 |
+
public class UserResponse {
|
| 9 |
+
private Long id;
|
| 10 |
+
private String email;
|
| 11 |
+
private String fullName;
|
| 12 |
+
private String avatar;
|
| 13 |
+
private String status;
|
| 14 |
+
private String createdAt;
|
| 15 |
+
private String updatedAt;
|
| 16 |
+
private Boolean deleted;
|
| 17 |
+
}
|
src/main/java/com/attendenceSystem/user/entity/User.java
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.entity;
|
| 2 |
+
|
| 3 |
+
import java.time.Instant;
|
| 4 |
+
|
| 5 |
+
import lombok.AllArgsConstructor;
|
| 6 |
+
import lombok.Builder;
|
| 7 |
+
import lombok.Getter;
|
| 8 |
+
import lombok.NoArgsConstructor;
|
| 9 |
+
import lombok.Setter;
|
| 10 |
+
|
| 11 |
+
@Getter
|
| 12 |
+
@Setter
|
| 13 |
+
@NoArgsConstructor
|
| 14 |
+
@AllArgsConstructor
|
| 15 |
+
@Builder
|
| 16 |
+
public class User {
|
| 17 |
+
private Long id;
|
| 18 |
+
private String email;
|
| 19 |
+
private String password;
|
| 20 |
+
private String fullName;
|
| 21 |
+
private String avatar;
|
| 22 |
+
private String role;
|
| 23 |
+
private String status;
|
| 24 |
+
private Instant createdAt;
|
| 25 |
+
private Instant updatedAt;
|
| 26 |
+
private Boolean deleted;
|
| 27 |
+
}
|
src/main/java/com/attendenceSystem/user/entity/converter/RoleConverter.java
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// package com.attendenceSystem.user.entity.converter;
|
| 2 |
+
|
| 3 |
+
// @Converter(autoApply = true)
|
| 4 |
+
// public class RoleConverter implements AttributeConverter<Role, Integer> {
|
| 5 |
+
|
| 6 |
+
// @Override
|
| 7 |
+
// public Integer convertToDatabaseColumn(Role role) {
|
| 8 |
+
// return role == null ? null : role.getValue();
|
| 9 |
+
// }
|
| 10 |
+
|
| 11 |
+
// @Override
|
| 12 |
+
// public Role convertToEntityAttribute(Integer dbData) {
|
| 13 |
+
// return dbData == null ? null : Role.fromValue(dbData);
|
| 14 |
+
// }
|
| 15 |
+
// }
|
src/main/java/com/attendenceSystem/user/entity/enums/Role.java
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.entity.enums;
|
| 2 |
+
|
| 3 |
+
import lombok.Getter;
|
| 4 |
+
import lombok.RequiredArgsConstructor;
|
| 5 |
+
|
| 6 |
+
@Getter
|
| 7 |
+
@RequiredArgsConstructor
|
| 8 |
+
public enum Role {
|
| 9 |
+
ADMIN(1), MANAGER(2), STAFF(3), ;
|
| 10 |
+
|
| 11 |
+
public final int value;
|
| 12 |
+
public static Role fromValue(int value){
|
| 13 |
+
for(Role role : Role.values()){
|
| 14 |
+
if(role.value == value){
|
| 15 |
+
return role;
|
| 16 |
+
}
|
| 17 |
+
}
|
| 18 |
+
throw new IllegalArgumentException("Không tìm thấy vai trò: "+ value);
|
| 19 |
+
}
|
| 20 |
+
}
|
src/main/java/com/attendenceSystem/user/mapper/request/LoginRequestMapper.java
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.mapper.request;
|
| 2 |
+
|
| 3 |
+
public class LoginRequestMapper {
|
| 4 |
+
|
| 5 |
+
}
|
src/main/java/com/attendenceSystem/user/mapper/request/RegisterRequestMapper.java
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.mapper.request;
|
| 2 |
+
|
| 3 |
+
public class RegisterRequestMapper {
|
| 4 |
+
|
| 5 |
+
}
|
src/main/java/com/attendenceSystem/user/mapper/response/UserResponseMapper.java
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.mapper.response;
|
| 2 |
+
|
| 3 |
+
import java.time.ZoneId;
|
| 4 |
+
|
| 5 |
+
import org.springframework.stereotype.Component;
|
| 6 |
+
|
| 7 |
+
import com.attendenceSystem.user.dto.response.UserResponse;
|
| 8 |
+
import com.attendenceSystem.user.entity.User;
|
| 9 |
+
import com.attendenceSystem.util.TimeUtil;
|
| 10 |
+
|
| 11 |
+
import lombok.RequiredArgsConstructor;
|
| 12 |
+
|
| 13 |
+
@Component
|
| 14 |
+
@RequiredArgsConstructor
|
| 15 |
+
public class UserResponseMapper {
|
| 16 |
+
|
| 17 |
+
private final ZoneId applicationZoneId;
|
| 18 |
+
|
| 19 |
+
public UserResponse toResponse(User user) {
|
| 20 |
+
|
| 21 |
+
return UserResponse.builder()
|
| 22 |
+
.id(user.getId())
|
| 23 |
+
.email(user.getEmail())
|
| 24 |
+
.fullName(user.getFullName())
|
| 25 |
+
.avatar(user.getAvatar())
|
| 26 |
+
.status(user.getStatus())
|
| 27 |
+
.createdAt(
|
| 28 |
+
TimeUtil.formatInstant(
|
| 29 |
+
user.getCreatedAt(),
|
| 30 |
+
applicationZoneId))
|
| 31 |
+
.updatedAt(
|
| 32 |
+
TimeUtil.formatInstant(
|
| 33 |
+
user.getUpdatedAt(),
|
| 34 |
+
applicationZoneId))
|
| 35 |
+
.deleted(user.getDeleted())
|
| 36 |
+
.build();
|
| 37 |
+
}
|
| 38 |
+
}
|
src/main/java/com/attendenceSystem/user/repository/UserRepository.java
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.repository;
|
| 2 |
+
|
| 3 |
+
public interface UserRepository {
|
| 4 |
+
|
| 5 |
+
}
|
src/main/java/com/attendenceSystem/user/service/UserService.java
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.service;
|
| 2 |
+
|
| 3 |
+
import com.attendenceSystem.user.dto.request.LoginRequest;
|
| 4 |
+
import com.attendenceSystem.user.dto.request.RegisterRequest;
|
| 5 |
+
import com.attendenceSystem.user.dto.response.UserResponse;
|
| 6 |
+
|
| 7 |
+
public interface UserService {
|
| 8 |
+
UserResponse login(LoginRequest request);
|
| 9 |
+
|
| 10 |
+
void register(RegisterRequest request);
|
| 11 |
+
|
| 12 |
+
void deleteUser(Long id);
|
| 13 |
+
|
| 14 |
+
UserResponse findAccountById(Long id);
|
| 15 |
+
}
|
src/main/java/com/attendenceSystem/user/service/impl/UserServiceImpl.java
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.user.service.impl;
|
| 2 |
+
|
| 3 |
+
import java.time.Instant;
|
| 4 |
+
import java.time.ZoneId;
|
| 5 |
+
|
| 6 |
+
import com.attendenceSystem.user.dto.request.LoginRequest;
|
| 7 |
+
import com.attendenceSystem.user.dto.request.RegisterRequest;
|
| 8 |
+
import com.attendenceSystem.user.dto.response.UserResponse;
|
| 9 |
+
import com.attendenceSystem.user.entity.User;
|
| 10 |
+
import com.attendenceSystem.user.repository.UserRepository;
|
| 11 |
+
import com.attendenceSystem.user.service.UserService;
|
| 12 |
+
import com.attendenceSystem.util.TimeUtil;
|
| 13 |
+
|
| 14 |
+
import lombok.RequiredArgsConstructor;
|
| 15 |
+
|
| 16 |
+
@RequiredArgsConstructor
|
| 17 |
+
public class UserServiceImpl implements UserService {
|
| 18 |
+
private final UserRepository userRepository;
|
| 19 |
+
private final ZoneId applicationZoneId;
|
| 20 |
+
// private final PasswordEncoder passwordEncoder;
|
| 21 |
+
|
| 22 |
+
@Override
|
| 23 |
+
public UserResponse login(LoginRequest request) {
|
| 24 |
+
// Tìm tài khoản thông qua email từ request, không có báo lỗi.
|
| 25 |
+
|
| 26 |
+
// Kiểm tra mật khẩu từ request có chính xác không. Sai báo lỗi
|
| 27 |
+
|
| 28 |
+
// Trả UserResponse
|
| 29 |
+
return null;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// @Transactional
|
| 33 |
+
@Override
|
| 34 |
+
public void register(RegisterRequest request) {
|
| 35 |
+
// Kiểm tra email
|
| 36 |
+
|
| 37 |
+
// encode password
|
| 38 |
+
|
| 39 |
+
// Lưu User
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
@Override
|
| 43 |
+
public void deleteUser(Long id) {
|
| 44 |
+
// TODO Auto-generated method stub
|
| 45 |
+
throw new UnsupportedOperationException("Unimplemented method 'deleteUser'");
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
@Override
|
| 49 |
+
public UserResponse findAccountById(Long id) {
|
| 50 |
+
// Kiểm tra id == null
|
| 51 |
+
|
| 52 |
+
// Tìm kiếm user thông qua id
|
| 53 |
+
|
| 54 |
+
// Trả về UserResponse.
|
| 55 |
+
return null;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
private String getCurrentTime() {
|
| 59 |
+
|
| 60 |
+
return TimeUtil.formatInstant(
|
| 61 |
+
Instant.now(),
|
| 62 |
+
applicationZoneId);
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
}
|
src/main/java/com/attendenceSystem/util/TimeUtil.java
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.util;
|
| 2 |
+
|
| 3 |
+
import java.time.Instant;
|
| 4 |
+
import java.time.LocalDateTime;
|
| 5 |
+
import java.time.ZoneId;
|
| 6 |
+
import java.time.format.DateTimeFormatter;
|
| 7 |
+
|
| 8 |
+
import lombok.experimental.UtilityClass;
|
| 9 |
+
|
| 10 |
+
@UtilityClass
|
| 11 |
+
public class TimeUtil {
|
| 12 |
+
|
| 13 |
+
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
| 14 |
+
|
| 15 |
+
public static String formatInstant(Instant instant, ZoneId zoneId) {
|
| 16 |
+
return instant.atZone(zoneId)
|
| 17 |
+
.format(DATE_TIME_FORMATTER);
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
public static LocalDateTime toLocalDateTime(Instant instant, ZoneId zoneId) {
|
| 21 |
+
return LocalDateTime.ofInstant(
|
| 22 |
+
instant,
|
| 23 |
+
zoneId);
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
public static Instant toInstant(LocalDateTime localDateTime, ZoneId zoneId) {
|
| 27 |
+
return localDateTime.atZone(zoneId)
|
| 28 |
+
.toInstant();
|
| 29 |
+
}
|
| 30 |
+
}
|
src/main/java/com/attendenceSystem/validator/PasswordMatchValidator.java
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package com.attendenceSystem.validator;
|
| 2 |
+
|
| 3 |
+
import com.attendenceSystem.annotation.PasswordMatch;
|
| 4 |
+
import com.attendenceSystem.user.dto.request.RegisterRequest;
|
| 5 |
+
|
| 6 |
+
import jakarta.validation.ConstraintValidator;
|
| 7 |
+
import jakarta.validation.ConstraintValidatorContext;
|
| 8 |
+
|
| 9 |
+
public class PasswordMatchValidator
|
| 10 |
+
implements ConstraintValidator<PasswordMatch, RegisterRequest> {
|
| 11 |
+
|
| 12 |
+
@Override
|
| 13 |
+
public boolean isValid(RegisterRequest request,
|
| 14 |
+
ConstraintValidatorContext context) {
|
| 15 |
+
|
| 16 |
+
if (request.getPassword() == null
|
| 17 |
+
|| request.getRePassword() == null) {
|
| 18 |
+
return true;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
boolean valid = request.getPassword()
|
| 22 |
+
.equals(request.getRePassword());
|
| 23 |
+
|
| 24 |
+
if (!valid) {
|
| 25 |
+
context.disableDefaultConstraintViolation();
|
| 26 |
+
|
| 27 |
+
context.buildConstraintViolationWithTemplate(
|
| 28 |
+
"Mật khẩu xác nhận không khớp")
|
| 29 |
+
.addPropertyNode("rePassword")
|
| 30 |
+
.addConstraintViolation();
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
return valid;
|
| 34 |
+
}
|
| 35 |
+
}
|
src/main/resources/application.properties
CHANGED
|
@@ -9,4 +9,7 @@ spring.mvc.view.suffix=.jsp
|
|
| 9 |
# spring.thymeleaf.suffix=.html
|
| 10 |
# spring.thymeleaf.cache=false
|
| 11 |
# spring.thymeleaf.encoding=UTF-8
|
| 12 |
-
# spring.thymeleaf.mode=HTML
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
# spring.thymeleaf.suffix=.html
|
| 10 |
# spring.thymeleaf.cache=false
|
| 11 |
# spring.thymeleaf.encoding=UTF-8
|
| 12 |
+
# spring.thymeleaf.mode=HTML
|
| 13 |
+
|
| 14 |
+
#TimeZone Setting
|
| 15 |
+
app.timezone=Asia/Ho_Chi_Minh
|