培训管理子系统开发1
整个项目预期的任务量 (任务量 = 所有工作的预期时间10天)和 目前已经花的时间 (所有记录的 ‘已经花费的时间’1天),还剩余的时间(所有工作的 ‘剩余时间’9天)
实现管理员和员工注册登录功能
代码实现:
package com.example.training.entity;
import javax.persistence.*;
@Entity
@Table(name = "user")
public class User {
// 内部枚举定义
public enum Role {
ADMIN, EMPLOYEE
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true)
private String name;
private String password;
@Enumerated(EnumType.STRING)
private Role role;
// 构造方法
public User() {}
public User(String name, String password, Role role) {
this.name = name;
this.password = password;
this.role = role;
}
// Getter和Setter
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
package com.example.training.service;
import com.example.training.entity.User;
import com.example.training.repository.UserRepository;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User register(String name, String password,User.Role role) {
if (userRepository.findByName(name) != null) {
throw new RuntimeException("用户名已存在");
}
User user = new User();
user.setName(name);
user.setPassword(password);
user.setRole(role);
return userRepository.save(user);
}
public User login(String name, String password) {
User user = userRepository.findByName(name);
if (user == null || !user.getPassword().equals(password)) {
throw new RuntimeException("用户名或密码错误");
}
return user;
}
}
package com.example.training.controller;
import com.example.training.entity.User;
import com.example.training.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
@Controller
public class AuthController {
private final UserService userService;
public AuthController(UserService userService) {
this.userService = userService;
}
@GetMapping("/")
public String home() {
return "redirect:/login";
}
@GetMapping("/login")
public String showLoginForm() {
return "login";
}
@PostMapping("/login")
public String login(@RequestParam String name,
@RequestParam String password,
HttpSession session,
Model model) {
try {
User user = userService.login(name, password);
session.setAttribute("user", user);
// 根据角色跳转不同页面
if (user.getRole() == User.Role.ADMIN) {
return "redirect:/admin/dashboard";
}
// 普通员工跳转到工作台页面(需要后续开发)
return "redirect:/employee/dashboard";
} catch (Exception e) {
model.addAttribute("error", e.getMessage());
return "login";
}
}
@GetMapping("/register")
public String showRegisterForm() {
return "register";
}
@PostMapping("/register")
public String register(@RequestParam String name,
@RequestParam String password,
@RequestParam User.Role role,
Model model) {
try {
userService.register(name, password, role);
model.addAttribute("message", "注册成功,请登录!");
return "redirect:/login";
} catch (Exception e) {
model.addAttribute("error", e.getMessage());
return "register";
}
}
@GetMapping("/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/login";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>登录</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.login-container {
background: rgba(255, 255, 255, 0.95);
padding: 2.5rem;
border-radius: 12px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 400px;
transition: transform 0.3s ease;
}
h2 {
color: #1e3c72;
text-align: center;
margin-bottom: 2rem;
font-size: 1.8rem;
border-bottom: 2px solid #1e3c72;
padding-bottom: 1rem;
}
form {
display: flex;
flex-direction: column;
gap: 1.2rem;
}
input {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 6px;
font-size: 1rem;
transition: border-color 0.3s ease;
}
input:focus {
outline: none;
border-color: #1e3c72;
}
button {
background: #1e3c72;
color: white;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
}
button:hover {
background: #2a5298;
}
.register-link {
text-align: center;
margin-top: 1.5rem;
color: #1e3c72;
}
.register-link a {
color: #2a5298;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
}
.register-link a:hover {
color: #1e3c72;
text-decoration: underline;
}
.error-message {
background: #ffebee;
color: #c62828;
padding: 12px;
border-radius: 6px;
margin-bottom: 1.5rem;
text-align: center;
border: 1px solid #ffcdd2;
}
</style>
</head>
<body>
<div class="login-container">
<h2>培训管理子系统</h2>
<!-- 显示错误信息 -->
<div th:if="${error}" class="error-message" th:text="${error}"></div>
<form th:action="@{/login}" method="post">
<input type="text" name="name" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">立即登录</button>
</form>
<div class="register-link">
<p>没有账号?<a th:href="@{/register}">立即注册</a></p>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>注册</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.register-container {
background: rgba(255, 255, 255, 0.95);
padding: 2.5rem;
border-radius: 12px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 400px;
}
h2 {
color: #1e3c72;
text-align: center;
margin-bottom: 1.5rem;
font-size: 1.8rem;
border-bottom: 2px solid #1e3c72;
padding-bottom: 1rem;
}
form {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
label {
color: #1e3c72;
font-weight: 600;
font-size: 0.9rem;
}
input, select {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 6px;
font-size: 1rem;
transition: all 0.3s ease;
}
input:focus, select:focus {
outline: none;
border-color: #1e3c72;
box-shadow: 0 0 5px rgba(30, 60, 114, 0.2);
}
button {
background: #1e3c72;
color: white;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
margin-top: 1rem;
}
button:hover {
background: #2a5298;
}
.login-link {
text-align: center;
margin-top: 1.5rem;
}
.login-link a {
color: #2a5298;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
}
.login-link a:hover {
color: #1e3c72;
text-decoration: underline;
}
.alert {
padding: 12px;
border-radius: 6px;
margin-bottom: 1.5rem;
text-align: center;
border: 1px solid transparent;
}
.alert-success {
background: #e8f5e9;
color: #2e7d32;
border-color: #c8e6c9;
}
.alert-error {
background: #ffebee;
color: #c62828;
border-color: #ffcdd2;
}
</style>
</head>
<body>
<div class="register-container">
<h2>培训管理子系统</h2>
<!-- 消息提示 -->
<div th:if="${message}" class="alert alert-success" th:text="${message}"></div>
<div th:if="${error}" class="alert alert-error" th:text="${error}"></div>
<form th:action="@{/register}" method="post">
<div class="form-group">
<label>用户名:</label>
<input type="text" name="name" required>
</div>
<div class="form-group">
<label>密码:</label>
<input type="password" name="password" required>
</div>
<div class="form-group">
<label>身份:</label>
<select name="role">
<option value="ADMIN">管理员</option>
<option value="EMPLOYEE">员工</option>
</select>
</div>
<button type="submit">立即注册</button>
</form>
<div class="login-link">
<a th:href="@{/login}">已有账号?去登录</a>
</div>
</div>
</body>package com.example.training.entity;
import javax.persistence.*;
@Entity
@Table(name = "user")
public class User {
// 内部枚举定义
public enum Role {
ADMIN, EMPLOYEE
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true)
private String name;
private String password;
@Enumerated(EnumType.STRING)
private Role role;
// 构造方法
public User() {}
public User(String name, String password, Role role) {
this.name = name;
this.password = password;
this.role = role;
}
// Getter和Setter
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
package com.example.training.service;
import com.example.training.entity.User;
import com.example.training.repository.UserRepository;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User register(String name, String password,User.Role role) {
if (userRepository.findByName(name) != null) {
throw new RuntimeException("用户名已存在");
}
User user = new User();
user.setName(name);
user.setPassword(password);
user.setRole(role);
return userRepository.save(user);
}
public User login(String name, String password) {
User user = userRepository.findByName(name);
if (user == null || !user.getPassword().equals(password)) {
throw new RuntimeException("用户名或密码错误");
}
return user;
}
}
package com.example.training.controller;
import com.example.training.entity.User;
import com.example.training.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
@Controller
public class AuthController {
private final UserService userService;
public AuthController(UserService userService) {
this.userService = userService;
}
@GetMapping("/")
public String home() {
return "redirect:/login";
}
@GetMapping("/login")
public String showLoginForm() {
return "login";
}
@PostMapping("/login")
public String login(@RequestParam String name,
@RequestParam String password,
HttpSession session,
Model model) {
try {
User user = userService.login(name, password);
session.setAttribute("user", user);
// 根据角色跳转不同页面
if (user.getRole() == User.Role.ADMIN) {
return "redirect:/admin/dashboard";
}
// 普通员工跳转到工作台页面(需要后续开发)
return "redirect:/employee/dashboard";
} catch (Exception e) {
model.addAttribute("error", e.getMessage());
return "login";
}
}
@GetMapping("/register")
public String showRegisterForm() {
return "register";
}
@PostMapping("/register")
public String register(@RequestParam String name,
@RequestParam String password,
@RequestParam User.Role role,
Model model) {
try {
userService.register(name, password, role);
model.addAttribute("message", "注册成功,请登录!");
return "redirect:/login";
} catch (Exception e) {
model.addAttribute("error", e.getMessage());
return "register";
}
}
@GetMapping("/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/login";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>登录</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.login-container {
background: rgba(255, 255, 255, 0.95);
padding: 2.5rem;
border-radius: 12px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 400px;
transition: transform 0.3s ease;
}
h2 {
color: #1e3c72;
text-align: center;
margin-bottom: 2rem;
font-size: 1.8rem;
border-bottom: 2px solid #1e3c72;
padding-bottom: 1rem;
}
form {
display: flex;
flex-direction: column;
gap: 1.2rem;
}
input {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 6px;
font-size: 1rem;
transition: border-color 0.3s ease;
}
input:focus {
outline: none;
border-color: #1e3c72;
}
button {
background: #1e3c72;
color: white;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
}
button:hover {
background: #2a5298;
}
.register-link {
text-align: center;
margin-top: 1.5rem;
color: #1e3c72;
}
.register-link a {
color: #2a5298;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
}
.register-link a:hover {
color: #1e3c72;
text-decoration: underline;
}
.error-message {
background: #ffebee;
color: #c62828;
padding: 12px;
border-radius: 6px;
margin-bottom: 1.5rem;
text-align: center;
border: 1px solid #ffcdd2;
}
</style>
</head>
<body>
<div class="login-container">
<h2>培训管理子系统</h2>
<!-- 显示错误信息 -->
<div th:if="${error}" class="error-message" th:text="${error}"></div>
<form th:action="@{/login}" method="post">
<input type="text" name="name" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">立即登录</button>
</form>
<div class="register-link">
<p>没有账号?<a th:href="@{/register}">立即注册</a></p>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>注册</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.register-container {
background: rgba(255, 255, 255, 0.95);
padding: 2.5rem;
border-radius: 12px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 400px;
}
h2 {
color: #1e3c72;
text-align: center;
margin-bottom: 1.5rem;
font-size: 1.8rem;
border-bottom: 2px solid #1e3c72;
padding-bottom: 1rem;
}
form {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
label {
color: #1e3c72;
font-weight: 600;
font-size: 0.9rem;
}
input, select {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 6px;
font-size: 1rem;
transition: all 0.3s ease;
}
input:focus, select:focus {
outline: none;
border-color: #1e3c72;
box-shadow: 0 0 5px rgba(30, 60, 114, 0.2);
}
button {
background: #1e3c72;
color: white;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
margin-top: 1rem;
}
button:hover {
background: #2a5298;
}
.login-link {
text-align: center;
margin-top: 1.5rem;
}
.login-link a {
color: #2a5298;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
}
.login-link a:hover {
color: #1e3c72;
text-decoration: underline;
}
.alert {
padding: 12px;
border-radius: 6px;
margin-bottom: 1.5rem;
text-align: center;
border: 1px solid transparent;
}
.alert-success {
background: #e8f5e9;
color: #2e7d32;
border-color: #c8e6c9;
}
.alert-error {
background: #ffebee;
color: #c62828;
border-color: #ffcdd2;
}
</style>
</head>
<body>
<div class="register-container">
<h2>培训管理子系统</h2>
<!-- 消息提示 -->
<div th:if="${message}" class="alert alert-success" th:text="${message}"></div>
<div th:if="${error}" class="alert alert-error" th:text="${error}"></div>
<form th:action="@{/register}" method="post">
<div class="form-group">
<label>用户名:</label>
<input type="text" name="name" required>
</div>
<div class="form-group">
<label>密码:</label>
<input type="password" name="password" required>
</div>
<div class="form-group">
<label>身份:</label>
<select name="role">
<option value="ADMIN">管理员</option>
<option value="EMPLOYEE">员工</option>
</select>
</div>
<button type="submit">立即注册</button>
</form>
<div class="login-link">
<a th:href="@{/login}">已有账号?去登录</a>
</div>
</div>
</body>
</html>
</html>