增加可默认的createtime排序

This commit is contained in:
dengqichen 2024-11-26 14:51:21 +08:00
parent 4b6239c944
commit 41d384f626
31 changed files with 202 additions and 122 deletions

View File

@ -1,7 +1,7 @@
package com.qqchen.deploy.backend.api;
import com.qqchen.deploy.common.controller.BaseController;
import com.qqchen.deploy.common.dto.Response;
import com.qqchen.deploy.backend.common.controller.BaseController;
import com.qqchen.deploy.backend.common.dto.Response;
import com.qqchen.deploy.backend.converter.UserConverter;
import com.qqchen.deploy.backend.entity.User;
import com.qqchen.deploy.backend.dto.query.UserQuery;
@ -9,7 +9,9 @@ import com.qqchen.deploy.backend.dto.request.UserRequest;
import com.qqchen.deploy.backend.dto.response.UserResponse;
import com.qqchen.deploy.backend.dto.request.UserRegisterRequest;
import com.qqchen.deploy.backend.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -38,6 +40,9 @@ public class UserApiController extends BaseController<User, Long, UserQuery, Use
return Response.success(converter.toVO(savedUser));
}
// 其他对外API...
// 可以覆盖父类的方法添加更严格的访问控制或参数校验
@GetMapping("/page")
public Response<Page<UserResponse>> page(UserQuery query) {
return super.page(query);
}
}

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.common.annotation;
package com.qqchen.deploy.backend.common.annotation;
import com.qqchen.deploy.common.enums.QueryType;
import com.qqchen.deploy.backend.common.enums.QueryType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.config;
package com.qqchen.deploy.backend.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -0,0 +1,72 @@
package com.qqchen.deploy.backend.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable()) // 禁用CSRF
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 禁用session
.formLogin(form -> form.disable()) // 禁用form登录
.httpBasic(basic -> basic.disable()) // 禁用basic认证
.logout(logout -> logout.disable()) // 禁用logout
.anonymous(anonymous -> {}) // 允许匿名访问
.authorizeHttpRequests(auth -> auth
// 公开接口
// .requestMatchers("/api/v1/users/register").permitAll()
// .requestMatchers("/api/v1/users/login").permitAll()
// // Swagger相关接口
// .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
// // 健康检查接口
// .requestMatchers("/actuator/**").permitAll()
// 开发阶段可以暂时允许所有请求
.anyRequest().permitAll()
// 生产环境建议改为需要认证
//.anyRequest().authenticated()
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withUsername("anonymous")
.password("{noop}")
.roles("ANONYMOUS")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}

View File

@ -0,0 +1,18 @@
package com.qqchen.deploy.backend.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // 允许所有来源
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法
.allowedHeaders("*") // 允许所有header
.maxAge(3600); // 预检请求的有效期单位为秒
}
}

View File

@ -1,11 +1,11 @@
package com.qqchen.deploy.common.controller;
package com.qqchen.deploy.backend.common.controller;
import com.qqchen.deploy.common.converter.BaseConverter;
import com.qqchen.deploy.common.domain.Entity;
import com.qqchen.deploy.common.query.BaseQuery;
import com.qqchen.deploy.common.dto.BaseRequest;
import com.qqchen.deploy.common.dto.Response;
import com.qqchen.deploy.common.service.BaseService;
import com.qqchen.deploy.backend.common.domain.Entity;
import com.qqchen.deploy.backend.common.converter.BaseConverter;
import com.qqchen.deploy.backend.common.query.BaseQuery;
import com.qqchen.deploy.backend.common.dto.BaseRequest;
import com.qqchen.deploy.backend.common.dto.Response;
import com.qqchen.deploy.backend.common.service.BaseService;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

View File

@ -1,7 +1,7 @@
package com.qqchen.deploy.common.converter;
package com.qqchen.deploy.backend.common.converter;
import com.qqchen.deploy.common.domain.Entity;
import com.qqchen.deploy.common.dto.BaseRequest;
import com.qqchen.deploy.backend.common.domain.Entity;
import com.qqchen.deploy.backend.common.dto.BaseRequest;
import org.mapstruct.MappingTarget;
import org.springframework.data.domain.Page;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.domain;
package com.qqchen.deploy.backend.common.domain;
import java.io.Serializable;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.domain;
package com.qqchen.deploy.backend.common.domain;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.dto;
package com.qqchen.deploy.backend.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.dto;
package com.qqchen.deploy.backend.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.dto;
package com.qqchen.deploy.backend.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.enums;
package com.qqchen.deploy.backend.common.enums;
public enum QueryType {
EQUAL, // 等于

View File

@ -1,13 +1,11 @@
package com.qqchen.deploy.common.query;
package com.qqchen.deploy.backend.common.query;
import com.qqchen.deploy.common.annotation.QueryField;
import com.qqchen.deploy.common.enums.QueryType;
import com.qqchen.deploy.common.query.DateRange;
import com.qqchen.deploy.backend.common.annotation.QueryField;
import com.qqchen.deploy.backend.common.enums.QueryType;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
@Data
public abstract class BaseQuery implements Serializable {
@ -15,9 +13,9 @@ public abstract class BaseQuery implements Serializable {
private Integer pageSize = 10;
private String sortField;
private String sortField = "createTime";
private String sortOrder;
private String sortOrder = "desc";
// 通用状态查询
@QueryField(field = "enabled")

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.query;
package com.qqchen.deploy.backend.common.query;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.qqchen.deploy.common.query;
package com.qqchen.deploy.backend.common.query;
import lombok.Data;

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.common.repository;
package com.qqchen.deploy.backend.common.repository;
import com.qqchen.deploy.common.domain.Entity;
import com.qqchen.deploy.backend.common.domain.Entity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;

View File

@ -1,7 +1,7 @@
package com.qqchen.deploy.common.service;
package com.qqchen.deploy.backend.common.service;
import com.qqchen.deploy.common.domain.Entity;
import com.qqchen.deploy.common.query.BaseQuery;
import com.qqchen.deploy.backend.common.domain.Entity;
import com.qqchen.deploy.backend.common.query.BaseQuery;
import org.springframework.data.domain.Page;
import java.io.Serializable;

View File

@ -1,20 +1,18 @@
package com.qqchen.deploy.common.service.impl;
package com.qqchen.deploy.backend.common.service.impl;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.stream.Collectors;
import java.util.Collection;
import java.util.List;
import com.qqchen.deploy.common.annotation.QueryField;
import com.qqchen.deploy.common.domain.Entity;
import com.qqchen.deploy.common.query.BaseQuery;
import com.qqchen.deploy.common.enums.QueryType;
import com.qqchen.deploy.common.query.DateRange;
import com.qqchen.deploy.common.query.Range;
import com.qqchen.deploy.common.repository.BaseRepository;
import com.qqchen.deploy.common.service.BaseService;
import com.qqchen.deploy.backend.common.domain.Entity;
import com.qqchen.deploy.backend.common.enums.QueryType;
import com.qqchen.deploy.backend.common.query.BaseQuery;
import com.qqchen.deploy.backend.common.query.DateRange;
import com.qqchen.deploy.backend.common.query.Range;
import com.qqchen.deploy.backend.common.repository.BaseRepository;
import com.qqchen.deploy.backend.common.annotation.QueryField;
import com.qqchen.deploy.backend.common.service.BaseService;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.EntityPath;
import com.querydsl.core.types.Path;
@ -273,19 +271,22 @@ public abstract class BaseServiceImpl<T extends Entity<ID>, ID extends Serializa
}
protected PageRequest createPageRequest(BaseQuery query) {
if (query == null) {
// 如果query为null使用默认值
return PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "createTime"));
}
Sort sort = StringUtils.hasText(query.getSortField()) ?
Sort.by(Sort.Direction.fromString(query.getSortOrder()), query.getSortField()) :
Sort.by(Sort.Direction.DESC, "createTime");
return PageRequest.of(
query.getPageNum() - 1,
query.getPageSize(),
createSort(query)
sort
);
}
protected Sort createSort(BaseQuery query) {
return StringUtils.hasText(query.getSortField()) ?
Sort.by(Sort.Direction.fromString(query.getSortOrder()), query.getSortField()) :
Sort.unsorted();
}
private Number parseNumber(Object value, Class<?> targetType) {
if (value == null) return null;
try {
@ -319,4 +320,5 @@ public abstract class BaseServiceImpl<T extends Entity<ID>, ID extends Serializa
}
}
}
}

View File

@ -1,7 +1,7 @@
package com.qqchen.deploy.backend.controller;
import com.qqchen.deploy.backend.api.UserApiController;
import com.qqchen.deploy.common.dto.Response;
import com.qqchen.deploy.backend.common.dto.Response;
import com.qqchen.deploy.backend.converter.UserConverter;
import com.qqchen.deploy.backend.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.converter;
import com.qqchen.deploy.common.converter.BaseConverter;
import com.qqchen.deploy.backend.common.converter.BaseConverter;
import com.qqchen.deploy.backend.entity.User;
import com.qqchen.deploy.backend.dto.request.UserRequest;
import com.qqchen.deploy.backend.dto.response.UserResponse;

View File

@ -1,7 +1,7 @@
package com.qqchen.deploy.backend.dto.query;
import com.qqchen.deploy.common.annotation.QueryField;
import com.qqchen.deploy.common.enums.QueryType;
import com.qqchen.deploy.backend.common.annotation.QueryField;
import com.qqchen.deploy.backend.common.enums.QueryType;
import lombok.Data;
@Data

View File

@ -1,30 +1,41 @@
package com.qqchen.deploy.backend.dto.query;
import com.qqchen.deploy.common.annotation.QueryField;
import com.qqchen.deploy.common.query.BaseQuery;
import com.qqchen.deploy.common.enums.QueryType;
import com.qqchen.deploy.common.query.DateRange;
import com.qqchen.deploy.backend.common.annotation.QueryField;
import com.qqchen.deploy.backend.common.query.BaseQuery;
import com.qqchen.deploy.backend.common.enums.QueryType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class UserQuery extends BaseQuery {
@QueryField(type = QueryType.LIKE)
private String username;
@QueryField(type = QueryType.LIKE)
private String email;
@QueryField(type = QueryType.IN)
private List<String> roles;
@QueryField(type = QueryType.LIKE)
private String nickname;
@QueryField(type = QueryType.BETWEEN)
private DateRange createTimeRange;
@QueryField(type = QueryType.LIKE)
private String phone;
// 嵌套对象查询
private UserAddressQuery address;
@QueryField(type = QueryType.EQUAL)
private Boolean enabled;
@QueryField(type = QueryType.EQUAL)
private Boolean deleted;
@QueryField(type = QueryType.LIKE)
private String createBy;
@QueryField(type = QueryType.LIKE)
private String updateBy;
@QueryField(type = QueryType.EQUAL)
private Integer version;
// createTimeRange updateTimeRange 已经在 BaseQuery 中定义
}

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.dto.request;
import com.qqchen.deploy.common.dto.BaseRequest;
import com.qqchen.deploy.backend.common.dto.BaseRequest;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.dto.response;
import com.qqchen.deploy.common.dto.BaseResponse;
import com.qqchen.deploy.backend.common.dto.BaseResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.entity;
import com.qqchen.deploy.common.domain.Entity;
import com.qqchen.deploy.backend.common.domain.Entity;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
import lombok.Data;

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.repository;
import com.qqchen.deploy.common.repository.BaseRepository;
import com.qqchen.deploy.backend.common.repository.BaseRepository;
import com.qqchen.deploy.backend.entity.User;
import org.springframework.stereotype.Repository;

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.service;
import com.qqchen.deploy.common.service.BaseService;
import com.qqchen.deploy.backend.common.service.BaseService;
import com.qqchen.deploy.backend.entity.User;
public interface UserService extends BaseService<User, Long> {

View File

@ -1,6 +1,6 @@
package com.qqchen.deploy.backend.service.impl;
import com.qqchen.deploy.common.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.common.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.entity.User;
import com.qqchen.deploy.backend.repository.UserRepository;
import com.qqchen.deploy.backend.service.UserService;

View File

@ -1,32 +0,0 @@
package com.qqchen.deploy.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // 禁用CSRF
.authorizeHttpRequests(auth -> auth
// // 公开接口
// .requestMatchers("/*/*").permitAll()
// // Swagger相关接口
// .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
// // 健康检查接口
// .requestMatchers("/actuator/**").permitAll()
// 开发阶段可以暂时允许所有请求
.anyRequest().permitAll()
// 生产环境建议改为需要认证
//.anyRequest().authenticated()
);
return http.build();
}
}

View File

@ -7,18 +7,24 @@ spring:
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
format_sql: false
use_sql_comments: true
dialect: org.hibernate.dialect.MySQL8Dialect
jdbc:
time_zone: Asia/Shanghai
mvc:
log-request-details: true # \u6253\u5370\u8BF7\u6C42\u8BE6\u60C5
logging:
level:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE # \u6253\u5370\u6240\u6709\u6CE8\u518C\u7684\u63A5\u53E3\u8DEF\u5F84
org.hibernate.type.descriptor.sql.BasicBinder: TRACE # \u663E\u793ASQL\u53C2\u6570
org.hibernate.type.descriptor.sql: TRACE
jwt:
secret: 'thisIsAVeryVerySecretKeyForJwtTokenGenerationAndValidation123456789'
expiration: 86400