├── .gitattributes ├── pic ├── login.png ├── show1.png ├── show2.png ├── show3.png └── show4.png ├── src ├── main │ ├── resources │ │ ├── application.yml │ │ ├── static │ │ │ ├── image │ │ │ │ ├── card.jpg │ │ │ │ └── class_img.png │ │ │ ├── css │ │ │ │ └── common.css │ │ │ ├── lib_web │ │ │ │ ├── datepicker │ │ │ │ │ ├── skin │ │ │ │ │ │ ├── twoer │ │ │ │ │ │ │ ├── img.gif │ │ │ │ │ │ │ ├── img.png │ │ │ │ │ │ │ ├── datepicker.css │ │ │ │ │ │ │ └── datepicker-dev.css │ │ │ │ │ │ ├── datePicker.gif │ │ │ │ │ │ ├── default │ │ │ │ │ │ │ ├── img.gif │ │ │ │ │ │ │ └── datepicker.css │ │ │ │ │ │ ├── whyGreen │ │ │ │ │ │ │ ├── bg.jpg │ │ │ │ │ │ │ ├── img.gif │ │ │ │ │ │ │ └── datepicker.css │ │ │ │ │ │ └── WdatePicker.css │ │ │ │ │ └── lang │ │ │ │ │ │ ├── en.js │ │ │ │ │ │ ├── zh-cn.js │ │ │ │ │ │ └── zh-tw.js │ │ │ │ ├── mdui │ │ │ │ │ ├── fonts │ │ │ │ │ │ └── roboto │ │ │ │ │ │ │ ├── Roboto-Bold.woff │ │ │ │ │ │ │ ├── Roboto-Thin.woff │ │ │ │ │ │ │ ├── Roboto-Black.woff │ │ │ │ │ │ │ ├── Roboto-Black.woff2 │ │ │ │ │ │ │ ├── Roboto-Bold.woff2 │ │ │ │ │ │ │ ├── Roboto-Light.woff │ │ │ │ │ │ │ ├── Roboto-Light.woff2 │ │ │ │ │ │ │ ├── Roboto-Medium.woff │ │ │ │ │ │ │ ├── Roboto-Thin.woff2 │ │ │ │ │ │ │ ├── Roboto-Medium.woff2 │ │ │ │ │ │ │ ├── Roboto-Regular.woff │ │ │ │ │ │ │ ├── Roboto-Regular.woff2 │ │ │ │ │ │ │ ├── Roboto-BlackItalic.woff │ │ │ │ │ │ │ ├── Roboto-BoldItalic.woff │ │ │ │ │ │ │ ├── Roboto-BoldItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-LightItalic.woff │ │ │ │ │ │ │ ├── Roboto-ThinItalic.woff │ │ │ │ │ │ │ ├── Roboto-ThinItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-BlackItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-LightItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-MediumItalic.woff │ │ │ │ │ │ │ ├── Roboto-MediumItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-RegularItalic.woff │ │ │ │ │ │ │ ├── Roboto-RegularItalic.woff2 │ │ │ │ │ │ │ └── LICENSE.txt │ │ │ │ │ └── icons │ │ │ │ │ │ └── material-icons │ │ │ │ │ │ ├── MaterialIcons-Regular.woff │ │ │ │ │ │ └── MaterialIcons-Regular.woff2 │ │ │ │ └── canvas-nest │ │ │ │ │ ├── canvas-nest.min.js │ │ │ │ │ └── canvas-nest.js │ │ │ └── js │ │ │ │ └── common.js │ │ ├── application-prod.yml │ │ ├── application-dev.yml │ │ ├── banner.txt │ │ └── templates │ │ │ ├── error.html │ │ │ ├── login.html │ │ │ ├── log.html │ │ │ ├── historyleave.html │ │ │ └── settheme.html │ └── java │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── top │ │ └── itning │ │ └── ta │ │ ├── exception │ │ ├── JsonException.java │ │ ├── DefaultException.java │ │ ├── DataNotFindException.java │ │ ├── NullParameterException.java │ │ ├── JsonNullParameterException.java │ │ ├── JsonDataNotFindException.java │ │ └── resolver │ │ │ └── ExceptionResolver.java │ │ ├── dao │ │ ├── LeaveTypeDao.java │ │ ├── UserDao.java │ │ ├── ClazzDao.java │ │ ├── StudentLeaveDao.java │ │ └── StudentInfoDao.java │ │ ├── service │ │ ├── LeaveTypeService.java │ │ ├── SettingService.java │ │ ├── ClassManageService.java │ │ ├── StudentLeaveService.java │ │ ├── impl │ │ │ ├── LeaveTypeServiceImpl.java │ │ │ ├── SettingServiceImpl.java │ │ │ ├── ClassManageServiceImpl.java │ │ │ └── StudentLeaveServiceImpl.java │ │ └── StudentInfoService.java │ │ ├── TaApplication.java │ │ ├── entity │ │ ├── ServerMessage.java │ │ ├── LeaveType.java │ │ ├── SearchLeave.java │ │ ├── Clazz.java │ │ ├── StudentLeave.java │ │ ├── User.java │ │ └── StudentInfo.java │ │ ├── config │ │ ├── UserDetailsServiceImpl.java │ │ └── WebSecurityConfig.java │ │ └── controller │ │ ├── FrameWorkController.java │ │ ├── clazz │ │ └── ClassManageController.java │ │ └── student │ │ ├── leave │ │ └── StudentLeaveController.java │ │ └── info │ │ └── StudentInfoController.java └── test │ └── java │ └── top │ └── itning │ └── ta │ └── TaApplicationTests.java ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml ├── mvnw.cmd └── mvnw /.gitattributes: -------------------------------------------------------------------------------- 1 | *.css linguist-language=java -------------------------------------------------------------------------------- /pic/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/pic/login.png -------------------------------------------------------------------------------- /pic/show1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/pic/show1.png -------------------------------------------------------------------------------- /pic/show2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/pic/show2.png -------------------------------------------------------------------------------- /pic/show3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/pic/show3.png -------------------------------------------------------------------------------- /pic/show4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/pic/show4.png -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev -------------------------------------------------------------------------------- /src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: top.itning.ta.TaApplication 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/static/image/card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/image/card.jpg -------------------------------------------------------------------------------- /src/main/resources/static/image/class_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/image/class_img.png -------------------------------------------------------------------------------- /src/main/resources/static/css/common.css: -------------------------------------------------------------------------------- 1 | a { 2 | color: inherit; 3 | text-decoration: inherit; 4 | } 5 | 6 | p { 7 | margin: 0; 8 | max-width: 200px; 9 | } -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/twoer/img.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/datepicker/skin/twoer/img.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/twoer/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/datepicker/skin/twoer/img.png -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/datePicker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/datepicker/skin/datePicker.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/default/img.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/datepicker/skin/default/img.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/whyGreen/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/datepicker/skin/whyGreen/bg.jpg -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/whyGreen/img.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/datepicker/skin/whyGreen/img.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Black.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Black.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BoldItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BoldItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-LightItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-ThinItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-ThinItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-LightItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-MediumItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-MediumItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-RegularItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-RegularItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-RegularItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-RegularItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/icons/material-icons/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/icons/material-icons/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/icons/material-icons/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Ta/master/src/main/resources/static/lib_web/mdui/icons/material-icons/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/JsonException.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception; 2 | 3 | /** 4 | * Json异常 5 | * 6 | * @author Ning 7 | */ 8 | public class JsonException extends RuntimeException { 9 | public JsonException(String exceptionMessage) { 10 | super(exceptionMessage); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/DefaultException.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception; 2 | 3 | /** 4 | * 默认异常 5 | * 6 | * @author Ning 7 | */ 8 | public class DefaultException extends RuntimeException { 9 | public DefaultException(String exceptionMessage) { 10 | super(exceptionMessage); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/WdatePicker.css: -------------------------------------------------------------------------------- 1 | .Wdate { 2 | border: #999 1px solid; 3 | height: 20px; 4 | background: #fff url(datePicker.gif) no-repeat right; 5 | } 6 | 7 | .Wdate::-ms-clear { 8 | display: none; 9 | } 10 | 11 | .WdateFmtErr { 12 | font-weight: bold; 13 | color: red; 14 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/dao/LeaveTypeDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.ta.entity.LeaveType; 5 | 6 | /** 7 | * LEAVE_TYPE Table Dao 8 | * 9 | * @author wangn 10 | */ 11 | public interface LeaveTypeDao extends JpaRepository { 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/LeaveTypeService.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service; 2 | 3 | import top.itning.ta.entity.LeaveType; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 学生请假类型服务 9 | * 10 | * @author Ning 11 | */ 12 | public interface LeaveTypeService { 13 | /** 14 | * 获取所有请假类型信息 15 | * 16 | * @return 请假类型集合 17 | */ 18 | List getAllLeaveType(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/TaApplication.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author wangn 8 | */ 9 | @SpringBootApplication 10 | public class TaApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(TaApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.ta.entity.User; 5 | 6 | /** 7 | * USER Table Dao 8 | * 9 | * @author wangn 10 | */ 11 | public interface UserDao extends JpaRepository { 12 | /** 13 | * 根据用户名查找用户 14 | * 15 | * @param username 用户名 16 | * @return User 实体 17 | */ 18 | User findByUsername(String username); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/dao/ClazzDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.ta.entity.Clazz; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * CLASS Table Dao 10 | * 11 | * @author wangn 12 | */ 13 | public interface ClazzDao extends JpaRepository { 14 | /** 15 | * 根据班级名查找班级 16 | * 17 | * @param clzz 班级名 18 | * @return 班级集合 19 | */ 20 | List findByClazz(String clzz); 21 | 22 | /** 23 | * 根据教师名查找班级 24 | * 25 | * @param teacher 教师名 26 | * @return 班级集合 27 | */ 28 | List findByTeacher(String teacher); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/static/js/common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | $(function () { 3 | /*夜间模式功能 start*/ 4 | var $nightMode = $('#night_mode'); 5 | if (localStorage.getItem('night_mode') === 'true') { 6 | $('body').addClass('mdui-theme-layout-dark'); 7 | $nightMode.prop('checked', true); 8 | } 9 | $nightMode.click(function () { 10 | if ($(this).prop('checked')) { 11 | localStorage.setItem('night_mode', true); 12 | $('body').addClass('mdui-theme-layout-dark'); 13 | } else { 14 | localStorage.setItem('night_mode', false); 15 | $('body').removeClass('mdui-theme-layout-dark'); 16 | } 17 | }); 18 | /*夜间模式功能 end*/ 19 | }); -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/DataNotFindException.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception; 2 | 3 | /** 4 | * 所查找的数据没有找到 5 | * 6 | * @author wangn 7 | */ 8 | public class DataNotFindException extends DefaultException { 9 | /** 10 | * 异常消息 11 | */ 12 | private String exceptionMessage; 13 | 14 | public DataNotFindException(String exceptionMessage) { 15 | super(exceptionMessage); 16 | this.exceptionMessage = exceptionMessage; 17 | } 18 | 19 | public String getExceptionMessage() { 20 | return exceptionMessage; 21 | } 22 | 23 | public void setExceptionMessage(String exceptionMessage) { 24 | this.exceptionMessage = exceptionMessage; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/NullParameterException.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception; 2 | 3 | /** 4 | * 空参数异常 5 | * 6 | * @author wangn 7 | */ 8 | public class NullParameterException extends DefaultException { 9 | /** 10 | * 异常消息 11 | */ 12 | private String exceptionMessage; 13 | 14 | public NullParameterException(String exceptionMessage) { 15 | super(exceptionMessage); 16 | this.exceptionMessage = exceptionMessage; 17 | } 18 | 19 | public String getExceptionMessage() { 20 | return exceptionMessage; 21 | } 22 | 23 | public void setExceptionMessage(String exceptionMessage) { 24 | this.exceptionMessage = exceptionMessage; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/JsonNullParameterException.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception; 2 | 3 | /** 4 | * Json格式空参数异常 5 | * 6 | * @author Ning 7 | */ 8 | public class JsonNullParameterException extends JsonException { 9 | /** 10 | * 异常消息 11 | */ 12 | private String exceptionMessage; 13 | 14 | public JsonNullParameterException(String exceptionMessage) { 15 | super(exceptionMessage); 16 | this.exceptionMessage = exceptionMessage; 17 | } 18 | 19 | public String getExceptionMessage() { 20 | return exceptionMessage; 21 | } 22 | 23 | public void setExceptionMessage(String exceptionMessage) { 24 | this.exceptionMessage = exceptionMessage; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/JsonDataNotFindException.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception; 2 | 3 | 4 | /** 5 | * Json格式所查找的数据没有找到 6 | * 7 | * @author Ning 8 | */ 9 | public class JsonDataNotFindException extends JsonException { 10 | /** 11 | * 异常消息 12 | */ 13 | private String exceptionMessage; 14 | 15 | public JsonDataNotFindException(String exceptionMessage) { 16 | super(exceptionMessage); 17 | this.exceptionMessage = exceptionMessage; 18 | } 19 | 20 | public String getExceptionMessage() { 21 | return exceptionMessage; 22 | } 23 | 24 | public void setExceptionMessage(String exceptionMessage) { 25 | this.exceptionMessage = exceptionMessage; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/lang/en.js: -------------------------------------------------------------------------------- 1 | var $lang = { 2 | errAlertMsg: "Invalid date or the date out of range,redo or not?", 3 | aWeekStr: ["wk", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 4 | aLongWeekStr: ["wk", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], 5 | aMonStr: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 6 | aLongMonStr: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], 7 | clearStr: "Clear", 8 | todayStr: "Today", 9 | okStr: "OK", 10 | updateStr: "OK", 11 | timeStr: "Time", 12 | quickStr: "Quick Selection", 13 | err_1: 'MinDate Cannot be bigger than MaxDate!' 14 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/SettingService.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service; 2 | 3 | import top.itning.ta.exception.NullParameterException; 4 | 5 | /** 6 | * 设置服务 7 | * 8 | * @author Ning 9 | */ 10 | public interface SettingService { 11 | /** 12 | * 获取主色 13 | * 14 | * @return 主色 15 | */ 16 | String getThemeColor(); 17 | 18 | /** 19 | * 获取强调色 20 | * 21 | * @return 强调色 22 | */ 23 | String getThemeColorAccent(); 24 | 25 | /** 26 | * 设置主色 27 | * 28 | * @param color 颜色 29 | * @throws NullParameterException 如果参数为空则抛出该异常 30 | */ 31 | void setThemeColor(String color) throws NullParameterException; 32 | 33 | /** 34 | * 设置强调色 35 | * 36 | * @param color 颜色 37 | * @throws NullParameterException 如果参数为空则抛出该异常 38 | */ 39 | void setThemeColorAccent(String color) throws NullParameterException; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 80 3 | debug: false 4 | spring: 5 | jpa: 6 | hibernate: 7 | ddl-auto: update 8 | show-sql: false 9 | datasource: 10 | driver-class-name: com.mysql.cj.jdbc.Driver 11 | url: jdbc:mysql://localhost:3306/ta?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=0&serverTimezone=UTC 12 | username: root 13 | password: kingston 14 | thymeleaf: 15 | cache: false 16 | mode: HTML 17 | mvc: 18 | favicon: 19 | enabled: false 20 | output: 21 | ansi: 22 | enabled: detect #控制台多彩输出 23 | http: 24 | multipart: 25 | location: C:/Users/Ning/Desktop/upload/ #文件上传路径 26 | resources: 27 | static-locations: /META-INF/resources/,classpath:/resources/, classpath:/static/, classpath:/public/, file:${spring.http.multipart.location} 28 | logging: 29 | level: warn 30 | level.top: warn 31 | file: C:/Users/Ning/Desktop/upload/log.log -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/ServerMessage.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | /** 4 | * 异常消息实体 5 | * 6 | * @author wangn 7 | */ 8 | public class ServerMessage { 9 | public static final int NOT_FIND = 404; 10 | public static final int SERVICE_ERROR = 500; 11 | public static final int SUCCESS_CODE = 200; 12 | /** 13 | * 错误码 14 | */ 15 | private int code; 16 | /** 17 | * 错误消息 18 | */ 19 | private String msg; 20 | /** 21 | * 发生错误的URL 22 | */ 23 | private String url; 24 | 25 | public int getCode() { 26 | return code; 27 | } 28 | 29 | public void setCode(int code) { 30 | this.code = code; 31 | } 32 | 33 | public String getMsg() { 34 | return msg; 35 | } 36 | 37 | public void setMsg(String msg) { 38 | this.msg = msg; 39 | } 40 | 41 | public String getUrl() { 42 | return url; 43 | } 44 | 45 | public void setUrl(String url) { 46 | this.url = url; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | debug: false 4 | spring: 5 | jpa: 6 | hibernate: 7 | ddl-auto: update 8 | show-sql: true 9 | datasource: 10 | driver-class-name: com.mysql.cj.jdbc.Driver 11 | url: jdbc:mysql://localhost:3306/ta?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=0&serverTimezone=UTC 12 | username: root 13 | password: kingston 14 | thymeleaf: 15 | cache: false 16 | mode: HTML 17 | mvc: 18 | favicon: 19 | enabled: false 20 | output: 21 | ansi: 22 | enabled: detect #控制台多彩输出 23 | http: 24 | multipart: 25 | location: C:/Users/Ning/Desktop/upload/ #文件上传路径 26 | resources: 27 | static-locations: /META-INF/resources/,classpath:/resources/, classpath:/static/, classpath:/public/, file:${spring.http.multipart.location} 28 | logging: 29 | level: debug 30 | level.top: debug 31 | file: C:/Users/Ning/Desktop/upload/log.log 32 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/dao/StudentLeaveDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 5 | import top.itning.ta.entity.StudentInfo; 6 | import top.itning.ta.entity.StudentLeave; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * STU_LEAVE Table Dao 12 | * 13 | * @author wangn 14 | */ 15 | public interface StudentLeaveDao extends JpaRepository, JpaSpecificationExecutor { 16 | /** 17 | * 根据学生ID删除所有请假信息 18 | * 19 | * @param studentInfo 要删除的学生 20 | */ 21 | void deleteAllBySid(StudentInfo studentInfo); 22 | 23 | /** 24 | * 查找用户查询请假信息 25 | * 26 | * @param uname 用户名 27 | * @return 请假信息集合 28 | */ 29 | List findByUname(String uname); 30 | 31 | /** 32 | * 根据用户名记算请假数量 33 | * 34 | * @param uname 用户名 35 | * @return 数量 36 | */ 37 | long countByUname(String uname); 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 a1837634447 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/lang/zh-cn.js: -------------------------------------------------------------------------------- 1 | var $lang = { 2 | errAlertMsg: "\u4E0D\u5408\u6CD5\u7684\u65E5\u671F\u683C\u5F0F\u6216\u8005\u65E5\u671F\u8D85\u51FA\u9650\u5B9A\u8303\u56F4,\u9700\u8981\u64A4\u9500\u5417?", 3 | aWeekStr: ["\u5468", "\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"], 4 | aLongWeekStr: ["\u5468", "\u661F\u671F\u65E5", "\u661F\u671F\u4E00", "\u661F\u671F\u4E8C", "\u661F\u671F\u4E09", "\u661F\u671F\u56DB", "\u661F\u671F\u4E94", "\u661F\u671F\u516D"], 5 | aMonStr: ["\u4E00\u6708", "\u4E8C\u6708", "\u4E09\u6708", "\u56DB\u6708", "\u4E94\u6708", "\u516D\u6708", "\u4E03\u6708", "\u516B\u6708", "\u4E5D\u6708", "\u5341\u6708", "\u5341\u4E00", "\u5341\u4E8C"], 6 | aLongMonStr: ["\u4E00\u6708", "\u4E8C\u6708", "\u4E09\u6708", "\u56DB\u6708", "\u4E94\u6708", "\u516D\u6708", "\u4E03\u6708", "\u516B\u6708", "\u4E5D\u6708", "\u5341\u6708", "\u5341\u4E00\u6708", "\u5341\u4E8C\u6708"], 7 | clearStr: "\u6E05\u7A7A", 8 | todayStr: "\u4ECA\u5929", 9 | okStr: "\u786E\u5B9A", 10 | updateStr: "\u786E\u5B9A", 11 | timeStr: "\u65F6\u95F4", 12 | quickStr: "\u5FEB\u901F\u9009\u62E9", 13 | err_1: '\u6700\u5C0F\u65E5\u671F\u4E0D\u80FD\u5927\u4E8E\u6700\u5927\u65E5\u671F!' 14 | } -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/lang/zh-tw.js: -------------------------------------------------------------------------------- 1 | var $lang = { 2 | errAlertMsg: "\u4E0D\u5408\u6CD5\u7684\u65E5\u671F\u683C\u5F0F\u6216\u8005\u65E5\u671F\u8D85\u51FA\u9650\u5B9A\u7BC4\u570D,\u9700\u8981\u64A4\u92B7\u55CE?", 3 | aWeekStr: ["\u5468", "\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"], 4 | aLongWeekStr: ["\u5468", "\u661F\u671F\u65E5", "\u661F\u671F\u4E00", "\u661F\u671F\u4E8C", "\u661F\u671F\u4E09", "\u661F\u671F\u56DB", "\u661F\u671F\u4E94", "\u661F\u671F\u516D"], 5 | aMonStr: ["\u4E00\u6708", "\u4E8C\u6708", "\u4E09\u6708", "\u56DB\u6708", "\u4E94\u6708", "\u516D\u6708", "\u4E03\u6708", "\u516B\u6708", "\u4E5D\u6708", "\u5341\u6708", "\u5341\u4E00", "\u5341\u4E8C"], 6 | aLongMonStr: ["\u4E00\u6708", "\u4E8C\u6708", "\u4E09\u6708", "\u56DB\u6708", "\u4E94\u6708", "\u516D\u6708", "\u4E03\u6708", "\u516B\u6708", "\u4E5D\u6708", "\u5341\u6708", "\u5341\u4E00\u6708", "\u5341\u4E8C\u6708"], 7 | clearStr: "\u6E05\u7A7A", 8 | todayStr: "\u4ECA\u5929", 9 | okStr: "\u78BA\u5B9A", 10 | updateStr: "\u78BA\u5B9A", 11 | timeStr: "\u6642\u9593", 12 | quickStr: "\u5FEB\u901F\u9078\u64C7", 13 | err_1: '\u6700\u5C0F\u65E5\u671F\u4E0D\u80FD\u5927\u65BC\u6700\u5927\u65E5\u671F!' 14 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/ClassManageService.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service; 2 | 3 | import top.itning.ta.entity.Clazz; 4 | import top.itning.ta.exception.DataNotFindException; 5 | import top.itning.ta.exception.NullParameterException; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 班级信息管理服务 11 | * 12 | * @author wangn 13 | */ 14 | public interface ClassManageService { 15 | /** 16 | * 获取所有班级信息 17 | * 18 | * @return 班级信息集合 19 | */ 20 | List getAllClassInfo(); 21 | 22 | /** 23 | * 根据班级ID获取该班级学生数量 24 | * 25 | * @param id 班级ID 26 | * @return 该班级学生数量 27 | */ 28 | int getStudentNumByClassID(String id); 29 | 30 | /** 31 | * 添加班级信息 32 | * 33 | * @param clazz 班级信息 34 | * @throws NullParameterException 如果班级信息有字段为空则抛出该异常 35 | */ 36 | void addClassInfo(Clazz clazz) throws NullParameterException; 37 | 38 | /** 39 | * 根据班级ID删除班级信息 40 | * 41 | * @param id 班级ID 42 | * @throws DataNotFindException 如果该班级没有找到则抛出该异常 43 | */ 44 | void delClassInfo(String id) throws DataNotFindException; 45 | 46 | /** 47 | * 检查所有班级是否有学生 48 | * 49 | * @return 当且仅当有班级有学生时返回true 50 | */ 51 | boolean hasStudent(); 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/config/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.core.userdetails.UserDetails; 7 | import org.springframework.security.core.userdetails.UserDetailsService; 8 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 9 | import org.springframework.stereotype.Service; 10 | import top.itning.ta.dao.UserDao; 11 | import top.itning.ta.entity.User; 12 | 13 | /** 14 | * @author Ning 15 | */ 16 | @Service 17 | public class UserDetailsServiceImpl implements UserDetailsService { 18 | private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class); 19 | 20 | @Autowired 21 | private UserDao userDao; 22 | 23 | @Override 24 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 25 | logger.debug("loadUserByUsername::开始登陆,用户名->" + username); 26 | User user = userDao.findByUsername(username); 27 | if (user == null) { 28 | logger.warn("loadUserByUsername::用户名:" + username + "不存在"); 29 | throw new UsernameNotFoundException("用户名:" + username + "不存在"); 30 | } 31 | return user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/dao/StudentInfoDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import top.itning.ta.entity.Clazz; 6 | import top.itning.ta.entity.StudentInfo; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * STU_INFO Table Dao 12 | * 13 | * @author wangn 14 | */ 15 | public interface StudentInfoDao extends JpaRepository { 16 | /** 17 | * 根据班级查找所有学生信息 18 | * 19 | * @param clazz 要查找的班级 20 | * @return 学生信息集合 21 | */ 22 | List findAllByClazz(Clazz clazz); 23 | 24 | /** 25 | * 根据ID查找img字段 26 | * 27 | * @param id 学生ID 28 | * @return 学生头像信息 29 | */ 30 | @Query("select s.img from StudentInfo s where s.id=?1") 31 | String findimgByID(String id); 32 | 33 | /** 34 | * 根据班级计算学生数量 35 | * 36 | * @param clazz 班级 37 | * @return 该班级学生数量 38 | */ 39 | int countAllByClazz(Clazz clazz); 40 | 41 | /** 42 | * 根据班级删除学生信息 43 | * 44 | * @param clazz 班级 45 | */ 46 | void deleteAllByClazz(Clazz clazz); 47 | 48 | /** 49 | * 根据学生姓名查询学生信息(like %name%) 50 | * 51 | * @param name 学生姓名 52 | * @return 学生信息集合 53 | */ 54 | List findByNameContaining(String name); 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/StudentLeaveService.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service; 2 | 3 | import top.itning.ta.entity.SearchLeave; 4 | import top.itning.ta.entity.StudentLeave; 5 | import top.itning.ta.exception.DataNotFindException; 6 | import top.itning.ta.exception.NullParameterException; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 请假信息管理服务 12 | * 13 | * @author Ning 14 | */ 15 | public interface StudentLeaveService { 16 | /** 17 | * 获得所有学生的请假信息 18 | * 19 | * @return 所有学生请假信息 20 | */ 21 | List getAllStudentLeave(); 22 | 23 | /** 24 | * 根据ID删除请假信息 25 | * 26 | * @param id 要删除的请假ID 27 | * @throws DataNotFindException 如果该ID的请假信息没有找到则抛出该异常 28 | */ 29 | void delStudentLeaveByID(String id) throws DataNotFindException; 30 | 31 | /** 32 | * 添加学生请假信息方法 33 | * 34 | * @param studentLeave 学生请假信息 35 | * @throws NullParameterException 如果学生请假信息有字段为空则抛出该异常 36 | */ 37 | void addStudentLeaveInfo(StudentLeave studentLeave) throws NullParameterException; 38 | 39 | /** 40 | * 搜索请假信息 41 | * 42 | * @param searchLeave 请假信息 43 | * @return 学生请假信息集合 44 | */ 45 | List searchStudentLeaveInfo(SearchLeave searchLeave); 46 | 47 | /** 48 | * 获得学生的请假数量信息 49 | * 50 | * @return 学生请假数 51 | */ 52 | long getStudentLeaveNum(); 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/LeaveType.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | import javax.validation.constraints.NotNull; 10 | import java.io.Serializable; 11 | 12 | /** 13 | * 实体类:LeaveType 14 | * 请假类型 15 | * 16 | * @author wangn 17 | */ 18 | @Entity 19 | @Table(name = "LEAVE_TYPE") 20 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 21 | public class LeaveType implements Serializable { 22 | /* 23 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 24 | https://stackoverflow.com/questions/24994440/no-serializer-found-for-class-org-hibernate-proxy-pojo-javassist-javassist 25 | */ 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | @Column(name = "id") 31 | private String id; 32 | /** 33 | * 班级名 34 | */ 35 | @NotNull 36 | @Column(name = "name") 37 | private String name; 38 | 39 | public String getId() { 40 | return id; 41 | } 42 | 43 | public void setId(String id) { 44 | this.id = id; 45 | } 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "LeaveType{" + 58 | "id='" + id + '\'' + 59 | ", name='" + name + '\'' + 60 | '}'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // _ooOoo_ // 3 | // o8888888o // 4 | // 88" . "88 // 5 | // (| ^_^ |) // 6 | // O\ = /O // 7 | // ____/`---'\____ // 8 | // .' \\| |// `. // 9 | // / \\||| : |||// \ // 10 | // / _||||| -:- |||||- \ // 11 | // | | \\\ - /// | | // 12 | // | \_| ''\---/'' | | // 13 | // \ .-\__ `-` ___/-. / // 14 | // ___`. .' /--.--\ `. . ___ // 15 | // ."" '< `.___\_<|>_/___.' >'"". // 16 | // | | : `- \`.;`\ _ /`;.`/ - ` : | | // 17 | // \ \ `-. \_ __\ /__ _/ .-` / / // 18 | // ========`-.____`-.___\_____/___.-`____.-'======== // 19 | // `=---=' // 20 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // 21 | // 佛祖保佑 永不宕机 永无BUG // 22 | /////////////////////////////////////////////////////////////////// 23 | Welcome Use Teacher Assistant 24 | Application Version: ${application.version}${application.formatted-version} 25 | Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/canvas-nest/canvas-nest.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: v1.0.1 5 | * GitHub: https://github.com/hustcc/canvas-nest.js 6 | **/ 7 | !function(){function n(n,e,t){return n.getAttribute(e)||t}function e(n){return document.getElementsByTagName(n)}function t(){var t=e("script"),o=t.length,i=t[o-1];return{l:o,z:n(i,"zIndex",-1),o:n(i,"opacity",.5),c:n(i,"color","0,0,0"),n:n(i,"count",99)}}function o(){a=m.width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,c=m.height=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}function i(){r.clearRect(0,0,a,c);var n,e,t,o,m,l;s.forEach(function(i,x){for(i.x+=i.xa,i.y+=i.ya,i.xa*=i.x>a||i.x<0?-1:1,i.ya*=i.y>c||i.y<0?-1:1,r.fillRect(i.x-.5,i.y-.5,1,1),e=x+1;e=n.max/2&&(i.x-=.03*o,i.y-=.03*m),t=(n.max-l)/n.max,r.beginPath(),r.lineWidth=t/2,r.strokeStyle="rgba("+d.c+","+(t+.2)+")",r.moveTo(i.x,i.y),r.lineTo(n.x,n.y),r.stroke()))}),x(i)}var a,c,u,m=document.createElement("canvas"),d=t(),l="c_n"+d.l,r=m.getContext("2d"),x=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(n){window.setTimeout(n,1e3/45)},w=Math.random,y={x:null,y:null,max:2e4};m.id=l,m.style.cssText="position:fixed;top:0;left:0;z-index:"+d.z+";opacity:"+d.o,e("body")[0].appendChild(m),o(),window.onresize=o,window.onmousemove=function(n){n=n||window.event,y.x=n.clientX,y.y=n.clientY},window.onmouseout=function(){y.x=null,y.y=null};for(var s=[],f=0;d.n>f;f++){var h=w()*a,g=w()*c,v=2*w()-1,p=2*w()-1;s.push({x:h,y:g,xa:v,ya:p,max:6e3})}u=s.concat([y]),setTimeout(function(){i()},100)}(); -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.authentication.AuthenticationManager; 6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 7 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | 12 | /** 13 | * @author Ning 14 | */ 15 | @Configuration 16 | @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) 17 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 18 | 19 | @Override 20 | @Bean 21 | public UserDetailsService userDetailsService() { 22 | return new UserDetailsServiceImpl(); 23 | } 24 | 25 | @Override 26 | @Bean 27 | public AuthenticationManager authenticationManagerBean() throws Exception { 28 | // ALTOUGH THIS SEEMS LIKE USELESS CODE, 29 | // ITS REQUIRED TO PREVEND SPRING BOOT AUTO-CONFIGURATION 30 | return super.authenticationManagerBean(); 31 | } 32 | 33 | @Override 34 | protected void configure(HttpSecurity http) throws Exception { 35 | http.csrf().disable(); 36 | http.authorizeRequests(). 37 | antMatchers("/css/**", "/image/**", "/js/**", "/lib_web/**").permitAll(). 38 | anyRequest().authenticated(). 39 | and().formLogin().loginPage("/login").permitAll(). 40 | and().logout().permitAll(); 41 | http.logout().logoutSuccessUrl("/"); 42 | } 43 | 44 | @Override 45 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 46 | auth.userDetailsService(userDetailsService()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/SearchLeave.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Arrays; 5 | import java.util.Date; 6 | 7 | /** 8 | * 搜索请假信息实体类 9 | * 10 | * @author Ning 11 | */ 12 | public class SearchLeave implements Serializable { 13 | /** 14 | * 要查询的关键字(姓名/ID) 15 | */ 16 | private String key; 17 | /** 18 | * 请假时常 19 | */ 20 | private String[] often; 21 | /** 22 | * 开始日期 23 | */ 24 | private Date startdate; 25 | /** 26 | * 结束日期 27 | */ 28 | private Date enddate; 29 | /** 30 | * 请假类型 31 | */ 32 | private String[] matter; 33 | /** 34 | * 班级 35 | */ 36 | private String[] clazz; 37 | 38 | public String getKey() { 39 | return key; 40 | } 41 | 42 | public void setKey(String key) { 43 | this.key = key; 44 | } 45 | 46 | public String[] getOften() { 47 | return often; 48 | } 49 | 50 | public void setOften(String[] often) { 51 | this.often = often; 52 | } 53 | 54 | public Date getStartdate() { 55 | return startdate; 56 | } 57 | 58 | public void setStartdate(Date startdate) { 59 | this.startdate = startdate; 60 | } 61 | 62 | public Date getEnddate() { 63 | return enddate; 64 | } 65 | 66 | public void setEnddate(Date enddate) { 67 | this.enddate = enddate; 68 | } 69 | 70 | public String[] getMatter() { 71 | return matter; 72 | } 73 | 74 | public void setMatter(String[] matter) { 75 | this.matter = matter; 76 | } 77 | 78 | public String[] getClazz() { 79 | return clazz; 80 | } 81 | 82 | public void setClazz(String[] clazz) { 83 | this.clazz = clazz; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | return "SearchLeave{" + 89 | "key='" + key + '\'' + 90 | ", often=" + Arrays.toString(often) + 91 | ", startdate=" + startdate + 92 | ", enddate=" + enddate + 93 | ", matter=" + Arrays.toString(matter) + 94 | ", clazz=" + Arrays.toString(clazz) + 95 | '}'; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/impl/LeaveTypeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service.impl; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import top.itning.ta.dao.LeaveTypeDao; 8 | import top.itning.ta.entity.LeaveType; 9 | import top.itning.ta.service.LeaveTypeService; 10 | 11 | import javax.transaction.Transactional; 12 | import java.util.List; 13 | 14 | /** 15 | * 学生请假类型服务实现类 16 | * 17 | * @author Ning 18 | */ 19 | @Service 20 | @Transactional(rollbackOn = Exception.class) 21 | public class LeaveTypeServiceImpl implements LeaveTypeService { 22 | private static final Logger logger = LoggerFactory.getLogger(LeaveTypeServiceImpl.class); 23 | 24 | /** 25 | * 默认请假类型数量,该字段用于判断自动生成是否成功 26 | */ 27 | private static final int DEFAUT_LEAVE_TYPE_NUM = 3; 28 | 29 | private final LeaveTypeDao leaveTypeDao; 30 | 31 | @Autowired 32 | public LeaveTypeServiceImpl(LeaveTypeDao leaveTypeDao) { 33 | this.leaveTypeDao = leaveTypeDao; 34 | if (leaveTypeDao.count() == 0) { 35 | logger.info("LeaveTypeServiceImpl::请假类型信息不存在,将自动生成3种请假类型"); 36 | LeaveType leaveType1 = new LeaveType(); 37 | leaveType1.setId("1"); 38 | leaveType1.setName("事假"); 39 | LeaveType leaveType2 = new LeaveType(); 40 | leaveType2.setId("2"); 41 | leaveType2.setName("病假"); 42 | LeaveType leaveType3 = new LeaveType(); 43 | leaveType3.setId("3"); 44 | leaveType3.setName("旷课"); 45 | leaveTypeDao.saveAndFlush(leaveType1); 46 | leaveTypeDao.saveAndFlush(leaveType2); 47 | leaveTypeDao.saveAndFlush(leaveType3); 48 | if (leaveTypeDao.count() == DEFAUT_LEAVE_TYPE_NUM) { 49 | logger.info("LeaveTypeServiceImpl::已自动生成3种请假类型,并保存"); 50 | } else { 51 | logger.warn("LeaveTypeServiceImpl::保存失败!!!"); 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | public List getAllLeaveType() { 58 | List leaveTypeList = leaveTypeDao.findAll(); 59 | logger.debug("getAllLeaveType::获取到请假类型数->" + leaveTypeList.size()); 60 | return leaveTypeList; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/StudentInfoService.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service; 2 | 3 | import org.springframework.web.multipart.MultipartFile; 4 | import top.itning.ta.entity.Clazz; 5 | import top.itning.ta.entity.StudentInfo; 6 | import top.itning.ta.exception.DataNotFindException; 7 | import top.itning.ta.exception.NullParameterException; 8 | 9 | import javax.servlet.ServletOutputStream; 10 | import java.io.IOException; 11 | import java.util.List; 12 | 13 | /** 14 | * 学生信息管理服务 15 | * 16 | * @author wangn 17 | */ 18 | public interface StudentInfoService { 19 | /** 20 | * 根据班级ID获取所有学生信息 21 | * 22 | * @param clazz 班级id 23 | * @return 该班级所有学生信息 24 | * @throws DataNotFindException 如果所查找的数据没有找到抛出该异常 25 | */ 26 | List getAllStudentInfoByClass(String clazz) throws DataNotFindException; 27 | 28 | /** 29 | * 根据学生ID获取学生信息 30 | * 31 | * @param id 学生ID 32 | * @return 学生实体 33 | * @throws DataNotFindException 该ID学生没有找到则抛出该异常 34 | */ 35 | StudentInfo getOneStudentInfoByID(String id) throws DataNotFindException; 36 | 37 | /** 38 | * 根据班级ID获取班级实体 39 | * 40 | * @param id 班级ID 41 | * @return 班级信息 42 | * @throws DataNotFindException 没有找到班级时抛出此异常 43 | */ 44 | Clazz getClassInfoByID(String id) throws DataNotFindException; 45 | 46 | /** 47 | * 添加学生信息 48 | * 49 | * @param studentInfo 学生信息 50 | * @param file 学生头像文件 51 | * @throws NullParameterException 实体类有空参数时抛出该异常 52 | */ 53 | void addStudentInfo(StudentInfo studentInfo, MultipartFile file) throws NullParameterException; 54 | 55 | 56 | /** 57 | * 根据ID删除学生信息 58 | * 59 | * @param id 学生ID 60 | * @throws DataNotFindException 学生ID不存在则抛出该异常 61 | */ 62 | void delStudentInfo(String id) throws DataNotFindException; 63 | 64 | /** 65 | * 根据学生ID批量生成EXCEL文件生成 66 | * 67 | * @param servletOutputStream servlet输出流 68 | * @param id 学生ID 69 | * @throws DataNotFindException 如果学生ID未找到则抛出该异常 70 | * @throws IOException 文件操作出错抛出该异常 71 | */ 72 | void downStudentInfo(ServletOutputStream servletOutputStream, String... id) throws DataNotFindException, IOException; 73 | 74 | /** 75 | * 使用Excel文件添加学生信息 76 | * 77 | * @param file Excel文件 78 | * @throws NullParameterException 文件为空则抛出该异常 79 | * @throws DataNotFindException 班级没有找到则抛出该异常 80 | * @throws IOException 文件读写失败抛出该异常 81 | */ 82 | void addStudentInfoByExcel(MultipartFile file) throws NullParameterException, DataNotFindException, IOException; 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/Clazz.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.Id; 6 | import javax.persistence.Table; 7 | import javax.validation.constraints.NotNull; 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 实体类:Class 12 | * 班级信息 13 | * 14 | * @author wangn 15 | */ 16 | @Entity 17 | @Table(name = "CLASS") 18 | public class Clazz implements Serializable { 19 | /** 20 | * UUID 21 | */ 22 | @Id 23 | @Column(name = "id") 24 | private String id; 25 | /** 26 | * 班级名 27 | */ 28 | @NotNull 29 | @Column(name = "class") 30 | private String clazz; 31 | /** 32 | * 教师 33 | */ 34 | @NotNull 35 | @Column(name = "teacher") 36 | private String teacher; 37 | /** 38 | * 所在学院 39 | */ 40 | @NotNull 41 | @Column(name = "college") 42 | private String college; 43 | /** 44 | * 所在专业 45 | */ 46 | @NotNull 47 | @Column(name = "profession") 48 | private String profession; 49 | 50 | private Integer num; 51 | 52 | public String getId() { 53 | return id; 54 | } 55 | 56 | public void setId(String id) { 57 | this.id = id; 58 | } 59 | 60 | public String getClazz() { 61 | return clazz; 62 | } 63 | 64 | public void setClazz(String clazz) { 65 | this.clazz = clazz; 66 | } 67 | 68 | public String getTeacher() { 69 | return teacher; 70 | } 71 | 72 | public void setTeacher(String teacher) { 73 | this.teacher = teacher; 74 | } 75 | 76 | public String getCollege() { 77 | return college; 78 | } 79 | 80 | public void setCollege(String college) { 81 | this.college = college; 82 | } 83 | 84 | public String getProfession() { 85 | return profession; 86 | } 87 | 88 | public void setProfession(String profession) { 89 | this.profession = profession; 90 | } 91 | 92 | public Integer getNum() { 93 | return num; 94 | } 95 | 96 | public void setNum(Integer num) { 97 | this.num = num; 98 | } 99 | 100 | @Override 101 | public String toString() { 102 | return "Clazz{" + 103 | "id='" + id + '\'' + 104 | ", clazz='" + clazz + '\'' + 105 | ", teacher='" + teacher + '\'' + 106 | ", college='" + college + '\'' + 107 | ", profession='" + profession + '\'' + 108 | '}'; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/impl/SettingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service.impl; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.stereotype.Service; 9 | import top.itning.ta.dao.UserDao; 10 | import top.itning.ta.entity.User; 11 | import top.itning.ta.exception.NullParameterException; 12 | import top.itning.ta.service.SettingService; 13 | 14 | import javax.transaction.Transactional; 15 | 16 | 17 | /** 18 | * 设置服务实线类 19 | * 20 | * @author Ning 21 | */ 22 | @Service 23 | @Transactional(rollbackOn = Exception.class) 24 | public class SettingServiceImpl implements SettingService { 25 | private static final Logger logger = LoggerFactory.getLogger(SettingServiceImpl.class); 26 | 27 | private final UserDao userDao; 28 | 29 | @Autowired 30 | public SettingServiceImpl(UserDao userDao) { 31 | this.userDao = userDao; 32 | } 33 | 34 | @Override 35 | public String getThemeColor() { 36 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 37 | if (StringUtils.isNotBlank(user.getThemeColor())) { 38 | logger.info("getThemeColor::设置主题颜色->" + user.getThemeColor()); 39 | return user.getThemeColor(); 40 | } else { 41 | logger.info("getThemeColor::设置默认主题颜色"); 42 | return "mdui-theme-primary-indigo"; 43 | } 44 | } 45 | 46 | @Override 47 | public String getThemeColorAccent() { 48 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 49 | if (StringUtils.isNotBlank(user.getThemeColorAccent())) { 50 | logger.info("getThemeColor::设置强调色->" + user.getThemeColorAccent()); 51 | return user.getThemeColorAccent(); 52 | } else { 53 | logger.info("getThemeColorAccent::设置默认强调色"); 54 | return "mdui-theme-accent-pink"; 55 | } 56 | } 57 | 58 | @Override 59 | public void setThemeColor(String color) throws NullParameterException { 60 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 61 | if (color == null) { 62 | logger.warn("setThemeColor::参数color为空"); 63 | throw new NullParameterException("参数color为空"); 64 | } 65 | user.setThemeColor("mdui-theme-primary-" + color); 66 | userDao.saveAndFlush(user); 67 | } 68 | 69 | @Override 70 | public void setThemeColorAccent(String color) throws NullParameterException { 71 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 72 | if (color == null) { 73 | logger.warn("setThemeColorAccent::参数color为空"); 74 | throw new NullParameterException("参数color为空"); 75 | } 76 | user.setThemeColorAccent("mdui-theme-accent-" + color); 77 | userDao.saveAndFlush(user); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/exception/resolver/ExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.exception.resolver; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.ExceptionHandler; 7 | import org.springframework.web.bind.annotation.ResponseBody; 8 | import org.springframework.web.servlet.ModelAndView; 9 | import top.itning.ta.entity.ServerMessage; 10 | import top.itning.ta.exception.DataNotFindException; 11 | import top.itning.ta.exception.DefaultException; 12 | import top.itning.ta.exception.JsonException; 13 | import top.itning.ta.exception.NullParameterException; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | 17 | /** 18 | * 异常处理 19 | * 20 | * @author wangn 21 | */ 22 | @ControllerAdvice 23 | public class ExceptionResolver { 24 | private static final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class); 25 | /** 26 | * 默认错误页面 27 | */ 28 | private static final String DEFAULT_ERROR_VIEW = "error"; 29 | 30 | /** 31 | * 默认错误适配 32 | * 33 | * @param req HttpServletRequest 34 | * @param e Exception 35 | * @return ModelAndView 36 | * @throws Exception 异常 37 | */ 38 | @ExceptionHandler(value = DefaultException.class) 39 | public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { 40 | logger.warn("defaultErrorHandler->" + e.getMessage()); 41 | ModelAndView mav = new ModelAndView(); 42 | mav.addObject("exceptionMessage", e.getMessage()); 43 | mav.addObject("url", req.getRequestURL().toString()); 44 | mav.setViewName(DEFAULT_ERROR_VIEW); 45 | return mav; 46 | } 47 | 48 | /** 49 | * 其他异常消息 50 | * 51 | * @param req HttpServletRequest 52 | * @param e Exception 53 | * @return ModelAndView 54 | * @throws Exception 异常 55 | */ 56 | @ExceptionHandler(value = Exception.class) 57 | public ModelAndView otherErrorHandler(HttpServletRequest req, Exception e) throws Exception { 58 | logger.warn("otherErrorHandler->" + e.getMessage()); 59 | ModelAndView mav = new ModelAndView(); 60 | mav.addObject("exceptionMessage", e.getMessage()); 61 | mav.addObject("url", req.getRequestURL().toString()); 62 | mav.setViewName(DEFAULT_ERROR_VIEW); 63 | return mav; 64 | } 65 | 66 | /** 67 | * json 格式错误消息 68 | * 69 | * @param req HttpServletRequest 70 | * @param e Exception 71 | * @return 异常消息 72 | * @throws Exception 异常 73 | */ 74 | @ExceptionHandler(value = JsonException.class) 75 | @ResponseBody 76 | public ServerMessage jsonErrorHandler(HttpServletRequest req, Exception e) throws Exception { 77 | logger.warn("jsonErrorHandler->" + e.getMessage()); 78 | ServerMessage serverMessage = new ServerMessage(); 79 | if (e instanceof NullParameterException || e instanceof DataNotFindException) { 80 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 81 | } else { 82 | serverMessage.setCode(ServerMessage.NOT_FIND); 83 | } 84 | serverMessage.setMsg(e.getMessage()); 85 | serverMessage.setUrl(req.getRequestURL().toString()); 86 | return serverMessage; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/twoer/datepicker.css: -------------------------------------------------------------------------------- 1 | .WdateDiv{position:relative;width:190px;font-size:12px;color:#333;border:solid 1px #DEDEDE;background-color:#F2F0F1;padding:5px;}.WdateDiv2{width:360px;}.WdateDiv .NavImg a,.WdateDiv .yminput,.WdateDiv .yminputfocus,.WdateDiv #dpQS{background:url(img.gif) no-repeat;}.WdateDiv .NavImg a{float:left;width:16px;height:16px;cursor:pointer;}.WdateDiv .NavImgll a{background-position:0 5px;}.WdateDiv .NavImgl a{background-position:0 -10px;}.WdateDiv .NavImgr a{background-position:0 -25px;float:right;}.WdateDiv .NavImgrr a{background-position:0 -40px;float:right;}.WdateDiv #dpTitle{line-height:0;height:23px;padding:3px 0 0;}.WdateDiv .yminput,.WdateDiv .yminputfocus{margin-left:3px;width:50px;height:20px;line-height:16px;border:solid 1px #F2F0F1;cursor:pointer;background-position:35px -68px;}.WdateDiv .yminputfocus{background-color:#fff;border:solid 1px #D8D8D8;}.WdateDiv .menuSel{z-index:1;position:absolute;background-color:#FFF;border:#A3C6C8 1px solid;display:none;}.WdateDiv .menu{background:#fff;}.WdateDiv .menuOn{color:#fff;background:#64A3F3;}.WdateDiv .MMenu,.WdateDiv .YMenu{margin-top:20px;margin-left:-1px;width:68px;border:solid 1px #D9D9D9;padding:2px;}.WdateDiv .MMenu table,.WdateDiv .YMenu table{width:100%;}.WdateDiv .MMenu table td,.WdateDiv .YMenu table td{line-height:20px;text-align:center;font-size:12px;cursor:pointer;padding:0;}.WdateDiv .Wweek{text-align:center;background:#DAF3F5;border-right:#BDEBEE 1px solid;}.WdateDiv td{line-height:20px;font-size:12px;color:#999;background:#fff;cursor:pointer;padding:1px;}.WdateDiv .MTitle td{line-height:24px;color:#7D7D7D;background:#F2F0F1;cursor:default;}.WdateDiv .WdayTable2{border-collapse:collapse;border:gray 1px solid;}.WdateDiv .WdayTable2 table{border:0;}.WdateDiv .WdayTable{line-height:20px;color:#13777e;background-color:#edfbfb;}.WdateDiv .WdayTable td{text-align:center;}.WdateDiv .Wday{color:#323232;}.WdateDiv .Wwday{color:#65A4F3;}.WdateDiv .Wtoday{color:#FF6D10;background:#E0EDFE;}.WdateDiv .WspecialDay{background-color:#66F4DF;}.WdateDiv .WotherDay{color:#D4D4D4;}.WdateDiv #dpTime{position:relative;margin-top:5px;}.WdateDiv #dpTime #dpTimeStr{display:inline-block;width:30px;color:#7d7d7d;}.WdateDiv #dpTime input{width:25px;height:20px;line-height:20px;text-align:center;color:#333;border:#D9D9D9 1px solid;margin:0;padding:0;}.WdateDiv #dpTime .tm{width:7px;border:none;background:#F2F0F1;}.WdateDiv #dpQS{float:left;margin-right:3px;margin-top:6px;width:16px;height:16px;cursor:pointer;background-position:0 -90px;}.WdateDiv #dpControl{text-align:right;margin-top:3px;}.WdateDiv .dpButton{margin-left:2px;line-height:16px;width:45px;background-color:#64A3F3;color:#fff;border:none;cursor:pointer;}.WdateDiv .dpButton:hover{background-color:#64A3F3;}.WdateDiv .hhMenu,.WdateDiv .mmMenu,.WdateDiv .ssMenu{position:absolute;font-size:12px;color:#333;border:solid 1px #DEDEDE;background-color:#F2F0F1;padding:3px;}.WdateDiv #dpTime .menu,.WdateDiv #dpTime .menuOn{width:18px;height:18px;line-height:18px;text-align:center;background:#fff;}.WdateDiv #dpTime .menuOn{background:#65A2F3;}.WdateDiv #dpTime td{background:#F2F0F1;}.WdateDiv .hhMenu{top:-87px;left:32px;}.WdateDiv .mmMenu{top:-47px;left:32px;}.WdateDiv .ssMenu{top:-27px;left:32px;}.WdateDiv .invalidMenu,.WdateDiv .WinvalidDay{color:#aaa;}.WdateDiv .WdayOn,.WdateDiv .WwdayOn,.WdateDiv .Wselday,.WdateDiv .WotherDayOn{background-color:#65A2F3;color:#fff;}.WdateDiv #dpTime #dpTimeUp,.WdateDiv #dpTime #dpTimeDown{display:none;} -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/StudentLeave.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | import javax.persistence.*; 4 | import javax.validation.constraints.NotNull; 5 | import java.io.Serializable; 6 | import java.util.Date; 7 | 8 | /** 9 | * 实体类:StudentLeave 10 | * 学生请假信息 11 | * 12 | * @author wangn 13 | */ 14 | @Entity 15 | @Table(name = "STU_LEAVE") 16 | public class StudentLeave implements Serializable { 17 | /** 18 | * UUID 19 | */ 20 | @Id 21 | @Column(name = "id") 22 | private String id; 23 | /** 24 | * 学生ID 25 | */ 26 | @NotNull 27 | @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 28 | @JoinColumn(name = "sid") 29 | private StudentInfo sid; 30 | /** 31 | * 开始日期 32 | */ 33 | @NotNull 34 | @Column(name = "starttime") 35 | private Date starttime; 36 | /** 37 | * 请假时长 38 | */ 39 | @NotNull 40 | @Column(name = "often") 41 | private String often; 42 | /** 43 | * 请假类型 44 | */ 45 | @NotNull 46 | @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 47 | @JoinColumn(name = "matter") 48 | private LeaveType matter; 49 | /** 50 | * 原因 51 | */ 52 | @NotNull 53 | @Column(name = "reason") 54 | private String reason; 55 | /** 56 | * 备注 57 | */ 58 | @Column(name = "remarks") 59 | private String remarks; 60 | 61 | /** 62 | * 所属用户名 63 | */ 64 | @NotNull 65 | @Column(name = "uname") 66 | private String uname; 67 | 68 | public String getId() { 69 | return id; 70 | } 71 | 72 | public void setId(String id) { 73 | this.id = id; 74 | } 75 | 76 | public StudentInfo getSid() { 77 | return sid; 78 | } 79 | 80 | public void setSid(StudentInfo sid) { 81 | this.sid = sid; 82 | } 83 | 84 | public Date getStarttime() { 85 | return starttime; 86 | } 87 | 88 | public void setStarttime(Date starttime) { 89 | this.starttime = starttime; 90 | } 91 | 92 | public String getOften() { 93 | return often; 94 | } 95 | 96 | public void setOften(String often) { 97 | this.often = often; 98 | } 99 | 100 | public LeaveType getMatter() { 101 | return matter; 102 | } 103 | 104 | public void setMatter(LeaveType matter) { 105 | this.matter = matter; 106 | } 107 | 108 | public String getReason() { 109 | return reason; 110 | } 111 | 112 | public void setReason(String reason) { 113 | this.reason = reason; 114 | } 115 | 116 | public String getRemarks() { 117 | return remarks; 118 | } 119 | 120 | public void setRemarks(String remarks) { 121 | this.remarks = remarks; 122 | } 123 | 124 | public String getUname() { 125 | return uname; 126 | } 127 | 128 | public void setUname(String uname) { 129 | this.uname = uname; 130 | } 131 | 132 | @Override 133 | public String toString() { 134 | return "StudentLeave{" + 135 | "id='" + id + '\'' + 136 | ", sid=" + sid + 137 | ", starttime=" + starttime + 138 | ", often='" + often + '\'' + 139 | ", matter=" + matter + 140 | ", reason='" + reason + '\'' + 141 | ", remarks='" + remarks + '\'' + 142 | ", uname='" + uname + '\'' + 143 | '}'; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Teacher Assistant 教师助手 2 | [![GitHub stars](https://img.shields.io/github/stars/itning/Ta.svg?style=social&label=Stars)](https://github.com/itning/Ta/stargazers) 3 | [![GitHub forks](https://img.shields.io/github/forks/itning/Ta.svg?style=social&label=Fork)](https://github.com/itning/Ta/network/members) 4 | [![GitHub watchers](https://img.shields.io/github/watchers/itning/Ta.svg?style=social&label=Watch)](https://github.com/itning/Ta/watchers) 5 | [![GitHub followers](https://img.shields.io/github/followers/itning.svg?style=social&label=Follow)](https://github.com/itning?tab=followers) 6 | 7 | [![GitHub issues](https://img.shields.io/github/issues/itning/Ta.svg)](https://github.com/itning/Ta/issues) 8 | [![GitHub license](https://img.shields.io/github/license/itning/Ta.svg)](https://github.com/itning/Ta/blob/master/LICENSE) 9 | [![GitHub last commit](https://img.shields.io/github/last-commit/itning/Ta.svg)](https://github.com/itning/Ta/commits) 10 | [![GitHub release](https://img.shields.io/github/release/itning/Ta.svg)](https://github.com/itning/Ta/releases) 11 | [![GitHub repo size in bytes](https://img.shields.io/github/repo-size/itning/Ta.svg)](https://github.com/itning/Ta) 12 | [![HitCount](http://hits.dwyl.io/itning/Ta.svg)](http://hits.dwyl.io/itning/Ta) 13 | [![language](https://img.shields.io/badge/language-JAVA-green.svg)](https://github.com/itning/Ta) 14 | 15 | ### 简介 16 | > 教师助手(以下简称Ta)是一款能帮助教师管理学生信息,学生请假记录,请假批复的平台 17 | 18 | > Ta为改善教师办公效率,实现办公自动化的目的而生 19 | 20 | > Ta的功能目前在不断开发测试完善中 21 | 22 | > 项目使用Spring Boot搭建,前端使用了Material Design风格的框架MDUI 23 | 24 | 目前已经实现: 25 | 26 | 1. 两种方式添加学生信息 27 | - 通过网页添加 28 | - 通过Excel文件批量导入 29 | 2. 删除学生信息 30 | - 通过复选框进行选择删除 31 | 3. 修改学生信息 32 | - 在学生详情页面进行修改学生信息 33 | 4. 根据班级信息查找该班所有学生信息 34 | 5. 批量下载学生信息到Excel文件 35 | 6. 历史请假信息显示 36 | 7. 条件搜索查询学生请假信息 37 | - 自由选择筛选条件 38 | 8. 通过网页添加学生请假信息 39 | 9. 增加班级信息 40 | 10. 删除班级信息 41 | 11. 登陆功能 42 | 12. 细颗粒度安全控制 43 | - 方法级别权限控制 44 | 13. 更改主题 45 | 14. 夜间模式 46 | 15. 多用户登陆支持 47 | 48 | ### 安装使用 49 | - 项目使用jdk9编译,项目使用编译器为IntelliJ IDEA 50 | - 要求最低jdk版本为9 (项目使用了jdk9新特性) 51 | - 项目数据库目前使用的是mysql,更改数据库请在配置文件中修改(application-dev.yml和application-prod.yml [开发环境和生产环境]) 52 | - 使用mysql用户名为root密码为kingston,修改也在配置文件中修改 53 | - 项目使用ORM技术 无需创建数据库和表 54 | - 启动 55 | ``` 56 | java -jar xxx.jar 57 | ``` 58 | - 登陆用户名密码目前需要手动添加到数据库中 59 | - user表建表语句 60 | ``` 61 | SET FOREIGN_KEY_CHECKS=0; 62 | DROP TABLE IF EXISTS `user`; 63 | CREATE TABLE `user` ( 64 | `id` varchar(255) NOT NULL, 65 | `name` varchar(255) NOT NULL, 66 | `password` varchar(255) NOT NULL, 67 | `role` varchar(255) NOT NULL, 68 | `tc` varchar(255) DEFAULT NULL, 69 | `tca` varchar(255) DEFAULT NULL, 70 | `username` varchar(255) NOT NULL, 71 | PRIMARY KEY (`id`) 72 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 73 | ``` 74 | 其中role可填A/B/C 75 | 76 | A为教师权限;B为班委权限;C为普通学生权限; 77 | ### 技术架构 78 | #### 前端 79 | - [MDUI](https://www.mdui.org/) 80 | - [canvas-nest](https://github.com/hustcc/canvas-nest.js) 81 | - [My97 DatePicker](http://www.my97.net/index.asp) 82 | - [Jquery](https://jquery.org/) 83 | #### 后端 84 | - Spring Boot 85 | - Spring JPA 86 | - Spring Security 87 | - Apache POI 88 | ### 预览 89 | 90 | ![i](https://github.com/itning/Ta/blob/master/pic/login.png). 91 | ![i](https://github.com/itning/Ta/blob/master/pic/show1.png) 92 | ![i](https://github.com/itning/Ta/blob/master/pic/show2.png) 93 | ![i](https://github.com/itning/Ta/blob/master/pic/show3.png) 94 | ![i](https://github.com/itning/Ta/blob/master/pic/show4.png) 95 | 96 | ### 开源协议 97 | - [MIT](https://github.com/itning/Ta/blob/master/LICENSE) 98 | -------------------------------------------------------------------------------- /src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 404-TA 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 |
30 |
31 | menu 33 |

学生管理系统

34 |
35 | refresh 37 |
38 |
39 | 40 | 72 |
73 |

404

74 | 75 |

76 | 77 |

78 |

点我回首页

79 |
80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 登陆-TA 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 31 | 32 | 33 | 60 | 61 | 62 | 63 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/User.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | import javax.validation.constraints.NotNull; 12 | import java.io.Serializable; 13 | import java.util.ArrayList; 14 | import java.util.Collection; 15 | import java.util.List; 16 | 17 | /** 18 | * 实体类:User 19 | * 用于登录信息 20 | * 21 | * @author wangn 22 | */ 23 | @Entity 24 | @Table(name = "USER") 25 | public class User implements Serializable, UserDetails { 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | @Column(name = "id") 31 | private String id; 32 | /** 33 | * 用户名 34 | */ 35 | @NotNull 36 | @Column(name = "username") 37 | private String username; 38 | /** 39 | * 密码 40 | */ 41 | @NotNull 42 | @Column(name = "password") 43 | private String password; 44 | /** 45 | * 角色 46 | */ 47 | @NotNull 48 | @Column(name = "role") 49 | private String role; 50 | /** 51 | * 姓名 52 | */ 53 | @NotNull 54 | @Column(name = "name") 55 | private String name; 56 | 57 | /** 58 | * 主色 59 | */ 60 | @Column(name = "tc") 61 | private String themeColor; 62 | 63 | /** 64 | * 强调色 65 | */ 66 | @Column(name = "tca") 67 | private String themeColorAccent; 68 | 69 | public String getId() { 70 | return id; 71 | } 72 | 73 | public void setId(String id) { 74 | this.id = id; 75 | } 76 | 77 | @Override 78 | public String getUsername() { 79 | return username; 80 | } 81 | 82 | @Override 83 | public boolean isAccountNonExpired() { 84 | return true; 85 | } 86 | 87 | @Override 88 | public boolean isAccountNonLocked() { 89 | return true; 90 | } 91 | 92 | @Override 93 | public boolean isCredentialsNonExpired() { 94 | return true; 95 | } 96 | 97 | @Override 98 | public boolean isEnabled() { 99 | return true; 100 | } 101 | 102 | public void setUsername(String username) { 103 | this.username = username; 104 | } 105 | 106 | @Override 107 | public Collection getAuthorities() { 108 | List auths = new ArrayList<>(); 109 | auths.add(new SimpleGrantedAuthority(this.getRole())); 110 | return auths; 111 | } 112 | 113 | @Override 114 | public String getPassword() { 115 | return password; 116 | } 117 | 118 | public void setPassword(String password) { 119 | this.password = password; 120 | } 121 | 122 | public String getRole() { 123 | return role; 124 | } 125 | 126 | public void setRole(String role) { 127 | this.role = role; 128 | } 129 | 130 | public String getName() { 131 | return name; 132 | } 133 | 134 | public void setName(String name) { 135 | this.name = name; 136 | } 137 | 138 | public String getThemeColor() { 139 | return themeColor; 140 | } 141 | 142 | public void setThemeColor(String themeColor) { 143 | this.themeColor = themeColor; 144 | } 145 | 146 | public String getThemeColorAccent() { 147 | return themeColorAccent; 148 | } 149 | 150 | public void setThemeColorAccent(String themeColorAccent) { 151 | this.themeColorAccent = themeColorAccent; 152 | } 153 | 154 | @Override 155 | public String toString() { 156 | return "User{" + 157 | "id='" + id + '\'' + 158 | ", username='" + username + '\'' + 159 | ", password='" + password + '\'' + 160 | ", role='" + role + '\'' + 161 | ", name='" + name + '\'' + 162 | ", themeColor='" + themeColor + '\'' + 163 | ", themeColorAccent='" + themeColorAccent + '\'' + 164 | '}'; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/controller/FrameWorkController.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.controller; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import top.itning.ta.entity.Clazz; 11 | import top.itning.ta.entity.ServerMessage; 12 | import top.itning.ta.exception.NullParameterException; 13 | import top.itning.ta.service.ClassManageService; 14 | import top.itning.ta.service.SettingService; 15 | import top.itning.ta.service.StudentLeaveService; 16 | 17 | import java.util.List; 18 | 19 | /** 20 | * 框架初始化控制器 21 | * 22 | * @author wangn 23 | */ 24 | @Controller 25 | public class FrameWorkController { 26 | private static final Logger logger = LoggerFactory.getLogger(FrameWorkController.class); 27 | 28 | private final ClassManageService classManageService; 29 | 30 | private final StudentLeaveService studentLeaveService; 31 | 32 | private final SettingService settingService; 33 | 34 | @Autowired 35 | public FrameWorkController(ClassManageService classManageService, StudentLeaveService studentLeaveService, SettingService settingService) { 36 | this.classManageService = classManageService; 37 | this.studentLeaveService = studentLeaveService; 38 | this.settingService = settingService; 39 | } 40 | 41 | /** 42 | * 根路径 43 | * 44 | * @return 重定向到主页 45 | */ 46 | @GetMapping("/") 47 | public String root() { 48 | logger.debug("root::重定向到主页"); 49 | return "redirect:/index"; 50 | } 51 | 52 | /** 53 | * 登陆页面 54 | * 55 | * @return login.html 56 | */ 57 | @GetMapping("/login") 58 | public String login() { 59 | logger.debug("login::跳转到登录页面"); 60 | return "login"; 61 | } 62 | 63 | /** 64 | * 页面框架初始化 65 | * 66 | * @param model 模型 67 | * @return index.html 68 | */ 69 | @GetMapping("/index") 70 | public String frameWorkInit(Model model) { 71 | List allClazzInfo = classManageService.getAllClassInfo(); 72 | if (allClazzInfo.size() == 0) { 73 | logger.info("frameWorkInit::没有班级信息,将重定向到班级显示页面"); 74 | return "redirect:/class/show"; 75 | } 76 | model.addAttribute("classList", allClazzInfo); 77 | model.addAttribute("studentLeaveNum", studentLeaveService.getStudentLeaveNum()); 78 | model.addAttribute("themeColor", settingService.getThemeColor()); 79 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 80 | model.addAttribute("hasStudent", classManageService.hasStudent()); 81 | logger.debug("frameWorkInit::添加classList完成,集合大小->" + allClazzInfo.size()); 82 | return "index"; 83 | } 84 | 85 | /** 86 | * 主题设置页面 87 | * 88 | * @param model 模型 89 | * @return settheme.html 90 | */ 91 | @GetMapping("/theme") 92 | public String theme(Model model) { 93 | model.addAttribute("classList", classManageService.getAllClassInfo()); 94 | model.addAttribute("studentLeaveNum", studentLeaveService.getStudentLeaveNum()); 95 | model.addAttribute("themeColor", settingService.getThemeColor()); 96 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 97 | return "settheme"; 98 | } 99 | 100 | /** 101 | * 设置主题颜色 102 | * 103 | * @param primaryColor 主色 104 | * @param accentColor 强调色 105 | * @return Json格式服务器消息 106 | */ 107 | @GetMapping("/theme/set") 108 | @ResponseBody 109 | public ServerMessage setTheme(String primaryColor, String accentColor) { 110 | ServerMessage serverMessage = new ServerMessage(); 111 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 112 | serverMessage.setMsg("设置成功"); 113 | try { 114 | settingService.setThemeColor(primaryColor); 115 | settingService.setThemeColorAccent(accentColor); 116 | } catch (NullParameterException e) { 117 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 118 | serverMessage.setMsg("设置失败:" + e.getExceptionMessage()); 119 | } 120 | serverMessage.setUrl("/theme/set?primaryColor=" + primaryColor + "&accentColor=" + accentColor); 121 | return serverMessage; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | top.itning 7 | ta 8 | 2.0.0-RELEASE 9 | jar 10 | 11 | ta 12 | Teacher Assistant 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.9.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 9 25 | 26 | 3.0.7.RELEASE 27 | 3.0.0.RELEASE 28 | 2.0.5 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-jpa 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-security 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-thymeleaf 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-web 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | org.springframework.security 56 | spring-security-test 57 | test 58 | 59 | 60 | 61 | 62 | mysql 63 | mysql-connector-java 64 | 6.0.6 65 | 66 | 67 | 68 | 69 | org.apache.commons 70 | commons-lang3 71 | 3.7 72 | 73 | 74 | 75 | 76 | javax.xml.bind 77 | jaxb-api 78 | 2.3.0 79 | 80 | 81 | 82 | 83 | org.apache.poi 84 | poi 85 | 3.17 86 | 87 | 88 | 89 | 90 | org.apache.poi 91 | poi-ooxml 92 | 3.17 93 | 94 | 95 | 96 | 97 | org.thymeleaf.extras 98 | thymeleaf-extras-springsecurity4 99 | 3.0.2.RELEASE 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | org.springframework.boot 108 | spring-boot-maven-plugin 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/controller/clazz/ClassManageController.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.controller.clazz; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.access.prepost.PreAuthorize; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | import top.itning.ta.entity.Clazz; 14 | import top.itning.ta.entity.ServerMessage; 15 | import top.itning.ta.exception.DataNotFindException; 16 | import top.itning.ta.exception.NullParameterException; 17 | import top.itning.ta.service.ClassManageService; 18 | import top.itning.ta.service.SettingService; 19 | import top.itning.ta.service.StudentLeaveService; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * 班级管理控制器 25 | * 26 | * @author wangn 27 | */ 28 | @Controller 29 | @PreAuthorize("hasAuthority('A')") 30 | @RequestMapping("/class") 31 | public class ClassManageController { 32 | private static final Logger logger = LoggerFactory.getLogger(ClassManageController.class); 33 | 34 | private final ClassManageService classManageService; 35 | 36 | private final StudentLeaveService studentLeaveService; 37 | 38 | private final SettingService settingService; 39 | 40 | @Autowired 41 | public ClassManageController(ClassManageService classManageService, StudentLeaveService studentLeaveService, SettingService settingService) { 42 | this.classManageService = classManageService; 43 | this.studentLeaveService = studentLeaveService; 44 | this.settingService = settingService; 45 | } 46 | 47 | /** 48 | * 显示所有班级信息 49 | * 50 | * @param model 模型 51 | * @return classset.html 52 | */ 53 | @GetMapping("/show") 54 | public String showClassInfo(Model model) { 55 | List allClassInfo = classManageService.getAllClassInfo(); 56 | logger.debug("showClassInfo::班级集合信息获取完成"); 57 | if (allClassInfo != null) { 58 | allClassInfo.forEach(clazz -> clazz.setNum(classManageService.getStudentNumByClassID(clazz.getId()))); 59 | model.addAttribute("classList", allClassInfo); 60 | logger.debug("showClassInfo::添加classList完成,集合大小->" + allClassInfo.size()); 61 | } 62 | model.addAttribute("studentLeaveNum", studentLeaveService.getStudentLeaveNum()); 63 | model.addAttribute("themeColor", settingService.getThemeColor()); 64 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 65 | model.addAttribute("hasStudent", classManageService.hasStudent()); 66 | return "classset"; 67 | } 68 | 69 | /** 70 | * 添加班级信息 71 | * 72 | * @param clazz 班级信息 73 | * @return 服务器消息Json 74 | */ 75 | @GetMapping("/add") 76 | @ResponseBody 77 | public ServerMessage addClassInfo(Clazz clazz) { 78 | ServerMessage serverMessage = new ServerMessage(); 79 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 80 | serverMessage.setMsg("添加成功"); 81 | try { 82 | classManageService.addClassInfo(clazz); 83 | } catch (NullParameterException e) { 84 | logger.warn("addClassInfo::添加失败->" + e.getExceptionMessage()); 85 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 86 | serverMessage.setMsg(e.getExceptionMessage()); 87 | } 88 | serverMessage.setUrl("/class/add"); 89 | return serverMessage; 90 | } 91 | 92 | /** 93 | * 删除班级信息 94 | * 95 | * @param id 班级ID 96 | * @return 服务器消息json 97 | */ 98 | @GetMapping("/del/{id}") 99 | @ResponseBody 100 | public ServerMessage delClassInfo(@PathVariable("id") String id) { 101 | logger.debug("delClassInfo::要删除的班级ID->" + id); 102 | ServerMessage serverMessage = new ServerMessage(); 103 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 104 | serverMessage.setMsg("删除成功"); 105 | try { 106 | classManageService.delClassInfo(id); 107 | } catch (DataNotFindException e) { 108 | logger.warn("delClassInfo::删除失败->" + e.getExceptionMessage()); 109 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 110 | serverMessage.setMsg(e.getExceptionMessage()); 111 | } 112 | serverMessage.setUrl("/class/del/" + id); 113 | return serverMessage; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/impl/ClassManageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service.impl; 2 | 3 | import org.apache.commons.lang3.ClassUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.stereotype.Service; 9 | import top.itning.ta.dao.ClazzDao; 10 | import top.itning.ta.dao.StudentInfoDao; 11 | import top.itning.ta.dao.StudentLeaveDao; 12 | import top.itning.ta.entity.Clazz; 13 | import top.itning.ta.entity.User; 14 | import top.itning.ta.exception.DataNotFindException; 15 | import top.itning.ta.exception.NullParameterException; 16 | import top.itning.ta.service.ClassManageService; 17 | 18 | import javax.transaction.Transactional; 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.UUID; 22 | 23 | /** 24 | * 班级信息管理服务实现类 25 | * 26 | * @author wangn 27 | */ 28 | @Service 29 | @Transactional(rollbackOn = Exception.class) 30 | public class ClassManageServiceImpl implements ClassManageService { 31 | private static final Logger logger = LoggerFactory.getLogger(ClassManageServiceImpl.class); 32 | 33 | private final ClazzDao clazzDao; 34 | 35 | private final StudentInfoDao studentInfoDao; 36 | 37 | private final StudentLeaveDao studentLeaveDao; 38 | 39 | @Autowired 40 | public ClassManageServiceImpl(ClazzDao clazzDao, StudentInfoDao studentInfoDao, StudentLeaveDao studentLeaveDao) { 41 | this.clazzDao = clazzDao; 42 | this.studentInfoDao = studentInfoDao; 43 | this.studentLeaveDao = studentLeaveDao; 44 | } 45 | 46 | @Override 47 | public List getAllClassInfo() { 48 | if (ClassUtils.isAssignable(SecurityContextHolder.getContext().getAuthentication().getPrincipal().getClass(), User.class)) { 49 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 50 | if (user.getName() != null) { 51 | logger.info("getAllClassInfo::获取到的登陆教师->" + user.getName()); 52 | List clazzList = clazzDao.findByTeacher(user.getName()); 53 | logger.debug("getAllClassInfo::获取到的班级数量" + clazzList.size()); 54 | return clazzList; 55 | } 56 | } 57 | return new ArrayList<>(); 58 | } 59 | 60 | @Override 61 | public int getStudentNumByClassID(String id) { 62 | logger.debug("getStudentNumByClassID::开始统计班级人数"); 63 | return studentInfoDao.countAllByClazz(clazzDao.findOne(id)); 64 | } 65 | 66 | @Override 67 | public void addClassInfo(Clazz clazz) throws NullParameterException { 68 | clazz.setId(UUID.randomUUID().toString().replace("-", "")); 69 | if (ClassUtils.isAssignable(SecurityContextHolder.getContext().getAuthentication().getPrincipal().getClass(), User.class)) { 70 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 71 | if (user.getName() != null) { 72 | logger.info("addClassInfo::获取到的登陆教师->" + user.getName()); 73 | clazz.setTeacher(((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName()); 74 | } else { 75 | logger.warn("addClassInfo::获取到的登陆教师为空"); 76 | throw new NullParameterException("登陆用户名为空"); 77 | } 78 | } else { 79 | logger.warn("addClassInfo::类转换出现异常"); 80 | throw new ClassCastException("类转换出现异常"); 81 | } 82 | if (clazz.getClazz() == null) { 83 | throw new NullParameterException("参数clazz为空"); 84 | } 85 | if (clazz.getCollege() == null) { 86 | throw new NullParameterException("参数college为空"); 87 | } 88 | if (clazz.getProfession() == null) { 89 | throw new NullParameterException("参数profession为空"); 90 | } 91 | clazzDao.saveAndFlush(clazz); 92 | } 93 | 94 | @Override 95 | public void delClassInfo(String id) throws DataNotFindException { 96 | if (!clazzDao.exists(id)) { 97 | logger.warn("delClassInfo::班级ID" + id + "没有找到"); 98 | throw new DataNotFindException("班级ID" + id + "没有找到"); 99 | } 100 | logger.debug("delClassInfo::开始删除请假信息"); 101 | studentInfoDao.findAllByClazz(clazzDao.findOne(id)).forEach(studentLeaveDao::deleteAllBySid); 102 | logger.debug("delClassInfo::开始删除学生信息"); 103 | studentInfoDao.deleteAllByClazz(clazzDao.findOne(id)); 104 | logger.debug("delClassInfo::开始班级信息"); 105 | clazzDao.delete(id); 106 | } 107 | 108 | @Override 109 | public boolean hasStudent() { 110 | return this.getAllClassInfo().stream().anyMatch(clazz -> this.getStudentNumByClassID(clazz.getId()) != 0); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/canvas-nest/canvas-nest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: v1.0.1 5 | * GitHub: https://github.com/hustcc/canvas-nest.js 6 | **/ 7 | !function () { 8 | //封装方法,压缩之后减少文件大小 9 | function get_attribute(node, attr, default_value) { 10 | return node.getAttribute(attr) || default_value; 11 | } 12 | 13 | //封装方法,压缩之后减少文件大小 14 | function get_by_tagname(name) { 15 | return document.getElementsByTagName(name); 16 | } 17 | 18 | //获取配置参数 19 | function get_config_option() { 20 | var scripts = get_by_tagname("script"), 21 | script_len = scripts.length, 22 | script = scripts[script_len - 1]; //当前加载的script 23 | return { 24 | l: script_len, //长度,用于生成id用 25 | z: get_attribute(script, "zIndex", -1), //z-index 26 | o: get_attribute(script, "opacity", 0.5), //opacity 27 | c: get_attribute(script, "color", "0,0,0"), //color 28 | n: get_attribute(script, "count", 99) //count 29 | }; 30 | } 31 | 32 | //设置canvas的高宽 33 | function set_canvas_size() { 34 | canvas_width = the_canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, 35 | canvas_height = the_canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 36 | } 37 | 38 | //绘制过程 39 | function draw_canvas() { 40 | context.clearRect(0, 0, canvas_width, canvas_height); 41 | //随机的线条和当前位置联合数组 42 | var e, i, d, x_dist, y_dist, dist; //临时节点 43 | //遍历处理每一个点 44 | random_points.forEach(function (r, idx) { 45 | r.x += r.xa, 46 | r.y += r.ya, //移动 47 | r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1, 48 | r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1, //碰到边界,反向反弹 49 | context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); //绘制一个宽高为1的点 50 | //从下一个点开始 51 | for (i = idx + 1; i < all_array.length; i++) { 52 | e = all_array[i]; 53 | // 当前点存在 54 | if (null !== e.x && null !== e.y) { 55 | x_dist = r.x - e.x; //x轴距离 l 56 | y_dist = r.y - e.y; //y轴距离 n 57 | dist = x_dist * x_dist + y_dist * y_dist; //总距离, m 58 | 59 | dist < e.max && (e === current_point && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), //靠近的时候加速 60 | d = (e.max - dist) / e.max, 61 | context.beginPath(), 62 | context.lineWidth = d / 2, 63 | context.strokeStyle = "rgba(" + config.c + "," + (d + 0.2) + ")", 64 | context.moveTo(r.x, r.y), 65 | context.lineTo(e.x, e.y), 66 | context.stroke()); 67 | } 68 | } 69 | }), frame_func(draw_canvas); 70 | } 71 | 72 | //创建画布,并添加到body中 73 | var the_canvas = document.createElement("canvas"), //画布 74 | config = get_config_option(), //配置 75 | canvas_id = "c_n" + config.l, //canvas id 76 | context = the_canvas.getContext("2d"), canvas_width, canvas_height, 77 | frame_func = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (func) { 78 | window.setTimeout(func, 1000 / 45); 79 | }, random = Math.random, 80 | current_point = { 81 | x: null, //当前鼠标x 82 | y: null, //当前鼠标y 83 | max: 20000 // 圈半径的平方 84 | }, 85 | all_array; 86 | the_canvas.id = canvas_id; 87 | the_canvas.style.cssText = "position:fixed;top:0;left:0;z-index:" + config.z + ";opacity:" + config.o; 88 | get_by_tagname("body")[0].appendChild(the_canvas); 89 | 90 | //初始化画布大小 91 | set_canvas_size(); 92 | window.onresize = set_canvas_size; 93 | //当时鼠标位置存储,离开的时候,释放当前位置信息 94 | window.onmousemove = function (e) { 95 | e = e || window.event; 96 | current_point.x = e.clientX; 97 | current_point.y = e.clientY; 98 | }, window.onmouseout = function () { 99 | current_point.x = null; 100 | current_point.y = null; 101 | }; 102 | //随机生成config.n条线位置信息 103 | for (var random_points = [], i = 0; config.n > i; i++) { 104 | var x = random() * canvas_width, //随机位置 105 | y = random() * canvas_height, 106 | xa = 2 * random() - 1, //随机运动方向 107 | ya = 2 * random() - 1; 108 | // 随机点 109 | random_points.push({ 110 | x: x, 111 | y: y, 112 | xa: xa, 113 | ya: ya, 114 | max: 6000 //沾附距离 115 | }); 116 | } 117 | all_array = random_points.concat([current_point]); 118 | //0.1秒后绘制 119 | setTimeout(function () { 120 | draw_canvas(); 121 | }, 100); 122 | }(); 123 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/default/datepicker.css: -------------------------------------------------------------------------------- 1 | /* 2 | * My97 DatePicker 4.8 3 | */ 4 | 5 | .WdateDiv { 6 | width: 180px; 7 | background-color: #FFFFFF; 8 | border: #bbb 1px solid; 9 | padding: 2px; 10 | } 11 | 12 | .WdateDiv2 { 13 | width: 360px; 14 | } 15 | 16 | .WdateDiv * { 17 | font-size: 9pt; 18 | } 19 | 20 | .WdateDiv .NavImg a { 21 | display: block; 22 | cursor: pointer; 23 | height: 16px; 24 | width: 16px; 25 | } 26 | 27 | .WdateDiv .NavImgll a { 28 | float: left; 29 | background: transparent url(img.gif) no-repeat scroll 0 0; 30 | } 31 | 32 | .WdateDiv .NavImgl a { 33 | float: left; 34 | background: transparent url(img.gif) no-repeat scroll -16px 0; 35 | } 36 | 37 | .WdateDiv .NavImgr a { 38 | float: right; 39 | background: transparent url(img.gif) no-repeat scroll -32px 0; 40 | } 41 | 42 | .WdateDiv .NavImgrr a { 43 | float: right; 44 | background: transparent url(img.gif) no-repeat scroll -48px 0; 45 | } 46 | 47 | .WdateDiv #dpTitle { 48 | height: 24px; 49 | margin-bottom: 2px; 50 | padding: 1px; 51 | } 52 | 53 | .WdateDiv .yminput { 54 | margin-top: 2px; 55 | text-align: center; 56 | height: 20px; 57 | border: 0px; 58 | width: 50px; 59 | cursor: pointer; 60 | } 61 | 62 | .WdateDiv .yminputfocus { 63 | margin-top: 2px; 64 | text-align: center; 65 | font-weight: bold; 66 | height: 20px; 67 | color: blue; 68 | border: #ccc 1px solid; 69 | width: 50px; 70 | } 71 | 72 | .WdateDiv .menuSel { 73 | z-index: 1; 74 | position: absolute; 75 | background-color: #FFFFFF; 76 | border: #ccc 1px solid; 77 | display: none; 78 | } 79 | 80 | .WdateDiv .menu { 81 | cursor: pointer; 82 | background-color: #fff; 83 | } 84 | 85 | .WdateDiv .menuOn { 86 | cursor: pointer; 87 | background-color: #BEEBEE; 88 | } 89 | 90 | .WdateDiv .invalidMenu { 91 | color: #aaa; 92 | } 93 | 94 | .WdateDiv .YMenu { 95 | margin-top: 20px; 96 | 97 | } 98 | 99 | .WdateDiv .MMenu { 100 | margin-top: 20px; 101 | *width: 62px; 102 | } 103 | 104 | .WdateDiv .hhMenu { 105 | margin-top: -90px; 106 | margin-left: 26px; 107 | } 108 | 109 | .WdateDiv .mmMenu { 110 | margin-top: -46px; 111 | margin-left: 26px; 112 | } 113 | 114 | .WdateDiv .ssMenu { 115 | margin-top: -24px; 116 | margin-left: 26px; 117 | } 118 | 119 | .WdateDiv .Wweek { 120 | text-align: center; 121 | background: #DAF3F5; 122 | border-right: #BDEBEE 1px solid; 123 | } 124 | 125 | .WdateDiv .MTitle { 126 | background-color: #BDEBEE; 127 | } 128 | 129 | .WdateDiv .WdayTable2 { 130 | border-collapse: collapse; 131 | border: #c5d9e8 1px solid; 132 | } 133 | 134 | .WdateDiv .WdayTable2 table { 135 | border: 0; 136 | } 137 | 138 | .WdateDiv .WdayTable { 139 | line-height: 20px; 140 | border: #c5d9e8 1px solid; 141 | } 142 | 143 | .WdateDiv .WdayTable td { 144 | text-align: center; 145 | } 146 | 147 | .WdateDiv .Wday { 148 | cursor: pointer; 149 | } 150 | 151 | .WdateDiv .WdayOn { 152 | cursor: pointer; 153 | background-color: #C0EBEF; 154 | } 155 | 156 | .WdateDiv .Wwday { 157 | cursor: pointer; 158 | color: #FF2F2F; 159 | } 160 | 161 | .WdateDiv .WwdayOn { 162 | cursor: pointer; 163 | color: #000; 164 | background-color: #C0EBEF; 165 | } 166 | 167 | .WdateDiv .Wtoday { 168 | cursor: pointer; 169 | color: blue; 170 | } 171 | 172 | .WdateDiv .Wselday { 173 | background-color: #A9E4E9; 174 | } 175 | 176 | .WdateDiv .WspecialDay { 177 | background-color: #66F4DF; 178 | } 179 | 180 | .WdateDiv .WotherDay { 181 | cursor: pointer; 182 | color: #6A6AFF; 183 | } 184 | 185 | .WdateDiv .WotherDayOn { 186 | cursor: pointer; 187 | background-color: #C0EBEF; 188 | } 189 | 190 | .WdateDiv .WinvalidDay { 191 | color: #aaa; 192 | } 193 | 194 | .WdateDiv #dpTime { 195 | float: left; 196 | margin-top: 3px; 197 | margin-right: 30px; 198 | } 199 | 200 | .WdateDiv #dpTime #dpTimeStr { 201 | margin-left: 1px; 202 | } 203 | 204 | .WdateDiv #dpTime input { 205 | width: 18px; 206 | height: 20px; 207 | text-align: center; 208 | border: #ccc 1px solid; 209 | } 210 | 211 | .WdateDiv #dpTime .tB { 212 | border-right: 0px; 213 | } 214 | 215 | .WdateDiv #dpTime .tE { 216 | border-left: 0; 217 | border-right: 0; 218 | } 219 | 220 | .WdateDiv #dpTime .tm { 221 | width: 7px; 222 | border-left: 0; 223 | border-right: 0; 224 | } 225 | 226 | .WdateDiv #dpTime #dpTimeUp { 227 | height: 10px; 228 | width: 13px; 229 | border: 0px; 230 | background: url(img.gif) no-repeat -32px -16px; 231 | } 232 | 233 | .WdateDiv #dpTime #dpTimeDown { 234 | height: 10px; 235 | width: 13px; 236 | border: 0px; 237 | background: url(img.gif) no-repeat -48px -16px; 238 | } 239 | 240 | .WdateDiv #dpQS { 241 | float: left; 242 | margin-right: 3px; 243 | margin-top: 3px; 244 | background: url(img.gif) no-repeat 0px -16px; 245 | width: 20px; 246 | height: 20px; 247 | cursor: pointer; 248 | } 249 | 250 | .WdateDiv #dpControl { 251 | text-align: right; 252 | } 253 | 254 | .WdateDiv .dpButton { 255 | height: 20px; 256 | width: 45px; 257 | border: #ccc 1px solid; 258 | margin-top: 2px; 259 | margin-right: 1px; 260 | } -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/whyGreen/datepicker.css: -------------------------------------------------------------------------------- 1 | /* 2 | * My97 DatePicker 4.8 Skin:whyGreen 3 | */ 4 | .WdateDiv { 5 | width: 180px; 6 | background-color: #fff; 7 | border: #C5E1E4 1px solid; 8 | padding: 2px; 9 | } 10 | 11 | .WdateDiv2 { 12 | width: 360px; 13 | } 14 | 15 | .WdateDiv * { 16 | font-size: 9pt; 17 | } 18 | 19 | .WdateDiv .NavImg a { 20 | cursor: pointer; 21 | display: block; 22 | width: 16px; 23 | height: 16px; 24 | margin-top: 1px; 25 | } 26 | 27 | .WdateDiv .NavImgll a { 28 | float: left; 29 | background: url(img.gif) no-repeat; 30 | } 31 | 32 | .WdateDiv .NavImgl a { 33 | float: left; 34 | background: url(img.gif) no-repeat -16px 0px; 35 | } 36 | 37 | .WdateDiv .NavImgr a { 38 | float: right; 39 | background: url(img.gif) no-repeat -32px 0px; 40 | } 41 | 42 | .WdateDiv .NavImgrr a { 43 | float: right; 44 | background: url(img.gif) no-repeat -48px 0px; 45 | } 46 | 47 | .WdateDiv #dpTitle { 48 | height: 24px; 49 | padding: 1px; 50 | border: #c5d9e8 1px solid; 51 | background: url(bg.jpg); 52 | margin-bottom: 2px; 53 | } 54 | 55 | .WdateDiv .yminput { 56 | margin-top: 2px; 57 | text-align: center; 58 | border: 0px; 59 | height: 20px; 60 | width: 50px; 61 | color: #034c50; 62 | background-color: transparent; 63 | cursor: pointer; 64 | } 65 | 66 | .WdateDiv .yminputfocus { 67 | margin-top: 2px; 68 | text-align: center; 69 | border: #939393 1px solid; 70 | font-weight: bold; 71 | color: #034c50; 72 | height: 20px; 73 | width: 50px; 74 | } 75 | 76 | .WdateDiv .menuSel { 77 | z-index: 1; 78 | position: absolute; 79 | background-color: #FFFFFF; 80 | border: #A3C6C8 1px solid; 81 | display: none; 82 | } 83 | 84 | .WdateDiv .menu { 85 | cursor: pointer; 86 | background-color: #fff; 87 | color: #11777C; 88 | } 89 | 90 | .WdateDiv .menuOn { 91 | cursor: pointer; 92 | background-color: #BEEBEE; 93 | } 94 | 95 | .WdateDiv .invalidMenu { 96 | color: #aaa; 97 | } 98 | 99 | .WdateDiv .YMenu { 100 | margin-top: 20px; 101 | } 102 | 103 | .WdateDiv .MMenu { 104 | margin-top: 20px; 105 | *width: 62px; 106 | } 107 | 108 | .WdateDiv .hhMenu { 109 | margin-top: -90px; 110 | margin-left: 26px; 111 | } 112 | 113 | .WdateDiv .mmMenu { 114 | margin-top: -46px; 115 | margin-left: 26px; 116 | } 117 | 118 | .WdateDiv .ssMenu { 119 | margin-top: -24px; 120 | margin-left: 26px; 121 | } 122 | 123 | .WdateDiv .Wweek { 124 | text-align: center; 125 | background: #DAF3F5; 126 | border-right: #BDEBEE 1px solid; 127 | } 128 | 129 | .WdateDiv .MTitle { 130 | color: #13777e; 131 | background-color: #bdebee; 132 | } 133 | 134 | .WdateDiv .WdayTable2 { 135 | border-collapse: collapse; 136 | border: #BEE9F0 1px solid; 137 | } 138 | 139 | .WdateDiv .WdayTable2 table { 140 | border: 0; 141 | } 142 | 143 | .WdateDiv .WdayTable { 144 | line-height: 20px; 145 | color: #13777e; 146 | background-color: #edfbfb; 147 | border: #BEE9F0 1px solid; 148 | } 149 | 150 | .WdateDiv .WdayTable td { 151 | text-align: center; 152 | } 153 | 154 | .WdateDiv .Wday { 155 | cursor: pointer; 156 | } 157 | 158 | .WdateDiv .WdayOn { 159 | cursor: pointer; 160 | background-color: #74d2d9; 161 | } 162 | 163 | .WdateDiv .Wwday { 164 | cursor: pointer; 165 | color: #ab1e1e; 166 | } 167 | 168 | .WdateDiv .WwdayOn { 169 | cursor: pointer; 170 | background-color: #74d2d9; 171 | } 172 | 173 | .WdateDiv .Wtoday { 174 | cursor: pointer; 175 | color: blue; 176 | } 177 | 178 | .WdateDiv .Wselday { 179 | background-color: #A7E2E7; 180 | } 181 | 182 | .WdateDiv .WspecialDay { 183 | background-color: #66F4DF; 184 | } 185 | 186 | .WdateDiv .WotherDay { 187 | cursor: pointer; 188 | color: #0099CC; 189 | } 190 | 191 | .WdateDiv .WotherDayOn { 192 | cursor: pointer; 193 | background-color: #C0EBEF; 194 | } 195 | 196 | .WdateDiv .WinvalidDay { 197 | color: #aaa; 198 | } 199 | 200 | .WdateDiv #dpTime { 201 | float: left; 202 | margin-top: 3px; 203 | margin-right: 30px; 204 | } 205 | 206 | .WdateDiv #dpTime #dpTimeStr { 207 | margin-left: 1px; 208 | color: #497F7F; 209 | } 210 | 211 | .WdateDiv #dpTime input { 212 | height: 20px; 213 | width: 18px; 214 | text-align: center; 215 | color: #333; 216 | border: #61CAD0 1px solid; 217 | } 218 | 219 | .WdateDiv #dpTime .tB { 220 | border-right: 0px; 221 | } 222 | 223 | .WdateDiv #dpTime .tE { 224 | border-left: 0; 225 | border-right: 0; 226 | } 227 | 228 | .WdateDiv #dpTime .tm { 229 | width: 7px; 230 | border-left: 0; 231 | border-right: 0; 232 | } 233 | 234 | .WdateDiv #dpTime #dpTimeUp { 235 | height: 10px; 236 | width: 13px; 237 | border: 0px; 238 | background: url(img.gif) no-repeat -32px -16px; 239 | } 240 | 241 | .WdateDiv #dpTime #dpTimeDown { 242 | height: 10px; 243 | width: 13px; 244 | border: 0px; 245 | background: url(img.gif) no-repeat -48px -16px; 246 | } 247 | 248 | .WdateDiv #dpQS { 249 | float: left; 250 | margin-right: 3px; 251 | margin-top: 3px; 252 | background: url(img.gif) no-repeat 0px -16px; 253 | width: 20px; 254 | height: 20px; 255 | cursor: pointer; 256 | } 257 | 258 | .WdateDiv #dpControl { 259 | text-align: right; 260 | margin-top: 3px; 261 | } 262 | 263 | .WdateDiv .dpButton { 264 | height: 20px; 265 | width: 45px; 266 | margin-top: 2px; 267 | border: #38B1B9 1px solid; 268 | background-color: #CFEBEE; 269 | color: #08575B; 270 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/entity/StudentInfo.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.entity; 2 | 3 | import javax.persistence.*; 4 | import javax.validation.constraints.NotNull; 5 | import java.io.Serializable; 6 | import java.util.Date; 7 | 8 | /** 9 | * 实体类:StudentInfo 10 | * 学生信息 11 | * 12 | * @author wangn 13 | */ 14 | @Entity 15 | @Table(name = "STU_INFO") 16 | public class StudentInfo implements Serializable { 17 | /** 18 | * 学号 19 | */ 20 | @Id 21 | @Column(name = "id") 22 | private String id; 23 | /** 24 | * 姓名 25 | */ 26 | @NotNull 27 | @Column(name = "name") 28 | private String name; 29 | /** 30 | * 性别 31 | */ 32 | @NotNull 33 | @Column(name = "sex") 34 | private boolean sex; 35 | /** 36 | * 出生日期 37 | */ 38 | @NotNull 39 | @Column(name = "birthday") 40 | private Date birthday; 41 | /** 42 | * 家庭地址 43 | */ 44 | @NotNull 45 | @Column(name = "address") 46 | private String address; 47 | /** 48 | * 联系电话 49 | */ 50 | @NotNull 51 | @Column(name = "tel") 52 | private String tel; 53 | /** 54 | * 家长电话 55 | */ 56 | @NotNull 57 | @Column(name = "htel") 58 | private String htel; 59 | /** 60 | * 所在学院 61 | */ 62 | @NotNull 63 | @Column(name = "college") 64 | private String college; 65 | /** 66 | * 所在专业 67 | */ 68 | @NotNull 69 | @Column(name = "profession") 70 | private String profession; 71 | /** 72 | * 班级 73 | */ 74 | @NotNull 75 | @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 76 | @JoinColumn(name = "class") 77 | private Clazz clazz; 78 | /** 79 | * 班主任 80 | */ 81 | @NotNull 82 | @Column(name = "teacher") 83 | private String teacher; 84 | /** 85 | * 职务 86 | */ 87 | @Column(name = "position") 88 | private String position; 89 | /** 90 | * 入学时间 91 | */ 92 | @NotNull 93 | @Column(name = "intime") 94 | private Date intime; 95 | /** 96 | * 是否在籍 97 | */ 98 | @NotNull 99 | @Column(name = "isin") 100 | private boolean isin; 101 | /** 102 | * 头像 103 | */ 104 | @Column(name = "img") 105 | private String img; 106 | /** 107 | * 备注 108 | */ 109 | @Column(name = "remarks") 110 | private String remarks; 111 | 112 | public String getId() { 113 | return id; 114 | } 115 | 116 | public void setId(String id) { 117 | this.id = id; 118 | } 119 | 120 | public String getName() { 121 | return name; 122 | } 123 | 124 | public void setName(String name) { 125 | this.name = name; 126 | } 127 | 128 | public boolean isSex() { 129 | return sex; 130 | } 131 | 132 | public void setSex(boolean sex) { 133 | this.sex = sex; 134 | } 135 | 136 | public Date getBirthday() { 137 | return birthday; 138 | } 139 | 140 | public void setBirthday(Date birthday) { 141 | this.birthday = birthday; 142 | } 143 | 144 | public String getAddress() { 145 | return address; 146 | } 147 | 148 | public void setAddress(String address) { 149 | this.address = address; 150 | } 151 | 152 | public String getTel() { 153 | return tel; 154 | } 155 | 156 | public void setTel(String tel) { 157 | this.tel = tel; 158 | } 159 | 160 | public String getHtel() { 161 | return htel; 162 | } 163 | 164 | public void setHtel(String htel) { 165 | this.htel = htel; 166 | } 167 | 168 | public String getCollege() { 169 | return college; 170 | } 171 | 172 | public void setCollege(String college) { 173 | this.college = college; 174 | } 175 | 176 | public String getProfession() { 177 | return profession; 178 | } 179 | 180 | public void setProfession(String profession) { 181 | this.profession = profession; 182 | } 183 | 184 | public Clazz getClazz() { 185 | return clazz; 186 | } 187 | 188 | public void setClazz(Clazz clazz) { 189 | this.clazz = clazz; 190 | } 191 | 192 | public String getTeacher() { 193 | return teacher; 194 | } 195 | 196 | public void setTeacher(String teacher) { 197 | this.teacher = teacher; 198 | } 199 | 200 | public String getPosition() { 201 | return position; 202 | } 203 | 204 | public void setPosition(String position) { 205 | this.position = position; 206 | } 207 | 208 | public Date getIntime() { 209 | return intime; 210 | } 211 | 212 | public void setIntime(Date intime) { 213 | this.intime = intime; 214 | } 215 | 216 | public boolean isIsin() { 217 | return isin; 218 | } 219 | 220 | public void setIsin(boolean isin) { 221 | this.isin = isin; 222 | } 223 | 224 | public String getImg() { 225 | return img; 226 | } 227 | 228 | public void setImg(String img) { 229 | this.img = img; 230 | } 231 | 232 | public String getRemarks() { 233 | return remarks; 234 | } 235 | 236 | public void setRemarks(String remarks) { 237 | this.remarks = remarks; 238 | } 239 | 240 | @Override 241 | public String toString() { 242 | return "StudentInfo{" + 243 | "id='" + id + '\'' + 244 | ", name='" + name + '\'' + 245 | ", sex=" + sex + 246 | ", birthday=" + birthday + 247 | ", address='" + address + '\'' + 248 | ", tel='" + tel + '\'' + 249 | ", htel='" + htel + '\'' + 250 | ", college='" + college + '\'' + 251 | ", profession='" + profession + '\'' + 252 | ", clazz=" + clazz + 253 | ", teacher='" + teacher + '\'' + 254 | ", position='" + position + '\'' + 255 | ", intime=" + intime + 256 | ", isin=" + isin + 257 | ", img='" + img + '\'' + 258 | ", remarks='" + remarks + '\'' + 259 | '}'; 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/datepicker/skin/twoer/datepicker-dev.css: -------------------------------------------------------------------------------- 1 | /* 2 | * My97 DatePicker 4.8 3 | * auther : zhangkun , hejianting(design) 4 | * email : zhangkun_net@hotmail.com 5 | * date : 2012-05-25 6 | */ 7 | .WdateDiv { 8 | position: relative; 9 | padding: 5px; 10 | width: 180px; 11 | *width: 190px; 12 | font-size: 12px; 13 | color: #333; 14 | border: solid 1px #DEDEDE; 15 | background-color: #F2F0F1; 16 | } 17 | 18 | .WdateDiv2 { 19 | width: 360px; 20 | } 21 | 22 | .WdateDiv .NavImg a, .WdateDiv .yminput, .WdateDiv .yminputfocus, .WdateDiv #dpQS { 23 | background: url(img.gif) no-repeat; 24 | } 25 | 26 | .WdateDiv .NavImg a { 27 | float: left; 28 | width: 16px; 29 | height: 16px; 30 | cursor: pointer; 31 | } 32 | 33 | .WdateDiv .NavImgll a { 34 | background-position: 0px 5px; 35 | } 36 | 37 | .WdateDiv .NavImgl a { 38 | background-position: 0px -10px; 39 | } 40 | 41 | .WdateDiv .NavImgr a { 42 | background-position: 0px -25px; 43 | float: right; 44 | } 45 | 46 | .WdateDiv .NavImgrr a { 47 | background-position: 0px -40px; 48 | float: right; 49 | } 50 | 51 | .WdateDiv #dpTitle { 52 | padding: 3px 0px 0px 0px; 53 | line-height: 0px; 54 | height: 20px; 55 | *height: 23; 56 | } 57 | 58 | .WdateDiv .yminput, .WdateDiv .yminputfocus { 59 | margin-left: 3px; 60 | width: 50px; 61 | height: 20px; 62 | line-height: 16px; 63 | border: solid 1px #F2F0F1; 64 | cursor: pointer; 65 | background-position: 35px -68px; 66 | } 67 | 68 | .WdateDiv .yminputfocus { 69 | background-color: #fff; 70 | border: solid 1px #D8D8D8; 71 | } 72 | 73 | .WdateDiv .menuSel { 74 | z-index: 1; 75 | position: absolute; 76 | background-color: #FFFFFF; 77 | border: #A3C6C8 1px solid; 78 | display: none; 79 | } 80 | 81 | .WdateDiv .menu { 82 | background: #fff; 83 | } 84 | 85 | .WdateDiv .menuOn { 86 | color: #fff; 87 | background: #64A3F3; 88 | } 89 | 90 | .WdateDiv .invalidMenu { 91 | color: #aaa; 92 | } 93 | 94 | .WdateDiv .MMenu, .WdateDiv .YMenu { 95 | padding: 2px; 96 | margin-top: 20px; 97 | margin-left: -1px; 98 | width: 68px; 99 | border: solid 1px #D9D9D9; 100 | } 101 | 102 | .WdateDiv .MMenu table, .WdateDiv .YMenu table { 103 | width: 100%; 104 | } 105 | 106 | .WdateDiv .MMenu table td, .WdateDiv .YMenu table td { 107 | padding: 0px; 108 | line-height: 20px; 109 | text-align: center; 110 | font-size: 12px; 111 | cursor: pointer; 112 | } 113 | 114 | .WdateDiv .Wweek { 115 | text-align: center; 116 | background: #DAF3F5; 117 | border-right: #BDEBEE 1px solid; 118 | } 119 | 120 | .WdateDiv td { 121 | padding: 1px; 122 | line-height: 20px; 123 | font-size: 12px; 124 | color: #999999; 125 | background: #fff; 126 | cursor: pointer; 127 | } 128 | 129 | .WdateDiv .MTitle td { 130 | line-height: 24px; 131 | color: #7D7D7D; 132 | background: #F2F0F1; 133 | cursor: default; 134 | } 135 | 136 | .WdateDiv .WdayTable2 { 137 | border-collapse: collapse; 138 | border: #808080 1px solid; 139 | } 140 | 141 | .WdateDiv .WdayTable2 table { 142 | border: 0; 143 | } 144 | 145 | .WdateDiv .WdayTable { 146 | line-height: 20px; 147 | color: #13777e; 148 | background-color: #edfbfb; 149 | } 150 | 151 | .WdateDiv .WdayTable td { 152 | text-align: center; 153 | } 154 | 155 | .WdateDiv .Wday { 156 | color: #323232; 157 | } 158 | 159 | .WdateDiv .WdayOn { 160 | color: #fff; 161 | background-color: #65A2F3; 162 | } 163 | 164 | .WdateDiv .Wwday { 165 | color: #65A4F3; 166 | } 167 | 168 | .WdateDiv .WwdayOn { 169 | color: #fff; 170 | background-color: #65A2F3; 171 | } 172 | 173 | .WdateDiv .Wtoday { 174 | color: #FF6D10; 175 | background: #E0EDFE; 176 | } 177 | 178 | .WdateDiv .Wselday { 179 | color: #fff; 180 | background-color: #65A2F3; 181 | } 182 | 183 | .WdateDiv .WspecialDay { 184 | background-color: #66F4DF; 185 | } 186 | 187 | .WdateDiv .WotherDay { 188 | color: #D4D4D4; 189 | } 190 | 191 | .WdateDiv .WotherDayOn { 192 | color: #fff; 193 | background-color: #65A2F3; 194 | } 195 | 196 | .WdateDiv .WinvalidDay { 197 | color: #aaa; 198 | } 199 | 200 | .WdateDiv #dpTime { 201 | position: relative; 202 | margin-top: 5px; 203 | } 204 | 205 | .WdateDiv #dpTime #dpTimeStr { 206 | display: inline-block; 207 | width: 28px; 208 | *width: 30px; 209 | color: #7d7d7d; 210 | } 211 | 212 | .WdateDiv #dpTime input { 213 | padding: 0px; 214 | margin: 0px; 215 | width: 25px; 216 | height: 20px; 217 | line-height: 20px; 218 | text-align: center; 219 | color: #333; 220 | border: #D9D9D9 1px solid; 221 | } 222 | 223 | .WdateDiv #dpTime .tm { 224 | width: 7px; 225 | border: none; 226 | background: #F2F0F1; 227 | } 228 | 229 | .WdateDiv #dpTime #dpTimeUp { 230 | display: none; 231 | } 232 | 233 | .WdateDiv #dpTime #dpTimeDown { 234 | display: none; 235 | } 236 | 237 | .WdateDiv #dpQS { 238 | float: left; 239 | margin-right: 3px; 240 | margin-top: 9px; 241 | *margin-top: 6px; 242 | width: 16px; 243 | height: 16px; 244 | cursor: pointer; 245 | background-position: 0px -90px; 246 | } 247 | 248 | .WdateDiv #dpControl { 249 | text-align: right; 250 | margin-top: 3px; 251 | } 252 | 253 | .WdateDiv .dpButton { 254 | margin-left: 2px; 255 | line-height: 18px; 256 | *line-height: 16px; 257 | width: 45px; 258 | background-color: #C3C3C3; 259 | *background-color: #64A3F3; 260 | color: #fff; 261 | border: none; 262 | cursor: pointer; 263 | } 264 | 265 | .WdateDiv .dpButton:hover { 266 | background-color: #64A3F3; 267 | } 268 | 269 | .WdateDiv .hhMenu, 270 | .WdateDiv .mmMenu, 271 | .WdateDiv .ssMenu { 272 | position: absolute; 273 | padding: 3px; 274 | font-size: 12px; 275 | color: #333; 276 | border: solid 1px #DEDEDE; 277 | background-color: #F2F0F1; 278 | } 279 | 280 | .WdateDiv #dpTime .menu, .WdateDiv #dpTime .menuOn { 281 | width: 18px; 282 | height: 18px; 283 | line-height: 18px; 284 | text-align: center; 285 | background: #fff; 286 | } 287 | 288 | .WdateDiv #dpTime .menuOn { 289 | background: #65A2F3; 290 | } 291 | 292 | .WdateDiv #dpTime td { 293 | background: #F2F0F1; 294 | } 295 | 296 | .WdateDiv .hhMenu { 297 | top: -87px; 298 | left: 35px; 299 | left: 32px \9; 300 | } 301 | 302 | .WdateDiv .mmMenu { 303 | top: -47px; 304 | left: 35px; 305 | left: 32px \9; 306 | } 307 | 308 | .WdateDiv .ssMenu { 309 | top: -27px; 310 | left: 35px; 311 | left: 32px \9; 312 | } -------------------------------------------------------------------------------- /src/main/resources/templates/log.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 操作日志-教师助手-Teacher Assistant 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 |
29 |
30 | menu 32 |

教师助手 Teacher Assistant

33 |
34 | refresh 36 |
37 |
38 | 39 | 101 |
102 |
103 |
104 | 105 |
106 |
107 |
操作日志
108 |
系统记录
109 |
110 |
111 |
112 |
113 | 130 |
131 | 132 | 133 | 134 | 140 | 141 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/controller/student/leave/StudentLeaveController.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.controller.student.leave; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.propertyeditors.CustomDateEditor; 7 | import org.springframework.security.access.prepost.PreAuthorize; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.ui.Model; 10 | import org.springframework.web.bind.ServletRequestDataBinder; 11 | import org.springframework.web.bind.annotation.*; 12 | import top.itning.ta.entity.SearchLeave; 13 | import top.itning.ta.entity.ServerMessage; 14 | import top.itning.ta.entity.StudentLeave; 15 | import top.itning.ta.exception.DataNotFindException; 16 | import top.itning.ta.exception.NullParameterException; 17 | import top.itning.ta.service.*; 18 | 19 | import javax.servlet.http.HttpServletRequest; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Date; 22 | import java.util.List; 23 | 24 | /** 25 | * 学生请假控制器 26 | * 27 | * @author Ning 28 | */ 29 | @Controller 30 | @RequestMapping("/studentLeave") 31 | public class StudentLeaveController { 32 | private static final Logger logger = LoggerFactory.getLogger(StudentLeaveController.class); 33 | 34 | private final StudentLeaveService studentLeaveService; 35 | 36 | private final ClassManageService classManageService; 37 | 38 | private final LeaveTypeService leaveTypeService; 39 | 40 | private final StudentInfoService studentInfoService; 41 | 42 | private final SettingService settingService; 43 | 44 | @Autowired 45 | public StudentLeaveController(StudentLeaveService studentLeaveService, ClassManageService classManageService, LeaveTypeService leaveTypeService, StudentInfoService studentInfoService, SettingService settingService) { 46 | this.studentLeaveService = studentLeaveService; 47 | this.classManageService = classManageService; 48 | this.leaveTypeService = leaveTypeService; 49 | this.studentInfoService = studentInfoService; 50 | this.settingService = settingService; 51 | } 52 | 53 | @InitBinder 54 | protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { 55 | binder.registerCustomEditor( 56 | Date.class, 57 | new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); 58 | } 59 | 60 | /** 61 | * 历史请假信息 62 | * 63 | * @param model 模型 64 | * @return historyleave.html 65 | */ 66 | @PreAuthorize("hasAnyAuthority('A','B')") 67 | @GetMapping("/show") 68 | public String getAllStudentLeaveInfo(Model model) { 69 | List studentLeaveList = studentLeaveService.getAllStudentLeave(); 70 | if (studentLeaveList.size() == 0) { 71 | logger.info("getAllStudentLeaveInfo::学生请假信息为空,重定向到添加页面"); 72 | return "redirect:/studentLeave/add"; 73 | } 74 | model.addAttribute("studentLeaveList", studentLeaveList); 75 | model.addAttribute("classList", classManageService.getAllClassInfo()); 76 | model.addAttribute("themeColor", settingService.getThemeColor()); 77 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 78 | logger.debug("getAllStudentLeaveInfo::studentLeaveList/classList添加完成"); 79 | return "historyleave"; 80 | } 81 | 82 | /** 83 | * 根据请假ID删除请假信息 84 | * 85 | * @param id 请假ID 86 | * @return 服务器消息Json 87 | */ 88 | @PreAuthorize("hasAuthority('A')") 89 | @GetMapping("/del/{id}") 90 | @ResponseBody 91 | public ServerMessage delStudentLeaveInfo(@PathVariable("id") String id) { 92 | logger.debug("delStudentLeaveInfo::要删除的ID->" + id); 93 | ServerMessage serverMessage = new ServerMessage(); 94 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 95 | serverMessage.setMsg("ID:" + id + "删除成功"); 96 | try { 97 | studentLeaveService.delStudentLeaveByID(id); 98 | } catch (DataNotFindException e) { 99 | logger.warn("delStudentLeaveInfo::ID->" + id + "没找到,删除失败"); 100 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 101 | serverMessage.setMsg(e.getExceptionMessage()); 102 | } 103 | serverMessage.setUrl("/studentLeave/del/" + id); 104 | return serverMessage; 105 | } 106 | 107 | /** 108 | * 添加学生请假信息页面 109 | * 110 | * @param model 模型 111 | * @return addleave.html 112 | */ 113 | @PreAuthorize("hasAnyAuthority('A','B')") 114 | @GetMapping("/add") 115 | public String addStudentLeaveInfoRoute(Model model) { 116 | if (classManageService.hasStudent()) { 117 | logger.debug("addStudentLeaveInfoRoute::有学生信息"); 118 | model.addAttribute("classList", classManageService.getAllClassInfo()); 119 | model.addAttribute("leaveTypeList", leaveTypeService.getAllLeaveType()); 120 | model.addAttribute("studentLeaveNum", studentLeaveService.getStudentLeaveNum()); 121 | model.addAttribute("themeColor", settingService.getThemeColor()); 122 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 123 | logger.debug("addStudentLeaveInfoRoute::leaveTypeList/classList添加完成"); 124 | return "addleave"; 125 | } else { 126 | logger.info("addStudentLeaveInfoRoute::没有学生,跳转到学生信息管理页面"); 127 | return "redirect:/index"; 128 | } 129 | } 130 | 131 | /** 132 | * 添加请假信息 133 | * 134 | * @param studentLeave 学生请假信息实体 135 | * @param sid 学生ID 136 | * @return 重定向到历史请假信息 137 | * @throws NullParameterException 如果studentLeave有参数为空则抛出该异常 138 | * @throws DataNotFindException 如果学生ID没有找到则抛出该异常 139 | */ 140 | @PreAuthorize("hasAnyAuthority('A','B')") 141 | @PostMapping("/addLeave") 142 | public String addStudentLeaveInfo(StudentLeave studentLeave, String sid) throws NullParameterException, DataNotFindException { 143 | if (sid == null) { 144 | logger.warn("addStudentLeaveInfo:;未获取到sid"); 145 | throw new NullParameterException("参数sid为空"); 146 | } 147 | studentLeave.setSid(studentInfoService.getOneStudentInfoByID(sid)); 148 | studentLeaveService.addStudentLeaveInfo(studentLeave); 149 | return "redirect:/studentLeave/show"; 150 | } 151 | 152 | /** 153 | * 搜索请假信息页面 154 | * 155 | * @param model 模型 156 | * @return searchleave.html 157 | */ 158 | @PreAuthorize("hasAnyAuthority('A','B')") 159 | @GetMapping("/search") 160 | public String searchStudentLeave(Model model) { 161 | if (studentLeaveService.getStudentLeaveNum() == 0) { 162 | logger.info("searchStudentLeave::学生请假信息为空,重定向到添加页面"); 163 | return "redirect:/studentLeave/add"; 164 | } 165 | model.addAttribute("classList", classManageService.getAllClassInfo()); 166 | model.addAttribute("leaveTypeList", leaveTypeService.getAllLeaveType()); 167 | model.addAttribute("themeColor", settingService.getThemeColor()); 168 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 169 | logger.debug("searchStudentLeave::leaveTypeList/classList添加完成"); 170 | return "searchleave"; 171 | } 172 | 173 | /** 174 | * 搜索请假信息 175 | * 176 | * @param searchLeave 搜索请假信息 177 | * @return 搜索的学生请假信息集合 178 | */ 179 | @PreAuthorize("hasAnyAuthority('A','B')") 180 | @GetMapping("/searchLeave") 181 | @ResponseBody 182 | public List searchStudentLeaveInfo(SearchLeave searchLeave) { 183 | logger.debug("searchStudentLeaveInfo::开始搜索"); 184 | return studentLeaveService.searchStudentLeaveInfo(searchLeave); 185 | } 186 | 187 | } 188 | -------------------------------------------------------------------------------- /src/test/java/top/itning/ta/TaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | import top.itning.ta.dao.ClazzDao; 11 | import top.itning.ta.dao.LeaveTypeDao; 12 | import top.itning.ta.dao.StudentInfoDao; 13 | import top.itning.ta.dao.StudentLeaveDao; 14 | 15 | import java.io.IOException; 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | import java.util.Random; 19 | 20 | @RunWith(SpringRunner.class) 21 | @SpringBootTest 22 | public class TaApplicationTests { 23 | @Autowired 24 | private StudentInfoDao studentInfoDao; 25 | 26 | @Autowired 27 | private ClazzDao clazzDao; 28 | 29 | @Autowired 30 | private LeaveTypeDao leaveTypeDao; 31 | 32 | @Autowired 33 | private StudentLeaveDao studentLeaveDao; 34 | 35 | 36 | @Test 37 | public void contextLoads() { 38 | Logger logger = LoggerFactory.getLogger(this.getClass()); 39 | logger.info("info"); 40 | logger.debug("debug"); 41 | logger.warn("warn"); 42 | logger.error("error"); 43 | } 44 | 45 | @Test 46 | public void testStudentInfo() { 47 | /* String uuid = UUID.randomUUID().toString().replace("-", ""); 48 | List clazzList = clazzDao.findAll(); 49 | int i = 0; 50 | while (true) { 51 | i++; 52 | StudentInfo studentInfo = new StudentInfo(); 53 | studentInfo.setImg(uuid); 54 | studentInfo.setAddress(uuid); 55 | studentInfo.setBirthday(randomDate("2016-01-01", "2017-12-08")); 56 | studentInfo.setClazz(clazzList.get(randomInt(0, clazzList.size()))); 57 | studentInfo.setCollege(uuid); 58 | studentInfo.setHtel(String.valueOf(randomInt(1765223, 1313113131))); 59 | studentInfo.setTel(String.valueOf(randomInt(1765223, 1313113131))); 60 | studentInfo.setTeacher(uuid); 61 | studentInfo.setIntime(randomDate("2016-01-01", "2017-12-08")); 62 | studentInfo.setPosition(uuid); 63 | studentInfo.setProfession(uuid); 64 | studentInfo.setId(String.valueOf(randomInt(1765223, 1313113131))); 65 | studentInfo.setName(uuid); 66 | studentInfo.setRemarks(uuid); 67 | System.out.println(studentInfo); 68 | studentInfoDao.saveAndFlush(studentInfo); 69 | if (i == 500) { 70 | break; 71 | } 72 | }*/ 73 | } 74 | 75 | @Test 76 | public void testStudentLeave() throws InterruptedException { 77 | /* List leaveTypeList = leaveTypeDao.findAll(); 78 | List studentInfoList = studentInfoDao.findAll(); 79 | String uuid = UUID.randomUUID().toString().replace("-", ""); 80 | int i = 0; 81 | while (true) { 82 | i++; 83 | StudentLeave studentLeave = new StudentLeave(); 84 | studentLeave.setId(UUID.randomUUID().toString().replace("-", "")); 85 | studentLeave.setOften(String.valueOf(randomInt(1, 31))); 86 | studentLeave.setReason(UUID.randomUUID().toString().replace("-", "")); 87 | studentLeave.setRemarks(UUID.randomUUID().toString().replace("-", "")); 88 | studentLeave.setStarttime(randomDate("2016-01-01", "2017-12-08")); 89 | studentLeave.setMatter(leaveTypeList.get(randomInt(0, leaveTypeList.size()))); 90 | studentLeave.setSid(studentInfoList.get(randomInt(0, studentInfoList.size()))); 91 | System.out.println(studentLeave); 92 | studentLeaveDao.saveAndFlush(studentLeave); 93 | if (i == 100) { 94 | break; 95 | } 96 | }*/ 97 | } 98 | 99 | /** 100 | * 获取随机日期 101 | * 102 | * @param beginDate 起始日期,格式为:yyyy-MM-dd 103 | * @param endDate 结束日期,格式为:yyyy-MM-dd 104 | * @return Date 105 | */ 106 | private static Date randomDate(String beginDate, String endDate) { 107 | try { 108 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 109 | Date start = format.parse(beginDate);// 构造开始日期 110 | Date end = format.parse(endDate);// 构造结束日期 111 | // getTime()表示返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 112 | if (start.getTime() >= end.getTime()) { 113 | return null; 114 | } 115 | long date = random(start.getTime(), end.getTime()); 116 | 117 | return new Date(date); 118 | } catch (Exception e) { 119 | e.printStackTrace(); 120 | } 121 | return null; 122 | } 123 | 124 | private static long random(long begin, long end) { 125 | long rtn = begin + (long) (Math.random() * (end - begin)); 126 | // 如果返回的是开始时间和结束时间,则递归调用本函数查找随机值 127 | if (rtn == begin || rtn == end) { 128 | return random(begin, end); 129 | } 130 | return rtn; 131 | } 132 | 133 | /** 134 | * @param min 包含 135 | * @param max 不包含 136 | * @return 137 | */ 138 | private int randomInt(int min, int max) { 139 | return new Random().nextInt(max) % (max - min + 1) + min; 140 | } 141 | 142 | @Test 143 | public void testDown() throws IOException { 144 | /*Clazz clazz = clazzDao.findOne("c54794e1-e1f6-4b9b-80bf-9f15d12e1119"); 145 | List studentInfoList = studentInfoDao.findAllByClazz(clazz); 146 | studentInfoList.forEach(System.out::println); 147 | Workbook workbook = new XSSFWorkbook(); 148 | //创建工作簿 名:专业+班级 149 | Sheet sheet = workbook.createSheet(clazz.getProfession() + clazz.getClazz()); 150 | 151 | Row row = sheet.createRow(0); 152 | List titleList = new ArrayList<>(); 153 | titleList.add("学号"); 154 | titleList.add("姓名"); 155 | titleList.add("性别"); 156 | titleList.add("出生日期"); 157 | titleList.add("联系电话"); 158 | titleList.add("家长电话"); 159 | titleList.add("入学时间"); 160 | titleList.add("是否在籍"); 161 | titleList.add("班内职务"); 162 | titleList.add("班主任"); 163 | titleList.add("班级"); 164 | titleList.add("家庭地址"); 165 | titleList.add("学院"); 166 | titleList.add("专业"); 167 | titleList.add("备注"); 168 | final int[] nowCell = {0}; 169 | titleList.forEach(s -> { 170 | Cell cell = row.createCell(nowCell[0]++); 171 | cell.setCellValue(s); 172 | }); 173 | nowCell[0] = 1; 174 | studentInfoList.forEach(studentInfo -> { 175 | Row dataRow = sheet.createRow(nowCell[0]++); 176 | Cell IDCell = dataRow.createCell(0); 177 | IDCell.setCellValue(studentInfo.getId()); 178 | 179 | Cell NameCell = dataRow.createCell(1); 180 | NameCell.setCellValue(studentInfo.getName()); 181 | 182 | Cell SexCell = dataRow.createCell(2); 183 | SexCell.setCellValue(studentInfo.isSex() ? "男" : "女"); 184 | 185 | Cell BirthdayCell = dataRow.createCell(3); 186 | BirthdayCell.setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(studentInfo.getBirthday())); 187 | 188 | Cell TelCell = dataRow.createCell(4); 189 | TelCell.setCellValue(studentInfo.getTel()); 190 | 191 | Cell HtelCell = dataRow.createCell(5); 192 | HtelCell.setCellValue(studentInfo.getHtel()); 193 | 194 | Cell IntimeCell = dataRow.createCell(6); 195 | IntimeCell.setCellValue(new SimpleDateFormat("yyyy-MM").format(studentInfo.getIntime())); 196 | 197 | Cell InCell = dataRow.createCell(7); 198 | InCell.setCellValue(studentInfo.isIsin() ? "是" : "否"); 199 | 200 | Cell PositionCell = dataRow.createCell(8); 201 | PositionCell.setCellValue(studentInfo.getPosition()); 202 | 203 | Cell TeacherCell = dataRow.createCell(9); 204 | TeacherCell.setCellValue(studentInfo.getTeacher()); 205 | 206 | Cell ClassCell = dataRow.createCell(10); 207 | ClassCell.setCellValue(studentInfo.getClazz().getClazz()); 208 | 209 | Cell AddressCell = dataRow.createCell(11); 210 | AddressCell.setCellValue(studentInfo.getAddress()); 211 | 212 | Cell CollegeCell = dataRow.createCell(12); 213 | CollegeCell.setCellValue(studentInfo.getCollege()); 214 | 215 | Cell ProfessionCell = dataRow.createCell(13); 216 | ProfessionCell.setCellValue(studentInfo.getProfession()); 217 | 218 | Cell RemarksCell = dataRow.createCell(13); 219 | RemarksCell.setCellValue(studentInfo.getRemarks()); 220 | }); 221 | FileOutputStream fileOutputStream = new FileOutputStream(new File("C:/Users/Ning/Desktop/test.xlsx")); 222 | workbook.write(fileOutputStream); 223 | fileOutputStream.close(); 224 | workbook.close();*/ 225 | } 226 | 227 | @Test 228 | public void testString() { 229 | /* String str = "1017322085-1020145467-1037459874-1045385098-1079119260-1080062371-1086758172"; 230 | String[] split = StringUtils.split(str, "-"); 231 | System.out.println(split.length); 232 | System.out.println(Arrays.toString(split));*/ 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/controller/student/info/StudentInfoController.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.controller.student.info; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.apache.commons.lang3.math.NumberUtils; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.propertyeditors.CustomDateEditor; 9 | import org.springframework.security.access.prepost.PreAuthorize; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.ui.Model; 12 | import org.springframework.web.bind.ServletRequestDataBinder; 13 | import org.springframework.web.bind.annotation.*; 14 | import org.springframework.web.multipart.MultipartFile; 15 | import top.itning.ta.entity.ServerMessage; 16 | import top.itning.ta.entity.StudentInfo; 17 | import top.itning.ta.exception.DataNotFindException; 18 | import top.itning.ta.exception.JsonDataNotFindException; 19 | import top.itning.ta.exception.NullParameterException; 20 | import top.itning.ta.service.ClassManageService; 21 | import top.itning.ta.service.SettingService; 22 | import top.itning.ta.service.StudentInfoService; 23 | 24 | import javax.servlet.ServletOutputStream; 25 | import javax.servlet.http.HttpServletRequest; 26 | import javax.servlet.http.HttpServletResponse; 27 | import java.io.IOException; 28 | import java.text.SimpleDateFormat; 29 | import java.util.Date; 30 | import java.util.List; 31 | 32 | /** 33 | * 学生信息控制器 34 | * 35 | * @author wangn 36 | */ 37 | @Controller 38 | @RequestMapping("/studentInfo") 39 | public class StudentInfoController { 40 | private static final Logger logger = LoggerFactory.getLogger(StudentInfoController.class); 41 | 42 | private final StudentInfoService studentInfoService; 43 | 44 | private final ClassManageService classManageService; 45 | 46 | private final SettingService settingService; 47 | 48 | @Autowired 49 | public StudentInfoController(StudentInfoService studentInfoService, ClassManageService classManageService, SettingService settingService) { 50 | this.studentInfoService = studentInfoService; 51 | this.classManageService = classManageService; 52 | this.settingService = settingService; 53 | } 54 | 55 | @InitBinder 56 | protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { 57 | binder.registerCustomEditor( 58 | Date.class, 59 | new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); 60 | } 61 | 62 | /** 63 | * 根据班级ID显示所有学生信息 64 | * 65 | * @param classID 班级ID 66 | * @return 学生信息集合 67 | * @throws JsonDataNotFindException 如果班级没有找到则抛出该异常 68 | */ 69 | @GetMapping("/show/class/{classID}") 70 | @ResponseBody 71 | public List showStudentInfo(@PathVariable("classID") String classID) throws JsonDataNotFindException { 72 | logger.debug("showStudentInfo::获取到的班级ID->" + classID); 73 | try { 74 | return studentInfoService.getAllStudentInfoByClass(classID); 75 | } catch (DataNotFindException e) { 76 | throw new JsonDataNotFindException(e.getExceptionMessage()); 77 | } 78 | } 79 | 80 | /** 81 | * 显示学生详情方法 82 | * 83 | * @param model 模型 84 | * @param id 学生ID 85 | * @return student.html 86 | * @throws DataNotFindException 该学生ID没有找到则抛出该异常 87 | */ 88 | @GetMapping("/show/student/{id}") 89 | public String showOneStudentInfo(Model model, @PathVariable("id") String id) throws DataNotFindException { 90 | logger.debug("showOneStudentInfo::获取到的学生ID->" + id); 91 | model.addAttribute("studentInfo", studentInfoService.getOneStudentInfoByID(id)); 92 | model.addAttribute("classList", classManageService.getAllClassInfo()); 93 | logger.debug("showOneStudentInfo::studentInfo/classList添加完成"); 94 | return "student"; 95 | } 96 | 97 | /** 98 | * 使用WEB页面添加学生 99 | * 100 | * @param model 模型 101 | * @param id 班级ID 102 | * @return addstudent.html 103 | * @throws DataNotFindException 该班级没有找到则抛出该异常 104 | */ 105 | @PreAuthorize("hasAnyAuthority('A','B')") 106 | @GetMapping("/add/web/{id}") 107 | public String addStudentByWeb(Model model, @PathVariable("id") String id) throws DataNotFindException { 108 | logger.debug("addStudentByWeb::获取到要添加学生的班级ID->" + id); 109 | model.addAttribute("classInfo", studentInfoService.getClassInfoByID(id)); 110 | model.addAttribute("classList", classManageService.getAllClassInfo()); 111 | model.addAttribute("themeColor", settingService.getThemeColor()); 112 | model.addAttribute("themeColorAccent", settingService.getThemeColorAccent()); 113 | model.addAttribute("hasStudent", classManageService.hasStudent()); 114 | logger.debug("addStudentByWeb::classInfo/classList添加完成"); 115 | return "addstudent"; 116 | } 117 | 118 | /** 119 | * 添加学生信息 120 | * 121 | * @param studentInfo 学生信息实体类 122 | * @param file 文件 123 | * @return 重定向到主页(添加哪个班就显示哪个班学生) 124 | * @throws DataNotFindException 如果数据没有找到抛出该异常 125 | * @throws NullParameterException 如果有参数为空抛出该异常 126 | */ 127 | @PreAuthorize("hasAnyAuthority('A','B')") 128 | @PostMapping("/add") 129 | public String addStudentInfo(StudentInfo studentInfo, @RequestParam("file") MultipartFile file) throws DataNotFindException, NullParameterException { 130 | logger.debug("addStudentInfo::file为空->" + file.isEmpty()); 131 | studentInfoService.addStudentInfo(studentInfo, file); 132 | return "redirect:/#/" + studentInfo.getClazz().getId(); 133 | } 134 | 135 | /** 136 | * 删除学生信息 137 | * 138 | * @param id 学生ID 139 | * @return json 消息 140 | */ 141 | @PreAuthorize("hasAuthority('A')") 142 | @GetMapping("/del/student/{id}") 143 | @ResponseBody 144 | public ServerMessage delStudentInfo(@PathVariable("id") String id) { 145 | logger.debug("delStudentInfo::删除学生的ID->" + id); 146 | ServerMessage serverMessage = new ServerMessage(); 147 | serverMessage.setMsg("学生ID:" + id + "删除成功"); 148 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 149 | try { 150 | studentInfoService.delStudentInfo(id); 151 | } catch (DataNotFindException e) { 152 | logger.warn("delStudentInfo::删除ID为" + id + "失败,消息->" + e.getExceptionMessage()); 153 | serverMessage.setCode(ServerMessage.NOT_FIND); 154 | serverMessage.setMsg(e.getExceptionMessage()); 155 | } 156 | serverMessage.setUrl("/studentInfo/del/student/" + id); 157 | return serverMessage; 158 | } 159 | 160 | /** 161 | * 修改学生信息 162 | * 163 | * @param studentInfo 学生信息 164 | * @param file 学生头像 165 | * @return 重定向到该生详情页 166 | * @throws NullParameterException StudentInfo实体类有空参数时抛出该异常 167 | */ 168 | @PreAuthorize("hasAnyAuthority('A','B')") 169 | @PostMapping("/modify/student") 170 | public String modifyStudentInfo(StudentInfo studentInfo, @RequestParam("file") MultipartFile file) throws NullParameterException { 171 | logger.debug("modifyStudentInfo::修改学生ID->" + studentInfo.getId() + "file为空->" + file.isEmpty()); 172 | studentInfoService.addStudentInfo(studentInfo, file); 173 | return "redirect:/studentInfo/show/student/" + studentInfo.getId(); 174 | } 175 | 176 | /** 177 | * 下载学生信息 178 | * 179 | * @param id 学生ID用 - 符号分割ID 180 | * @param response HttpServletResponse 181 | * @throws IOException 文件操作失败抛出该异常 182 | * @throws DataNotFindException 该学生ID没有找到则抛出该异常 183 | */ 184 | @PreAuthorize("hasAnyAuthority('A','B')") 185 | @GetMapping("/down") 186 | public void downStudentInfoListByClass(String id, HttpServletResponse response) throws IOException, DataNotFindException { 187 | logger.debug("downStudentInfoListByClass::要下载的学生ID->" + id); 188 | String[] idArray = StringUtils.split(id, "-"); 189 | for (String i : idArray) { 190 | if (!NumberUtils.isParsable(i)) { 191 | logger.warn("downStudentInfoListByClass::错误参数->" + i); 192 | throw new IllegalArgumentException("参数不正确->" + i); 193 | } 194 | } 195 | String nowTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); 196 | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 197 | response.setHeader("Content-Disposition", "attachment;filename=" + new String(("学生信息" + nowTime + ".xlsx").getBytes(), "ISO-8859-1")); 198 | ServletOutputStream outputStream = response.getOutputStream(); 199 | logger.debug("downStudentInfoListByClass::outputStream.isReady->" + outputStream.isReady()); 200 | studentInfoService.downStudentInfo(outputStream, idArray); 201 | outputStream.flush(); 202 | outputStream.close(); 203 | logger.debug("downStudentInfoListByClass::outputStream close"); 204 | } 205 | 206 | /** 207 | * 上传学生信息通过Excel文件 208 | * 209 | * @param file 文件 210 | * @return 重定向到主页 211 | * @throws NullParameterException 文件不存在则抛出该异常 212 | * @throws DataNotFindException 班级没有找到则抛出该异常 213 | * @throws IOException 文件操作异常抛出 214 | */ 215 | @PreAuthorize("hasAnyAuthority('A','B')") 216 | @PostMapping("/upExcelFile") 217 | public String upExcelFile(@RequestParam("file") MultipartFile file) throws NullParameterException, DataNotFindException, IOException { 218 | if (file.isEmpty()) { 219 | logger.warn("upExcelFile::file为空"); 220 | throw new NullParameterException("file为空"); 221 | } 222 | studentInfoService.addStudentInfoByExcel(file); 223 | return "redirect:/"; 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/main/java/top/itning/ta/service/impl/StudentLeaveServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta.service.impl; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.apache.commons.lang3.math.NumberUtils; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.security.core.context.SecurityContextHolder; 9 | import org.springframework.stereotype.Service; 10 | import top.itning.ta.dao.ClazzDao; 11 | import top.itning.ta.dao.LeaveTypeDao; 12 | import top.itning.ta.dao.StudentInfoDao; 13 | import top.itning.ta.dao.StudentLeaveDao; 14 | import top.itning.ta.entity.SearchLeave; 15 | import top.itning.ta.entity.StudentInfo; 16 | import top.itning.ta.entity.StudentLeave; 17 | import top.itning.ta.entity.User; 18 | import top.itning.ta.exception.DataNotFindException; 19 | import top.itning.ta.exception.NullParameterException; 20 | import top.itning.ta.service.StudentLeaveService; 21 | 22 | import javax.persistence.criteria.Predicate; 23 | import javax.transaction.Transactional; 24 | import java.text.ParseException; 25 | import java.text.SimpleDateFormat; 26 | import java.util.*; 27 | 28 | /** 29 | * 请假信息服务实现类 30 | * 31 | * @author Ning 32 | */ 33 | @Service 34 | @Transactional(rollbackOn = Exception.class) 35 | public class StudentLeaveServiceImpl implements StudentLeaveService { 36 | private static final Logger logger = LoggerFactory.getLogger(StudentLeaveServiceImpl.class); 37 | 38 | private final StudentLeaveDao studentLeaveDao; 39 | 40 | private final StudentInfoDao studentInfoDao; 41 | 42 | private final LeaveTypeDao leaveTypeDao; 43 | 44 | private final ClazzDao clazzDao; 45 | 46 | @Autowired 47 | public StudentLeaveServiceImpl(StudentLeaveDao studentLeaveDao, StudentInfoDao studentInfoDao, LeaveTypeDao leaveTypeDao, ClazzDao clazzDao) { 48 | this.studentLeaveDao = studentLeaveDao; 49 | this.studentInfoDao = studentInfoDao; 50 | this.leaveTypeDao = leaveTypeDao; 51 | this.clazzDao = clazzDao; 52 | } 53 | 54 | @Override 55 | public List getAllStudentLeave() { 56 | logger.debug("getAllStudentLeave::开始获取学生请假信息"); 57 | List studentLeaveList = studentLeaveDao.findByUname(((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName()); 58 | logger.debug("getAllStudentLeave::获取学生请假信息的数量" + studentLeaveList.size()); 59 | return studentLeaveList; 60 | } 61 | 62 | @Override 63 | public void delStudentLeaveByID(String id) throws DataNotFindException { 64 | if (!studentLeaveDao.exists(id)) { 65 | logger.warn("delStudentLeaveByID::请假ID:" + id + "没有找到"); 66 | throw new DataNotFindException("请假ID:" + id + "没有找到"); 67 | } 68 | studentLeaveDao.delete(id); 69 | logger.debug("delStudentLeaveByID::已删除学生->" + id); 70 | } 71 | 72 | @Override 73 | public void addStudentLeaveInfo(StudentLeave studentLeave) throws NullParameterException { 74 | studentLeave.setUname(((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName()); 75 | if (studentLeave.getId() == null) { 76 | studentLeave.setId(UUID.randomUUID().toString().replace("-", "")); 77 | } 78 | if (studentLeave.getOften() == null) { 79 | throw new NullParameterException("参数often为空"); 80 | } 81 | if (studentLeave.getMatter() == null) { 82 | throw new NullParameterException("参数Matter为空"); 83 | } 84 | if (studentLeave.getSid() == null) { 85 | throw new NullParameterException("参数sid为空"); 86 | } 87 | if (studentLeave.getStarttime() == null) { 88 | throw new NullParameterException("参数starttime为空"); 89 | } 90 | if (studentLeave.getReason() == null) { 91 | throw new NullParameterException("参数reason为空"); 92 | } 93 | studentLeaveDao.saveAndFlush(studentLeave); 94 | } 95 | 96 | @Override 97 | public List searchStudentLeaveInfo(SearchLeave searchLeave) { 98 | logger.debug("searchStudentLeaveInfo::开始搜素"); 99 | return studentLeaveDao.findAll((root, query, cb) -> { 100 | List list = new ArrayList<>(); 101 | list.add(cb.equal(root.get("uname"), ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName())); 102 | if (StringUtils.isNoneBlank(searchLeave.getKey())) { 103 | logger.debug("searchStudentLeaveInfo::已获取到key->" + searchLeave.getKey()); 104 | if (NumberUtils.isParsable(searchLeave.getKey())) { 105 | logger.debug("searchStudentLeaveInfo::" + searchLeave.getKey() + "参数为数字"); 106 | list.add(cb.equal(root.get("sid"), studentInfoDao.findOne(searchLeave.getKey()))); 107 | } else { 108 | logger.debug("searchStudentLeaveInfo::" + searchLeave.getKey() + "参数为文本"); 109 | List predicateList = new ArrayList<>(); 110 | List byNameContaining = studentInfoDao.findByNameContaining(searchLeave.getKey()); 111 | logger.debug("searchStudentLeaveInfo::" + searchLeave.getKey() + "参数模糊查询有" + byNameContaining.size() + "条数据"); 112 | byNameContaining.forEach(studentInfo -> predicateList.add(cb.equal(root.get("sid"), studentInfo))); 113 | Predicate[] p = new Predicate[predicateList.size()]; 114 | list.add(cb.or(predicateList.toArray(p))); 115 | } 116 | } 117 | 118 | //班级 119 | if (searchLeave.getClazz() != null) { 120 | logger.debug("searchStudentLeaveInfo::已获取到clazz->" + Arrays.toString(searchLeave.getClazz())); 121 | List predicateList = new ArrayList<>(); 122 | for (int i = 0; i < searchLeave.getClazz().length; i++) { 123 | List allByClazz = studentInfoDao.findAllByClazz(clazzDao.findOne(searchLeave.getClazz()[i])); 124 | allByClazz.forEach(studentInfo -> predicateList.add(cb.equal(root.get("sid"), studentInfo))); 125 | } 126 | Predicate[] p = new Predicate[predicateList.size()]; 127 | list.add(cb.or(predicateList.toArray(p))); 128 | } 129 | 130 | //请假类型 131 | if (searchLeave.getMatter() != null) { 132 | logger.debug("searchStudentLeaveInfo::已获取到Matter->" + Arrays.toString(searchLeave.getMatter())); 133 | Predicate[] p = new Predicate[searchLeave.getMatter().length]; 134 | for (int i = 0; i < searchLeave.getMatter().length; i++) { 135 | p[i] = cb.equal(root.get("matter"), leaveTypeDao.getOne(searchLeave.getMatter()[i])); 136 | } 137 | list.add(cb.or(p)); 138 | } 139 | 140 | //请假时常often 141 | if (searchLeave.getOften() != null) { 142 | logger.debug("searchStudentLeaveInfo::已获取到请假时常often->" + Arrays.toString(searchLeave.getOften())); 143 | boolean hadMore3 = false; 144 | for (String s : searchLeave.getOften()) { 145 | if ("-1".equals(s)) { 146 | hadMore3 = true; 147 | logger.debug("searchStudentLeaveInfo::请假时常参数有3天以上条件"); 148 | break; 149 | } 150 | } 151 | Predicate[] p; 152 | if (hadMore3) { 153 | p = new Predicate[searchLeave.getOften().length + 1]; 154 | p[searchLeave.getOften().length] = cb.greaterThan(root.get("often"), 3); 155 | } else { 156 | p = new Predicate[searchLeave.getOften().length]; 157 | } 158 | for (int i = 0; i < searchLeave.getOften().length; i++) { 159 | p[i] = cb.equal(root.get("often"), searchLeave.getOften()[i]); 160 | } 161 | list.add(cb.or(p)); 162 | } 163 | 164 | //时间区间 165 | if (searchLeave.getStartdate() != null || searchLeave.getEnddate() != null) { 166 | //有开始有结束 167 | if (searchLeave.getStartdate() != null && searchLeave.getEnddate() != null) { 168 | logger.debug("searchStudentLeaveInfo::已获取到开始和结束时间"); 169 | list.add(cb.between(root.get("starttime"), searchLeave.getStartdate(), searchLeave.getEnddate())); 170 | } else { 171 | Date minDate = null; 172 | Date maxDate = null; 173 | try { 174 | minDate = new SimpleDateFormat("yyyy-MM-dd").parse("2005-01-01"); 175 | maxDate = new SimpleDateFormat("yyyy-MM-dd").parse("9999-12-31"); 176 | } catch (ParseException e) { 177 | logger.warn("searchStudentLeaveInfo::日期转换出现问题?" + e.getMessage()); 178 | } 179 | //只有开始时间 180 | if (searchLeave.getStartdate() != null) { 181 | logger.debug("searchStudentLeaveInfo::已获取到开始时间"); 182 | list.add(cb.between(root.get("starttime"), searchLeave.getStartdate(), maxDate)); 183 | } else {//只有结束时间 184 | logger.debug("searchStudentLeaveInfo::已获取到结束时间"); 185 | list.add(cb.between(root.get("starttime"), minDate, searchLeave.getEnddate())); 186 | } 187 | } 188 | } 189 | Predicate[] p = new Predicate[list.size()]; 190 | return cb.and(list.toArray(p)); 191 | }); 192 | } 193 | 194 | @Override 195 | public long getStudentLeaveNum() { 196 | return studentLeaveDao.countByUname(((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName()); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/main/resources/templates/historyleave.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 历史请假信息-TA 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 |
32 |
33 | menu 35 |

教师助手 Teacher Assistant

36 |
37 | refresh 39 |
40 |
41 | 42 | 103 |
104 |
105 |
106 | 107 |
108 |
109 |
历史请假信息
110 |
学生请假管理
111 |
112 |
113 |
114 |
115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 |
学号姓名起始时间时常(天)事项原因备注
201601010301荆小余2016-05-303事假回家
141 |
142 |
143 | 146 | 149 |
150 |
151 |
152 |
153 |
确定删除吗?
154 |
这会删除该生请假信息!
155 |
156 | 157 | 158 |
159 |
160 |
161 | 162 | 163 | 164 | 202 | 203 | -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/main/resources/templates/settheme.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 主题设置-TA 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 |
32 |
33 | menu 35 |

学生管理系统

36 |
37 | refresh 39 |
40 |
41 | 42 | 103 |
104 |
105 |
106 |

主题设置

107 |
108 |
109 |
主色设置
110 |
128 |
129 |
130 |
强调色设置
131 |
149 |
150 | 151 | 154 | 158 |
159 |
160 |
161 |
162 | 163 | 164 | 165 | 218 | 219 | --------------------------------------------------------------------------------