强制学号登录;适配Home界面

This commit is contained in:
Saturneric 2020-02-16 17:41:40 +08:00
parent 00d626d394
commit 62cb783b31
13 changed files with 518 additions and 38 deletions

View File

@ -0,0 +1,66 @@
package com.codesdream.ase.component;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
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.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
@Component
public class ASESecurityAuthenticationProvider implements AuthenticationProvider {
@Resource
UserDetailsService userDetailsService;
@Resource
ASEUsernameEncoder usernameEncoder;
@Resource
PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 获得登录表单中的学号
String username = usernameEncoder.encode(authentication.getName());
// 获得表单中的密码
String password = passwordEncoder.encode(authentication.getCredentials().toString());
// 判断用户是否存在
UserDetails userInfo = userDetailsService.loadUserByUsername(username);
if (userInfo == null) {
throw new UsernameNotFoundException("User IS Not Existing");
}
// 判断密码是否正确
if (!userInfo.getPassword().equals(password)) {
throw new BadCredentialsException("Password IS Uncorrected");
}
// 判断账号是否停用/删除
if (!userInfo.isEnabled()) {
throw new DisabledException("User IS Disabled");
}
else if(!userInfo.isAccountNonLocked()){
throw new LockedException("User IS Locked");
}
else if(!userInfo.isAccountNonExpired()){
throw new AccountExpiredException("User IS Expired");
}
Collection<? extends GrantedAuthority> authorities = userInfo.getAuthorities();
return new UsernamePasswordAuthenticationToken(userInfo, password, authorities);
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}

View File

@ -0,0 +1,15 @@
package com.codesdream.ase.component;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;
@Component
public class ASEUsernameEncoder {
public String encode(CharSequence charSequence){
return "u_id_" + DigestUtils.sha256Hex(charSequence.toString());
}
public boolean matches(CharSequence charSequence, String s){
return s.equals(encode(charSequence.toString()));
}
}

View File

@ -1,6 +1,7 @@
package com.codesdream.ase.configure; package com.codesdream.ase.configure;
import com.codesdream.ase.component.ASEPasswordEncoder; import com.codesdream.ase.component.ASEPasswordEncoder;
import com.codesdream.ase.component.ASESecurityAuthenticationProvider;
import com.codesdream.ase.service.ASEUserDetailsService; import com.codesdream.ase.service.ASEUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -26,6 +27,9 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource @Resource
ASEPasswordEncoder asePasswordEncoder; ASEPasswordEncoder asePasswordEncoder;
@Resource
ASESecurityAuthenticationProvider aseSecurityAuthenticationProvider;
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() http.authorizeRequests()
@ -34,7 +38,7 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
.csrf().disable().formLogin() .csrf().disable().formLogin()
.and() .and()
.formLogin().loginPage("/login") .formLogin().loginPage("/login")
.permitAll().defaultSuccessUrl("/").permitAll() .permitAll().defaultSuccessUrl("/home").permitAll()
.and() .and()
.logout().permitAll(); .logout().permitAll();
@ -42,7 +46,8 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(aseUserDetailService) auth.authenticationProvider(aseSecurityAuthenticationProvider)
.userDetailsService(aseUserDetailService)
.passwordEncoder(asePasswordEncoder); .passwordEncoder(asePasswordEncoder);
} }

View File

@ -1,12 +1,27 @@
package com.codesdream.ase.controller; package com.codesdream.ase.controller;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.IUserService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.security.Principal;
import java.util.Optional;
@Controller @Controller
public class HomeController { public class HomeController {
@Resource
IUserService userService;
@RequestMapping(value = "/home") @RequestMapping(value = "/home")
public String showHomeView(){ public String showHomeView(Model model, Principal principal){
User user = userService.findUserByUsername(principal.getName());
// 为视图模板指定参数
model.addAttribute("username", user.getUsername().substring(0, 18));
model.addAttribute("student_id", user.getUserAuth().getStudentID());
model.addAttribute("is_at_school", user.getUserDetail().isAtSchool());
return "home"; return "home";
} }
} }

View File

@ -1,22 +1,15 @@
package com.codesdream.ase.controller; package com.codesdream.ase.controller;
import com.codesdream.ase.component.ASEPasswordEncoder;
import com.codesdream.ase.model.permission.User; import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.repository.UserRepository;
import com.codesdream.ase.service.UserService; import com.codesdream.ase.service.UserService;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Map; import java.util.Map;
import java.util.Objects;
@Controller @Controller
public class RegisterController { public class RegisterController {
@ -34,14 +27,16 @@ public class RegisterController {
Map<String, String[]> parameterMap= request.getParameterMap(); Map<String, String[]> parameterMap= request.getParameterMap();
// 进行处理前的检查 // 进行处理前的检查
if(parameterMap.containsKey("username") if(parameterMap.containsKey("student-id")
&& parameterMap.containsKey("password") && parameterMap.containsKey("password")
&& parameterMap.containsKey("retry-password") && parameterMap.containsKey("retry-password")
&& parameterMap.containsKey("user-question") && parameterMap.containsKey("user-question")
&& parameterMap.containsKey("user-answer") && parameterMap.containsKey("user-answer")
) { ) {
User user = userService.getDefaultUser(); User user = userService.getDefaultUser();
user.setUsername(parameterMap.get("username")[0].toString()); String student_id = parameterMap.get("student-id")[0].toString();
// 生成随机用户名
userService.generateRandomUsernameByStudentID(user, student_id);
String password = parameterMap.get("password")[0].toString(); String password = parameterMap.get("password")[0].toString();
String retry_password = parameterMap.get("retry-password")[0].toString(); String retry_password = parameterMap.get("retry-password")[0].toString();

View File

@ -14,11 +14,14 @@ public class UserAuth {
private int id; private int id;
// 密保问题 // 密保问题
private String user_question; private String userQuestion;
// 密保问题答案 // 密保问题答案
private String user_answer; private String userAnswer;
// 用户邮箱 // 用户邮箱
private String mail; private String mail;
// 学生ID
private String studentID;
} }

View File

@ -33,9 +33,6 @@ public class UserDetail {
// 真实姓名 // 真实姓名
private String realName; private String realName;
// 学生ID
private String studentID;
// 在校状态 // 在校状态
private boolean atSchool; private boolean atSchool;
} }

View File

@ -23,16 +23,8 @@ public class ASEUserDetailsService implements UserDetailsService {
@Override @Override
@Transactional @Transactional
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
System.out.println("User: " + s); User user = userService.findUserByUsername(s);
Optional<User> user = userService.findUserByUsername(s); user.setAuthorities(userAuthoritiesGenerator.grantedAuthorities(user));
if(!user.isPresent()){ return user;
throw new UsernameNotFoundException("User Not Found");
}
else {
System.out.println("Returning user information");
System.out.println("User Password: "+user.get().getPassword());
user.get().setAuthorities(userAuthoritiesGenerator.grantedAuthorities(user.get()));
return user.get();
}
} }
} }

View File

@ -16,7 +16,7 @@ public interface IUserService {
List<User> findAll(); List<User> findAll();
Optional<User> findUserById(int id); Optional<User> findUserById(int id);
Optional<User> findUserByUsername(String username); User findUserByUsername(String username);
// 获得用户所有的权限角色 // 获得用户所有的权限角色
Collection<? extends GrantedAuthority> getUserAuthorities(User user); Collection<? extends GrantedAuthority> getUserAuthorities(User user);
@ -24,6 +24,9 @@ public interface IUserService {
// 更新用户的密码 // 更新用户的密码
void updatePassword(User user, String password); void updatePassword(User user, String password);
// 生成随机用户名
void generateRandomUsernameByStudentID(User user, String id);
User save(User user); User save(User user);
User update(User user); User update(User user);

View File

@ -1,10 +1,12 @@
package com.codesdream.ase.service; package com.codesdream.ase.service;
import com.codesdream.ase.component.ASEPasswordEncoder; import com.codesdream.ase.component.ASEPasswordEncoder;
import com.codesdream.ase.component.ASEUsernameEncoder;
import com.codesdream.ase.component.UserRolesListGenerator; import com.codesdream.ase.component.UserRolesListGenerator;
import com.codesdream.ase.model.permission.User; import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.repository.UserRepository; import com.codesdream.ase.repository.UserRepository;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -21,7 +23,10 @@ public class UserService implements IUserService {
UserRepository userRepository; UserRepository userRepository;
@Resource @Resource
ASEPasswordEncoder asePasswordEncoder; ASEPasswordEncoder passwordEncoder;
@Resource
ASEUsernameEncoder usernameEncoder;
@Override @Override
public List<User> findAll() { public List<User> findAll() {
@ -34,8 +39,10 @@ public class UserService implements IUserService {
} }
@Override @Override
public Optional<User> findUserByUsername(String username) { public User findUserByUsername(String username) {
return userRepository.findByUsername(username); Optional<User> user = userRepository.findByUsername(username);
if(!user.isPresent()) throw new UsernameNotFoundException("User Not Found");
return user.get();
} }
@Override @Override
@ -45,16 +52,22 @@ public class UserService implements IUserService {
@Override @Override
public void updatePassword(User user, String password) { public void updatePassword(User user, String password) {
user.setPassword(asePasswordEncoder.encode(password)); user.setPassword(passwordEncoder.encode(password));
update(user); update(user);
} }
@Override
public void generateRandomUsernameByStudentID(User user, String id) {
user.getUserAuth().setStudentID(id);
user.setUsername(usernameEncoder.encode(id));
}
@Override @Override
public User save(User user) { public User save(User user) {
// 查找用户名是否已经被注册 // 查找用户名是否已经被注册
if(userRepository.findByUsername(user.getUsername()).isPresent()) if(userRepository.findByUsername(user.getUsername()).isPresent())
throw new RuntimeException("Username Already Exists"); throw new RuntimeException("Username Already Exists");
user.setPassword(asePasswordEncoder.encode(user.getPassword())); user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user); return userRepository.save(user);
} }

View File

@ -0,0 +1,376 @@
<!doctype html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<div th:include="layout::head"></div>
<meta charset="utf-8">
<title>home</title>
</head>
<body>
<!-- Custom template | don't include it in your project! -->
<!-- End Custom template -->
<!-- Core JS Files -->
<div class="wrapper">
<div class="main-header">
<!-- Logo Header -->
<div class="logo-header" data-background-color="blue"> <a href="index.html" class="logo"> <img src="../assets/img/logo.svg" alt="navbar brand" class="navbar-brand"></a>
<button class="navbar-toggler sidenav-toggler ml-auto" type="button" data-toggle="collapse" data-target="collapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"> <i class="icon-menu"></i></span></button>
<button class="topbar-toggler more"><i class="icon-options-vertical"></i></button>
<div class="nav-toggle">
<button class="btn btn-toggle toggle-sidebar"> <i class="icon-menu"></i></button>
</div>
</div>
<!-- End Logo Header -->
<!-- Navbar Header -->
<nav class="navbar navbar-header navbar-expand-lg" data-background-color="blue2">
<div class="container-fluid">
<div class="collapse" id="search-nav">
<form class="navbar-left navbar-form nav-search mr-md-3">
<div class="input-group">
<div class="input-group-prepend">
<button type="submit" class="btn btn-search pr-1"> <i class="fa fa-search search-icon"></i></button>
</div>
<input type="text" placeholder="Search ..." class="form-control">
</div>
</form>
</div>
<ul class="navbar-nav topbar-nav ml-md-auto align-items-center">
<li class="nav-item toggle-nav-search hidden-caret"> <a class="nav-link" data-toggle="collapse" href="#search-nav" role="button" aria-expanded="false" aria-controls="search-nav"> <i class="fa fa-search"></i></a></li>
<li class="nav-item dropdown hidden-caret"> <a class="nav-link dropdown-toggle" href="#" id="messageDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fa fa-envelope"></i></a>
<ul class="dropdown-menu messages-notif-box animated fadeIn" aria-labelledby="messageDropdown">
<li>
<div class="dropdown-title d-flex justify-content-between align-items-center"> Messages <a href="#" class="small">Mark all as read</a></div>
</li>
<li>
<div class="message-notif-scroll scrollbar-outer">
<div class="notif-center"> <a href="#">
<div class="notif-img"> <img src="../assets/img/jm_denis.jpg" alt="Img Profile"></div>
<div class="notif-content"> <span class="subject">Jimmy Denis</span> <span class="block"> How are you ? </span> <span class="time">5 minutes ago</span></div>
</a> <a href="#">
<div class="notif-img"> <img src="../assets/img/chadengle.jpg" alt="Img Profile"></div>
<div class="notif-content"> <span class="subject">Chad</span> <span class="block"> Ok, Thanks ! </span> <span class="time">12 minutes ago</span></div>
</a> <a href="#">
<div class="notif-img"> <img src="../assets/img/mlane.jpg" alt="Img Profile"></div>
<div class="notif-content"> <span class="subject">Jhon Doe</span> <span class="block"> Ready for the meeting today... </span> <span class="time">12 minutes ago</span></div>
</a> <a href="#">
<div class="notif-img"> <img src="../assets/img/talha.jpg" alt="Img Profile"></div>
<div class="notif-content"> <span class="subject">Talha</span> <span class="block"> Hi, Apa Kabar ? </span> <span class="time">17 minutes ago</span></div>
</a></div>
</div>
</li>
<li> <a class="see-all" href="javascript:void(0);">See all messages<i class="fa fa-angle-right"></i></a></li>
</ul>
</li>
<li class="nav-item dropdown hidden-caret"> <a class="nav-link dropdown-toggle" href="#" id="notifDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fa fa-bell"></i> <span class="notification">4</span></a>
<ul class="dropdown-menu notif-box animated fadeIn" aria-labelledby="notifDropdown">
<li>
<div class="dropdown-title">You have 4 new notification</div>
</li>
<li>
<div class="notif-scroll scrollbar-outer">
<div class="notif-center"> <a href="#">
<div class="notif-icon notif-primary"> <i class="fa fa-user-plus"></i></div>
<div class="notif-content"> <span class="block"> New user registered </span> <span class="time">5 minutes ago</span></div>
</a> <a href="#">
<div class="notif-icon notif-success"> <i class="fa fa-comment"></i></div>
<div class="notif-content"> <span class="block"> Rahmad commented on Admin </span> <span class="time">12 minutes ago</span></div>
</a> <a href="#">
<div class="notif-img"> <img src="../assets/img/profile2.jpg" alt="Img Profile"></div>
<div class="notif-content"> <span class="block"> Reza send messages to you </span> <span class="time">12 minutes ago</span></div>
</a> <a href="#">
<div class="notif-icon notif-danger"> <i class="fa fa-heart"></i></div>
<div class="notif-content"> <span class="block"> Farrah liked Admin </span> <span class="time">17 minutes ago</span></div>
</a></div>
</div>
</li>
<li> <a class="see-all" href="javascript:void(0);">See all notifications<i class="fa fa-angle-right"></i></a></li>
</ul>
</li>
<li class="nav-item dropdown hidden-caret"> <a class="nav-link" data-toggle="dropdown" href="#" aria-expanded="false"> <i class="fas fa-layer-group"></i></a>
<div class="dropdown-menu quick-actions quick-actions-info animated fadeIn">
<div class="quick-actions-header"> <span class="title mb-1">Quick Actions</span> <span class="subtitle op-8">Shortcuts</span></div>
<div class="quick-actions-scroll scrollbar-outer">
<div class="quick-actions-items">
<div class="row m-0"> <a class="col-6 col-md-4 p-0" href="#">
<div class="quick-actions-item"> <i class="flaticon-file-1"></i> <span class="text">Generated Report</span></div>
</a> <a class="col-6 col-md-4 p-0" href="#">
<div class="quick-actions-item"> <i class="flaticon-database"></i> <span class="text">Create New Database</span></div>
</a> <a class="col-6 col-md-4 p-0" href="#">
<div class="quick-actions-item"> <i class="flaticon-pen"></i> <span class="text">Create New Post</span></div>
</a> <a class="col-6 col-md-4 p-0" href="#">
<div class="quick-actions-item"> <i class="flaticon-interface-1"></i> <span class="text">Create New Task</span></div>
</a> <a class="col-6 col-md-4 p-0" href="#">
<div class="quick-actions-item"> <i class="flaticon-list"></i> <span class="text">Completed Tasks</span></div>
</a> <a class="col-6 col-md-4 p-0" href="#">
<div class="quick-actions-item"> <i class="flaticon-file"></i> <span class="text">Create New Invoice</span></div>
</a></div>
</div>
</div>
</div>
</li>
<li class="nav-item dropdown hidden-caret"> <a class="dropdown-toggle profile-pic" data-toggle="dropdown" href="#" aria-expanded="false">
<div class="avatar-sm"> <img src="../assets/img/profile.jpg" alt="..." class="avatar-img rounded-circle"></div>
</a>
<ul class="dropdown-menu dropdown-user animated fadeIn">
<div class="dropdown-user-scroll scrollbar-outer">
<li>
<div class="user-box">
<div class="avatar-lg"><img src="../assets/img/profile.jpg" alt="image profile" class="avatar-img rounded"></div>
<div class="u-text">
<h4>Hizrian</h4>
<p class="text-muted">hello@example.com</p>
<a href="profile.html" class="btn btn-xs btn-secondary btn-sm">View Profile</a></div>
</div>
</li>
<li>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">My Profile</a> <a class="dropdown-item" href="#">My Balance</a> <a class="dropdown-item" href="#">Inbox</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Account Setting</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Logout</a></li>
</div>
</ul>
</li>
</ul>
</div>
</nav>
<!-- End Navbar -->
</div>
<!-- Sidebar -->
<div class="sidebar sidebar-style-2">
<div class="sidebar-wrapper scrollbar scrollbar-inner">
<div class="sidebar-content">
<div class="user">
<div class="avatar-sm float-left mr-2"> <img src="../assets/img/profile.jpg" alt="..." class="avatar-img rounded-circle"></div>
<div class="info">
<a data-toggle="collapse" href="#collapseExample" aria-expanded="true">
<span th:text="${username}">二狗子</span>
<span class="user-level">学生</span>
<span class="caret"></span>
</a>
<div class="clear-fix"></div>
<div class="collapse in" id="collapseExample">
<ul class="nav">
<li> <a href="#profile"> <span class="link-collapse">基本资料</span></a></li>
<li> <a href="#edit"> <span class="link-collapse">编辑个人信息</span></a></li>
<li> <a href="#settings"> <span class="link-collapse">设置</span></a></li>
</ul>
</div>
</div>
</div>
<ul class="nav nav-primary">
<!--
<li class="nav-item active"> <a data-toggle="collapse" href="#dashboard" class="collapsed" aria-expanded="false"> <i class="fas fa-home"></i>
<p>主页</p>
<span class="caret"></span></a>
<div class="collapse" id="dashboard">
<ul class="nav nav-collapse">
<li> <a href="../demo1/index.html"> <span class="sub-item">个人信息</span></a></li>
<li> <a href="../demo2/index.html"> <span class="sub-item">成绩</span></a></li>
</ul>
</div>
</li>
-->
<li class="nav-section"> <span class="sidebar-mini-icon"> <i class="fa fa-ellipsis-h"></i></span>
<h4 class="text-section">功能</h4>
</li>
<li class="nav-item"> <a data-toggle="collapse" href="#base"> <i class="fas fa-layer-group"></i>
<p>活动</p>
<span class="caret"></span></a>
<div class="collapse" id="base">
<ul class="nav nav-collapse">
<li> <a href="huodong1.html"> <span class="sub-item">我的活动</span></a></li>
<li> <a href="huodong2.html"> <span class="sub-item">创建活动</span></a></li>
<li> <a href="huodong3.html"> <span class="sub-item">活动列表</span></a></li>
<li> <a href="huodong4.html"> <span class="sub-item">活动报告</span></a></li>
</ul>
</div>
</li>
<li class="nav-item"> <a data-toggle="collapse" href="#sidebarLayouts"> <i class="fas fa-th-list"></i>
<p>消息</p>
<span class="caret"></span></a>
<div class="collapse" id="sidebarLayouts">
<ul class="nav nav-collapse">
<li> <a href="sidebar-style-1.html"> <span class="sub-item">我的消息</span></a></li>
<li> <a href="overlay-sidebar.html"> <span class="sub-item">发送消息</span></a></li>
</ul>
</div>
</li>
<li class="nav-item"> <a data-toggle="collapse" href="#forms"> <i class="fas fa-pen-square"></i>
<p>请假</p>
<span class="caret"></span></a>
<div class="collapse" id="forms">
<ul class="nav nav-collapse">
<li> <a href="forms/forms.html"> <span class="sub-item">请假申请</span></a></li>
<li> <a href="forms/forms.html"> <span class="sub-item">假条审核</span></a></li>
</ul>
</div>
</li>
<li class="nav-item"> <a href="widgets.html"> <i class="fas fa-desktop"></i>
<p>Widgets</p>
<span class="badge badge-success">4</span></a></li>
<!--
<li class="nav-item"> <a data-toggle="collapse" href="#submenu"> <i class="fas fa-bars"></i>
<p>Menu Levels</p>
<span class="caret"></span></a>
<div class="collapse" id="submenu">
<ul class="nav nav-collapse">
<li> <a data-toggle="collapse" href="#subnav1"> <span class="sub-item">Level 1</span> <span class="caret"></span></a>
<div class="collapse" id="subnav1">
<ul class="nav nav-collapse subnav">
<li> <a href="#"> <span class="sub-item">Level 2</span></a></li>
<li> <a href="#"> <span class="sub-item">Level 2</span></a></li>
</ul>
</div>
</li>
<li> <a data-toggle="collapse" href="#subnav2"> <span class="sub-item">Level 1</span> <span class="caret"></span></a>
<div class="collapse" id="subnav2">
<ul class="nav nav-collapse subnav">
<li> <a href="#"> <span class="sub-item">Level 2</span></a></li>
</ul>
</div>
</li>
<li> <a href="#"> <span class="sub-item">Level 1</span></a></li>
</ul>
</div>
</li>
-->
<li class="mx-4 mt-2"> <a href="#" class="btn btn-primary btn-block"><span class="btn-label mr-2"> <i class="fa fa-heart"></i></span>Buy Pro</a></li>
</ul>
</div>
</div>
</div>
<div class="main-panel" >
<div class="card" style="left:20px;position:inherit ">
<div class="page-header" style="height:60px;left:20px"></div>
<div class="card-title" style="left:30px;position:inherit ">
<font style="vertical-align: inherit" ><font style="vertical-align: inherit;">基本信息</font></font>
</div>
<table style="width: 80% ;left:20px;position:inherit " class="table table-bordered" >
<tbody>
<tr style="background-color: #F2F2F2;border-color: #212121">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">姓名</font></font></th>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">二狗子</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">在校状态</font></font></td>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<div th:switch="${is_at_school}">
<span th:case="${true}">在校</span>
<span th:case="${false}">未在校</span>
<span th:case="*">未知</span>
</div>
</font></font></td>
</tr>
<tr style="background-color: #F2F2F2;border-color: #212121">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">学号</font></font></th>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"><span th:text="${student_id}"></span></font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">身份</font></font></td>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">学生</font></font></td>
</tr>
<tr style="background-color: #F2F2F2;border-color: #212121">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">手机</font></font></th>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">180892131811</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">性别</font></font></td>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"></font></font></td>
</tr><tr style="background-color: #F2F2F2;border-color: #212121">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">班号</font></font></th>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">14011809</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">班级</font></font></td>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">软件九班</font></font></td>
</tr><tr style="background-color: #F2F2F2;border-color: #212121">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">专业</font></font></th>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">软件工程</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">学院</font></font></td>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">软件学院</font></font></td>
</tr><tr style="background-color: #F2F2F2;border-color: #212121">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">邮箱</font></font></th>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">857331073@qq.com</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">职务</font></font></td>
<td style="background-color: #FFFFFF"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;"></font></font></td>
</tr>
</tbody>
</table>
<div class="card-title" style="left:20px;position:inherit " >
<font style="vertical-align: inherit" ><font style="vertical-align: inherit;">统计信息</font></font>
</div>
<table class="table table-bordered" style="width: 80%;left:20px;position:inherit ">
<thead>
<tr>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">学分积</font></font></th>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">学分积排名</font></font></th>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">综合测评</font></font></th>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">综测排名</font></font></th>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">考勤次数</font></font></th>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">考勤率</font></font></th>
<th><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">活动参加数 </font></font></th>
</tr>
</thead>
<tbody>
<tr style="background-color: #F2F2F2">
<th scope="row"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">1个</font></font></th>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">表格单元格</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">表格单元格</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">表格单元格</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">表格单元格</font></font></td>
<td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">表格单元格</font></font></td> <td><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">表格单元格</font></font></td>
</tr>
</tbody>
</table>
<!--
<footer class="footer">
<div class="container-fluid">
<nav class="pull-left">
<ul class="nav">
<li class="nav-item"> <a class="nav-link" href="#"> ThemeKita </a></li>
<li class="nav-item"> <a class="nav-link" href="#"> Help </a></li>
<li class="nav-item"> <a class="nav-link" href="#"> Licenses </a></li>
</ul>
</nav>
<div class="copyright ml-auto"> 2018, made with by ThemeKita - More Templates <a href="http://www.cssmoban.com/" target="_blank" title="模板之家">模板之家</a> - Collect from <a href="http://www.cssmoban.com/" title="网页模板" target="_blank">网页模板</a></div>
</div>
</footer>
-->
</div>
</div>
<!-- End Sidebar -->
<!-- Custom template | don't include it in your project! --> <!-- End Custom template -->
</div>
<div th:include="layout::js"></div>
</body>
</html>

View File

@ -17,8 +17,8 @@
<form action="/login" method="post"> <form action="/login" method="post">
<div class="card-body"> <div class="card-body">
<div class="form-group"> <div class="form-group">
<label for="username">用户名</label> <label for="username">学号</label>
<input type="text" class="form-control" id="username" name="username" placeholder="这里输入用户名" required> <input type="text" class="form-control" id="username" name="username" placeholder="这里输入学号" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">密码</label> <label for="password">密码</label>

View File

@ -17,8 +17,8 @@
<form action="/register" method="post"> <form action="/register" method="post">
<div class="card-body"> <div class="card-body">
<div class="form-group"> <div class="form-group">
<label for="username">用户名</label> <label for="student-id">学号</label>
<input type="text" class="form-control" id="username" name="username" placeholder="这里输入用户名"> <input type="text" class="form-control" id="student-id" name="student-id" placeholder="这里输入学号">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">密码</label> <label for="password">密码</label>