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>

三.关于我的联系方式

相关推荐
现在,此刻17 分钟前
leetcode 11. 盛最多水的容器 -java
java·算法·leetcode
DKPT1 小时前
Java设计模式之开闭原则介绍与说明
java·设计模式·开闭原则
hyy27952276841 小时前
企业级WEB应用服务器TOMCAT
java·前端·tomcat
布朗克1681 小时前
Spring Boot项目通过Feign调用三方接口的详细教程
java·spring boot·feign
Arva .1 小时前
Spring基于XML的自动装配
xml·java·spring
这是个栗子2 小时前
【问题解决】Vue调试工具Vue Devtools插件安装后不显示
前端·javascript·vue.js
帅得不敢出门3 小时前
Android Framework定制长按电源键关机的窗口
android·java·framework
fatfishccc3 小时前
循序渐进学 Spring (上):从 IoC/DI 核心原理到 XML 配置实战
xml·java·数据库·spring·intellij-idea·ioc·di
小厂永远得不到的男人4 小时前
一篇文章搞懂 java 反射
java·后端
鼠鼠我捏,要死了捏4 小时前
基于Spring Boot与gRPC的高性能微服务架构设计分享
spring boot·微服务·grpc