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

相關文章
相關標籤/搜索