页面发布
技术方案
本项目使用MQ实现页面发布的技术方案如下:
技术方案说明:
- 平台包括多个站点,页面归属不同的站点。
- 发布一个页面应将该页面发布到所属站点的服务器上。
- 每个站点服务部署cms client程序,并与交换机绑定,绑定时指定站点Id为routingKey。指定站点id为routingKey就可以实现cms client只能接收到所属站点的页面发布消息。
- 页面发布程序向MQ发布消息时指定页面所属站点Id为routingKey,将该页面发布到它所在服务器上的cms client。
页面发布流程图如下:
- 前端请求cms执行页面发布。
- cms执行静态化程序生成html文件。
- cms将html文件存储到GridFS中。
- cms向MQ发送页面发布消息。
- MQ将页面发布消息通知给Cms Client。
- Cms Client从GridFS中下载html文件。
- Cms Client将html保存到所在服务器指定目录。
页面发布消费方
需求
功能分析:
创建Cms Client
工程作为页面发布消费方,将Cms Client
部署在多个服务器上,它负责接收到页面发布的消息后从GridFS
中下载文件在本地保存。
需求如下:
- 将cms Client部署在服务器,配置队列名称和站点ID。
- cms Client连接RabbitMQ并监听各自的“页面发布队列”。
- cms Client接收页面发布队列的消息。
- 根据消息中的页面id从mongodb数据库下载页面到本地。
工程搭建省略
pom.xml
1 |
|
配置文件
1 | server: |
启动类
1 | package com.xuecheng.cms_manage_client; |
RabbitmqConfig(配置类)
1 | package com.xuecheng.cms_manage_client.config; |
Dao
数据访问代码参考xc-service-manage-cms
中的dao
,直接复制即可
PageService
1 | package com.xuecheng.cms_manage_client.service; |
注意:我使用的这一版本的数据库中cms_site
中没有物理路径这一字段,但是在cms_page
中的物理字段使用的是绝对路径,所以我这里直接使用的cms_page
中的物理路径。
ConsumerPostPage
编写页面发布消费方代码
1 | package com.xuecheng.cms_manage_client.mq; |
页面发布生产方
需求
管理员通过cms系统发布“页面发布”的消费,cms系统作为页面发布的生产方。
需求如下:
- 管理员进入管理界面点击“页面发布”,前端请求cms页面发布接口。
- cms页面发布接口执行页面静态化,并将静态化页面存储至GridFS中。
- 静态化成功后,向消息队列发送页面发布的消息。
- 获取页面的信息及页面所属站点ID。
- 设置消息内容为页面ID。(采用json格式,方便日后扩展)
- 发送消息给ex_cms_postpage交换机,并将站点ID作为routingKey。
RabbitMQ配置
在xc-service-manage-cms
工程中,进行下列配置:
引入依赖(若没有引入amqp的依赖,则需要引入)
1
2
3
4<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>application.yml中新增Rabbitmq相关配置
1
2
3
4
5
6
7
8spring:
rabbitmq:
host: 127.0.0.1
port: 5672
# 此账号是我自行创建的,也可以直接使用默认账号:guest
username: xcEdu
password: 123456
virtualHost: /RabbitMQ配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.xuecheng.manage_cms.config;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.ExchangeBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class RabbitmqConfig {
//交换机的名称
public static final String EX_ROUTING_CMS_POSTPAGE = "ex_routing_cms_postpage";
/**
* 交换机配置使用direct类型
*
* @return the exchange
*/
(EX_ROUTING_CMS_POSTPAGE)
public Exchange EXCHANGE_TOPICS_INFORM() {
return ExchangeBuilder.directExchange(EX_ROUTING_CMS_POSTPAGE).durable(true).build();
}
}
CmsPageControllerApi
在CmsPageControllerApi
中新增接口定义
1 | "页面发布") ( |
CmsPageController
1 | /** |
CmsPageService
1 |
|
前端
用户操作流程:
- 用户进入cms页面列表。
- 点击“发布”请求服务端接口,发布页面。
- 提示“发布成功”,或发布失败。
代码实现如下
cms.js
中新增接口定义1
2
3
4
5
6/**
* 页面发布
*/
export const postPage = (pageId) => {
return http.requestQuickGet(apiUrl + '/cms/page/post/'+ pageId)
}在
page_list.vue
中新增发布
按钮,与页面预览
按钮类似1
2
3
4
5<el-button
size="small"
type="text"
@click="postPage(scope.$index, scope.row)">发布
</el-button>在
page_list.vue
的方法区中,新增postPage
方法,用于调用页面发布接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17postPage:function(index, data) {
this.$confirm('确认发布此页面?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 页面发布
cmsApi.postPage(data.pageId).then(res => {
// 提示消息
this.$message({
showClose: true,
message: res.message,
type: 'success'
})
})
})
}
测试
设置页面信息
点击发布
查看是否生成文件
OK,文件成功发布并保存。
课程管理
微服务工程导入(省略)
前端工程导入排坑
我这里导入前端工程后,运行报错!!!
错误信息:
1 | Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime (64) |
???what f**k
然后我去node-sass
的github看了下,好像也有蛮多人遇到类似问题的。
https://github.com/microsoft/PartsUnlimited/issues/134
解决方法:
使用
npm update
更新版本,需要注意从npm v2.6.1
开始,npm update
只更新顶层模块,而不更新依赖的模块,以前版本是递归更新的。如果想取到老版本的效果,要使用下面的命令1
npm --depth 9999 update
重新build一下
node-sass
1
npm rebuild node-sass
然后就可以直接:npm run dev
成功运行。
课程管理实现
分析
- 课程列表查询,该功能前端基本上没什么需要修改的地方了,直接写后端的分页查询接口即可。
- 课程的新增和编辑(重点),前端已经帮我把课程中的课程分类,适用等级以及学习模式的查询调用给我写好了,我们只需要完成响应接口的编写。
- 课程分类的查询比较简单,在课程微服务中
Category
表中就能够取到数据,结果只需要封装在CategoryNode
中即可。都是已经写好的实体类。 - 适用等级和学习模式查询,都在
mongodb
数据库中,也就是之前的CMS相关的数据库中,我们需要在CMS微服务中新增数据字典数据的查询,实体类分别是:SysDictionary
和SysDictionaryValue
- 编辑的时候,还需要数据的回显,这就需要完成查询。
- 课程分类的查询比较简单,在课程微服务中
数据字典查询实现
DictionaryController
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
33package com.xuecheng.system.controller;
import com.xuecheng.framework.domain.system.SysDictionary;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.web.BaseController;
import com.xuecheng.system.service.DictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
"sys/dictionary") (
public class DictionaryController extends BaseController {
private DictionaryService dictionaryService;
/**
* 按type获取数据字段值
*
* @param type 数据类型
* @return SysDictionary
*/
"get/{type}") (
public SysDictionary getDictionaryByType(@PathVariable String type) {
SysDictionary sysDictionary = dictionaryService.findByType(type);
isNullOrEmpty(sysDictionary, CommonCode.PARAMS_ERROR);
return sysDictionary;
}
}DictionaryService
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
26package com.xuecheng.system.service;
import com.xuecheng.framework.domain.system.SysDictionary;
import com.xuecheng.framework.service.BaseService;
import com.xuecheng.manage_cms.dao.DictionaryRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
4j
public class DictionaryService extends BaseService {
private DictionaryRepository dictionaryRepository;
/**
* 按type获取数据字段值
*
* @param type 数据类型
* @return SysDictionary
*/
public SysDictionary findByType(String type) {
return dictionaryRepository.findByDType(type);
}
}DictionaryRepository
1
2
3
4
5
6
7
8
9
10package com.xuecheng.manage_cms.dao;
import com.xuecheng.framework.domain.system.SysDictionary;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface DictionaryRepository extends MongoRepository<SysDictionary, String> {
SysDictionary findByDType(String type);
}
注意:
因为前端已经写好了接口调用而且调用的端口号是cms微服务对应端口号,所以如果不想修改前端的调用端口的话,建议直接将数据字典查询的代码写在cms微服务中。
课程管理实现
CourseController
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
72package com.xuecheng.manage_course.controller;
import com.xuecheng.api.course.CourseBaseControllerApi;
import com.xuecheng.framework.domain.course.CourseBase;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import com.xuecheng.framework.domain.course.response.AddCourseResult;
import com.xuecheng.framework.domain.course.response.CourseBaseResult;
import com.xuecheng.framework.domain.course.response.CourseCode;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.web.BaseController;
import com.xuecheng.manage_course.service.CourseBaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
"course/coursebase") (
public class CourseBaseController extends BaseController implements CourseBaseControllerApi {
private CourseBaseService courseBaseService;
"list/{page}/{size}") (
public QueryResponseResult findList(@PathVariable int page,
@PathVariable int size,
CourseListRequest queryPageRequest) {
return courseBaseService.findList(page, size, queryPageRequest);
}
/**
* 新增课程基本信息
*
* @param courseBase 课程基本信息
*/
"add") (
public AddCourseResult addCourse(@RequestBody CourseBase courseBase) {
isNullOrEmpty(courseBase, CommonCode.PARAMS_ERROR);
CourseBase add = courseBaseService.add(courseBase);
isNullOrEmpty(add, CommonCode.SERVER_ERROR);
return new AddCourseResult(CommonCode.SUCCESS, add.getId());
}
/**
* 编辑课程基本信息
*
* @param courseBase 课程基本信息
*/
"edit") (
public AddCourseResult editCourse(@RequestBody CourseBase courseBase) {
isNullOrEmpty(courseBase, CommonCode.PARAMS_ERROR);
courseBaseService.edit(courseBase);
return null;
}
/**
* 按课程ID查询课程基本信息
*
* @param courseId
*/
"{courseId}") (
public CourseBaseResult findById(@PathVariable String courseId) {
isNullOrEmpty(courseId, CommonCode.PARAMS_ERROR);
CourseBase courseBase = courseBaseService.findById(courseId);
isNullOrEmpty(courseBase, CourseCode.COURSE_NOT_EXIST);
return CourseBaseResult.SUCCESS(courseBase);
}
}CourseBaseService
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
97package com.xuecheng.manage_course.service;
import com.xuecheng.framework.domain.course.CourseBase;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import com.xuecheng.framework.domain.course.response.CourseCode;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.QueryResult;
import com.xuecheng.framework.service.BaseService;
import com.xuecheng.manage_course.dao.CourseBaseRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
4j
public class CourseBaseService extends BaseService {
private CourseBaseRepository courseBaseRepository;
/**
* 新增课程基本信息
*
* @param courseBase 课程基本信息
* @return CourseBase
*/
public CourseBase add(CourseBase courseBase) {
// 新增
return courseBaseRepository.save(courseBase);
}
/**
* 编辑课程基本信息
*
* @param courseBase 课程基本信息
* @return CourseBase
*/
public CourseBase edit(CourseBase courseBase) {
CourseBase _courseBase = findById(courseBase.getId());
isNullOrEmpty(_courseBase, CourseCode.COURSE_NOT_EXIST);
// 更新
_courseBase.setName(courseBase.getName());
_courseBase.setMt(courseBase.getMt());
_courseBase.setSt(courseBase.getSt());
_courseBase.setGrade(courseBase.getGrade());
_courseBase.setStudymodel(courseBase.getStudymodel());
_courseBase.setDescription(courseBase.getDescription());
return courseBaseRepository.save(_courseBase);
}
/**
* 按ID查询课程基本信息
*
* @param courseBaseId 课程ID
* @return CourseBase
*/
public CourseBase findById(String courseBaseId) {
return courseBaseRepository.findById(courseBaseId).orElse(null);
}
/**
* 分页查询课程基本信息
*
* @param page 当前页码
* @param size 每页记录数
* @param queryPageRequest 查询条件
* @return QueryResponseResult
*/
public QueryResponseResult findList(int page, int size, CourseListRequest queryPageRequest) {
if (page < 0) {
page = 1;
}
// 页码下标从0开始
page = page - 1;
CourseBase params = new CourseBase();
if (StringUtils.isNotBlank(queryPageRequest.getCompanyId())) {
params.setCompanyId(queryPageRequest.getCompanyId());
}
Example<CourseBase> courseBaseExample = Example.of(params);
// 分页查询
Page<CourseBase> pageResult = courseBaseRepository.findAll(courseBaseExample, PageRequest.of(page, size));
QueryResult<CourseBase> queryResult = new QueryResult<>();
queryResult.setTotal(pageResult.getTotalElements());
queryResult.setList(pageResult.getContent());
return new QueryResponseResult(CommonCode.SUCCESS, queryResult);
}
}CourseBaseRepository
1
2
3
4
5
6
7
8
9
10package com.xuecheng.manage_course.dao;
import com.xuecheng.framework.domain.course.CourseBase;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Created by Administrator.
*/
public interface CourseBaseRepository extends JpaRepository<CourseBase,String> {
}
分类列表查询
CategoryController
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
29package com.xuecheng.manage_course.controller;
import com.xuecheng.api.course.CategoryControllerApi;
import com.xuecheng.framework.domain.course.ext.CategoryNode;
import com.xuecheng.framework.web.BaseController;
import com.xuecheng.manage_course.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
"category") (
public class CategoryController extends BaseController implements CategoryControllerApi {
private CategoryService categoryService;
/**
* 查询分类列表
*
* @return CategoryNode
*/
"list") (
public CategoryNode findCategoryList() {
return categoryService.findCategoryList();
}
}CategoryService
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
73package com.xuecheng.manage_course.service;
import com.xuecheng.framework.domain.course.Category;
import com.xuecheng.framework.domain.course.ext.CategoryNode;
import com.xuecheng.manage_course.dao.CategoryRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
4j
public class CategoryService {
private CategoryRepository categoryRepository;
/**
* 查询分类列表
*
* @return CategoryNode
*/
public CategoryNode findCategoryList() {
CategoryNode sourceCategoryNode = buildCategoryNode(categoryRepository.findByParentid("0").get(0));
// 查询第二级分类列表
List<Category> secondaryCategoryList = categoryRepository.findByParentid(sourceCategoryNode.getId());
List<CategoryNode> secondaryCategoryNodeList = buildCategoryNodeList(secondaryCategoryList);
sourceCategoryNode.setChildren(secondaryCategoryNodeList);
return sourceCategoryNode;
}
/**
* 构造分类节点列表
*
* @param categoryList
* @return List<CategoryNode>
*/
private List<CategoryNode> buildCategoryNodeList(List<Category> categoryList) {
return categoryList.stream().map(secondaryCategory -> {
CategoryNode categoryNode = buildCategoryNode(secondaryCategory);
// 查询子节点
List<Category> children = categoryRepository.findByParentid(categoryNode.getId());
List<CategoryNode> categoryNodes = buildCategoryNodeList(children);
if (!categoryNodes.isEmpty()) {
categoryNode.setChildren(categoryNodes);
}
return categoryNode;
}).collect(Collectors.toList());
}
/**
* 构造分类节点数据
*
* @param category 分类
* @return CategoryNode
*/
private CategoryNode buildCategoryNode(Category category) {
CategoryNode categoryNode = new CategoryNode();
categoryNode.setId(category.getId());
categoryNode.setIsleaf(category.getIsleaf());
categoryNode.setLabel(category.getLabel());
categoryNode.setName(category.getName());
return categoryNode;
}
}CategoryRepository
1
2
3
4
5
6
7
8
9
10
11package com.xuecheng.manage_course.dao;
import com.xuecheng.framework.domain.course.Category;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface CategoryRepository extends CrudRepository<Category, String> {
List<Category> findByParentid(String parentId);
}
前端
前端基本没什么需要改动的地方,因为我在课程管理中,使用了自己新建的返回对象CourseBaseResult
,所以前端就需要改一点东西,费力不讨好啊,建议各位直接使用CourseBase
作为查询的返回值!
还有就是前端使用element-ui
版本,属实有点太低了,很多效果是出不来的,所以我进行了版本更换,我更换到2.10.1
之后,课程的新增和编辑页的头部导航菜单出现了样式错误,我修改了一下
修改之前,是用router-link
标签包裹的el-menu-item
标签。
基本就这些了。
课程计划
课程计划查询
CoursePlanController
1 | package com.xuecheng.manage_course.controller; |
CoursePlanService
1 | package com.xuecheng.manage_course.service; |
CoursePlanMapper
1 | package com.xuecheng.manage_course.dao; |
TeachplanMapper.xml
1 |
|
测试
排坑
调用mapper
方法的时候报错:
1 | Invalid bound statement (not found): com.xuecheng.manage_course.dao.CoursePlanMapper.findList |
原因是mybatis
没有正确的加载到mapper.xml
文件,在application.yml
中加入下方配置
1 | mybatis: |
添加课程计划
CoursePlanController
1 | /** |
CoursePlanService
1 | /** |
CoursePlanRepository
1 | package com.xuecheng.manage_course.dao; |
前端
修改保存成功后,关闭表单输入窗口,修改course_pan.vue
中的addTeachplan
方法
1 | addTeachplan(){ |
编辑/删除课程计划
后端
CoursePlanController
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/**
* 编辑课程计划
*
* @param teachplan 课程计划
* @return ResponseResult
*/
"edit") (
public ResponseResult edit(@RequestBody Teachplan teachplan) {
if (teachplan == null
|| StringUtils.isBlank(teachplan.getCourseid())
|| StringUtils.isBlank(teachplan.getId())) {
return new ResponseResult(CommonCode.PARAMS_ERROR);
}
// 编辑
Teachplan edit = coursePlanService.edit(teachplan);
isNullOrEmpty(edit, CourseCode.COURSE_PLAN_ADD_ERROR);
return ResponseResult.SUCCESS();
}
/**
* 删除课程计划
*
* @param teachplanId 课程计划ID
* @return ResponseResult
*/
"{teachplanId}") (
public ResponseResult delete(@PathVariable String teachplanId) {
coursePlanService.deleteById(teachplanId);
return ResponseResult.SUCCESS();
}CoursePlanService
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/**
* 编辑课程计划
*
* @param teachplan 课程计划
* @return Teachplan
*/
public Teachplan edit(Teachplan teachplan) {
Optional<Teachplan> optionalTeachplan = coursePlanRepository.findById(teachplan.getId());
if (!optionalTeachplan.isPresent()) {
ExceptionCast.cast(CourseCode.COURSE_NOT_EXIST);
}
Teachplan _teachplan = optionalTeachplan.get();
_teachplan.setGrade(teachplan.getGrade());
_teachplan.setPname(teachplan.getPname());
_teachplan.setCourseid(teachplan.getCourseid());
_teachplan.setDescription(teachplan.getDescription());
_teachplan.setOrderby(teachplan.getOrderby());
_teachplan.setStatus(teachplan.getStatus());
_teachplan.setTimelength(teachplan.getTimelength());
Teachplan root = getTeachplanRoot(teachplan.getCourseid());
// 设置父ID
if (StringUtils.isBlank(teachplan.getParentid())) {
_teachplan.setParentid(root.getId());
}
return coursePlanRepository.save(_teachplan);
}
/**
* 查询指定ID的课程计划
*
* @param teachplanId 课程计划ID
* @return Teachplan
*/
public Teachplan findById(String teachplanId) {
Optional<Teachplan> optionalTeachplan = coursePlanRepository.findById(teachplanId);
if (!optionalTeachplan.isPresent()) {
ExceptionCast.cast(CourseCode.COURSE_NOT_EXIST);
}
return optionalTeachplan.get();
}
/**
* 删除指定ID的课程计划
*
* @param teachplanId 课程计划ID
*/
public void deleteById(String teachplanId) {
coursePlanRepository.deleteById(teachplanId);
}
前端
新增API定义,修改
course.js
1
2
3
4
5
6
7
8
9
10
11
12/*查询课程计划*/
export const findTeachplanById = teachplanById => {
return http.requestQuickGet(apiUrl+'/course/teachplan/'+teachplanById)
}
/*编辑课程计划*/
export const editTeachplan = teachplah => {
return http.requestPut(apiUrl+'/course/teachplan/edit',teachplah)
}
/*删除课程计划*/
export const deleteTeachplan = teachplahId => {
return http.requestDelete(apiUrl+'/course/teachplan/' + teachplahId)
}页面修改,修改内容主要为
- 点击修改按钮,弹出修改框并回显数据,提交API调用
- 点击删除按钮,弹出确认框,确认后API调用
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
55edit(data){
// 查询
courseApi.findTeachplanById(data.id).then(res => {
this.teachplanActive = res
if (res.grade === '2') {
this.teachplanActive.parentid = ''
}
this.teachplayFormVisible = true
})
//校验表单
this.$refs.teachplanForm.validate((valid) => {
if (valid) {
//调用api方法
//将课程id设置到teachplanActive
this.teachplanActive.courseid = this.courseid
courseApi.editTeachplan(this.teachplanActive).then(res=>{
if(res.success){
this.$message({
showClose: true,
message: res.message,
type: 'success'
})
this.teachplayFormVisible = false
//刷新树
this.findTeachplan()
}else{
this.$message.error(res.message)
}
})
}
})
},
remove(node, data) {
// 执行删除
this.$confirm('确认删除该课程计划?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 删除
courseApi.deleteTeachplan(data.id).then(res => {
// 提示消息
this.$message({
showClose: true,
message: res.message,
type: 'success'
})
//刷新树
this.findTeachplan()
})
})
}注意:
由于新增和编辑用的同一个表单按钮,所以要做判断,若ID为空时调用新增,否则调用编辑
1
2
3
4
5
6
7
8
9
10// 将按钮调用改为save方法
<el-button type="primary" v-on:click="save">提交</el-button>
save() {
if (this.teachplanActive.id) {
this.edit(this.teachplanActive)
} else {
this.addTeachplan()
}
}
因为我没看课程目录,后一天的内容居然是课程管理的实战。。我在这一笔记里面就自己把课程管理的实战给做了,但是缺少课程营销相关的内容,我就不做了,懒得做(懒人就是我😜😜😜)