day07项目【课程发布-添加课程信息】

课程相关表关系

01-课程发布表单-步骤导航

一、需求

二、配置路由

1、添加路由

 {

    path: '/course',

    component: Layout,

    redirect: '/course/list',

    name: '课程管理',

    meta: { title: '课程管理', icon: 'example' },

    children: [

      {

        path: 'list',

        name: '课程列表',

        component: () => import('@/views/edu/course/list'),

        meta: { title: '课程列表', icon: 'table' }

      },

      {

        path: 'info',

        name: 'EduCourseInfo',

        component: () => import('@/views/edu/course/info'),

        meta: { title: '发布课程' ,icon: 'tree'}

      },

      {

        path: 'info/:id',

        name: 'EduCourseInfoEdit',

        component: () => import('@/views/edu/course/info'),

        meta: { title: '编辑课程基本信息', noCache: true },

        hidden: true

      },

      {

        path: 'chapter/:id',

        name: '编辑课程大纲',

        component: () => import('@/views/edu/course/chapter'),

        meta: { title: '编辑课程大纲', icon: 'tree' },

        hidden: true

      },

      {

        path: 'publish/:id',

        name: 'EduTeacherEdit',

        component: () => import('@/views/edu/course/publish'),

        meta: { title: '发布课程', noCache:true },

        hidden:true

      }

    ]

  },

2、添加vue组件

三、整合步骤条组件

参考 http://element-cn.eleme.io/#/zh-CN/component/steps

1、课程信息页面

info.vue

2、课程大纲页面

chapter.vue

3、课程发布页面

publish.vue


02-编辑课程基本信息

一、后台api

1、定义form表单对象

CourseInfoVo.java

@ApiModel(value = "课程基本信息", description = "编辑课程基本信息的表单对象")

@Data

public class CourseInfoVo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "课程ID")

    private String id;

    @ApiModelProperty(value = "课程讲师ID")

    private String teacherId;

    @ApiModelProperty(value = "课程专业ID")

    private String subjectId;

    @ApiModelProperty(value = "课程标题")

    private String title;

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

    //0.01

    private BigDecimal price;

    @ApiModelProperty(value = "总课时")

    private Integer lessonNum;

    @ApiModelProperty(value = "课程封面图片路径")

    private String cover;

    @ApiModelProperty(value = "课程简介")

    private String description;

}

2、修改CourseDescription主键生成策略

由于课程表和课程简介表是一对一的关系,所以简介表的id应该与课程表的id一致。

3、定义控制层接口

@RestController

@RequestMapping("/eduservice/course")

@CrossOrigin

public class EduCourseController {

    @Autowired

    private EduCourseService courseService;

    //添加课程基本信息的方法

    @ApiOperation(value = "新增课程")

    @PostMapping("addCourseInfo")

    public R addCourseInfo( @ApiParam(name = "CourseInfoForm", value = "课程基本信息", required = true)

            @RequestBody CourseInfoVo courseInfoVo){

        courseService.saveCourseInfo(courseInfoVo);

        return R.ok();

    }

}

4、定义业务层方法

接口:EduCourseService.java

public interface EduCourseService extends IService {

    //添加课程基本信息的方法

    void saveCourseInfo(CourseInfoVo courseInfoVo);

}

实现:EduCourseServiceImpl.java

@Service

public class EduCourseServiceImpl extends ServiceImpl implements EduCourseService {

    @Autowired

    private EduCourseDescriptionService courseDescriptionService;

    @Override

    public void saveCourseInfo(CourseInfoVo courseInfoVo) {

        //1 向课程表添加课程基本信息

        //将CourseInfoVo对象转换为eduCourse对象

        EduCourse eduCourse = new EduCourse();

        BeanUtils.copyProperties(courseInfoVo,eduCourse);

        int insert = baseMapper.insert(eduCourse);

        if (insert == 0){

            //添加失败

            throw new GuliException(20001,"添加课程信息失败");

        }

        //获取添加之后的课程id

        String cid = eduCourse.getId();


        //2 向课程简介表添加课程简介

        //EduCourseDescription

        EduCourseDescription courseDescription = new EduCourseDescription();

        courseDescription.setDescription(courseInfoVo.getDescription());


        //设置描述id就是课程id

        courseDescription.setId(cid);

        courseDescriptionService.save(courseDescription);

    }

}

6、Swagger测试

二、前端实现

1、定义api

import request from '@/utils/request'

export default{

    //1 添加课程信息

    addCourseInfo(courseInfo){

        return request({

            url:`/eduservice/course/addCourseInfo`,

            method:'post',

            data:courseInfo

        })

    }

}

2、组件模板


        

            

        


        


        


        

            

        


        

        

            

        

        

        

             元

        

        

            保存并下一步

        

    

3、组件js



03-课程分类多级联动的实现

一、需求

二、获取一级分类

1、组件数据定义

定义在data中

            subjectOneList:[],//一级分类

            subjectTwoList:[],//二级分类

2、组件模板

        

            

                v-model="courseInfo.subjectParentId"

                placeholder="一级分类">

                

                    v-for="subject in subjectOneList"

                    :key="subject.id"

                    :label="subject.title"

                    :value="subject.id"/>

            

    

3、组件脚本

表单初始化时获取一级分类嵌套列表,引入subject api

import subject from '@/api/edu/subject'

定义方法

        //获取一级分类

        getOneSubjectList(){

            subject.getSubjectList()

                .then(response=>{

                    this.subjectOneList = response.data.list

                })

        },

三、级联显示二级分类

1、组件模板

            

            subjectId" placeholder="二级分类">

                

                    v-for="subject in subjectTwoList"

                    :key="subject.id"

                    :label="subject.title"

                    :value="subject.id"/>

            

2、注册change事件

在一级分类的组件中注册change事件

        

        

            

                v-model="courseInfo.subjectParentId"

                placeholder="一级分类" @change="subjectLevelOneChanged">

               .......

            

3、定义change事件方法

        //点击某一个一级分类,触发change事件,显示对应二级分类

        subjectLevelOneChanged(value){

            //value就是一级分类id值

            //遍历所有的分类,包含一级和二级

            for(var i =0; isubjectOneList.length;i++){

                //每一个一级分类

                var oneSubject = this.subjectOneList[i]

                //判断:所有一级分类id和点击一级分类id是否一样

                if(oneSubject.id === value){

                    //从一级分类获取里面所有的二级分类

                    this.subjectTwoList = oneSubject.children

                    //把二级分类id值清空

                    this.courseInfo.subjectId = ''

                }

            }

        },


04-讲师下拉列表

一、前端实现

1、组件模板

        

        

        

            

                v-model="courseInfo.teacherId"

                placeholder="请选择">

                

                    v-for="teacher in teacherList"

                    :key="teacher.id"

                    :label="teacher.name"

                    :value="teacher.id"/>

            

        

2、定义api

api/edu/course.js

//2 查询所有讲师

    getListTeacher(){

        return request({

            url:`/eduservice/teacher/findAll`,

            method:'get'

        })

    }

组件中引入course api

import course from '@/api/edu/course'

3、组件脚本

定义data

teacherList:[],//讲师列表

获取讲师列表:

        //查询所有讲师

        getListTeacher(){

            course.getListTeacher()

                .then(response => {

                    this.teacherList = response.data.items

                })

        }

  created(){

        //初始化所有讲师

        this.getListTeacher()

    },


05-富文本编辑器Tinymce

一、Tinymce可视化编辑器

参考

https://panjiachen.gitee.io/vue-element-admin/#/components/tinymce

https://panjiachen.gitee.io/vue-element-admin/#/example/create

二、组件初始化

Tinymce是一个传统javascript插件,默认不能用于Vue.js因此需要做一些特殊的整合步骤

1、复制脚本库

将脚本库复制到项目的static目录下(在vue-element-admin-master的static路径下)

2、配置html变量

在 guli-admin/build/webpack.dev.conf.js 中添加配置

使在html页面中可是使用这里定义的BASE_URL变量

3、引入js脚本

在guli-admin/index.html 中引入js脚本

    /tinymce4.7.5/tinymce.min.js>

    /tinymce4.7.5/langs/zh_CN.js>

三、组件引入

为了让Tinymce能用于Vue.js项目,vue-element-admin-master对Tinymce进行了封装,下面我们将它引入到我们的课程信息页面

1、复制组件

src/components/Tinymce

2、引入组件

课程信息组件中引入 Tinymce

import Tinymce from '@/components/Tinymce' //引用

export default {

    components: { Tinymce }, //声明

    .......

}

3、组件模板

       

        

            courseInfo.description"/>

        

4、组件样式

在info.vue文件的最后添加如下代码,调整上传图片按钮的高度

/* scoped表示只在当前页面有效 */    

    .tinymce-container {

        line-height: 29px;

    }

5、图片的base64编码

Tinymce中的图片上传功能直接存储的是图片的base64编码,因此无需图片服务器

测试:

添加一级分类id:



06-课程封面

一、整合上传组件

参考 http://element-cn.eleme.io/#/zh-CN/component/upload用户头像上传

1、定义data数据

BASE_API: process.env.BASE_API, // 接口API地址

2、组件模板

在info.vue中添加上传组件模板

        

                 


            

                :show-file-list="false"

                :on-success="handleAvatarSuccess"

                :before-upload="beforeAvatarUpload"

                :action="BASE_API+'/eduoss/fileoss'"

                class="avatar-uploader">

            

        

5、结果回调

        //上传封面成功

        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

        },




07-课程信息回显

一、后端实现

1、业务层

接口:CourseService.java

//根据ID查询课程

CourseInfoVo getCourseInfoFormById(String courseId);

实现:CourseServiceImpl.java

@Override

    public CourseInfoVo getCourseInfoFormById(String courseId) {

        //1 查询课程表

        EduCourse eduCourse = baseMapper.selectById(courseId);

//        EduCourse eduCourse = this.getById(courseId);

        if (eduCourse == null){

            throw new GuliException(20001, "数据不存在");

        }

        //把eduCourse对象中的值复制到courseInfoVo中

        CourseInfoVo courseInfoVo = new CourseInfoVo();

        BeanUtils.copyProperties(eduCourse,courseInfoVo);


        //2 查询描述表

        EduCourseDescription courseDescription = courseDescriptionService.getById(courseId);

        if (eduCourse !=null){

            //讲描述信息放入courseInfoVo

            courseInfoVo.setDescription(courseDescription.getDescription());

        }

        return courseInfoVo;

    }

2、web层

    @ApiOperation(value = "根据ID查询课程")

    @GetMapping("getCourseInfo/{courseId}")

    public R getCourseInfo(@ApiParam(name = "id", value = "课程ID", required = true)

                        @PathVariable String courseId){

      CourseInfoVo courseInfoVo  = courseService.getCourseInfoFormById(courseId);

        return R.ok().data("courseInfoVo",courseInfoVo);

    }

3、Swagger中测试

二、前端实现

1、定义api

api/edu/course.js

 //3 根据id获取课程基本信息

    getCourseInfoById(id){

        return request({

            url:`/eduservice/course/getCourseInfo/${id}`,

            method:'get'            

        })

    },

2、组件js

data中声明:

  courseId:'',

created()

    //获取路由中的路由id值

        if(this.$route.params && this.$route.params.id){

            this.courseId = this.$route.params.id

            //调用

            this.getInfo()

        }

方法:

    //根据id获取课程信息

        getInfo(){

            course.getCourseInfoById(this.courseId)

                .then(response => {

                    this.courseInfo = response.data.courseInfoVo

                })

        },

三、解决级联下拉菜单回显问题

1、数据库中增加冗余列

subject_parent_id课程专业父级ID

2、pojo中增加属性

entity.Course.java

form.CourseInfo.java

@ApiModelProperty(value = "一级分类ID")

    private String subjectParentId;

3、vue组件中绑定数据

edu/course/info.vue

4、修改init方法

将 this.initSubjectList() 和 this.initTeacherList()移至else

        //init方法

        init(){

             //获取路由中的路由id值

            if(this.$route.params && this.$route.params.id){

                this.courseId = this.$route.params.id

                //调用

                this.getInfo()

            }else{

                //清空表单

                this.courseInfo = {...defaultForm}

                //初始化所有讲师

                this.getListTeacher()

                //初始化一级分类

                this.getOneSubjectList()

            }

        },

5、修改fetchCourseInfoById方法

解决在返回上一步的二级表单的问题。

    //根据id获取课程信息

        getInfo(){

            course.getCourseInfoById(this.courseId)

                .then(response => {

                    this.courseInfo = response.data.courseInfoVo

                    //1 查询所有的分类,包含一级和二级

                    subject.getSubjectList()

                        .then(response=>{

                            //2 获取所有一级分类

                            this.subjectOneList = response.data.list

                            //3 把所有的一级分类数组进行遍历

                            for(var i=0;i

                                //获取每一个一级分类

                                var subjectOne = this.subjectOneList[i]

                                //比较当前courseInfo里面的一级分类id和所有的一级分类id

                                if(this.courseInfo.subjectParentId == subjectOne.id){

                                    //获取一级分类里面的所有二级分类

                                    this.subjectTwoList = subjectOne.children

                                }

                            }

                        })

                        //初始化所有讲师

                        this.getListTeacher()

                })

        },

刷新发布课程页面:

const defaultForm = {

    title: '',

    subjectId: '',//二级分类id

    subjectParentId:'',//一级分类id

    teacherId: '',

    lessonNum: 0,

    description: '',

    cover: '/static/11.jpg',

    price: 0

}

 created(){

       this.init()

    },

        //init方法

        init(){

             //获取路由中的路由id值

            if(this.$route.params && this.$route.params.id){

                this.courseId = this.$route.params.id

                //调用

                this.getInfo()

            }else{

                //清空表单

                this.courseInfo = {...defaultForm}

                //初始化所有讲师

                this.getListTeacher()

                //初始化一级分类

                this.getOneSubjectList()

            }

        },


    //监听

    watch:{

        $route(to,from){ //路由变化方式,路由发生变化,方法就会执行

            this.init()

        }

    },



08-更新课程信息

一、后端实现

1、业务层

接口:EduCourseService.java

    //更新课程信息

    void updateCourseInfoById(CourseInfoVo courseInfoVo);

实现:EduCourseServiceImpl.java

    //更新课程信息

    @Override

    public void updateCourseInfoById(CourseInfoVo courseInfoVo) {

        //1 修改课程表

        EduCourse eduCourse = new EduCourse();

        BeanUtils.copyProperties(courseInfoVo,eduCourse);

        int update = baseMapper.updateById(eduCourse);

        if (update == 0){

            throw new GuliException(20001,"修改课程信息失败");

        }

        //2 修改描述表

        EduCourseDescription courseDescription = new EduCourseDescription();

        courseDescription.setId(courseInfoVo.getId());

        courseDescription.setDescription(courseInfoVo.getDescription());

        courseDescriptionService.updateById(courseDescription);

    }

2、web层

    //更新课程信息

    @ApiOperation(value = "更新课程")

    @PostMapping("updateCourseInfo")

    public R updateCourseInfo( @ApiParam(name = "CourseInfoForm", value = "课程基本信息", required = true)

                                  @RequestBody CourseInfoVo courseInfoVo){

        courseService.updateCourseInfoById(courseInfoVo);

        return R.ok();

    }

二、前端实现

1、定义api

course.js

 //4 修改课程基本信息

    updateCourseInfoById(courseInfo){

        return request({

            url:`/eduservice/course/updateCourseInfo`,

            method:'post',

            data:courseInfo

        })

    }

2、组件js

info.vue

 updateCourse(){

            course.updateCourseInfoById(this.courseInfo)

                .then(response=>{

                    //提示

                    this.$message({

                         type: 'success',

                         message: '修改课程信息成功!'

                    });

                    //跳转到第二步

                    this.$router.push({path:'/course/chapter/'+this.courseId})

                })

        },

 saveOrUpdate(){

           if(!this.courseInfo.id){

               //添加

               this.addCourse()

           }else{

               //修改

               this.updateCourse()

           }

        },

403错误

你可能感兴趣的:(day07项目【课程发布-添加课程信息】)