Springboot+vue+小程序+基于微信小程序的在线学习平台

一、项目介绍

基于Spring Boot+Vue+小程序的在线学习平台从实际情况出发,结合当前年轻人的学习环境喜好来开发。基于Spring Boot+Vue+小程序的在线学习平台在语言上使用Java语言进行开发,在数据库存储方面使用的MySQL数据库,开发工具是IDEA。

功能丰富,项目保证质量,需要可以最底下查看QQ二维码找我私聊。运行讲解服务均可有尝提供,即便你是零基础,也能听懂的优秀讲解老师。

功能:

1.个人中心修改密码里查看个人信息

2.教师管理

3.学生管理

4.课程视频管理

5.课程签到管理

6.课程问题管理

7.课程答题管理

8.答题成绩管理

9.课程类型管理

10.课程资料管理

11.通知信息管理

12.加入课程管理

13.学习论坛管理

14.课程考试管理

15.试题管理

16.系统简介,轮播图,平台公告,关于我们管理

17.考试管理

关键词:商品;购物;Spring Boot框架;MySQL

二、开发环境

开发语言:Java

框架:springboot + vue + 小程序

JDK版本:JDK1.8

数据库:mysql

数据库工具:Navicat11

开发软件:idea/vscode/eclipse

Maven包:Maven

表结构示例:

表名:kechengxinxi

功能:课程信息

|------------------|-----------|------------|------|----|-------------------|
| 字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
| id | bigint | | 主键 | 主键 | |
| addtime | timestamp | | 创建时间 | | CURRENT_TIMESTAMP |
| kechengbianhao | varchar | 200 | 课程编号 | | |
| kechengmingcheng | varchar | 200 | 课程名称 | | |
| kechengleixing | varchar | 200 | 课程类型 | | |
| keshi | varchar | 200 | 课时 | | |
| xuefen | varchar | 200 | 学分 | | |
| kechengtupian | longtext | 4294967295 | 课程图片 | | |
| shangkeshijian | varchar | 200 | 上课时间 | | |
| shangkedidian | varchar | 200 | 上课地点 | | |
| jiaoshigonghao | varchar | 200 | 教师工号 | | |
| jiaoshixingming | varchar | 200 | 教师姓名 | | |
| kechengjieshao | longtext | 4294967295 | 课程介绍 | | |

表名:discusskechengshipin

功能:课程视频评论表

|-----------|-----------|------------|-------|----|-------------------|
| 字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
| id | bigint | | 主键 | 主键 | |
| addtime | timestamp | | 创建时间 | | CURRENT_TIMESTAMP |
| refid | bigint | | 关联表id | | |
| userid | bigint | | 用户id | | |
| avatarurl | longtext | 4294967295 | 头像 | | |
| nickname | varchar | 200 | 用户名 | | |
| content | longtext | 4294967295 | 评论内容 | | |
| reply | longtext | 4294967295 | 回复内容 | | |

表名:kechengqiandao

功能:课程签到

|------------------|-----------|------------|------|----|-------------------|
| 字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
| id | bigint | | 主键 | 主键 | |
| addtime | timestamp | | 创建时间 | | CURRENT_TIMESTAMP |
| kechengbianhao | varchar | 200 | 课程编号 | | |
| kechengmingcheng | varchar | 200 | 课程名称 | | |
| kechengtupian | longtext | 4294967295 | 课程图片 | | |
| kechengleixing | varchar | 200 | 课程类型 | | |
| jiaoshigonghao | varchar | 200 | 教师工号 | | |
| jiaoshixingming | varchar | 200 | 教师姓名 | | |
| zhangcheng | varchar | 200 | 章程 | | |
| xuehao | varchar | 200 | 学号 | | |
| xueshengxingming | varchar | 200 | 学生姓名 | | |
| xueshengshouji | varchar | 200 | 学生手机 | | |
| zhuanye | varchar | 200 | 专业 | | |
| banji | varchar | 200 | 班级 | | |
| qiandaoshijian | datetime | | 签到时间 | | |
| kechengxinde | longtext | 4294967295 | 课程心得 | | |

代码示例一,课程信息代码

java 复制代码
package com.controller;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;

import com.entity.KechengxinxiEntity;
import com.entity.view.KechengxinxiView;

import com.service.KechengxinxiService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MPUtil;

/**
 * 课程信息
 * 后端接口
 */
@RestController
@RequestMapping("/kechengxinxi")
public class KechengxinxiController {
    @Autowired
    private KechengxinxiService kechengxinxiService;

    /**
     * 后端列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params, KechengxinxiEntity kechengxinxi,
                  HttpServletRequest request) {
        String tableName = request.getSession().getAttribute("tableName").toString();
        if (tableName.equals("jiaoshi")) {
            kechengxinxi.setJiaoshigonghao((String) request.getSession().getAttribute("username"));
        }
        EntityWrapper<KechengxinxiEntity> ew = new EntityWrapper<KechengxinxiEntity>();
        PageUtils page = kechengxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, kechengxinxi), params), params));
        return R.ok().put("data", page);
    }

    /**
     * 前端列表
     */
    @IgnoreAuth
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params, KechengxinxiEntity kechengxinxi,
                  HttpServletRequest request) {
        EntityWrapper<KechengxinxiEntity> ew = new EntityWrapper<KechengxinxiEntity>();

        PageUtils page = kechengxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, kechengxinxi), params), params));
        return R.ok().put("data", page);
    }

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

    /**
     * 查询
     */
    @RequestMapping("/query")
    public R query(KechengxinxiEntity kechengxinxi) {
        EntityWrapper<KechengxinxiEntity> ew = new EntityWrapper<KechengxinxiEntity>();
        ew.allEq(MPUtil.allEQMapPre(kechengxinxi, "kechengxinxi"));
        KechengxinxiView kechengxinxiView = kechengxinxiService.selectView(ew);
        return R.ok("查询课程信息成功").put("data", kechengxinxiView);
    }

    /**
     * 后端详情
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id) {
        KechengxinxiEntity kechengxinxi = kechengxinxiService.selectById(id);
        return R.ok().put("data", kechengxinxi);
    }

    /**
     * 前端详情
     */
    @IgnoreAuth
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id) {
        KechengxinxiEntity kechengxinxi = kechengxinxiService.selectById(id);
        return R.ok().put("data", kechengxinxi);
    }
    
    /**
     * 后端保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody KechengxinxiEntity kechengxinxi, HttpServletRequest request) {
        kechengxinxi.setId(new Date().getTime() + new Double(Math.floor(Math.random() * 1000)).longValue());
        //ValidatorUtils.validateEntity(kechengxinxi);
        kechengxinxiService.insert(kechengxinxi);
        return R.ok();
    }

    /**
     * 前端保存
     */
    @RequestMapping("/add")
    public R add(@RequestBody KechengxinxiEntity kechengxinxi, HttpServletRequest request) {
        kechengxinxi.setId(new Date().getTime() + new Double(Math.floor(Math.random() * 1000)).longValue());
        //ValidatorUtils.validateEntity(kechengxinxi);
        kechengxinxiService.insert(kechengxinxi);
        return R.ok();
    }
    
    /**
     * 修改
     */
    @RequestMapping("/update")
    @Transactional
    public R update(@RequestBody KechengxinxiEntity kechengxinxi, HttpServletRequest request) {
        kechengxinxiService.updateById(kechengxinxi);//全部更新
        return R.ok();
    }
    
    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids) {
        kechengxinxiService.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<KechengxinxiEntity> wrapper = new EntityWrapper<KechengxinxiEntity>();
        if (map.get("remindstart") != null) {
            wrapper.ge(columnName, map.get("remindstart"));
        }
        if (map.get("remindend") != null) {
            wrapper.le(columnName, map.get("remindend"));
        }

        String tableName = request.getSession().getAttribute("tableName").toString();
        if (tableName.equals("jiaoshi")) {
            wrapper.eq("jiaoshigonghao", (String) request.getSession().getAttribute("username"));
        }
        int count = kechengxinxiService.selectCount(wrapper);
        return R.ok().put("count", count);
    }
}
html 复制代码
 <template v-if="showFlag">
      <el-form class="center-form-pv" :style='{"margin":"0 0 30px"}' :inline="true" :model="searchForm">
        <el-row :style='{"padding":"10px","borderRadius":"3px","background":"#fff","display":"block"}'>
          <div :style='{"margin":"0 10px 0 0","display":"inline-block"}'>
            <label
                :style='{"margin":"0 10px 0 0","color":"#666","display":"inline-block","lineHeight":"40px","fontSize":"14px","fontWeight":"500","height":"40px"}'
                class="item-label">课程名称</label>
            <el-input v-model="searchForm.kechengmingcheng" placeholder="课程名称" clearable></el-input>
          </div>
          <div :style='{"margin":"0 10px 0 0","display":"inline-block"}' class="select" label="课程类型"
               prop="kechengleixing">
            <label
                :style='{"margin":"0 10px 0 0","color":"#666","display":"inline-block","lineHeight":"40px","fontSize":"14px","fontWeight":"500","height":"40px"}'
                class="item-label">课程类型</label>
            <el-select @change="kechengleixingChange" clearable v-model="searchForm.kechengleixing"
                       placeholder="请选择课程类型">
              <el-option v-for="(item,index) in kechengleixingOptions" v-bind:key="index" :label="item"
                         :value="item"></el-option>
            </el-select>
          </div>
          <div :style='{"margin":"0 10px 0 0","display":"inline-block"}'>
            <label
                :style='{"margin":"0 10px 0 0","color":"#666","display":"inline-block","lineHeight":"40px","fontSize":"14px","fontWeight":"500","height":"40px"}'
                class="item-label">教师姓名</label>
            <el-input v-model="searchForm.jiaoshixingming" placeholder="教师姓名" clearable></el-input>
          </div>
          <el-button
              :style='{"border":"1px solid #5494cb","cursor":"pointer","padding":"0 34px","outline":"none","margin":"0 0px 0 10px","color":"#fff","borderRadius":"4px","background":"-webkit-linear-gradient(top,#66a4d8,#337ab7)","width":"auto","fontSize":"14px","height":"40px"}'
              type="success" @click="search()">查询
          </el-button>
        </el-row>

        <el-row :style='{"margin":"20px 0 20px 0","display":"flex"}'>
          <el-button
              :style='{"border":"0","cursor":"pointer","padding":"0 24px","margin":"0 10px 0 0","outline":"none","color":"#fff","borderRadius":"4px","background":"rgba(64, 158, 255, 1)","width":"auto","fontSize":"14px","height":"40px"}'
              v-if="isAuth('kechengxinxi','新增')" type="success" @click="addOrUpdateHandler()">新增
          </el-button>
          <el-button
              :style='{"border":"0","cursor":"pointer","padding":"0 24px","margin":"0 10px 0 0","outline":"none","color":"#fff","borderRadius":"4px","background":"rgba(255, 0, 0, 1)","width":"auto","fontSize":"14px","height":"40px"}'
              v-if="isAuth('kechengxinxi','删除')" :disabled="dataListSelections.length <= 0" type="danger"
              @click="deleteHandler()">删除
          </el-button>
        </el-row>
      </el-form>

      <!-- <div> -->
      <el-table class="tables"
                :stripe='false'
                :style='{"padding":"0","borderColor":"#eee","borderRadius":"5px","borderWidth":"1px 0 0 1px","background":"#fff","width":"100%","borderStyle":"solid"}'
                v-if="isAuth('kechengxinxi','查看')"
                :data="dataList"
                v-loading="dataListLoading"
                @selection-change="selectionChangeHandler">
        <el-table-column :resizable='true' type="selection" align="center" width="50"></el-table-column>
        <el-table-column :resizable='true' :sortable='false' label="索引" type="index" width="50"/>
        <el-table-column :resizable='true' :sortable='false'
                         prop="kechengbianhao"
                         label="课程编号">
          <template slot-scope="scope">
            {{ scope.row.kechengbianhao }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="kechengmingcheng"
                         label="课程名称">
          <template slot-scope="scope">
            {{ scope.row.kechengmingcheng }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="kechengleixing"
                         label="课程类型">
          <template slot-scope="scope">
            {{ scope.row.kechengleixing }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="keshi"
                         label="课时">
          <template slot-scope="scope">
            {{ scope.row.keshi }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="xuefen"
                         label="学分">
          <template slot-scope="scope">
            {{ scope.row.xuefen }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false' prop="kechengtupian" width="200" label="课程图片">
          <template slot-scope="scope">
            <div v-if="scope.row.kechengtupian">
              <img v-if="scope.row.kechengtupian.substring(0,4)=='http'" :src="scope.row.kechengtupian.split(',')[0]"
                   width="100" height="100">
              <img v-else :src="$base.url+scope.row.kechengtupian.split(',')[0]" width="100" height="100">
            </div>
            <div v-else>无图片</div>
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="shangkeshijian"
                         label="上课时间">
          <template slot-scope="scope">
            {{ scope.row.shangkeshijian }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="shangkedidian"
                         label="上课地点">
          <template slot-scope="scope">
            {{ scope.row.shangkedidian }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="jiaoshigonghao"
                         label="教师工号">
          <template slot-scope="scope">
            {{ scope.row.jiaoshigonghao }}
          </template>
        </el-table-column>
        <el-table-column :resizable='true' :sortable='false'
                         prop="jiaoshixingming"
                         label="教师姓名">
          <template slot-scope="scope">
            {{ scope.row.jiaoshixingming }}
          </template>
        </el-table-column>
        <el-table-column width="300" label="操作">
          <template slot-scope="scope">
            <el-button
                :style='{"border":"1px solid #3ca512","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/ca1c191554d24b108bc94f4a2046d636.png) #41b314 no-repeat 5px 8px","width":"auto","fontSize":"12px","height":"32px"}'
                v-if=" isAuth('kechengxinxi','查看')" type="success" size="mini"
                @click="addOrUpdateHandler(scope.row.id,'info')">详情
            </el-button>
            <el-button
                :style='{"border":"1px solid #3ca512","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/ca1c191554d24b108bc94f4a2046d636.png) #41b314 no-repeat 5px 8px","width":"auto","fontSize":"12px","height":"32px"}'
                v-if="isAuth('kechengxinxi','加入课程')" type="success" size="mini"
                @click="jiarukechengCrossAddOrUpdateHandler(scope.row,'cross','','','')">加入课程
            </el-button>
            <el-button
                :style='{"border":"1px solid #3ca512","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/ca1c191554d24b108bc94f4a2046d636.png) #41b314 no-repeat 5px 8px","width":"auto","fontSize":"12px","height":"32px"}'
                v-if="isAuth('kechengxinxi','发布视频')" type="success" size="mini"
                @click="kechengshipinCrossAddOrUpdateHandler(scope.row,'cross','','','')">发布视频
            </el-button>
            <el-button
                :style='{"border":"1px solid #3ca512","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/ca1c191554d24b108bc94f4a2046d636.png) #41b314 no-repeat 5px 8px","width":"auto","fontSize":"12px","height":"32px"}'
                v-if="isAuth('kechengxinxi','发布资料')" type="success" size="mini"
                @click="kechengziliaoCrossAddOrUpdateHandler(scope.row,'cross','','','')">发布资料
            </el-button>
            <el-button
                :style='{"border":"1px solid #00a0f0","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/161eb7a46f5d4cd19d68a1386174d662.png) #00aaff no-repeat 5px 8px","width":"auto","fontSize":"12px","height":"32px"}'
                v-if=" isAuth('kechengxinxi','修改')" type="primary" size="mini"
                @click="addOrUpdateHandler(scope.row.id)">修改
            </el-button>


            <el-button
                :style='{"border":"1px solid #3ca512","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/ca1c191554d24b108bc94f4a2046d636.png) #41b314 no-repeat 5px 8px","width":"auto","fontSize":"12px","height":"32px"}'
                v-if="isAuth('kechengxinxi','查看评论')" type="primary" size="mini"
                @click="disscussListHandler(scope.row.id)">查看评论
            </el-button>


            <el-button
                :style='{"border":"0","cursor":"pointer","padding":"0 10px 0 24px","margin":"3px 6px 3px 0","outline":"none","color":"#fff","borderRadius":"4px","background":"url(http://codegen.caihongy.cn/20221011/68bd264a8e4341c6aa5409f871d590d0.png) #d9534f no-repeat 5px 8px","width":"auto","fontSize":"14px","height":"32px"}'
                v-if="isAuth('kechengxinxi','删除') " type="danger" size="mini" @click="deleteHandler(scope.row.id)">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          @size-change="sizeChangeHandle"
          @current-change="currentChangeHandle"
          :current-page="pageIndex"
          background
          :page-sizes="[10, 20, 30, 50]"
          :page-size="pageSize"
          :layout="layouts.join()"
          :total="totalPage"
          prev-text="<"
          next-text=">"
          :hide-on-single-page="true"
          :style='{"width":"100%","padding":"0","margin":"20px 0 0","whiteSpace":"nowrap","color":"#333","fontWeight":"500"}'
      ></el-pagination>
      <!-- </div> -->
    </template>

三.关于我的联系方式

相关推荐
407指导员21 分钟前
uniapp 微信小程序 页面部分截图实现
微信小程序·小程序·uni-app
J不A秃V头A33 分钟前
IntelliJ IDEA中设置激活的profile
java·intellij-idea
cronaldo9133 分钟前
研发效能DevOps: Vite 使用 Element Plus
vue.js·vue·devops
DARLING Zero two♡35 分钟前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
小池先生1 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
CodeClimb1 小时前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
odng1 小时前
IDEA自己常用的几个快捷方式(自己的习惯)
java·ide·intellij-idea
CT随1 小时前
Redis内存碎片详解
java·开发语言
brrdg_sefg1 小时前
gitlab代码推送
java
hanbarger2 小时前
mybatis框架——缓存,分页
java·spring·mybatis