[tag] 初步实现除鉴权外的登录功能
This commit is contained in:
parent
914ab87beb
commit
f5188d8032
10
pom.xml
10
pom.xml
|
|
@ -78,6 +78,16 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
<version>0.9.1</version> <!-- 或者使用最新版本 -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.waterquality.projectmanagement.config;
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain
|
||||||
|
) throws ServletException, IOException {
|
||||||
|
// 1. 从请求头中获取 JWT Token
|
||||||
|
String token = resolveToken(request);
|
||||||
|
|
||||||
|
// 2. 验证 Token 是否有效
|
||||||
|
if (token != null && jwtTokenProvider.validateToken(token)) {
|
||||||
|
// 3. 如果 Token 有效,获取认证信息
|
||||||
|
Authentication authentication = jwtTokenProvider.getAuthentication(token);
|
||||||
|
|
||||||
|
// 4. 将认证信息设置到 SecurityContext 中
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 继续执行过滤器链
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从请求头中解析 JWT Token
|
||||||
|
private String resolveToken(HttpServletRequest request) {
|
||||||
|
String bearerToken = request.getHeader("Authorization");
|
||||||
|
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
||||||
|
return bearerToken.substring(7);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.waterquality.projectmanagement.config;
|
||||||
|
|
||||||
|
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
|
public class JwtConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||||
|
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
|
public JwtConfigurer(JwtTokenProvider jwtTokenProvider) {
|
||||||
|
this.jwtTokenProvider = jwtTokenProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(HttpSecurity http) {
|
||||||
|
JwtTokenFilter customFilter = new JwtTokenFilter(jwtTokenProvider);
|
||||||
|
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.waterquality.projectmanagement.config;
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class JwtTokenFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
|
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
|
||||||
|
this.jwtTokenProvider = jwtTokenProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
String token = resolveToken(request);
|
||||||
|
if (token != null && jwtTokenProvider.validateToken(token)) {
|
||||||
|
Authentication auth = jwtTokenProvider.getAuthentication(token);
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
|
}
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveToken(HttpServletRequest req) {
|
||||||
|
String bearerToken = req.getHeader("Authorization");
|
||||||
|
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
||||||
|
return bearerToken.substring(7);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.waterquality.projectmanagement.config;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import org.springframework.beans.factory.annotation.Value; // 确保导入这个
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import com.waterquality.projectmanagement.repository.EmployeeRepository; // 确保正确导入你的 EmployeeRepository
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtTokenProvider {
|
||||||
|
|
||||||
|
@Value("${jwt.secret}")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
@Value("${jwt.expiration}")
|
||||||
|
private long validityInMilliseconds;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmployeeRepository employeeRepository; // 添加 EmployeeRepository 的依赖注入
|
||||||
|
|
||||||
|
public String createToken(UserDetails userDetails) {
|
||||||
|
Claims claims = Jwts.claims().setSubject(userDetails.getUsername());
|
||||||
|
claims.put("roles", userDetails.getAuthorities().stream()
|
||||||
|
.map(GrantedAuthority::getAuthority)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
|
Date now = new Date();
|
||||||
|
Date validity = new Date(now.getTime() + validityInMilliseconds);
|
||||||
|
|
||||||
|
return Jwts.builder()
|
||||||
|
.setClaims(claims)
|
||||||
|
.setIssuedAt(now)
|
||||||
|
.setExpiration(validity)
|
||||||
|
.signWith(SignatureAlgorithm.HS256, secret)
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authentication getAuthentication(String token) {
|
||||||
|
UserDetails userDetails = (UserDetails) employeeRepository.findByUsername(getUsername(token))
|
||||||
|
.orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
|
||||||
|
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getUsername(String token) {
|
||||||
|
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateToken(String token) {
|
||||||
|
try {
|
||||||
|
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
|
||||||
|
return true; // 验证成功
|
||||||
|
} catch (io.jsonwebtoken.ExpiredJwtException e) {
|
||||||
|
// 处理过期的令牌
|
||||||
|
return false;
|
||||||
|
} catch (io.jsonwebtoken.SignatureException e) {
|
||||||
|
// 处理签名异常
|
||||||
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 处理其他异常
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 其他验证方法...
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.waterquality.projectmanagement.config;
|
||||||
|
|
||||||
|
import com.waterquality.projectmanagement.repository.EmployeeRepository;
|
||||||
|
import jakarta.servlet.Filter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@EnableMethodSecurity(prePostEnabled = true)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
private final EmployeeRepository employeeRepository;
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf(csrf -> csrf.disable())
|
||||||
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
|
.authorizeHttpRequests(authz -> authz
|
||||||
|
.requestMatchers("/api/auth/**").permitAll()
|
||||||
|
.anyRequest().authenticated())
|
||||||
|
.authenticationProvider(authenticationProvider())
|
||||||
|
.addFilterBefore((Filter) new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public UserDetailsService userDetailsService() {
|
||||||
|
return username -> (UserDetails) employeeRepository.findByUsername(username)
|
||||||
|
.orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationProvider authenticationProvider() {
|
||||||
|
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||||
|
authProvider.setUserDetailsService(userDetailsService());
|
||||||
|
authProvider.setPasswordEncoder(passwordEncoder());
|
||||||
|
return authProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||||
|
return config.getAuthenticationManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.waterquality.projectmanagement.controller;
|
||||||
|
|
||||||
|
// 明文密码,请注意
|
||||||
|
|
||||||
|
import com.waterquality.projectmanagement.config.JwtTokenProvider;
|
||||||
|
import com.waterquality.projectmanagement.dto.login.AuthResponse;
|
||||||
|
import com.waterquality.projectmanagement.dto.login.LoginDTO;
|
||||||
|
import com.waterquality.projectmanagement.entity.employee.Employee;
|
||||||
|
import com.waterquality.projectmanagement.repository.EmployeeRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/auth")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final AuthenticationManager authenticationManager;
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
private final EmployeeRepository employeeRepository;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public ResponseEntity<?> login(@Valid @RequestBody LoginDTO dto) {
|
||||||
|
try {
|
||||||
|
// 查找用户
|
||||||
|
Employee employee = (Employee) employeeRepository.findByUsername(dto.getUsername())
|
||||||
|
.orElseThrow(() -> new BadCredentialsException("用户不存在"));
|
||||||
|
|
||||||
|
// 检查密码是否匹配
|
||||||
|
if (!employee.getPassword().equals(dto.getPassword())) {
|
||||||
|
log.error("登录失败 - 无效凭证: {},原因: Bad credentials", dto.getUsername());
|
||||||
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查账号状态(可选)
|
||||||
|
if (!employee.isEnabled()) {
|
||||||
|
log.warn("尝试登录的账号已被禁用: {}", dto.getUsername());
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("账号已被禁用");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成token
|
||||||
|
String token = jwtTokenProvider.createToken(employee);
|
||||||
|
|
||||||
|
// 返回认证响应
|
||||||
|
return ResponseEntity.ok(new AuthResponse(
|
||||||
|
token,
|
||||||
|
employee.getEmployeeId(),
|
||||||
|
employee.getName(),
|
||||||
|
employee.getPosition().name()
|
||||||
|
));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("登录过程中发生未知错误,用户: {},异常信息: {}", dto.getUsername(), e.getMessage(), e);
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("系统错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,11 @@ package com.waterquality.projectmanagement.controller;
|
||||||
|
|
||||||
import com.waterquality.projectmanagement.Response;
|
import com.waterquality.projectmanagement.Response;
|
||||||
import com.waterquality.projectmanagement.dto.order.*;
|
import com.waterquality.projectmanagement.dto.order.*;
|
||||||
|
import com.waterquality.projectmanagement.entity.employee.CustomUserDetails;
|
||||||
import com.waterquality.projectmanagement.entity.order.WorkOrderStatus;
|
import com.waterquality.projectmanagement.entity.order.WorkOrderStatus;
|
||||||
import com.waterquality.projectmanagement.service.WorkOrderService;
|
import com.waterquality.projectmanagement.service.WorkOrderService;
|
||||||
import lombok.*;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.catalina.User;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.web.PageableDefault;
|
import org.springframework.data.web.PageableDefault;
|
||||||
|
|
@ -31,9 +32,10 @@ public class WorkOrderController {
|
||||||
@PreAuthorize("hasRole('MAINTENANCE')")
|
@PreAuthorize("hasRole('MAINTENANCE')")
|
||||||
public ResponseEntity<Response<WorkOrderVO>> createOrder(
|
public ResponseEntity<Response<WorkOrderVO>> createOrder(
|
||||||
@Valid @RequestBody WorkOrderCreateDTO dto,
|
@Valid @RequestBody WorkOrderCreateDTO dto,
|
||||||
@AuthenticationPrincipal User user) {
|
@AuthenticationPrincipal UserDetails user) {
|
||||||
|
// 假设 UserDetails 实现了 getUsername() 方法返回用户 ID
|
||||||
return ResponseEntity.ok(Response.newSuccess(
|
return ResponseEntity.ok(Response.newSuccess(
|
||||||
workOrderService.createOrder(dto, user.getId())));
|
workOrderService.createOrder(dto, Integer.valueOf(user.getUsername()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/{id}/status")
|
@PatchMapping("/{id}/status")
|
||||||
|
|
@ -48,10 +50,10 @@ public class WorkOrderController {
|
||||||
@GetMapping("/my-orders")
|
@GetMapping("/my-orders")
|
||||||
public ResponseEntity<Response<Page<WorkOrderVO>>> getMyOrders(
|
public ResponseEntity<Response<Page<WorkOrderVO>>> getMyOrders(
|
||||||
@RequestParam(required = false) Set<WorkOrderStatus> statuses,
|
@RequestParam(required = false) Set<WorkOrderStatus> statuses,
|
||||||
@AuthenticationPrincipal User user,
|
@AuthenticationPrincipal CustomUserDetails user,
|
||||||
@PageableDefault Pageable pageable) {
|
@PageableDefault Pageable pageable) {
|
||||||
return ResponseEntity.ok(Response.newSuccess(
|
return ResponseEntity.ok(Response.newSuccess(
|
||||||
workOrderService.getOrdersByAssignee(user.getId(),
|
workOrderService.getOrdersByAssignee(user.getUserID(),
|
||||||
statuses != null ? statuses : EnumSet.allOf(WorkOrderStatus.class),
|
statuses != null ? statuses : EnumSet.allOf(WorkOrderStatus.class),
|
||||||
pageable)));
|
pageable)));
|
||||||
}
|
}
|
||||||
|
|
@ -14,6 +14,8 @@ public class EmployeeDTO {
|
||||||
private String contact_phone;
|
private String contact_phone;
|
||||||
private Status status;
|
private Status status;
|
||||||
private Integer department; // 可以考虑使用简化的部门信息
|
private Integer department; // 可以考虑使用简化的部门信息
|
||||||
|
private String password;
|
||||||
|
private String username;
|
||||||
|
|
||||||
// 可以根据需要添加其他字段
|
// 可以根据需要添加其他字段
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.waterquality.projectmanagement.dto.login;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
// AuthResponse.java
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AuthResponse {
|
||||||
|
private String token;
|
||||||
|
private Integer employeeId;
|
||||||
|
private String name;
|
||||||
|
private String position;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.waterquality.projectmanagement.dto.login;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
// LoginDTO.java
|
||||||
|
@Data
|
||||||
|
public class LoginDTO {
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ import java.time.LocalDateTime;
|
||||||
@Data
|
@Data
|
||||||
public class InspectionPlanVO {
|
public class InspectionPlanVO {
|
||||||
private Integer planId;
|
private Integer planId;
|
||||||
private String employeeName;
|
private Integer employeeId;
|
||||||
private String area;
|
private String area;
|
||||||
private LocalDateTime plannedTime;
|
private LocalDateTime plannedTime;
|
||||||
private PlanStatus status;
|
private PlanStatus status;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.waterquality.projectmanagement.entity.employee;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
public interface CustomUserDetails extends UserDetails {
|
||||||
|
Integer getUserID();
|
||||||
|
String getUsername();
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,16 @@ package com.waterquality.projectmanagement.entity.employee;
|
||||||
import com.waterquality.projectmanagement.entity.department.Department;
|
import com.waterquality.projectmanagement.entity.department.Department;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "employees")
|
@Table(name = "employees")
|
||||||
@Data
|
@Data
|
||||||
public class Employee {
|
public class Employee implements CustomUserDetails {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "employee_id")
|
@Column(name = "employee_id")
|
||||||
|
|
@ -31,6 +36,40 @@ public class Employee {
|
||||||
@Column(name = "department_id")
|
@Column(name = "department_id")
|
||||||
private Integer department;
|
private Integer department;
|
||||||
|
|
||||||
|
// login
|
||||||
|
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
// 实现 UserDetails 接口方法
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + position.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() { return true; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() { return true; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() { return true; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() { return status == Status.ACTIVE; }
|
||||||
|
|
||||||
|
// 实现 getUserID 方法
|
||||||
|
@Override
|
||||||
|
public Integer getUserID() {
|
||||||
|
return employeeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return name; // 返回用户名
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,10 +14,13 @@ public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
|
||||||
|
|
||||||
// 根据工号查询
|
// 根据工号查询
|
||||||
Optional<Employee> findByEmployeeNo(String employeeNo);
|
Optional<Employee> findByEmployeeNo(String employeeNo);
|
||||||
|
|
||||||
Employee findEmployeeByEmployeeId(Integer employeeId);
|
Employee findEmployeeByEmployeeId(Integer employeeId);
|
||||||
|
|
||||||
// 按部门查询在职员工
|
// 按部门查询在职员工
|
||||||
List<Employee> findByDepartmentAndStatus(Department department, Status status);
|
List<Employee> findByDepartmentAndStatus(Department department, Status status);
|
||||||
|
|
||||||
Page<Employee> findByDepartment(Department department, Pageable pageable);
|
Page<Employee> findByDepartment(Department department, Pageable pageable);
|
||||||
|
|
||||||
|
Optional<Object> findByUsername(String username);
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +25,8 @@ public class EmployeeService {
|
||||||
public Employee createEmployee(EmployeeDTO dto) {
|
public Employee createEmployee(EmployeeDTO dto) {
|
||||||
Employee employee = new Employee();
|
Employee employee = new Employee();
|
||||||
BeanUtils.copyProperties(dto, employee);
|
BeanUtils.copyProperties(dto, employee);
|
||||||
|
employee.setUsername(dto.getEmployeeNo());
|
||||||
|
employee.setPassword("114514");
|
||||||
return employeeRepository.save(employee);
|
return employeeRepository.save(employee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ public class InspectionPlanService {
|
||||||
private InspectionPlanVO convertToVO(InspectionPlan plan) {
|
private InspectionPlanVO convertToVO(InspectionPlan plan) {
|
||||||
InspectionPlanVO vo = new InspectionPlanVO();
|
InspectionPlanVO vo = new InspectionPlanVO();
|
||||||
vo.setPlanId(plan.getPlanId());
|
vo.setPlanId(plan.getPlanId());
|
||||||
vo.setEmployeeName(plan.getEmployee().getName());
|
vo.setEmployeeId(plan.getEmployee().getEmployeeId());
|
||||||
vo.setArea(plan.getArea());
|
vo.setArea(plan.getArea());
|
||||||
vo.setPlannedTime(plan.getPlannedTime());
|
vo.setPlannedTime(plan.getPlannedTime());
|
||||||
vo.setStatus(plan.getStatus());
|
vo.setStatus(plan.getStatus());
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ spring.datasource.username=root
|
||||||
spring.datasource.password=tju1895
|
spring.datasource.password=tju1895
|
||||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
|
|
||||||
|
jwt.secret=your_secret_key
|
||||||
|
jwt.expiration=3600000
|
||||||
|
|
||||||
|
|
||||||
server.port=8080
|
server.port=8080
|
||||||
Loading…
Reference in New Issue