day71_淘淘商城项目_04_门户网站介绍 + 商城首页搭建 + CMS内容管理系统的建立 + CMS内容管理系统的实现_匠心笔记

  • 课程计划
    • 一、门户(前台)系统的搭建
    • 二、显示前台商城首页
    • 三、CMS内容管理系统的介绍
    • 四、CMS内容管理系统的建立
    • 五、CMS内容管理系统的实现
      • a) 内容分类管理
      • b) 内容管理

一、门户(前台)系统的搭建

1.一、什么是门户系统

  从广义上来讲,它将各类应用系统数据资源互联网资源集成到一个信息管理平台之上,并以统一的用户界面提供给用户,并创建企业对客户、企业对内部员工和企业对企业的信息通道,使企业可以释放存储在企业内部和外部的各类信息。
  门户就是访问网站的入口,通俗的说在这里就是首页。好比:jd首页,taotao首页,taobao首页。
  门户属于前台系统:面向广大的互联网网民。
  后台系统:面向维护人员、入住的商家使用。php

1.二、系统架构

1.三、搭建taotao-portal-web工程

  能够参考taotao-manager-web工程的搭建。css

1.3.一、建立Maven工程

不使用骨架建立html


打包方式为war

1.3.二、修改pom.xml 文件

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd"
>

  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.taotao</groupId>
    <artifactId>taotao-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>taotao-portal-web</artifactId>
  <packaging>war</packaging>
    <dependencies>
        <!-- 配置对taotao-common的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- JSP相关 -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- 配置对dubbo的依赖 -->
        <!-- dubbo相关 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <!-- 排除对低版本jar包的依赖 -->
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>netty</artifactId>
                    <groupId>org.jboss.netty</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 配置Tomcat插件  -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8082</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

1.3.三、配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

    id="WebApp_ID" version="2.5">

    <display-name>taotao-portal-web</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
     <welcome-file>index.html</welcome-file>

    </welcome-file-list>
    <!-- 配置解决post乱码的过滤器 -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 配置springmvc的前端控制器 -->
    <servlet>
        <servlet-name>taotao-portal-web</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation不是必须的, 若是不配置contextConfigLocation, 
             springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->

        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>taotao-portal-web</servlet-name>
        <!-- 拦截(*.html)结尾的请求,实现了网页的伪静态化,SEO:搜索引擎优化-->
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
</web-app>

  SEO:搜索引擎优化,为了提升网站的流量,提升在各搜索引擎中的搜索排名,须要进行优化,那么能够为动态网站伪静态化,以提升排名。前端

1.3.四、加入配置文件

springmvc.xml
log4j.properties (添加log4j不是必须的,可是建议添加)
搭建后的效果图:java

二、显示前台商城首页

首页的原型以下图所示:node


添加静态页面及资源。页面位置以下:

2.一、功能分析

请求的url:/index
  http://localhost:8082/index.html
参数:没有
返回值:String 逻辑视图git

2.二、功能实现


https://www.jd.com/
https://www.jd.com/index.html
通常:jd、taobao访问时直接访问域名
咱们这里可否直接访问: http://localhost:8082/ 呢?
(http://localhost:8082/ 至关于访问域名,后面部署的时候将会换成域名访问)
答案是否认的,要想实现此功能,须要修改:web.xml
添加红色部分以下图:

三、CMS内容管理系统的介绍

3.一、首页大广告位开发实现分析

  • 能够根据首页大广告位的数据结构设计一张表,进行增删改查管理。
  • 其余部分的展现内容一样能够设计表,进行增删改查。
  • 上述思路存在的问题: 若是每个前端展现内容(大广告位、小广告位等等),单独创建表,进行CRUD操做,会有如下问题:
    • 一、首页页面信息大量堆积,发布显的异常繁琐沉重;
    • 二、内容繁杂,管理效率低下;
    • 三、许多工做都须要其余技术人员配合完成;
    • 四、改版工做量大,维护,扩展性差。
  • 使用内容管理系统解决以上问题。

3.二、内容管理系统

  内容管理系统(content management system,CMS)是一种位于WEB 前端(Web服务器)和后端办公系统或流程(内容创做、编辑)之间的软件系统。内容的创做人员、编辑人员、发布人员使用内容管理系统来提交、修改、审批、发布内容。这里指的“内容”可能包括文件、表格、图片、数据库中的数据甚至视频等一切你想要发布到Internet网站的信息。github

3.三、动态展现分析

  • 对首页展现功能进行分析,抽取,发现应当有如下的字段属性:
    • 有图片
    • 有连接
    • 有标题
    • 有价格
    • 图片提示
    • 包含大文本类型,能够做为公告
  • 把首页的每一个展现功能(大广告位,淘淘快报等),看做是一个分类,每一个展现功能里面展现的多条信息,看做是分类下的内容。
    • 例如:首页大广告,对应的是大广告分类,而大广告位展现的多张图片,就是大广告分类下的内容。
  • 前台须要获取大广告的图片,只须要根据大广告的id查询对应的内容便可。
  • 须要一个内容分类表和一个内容表。内容分类和内容表是一对多的关系。
  • 内容分类表,须要存储树形结构的数据。(大分类下有小分类)
    • 内容分类表:tb_content_category
    • 内容表:tb_content
    • 内容分类表结构:
    • 内容表结构:
  • 须要有后台来维护内容信息CMS系统
  • 须要建立一个内容服务系统。

四、CMS内容管理系统的建立

根据单一职能原则,内容服务只管内容,商品服务只管商品,因此须要新建立一个内容服务工程。
能够参考taotao-manager的建立。
taotao-content:聚合工程,打包方式pom。
  |--taotao-content-interface 打包方式为jar
  |--taotao-content-service 打包方式为war
  // 直接依赖POJO过来
  // 直接依赖dao过来web

4.一、taotao-content

建立Maven工程taotao-content,跳过骨架ajax

4.1.一、pom文件

能够参考聚合工程taotao-manager的pom.xml文件的配置

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd"
>

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taotao</groupId>
        <artifactId>taotao-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>taotao-content</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>taotao-content-interface</module>
        <module>taotao-content-service</module>
    </modules>
    <dependencies>
        <!-- 配置对taotao-common的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 配置Tomcat插件  -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8083</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

4.二、taotao-content-interface

4.2.一、pom文件

能够参考模块工程taotao-manager-interface的pom.xml文件的配置

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd"
>

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taotao</groupId>
        <artifactId>taotao-content</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>taotao-content-interface</artifactId>
    <dependencies>
        <!-- 配置对taotao-manager-pojo的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-manager-pojo</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

4.三、taotao-content-service

4.3.一、pom文件

能够参考模块工程taotao-manager-service的pom.xml文件的配置

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd"
>

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taotao</groupId>
        <artifactId>taotao-content</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>taotao-content-service</artifactId>
    <packaging>war</packaging>
    <dependencies>
        <!-- 配置对taotao-manager-dao的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-manager-dao</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 配置对taotao-content-interface的依赖:服务层发布服务要经过该接口 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-content-interface</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 配置对spring的依赖 -->
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- 配置对dubbo的依赖 -->
        <!-- dubbo相关 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <!-- 排除对低版本jar包的依赖 -->
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>netty</artifactId>
                    <groupId>org.jboss.netty</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>
    </dependencies>
</project>

4.四、框架整合

参考taotao-manager


思考一个问题:服务层发布服务必定须要一个tomcat吗?
  答:不必定。服务层发布服务须要初始化一个spring容器便可。
那么咱们为何还要使用tomcat呢?
  答:其一:咱们首先利用tomcat能够做为容器的功能;
  其二:咱们可使用tomcat打成war包,打成war包会把全部的jar包打在一块儿,部署发布起来很方便。
  若是咱们不打成war包的话,一个一个的jar包都是独立的,jar包中不能包含jar包。部署发布起来很麻烦。
  与tomcat相似的有 jetty。有空能够学习一下!

五、CMS内容管理系统的实现

5.一、内容分类管理

5.1.一、内容分类列表展现

a) 原型图

b) 功能分析


详解以下:
请求的url:/content/category/list
请求的参数:id,当前节点的id。第一次请求是没有参数,须要给默认值“0”。
响应数据:List (须要使用注解@ResponseBody)
Json格式数据:
  [{id:1,text:节点名称,state:open/closed},
  {id:2,text:节点名称2,state:open/closed},
  {id:3,text:节点名称3,state:open/closed}]

业务逻辑:
  一、取查询参数id,parentId
  二、根据parentId查询tb_content_category,查询子节点列表。
  三、获得List
  四、把列表转换成List

c) Dao
咱们查询的是单表,可使用逆向工程的Mapper。

d) Service
参数:Long parentId
返回值:List<EasyUITreeNode>
ContentCategoryService接口代码:

public interface ContentCategoryService {

    /**
     * 根据内容分类的父节点id,查询该节点的子节点列表
     * @param parentId
     * @return
     */

    List<EasyUITreeNode> getContentCategoryList(Long parentId);
}

ContentCategoryServiceImpl实现类代码:

/**
 * 内容分类管理Service
 * @author    chenmingjun
 * @date    2018年11月15日下午12:57:47
 * @version 1.0
 */

public class ContentCategoryServiceImpl implements ContentCategoryService {

    @Autowired
    private TbContentCategoryMapper contentCategoryMapper;

    @Override
    public List<EasyUITreeNode> getContentCategoryList(Long parentId) {
        // 根据内容分类的父节点id,查询该节点的子节点列表
        TbContentCategoryExample example = new TbContentCategoryExample();
        // 设置查询条件
        Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(parentId);
        // 执行查询
        List<TbContentCategory> list = contentCategoryMapper.selectByExample(example);
        // 将list转换成EasyUITreeNode列表
        List<EasyUITreeNode> resultList = new ArrayList<>();
        for (TbContentCategory tbContentCategory : list) {
            EasyUITreeNode node = new EasyUITreeNode();
            node.setId(tbContentCategory.getId());
            node.setText(tbContentCategory.getName());
            node.setState(tbContentCategory.getIsParent() ? "closed" : "open");
            // 将节点添加到list集合(列表)
            resultList.add(node);
        }
        return resultList;
    }
}

e) 服务层发布服务

f) 表现层引用服务
注意:表现层的后台管理系统能够调用服务层的多个服务
taotao-manager-web须要依赖taotao-content-interface模块


引用服务

h) Controller

@Controller
@RequestMapping("/content/category")
public class ContentCategoryController {

    @Autowired
    private ContentCategoryService contentCategoryService;

    /**
     * 根据内容分类的父节点id,查询该节点的内容列表
     * @param parentId
     * @return
     */

    @RequestMapping("/list")
    @ResponseBody
    public List<EasyUITreeNode> getContentCategoryList(@RequestParam(value="id", defaultValue="0") Long parentId) {
        List<EasyUITreeNode> list = contentCategoryService.getContentCategoryList(parentId);
                return list;
    }
}

5.1.二、新增内容分类节点

功能分析:


请求的url:/content/category/create
请求的参数:
  Long parentId
  String name
响应的结果:
  json格式的数据,TaotaoResult,其中包含一个对象,对象有id属性,值是新添加的内容分类的id。
注意:
  插入新的叶子结点以后须要判断,
  若是在原结点是叶子节点的时候添加新的叶子节点,
  即须要将“原结点是叶子节点”更新为新的父节点,
  即将新的父节点的is_parent属性设置为“1”,
  由于它的下面有新的叶子节点了!!!

业务逻辑:
  一、接收两个参数:parentId、name。
  二、向tb_content_category表中插入数据。
    a) 建立一个TbContentCategory对象
    b) 补全TbContentCategory对象的其余属性
    c) 向tb_content_category表中插入数据
  三、判断父节点的isparent是否为true,不是true须要改成true。
  四、须要主键返回。
  五、返回TaotaoResult,其中包装TbContentCategory对象。

a) Dao
向tb_content_category表中插入数据,可使用逆向工程生成的代码。
可是须要添加主键返回,mybatis提供的函数SELECT LAST_INSERT_ID();,该函数能够取到最后生成的主键id,这个方法是事务隔离的,不会出现冲突。
在咱们插入记录以后使用该函数。
咱们修改下逆向工程生成的代码:


注意: 修改完代码后,须要向本地仓库安装taotao-manager-dao包
注意: 语句末尾去掉分号!!!

b) Service
参数:parentId、name
返回值:返回TaotaoResult,其中包装了TbContentCategory对象

    @Override
    public TaotaoResult addContentCategory(Long parentId, String name) {
        // 一、接收两个参数:parentId、name
        // 二、向tb_content_category表中插入数据。
        // a) 建立一个TbContentCategory对象
        TbContentCategory contentCategory = new TbContentCategory();
        // b) 补全TbContentCategory对象的其余属性
        contentCategory.setParentId(parentId);
        contentCategory.setName(name);
        // 状态。可选值:1(正常),2(删除)
        contentCategory.setStatus(1);
        // 排列序号,表示同级类目的展示次序,如数值相等则按名称次序排列。取值范围:大于零的整数
        contentCategory.setSortOrder(1);
        // 新增的节点必定是子节点
        contentCategory.setIsParent(false);
        // 新建时间和更新时间
        contentCategory.setCreated(new Date());
        contentCategory.setUpdated(contentCategory.getCreated());
        // c) 向tb_content_category表中插入数据
        contentCategoryMapper.insert(contentCategory);
        // 四、判断父节点的isParent是否为true,是false须要改成true
        // 插入新的叶子结点以后须要判断, 
        // 若是在原结点是叶子节点的时候添加新的叶子节点, 
        // 即须要将“原结点是叶子节点”更新为新的父节点, 
        // 即将新的父节点的is_parent属性设置为“1”, 
        // 由于它的下面有新的叶子节点了!!!
        TbContentCategory contentCategory2 = contentCategoryMapper.selectByPrimaryKey(parentId);
        if (contentCategory2.getIsParent() == false) { // 该类目是否为父类目,1为true,0为false
            contentCategory2.setIsParent(true);
            // 更新新的父节点
            contentCategoryMapper.updateByPrimaryKey(contentCategory2);
        }
        // 五、须要主键返回,返回新的内容分类的id,这里使用了mybatis提供的函数,已在Mapper文件中配置
        // 六、返回TaotaoResult,其中包装了TbContentCategory对象
        return TaotaoResult.ok(contentCategory);
    }

特别注意一个问题:


发布服务。
每次使用maven命令安装修改过的jar包时,须要测试该jar包类里面的方法,影响效率,咱们可否跳过测试呢?
答:答案是确定的。
在taotao-manager-service的pom.xml中添加以下插件便可跳过测试:

c) Controller
请求的url:/content/category/create
请求的参数:
  Long parentId
  String name
响应的结果:
  json格式的数据,TaotaoResult

    /**
     * 添加内容分类节点
     * @param parentId
     * @param name
     * @return
     */

    @RequestMapping("/create")
    @ResponseBody
    public TaotaoResult createContentCategory(Long parentId, String name) {
        TaotaoResult result = contentCategoryService.addContentCategory(parentId, name);
        return result;
    }

浏览器实现效果以下:


后台数据库效果以下:

5.1.三、内容分类重命名、删除

一、重命名
功能分析:


请求的url:/content/category/update
参数:id,当前节点id。name,重命名后的名称。
业务逻辑:根据id更新记录。
返回值:返回TaotaoResult.ok()

a) Dao
向tb_content_category表中更新数据,可使用逆向工程生成的代码。

b) Service
参数:id,当前节点id。name,重命名后的名称。
返回值:返回TaotaoResult.ok()

    @Override
    public TaotaoResult updateContentCategoryName(Long id, String name) {
        TbContentCategory contentCategory = contentCategoryMapper.selectByPrimaryKey(id);
        contentCategory.setName(name);
        // 更新内容分类数据
        contentCategoryMapper.updateByPrimaryKey(contentCategory);
        return TaotaoResult.ok();
    }

c) Controller
请求的url:/content/category/update
请求的参数:
  Long id
  String name
响应的结果:
  json格式的数据,TaotaoResult

    /**
     * 重命名内容分类名称
     * @param id 
     * @param name
     * @return
     */

    @RequestMapping("/update")
    @ResponseBody
    public TaotaoResult updateContentCategoryName(Long id, String name) {
        TaotaoResult result = contentCategoryService.updateContentCategoryName(id, name);
        return result;
    }

二、删除内容分类
功能分析:
咱们须要稍微修改一下content-category.jsp,以下图:


请求的url:/content/category/delete/
参数:id,当前节点的id。
响应的数据:json格式的数据。TaotaoResult。

业务逻辑:
  一、根据id删除记录。
  二、若是删除的节点是子节点,则直接删除;
  再查看删除节点的父节点下是否还有子节点,若是没有须要把删除节点的父节点的is_parent改成false。
  三、若是删除的节点是父节点,则子节点要级联删除。
  两种解决方案:
    方案1:若是判断是父节点则不容许删除。
    方案2:递归删除。(不推荐使用)

a) Dao
从tb_content_category表中删除数据,可使用逆向工程生成的代码。

b) Service

    @Override
    public TaotaoResult deleteContentCategory(Long id) {
        // 获取删除节点的is_parent
        TbContentCategory contentCategory = contentCategoryMapper.selectByPrimaryKey(id);

        // 若是是父类节点,则递归删除子节点
        if (contentCategory.getIsParent()) { 
            /*
            // 方案二:递归删除子节点
            // 获得父节点下的全部子节点列表
            List<TbContentCategory> list = getContentCategoryListByParentId(id); 
            // 递归删除
            for (TbContentCategory tbContentCategory : list) {
                deleteContentCategory(tbContentCategory.getId()); // 删除当前子节点数据
            }
            */


            // 方案一:父节点不容许删除
            String msg = "请先删 "+ contentCategory.getName() +" 分类下的全部子分类,再删除 "+ contentCategory.getName()+ " 分类!";
            TaotaoResult result = TaotaoResult.build(500, msg, null);
            return result;
        }

        // 若是是子节点,则判断该子节点的父节点是否只有一个子节点
        if (getContentCategoryList(contentCategory.getParentId()).size() == 1) { // 经过该子节点的父节点id获取对应父节点的子节点列表的长度
            // 是单个子节点,获取单个子节点的父节点,把该父节点的is_parent改成false,更新数据
            TbContentCategory parentCategory = contentCategoryMapper.selectByPrimaryKey(contentCategory.getParentId());
            parentCategory.setIsParent(false); 
            contentCategoryMapper.updateByPrimaryKey(parentCategory); 
        }

        // 删除本节点
        contentCategoryMapper.deleteByPrimaryKey(id);
        return TaotaoResult.ok();
    }

    /**
     * 根据parentId查询子节点列表的方法
     * @param parentId
     * @return
     */

    private List<TbContentCategory> getContentCategoryListByParentId(long parentId){
        TbContentCategoryExample example = new TbContentCategoryExample();
        Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(parentId);
        List<TbContentCategory> list = contentCategoryMapper.selectByExample(example);
        return list;
    }

c) Controller

    /**
     * 递归删除内容分类
     * @param id
     * @return
     */

    @RequestMapping("/delete")
    @ResponseBody
    public TaotaoResult update(Long id) {
        TaotaoResult result = contentCategoryService.deleteContentCategory(id);
        return result;
    }

咱们从新安装taotao-content工程、taotao-manager工程和taotao-manager-web工程。测试成功!

5.二、内容管理

5.2.一、功能点分析

  • 一、内容列表查询(做业)
  • 二、新增内容
  • 三、编辑内容(做业)
  • 四、删除内容(做业)

5.2.二、内容列表查询

功能分析:


请求的url:/content/query/list
参数:categoryId 内容分类id
响应的数据:EasyUIDataGridResult (须要使用注解@ResponseBody)
json格式的数据
  {total:查询结果总数量,rows[{id:1,title:aaa,subtitle:bb,…}]}
封装内容数据: List<TbContent>
查询的表:tb_content

业务逻辑:
  根据内容分类id查询内容列表。要进行分页处理。
参考商品列表的查询。

1)Dao
  单表查询内容数据,直接使用逆向工程生成的Mapper。注意:须要根据条件进行查询。

2)Service
ContentService接口代码:

    /**
     * 根据内容分类id,分页查询前台内容列表信息
     * @param categoryId
     * @param page
     * @param rows
     * @return
     */

    EasyUIDataGridResult getContentList(Long categoryId, Integer page, Integer rows);

ContentServiceImpl实现类代码:

    @Override
    public EasyUIDataGridResult getContentList(Long categoryId, Integer page, Integer rows) {
        // 设置分页信息,使用PageHelper
        if (page == null) {
            page = 1;
        }
        if (rows == null) {
            rows = 30;
        }
        PageHelper.startPage(page, rows);
        TbContentExample contentExample = new TbContentExample();
        // 设置查询条件
        Criteria criteria = contentExample.createCriteria();
        criteria.andCategoryIdEqualTo(categoryId);
        // 执行查询,须要设置查询条件,根据内容分类id查询内容列表
        List<TbContent> list = contentMapper.selectByExample(contentExample);
        // 取出分页信息
        PageInfo<TbContent> pageInfo = new PageInfo<>(list);
        // 建立返回结果对象
        EasyUIDataGridResult result = new EasyUIDataGridResult();
        // 给返回结果对象设置值
        result.setTotal(pageInfo.getTotal());
        result.setRows(list);
        // 返回结果
        return result;
    }

3)发布服务
  已在“新增内容”中发布服务了。参考下面。

4)引用服务
  已在“新增内容”中引用服务了。参考下面。

5)Controller

    /**
     * 根据内容分类id,分页查询内容列表
     * @param categoryId
     * @param page
     * @param rows
     * @return
     */

    @RequestMapping("/query/list")
    @ResponseBody
    public EasyUIDataGridResult getContentList(Long categoryId, Integer page, Integer rows) {
        EasyUIDataGridResult result = contentService.getContentList(categoryId, page, rows);
        return result;
    }

6)测试
  咱们从新安装taotao-content工程、taotao-manager工程和taotao-manager-web工程,启动他们。浏览器测试结果以下:

5.2.三、新增内容

功能分析:
新增内容,必须指定一个内容分类。


content-add.jsp页面

提交表单请求的url:/content/save
参数:表单的数据。使用pojo接收TbContent。
返回值:TaotaoResult(json格式的数据)

业务逻辑:
  一、把TbContent对象的其余属性补全。
  二、向tb_content表中插入数据。
  三、返回TaotaoResult.ok()。

1)Dao
  单表插入内容数据,直接使用逆向工程生成的Mapper。

2)Service
ContentService接口代码:

    /**
     * 新增内容
     * @param content
     * @return
     */

    TaotaoResult saveContent(TbContent content);

ContentServiceImpl实现类代码:
参数:TbContent
返回值:TaotaoResult.ok()

    @Autowired
    private TbContentMapper contentMapper;

    @Override
    public TaotaoResult saveContent(TbContent content) {
        content.setCreated(new Date());
        content.setUpdated(content.getCreated());
        contentMapper.insert(content);
        return TaotaoResult.ok();
    }

3)发布服务
在taotao-content-service的applicationContext-service.xml中发布:

4)引用服务
在toatao-manager-web工程中引用:

5)Controller
提交表单请求的url:/content/save
参数:表单的数据。使用pojo接收TbContent。
返回值:TaotaoResult(json格式的数据)

@Controller
@RequestMapping("/content")
public class ContentController {

    @Autowired
    private ContentService contentService;

    /**
     * 新增内容
     * @param content
     * @return
     */

    @RequestMapping("/save")
    @ResponseBody
    public TaotaoResult saveContent(TbContent content) {
        TaotaoResult result = contentService.saveContent(content);
        return result;
    }
}

6)测试
  咱们从新安装taotao-content工程、taotao-manager工程和taotao-manager-web工程后,启动他们。浏览器测试结果以下:

5.2.四、编辑内容

功能分析:
选择一个复选框点击编辑:


注意:由于内容列表查询的时候没有查询content字段,也就是富文本编辑框中的内容,因此咱们点击【编辑】,就会发现富文本编辑框是空的,并无咱们添加内容时添加的内容文本。 这是为何呢?
答:其实咱们能够从获取内容列表的实现接口中 List<TbContent> list = contentMapper.selectByExample(example);这段代码去查找端倪,既然是调用的selectByExample这个方法,咱们便去Mybatis的 TbContentMapper.xml文件当中去看下sql语句。以下图所示:

能够看到要查询的字段在 Base_Column_List当中,咱们再看看 Base_Column_List当中的字段,发现并无content字段,而content字段在 Blob_Column_List中,以下图所示:

这么作的好处是:咱们在查询内容列表的时候因为并不须要显示内容文本,而内容文本信息量多是很是庞大的,若是把内容文本字段也一并查询出来的话,那么一定是很消耗性能的。
所以 默认采起了不查询内容字段的方式进行内容列表的查询,因此咱们点击【编辑】按钮的时候,数据回显时咱们看见富文本框中没有显示内容。
  • 解决方式一:其实查询内容列表时,咱们可使用上图的selectByExampleWithBLOBs这个查询方法,该查询方法查询内容列表的时候会将字段content也查询出来。以下图:

    若是咱们仅仅是查询内容列表而并不编辑内容的话,那么咱们查询出来的字段content就没有用,因此浪费了带宽,使性能下降。
    同时须要注意的是:咱们更新内容的时候一样也要使用updateByPrimaryKeyWithBLOBs方法,不然,字段content不会被更新。
  • 解决方式二:按需查询内容表,修改content.jsp编辑部分的代码,对于回显内容文本,$.post("/content/getContentText",{"id":data.id},function(rt){…},因为内容列表在加载的时候并无加载content字段,由于content字段内容太多,因此咱们点击【编辑】按钮的时候,使用ajax动态获取字段content内容。以下图:

    同时也须要注意的是:咱们更新内容的时候要使用updateByPrimaryKeyWithBLOBs方法,不然,字段content不会被更新。

咱们回到编辑的页面content-edit.jsp以下,咱们先注意下表单的两个隐藏域:


再来看看URL部分:

URL: /content/edit
参数:表单数据(TbContent 来接收)
返回值:TaotaoResult

业务逻辑:
  根据id更新tb_content,可使用逆向工程。(单表操做)
  补全其余没有更新过来的属性。(created updated)
  服务层发布服务(前面已经发布过了)。
  表现层引入服务(调用服务方法,返回)。

1)Dao
单表更新内容数据,直接使用逆向工程生成的Mapper。

2)Service
咱们使用上述的解决方案二。
ContentService接口代码:

    /**
     * 更新内容
     * @param content
     * @return
     */

    TaotaoResult updateContent(TbContent content);

    /**
     * 根据内容id获取内容文本
     * @param id
     * @return
     */

    TaotaoResult getContentText(Long id);

ContentServiceImpl实现类代码:

    @Override
    public TaotaoResult updateContent(TbContent content) {
        // 设置建立时间
        content.setCreated(new Date());
        // 设置更新时间
        content.setUpdated(new Date());
        contentMapper.updateByPrimaryKeyWithBLOBs(content);
        return TaotaoResult.ok();
    }

    @Override
    public TaotaoResult getContentText(Long id) {
        TbContent content = contentMapper.selectByPrimaryKey(id);
        return TaotaoResult.ok(content);
    }

3)发布服务
  同上“新增内容”。

4)引用服务
  同上“新增内容”。

5)Controller

    /**
     * 编辑内容
     * @param content
     * @return
     */

    @RequestMapping("/edit")
    @ResponseBody
    public TaotaoResult updateContent(TbContent content) {
        TaotaoResult result = contentService.updateContent(content);
        return result;
    }

    /**
     * 根据内容id,获取内容
     * @param id
     * @return
     */

    @RequestMapping("/getContentText")
    @ResponseBody
    public TaotaoResult getContentText(Long id) {
        TaotaoResult result = contentService.getContentText(id);
        return result;
    }

6)测试
  咱们从新安装taotao-content工程、taotao-manager工程和taotao-manager-web工程后,启动他们。浏览器测试成功。不在赘图!

5.2.五、删除内容

功能分析:

请求URL: /content/delete
参数: ids (一个内容id拼成的字符串,如上图所示:[12,23,45,21,……])
返回值:Taotaoresult


业务逻辑:
  根据ids的值分割字符串,获得id的数组。
  根据id循环删除。
  返回Taotaoresult。

1)Dao
  单表删除内容数据,直接使用逆向工程生成的Mapper。

2)Service
ContentService接口代码:

    /**
     * 根据内容id批量删除内容
     * @param ids
     * @return
     */

    TaotaoResult deleteContent(List<Long> ids);

ContentServiceImpl实现类代码:

    @Override
    public TaotaoResult deleteContent(List<Long> ids) {
        for (Long id : ids) {
            contentMapper.deleteByPrimaryKey(id);
        }
        return TaotaoResult.ok();
    }

3)发布服务
  同上“新增内容”。

4)引用服务
  同上“新增内容”。

5)Controller

    /**
     * 根据内容id,批量删除内容
     * @param ids
     * @return
     */

    @RequestMapping("/delete")
    @ResponseBody
    public TaotaoResult deleteContent(@RequestParam("ids") List<Long> ids) {
        TaotaoResult result = contentService.deleteContent(ids);
        return result;
    }

6)测试
  咱们从新安装taotao-content工程、taotao-manager工程和taotao-manager-web工程后,启动他们。浏览器测试成功。不在赘图!

  至此内容管理就完成了。

六、参考文章

  https://blog.csdn.net/pdsu161530247/article/details/81871988  https://blog.csdn.net/pdsu161530247/article/details/81873987  https://blog.csdn.net/u012453843/article/details/70215288  https://blog.csdn.net/qq_34337272/article/details/79951622

相关文章
相关标签/搜索