在线教育项目

87 阅读4分钟

D7

2022年1月10日19:44:25

D7-1.添加课程分类前端对接

1.添加路由和页面

//guli-admin/src/router/index.js
{
    path: '/subject',
    component: Layout,
    redirect: '/subject/table',
    name: '课程分类管理',
    meta: { title: '课程分类管理', icon: 'example' },
    children: [
      {
        path: 'add',
        name: '导入课程分类',
        component: () => import('@/views/subject/add'),
        meta: { title: '导入课程分类', icon: 'tree' }
      },
      {
        path: 'list',
        name: '课程分类展示',
        component: () => import('@/views/subject/list'),
        meta: { title: '课程分类展示', icon: 'table' }
      },
    ]
  },

添加页面:在guli-admin/src/views下新建subject文件夹,在此文件夹下新建add.vue和list.vue

2.页面实现

1) 添加页面元素

<template>
  <div class="app-container">
    <el-form label-width="120px">
      <el-form-item label="信息描述">
        <el-tag type="info">excel模版说明</el-tag>
        <el-tag>
          <i class="el-icon-download"/>
          <a :href=" '/excel/%E8%AF%BE%E7%A8%8B%E5%88%86%E7%B1%BB%E5%88%97%E8%A1%A8%E6%A8%A1%E6%9D%BF.xls'">点击下载模版</a>
        </el-tag>
      </el-form-item>

<!--ref类比成HTML中的id,唯一标识。auto-upload是否自动提交。
disabled是否不可操作。-->

      <el-form-item label="选择Excel"> 
        <el-upload
          ref="upload"
          :auto-upload="false"
          :on-success="fileUploadSuccess"
          :on-error="fileUploadError"
          :disabled="importBtnDisabled"
          :limit="1"
          :action="BASE_API+'/eduservice/subject/addSubject'"
          name="file"
          accept="application/vnd.ms-excel">
          <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
          <el-button
            :loading="loading"
            style="margin-left: 10px;"
            size="small"
            type="success"
            @click="submitUpload">{{ fileUploadBtnText }}</el-button>
        </el-upload>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  data() {
    return {
      BASE_API: process.env.BASE_API, // 接口API地址
      //OSS_PATH: process.env.OSS_PATH, //阿里云OSS地址
      fileUploadBtnText: "上传到服务器", // 按钮文字
      importBtnDisabled: false, // 按钮是否禁用
      loading: false
    };
  },
  created() {},
  methods: {
    submitUpload() {
      this.fileUploadBtnText = "正在上传";
      this.importBtnDisabled = true;
      this.loading = true;
      this.$refs.upload.submit();
    },
    fileUploadSuccess(response) {
      if (response.success === true) {
        this.fileUploadBtnText = '导入成功'
        this.loading = false
        this.$message({
          type: 'success',
          message: '导入成功'
        })
      }
    },

    fileUploadError(response) {
      this.fileUploadBtnText = '导入失败'
      this.loading = false
      this.$message({
        type: 'error',
        message: '导入失败'
      })
    }
  }
};
</script>

D7-2.课程分类属性结构展示

  • 复制已有的类似页面:guli-admin/src/views/tree/index.vue

1.后端实现接口

  • 在service_edu/src/main/entity/vo下创建Vo类
@Data
public class OneSubjectVo {
    private String id;
    private String title;
    private List<TwoSubjectVo> children = new ArrayList<>();
}
@Data
public class TwoSubjectVo {
    private String id;
    private String title;
}

2.实现controller和service

//service_edu/src/main/controller/EduSubjectController.java
@ApiOperation(value = "查询所有课程分类信息") //Day7
@GetMapping("getAllSubject")
public R getAllSubject() {
    List<OneSubjectVo> oneSubjectVoList = subjectService.getAllSubject();
    return R.ok().data("allSubject", oneSubjectVoList);
}
//service_edu/src/main/service/impl/EduSubjectServiceImpl.java
//查询所有课程分类信息
@Override
public List<OneSubjectVo> getAllSubject() {
    //1查询一级信息
    QueryWrapper<EduSubject> oneSubjectWrapper = new QueryWrapper<>();
    oneSubjectWrapper.eq("parent_id","0");
    List<EduSubject> oneSubjectList = baseMapper.selectList(oneSubjectWrapper);
    //2查询二级信息
    QueryWrapper<EduSubject> twoSubjectWrapper = new QueryWrapper<>();
    twoSubjectWrapper.ne("parent_id","0"); //不等于
    List<EduSubject> twoSubjectList = baseMapper.selectList(twoSubjectWrapper);
    //3封装一级
    List<OneSubjectVo>  allSubjectList = new ArrayList<>();
    for (int i = 0; i <oneSubjectList.size() ; i++) {
        //3.1取出每一条一级信息
        EduSubject oneSubject = oneSubjectList.get(i);
        //3.2把EduSubject转化OneSubjectVo
        OneSubjectVo oneSubjectVo = new OneSubjectVo();
        //oneSubjectVo.setId(oneSubject.getId());
        //oneSubjectVo.setTitle(oneSubject.getTitle());
        BeanUtils.copyProperties(oneSubject,oneSubjectVo); //参数一:source,参数二:target
        allSubjectList.add(oneSubjectVo);
        //4封装二级信息
        List<TwoSubjectVo> twoVoList = new ArrayList<>();
        for (int m = 0; m < twoSubjectList.size(); m++) {
            //4.1取出每一条二级信息
            EduSubject twoSubject = twoSubjectList.get(m);
            if(oneSubject.getId().equals(twoSubject.getParentId())){
                //4.2把EduSubject转化TwoSubjectVo
                TwoSubjectVo twoSubjectVo = new TwoSubjectVo();
                BeanUtils.copyProperties(twoSubject,twoSubjectVo);
                twoVoList.add(twoSubjectVo);
            }
        }
        oneSubjectVo.setChildren(twoVoList);
    }
    return allSubjectList;
}

3.前端对接

  • guli-admin/src/api/subject.js
import request from '@/utils/request'

export default {
  //查询所有课程分类信息
  getAllSubject(){
    return request({
      url: `/eduservice/subject/getAllSubject`,
      method: 'get'
    })
  }
}
  • guli-admin/src/views/subject/list.vue中的js实现
<template>
  <div class="app-container">
    <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />

    <el-tree
      ref="tree2"
      :data="data2"
      :props="defaultProps"
      :filter-node-method="filterNode"
      class="filter-tree"
      default-expand-all
    />
  </div>
</template>

<script>
// import subject from "../../api/subject";
import subject from "@/api/subject";
export default {

  data() {
    return {
      filterText: '',
      data2: [],
      defaultProps: {
        children: 'children',
        label: 'title'
      }
    }
  },
  watch: { //侦听输入框
    filterText(val) {
      this.$refs.tree2.filter(val)
    }
  },
  created () {
    this.getAllSubjectList();
  },
  methods: {
    getAllSubjectList() {
      subject.getAllSubject().then(response => {
        this.data2 = response.data.allSubject;
      });
    },
    filterNode(value, data) {
      if (!value) return true
      return data.title.indexOf(value) !== -1
    }
  }
}
</script>

D7-3.课程发布

1.代码生成器生成代码

public class CodeGenerator {
    @Test
    public void run() {
        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器(目录是否展开)
        gc.setFileOverride(false); //重新生成时文件是否覆盖
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER_STR); //主键策略(字符串类型)
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("hrj");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("eduservice"); //模块名
        pc.setParent("com.jun");
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        //strategy.setInclude("edu_teacher"); //括号中可以写多张表的名字
        //strategy.setInclude("edu_subject");
        strategy.setInclude("edu_course","edu_course_description");
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
        mpg.setStrategy(strategy);
        // 6、执行
        mpg.execute();
    }
}
  • 给EduCourse和EduCourseDescription添加注解
@ApiModelProperty(value = "课程ID")
@TableId(value = "id", type = IdType.INPUT) //修改主键策略
private String id;

@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;

@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新时间")
private Date gmtModified;

2.添加课程信息接口

1)创建Vo类

//service_edu/src/main/java/entity/vo/CourseInfoForm.java
@Data
public class CourseInfoForm {
    @ApiModelProperty(value = "课程ID")
    private String id;

    @ApiModelProperty(value = "课程讲师ID")
    private String teacherId;

    @ApiModelProperty(value = "二级分类")
    private String subjectId;

    @ApiModelProperty(value = "一级分类")
    private String subjectParentId;

    @ApiModelProperty(value = "课程标题")
    private String title;

    @ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
    private BigDecimal price;

    @ApiModelProperty(value = "总课时")
    private Integer lessonNum;

    @ApiModelProperty(value = "课程封面图片路径")
    private String cover;

    @ApiModelProperty(value = "课程简介")
    private String description;
}

2)实现controller

@Api(description="课程管理")
@RestController
@RequestMapping("/eduservice/course")
@CrossOrigin
public class EduCourseController {
    @Autowired
    private EduCourseService courseService;

    @ApiOperation(value = "添加课程信息")
    @PostMapping("addCourseInfo")
    public R addCourseInfo(@RequestBody CourseInfoForm courseInfoForm){
        courseService.addCourseInfo(courseInfoForm);
        return R.ok();
    }
}

3)实现service

@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {
    @Autowired
    private EduCourseDescriptionService courseDescriptionService;

    //添加课程信息
    @Override
    public void addCourseInfo(CourseInfoForm courseInfoForm) {
        //1.添加课程信息
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoForm,eduCourse);
        int insert = baseMapper.insert(eduCourse); //插入数据库
        if(insert==0){
            throw  new GuliException(20001,"添加课程信息失败");
        }
        //2添加课程描述信息
        String courseId = eduCourse.getId();
        EduCourseDescription courseDescription = new EduCourseDescription();
        courseDescription.setId(courseId);
        courseDescription.setDescription(courseInfoForm.getDescription());
        courseDescriptionService.save(courseDescription);
    }
}

3.添加课程信息前端实现

1)添加路由

  {
    path: '/course',
    component: Layout,
    redirect: '/course/table',
    name: '课程管理',
    meta: { title: '课程管理', icon: 'example' },
    children: [
      {
        path: 'add',
        name: '课程发布',
        component: () => import('@/views/course/add'),
        meta: { title: '课程发布', icon: 'tree' }
      },
      {
        path: 'list',
        name: '课程列表',
        component: () => import('@/views/course/list'),
        meta: { title: '课程列表', icon: 'table' }
      },
    ]
  },

2)创建api接口方法

//guli-admin/src/api/course.js
import request from '@/utils/request'

export default  {
  //添加课程信息
  addCourseInfo(courseInfo){
    return request({
      url: `/eduservice/course/addCourseInfo`,
      method: 'post',
      data:courseInfo
    })
  }
}

3)创建页面,实现js

  • 在views文件夹中新建course文件夹,并创建add.vue和list.vue页面
add.vue
<template>
  <div class="app-container">
    <h2 style="text-align: center;">发布新课程</h2>

    <el-steps :active="1" process-status="wait" align-center style="margin-bottom: 40px;">
      <el-step title="填写课程基本信息"/>
      <el-step title="创建课程大纲"/>
      <el-step title="提交审核"/>
    </el-steps>

    <el-form label-width="120px">
      <el-form-item label="课程标题">
        <el-input v-model="courseInfo.title" placeholder=" 示例:机器学习项目课:从基础到搭建项目视频课程。专业名称注意大小写"/>
      </el-form-item>
      <!-- 所属分类 TODO -->
      
      <!-- 课程讲师 TODO -->

      <el-form-item label="总课时">
        <el-input-number
          :min="0"
          v-model="courseInfo.lessonNum"
          controls-position="right"
          placeholder="请填写课程的总课时数"
        />
      </el-form-item>

      <!-- 课程简介 TODO -->
      <el-form-item label="课程简介">
        <el-input v-model="courseInfo.description" />
      </el-form-item>

      <!-- 课程封面 TODO -->

      <el-form-item label="课程价格">
        <el-input-number
          :min="0"
          v-model="courseInfo.price"
          controls-position="right"
          placeholder="免费课程请设置为0元"
        /></el-form-item>

      <el-form-item>
        <el-button :disabled="saveBtnDisabled" type="primary" @click="next">保存并下一步</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import course from "@/api/course";
export default {
  data() {
    return {
      saveBtnDisabled: false, //保存按钮是否禁用
      courseInfo: {} //课程信息
    };
  },
  created() {
    console.log("info created");
  },
  methods: {
    next() {
      console.log("next");
      //1调用接口保存数据
      course.addCourseInfo(this.courseInfo).then(response => {
        this.$message({
          type: "success",
          message: "添加成功!"
        });
        //2跳转到课程大纲页面
        //this.$router.push({ path: "/edu/course/chapter/1" });
      });
    }
  }
};
</script>

4.添加讲师信息

1)创建api接口方法

//guli-admin/src/api/teacher.js
//6.查询所有讲师
  getAllTeacher() {
    return request({
      url: `/eduservice/eduteacher`,
      method: 'get'
    });
  }

2)添加页面元素

//guli-admin/src/views/course/add.vue
<!-- 课程讲师 -->
<el-form-item label="课程讲师">
<el-select v-model="courseInfo.teacherId" placeholder="请选择">
  <el-option
    v-for="teacher in teacherList"
    :key="teacher.id"
    :label="teacher.name"
    :value="teacher.id"
  />
</el-select>
</el-form-item>

5.实现课程分类

1)确认接口方法

//src/main/java/controller/EduSubjectController.java
@ApiOperation(value = "查询所有课程分类信息") //Day7
@GetMapping("getAllSubject")
public R getAllSubject() {
    List<OneSubjectVo> oneSubjectVoList = subjectService.getAllSubject();
    return R.ok().data("allSubject", oneSubjectVoList);
}

2)确认api接口方法

//guli-admin/src/api/subject.js
import request from '@/utils/request'

export default {
  //查询所有课程分类信息
  getAllSubject(){
    return request({
      url: `/eduservice/subject/getAllSubject`,
      method: 'get'
    })
  }
}

3)添加页面元素

<!-- 所属分类:级联下拉列表 -->
<el-form-item label="课程类别">
<!-- 一级分类 --> <!--element-ui中,触发的事件中没有加括号,自动将参数塞进去-->
<el-select @change="getTwoByOneSubjectId"
  v-model="courseInfo.subjectParentId" placeholder="一级分类">
  <el-option
    v-for="subject in oneSubjectList"
    :key="subject.id"
    :label="subject.title"
    :value="subject.id"
  />
</el-select>
<!-- 二级分类 -->
<el-select v-model="courseInfo.subjectId" placeholder="二级分类">
  <el-option
    v-for="subject in twoSubjectList"
    :key="subject.id"
    :label="subject.title"
    :value="subject.id"
  />
</el-select>
</el-form-item>

4)实现一级数据和二级联动

<script>
import course from "@/api/course";
import teacher from "@/api/teacher";
import subject from "@/api/subject";
export default {
  data() {
    return {
      saveBtnDisabled: false, //保存按钮是否禁用
      courseInfo: {
        subjectId:''
      }, //课程信息
      teacherList:[], //讲师信息
      oneSubjectList:[],//一级分类
      twoSubjectList:[]//二级分类
    };
  },

  created() {
    console.log("info created");
    this.getTeacherList();
    this.getOneSubjectList();
  },

  methods: {
    //获取分类信息
    getOneSubjectList(){
      subject.getAllSubject().then(response=>{
        this.oneSubjectList = response.data.allSubject
      })
    },
    //二级联动事件
    getTwoByOneSubjectId(oneId){
      for(let i=0;i<this.oneSubjectList.length;i++){
        let oneSubject = this.oneSubjectList[i]
        if(oneId === oneSubject.id){ //恒等,既判断数值又判断类型
          this.twoSubjectList = oneSubject.children;
          this.courseInfo.subjectId = '';
        }
      }
    },
    //获得讲师信息
    getTeacherList() {  //此初始化方法在页面加载的时候执行
      teacher.getAllTeacher().then(response => {
        this.teacherList = response.data.items;
      });
    },
      next() {
      console.log("next");
      //1调用接口保存数据
      course.addCourseInfo(this.courseInfo).then(response => {
        this.$message({
          type: "success",
          message: "添加成功!"
        });
        //2跳转到课程大纲页面
        //this.$router.push({ path: "/edu/course/chapter/1" });
      });
    }
  }
};
</script>

6.上传封面

1)添加页面元素

<!-- 课程封面-->
<el-form-item label="课程封面">
<el-upload
  :show-file-list="false"
  :on-success="handleAvatarSuccess"
  :before-upload="beforeAvatarUpload"
  :action="BASE_API+'/eduoss/ossfile/uploadFile'"
  class="avatar-uploader"
>
  <img :src="courseInfo.cover">
</el-upload>
</el-form-item>

2)js实现

//guli-admin/src/views/course/add.vue
export default {
  data() {
    return {
      saveBtnDisabled: false, //保存按钮是否禁用
      courseInfo: {
        subjectId:"",
        cover:"/static/vue.png"
      }, //课程信息
      teacherList:[], //讲师信息
      oneSubjectList:[],//一级分类
      twoSubjectList:[],//二级分类
      BASE_API: process.env.BASE_API // 接口API地址
    };
  },

  created() {
    console.log("info created");
    this.getTeacherList();
    this.getOneSubjectList();
  },

  methods: {
    //获取分类信息
    getOneSubjectList(){
      subject.getAllSubject().then(response=>{
        this.oneSubjectList = response.data.allSubject;
      })
    },
    //二级联动事件
    getTwoByOneSubjectId(oneId){
      for(let i=0;i<this.oneSubjectList.length;i++){
        let oneSubject = this.oneSubjectList[i]
        if(oneId === oneSubject.id){ //恒等,既判断数值又判断类型
          this.twoSubjectList = oneSubject.children;
          this.courseInfo.subjectId = '';
        }
      }
    },
    //获得讲师信息
    getTeacherList() {  //此初始化方法在页面加载的时候执行
      teacher.getAllTeacher().then(response => {
        this.teacherList = response.data.items;
      });
    },
    handleAvatarSuccess(res, file) {
      this.courseInfo.cover = res.data.url;
    },
    //上传前方法
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg";
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
    next() {
      console.log("next");
      //1调用接口保存数据
      course.addCourseInfo(this.courseInfo).then(response => {
        this.$message({
          type: "success",
          message: "添加成功!"
        });
        //2跳转到课程大纲页面
        //this.$router.push({ path: "/edu/course/chapter/1" });
      });
    }
  }
};

7.富文本编辑框

1)添加配置

//在 guli-admin/build/webpack.dev.conf.js 中添加配置
new HtmlWebpackPlugin({
  filename: 'index.html',
  template: 'index.html',
  inject: true,
  favicon: resolve('favicon.ico'),
  title: 'vue-admin-template',
  templateParameters: {
    BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
  }
})

2)引入js脚本

//在guli-admin/index.html 中引入js脚本
<body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <script src=<%=BASE_URL %>/tinymce4.7.5/tinymce.min.js ></script>
    <script src=<%=BASE_URL %>/tinymce4.7.5/langs / zh_CN.js ></script>
</body>

3)页面引入组件

import Tinymce from '@/components/Tinymce';
export default {
  components: {Tinymce},
  ..........

4)添加页面元素

<!-- 课程简介-->
<el-form-item label="课程简介">
    <tinymce :height="300" v-model="courseInfo.description"/>
</el-form-item>

5)添加样式

<style scoped>
.tinymce-container {
  line-height: 29px;
}
</style>

8.课程发布页面整合

2)初始化新增页面

//guli-admin/src/views/course/chapter.vue
<template>
  <div class="app-container">
    <h2 style="text-align: center;">发布新课程</h2>

    <el-steps :active="2" process-status="wait" align-center style="margin-bottom: 40px;">
      <el-step title="填写课程基本信息"/>
      <el-step title="创建课程大纲"/>
      <el-step title="提交审核"/>
    </el-steps>

    <el-form label-width="120px">

      <el-form-item>
        <el-button @click="previous">上一步</el-button>
        <el-button :disabled="saveBtnDisabled" type="primary" @click="next">下一步</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      saveBtnDisabled: false // 保存按钮是否禁用
    }
  },
  created() {
    console.log('chapter created')
  },
  methods: {
    previous() {
      console.log('previous')
      this.$router.push({ path: '/edu/course/info/1' })
    },
    next() {
      console.log('next')
      this.$router.push({ path: '/edu/course/publish/1' })
    }
  }
}
</script>
//guli-admin/src/views/course/publish.vue
<template>
  <div class="app-container">
    <h2 style="text-align: center;">发布新课程</h2>

    <el-steps :active="3" process-status="wait" align-center style="margin-bottom: 40px;">
      <el-step title="填写课程基本信息"/>
      <el-step title="创建课程大纲"/>
      <el-step title="提交审核"/>
    </el-steps>

    <el-form label-width="120px">

      <el-form-item>
        <el-button @click="previous">返回修改</el-button>
        <el-button :disabled="saveBtnDisabled" type="primary" @click="publish">发布课程</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      saveBtnDisabled: false // 保存按钮是否禁用
    }
  },
  created() {
    console.log('publish created')
  },
  methods: {
    previous() {
      console.log('previous')
      this.$router.push({ path: '/edu/course/chapter/1' })
    },
    publish() {
      console.log('publish')
      this.$router.push({ path: '/edu/course/list' })
    }
  }
}
</script>

3)修改课程信息接口

@Api(description="课程管理")
@RestController
@RequestMapping("/eduservice/course")
@CrossOrigin
public class EduCourseController {
    @Autowired
    private EduCourseService courseService;

    @ApiOperation(value = "添加课程信息")
    @PostMapping("addCourseInfo")
    public R addCourseInfo(@RequestBody CourseInfoForm courseInfoForm){
        String courseId = courseService.addCourseInfo(courseInfoForm);
        return R.ok().data("courseId",courseId);
    }
}