迁移合理目录,增加系统参数
This commit is contained in:
parent
6655f120de
commit
39b26ac2f8
@ -1,8 +1,8 @@
|
|||||||
package com.qqchen.deploy.backend.api;
|
package com.qqchen.deploy.backend.api;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.dto.TenantDTO;
|
import com.qqchen.deploy.backend.model.TenantDTO;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
import com.qqchen.deploy.backend.dto.query.TenantQuery;
|
import com.qqchen.deploy.backend.model.query.TenantQuery;
|
||||||
import com.qqchen.deploy.backend.entity.Tenant;
|
import com.qqchen.deploy.backend.entity.Tenant;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
package com.qqchen.deploy.backend.api;
|
package com.qqchen.deploy.backend.api;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.dto.RoleDTO;
|
import com.qqchen.deploy.backend.model.RoleDTO;
|
||||||
import com.qqchen.deploy.backend.dto.query.UserQuery;
|
import com.qqchen.deploy.backend.model.query.UserQuery;
|
||||||
import com.qqchen.deploy.backend.dto.request.UserRequest;
|
import com.qqchen.deploy.backend.model.request.UserRequest;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.entity.User;
|
import com.qqchen.deploy.backend.entity.User;
|
||||||
import com.qqchen.deploy.backend.dto.UserDTO;
|
import com.qqchen.deploy.backend.model.UserDTO;
|
||||||
import com.qqchen.deploy.backend.dto.request.LoginRequest;
|
import com.qqchen.deploy.backend.model.request.LoginRequest;
|
||||||
import com.qqchen.deploy.backend.dto.response.LoginResponse;
|
import com.qqchen.deploy.backend.model.response.LoginResponse;
|
||||||
import com.qqchen.deploy.backend.service.IUserService;
|
import com.qqchen.deploy.backend.service.IUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@ -21,7 +21,7 @@ import java.io.OutputStream;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/users")
|
@RequestMapping("/api/v1/user")
|
||||||
public class UserApiController extends BaseController<User, UserDTO, Long, UserQuery> {
|
public class UserApiController extends BaseController<User, UserDTO, Long, UserQuery> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@ -34,10 +34,10 @@ public class UserApiController extends BaseController<User, UserDTO, Long, UserQ
|
|||||||
return Response.success(userService.login(request));
|
return Response.success(userService.login(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "用户注册")
|
@Operation(summary = "获取当前用户信息")
|
||||||
@PostMapping("/register")
|
@GetMapping("/current")
|
||||||
public Response<UserDTO> register(@Validated @RequestBody UserRequest request) {
|
public Response<LoginResponse> getCurrentUser() {
|
||||||
return Response.success(userService.register(request));
|
return Response.success(userService.getCurrentUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,15 +52,4 @@ public class UserApiController extends BaseController<User, UserDTO, Long, UserQ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/roles")
|
|
||||||
@Operation(summary = "获取当前用户的角色")
|
|
||||||
public Response<List<RoleDTO>> getCurrentUserRoles() {
|
|
||||||
return Response.success(userService.getCurrentUserRoles());
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/{id}/roles")
|
|
||||||
@Operation(summary = "获取指定用户的角色")
|
|
||||||
public Response<List<RoleDTO>> getUserRoles(@PathVariable Long id) {
|
|
||||||
return Response.success(userService.getUserRoles(id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package com.qqchen.deploy.backend.controller;
|
package com.qqchen.deploy.backend.controller;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.dto.query.TenantQuery;
|
import com.qqchen.deploy.backend.model.query.TenantQuery;
|
||||||
import com.qqchen.deploy.backend.entity.Tenant;
|
import com.qqchen.deploy.backend.entity.Tenant;
|
||||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||||
import com.qqchen.deploy.backend.dto.TenantDTO;
|
import com.qqchen.deploy.backend.model.TenantDTO;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
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;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.controller;
|
package com.qqchen.deploy.backend.controller;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.api.UserApiController;
|
import com.qqchen.deploy.backend.api.UserApiController;
|
||||||
import com.qqchen.deploy.backend.dto.UserDTO;
|
import com.qqchen.deploy.backend.model.UserDTO;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
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;
|
||||||
@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/mgmt/users")
|
@RequestMapping("/mgmt/user")
|
||||||
public class UserController extends UserApiController {
|
public class UserController extends UserApiController {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.qqchen.deploy.backend.converter;
|
package com.qqchen.deploy.backend.converter;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.dto.RoleDTO;
|
import com.qqchen.deploy.backend.model.RoleDTO;
|
||||||
import com.qqchen.deploy.backend.entity.Role;
|
import com.qqchen.deploy.backend.entity.Role;
|
||||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.qqchen.deploy.backend.converter;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.entity.SysParam;
|
||||||
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
|
import com.qqchen.deploy.backend.model.SysParamDTO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper(config = BaseConverter.class)
|
||||||
|
public interface SysParamConverter extends BaseConverter<SysParam, SysParamDTO> {
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.qqchen.deploy.backend.converter;
|
package com.qqchen.deploy.backend.converter;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.dto.TenantDTO;
|
import com.qqchen.deploy.backend.model.TenantDTO;
|
||||||
import com.qqchen.deploy.backend.entity.Tenant;
|
import com.qqchen.deploy.backend.entity.Tenant;
|
||||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
|||||||
@ -1,11 +1,19 @@
|
|||||||
package com.qqchen.deploy.backend.converter;
|
package com.qqchen.deploy.backend.converter;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
|
||||||
import com.qqchen.deploy.backend.entity.User;
|
import com.qqchen.deploy.backend.entity.User;
|
||||||
import com.qqchen.deploy.backend.dto.UserDTO;
|
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||||
|
import com.qqchen.deploy.backend.model.UserDTO;
|
||||||
|
import com.qqchen.deploy.backend.model.response.LoginResponse;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
|
||||||
@Mapper(config = BaseConverter.class)
|
@Mapper(config = BaseConverter.class)
|
||||||
public interface UserConverter extends BaseConverter<User, UserDTO> {
|
public interface UserConverter extends BaseConverter<User, UserDTO> {
|
||||||
// MapStruct 会自动实现所有方法
|
// MapStruct 会自动实现所有方法
|
||||||
|
|
||||||
|
@Mapping(target = "token", ignore = true)
|
||||||
|
LoginResponse toLoginResponse(User user);
|
||||||
|
|
||||||
|
@Mapping(target = "token", source = "token")
|
||||||
|
LoginResponse toLoginResponse(User user, String token);
|
||||||
}
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.qqchen.deploy.backend.entity;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.annotation.LogicDelete;
|
||||||
|
import com.qqchen.deploy.backend.framework.domain.Entity;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@jakarta.persistence.Entity
|
||||||
|
@Table(name = "sys_param")
|
||||||
|
@LogicDelete
|
||||||
|
public class SysParam extends Entity<Long> {
|
||||||
|
|
||||||
|
@Column(nullable = false, length = 100)
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
@Column(nullable = false, length = 100)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
@Column(nullable = false, length = 50)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.framework.audit.annotation;
|
package com.qqchen.deploy.backend.framework.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.framework.audit.aspect;
|
package com.qqchen.deploy.backend.framework.audit.aspect;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.audit.AuditMetadata;
|
import com.qqchen.deploy.backend.framework.audit.AuditMetadata;
|
||||||
import com.qqchen.deploy.backend.framework.audit.annotation.Audited;
|
import com.qqchen.deploy.backend.framework.annotation.Audited;
|
||||||
import com.qqchen.deploy.backend.framework.audit.event.AuditEvent;
|
import com.qqchen.deploy.backend.framework.audit.event.AuditEvent;
|
||||||
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@ -26,7 +26,7 @@ public class AuditAspect {
|
|||||||
|
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
private final ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
@Around("@annotation(com.qqchen.deploy.backend.framework.audit.annotation.Audited)")
|
@Around("@annotation(com.qqchen.deploy.backend.framework.annotation.Audited)")
|
||||||
public Object auditMethod(ProceedingJoinPoint joinPoint) throws Throwable {
|
public Object auditMethod(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
// 获取审计元数据
|
// 获取审计元数据
|
||||||
AuditMetadata metadata = extractAuditMetadata(joinPoint);
|
AuditMetadata metadata = extractAuditMetadata(joinPoint);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.framework.config;
|
package com.qqchen.deploy.backend.framework.audit.config;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@ -1,6 +1,5 @@
|
|||||||
package com.qqchen.deploy.backend.framework.config;
|
package com.qqchen.deploy.backend.framework.config;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.interceptor.TenantInterceptor;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
|||||||
@ -55,14 +55,11 @@ public class DependencyInjectionPostProcessor implements BeanPostProcessor, Disp
|
|||||||
if (bean instanceof BaseServiceImpl<?, ?, ?> service) {
|
if (bean instanceof BaseServiceImpl<?, ?, ?> service) {
|
||||||
return injectServiceDependencies(service, beanName);
|
return injectServiceDependencies(service, beanName);
|
||||||
}
|
}
|
||||||
} catch (DependencyInjectionException e) {
|
|
||||||
log.error("Dependency injection failed for bean: {}", beanName, e);
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Unexpected error during dependency injection for bean: {}", beanName, e);
|
String errorMsg = String.format("依赖注入失败 - Bean: %s, 类型: %s, 原因: %s",
|
||||||
throw new DependencyInjectionException(
|
beanName, bean.getClass().getName(), e.getMessage());
|
||||||
String.format("Failed to inject dependencies for bean: %s", beanName),
|
log.error(errorMsg, e);
|
||||||
e);
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
}
|
}
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
@ -151,12 +148,9 @@ public class DependencyInjectionPostProcessor implements BeanPostProcessor, Disp
|
|||||||
|
|
||||||
log.debug("Successfully injected all dependencies for service: {}", beanName);
|
log.debug("Successfully injected all dependencies for service: {}", beanName);
|
||||||
return service;
|
return service;
|
||||||
} catch (DependencyInjectionException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new DependencyInjectionException(
|
throw new DependencyInjectionException(
|
||||||
String.format("Failed to inject dependencies for service: %s", service.getClass().getSimpleName()),
|
String.format("Failed to inject dependencies for service: %s", service.getClass().getSimpleName()), e);
|
||||||
e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,20 +183,28 @@ public class DependencyInjectionPostProcessor implements BeanPostProcessor, Disp
|
|||||||
private <T extends Entity<ID>, D extends BaseDTO, ID extends Serializable>
|
private <T extends Entity<ID>, D extends BaseDTO, ID extends Serializable>
|
||||||
void injectRepository(BaseServiceImpl<T, D, ID> service, Class<T> entityClass) {
|
void injectRepository(BaseServiceImpl<T, D, ID> service, Class<T> entityClass) {
|
||||||
String repositoryBeanName = "I" + entityClass.getSimpleName() + "Repository";
|
String repositoryBeanName = "I" + entityClass.getSimpleName() + "Repository";
|
||||||
log.debug("Looking for repository bean: {}", repositoryBeanName);
|
log.debug("正在查找 Repository: {}", repositoryBeanName);
|
||||||
|
|
||||||
|
try {
|
||||||
IBaseRepository<T, ID> repository = (IBaseRepository<T, ID>) repositoryCache.computeIfAbsent(
|
IBaseRepository<T, ID> repository = (IBaseRepository<T, ID>) repositoryCache.computeIfAbsent(
|
||||||
entityClass,
|
entityClass,
|
||||||
key -> {
|
key -> {
|
||||||
if (!applicationContext.containsBean(repositoryBeanName)) {
|
if (!applicationContext.containsBean(repositoryBeanName)) {
|
||||||
throw new BusinessException(
|
String errorMsg = String.format("找不到 Repository - 服务类: %s, 实体类: %s, Repository名称: %s",
|
||||||
ResponseCode.DEPENDENCY_INJECTION_REPOSITORY_NOT_FOUND,
|
service.getClass().getName(), key.getSimpleName(), repositoryBeanName);
|
||||||
new Object[] {key.getSimpleName(), repositoryBeanName});
|
log.error(errorMsg);
|
||||||
|
throw new DependencyInjectionException(errorMsg, new RuntimeException(errorMsg));
|
||||||
}
|
}
|
||||||
return (IBaseRepository<?, ?>) applicationContext.getBean(repositoryBeanName);
|
return (IBaseRepository<?, ?>) applicationContext.getBean(repositoryBeanName);
|
||||||
});
|
});
|
||||||
|
|
||||||
ReflectionUtils.setField("repository", service, repository);
|
ReflectionUtils.setField("repository", service, repository);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String errorMsg = String.format("注入 Repository 失败 - 服务类: %s, 实体类: %s, Repository名称: %s, 原因: %s",
|
||||||
|
service.getClass().getName(), entityClass.getSimpleName(), repositoryBeanName, e.getMessage());
|
||||||
|
log.error(errorMsg, e);
|
||||||
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -210,44 +212,68 @@ public class DependencyInjectionPostProcessor implements BeanPostProcessor, Disp
|
|||||||
void injectConverter(BaseServiceImpl<T, D, ID> service, Class<T> entityClass) {
|
void injectConverter(BaseServiceImpl<T, D, ID> service, Class<T> entityClass) {
|
||||||
String converterBeanName = entityClass.getSimpleName().substring(0, 1).toLowerCase()
|
String converterBeanName = entityClass.getSimpleName().substring(0, 1).toLowerCase()
|
||||||
+ entityClass.getSimpleName().substring(1) + "ConverterImpl";
|
+ entityClass.getSimpleName().substring(1) + "ConverterImpl";
|
||||||
log.debug("Looking for converter bean: {}", converterBeanName);
|
log.debug("正在查找 Converter: {}", converterBeanName);
|
||||||
|
|
||||||
|
try {
|
||||||
BaseConverter<T, D> converter = (BaseConverter<T, D>) converterCache.computeIfAbsent(
|
BaseConverter<T, D> converter = (BaseConverter<T, D>) converterCache.computeIfAbsent(
|
||||||
entityClass,
|
entityClass,
|
||||||
key -> {
|
key -> {
|
||||||
if (!applicationContext.containsBean(converterBeanName)) {
|
if (!applicationContext.containsBean(converterBeanName)) {
|
||||||
throw new BusinessException(
|
String errorMsg = String.format("找不到 Converter - 服务类: %s, 实体类: %s, Converter名称: %s",
|
||||||
ResponseCode.DEPENDENCY_INJECTION_CONVERTER_NOT_FOUND,
|
service.getClass().getName(), key.getSimpleName(), converterBeanName);
|
||||||
new Object[] {key.getSimpleName(), converterBeanName});
|
log.error(errorMsg);
|
||||||
|
throw new DependencyInjectionException(errorMsg, new RuntimeException(errorMsg));
|
||||||
}
|
}
|
||||||
return (BaseConverter<?, ?>) applicationContext.getBean(converterBeanName);
|
return (BaseConverter<?, ?>) applicationContext.getBean(converterBeanName);
|
||||||
});
|
});
|
||||||
|
|
||||||
ReflectionUtils.setField("converter", service, converter);
|
ReflectionUtils.setField("converter", service, converter);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String errorMsg = String.format("注入 Converter 失败 - 服务类: %s, 实体类: %s, Converter名称: %s, 原因: %s",
|
||||||
|
service.getClass().getName(), entityClass.getSimpleName(), converterBeanName, e.getMessage());
|
||||||
|
log.error(errorMsg, e);
|
||||||
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T extends Entity<ID>, D extends BaseDTO, ID extends Serializable> void injectEntityPath(BaseServiceImpl<T, D, ID> service, Class<T> entityClass) {
|
private <T extends Entity<ID>, D extends BaseDTO, ID extends Serializable>
|
||||||
|
void injectEntityPath(BaseServiceImpl<T, D, ID> service, Class<T> entityClass) {
|
||||||
try {
|
try {
|
||||||
EntityPath<T> entityPath = (EntityPath<T>) entityPathCache.computeIfAbsent(
|
EntityPath<T> entityPath = (EntityPath<T>) entityPathCache.computeIfAbsent(
|
||||||
entityClass,
|
entityClass,
|
||||||
key -> {
|
key -> {
|
||||||
try {
|
|
||||||
String qClassName = key.getPackageName() + ".Q" + key.getSimpleName();
|
String qClassName = key.getPackageName() + ".Q" + key.getSimpleName();
|
||||||
|
try {
|
||||||
Class<?> qClass = Class.forName(qClassName);
|
Class<?> qClass = Class.forName(qClassName);
|
||||||
Field instanceField = qClass.getDeclaredField(key.getSimpleName().toLowerCase());
|
String fieldName = key.getSimpleName();
|
||||||
|
fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
||||||
|
Field instanceField = qClass.getDeclaredField(fieldName);
|
||||||
return (EntityPath<?>) instanceField.get(null);
|
return (EntityPath<?>) instanceField.get(null);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
String errorMsg = String.format("找不到 QueryDSL 实体类 - 服务类: %s, 实体类: %s, Q类名: %s",
|
||||||
|
service.getClass().getName(), key.getSimpleName(), qClassName);
|
||||||
|
log.error(errorMsg, e);
|
||||||
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
String errorMsg = String.format("找不到 QueryDSL 实体字段 - 服务类: %s, 实体类: %s, Q类名: %s",
|
||||||
|
service.getClass().getName(), key.getSimpleName(), qClassName);
|
||||||
|
log.error(errorMsg, e);
|
||||||
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new BusinessException(
|
String errorMsg = String.format("获取 QueryDSL 实体失败 - 服务类: %s, 实体类: %s, Q类名: %s, 原因: %s",
|
||||||
ResponseCode.DEPENDENCY_INJECTION_ENTITYPATH_FAILED,
|
service.getClass().getName(), key.getSimpleName(), qClassName, e.getMessage());
|
||||||
new Object[] {key.getSimpleName(), e.getMessage()});
|
log.error(errorMsg, e);
|
||||||
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ReflectionUtils.setField("entityPath", service, entityPath);
|
ReflectionUtils.setField("entityPath", service, entityPath);
|
||||||
} catch (BusinessException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new BusinessException(ResponseCode.DEPENDENCY_INJECTION_ENTITYPATH_FAILED, new Object[] {entityClass.getSimpleName(), e.getMessage()});
|
String errorMsg = String.format("注入 EntityPath 失败 - 服务类: %s, 实体类: %s, 原因: %s",
|
||||||
|
service.getClass().getName(), entityClass.getSimpleName(), e.getMessage());
|
||||||
|
log.error(errorMsg, e);
|
||||||
|
throw new DependencyInjectionException(errorMsg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,14 +1,12 @@
|
|||||||
package com.qqchen.deploy.backend.framework.filter;
|
package com.qqchen.deploy.backend.framework.filter;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.context.TenantContext;
|
import com.qqchen.deploy.backend.framework.tenant.TenantContext;
|
||||||
import jakarta.servlet.Filter;
|
import jakarta.servlet.Filter;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.ServletRequest;
|
import jakarta.servlet.ServletRequest;
|
||||||
import jakarta.servlet.ServletResponse;
|
import jakarta.servlet.ServletResponse;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
package com.qqchen.deploy.backend.framework.exception;
|
package com.qqchen.deploy.backend.framework.handler;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
|
import com.qqchen.deploy.backend.framework.exception.SystemException;
|
||||||
import io.jsonwebtoken.ExpiredJwtException;
|
import io.jsonwebtoken.ExpiredJwtException;
|
||||||
import io.jsonwebtoken.MalformedJwtException;
|
import io.jsonwebtoken.MalformedJwtException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.framework.config;
|
package com.qqchen.deploy.backend.framework.i18n;
|
||||||
|
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.framework.config;
|
package com.qqchen.deploy.backend.framework.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
@ -22,48 +22,45 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
private final CustomAuthenticationEntryPoint authenticationEntryPoint;
|
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
|
||||||
|
private final JwtTokenUtil jwtTokenUtil;
|
||||||
private final UserDetailsService userDetailsService;
|
private final UserDetailsService userDetailsService;
|
||||||
|
|
||||||
private final JwtTokenUtil jwtTokenUtil;
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf(csrf -> csrf.disable())
|
||||||
|
.cors(cors -> cors.disable())
|
||||||
|
.sessionManagement(session ->
|
||||||
|
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
|
)
|
||||||
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
.requestMatchers(
|
||||||
|
"/api/v1/user/login",
|
||||||
|
"/api/v1/user/register",
|
||||||
|
"/api/v1/tenant/list",
|
||||||
|
"/swagger-ui/**",
|
||||||
|
"/v3/api-docs/**",
|
||||||
|
"/actuator/health"
|
||||||
|
).permitAll()
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
)
|
||||||
|
.addFilterBefore(
|
||||||
|
jwtAuthenticationFilter(),
|
||||||
|
UsernamePasswordAuthenticationFilter.class
|
||||||
|
)
|
||||||
|
.exceptionHandling(ex -> ex
|
||||||
|
.authenticationEntryPoint(customAuthenticationEntryPoint)
|
||||||
|
);
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JwtAuthenticationFilter jwtAuthenticationFilter() {
|
public JwtAuthenticationFilter jwtAuthenticationFilter() {
|
||||||
return new JwtAuthenticationFilter(jwtTokenUtil, userDetailsService);
|
return new JwtAuthenticationFilter(jwtTokenUtil, userDetailsService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
||||||
http
|
|
||||||
// .cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
|
||||||
.csrf(csrf -> csrf.disable())
|
|
||||||
.sessionManagement(session -> session
|
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
||||||
.exceptionHandling(exceptions -> exceptions
|
|
||||||
.authenticationEntryPoint(authenticationEntryPoint))
|
|
||||||
.authorizeHttpRequests(auth -> auth
|
|
||||||
.requestMatchers("/api/v1/users/login", "/api/v1/users/register", "/api/v1/tenant/list").permitAll()
|
|
||||||
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
|
|
||||||
.requestMatchers("/actuator/health").permitAll()
|
|
||||||
.anyRequest().authenticated()
|
|
||||||
)
|
|
||||||
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
|
||||||
|
|
||||||
return http.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO 这里会导致无限递归循环报错
|
|
||||||
// @Bean
|
|
||||||
// public UserDetailsService userDetailsService() {
|
|
||||||
// UserDetails user = User.withUsername("anonymous")
|
|
||||||
// .password("{noop}")
|
|
||||||
// .roles("ANONYMOUS")
|
|
||||||
// .build();
|
|
||||||
// return new InMemoryUserDetailsManager(user);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PasswordEncoder passwordEncoder() {
|
public PasswordEncoder passwordEncoder() {
|
||||||
return new BCryptPasswordEncoder();
|
return new BCryptPasswordEncoder();
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package com.qqchen.deploy.backend.framework.security.filter;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.qqchen.deploy.backend.framework.api.Response;
|
import com.qqchen.deploy.backend.framework.api.Response;
|
||||||
import com.qqchen.deploy.backend.framework.context.TenantContext;
|
import com.qqchen.deploy.backend.framework.tenant.TenantContext;
|
||||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
import com.qqchen.deploy.backend.framework.exception.JwtAuthenticationException;
|
import com.qqchen.deploy.backend.framework.exception.JwtAuthenticationException;
|
||||||
@ -39,8 +39,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
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/user/login",
|
||||||
"/api/v1/users/register",
|
"/api/v1/user/register",
|
||||||
"/api/v1/tenant/list",
|
"/api/v1/tenant/list",
|
||||||
"/swagger-ui/**",
|
"/swagger-ui/**",
|
||||||
"/v3/api-docs/**",
|
"/v3/api-docs/**",
|
||||||
@ -59,10 +59,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
String jwt = getJwtFromRequest(request);
|
String jwt = getJwtFromRequest(request);
|
||||||
if (StringUtils.hasText(jwt)) {
|
if (StringUtils.hasText(jwt)) {
|
||||||
String username = jwtTokenUtil.getUsernameFromToken(jwt);
|
String username = jwtTokenUtil.getUsernameFromToken(jwt);
|
||||||
|
|
||||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||||
|
|
||||||
if (jwtTokenUtil.validateToken(jwt, userDetails)) {
|
if (jwtTokenUtil.validateToken(jwt, userDetails)) {
|
||||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||||
userDetails, null, userDetails.getAuthorities());
|
userDetails, null, userDetails.getAuthorities());
|
||||||
|
|||||||
@ -39,7 +39,18 @@ public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint
|
|||||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
|
||||||
Response<?> errorResponse = Response.error(ResponseCode.UNAUTHORIZED);
|
Response<?> errorResponse;
|
||||||
|
|
||||||
|
if (authException instanceof BadCredentialsException) {
|
||||||
|
errorResponse = Response.error(ResponseCode.LOGIN_ERROR);
|
||||||
|
} else if (authException instanceof InternalAuthenticationServiceException) {
|
||||||
|
errorResponse = Response.error(ResponseCode.ERROR);
|
||||||
|
} else if (authException instanceof InsufficientAuthenticationException) {
|
||||||
|
errorResponse = Response.error(ResponseCode.AUTH_REQUIRED);
|
||||||
|
} else {
|
||||||
|
errorResponse = Response.error(ResponseCode.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
objectMapper.writeValue(response.getOutputStream(), errorResponse);
|
objectMapper.writeValue(response.getOutputStream(), errorResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.framework.context;
|
package com.qqchen.deploy.backend.framework.tenant;
|
||||||
|
|
||||||
public class TenantContext {
|
public class TenantContext {
|
||||||
private static final ThreadLocal<String> CURRENT_TENANT = new ThreadLocal<>();
|
private static final ThreadLocal<String> CURRENT_TENANT = new ThreadLocal<>();
|
||||||
@ -1,11 +1,9 @@
|
|||||||
package com.qqchen.deploy.backend.framework.interceptor;
|
package com.qqchen.deploy.backend.framework.tenant;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.context.TenantContext;
|
|
||||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto;
|
package com.qqchen.deploy.backend.model;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.qqchen.deploy.backend.model;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SysParamDTO extends BaseDTO {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto;
|
package com.qqchen.deploy.backend.model;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto;
|
package com.qqchen.deploy.backend.model;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.qqchen.deploy.backend.model.query;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SysParamQuery extends BaseQuery {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private Boolean enabled;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.query;
|
package com.qqchen.deploy.backend.model.query;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
||||||
import com.qqchen.deploy.backend.framework.enums.QueryType;
|
import com.qqchen.deploy.backend.framework.enums.QueryType;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.query;
|
package com.qqchen.deploy.backend.model.query;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
||||||
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.request;
|
package com.qqchen.deploy.backend.model.request;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -11,4 +11,7 @@ public class LoginRequest {
|
|||||||
|
|
||||||
@NotBlank(message = "密码不能为空")
|
@NotBlank(message = "密码不能为空")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
@NotBlank(message = "租户不能为空")
|
||||||
|
private String tenantId;
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.request;
|
package com.qqchen.deploy.backend.model.request;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -1,10 +1,9 @@
|
|||||||
package com.qqchen.deploy.backend.dto.request;
|
package com.qqchen.deploy.backend.model.request;
|
||||||
|
|
||||||
import jakarta.validation.constraints.Email;
|
import jakarta.validation.constraints.Email;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class UserRequest {
|
public class UserRequest {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.response;
|
package com.qqchen.deploy.backend.model.response;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.response;
|
package com.qqchen.deploy.backend.model.response;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.dto.BaseResponse;
|
import com.qqchen.deploy.backend.framework.dto.BaseResponse;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.dto.response;
|
package com.qqchen.deploy.backend.model.response;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.framework.dto.BaseResponse;
|
import com.qqchen.deploy.backend.framework.dto.BaseResponse;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -9,8 +9,6 @@ import lombok.EqualsAndHashCode;
|
|||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class UserResponse extends BaseResponse {
|
public class UserResponse extends BaseResponse {
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
private String email;
|
private String email;
|
||||||
@ -21,5 +19,4 @@ public class UserResponse extends BaseResponse {
|
|||||||
|
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
|
|
||||||
private String password;
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.qqchen.deploy.backend.repository;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.entity.SysParam;
|
||||||
|
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface ISysParamRepository extends IBaseRepository<SysParam, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据参数编码查询参数
|
||||||
|
* @param code 参数编码
|
||||||
|
* @return 参数对象
|
||||||
|
*/
|
||||||
|
Optional<SysParam> findByCodeAndDeletedFalse(String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据参数编码和启用状态查询参数
|
||||||
|
* @param code 参数编码
|
||||||
|
* @param enabled 启用状态
|
||||||
|
* @return 参数对象
|
||||||
|
*/
|
||||||
|
Optional<SysParam> findByCodeAndEnabledAndDeletedFalse(String code, Boolean enabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据参数类型查询参数列表
|
||||||
|
* @param type 参数类型
|
||||||
|
* @return 参数列表
|
||||||
|
*/
|
||||||
|
List<SysParam> findByTypeAndDeletedFalse(String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查参数编码是否存在
|
||||||
|
* @param code 参数编码
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
boolean existsByCodeAndDeletedFalse(String code);
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package com.qqchen.deploy.backend.service;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.entity.SysParam;
|
||||||
|
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||||
|
import com.qqchen.deploy.backend.model.SysParamDTO;
|
||||||
|
|
||||||
|
public interface ISysParamService extends IBaseService<SysParam, SysParamDTO, Long> {
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ package com.qqchen.deploy.backend.service;
|
|||||||
|
|
||||||
import com.qqchen.deploy.backend.entity.Tenant;
|
import com.qqchen.deploy.backend.entity.Tenant;
|
||||||
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||||
import com.qqchen.deploy.backend.dto.TenantDTO;
|
import com.qqchen.deploy.backend.model.TenantDTO;
|
||||||
|
|
||||||
public interface ITenantService extends IBaseService<Tenant, TenantDTO, Long> {
|
public interface ITenantService extends IBaseService<Tenant, TenantDTO, Long> {
|
||||||
// 添加租户特有的业务方法
|
// 添加租户特有的业务方法
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
package com.qqchen.deploy.backend.service;
|
package com.qqchen.deploy.backend.service;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.dto.UserDTO;
|
import com.qqchen.deploy.backend.model.UserDTO;
|
||||||
import com.qqchen.deploy.backend.framework.audit.annotation.Audited;
|
import com.qqchen.deploy.backend.framework.annotation.Audited;
|
||||||
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||||
import com.qqchen.deploy.backend.dto.request.LoginRequest;
|
import com.qqchen.deploy.backend.model.request.LoginRequest;
|
||||||
import com.qqchen.deploy.backend.dto.response.LoginResponse;
|
import com.qqchen.deploy.backend.model.response.LoginResponse;
|
||||||
import com.qqchen.deploy.backend.entity.User;
|
import com.qqchen.deploy.backend.entity.User;
|
||||||
import com.qqchen.deploy.backend.dto.request.UserRequest;
|
import com.qqchen.deploy.backend.model.request.UserRequest;
|
||||||
import com.qqchen.deploy.backend.dto.RoleDTO;
|
import com.qqchen.deploy.backend.model.RoleDTO;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -23,4 +23,7 @@ public interface IUserService extends IBaseService<User, UserDTO, Long> {
|
|||||||
@Transactional(readOnly = false)
|
@Transactional(readOnly = false)
|
||||||
@Audited(action = "CHANGE_PASSWORD", detail = "修改密码")
|
@Audited(action = "CHANGE_PASSWORD", detail = "修改密码")
|
||||||
void changePassword(Long userId, String oldPassword, String newPassword);
|
void changePassword(Long userId, String oldPassword, String newPassword);
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
LoginResponse getCurrentUser();
|
||||||
}
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.qqchen.deploy.backend.service.impl;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.converter.SysParamConverter;
|
||||||
|
import com.qqchen.deploy.backend.entity.SysParam;
|
||||||
|
import com.qqchen.deploy.backend.framework.annotation.ServiceType;
|
||||||
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
|
import com.qqchen.deploy.backend.model.SysParamDTO;
|
||||||
|
import com.qqchen.deploy.backend.repository.ISysParamRepository;
|
||||||
|
import com.qqchen.deploy.backend.service.ISysParamService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import static com.qqchen.deploy.backend.framework.annotation.ServiceType.Type.DATABASE;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@ServiceType(DATABASE)
|
||||||
|
public class SysParamServiceImpl extends BaseServiceImpl<SysParam, SysParamDTO, Long> implements ISysParamService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysParamConverter converter;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ISysParamRepository repository;
|
||||||
|
}
|
||||||
@ -1,16 +1,11 @@
|
|||||||
package com.qqchen.deploy.backend.service.impl;
|
package com.qqchen.deploy.backend.service.impl;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.entity.Tenant;
|
import com.qqchen.deploy.backend.entity.Tenant;
|
||||||
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
|
||||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
import com.qqchen.deploy.backend.repository.ITenantRepository;
|
|
||||||
import com.qqchen.deploy.backend.service.ITenantService;
|
import com.qqchen.deploy.backend.service.ITenantService;
|
||||||
import com.qqchen.deploy.backend.dto.TenantDTO;
|
import com.qqchen.deploy.backend.model.TenantDTO;
|
||||||
import com.qqchen.deploy.backend.converter.TenantConverter;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TenantServiceImpl extends BaseServiceImpl<Tenant, TenantDTO, Long> implements ITenantService {
|
public class TenantServiceImpl extends BaseServiceImpl<Tenant, TenantDTO, Long> implements ITenantService {
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
package com.qqchen.deploy.backend.service.impl;
|
package com.qqchen.deploy.backend.service.impl;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.converter.UserConverter;
|
||||||
import com.qqchen.deploy.backend.framework.annotation.ServiceType;
|
import com.qqchen.deploy.backend.framework.annotation.ServiceType;
|
||||||
import com.qqchen.deploy.backend.framework.audit.annotation.Audited;
|
import com.qqchen.deploy.backend.framework.annotation.Audited;
|
||||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
|
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
||||||
import com.qqchen.deploy.backend.framework.security.util.JwtTokenUtil;
|
import com.qqchen.deploy.backend.framework.security.util.JwtTokenUtil;
|
||||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
import com.qqchen.deploy.backend.dto.request.LoginRequest;
|
import com.qqchen.deploy.backend.model.request.LoginRequest;
|
||||||
import com.qqchen.deploy.backend.dto.request.UserRequest;
|
import com.qqchen.deploy.backend.model.request.UserRequest;
|
||||||
import com.qqchen.deploy.backend.dto.response.LoginResponse;
|
import com.qqchen.deploy.backend.model.response.LoginResponse;
|
||||||
import com.qqchen.deploy.backend.entity.User;
|
import com.qqchen.deploy.backend.entity.User;
|
||||||
import com.qqchen.deploy.backend.repository.IUserRepository;
|
import com.qqchen.deploy.backend.repository.IUserRepository;
|
||||||
import com.qqchen.deploy.backend.service.IUserService;
|
import com.qqchen.deploy.backend.service.IUserService;
|
||||||
import com.qqchen.deploy.backend.converter.RoleConverter;
|
import com.qqchen.deploy.backend.converter.RoleConverter;
|
||||||
import com.qqchen.deploy.backend.converter.UserConverter;
|
import com.qqchen.deploy.backend.model.UserDTO;
|
||||||
import com.qqchen.deploy.backend.dto.UserDTO;
|
import com.qqchen.deploy.backend.model.RoleDTO;
|
||||||
import com.qqchen.deploy.backend.dto.RoleDTO;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
@ -39,6 +40,9 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
|||||||
@Resource
|
@Resource
|
||||||
private RoleConverter roleConverter;
|
private RoleConverter roleConverter;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserConverter userConverter;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
@ -88,13 +92,8 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
|||||||
String token = jwtTokenUtil.generateToken(userDetails);
|
String token = jwtTokenUtil.generateToken(userDetails);
|
||||||
User user = userRepository.findByUsernameAndDeletedFalse(userDetails.getUsername())
|
User user = userRepository.findByUsernameAndDeletedFalse(userDetails.getUsername())
|
||||||
.orElseThrow(() -> new BusinessException(ResponseCode.USER_NOT_FOUND));
|
.orElseThrow(() -> new BusinessException(ResponseCode.USER_NOT_FOUND));
|
||||||
LoginResponse response = new LoginResponse();
|
|
||||||
response.setId(user.getId());
|
LoginResponse response = userConverter.toLoginResponse(user, token);
|
||||||
response.setUsername(user.getUsername());
|
|
||||||
response.setNickname(user.getNickname());
|
|
||||||
response.setEmail(user.getEmail());
|
|
||||||
response.setPhone(user.getPhone());
|
|
||||||
response.setToken(token);
|
|
||||||
log.info("用户 {} ({}) 登录成功", user.getUsername(), user.getNickname());
|
log.info("用户 {} ({}) 登录成功", user.getUsername(), user.getNickname());
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -129,4 +128,17 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
|||||||
public void changePassword(Long userId, String oldPassword, String newPassword) {
|
public void changePassword(Long userId, String oldPassword, String newPassword) {
|
||||||
// ... 密码修改逻辑 ...
|
// ... 密码修改逻辑 ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@Audited(action = "GET_CURRENT_USER", detail = "获取当前用户信息")
|
||||||
|
public LoginResponse getCurrentUser() {
|
||||||
|
String username = SecurityUtils.getCurrentUsername();
|
||||||
|
User user = userRepository.findByUsernameAndDeletedFalse(username)
|
||||||
|
.orElseThrow(() -> new BusinessException(ResponseCode.USER_NOT_FOUND));
|
||||||
|
|
||||||
|
LoginResponse response = userConverter.toLoginResponse(user);
|
||||||
|
log.debug("获取当前用户信息: {}", user.getUsername());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2,9 +2,9 @@ server:
|
|||||||
port: 8080
|
port: 8080
|
||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:mysql://127.0.0.1:3306/deploy-ease-platform?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
|
url: jdbc:mysql://192.168.1.111:3306/deploy-ease-platform?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
|
||||||
username: root
|
username: deploy-ease-platform
|
||||||
password: root
|
password: qichen5210523
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
@ -47,3 +47,10 @@ jwt:
|
|||||||
|
|
||||||
jackson:
|
jackson:
|
||||||
time-zone: Asia/Shanghai
|
time-zone: Asia/Shanghai
|
||||||
|
flyway:
|
||||||
|
enabled: true
|
||||||
|
baseline-on-migrate: true
|
||||||
|
locations: classpath:db/migration
|
||||||
|
table: flyway_schema_history
|
||||||
|
baseline-version: 0
|
||||||
|
validate-on-migrate: true
|
||||||
@ -34,3 +34,24 @@ CREATE TABLE IF NOT EXISTS sys_user (
|
|||||||
username VARCHAR(255) NOT NULL,
|
username VARCHAR(255) NOT NULL,
|
||||||
CONSTRAINT UK_user_username UNIQUE (username)
|
CONSTRAINT UK_user_username UNIQUE (username)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- 创建系统参数表
|
||||||
|
CREATE TABLE sys_param (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
create_by VARCHAR(255),
|
||||||
|
create_time DATETIME(6),
|
||||||
|
deleted BIT NOT NULL DEFAULT 0,
|
||||||
|
update_by VARCHAR(255),
|
||||||
|
update_time DATETIME(6),
|
||||||
|
version INT NOT NULL DEFAULT 0,
|
||||||
|
|
||||||
|
code VARCHAR(100) NOT NULL COMMENT '参数编码',
|
||||||
|
name VARCHAR(100) NOT NULL COMMENT '参数名称',
|
||||||
|
value TEXT COMMENT '参数值',
|
||||||
|
type VARCHAR(50) NOT NULL COMMENT '参数类型',
|
||||||
|
description VARCHAR(255) COMMENT '参数描述',
|
||||||
|
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用',
|
||||||
|
|
||||||
|
CONSTRAINT UK_sys_param_code UNIQUE (code)
|
||||||
|
) COMMENT '系统参数表';
|
||||||
|
|
||||||
@ -3,15 +3,24 @@ INSERT INTO sys_tenant
|
|||||||
(create_by, create_time, deleted, update_by, update_time, version,
|
(create_by, create_time, deleted, update_by, update_time, version,
|
||||||
address, code, contact_name, contact_phone, email, enabled, name)
|
address, code, contact_name, contact_phone, email, enabled, name)
|
||||||
VALUES
|
VALUES
|
||||||
('system', NOW(), 0, 'system', NOW(), 0,
|
('system', '2024-01-01 00:00:00', 0, 'system', '2024-01-01 00:00:00', 0,
|
||||||
'北京市朝阳区xxx街道', 'default', '张三', '13900000001', 'default@example.com', 1, '默认租户');
|
'北京市朝阳区望京SOHO T1 C座', 'default', '张三', '13900000001',
|
||||||
|
'admin@deploy-ease.com', 1, '默认租户');
|
||||||
|
|
||||||
-- 插入管理员用户
|
-- 插入管理员用户
|
||||||
INSERT INTO sys_user
|
INSERT INTO sys_user
|
||||||
(create_by, create_time, deleted, update_by, update_time, version,
|
(create_by, create_time, deleted, update_by, update_time, version,
|
||||||
email, enabled, nickname, password, phone, username)
|
email, enabled, nickname, password, phone, username)
|
||||||
VALUES
|
VALUES
|
||||||
('system', NOW(), 0, 'system', NOW(), 0,
|
('system', '2024-01-01 00:00:00', 0, 'system', '2024-01-01 00:00:00', 0,
|
||||||
'admin@example.com', 1, '系统管理员',
|
'admin@deploy-ease.com', 1, '系统管理员',
|
||||||
'$2a$10$mW/yJPHjyueQ1g82qWXg8eYqyUVNxFQPagkUvqtWPhKhqB8Z3Vw2y',
|
'$2a$10$B5qWUPyWyXxfm6Jq4JKcAOp/XcQLjtv3jifafsqPqZvzY9owae2ve', -- 密码: admin123
|
||||||
'13800138000', 'admin');
|
'13800138000', 'admin');
|
||||||
|
|
||||||
|
-- 系统参数初始化
|
||||||
|
INSERT INTO sys_param (code, name, value, type, description, enabled, create_by, create_time)
|
||||||
|
VALUES
|
||||||
|
('SYSTEM_NAME', '系统名称', 'DevOps平台', 'TEXT', '系统显示名称', 1, 'system', '2024-01-01 00:00:00'),
|
||||||
|
('SYSTEM_LOGO', '系统Logo', '/logo.png', 'TEXT', '系统Logo路径', 1, 'system', '2024-01-01 00:00:00'),
|
||||||
|
('GENDER_ENUM', '性别枚举', '[{"code":"1","name":"男"},{"code":"2","name":"女"}]', 'ENUM', '性别枚举值', 1, 'system', '2024-01-01 00:00:00'),
|
||||||
|
('USER_STATUS_ENUM', '用户状态枚举', '[{"code":"0","name":"禁用"},{"code":"1","name":"启用"}]', 'ENUM', '用户状态枚举值', 1, 'system', '2024-01-01 00:00:00');
|
||||||
Loading…
Reference in New Issue
Block a user