SpringBoot+Vue项目线上教学平台

文末获取源码

开发语言:Java

开发工具:IDEA /Eclipse

数据库:MYSQL5.7

使用框架:springboot+vue

JDK版本:jdk1.8

前言介绍 

本系统地描绘了整个网上线上教学平台的设计与实现,主要实现的功能有以下几点:管理员;首页、个人中心、学员管理、资料类型管理、学习资料管理、交流论坛、我的收藏管理、试卷管理、留言板管理、试题管理、系统管理、考试管理,学员;首页、个人中心、我的收藏管理、留言板管理、考试管理,前台首页;首页、学习资料、交流论坛、试卷列表、留言反馈、个人中心、后台管理等功能,其具有简单的接口,方便的应用,强大的互动,完全基于互联网的特点。

系统设计

线上教学平台结构图

数据库设计

数据库可以说是所有软件的根本,如果数据库存在缺陷,那么会导致系统开发的不顺利、维护困难、学员使用不顺畅等一系列问题,严重时将会直接损害学员的利益,同时在开发完成后,数据库缺陷也更加难以解决。所以必须要对数据库设计重点把握,做到认真细致。因此,数据库设计是这个线上教学平台的重点要素。

扫描二维码关注公众号,回复: 14323260 查看本文章

管理员实体属性图如下图

 学习资料信息实体属性如下图

学员信息实体属性如下图

考试记录信息实体属性如下图

试题信息实体属性如下图

数据库表设计

 

将数据库概念设计的E-R图转换为关系数据库。在关系数据库中,数据关系由数据表组成,但是表的结构表现在表的字段上。

表名:token

功能:token表

字段名称

类型

长度

字段说明

主键

默认值

id

bigint

主键

主键

userid

bigint

用户id

username

varchar

100

用户名

tablename

varchar

100

表名

role

varchar

100

角色

token

varchar

200

密码

addtime

timestamp

新增时间

CURRENT_TIMESTAMP

expiratedtime

timestamp

过期时间

CURRENT_TIMESTAMP

表名:xuexiziliao

功能:学习资料

字段名称

类型

长度

字段说明

主键

默认值

id

bigint

主键

主键

addtime

timestamp

创建时间

CURRENT_TIMESTAMP

ziliaomingcheng

varchar

200

资料名称

ziliaoleixing

varchar

200

资料类型

tupian

varchar

200

图片

ziliaowenjian

varchar

200

资料文件

jiaoxueshipin

varchar

200

教学视频

ziliaoxiangqing

varchar

200

资料详情

fabushijian

varchar

200

发布时间

表名:xueyuan

功能:学员

字段名称

类型

长度

字段说明

主键

默认值

id

bigint

主键

主键

addtime

timestamp

创建时间

CURRENT_TIMESTAMP

xuehao

varchar

200

学号

mima

varchar

200

密码

xingming

varchar

200

姓名

xingbie

varchar

200

性别

touxiang

varchar

200

头像

youxiang

varchar

200

邮箱

shouji

datetime

时间

表名:ziliaoleixing

功能:资料类型

字段名称

类型

长度

字段说明

主键

默认值

id

bigint

主键

主键

addtime

timestamp

创建时间

CURRENT_TIMESTAMP

ziliaoleixing

varchar

200

资料类型

系统实现

前台首页功能模块

学员登录、学员注册,通过填写学号、密码、姓名、邮箱、手机等信息进行注册,登录,如图

 学员登录界面图

线上教学平台,通过系统可以获取首页、学习资料、交流论坛、试卷列表、公告信息、留言反馈、个人中心、后台管理等信息操作内容,如图

 

学习资料,通过内容列表可以获取资料名称、资料类型、图片、资料文件、教学视频、发布时间等信息可进行点我收藏操作,如图

交流论坛,通过内容列表可以获取标题、类型、内容等信息进行发布帖子操作,如图

试卷列表,通过内容列表可以获取试卷名称、考试时长、创建时间等信息进行考试操作,如图

我的发布,通过内容列表可以获取标题、发布时间等信息进行修改、删除操作,如图

管理员功能模块

管理员登录,通过填写注册时输入的用户名、密码、角色进行登录,如图

管理员登录进入线上教学平台可以查看首页、个人中心、学员管理、资料类型管理、学习资料管理、交流论坛、我的收藏管理、试卷管理、留言板管理、试题管理、

系统管理、考试管理等信息。

 

学员管理,在学员管理页面中可以通过填写学号、密码、姓名、性别、头像、邮箱、手机等内容进行详情、修改、删除,如图

 

还可以根据需要对资料类型管理进行详情,修改或删除等详细操作,如图

学习资料管理,在学习资料管理页面中可以查看资料名称、资料类型、图片、资料文件、教学视频、发布时间等信息,并可根据需要对已有学习资料管理进行修改或删除等操作,如图

试卷管理,在试卷管理页面中可以查看试卷名称、考试时长、试卷状态等信息,并可根据需要对已有试卷管理进行修改或删除等详细操作,如图

试题管理,在试题管理页面中可以查看试卷、试题名称、分值、答案、类型等内容,并且根据需要对已有试题管理进行详情,修改或删除等详细操作,如图

 

考试记录,在考试记录页面中可以查看用户ID、试卷、试题名称、分值、正确答案、考生答案、考生分值等内容,并且根据需要对已有考试记录进行修改或删除等详细操作,如图

留言板管理,在留言板管理页面中可以查看用户名、留言内容、回复内容等内容,并且根据需要对已有留言板管理进行详情,修改或删除等详细操作,如图

公告信息,在公告信息页面中可以查看标题、简介、图片等内容,并且根据需要对已有公告信息进行详情,修改或删除等详细操作,如图

 

学员功能模块

学员点击进入到系统操作界面,可以对首页、个人中心、我的收藏管理、留言板管理、考试管理等功能模块,个人信息:通过列表可以获取学号、密码、姓名、性别、头像、邮箱、手机并进行修改操作,如图

修改密码:通过列表可以获取原密码、新密码、确认密码等信息,进行修改、删除等操作,如图

我的收藏管理:通过列表可以获取收藏名称、收藏图片等信息,进行修改、删除操作,如图

留言板管理:通过列表可以获取用户名、留言内容、回复内容等信息,进行详情、删除操作,如图

错题本:通过列表可以获取用户ID、试卷、试题名称、分值、正确答案、考生答案、试题分析、考试时间等信息,进行详情、删除操作,如图

考试记录:通过列表可以获取用户ID、试卷、考试得分等信息,进行详情、删除操作,如图

部分核心代码:

# Tomcat
server:
    tomcat:
        uri-encoding: UTF-8
    port: 8080
    servlet:
        context-path: /springboota53y0

spring:
    datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/springboota53y0?useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
        username: root
        password: 123456
    servlet:
      multipart:
        max-file-size: 10MB
        max-request-size: 10MB
    resources:
      static-locations: classpath:static/,file:static/

#mybatis
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.entity
  global-config:
    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 1
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #刷新mapper 调试神器
    refresh-mapper: true
    #逻辑删除配置
    logic-delete-value: -1
    logic-not-delete-value: 0
    #自定义SQL注入器
    sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true
    #springboot 项目mybatis plus 设置 jdbcTypeForNull (oracle数据库需配置JdbcType.NULL, 默认是Other)
    jdbc-type-for-null: 'null' 

控制层(controller)

/**
 * 学员
 * 后端接口
 * @author 
 * @email 
 * @date 2021-02-26 22:02:58
 */
@RestController
@RequestMapping("/xueyuan")
public class XueyuanController {
    @Autowired
    private XueyuanService xueyuanService;
    
	@Autowired
	private TokenService tokenService;
	
	/**
	 * 登录
	 */
	@IgnoreAuth
	@RequestMapping(value = "/login")
	public R login(String username, String password, String captcha, HttpServletRequest request) {
		XueyuanEntity user = xueyuanService.selectOne(new EntityWrapper<XueyuanEntity>().eq("xuehao", username));
		if(user==null || !user.getMima().equals(password)) {
			return R.error("账号或密码不正确");
		}
		
		String token = tokenService.generateToken(user.getId(), username,"xueyuan",  "学员" );
		return R.ok().put("token", token);
	}
	
	/**
     * 注册
     */
	@IgnoreAuth
    @RequestMapping("/register")
    public R register(@RequestBody XueyuanEntity xueyuan){
    	//ValidatorUtils.validateEntity(xueyuan);
    	XueyuanEntity user = xueyuanService.selectOne(new EntityWrapper<XueyuanEntity>().eq("xuehao", xueyuan.getXuehao()));
		if(user!=null) {
			return R.error("注册用户已存在");
		}
		Long uId = new Date().getTime();
		xueyuan.setId(uId);
        xueyuanService.insert(xueyuan);
        return R.ok();
    }
	
	/**
	 * 退出
	 */
	@RequestMapping("/logout")
	public R logout(HttpServletRequest request) {
		request.getSession().invalidate();
		return R.ok("退出成功");
	}
	
	/**
     * 获取用户的session用户信息
     */
    @RequestMapping("/session")
    public R getCurrUser(HttpServletRequest request){
    	Long id = (Long)request.getSession().getAttribute("userId");
        XueyuanEntity user = xueyuanService.selectById(id);
        return R.ok().put("data", user);
    }
    
    /**
     * 密码重置
     */
    @IgnoreAuth
	@RequestMapping(value = "/resetPass")
    public R resetPass(String username, HttpServletRequest request){
    	XueyuanEntity user = xueyuanService.selectOne(new EntityWrapper<XueyuanEntity>().eq("xuehao", username));
    	if(user==null) {
    		return R.error("账号不存在");
    	}
        user.setMima("123456");
        xueyuanService.updateById(user);
        return R.ok("密码已重置为:123456");
    }


    /**
     * 后端列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,XueyuanEntity xueyuan, HttpServletRequest request){
        EntityWrapper<XueyuanEntity> ew = new EntityWrapper<XueyuanEntity>();
		PageUtils page = xueyuanService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, xueyuan), params), params));

        return R.ok().put("data", page);
    }
    
    /**
     * 前端列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params,XueyuanEntity xueyuan, HttpServletRequest request){
        EntityWrapper<XueyuanEntity> ew = new EntityWrapper<XueyuanEntity>();
		PageUtils page = xueyuanService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, xueyuan), params), params));
        return R.ok().put("data", page);
    }

	/**
     * 列表
     */
    @RequestMapping("/lists")
    public R list( XueyuanEntity xueyuan){
       	EntityWrapper<XueyuanEntity> ew = new EntityWrapper<XueyuanEntity>();
      	ew.allEq(MPUtil.allEQMapPre( xueyuan, "xueyuan")); 
        return R.ok().put("data", xueyuanService.selectListView(ew));
    }

	 /**
     * 查询
     */
    @RequestMapping("/query")
    public R query(XueyuanEntity xueyuan){
        EntityWrapper< XueyuanEntity> ew = new EntityWrapper< XueyuanEntity>();
 		ew.allEq(MPUtil.allEQMapPre( xueyuan, "xueyuan")); 
		XueyuanView xueyuanView =  xueyuanService.selectView(ew);
		return R.ok("查询学员成功").put("data", xueyuanView);
    }
	
    /**
     * 后端详情
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        XueyuanEntity xueyuan = xueyuanService.selectById(id);
        return R.ok().put("data", xueyuan);
    }

    /**
     * 前端详情
     */
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id){
        XueyuanEntity xueyuan = xueyuanService.selectById(id);
        return R.ok().put("data", xueyuan);
    }
    



    /**
     * 后端保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody XueyuanEntity xueyuan, HttpServletRequest request){
    	xueyuan.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    	//ValidatorUtils.validateEntity(xueyuan);
    	XueyuanEntity user = xueyuanService.selectOne(new EntityWrapper<XueyuanEntity>().eq("xuehao", xueyuan.getXuehao()));
		if(user!=null) {
			return R.error("用户已存在");
		}
		xueyuan.setId(new Date().getTime());
        xueyuanService.insert(xueyuan);
        return R.ok();
    }
    
    /**
     * 前端保存
     */
    @RequestMapping("/add")
    public R add(@RequestBody XueyuanEntity xueyuan, HttpServletRequest request){
    	xueyuan.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    	//ValidatorUtils.validateEntity(xueyuan);
    	XueyuanEntity user = xueyuanService.selectOne(new EntityWrapper<XueyuanEntity>().eq("xuehao", xueyuan.getXuehao()));
		if(user!=null) {
			return R.error("用户已存在");
		}
		xueyuan.setId(new Date().getTime());
        xueyuanService.insert(xueyuan);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody XueyuanEntity xueyuan, HttpServletRequest request){
        //ValidatorUtils.validateEntity(xueyuan);
        xueyuanService.updateById(xueyuan);//全部更新
        return R.ok();
    }
    

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        xueyuanService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }
    
    /**
     * 提醒接口
     */
	@RequestMapping("/remind/{columnName}/{type}")
	public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request, 
						 @PathVariable("type") String type,@RequestParam Map<String, Object> map) {
		map.put("column", columnName);
		map.put("type", type);
		
		if(type.equals("2")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar c = Calendar.getInstance();
			Date remindStartDate = null;
			Date remindEndDate = null;
			if(map.get("remindstart")!=null) {
				Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
				c.setTime(new Date()); 
				c.add(Calendar.DAY_OF_MONTH,remindStart);
				remindStartDate = c.getTime();
				map.put("remindstart", sdf.format(remindStartDate));
			}
			if(map.get("remindend")!=null) {
				Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
				c.setTime(new Date());
				c.add(Calendar.DAY_OF_MONTH,remindEnd);
				remindEndDate = c.getTime();
				map.put("remindend", sdf.format(remindEndDate));
			}
		}
		
		Wrapper<XueyuanEntity> wrapper = new EntityWrapper<XueyuanEntity>();
		if(map.get("remindstart")!=null) {
			wrapper.ge(columnName, map.get("remindstart"));
		}
		if(map.get("remindend")!=null) {
			wrapper.le(columnName, map.get("remindend"));
		}


		int count = xueyuanService.selectCount(wrapper);
		return R.ok().put("count", count);
	}
	


}

 文件上传功能

/**
 * 上传文件映射表
 */
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{
	@Autowired
    private ConfigService configService;
	/**
	 * 上传文件
	 */
	@RequestMapping("/upload")
	public R upload(@RequestParam("file") MultipartFile file, String type,HttpServletRequest request) throws Exception {
		if (file.isEmpty()) {
			throw new EIException("上传文件不能为空");
		}
		String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
		String fileName = new Date().getTime()+"."+fileExt;
		File dest = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
		file.transferTo(dest);
		if(StringUtils.isNotBlank(type) && type.equals("1")) {
			ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
			if(configEntity==null) {
				configEntity = new ConfigEntity();
				configEntity.setName("faceFile");
				configEntity.setValue(fileName);
			} else {
				configEntity.setValue(fileName);
			}
			configService.insertOrUpdate(configEntity);
		}
		return R.ok().put("file", fileName);
	}
	
	/**
	 * 下载文件
	 */
	@IgnoreAuth
	@RequestMapping("/download")
	public void download(@RequestParam String fileName, HttpServletRequest request, HttpServletResponse response) {
		try {
			File file = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
			if (file.exists()) {
				response.reset();
				response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName+"\"");
				response.setHeader("Cache-Control", "no-cache");
				response.setHeader("Access-Control-Allow-Credentials", "true");
				response.setContentType("application/octet-stream; charset=UTF-8");
				IOUtils.write(FileUtils.readFileToByteArray(file), response.getOutputStream());
			}
 
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

猜你喜欢

转载自blog.csdn.net/m0_49113107/article/details/125146267