feat(blog-backend): 后端代码开发中...

This commit is contained in:
2023-03-04 22:50:45 +08:00
parent ac4dda3220
commit 6443f63f6e
30 changed files with 392 additions and 119 deletions

View File

@@ -21,16 +21,36 @@ repositories {
} }
dependencies { dependencies {
// https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.mapstruct:mapstruct:1.5.3.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
// https://mvnrepository.com/artifact/com.github.therapi/therapi-runtime-javadoc
implementation 'com.github.therapi:therapi-runtime-javadoc:0.15.0'
annotationProcessor 'com.github.therapi:therapi-runtime-javadoc:0.15.0'
// https://mvnrepository.com/artifact/org.jetbrains/annotations
compileOnly 'org.jetbrains:annotations:24.0.0'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.session:spring-session-core'
implementation 'org.flywaydb:flyway-core' implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql' implementation 'org.flywaydb:flyway-mysql'
implementation 'org.springframework.session:spring-session-core'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j' runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.security:spring-security-test'
} }

View File

@@ -2,12 +2,13 @@ package cn.hamster3.application.blog;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@EnableJpaAuditing
@SpringBootApplication @SpringBootApplication
public class HamsterBlogApplication { public class HamsterBlogApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(HamsterBlogApplication.class, args); SpringApplication.run(HamsterBlogApplication.class, args);
} }
} }

View File

@@ -1,22 +0,0 @@
package cn.hamster3.application.blog.config;
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class UserIDAuditorAware implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return Optional.empty();
}
User user = (User) authentication.getPrincipal();
return Optional.of(user.getUsername());
}
}

View File

@@ -1,11 +1,34 @@
package cn.hamster3.application.blog.config; package cn.hamster3.application.blog.config;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.Optional;
@Configuration @Configuration
@Slf4j @Slf4j
public class WebConfig implements WebMvcConfigurer { public class WebConfig {
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder(5);
}
@Bean
public AuditorAware<String> getUserIDAuditorAware() {
return () -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return Optional.empty();
}
User user = (User) authentication.getPrincipal();
return Optional.of(user.getUsername());
};
}
} }

View File

@@ -0,0 +1,26 @@
package cn.hamster3.application.blog.config.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Slf4j
@Configuration
@Profile("dev")
public class DevSecurityConfiguration {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
log.info("development environment security settings enabled.");
return http.authorizeHttpRequests(request -> request
.anyRequest().permitAll()
).csrf().disable()
.formLogin()
.and()
.httpBasic()
.and()
.build();
}
}

View File

@@ -0,0 +1,32 @@
package cn.hamster3.application.blog.config.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Slf4j
@Configuration
@Profile("prod")
public class SecurityConfiguration {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
log.info("production environment security settings enabled.");
return http.authorizeHttpRequests(request -> request
.requestMatchers(HttpMethod.GET, "/", "/index", "/index.html").permitAll()
.requestMatchers(HttpMethod.GET, "/favicon.ico", "/assets/**").permitAll()
.requestMatchers(HttpMethod.GET, "/register", "/login").permitAll()
.requestMatchers(HttpMethod.GET, "/swagger-ui/**", "v3/api-docs/**").permitAll()
.requestMatchers(HttpMethod.POST, "/api/v1/user/").anonymous()
.anyRequest().authenticated()
).csrf().disable()
.formLogin()
.and()
.httpBasic()
.and()
.build();
}
}

View File

@@ -1,22 +1,31 @@
package cn.hamster3.application.blog.config.security; package cn.hamster3.application.blog.config.security;
import cn.hamster3.application.blog.dao.UserEntityRepository; import cn.hamster3.application.blog.dao.UserRepository;
import cn.hamster3.application.blog.entity.UserEntity;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.hibernate.Hibernate;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.Collections; @Component
public class UserDetailServiceImpl implements UserDetailsService { public class UserDetailServiceImpl implements UserDetailsService {
@Resource @Resource
private UserEntityRepository userRepo; private UserRepository userRepo;
@Override @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepo.findByEmailOrUsername(username, username) return userRepo.findByEmailOrNicknameAllIgnoreCase(username, username, UserEntity.class)
.map(o -> new User(o.getUsername(), o.getPassword(), Collections.emptyList())) .map(user -> new User(
.orElseThrow(() -> new UsernameNotFoundException("user not found.")); user.getId().toString(),
user.getPassword(),
user.getPermissions()
.stream()
.map(permission -> new SimpleGrantedAuthority(permission.name()))
.toList()
)).orElseThrow(() -> new UsernameNotFoundException("user not found."));
} }
} }

View File

@@ -0,0 +1,5 @@
package cn.hamster3.application.blog.constant;
public enum UserPermission {
}

View File

@@ -0,0 +1,16 @@
package cn.hamster3.application.blog.constant;
public enum UserRole {
/**
* 游客
*/
GUEST,
/**
* 作者
*/
AUTHOR,
/**
* 管理员
*/
ADMINISTRATOR
}

View File

@@ -7,6 +7,6 @@ import org.springframework.web.bind.annotation.RestController;
* 附件相关接口 * 附件相关接口
*/ */
@RestController @RestController
@RequestMapping("/v1/attach") @RequestMapping("/api/v1/attach")
public class AttachController { public class AttachController {
} }

View File

@@ -1,12 +1,21 @@
package cn.hamster3.application.blog.controller; package cn.hamster3.application.blog.controller;
import cn.hamster3.application.blog.entity.BlogEntity;
import cn.hamster3.application.blog.vo.ResponseVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/** /**
* 博文相关接口 * 博文相关接口
*/ */
@RestController @RestController
@RequestMapping("/v1/blog") @RequestMapping("/api/v1/blog")
public class BlogController { public class BlogController {
@GetMapping("/")
public ResponseVO<List<BlogEntity>> getBlogList() {
return null;
}
} }

View File

@@ -1,21 +1,25 @@
package cn.hamster3.application.blog.controller; package cn.hamster3.application.blog.controller;
import cn.hamster3.application.blog.service.IUserService; import cn.hamster3.application.blog.service.IUserService;
import cn.hamster3.application.blog.vo.ResponseVO;
import cn.hamster3.application.blog.vo.user.UserRegisterRequireVO;
import cn.hamster3.application.blog.vo.user.UserRegisterResponseVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
/** /**
* 用户相关接口 * 用户相关接口
*/ */
@RestController @RestController
@RequestMapping("/v1/user") @RequestMapping("/api/v1/user")
public class UserController { public class UserController {
@Resource @Resource
private IUserService userService; private IUserService userService;
@PostMapping("/") @PostMapping("/")
public Object registerUser() { public ResponseVO<UserRegisterResponseVO> registerUser(@RequestBody @Valid UserRegisterRequireVO requireVO) {
return null; return userService.registerUser(requireVO);
} }
@PutMapping("/") @PutMapping("/")
@@ -24,7 +28,12 @@ public class UserController {
} }
@GetMapping("/") @GetMapping("/")
public Object getUserInfo() { public ResponseVO<Void> getAllUserInfo() {
return ResponseVO.success();
}
@GetMapping("/{userID}/")
public Object getUserInfo(@PathVariable String userID) {
return null; return null;
} }
} }

View File

@@ -4,5 +4,5 @@ import cn.hamster3.application.blog.entity.BlogEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface BlogEntityRepository extends JpaRepository<BlogEntity, Long>, JpaSpecificationExecutor<BlogEntity> { public interface BlogRepository extends JpaRepository<BlogEntity, Long>, JpaSpecificationExecutor<BlogEntity> {
} }

View File

@@ -2,6 +2,7 @@ package cn.hamster3.application.blog.entity;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.annotation.LastModifiedDate;
@@ -17,14 +18,15 @@ public class AttachEntity {
@Column(name = "id", nullable = false) @Column(name = "id", nullable = false)
private Long id; private Long id;
@ManyToOne(optional = false) @Setter
@JoinColumn(name = "uploader_id", nullable = false)
private UserEntity uploader;
@Lob @Lob
@Basic(fetch = FetchType.LAZY) @Basic(fetch = FetchType.LAZY)
@Column(name = "data") @Column(name = "data")
private Blob data; private byte[] data;
@ManyToOne(optional = false)
@JoinColumn(name = "uploader_id", nullable = false)
private UserEntity uploader;
@CreatedDate @CreatedDate
@Column(name = "create_time", nullable = false) @Column(name = "create_time", nullable = false)

View File

@@ -0,0 +1,39 @@
package cn.hamster3.application.blog.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import java.sql.Blob;
import java.util.Date;
@Getter
@Setter
@Entity
@Table(name = "blog_attach_entity")
public class BlogAttachEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private Long id;
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(name = "data", nullable = false)
private byte[] data;
@ManyToOne(optional = false)
@JoinColumn(name = "blog_entity_id", nullable = false)
private BlogEntity blogEntity;
@CreatedDate
@Column(name = "create_time", nullable = false)
private Date createTime;
@LastModifiedDate
@Column(name = "update_time", nullable = false)
private Date updateTime;
}

View File

@@ -9,7 +9,7 @@ import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.annotation.LastModifiedDate;
import java.util.Date; import java.util.*;
/** /**
* 博文实体 * 博文实体
@@ -34,8 +34,10 @@ public class BlogEntity {
@Column(name = "content") @Column(name = "content")
private String content; private String content;
@Setter @OneToMany(mappedBy = "blogEntity", orphanRemoval = true)
@CreatedBy @OrderBy("create_time DESC")
private List<BlogAttachEntity> attachEntities = new ArrayList<>();
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = "uploader_id", nullable = false) @JoinColumn(name = "uploader_id", nullable = false)
private UserEntity uploader; private UserEntity uploader;

View File

@@ -1,5 +1,7 @@
package cn.hamster3.application.blog.entity; package cn.hamster3.application.blog.entity;
import cn.hamster3.application.blog.constant.UserPermission;
import cn.hamster3.application.blog.constant.UserRole;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -7,15 +9,15 @@ import lombok.ToString;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.util.Date; import java.util.*;
import java.util.Objects;
import java.util.UUID;
@Getter @Getter
@ToString @ToString
@Entity @Entity
@Table(name = "user_entity") @Table(name = "user_entity")
@EntityListeners(AuditingEntityListener.class)
public class UserEntity { public class UserEntity {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@@ -27,16 +29,34 @@ public class UserEntity {
private String email; private String email;
@Setter @Setter
@Column(name = "username", nullable = false, unique = true, length = 32) @Column(name = "nickname", nullable = false, unique = true, length = 32)
private String username; private String nickname;
@Setter @Setter
@Column(name = "password", nullable = false, length = 32) @Column(name = "password", nullable = false, length = 32)
private String password; private String password;
@ElementCollection
@Column(name = "permission")
@CollectionTable(name = "user_entity_permissions", joinColumns = @JoinColumn(name = "user_id"))
private Set<UserPermission> permissions = new HashSet<>();
@Enumerated
@Column(name = "role", nullable = false)
private UserRole role;
@OneToMany(mappedBy = "uploader", orphanRemoval = true)
@OrderBy("create_time DESC")
private List<AttachEntity> attachEntities = new ArrayList<>();
@OneToMany(mappedBy = "uploader", orphanRemoval = true)
@OrderBy("create_time DESC")
private List<BlogEntity> blogEntities = new ArrayList<>();
@CreatedDate @CreatedDate
@Column(name = "create_time", nullable = false) @Column(name = "create_time", nullable = false)
private Date createTime; private Date createTime;
@LastModifiedDate @LastModifiedDate
@Column(name = "update_time", nullable = false) @Column(name = "update_time", nullable = false)
private Date updateTime; private Date updateTime;

View File

@@ -0,0 +1,18 @@
package cn.hamster3.application.blog.mapper;
import cn.hamster3.application.blog.entity.UserEntity;
import cn.hamster3.application.blog.vo.user.UserRegisterRequireVO;
import cn.hamster3.application.blog.vo.user.UserRegisterResponseVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(componentModel = "spring")
public interface UserMapper {
@Mapping(target = "permissions", ignore = true)
@Mapping(target = "attachEntities", ignore = true)
@Mapping(target = "blogEntities", ignore = true)
UserEntity voToEntity(UserRegisterRequireVO requireVO);
UserRegisterResponseVO entityToVO(UserEntity requireVO);
}

View File

@@ -1,4 +1,10 @@
package cn.hamster3.application.blog.service; package cn.hamster3.application.blog.service;
import cn.hamster3.application.blog.vo.ResponseVO;
import cn.hamster3.application.blog.vo.user.UserRegisterRequireVO;
import cn.hamster3.application.blog.vo.user.UserRegisterResponseVO;
import org.jetbrains.annotations.NotNull;
public interface IUserService { public interface IUserService {
@NotNull ResponseVO<UserRegisterResponseVO> registerUser(@NotNull UserRegisterRequireVO requireVO);
} }

View File

@@ -1,6 +1,12 @@
package cn.hamster3.application.blog.service.impl; package cn.hamster3.application.blog.service.impl;
import cn.hamster3.application.blog.dao.BlogRepository;
import cn.hamster3.application.blog.service.IBlogService; import cn.hamster3.application.blog.service.IBlogService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class BlogService implements IBlogService { public class BlogService implements IBlogService {
@Resource
private BlogRepository blogRepo;
} }

View File

@@ -1,17 +1,42 @@
package cn.hamster3.application.blog.service.impl; package cn.hamster3.application.blog.service.impl;
import cn.hamster3.application.blog.dao.UserEntityRepository; import cn.hamster3.application.blog.dao.UserRepository;
import cn.hamster3.application.blog.entity.UserEntity;
import cn.hamster3.application.blog.mapper.UserMapper;
import cn.hamster3.application.blog.service.IUserService; import cn.hamster3.application.blog.service.IUserService;
import cn.hamster3.application.blog.vo.ResponseVO; import cn.hamster3.application.blog.vo.ResponseVO;
import cn.hamster3.application.blog.vo.user.UserRegisterRequireVO;
import cn.hamster3.application.blog.vo.user.UserRegisterResponseVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class UserService implements IUserService { public class UserService implements IUserService {
@Resource @Resource
private UserEntityRepository userRepo; private PasswordEncoder passwordEncoder;
@Resource
private UserMapper userMapper;
@Resource
private UserRepository userRepo;
public ResponseVO<Void> registerUser() { @Override
return null; public @NotNull ResponseVO<UserRegisterResponseVO> registerUser(@NotNull UserRegisterRequireVO requireVO) {
UserEntity entity = userMapper.voToEntity(requireVO);
entity.setEmail(entity.getEmail().toLowerCase());
if (userRepo.existsByEmailIgnoreCase(entity.getEmail())) {
return ResponseVO.failed("已存在相同邮箱的账户!");
}
if (userRepo.existsByNicknameIgnoreCase(entity.getNickname())) {
return ResponseVO.failed("已存在相同的用户昵称!");
}
entity.setPassword(passwordEncoder.encode(entity.getPassword()));
UserEntity save = userRepo.save(entity);
return ResponseVO.success("注册成功!", userMapper.entityToVO(save));
} }
} }

View File

@@ -1,19 +1,20 @@
package cn.hamster3.application.blog.vo; package cn.hamster3.application.blog.vo;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Data @Data
@AllArgsConstructor
public class ResponseVO<T> { public class ResponseVO<T> {
private int code; @NotNull
private Integer code;
@NotNull
private String msg; private String msg;
@Nullable
private T data; private T data;
private ResponseVO(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static ResponseVO<Void> success() { public static ResponseVO<Void> success() {
return new ResponseVO<>(200, "", null); return new ResponseVO<>(200, "", null);
} }
@@ -30,7 +31,7 @@ public class ResponseVO<T> {
return new ResponseVO<>(200, msg, data); return new ResponseVO<>(200, msg, data);
} }
public static ResponseVO<Void> failed(String msg) { public static <T> ResponseVO<T> failed(String msg) {
return new ResponseVO<>(403, msg, null); return new ResponseVO<>(403, msg, null);
} }

View File

@@ -0,0 +1,17 @@
package cn.hamster3.application.blog.vo.user;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class UserRegisterRequireVO {
@Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", message = "邮箱配置不合法!")
private String email;
@Size(min = 3, max = 16, message = "用户昵称必须包含 3~16 个字符!")
private String nickname;
@Size(min = 8, max = 16, message = "密码必须包含 8~16 个字符!")
private String password;
}

View File

@@ -0,0 +1,20 @@
package cn.hamster3.application.blog.vo.user;
import cn.hamster3.application.blog.constant.UserPermission;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Data
@AllArgsConstructor
public class UserRegisterResponseVO {
private UUID id;
private String email;
private String nickname;
private List<UserPermission> permissions;
private Date createTime;
private Date updateTime;
}

View File

@@ -1,27 +1,16 @@
spring: spring:
# 数据库连接配置 jpa:
datasource: hibernate:
driver-class-name: com.mysql.cj.jdbc.Driver # 自动创建 Entity 类的数据库表
url: jdbc:mysql://sql.hamster3.cn:3306/Test3?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8 ddl-auto: update
username: Test # open-in-view: true
password: Test123.. show-ddl: true
flyway: # show-sql: true
# 是否启用flyway
enabled: true
# 编码格式默认UTF-8
encoding: UTF-8
# 迁移sql脚本文件存放路径默认db/migration
locations: classpath:db/migration
# 迁移sql脚本文件名称的前缀默认V
sql-migration-prefix: V
# 迁移sql脚本文件名称的分隔符默认2个下划线__
sql-migration-separator: __
# 迁移sql脚本文件名称的后缀
sql-migration-suffixes: .sql
# 迁移时是否进行校验默认true
validate-on-migrate: true
# 当迁移发现数据库非空且存在没有元数据的表时自动执行基准迁移新建schema_version表
baseline-on-migrate: true
autoconfigure: autoconfigure:
exclude[0]: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration exclude:
exclude[1]: org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfigurationspring # - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
# - org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfigurationspring
springdoc:
swagger-ui:
enabled: true

View File

@@ -0,0 +1,3 @@
springdoc:
swagger-ui:
enabled: false

View File

@@ -1,25 +0,0 @@
spring:
# 数据库连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://sql.hamster3.cn:3306/Test3?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: Test
password: Test123..
flyway:
# 是否启用flyway
enabled: true
# 编码格式默认UTF-8
encoding: UTF-8
# 迁移sql脚本文件存放路径默认db/migration
locations: classpath:db/migration
# 迁移sql脚本文件名称的前缀默认V
sql-migration-prefix: V
# 迁移sql脚本文件名称的分隔符默认2个下划线__
sql-migration-separator: __
# 迁移sql脚本文件名称的后缀
sql-migration-suffixes: .sql
# 迁移时是否进行校验默认true
validate-on-migrate: true
# 当迁移发现数据库非空且存在没有元数据的表时自动执行基准迁移新建schema_version表
baseline-on-migrate: true

View File

@@ -1,4 +1,10 @@
spring: spring:
# 要使用的环境预设
# prod: 生产环境
# dev: 开发环境
# test: 测试环境
profiles:
active: prod
# 数据库连接配置 # 数据库连接配置
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver

View File

@@ -0,0 +1,8 @@
__ __ ___ .___ ___. _______.___________. _______ .______ .______ __ ______ _______ _______ ___________ ____
| | | | / \ | \/ | / | || ____|| _ \ | _ \ | | / __ \ / _____| | \ | ____\ \ / /
| |__| | / ^ \ | \ / | | (----`---| |----`| |__ | |_) | | |_) | | | | | | | | | __ ______ | .--. || |__ \ \/ /
| __ | / /_\ \ | |\/| | \ \ | | | __| | / | _ < | | | | | | | | |_ | |______| | | | || __| \ /
| | | | / _____ \ | | | | .----) | | | | |____ | |\ \----.| |_) | | `----.| `--' | | |__| | | '--' || |____ \ /
|__| |__| /__/ \__\ |__| |__| |_______/ |__| |_______|| _| `._____||______/ |_______| \______/ \______| |_______/ |_______| \__/

View File

@@ -0,0 +1,8 @@
__ __ ___ .___ ___. _______.___________. _______ .______ .______ __ ______ _______
| | | | / \ | \/ | / | || ____|| _ \ | _ \ | | / __ \ / _____|
| |__| | / ^ \ | \ / | | (----`---| |----`| |__ | |_) | ______ | |_) | | | | | | | | | __
| __ | / /_\ \ | |\/| | \ \ | | | __| | / |______| | _ < | | | | | | | | |_ |
| | | | / _____ \ | | | | .----) | | | | |____ | |\ \----. | |_) | | `----.| `--' | | |__| |
|__| |__| /__/ \__\ |__| |__| |_______/ |__| |_______|| _| `._____| |______/ |_______| \______/ \______|