易课寄在线购课系统开发笔记(十七)–完成CMS系统的分析与实现
内容分类管理
展示内容分类
功能分析
请求的 url:/content/category/list
请求的参数:id,当前节点的\id。第一次请求没有参数,需要给默认值 “0”
响应数据:List<EasyUITreeNode>(@ResponseBody)
Json 数据。
[{id:1,text:节点名称,state:open(closed)},
{id:2,text:节点名称2,state:open(closed)},
{id:3,text:节点名称3,state:open(closed)}]
业务逻辑:
1、取查询参数 id,parentId
2、根据 parentId 查询 ecourses_content_category,查询子节点列表。
3、得到List<EcoursesContentCategory>
4、把列表转换成List<EasyUITreeNode>
Dao 层
使用逆向工程
Service
参数:long parentId
返回值:List<EasyUITreeNode>
package cn.ecourses.content.service.impl;
//Content classification management Service
@Service
public class ContentCategoryServiceImpl implements ContentCategoryService {
@Autowired
private EcoursesContentCategoryMapper contentCategoryMapper;
@Override
public List<EasyUITreeNode> getContentCatList(long parentId) {
// List of query subnodes based on parentid
EcoursesContentCategoryExample example = new EcoursesContentCategoryExample();
Criteria criteria = example.createCriteria();
//Setting up query conditions
criteria.andParentIdEqualTo(parentId);
//Execute the query
List<EcoursesContentCategory> catList = contentCategoryMapper.selectByExample(example);
//Convert to EasyUITreeNode list
List<EasyUITreeNode> nodeList = new ArrayList<>();
for (EcoursesContentCategory ecoursesContentCategory : catList) {
EasyUITreeNode node = new EasyUITreeNode();
node.setId(ecoursesContentCategory.getId());
node.setText(ecoursesContentCategory.getName());
node.setState(ecoursesContentCategory.getIsParent()?"closed":"open");
//Add to the list
nodeList.add(node);
}
return nodeList;
}
}
发布服务
<dubbo:service interface="cn.ecourses.content.service.ContentCategoryService" ref="contentCategoryServiceImpl" timeout="600000"/>
表现层
ecourses-bms-web 依赖 ecourses-content-interface 模块
springmvc.xml 中添加服务的引用
<dubbo:reference interface="cn.ecourses.content.service.ContentCategoryService" id="contentCategoryService" />
新增节点
功能分析
请求的url:/content/category/create 请求的参数: Long parentId,String name 响应的结果: JSON 数据,ECoursesResult,其中包含一个对象,对象有 id 属性,新产生的内容分类 id 业务逻辑: 1、接收两个参数:parentId、name 2、向 ecourses_content_category 表中插入数据。 a) 创建一个 EcoursesContentCategory 对象 b) 补全 EcoursesContentCategory 对象的属性 c) 向 ecourses_content_category 表中插入数据 3、判断父节点的 isparent 是否为 true,不是 true 需要改为 true。 4、需要主键返回。 5、返回 ECoursesResult,其中包装 EcoursesContentCategory 对象
Dao 层
可以使用逆向工程。需要添加主键返回:
注意:修改完代码后,需要向本地仓库安装 ecourses-bms-dao 包
Service层
参数:parentId、name 返回值:返回 ECoursesResult,其中包装 EcoursesContentCategory 对象
@Override
public ECoursesResult addContentCategory(long parentId, String name) {
//Create a POJO object corresponding to the ecourses_content_category table
EcoursesContentCategory contentCategory = new EcoursesContentCategory();
//Setting the properties of the POJO
contentCategory.setParentId(parentId);
contentCategory.setName(name);
//1(normal),2(delete)
contentCategory.setStatus(1);
//The default sort is 1
contentCategory.setSortOrder(1);
//The newly added node must be a leaf node
contentCategory.setIsParent(false);
contentCategory.setCreated(new Date());
contentCategory.setUpdated(new Date());
//Insert into the database
contentCategoryMapper.insert(contentCategory);
//Determine the isparent property of the parent node. If not true is changed to true
//Query the parent node according to parentid
EcoursesContentCategory parent = contentCategoryMapper.selectByPrimaryKey(parentId);
if (!parent.getIsParent()) {
parent.setIsParent(true);
//Update to the database
contentCategoryMapper.updateByPrimaryKey(parent);
}
//Return to the result, return to ECoursesResult, including POJO
return ECoursesResult.ok(contentCategory);
}
发布服务
<dubbo:service interface="cn.ecourses.content.service.ContentCategoryService" ref="contentCategoryServiceImpl" timeout="600000"/>
表现层
请求的url:/content/category/create
请求的参数:
Long parentId,String name
响应的结果:
JSON 数据,ECoursesResult
@RequestMapping(value="/create", method=RequestMethod.POST)
@ResponseBody
public ECoursesResult createContentCategory(Long parentId, String name) {
//调用服务添加节点
ECoursesResult ecoursesResult = contentCategoryService.addContentCategory(parentId, name);
return ecoursesResult;
}
内容分类重命名
请求的 url:/content/category/update 参数:id,当前节点id。name,重命名后的名称。 业务逻辑:根据 id 更新记录。 返回值:返回 ECoursesResult.ok()
Dao 层
可以使用逆向工程。
Service层
参数:Long id, String name 返回值:返回 ECoursesResult
@Override
public ECoursesResult updateContentCategory(Long id, String name) {
//创建一个pojo
EcoursesContentCategory contentCategory = contentCategoryMapper.selectByPrimaryKey(id);
contentCategory.setName(name);
contentCategoryMapper.updateByPrimaryKey(contentCategory);
return ECoursesResult.ok();
}
表现层
请求的 url:/content/category/update 参数:Long id, String name 返回值:ECoursesResult
@RequestMapping("/update")
@ResponseBody
public ECoursesResult updateNode(Long id, String name) {
ECoursesResult result = contentCategoryService.updateContentCategory(id, name);
return result;
}
内容分类删除结点
请求的url:/content/category/delete/
参数:id,当前节点的 id。
响应的数据:JSON ECoursesResult
业务逻辑:
1、根据 id 删除记录。
2、判断父节点下是否还有子节点,如果没有需要把父节点的 isparent 改为 false
3、如果删除的是父节点,子节点要级联删除。
两种解决方案:
1)如果判断是父节点不允许删除。
2)递归删除。
Dao 层
可以使用逆向工程。
Service层
参数:Long id 返回值:ECoursesResult
@Override
public ECoursesResult deleteContentCategory(Long id) {
deleteCategoryAndChildNode(id);
return ECoursesResult.ok();
}
@Override
public List<EcoursesContentCategory> getChildNodeList(Long id) {
//查询所有父节点为传入id的节点
EcoursesContentCategoryExample example = new EcoursesContentCategoryExample();
Criteria criteria = example.createCriteria();
criteria.andParentIdEqualTo(id);
//返回所有符合要求的节点
return contentCategoryMapper.selectByExample(example);
}
@Override
public void deleteCategoryAndChildNode(Long id) {
//获取要删除的Category
EcoursesContentCategory ecContentCategory = new EcoursesContentCategory();
ecContentCategory = contentCategoryMapper.selectByPrimaryKey(id);
//判断是否为父节点
if(ecContentCategory.getIsParent()){
//获得所有该节点下的孩子节点
List<EcoursesContentCategory> list = getChildNodeList(id);
//删除所有孩子节点
for(EcoursesContentCategory category : list){
deleteCategoryAndChildNode(category.getId());
}
}
//判断父节点下是否还有其他子节点
if(getChildNodeList(ecContentCategory.getParentId()).size()==1){
//没有则将父节点标记为叶子节点
EcoursesContentCategory parentCategory = contentCategoryMapper.selectByPrimaryKey(ecContentCategory.getParentId());
parentCategory.setIsParent(false);
contentCategoryMapper.updateByPrimaryKey(parentCategory);
}
//删除本节点
contentCategoryMapper.deleteByPrimaryKey(id);
return;
}
表现层
请求的 url:/content/category/delete 参数:Long id 返回值:ECoursesResult
@RequestMapping("/delete")
@ResponseBody
public ECoursesResult deleteNode(Long id) {
ECoursesResult result = contentCategoryService.deleteContentCategory(id);
return result;
}
内容管理
功能点分析
1、内容列表查询
2、新增内容
3、编辑内容
4、删除内容
内容列表查询
请求的 url:/content/query/list
参数:categoryId 分类 id
响应的数据:JSON 数据
{total:查询结果总数量,rows[{id:1,title:aaa,subtitle:bb,…}]}
EasyUIDataGridResult
描述课程数据 List<EcoursesContent>
查询的表:ecourses_content
业务逻辑:
根据内容分类 id 查询内容列表。要进行分页处理。
Dao 层
可以使用逆向工程。
Service层
参数:Long categoryId, int page, int rows 返回值:EasyUIDataGridResult
@Override
public EasyUIDataGridResult queryContentList(Long categoryId, int page, int rows) {
//分页处理
PageHelper.startPage(page, rows);
//查询课程列表
EcoursesContentExample example = new EcoursesContentExample();
Criteria criteria = example.createCriteria();
criteria.andCategoryIdEqualTo(categoryId);
List<EcoursesContent> list = contentMapper.selectByExampleWithBLOBs(example);
//取记录总条数
PageInfo<EcoursesContent> pageInfo = new PageInfo<>(list);
//创建EasyUIDataGridResult结果集
EasyUIDataGridResult result = new EasyUIDataGridResult();
result.setRows(list);
result.setTotal(pageInfo.getTotal());
return result;
}
表现层
请求的 url:/content/query/list 参数:Long categoryId, int page, int rows 返回值:EasyUIDataGridResult
@RequestMapping("/query/list")
@ResponseBody
public EasyUIDataGridResult queryContentList(Long categoryId, int page, int rows) {
return contentService.queryContentList(categoryId, page, rows);
}
新增内容
功能分析
新增内容,必须指定一个内容分类。
提交表单请求的 url:/content/save 参数:表单的数据。使用 pojo 接收 EcoursesContent 返回值:ECoursesResult(json 数据) 业务逻辑: 1、把 EcoursesContent 对象属性补全。 2、向 ecourses_content 表中插入数据。 3、返回 ECoursesResult
Dao 层
可以使用逆向工程。
Service 层
参数:EcoursesContent content 返回值:ECoursesResult
@Override
public ECoursesResult addContent(EcoursesContent content) {
//将内容数据插入到内容表
content.setCreated(new Date());
content.setUpdated(new Date());
//插入到数据库
contentMapper.insert(content);
//缓存同步,删除缓存中对应的数据。
jedisClient.hdel(CONTENT_LIST, content.getCategoryId().toString());
return ECoursesResult.ok();
}
表现层
请求的 url:/content/save 参数:EcoursesContent content 返回值:ECoursesResult
@RequestMapping(value="/save", method=RequestMethod.POST)
@ResponseBody
public ECoursesResult addContent(EcoursesContent content) {
//调用服务把内容数据保存到数据库
ECoursesResult ecoursesResult = contentService.addContent(content);
return ecoursesResult;
}
编辑内容
Dao 层
可以使用逆向工程。
Service 层
参数:EcoursesContent content 返回值:ECoursesResult
@Override
public ECoursesResult updateContent(EcoursesContent content) {
//将内容数据插入到内容表
content.setUpdated(new Date());
//插入到数据库
contentMapper.updateByPrimaryKeySelective(content);
//缓存同步,删除缓存中对应的数据。
jedisClient.hdel(CONTENT_LIST, content.getCategoryId().toString());
return ECoursesResult.ok();
}
表现层
请求的 url:/content/edit 参数:EcoursesContent content 返回值:ECoursesResult
@RequestMapping(value="/edit", method=RequestMethod.POST)
@ResponseBody
public ECoursesResult editParam(EcoursesContent content) {
ECoursesResult result = contentService.updateContent(content);
return result;
}
删除内容
Dao 层
可以使用逆向工程。
Service 层
参数:String ids 返回值:ECoursesResult
@Override
public ECoursesResult deleteContentByIds(String ids) {
String[] idArray = ids.split(",");
for (String id : idArray) {
contentMapper.deleteByPrimaryKey(Long.valueOf(id));
}
return ECoursesResult.ok();
}
表现层
请求的 url:/content/delete 参数:String ids 返回值:ECoursesResult
@RequestMapping("/delete")
@ResponseBody
public ECoursesResult deleteParam(@RequestParam("ids") String ids) {
ECoursesResult result = contentService.deleteContentByIds(ids);
return result;
}
发布服务
<dubbo:service interface="cn.ecourses.content.service.ContentService" ref="contentServiceImpl" timeout="600000"/>
引用服务
ecourses-bms-web 工程中引用
<dubbo:reference interface="cn.ecourses.content.service.ContentService" id="contentService" />