├── .gitattributes ├── pic └── login.png ├── src ├── main │ ├── resources │ │ ├── application.yml │ │ ├── static │ │ │ ├── up.xlsx │ │ │ ├── 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-Medium.woff2 │ │ │ │ │ │ │ ├── Roboto-Regular.woff │ │ │ │ │ │ │ ├── Roboto-Thin.woff2 │ │ │ │ │ │ │ ├── Roboto-Regular.woff2 │ │ │ │ │ │ │ ├── Roboto-BlackItalic.woff │ │ │ │ │ │ │ ├── Roboto-BlackItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-BoldItalic.woff │ │ │ │ │ │ │ ├── Roboto-BoldItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-LightItalic.woff │ │ │ │ │ │ │ ├── Roboto-LightItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-MediumItalic.woff │ │ │ │ │ │ │ ├── Roboto-ThinItalic.woff │ │ │ │ │ │ │ ├── Roboto-ThinItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-MediumItalic.woff2 │ │ │ │ │ │ │ ├── Roboto-RegularItalic.woff │ │ │ │ │ │ │ └── Roboto-RegularItalic.woff2 │ │ │ │ │ └── icons │ │ │ │ │ │ └── material-icons │ │ │ │ │ │ ├── MaterialIcons-Regular.woff │ │ │ │ │ │ └── MaterialIcons-Regular.woff2 │ │ │ │ └── canvas-nest │ │ │ │ │ ├── canvas-nest.min.js │ │ │ │ │ └── canvas-nest.js │ │ │ └── js │ │ │ │ ├── common.js │ │ │ │ └── staff.js │ │ ├── application-prod.yml │ │ ├── templates │ │ │ ├── contractExpiresTemplate.html │ │ │ ├── payrollMailTemplate.html │ │ │ ├── error.html │ │ │ └── login.html │ │ └── application-dev.yml │ └── java │ │ └── top │ │ └── itning │ │ └── hrms │ │ ├── exception │ │ ├── defaults │ │ │ ├── DefaultException.java │ │ │ ├── NoSuchIdException.java │ │ │ ├── NullParameterException.java │ │ │ └── IllegalParametersException.java │ │ ├── json │ │ │ └── JsonException.java │ │ └── resolver │ │ │ └── ExceptionResolver.java │ │ ├── dao │ │ ├── UserDao.java │ │ ├── fixed │ │ │ ├── EthnicDao.java │ │ │ └── PoliticalStatusDao.java │ │ ├── job │ │ │ ├── JobLevelDao.java │ │ │ └── JobTitleDao.java │ │ ├── department │ │ │ ├── DepartmentDao.java │ │ │ └── GrassrootDao.java │ │ ├── post │ │ │ ├── PositionTitleDao.java │ │ │ └── PositionCategoryDao.java │ │ ├── employee │ │ │ └── EmploymentFormDao.java │ │ ├── WageDao.java │ │ └── StaffDao.java │ │ ├── HrmsApplication.java │ │ ├── service │ │ ├── FixedService.java │ │ ├── DepartmentService.java │ │ ├── EmploymentService.java │ │ ├── GrassrootService.java │ │ ├── WageService.java │ │ ├── JobService.java │ │ ├── PostService.java │ │ ├── impl │ │ │ ├── EmploymentServiceImpl.java │ │ │ ├── DepartmentServiceImpl.java │ │ │ ├── JobServiceImpl.java │ │ │ ├── FixedServiceImpl.java │ │ │ ├── PostServiceImpl.java │ │ │ └── GrassrootServiceImpl.java │ │ └── StaffService.java │ │ ├── entity │ │ ├── employment │ │ │ └── EmploymentForm.java │ │ ├── search │ │ │ ├── SearchWage.java │ │ │ └── SearchStaff.java │ │ ├── job │ │ │ ├── JobLevel.java │ │ │ └── JobTitle.java │ │ ├── post │ │ │ ├── PositionTitle.java │ │ │ └── PositionCategory.java │ │ ├── department │ │ │ ├── Grassroot.java │ │ │ └── Department.java │ │ ├── ServerMessage.java │ │ ├── fixed │ │ │ ├── PoliticalStatus.java │ │ │ └── Ethnic.java │ │ ├── User.java │ │ ├── Wage.java │ │ └── WageEmail.java │ │ ├── schedul │ │ ├── ScheduledTasks.java │ │ ├── PayrollSendingTask.java │ │ └── ContractExpires.java │ │ ├── security │ │ ├── UserDetailsServiceImpl.java │ │ └── WebSecurityConfig.java │ │ ├── controller │ │ ├── FrameController.java │ │ ├── job │ │ │ ├── JobLevelController.java │ │ │ └── JobTitleController.java │ │ ├── post │ │ │ ├── PostTitleController.java │ │ │ └── PostCategoryController.java │ │ ├── department │ │ │ ├── DepartmentController.java │ │ │ └── GrassrootController.java │ │ ├── employment │ │ │ └── EmploymentFormController.java │ │ └── staff │ │ │ └── StaffWageController.java │ │ └── util │ │ ├── ObjectUtils.java │ │ └── StaffUtils.java └── test │ └── java │ └── top │ └── itning │ └── hrms │ └── HrmsApplicationTests.java ├── .gitignore ├── LICENSE ├── README.md ├── mvnw.cmd └── pom.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | *.css linguist-language=java -------------------------------------------------------------------------------- /pic/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/pic/login.png -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev -------------------------------------------------------------------------------- /src/main/resources/static/up.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/src/main/resources/static/up.xlsx -------------------------------------------------------------------------------- /src/main/resources/static/image/card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/src/main/resources/static/image/card.jpg -------------------------------------------------------------------------------- /src/main/resources/static/image/class_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BlackItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-LightItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-MediumItalic.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-ThinItalic.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib_web/mdui/fonts/roboto/Roboto-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/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/hrms/dev/src/main/resources/static/lib_web/mdui/icons/material-icons/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /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/hrms/exception/defaults/DefaultException.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.exception.defaults; 2 | 3 | /** 4 | * 默认异常 5 | * 6 | * @author Ning 7 | */ 8 | public class DefaultException extends Exception { 9 | public DefaultException(String exceptionMessage) { 10 | super(exceptionMessage); 11 | } 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/hrms/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.User; 5 | 6 | /** 7 | * 用户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/hrms/dao/fixed/EthnicDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.fixed; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.fixed.Ethnic; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Ethnic DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface EthnicDao extends JpaRepository { 14 | /** 15 | * 根据name查询所有民族 16 | * 17 | * @param name 民族名 18 | * @return 民族集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/job/JobLevelDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.job; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.job.JobLevel; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * JobLevel DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface JobLevelDao extends JpaRepository { 14 | /** 15 | * 根据职称级别名查找职称级别 16 | * 17 | * @param name 职称级别名 18 | * @return 职称级别集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/job/JobTitleDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.job; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.job.JobTitle; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * JobTitle DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface JobTitleDao extends JpaRepository { 14 | /** 15 | * 根据社会职称名查找社会职称 16 | * 17 | * @param name 社会职称名 18 | * @return 社会职称集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/department/DepartmentDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.department; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.department.Department; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Department Dao 10 | * 11 | * @author Ning 12 | */ 13 | public interface DepartmentDao extends JpaRepository { 14 | /** 15 | * 根据部门名查找部门 16 | * 17 | * @param name 部门名 18 | * @return 部门集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/HrmsApplication.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cache.annotation.EnableCaching; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | 8 | @SpringBootApplication 9 | @EnableCaching 10 | @EnableScheduling 11 | public class HrmsApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(HrmsApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/post/PositionTitleDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.post; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.post.PositionTitle; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * PositionTitle DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface PositionTitleDao extends JpaRepository { 14 | /** 15 | * 根据岗位名称名查找岗位名称信息 16 | * 17 | * @param name 岗位名称名 18 | * @return 岗位名称集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/exception/json/JsonException.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.exception.json; 2 | 3 | /** 4 | * Json异常 5 | * 6 | * @author Ning 7 | */ 8 | public class JsonException extends Exception { 9 | /** 10 | * 错误代码 11 | */ 12 | private int code; 13 | 14 | public JsonException(String exceptionMessage, int code) { 15 | super(exceptionMessage); 16 | this.code = code; 17 | } 18 | 19 | public int getCode() { 20 | return code; 21 | } 22 | 23 | public void setCode(int code) { 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/fixed/PoliticalStatusDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.fixed; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.fixed.PoliticalStatus; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * PoliticalStatus DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface PoliticalStatusDao extends JpaRepository { 14 | /** 15 | * 根据name查询政治面貌信息 16 | * 17 | * @param name 政治面貌名 18 | * @return 政治面貌集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/post/PositionCategoryDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.post; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.post.PositionCategory; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * PositionCategory DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface PositionCategoryDao extends JpaRepository { 14 | /** 15 | * 根据岗位类别名查找岗位类别 16 | * 17 | * @param name 岗位类别名 18 | * @return 岗位类别集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/employee/EmploymentFormDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.employee; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.hrms.entity.employment.EmploymentForm; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * EmploymentForm DAO 10 | * 11 | * @author Ning 12 | */ 13 | public interface EmploymentFormDao extends JpaRepository { 14 | /** 15 | * 根据用工形式名查找用工形式 16 | * 17 | * @param name 用工形式名 18 | * @return 用工形式集合 19 | */ 20 | List findByName(String name); 21 | } 22 | -------------------------------------------------------------------------------- /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/hrms/exception/defaults/NoSuchIdException.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.exception.defaults; 2 | 3 | /** 4 | * 没有这个ID异常 5 | * 6 | * @author Ning 7 | */ 8 | public class NoSuchIdException extends DefaultException { 9 | /** 10 | * 异常消息 11 | */ 12 | private String exceptionMessage; 13 | 14 | public NoSuchIdException(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/hrms/exception/defaults/NullParameterException.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.exception.defaults; 2 | 3 | /** 4 | * 空参数异常 5 | * 6 | * @author Ning 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/hrms/exception/defaults/IllegalParametersException.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.exception.defaults; 2 | 3 | /** 4 | * 非法参数异常 5 | * 6 | * @author Ning 7 | */ 8 | public class IllegalParametersException extends DefaultException { 9 | /** 10 | * 异常消息 11 | */ 12 | private String exceptionMessage; 13 | 14 | public IllegalParametersException(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/hrms/service/FixedService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.fixed.Ethnic; 4 | import top.itning.hrms.entity.fixed.PoliticalStatus; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 固定信息服务 10 | * 11 | * @author Ning 12 | */ 13 | public interface FixedService { 14 | /** 15 | * 获取所有民族信息集合 16 | * 17 | * @param key 默认:getAllEthnicInfoList 该参数用于缓存的KEY 18 | * @return 所有民族信息集合 19 | */ 20 | List getAllEthnicInfoList(String key); 21 | 22 | /** 23 | * 获取所有政治面貌信息集合 24 | * 25 | * @param key 默认:getAllPoliticalStatusInfoList 该参数用于缓存的KEY 26 | * @return 所有政治面貌信息集合 27 | */ 28 | List getAllPoliticalStatusInfoList(String key); 29 | } 30 | -------------------------------------------------------------------------------- /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/hrms/entity/employment/EmploymentForm.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.employment; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.Id; 9 | import javax.persistence.Table; 10 | import javax.validation.constraints.NotNull; 11 | import java.io.Serializable; 12 | 13 | /** 14 | * 用工形式实体 15 | * 16 | * @author Ning 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | @Entity 22 | @Table(name = "EMP_FORM") 23 | public class EmploymentForm implements Serializable { 24 | /** 25 | * UUID 26 | */ 27 | @Id 28 | private String id; 29 | /** 30 | * 用工形式名 31 | */ 32 | @NotNull 33 | private String name; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/search/SearchWage.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.search; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 工资搜索实体 9 | * 10 | * @author Ning 11 | */ 12 | @Data 13 | public class SearchWage implements Serializable { 14 | /** 15 | * 姓名 16 | */ 17 | private String name; 18 | /** 19 | * 身份证号 20 | */ 21 | private String nid; 22 | /** 23 | * 社会职称 24 | */ 25 | private String[] jobTitle; 26 | /** 27 | * 部门ID 28 | */ 29 | private String[] department; 30 | /** 31 | * 基层单位ID 32 | */ 33 | private String[] grassroot; 34 | /** 35 | * 年份 36 | */ 37 | private String[] year; 38 | /** 39 | * 月份 40 | */ 41 | private String[] month; 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/WageDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 5 | import org.springframework.data.jpa.repository.Query; 6 | import top.itning.hrms.entity.Staff; 7 | import top.itning.hrms.entity.Wage; 8 | 9 | /** 10 | * Wage DAO 11 | * 12 | * @author Ning 13 | */ 14 | public interface WageDao extends JpaRepository, JpaSpecificationExecutor { 15 | /** 16 | * 删除工资信息根据职工 17 | * 18 | * @param staff 职工信息 19 | */ 20 | void deleteByStaff(Staff staff); 21 | 22 | /** 23 | * 查询数据库中所有年 24 | * 25 | * @return 年数组 26 | */ 27 | @Query("select w.year from Wage w group by w.year") 28 | String[] findYear(); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | #!application-prod.yml 生产环境配置文件 2 | server: 3 | port: 80 #端口 4 | debug: false #调试模式 5 | spring: 6 | jpa: 7 | hibernate: 8 | ddl-auto: update 9 | show-sql: false #显示sql 10 | datasource: 11 | driver-class-name: com.mysql.cj.jdbc.Driver #驱动类 12 | url: jdbc:mysql://localhost:3306/hrms?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=0&serverTimezone=UTC 13 | username: root #数据库用户名 14 | password: kingston #密码 15 | thymeleaf: 16 | cache: true #缓存 17 | mode: HTML 18 | mvc: 19 | favicon: 20 | enabled: false 21 | output: 22 | ansi: 23 | enabled: detect #控制台多彩输出 24 | logging: 25 | level: warn 26 | level.top: warn 27 | file: C:/Users/Ning/Desktop/upload/log.log -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/job/JobLevel.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.job; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 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 | 14 | /** 15 | * 职称级别实体 16 | * 17 | * @author Ning 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Entity 23 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 24 | @Table(name = "JOB_LEVEL") 25 | public class JobLevel implements Serializable { 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | private String id; 31 | /** 32 | * 职称级别名 33 | */ 34 | @NotNull 35 | private String name; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/job/JobTitle.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.job; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 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 | 14 | /** 15 | * 社会职称名实体 16 | * 17 | * @author Ning 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Entity 23 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 24 | @Table(name = "JOB_TITLE") 25 | public class JobTitle implements Serializable { 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | private String id; 31 | /** 32 | * 社会职称名 33 | */ 34 | @NotNull 35 | private String name; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/resources/templates/contractExpiresTemplate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 合同到期提醒 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
姓名所属部门电话号码第一次签约到期日第二次签约到期日第三次签约到期日
30 | 31 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/post/PositionTitle.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.post; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 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 | 14 | /** 15 | * 岗位名称实体 16 | * 17 | * @author Ning 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Entity 23 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 24 | @Table(name = "POST_TITLE") 25 | public class PositionTitle implements Serializable { 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | private String id; 31 | /** 32 | * 岗位名称 33 | */ 34 | @NotNull 35 | private String name; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/department/Grassroot.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.department; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 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 | 14 | /** 15 | * 基层单位实体 16 | * 17 | * @author Ning 18 | */ 19 | @Data 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | @Entity 23 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 24 | @Table(name = "DEP_GRASSROOT") 25 | public class Grassroot implements Serializable { 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | private String id; 31 | /** 32 | * 专业/基层单位 33 | */ 34 | @NotNull 35 | private String name; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/post/PositionCategory.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.post; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 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 | 14 | /** 15 | * 岗位类别实体 16 | * 17 | * @author Ning 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Entity 23 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 24 | @Table(name = "POST_CATEGORY") 25 | public class PositionCategory implements Serializable { 26 | /** 27 | * UUID 28 | */ 29 | @Id 30 | private String id; 31 | /** 32 | * 岗位类别名 33 | */ 34 | @NotNull 35 | private String name; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/department/GrassrootDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao.department; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Modifying; 5 | import org.springframework.data.jpa.repository.Query; 6 | import top.itning.hrms.entity.department.Grassroot; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Grassroot DAO 12 | * 13 | * @author Ning 14 | */ 15 | public interface GrassrootDao extends JpaRepository { 16 | /** 17 | * 根据基层单位ID修改基层单位名称 18 | * 19 | * @param id 基层单位ID 20 | * @param name 基层单位名称 21 | */ 22 | @Modifying 23 | @Query("update Grassroot g set g.name=?2 where g.id=?1") 24 | void modifyGrassrootInfo(String id, String name); 25 | 26 | /** 27 | * 根据基层单位名查找基层单位 28 | * 29 | * @param name 基层单位名 30 | * @return 基层单位集合 31 | */ 32 | List findByName(String name); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/ServerMessage.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 服务器消息实体 7 | * 8 | * @author wangn 9 | */ 10 | @Data 11 | public class ServerMessage { 12 | /** 13 | * 未找到 14 | */ 15 | public static final int NOT_FIND = 404; 16 | /** 17 | * 内部服务错误 18 | */ 19 | public static final int SERVICE_ERROR = 500; 20 | /** 21 | * 成功 22 | */ 23 | public static final int SUCCESS_CODE = 200; 24 | /** 25 | * 消息代码 26 | */ 27 | private int code; 28 | /** 29 | * 消息内容 30 | */ 31 | private String msg; 32 | /** 33 | * 发生该消息的URL 34 | */ 35 | private String url; 36 | 37 | /** 38 | * 添加消息 39 | * 40 | * @param msg 消息 41 | */ 42 | public void addMsg(String msg) { 43 | if (this.msg == null) { 44 | this.msg = msg; 45 | } else { 46 | this.msg += msg; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/fixed/PoliticalStatus.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.fixed; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.Id; 9 | import javax.persistence.Table; 10 | import javax.validation.constraints.NotNull; 11 | import java.io.Serializable; 12 | 13 | /** 14 | * 政治面貌实体 15 | *

【政治面貌分为以下13类,代码及名称如下】: 16 | *

01 中共党员 17 | *

02 中共预备党员 18 | *

03 共青团员 19 | *

04 民革党员 20 | *

05 民盟盟员 21 | *

06 民建会员 22 | *

07 民进会员 23 | *

08 农工党党员 24 | *

09 致公党党员 25 | *

10 九三学社社员 26 | *

11 台盟盟员 27 | *

12 无党派人士 28 | *

13 群众(现称普通居民,与居民身份证相对应) 29 | * 30 | * @author Ning 31 | */ 32 | @Data 33 | @NoArgsConstructor 34 | @AllArgsConstructor 35 | @Entity 36 | @Table(name = "FIXED_PS") 37 | public class PoliticalStatus implements Serializable { 38 | /** 39 | * ID 40 | */ 41 | @Id 42 | private String id; 43 | /** 44 | * 名称 45 | */ 46 | @NotNull 47 | private String name; 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/department/Department.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.department; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.*; 9 | import javax.validation.constraints.NotNull; 10 | import java.io.Serializable; 11 | import java.util.List; 12 | 13 | /** 14 | * 部门实体 15 | * 16 | * @author Ning 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | @Entity 22 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 23 | @Table(name = "DEP_DEPARTMENT") 24 | public class Department implements Serializable { 25 | /** 26 | * UUID 27 | */ 28 | @Id 29 | private String id; 30 | /** 31 | * 部门名 32 | */ 33 | @NotNull 34 | private String name; 35 | /** 36 | * 专业/基层单位 37 | */ 38 | @OneToMany(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) 39 | @JoinColumn(name = "grassroot") 40 | private List grassroots; 41 | } 42 | -------------------------------------------------------------------------------- /src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | #!application-dev.yml 开发环境配置文件 2 | server: 3 | port: 8080 #端口 4 | debug: false #调试模式 5 | spring: 6 | jpa: 7 | hibernate: 8 | ddl-auto: update 9 | show-sql: true #显示sql 10 | datasource: 11 | driver-class-name: com.mysql.cj.jdbc.Driver #驱动类 12 | url: jdbc:mysql://localhost:3306/hrms?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=0&serverTimezone=UTC 13 | username: root #数据库用户名 14 | password: kingston #密码 15 | thymeleaf: 16 | cache: false #缓存 17 | mode: HTML 18 | mvc: 19 | favicon: 20 | enabled: false 21 | output: 22 | ansi: 23 | enabled: detect #控制台多彩输出 24 | mail: 25 | host: smtp.mxhichina.com 26 | username: itning@itning.top 27 | password: 28 | properties: 29 | mail: 30 | smtp: 31 | auth: true 32 | starttls: 33 | enable: true 34 | required: true 35 | 36 | logging: 37 | level: debug 38 | level.top: debug 39 | file: C:/Users/Ning/Desktop/upload/log.log -------------------------------------------------------------------------------- /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/java/top/itning/hrms/schedul/ScheduledTasks.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.schedul; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.scheduling.annotation.Scheduled; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * 定时任务 9 | * 10 | * @author wangn 11 | */ 12 | @Component 13 | public class ScheduledTasks { 14 | 15 | private final PayrollSendingTask payrollSendingTask; 16 | 17 | private final ContractExpires contractExpires; 18 | 19 | @Autowired 20 | public ScheduledTasks(PayrollSendingTask payrollSendingTask, ContractExpires contractExpires) { 21 | this.payrollSendingTask = payrollSendingTask; 22 | this.contractExpires = contractExpires; 23 | } 24 | 25 | /** 26 | * 每天12点执行,查找合同到期的职工 27 | */ 28 | @Scheduled(cron = "0 0 12 * * ?") 29 | public void findingTheContractExpires() { 30 | contractExpires.startSend(); 31 | } 32 | 33 | /** 34 | * 自动发送工资条,每月1日12时执行 35 | */ 36 | @Scheduled(cron = "0 0 12 1 * ?") 37 | public void autoSendWageEmail() { 38 | payrollSendingTask.startSend(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/top/itning/hrms/HrmsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | import top.itning.hrms.schedul.ContractExpires; 9 | import top.itning.hrms.schedul.PayrollSendingTask; 10 | 11 | import javax.mail.MessagingException; 12 | import java.text.ParseException; 13 | import java.util.zip.DataFormatException; 14 | 15 | @RunWith(SpringRunner.class) 16 | @SpringBootTest 17 | public class HrmsApplicationTests { 18 | @Autowired 19 | private PayrollSendingTask payrollSendingTask; 20 | 21 | @Autowired 22 | private ContractExpires contractExpires; 23 | 24 | @Test 25 | public void contextLoads() throws MessagingException, DataFormatException, ParseException { 26 | //WageEmail wageEmail = new WageEmail(); 27 | //payrollSendingTask.sendPayrollInfo(wageEmail.getAllFiledMap(),"2018年06月工资信息","3579677768@qq.com"); 28 | contractExpires.startSend(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/DepartmentService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.department.Department; 4 | import top.itning.hrms.exception.defaults.NoSuchIdException; 5 | import top.itning.hrms.exception.defaults.NullParameterException; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 部门管理服务 11 | * 12 | * @author Ning 13 | */ 14 | public interface DepartmentService { 15 | /** 16 | * 获取所有部门信息 17 | * 18 | * @param key 默认:getAllDepartmentInfo 该参数用于缓存的KEY 19 | * @return 部门信息集合 20 | */ 21 | List getAllDepartmentInfoList(String key); 22 | 23 | /** 24 | * 根据部门ID删除部门信息 25 | * 26 | * @param id 部门ID 27 | * @param key 该参数用于删除缓存名为key的缓存 28 | * @throws NoSuchIdException ID不存在则抛出该异常 29 | */ 30 | void delDepartmentByID(String id, String key) throws NoSuchIdException; 31 | 32 | /** 33 | * 添加或修改部门 34 | * 35 | * @param department 部门 36 | * @param key 该参数用于删除缓存名为key的缓存 37 | * @throws NullParameterException 如果参数为空则抛出该异常 38 | */ 39 | void addOrModifyDepartmentInfo(Department department, String key) throws NullParameterException; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/EmploymentService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.employment.EmploymentForm; 4 | import top.itning.hrms.exception.defaults.NoSuchIdException; 5 | import top.itning.hrms.exception.defaults.NullParameterException; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 用工形式服务 11 | * 12 | * @author Ning 13 | */ 14 | public interface EmploymentService { 15 | /** 16 | * 获取所有用工形式 17 | * 18 | * @param key 默认:getAllEmploymentFormList 该参数用于缓存的KEY 19 | * @return 所有用工形式集合 20 | */ 21 | List getAllEmploymentFormList(String key); 22 | 23 | /** 24 | * 根据用工形式ID删除用工形式信息 25 | * 26 | * @param id 用工形式ID 27 | * @param key 该参数用于删除缓存名为key的缓存 28 | * @throws NoSuchIdException ID不存在则抛出该异常 29 | */ 30 | void delEmploymentFormByID(String id, String key) throws NoSuchIdException; 31 | 32 | /** 33 | * 添加或修改用工形式 34 | * 35 | * @param employmentForm 用工形式 36 | * @param key 该参数用于删除缓存名为key的缓存 37 | * @throws NullParameterException 如果参数为空则抛出该异常 38 | */ 39 | void addOrModifyEmploymentFormInfo(EmploymentForm employmentForm, String key) throws NullParameterException; 40 | } 41 | -------------------------------------------------------------------------------- /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/hrms/security/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.security; 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.hrms.dao.UserDao; 11 | import top.itning.hrms.entity.User; 12 | 13 | /** 14 | * 用户详细信息服务实现类 15 | * 16 | * @author wangn 17 | */ 18 | @Service 19 | public class UserDetailsServiceImpl implements UserDetailsService { 20 | private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class); 21 | 22 | @Autowired 23 | private UserDao userDao; 24 | 25 | @Override 26 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 27 | logger.debug("loadUserByUsername::开始登陆,用户名->" + username); 28 | User user = userDao.findByUsername(username); 29 | if (user == null) { 30 | logger.warn("loadUserByUsername::用户名:" + username + "不存在"); 31 | throw new UsernameNotFoundException("用户名:" + username + "不存在"); 32 | } 33 | return user; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/dao/StaffDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 5 | import top.itning.hrms.entity.Staff; 6 | import top.itning.hrms.entity.department.Department; 7 | import top.itning.hrms.entity.department.Grassroot; 8 | import top.itning.hrms.entity.job.JobTitle; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Staff DAO 14 | * 15 | * @author Ning 16 | */ 17 | public interface StaffDao extends JpaRepository, JpaSpecificationExecutor { 18 | /** 19 | * 根据部门查找职工 20 | * 21 | * @param department 部门 22 | * @return 职工信息集合 23 | */ 24 | List findByDepartment(Department department); 25 | 26 | /** 27 | * 根据基层单位查找职工 28 | * 29 | * @param grassroot 基层单位 30 | * @return 职工信息集合 31 | */ 32 | List findByGrassroot(Grassroot grassroot); 33 | 34 | /** 35 | * 根据职称信息查询职工 36 | * 37 | * @param jobTitle 职称信息 38 | * @return 职工信息集合 39 | */ 40 | List findByJobTitle(JobTitle jobTitle); 41 | 42 | /** 43 | * 根据身份证号查找员工 44 | * 45 | * @param nid 身份证号 46 | * @return 职工信息集合 47 | */ 48 | List findByNid(String nid); 49 | 50 | /** 51 | * 根据姓名查询职工信息 52 | * 53 | * @param name 职工姓名 54 | * @return 职工信息集合 55 | */ 56 | List findByName(String name); 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/GrassrootService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.department.Grassroot; 4 | import top.itning.hrms.exception.defaults.NoSuchIdException; 5 | import top.itning.hrms.exception.defaults.NullParameterException; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 基层单位服务 11 | * 12 | * @author Ning 13 | */ 14 | public interface GrassrootService { 15 | /** 16 | * 根据部门ID获取基层单位集合 17 | * 18 | * @param id 部门ID 19 | * @return 基层单位集合 20 | * @throws NoSuchIdException 如果ID不存在则抛出该异常 21 | */ 22 | List getGrassrootListByDepartment(String id) throws NoSuchIdException; 23 | 24 | /** 25 | * 修改基层单位信息 26 | * 27 | * @param grassroot 基层单位 28 | * @param did 部门ID,用于删除缓存 29 | * @throws NullParameterException 如果参数为空则抛出该异常 30 | */ 31 | void modifyGrassroot(Grassroot grassroot, String did) throws NullParameterException; 32 | 33 | /** 34 | * 根据部门ID添加基层单位信息 35 | * 36 | * @param id 部门ID 37 | * @param grassroot 基层单位 38 | * @throws NoSuchIdException 部门ID不存在则抛出该异常 39 | * @throws NullParameterException 参数为空则抛出该异常 40 | */ 41 | void addGrassrootByDepartmentID(String id, Grassroot grassroot) throws NoSuchIdException, NullParameterException; 42 | 43 | /** 44 | * 根据基层单位ID删除基层单位信息 45 | * 46 | * @param id 基层单位ID 47 | * @param did 部门ID,用于删除缓存 48 | * @throws NoSuchIdException 基层单位ID没找到则抛出该异常 49 | */ 50 | void delGrassrootByID(String id, String did) throws NoSuchIdException; 51 | } 52 | -------------------------------------------------------------------------------- /src/main/resources/static/js/staff.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //身份证号校验 4 | function checkNid(that) { 5 | if ($(that).val().length !== 18) { 6 | that.focus(); 7 | mdui.snackbar({ 8 | message: "身份证号不是18位,当前" + $(that).val().length + "位.请检查!" 9 | }); 10 | } 11 | } 12 | 13 | //实时检测用户输入 14 | function checkRtNid(that) { 15 | var str = $(that).val(); 16 | var last_str = str.charAt(str.length - 1); 17 | if (str.length === 18 && (last_str === "X" || last_str === "x")) { 18 | $(that).val(str.substring(0, 17) + "X"); 19 | return; 20 | } 21 | if (!$.isNumeric(last_str)) { 22 | if (str.length > 1) { 23 | $(that).val(str.substring(0, str.length - 1)); 24 | } else { 25 | $(that).val(""); 26 | } 27 | 28 | } else if (str.length > 18) { 29 | $(that).val(str.substring(0, 18)); 30 | } 31 | } 32 | 33 | //提交检查 34 | function submit_staff() { 35 | var $comeDateId = $('#comeDate_id'); 36 | var $startDateId = $('#startDate_id'); 37 | if ($('#comeDate').val() === "") { 38 | $comeDateId.addClass("mdui-textfield-invalid"); 39 | mdui.snackbar({ 40 | message: "请选择来校日期!" 41 | }); 42 | } else { 43 | $comeDateId.removeClass("mdui-textfield-invalid"); 44 | } 45 | if ($('#startDate').val() === "") { 46 | $startDateId.addClass("mdui-textfield-invalid"); 47 | mdui.snackbar({ 48 | message: "请选择工龄起始日期!" 49 | }); 50 | } else { 51 | $startDateId.removeClass("mdui-textfield-invalid"); 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/WageService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.search.SearchWage; 4 | import top.itning.hrms.exception.defaults.NoSuchIdException; 5 | import top.itning.hrms.exception.json.JsonException; 6 | 7 | import javax.servlet.ServletOutputStream; 8 | import java.io.IOException; 9 | import java.util.Map; 10 | 11 | /** 12 | * 职工工资服务 13 | * 14 | * @author Ning 15 | */ 16 | public interface WageService { 17 | /** 18 | * 获取工资所有年份 19 | * 20 | * @return 年份数组 21 | */ 22 | String[] getWageYear(); 23 | 24 | /** 25 | * 搜索工资信息 26 | * 27 | * @param searchWage 搜索工资实体 28 | * @return 搜索到的工资实体集合 29 | * @throws JsonException JsonException 30 | */ 31 | Map searchWage(SearchWage searchWage) throws JsonException; 32 | 33 | /** 34 | * 根据ID下载职工工资信息 35 | * 36 | * @param servletOutputStream ServletOutputStream 37 | * @param id 要下载的职工工资ID 38 | * @throws NoSuchIdException ID不存在时则抛出该异常 39 | * @throws IllegalAccessException IllegalAccessException 40 | * @throws IOException IOException 41 | * @throws InstantiationException InstantiationException 42 | */ 43 | void downWageInfoByID(ServletOutputStream servletOutputStream, String... id) throws NoSuchIdException, IllegalAccessException, IOException, InstantiationException; 44 | 45 | /** 46 | * 根据工资ID删除职工工资信息 47 | * 48 | * @param id 工资ID 49 | * @throws NoSuchIdException 如果工资ID不存在则抛出该异常 50 | */ 51 | void delWageInfoByID(String id) throws NoSuchIdException; 52 | } 53 | -------------------------------------------------------------------------------- /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/hrms/entity/fixed/Ethnic.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.fixed; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.Id; 9 | import javax.persistence.Table; 10 | import javax.validation.constraints.NotNull; 11 | import java.io.Serializable; 12 | 13 | /** 14 | * 民族实体 15 | *

【民族代码及名称如下】: 16 | *

01 汉族 17 | *

02 蒙古族 18 | *

03 回族 19 | *

04 藏族 20 | *

05 维吾尔族 21 | *

06 苗族 22 | *

07 彝族 23 | *

08 壮族 24 | *

09 布依族 25 | *

10 朝鲜族 26 | *

11 满族 27 | *

12 侗族 28 | *

13 瑶族 29 | *

14 白族 30 | *

15 土家族 31 | *

16 哈尼族 32 | *

17 哈萨克族 33 | *

18 傣族 34 | *

19 黎族 35 | *

20 傈僳族 36 | *

21 佤族 37 | *

22 畲族 38 | *

23 高山族 39 | *

24 拉祜族 40 | *

25 水族 41 | *

26 东乡族 42 | *

27 纳西族 43 | *

28 景颇族 44 | *

29 柯尔克孜族 45 | *

30 土族 46 | *

31 达斡尔族 47 | *

32 仫佬族 48 | *

33 羌族 49 | *

34 布朗族 50 | *

35 撒拉族 51 | *

36 毛难族 52 | *

37 仡佬族 53 | *

38 锡伯族 54 | *

39 阿昌族 55 | *

40 普米族 56 | *

41 塔吉克族 57 | *

42 怒族 58 | *

43 乌孜别克族 59 | *

44 俄罗斯族 60 | *

45 鄂温克族 61 | *

46 崩龙族 62 | *

47 保安族 63 | *

48 裕固族 64 | *

49 京族 65 | *

50 塔塔尔族 66 | *

51 独龙族 67 | *

52 鄂伦春族 68 | *

53 赫哲族 69 | *

54 门巴族 70 | *

55 珞巴族 71 | *

56 基诺族 72 | *

97 其他 73 | *

98 外国血统 74 | * 75 | * @author Ning 76 | */ 77 | @Data 78 | @NoArgsConstructor 79 | @AllArgsConstructor 80 | @Entity 81 | @Table(name = "FIXED_ETHNIC") 82 | public class Ethnic implements Serializable { 83 | /** 84 | * ID 85 | */ 86 | @Id 87 | private String id; 88 | /** 89 | * 名称 90 | */ 91 | @NotNull 92 | private String name; 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/JobService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.job.JobLevel; 4 | import top.itning.hrms.entity.job.JobTitle; 5 | import top.itning.hrms.exception.defaults.NoSuchIdException; 6 | import top.itning.hrms.exception.defaults.NullParameterException; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 社会职称/级别服务 12 | * 13 | * @author Ning 14 | */ 15 | public interface JobService { 16 | /** 17 | * 获取所有社会职称信息 18 | * 19 | * @param key 默认:getAllJobTitleInfoList 该参数用于缓存的KEY 20 | * @return 社会职称信息集合 21 | */ 22 | List getAllJobTitleInfoList(String key); 23 | 24 | /** 25 | * 获取所有职称级别信息 26 | * 27 | * @param key 默认:getAllJobLevelInfoList 该参数用于缓存的KEY 28 | * @return 职称级别信息集合 29 | */ 30 | List getAllJobLevelInfoList(String key); 31 | 32 | /** 33 | * 根据社会职称ID删除社会职称信息 34 | * 35 | * @param id 社会职称ID 36 | * @param key 该参数用于删除缓存名为key的缓存 37 | * @throws NoSuchIdException ID不存在则抛出该异常 38 | */ 39 | void delJobTitleInfoByID(String id, String key) throws NoSuchIdException; 40 | 41 | /** 42 | * 根据职称级别ID删除职称级别信息 43 | * 44 | * @param id 职称级别ID 45 | * @param key 该参数用于删除缓存名为key的缓存 46 | * @throws NoSuchIdException ID不存在则抛出该异常 47 | */ 48 | void delJobLevelByID(String id, String key) throws NoSuchIdException; 49 | 50 | /** 51 | * 添加或修改社会职称 52 | * 53 | * @param jobTitle 社会职称 54 | * @param key 该参数用于删除缓存名为key的缓存 55 | * @throws NullParameterException 如果参数为空则抛出该异常 56 | */ 57 | void addOrModifyJobTitleInfo(JobTitle jobTitle, String key) throws NullParameterException; 58 | 59 | /** 60 | * 添加或修改职称级别 61 | * 62 | * @param jobLevel 职称级别 63 | * @param key 该参数用于删除缓存名为key的缓存 64 | * @throws NullParameterException 如果参数为空则抛出该异常 65 | */ 66 | void addOrModifyJobLevelInfo(JobLevel jobLevel, String key) throws NullParameterException; 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/PostService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import top.itning.hrms.entity.post.PositionCategory; 4 | import top.itning.hrms.entity.post.PositionTitle; 5 | import top.itning.hrms.exception.defaults.NoSuchIdException; 6 | import top.itning.hrms.exception.defaults.NullParameterException; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 岗位服务 12 | * 13 | * @author Ning 14 | */ 15 | public interface PostService { 16 | /** 17 | * 获取所有岗位名称信息集合 18 | * 19 | * @param key 默认:getAllPositionTitleInfoList 该参数用于缓存的KEY 20 | * @return 岗位名称信息集合 21 | */ 22 | List getAllPositionTitleInfoList(String key); 23 | 24 | /** 25 | * 获取所有岗位类别信息集合 26 | * 27 | * @param key 默认:getAllPositionCategoryInfoList 该参数用于缓存的KEY 28 | * @return 岗位类别信息集合 29 | */ 30 | List getAllPositionCategoryInfoList(String key); 31 | 32 | /** 33 | * 根据岗位名称ID删除岗位名称信息 34 | * 35 | * @param id 岗位名称ID 36 | * @param key 该参数用于删除缓存名为key的缓存 37 | * @throws NoSuchIdException ID不存在则抛出该异常 38 | */ 39 | void delPositionTitleInfoByID(String id, String key) throws NoSuchIdException; 40 | 41 | /** 42 | * 根据岗位类别ID删除岗位类别信息 43 | * 44 | * @param id 岗位类别ID 45 | * @param key 该参数用于删除缓存名为key的缓存 46 | * @throws NoSuchIdException ID不存在则抛出该异常 47 | */ 48 | void delPositionCategoryInfoByID(String id, String key) throws NoSuchIdException; 49 | 50 | /** 51 | * 添加或修改岗位名称 52 | * 53 | * @param positionTitle 岗位名称 54 | * @param key 该参数用于删除缓存名为key的缓存 55 | * @throws NullParameterException 如果参数为空则抛出该异常 56 | */ 57 | void addOrModifyPositionTitleInfo(PositionTitle positionTitle, String key) throws NullParameterException; 58 | 59 | /** 60 | * 添加或修改岗位类别 61 | * 62 | * @param positionCategory 岗位类别 63 | * @param key 该参数用于删除缓存名为key的缓存 64 | * @throws NullParameterException 如果参数为空则抛出该异常 65 | */ 66 | void addOrModifyCategoryTitleInfo(PositionCategory positionCategory, String key) throws NullParameterException; 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/search/SearchStaff.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity.search; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.Date; 7 | 8 | /** 9 | * 职工搜索实体 10 | * 11 | * @author Ning 12 | */ 13 | @Data 14 | public class SearchStaff implements Serializable { 15 | /** 16 | * 姓名 17 | */ 18 | private String name; 19 | /** 20 | * 银行卡号 21 | */ 22 | private String bankID; 23 | /** 24 | * 邮箱 25 | */ 26 | private String email; 27 | /** 28 | * 性别 29 | */ 30 | private Boolean[] sex; 31 | /** 32 | * 身份证号 33 | */ 34 | private String nid; 35 | /** 36 | * 出生日期开始 37 | */ 38 | private Date startBirthday; 39 | /** 40 | * 出生日期结束 41 | */ 42 | private Date endBirthday; 43 | /** 44 | * 电话号码 45 | */ 46 | private String tel; 47 | /** 48 | * 部门ID 49 | */ 50 | private String[] department; 51 | /** 52 | * 基层单位ID 53 | */ 54 | private String[] grassroot; 55 | /** 56 | * 岗位名称 57 | */ 58 | private String[] positionTitle; 59 | /** 60 | * 岗位类别 61 | */ 62 | private String[] positionCategory; 63 | /** 64 | * 来校日期开始 65 | */ 66 | private Date startComeDate; 67 | /** 68 | * 来校日期结束 69 | */ 70 | private Date endComeDate; 71 | /** 72 | * 工龄起始日期开始 73 | */ 74 | private Date startDate; 75 | /** 76 | * 工龄起始日期结束 77 | */ 78 | private Date endDate; 79 | /** 80 | * 社会职称 81 | */ 82 | private String[] jobTitle; 83 | /** 84 | * 职称级别 85 | */ 86 | private String[] jobLevel; 87 | /** 88 | * 岗位工资开始 89 | */ 90 | private Integer startWage; 91 | /** 92 | * 岗位工资结束 93 | */ 94 | private Integer endWage; 95 | /** 96 | * 绩效工资开始 97 | */ 98 | private Integer startPerformancePay; 99 | /** 100 | * 绩效工资结束 101 | */ 102 | private Integer endPerformancePay; 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/security/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.security; 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 | /** 14 | * 安全配置 15 | * 16 | * @author wangn 17 | */ 18 | @Configuration 19 | @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) 20 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 21 | @Override 22 | @Bean 23 | public UserDetailsService userDetailsService() { 24 | return new UserDetailsServiceImpl(); 25 | } 26 | 27 | @Override 28 | @Bean 29 | public AuthenticationManager authenticationManagerBean() throws Exception { 30 | // ALTOUGH THIS SEEMS LIKE USELESS CODE, 31 | // ITS REQUIRED TO PREVEND SPRING BOOT AUTO-CONFIGURATION 32 | return super.authenticationManagerBean(); 33 | } 34 | 35 | @Override 36 | protected void configure(HttpSecurity http) throws Exception { 37 | http.csrf().disable(); 38 | http.authorizeRequests(). 39 | antMatchers("/css/**", "/image/**", "/js/**", "/lib_web/**").permitAll(). 40 | anyRequest().authenticated(). 41 | and().formLogin().loginPage("/login").permitAll(). 42 | and().logout().permitAll(); 43 | http.logout().logoutSuccessUrl("/"); 44 | } 45 | 46 | @Override 47 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 48 | auth.userDetailsService(userDetailsService()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Human Resource Manage System 2 | 人力资源管理系统 3 | 4 | [![GitHub stars](https://img.shields.io/github/stars/itning/hrms.svg?style=social&label=Stars)](https://github.com/itning/hrms/stargazers) 5 | [![GitHub forks](https://img.shields.io/github/forks/itning/hrms.svg?style=social&label=Fork)](https://github.com/itning/hrms/network/members) 6 | [![GitHub watchers](https://img.shields.io/github/watchers/itning/hrms.svg?style=social&label=Watch)](https://github.com/itning/hrms/watchers) 7 | [![GitHub followers](https://img.shields.io/github/followers/itning.svg?style=social&label=Follow)](https://github.com/itning?tab=followers) 8 | 9 | [![GitHub issues](https://img.shields.io/github/issues/itning/hrms.svg)](https://github.com/itning/hrms/issues) 10 | [![GitHub license](https://img.shields.io/github/license/itning/hrms.svg)](https://github.com/itning/hrms/blob/master/LICENSE) 11 | [![GitHub last commit](https://img.shields.io/github/last-commit/itning/hrms.svg)](https://github.com/itning/hrms/commits) 12 | [![GitHub release](https://img.shields.io/github/release/itning/hrms.svg)](https://github.com/itning/hrms/releases) 13 | [![GitHub repo size in bytes](https://img.shields.io/github/repo-size/itning/hrms.svg)](https://github.com/itning/hrms) 14 | [![HitCount](https://hitcount.itning.top/?u=itning&r=hrms)](https://github.com/itning/hit-count) 15 | [![language](https://img.shields.io/badge/language-JAVA-green.svg)](https://github.com/itning/hrms) 16 | 17 | > 项目目前正在开发中 18 | 19 | Doc 文档 20 | https://itning.github.io/doc/hrms/index.html 21 | 22 | ### 技术架构 23 | #### 前端 24 | - [MDUI](https://www.mdui.org/) -> 一个Material Design风格的CSS框架 25 | - [canvas-nest](https://github.com/hustcc/canvas-nest.js) -> 好看的动态背景 26 | - [My97 DatePicker](http://www.my97.net/index.asp) -> 日期控件 27 | - [Jquery](https://jquery.org/) -> 前端常用框架工具 28 | #### 后端 29 | - Spring Boot -> 约定优于配置 30 | - Spring JPA -> Spring的JAVA持久层实现 31 | - Spring Security -> Spring的安全控制框架 32 | - [Apache POI](https://poi.apache.org/) -> 用JAVA对Excel进行操作 33 | - [CAS](https://github.com/apereo/cas) -> 单点登录 34 | ### 预览 35 | 36 | ![](https://github.com/itning/hrms/blob/dev/pic/login.png) 37 | 38 | ### 开源协议 39 | - [MIT](https://github.com/itning/hrms/blob/dev/LICENSE) 40 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/impl/EmploymentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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.cache.annotation.CacheEvict; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.stereotype.Service; 10 | import top.itning.hrms.dao.employee.EmploymentFormDao; 11 | import top.itning.hrms.entity.employment.EmploymentForm; 12 | import top.itning.hrms.exception.defaults.NoSuchIdException; 13 | import top.itning.hrms.exception.defaults.NullParameterException; 14 | import top.itning.hrms.service.EmploymentService; 15 | 16 | import javax.transaction.Transactional; 17 | import java.util.List; 18 | 19 | /** 20 | * 用工形式服务实现类 21 | * 22 | * @author Ning 23 | */ 24 | @Service 25 | @Transactional(rollbackOn = Exception.class) 26 | public class EmploymentServiceImpl implements EmploymentService { 27 | private static final Logger logger = LoggerFactory.getLogger(EmploymentServiceImpl.class); 28 | 29 | private final EmploymentFormDao employmentFormDao; 30 | 31 | @Autowired 32 | public EmploymentServiceImpl(EmploymentFormDao employmentFormDao) { 33 | this.employmentFormDao = employmentFormDao; 34 | } 35 | 36 | @Override 37 | @Cacheable(cacheNames = "EmploymentList", key = "#key") 38 | public List getAllEmploymentFormList(String key) { 39 | logger.debug("getAllEmploymentFormList::获取所有用工形式信息"); 40 | return employmentFormDao.findAll(); 41 | } 42 | 43 | @Override 44 | @CacheEvict(cacheNames = "EmploymentList", key = "#key") 45 | public void delEmploymentFormByID(String id, String key) throws NoSuchIdException { 46 | if (!employmentFormDao.exists(id)) { 47 | logger.warn("delEmploymentFormByID::ID->" + id + "的用工形式信息不存在"); 48 | throw new NoSuchIdException("ID为" + id + "的用工形式信息不存在"); 49 | } 50 | employmentFormDao.delete(id); 51 | } 52 | 53 | @Override 54 | @CacheEvict(cacheNames = "EmploymentList", key = "#key") 55 | public void addOrModifyEmploymentFormInfo(EmploymentForm employmentForm, String key) throws NullParameterException { 56 | if (StringUtils.isAnyBlank(employmentForm.getId(), employmentForm.getName())) { 57 | logger.warn("addOrModifyEmploymentFormInfo::参数为空->" + employmentForm); 58 | throw new NullParameterException("参数为空"); 59 | } 60 | employmentFormDao.saveAndFlush(employmentForm); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/User.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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 | * 用户实体 19 | * 20 | * @author wangn 21 | */ 22 | @Entity 23 | @Table(name = "sec_user") 24 | public class User implements Serializable, UserDetails { 25 | /** 26 | * 用户ID 27 | */ 28 | @Id 29 | private String id; 30 | /** 31 | * 用户名 32 | */ 33 | @NotNull 34 | private String username; 35 | /** 36 | * 密码 37 | */ 38 | @NotNull 39 | private String password; 40 | /** 41 | * 角色 42 | */ 43 | @NotNull 44 | private String role; 45 | 46 | public String getId() { 47 | return id; 48 | } 49 | 50 | public void setId(String id) { 51 | this.id = id; 52 | } 53 | 54 | public void setUsername(String username) { 55 | this.username = username; 56 | } 57 | 58 | public void setPassword(String password) { 59 | this.password = password; 60 | } 61 | 62 | public String getRole() { 63 | return role; 64 | } 65 | 66 | public void setRole(String role) { 67 | this.role = role; 68 | } 69 | 70 | @Override 71 | public Collection getAuthorities() { 72 | List auths = new ArrayList<>(); 73 | auths.add(new SimpleGrantedAuthority(this.getRole())); 74 | return auths; 75 | } 76 | 77 | @Override 78 | public String getPassword() { 79 | return this.password; 80 | } 81 | 82 | @Override 83 | public String getUsername() { 84 | return this.username; 85 | } 86 | 87 | @Override 88 | public boolean isAccountNonExpired() { 89 | return true; 90 | } 91 | 92 | @Override 93 | public boolean isAccountNonLocked() { 94 | return true; 95 | } 96 | 97 | @Override 98 | public boolean isCredentialsNonExpired() { 99 | return true; 100 | } 101 | 102 | @Override 103 | public boolean isEnabled() { 104 | return true; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/resources/templates/payrollMailTemplate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 工资 6 | 11 | 12 | 13 |

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
姓名:舒露
岗位工资:2000绩效工资:3200职务津贴:6000岗位超时补助:2000
小计1:8000
补款:200扣款:300
小计2:500
教学奖金:300硕士津贴:300电话补助:300带学生津贴:300奖金:300
本学院校拨津贴:500学生处发放8小时以外补助:600加班补助:800值班补助:440其他补助:800
补助小计:6000
工资合计:6000
代扣养老保险:6000代扣医疗保险:6000代扣失业保险:6000代扣住房公积金:6000
应发额:8888
代扣款:660
67 |
68 | 69 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/exception/resolver/ExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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.hrms.entity.ServerMessage; 10 | import top.itning.hrms.exception.defaults.DefaultException; 11 | import top.itning.hrms.exception.json.JsonException; 12 | 13 | import javax.servlet.http.HttpServletRequest; 14 | import java.util.Arrays; 15 | 16 | /** 17 | * 异常处理 18 | * 19 | * @author Ning 20 | */ 21 | @ControllerAdvice 22 | public class ExceptionResolver { 23 | private static final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class); 24 | /** 25 | * 默认错误页面 26 | */ 27 | private static final String DEFAULT_ERROR_VIEW = "error"; 28 | 29 | /** 30 | * 默认错误适配 31 | * 32 | * @param req HttpServletRequest 33 | * @param e Exception 34 | * @return ModelAndView 35 | */ 36 | @ExceptionHandler(value = DefaultException.class) 37 | public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) { 38 | logger.error("defaultErrorHandler->" + e.getClass().getSimpleName() + ":" + e.getMessage()); 39 | ModelAndView mav = new ModelAndView(); 40 | mav.addObject("exceptionMessage", e.getMessage()); 41 | mav.addObject("url", req.getRequestURL().toString()); 42 | mav.setViewName(DEFAULT_ERROR_VIEW); 43 | return mav; 44 | } 45 | 46 | /** 47 | * 其他异常消息 48 | * 49 | * @param req HttpServletRequest 50 | * @param e Exception 51 | * @return ModelAndView 52 | */ 53 | @ExceptionHandler(value = Exception.class) 54 | public ModelAndView otherErrorHandler(HttpServletRequest req, Exception e) { 55 | logger.error("otherErrorHandler->" + e.getClass().getSimpleName() + ":" + e.getMessage()); 56 | logger.error("otherErrorHandler->" + Arrays.toString(e.getStackTrace())); 57 | ModelAndView mav = new ModelAndView(); 58 | mav.addObject("exceptionMessage", e.getMessage()); 59 | mav.addObject("url", req.getRequestURL().toString()); 60 | mav.setViewName(DEFAULT_ERROR_VIEW); 61 | return mav; 62 | } 63 | 64 | /** 65 | * json 格式错误消息 66 | * 67 | * @param req HttpServletRequest 68 | * @param e Exception 69 | * @return 异常消息 70 | */ 71 | @ExceptionHandler(value = JsonException.class) 72 | @ResponseBody 73 | public ServerMessage jsonErrorHandler(HttpServletRequest req, JsonException e) { 74 | logger.error("jsonErrorHandler->" + e.getClass().getSimpleName() + ":" + e.getMessage()); 75 | ServerMessage serverMessage = new ServerMessage(); 76 | serverMessage.setCode(e.getCode()); 77 | serverMessage.setMsg(e.getMessage()); 78 | serverMessage.setUrl(req.getRequestURL().toString()); 79 | return serverMessage; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/impl/DepartmentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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.cache.annotation.CacheEvict; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.stereotype.Service; 10 | import top.itning.hrms.dao.department.DepartmentDao; 11 | import top.itning.hrms.entity.department.Department; 12 | import top.itning.hrms.entity.department.Grassroot; 13 | import top.itning.hrms.exception.defaults.NoSuchIdException; 14 | import top.itning.hrms.exception.defaults.NullParameterException; 15 | import top.itning.hrms.service.DepartmentService; 16 | 17 | import javax.transaction.Transactional; 18 | import java.util.List; 19 | 20 | /** 21 | * 部门管理服务实现类 22 | * 23 | * @author Ning 24 | */ 25 | @Service 26 | @Transactional(rollbackOn = Exception.class) 27 | public class DepartmentServiceImpl implements DepartmentService { 28 | private static final Logger logger = LoggerFactory.getLogger(DepartmentServiceImpl.class); 29 | 30 | private final DepartmentDao departmentDao; 31 | 32 | @Autowired 33 | public DepartmentServiceImpl(DepartmentDao departmentDao) { 34 | this.departmentDao = departmentDao; 35 | } 36 | 37 | @Override 38 | @Cacheable(cacheNames = "DepartmentList", key = "#key") 39 | public List getAllDepartmentInfoList(String key) { 40 | logger.debug("getAllDepartmentInfo::获取部门信息集合"); 41 | return departmentDao.findAll(); 42 | } 43 | 44 | @Override 45 | @CacheEvict(cacheNames = "DepartmentList", key = "#key") 46 | public void delDepartmentByID(String id, String key) throws NoSuchIdException { 47 | if (!departmentDao.exists(id)) { 48 | logger.warn("delDepartmentByID::ID->" + id + "的部门不存在"); 49 | throw new NoSuchIdException("ID为" + id + "的部门信息不存在"); 50 | } 51 | //逻辑:检查基层单位是否存在,存在提示,不存在删除 52 | List grassrootList = departmentDao.getOne(id).getGrassroots(); 53 | if (grassrootList != null && grassrootList.size() != 0) { 54 | throw new NoSuchIdException("请先检查该部门下是否存在基层单位!"); 55 | } 56 | departmentDao.delete(id); 57 | } 58 | 59 | @Override 60 | @CacheEvict(cacheNames = "DepartmentList", key = "#key") 61 | public void addOrModifyDepartmentInfo(Department department, String key) throws NullParameterException { 62 | if (StringUtils.isAnyBlank(department.getId(), department.getName())) { 63 | logger.warn("addOrModifyDepartmentInfo::参数为空->" + department); 64 | throw new NullParameterException("参数为空"); 65 | } 66 | //如果基层单位不存在且有这个部门(修改操作) 67 | if (department.getGrassroots() == null && departmentDao.exists(department.getId())) { 68 | Department wantUpDepartment = departmentDao.findOne(department.getId()); 69 | department.setGrassroots(wantUpDepartment.getGrassroots()); 70 | } 71 | departmentDao.saveAndFlush(department); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/Wage.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.*; 6 | import javax.validation.constraints.NotNull; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * 工资实体 11 | * 12 | * @author Ning 13 | */ 14 | @Data 15 | @Entity 16 | @Table(name = "WAGE") 17 | public class Wage implements Serializable { 18 | /** 19 | * UUID 20 | */ 21 | @Id 22 | private String id; 23 | /** 24 | * 年 25 | */ 26 | @NotNull 27 | private String year; 28 | /** 29 | * 月 30 | */ 31 | @NotNull 32 | private String month; 33 | /** 34 | * 职工 35 | */ 36 | @NotNull 37 | @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 38 | @JoinColumn(name = "staff") 39 | private Staff staff; 40 | /** 41 | * 小计1 42 | * wage+performancePay+dutyAllowance+grants 43 | * "岗位工资" "绩效工资" "职务津贴" 岗位超时补助 44 | */ 45 | private int total1; 46 | /** 47 | * 补款 48 | */ 49 | private int replenishment; 50 | /** 51 | * 扣款 52 | */ 53 | private int chargeBack; 54 | /** 55 | * 小计2 56 | */ 57 | private int total2; 58 | /** 59 | * 教学奖金 60 | */ 61 | private int teachingBonus; 62 | /** 63 | * 带学生津贴 64 | */ 65 | private int studentAllowance; 66 | /** 67 | * 奖金 68 | */ 69 | private int bonus; 70 | /** 71 | * 校拨津贴 72 | */ 73 | private int schoolGrant; 74 | /** 75 | * 教师节津贴 76 | */ 77 | private int teacherDayAllowance; 78 | /** 79 | * 加班补助 80 | */ 81 | private int overtimeAssistance; 82 | /** 83 | * 学生处发放8小时以外补助 84 | */ 85 | private int time8; 86 | /** 87 | * 值班补助 88 | */ 89 | private int onDutySubsidies; 90 | /** 91 | * 其他补助 92 | */ 93 | private int otherBenefits; 94 | /** 95 | * 补助小计 96 | */ 97 | private int totalBenefits; 98 | /** 99 | * 工资合计 100 | */ 101 | private int total; 102 | /** 103 | * 代扣养老保险 104 | */ 105 | private int pensionInsurance; 106 | /** 107 | * 代扣医疗保险 108 | */ 109 | private int medicalInsurance; 110 | /** 111 | * 代扣失业保险 112 | */ 113 | private int unemploymentInsurance; 114 | /** 115 | * 代扣住房公积金 116 | */ 117 | private int housingFund; 118 | /** 119 | * 应发额 120 | */ 121 | private int shouldMade; 122 | /** 123 | * 代扣款 124 | */ 125 | private int withholding; 126 | /** 127 | * 个人所得税 128 | */ 129 | private int personalIncomeTax; 130 | /** 131 | * 税后实发 132 | */ 133 | private int afterTaxRealHair; 134 | /** 135 | * 单位承担养老保险 136 | */ 137 | private int unitPensionInsurance; 138 | /** 139 | * 单位承担医疗保险 140 | */ 141 | private int unitMedicalInsurance; 142 | /** 143 | * 单位承担工伤保险 144 | */ 145 | private int unitInjuryInsurance; 146 | /** 147 | * 单位承担生育保险 148 | */ 149 | private int unitMaternityInsurance; 150 | /** 151 | * 单位承担失业保险 152 | */ 153 | private int unitUnemploymentInsurance; 154 | /** 155 | * 单位承担住房公积金 156 | */ 157 | private int unitHousingFund; 158 | } 159 | -------------------------------------------------------------------------------- /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/hrms/controller/FrameController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller; 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.access.prepost.PreAuthorize; 8 | import org.springframework.security.core.GrantedAuthority; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | import org.springframework.security.core.userdetails.UserDetails; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.Model; 13 | import org.springframework.web.bind.annotation.GetMapping; 14 | import top.itning.hrms.entity.User; 15 | import top.itning.hrms.entity.department.Department; 16 | import top.itning.hrms.service.DepartmentService; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * 框架控制器 22 | * 23 | * @author Ning 24 | */ 25 | @Controller 26 | public class FrameController { 27 | private static final Logger logger = LoggerFactory.getLogger(FrameController.class); 28 | 29 | private final DepartmentService departmentService; 30 | 31 | @Autowired 32 | public FrameController(DepartmentService departmentService) { 33 | this.departmentService = departmentService; 34 | } 35 | 36 | /** 37 | * 根路径 38 | * 39 | * @return 重定向到主页/搜索页 40 | */ 41 | @GetMapping("/") 42 | public String root() { 43 | if (!ClassUtils.isAssignable(SecurityContextHolder.getContext().getAuthentication().getPrincipal().getClass(), User.class)) { 44 | return "redirect:/index"; 45 | } 46 | User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 47 | for (GrantedAuthority authority : user.getAuthorities()) { 48 | if ("USER".equals(authority.getAuthority())) { 49 | logger.debug("root::重定向到工资搜索页"); 50 | return "redirect:/staffWage/search"; 51 | } 52 | } 53 | logger.debug("root::重定向到主页"); 54 | return "redirect:/index"; 55 | } 56 | 57 | /** 58 | * 主页控制器 59 | * 60 | * @param model 模型 61 | * @return index.html 62 | */ 63 | @GetMapping("/index") 64 | @PreAuthorize("hasAnyAuthority('ADMIN')") 65 | public String index(Model model) { 66 | logger.debug("index::开始获取部门信息集合"); 67 | List departmentList = departmentService.getAllDepartmentInfoList("getAllDepartmentInfoList"); 68 | logger.debug("index::获取部门信息集合完成,大小->" + departmentList.size()); 69 | model.addAttribute("departmentList", departmentList); 70 | return "index"; 71 | } 72 | 73 | /** 74 | * 管理控制器 75 | * 76 | * @param model 模型 77 | * @return defaultManage.html 78 | */ 79 | @GetMapping("/manage") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public String manage(Model model) { 82 | model.addAttribute("departmentList", departmentService.getAllDepartmentInfoList("getAllDepartmentInfoList")); 83 | return "defaultManage"; 84 | } 85 | 86 | /** 87 | * 基层单位控制器 88 | * 89 | * @param model 模型 90 | * @return grassroot.html 91 | */ 92 | @GetMapping("/grassroot") 93 | @PreAuthorize("hasAnyAuthority('ADMIN')") 94 | public String grassroot(Model model) { 95 | model.addAttribute("departmentList", departmentService.getAllDepartmentInfoList("getAllDepartmentInfoList")); 96 | return "grassroot"; 97 | } 98 | 99 | /** 100 | * 登陆控制器 101 | * 102 | * @return login.html 103 | */ 104 | @GetMapping("/login") 105 | public String login() { 106 | return "login"; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 404-哈信息人力资源管理系统 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 |
30 |
31 | menu 33 |

哈信息人力资源管理系统

34 |
35 | refresh 37 |
38 |
39 | 40 | 68 |
69 |

404

70 | 71 |

72 | 73 |

74 |

点我回首页

75 |
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/impl/JobServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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.cache.annotation.CacheEvict; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.stereotype.Service; 10 | import top.itning.hrms.dao.job.JobLevelDao; 11 | import top.itning.hrms.dao.job.JobTitleDao; 12 | import top.itning.hrms.entity.job.JobLevel; 13 | import top.itning.hrms.entity.job.JobTitle; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.JobService; 17 | 18 | import javax.transaction.Transactional; 19 | import java.util.List; 20 | 21 | /** 22 | * 社会职称/级别服务实现类 23 | * 24 | * @author Ning 25 | */ 26 | @Service 27 | @Transactional(rollbackOn = Exception.class) 28 | public class JobServiceImpl implements JobService { 29 | private static final Logger logger = LoggerFactory.getLogger(JobServiceImpl.class); 30 | 31 | private final JobTitleDao jobTitleDao; 32 | 33 | private final JobLevelDao jobLevelDao; 34 | 35 | @Autowired 36 | public JobServiceImpl(JobTitleDao jobTitleDao, JobLevelDao jobLevelDao) { 37 | this.jobTitleDao = jobTitleDao; 38 | this.jobLevelDao = jobLevelDao; 39 | } 40 | 41 | @Override 42 | @Cacheable(cacheNames = "JobTitleInfoList", key = "#key") 43 | public List getAllJobTitleInfoList(String key) { 44 | logger.debug("getAllJobTitleInfoList::开始获取所有社会职称信息集合"); 45 | return jobTitleDao.findAll(); 46 | } 47 | 48 | @Override 49 | @Cacheable(cacheNames = "JobLevelInfoList", key = "#key") 50 | public List getAllJobLevelInfoList(String key) { 51 | logger.debug("getAllJobLevelInfoList::开始获取所有职称级别信息集合"); 52 | return jobLevelDao.findAll(); 53 | } 54 | 55 | @Override 56 | @CacheEvict(cacheNames = "JobTitleInfoList", key = "#key") 57 | public void delJobTitleInfoByID(String id, String key) throws NoSuchIdException { 58 | if (!jobTitleDao.exists(id)) { 59 | logger.warn("delJobTitleInfoByID::ID->" + id + "的社会职称信息不存在"); 60 | throw new NoSuchIdException("ID为" + id + "的社会职称信息不存在"); 61 | } 62 | jobTitleDao.delete(id); 63 | } 64 | 65 | @Override 66 | @CacheEvict(cacheNames = "JobLevelInfoList", key = "#key") 67 | public void delJobLevelByID(String id, String key) throws NoSuchIdException { 68 | if (!jobLevelDao.exists(id)) { 69 | logger.warn("delJobLevelByID::ID->" + id + "的职称级别信息不存在"); 70 | throw new NoSuchIdException("ID为" + id + "的职称级别信息不存在"); 71 | } 72 | jobLevelDao.delete(id); 73 | } 74 | 75 | @Override 76 | @CacheEvict(cacheNames = "JobTitleInfoList", key = "#key") 77 | public void addOrModifyJobTitleInfo(JobTitle jobTitle, String key) throws NullParameterException { 78 | if (StringUtils.isAnyBlank(jobTitle.getId(), jobTitle.getName())) { 79 | logger.warn("addOrModifyJobTitleInfo::参数为空->" + jobTitle); 80 | throw new NullParameterException("参数为空"); 81 | } 82 | jobTitleDao.saveAndFlush(jobTitle); 83 | } 84 | 85 | @Override 86 | @CacheEvict(cacheNames = "JobLevelInfoList", key = "#key") 87 | public void addOrModifyJobLevelInfo(JobLevel jobLevel, String key) throws NullParameterException { 88 | if (StringUtils.isAnyBlank(jobLevel.getId(), jobLevel.getName())) { 89 | logger.warn("addOrModifyJobLevelInfo::参数为空->" + jobLevel); 90 | throw new NullParameterException("参数为空"); 91 | } 92 | jobLevelDao.saveAndFlush(jobLevel); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 登陆-哈信息人力资源管理系统 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 31 | 32 | 33 | 60 | 61 | 62 | 90 | 91 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/schedul/PayrollSendingTask.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.schedul; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.mail.javamail.JavaMailSender; 6 | import org.springframework.mail.javamail.MimeMessageHelper; 7 | import org.springframework.stereotype.Component; 8 | import org.thymeleaf.TemplateEngine; 9 | import org.thymeleaf.context.Context; 10 | import top.itning.hrms.entity.Wage; 11 | import top.itning.hrms.entity.WageEmail; 12 | import top.itning.hrms.entity.search.SearchWage; 13 | import top.itning.hrms.exception.json.JsonException; 14 | import top.itning.hrms.service.WageService; 15 | 16 | import javax.mail.MessagingException; 17 | import javax.mail.internet.MimeMessage; 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.stream.Collectors; 23 | 24 | /** 25 | * 工资每月发送 26 | * 27 | * @author wangn 28 | */ 29 | @Component 30 | public class PayrollSendingTask { 31 | private final JavaMailSender mailSender; 32 | 33 | private final TemplateEngine templateEngine; 34 | 35 | private final WageService wageService; 36 | 37 | @Value("${spring.mail.username}") 38 | private String sendFrom; 39 | 40 | @Autowired 41 | public PayrollSendingTask(@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") JavaMailSender mailSender, TemplateEngine templateEngine, WageService wageService) { 42 | this.mailSender = mailSender; 43 | this.templateEngine = templateEngine; 44 | this.wageService = wageService; 45 | } 46 | 47 | /** 48 | * 开始 49 | */ 50 | void startSend() { 51 | //假设本月工资已经导入 52 | //查找当前年,月,的工资信息 53 | //获取Wage实体集合 54 | //拼装WageEmail实体集合 55 | String year = new SimpleDateFormat("yyyy").format(new Date()); 56 | String month = new SimpleDateFormat("yyyy-M").format(new Date()); 57 | SearchWage searchWage = new SearchWage(); 58 | searchWage.setMonth(new String[]{month}); 59 | searchWage.setYear(new String[]{year}); 60 | try { 61 | Map map = wageService.searchWage(searchWage); 62 | @SuppressWarnings("unchecked") 63 | List wageList = (List) map.get("wageList"); 64 | if (wageList != null) { 65 | List emailList = wageList.stream().map(wage -> { 66 | WageEmail wageEmail = new WageEmail(); 67 | wageEmail.setFields(wage); 68 | return wageEmail; 69 | }).collect(Collectors.toList()); 70 | emailList.forEach(wageEmail -> { 71 | try { 72 | sendPayrollInfo(wageEmail.getAllFiledMap(), month + "工资信息", wageEmail.getEmail()); 73 | } catch (MessagingException e) { 74 | e.printStackTrace(); 75 | } 76 | }); 77 | } 78 | } catch (JsonException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | 83 | /** 84 | * 发送邮件 85 | * 86 | * @param map 模板值 87 | * @throws MessagingException MessagingException 88 | */ 89 | private void sendPayrollInfo(Map map, String subject, String sendTo) throws MessagingException { 90 | MimeMessage mimeMessage = mailSender.createMimeMessage(); 91 | MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); 92 | Context c = new Context(); 93 | c.setVariables(map); 94 | String mailTemplate = templateEngine.process("payrollMailTemplate", c); 95 | helper.setFrom(sendFrom); 96 | helper.setTo(sendTo); 97 | helper.setSubject(subject); 98 | helper.setText(mailTemplate, true); 99 | mailSender.send(mimeMessage); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/impl/FixedServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service.impl; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.cache.annotation.Cacheable; 6 | import org.springframework.stereotype.Service; 7 | import top.itning.hrms.dao.fixed.EthnicDao; 8 | import top.itning.hrms.dao.fixed.PoliticalStatusDao; 9 | import top.itning.hrms.entity.fixed.Ethnic; 10 | import top.itning.hrms.entity.fixed.PoliticalStatus; 11 | import top.itning.hrms.service.FixedService; 12 | 13 | import javax.transaction.Transactional; 14 | import java.text.DecimalFormat; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | * @author Ning 20 | */ 21 | @Service 22 | @Transactional(rollbackOn = Exception.class) 23 | public class FixedServiceImpl implements FixedService { 24 | private static final Logger logger = LoggerFactory.getLogger(FixedServiceImpl.class); 25 | 26 | private final EthnicDao ethnicDao; 27 | 28 | private final PoliticalStatusDao politicalStatusDao; 29 | 30 | public FixedServiceImpl(EthnicDao ethnicDao, PoliticalStatusDao politicalStatusDao) { 31 | this.ethnicDao = ethnicDao; 32 | this.politicalStatusDao = politicalStatusDao; 33 | if (ethnicDao.count() == 0) { 34 | logger.info("FixedServiceImpl::初始化民族信息"); 35 | initEthnicInfo(); 36 | } 37 | if (politicalStatusDao.count() == 0) { 38 | logger.info("FixedServiceImpl::初始化政治面貌信息"); 39 | initPoliticalStatusInfo(); 40 | } 41 | } 42 | 43 | private void initPoliticalStatusInfo() { 44 | logger.info("init::开始初始化政治面貌信息"); 45 | List politicalStatusList = new ArrayList<>(); 46 | String[] psStr = {"中共党员", "中共预备党员", "共青团员", "民革党员", "民盟盟员", "民建会员", "民进会员", "农工党党员", "致公党党员", "九三学社社员", "台盟盟员", "无党派人士", "群众"}; 47 | for (int i = 0; i < psStr.length; i++) { 48 | politicalStatusList.add(new PoliticalStatus(String.valueOf(new DecimalFormat("00").format(i + 1)), psStr[i])); 49 | } 50 | logger.info("init::初始化政治面貌信息数量->" + politicalStatusList.size()); 51 | politicalStatusDao.save(politicalStatusList); 52 | politicalStatusDao.flush(); 53 | logger.info("init::添加政治面貌信息完成"); 54 | } 55 | 56 | private void initEthnicInfo() { 57 | logger.info("init::开始初始化民族信息"); 58 | List ethnicList = new ArrayList<>(); 59 | String[] ethnicStr = {"汉族", "蒙古族", "回族", "藏族", 60 | "维吾尔族", "苗族", "彝族", "壮族", "布依族", "朝鲜族", "满族", "侗族", "瑶族", "白族", 61 | "土家族", "哈尼族", "哈萨克族", "傣族", "黎族", "傈僳族", "佤族", "畲族", "高山族", "拉祜族", "水族", "东乡族", "纳西族", 62 | "景颇族", "柯尔克孜族", "土族", "达斡尔族", "仫佬族", "羌族", "布朗族", "撒拉族", "毛难族", "仡佬族", "锡伯族", "阿昌族", 63 | "普米族", "塔吉克族", "怒族", "乌孜别克族", "俄罗斯族", "鄂温克族", "崩龙族", "保安族", "裕固族", "京族", "塔塔尔族", 64 | "独龙族", "鄂伦春族", "赫哲族", "门巴族", "珞巴族", "基诺族", "其他", "外国血统"}; 65 | for (int i = 0; i < ethnicStr.length; i++) { 66 | if (i < 56) { 67 | ethnicList.add(new Ethnic(String.valueOf(new DecimalFormat("00").format(i + 1)), ethnicStr[i])); 68 | } else { 69 | ethnicList.add(new Ethnic(String.valueOf(i + 41), ethnicStr[i])); 70 | } 71 | } 72 | logger.info("init::初始化民族信息数量->" + ethnicList.size()); 73 | ethnicDao.save(ethnicList); 74 | ethnicDao.flush(); 75 | logger.info("init::添加民族信息完成"); 76 | } 77 | 78 | @Override 79 | @Cacheable(cacheNames = "EthnicInfoList", key = "#key") 80 | public List getAllEthnicInfoList(String key) { 81 | logger.debug("getAllEthnicInfoList::开始获取所有民族信息集合"); 82 | return ethnicDao.findAll(); 83 | } 84 | 85 | @Override 86 | @Cacheable(cacheNames = "PoliticalStatusInfoList", key = "#key") 87 | public List getAllPoliticalStatusInfoList(String key) { 88 | logger.debug("getAllPoliticalStatusInfoList::开始获取所有政治面貌信息"); 89 | return politicalStatusDao.findAll(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/impl/PostServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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.cache.annotation.CacheEvict; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.stereotype.Service; 10 | import top.itning.hrms.dao.post.PositionCategoryDao; 11 | import top.itning.hrms.dao.post.PositionTitleDao; 12 | import top.itning.hrms.entity.post.PositionCategory; 13 | import top.itning.hrms.entity.post.PositionTitle; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.PostService; 17 | 18 | import javax.transaction.Transactional; 19 | import java.util.List; 20 | 21 | /** 22 | * 岗位服务实现类 23 | * 24 | * @author Ning 25 | */ 26 | @Service 27 | @Transactional(rollbackOn = Exception.class) 28 | public class PostServiceImpl implements PostService { 29 | private static final Logger logger = LoggerFactory.getLogger(PostServiceImpl.class); 30 | 31 | private final PositionTitleDao positionTitleDao; 32 | 33 | private final PositionCategoryDao positionCategoryDao; 34 | 35 | @Autowired 36 | public PostServiceImpl(PositionTitleDao positionTitleDao, PositionCategoryDao positionCategoryDao) { 37 | this.positionTitleDao = positionTitleDao; 38 | this.positionCategoryDao = positionCategoryDao; 39 | } 40 | 41 | @Override 42 | @Cacheable(cacheNames = "PositionTitleInfoList", key = "#key") 43 | public List getAllPositionTitleInfoList(String key) { 44 | logger.debug("getAllPositionTitleInfoList::开始获取所有岗位名称信息集合"); 45 | return positionTitleDao.findAll(); 46 | } 47 | 48 | @Override 49 | @Cacheable(cacheNames = "PositionCategoryInfoList", key = "#key") 50 | public List getAllPositionCategoryInfoList(String key) { 51 | logger.debug("getAllPositionCategoryInfoList::开始获取所有岗位类别信息集合"); 52 | return positionCategoryDao.findAll(); 53 | } 54 | 55 | @Override 56 | @CacheEvict(cacheNames = "PositionTitleInfoList", key = "#key") 57 | public void delPositionTitleInfoByID(String id, String key) throws NoSuchIdException { 58 | if (!positionTitleDao.exists(id)) { 59 | logger.warn("delPositionTitleInfoByID::ID->" + id + "的岗位名称信息不存在"); 60 | throw new NoSuchIdException("ID为" + id + "的岗位名称信息不存在"); 61 | } 62 | //TODO 检查外键关联 当有关联时给提示,还是直接删除关联 63 | positionTitleDao.delete(id); 64 | } 65 | 66 | @Override 67 | @CacheEvict(cacheNames = "PositionCategoryInfoList", key = "#key") 68 | public void delPositionCategoryInfoByID(String id, String key) throws NoSuchIdException { 69 | if (!positionCategoryDao.exists(id)) { 70 | logger.warn("delPositionCategoryInfoByID::ID->" + id + "的岗位类别信息不存在"); 71 | throw new NoSuchIdException("ID为" + id + "的岗位类别信息不存在"); 72 | } 73 | positionCategoryDao.delete(id); 74 | } 75 | 76 | @Override 77 | @CacheEvict(cacheNames = "PositionTitleInfoList", key = "#key") 78 | public void addOrModifyPositionTitleInfo(PositionTitle positionTitle, String key) throws NullParameterException { 79 | if (StringUtils.isAnyBlank(positionTitle.getId(), positionTitle.getName())) { 80 | logger.warn("addOrModifyPositionTitleInfo::参数为空->" + positionTitle); 81 | throw new NullParameterException("参数为空"); 82 | } 83 | positionTitleDao.saveAndFlush(positionTitle); 84 | } 85 | 86 | @Override 87 | @CacheEvict(cacheNames = "PositionCategoryInfoList", key = "#key") 88 | public void addOrModifyCategoryTitleInfo(PositionCategory positionCategory, String key) throws NullParameterException { 89 | if (StringUtils.isAnyBlank(positionCategory.getId(), positionCategory.getName())) { 90 | logger.warn("addOrModifyCategoryTitleInfo::参数为空->" + positionCategory); 91 | throw new NullParameterException("参数为空"); 92 | } 93 | positionCategoryDao.saveAndFlush(positionCategory); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/schedul/ContractExpires.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.schedul; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.mail.javamail.JavaMailSender; 6 | import org.springframework.mail.javamail.MimeMessageHelper; 7 | import org.springframework.stereotype.Component; 8 | import org.thymeleaf.TemplateEngine; 9 | import org.thymeleaf.context.Context; 10 | import top.itning.hrms.dao.StaffDao; 11 | import top.itning.hrms.entity.Staff; 12 | 13 | import javax.mail.MessagingException; 14 | import javax.mail.internet.MimeMessage; 15 | import java.text.SimpleDateFormat; 16 | import java.util.Date; 17 | import java.util.LinkedList; 18 | import java.util.List; 19 | import java.util.stream.Collectors; 20 | 21 | /** 22 | * 合同到期员工计算 23 | * 24 | * @author wangn 25 | */ 26 | @Component 27 | public class ContractExpires { 28 | /** 29 | * 合同到期提前几天提醒 30 | */ 31 | private static final int DAY = 30; 32 | 33 | private final StaffDao staffDao; 34 | 35 | private final JavaMailSender mailSender; 36 | 37 | private final TemplateEngine templateEngine; 38 | 39 | @Value("${spring.mail.username}") 40 | private String sendFrom; 41 | 42 | @Autowired 43 | public ContractExpires(StaffDao staffDao, @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") JavaMailSender mailSender, TemplateEngine templateEngine) { 44 | this.staffDao = staffDao; 45 | this.mailSender = mailSender; 46 | this.templateEngine = templateEngine; 47 | } 48 | 49 | /** 50 | * 开始 51 | */ 52 | public void startSend() { 53 | Date date = new Date(); 54 | //一共有3次签约 55 | //从后往前查找 56 | List staffList = staffDao.findAll(); 57 | //查找第三次签约到期时间不足30天的员工 58 | List laborContract3EndList = staffList.stream().filter(staff -> staff.getLaborContract3End() != null).filter(staff -> comparisonDateDifferenceDays(date, staff.getLaborContract3End()) <= DAY).collect(Collectors.toList()); 59 | //查找没有第三次签约但签约第二次且到期时间不足30天的员工 60 | List laborContract2EndList = staffList.stream().filter(staff -> staff.getLaborContract3End() == null && staff.getLaborContract2End() != null).filter(staff -> comparisonDateDifferenceDays(date, staff.getLaborContract2End()) <= DAY).collect(Collectors.toList()); 61 | //查找第二三次均没有签约且第一次签约到期时间不足30天的员工 62 | List laborContract1EndList = staffList.stream().filter(staff -> staff.getLaborContract2End() == null && staff.getLaborContract3End() == null && staff.getLaborContract1End() != null).filter(staff -> comparisonDateDifferenceDays(date, staff.getLaborContract1End()) <= DAY).collect(Collectors.toList()); 63 | List list = new LinkedList<>(); 64 | list.addAll(laborContract1EndList); 65 | list.addAll(laborContract2EndList); 66 | list.addAll(laborContract3EndList); 67 | sendEmail(list); 68 | } 69 | 70 | private void sendEmail(List list) { 71 | try { 72 | String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); 73 | MimeMessage mimeMessage = mailSender.createMimeMessage(); 74 | MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); 75 | Context c = new Context(); 76 | c.setVariable("staffList", list); 77 | String mailTemplate = templateEngine.process("contractExpiresTemplate", c); 78 | helper.setFrom(sendFrom); 79 | helper.setTo(sendFrom); 80 | helper.setSubject("合同签约到期提醒名单-" + time); 81 | helper.setText(mailTemplate, true); 82 | mailSender.send(mimeMessage); 83 | } catch (MessagingException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | 88 | /** 89 | * 比较日期相差天数 90 | * 91 | * @param first 第一个日期 92 | * @param second 第二个日期 93 | * @return 相差天数 94 | */ 95 | private int comparisonDateDifferenceDays(Date first, Date second) { 96 | return (int) ((second.getTime() - first.getTime()) / (1000 * 3600 * 24)); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/service/impl/GrassrootServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.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.cache.annotation.CacheEvict; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.cache.annotation.Caching; 10 | import org.springframework.stereotype.Service; 11 | import top.itning.hrms.dao.StaffDao; 12 | import top.itning.hrms.dao.department.DepartmentDao; 13 | import top.itning.hrms.dao.department.GrassrootDao; 14 | import top.itning.hrms.entity.Staff; 15 | import top.itning.hrms.entity.department.Department; 16 | import top.itning.hrms.entity.department.Grassroot; 17 | import top.itning.hrms.exception.defaults.NoSuchIdException; 18 | import top.itning.hrms.exception.defaults.NullParameterException; 19 | import top.itning.hrms.service.GrassrootService; 20 | 21 | import javax.transaction.Transactional; 22 | import java.util.List; 23 | 24 | /** 25 | * 基层单位服务实现类 26 | * 27 | * @author Ning 28 | */ 29 | @Service 30 | @Transactional(rollbackOn = Exception.class) 31 | public class GrassrootServiceImpl implements GrassrootService { 32 | private static final Logger logger = LoggerFactory.getLogger(GrassrootServiceImpl.class); 33 | 34 | private final DepartmentDao departmentDao; 35 | 36 | private final GrassrootDao grassrootDao; 37 | 38 | private final StaffDao staffDao; 39 | 40 | @Autowired 41 | public GrassrootServiceImpl(DepartmentDao departmentDao, GrassrootDao grassrootDao, StaffDao staffDao) { 42 | this.departmentDao = departmentDao; 43 | this.grassrootDao = grassrootDao; 44 | this.staffDao = staffDao; 45 | } 46 | 47 | @Override 48 | @Cacheable(cacheNames = "GrassrootListByDepartment", key = "#id") 49 | public List getGrassrootListByDepartment(String id) throws NoSuchIdException { 50 | if (StringUtils.isBlank(id) || !departmentDao.exists(id)) { 51 | logger.warn("getGrassrootListByDepartment::ID不存在,ID->" + id); 52 | throw new NoSuchIdException("ID:" + id + "不存在"); 53 | } 54 | return departmentDao.getOne(id).getGrassroots(); 55 | } 56 | 57 | @Override 58 | @Caching(evict = { 59 | @CacheEvict(value = "GrassrootListByDepartment", key = "#did"), 60 | @CacheEvict(value = "StaffInfoList", key = "#did")}) 61 | public void modifyGrassroot(Grassroot grassroot, String did) throws NullParameterException { 62 | if (StringUtils.isAnyBlank(grassroot.getId(), grassroot.getName())) { 63 | logger.warn("modifyGrassrootByDepartment::参数为空->" + grassroot); 64 | throw new NullParameterException("参数为空"); 65 | } 66 | grassrootDao.modifyGrassrootInfo(grassroot.getId(), grassroot.getName()); 67 | } 68 | 69 | @Override 70 | @CacheEvict(cacheNames = "GrassrootListByDepartment", key = "#id") 71 | public void addGrassrootByDepartmentID(String id, Grassroot grassroot) throws NoSuchIdException, NullParameterException { 72 | if (StringUtils.isAnyBlank(id, grassroot.getName(), grassroot.getId())) { 73 | logger.warn("addGrassrootByDepartmentID::参数为空,ID->" + id + "Grassroot->" + grassroot); 74 | throw new NullParameterException("参数为空"); 75 | } 76 | if (!departmentDao.exists(id)) { 77 | logger.warn("addGrassrootByDepartmentID::ID->" + id + "不存在"); 78 | throw new NoSuchIdException("部门ID:" + id + "不存在"); 79 | } 80 | Department department = departmentDao.getOne(id); 81 | List grassroots = department.getGrassroots(); 82 | grassroots.add(grassroot); 83 | department.setGrassroots(grassroots); 84 | departmentDao.saveAndFlush(department); 85 | } 86 | 87 | @Override 88 | @CacheEvict(cacheNames = "GrassrootListByDepartment", key = "#did") 89 | public void delGrassrootByID(String id, String did) throws NoSuchIdException { 90 | if (StringUtils.isBlank(id) && !grassrootDao.exists(id)) { 91 | logger.warn("delGrassrootByID::ID不存在或为空->" + id); 92 | throw new NoSuchIdException("ID:" + id + "不存在或为空"); 93 | } 94 | List staffList = staffDao.findByGrassroot(grassrootDao.findOne(id)); 95 | if (staffList != null && staffList.size() != 0) { 96 | throw new NoSuchIdException("请先检查该基层单位下职工是否已经移除!"); 97 | } 98 | grassrootDao.delete(id); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/controller/job/JobLevelController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.job; 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.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import top.itning.hrms.entity.ServerMessage; 13 | import top.itning.hrms.entity.job.JobLevel; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.JobService; 17 | 18 | import java.util.List; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 职称级别控制器 23 | * 24 | * @author Ning 25 | */ 26 | @RestController 27 | @RequestMapping("/jobLevel") 28 | public class JobLevelController { 29 | private static final Logger logger = LoggerFactory.getLogger(JobLevelController.class); 30 | 31 | private final JobService jobService; 32 | 33 | @Autowired 34 | public JobLevelController(JobService jobService) { 35 | this.jobService = jobService; 36 | } 37 | 38 | /** 39 | * 获取职称级别信息集合 40 | * 41 | * @return 职称级别信息集合 42 | */ 43 | @GetMapping("") 44 | @PreAuthorize("hasAnyAuthority('ADMIN')") 45 | public List getJobLevelInfoList() { 46 | logger.debug("getJobLevelInfoList::获取职称级别集合"); 47 | return jobService.getAllJobLevelInfoList("getAllJobLevelInfoList"); 48 | } 49 | 50 | /** 51 | * 根据职称级别ID删除职称级别 52 | * 53 | * @param id 职称级别ID 54 | * @return JSON格式服务器消息 55 | */ 56 | @GetMapping("/del/{id}") 57 | @PreAuthorize("hasAnyAuthority('ADMIN')") 58 | public ServerMessage delJobLevelInfoByID(@PathVariable("id") String id) { 59 | logger.debug("delJobTitleInfoByID::要删除的ID->" + id); 60 | ServerMessage serverMessage = new ServerMessage(); 61 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 62 | serverMessage.setMsg("成功删除ID为" + id + "的职称级别"); 63 | serverMessage.setUrl("/jobLevel/del/" + id); 64 | try { 65 | jobService.delJobLevelByID(id, "getAllJobLevelInfoList"); 66 | } catch (NoSuchIdException e) { 67 | serverMessage.setCode(ServerMessage.NOT_FIND); 68 | serverMessage.setMsg("删除失败->" + e.getMessage()); 69 | } 70 | return serverMessage; 71 | } 72 | 73 | /** 74 | * 添加职称级别 75 | * 76 | * @param name 职称级别 77 | * @return JSON服务器消息 78 | */ 79 | @GetMapping("/add/{name}") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public ServerMessage addJobLevelInfo(@PathVariable("name") String name) { 82 | JobLevel jobLevel = new JobLevel(UUID.randomUUID().toString().replace("-", ""), name); 83 | logger.debug("addJobLevelInfo::要添加的职称级别->" + jobLevel); 84 | ServerMessage serverMessage = new ServerMessage(); 85 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 86 | serverMessage.setMsg("添加成功"); 87 | serverMessage.setUrl("/jobLevel/add/" + name); 88 | try { 89 | jobService.addOrModifyJobLevelInfo(jobLevel, "getAllJobLevelInfoList"); 90 | } catch (NullParameterException e) { 91 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 92 | serverMessage.setMsg("添加失败->" + e.getMessage()); 93 | } 94 | return serverMessage; 95 | } 96 | 97 | /** 98 | * 修改职称级别 99 | * 100 | * @param jobLevel 职称级别 101 | * @return JSON服务器消息 102 | */ 103 | @GetMapping("/modify") 104 | @PreAuthorize("hasAnyAuthority('ADMIN')") 105 | public ServerMessage modifyJobLevelInfo(JobLevel jobLevel) { 106 | ServerMessage serverMessage = new ServerMessage(); 107 | serverMessage.setUrl("/jobLevel/modify"); 108 | if (StringUtils.isBlank(jobLevel.getId())) { 109 | serverMessage.setCode(ServerMessage.NOT_FIND); 110 | serverMessage.setMsg("修改失败->ID为空"); 111 | return serverMessage; 112 | } 113 | logger.debug("modifyJobLevelInfo::要修改的ID为" + jobLevel.getId()); 114 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 115 | serverMessage.setMsg("修改成功"); 116 | try { 117 | jobService.addOrModifyJobLevelInfo(jobLevel, "getAllJobLevelInfoList"); 118 | } catch (NullParameterException e) { 119 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 120 | serverMessage.setMsg("修改失败->" + e.getMessage()); 121 | } 122 | return serverMessage; 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/controller/job/JobTitleController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.job; 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.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import top.itning.hrms.entity.ServerMessage; 13 | import top.itning.hrms.entity.job.JobTitle; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.JobService; 17 | 18 | import java.util.List; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 社会职称名控制器 23 | * 24 | * @author Ning 25 | */ 26 | @RestController 27 | @RequestMapping("/jobTitle") 28 | public class JobTitleController { 29 | private static final Logger logger = LoggerFactory.getLogger(JobTitleController.class); 30 | 31 | private final JobService jobService; 32 | 33 | @Autowired 34 | public JobTitleController(JobService jobService) { 35 | this.jobService = jobService; 36 | } 37 | 38 | /** 39 | * 获取社会职称信息集合 40 | * 41 | * @return 社会职称信息集合 42 | */ 43 | @GetMapping("") 44 | @PreAuthorize("hasAnyAuthority('ADMIN')") 45 | public List getJobTitleInfoList() { 46 | logger.debug("getJobTitleInfoList::获取社会职称信息集合"); 47 | return jobService.getAllJobTitleInfoList("getAllJobTitleInfoList"); 48 | } 49 | 50 | /** 51 | * 根据社会职称ID删除社会职称 52 | * 53 | * @param id 社会职称ID 54 | * @return JSON格式服务器消息 55 | */ 56 | @GetMapping("/del/{id}") 57 | @PreAuthorize("hasAnyAuthority('ADMIN')") 58 | public ServerMessage delJobTitleInfoByID(@PathVariable("id") String id) { 59 | logger.debug("delJobTitleInfoByID::要删除的ID->" + id); 60 | ServerMessage serverMessage = new ServerMessage(); 61 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 62 | serverMessage.setMsg("成功删除ID为" + id + "的社会职称"); 63 | serverMessage.setUrl("/jobTitle/del/" + id); 64 | try { 65 | jobService.delJobTitleInfoByID(id, "getAllJobTitleInfoList"); 66 | } catch (NoSuchIdException e) { 67 | serverMessage.setCode(ServerMessage.NOT_FIND); 68 | serverMessage.setMsg("删除失败->" + e.getMessage()); 69 | } 70 | return serverMessage; 71 | } 72 | 73 | /** 74 | * 添加社会职称 75 | * 76 | * @param name 社会职称名 77 | * @return JSON服务器消息 78 | */ 79 | @GetMapping("/add/{name}") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public ServerMessage addJobTitleInfo(@PathVariable("name") String name) { 82 | JobTitle jobTitle = new JobTitle(UUID.randomUUID().toString().replace("-", ""), name); 83 | logger.debug("addJobTitleInfo::要添加的社会职称->" + jobTitle); 84 | ServerMessage serverMessage = new ServerMessage(); 85 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 86 | serverMessage.setMsg("添加成功"); 87 | serverMessage.setUrl("/jobTitle/add/" + name); 88 | try { 89 | jobService.addOrModifyJobTitleInfo(jobTitle, "getAllJobTitleInfoList"); 90 | } catch (NullParameterException e) { 91 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 92 | serverMessage.setMsg("添加失败->" + e.getMessage()); 93 | } 94 | return serverMessage; 95 | } 96 | 97 | /** 98 | * 修改社会职称 99 | * 100 | * @param jobTitle 社会职称 101 | * @return JSON服务器消息 102 | */ 103 | @GetMapping("/modify") 104 | @PreAuthorize("hasAnyAuthority('ADMIN')") 105 | public ServerMessage modifyJobTitleInfo(JobTitle jobTitle) { 106 | ServerMessage serverMessage = new ServerMessage(); 107 | serverMessage.setUrl("/jobTitle/modify"); 108 | if (StringUtils.isBlank(jobTitle.getId())) { 109 | serverMessage.setCode(ServerMessage.NOT_FIND); 110 | serverMessage.setMsg("修改失败->ID为空"); 111 | return serverMessage; 112 | } 113 | logger.debug("modifyJobTitleInfo::要修改的ID为" + jobTitle.getId()); 114 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 115 | serverMessage.setMsg("修改成功"); 116 | try { 117 | jobService.addOrModifyJobTitleInfo(jobTitle, "getAllJobTitleInfoList"); 118 | } catch (NullParameterException e) { 119 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 120 | serverMessage.setMsg("修改失败->" + e.getMessage()); 121 | } 122 | return serverMessage; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/controller/post/PostTitleController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.post; 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.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import top.itning.hrms.entity.ServerMessage; 13 | import top.itning.hrms.entity.post.PositionTitle; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.PostService; 17 | 18 | import java.util.List; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 岗位名称控制器 23 | * 24 | * @author Ning 25 | */ 26 | @RestController 27 | @RequestMapping("/postTitle") 28 | public class PostTitleController { 29 | private static final Logger logger = LoggerFactory.getLogger(PostTitleController.class); 30 | 31 | private final PostService postService; 32 | 33 | @Autowired 34 | public PostTitleController(PostService postService) { 35 | this.postService = postService; 36 | } 37 | 38 | /** 39 | * 获取岗位名称信息集合 40 | * 41 | * @return 岗位名称信息集合 42 | */ 43 | @GetMapping("") 44 | @PreAuthorize("hasAnyAuthority('ADMIN')") 45 | public List getPostTitleInfoList() { 46 | logger.debug("getPostTitleInfoList::获取岗位名称集合"); 47 | return postService.getAllPositionTitleInfoList("getAllPositionTitleInfoList"); 48 | } 49 | 50 | /** 51 | * 根据岗位名称ID删除岗位名称 52 | * 53 | * @param id 岗位名称ID 54 | * @return JSON格式服务器消息 55 | */ 56 | @GetMapping("/del/{id}") 57 | @PreAuthorize("hasAnyAuthority('ADMIN')") 58 | public ServerMessage delPostTitleInfoByID(@PathVariable("id") String id) { 59 | logger.debug("delPostTitleInfoByID::要删除的ID->" + id); 60 | ServerMessage serverMessage = new ServerMessage(); 61 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 62 | serverMessage.setMsg("成功删除ID为" + id + "的岗位名称"); 63 | serverMessage.setUrl("/postTitle/del/" + id); 64 | try { 65 | postService.delPositionTitleInfoByID(id, "getAllPositionTitleInfoList"); 66 | } catch (NoSuchIdException e) { 67 | serverMessage.setCode(ServerMessage.NOT_FIND); 68 | serverMessage.setMsg("删除失败->" + e.getMessage()); 69 | } 70 | return serverMessage; 71 | } 72 | 73 | /** 74 | * 添加岗位名称信息 75 | * 76 | * @param name 岗位名称 77 | * @return JSON格式服务器消息 78 | */ 79 | @GetMapping("/add/{name}") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public ServerMessage addPostTitleInfo(@PathVariable("name") String name) { 82 | PositionTitle positionTitle = new PositionTitle(UUID.randomUUID().toString().replace("-", ""), name); 83 | logger.debug("addPostTitleInfo::要添加的岗位实体->" + positionTitle); 84 | ServerMessage serverMessage = new ServerMessage(); 85 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 86 | serverMessage.setMsg("添加成功"); 87 | serverMessage.setUrl("/postTitle/add/" + name); 88 | try { 89 | postService.addOrModifyPositionTitleInfo(positionTitle, "getAllPositionTitleInfoList"); 90 | } catch (NullParameterException e) { 91 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 92 | serverMessage.setMsg("添加失败->" + e.getMessage()); 93 | } 94 | return serverMessage; 95 | } 96 | 97 | /** 98 | * 修改岗位名称 99 | * 100 | * @param positionTitle 岗位名称 101 | * @return JSON服务器消息 102 | */ 103 | @GetMapping("/modify") 104 | @PreAuthorize("hasAnyAuthority('ADMIN')") 105 | public ServerMessage modifyPostTitleInfo(PositionTitle positionTitle) { 106 | ServerMessage serverMessage = new ServerMessage(); 107 | serverMessage.setUrl("/postTitle/modify"); 108 | if (StringUtils.isBlank(positionTitle.getId())) { 109 | serverMessage.setCode(ServerMessage.NOT_FIND); 110 | serverMessage.setMsg("修改失败->ID为空"); 111 | return serverMessage; 112 | } 113 | logger.debug("modifyPostTitleInfo::要修改的ID为" + positionTitle.getId()); 114 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 115 | serverMessage.setMsg("修改成功"); 116 | try { 117 | postService.addOrModifyPositionTitleInfo(positionTitle, "getAllPositionTitleInfoList"); 118 | } catch (NullParameterException e) { 119 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 120 | serverMessage.setMsg("修改失败->" + e.getMessage()); 121 | } 122 | return serverMessage; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/controller/department/DepartmentController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.department; 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.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import top.itning.hrms.entity.ServerMessage; 13 | import top.itning.hrms.entity.department.Department; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.DepartmentService; 17 | 18 | import java.util.List; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 部门控制器 23 | * 24 | * @author Ning 25 | */ 26 | @RestController 27 | @RequestMapping("/department") 28 | public class DepartmentController { 29 | private static final Logger logger = LoggerFactory.getLogger(DepartmentController.class); 30 | 31 | private final DepartmentService departmentService; 32 | 33 | @Autowired 34 | public DepartmentController(DepartmentService departmentService) { 35 | this.departmentService = departmentService; 36 | } 37 | 38 | /** 39 | * 获取部门信息集合 40 | * 41 | * @return 部门信息集合 42 | */ 43 | @GetMapping("") 44 | @PreAuthorize("hasAnyAuthority('ADMIN')") 45 | public List getDepartmentList() { 46 | logger.debug("getEmploymentFormList::获取用工形式集合"); 47 | return departmentService.getAllDepartmentInfoList("getAllDepartmentInfoList"); 48 | } 49 | 50 | /** 51 | * 根据部门ID删除部门 52 | * 53 | * @param id 部门ID 54 | * @return JSON格式服务器消息 55 | */ 56 | @GetMapping("/del/{id}") 57 | @PreAuthorize("hasAnyAuthority('ADMIN')") 58 | public ServerMessage delDepartmentInfoByID(@PathVariable("id") String id) { 59 | logger.debug("delDepartmentInfoByID::要删除的ID->" + id); 60 | ServerMessage serverMessage = new ServerMessage(); 61 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 62 | serverMessage.setMsg("成功删除ID为" + id + "的部门"); 63 | serverMessage.setUrl("/department/del/" + id); 64 | try { 65 | departmentService.delDepartmentByID(id, "getAllDepartmentInfoList"); 66 | } catch (NoSuchIdException e) { 67 | serverMessage.setCode(ServerMessage.NOT_FIND); 68 | serverMessage.setMsg("删除失败->" + e.getMessage()); 69 | } 70 | return serverMessage; 71 | } 72 | 73 | /** 74 | * 添加部门 75 | * 76 | * @param name 部门 77 | * @return JSON服务器消息 78 | */ 79 | @GetMapping("/add/{name}") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public ServerMessage addDepartmentInfo(@PathVariable("name") String name) { 82 | Department department = new Department(UUID.randomUUID().toString().replace("-", ""), name, null); 83 | logger.debug("addEmploymentFormInfo::要添加的部门->" + department); 84 | ServerMessage serverMessage = new ServerMessage(); 85 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 86 | serverMessage.setMsg("添加成功"); 87 | serverMessage.setUrl("/department/add/" + name); 88 | try { 89 | departmentService.addOrModifyDepartmentInfo(department, "getAllDepartmentInfoList"); 90 | } catch (NullParameterException e) { 91 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 92 | serverMessage.setMsg("添加失败->" + e.getMessage()); 93 | } 94 | return serverMessage; 95 | } 96 | 97 | /** 98 | * 修改部门 99 | * 100 | * @param department 部门 101 | * @return JSON服务器消息 102 | */ 103 | @GetMapping("/modify") 104 | @PreAuthorize("hasAnyAuthority('ADMIN')") 105 | public ServerMessage modifyDepartmentInfo(Department department) { 106 | ServerMessage serverMessage = new ServerMessage(); 107 | serverMessage.setUrl("/department/modify"); 108 | if (StringUtils.isBlank(department.getId())) { 109 | serverMessage.setCode(ServerMessage.NOT_FIND); 110 | serverMessage.setMsg("修改失败->ID为空"); 111 | return serverMessage; 112 | } 113 | logger.debug("modifyDepartmentInfo::要修改的ID为" + department.getId()); 114 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 115 | serverMessage.setMsg("修改成功"); 116 | try { 117 | departmentService.addOrModifyDepartmentInfo(department, "getAllDepartmentInfoList"); 118 | } catch (NullParameterException e) { 119 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 120 | serverMessage.setMsg("修改失败->" + e.getMessage()); 121 | } 122 | return serverMessage; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/util/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.util; 2 | 3 | import org.apache.commons.lang3.math.NumberUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.lang.reflect.Field; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /** 12 | * 对象工具类 13 | * 14 | * @author Ning 15 | */ 16 | public class ObjectUtils { 17 | private static final Logger logger = LoggerFactory.getLogger(ObjectUtils.class); 18 | 19 | private ObjectUtils() { 20 | } 21 | 22 | /** 23 | * 检查对象中属性是否为空 24 | * 25 | * @param obj 要检查的对象 26 | * @param allStr 要检查的属性全为String时为true 27 | * @return 如果有字段为空则返回true, 所有属性都不为空返回false 28 | */ 29 | public static boolean checkObjFieldIsNull(Object obj, boolean allStr) { 30 | for (Field f : obj.getClass().getDeclaredFields()) { 31 | f.setAccessible(true); 32 | logger.debug("checkObjFieldIsNull::检查" + obj.getClass().getSimpleName() + "对象的" + f.getName() + "属性是否为NULL"); 33 | try { 34 | if (f.get(obj) == null) { 35 | return true; 36 | } 37 | } catch (IllegalAccessException e) { 38 | e.printStackTrace(); 39 | } 40 | if (allStr) { 41 | logger.debug("checkObjFieldIsNull::检查" + obj.getClass().getSimpleName() + "对象的" + f.getName() + "属性是否为空字符串"); 42 | try { 43 | if (" ".equals(f.get(obj).toString()) || "".equals(f.get(obj).toString())) { 44 | return true; 45 | } 46 | } catch (IllegalAccessException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | return false; 52 | } 53 | 54 | /** 55 | * 获取集合中 JAVA Bean 的所有int或double属性的累加并返回新的JAVA Bean 56 | * 57 | * @param list 包含T类型的要累加集合 58 | * @param clazz 返回的实例class 59 | * @param JAVA Bean 类型 60 | * @return 累加完成的Java Bean 61 | * @throws IllegalAccessException IllegalAccessException 62 | * @throws InstantiationException InstantiationException 63 | */ 64 | public static T getAllFieldsSum(List list, Class clazz) throws IllegalAccessException, InstantiationException { 65 | logger.info("getAllFieldsSum::方法开始"); 66 | T newInstance = clazz.newInstance(); 67 | logger.info("getAllFieldsSum::已构建新实例"); 68 | Class newInstanceClass = newInstance.getClass(); 69 | logger.info("getAllFieldsSum::已获取clazz的字节码,简单类名->" + newInstanceClass.getSimpleName()); 70 | logger.info("getAllFieldsSum::开始迭代集合,集合大小->" + list.size()); 71 | list.forEach(t -> { 72 | Class tClass = t.getClass(); 73 | logger.info("getAllFieldsSum::已获取字节码"); 74 | Field[] tClassDeclaredFields = tClass.getDeclaredFields(); 75 | Field[] newInstanceClassDeclaredFields = newInstanceClass.getDeclaredFields(); 76 | logger.info("getAllFieldsSum::已获取所有字段"); 77 | logger.info("getAllFieldsSum::开始迭代字段,并累加"); 78 | for (int i = 0; i < tClassDeclaredFields.length; i++) { 79 | tClassDeclaredFields[i].setAccessible(true); 80 | newInstanceClassDeclaredFields[i].setAccessible(true); 81 | try { 82 | logger.info("getAllFieldsSum::字段" + tClassDeclaredFields[i].getName() + "的类型:" + tClassDeclaredFields[i].getAnnotatedType().getType().getTypeName() + "字段值:" + tClassDeclaredFields[i].get(t)); 83 | if (tClassDeclaredFields[i].getAnnotatedType().getType() == int.class) { 84 | logger.info("getAllFieldsSum::Int类型字段->" + tClassDeclaredFields[i].getName()); 85 | newInstanceClassDeclaredFields[i].set(newInstance, newInstanceClassDeclaredFields[i].getInt(newInstance) + tClassDeclaredFields[i].getInt(t)); 86 | } else if (tClassDeclaredFields[i].getAnnotatedType().getType() == double.class) { 87 | logger.info("getAllFieldsSum::Double类型字段->" + tClassDeclaredFields[i].getName()); 88 | newInstanceClassDeclaredFields[i].set(newInstance, newInstanceClassDeclaredFields[i].getDouble(newInstance) + tClassDeclaredFields[i].getDouble(t)); 89 | } 90 | } catch (IllegalAccessException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | logger.info("getAllFieldsSum::结束迭代字段"); 95 | }); 96 | logger.info("getAllFieldsSum::结束迭代集合"); 97 | logger.info("getAllFieldsSum::方法结束"); 98 | return newInstance; 99 | } 100 | 101 | /** 102 | * 检查字段是否全是数字 103 | * 104 | * @param fields 字段 105 | * @return 所有都是返回真, 否则返回假 106 | */ 107 | public static boolean checkAllFieldsIsNumber(String... fields) { 108 | return Arrays.stream(fields).filter(NumberUtils::isDigits).count() == fields.length; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /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/java/top/itning/hrms/controller/department/GrassrootController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.department; 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.web.bind.annotation.*; 8 | import top.itning.hrms.entity.ServerMessage; 9 | import top.itning.hrms.entity.department.Grassroot; 10 | import top.itning.hrms.exception.defaults.NoSuchIdException; 11 | import top.itning.hrms.exception.defaults.NullParameterException; 12 | import top.itning.hrms.exception.json.JsonException; 13 | import top.itning.hrms.service.GrassrootService; 14 | 15 | import java.util.List; 16 | import java.util.UUID; 17 | 18 | /** 19 | * 基层单位控制器 20 | * 21 | * @author Ning 22 | */ 23 | @RestController 24 | @RequestMapping("/grassroot") 25 | public class GrassrootController { 26 | private static final Logger logger = LoggerFactory.getLogger(GrassrootController.class); 27 | 28 | private final GrassrootService grassrootService; 29 | 30 | @Autowired 31 | public GrassrootController(GrassrootService grassrootService) { 32 | this.grassrootService = grassrootService; 33 | } 34 | 35 | /** 36 | * 根据部门ID获取基层单位信息集合 37 | * 38 | * @param id 部门ID 39 | * @return 基层单位信息集合 40 | * @throws JsonException 如果该部门ID不存在则抛出该异常 41 | */ 42 | @GetMapping("/show/{id}") 43 | @PreAuthorize("hasAnyAuthority('ADMIN')") 44 | @ResponseBody 45 | public List getGrassrootListByDepartmentID(@PathVariable("id") String id) throws JsonException { 46 | logger.debug("getGrassrootListByDepartmentID::部门ID为->" + id); 47 | try { 48 | return grassrootService.getGrassrootListByDepartment(id); 49 | } catch (NoSuchIdException e) { 50 | throw new JsonException(e.getMessage(), ServerMessage.NOT_FIND); 51 | } 52 | } 53 | 54 | /** 55 | * 修改基层单位信息 56 | * 57 | * @param grassroot 基层单位 58 | * @param did 部门ID,用于删除缓存 59 | * @return JSON服务器消息 60 | */ 61 | @GetMapping("/modify") 62 | @PreAuthorize("hasAnyAuthority('ADMIN')") 63 | @ResponseBody 64 | public ServerMessage modifyGrassroot(Grassroot grassroot, String did) { 65 | ServerMessage serverMessage = new ServerMessage(); 66 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 67 | serverMessage.setMsg("修改成功"); 68 | serverMessage.setUrl("/grassroot/modify?id=" + grassroot.getId() + "&name=" + grassroot.getName()); 69 | logger.debug("modifyGrassrootByDepartmentID::要修改的基层单位->" + grassroot); 70 | try { 71 | grassrootService.modifyGrassroot(grassroot, did); 72 | } catch (NullParameterException e) { 73 | serverMessage.setCode(ServerMessage.NOT_FIND); 74 | serverMessage.setMsg("修改失败:" + e.getMessage()); 75 | } 76 | return serverMessage; 77 | } 78 | 79 | /** 80 | * 根据部门ID添加基层单位信息 81 | * 82 | * @param did 部门ID 83 | * @param grassroot 基层单位 84 | * @return JSON服务器消息 85 | */ 86 | @GetMapping("/add") 87 | @PreAuthorize("hasAnyAuthority('ADMIN')") 88 | @ResponseBody 89 | public ServerMessage addmodifyGrassrootByDepartmentID(String did, Grassroot grassroot) { 90 | grassroot.setId(UUID.randomUUID().toString().replace("-", "")); 91 | ServerMessage serverMessage = new ServerMessage(); 92 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 93 | serverMessage.setMsg("添加成功"); 94 | serverMessage.setUrl("/grassroot/add?did=" + did + "&name=" + grassroot.getName()); 95 | logger.debug("addmodifyGrassrootByDepartmentID::部门ID->" + did + " 基层单位信息" + grassroot); 96 | try { 97 | grassrootService.addGrassrootByDepartmentID(did, grassroot); 98 | } catch (NoSuchIdException | NullParameterException e) { 99 | serverMessage.setCode(ServerMessage.NOT_FIND); 100 | serverMessage.setMsg("添加失败:" + e.getMessage()); 101 | } 102 | return serverMessage; 103 | } 104 | 105 | /** 106 | * 根据基层单位ID删除基层单位信息 107 | * 108 | * @param id 基层单位ID 109 | * @param did 部门ID,用于删除缓存 110 | * @return JSON服务器消息 111 | */ 112 | @GetMapping("/del") 113 | @PreAuthorize("hasAnyAuthority('ADMIN')") 114 | @ResponseBody 115 | public ServerMessage delGrassrootByID(String id, String did) { 116 | ServerMessage serverMessage = new ServerMessage(); 117 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 118 | serverMessage.setMsg("删除成功"); 119 | serverMessage.setUrl("/grassroot/del/" + id); 120 | logger.debug("delGrassrootByID::要删除的ID->" + id); 121 | try { 122 | grassrootService.delGrassrootByID(id, did); 123 | } catch (NoSuchIdException e) { 124 | serverMessage.setCode(ServerMessage.NOT_FIND); 125 | serverMessage.setMsg("删除失败:" + e.getMessage()); 126 | } 127 | return serverMessage; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/controller/post/PostCategoryController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.post; 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.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import top.itning.hrms.entity.ServerMessage; 13 | import top.itning.hrms.entity.post.PositionCategory; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.PostService; 17 | 18 | import java.util.List; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 岗位类别控制器 23 | * 24 | * @author Ning 25 | */ 26 | @RestController 27 | @RequestMapping("/postCategory") 28 | public class PostCategoryController { 29 | private static final Logger logger = LoggerFactory.getLogger(PostCategoryController.class); 30 | 31 | private final PostService postService; 32 | 33 | @Autowired 34 | public PostCategoryController(PostService postService) { 35 | this.postService = postService; 36 | } 37 | 38 | /** 39 | * 获取岗位类别信息集合 40 | * 41 | * @return 岗位类别信息集合 42 | */ 43 | @GetMapping("") 44 | @PreAuthorize("hasAnyAuthority('ADMIN')") 45 | public List getPostCategoryInfoList() { 46 | logger.debug("getPostCategoryInfoList::获取岗位名称集合"); 47 | return postService.getAllPositionCategoryInfoList("getAllPositionCategoryInfoList"); 48 | } 49 | 50 | /** 51 | * 根据岗位类别ID删除岗位类别 52 | * 53 | * @param id 岗位类别ID 54 | * @return JSON格式服务器消息 55 | */ 56 | @GetMapping("/del/{id}") 57 | @PreAuthorize("hasAnyAuthority('ADMIN')") 58 | public ServerMessage delPostCategoryInfoByID(@PathVariable("id") String id) { 59 | logger.debug("delPostCategoryInfoByID::要删除的ID->" + id); 60 | ServerMessage serverMessage = new ServerMessage(); 61 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 62 | serverMessage.setMsg("成功删除ID为" + id + "的岗位类别"); 63 | serverMessage.setUrl("/postCategory/del/" + id); 64 | try { 65 | postService.delPositionCategoryInfoByID(id, "getAllPositionCategoryInfoList"); 66 | } catch (NoSuchIdException e) { 67 | serverMessage.setCode(ServerMessage.NOT_FIND); 68 | serverMessage.setMsg("删除失败->" + e.getMessage()); 69 | } 70 | return serverMessage; 71 | } 72 | 73 | /** 74 | * 添加岗位类别 75 | * 76 | * @param name 岗位类别名 77 | * @return JSON服务器消息 78 | */ 79 | @GetMapping("/add/{name}") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public ServerMessage addPostCategoryInfo(@PathVariable("name") String name) { 82 | PositionCategory positionCategory = new PositionCategory(UUID.randomUUID().toString().replace("-", ""), name); 83 | logger.debug("addPostTitleInfo::要添加的岗位实体->" + positionCategory); 84 | ServerMessage serverMessage = new ServerMessage(); 85 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 86 | serverMessage.setMsg("添加成功"); 87 | serverMessage.setUrl("/postCategory/add/" + name); 88 | try { 89 | postService.addOrModifyCategoryTitleInfo(positionCategory, "getAllPositionCategoryInfoList"); 90 | } catch (NullParameterException e) { 91 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 92 | serverMessage.setMsg("添加失败->" + e.getMessage()); 93 | } 94 | return serverMessage; 95 | } 96 | 97 | /** 98 | * 修改岗位类别 99 | * 100 | * @param positionCategory 岗位类别 101 | * @return JSON服务器消息 102 | */ 103 | @GetMapping("/modify") 104 | @PreAuthorize("hasAnyAuthority('ADMIN')") 105 | public ServerMessage modifyPostCategoryInfo(PositionCategory positionCategory) { 106 | ServerMessage serverMessage = new ServerMessage(); 107 | serverMessage.setUrl("/postCategory/modify"); 108 | if (StringUtils.isBlank(positionCategory.getId())) { 109 | serverMessage.setCode(ServerMessage.NOT_FIND); 110 | serverMessage.setMsg("修改失败->ID为空"); 111 | return serverMessage; 112 | } 113 | logger.debug("modifyPostCategoryInfo::要修改的ID为" + positionCategory.getId()); 114 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 115 | serverMessage.setMsg("修改成功"); 116 | try { 117 | postService.addOrModifyCategoryTitleInfo(positionCategory, "getAllPositionCategoryInfoList"); 118 | } catch (NullParameterException e) { 119 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 120 | serverMessage.setMsg("修改失败->" + e.getMessage()); 121 | } 122 | return serverMessage; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/controller/employment/EmploymentFormController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.employment; 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.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | import top.itning.hrms.entity.ServerMessage; 13 | import top.itning.hrms.entity.employment.EmploymentForm; 14 | import top.itning.hrms.exception.defaults.NoSuchIdException; 15 | import top.itning.hrms.exception.defaults.NullParameterException; 16 | import top.itning.hrms.service.EmploymentService; 17 | 18 | import java.util.List; 19 | import java.util.UUID; 20 | 21 | /** 22 | * 用工形式控制器 23 | * 24 | * @author Ning 25 | */ 26 | @RestController 27 | @RequestMapping("/employmentForm") 28 | public class EmploymentFormController { 29 | private static final Logger logger = LoggerFactory.getLogger(EmploymentFormController.class); 30 | 31 | private final EmploymentService employmentService; 32 | 33 | @Autowired 34 | public EmploymentFormController(EmploymentService employmentService) { 35 | this.employmentService = employmentService; 36 | } 37 | 38 | /** 39 | * 获取用工形式信息集合 40 | * 41 | * @return 用工形式信息集合 42 | */ 43 | @GetMapping("") 44 | @PreAuthorize("hasAnyAuthority('ADMIN')") 45 | public List getEmploymentFormList() { 46 | logger.debug("getEmploymentFormList::获取用工形式集合"); 47 | return employmentService.getAllEmploymentFormList("getAllEmploymentFormList"); 48 | } 49 | 50 | /** 51 | * 根据用工形式ID删除用工形式 52 | * 53 | * @param id 用工形式ID 54 | * @return JSON格式服务器消息 55 | */ 56 | @GetMapping("/del/{id}") 57 | @PreAuthorize("hasAnyAuthority('ADMIN')") 58 | public ServerMessage delEmploymentFormInfoByID(@PathVariable("id") String id) { 59 | logger.debug("delEmploymentFormInfoByID::要删除的ID->" + id); 60 | ServerMessage serverMessage = new ServerMessage(); 61 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 62 | serverMessage.setMsg("成功删除ID为" + id + "的用工形式"); 63 | serverMessage.setUrl("/employmentForm/del/" + id); 64 | try { 65 | employmentService.delEmploymentFormByID(id, "getAllEmploymentFormList"); 66 | } catch (NoSuchIdException e) { 67 | serverMessage.setCode(ServerMessage.NOT_FIND); 68 | serverMessage.setMsg("删除失败->" + e.getMessage()); 69 | } 70 | return serverMessage; 71 | } 72 | 73 | /** 74 | * 添加用工形式 75 | * 76 | * @param name 用工形式 77 | * @return JSON服务器消息 78 | */ 79 | @GetMapping("/add/{name}") 80 | @PreAuthorize("hasAnyAuthority('ADMIN')") 81 | public ServerMessage addEmploymentFormInfo(@PathVariable("name") String name) { 82 | EmploymentForm employmentForm = new EmploymentForm(UUID.randomUUID().toString().replace("-", ""), name); 83 | logger.debug("addEmploymentFormInfo::要添加的用工形式->" + employmentForm); 84 | ServerMessage serverMessage = new ServerMessage(); 85 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 86 | serverMessage.setMsg("添加成功"); 87 | serverMessage.setUrl("/employmentForm/add/" + name); 88 | try { 89 | employmentService.addOrModifyEmploymentFormInfo(employmentForm, "getAllEmploymentFormList"); 90 | } catch (NullParameterException e) { 91 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 92 | serverMessage.setMsg("添加失败->" + e.getMessage()); 93 | } 94 | return serverMessage; 95 | } 96 | 97 | /** 98 | * 修改用工形式 99 | * 100 | * @param employmentForm 用工形式 101 | * @return JSON服务器消息 102 | */ 103 | @GetMapping("/modify") 104 | @PreAuthorize("hasAnyAuthority('ADMIN')") 105 | public ServerMessage modifyEmploymentFormInfo(EmploymentForm employmentForm) { 106 | ServerMessage serverMessage = new ServerMessage(); 107 | serverMessage.setUrl("/employmentForm/modify"); 108 | if (StringUtils.isBlank(employmentForm.getId())) { 109 | serverMessage.setCode(ServerMessage.NOT_FIND); 110 | serverMessage.setMsg("修改失败->ID为空"); 111 | return serverMessage; 112 | } 113 | logger.debug("modifyEmploymentFormInfo::要修改的ID为" + employmentForm.getId()); 114 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 115 | serverMessage.setMsg("修改成功"); 116 | try { 117 | employmentService.addOrModifyEmploymentFormInfo(employmentForm, "getAllEmploymentFormList"); 118 | } catch (NullParameterException e) { 119 | serverMessage.setCode(ServerMessage.SERVICE_ERROR); 120 | serverMessage.setMsg("修改失败->" + e.getMessage()); 121 | } 122 | return serverMessage; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/util/StaffUtils.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.util; 2 | 3 | import org.apache.commons.lang3.ObjectUtils; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.apache.commons.lang3.math.NumberUtils; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import top.itning.hrms.entity.Staff; 9 | import top.itning.hrms.exception.defaults.IllegalParametersException; 10 | 11 | import java.text.DecimalFormat; 12 | import java.text.ParseException; 13 | import java.text.SimpleDateFormat; 14 | import java.util.*; 15 | import java.util.zip.DataFormatException; 16 | 17 | /** 18 | * 与职工有关的工具类 19 | * 20 | * @author Ning 21 | */ 22 | public class StaffUtils { 23 | private static final Logger logger = LoggerFactory.getLogger(StaffUtils.class); 24 | 25 | /** 26 | * 身份证号位数 27 | */ 28 | private static final int ID_NUM_LENGTH = 18; 29 | 30 | /** 31 | * 身份证号结尾字符X 32 | */ 33 | private static final String ID_END_CHAR = "X"; 34 | 35 | private StaffUtils() { 36 | } 37 | 38 | /** 39 | * 获取校龄/工龄 40 | *

当前年-来校年+((来校月/当前月)/12)(保留一位小数) 41 | * 42 | * @param comeDate 来校日期/工龄起始日期 43 | * @return 校龄/工龄 44 | * @throws IllegalParametersException 非法参数异常 45 | */ 46 | public static String getFormatTime(Date comeDate) throws IllegalParametersException { 47 | Date nowData = new Date(); 48 | if (nowData.before(comeDate)) { 49 | throw new IllegalParametersException("来校日期不能在当前日期之后,请检查"); 50 | } 51 | Calendar calendar = Calendar.getInstance(); 52 | calendar.setTime(comeDate); 53 | int comeYear = calendar.get(Calendar.YEAR); 54 | double comeMonth = calendar.get(Calendar.MONTH) + 1; 55 | Calendar calendar1 = Calendar.getInstance(); 56 | calendar1.setTime(nowData); 57 | int nowYear = calendar1.get(Calendar.YEAR); 58 | double nowMonth = calendar1.get(Calendar.MONTH) + 1; 59 | return new DecimalFormat("0.0").format(nowYear - comeYear + ((comeMonth / nowMonth) / 12)); 60 | } 61 | 62 | /** 63 | * 获取应发额数 64 | * 65 | * @param moneys 钱数 66 | * @return 应发额 67 | * @throws IllegalParametersException 参数不正确的时候抛出该异常 68 | */ 69 | public static String sbm(String... moneys) throws IllegalParametersException { 70 | if (!ObjectUtils.allNotNull((Object) moneys)) { 71 | return "0"; 72 | } 73 | moneys = Arrays.stream(moneys).filter(s -> s != null).toArray(String[]::new); 74 | System.out.println(Arrays.toString(moneys)); 75 | if (Arrays.stream(moneys).filter(StringUtils::isNumeric).count() != moneys.length) { 76 | logger.warn("sbm::参数并非全部为数字->" + Arrays.toString(moneys)); 77 | throw new IllegalParametersException("参数并非全部为数字"); 78 | } 79 | int totalMoney = 0; 80 | for (String money : moneys) { 81 | totalMoney += Integer.parseInt(money); 82 | } 83 | return String.valueOf(totalMoney); 84 | } 85 | 86 | /** 87 | * 解析身份证号 88 | * 89 | * @param nid 身份证号 90 | * @return 年龄, 性别, 出生日期集合 91 | */ 92 | public static Map parserId(String nid) throws DataFormatException { 93 | if (!StringUtils.isNumeric(nid.substring(0, nid.length() - 1))) { 94 | logger.warn("addOrModifyStaffInfo::nid不是纯数字->" + nid); 95 | throw new NumberFormatException("身份证号码不是纯数字,请检查!"); 96 | } 97 | if (!NumberUtils.isDigits(nid) && !StringUtils.endsWith(StringUtils.upperCase(nid), ID_END_CHAR)) { 98 | logger.warn("addOrModifyStaffInfo::nid结尾非大写X->" + nid); 99 | throw new NumberFormatException("身份证号码nid结尾非大写X,请检查!"); 100 | } 101 | //判断身份证号长度 102 | if (nid.length() != ID_NUM_LENGTH) { 103 | logger.warn("addOrModifyStaffInfo::nid位数为" + nid.length() + "与" + ID_NUM_LENGTH + "不匹配"); 104 | throw new NumberFormatException("您输入的身份证号码位数为" + nid.length() + "位,不是" + ID_NUM_LENGTH + "位,请检查"); 105 | } 106 | Map map = new HashMap<>(3); 107 | try { 108 | //根据身份证号设置出生日期 109 | map.put("birthday", new SimpleDateFormat("yyyyMMdd").parse(nid.substring(6, 14))); 110 | } catch (ParseException e) { 111 | logger.warn("addOrModifyStaffInfo::出生日期格式化出错,日期->" + nid.substring(6, 14) + "异常信息->" + e.getMessage()); 112 | throw new DataFormatException("出生日期格式化出错,检查日期是否有误"); 113 | } 114 | //根据身份证号设置性别 115 | map.put("sex", Integer.parseInt(nid.substring(16, 17)) % 2 != 0); 116 | //根据身份证号设置年龄 117 | map.put("age", String.valueOf(Calendar.getInstance().get(Calendar.YEAR) - Integer.parseInt(nid.substring(6, 10)))); 118 | return map; 119 | } 120 | 121 | /** 122 | * 简单设置性别年龄生日 123 | * 124 | * @param staff 职工实体 125 | * @throws DataFormatException 日期格式化异常 126 | */ 127 | public static void simpleSetStaffFileds(Staff staff) { 128 | Map parserId = null; 129 | try { 130 | parserId = parserId(staff.getNid()); 131 | } catch (DataFormatException e) { 132 | e.printStackTrace(); 133 | } 134 | staff.setBirthday((Date) parserId.get("birthday")); 135 | //根据身份证号设置性别 136 | staff.setSex((Boolean) parserId.get("sex")); 137 | //根据身份证号设置年龄 138 | staff.setAge((String) parserId.get("age")); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | top.itning 7 | hrms 8 | 1.0.2-RELEASE 9 | jar 10 | 11 | hrms 12 | Human Resource Manage System 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 | 1.8 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 | org.projectlombok 105 | lombok 106 | 1.16.18 107 | provided 108 | 109 | 110 | 111 | org.springframework.boot 112 | spring-boot-configuration-processor 113 | true 114 | 115 | 116 | 117 | org.springframework.boot 118 | spring-boot-devtools 119 | true 120 | 121 | 122 | 123 | org.springframework.boot 124 | spring-boot-starter-mail 125 | 126 | 127 | 128 | 129 | 130 | 131 | org.springframework.boot 132 | spring-boot-maven-plugin 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /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/hrms/controller/staff/StaffWageController.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.controller.staff; 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.access.prepost.PreAuthorize; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.ui.Model; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | import top.itning.hrms.entity.ServerMessage; 15 | import top.itning.hrms.entity.search.SearchWage; 16 | import top.itning.hrms.exception.defaults.NoSuchIdException; 17 | import top.itning.hrms.exception.json.JsonException; 18 | import top.itning.hrms.service.DepartmentService; 19 | import top.itning.hrms.service.JobService; 20 | import top.itning.hrms.service.WageService; 21 | 22 | import javax.servlet.ServletOutputStream; 23 | import javax.servlet.http.HttpServletResponse; 24 | import java.io.IOException; 25 | import java.text.SimpleDateFormat; 26 | import java.util.Date; 27 | import java.util.Map; 28 | 29 | /** 30 | * 职工工资控制器 31 | * 32 | * @author Ning 33 | */ 34 | @Controller 35 | @RequestMapping("/staffWage") 36 | public class StaffWageController { 37 | private static final Logger logger = LoggerFactory.getLogger(StaffWageController.class); 38 | 39 | private final DepartmentService departmentService; 40 | 41 | private final JobService jobService; 42 | 43 | private final WageService wageService; 44 | 45 | @Autowired 46 | public StaffWageController(DepartmentService departmentService, JobService jobService, WageService wageService) { 47 | this.departmentService = departmentService; 48 | this.jobService = jobService; 49 | this.wageService = wageService; 50 | } 51 | 52 | /** 53 | * 添加职工工资信息页面 54 | * @param model 模型 55 | * @return addWage.html 56 | */ 57 | @GetMapping("/add") 58 | @PreAuthorize("hasAnyAuthority('ADMIN')") 59 | public String addWage(Model model) { 60 | model.addAttribute("departmentList", departmentService.getAllDepartmentInfoList("getAllDepartmentInfo")); 61 | return "addWage"; 62 | } 63 | 64 | /** 65 | * 搜索页面 66 | * 67 | * @param model 模型 68 | * @return searchWage.html 69 | */ 70 | @GetMapping("/search") 71 | public String searchWage(Model model) { 72 | model.addAttribute("departmentList", departmentService.getAllDepartmentInfoList("getAllDepartmentInfo")); 73 | model.addAttribute("jobTitleInfoList", jobService.getAllJobTitleInfoList("getAllJobTitleInfoList")); 74 | model.addAttribute("wageYears", wageService.getWageYear()); 75 | return "searchWage"; 76 | } 77 | 78 | /** 79 | * 搜索职工工资信息 80 | * 81 | * @param searchWage 搜索工资实体 82 | * @return Map集合 83 | * @throws JsonException JsonException 84 | */ 85 | @GetMapping("/searchWage") 86 | @ResponseBody 87 | public Map searchWage(SearchWage searchWage) throws JsonException { 88 | logger.debug("searchWage::搜索条件->" + searchWage); 89 | return wageService.searchWage(searchWage); 90 | } 91 | 92 | /** 93 | * 根据ID下载职工工资 94 | * 95 | * @param id ID 96 | * @param response HttpServletResponse 97 | * @throws IllegalAccessException IllegalAccessException 98 | * @throws NoSuchIdException 如果工资ID不存在则抛出该异常 99 | * @throws IOException IOException 100 | * @throws InstantiationException InstantiationException 101 | */ 102 | @GetMapping("/down") 103 | public void downStaffWageInfoByID(String id, HttpServletResponse response) throws IllegalAccessException, NoSuchIdException, IOException, InstantiationException { 104 | logger.debug("downStaffWageInfoByID::要下载的工资ID->" + id); 105 | String[] idArray = StringUtils.split(id, "-"); 106 | String nowTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); 107 | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 108 | response.setHeader("Content-Disposition", "attachment;filename=" + new String(("职工工资信息" + nowTime + ".xlsx").getBytes(), "ISO-8859-1")); 109 | ServletOutputStream outputStream = response.getOutputStream(); 110 | logger.debug("downStaffWageInfoByID::outputStream.isReady->" + outputStream.isReady()); 111 | wageService.downWageInfoByID(outputStream, idArray); 112 | outputStream.flush(); 113 | outputStream.close(); 114 | logger.debug("downStaffWageInfoByID::outputStream close"); 115 | } 116 | 117 | /** 118 | * 根据工资ID删除职工信息 119 | * 120 | * @param id 工资ID 121 | * @return JSON服务器消息 122 | */ 123 | @GetMapping("/del/{id}") 124 | @PreAuthorize("hasAnyAuthority('ADMIN')") 125 | @ResponseBody 126 | public ServerMessage delStaffWageInfoByID(@PathVariable("id") String id) { 127 | ServerMessage serverMessage = new ServerMessage(); 128 | serverMessage.setCode(ServerMessage.SUCCESS_CODE); 129 | serverMessage.setMsg("删除ID为" + id + "的工资信息成功"); 130 | serverMessage.setUrl("/staffWage/del/" + id); 131 | try { 132 | wageService.delWageInfoByID(id); 133 | } catch (NoSuchIdException e) { 134 | serverMessage.setCode(ServerMessage.NOT_FIND); 135 | serverMessage.setMsg(e.getMessage()); 136 | } 137 | return serverMessage; 138 | } 139 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/hrms/entity/WageEmail.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * 工资信息邮件实体 11 | * 12 | * @author wangn 13 | */ 14 | @Data 15 | public class WageEmail implements Serializable { 16 | /** 17 | * Email 18 | */ 19 | private String email; 20 | /** 21 | * 姓名 22 | */ 23 | private String name; 24 | /** 25 | * 岗位工资 26 | */ 27 | private int wage; 28 | /** 29 | * 绩效工资 30 | */ 31 | private int performancePay; 32 | /** 33 | * 职务津贴 34 | */ 35 | private Integer dutyAllowance; 36 | /** 37 | * 岗位超时补助 38 | */ 39 | private Integer grants; 40 | /** 41 | * 小计1 42 | */ 43 | private int total1; 44 | /** 45 | * 补款 46 | */ 47 | private int replenishment; 48 | /** 49 | * 扣款 50 | */ 51 | private int chargeBack; 52 | /** 53 | * 小计2 54 | */ 55 | private int total2; 56 | /** 57 | * 教学奖金 58 | */ 59 | private int teachingBonus; 60 | /** 61 | * 硕士津贴 62 | */ 63 | private Integer mAllowance; 64 | /** 65 | * 电话补助 66 | */ 67 | private Integer pSubsidies; 68 | /** 69 | * 带学生津贴 70 | */ 71 | private int studentAllowance; 72 | /** 73 | * 奖金 74 | */ 75 | private int bonus; 76 | /** 77 | * 校拨津贴 78 | */ 79 | private int schoolGrant; 80 | /** 81 | * 学生处发放8小时以外补助 82 | */ 83 | private int time8; 84 | /** 85 | * 加班补助 86 | */ 87 | private int overtimeAssistance; 88 | /** 89 | * 值班补助 90 | */ 91 | private int onDutySubsidies; 92 | /** 93 | * 其他补助 94 | */ 95 | private int otherBenefits; 96 | /** 97 | * 补助小计 98 | */ 99 | private int totalBenefits; 100 | /** 101 | * 工资合计 102 | */ 103 | private int total; 104 | /** 105 | * 代扣养老保险 106 | */ 107 | private int pensionInsurance; 108 | /** 109 | * 代扣医疗保险 110 | */ 111 | private int medicalInsurance; 112 | /** 113 | * 代扣失业保险 114 | */ 115 | private int unemploymentInsurance; 116 | /** 117 | * 代扣住房公积金 118 | */ 119 | private int housingFund; 120 | /** 121 | * 应发额 122 | */ 123 | private int shouldMade; 124 | /** 125 | * 代扣款 126 | */ 127 | private int withholding; 128 | 129 | /** 130 | * 获取所有属性的Map 131 | * 132 | * @return map 133 | */ 134 | public Map getAllFiledMap() { 135 | Map map = new HashMap<>(27); 136 | map.put("name", name); 137 | map.put("wage", wage); 138 | map.put("performancePay", performancePay); 139 | map.put("dutyAllowance", dutyAllowance); 140 | map.put("grants", grants); 141 | map.put("total1", total1); 142 | map.put("replenishment", replenishment); 143 | map.put("chargeBack", chargeBack); 144 | map.put("total2", total2); 145 | map.put("teachingBonus", teachingBonus); 146 | map.put("mAllowance", mAllowance); 147 | map.put("pSubsidies", pSubsidies); 148 | map.put("studentAllowance", studentAllowance); 149 | map.put("bonus", bonus); 150 | map.put("schoolGrant", schoolGrant); 151 | map.put("time8", time8); 152 | map.put("overtimeAssistance", overtimeAssistance); 153 | map.put("onDutySubsidies", onDutySubsidies); 154 | map.put("otherBenefits", otherBenefits); 155 | map.put("totalBenefits", totalBenefits); 156 | map.put("total", total); 157 | map.put("pensionInsurance", pensionInsurance); 158 | map.put("medicalInsurance", medicalInsurance); 159 | map.put("unemploymentInsurance", unemploymentInsurance); 160 | map.put("housingFund", housingFund); 161 | map.put("shouldMade", schoolGrant); 162 | map.put("withholding", withholding); 163 | return map; 164 | } 165 | 166 | public void setFields(Wage wage) { 167 | this.email = wage.getStaff().getEmail(); 168 | this.name = wage.getStaff().getName(); 169 | this.wage = wage.getStaff().getWage(); 170 | this.performancePay = wage.getStaff().getPerformancePay(); 171 | this.dutyAllowance = wage.getStaff().getDutyAllowance(); 172 | this.grants = wage.getStaff().getGrants(); 173 | this.total1 = wage.getTotal1(); 174 | this.replenishment = wage.getReplenishment(); 175 | this.chargeBack = wage.getChargeBack(); 176 | this.total2 = wage.getTotal2(); 177 | this.teachingBonus = wage.getTeachingBonus(); 178 | this.mAllowance = wage.getStaff().getMAllowance(); 179 | this.pSubsidies = wage.getStaff().getPSubsidies(); 180 | this.studentAllowance = wage.getStudentAllowance(); 181 | this.bonus = wage.getBonus(); 182 | this.schoolGrant = wage.getSchoolGrant(); 183 | this.time8 = wage.getTime8(); 184 | this.overtimeAssistance = wage.getOvertimeAssistance(); 185 | this.onDutySubsidies = wage.getOnDutySubsidies(); 186 | this.otherBenefits = wage.getOtherBenefits(); 187 | this.totalBenefits = wage.getTotalBenefits(); 188 | this.total = wage.getTotal(); 189 | this.pensionInsurance = wage.getPensionInsurance(); 190 | this.medicalInsurance = wage.getMedicalInsurance(); 191 | this.unemploymentInsurance = wage.getUnemploymentInsurance(); 192 | this.housingFund = wage.getHousingFund(); 193 | this.shouldMade = wage.getShouldMade(); 194 | this.withholding = wage.getWithholding(); 195 | 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /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/java/top/itning/hrms/service/StaffService.java: -------------------------------------------------------------------------------- 1 | package top.itning.hrms.service; 2 | 3 | import org.slf4j.Logger; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.web.multipart.MultipartFile; 6 | import top.itning.hrms.entity.ServerMessage; 7 | import top.itning.hrms.entity.Staff; 8 | import top.itning.hrms.entity.search.SearchStaff; 9 | import top.itning.hrms.exception.defaults.NoSuchIdException; 10 | import top.itning.hrms.exception.defaults.NullParameterException; 11 | 12 | import javax.persistence.criteria.CriteriaBuilder; 13 | import javax.persistence.criteria.Predicate; 14 | import javax.persistence.criteria.Root; 15 | import javax.servlet.ServletOutputStream; 16 | import java.io.IOException; 17 | import java.text.ParseException; 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.zip.DataFormatException; 22 | 23 | /** 24 | * 职工信息服务 25 | * 26 | * @author Ning 27 | */ 28 | public interface StaffService { 29 | /** 30 | * 根据部门ID获取该部门的所有职工信息集合 31 | * 32 | * @param id 部门ID 33 | * @return 职工信息集合 34 | * @throws NullParameterException ID为空时抛出该异常 35 | * @throws NoSuchIdException ID不存在时抛出该异常 36 | */ 37 | List getStaffInfoListByDepartmentID(String id) throws NullParameterException, NoSuchIdException; 38 | 39 | /** 40 | * 添加或修改职工信息 41 | * 42 | * @param staff 职工实体类 43 | * @return 添加获取修改的职工信息 44 | * @throws NumberFormatException 身份证ID不正确则抛出该异常 45 | * @throws NullParameterException 实体信息必填字段有空则抛出该异常 46 | * @throws DataFormatException 出生日期格式化出现问题则抛出该异常 47 | */ 48 | Staff addOrModifyStaffInfo(Staff staff) throws NumberFormatException, NullParameterException, DataFormatException; 49 | 50 | /** 51 | * 根据职工ID查找该职工实体信息 52 | * 53 | * @param id 职工ID 54 | * @return 职工实体信息 55 | * @throws NoSuchIdException 如果该职工ID不存在则抛出该异常 56 | * @throws NullParameterException 如果ID为空则抛出该异常 57 | */ 58 | Staff getStaffInfoByID(String id) throws NoSuchIdException, NullParameterException; 59 | 60 | /** 61 | * 根据职工实体删除职工信息 62 | * 63 | * @param staff 职工 64 | */ 65 | void delStaffInfoByID(Staff staff); 66 | 67 | /** 68 | * 职工信息搜索 69 | * 70 | * @param searchStaff 职工信息搜索实体 71 | * @return 搜索到的职工信息集合 72 | */ 73 | List searchStaff(SearchStaff searchStaff); 74 | 75 | /** 76 | * 根据ID下载职工信息 77 | * 78 | * @param servletOutputStream servletOutputStream 79 | * @param id 职工ID 80 | * @throws NoSuchIdException 如果ID没有找到则抛出该异常 81 | * @throws IOException IOException 82 | */ 83 | void downStaffInfoByID(ServletOutputStream servletOutputStream, String... id) throws NoSuchIdException, IOException; 84 | 85 | 86 | /** 87 | * 通过Excel文件添加职工信息 88 | * 89 | * @param file 文件 90 | * @return JSON服务器消息 91 | * @throws NullParameterException 参数为空则抛出该异常 92 | * @throws IOException IOException 93 | */ 94 | ServerMessage addStaffInfoByFile(MultipartFile file) throws NullParameterException, IOException; 95 | 96 | /** 97 | * 日期区间查询 98 | * 99 | * @param logger 日志工厂 100 | * @param list 条件集合 101 | * @param cb CriteriaBuilder 102 | * @param root Root Staff 103 | * @param field 查询字段 104 | * @param startDate 开始日期 105 | * @param endDate 结束日期 106 | */ 107 | default void dateIntervalQuery(Logger logger, List list, CriteriaBuilder cb, Root root, String field, Date startDate, Date endDate) { 108 | //有开始有结束 109 | if (startDate != null && endDate != null) { 110 | logger.info("dateIntervalQuery::已获取到开始和结束时间"); 111 | list.add(cb.between(root.get(field), startDate, endDate)); 112 | } else { 113 | Date minDate = null; 114 | Date maxDate = null; 115 | try { 116 | minDate = new SimpleDateFormat("yyyy-MM-dd").parse("2001-01-01"); 117 | maxDate = new SimpleDateFormat("yyyy-MM-dd").parse("9999-12-31"); 118 | } catch (ParseException e) { 119 | //不可能的异常 120 | logger.error("dateIntervalQuery::日期转换出现问题?" + e.getMessage()); 121 | } 122 | //只有开始时间 123 | if (startDate != null) { 124 | logger.debug("dateIntervalQuery::已获取到开始时间"); 125 | list.add(cb.between(root.get(field), startDate, maxDate)); 126 | } else {//只有结束时间 127 | logger.debug("dateIntervalQuery::已获取到结束时间"); 128 | list.add(cb.between(root.get(field), minDate, endDate)); 129 | } 130 | } 131 | } 132 | 133 | /** 134 | * 数字区间查询 135 | * 136 | * @param logger 日志工厂 137 | * @param list 条件集合 138 | * @param cb CriteriaBuilder 139 | * @param root Root Staff 140 | * @param field 查询字段 141 | * @param start 开始 142 | * @param end 结束 143 | */ 144 | default void intIntervalQuery(Logger logger, List list, CriteriaBuilder cb, Root root, String field, Integer start, Integer end) { 145 | //有开始有结束 146 | if (start != null && end != null) { 147 | if (start > end) { 148 | logger.info("stringIntervalQuery::开始大于结束"); 149 | return; 150 | } 151 | logger.info("stringIntervalQuery::已获取到开始和结束->" + start + "\t" + end); 152 | list.add(cb.between(root.get(field), start, end)); 153 | } else { 154 | int min = 0; 155 | int max = 9999999; 156 | //只有开始 157 | if (start != null) { 158 | logger.debug("stringIntervalQuery::已获取到开始->" + start); 159 | list.add(cb.between(root.get(field), start, max)); 160 | //只有结束 161 | } else { 162 | logger.debug("stringIntervalQuery::已获取到结束->" + end); 163 | list.add(cb.between(root.get(field), min, end)); 164 | } 165 | } 166 | } 167 | 168 | /** 169 | * 多条件查询 170 | * 171 | * @param logger 日志工厂 172 | * @param staffDao 职工DAO 173 | * @param cb CriteriaBuilder 174 | * @param root Root Staff 175 | * @param field 查询字段 176 | * @param key 多查询条件关键字 177 | * @return Predicate 178 | */ 179 | default Predicate multipleConditionsQuery(Logger logger, JpaRepository staffDao, CriteriaBuilder cb, Root root, String field, String[] key) { 180 | logger.info("multipleConditionsQuery::多查询条件关键字长度->" + key.length); 181 | Predicate[] p = new Predicate[key.length]; 182 | for (int i = 0; i < key.length; i++) { 183 | logger.info("multipleConditionsQuery::添加查询条件->" + key[i]); 184 | p[i] = cb.equal(root.get(field), staffDao.getOne(key[i])); 185 | } 186 | logger.info("multipleConditionsQuery::添加查询条件完成"); 187 | return cb.or(p); 188 | } 189 | } 190 | --------------------------------------------------------------------------------