智能化校园:深入探讨云端管理系统设计与实现(一)

推荐阅读

轻松驾驭JDBC:一篇文章帮你搞定数据库连接
ChatGPT爆火一周年,快来拥有专属你的ChatGPT应用!


文章目录

  • 推荐阅读
  • 智慧校园云端管理系统的设计和实现
    • 项目简介
    • 项目技术栈
    • 项目功能
    • 项目开发
      • 项目搭建
        • 修改pom.xml文件
        • 项目包结构
        • 配置application.yml文件
          • Hikari
          • jackson
          • mybatis-plus
        • 配置类
          • 分页插件配置类
          • Swagger2的配置类
        • 工具类
          • 验证码图片生成类
          • JwtHelper
          • AuthContextHolder类
          • MD5加密类
          • 全局统一返回类
          • 返回状态结果响应类
          • 文件上传类
        • pojo和mapper类


智能化校园:深入探讨云端管理系统设计与实现(一)_第1张图片

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

项目简介

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

智慧校园指的是信息化为基础构建起来的校园信息化教育管理的一种新的模式,智慧校园能够实现校园工作,学习和生活的一体化发展,在各种信息系统应用的基础上,能实现教学,科研管理和校园生活的有效融合。智慧校园建设所包括的内容很丰富,通过云计算,互联网技术将校园运行中的所有数据有效的联系在一起,通过相关软件系统的有效应用,实现学校智能监控和智能识别的综合信息服务平台的有效构建。
智慧校园有三个基本特征,第一,智慧校园能够提供个性化的服务,通过智能化服务平台及智能感知功能,实现教育管理工作的个性化服务。第二,智慧校园是建立在互联网基础上的, 通过互联网实现信息服务与校园各种应用领域的结合。第三,智慧校园在个性化定制服务的基础上,能够为学校与外部世界的联系提供有效的平台和接口,促进学校资源与外部资源的有效融合。智慧校园是校园信息化的一种高级形式,通过智慧校园可以把学校的物理空间和数字空间结合起来,为师生学习生活,提供智能化的学习生活环境,为师生提供个性化的智能服务。

项目技术栈

智能化校园:深入探讨云端管理系统设计与实现(一)_第2张图片

项目功能

智慧校园云端管理系统的使用者主要包含三种用户角色,其一是管理员角色,其二是老师角色,其三是学生角色。这三个角色的具体功能如下:

  • 管理员角色:管理员登录智慧校园系统后可以进行相应的管理操作,主要包含:学生信息管理、老师信息管理、年级信息管理、班级信息管理、个人信息管理、账户密码重置等操作。
  • 老师用户角色:老师用户登录智慧校园系统后可以进行参与相关学生、班级信息管理的相关操作以及个人信息管理等操作。
  • 学生用户角色:学生进入系统后,主要查看自己的班级,同学信息以及个人信息管理等操作。

智能化校园:深入探讨云端管理系统设计与实现(一)_第3张图片

项目开发

项目搭建

使用idea的springboot脚手架搭建一个maven项目
智能化校园:深入探讨云端管理系统设计与实现(一)_第4张图片
项目创建完成后,更改一下maven的配置,改成自己的本地maven仓库。
智能化校园:深入探讨云端管理系统设计与实现(一)_第5张图片

修改pom.xml文件


	4.0.0

	
	
		org.springframework.boot
		spring-boot-starter-parent
		2.7.13
		 
	
	com.project
	smart_campus
	0.0.1-SNAPSHOT
	smart_campus
	smart_campus

	
		11
	

	

		
			org.springframework.boot
			spring-boot-starter
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
		

		
		
			com.baomidou
			mybatis-plus-boot-starter
			3.3.1
		

		
		
			org.mybatis
			mybatis
			3.5.7
		

		
		
			org.projectlombok
			lombok
			true
		

		
		
			mysql
			mysql-connector-java
			8.0.28
		

		
			com.baomidou
			mybatis-plus-generator
			3.3.1
		
		
			org.freemarker
			freemarker
			2.3.31
		

		
		
			io.springfox
			springfox-swagger2
			2.7.0
		
		
		
			io.springfox
			springfox-swagger-ui
			2.7.0
		
		
		
			com.github.xiaoymin
			knife4j-spring-boot-starter
			2.0.4
		

		
			javax.xml.bind
			jaxb-api
			2.3.0
		


		
		
			org.springframework.boot
			spring-boot-devtools
			true
		

		
			com.alibaba
			fastjson
			1.2.29
		

		
		
			io.jsonwebtoken
			jjwt
			0.7.0
		

		
			commons-fileupload
			commons-fileupload
			1.4
		

	

	
		
			
			
				org.springframework.boot
				spring-boot-maven-plugin
			

			
			
				org.mybatis.generator
				mybatis-generator-maven-plugin
				1.3.0

				
				

					
					
						org.mybatis.generator
						mybatis-generator-core
						1.3.2
					

					
					
						com.mchange
						c3p0
						0.9.2
					

					
					
						mysql
						mysql-connector-java
						8.0.28
					
				
			
		
	


项目包结构
  1. java目录下
  • config : 项目的配置类
  • controller: 控制层
  • mapper : 持久层接口
  • pojo : 实体类
  • service: 服务层
  • util: 工具类包
  • SmartCampusApplication : 启动类
  1. resources目录下
  • mapper :持久层映射文件
  • public/upload:文件上传目录
  • static: 静态资源目录
  • application.yml :SpringBoot核心配置文

智能化校园:深入探讨云端管理系统设计与实现(一)_第6张图片

这里注意一下:public/upload
设置该目录时,如果为public.upload,那么在本地文件夹,并不会创建一个public下的新文件夹upload ,默认为该文件的文件名。
但是如果设置时,按照这种 public/upload 格式,虽然在目录中显示为public.upload (这是因为public目录下目前只有一个文件夹),但是实际上upload是public文件夹下的一个文件。

智能化校园:深入探讨云端管理系统设计与实现(一)_第7张图片

配置application.yml文件
server:
  port: 9000
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://......./sgg_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

Hikari

hikari使用


   com.zaxxer
   HikariCP
   5.0.0

初始化

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 开头的配置都是可选的配置,都有默认的值,不配也行的。

name 描述 构造器默认值 默认配置validate之后的值 validate重置
autoCommit 自动提交从池中返回的连接 true true -
connectionTimeout 等待来自池的连接的最大毫秒数 SECONDS.toMillis(30) = 30000 30000 如果小于250毫秒,则被重置回30秒
idleTimeout 连接允许在池中闲置的最长时间 MINUTES.toMillis(10) = 600000 600000 如果idleTimeout+1秒>maxLifetime 且 maxLifetime>0,则会被重置为0(代表永远不会退出);如果idleTimeout!=0且小于10秒,则会被重置为10秒
maxLifetime 池中连接最长生命周期 MINUTES.toMillis(30) = 1800000 1800000 如果不等于0且小于30秒则会被重置回30分钟
connectionTestQuery 如果您的驱动程序支持JDBC4,我们强烈建议您不要设置此属性 null null -
minimumIdle 池中维护的最小空闲连接数 -1 10 minIdle<0或者minIdle>maxPoolSize,则被重置为maxPoolSize
maximumPoolSize 池中最大连接数,包括闲置和使用中的连接 -1 10 如果maxPoolSize小于1,则会被重置。当minIdle<=0被重置为DEFAULT_POOL_SIZE则为10;如果minIdle>0则重置为minIdle的值
metricRegistry 该属性允许您指定一个 Codahale / Dropwizard MetricRegistry 的实例,供池使用以记录各种指标 null null -
healthCheckRegistry 该属性允许您指定池使用的Codahale / Dropwizard HealthCheckRegistry的实例来报告当前健康信息 null null -
poolName 连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置 null HikariPool-1 -
initializationFailTimeout 如果池无法成功初始化连接,则此属性控制池是否将 fail fast 1 1 -
isolateInternalQueries 是否在其自己的事务中隔离内部池查询,例如连接活动测试 false false -
allowPoolSuspension 控制池是否可以通过JMX暂停和恢复 false false -
readOnly 从池中获取的连接是否默认处于只读模式 false false -
registerMbeans 是否注册JMX管理Bean(MBeans) false false -
catalog 为支持 catalog 概念的数据库设置默认 catalog driver default null -
connectionInitSql 该属性设置一个SQL语句,在将每个新连接创建后,将其添加到池中之前执行该语句。 null null -
driverClassName HikariCP将尝试通过仅基于jdbcUrl的DriverManager解析驱动程序,但对于一些较旧的驱动程序,还必须指定driverClassName null null -
transactionIsolation 控制从池返回的连接的默认事务隔离级别 null null -
validationTimeout 连接将被测试活动的最大时间量 SECONDS.toMillis(5) = 5000 5000 如果小于250毫秒,则会被重置回5秒
leakDetectionThreshold 记录消息之前连接可能离开池的时间量,表示可能的连接泄漏 0 0 如果大于0且不是单元测试,则进一步判断:(leakDetectionThreshold < SECONDS.toMillis(2) or (leakDetectionThreshold > maxLifetime && maxLifetime > 0),会被重置为0 . 即如果要生效则必须>0,而且不能小于2秒,而且当maxLifetime > 0时不能大于maxLifetime
dataSource 这个属性允许你直接设置数据源的实例被池包装,而不是让HikariCP通过反射来构造它 null null -
schema 该属性为支持模式概念的数据库设置默认模式 driver default null -
threadFactory 此属性允许您设置将用于创建池使用的所有线程的java.util.concurrent.ThreadFactory的实例。 null null -
scheduledExecutor 此属性允许您设置将用于各种内部计划任务的java.util.concurrent.ScheduledExecutorService实例 null null -

jackson

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架.
优点:

  • Jackson 解析大的 json 文件速度比较快;
  • Jackson 运行时占用内存比较低,性能比较好;
  • Jackson 有灵活的 API,可以很容易进行扩展和定制。
    
    
      org.springframework.boot
      spring-boot-starter-json
    

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

  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
设置映射文件位置:
智能化校园:深入探讨云端管理系统设计与实现(一)_第8张图片

配置类

分页插件配置类
@Configuration
@MapperScan("com.project.smart_campus.mapper")
public class MyConfig {

    /*
    * 分页插件
    * */
    
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor paginationInterceptor=new PaginationInterceptor();
        return paginationInterceptor;
    }

}

Swagger2的配置类

引入依赖



    io.springfox
    springfox-swagger2
    2.7.0


    io.springfox
    springfox-swagger-ui
    2.7.0

配置类

@Configuration
@EnableSwagger2
public class Swagger2Config {

    @Bean
    public Docket webApiConfig(){

        //添加head参数start
        List 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(ApiOperation.class))
                .apis(RequestHandlerSelectors.basePackage("com.project.smart_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();
    }


}

常用配置参数表
智能化校园:深入探讨云端管理系统设计与实现(一)_第9张图片
swagger常用注解表
智能化校园:深入探讨云端管理系统设计与实现(一)_第10张图片
Swagger2 常用注解@ApiOperation@ApiParam
@ApiOperation(使用于在方法上,表示一个http请求的操作)

  • value用于方法描述
  • notes用于提示内容
  • tags可以重新分组(视情况而用)

@ApiParam
使用在方法上或者参数上,字段说明;表示对参数的添加元数据(说明或是否必填等)

  • name–参数名
  • value–参数说明
  • required–是否必填

学生管理系统接口文档示例:
智能化校园:深入探讨云端管理系统设计与实现(一)_第11张图片

工具类

验证码图片生成类

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

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 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 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 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): 使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 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 {
    @ApiModelProperty(value = "返回码")
    private Integer code;

    @ApiModelProperty(value = "返回消息")
    private String message;

    @ApiModelProperty(value = "返回数据")
    private T data;

    public Result(){}

    // 返回数据
    protected static  Result build(T data) {
        Result result = new Result();
        if (data != null)
            result.setData(data);
        return result;
    }

    public static  Result build(T body, ResultCodeEnum resultCodeEnum) {
        Result result = build(body);
        result.setCode(resultCodeEnum.getCode());
        result.setMessage(resultCodeEnum.getMessage());
        return result;
    }

    public static Result ok(){
        return Result.ok(null);
    }

    /**
     * 操作成功
     * @param data
     * @param 
     * @return
     */
    public static Result ok(T data){
        Result result = build(data);
        return build(data, ResultCodeEnum.SUCCESS);
    }

    public static Result fail(){
        return Result.fail(null);
    }

    /**
     * 操作失败
     * @param data
     * @param 
     * @return
     */
    public static Result fail(T data){
        Result result = build(data);
        return build(data, ResultCodeEnum.FAIL);
    }

    public Result message(String msg){
        this.setMessage(msg);
        return this;
    }

    public Result code(Integer code){
        this.setCode(code);
        return this;
    }

    public boolean isOk() {
        if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {
            return true;
        }
        return false;
    }
}

智能化校园:深入探讨云端管理系统设计与实现(一)_第12张图片

返回状态结果响应类
@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, "优惠券已发放完毕"),
   
    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 error_result = new HashMap<>();
    //存储头像的上传结果信息
    private static Map upload_result = new HashMap<>();

    /**
     * @description: 效验所上传图片的大小及格式等信息...
     * @param: photo
     * @param: path
     * @return: java.util.Map
     */
    private static Map 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 getUploadResult(MultipartFile photo, String dirPaht, String portraitPath) {

        if (!photo.isEmpty() && photo.getSize() > 0) {
            //获取图片的原始名称
            String orginalName = photo.getOriginalFilename();
            //上传图片,error_result:存储头像上传失败的错误信息
            Map 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类

智能化校园:深入探讨云端管理系统设计与实现(一)_第13张图片
根据数据库表的信息,可以借助mybatis的逆向工程生成。
配至pom.xml



    
        org.mybatis
        mybatis
        3.5.7
    

    


        
    
    
        
        
        
            org.mybatis.generator
            mybatis-generator-maven-plugin
            1.3.0
    
            
            
                
                
                
                    org.mybatis.generator
                    mybatis-generator-core
                    1.3.2
                
                    
                
                
                    com.mchange
                    c3p0
                    0.9.2
                
                    
                
                
                    mysql
                    mysql-connector-java
                    8.0.27
                
            
        
    


配置generatorConfig.xml




    
    
        
        
        
        
        
            
            
        
        
        
            
        
        
        
            
        
        
        
        
        

执行generate目标
智能化校园:深入探讨云端管理系统设计与实现(一)_第14张图片

生成相对应的mapper类和pojo类
智能化校园:深入探讨云端管理系统设计与实现(一)_第15张图片
感谢您对本文的阅读,期待您继续关注后续的文章,一同探索智慧校园管理系统功能的具体实现和应用。
敬请期待下一篇文章的发布!
智能化校园:深入探讨云端管理系统设计与实现(一)_第16张图片

你可能感兴趣的:(Java,Spring,项目,java,后端,spring,boot,spring)