智慧校园云端管理系统的设计和实现

智慧校园云端管理系统的设计和实现_第1张图片

智慧校园云端管理系统的设计和实现

项⽬简介

智慧校园云端管理系统主要⽤来管理校内学⽣、⽼师、班级、年级的相关信息,进⾏⽼师和学⽣信
息记录和统计的功能,⽽这些信息是校园信息化建设的核⼼基础业务数据。项⽬采⽤前后端分离架构思
想,前端采⽤HTML+CSS+VUE来实现⻚⾯效果展示,后端采⽤SpringBoot+MybatisPlus框架实
现数据存储等服务。存储层使⽤⾼性能的MySQL,服务器使⽤SpringBoot内置的Tomcat9.x,项
⽬构建⼯具使⽤Maven来管理jar包和项⽬构建。
智慧校园指的是信息化为基础构建起来的校园信息化教育管理的⼀种新的模式,智慧校园能够实现
校园⼯作,学习和⽣活的⼀体化发展,在各种信息系统应⽤的基础上,能实现教学,科研管理和校园⽣
活的有效融合。智慧校园建设所包括的内容很丰富,通过云计算,互联⽹技术将校园运⾏中的所有数据
有效的联系在⼀起,通过相关软件系统的有效应⽤,实现学校智能监控和智能识别的综合信息服务平台
的有效构建。
智慧校园有三个基本特征,
第⼀,智慧校园能够提供个性化的服务,通过智能化服务平台及智能感知功能,实现教育管理⼯作的个性化服务。
第⼆,智慧校园是建⽴在互联⽹基础上的, 通过互联⽹实现信息服务与校园各种应⽤领域的结合。
第三,智慧校园在个性化定制服务的基础上,能够为学校与外部世界的联系提供有效的平台和接⼝,促进学校资源与外部资源的有效融合。智慧校园是校园信息化的⼀种⾼级形式,通过智慧校园可以把学校的物理空间和数字空间结合起来,为师⽣学习⽣活,提供智能
化的学习⽣活环境,为师⽣提供个性化的智能服务。

项⽬技术栈

智慧校园云端管理系统的设计和实现_第2张图片

项⽬功能

智慧校园云端管理系统的使⽤者主要包含三种⽤户⻆⾊,其⼀是管理员⻆⾊,其⼆是⽼师⻆⾊,其
三是学⽣⻆⾊。这三个⻆⾊的具体功能如下:
● 管理员⻆⾊:管理员登录智慧校园系统后可以进⾏相应的管理操作,主要包含:学⽣信息管理、⽼
师信息管理、年级信息管理、班级信息管理、个⼈信息管理、账户密码重置等操作。
● ⽼师⽤户⻆⾊:⽼师⽤户登录智慧校园系统后可以进⾏参与相关学⽣、班级信息管理的相关操作以
及个⼈信息管理等操作。
● 学⽣⽤户⻆⾊:学⽣进⼊系统后,主要查看⾃⼰的班级,同学信息以及个⼈信息管理等操作
智慧校园云端管理系统的设计和实现_第3张图片

项⽬开发

使⽤idea的springboot脚⼿架搭建⼀个maven项⽬

智慧校园云端管理系统的设计和实现_第4张图片
项⽬创建完成后,更改⼀下maven的配置,改成⾃⼰的本地maven仓库。
智慧校园云端管理系统的设计和实现_第5张图片
修改pom.xml⽂件

>  <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.0modelVersion>
> 
>     
>     <parent>
>         <groupId>org.springframework.bootgroupId>
>         <artifactId>spring-boot-starter-parentartifactId>
>         <version>2.2.1.RELEASEversion>
>         <relativePath/>
>     parent>
> 
> 
>     <groupId>com.atguigugroupId>
>     <artifactId>myzhxyartifactId>
>     <version>0.0.1-SNAPSHOTversion>
> 
>     <dependencies>
> 
>         <dependency>
>             <groupId>org.springframework.bootgroupId>
>             <artifactId>spring-boot-starterartifactId>
>         dependency>
>         <dependency>
>             <groupId>org.springframework.bootgroupId>
>             <artifactId>spring-boot-starter-webartifactId>
>         dependency>
>         
>         <dependency>
>             <groupId>org.springframework.bootgroupId>
>             <artifactId>spring-boot-starter-testartifactId>
>             <scope>testscope>
>         dependency>
>         
>         <dependency>
>             <groupId>org.springframework.bootgroupId>
>             <artifactId>spring-boot-starter-thymeleafartifactId>
>         dependency>
> 
>         
>         <dependency>
>             <groupId>com.baomidougroupId>
>             <artifactId>mybatis-plus-boot-starterartifactId>
>             <version>3.3.1version>
>         dependency>
> 
>         
>         <dependency>
>             <groupId>org.projectlombokgroupId>
>             <artifactId>lombokartifactId>
>             <optional>trueoptional>
>         dependency>
> 
>         
>         <dependency>
>             <groupId>mysqlgroupId>
>             <artifactId>mysql-connector-javaartifactId>
>         dependency>
> 
>         <dependency>
>             <groupId>com.baomidougroupId>
>             <artifactId>mybatis-plus-generatorartifactId>
>             <version>3.3.1version>
>         dependency>
>         <dependency>
>             <groupId>org.freemarkergroupId>
>             <artifactId>freemarkerartifactId>
>             <version>2.3.31version>
>         dependency>
> 
>         
>         <dependency>
>             <groupId>io.springfoxgroupId>
>             <artifactId>springfox-swagger2artifactId>
>             <version>2.7.0version>
>         dependency>
>         
>         <dependency>
>             <groupId>io.springfoxgroupId>
>             <artifactId>springfox-swagger-uiartifactId>
>             <version>2.7.0version>
>         dependency>
>         
>         <dependency>
>             <groupId>com.github.xiaoymingroupId>
>             <artifactId>knife4j-spring-boot-starterartifactId>
>             <version>2.0.4version>
>         dependency>
> 
> 
>         
>         <dependency>
>             <groupId>org.springframework.bootgroupId>
>             <artifactId>spring-boot-devtoolsartifactId>
>             <optional>trueoptional>
>         dependency>
> 
>         <dependency>
>             <groupId>com.alibabagroupId>
>             <artifactId>fastjsonartifactId>
>             <version>1.2.29version>
>         dependency>
> 
>         
>         <dependency>
>             <groupId>io.jsonwebtokengroupId>
>             <artifactId>jjwtartifactId>
>             <version>0.7.0version>
>         dependency>
> 
>         <dependency>
>             <groupId>commons-fileuploadgroupId>
>             <artifactId>commons-fileuploadartifactId>
>             <version>1.4version>
>         dependency>
> 
>     dependencies>
> 
>     <build>
>         <plugins>
>             
>             <plugin>
>                 <groupId>org.springframework.bootgroupId>
>                 <artifactId>spring-boot-maven-pluginartifactId>
>             plugin>
>         plugins>
>     build>
> 
> project>

项⽬包结构

  1. java⽬录下
    ○ config : 项⽬的配置类
    ○ controller: 控制层
    ○ mapper : 持久层接⼝
    ○ pojo : 实体类
    ○ service: 服务层
    ○ util: ⼯具类包
    ○ SmartCampusApplication : 启动类
  2. resources⽬录下
    ○ mapper :持久层映射⽂件
    ○ public/upload:⽂件上传⽬录
    ○ static: 静态资源⽬录
    ○ application.yml :SpringBoot核⼼配置⽂
    智慧校园云端管理系统的设计和实现_第6张图片
    这⾥注意⼀下:public/upload
    设置该⽬录时,如果为public.upload,那么在本地⽂件夹,并不会创建⼀个public下的新⽂件夹upload ,
    默认为该⽂件的⽂件名。
    但是如果设置时,按照这种 public/upload 格式,虽然在⽬录中显示为public.upload (这是因为
    public⽬录下⽬前只有⼀个⽂件夹),但是实际上upload是public⽂件夹下的⼀个⽂件。
    在这里插入图片描述
    配置application.yml⽂件
server:
  port: 9001
spring:
  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/sc_tb?characterEncoding=utf-8&serverTimezone=GMT%2B8&userSSL=false
    username: root
    password: 1qaz0okm
    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:
    mode: HTML5
    encoding: UTF-8
    cache: false
    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
 

Hikari

hikari使⽤

<dependency>
 <groupId>com.zaxxergroupId>
 <artifactId>HikariCPartifactId>
 <version>5.0.0version>
dependency>

初始化

HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("root");
ds.setPassword("123456");

基于配置⽂件的初始化

HikariConfig config = new HikariConfig("/../hikari.properties");
HikariDataSource ds = new HikariDataSource(config);
// properties file
dataSourceClassName=org.postgresql.ds.PGSimpleDataSource
dataSource.user=test
dataSource.password=test
dataSource.databaseName=mydb
dataSource.portNumber=5432
dataSource.serverName=localhost

常⽤参数

 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
 

根据 less is more 的设计哲学,以 Hikari 开头的配置都是可选的配置,都有默认的值,不配也⾏的。


智慧校园云端管理系统的设计和实现_第7张图片

jackson

	Jackson 是当前⽤的⽐较⼴泛的,⽤来序列化和反序列化 json 的 Java 的开源框架.

优点:

  • Jackson 解析⼤的 json ⽂件速度⽐较快;
  • Jackson 运⾏时占⽤内存⽐较低,性能⽐较好;
  • Jackson 有灵活的API,可以很容易进⾏扩展和定制。
 
 <dependency>
 <groupId>org.springframework.bootgroupId>
 <artifactId>spring-boot-starter-jsonartifactId>
 dependency>

按照这种格式去解析⽇期和时区

 jackson:
 date-format: yyyy-MM-dd HH:mm:ss
 time-zone: GMT+8

mybatis-plus

mybatis-plus:
 configuration:
 #添加⽇志⽀持
 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 mapper-locations: classpath*:/mapper/**/*.xml

mapper-locations: classpath*:/mapper/**/*.xml

设置映射⽂件位置:

在这里插入图片描述

配置类

分⻚插件配置类

@Configuration
@MapperScan("com.project.smart_campus.mapper")
public class MyConfig {
 /*
 * 分⻚插件
 * */
 
 @Bean
 public PaginationInterceptor paginationInterceptor(){
 PaginationInterceptor paginationInterceptor=new PaginationInterceptor();
 return paginationInterceptor;
 }
}

Swagger2的配置类

引⼊依赖



<dependency>
 <groupId>io.springfoxgroupId>
 <artifactId>springfox-swagger2artifactId>
 <version>2.7.0version>
dependency>
<dependency>
 <groupId>io.springfoxgroupId>
 <artifactId>springfox-swagger-uiartifactId>
 <version>2.7.0version>
dependency>

配置类

@Configuration
@EnableSwagger2
public class Swagger2Config {
 @Bean
 public Docket webApiConfig(){
 //添加head参数start
 List<Parameter> parameters=new ArrayList<>();
 ParameterBuilder tokenPar=new ParameterBuilder();
 tokenPar.name("userId")
 .description("测试⽤户1")
 .defaultValue("1")
 .modelRef(new ModelRef("string"))
 .parameterType("header")
 .required(false)
 .build();
 parameters.add(tokenPar.build());
 ParameterBuilder tmpPar = new ParameterBuilder();
 tmpPar.name("userTempId")
 .description("测试⽤户2")
 .defaultValue("1")
 .modelRef(new ModelRef("string"))
 .parameterType("header")
 .required(false)
 .build();
 parameters.add(tmpPar.build());
 //添加head参数end
 return new Docket(DocumentationType.SWAGGER_2)
 .groupName("webApi")
 .apiInfo(webApiInfo())
 .select()
 //可以测试请求头中:输⼊token
 //.apis(RequestHandlerSelectors.withClassAnnotation(ApiOpe
ration.class))
 .apis(RequestHandlerSelectors.basePackage("com.project.sma
rt_campus.controller"))
 //过滤掉admin路径下的所有⻚⾯
 //.paths(Predicates.and(PathSelectors.regex("/sms/.*")))
 //过滤掉所有error或error.*⻚⾯
 //.paths(Predicates.not(PathSelectors.regex("/error.*")))
 .build()
 .globalOperationParameters(parameters);
 }
 private ApiInfo webApiInfo(){
 return new ApiInfoBuilder()
 .title("⽹站-API⽂档")
 .description("本⽂档描述了⽹站微服务接⼝定义")
 .version("1.0")
 .contact(new Contact("sc", "http://mypoject.com", "[email protected]"))
 .build();
 }
 private ApiInfo adminApiInfo(){
 return new ApiInfoBuilder()
 .title("后台管理系统-API⽂档")
 .description("本⽂档描述了后台管理系统微服务接⼝定义")
 .version("1.0")
 .contact(new Contact("sc", "http://mypoject.com", "[email protected]"))
 .build();
 }
}

常⽤配置参数表

智慧校园云端管理系统的设计和实现_第8张图片

swagger常⽤注解表

智慧校园云端管理系统的设计和实现_第9张图片

Swagger2 常⽤注解@ApiOperation@ApiParam

@ApiOperation

(使⽤于在⽅法上,表示⼀个http请求的操作)
● value⽤于⽅法描述
● notes⽤于提示内容
● tags可以重新分组(视情况⽽⽤)

@ApiParam

使⽤在⽅法上或者参数上,字段说明;表示对参数的添加元数据(说明或是否必填等)
● name–参数名
● value–参数说明
● required–是否必填

学⽣管理系统接⼝⽂档示例:

智慧校园云端管理系统的设计和实现_第10张图片

⼯具类

验证码图⽚⽣成类

先定义验证码图⽚的基本属性,随后是验证码图⽚(获取)+验证码(⽣成+获取+绘制)

public class CreateVerifiCodeImage {
 /*
 * 定义⻓宽,字符⼤⼩,验证码,验证码图⽚
 * */
 private static int WIDTH = 90;
 private static int HEIGHT = 35;
 private static int FONT_SIZE = 20;
 private static char[] verifiCode;
 private static BufferedImage verifiCodeImage;
 /**
 * @description: 获取验证码图⽚
 * @param: no
 * @return: java.awt.image.BufferedImage
 */
 public static BufferedImage getVerifiCodeImage() {
 verifiCodeImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_BGR);// create a image
 Graphics graphics = verifiCodeImage.getGraphics();
 verifiCode = generateCheckCode();
 drawBackground(graphics);
 drawRands(graphics, verifiCode);
 graphics.dispose();
 return verifiCodeImage;
 }
 /**
 * @description: 获取验证码
 * @param: no
 * @return: char[]
 */
 public static char[] getVerifiCode() {
 return verifiCode;
 }
 /**
 * @description: 随机⽣成验证码
 * @param: no
 * @return: char[]
 */
 private static char[] generateCheckCode() {
 //从这些数字和字母中选择
String chars = "0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 char[] rands = new char[4];
 for (int i = 0; i < 4; i++) {
 int rand = (int) (Math.random() * (10 + 26 * 2));
 rands[i] = chars.charAt(rand);
 }
 return rands;
 }
 /**
 * @description: 绘制验证码
 * @param: g
 * @param: rands
 * @return: void
 */
 private static void drawRands(Graphics g, char[] rands) {
 g.setFont(new Font("Console", Font.BOLD, FONT_SIZE));
 for (int i = 0; i < rands.length; i++) {
 g.setColor(getRandomColor());
 g.drawString("" + rands[i], i * FONT_SIZE + 10, 25);
 }
 }
 /**
 * @description: 绘制验证码图⽚背景
 * @param: g
 * @return: void
 */
 private static void drawBackground(Graphics g) {
 g.setColor(Color.white);
 g.fillRect(0, 0, WIDTH, HEIGHT);
 // 绘制验证码⼲扰点
 for (int i = 0; i < 200; i++) {
 int x = (int) (Math.random() * WIDTH);
 int y = (int) (Math.random() * HEIGHT);
 g.setColor(getRandomColor());
 g.drawOval(x, y, 1, 1);
 }
 }
 
 /**
 * @description: 获取随机颜⾊
 * @param: no
 * @return: java.awt.Color
 */
 private static Color getRandomColor() {
 Random ran = new Random();
 return new Color(ran.nextInt(220), ran.nextInt(220), ran.nextInt(220));
 }
}

JwtHelper

token⼝令⽣成

public class JwtHelper {
 private static long tokenExpiration = 24*60*60*1000;
 private static String tokenSignKey = "123456";
 //⽣成token字符串
 public static String createToken(Long userId, Integer userType) {
 String token = Jwts.builder()
 .setSubject("YYGH-USER")
 .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
 .claim("userId", userId)
// .claim("userName", userName)
 .claim("userType", userType)
 .signWith(SignatureAlgorithm.HS512, tokenSignKey)
 .compressWith(CompressionCodecs.GZIP)
 .compact();
 return token;
 }
 //从token字符串获取userid
 public static Long getUserId(String token) {
 if(StringUtils.isEmpty(token)) return null;
 Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
 Claims claims = claimsJws.getBody();
 Integer userId = (Integer)claims.get("userId");
 return userId.longValue();
 }
 //从token字符串获取userType
 public static Integer getUserType(String token) {
 if(StringUtils.isEmpty(token)) return null;
 Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
 Claims claims = claimsJws.getBody();
 return (Integer)(claims.get("userType"));
 }
 //从token字符串获取userName
 public static String getUserName(String token) {
 if(StringUtils.isEmpty(token)) return "";
 Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
 Claims claims = claimsJws.getBody();
 return (String)claims.get("userName");
 }
 //判断token是否有效
 public static boolean isExpiration(String token){
 try {
 boolean isExpire = Jwts.parser()
 .setSigningKey(tokenSignKey)
 .parseClaimsJws(token)
 .getBody()
 .getExpiration().before(new Date());
 //没有过期,有效,返回false
 return isExpire;
 }catch(Exception e) {
 //过期出现异常,返回true
 return true;
 }
 }
 /**
 * 刷新Token
 * @param token
 * @return
 */
 public String refreshToken(String token) {
 String refreshedToken;
 try {
 final Claims claims = Jwts.parser()
 .setSigningKey(tokenSignKey)
 .parseClaimsJws(token)
 .getBody();
 refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));
 } catch (Exception e) {
 refreshedToken = null;
 }
 return refreshedToken;
 }
 
}

AuthContextHolder类

从request请求中获取token⼝令

public class AuthContextHolder {
 //从请求头token获取userid
 public static Long getUserIdToken(HttpServletRequest request) {
 //从请求头token
 String token = request.getHeader("token");
 //调⽤⼯具类
 Long userId = JwtHelper.getUserId(token);
 return userId;
 }
 //从请求头token获取name
 public static String getUserName(HttpServletRequest request) {
 //从header获取token
 String token = request.getHeader("token");
 //jwt从token获取username
 String userName = JwtHelper.getUserName(token);
 return userName;
 }
}

MD5加密类

public final class MD5 {
 public static String encrypt(String strSrc) {
 try {
 char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8',
 '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 //getBytes(String charsetName): 使⽤指定的字符集将字符串编码为 byt
e 序列,并将结果存储到⼀个新的 byte 数组中。
 byte[] bytes = strSrc.getBytes();
 //获取MD5摘要算法的MessageDiges 的对象
 MessageDigest md=MessageDigest.getInstance("MD5");
 //使⽤了指定字节更新摘要
 md.update(bytes);
 //对于给定数量的更新数据,digest ⽅法只能被调⽤⼀次。在调⽤ digest 之
后,MessageDigest 对象被重新设置成其初始状态。
 bytes = md.digest();
 // 获取初识状态下摘要的⻓度
 int j = bytes.length;
 char[] chars = new char[j * 2];
 int k = 0;
 for (int i = 0; i < bytes.length; i++) {
 byte b = bytes[i];
 chars[k++] = hexChars[b >>> 4 & 0xf];
 chars[k++] = hexChars[b & 0xf];
 }
 //返回加密后的md5密钥串
 return new String(chars);
 } catch (NoSuchAlgorithmException e) {
 e.printStackTrace();
 throw new RuntimeException("MD5加密出错!!+" + e);
 }
 }
}

全局统⼀返回类



@Data
@ApiModel(value = "全局统⼀返回结果")
public class Result<T> {
 @ApiModelProperty(value = "返回码")
 private Integer code;
 @ApiModelProperty(value = "返回消息")
 private String message;
 @ApiModelProperty(value = "返回数据")
 private T data;
 public Result(){}
 // 返回数据
 protected static <T> Result<T> build(T data) {
 Result<T> result = new Result<T>();
 if (data != null)
 result.setData(data);
 return result;
 }
 public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
 Result<T> result = build(body);
 result.setCode(resultCodeEnum.getCode());
 result.setMessage(resultCodeEnum.getMessage());
 return result;
 }
 public static<T> Result<T> ok(){
 return Result.ok(null);
 }
 /**
 * 操作成功
 * @param data
 * @param 
 * @return
 */
 public static<T> Result<T> ok(T data){
 Result<T> result = build(data);
 return build(data, ResultCodeEnum.SUCCESS);
 }
 public static<T> Result<T> fail(){
 return Result.fail(null);
 }
 /**
 * 操作失败
 * @param data
 * @param 
 * @return
 */
 public static<T> Result<T> fail(T data){
 Result<T> result = build(data);
 return build(data, ResultCodeEnum.FAIL);
 }
 public Result<T> message(String msg){
 this.setMessage(msg);
 return this;
 }
 public Result<T> code(Integer code){
 this.setCode(code);
 return this;
 }
 public boolean isOk() {
 if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {
 return true;
 }
 return false;
 }
}

智慧校园云端管理系统的设计和实现_第11张图片

返回状态结果响应类

@Getter
public enum ResultCodeEnum {
 SUCCESS(200,"成功"),
 FAIL(201, "失败"),
 SERVICE_ERROR(2012, "服务异常"),
 ILLEGAL_REQUEST( 204, "⾮法请求"),
 PAY_RUN(205, "⽀付中"),
 ARGUMENT_VALID_ERROR(206, "参数校验错误"),
 LOGIN_ERROR(207, "⽤户名或密码错误"),
 LOGIN_AUTH(208, "未登陆"),
 PERMISSION(209, "没有权限"),
 SECKILL_NO_START(210, "秒杀还没开始"),
 SECKILL_RUN(211, "正在排队中"),
 SECKILL_NO_PAY_ORDER(212, "您有未⽀付的订单"),
 SECKILL_FINISH(213, "已售罄"),
 SECKILL_END(214, "秒杀已结束"),
 SECKILL_SUCCESS(215, "抢单成功"),
 SECKILL_FAIL(216, "抢单失败"),
 SECKILL_ILLEGAL(217, "请求不合法"),
 SECKILL_ORDER_SUCCESS(218, "下单成功"),
 COUPON_GET(220, "优惠券已经领取"),
 COUPON_LIMIT_GET(221, "优惠券已发放完毕"),
 //2022-02-22
 LOGIN_CODE(222,"⻓时间未操作,会话已失效,请刷新⻚⾯后重试!"),
 CODE_ERROR(223,"验证码错误!"),
 TOKEN_ERROR(224,"Token⽆效!");
 private Integer code;
 private String message;
 private ResultCodeEnum(Integer code, String message) {
 this.code = code;
 this.message = message;
 }
}

⽂件上传类


public class UploadFile {
 //存储⽂件上传失败的错误信息
 private static Map<String, Object> error_result = new HashMap<>();
 //存储头像的上传结果信息
 private static Map<String, Object> upload_result = new HashMap<>();
 /**
 * @description: 效验所上传图⽚的⼤⼩及格式等信息...
 * @param: photo
 * @param: path
 * @return: java.util.Map
 */
 private static Map<String, Object> uploadPhoto(MultipartFile photo, String path) {
 //限制头像⼤⼩(20M)
 int MAX_SIZE = 20971520;
 //获取图⽚的原始名称
 String orginalName = photo.getOriginalFilename();
 //如果保存⽂件的路径不存在,则创建该⽬录
 File filePath = new File(path);
 if (!filePath.exists()) {
 filePath.mkdirs();
 }
 //限制上传⽂件的⼤⼩
 if (photo.getSize() > MAX_SIZE) {
 error_result.put("success", false);
 error_result.put("msg", "上传的图⽚⼤⼩不能超过20M哟!");
 return error_result;
 }
 // 限制上传的⽂件类型
 String[] suffixs = new String[]{".png", ".PNG", ".jpg", ".JPG", ".jpeg", ".JPEG", ".gif", ".GIF", ".bmp", ".BMP"};
 SuffixFileFilter suffixFileFilter = new SuffixFileFilter(suffixs);
 if (!suffixFileFilter.accept(new File(path + orginalName))) {
 error_result.put("success", false);
 error_result.put("msg", "禁⽌上传此类型⽂件! 请上传图⽚哟!");
 return error_result;
 }
 return null;
 }
 /**
 * @description: (提取公共代码 : 提⾼代码的可重⽤性)获取头像的上传结果信息
 * @param: photo
 * * @param: dirPaht
 * @param: portraitPath
 * @return: java.util.Map
 */
 public static Map<String, Object> getUploadResult(MultipartFile photo, String dirPaht, String portraitPath) {
 if (!photo.isEmpty() && photo.getSize() > 0) {
 //获取图⽚的原始名称
 String orginalName = photo.getOriginalFilename();
 //上传图⽚,error_result:存储头像上传失败的错误信息
 Map<String, Object> error_result = UploadFile.uploadPhoto(photo, dirPaht);
 if (error_result != null) {
 return error_result;
 }
 //使⽤UUID重命名图⽚名称(uuid__原始图⽚名称)
 String newPhotoName = UUID.randomUUID() + "__" + orginalName;
 //将上传的⽂件保存到⽬标⽬录下
 try {
 photo.transferTo(new File(dirPaht + newPhotoName));
 upload_result.put("success", true);
 upload_result.put("portrait_path", portraitPath + newPhotoName);//将存储头像的项⽬路径返回给⻚⾯
 } catch (IOException e) {
 e.printStackTrace();
 upload_result.put("success", false);
 upload_result.put("msg", "上传⽂件失败! 服务器端发⽣异常!");
 return upload_result;
 }
 } else {
 upload_result.put("success", false);
 upload_result.put("msg", "头像上传失败! 未找到指定图⽚!");
 }
 return upload_result;
 }
}

pojo和mapper类

智慧校园云端管理系统的设计和实现_第12张图片

根据数据库表的信息,可以借助mybatis的逆向⼯程⽣成。

配⾄pom.xml


<dependencies>
 <dependency>
 <groupId>org.mybatisgroupId>
 <artifactId>mybatisartifactId>
 <version>3.5.7version>
 dependency>
dependencies>
 

<build>
 
 
 <plugins>
 
 
 <plugin>
 <groupId>org.mybatis.generatorgroupId>
 <artifactId>mybatis-generator-maven-pluginartifactId>
 <version>1.3.0version>
 
 
 <dependencies>
 
 
 <dependency>
 <groupId>org.mybatis.generatorgroupId>
 <artifactId>mybatis-generator-coreartifactId>
 <version>1.3.2version>
 dependency>
 
 
 <dependency>
 <groupId>com.mchangegroupId>
 <artifactId>c3p0artifactId>
 <version>0.9.2version>
 dependency>
 
 
 <dependency>
 <groupId>mysqlgroupId>
 <artifactId>mysql-connector-javaartifactId>
 <version>8.0.27version>
 dependency>
 dependencies>
  plugin>
 plugins>
build>

配置generatorConfig.xml


DOCTYPE generatorConfiguration
 PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//E
N"
 "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
 
 <context id="DB2Tables" targetRuntime="MyBatis3">
 
 <jdbcConnection driverClass="com.mysql.jdbc.Driver"
 connectionURL="jdbc:mysql://..../sc_tb"
 userId="root"
 password="123456">
 jdbcConnection>
 
 <javaModelGenerator targetPackage="com.project.smart_campus.pojo"
targetProject=".\src\main\java">
 <property name="enableSubPackages" value="true" />
 <property name="trimStrings" value="true" />
 javaModelGenerator>
 
 <sqlMapGenerator targetPackage="com.project.smart_campus.mapper" 
targetProject=".\src\main\resources">
 <property name="enableSubPackages" value="true" />
 sqlMapGenerator>
 
 <javaClientGenerator type="XMLMAPPER" targetPackage="com.project.s
mart_campus.mapper" targetProject=".\src\main\java">
 <property name="enableSubPackages" value="true" />
 javaClientGenerator>
 
 
 
 <table tableName="tb_test" domainObjectName="Test"/>
 context>
generatorConfiguration>

执⾏generate⽬标

智慧校园云端管理系统的设计和实现_第13张图片

⽣成相对应的mapper类和pojo类

智慧校园云端管理系统的设计和实现_第14张图片

功能开发

登录功能分析

输⼊⽤户账户和密码,验证码,然后进⾏登录校验,通过登录校验后,跳转⾄⾸⻚功能。
与此同时,该系统所有⽤户都必须登录后才能跳转到后台⾸⻚,所以,登录功能在全局系统控制器的代
码中实现。

验证码功能实现

智慧校园云端管理系统的设计和实现_第15张图片

智慧校园云端管理系统的设计和实现_第16张图片

请求的是后端⽅法getVerifiCodeImage,该⽅法中,先获取请求和响应的参数,获取从⼯具类中创
建的图⽚,获取图⽚上的验证码⽂本,将验证码图⽚响应给浏览器。

@ApiOperation("获取验证码⽅法")
 @GetMapping("/getVerifiCodeImage")
 public void getVerifiCodeImage(
 @ApiParam("请求") HttpServletRequest request, @ApiParam("响应") HttpServletResponse response){
 //获取图⽚
 BufferedImage verifiCodeImage= CreateVerifiCodeImage.getVerifiCodeImage();
 //获取图⽚上的验证码
 String verifiCode=new String(CreateVerifiCodeImage.getVerifiCode());
 //将验证码⽂本放⼊session 域,为下⼀次验证做准备
 HttpSession session=request.getSession();
  session.setAttribute("verifiCode",verifiCode);
 /*
 * 将验证码图⽚响应到浏览器 response输出流
 * 将⽣成的验证码图⽚,按照PNG格式传给浏览器。
 * */
 try {
 ServletOutputStream outputStream= response.getOutputStream();
 ImageIO.write(verifiCodeImage,"PNG",outputStream);
 } catch (IOException e) {
 e.printStackTrace();
 }
 }

登录校验功能

登录校验功能⾸先需要判断,⽤户输⼊的验证码和系统图⽚的验证码⽂本是否⼀致,如若不⼀致,
则会提示验证码有误,请刷新后重试。如若判断⼀致后,会先将现有session中移除现有验证码,在进⾏
⽤户类型验证(管理员,学⽣,⽼师)。
在这⾥,采⽤map类型,进⾏⽤户响应数据的存放,将传⼊的⽤户类型分为三种,1代表管理员,2代表
学⽣,3 代表⽼师。(以管理员⽤户为例)将传⼊的对象,在数据库进⾏查询,如果查询找到了,则为
admin对象。如果没有找到,则admin对象为null,那么说明⽤户名或者密码错误。
在这里插入图片描述

 /*
 * 登录校验
 * */
 @ApiOperation("登录的⽅法")
 @PostMapping("/login")
 //传⼊两个参数,⼀个是系统的验证码图⽚,⼀个是⽤户输⼊的验证码
 public Result login(@ApiParam("登录提交的表单")@RequestBody LoginForm lo
ginForm,HttpServletRequest request){
 //验证码
 HttpSession session=request.getSession();
 String sessionVerifiCode=(String) session.getAttribute("verifiCod
e");
 String loginVerifiCode=loginForm.getVerifiCode();
 //验证码判断,是否失效或者为空
 if ("".equals(sessionVerifiCode ) || null==sessionVerifiCode){
 return Result.fail().message("验证码失效,请刷新后重试");
 }
 //判断⽤户输⼊验证码和系统验证码是否相同,不区分⼤⼩写
 if (!sessionVerifiCode.equalsIgnoreCase(loginVerifiCode)){
 return Result.fail().message("验证码有误,请输⼊后重试");
 }
 //从session移除现有验证码
 session.removeAttribute("verifiCode");
 //分⽤户类型验证 管理员,学⽣,⽼师等
 //准备⼀个map⽤户存放响应的数据
 Map<String,Object> map=new LinkedHashMap<>();
 switch (loginForm.getUserType()){
 //管理员表
 case 1:
 try {
 //传⼊的对象,判断登录,数据库中查询,找到为admin,如果为null,
即没有找到。
 Admin admin= adminService.login(loginForm);
 if (null !=admin){
 //⽤户的id 和类型,转换为⼀个密⽂,以token形式的名称反馈前String token= JwtHelper.createToken(admin.getId().
longValue(),1);
 map.put("token",token);
 }else {
 throw new RuntimeException("⽤户名或者密码有误");
 }
 return Result.ok(map);
 }catch (RuntimeException e){
 e.printStackTrace();
 //异常对象抛出来的信息 new RuntimeException("⽤户名或者密
码有误");
 return Result.fail().message(e.getMessage());
 }
 //学⽣信息
 case 2:
 try {
 Student student= studentService.login(loginForm);
 if (null !=student){
 String token=JwtHelper.createToken(student.getId
().longValue(),2);
 map.put("token",token);
 }else {
 throw new RuntimeException("⽤户名或者密码错误");
 }
 return Result.ok(map);
 }catch (RuntimeException e){
 e.printStackTrace();
 return Result.fail().message(e.getMessage());
 }
 case 3:
 try {
 Teacher teacher= teacherService.login(loginForm);
 if (null !=teacher){
 String token=JwtHelper.createToken(teacher.getId
().longValue(),3);
 map.put("token",token);
 }else {
 throw new RuntimeException("⽤户名或者密码错误");
 }
 return Result.ok(map);
 }catch (RuntimeException e){
 e.printStackTrace();
 return Result.fail().message(e.getMessage());
 }
 }
 return Result.fail().message("查⽆此⼈");
 }

登录后跳转功能

在登录过程中,先请求login,再次请求getinfo ,来判断登录⻚⾯。

在这里插入图片描述
请求login⻚⾯:
智慧校园云端管理系统的设计和实现_第17张图片
响应码:200

信息:成功

data对象:⽤户id+类型+token有效时间 =>⽣成密⽂
智慧校园云端管理系统的设计和实现_第18张图片
第⼆次请求(在login请求成功后,会请求访问getinfo⻚⾯):

智慧校园云端管理系统的设计和实现_第19张图片
第⼆次请求中也带有⼀个token。
智慧校园云端管理系统的设计和实现_第20张图片
请求信息头:
智慧校园云端管理系统的设计和实现_第21张图片
响应admin 的数据信息:
智慧校园云端管理系统的设计和实现_第22张图片
源码

@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
 @Autowired
 private AdminService adService;
 @Autowired
 private StudentService studentService;
 @Autowired
 private TeacherService teacherService;
 /*
 * token 判断登录
 * */
 @ApiOperation("通过taken⼝令来获取当前登录的⽤户信息的⽅法")
 @GetMapping("/getInfo")
 public Result getInfoByToken(
 //请求头 token
 @ApiParam("token⼝令") @RequestHeader("token") String token){
 boolean expiration=JwtHelper.isExpiration(token);//验证token是否过
期。
 if (expiration){
 //token⽆效
 return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
 }
 //从token解析出 ⽤户id+⽤户类型
 Long userId=JwtHelper.getUserId(token);
 Integer userType=JwtHelper.getUserType(token);
 //判断登录状态
 Map<String,Object> map=new LinkedHashMap<>();
 //⽤户类型
 switch (userType){
 case 1:
 //根据adminid查询⼀个对象,键值对
 Admin admin=adminService.getAdminById(userId);
 map.put("userType",1);
 map.put("user",admin);
 break;
 case 2:
 Student student=studentService.getStudentById(userId);
 map.put("userType",2);
 map.put("user",student);
 break;
 case 3:
 Teacher teacher=teacherService.getByTeacherById(userId);
 map.put("userType",3);
 map.put("user",teacher);
 break;
 }
 return Result.ok(map);
 }
}

智慧校园云端管理系统的设计和实现_第23张图片
这段代码同时可以优化为以下代码,(后续不少代码给出的是优化后或有⼀定变动后的代码)

@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
 private static final int ADMIN_USER_TYPE = 1;
private static final int STUDENT_USER_TYPE = 2;
private static final int TEACHER_USER_TYPE = 3;
 private final AdminService adService;
private final StudentService studentService;
private final TeacherService teacherService;
@Autowired
public SystemController(AdminService adService, StudentService student
Service, TeacherService teacherService) {
 this.adService = adService;
 this.studentService = studentService;
 this.teacherService = teacherService;
}
 /*
 * token 判断登录
 * */
 @ApiOperation("通过taken⼝令来获取当前登录的⽤户信息的⽅法")
 @GetMapping("/getInfo")
 public Result getInfoByToken(
 //请求头 token
 @ApiParam("token⼝令") @RequestHeader("token") String token){
 boolean isTokenExpired=JwtHelper.isExpiration(token);//验证token是
否过期。
 if (isTokenExpired){
 //token⽆效
 return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
 }
 //从token解析出 ⽤户id+⽤户类型
 Long userId=JwtHelper.getUserId(token);
 Integer userType=JwtHelper.getUserType(token);
 //判断登录状态
 Map<String,Object> map=new LinkedHashMap<>();
 //⽤户类型
 if (userType == ADMIN_USER_TYPE) {
 // 处理管理员⽤户逻辑
 Admin admin=adminService.getAdminById(userId);
 map.put("userType",1);
 map.put("user",admin);
 break;
} else if (userType == STUDENT_USER_TYPE) {
 // 处理学⽣⽤户逻辑
 Student student=studentService.getStudentById(userId);
 map.put("userType",2);
 map.put("user",student);
 break;
} else if (userType == TEACHER_USER_TYPE) {
 // 处理教师⽤户逻辑
 Teacher teacher=teacherService.getByTeacherById(userId);
 map.put("userType",3);
 map.put("user",teacher);
 break;
} else {
 // 处理其他⽤户类型逻辑
 return Result.ok(map);
}
}

系统管理器实现

验证码响应图⽚功能实现

验证码图⽚请求

智慧校园云端管理系统的设计和实现_第24张图片

Controller层代码

/*

  • 响应验证码图⽚的流程
  • 匹配处理器⽅法路径
 * */
 @ApiOperation("获取验证码⽅法")
 @GetMapping("/getVerifiCodeImage")
 public void getVerifiCodeImage(
 @ApiParam("请求") HttpServletRequest request,
 @ApiParam("响应") HttpServletResponse response){
 //获取图⽚
 BufferedImage verifiCodeImage= CreateVerifiCodeImage.getVerifiCode
Image();
 //获取图⽚上的验证码
 String verifiCode=new String(CreateVerifiCodeImage.getVerifiCode
());
 //将验证码⽂本放⼊session 域,为下⼀次验证做准备
 HttpSession session=request.getSession();
 session.setAttribute("verifiCode",verifiCode);
 /*
 * 将验证码图⽚响应到浏览器 response输出流
 * 将⽣成的验证码图⽚,按照PNG格式传给浏览器。
 * */
 try {
 ServletOutputStream outputStream= response.getOutputStream();
 ImageIO.write(verifiCodeImage,"PNG",outputStream);
 } catch (IOException e) {
 e.printStackTrace();
 }
 }

在这里插入图片描述

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第25张图片

异步图⽚上传头像功能实现

该操作响应流程

智慧校园云端管理系统的设计和实现_第26张图片

Controller层代码

@ApiOperation("⽂件上传统⼀⼊⼝")
@PostMapping("/headerImgUpload")
public Result headerImgUpload(
 @ApiParam("头像⽂件") @RequestParam("file") MultipartFile file,
 HttpServletRequest request
) {
 if (file.isEmpty()) {
 return Result.error("⽂件为空");
 }
 String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCas
e();
 String originalFilename = file.getOriginalFilename();
 String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
 String newFileName = uuid + fileExtension;
 String uploadDirectory = "D:/ideaProjects/smart_campus/target/classes/public/upload/";
 String portraitPath = uploadDirectory + newFileName;
 try {
 Files.createDirectories(Paths.get(uploadDirectory));
 file.transferTo(new File(portraitPath));
 } catch (IOException e) {
 e.printStackTrace();
 return Result.error("⽂件上传失败");
 }
 String path = "upload/" + newFileName;
 return Result.ok(path);
}

智慧校园云端管理系统的设计和实现_第27张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第28张图片

全局修改密码功能实现

Controller层代码

@ApiOperation("全局密码更新器")
@PostMapping("/updatePwd/{oldPwd}/{newPwd}")
public Result updatePwd(
 @ApiParam("token⼝令") @RequestHeader("token") String token,
 @ApiParam("旧密码") @PathVariable("oldPwd") String oldPwd,
 @ApiParam("新密码") @PathVariable("newPwd") String newPwd
) {
 boolean expiration = JwtHelper.isExpiration(token);
 if (expiration) {
 // token 过期
 return Result.fail().message("token过期,请重新登录");
 }
 // 获取⽤户id和⽤户类型
 Long userId = JwtHelper.getUserId(token);
 Integer userType = JwtHelper.getUserType(token);
 // 定义⽤户实体类和服务类
 BaseUser user = null;
 BaseService<BaseUser> userService = null;
 // 根据⽤户类型选择对应的实体类和服务类
 switch (userType) {
 case 1:
 user = adminService.getById(userId);
 userService = adminService;
 break;
 case 2:
 user = studentService.getById(userId);
 userService = studentService;
 break;
 case 3:
 user = teacherService.getById(userId);
 userService = teacherService;
 break;
 }
 // 验证⽤户和密码
 if (user != null && user.getPassword().equals(MD5.encrypt(oldPwd))) {
 // 修改密码
 user.setPassword(MD5.encrypt(newPwd));
 userService.saveOrUpdate(user);
 return Result.ok().message("密码修改成功");
 } else {
 return Result.fail().message("原密码有误!");
 }
}

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第29张图片

管理员管理功能实现

进⼊管理员管理界⾯

智慧校园云端管理系统的设计和实现_第30张图片

查询管理员信息

先看查询数据流的请求信息

在这里插入图片描述
根据请求路径,到后端请求地址

智慧校园云端管理系统的设计和实现_第31张图片
Controller层代码

@Autowired
private AdminService adminService;
/*
* /sms/adminController/getAllAdmin/1/3
* 分⻚查询
* */
@ApiOperation("分⻚查询功能")
@GetMapping("/getAllAdmin/{pageNo}/{pageSize}")
public Result getAllAdmin(
 @ApiParam("⻚码") @PathVariable("pageNo") Integer pageNo,
 @ApiParam("⻚⼤⼩") @PathVariable("pageSize") Integer pageSize,
 @ApiParam("管理员名字") String adminName
){
 Page<Admin> page = new Page<>(pageNo, pageSize);
 IPage<Admin> iPage = adminService.getAdminsByOpr(page, adminName);
 return Result.ok(iPage);
}

service层代码

@Override
public IPage<Admin> getAdminsByOpr(Page<Admin> page, String adminName) {
 QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
 if (!StringUtils.isEmpty(adminName)) {
 queryWrapper.like("name", adminName);
 }
 queryWrapper.orderByDesc("id");
 return baseMapper.selectPage(page, queryWrapper);
}

该请求响应为:
智慧校园云端管理系统的设计和实现_第32张图片

swagger测试接⼝:
智慧校园云端管理系统的设计和实现_第33张图片

添加和修改管理员信息

弹出添加表单,填写相关信息。
智慧校园云端管理系统的设计和实现_第34张图片

数据流请求地址
智慧校园云端管理系统的设计和实现_第35张图片
Controller层代码

@ApiOperation("增加或者修改管理员信息")
@PostMapping("/saveOrUpdateAdmin")
public Result saveOrUpdateAdmin(@ApiParam("JSON格式的Admin对象") @RequestBo
dy Admin admin) {
 if (admin.getId() == null || admin.getId() == 0) {
 admin.setPassword(MD5.encrypt(admin.getPassword()));
 }
 adminService.saveOrUpdate(admin);
 return Result.ok();
}

在这⾥区分⼀下增加和修改操作。

  1. admin 对象的 id 是否为 null 或者为 0。如果是,则表示这是⼀个新增的管理员,需要对密码进⾏加密处 理。
  2. 如果 id 不为 null 或者不为 0,则表示这是⼀个修改操作,不需要对密码进⾏处理

请求响应头

智慧校园云端管理系统的设计和实现_第36张图片
swagger测试接⼝
智慧校园云端管理系统的设计和实现_第37张图片

删除和批量删除管理员信息

删除操作请求数据流

智慧校园云端管理系统的设计和实现_第38张图片
Controller层代码

@ApiOperation("删除单个⽤户或者批量删除多个⽤户")
@DeleteMapping("/deleteAdmin")
public Result deleteAdmin(@ApiParam("删除管理员⽤户的id的JSON集合") @RequestB
ody List<Integer> ids) {
 if (ids.size() == 1) {
 // 单⼀删除逻辑
 adminService.removeById(ids.get(0));
 } else {
 // 批量删除逻辑
 adminService.removeByIds(ids);
 }
 return Result.ok();
}

通过判断ids列表的⻓度,来区分是单⼀删除还是批量删除
如果⻓度为1,则执⾏单⼀删除逻辑,调⽤adminService.removeById(ids.get(0))⽅法删除对应的管理员⽤户;
如果⻓度⼤于1,则执⾏批量删除逻辑,调⽤adminService.removeByIds(ids)⽅法删除对应的管理员⽤户。

该请求响应操作

在这里插入图片描述
swagger测试接⼝

智慧校园云端管理系统的设计和实现_第39张图片

年级管理功能实现

查询年级信息

先查询数据流的请求信息

在这里插入图片描述

根据请求路径,到后端请求地址
智慧校园云端管理系统的设计和实现_第40张图片

Controller层代码

@Api(tags = "年级控制器")
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
 private final GradeService gradeService;
 public GradeController(GradeService gradeService) {
 this.gradeService = gradeService;
 }
 @ApiOperation("查询年级信息,分⻚带条件")
 @GetMapping("/getGrades")
 public Result getGrades(
 @ApiParam("分⻚查询⻚码数") @RequestParam(value = "pageNo", defa
ultValue = "1") Integer pageNo,
 @ApiParam("分⻚查询⻚⼤⼩") @RequestParam(value = "pageSize", de
faultValue = "10") Integer pageSize,
 @ApiParam("分⻚查询模糊匹配班级名") @RequestParam(value = "gradeN
ame", required = false) String gradeName) {
 Page<Grade> page = new Page<>(pageNo, pageSize);
 IPage<Grade> pageRs = gradeService.getGradeByOpr(page, gradeName);
 return Result.ok(pageRs);
 }
}

Service层代码

@Service
@Transactional
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> impl
ements GradeService {
 private final GradeMapper gradeMapper;
 public GradeServiceImpl(GradeMapper gradeMapper) {
 this.gradeMapper = gradeMapper;
 }
 @Override
 public IPage<Grade> getGradeByOpr(Page<Grade> pageParam, String gradeN
ame) {
 // 设置查询条件
 QueryWrapper<Grade> queryWrapper = new QueryWrapper<>();
 if (!StringUtils.isEmpty(gradeName)) {
 queryWrapper.like("name", gradeName);
 }
 // 设置排序规则
 queryWrapper.orderByDesc("id");
 queryWrapper.orderByAsc("name");
 // 分⻚查询数据
 IPage<Grade> page = gradeMapper.selectPage(pageParam, queryWrappe
r);
 return page;
 }
}

该请求响应头

智慧校园云端管理系统的设计和实现_第41张图片

swagger测试接⼝功能

智慧校园云端管理系统的设计和实现_第42张图片

添加和修改年级信息

添加年级表单,填⼊数据。

智慧校园云端管理系统的设计和实现_第43张图片

数据流的请求头

在这里插入图片描述

Controller层代码

@Api(tags = "年级控制器")
@RestController
@RequestMapping("/sms/gradeController")
public class GradeController {
 private final GradeService gradeService;
 @Autowired
 public GradeController(GradeService gradeService) {
 this.gradeService = gradeService;
 }
 @ApiOperation("添加或者修改年级信息")
 @PostMapping("/saveOrUpdateGrade")
 public Result saveOrUpdateGrade(@ApiParam("JSON的grade对象转换后台数据模
型") @RequestBody Grade grade) {
 // 调⽤服务层⽅法,实现添加或者修改年级信息
 gradeService.saveOrUpdate(grade);
 return Result.ok();
 }
}

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第44张图片

删除和批量删除年级信息

删除操作请求数据流
智慧校园云端管理系统的设计和实现_第45张图片

Controller层代码

private final GradeService gradeService;
public GradeController(GradeService gradeService) {
 this.gradeService = gradeService;
}
@ApiOperation("删除⼀个或者多个grade信息")
@DeleteMapping("/deleteGrade")
public Result deleteGradeById(
 @ApiParam("JSON的年级id集合,映射为后台List") @RequestBody Li
st<Integer> ids
) {
 gradeService.removeByIds(ids);
 return Result.ok();
}

请求后的响应

智慧校园云端管理系统的设计和实现_第46张图片
swagger测试接⼝

智慧校园云端管理系统的设计和实现_第47张图片

班级管理功能实现

搜索条件中的年级选项

智慧校园云端管理系统的设计和实现_第48张图片

Controller层代码

@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层代码

@Service
@Transactional
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> implements GradeService {
public List<Grade> getGrades(){
 List<Grade> grades = baseMapper.selectList(null);
 return grades;
 }
}

mapper层代码

public interface BaseMapper<T> extends Mapper<T>{
 List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
}

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第49张图片

查询班级信息

先看查询数据流的请求信息
在这里插入图片描述

根据请求路径,到后端请求地址

智慧校园云端管理系统的设计和实现_第50张图片

Controller层代码

@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 pageSiz
e,
 @ApiParam("查询条件") Clazz clazz
 ){
 //设置分⻚信息
 Page<Clazz> page =new Page<>(pageNo,pageSize);
 IPage<Clazz> iPage = clazzService.getClazzsByOpr(page, clazz);
 return Result.ok(iPage);
 }
}

service层代码

@Service
@Transactional
public class ClazzServiceImpl extends ServiceImpl<ClazzMapper, Clazz> impl
ements ClazzService {
 /**
 * 分⻚查询所有班级信息【带条件】
 * @param clazz
 * @return
 */
 @Override
 public IPage<Clazz> getClazzsByOpr(Page<Clazz> pageParam,Clazz clazz)
{
 QueryWrapper 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.orderByDesc("id");
 queryWrapper.orderByAsc("name");
 }
 Page page = baseMapper.selectPage(pageParam, queryWrapper);
 return page;
 }
}

该请求响应头

智慧校园云端管理系统的设计和实现_第51张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第52张图片

添加和修改班级信息

填写表单,添加数据

智慧校园云端管理系统的设计和实现_第53张图片

该数据流请求头

智慧校园云端管理系统的设计和实现_第54张图片

Controller层代码

@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();
 }
}

请求响应后
在这里插入图片描述
增加

智慧校园云端管理系统的设计和实现_第55张图片
修改

智慧校园云端管理系统的设计和实现_第56张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第57张图片

删除和批量删除班级信息

删除响应:

智慧校园云端管理系统的设计和实现_第58张图片

Controller层代码

public class ClazzController {
private final ClazzService clazzService;
public ClazzController(ClazzService clazzService) {
 this.clazzService = clazzService;
}
@ApiOperation("删除⼀个或者多个班级信息")
@DeleteMapping("/deleteClazz")
public Result deleteClazzByIds(
 @ApiParam("多个班级id的JSON") @RequestBody List<Integer> ids
){
 clazzService.removeByIds(ids);
 return Result.ok();
}
}

请求响应后
在这里插入图片描述

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第59张图片

教师管理功能实现

搜索条件中班级选项

智慧校园云端管理系统的设计和实现_第60张图片

Controller层代码

//查询所有班级信息
 @ApiOperation("查询所有班级的信息")
 @GetMapping("/getClazzs")
 public Result getClazzs(){
 List<Clazz> clazzes=clazzService.getClazzs();
 return Result.ok(clazzes);
 }

service层代码

@Service("clazzServiceImpl")
@Transactional //事务控制
public class ClazzServiceImpl extends ServiceImpl<ClazzMapper, Clazz> imple
ments ClazzService {
 @Override
 public List<Clazz> getClazzs() {
 return baseMapper.selectList(null);
 }
}

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第61张图片

查询教师功能实现

先查询数据流的请求信息

在这里插入图片描述

根据请求路径,到后端请求地址

智慧校园云端管理系统的设计和实现_第62张图片

Controller层代码

@Api(tags = "教师信息管理控制器")
@RestController
@RequestMapping("/sms/teacherController")
public class TeacherController {
 @Autowired
 private TeacherService teacherService;
 
 @ApiOperation("获取教师信息,分⻚带条件")
 @GetMapping("/getTeachers/{pageNo}/{pageSize}")
 public Result getTeachers(
 @PathVariable("pageNo") Integer pageNo,
 @PathVariable("pageSize") Integer pageSize,
 Teacher teacher
 ){
 Page<Teacher> pageParam = new Page<>(pageNo,pageSize);
 IPage<Teacher> page = teacherService.getTeachersByOpr(pageParam, t
eacher);
 return Result.ok(page);
 }
}

service层代码

@Override
public IPage<Teacher> getTeachersByOpr(Page<Teacher> pageParam, Teacher te
acher) {
 QueryWrapper queryWrapper = new QueryWrapper();
 if(teacher != null){
 //班级名称条件
 String clazzName = teacher.getClazzName();
 if (!StringUtils.isEmpty(clazzName)) {
 queryWrapper.eq("clazz_name",clazzName);
 }
 //教师名称条件
 String teacherName = teacher.getName();
 if(!StringUtils.isEmpty(teacherName)){
 queryWrapper.like("name",teacherName);
 }
 queryWrapper.orderByDesc("id");
 queryWrapper.orderByAsc("name");
 }
 IPage<Teacher> page = baseMapper.selectPage(pageParam, queryWrapper);
 return page;
}

该请求响应为

智慧校园云端管理系统的设计和实现_第63张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第64张图片

添加和修改教师信息

填写表单数据
智慧校园云端管理系统的设计和实现_第65张图片

该操作请求数据响应头

智慧校园云端管理系统的设计和实现_第66张图片

Controller层代码

@ApiOperation("添加和修改教师信息")
@PostMapping("/saveOrUpdateTeacher")
public Result saveOrUpdateTeacher(
 @RequestBody Teacher teacher
){
 if (teacher.getId() != null) {
 // ID 不为空,执⾏修改操作
 teacherService.update(teacher);
 } else {
 // ID 为空,执⾏增加操作
 teacherService.add(teacher);
 }
 return Result.ok();
}

通过判断teacher对象的id属性是否为空来确定是执⾏增加操作还是修改操作。如果id不为空,则执⾏修改操 作;如果
id为空,则执⾏增加操作。

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第67张图片
删除和批量删除教师信息

该删除操作请求路径

智慧校园云端管理系统的设计和实现_第68张图片
Controller层代码

@ApiOperation("删除⼀个或者多个教师信息")
@DeleteMapping("/deleteTeacher")
public Result deleteTeacher(
 @RequestBody List<Integer> ids
){
 if (ids.size() == 1) {
 // ids 列表只包含⼀个元素,执⾏删除操作
 teacherService.removeById(ids.get(0));
 } else {
 // ids 列表包含多个元素,执⾏批量删除操作
 teacherService.removeByIds(ids);
 }
 return Result.ok();
}

通过判断ids列表的⼤⼩来确定是执⾏删除操作还是批量删除操作。如果ids列表只包含⼀个元素,则执⾏删除操 作;如果
ids列表包含多个元素,则执⾏批量删除操作。

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第69张图片

学⽣管理功能实现

搜索条件中班级选项

智慧校园云端管理系统的设计和实现_第70张图片

Controller层代码

//查询所有班级信息
 @ApiOperation("查询所有班级的信息")
 @GetMapping("/getClazzs")
 public Result getClazzs(){
 List<Clazz> clazzes=clazzService.getClazzs();
 return Result.ok(clazzes);
 }

service层代码

@Service("clazzServiceImpl")
@Transactional //事务控制
public class ClazzServiceImpl extends ServiceImpl<ClazzMapper, Clazz> imple
ments ClazzService {
 @Override
 public List<Clazz> getClazzs() {
 return baseMapper.selectList(null);
 }
}

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第71张图片

查询学⽣功能实现

先查询数据流的请求信息

在这里插入图片描述

Controller层代码

@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, studen
t);
 // 返回学⽣信息
 return Result.ok(iPage);
 }
}

service层代码

@Service("stuService")
@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.orderByDesc("id");
 queryWrapper.orderByAsc("name");
 } 
 //创建分⻚对象
 IPage<Student> pages = baseMapper.selectPage(pageParam, queryWrapp
er);
 return pages;
 }

请求响应

智慧校园云端管理系统的设计和实现_第72张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第73张图片

添加和修改学⽣信息

填写表单数据

智慧校园云端管理系统的设计和实现_第74张图片

该操作数据请求

智慧校园云端管理系统的设计和实现_第75张图片

Controller层代码

@Api(tags = "学⽣控制器")
@RestController
@RequestMapping("/sms/studentController")
public class StudentController {
 @Autowired
 private StudentService studentService;
 @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();
 }
}

根据学⽣对象是否具有唯⼀标识(如学⽣ID)来进⾏判断。如果学⽣对象具有唯⼀标识,则可以将其视为修改 操作;否则,可以将其视为增加操作。

该操作响应

智慧校园云端管理系统的设计和实现_第76张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第77张图片

删除和批量删除学⽣信息

该操作请求路径

智慧校园云端管理系统的设计和实现_第78张图片

Controller层代码

@Api(tags = "学⽣控制器")
@RestController
@RequestMapping("/sms/studentController")
public class StudentController {
 @Autowired
 private StudentService studentService;
 @ApiOperation("删除⼀个或者多个学⽣信息")
 @DeleteMapping("/delStudentById")
 public Result delStudentById(
 @ApiParam("多个学⽣id的JSON") @RequestBody List<Integer> ids
 ){
 studentService.removeByIds(ids);
 return Result.ok();
 }
}

该请求响应数据

智慧校园云端管理系统的设计和实现_第79张图片

swagger测试接⼝

智慧校园云端管理系统的设计和实现_第80张图片

项⽬bug解决

项⽬启动报错“javax.xml.bind.DatatypeConverter”

项⽬启动时没有问题,swagger调接⼝也没有问题,前后端联调的时候出现以下问题,提示:
javax.xml.bind.DatatypeConverter

在这里插入图片描述

JAXB API是java EE 的API,因此在java SE 9.0 中不再包含这个 Jar 包。 java 9
中引⼊了模块的概念,默认情况下,Java SE中将不再包含java EE 的Jar包⽽在 java 6/7 / 8 时关于这个API
都是捆绑在⼀起的 jar包中缺少这⼀依赖-javax.xml.bind.api 导⼊依赖即可。

<dependency>
<groupId>javax.xml.bindgroupId>
<artifactId>jaxb-apiartifactId>
<version>2.3.0version>
dependency>

项⽬总结

智慧校园云端管理系统是⼀个基于前后端分离架构的校园管理系统,主要⽤于管理校内学⽣、
⽼师、班级和年级的相关信息,并提供学⽣和⽼师信息记录和统计的功能。该系统采⽤了以下技术
和⼯具:

  • 前端技术:HTML、CSS和Vue.js,⽤于实现⻚⾯效果展示和交互功能。
  • 后端框架:Spring Boot和MyBatisPlus,⽤于实现数据存储和服务。
  • 数据库:MySQL,作为存储层,提供⾼性能的数据存储和查询。
  • 服务器:使⽤SpringBoot内置的Tomcat 9.x作为Web服务器,⽤于部署和运⾏系统。
  • 项⽬构建⼯具:Maven,⽤于管理项⽬依赖和构建过程。

系统的⽤户⻆⾊包括管理员、⽼师和学⽣。每个⻆⾊都有不同的功能和权限:

  • 管理员⻆⾊:可以进⾏学⽣、⽼师、年级和班级信息的管理,包括添加、编辑和删除操作,还 可以管理个⼈信息和重置账户密码。
  • ⽼师⻆⾊:可以参与相关学⽣和班级信息的管理,包括查看和编辑操作,同时也可以管理个⼈ 信息。
  • 学⽣⻆⾊:可以查看⾃⼰所在班级的信息、同学信息,还可以管理个⼈信息。

通过该系统,管理员可以⽅便地管理校园的核⼼基础业务数据,⽼师和学⽣可以更好地进⾏信息管理和查看。采⽤前后端分离架构使得系统具有良好的可维护性和扩展性。
在项⽬开发过程中,我们遵循了MVC设计模式,合理划分了前后端的职责,提⾼了开发效率和代码质量。同时,我们也注重系统的安全性和性能优化,确保系统的稳定运⾏和良好的⽤户体验。
总体⽽⾔,智慧校园云端管理系统为校园信息化建设提供了⼀个强⼤⽽⾼效的⼯具,帮助管理者更好地管理学⽣、⽼师、班级和年级的相关信息。在未来的发展中,可以进⼀步扩展系统的功能和优化⽤户体验,以满⾜不断变化的需求。

你可能感兴趣的:(项目,java,intellij-idea,spring,boot,mybatis)