(九)在线教育网站搭建-课程列表实现

element 标签组件 form表单

1. 后端

1.1. ListCourse - 课程显示数据封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.online.edu.eduservice.entity.query;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;

@Data
public class ListCourse {

@ApiModelProperty(value = "课程ID")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;

@ApiModelProperty(value = "课程讲师姓名")
private String teacherName;

@ApiModelProperty(value = "课程专业姓名")
private String subjectTitle;

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

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

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

@ApiModelProperty(value = "视频状态 Draft未发布 Normal已发布")
private String status;
}

1.2. QueryCourse-查询数据封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.online.edu.eduservice.entity.query;

import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;

@Data
public class QueryCourse {

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

@ApiModelProperty(value = "课程专业ID")
private String subjectId;

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

@ApiModelProperty(value = "课程销售价格 0 递增,1 递减排序")
private int priceSort;

}

1.3. 分页查询-pageListCondition

按查询参数查询课程表edu_course,再将课程表中的数据赋值给ListCourse,讲师名edu_teacher和科目名edu_subject又需要通过讲师表,科目表查询到名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@Override
public List<ListCourse> pageListCondition(Page<EduCourse> pageCourse, QueryCourse queryCourse) {

List<EduCourse> eduCourses = null;

if(queryCourse == null){
eduCourses = baseMapper.selectPage(pageCourse,null).getRecords();
}else {
String title = queryCourse.getTitle();
String teacherId = queryCourse.getTeacherId();
String subjectId = queryCourse.getSubjectId();

int priceSort = queryCourse.getPriceSort();

QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(title)) {
queryWrapper.eq("title", title);
}
if (!StringUtils.isEmpty(teacherId)) {
queryWrapper.eq("teacher_id", teacherId);
}
if (!StringUtils.isEmpty(subjectId)) {
queryWrapper.eq("subject_id", subjectId);
}
if (priceSort != 0) {
queryWrapper.orderByDesc("price");
}
queryWrapper.orderByDesc("id");
Page<EduCourse> eduCoursePage = baseMapper.selectPage(pageCourse, queryWrapper);

eduCourses = eduCoursePage.getRecords();
}
//查询列表中要显示的课程信息
List<ListCourse> listCourses = new ArrayList<>();

for(EduCourse course:eduCourses){

ListCourse listCourse = new ListCourse();
BeanUtils.copyProperties(course,listCourse);

String teacherName = eduTeacherService.getById(course.getTeacherId()).getName();
listCourse.setTeacherName(teacherName);

String subjectTitle = eduSubjectService.getById(course.getSubjectId()).getTitle();
listCourse.setSubjectTitle(subjectTitle);

listCourses.add(listCourse);
}
return listCourses;
}

1.4. EduCourseController - MoreCondtionPageList()

1
2
3
4
5
6
7
8
9
10
11
12
13
//多条件查询
@ApiOperation("多条件查询信息")
@PostMapping("/moreCondtionPageList/{current}/{size}")
public R MoreCondtionPageList(
@ApiParam(value = "当前页") @PathVariable @RequestParam(defaultValue = "1") Long current,
@ApiParam(value = "页内记录数") @PathVariable @RequestParam(defaultValue = "10")Long size,
@ApiParam(value = "查询信息") @RequestBody(required = false) QueryCourse queryCourse){

Page<EduCourse> pageCourse = new Page<>(current,size);
List<ListCourse> courses=eduCourseService.pageListCondition(pageCourse,queryCourse);

return R.ok().data("items",courses).data("total",pageCourse.getTotal());
}

1.5. swagger-ui测试

2. 前端

2.1. course.js

1
2
3
4
5
6
7
8
9
10
//条件分页查询
getCoursePageList(current,size,searchObj){
return request({
//controller请求方式
url:`${base}/moreCondtionPageList/${current}/${size}`,
method:'post',
//传递的是json用data:searchObj , 参数的话使用params:searchObj
data:searchObj
})
}

2.2. edu/course/index.vue

表单按照课程名,讲师名,科目名,课程售价,课程是否发布,可用操作来显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
<template>
<div class="app-container">
<!--查询表单-->
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="按条件查询">
<el-input v-model="searchObj.title" placeholder="课程名"/>
</el-form-item>
<!--价格选择 -->
<el-form-item>
<el-select v-model="searchObj.priceSort" clearable placeholder="按价格排序">
<el-option :value="0" label="从低到高"/>
<el-option :value="1" label="从高到低"/>
</el-select>
</el-form-item>
<!--讲师选择 -->
<el-form-item >
<el-select v-model="searchObj.teacherId" placeholder="请选择讲师" clearable filterable>
<el-option
v-for="teacher in teacherList"
:key="teacher.id"
:label="teacher.name"
:value="teacher.id"/>
</el-select>
</el-form-item>
<!--科目选择 -->
<el-form-item>
<el-cascader
v-model="searchObj.subjectId"
:props="defaultProps"
:options="subjectList"
clearable
:show-all-levels="false"
filterable
placeholder="请选择科目">
<template slot-scope="{ node, data }">
<!-- 将子科目为0的定为叶节点 -->
<span v-if="data.children.length===0">
{{dealLeaf(node)}}
</span>

<span>{{ node.label }}</span>
<span v-if="!node.isLeaf">
({{ data.children.length }})
</span>
</template>
</el-cascader>
</el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getCourseList()">查询</el-button>
<el-button type="default" @click="resetData()">清空</el-button>
</el-form>
<!-- 表格 -->
<el-table v-loading="listLoading"
:data="list"
element-loading-text="数据加载中"
border
fit
highlight-current-row>

<el-table-column label="序号" width="80" align="center">
<template slot-scope="scope">
{{ (current - 1) * size + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="title" label="名称" width="350" />
<el-table-column label="讲师" width="120" prop="teacherName" />
<el-table-column label="所属科目" width="120" prop="subjectTitle" >
</el-table-column>
<el-table-column prop="lessonNum" label="总课时" width="80"/>
<el-table-column prop="price" label="价格" width="80"/>

<el-table-column label="课程状态">
<template slot-scope="{row}">
<el-tag v-if="row.status=='Normal'" type="success">{{row.status}}</el-tag>
<el-tag v-else type="info">
{{ row.status }}
</el-tag>
</template>
</el-table-column>

<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<router-link :to="'/course/info/'+scope.row.id">
<el-button type="primary" size="mini" icon="el-icon-edit">修改</el-button>
</router-link>
<el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
:current-page="current"
:page-size="size"
:total="total"
style="padding: 30px 0; text-align: center;"
layout="total, prev, pager, next, jumper"
@current-change="getCourseList"/>
</div>
</template>

<script>
import course from '@/api/edu/course'
import teacher from '@/api/edu/teacher'
import subject from '@/api/edu/subject'

export default{
//定义初值
data(){
return {
list:null, //每页数据集合
current: 1, //当前页
size: 10, //页内记录数
searchObj: {}, //条件
total :0, //总记录数
listLoading: true,
teacherList:[],
subjectList:[],
defaultProps: {
//value 指定选项的值为选项对象的某个属性值
//label 指定选项标签为选项对象的某个属性值
//children 指定选项的子选项为选项对象的某个属性值
//expandTrigger 次级菜单的展开方式
//来设置父子节点取消选中关联,从而达到选择任意一级选项的目的
children: 'children',
label: 'title',
value: 'id',
expandTrigger: 'hover',
emitPath: false,
checkStrictly = true
}
}
},
//页面渲染前,调用方法
created(){
this.searchObj={}
this.getCourseList()
this.resetData()
this.getTeacherList()
this.getSubjectList()
},
//方法定义
methods:{
getTeacherList(){
teacher.getTeacherList().then(response=>{
this.teacherList = response.data.items
})
},
//得到科目分级列表
getSubjectList(){
subject.getSubjectList().then(response=>{
this.subjectList = response.data.nestedList
}).catch()
},
//定义叶节点
dealLeaf(node){
//当子科目为0时,设为叶科目
node.hasChildren=false
//console.log(node)
},
getCourseList(current=1){
this.current=current
this.listLoading=true
course.getCoursePageList(this.current,this.size,this.searchObj)
//当状态码为20000时,才能执行then操作
.then(reponse=>{
//console.log(reponse)
this.list = reponse.data.items
this.total = reponse.data.total
//console.log(this.list)
//console.log(this.total)
this.listLoading=false

this.searchObj.subjectId=''
})
//请求失败调用
.catch()
},
resetData(){
this.searchObj={},
this.getCourseList()
},
//删除课程
removeDataById(id){
this.$confirm('此操作将永久删除该课程相关信息, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
//return 后then方法才会执行
return course.deleteCourseById(id)
})
.then(()=> {
//重新查看所有讲师
this.getCourseList()
this.$message({
type: 'success',
message: '删除成功!'
})
}).catch(response => {
//判断错误操作类别
//console.log(response)
if(response === 'cancel'){
this.$message({
type: 'info',
message: '已取消删除'
})
} else{
this.$message({
type: 'error',
message: '删除失败'
})
}
})
}
}
}

</script>

2.3. 整体显示

form

本文结束  感谢您的阅读