尝试修改convert迁移到service

This commit is contained in:
dengqichen 2024-11-28 11:01:02 +08:00
parent 486cdfcd89
commit fa66642718
18 changed files with 238 additions and 129 deletions

View File

@ -0,0 +1,33 @@
package com.qqchen.deploy.backend.api;
import com.qqchen.deploy.backend.common.api.Response;
import com.qqchen.deploy.backend.common.controller.BaseController;
import com.qqchen.deploy.backend.converter.TenantConverter;
import com.qqchen.deploy.backend.dto.query.TenantQuery;
import com.qqchen.deploy.backend.dto.request.TenantRequest;
import com.qqchen.deploy.backend.dto.response.TenantResponse;
import com.qqchen.deploy.backend.entity.Tenant;
import com.qqchen.deploy.backend.service.ITenantService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/tenant")
public class TenantApiController extends BaseController<Tenant, Long, TenantQuery, TenantRequest, TenantResponse> {
protected final ITenantService service;
public TenantApiController(ITenantService service, TenantConverter converter) {
super(service, converter);
this.service = service;
}
@GetMapping("/code/{code}")
public Response<TenantResponse> findByCode(@PathVariable String code) {
Tenant tenant = service.findByCode(code);
return Response.success(converter.toResponse(tenant));
}
}

View File

@ -8,12 +8,16 @@ public enum ResponseCode {
ERROR(500, "response.error"), ERROR(500, "response.error"),
INVALID_PARAM(400, "response.invalid.param"), INVALID_PARAM(400, "response.invalid.param"),
UNAUTHORIZED(401, "response.unauthorized"), UNAUTHORIZED(401, "response.unauthorized"),
AUTH_REQUIRED(401, "response.unauthorized.full"),
FORBIDDEN(403, "response.forbidden"), FORBIDDEN(403, "response.forbidden"),
NOT_FOUND(404, "response.not.found"), NOT_FOUND(404, "response.not.found"),
CONFLICT(409, "response.conflict"), CONFLICT(409, "response.conflict"),
// 业务错误码 // 业务错误码
TENANT_NOT_FOUND(1001, "tenant.not.found"), TENANT_NOT_FOUND(1001, "tenant.not.found"),
DATA_NOT_FOUND(1002, "data.not.found"),
// 用户相关错误码2开头
USER_NOT_FOUND(2001, "user.not.found"), USER_NOT_FOUND(2001, "user.not.found"),
USERNAME_EXISTS(2002, "user.username.exists"), USERNAME_EXISTS(2002, "user.username.exists"),
EMAIL_EXISTS(2003, "user.email.exists"); EMAIL_EXISTS(2003, "user.email.exists");

View File

@ -20,7 +20,7 @@ public class TenantInterceptor implements HandlerInterceptor {
// 不需要进行租户隔离的路径 // 不需要进行租户隔离的路径
private final List<String> excludePaths = Arrays.asList( private final List<String> excludePaths = Arrays.asList(
// "/api/v1/users/login", // "/api/v1/users/login",
"/api/system/tenants/list", "/api/v1/tenant/list",
"/swagger-ui/**", "/swagger-ui/**",
"/v3/api-docs/**" "/v3/api-docs/**"
); );
@ -28,7 +28,6 @@ public class TenantInterceptor implements HandlerInterceptor {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String path = request.getRequestURI(); String path = request.getRequestURI();
System.out.println("Intercepting path: " + path); // 添加日志
// 如果是白名单路径不进行租户校验 // 如果是白名单路径不进行租户校验
if (isExcludePath(path)) { if (isExcludePath(path)) {
TenantContext.clear(); TenantContext.clear();

View File

@ -9,9 +9,13 @@ import java.time.LocalDateTime;
@Data @Data
public abstract class BaseQuery implements Serializable { public abstract class BaseQuery implements Serializable {
private Integer pageNum = 1; private Integer pageNum = 1;
private Integer pageSize = 10; private Integer pageSize = 10;
private String sortField = "createTime"; private String sortField = "createTime";
private String sortOrder = "desc"; private String sortOrder = "desc";
// 通用状态查询 // 通用状态查询

View File

@ -49,7 +49,7 @@ public class SecurityConfig {
.exceptionHandling(exceptions -> exceptions .exceptionHandling(exceptions -> exceptions
.authenticationEntryPoint(authenticationEntryPoint)) .authenticationEntryPoint(authenticationEntryPoint))
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/users/login", "/api/v1/users/register").permitAll() .requestMatchers("/api/v1/users/login", "/api/v1/users/register", "/api/v1/tenant/list").permitAll()
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.requestMatchers("/actuator/health").permitAll() .requestMatchers("/actuator/health").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()

View File

@ -25,11 +25,13 @@ import java.util.List;
public class JwtAuthenticationFilter extends OncePerRequestFilter { public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtTokenUtil jwtTokenUtil; private final JwtTokenUtil jwtTokenUtil;
private final UserDetailsService userDetailsService; private final UserDetailsService userDetailsService;
private static final List<String> WHITELIST = Arrays.asList( private static final List<String> WHITELIST = Arrays.asList(
"/api/v1/users/login", "/api/v1/users/login",
"/api/v1/users/register", "/api/v1/users/register",
"/api/v1/tenant/list",
"/swagger-ui/**", "/swagger-ui/**",
"/v3/api-docs/**", "/v3/api-docs/**",
"/actuator/health" "/actuator/health"
@ -42,14 +44,12 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
} }
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
throws ServletException, IOException {
try { try {
String tenantId = request.getHeader("X-Tenant-ID"); // String tenantId = request.getHeader("X-Tenant-ID");
if (tenantId != null && !tenantId.isEmpty()) { // if (tenantId != null && !tenantId.isEmpty()) {
TenantContext.setTenantId(tenantId); // TenantContext.setTenantId(tenantId);
} // }
String authHeader = request.getHeader("Authorization"); String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) { if (authHeader == null || !authHeader.startsWith("Bearer ")) {
chain.doFilter(request, response); chain.doFilter(request, response);

View File

@ -8,6 +8,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.InternalAuthenticationServiceException; import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
@ -27,11 +28,13 @@ public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint
response.setCharacterEncoding(StandardCharsets.UTF_8.name()); response.setCharacterEncoding(StandardCharsets.UTF_8.name());
Response<?> result; Response<?> result;
if (authException instanceof BadCredentialsException) { if (authException instanceof BadCredentialsException) {
result = Response.error(ResponseCode.UNAUTHORIZED, MessageUtils.getMessage(ResponseCode.SUCCESS.getMessageKey())); result = Response.error(ResponseCode.UNAUTHORIZED, MessageUtils.getMessage(ResponseCode.UNAUTHORIZED.getMessageKey()));
} else if (authException instanceof InternalAuthenticationServiceException) { } else if (authException instanceof InternalAuthenticationServiceException) {
result = Response.error(ResponseCode.USER_NOT_FOUND, MessageUtils.getMessage(ResponseCode.USER_NOT_FOUND.getMessageKey())); result = Response.error(ResponseCode.USER_NOT_FOUND, MessageUtils.getMessage(ResponseCode.USER_NOT_FOUND.getMessageKey()));
} else if (authException instanceof InsufficientAuthenticationException) {
result = Response.error(ResponseCode.AUTH_REQUIRED, MessageUtils.getMessage(ResponseCode.AUTH_REQUIRED.getMessageKey()));
} else { } else {
result = Response.error(ResponseCode.UNAUTHORIZED, MessageUtils.getMessage(ResponseCode.SUCCESS.getMessageKey())); result = Response.error(ResponseCode.UNAUTHORIZED, MessageUtils.getMessage(ResponseCode.UNAUTHORIZED.getMessageKey()));
} }
response.getWriter().write(objectMapper.writeValueAsString(result)); response.getWriter().write(objectMapper.writeValueAsString(result));

View File

@ -0,0 +1,18 @@
package com.qqchen.deploy.backend.converter;
import com.qqchen.deploy.backend.common.converter.BaseConverter;
import com.qqchen.deploy.backend.dto.request.TenantRequest;
import com.qqchen.deploy.backend.dto.request.UserRequest;
import com.qqchen.deploy.backend.dto.response.TenantResponse;
import com.qqchen.deploy.backend.dto.response.UserResponse;
import com.qqchen.deploy.backend.entity.Tenant;
import com.qqchen.deploy.backend.entity.User;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TenantConverter extends BaseConverter<Tenant, TenantRequest, TenantResponse> {
}

View File

@ -0,0 +1,27 @@
package com.qqchen.deploy.backend.dto.query;
import com.qqchen.deploy.backend.common.annotation.QueryField;
import com.qqchen.deploy.backend.common.enums.QueryType;
import com.qqchen.deploy.backend.common.query.BaseQuery;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class TenantQuery extends BaseQuery {
@QueryField(type = QueryType.EQUAL)
private String name;
@QueryField(type = QueryType.EQUAL)
private String code;
@QueryField(type = QueryType.EQUAL)
private String contactPhone;
@QueryField(type = QueryType.EQUAL)
private String email;
}

View File

@ -0,0 +1,27 @@
package com.qqchen.deploy.backend.dto.request;
import com.qqchen.deploy.backend.common.dto.BaseRequest;
import jakarta.persistence.Column;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class TenantRequest extends BaseRequest {
@NotBlank(message = "租户名称不能为空")
private String name;
@NotBlank(message = "租户编码不能为空")
private String code;
@NotBlank(message = "租户维护人")
private String contactName;
@NotBlank(message = "租户维护人电话")
private String contactPhone;
}

View File

@ -0,0 +1,29 @@
package com.qqchen.deploy.backend.dto.response;
import com.qqchen.deploy.backend.common.dto.BaseResponse;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class TenantResponse extends BaseResponse {
private Long id;
private String name;
private String code;
private String contactName;
private String contactPhone;
private String email;
private String address;
private Boolean enabled = true;
}

View File

@ -36,4 +36,5 @@ public class Tenant extends Entity<Long> {
@Column(nullable = false) @Column(nullable = false)
private Boolean enabled = true; private Boolean enabled = true;
} }

View File

@ -17,5 +17,5 @@ public interface ITenantService extends IBaseService<Tenant, Long> {
boolean existsByName(String name); boolean existsByName(String name);
// List<Tenant> findAll(TenantQuery query); Tenant findByCode(String code);
} }

View File

@ -1,113 +1,69 @@
//package com.qqchen.deploy.backend.service.impl; package com.qqchen.deploy.backend.service.impl;
//
//import com.qqchen.deploy.backend.common.service.impl.BaseServiceImpl; import com.qqchen.deploy.backend.common.exception.BusinessException;
//import com.qqchen.deploy.backend.entity.Tenant; import com.qqchen.deploy.backend.common.enums.ResponseCode;
//import com.qqchen.deploy.backend.repository.ITenantRepository; import com.qqchen.deploy.backend.common.service.impl.BaseServiceImpl;
//import com.qqchen.deploy.backend.service.ITenantService; import com.qqchen.deploy.backend.entity.QTenant;
//import com.querydsl.core.BooleanBuilder; import com.qqchen.deploy.backend.entity.Tenant;
//import jakarta.transaction.Transactional; import com.qqchen.deploy.backend.repository.ITenantRepository;
//import org.springframework.stereotype.Service; import com.qqchen.deploy.backend.service.ITenantService;
//import org.springframework.util.StringUtils; import jakarta.transaction.Transactional;
// import org.springframework.stereotype.Service;
//import java.util.List;
// import java.util.List;
//@Service
//@Transactional @Service
//public class TenantServiceImpl extends BaseServiceImpl<Tenant, Long> implements ITenantService { @Transactional
// public class TenantServiceImpl extends BaseServiceImpl<Tenant, Long> implements ITenantService {
// private final ITenantRepository tenantRepository;
// private final ITenantRepository tenantRepository;
// public TenantServiceImpl(ITenantRepository tenantRepository) {
// super(tenantRepository); public TenantServiceImpl(ITenantRepository tenantRepository) {
// this.tenantRepository = tenantRepository; super(tenantRepository);
// } this.tenantRepository = tenantRepository;
// }
// @Override
// public List<Tenant> findAll(TenantQuery query) { @Override
// QTenant tenant = QTenant.tenant; public List<Tenant> findAllEnabled() {
// BooleanBuilder builder = new BooleanBuilder(); QTenant tenant = QTenant.tenant;
// return (List<Tenant>) tenantRepository.findAll(
// // 基础条件未删除 tenant.deleted.eq(false)
// builder.and(tenant.deleted.eq(false)); .and(tenant.enabled.eq(true)),
// tenant.id.asc()
// // 动态条件 );
// if (query != null) { }
// // 名称模糊查询
// if (StringUtils.hasText(query.getName())) {
// builder.and(tenant.name.like("%" + query.getName().trim() + "%")); @Override
// } public void validateCode(String code) {
//
// // 编码模糊查询
// if (StringUtils.hasText(query.getCode())) {
// builder.and(tenant.code.like("%" + query.getCode().trim() + "%"));
// }
//
// // 状态精确查询
// if (query.getEnabled() != null) {
// builder.and(tenant.enabled.eq(query.getEnabled()));
// }
// }
//
// // 按ID排序
// return (List<Tenant>) tenantRepository.findAll(builder, tenant.id.asc());
// }
//
// @Override
// public List<Tenant> findAllEnabled() {
// QTenant tenant = QTenant.tenant;
// return (List<Tenant>) tenantRepository.findAll(
// tenant.deleted.eq(false)
// .and(tenant.enabled.eq(true)),
// tenant.id.asc()
// );
// }
//
// @Override
// public Tenant save(Tenant entity) {
// validateCode(entity.getCode());
// validateName(entity.getName());
// entity.setDeleted(false);
// return super.save(entity);
// }
//
// @Override
// public Tenant update(Long id, Tenant entity) {
// Tenant existing = findById(id)
// .orElseThrow(() -> new ApiException("租户不存在"));
//
// if (!existing.getCode().equals(entity.getCode())) {
// validateCode(entity.getCode());
// }
// if (!existing.getName().equals(entity.getName())) {
// validateName(entity.getName());
// }
//
// entity.setVersion(existing.getVersion());
// entity.setDeleted(existing.getDeleted());
// return super.update(id, entity);
// }
//
// @Override
// public void validateCode(String code) {
// if (tenantRepository.existsByCodeAndDeletedFalse(code)) { // if (tenantRepository.existsByCodeAndDeletedFalse(code)) {
// throw new ApiException("租户编码已存在"); // throw new ApiException("租户编码已存在");
// } // }
// } }
//
// @Override @Override
// public void validateName(String name) { public void validateName(String name) {
// if (tenantRepository.existsByNameAndDeletedFalse(name)) { // if (tenantRepository.existsByNameAndDeletedFalse(name)) {
// throw new ApiException("租户名称已存在"); // throw new ApiException("租户名称已存在");
// } // }
// } }
//
// @Override @Override
// public boolean existsByCode(String code) { public boolean existsByCode(String code) {
// return tenantRepository.existsByCodeAndDeletedFalse(code); return tenantRepository.existsByCodeAndDeletedFalse(code);
// } }
//
// @Override @Override
// public boolean existsByName(String name) { public boolean existsByName(String name) {
// return tenantRepository.existsByNameAndDeletedFalse(name); return tenantRepository.existsByNameAndDeletedFalse(name);
// } }
//}
@Override
public Tenant findByCode(String code) {
QTenant tenant = QTenant.tenant;
return (Tenant) tenantRepository.findOne(
tenant.code.eq(code)
.and(tenant.deleted.eq(false))
).orElseThrow(() -> new BusinessException(ResponseCode.DATA_NOT_FOUND));
}
}

View File

@ -3,9 +3,9 @@ server:
spring: spring:
datasource: datasource:
url: jdbc:mysql://192.168.1.111:3306/deploy-ease-platform?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/deploy-ease-platform?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: deploy-ease-platform username: root
password: qichen5210523 password: root
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
jpa: jpa:
hibernate: hibernate:

View File

@ -6,6 +6,7 @@ response.unauthorized=\u672A\u6388\u6743
response.forbidden=\u7981\u6B62\u8BBF\u95EE response.forbidden=\u7981\u6B62\u8BBF\u95EE
response.not.found=\u8D44\u6E90\u672A\u627E\u5230 response.not.found=\u8D44\u6E90\u672A\u627E\u5230
response.conflict=\u8D44\u6E90\u51B2\u7A81 response.conflict=\u8D44\u6E90\u51B2\u7A81
response.unauthorized.full=\u8BBF\u95EE\u6B64\u8D44\u6E90\u9700\u8981\u5B8C\u5168\u8EAB\u4EFD\u9A8C\u8BC1
tenant.not.found=\u79DF\u6237\u4E0D\u5B58\u5728 tenant.not.found=\u79DF\u6237\u4E0D\u5B58\u5728
@ -13,3 +14,5 @@ tenant.not.found=\u79DF\u6237\u4E0D\u5B58\u5728
user.not.found=\u7528\u6237\u4E0D\u5B58\u5728 user.not.found=\u7528\u6237\u4E0D\u5B58\u5728
user.username.exists=\u7528\u6237\u540D\u5DF2\u5B58\u5728 user.username.exists=\u7528\u6237\u540D\u5DF2\u5B58\u5728
user.email.exists=\u90AE\u7BB1\u5DF2\u5B58\u5728 user.email.exists=\u90AE\u7BB1\u5DF2\u5B58\u5728
data.not.found=数据不存在

View File

@ -6,6 +6,7 @@ response.unauthorized=Unauthorized
response.forbidden=Forbidden response.forbidden=Forbidden
response.not.found=Resource Not Found response.not.found=Resource Not Found
response.conflict=Resource Conflict response.conflict=Resource Conflict
response.unauthorized.full=Full authentication is required to access this resource
tenant.not.found=Tenant not found tenant.not.found=Tenant not found
@ -13,3 +14,5 @@ tenant.not.found=Tenant not found
user.not.found=User not found user.not.found=User not found
user.username.exists=Username already exists user.username.exists=Username already exists
user.email.exists=Email already exists user.email.exists=Email already exists
data.not.found=Data not found

View File

@ -6,9 +6,11 @@ response.unauthorized=\u672A\u6388\u6743
response.forbidden=\u7981\u6B62\u8BBF\u95EE response.forbidden=\u7981\u6B62\u8BBF\u95EE
response.not.found=\u8D44\u6E90\u672A\u627E\u5230 response.not.found=\u8D44\u6E90\u672A\u627E\u5230
response.conflict=\u8D44\u6E90\u51B2\u7A81 response.conflict=\u8D44\u6E90\u51B2\u7A81
response.unauthorized.full=\u8BBF\u95EE\u6B64\u8D44\u6E90\u9700\u8981\u5B8C\u5168\u8EAB\u4EFD\u9A8C\u8BC1
tenant.not.found=\u79DF\u6237\u4E0D\u5B58\u5728 tenant.not.found=\u79DF\u6237\u4E0D\u5B58\u5728
user.not.found=\u7528\u6237\u4E0D\u5B58\u5728 user.not.found=\u7528\u6237\u4E0D\u5B58\u5728
user.username.exists=\u7528\u6237\u540D\u5DF2\u5B58\u5728 user.username.exists=\u7528\u6237\u540D\u5DF2\u5B58\u5728
user.email.exists=\u90AE\u7BB1\u5DF2\u5B58\u5728 user.email.exists=\u90AE\u7BB1\u5DF2\u5B58\u5728
data.not.found=数据不存在