diff --git a/README.md b/README.md index d0d880b..5fc1c9d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Схема базы данных https://www.drawdb.app/editor?shareId=92ab675631181485a028270c35276710 -[Архитектура базы данных](static/bd.png) +[Архитектура базы данных](docs/static/bd.png) ## 📖 Предыстория diff --git a/docs/static/bd.png b/docs/static/bd.png new file mode 100644 index 0000000..8f611e8 Binary files /dev/null and b/docs/static/bd.png differ diff --git a/images/profile--1.jpg b/images/profile--1.jpg new file mode 100644 index 0000000..1eb8cec Binary files /dev/null and b/images/profile--1.jpg differ diff --git a/images/profile--10.jpg b/images/profile--10.jpg new file mode 100644 index 0000000..0a82304 Binary files /dev/null and b/images/profile--10.jpg differ diff --git a/images/profile--11.jpg b/images/profile--11.jpg new file mode 100644 index 0000000..12f6884 Binary files /dev/null and b/images/profile--11.jpg differ diff --git a/images/profile--12.jpg b/images/profile--12.jpg new file mode 100644 index 0000000..cc409d6 Binary files /dev/null and b/images/profile--12.jpg differ diff --git a/images/profile--13.jpg b/images/profile--13.jpg new file mode 100644 index 0000000..f7be936 Binary files /dev/null and b/images/profile--13.jpg differ diff --git a/images/profile--14.jpg b/images/profile--14.jpg new file mode 100644 index 0000000..e2864e2 Binary files /dev/null and b/images/profile--14.jpg differ diff --git a/images/profile--15.jpg b/images/profile--15.jpg new file mode 100644 index 0000000..9d5d79f Binary files /dev/null and b/images/profile--15.jpg differ diff --git a/images/profile--16.jpg b/images/profile--16.jpg new file mode 100644 index 0000000..e040697 Binary files /dev/null and b/images/profile--16.jpg differ diff --git a/images/profile--17.jpg b/images/profile--17.jpg new file mode 100644 index 0000000..9543c34 Binary files /dev/null and b/images/profile--17.jpg differ diff --git a/images/profile--18.jpg b/images/profile--18.jpg new file mode 100644 index 0000000..07b6a60 Binary files /dev/null and b/images/profile--18.jpg differ diff --git a/images/profile--19.jpg b/images/profile--19.jpg new file mode 100644 index 0000000..691e8c8 Binary files /dev/null and b/images/profile--19.jpg differ diff --git a/images/profile--2.jpg b/images/profile--2.jpg new file mode 100644 index 0000000..d64a583 Binary files /dev/null and b/images/profile--2.jpg differ diff --git a/images/profile--20.jpg b/images/profile--20.jpg new file mode 100644 index 0000000..88dd854 Binary files /dev/null and b/images/profile--20.jpg differ diff --git a/images/profile--21.jpg b/images/profile--21.jpg new file mode 100644 index 0000000..b7ae48b Binary files /dev/null and b/images/profile--21.jpg differ diff --git a/images/profile--22.jpg b/images/profile--22.jpg new file mode 100644 index 0000000..48702e3 Binary files /dev/null and b/images/profile--22.jpg differ diff --git a/images/profile--23.jpg b/images/profile--23.jpg new file mode 100644 index 0000000..e58964f Binary files /dev/null and b/images/profile--23.jpg differ diff --git a/images/profile--24.jpg b/images/profile--24.jpg new file mode 100644 index 0000000..d495869 Binary files /dev/null and b/images/profile--24.jpg differ diff --git a/images/profile--25.jpg b/images/profile--25.jpg new file mode 100644 index 0000000..a26051f Binary files /dev/null and b/images/profile--25.jpg differ diff --git a/images/profile--26.jpg b/images/profile--26.jpg new file mode 100644 index 0000000..c9816f8 Binary files /dev/null and b/images/profile--26.jpg differ diff --git a/images/profile--3.jpg b/images/profile--3.jpg new file mode 100644 index 0000000..27435b3 Binary files /dev/null and b/images/profile--3.jpg differ diff --git a/images/profile--4.jpg b/images/profile--4.jpg new file mode 100644 index 0000000..a2e0224 Binary files /dev/null and b/images/profile--4.jpg differ diff --git a/images/profile--5.jpg b/images/profile--5.jpg new file mode 100644 index 0000000..9f1fa1f Binary files /dev/null and b/images/profile--5.jpg differ diff --git a/images/profile--6.jpg b/images/profile--6.jpg new file mode 100644 index 0000000..4ba8b1e Binary files /dev/null and b/images/profile--6.jpg differ diff --git a/images/profile--7.jpg b/images/profile--7.jpg new file mode 100644 index 0000000..68ab88a Binary files /dev/null and b/images/profile--7.jpg differ diff --git a/images/profile--8.jpg b/images/profile--8.jpg new file mode 100644 index 0000000..4a50826 Binary files /dev/null and b/images/profile--8.jpg differ diff --git a/images/profile--9.jpg b/images/profile--9.jpg new file mode 100644 index 0000000..385e7ad Binary files /dev/null and b/images/profile--9.jpg differ diff --git a/pom.xml b/pom.xml index da3dbeb..f3ce82f 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.0 + 2.7.10 diff --git a/src/main/java/com/example/nto/config/ObjectStorageConfig.java b/src/main/java/com/example/nto/config/ObjectStorageConfig.java new file mode 100644 index 0000000..c37b694 --- /dev/null +++ b/src/main/java/com/example/nto/config/ObjectStorageConfig.java @@ -0,0 +1,42 @@ +package com.example.nto.config; + +import com.amazonaws.SdkClientException; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Slf4j +@Getter +@Configuration +public class ObjectStorageConfig { + @Value("${yandex.cloud.region}") + private String region; + @Value("${yandex.cloud.s3_endpoint}") + private String s3Endpoint; + + @Value("${yandex.cloud.bucket}") + private String bucketName; + @Value("${yandex.cloud.key_id}") + private String accessKeyId; + @Value("${yandex.cloud.secret_key}") + private String secretAccessKey; + + + public AmazonS3 createAmazonS3() { + // Создание клиента AmazonS3 с подключением к Object Storage + try { + return AmazonS3ClientBuilder.standard() + .withEndpointConfiguration(new com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration(s3Endpoint, region)) + .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKeyId, secretAccessKey))) + .build(); + } catch (SdkClientException e) { + log.error("Ошибка при создании клиента для хранения объектов с помощью AWS SDK. Причина: {}", e.getMessage()); + throw new SdkClientException(e.getMessage()); + } + } +} diff --git a/src/main/java/com/example/nto/config/SwaggerConfig.java b/src/main/java/com/example/nto/config/SwaggerConfig.java new file mode 100644 index 0000000..de997f4 --- /dev/null +++ b/src/main/java/com/example/nto/config/SwaggerConfig.java @@ -0,0 +1,20 @@ +package com.example.nto.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +@Configuration +public class SwaggerConfig { + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("com.example.preparation")) + .paths(PathSelectors.any()) + .build(); + } +} diff --git a/src/main/java/com/example/nto/config/WebSecurityConfig.java b/src/main/java/com/example/nto/config/WebSecurityConfig.java new file mode 100644 index 0000000..350422c --- /dev/null +++ b/src/main/java/com/example/nto/config/WebSecurityConfig.java @@ -0,0 +1,53 @@ +package com.example.nto.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + private final UserDetailsService userDetailsService; + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable() + .authorizeRequests() + .antMatchers("/h2-console/**").permitAll() + .antMatchers("/api/v1/images/**").permitAll() + .antMatchers("/api/v1/volunteers/login").permitAll() + .antMatchers("/api/v1/volunteers/register").permitAll() + + .antMatchers("/api/v1/**").permitAll() + //.antMatchers("/api/v1/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN") + .anyRequest().authenticated() + .and() + .httpBasic() + .and() + .headers().frameOptions().disable(); + } + + @Override + public void configure(WebSecurity web) { + web.ignoring().antMatchers("/api/v1/volunteers/images"); + } +} diff --git a/src/main/java/com/example/nto/domain/entity/Employee.java b/src/main/java/com/example/nto/domain/entity/Employee.java index f667855..33b0482 100644 --- a/src/main/java/com/example/nto/domain/entity/Employee.java +++ b/src/main/java/com/example/nto/domain/entity/Employee.java @@ -1,9 +1,6 @@ package com.example.nto.domain.entity; -import jakarta.persistence.*; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,8 +9,11 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -62,9 +62,9 @@ public class Employee implements UserDetails { @Size(max = 300, message = "Максимальная длина пароля 300 символов!") private String password; - // @ManyToOne(fetch = FetchType.EAGER) - // @JoinColumn(name = "office_id", referencedColumnName = "id", nullable = false) - // private Office office; + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "office_id", referencedColumnName = "id", nullable = false) + private Office office; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "pos_id", referencedColumnName = "id", nullable = false) @@ -78,12 +78,15 @@ public class Employee implements UserDetails { @Size(max = 300, message = "Максимальная длина адреса изображения 300 символов!") private String profileImageUrl; + @Column(name = "is_blocked") + private boolean isBlocked; + @CreatedDate @Column(name = "created_at", columnDefinition = "TIMESTAMP", nullable = false) private LocalDateTime createdAt; - // @OneToMany(mappedBy = "employee") - // private List visits = new ArrayList<>(); + @OneToMany(mappedBy = "employee") + private List visits; @Override public Collection getAuthorities() { @@ -92,7 +95,7 @@ public class Employee implements UserDetails { @Override public String getPassword() { - return ""; + return this.password; } @Override diff --git a/src/main/java/com/example/nto/domain/entity/Office.java b/src/main/java/com/example/nto/domain/entity/Office.java index cee9e88..5f3aa55 100644 --- a/src/main/java/com/example/nto/domain/entity/Office.java +++ b/src/main/java/com/example/nto/domain/entity/Office.java @@ -1,15 +1,16 @@ package com.example.nto.domain.entity; -import jakarta.persistence.*; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.util.List; @Data diff --git a/src/main/java/com/example/nto/domain/entity/Passage.java b/src/main/java/com/example/nto/domain/entity/Passage.java new file mode 100644 index 0000000..c6b14d0 --- /dev/null +++ b/src/main/java/com/example/nto/domain/entity/Passage.java @@ -0,0 +1,32 @@ +package com.example.nto.domain.entity; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.List; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "passages") +public class Passage { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "passage", unique = true) + @NotBlank(message = "Название не может быть пустым!") + @Size(max = 100, message = "Максимальная длина названия 100 символов!") + private String passage; + + @OneToMany(mappedBy = "passage") + private List visits; +} diff --git a/src/main/java/com/example/nto/domain/entity/Position.java b/src/main/java/com/example/nto/domain/entity/Position.java index 61d900e..d934618 100644 --- a/src/main/java/com/example/nto/domain/entity/Position.java +++ b/src/main/java/com/example/nto/domain/entity/Position.java @@ -1,13 +1,14 @@ package com.example.nto.domain.entity; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; import java.util.List; @Data diff --git a/src/main/java/com/example/nto/domain/entity/Role.java b/src/main/java/com/example/nto/domain/entity/Role.java index 73c2b81..4046177 100644 --- a/src/main/java/com/example/nto/domain/entity/Role.java +++ b/src/main/java/com/example/nto/domain/entity/Role.java @@ -1,14 +1,15 @@ package com.example.nto.domain.entity; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.security.core.GrantedAuthority; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; import java.util.List; @Data diff --git a/src/main/java/com/example/nto/domain/entity/Terminal.java b/src/main/java/com/example/nto/domain/entity/Terminal.java index d1ff6aa..c8d1639 100644 --- a/src/main/java/com/example/nto/domain/entity/Terminal.java +++ b/src/main/java/com/example/nto/domain/entity/Terminal.java @@ -1,14 +1,15 @@ package com.example.nto.domain.entity; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.hibernate.annotations.UuidGenerator; +import org.hibernate.annotations.GenericGenerator; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; import java.util.List; @Data @@ -29,8 +30,9 @@ public class Terminal { // Мне нужна была рандомная генерация кода для терминала, так что я мог сделать кривую реализацию через самописную функцию, // но боялся, что она будет генерировать не уникальные значения. (я очень смутно представляю, как эта штука работает) - // Код взят отсюда: https://stackoverflow.com/questions/76723290/using-the-new-type-for-uuidgenerator-instead-of-strategy - @UuidGenerator + // Код взят отсюда: https://stackoverflow.com/questions/25082244/auto-generate-unique-random-string-in-spring-mvc-hibernate + @GenericGenerator(name = "uuid-gen", strategy = "uuid") + @GeneratedValue(generator = "uuid-gen") @NotBlank(message = "Код не может быть пустым!") @Column(name = "code", nullable = false, unique = true) private String code; diff --git a/src/main/java/com/example/nto/domain/entity/Visit.java b/src/main/java/com/example/nto/domain/entity/Visit.java index 58d2f3b..7b30d9f 100644 --- a/src/main/java/com/example/nto/domain/entity/Visit.java +++ b/src/main/java/com/example/nto/domain/entity/Visit.java @@ -1,11 +1,11 @@ package com.example.nto.domain.entity; -import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import javax.persistence.*; import java.time.LocalDateTime; @Data @@ -30,7 +30,7 @@ public class Visit { private LocalDateTime endVisit; @Column(name = "is_finished", nullable = false) - private boolean isFinished = false; + private final boolean isFinished = false; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "start_terminal_id", referencedColumnName = "code", nullable = false) @@ -39,5 +39,9 @@ public class Visit { @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "end_terminal_id", referencedColumnName = "code") private Terminal endTerminal; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "type_passage", referencedColumnName = "id", nullable = false) + private Passage passage; } diff --git a/src/main/java/com/example/nto/dto/entity/OfficeDTO.java b/src/main/java/com/example/nto/dto/entity/OfficeDTO.java index 9bf6ae6..a1dc490 100644 --- a/src/main/java/com/example/nto/dto/entity/OfficeDTO.java +++ b/src/main/java/com/example/nto/dto/entity/OfficeDTO.java @@ -1,14 +1,29 @@ package com.example.nto.dto.entity; +import com.example.nto.dto.entity.employee.EmployeeItemDTO; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; + @Data @Builder @NoArgsConstructor @AllArgsConstructor public class OfficeDTO { + private long id; + private String name; + private String description; + private String address; + private Double latitude; + private Double longitude; + private String linkLogo; + private String telephone; + private String email; + + private List employees; + private List terminals; } diff --git a/src/main/java/com/example/nto/dto/entity/employee/EmployeeCreateDTO.java b/src/main/java/com/example/nto/dto/entity/employee/EmployeeCreateDTO.java index f196024..06de761 100644 --- a/src/main/java/com/example/nto/dto/entity/employee/EmployeeCreateDTO.java +++ b/src/main/java/com/example/nto/dto/entity/employee/EmployeeCreateDTO.java @@ -10,4 +10,17 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class EmployeeCreateDTO { -} + private String name; + private String surname; + private String patronymic; + private String telephone; + private String email; + private String password; + private boolean isBlocked; + + private String officeName; // Имя офиса, к которому присоединится работник. + private String positionName; // Должность работника. + private String role; // строка либо ROLE_USER, либо ROLE_ADMIN + + // Изображение профиля выберется рандомно из заготовок. +} \ No newline at end of file diff --git a/src/main/java/com/example/nto/dto/entity/employee/EmployeeDTO.java b/src/main/java/com/example/nto/dto/entity/employee/EmployeeDTO.java index 450d94b..ac9698f 100644 --- a/src/main/java/com/example/nto/dto/entity/employee/EmployeeDTO.java +++ b/src/main/java/com/example/nto/dto/entity/employee/EmployeeDTO.java @@ -27,6 +27,7 @@ public class EmployeeDTO { private String role; // строка либо ROLE_USER, либо ROLE_ADMIN private String profileImageUrl; + private boolean isBlocked; // Текущее состояние входа: false - visit (посещение) ещё не началось, true - visit идёт private boolean visitStatus; diff --git a/src/main/java/com/example/nto/dto/entity/employee/EmployeeItemDTO.java b/src/main/java/com/example/nto/dto/entity/employee/EmployeeItemDTO.java index 50a72cc..5b9518f 100644 --- a/src/main/java/com/example/nto/dto/entity/employee/EmployeeItemDTO.java +++ b/src/main/java/com/example/nto/dto/entity/employee/EmployeeItemDTO.java @@ -11,4 +11,16 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class EmployeeItemDTO { + private long id; + private String name; + private String surname; + private String patronymic; + private String profileImageUrl; + private boolean isBlocked; + + private String officeName; + private String position; // Название должности + + // Текущее состояние входа: false - visit (посещение) ещё не началось, true - visit идёт + private boolean visitStatus; } diff --git a/src/main/java/com/example/nto/dto/mappers/employee/EmployeeCreateMapper.java b/src/main/java/com/example/nto/dto/mappers/employee/EmployeeCreateMapper.java index 408eae4..4a2098d 100644 --- a/src/main/java/com/example/nto/dto/mappers/employee/EmployeeCreateMapper.java +++ b/src/main/java/com/example/nto/dto/mappers/employee/EmployeeCreateMapper.java @@ -1,4 +1,32 @@ package com.example.nto.dto.mappers.employee; + import com.example.nto.domain.entity.Employee; +import com.example.nto.domain.entity.Office; +import com.example.nto.domain.entity.Position; +import com.example.nto.domain.entity.Role; +import com.example.nto.dto.entity.employee.EmployeeCreateDTO; +import com.example.nto.utils.Utils; +import lombok.experimental.UtilityClass; + +@UtilityClass public class EmployeeCreateMapper { + public static Employee convertFromDTO( + EmployeeCreateDTO employeeDTO, String password, Office office, + Position position, Role role + ) { + Employee employee = new Employee(); + + employee.setName(employeeDTO.getName()); + employee.setSurname(employeeDTO.getSurname()); + employee.setPatronymic(employeeDTO.getPatronymic()); + employee.setTelephone(employeeDTO.getTelephone()); + employee.setEmail(employeeDTO.getEmail()); + employee.setPassword(password); + employee.setOffice(office); + employee.setPosition(position); + employee.setRole(role); + employee.setProfileImageUrl(Utils.getRandomUrlProfileImage()); + + return employee; + } } diff --git a/src/main/java/com/example/nto/service/impl/UserDetailsServiceImpl.java b/src/main/java/com/example/nto/service/impl/UserDetailsServiceImpl.java new file mode 100644 index 0000000..cf8cdb3 --- /dev/null +++ b/src/main/java/com/example/nto/service/impl/UserDetailsServiceImpl.java @@ -0,0 +1,14 @@ +package com.example.nto.service.impl; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +public class UserDetailsServiceImpl implements UserDetailsService { + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return null; + } +} diff --git a/src/main/java/com/example/nto/utils/Utils.java b/src/main/java/com/example/nto/utils/Utils.java index b8bf742..58ec198 100644 --- a/src/main/java/com/example/nto/utils/Utils.java +++ b/src/main/java/com/example/nto/utils/Utils.java @@ -1,5 +1,7 @@ package com.example.nto.utils; +import com.example.nto.config.ObjectStorageConfig; +import com.example.nto.domain.entity.Visit; import lombok.experimental.UtilityClass; import java.time.*; @@ -7,6 +9,7 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.Random; import java.util.UUID; @UtilityClass @@ -15,6 +18,8 @@ public class Utils { private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss"); + private static final ObjectStorageConfig storageConfig = new ObjectStorageConfig(); + public static String profileFileName(long userId) { return "profile--" + userId; } @@ -25,12 +30,17 @@ public class Utils { public static String nowTime(DataFormatType type) { switch (type) { - case DATE_TIME: return LocalDateTime.now().format(DATE_TIME_FORMAT); - case DATE: return LocalDateTime.now().format(DATE_FORMAT); - case TIME: return LocalDateTime.now().format(TIME_FORMAT); - default: return "Произошла ошибка при форматировании даты или времени."; + case DATE_TIME: + return LocalDateTime.now().format(DATE_TIME_FORMAT); + case DATE: + return LocalDateTime.now().format(DATE_FORMAT); + case TIME: + return LocalDateTime.now().format(TIME_FORMAT); + default: + return "Произошла ошибка при форматировании даты или времени."; } } + public static LocalDateTime period(LocalDateTime dtStart, LocalDateTime dtEnd) { // Возвращает разницу между двумя LocalDateTime Period period = Period.between(dtStart.toLocalDate(), dtEnd.toLocalDate()); @@ -52,6 +62,23 @@ public class Utils { return hours; } + public static List filterDateLast30Days(List visits) { + final LocalDateTime referenceDate = LocalDateTime.now(); + List result = new ArrayList<>(); + + for (Visit visit : visits) { + long daysBetween = ChronoUnit.DAYS.between(visit.getStartVisit(), referenceDate); + if (daysBetween >= 0 && daysBetween <= 30) result.add(visit); + } + return result; + } + + public static String getRandomUrlProfileImage() { + int max = 26, min = 1; + String fileName = profileFileName(new Random().nextInt(max - min + 1) + min) + ".jpg"; + return storageConfig.getS3Endpoint() + "/" + storageConfig.getBucketName() + "/standard/" + fileName; + } + public static String convertDistance(float distance) { if (distance > 1000) return String.format("%.1f", distance / 1000) + " км"; else return String.format("%.1f", distance) + " м"; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..05a1f51 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,7 @@ +spring.servlet.multipart.max-file-size=10MB +spring.servlet.multipart.max-request-size=10MB +yandex.cloud.region=ru-central1 +yandex.cloud.s3_endpoint=https://storage.yandexcloud.net +yandex.cloud.key_id=YCAJEIOy-pmwxonO9XLqdhAVI +yandex.cloud.secret_key=YCNJMJf9VGP9OmFiPs5XbnfKzzarBl1B1ymGz1uu +yandex.cloud.bucket=spring-boot-final-nto-bacet \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c6bfd72..0e48c65 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,28 +1,25 @@ +server: + port: 8080 + spring: + servlet: + multipart: + max-file-size: ${MAX_FILE_SIZE:8MB} + max-request-size: ${MAX_REQUEST_SIZE:8MB} datasource: - url: jdbc:h2:mem:testdb + url: jdbc:h2:mem:database h2: console: - #enabled: false enabled: true + liquibase: + enabled: true + change-log: classpath:db.changelog/db.changelog-master.xml + jpa: - #generate-ddl: false - generate-ddl: true - + generate-ddl: false hibernate: - #ddl-auto: none - ddl-auto: create-drop - - # Показываем запросы - show-sql: true - - # Своевременный запуск data.sql - defer-datasource-initialization: true - - spring-doc: - swagger-ui: - path: /swagger-ui.html - operationsSorter: method \ No newline at end of file + ddl-auto: none + show-sql: true \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql deleted file mode 100644 index 03720a9..0000000 --- a/src/main/resources/data.sql +++ /dev/null @@ -1,14 +0,0 @@ -INSERT INTO employee (id, login, name, photo, position, last_visit) -VALUES -(1, 'pivanov', 'Иванов Петр Федорович', 'https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg', 'Разработчик', '2024-02-12T08:30'), -(2, 'ipetrov', 'Петров Иван Константинович', 'https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg', 'Аналитик', '2024-02-13T08:35'), -(3, 'asemenov', 'Семенов Анатолий Анатольевич', 'https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg', 'Разработчик', '2024-02-13T08:31'), -(4, 'afedorov', 'Федоров Александр Сергеевич', 'https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg', 'Тестировщик', '2024-02-12T08:36'); - -INSERT INTO code (value) -VALUES -(1234567890123456789), -(9223372036854775807), -(1122334455667788990), -(998877665544332211), -(5566778899001122334); \ No newline at end of file diff --git a/src/main/resources/db.changelog/db.changelog-master.xml b/src/main/resources/db.changelog/db.changelog-master.xml new file mode 100644 index 0000000..ece04a5 --- /dev/null +++ b/src/main/resources/db.changelog/db.changelog-master.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/static/bd.png b/static/bd.png deleted file mode 100644 index ac5384f..0000000 Binary files a/static/bd.png and /dev/null differ