目录
1、登录及角色控制

2、业务模块展示

智慧校园管理系统:主要是以年级、班级为单位,进行老师和学生信息记录和统计功能。项目采用前后端分离架构思想,前端采用HTML+CSS+VUE来实现页面效果展示,后端采用SpringBoot+MybatisPlus框架实现数据存储等服务。存储层使用高性能的MySQL,服务器使用SpringBoot内置的Tomcat9.x,项目构建工具使用Maven来管理jar包和项目构建。


VUE
是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。 前后端分离是目前一种非常流行的开发模式,它使项目的分工更加明确:后端:负责处理、存储数据. 前端:负责显示数据 前端和后端开发人员通过 接口 进行数据的交换。
Spring
Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。
Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。
SpringMVC
SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。SpringMVC相当于SSH框架中struts。
mybatis-plus
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。MyBatis-plus就是在MyBatis的基础上,为Mapper接口,Service层提供一些比较全面的CURD的业务逻辑功能,使程序员可以减少在Mapper和Service层的代码编写
MVC项目架构
页面发送请求给控制器,控制器调用业务层处理逻辑,逻辑层向持久层发送请求,持久层与数据库交互,后将结果返回给业务层,业务层将处理逻辑发送给控制器,控制器再调用视图展现数据。

1、新建工程 - zhxy - 包名:com.laptoy.zhxy - Group:com.laptoy

2、安装插件
MybatisX、Lombok
3、开启注解功能

4、指定Maven配置

5、指定字符编码

6、POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.laptoy</groupId>
<artifactId>zhxy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zhxy</name>
<description>zhxy</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--单元测试启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- thymeleaf支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- 简化POJO实体类开发 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<!--swagger2 增强版接口文档-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
<!--开发者工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.29</version>
</dependency>
<!-- JWT生成Token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1、目录结构
java目录:
resources目录:创建多级目录以 / 连接而不是 .
效果展示:

2、新建数据库 - 执行资料的SQL文件(资料在最上面)

3、application.yml
server:
port: 9001
spring:
# 解决SpringBoot2.6.0与swagger冲突问题【原因是在springboot2.6.0中将SpringMVC 默认路径匹配策略从AntPathMatcher 更改为PathPatternParser,导致出错,解决办法是切换回原先的AntPathMatcher】
mvc:
pathmatch:
matching-strategy: ant_path_matcher
datasource:
# 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/zhxy_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&userSSL=false
username: root
password: root
# Mybatis-plus内置连接池
hikari:
connection-test-query: SELECT 1
connection-timeout: 60000
idle-timeout: 500000
max-lifetime: 540000
maximum-pool-size: 12
minimum-idle: 10
pool-name: GuliHikariPool
thymeleaf:
# 模板的模式,支持 HTML, XML TEXT JAVASCRIPT
mode: HTML5
# 编码 可不用配置
encoding: UTF-8
# 开发配置为false,避免修改模板还要重启服务器
cache: false
# 配置模板路径,默认是templates,可以不用配置
prefix: classpath:/static/
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
servlet:
# 设置文件上传上限
multipart:
max-file-size: 10MB
max-request-size: 100MB
mybatis-plus:
configuration:
#添加日志支持
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:/mapper/**/*.xml
4、前端页面放入static目录(资料在最上面)

5、测试
运行主启动类访问 localhost:9001

1、分页插件的配置类
package com.laptoy.zhxy.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.laptoy.zhxy.mapper")
public class MpConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// paginationInterceptor.setLimit(你的最大单页限制数量,默认 500 条,小于 0 如 -1 不受限制);
return paginationInterceptor;
}
}
2、Swagger2的配置类
package com.laptoy.zhxy.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* Swagger2配置信息
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket webApiConfig() {
//添加head参数start
List<Parameter> pars = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
tokenPar.name("userId")
.description("用户ID")
.defaultValue("1")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build();
pars.add(tokenPar.build());
ParameterBuilder tmpPar = new ParameterBuilder();
tmpPar.name("userTempId")
.description("临时用户ID")
.defaultValue("1")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build();
pars.add(tmpPar.build());
//添加head参数end
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
//可以测试请求头中:输入token
.apis(RequestHandlerSelectors.basePackage("com.laptoy.zhxy.controller"))
//过滤掉admin路径下的所有页面
//.paths(Predicates.and(PathSelectors.regex("/sms/.*")))
//过滤掉所有error或error.*页面
//.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build()
.globalOperationParameters(pars);
}
private ApiInfo webApiInfo() {
return new ApiInfoBuilder()
.title("网站-API文档")
.description("本文档描述了网站微服务接口定义")
.version("1.0")
.contact(new Contact("Laptoy", "https://blog.csdn.net/apple_53947466", "laptoy458@163.com"))
.build();
}
private ApiInfo adminApiInfo() {
return new ApiInfoBuilder()
.title("后台管理系统-API文档")
.description("本文档描述了后台管理系统微服务接口定义")
.version("1.0")
.contact(new Contact("Laptoy", "https://blog.csdn.net/apple_53947466", "laptoy458@163.com"))
.build();
}
}
从资源直接粘贴到 util包
1、验证码图片工具类 - CreateVerifiCodeImage
2、token口令生成工具 - JwtHelper
3、解析request请求中的 token口令的工具 - AuthContextHolder
4、MD5加密工具类 - MD5
5、响应结果类型码枚举 - ResultCodeEnum
6、JSON响应结果格式封装类 - Result
7、文件上传工具类 - UploadFile
使用MybatisX插件进行逆向生成
1、选中所有表

2、配置实体类

3、配置

4、每个impl添加 - @Transactional 开启事务
5、最终效果

6、额外 - 实体类 LoginForm 封装登录表单信息
@Data
public class LoginForm {
private String username;
private String password;
private String verifiCode;
private Integer userType;
}
7、控制层 - 按照前端接口 /sms/xxxController 进行编写
@RestController
@RequestMapping("/sms/adminController")
public class AdminController {
}
@RestController
@RequestMapping("/sms/clazzController")
public class ClazzController {
}
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
}
@RestController
@RequestMapping("/sms/teacherController")
public class TeacherController {
}
@RestController
@RequestMapping("/sms/studentController")
public class StudentController {
}
8、系统控制层(如验证码)
@RestController
@RequestMapping("/sms/system")
public class SystemController {
}
刷新页面 - 验证码API - /sms/system/getVerifiCodeImage

获取验证码图片及向session中存储验证码功能实现
1、控制层 - SystemController
@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
/**
* 获取验证码及展示验证码
*/
@ApiOperation("获取验证码图片")
@GetMapping("/getVerifiCodeImage")
public void getVerifiCodeImage(HttpServletRequest request, HttpServletResponse response) {
// 获取图片及图片上的验证码
BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
String verifiCode = String.valueOf(CreateVerifiCodeImage.getVerifiCode());
// 将验证码放入session,为验证做准备
HttpSession session = request.getSession();
session.setAttribute("verifiCode", verifiCode);
// 将验证码图片响应给浏览器
try {
ImageIO.write(verifiCodeImage, "JPEG", response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、效果

点击登录按钮 - 登录API - /sms/system/login

代码实现
@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
@Autowired
private AdminService adminService;
@Autowired
private StudentService studentService;
@Autowired
private TeacherService teacherService;
/**
* 登录验证
*/
@ApiOperation("登录请求验证")
@PostMapping("/login")
public Result login(@RequestBody LoginForm loginForm, HttpServletRequest request) {
// 获取用户提交的验证码和session域中的验证码
HttpSession session = request.getSession();
String systemVerifiCode = (String) session.getAttribute("verifiCode");
String loginVerifiCode = loginForm.getVerifiCode();
// session过期,验证码超时
if ("".equals(systemVerifiCode)) {
return Result.fail().message("验证码失效,请刷新后重试");
}
// 验证码错误
if (!loginVerifiCode.equalsIgnoreCase(systemVerifiCode)) {
return Result.fail().message("验证码有误,请刷新后重新输入");
}
// 验证码使用完毕,移除当前请求域中的验证码
session.removeAttribute("verifiCode");
// 准备一个Map集合,用户存放响应的信息
Map<String, Object> map = new HashMap<>();
// 根据用户身份,验证登录的用户信息
switch (loginForm.getUserType()) {
case 1: // 管理员身份
try {
// 调用服务层登录方法,根据用户提交的LoginInfo信息,查询对应的Admin对象,找不到返回Null
Admin login = adminService.login(loginForm);
if (null != login) {
// 登录成功,将用户id和用户类型转换为token口令,作为信息响应给前端
map.put("token", JwtHelper.createToken(login.getId().longValue(), 1));
} else {
throw new RuntimeException("用户名或者密码有误!");
}
return Result.ok(map);
} catch (RuntimeException e) {
e.printStackTrace();
// 捕获异常,向用户响应错误信息
return Result.fail().message(e.getMessage());
}
case 2: // 学生身份
try {
// 调用服务层登录方法,根据用户提交的LoginInfo信息,查询对应的Student对象,找不到返回Null
Student login = studentService.login(loginForm);
if (null != login) {
// 登录成功,将用户id和用户类型转换为token口令,作为信息响应给前端
map.put("token", JwtHelper.createToken(login.getId().longValue(), 2));
} else {
throw new RuntimeException("用户名或者密码有误!");
}
return Result.ok(map);
} catch (RuntimeException e) {
e.printStackTrace();
// 捕获异常,向用户响应错误信息
return Result.fail().message(e.getMessage());
}
case 3: // 教师身份
try {
// 调用服务层登录方法,根据用户提交的LoginInfo信息,查询对应的Student对象,找不到返回Null
Teacher login = teacherService.login(loginForm);
if (null != login) {
// 登录成功,将用户id和用户类型转换为token口令,作为信息响应给前端
map.put("token", JwtHelper.createToken(login.getId().longValue(), 3));
} else {
throw new RuntimeException("用户名或者密码有误!");
}
return Result.ok(map);
} catch (RuntimeException e) {
e.printStackTrace();
// 捕获异常,向用户响应错误信息
return Result.fail().message(e.getMessage());
}
}
// 查无此用户,响应失败
return Result.fail().message("查无此用户");
}
}
AdminService中的login方法
@Service
@Transactional
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin>
implements AdminService {
/**
* 超级管理员登录
*/
@Override
public Admin login(LoginForm loginForm) {
QueryWrapper<Admin> wrapper = new QueryWrapper<>();
wrapper.eq("name", loginForm.getUsername());
// 转换为密文进行查询
wrapper.eq("password", MD5.encrypt(loginForm.getPassword()));
Admin admin = baseMapper.selectOne(wrapper);
return admin;
}
}
StudentService中的login方法
@Service
@Transactional
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
implements StudentService {
/**
* 学生登录方法
*/
@Override
public Student login(LoginForm loginForm) {
QueryWrapper<Student> wrapper = new QueryWrapper<>();
wrapper.eq("name", loginForm.getUsername());
wrapper.eq("password", MD5.encrypt(loginForm.getPassword()));
return baseMapper.selectOne(wrapper);
}
}
TeacherService中的login方法
@Service
@Transactional
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher>
implements TeacherService {
/**
* Teacher登录方法
*/
@Override
public Teacher login(LoginForm loginForm) {
QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
wrapper.eq("name", loginForm.getUsername());
wrapper.eq("password", MD5.encrypt(loginForm.getPassword()));
return baseMapper.selectOne(wrapper);
}
}
2、登录测试



当验证通过后,前端会产生第二个请求,用以获取用户的类型,然后根据用户的类型来展现不同的页面,所以后端要有一个根据token解析用户类型并做出结果响应的控制层
获取信息API - /sms/system/getInfo

代码实现
@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
@Autowired
private AdminService adminService;
@Autowired
private StudentService studentService;
@Autowired
private TeacherService teacherService;
/**
* 跳转至首页
*/
@ApiOperation("通过token获取用户信息")
@GetMapping("/getInfo")
public Result getUserInfoByToken(HttpServletRequest request, @RequestHeader("token") String token) {
// 检查token 是否过期
if (JwtHelper.isExpiration(token)) {
return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
}
// 解析token,获取用户id和用户类型
Long userId =JwtHelper.getUserId(token);
Integer userType =JwtHelper.getUserType(token);
// 准备一个Map集合用于存响应的数据
Map<String,Object> map=new HashMap<>();
switch (userType){
case 1:
Admin admin = adminService.getAdminById(userId.intValue());
map.put("user",admin);
map.put("userType",1);
break;
case 2:
Student student = studentService.getStudentById(userId.intValue());
map.put("user",student);
map.put("userType",2);
break;
case 3:
Teacher teacher = teacherService.getTeacherById(userId.intValue());
map.put("user",teacher);
map.put("userType",3);
break;
}
return Result.ok(map);
}
}
AdminService中的getAdminById方法
@Override
public Admin getAdminById(int intValue) {
QueryWrapper<Admin> wrapper = new QueryWrapper<>();
wrapper.eq("id",intValue);
Admin admin = baseMapper.selectOne(wrapper);
return admin;
}
StudentService中的getAdminById方法
@Override
public Student getStudentById(int intValue) {
QueryWrapper<Student> wrapper = new QueryWrapper<>();
wrapper.eq("id",intValue);
Student student = baseMapper.selectOne(wrapper);
return student;
}
TeacherService中的getAdminById方法
@Override
public Teacher getTeacherById(int intValue) {
QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
wrapper.eq("id",intValue);
Teacher teacher = baseMapper.selectOne(wrapper);
return teacher;
}
效果



点击年级管理模块API - /sms/gradeController/getGrades/1/3

GradeController 控制层代码
@Api(tags = "年级控制器")
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
@Autowired
private GradeService gradeService;
/**
* 分页展示数据
*/
@ApiOperation("查询年级信息,分页带条件")
@GetMapping("/getGrades/{pageNo}/{pageSize}")
public Result getGradeByOpr(
@ApiParam("分页查询页码数") @PathVariable(value = "pageNo") Integer pageNo, // 页码数
@ApiParam("分页查询页大小") @PathVariable(value = "pageSize") Integer pageSize, // 页大小
@ApiParam("分页查询模糊匹配班级名") String gradeName) {
// 设置分页信息
Page<Grade> page = new Page<>(pageNo, pageSize);
// 调用服务层方法,传入分页信息,和查询的条件
IPage<Grade> pageRs = gradeService.getGradeByOpr(page, gradeName);
return Result.ok(pageRs);
}
}
GradeServiceImpl 业务层代码
@Service
@Transactional
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> implements GradeService {
@Override
public IPage<Grade> getGradeByOpr(Page<Grade> page, String gradeName) {
QueryWrapper<Grade> wrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(gradeName)) {
wrapper.like("name", gradeName);
}
wrapper.orderByAsc("id");
Page<Grade> gradePage = baseMapper.selectPage(page, wrapper);
return gradePage;
}
}
点击添加年级按钮输入数据执行添加API - /sms/gradeController/saveOrUpdateGrade

Controller层代码
@Api(tags = "年级控制器")
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
@Autowired
private GradeService gradeService;
/**
* 保存或更新信息
*/
@ApiOperation("添加或者修改年级信息")
@PostMapping("/saveOrUpdateGrade")
public Result saveOrUpdateGrade(@ApiParam("JSON的grade对象转换后台数据模型") @RequestBody Grade grade) {
// 调用服务层方法,实现添加或者修改年级信息
gradeService.saveOrUpdate(grade);
return Result.ok();
}
}
点击删除按钮API - sms/gradeController/deleteGrade (这张截图后面补截的)

Controller层代码
@Api(tags = "年级控制器")
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
@Autowired
private GradeService gradeService;
/**
* 删除或批量删除
*/
@ApiOperation("删除一个或者多个grade信息")
@DeleteMapping("/deleteGrade")
public Result deleteGradeById(@ApiParam("JSON的年级id集合,映射为后台List<Integer>") @RequestBody List<Integer> ids) {
gradeService.removeByIds(ids);
return Result.ok();
}
}

点击班级管理模块 - 年级名称API - /sms/gradeController/getGrades


控制层
@Api(tags = "年级控制器")
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
@Autowired
private GradeService gradeService;
/**
* 回显搜索条件中的年级选项
*/
@ApiOperation("获取所有Grade信息")
@GetMapping("/getGrades")
public Result getGrades(){
List<Grade> grades = gradeService.getGrades();
return Result.ok(grades);
}
}
业务层
@Service
@Transactional
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> implements GradeService {
@Override
public List<Grade> getGrades() {
return baseMapper.selectList(null);
}
}
点击年级管理模块API - /sms/clazzController/getClazzsByOpr/1/3

控制层
@Api(tags = "班级控制器")
@RestController
@RequestMapping("/sms/clazzController")
public class ClazzController {
@Autowired
private ClazzService clazzService;
@ApiOperation("查询班级信息,分页带条件")
@GetMapping("/getClazzsByOpr/{pageNo}/{pageSize}")
public Result getClazzsByOpr(@ApiParam("页码数") @PathVariable("pageNo") Integer pageNo,
@ApiParam("页大小") @PathVariable("pageSize") Integer pageSize,
@ApiParam("查询条件") Clazz clazz) {
//设置分页信息
Page<Clazz> page = new Page<>(pageNo, pageSize);
IPage<Clazz> iPage = clazzService.getClazzsByOpr(page, clazz);
return Result.ok(iPage);
}
}
业务层
@Service
@Transactional
public class ClazzServiceImpl extends ServiceImpl<ClazzMapper, Clazz> implements ClazzService {
/**
* 分页查询所有班级信息【带条件】
*
* @param clazz
* @return
*/
@Override
public IPage<Clazz> getClazzsByOpr(Page<Clazz> pageParam, Clazz clazz) {
QueryWrapper<Clazz> queryWrapper = new QueryWrapper<>();
if (clazz != null) {
//年级名称条件
String gradeName = clazz.getGradeName();
if (!StringUtils.isEmpty(gradeName)) {
queryWrapper.eq("grade_name", gradeName);
}
//班级名称条件
String clazzName = clazz.getName();
if (!StringUtils.isEmpty(clazzName)) {
queryWrapper.like("name", clazzName);
}
queryWrapper.orderByAsc("id");
}
Page<Clazz> clazzPage = baseMapper.selectPage(pageParam, queryWrapper);
return clazzPage;
}
}
添加功能API - sms/clazzController/saveOrUpdateClazz

控制层
@Api(tags = "班级控制器")
@RestController
@RequestMapping("/sms/clazzController")
public class ClazzController {
@Autowired
private ClazzService clazzService;
@ApiOperation("保存或者修改班级信息")
@PostMapping("/saveOrUpdateClazz")
public Result saveOrUpdateClazz(@ApiParam("JSON转换后端Clazz数据模型") @RequestBody Clazz clazz) {
clazzService.saveOrUpdate(clazz);
return Result.ok();
}
}
删除功能API - sms/clazzController/deleteClazz

控制层
@Api(tags = "班级控制器")
@RestController
@RequestMapping("/sms/clazzController")
public class ClazzController {
@Autowired
private ClazzService clazzService;
@ApiOperation("删除一个或者多个班级信息")
@DeleteMapping("/deleteClazz")
public Result deleteClazzByIds(@ApiParam("多个班级id的JSON") @RequestBody List<Integer> ids) {
clazzService.removeByIds(ids);
return Result.ok();
}
}

点击教师管理API - sms/clazzController/getClazzs

控制层
@Api(tags = "班级控制器")
@RestController
@RequestMapping("/sms/clazzController")
public class ClazzController {
@Autowired
private ClazzService clazzService;
@ApiOperation("获取所有Clazz信息")
@GetMapping("/getClazzs")
public Result getClazzs() {
List<Clazz> list = clazzService.getClazzs();
return Result.ok(list);
}
}
业务层
@Service
@Transactional
public class ClazzServiceImpl extends ServiceImpl<ClazzMapper, Clazz> implements ClazzService {
@Override
public List<Clazz> getClazzs() {
return baseMapper.selectList(null);
}
}
控制层
@Api(tags = "学生控制器")
@RestController
@RequestMapping("/sms/studentController")
public class StudentController {
@Autowired
private StudentService studentService;
@ApiOperation("查询学生信息,分页带条件")
@GetMapping("/getStudentByOpr/{pageNo}/{pageSize}")
public Result getStudentsByOpr(@ApiParam("页码数") @PathVariable("pageNo") Integer pageNo,
@ApiParam("页大小") @PathVariable("pageSize") Integer pageSize,
@ApiParam("查询条件转换后端数据模型") Student student) {
// 准备分页信息封装的page对象
Page<Student> page = new Page<>(pageNo, pageSize);
// 获取分页的学生信息
IPage<Student> iPage = studentService.getStudentByOpr(page, student);
// 返回学生信息
return Result.ok(iPage);
}
}
业务层
@Service
@Transactional
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
/**
* 按条件查询学生信息【带分页】
*/
public IPage<Student> getStudentByOpr(Page<Student> pageParam, Student student) {
QueryWrapper<Student> queryWrapper = null;
if (student != null) {
queryWrapper = new QueryWrapper<>();
if (student.getClazzName() != null) {
queryWrapper.eq("clazz_name", student.getClazzName());
}
if (student.getName() != null) {
queryWrapper.like("name", student.getName());
}
queryWrapper.orderByAsc("id");
}
//创建分页对象
IPage<Student> pages = baseMapper.selectPage(pageParam, queryWrapper);
return pages;
}
}
Controller层代码
@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
@ApiOperation("头像上传统一入口")
@PostMapping("/headerImgUpload")
public Result headerImgUpload(@ApiParam("文件二进制数据") @RequestPart("multipartFile") MultipartFile multipartFile) {
//使用UUID随机生成文件名
String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
//生成新的文件名字
String filename = uuid.concat(multipartFile.getOriginalFilename());
//生成文件的保存路径(实际生产环境这里会使用真正的文件存储服务器)
String portraitPath = "D:/MyCode/IdeaCode/zhxy/target/classes/public/upload/".concat(filename);
//保存文件
try {
multipartFile.transferTo(new File(portraitPath));
} catch (IOException e) {
e.printStackTrace();
}
String headerImg = "upload/" + filename;
return Result.ok(headerImg);
}
}
@Api(tags = "学生控制器")
@RestController
@RequestMapping("/sms/studentController")
public class StudentController {
@ApiOperation("增加学生信息")
@PostMapping("/addOrUpdateStudent")
public Result addOrUpdateStudent(@RequestBody Student student) {
//对学生的密码进行加密
if (!Strings.isEmpty(student.getPassword())) {
student.setPassword(MD5.encrypt(student.getPassword()));
}
//保存学生信息进入数据库
studentService.saveOrUpdate(student);
return Result.ok();
}
@ApiOperation("删除一个或者多个学生信息")
@DeleteMapping("/delStudentById")
public Result delStudentById(@ApiParam("多个学生id的JSON") @RequestBody List<Integer> ids) {
studentService.removeByIds(ids);
return Result.ok();
}
}
点击教师管理API - sms/teacherController/getTeachers/1/3

控制层
@Api(tags = "教师控制器")
@RestController
@RequestMapping("/sms/teacherController")
public class TeacherController {
@Autowired
private TeacherService teacherService;
@ApiOperation("获取教师信息,分页带条件")
@GetMapping("/getTeachers/{pageNo}/{pageSize}")
public Result getTeachers(@PathVariable Integer pageNo, @PathVariable Integer pageSize, Teacher teacher) {
Page<Teacher> pageParam = new Page<>(pageNo, pageSize);
IPage<Teacher> page = teacherService.getTeachersByOpr(pageParam, teacher);
return Result.ok(page);
}
}
业务层
@Service
@Transactional
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {
@Override
public IPage<Teacher> getTeachersByOpr(Page<Teacher> pageParam, Teacher teacher) {
QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
if (teacher != null) {
//班级名称条件
String clazzName = teacher.getClazzName();
if (!StringUtils.isEmpty(clazzName)) {
wrapper.eq("clazz_name", clazzName);
}
//教师名称条件
String teacherName = teacher.getName();
if (!StringUtils.isEmpty(teacherName)) {
wrapper.like("name", teacherName);
}
wrapper.orderByAsc("id");
}
Page<Teacher> page = baseMapper.selectPage(pageParam, wrapper);
return page;
}
}
@ApiOperation("添加和修改教师信息")
@PostMapping("/saveOrUpdateTeacher")
public Result saveOrUpdateTeacher(@RequestBody Teacher teacher) {
teacherService.saveOrUpdate(teacher);
return Result.ok();
}
@ApiOperation("删除一个或者多个教师信息")
@DeleteMapping("/deleteTeacher")
public Result deleteTeacher(@RequestBody List<Integer> ids) {
teacherService.removeByIds(ids);
return Result.ok();
}
控制层
@Api(tags = "系统管理员控制器")
@RestController
@RequestMapping("/sms/adminController")
public class AdminController {
@Autowired
private AdminService adService;
@ApiOperation("分页获取所有Admin信息【带条件】")
@GetMapping("/getAllAdmin/{pageNo}/{pageSize}")
public Result getAllAdmin(@PathVariable Integer pageNo,
@PathVariable Integer pageSize,
String adminName){
Page<Admin> pageParam = new Page<>(pageNo,pageSize);
IPage<Admin> page = adService.getAdmins(pageParam, adminName);
return Result.ok(page);
}
}
业务层
@Service
@Transactional
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
@Override
public IPage<Admin> getAdmins(Page<Admin> pageParam, String adminName) {
QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(adminName)) {
queryWrapper.like("name", adminName);
}
queryWrapper.orderByAsc("id");
Page page = baseMapper.selectPage(pageParam, queryWrapper);
return page;
}
}
@ApiOperation("添加或修改Admin信息")
@PostMapping("/saveOrUpdateAdmin")
public Result saveOrUpdateAdmin(@RequestBody Admin admin){
if (!Strings.isEmpty(admin.getPassword())) {
admin.setPassword(MD5.encrypt(admin.getPassword()));
}
adService.saveOrUpdate(admin);
return Result.ok();
}
@ApiOperation("删除Admin信息")
@DeleteMapping("/deleteAdmin")
public Result deleteAdmin(@RequestBody List<Integer> ids){
adService.removeByIds(ids);
return Result.ok();
}

@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
@Autowired
private AdminService adminService;
@Autowired
private StudentService studentService;
@Autowired
private TeacherService teacherService;
@ApiOperation("修改密码")
@PostMapping("/updatePwd/{oldPwd}/{newPwd}")
public Result updatePwd(@RequestHeader("token") String token,
@PathVariable("oldPwd") String oldPwd,
@PathVariable("newPwd") String newPwd) {
if (JwtHelper.isExpiration(token)) {
// token过期
return Result.fail().message("token失效");
}
// 通过token获取当前登录的用户id
Long userId = JwtHelper.getUserId(token);
// 通过token获取当前登录的用户类型
Integer userType = JwtHelper.getUserType(token);
// 将明文密码转换为暗文
oldPwd = MD5.encrypt(oldPwd);
newPwd = MD5.encrypt(newPwd);
if (userType == 1) {
QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", userId.intValue()).eq("password", oldPwd);
Admin admin = adminService.getOne(queryWrapper);
if (null != admin) {
admin.setPassword(newPwd);
adminService.saveOrUpdate(admin);
} else {
return Result.fail().message("原密码输入有误!");
}
} else if (userType == 2) {
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", userId.intValue()).eq("password", oldPwd);
Student student = studentService.getOne(queryWrapper);
if (null != student) {
student.setPassword(newPwd);
studentService.saveOrUpdate(student);
} else {
return Result.fail().message("原密码输入有误!");
}
} else if (userType == 3) {
QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", userId.intValue()).eq("password", oldPwd);
Teacher teacher = teacherService.getOne(queryWrapper);
if (null != teacher) {
teacher.setPassword(newPwd);
teacherService.saveOrUpdate(teacher);
} else {
return Result.fail().message("原密码输入有误!");
}
}
return Result.ok();
}
}
1、课题的名称
2、设计课题的目标和意义
3、预期目标及成果形式

4、 成果的展现形式
项目成果展示+毕业论文
5、开发工具和技术栈
操作系统的选择:开发者使用Windows10 /11 ,项目运行环境为Linux.服务容器使用Tomcat
开发使用的工具
数据库管理系统:mysql8作为数据库服务,同时配合Navicat/Sqlyog可视化数据库前端工具
相关框架
6、项目的架构模式和开发模式
7、进度和计划
8、参考的相关资料
中国知网: 搜索关键字 校园管理 VUE SpringBoot MyBatisPlus swagger2
目录
1 论文名称
2 摘要
3 绪论
4 相关技术介绍
5 系统需求分析
6 系统概要设计
7 系统各功能模块的详细设计
8 系统实现中关键的问题和解决方案
9 系统测试及实现效果
10 总结与展望
11 参考文献
12 致谢
1、论文名称
如:智慧校园云端管理系统的设计和实现
2、 摘要
3、绪论(第一章)
本文主要进行了互联网时代校园管理的设计和实现. 由于… 因此… 本文在深入分析Vue+SpringBoot+MyBatisPlus的技术前提下,提出了一套校园管理的软件系统并详细阐述了技术选型和实现过程. 需求如何分析的,数据库如何设计的,技术如何选型的,项目如何搭建的. 过程是如何开发的
论文的组织结构
4、核心组件技术介绍(第二章)
5、系统需求分析(第三章)
功能需求分析
非功能需求
6、软件安装和项目环境搭建(第四章)
7、系统各功能模块的实现(第五章)
例如:验证码功能的实现
1、效果截图
业务分析 当加载登录页时,前端项目自动向后端请求一个验证码图片并展示在页面上,后端生成验证码后响应给前端,并将 验证码图片上的文本存储在session中,可以采用时序图,流程图等
2、接口介绍
3、核心代码实现
8、系统实现中关键的问题和解决方案(第六章)
9、系统测试及实现效果(第七章)
每个业务如何使用swagger2测试,在这里进行介绍
删除学生信息测试
swagger2测试的结果效果截图
10、总结与展望(第八章)
11、参考文献
12、致谢
主要包含的内容
首页 课题+答辩人+指导教师
第二页 后面的内容
第三页 目的和意义
第四页 系统的需求
第五页 项目的架构和技术栈
第六页 系统测试及实现效果
第七页 总结和展望
第八页 致谢
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht