可正常启动
This commit is contained in:
parent
00de9c57cb
commit
c913ab3cc5
@ -1,33 +1,36 @@
|
||||
//package com.qqchen.deploy.backend.api;
|
||||
//
|
||||
//import com.qqchen.deploy.backend.framework.api.Response;
|
||||
//import com.qqchen.deploy.backend.framework.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;
|
||||
// }
|
||||
//
|
||||
package com.qqchen.deploy.backend.api;
|
||||
|
||||
import com.qqchen.deploy.backend.dto.TenantDTO;
|
||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||
import com.qqchen.deploy.backend.dto.query.TenantQuery;
|
||||
import com.qqchen.deploy.backend.entity.Tenant;
|
||||
import com.qqchen.deploy.backend.service.ITenantService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/tenant")
|
||||
public class TenantApiController extends BaseController<Tenant, TenantDTO, Long, TenantQuery> {
|
||||
|
||||
protected final ITenantService service;
|
||||
|
||||
public TenantApiController(ITenantService service) {
|
||||
super(service);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exportData(HttpServletResponse response, List<TenantDTO> data) {
|
||||
|
||||
}
|
||||
|
||||
// @GetMapping("/code/{code}")
|
||||
// public Response<TenantResponse> findByCode(@PathVariable String code) {
|
||||
// Tenant tenant = service.findByCode(code);
|
||||
// return Response.success(converter.toResponse(tenant));
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.qqchen.deploy.backend.dto.response;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.dto.BaseResponse;
|
||||
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;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.qqchen.deploy.backend.framework.audit;
|
||||
|
||||
import lombok.Data;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class AuditMetadata {
|
||||
private String operator; // 操作人
|
||||
private String action; // 操作类型(CREATE/UPDATE/DELETE)
|
||||
private String entityType; // 实体类型
|
||||
private String entityId; // 实体ID
|
||||
private String detail; // 操作详情
|
||||
private LocalDateTime timestamp; // 操作时间
|
||||
private String ip; // 操作IP
|
||||
private String tenantId; // 租户ID
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.qqchen.deploy.backend.framework.audit.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Audited {
|
||||
String action() default "";
|
||||
String detail() default "";
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.qqchen.deploy.backend.framework.audit.aspect;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.audit.AuditMetadata;
|
||||
import com.qqchen.deploy.backend.framework.audit.annotation.Audited;
|
||||
import com.qqchen.deploy.backend.framework.audit.event.AuditEvent;
|
||||
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class AuditAspect {
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Around("@annotation(com.qqchen.deploy.backend.framework.audit.annotation.Audited)")
|
||||
public Object auditMethod(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
// 获取审计元数据
|
||||
AuditMetadata metadata = extractAuditMetadata(joinPoint);
|
||||
|
||||
try {
|
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed();
|
||||
|
||||
// 发布审计事件
|
||||
eventPublisher.publishEvent(new AuditEvent(this, metadata));
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
// 记录异常信息
|
||||
metadata.setDetail(metadata.getDetail() + " [Error: " + e.getMessage() + "]");
|
||||
eventPublisher.publishEvent(new AuditEvent(this, metadata));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private AuditMetadata extractAuditMetadata(ProceedingJoinPoint joinPoint) {
|
||||
AuditMetadata metadata = new AuditMetadata();
|
||||
|
||||
// 设置基本信息
|
||||
metadata.setOperator(SecurityUtils.getCurrentUsername());
|
||||
metadata.setTimestamp(LocalDateTime.now());
|
||||
// metadata.setTenantId(SecurityUtils.getCurrentTenantId());
|
||||
|
||||
// 设置IP地址
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
|
||||
.getRequestAttributes()).getRequest();
|
||||
metadata.setIp(getClientIp(request));
|
||||
|
||||
// 获取方法上的注解信息
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Audited audited = signature.getMethod().getAnnotation(Audited.class);
|
||||
|
||||
metadata.setAction(audited.action());
|
||||
metadata.setDetail(audited.detail());
|
||||
|
||||
// 设置实体信息
|
||||
String className = joinPoint.getTarget().getClass().getSimpleName();
|
||||
metadata.setEntityType(className.replace("ServiceImpl", ""));
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private String getClientIp(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.qqchen.deploy.backend.framework.audit.event;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.audit.AuditMetadata;
|
||||
import lombok.Getter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
@Getter
|
||||
public class AuditEvent extends ApplicationEvent {
|
||||
private final AuditMetadata metadata;
|
||||
|
||||
public AuditEvent(Object source, AuditMetadata metadata) {
|
||||
super(source);
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.qqchen.deploy.backend.framework.audit.listener;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.audit.event.AuditEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AuditEventListener {
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void handleAuditEvent(AuditEvent event) {
|
||||
// 这里可以将审计信息保存到数据库或发送到日志系统
|
||||
log.info("Audit: {} performed {} on {} (ID: {}) at {}, detail: {}",
|
||||
event.getMetadata().getOperator(),
|
||||
event.getMetadata().getAction(),
|
||||
event.getMetadata().getEntityType(),
|
||||
event.getMetadata().getEntityId(),
|
||||
event.getMetadata().getTimestamp(),
|
||||
event.getMetadata().getDetail()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -10,8 +10,4 @@ import java.util.Optional;
|
||||
public interface IUserRepository extends IBaseRepository<User, Long> {
|
||||
|
||||
Optional<User> findByUsernameAndDeletedFalse(String username);
|
||||
|
||||
boolean existsByUsername(String username);
|
||||
|
||||
boolean existsByEmail(String email);
|
||||
}
|
||||
@ -1,12 +1,14 @@
|
||||
package com.qqchen.deploy.backend.service;
|
||||
|
||||
import com.qqchen.deploy.backend.dto.UserDTO;
|
||||
import com.qqchen.deploy.backend.framework.audit.annotation.Audited;
|
||||
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||
import com.qqchen.deploy.backend.dto.request.LoginRequest;
|
||||
import com.qqchen.deploy.backend.dto.response.LoginResponse;
|
||||
import com.qqchen.deploy.backend.entity.User;
|
||||
import com.qqchen.deploy.backend.dto.request.UserRequest;
|
||||
import com.qqchen.deploy.backend.dto.RoleDTO;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -17,4 +19,8 @@ public interface IUserService extends IBaseService<User, UserDTO, Long> {
|
||||
boolean checkEmailExists(String email);
|
||||
List<RoleDTO> getUserRoles(Long userId);
|
||||
List<RoleDTO> getCurrentUserRoles();
|
||||
|
||||
@Transactional(readOnly = false)
|
||||
@Audited(action = "CHANGE_PASSWORD", detail = "修改密码")
|
||||
void changePassword(Long userId, String oldPassword, String newPassword);
|
||||
}
|
||||
@ -18,8 +18,8 @@ public class TenantServiceImpl extends BaseServiceImpl<Tenant, TenantDTO, Long>
|
||||
super(repository, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TenantDTO> findAll(BaseQuery query) {
|
||||
return null;
|
||||
}
|
||||
// @Override
|
||||
// public List<TenantDTO> findAll(BaseQuery query) {
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
@ -1,9 +1,8 @@
|
||||
package com.qqchen.deploy.backend.service.impl;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.audit.annotation.Audited;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
||||
import com.qqchen.deploy.backend.framework.security.util.JwtTokenUtil;
|
||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||
import com.qqchen.deploy.backend.dto.request.LoginRequest;
|
||||
@ -39,6 +38,9 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
||||
@Resource
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Resource
|
||||
private IUserRepository userRepository;
|
||||
|
||||
@Resource
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
@ -50,6 +52,7 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = false)
|
||||
@Audited(action = "REGISTER", detail = "用户注册")
|
||||
public UserDTO register(UserRequest request) {
|
||||
if (checkUsernameExists(request.getUsername())) {
|
||||
throw new BusinessException(ResponseCode.USERNAME_EXISTS);
|
||||
@ -63,7 +66,6 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
||||
userDTO.setEmail(request.getEmail());
|
||||
userDTO.setNickname(request.getNickname());
|
||||
userDTO.setPhone(request.getPhone());
|
||||
|
||||
return create(userDTO);
|
||||
}
|
||||
|
||||
@ -79,28 +81,28 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
@Audited(action = "USER_LOGIN", detail = "登录")
|
||||
public LoginResponse login(LoginRequest request) {
|
||||
// Authentication authentication = authenticationManager.authenticate(
|
||||
// new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
|
||||
// );
|
||||
//
|
||||
// UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
||||
// String token = jwtTokenUtil.generateToken(userDetails);
|
||||
//
|
||||
// User user = repository.findByUsernameAndDeletedFalse(userDetails.getUsername())
|
||||
// .orElseThrow(() -> new BusinessException(ResponseCode.USER_NOT_FOUND));
|
||||
//
|
||||
// LoginResponse response = new LoginResponse();
|
||||
// response.setId(user.getId());
|
||||
// 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());
|
||||
// return response;
|
||||
return null;
|
||||
Authentication authentication = authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
|
||||
);
|
||||
|
||||
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
||||
String token = jwtTokenUtil.generateToken(userDetails);
|
||||
|
||||
User user = userRepository.findByUsernameAndDeletedFalse(userDetails.getUsername())
|
||||
.orElseThrow(() -> new BusinessException(ResponseCode.USER_NOT_FOUND));
|
||||
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.setId(user.getId());
|
||||
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());
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,4 +128,11 @@ public class UserServiceImpl extends BaseServiceImpl<User, UserDTO, Long> implem
|
||||
// public List<UserDTO> findAll(BaseQuery query) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = false)
|
||||
@Audited(action = "CHANGE_PASSWORD", detail = "修改密码")
|
||||
public void changePassword(Long userId, String oldPassword, String newPassword) {
|
||||
// ... 密码修改逻辑 ...
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user