diff --git a/backend/src/main/java/com/bycrm/dto/LoginDTO.java b/backend/src/main/java/com/bycrm/dto/LoginDTO.java index c42d459..137bff4 100644 --- a/backend/src/main/java/com/bycrm/dto/LoginDTO.java +++ b/backend/src/main/java/com/bycrm/dto/LoginDTO.java @@ -24,4 +24,9 @@ public class LoginDTO implements Serializable { */ @NotBlank(message = "密码不能为空") private String password; + + /** + * 记住我(true 时签发 7 天有效期的 token) + */ + private Boolean rememberMe = false; } diff --git a/backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java index aa4144a..bbb283a 100644 --- a/backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java @@ -46,6 +46,10 @@ public class UserServiceImpl implements UserService { throw new BusinessException("用户名或密码错误"); } + if (Boolean.TRUE.equals(loginDTO.getRememberMe())) { + return jwtUtil.generateToken(user.getId(), user.getUsername(), user.getRole(), + user.getDealerId(), jwtUtil.getRememberExpiration()); + } return jwtUtil.generateToken(user.getId(), user.getUsername(), user.getRole(), user.getDealerId()); } diff --git a/backend/src/main/java/com/bycrm/util/JwtUtil.java b/backend/src/main/java/com/bycrm/util/JwtUtil.java index 85b099a..fedabc7 100644 --- a/backend/src/main/java/com/bycrm/util/JwtUtil.java +++ b/backend/src/main/java/com/bycrm/util/JwtUtil.java @@ -25,24 +25,45 @@ public class JwtUtil { @Value("${jwt.expiration}") private Long expiration; + @Value("${jwt.remember-expiration:604800000}") + private Long rememberExpiration; + + public Long getRememberExpiration() { + return rememberExpiration; + } + /** * 生成 Token */ public String generateToken(Long userId, String username, Integer role, Long dealerId) { + return generateToken(userId, username, role, dealerId, expiration); + } + + /** + * 生成指定有效期的 Token(用于"记住我"延长有效期) + */ + public String generateToken(Long userId, String username, Integer role, Long dealerId, long expirationMillis) { Map claims = new HashMap<>(); claims.put("userId", userId); claims.put("username", username); claims.put("role", role); claims.put("dealerId", dealerId); - return generateToken(claims); + return generateToken(claims, expirationMillis); } /** * 生成 Token */ public String generateToken(Map claims) { + return generateToken(claims, expiration); + } + + /** + * 生成指定有效期的 Token + */ + public String generateToken(Map claims, long expirationMillis) { Date now = new Date(); - Date expiryDate = new Date(now.getTime() + expiration); + Date expiryDate = new Date(now.getTime() + expirationMillis); return Jwts.builder() .setClaims(claims) diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index bd0810d..a252a16 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -58,6 +58,7 @@ jwt: # 生产环境请使用环境变量或密钥管理系统存储此密钥 secret: by-crm-jwt-secret-key-2024-hs512-requires-at-least-64-bytes-for-secure-signing-please-change-in-production-environment expiration: 86400000 # 24小时,单位:毫秒 + remember-expiration: 604800000 # 记住我:7天免登录,单位:毫秒 # CRM 业务配置 crm: diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 221dafb..50454ce 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -14,6 +14,7 @@ export interface User { export interface LoginRequest { username: string password: string + rememberMe?: boolean } export interface LoginResponse { diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue index 98eedf7..8d31592 100644 --- a/frontend/src/views/Login.vue +++ b/frontend/src/views/Login.vue @@ -21,6 +21,9 @@ @keyup.enter="handleLogin" /> + + 记住我(7天免登录) +