如何做一個(gè)電商系統(tǒng)(三)

1.搭建前臺(tái)系統(tǒng)

1.1.前臺(tái)系統(tǒng)架構(gòu)

image.png

在互聯(lián)網(wǎng)系統(tǒng)開(kāi)發(fā)當(dāng)中浆竭,我們一般都是采用了分層的方式來(lái)架構(gòu)系統(tǒng)鬼贱,即:

(1)門(mén)戶(hù)層(門(mén)戶(hù)系統(tǒng)):網(wǎng)站的入口

i、渲染視圖始赎,提供用戶(hù)訪問(wèn)的頁(yè)面和橙。

ii、不查詢(xún)數(shù)據(jù)庫(kù)造垛,數(shù)據(jù)來(lái)自對(duì)遠(yuǎn)程服務(wù)(接口)的調(diào)用魔招。

(2)服務(wù)層:基于restful,以接口的形式對(duì)外提供公共的服務(wù)筋搏。

i仆百、連接數(shù)據(jù)庫(kù),返回json格式的數(shù)據(jù)奔脐。

1.1.1.分層架構(gòu)的好處

(1)俄周、有利于系統(tǒng)的維護(hù)和拓展。

(2)髓迎、有利于SOA服務(wù)治理的基礎(chǔ)峦朗。

1.2.搭建服務(wù)層系統(tǒng)

1.2.1.系統(tǒng)簡(jiǎn)介

基于RESTful實(shí)現(xiàn)。以接口的形式排龄,對(duì)外提供公共的服務(wù)波势。(比如購(gòu)物車(chē)档痪、導(dǎo)航菜單、搜索证舟、訂單等等)

RESTful是一種接口設(shè)計(jì)理念酗洒,即:

(1)不同的請(qǐng)求方式,對(duì)應(yīng)不同的業(yè)務(wù)類(lèi)型:

       GET   :查詢(xún)

       POST  :添加

       PUT   :更新

       DELETE: 刪除

(2)返回json格式數(shù)據(jù)凛忿。

1.2.2.技術(shù)選擇

核心框架:Spring+SpringMVC+Mybatis-plus

數(shù) 據(jù) 庫(kù):MySQL

前端框架:無(wú)

1.2.3.配置步驟

思路:
(1)創(chuàng)建項(xiàng)目澈灼,導(dǎo)入jar依賴(lài)。

(2)整合SSM框架店溢。

1.2.3.1.第一步:創(chuàng)建maven項(xiàng)目(war)模型

注意:(1)項(xiàng)目繼承ego-project叁熔。

  (2)使用maven module創(chuàng)建項(xiàng)目
image.png

1.2.3.2.第二步:導(dǎo)入jar依賴(lài)

導(dǎo)包說(shuō)明:

(1)ego-base子工程

(2)Spring核心包

(3)SpringMVC相關(guān)包

(4)AOP相關(guān)包

(5)JDBC、事物相關(guān)包

(6)Mybatis-plus及整合包

(7)JSON依賴(lài)包

導(dǎo)入插件:Tomcat插件(開(kāi)發(fā)階段床牧,啟動(dòng)項(xiàng)目荣回,對(duì)外發(fā)布接口)

<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>cn.gzsxt.ego</groupId>

    <artifactId>ego-project</artifactId>

    <version>1.0</version>

  </parent>

  <groupId>cn.gzsxt.ego</groupId>

  <artifactId>ego-rest</artifactId>

  <version>1.0</version>

  <packaging>war</packaging>

  <dependencies>

    <dependency>

       <groupId>cn.gzsxt.ego</groupId>

        <artifactId>ego-base</artifactId>

        <version>1.0</version>

    </dependency>

    <!-- 整合SSM,導(dǎo)入spring戈咳、springmvc心软、mybatis相關(guān)依賴(lài) -->

    <!-- 導(dǎo)入spring核心依賴(lài)   4+1 -->

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-context</artifactId>

    </dependency>

    <!-- 導(dǎo)入spirng-jdbc+事物 -->

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-jdbc</artifactId>

    </dependency>

    <!-- 導(dǎo)入事物的依賴(lài) :切面 -->

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-aspects</artifactId>

    </dependency>

    <!-- 導(dǎo)入springmvc相關(guān)依賴(lài) -->

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-webmvc</artifactId>

    </dependency>

    <!-- 導(dǎo)入mybatis相關(guān)依賴(lài) -->

    <dependency>

       <groupId>org.mybatis</groupId>

       <artifactId>mybatis-spring</artifactId>

    </dependency>

    <!-- 導(dǎo)入jdbc、連接池依賴(lài) -->

    <!-- MySql -->

    <dependency>

       <groupId>mysql</groupId>

       <artifactId>mysql-connector-java</artifactId>

    </dependency>

    <!-- 連接池 -->

    <dependency>

       <groupId>com.alibaba</groupId>

       <artifactId>druid</artifactId>

    </dependency>

    <!-- Jackson Json處理工具包 -->

    <dependency>

       <groupId>com.fasterxml.jackson.core</groupId>

       <artifactId>jackson-databind</artifactId>

    </dependency>

  </dependencies>

  <build>

       <plugins>

            <!-- 配置Tomcat插件 -->

            <plugin>

                 <groupId>org.apache.tomcat.maven</groupId>

                 <artifactId>tomcat7-maven-plugin</artifactId>

                 <configuration>

                     <port>8081</port>

                     <path>/</path>

                     <uriEncoding>UTF-8</uriEncoding>

                 </configuration>

            </plugin>

         </plugins>

    </build>

</project>

1.2.3.3.第三步:創(chuàng)建web.xml文件

說(shuō)明:可以從ego-manager工程中拷貝除秀,修改<url-pattern>即可糯累。

<?xml version="1.0" encoding="UTF-8"?>     

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"      xmlns:xml="http://www.w3.org/XML/1998/namespace"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee      http://xmlns.jcp.org/xml/ns/javaee/web-app_2_5.xsd ">

    <!-- 配置編碼過(guò)濾器,防止post請(qǐng)求亂碼 -->

      <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>

    <servlet>

       <servlet-name>dispatcherServlet</servlet-name>

       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

       <init-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>classpath:spring-*.xml</param-value>

       </init-param>

       <!-- 項(xiàng)目啟動(dòng)的時(shí)候册踩,就加載spring容器 -->

       <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

       <servlet-name>dispatcherServlet</servlet-name>

       <!-- 所有請(qǐng)求rest服務(wù)層系統(tǒng)的請(qǐng)求泳姐,都必須在url加上/rest前綴,好處:方便做維護(hù)暂吉。 -->

        <url-pattern>/rest/*</url-pattern>

    </servlet-mapping>

</web-app>

1.2.3.4.第四步:整合SSM框架

整合中所需要的配置文件胖秒,均可從ego-manager工程中拷貝,修改局部的配置即可慕的。

1.2.3.4.1.Step1:Spring整合SpringMVC

創(chuàng)建spring-mvc.xml文件阎肝,做如下配置:

<?xml version="1.0" encoding="UTF-8"?>     

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/mvc      http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd

       http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context      http://www.springframework.org/schema/context/spring-context-4.1.xsd">

    <!-- 開(kāi)啟注解掃描 -->

    <context:component-scan base-package="cn.gzsxt.rest"/>

    <!-- 開(kāi)啟注解驅(qū)動(dòng) -->

    <mvc:annotation-driven/>

</beans>
1.2.3.4.2.Step2:mybatis-plus整合spring

在這里,我們一定要有一個(gè)概念:任何持久層框架和Spring的整合肮街,都是為了使用Spring的事物代理风题。

(1)創(chuàng)建resource.properties文件,配置數(shù)據(jù)庫(kù)連接信息如下:

#配置數(shù)據(jù)源     

db.driver=com.mysql.jdbc.Driver

db.url=jdbc:mysql://localhost:3306/ego

db.username=root

db.password=gzsxt

(2)創(chuàng)建spring-data.xml文件嫉父,配置框架整合沛硅。

<?xml version="1.0" encoding="UTF-8"?>     

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

       http://www.springframework.org/schema/context      http://www.springframework.org/schema/context/spring-context-4.3.xsd

       http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

    <context:property-placeholder file-encoding="utf-8"      location="classpath:resource.properties"/>

    <!-- 1、創(chuàng)建數(shù)據(jù)源 -->

    <bean name="dataSource"      class="com.alibaba.druid.pool.DruidDataSource">

       <property name="driverClassName" value="${db.driver}"/>

       <property name="url" value="${db.url}"/>

       <property name="username" value="${db.username}"/>

       <property name="password" value="${db.password}"/>

       <property name="maxActive" value="20"/>

       <property name="minIdle" value="5"/>

    </bean>

    <!-- 2绕辖、mybatis-plus整合Spring

       任何的數(shù)據(jù)庫(kù)的框架摇肌,要使用spring的事物代理,必須使用spring提供的數(shù)據(jù)源仪际,必須整合spring才可以使用

    -->

    <bean name="sqlSessionFactoryBean"      class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">

       <!-- 加載數(shù)據(jù)源 -->

       <property name="dataSource" ref="dataSource"/>

       <!-- 指定pojo目錄 -->

       <property name="typeAliasesPackage"      value="cn.gzsxt.base.pojo"/>

       <!-- 配置mybatis-plus插件 -->

       <property name="plugins">

           <list>

               <!-- 配置分頁(yè)插件 -->

              <bean      class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"/>

              <!-- 配置攔截器屬性 -->

              <bean      class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">

                  <!-- 配置sql響應(yīng)時(shí)間围小,開(kāi)發(fā)階段方便做調(diào)優(yōu) -->

                  <property name="maxTime" value="1000"/>

                  <property name="format" value="true"/>

              </bean>

           </list>

       </property>

       <!-- 配置mybatis-plus全局策略 -->

       <property name="globalConfig"      ref="globalConfiguration"></property>

    </bean>

    <!-- 3昵骤、配置mybatis的動(dòng)態(tài)代理 -->

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

       <property name="sqlSessionFactoryBeanName"      value="sqlSessionFactoryBean"/>

       <property name="basePackage"      value="cn.gzsxt.base.mapper"></property>

    </bean>

    <!-- 配置mybatis-plus全局屬性 -->

    <!-- 定義 MybatisPlus 的全局策略配置-->

    <bean id ="globalConfiguration"      class="com.baomidou.mybatisplus.entity.GlobalConfiguration">

        <!-- 在 2.3 版本以后,dbColumnUnderline 默認(rèn)值是 true肯适,即pojo屬性開(kāi)啟駝峰標(biāo)識(shí) -->

        <property name="dbColumnUnderline" value="true"></property>

        <!-- 全局的主鍵策略 -->

        <!--

            AUTO->`0`("數(shù)據(jù)庫(kù)ID自增")

             INPUT->`1`(用戶(hù)輸入ID")

            ID_WORKER->`2`("全局唯一ID")

            UUID->`3`("全局唯一ID")

        -->

        <property name="idType" value="0"></property>

        <!-- 全局的表前綴策略配置 -->

        <property name="tablePrefix" value="tb_"></property>

    </bean>

    <!-- 4变秦、配置事物管理器 -->

     <bean name="transactionManager"      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

           <property name="dataSource" ref="dataSource"></property>

     </bean>

    <!-- 5、開(kāi)啟注解聲明式事物 -->

    <tx:annotation-driven/>

</beans>

1.2.3.5.第五步:整合測(cè)試

在這里我們使用靜態(tài)數(shù)據(jù)(category.json)框舔,來(lái)模擬導(dǎo)航菜單接口的實(shí)現(xiàn)伴栓。

(1)拷貝category.json文件到webapp目錄下。

image.png

(2)更新項(xiàng)目雨饺、安裝到本地倉(cāng)庫(kù)(updata、maven clean惑淳、maven install)

(3)啟動(dòng)項(xiàng)目

image.png

查看控制臺(tái)额港,啟動(dòng)成功!!!

image.png

(4)瀏覽器訪問(wèn),地址:http://localhost:8081/category.json歧焦,整合成功R普丁!绢馍!

image.png

1.3.搭建門(mén)戶(hù)系統(tǒng)

1.3.1.系統(tǒng)簡(jiǎn)介

簡(jiǎn)單來(lái)說(shuō)就是網(wǎng)站的入口向瓷,提供用戶(hù)瀏覽、下單的操作頁(yè)面舰涌。

門(mén)戶(hù)系統(tǒng)不直接調(diào)用數(shù)據(jù)庫(kù)猖任,而是通過(guò)服務(wù)系統(tǒng)提供的接口獲取數(shù)據(jù)。電商瓷耙、互聯(lián)網(wǎng)行業(yè)開(kāi)發(fā)都是面向服務(wù)開(kāi)發(fā)朱躺。

1.3.2.技術(shù)選擇

核心框架:Spring+SpringMVC

數(shù) 據(jù) 庫(kù):無(wú)

前端技術(shù):jquery、ajax搁痛、css+div长搀、easyui等

1.3.3.配置步驟

思路:
(1)創(chuàng)建項(xiàng)目

(2)框架整合

1.3.3.1.第一步:創(chuàng)建maven項(xiàng)目(war模型)

注意:
(1)繼承ego-project工程
(2)使用maven module創(chuàng)建子系統(tǒng)

image.png

1.3.3.2.第二步:導(dǎo)入jar依賴(lài)

在門(mén)戶(hù)系統(tǒng)中,不直接查詢(xún)數(shù)據(jù)庫(kù)鸡典,所以不需要導(dǎo)入數(shù)據(jù)庫(kù)相關(guān)的jar包源请。

在門(mén)戶(hù)系統(tǒng)中,用戶(hù)能夠搜索彻况、瀏覽商品谁尸,提交訂單等,所以需要添加jsp視圖相關(guān)依賴(lài)疗垛。

<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>cn.gzsxt.ego</groupId>

    <artifactId>ego-parent</artifactId>

    <version>1.0</version>

  </parent>

  <groupId>cn.gzsxt.ego</groupId>

  <artifactId>ego-portal</artifactId>

  <version>1.0</version>

  <packaging>war</packaging>

  <dependencies>

       <dependency>

              <groupId>cn.gzsxt.ego</groupId>

              <artifactId>ego-base</artifactId>

              <version>1.0</version>

       </dependency>

       <!-- jsp相關(guān)依賴(lài) -->

       <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>

           <!-- 導(dǎo)入spring核心依賴(lài)   4+1 -->

           <dependency>

           <groupId>org.springframework</groupId>

           <artifactId>spring-context</artifactId>

       </dependency>

       <!-- 導(dǎo)入springmvc相關(guān)依賴(lài) -->

       <dependency>

           <groupId>org.springframework</groupId>

           <artifactId>spring-webmvc</artifactId>

       </dependency>

       <!-- Jackson Json處理工具包 -->

       <dependency>

           <groupId>com.fasterxml.jackson.core</groupId>

           <artifactId>jackson-databind</artifactId>

       </dependency>

  </dependencies>

  <build>

       <plugins>

       <!-- 配置Tomcat插件 -->

       <plugin>

           <groupId>org.apache.tomcat.maven</groupId>

           <artifactId>tomcat7-maven-plugin</artifactId>

           <configuration>

              <port>8082</port>

              <path>/</path>

              <uriEncoding>UTF-8</uriEncoding>

           </configuration>

       </plugin>

    </plugins>

    </build>

</project>

1.3.3.3.第三步:創(chuàng)建web.xml文件

可以從ego-rest工程拷貝症汹,修改<url-parten>配置

<?xml version="1.0" encoding="UTF-8"?>     

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"      xmlns:xml="http://www.w3.org/XML/1998/namespace"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee      http://xmlns.jcp.org/xml/ns/javaee/web-app_2_5.xsd ">

    <welcome-file-list>

       <welcome-file>index.html</welcome-file>

    </welcome-file-list>

    <!-- 配置編碼過(guò)濾器,防止post請(qǐng)求亂碼 -->

      <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>

    <servlet>

       <servlet-name>dispatcherServlet</servlet-name>

       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

       <init-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>classpath:spring-*.xml</param-value>

       </init-param>

       <!-- 項(xiàng)目啟動(dòng)的時(shí)候贷腕,就加載spring容器 -->

       <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

       <servlet-name>dispatcherServlet</servlet-name>

       <!-- 把請(qǐng)求路徑偽靜態(tài)話(huà)背镇,方便做seo搜索引擎優(yōu)化咬展,有利于做網(wǎng)站推廣 -->

       <url-pattern>*.html</url-pattern>

    </servlet-mapping>

</web-app>

1.3.3.4.第四步:導(dǎo)入jsp頁(yè)面、靜態(tài)資源

說(shuō)明:
(1)靜態(tài)資源放在/webapp目錄
(2)jsp放到/WEB-INF/JSP目錄下

image.png

1.3.3.5.第五步:Spring整合SpringMVC

從ego-rest工程拷貝瞒斩,修改部分配置即可破婆。

<?xml version="1.0" encoding="UTF-8"?>     

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/mvc      http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd

       http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context      http://www.springframework.org/schema/context/spring-context-4.1.xsd">

    <!-- 開(kāi)啟注解掃描 -->

    <context:component-scan base-package="cn.gzsxt.portal"/>

    <!-- 開(kāi)啟注解驅(qū)動(dòng) -->

    <mvc:annotation-driven/>

    <!-- 由于jsp存放路徑在WEB-INF下面,默認(rèn)視圖解析器解析不到胸囱,需要自己配一個(gè)視圖解析器 -->

    <bean      class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="prefix" value="/WEB-INF/jsp/"></property>

       <property name="suffix" value=".jsp"></property>

    </bean>

</beans>

1.3.3.6.第六步:整合測(cè)試

需求:訪問(wèn)門(mén)戶(hù)系統(tǒng)首頁(yè)祷舀。

(1)創(chuàng)建PageController類(lèi)

package cn.gzsxt.portal.controller;     

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class PageController {

    @RequestMapping("/index")

    public String showIndex(){

       return "index";

    }

}

(2)更新項(xiàng)目、安裝到本地倉(cāng)庫(kù)烹笔。(update裳扯、clean、install)

(3)啟動(dòng)項(xiàng)目

image.png

(4)訪問(wèn)首頁(yè)谤职,地址:http://localhost:8082

image.png

前臺(tái)系統(tǒng)搭建成功J尾颉!允蜈!

2.首頁(yè)導(dǎo)航菜單實(shí)現(xiàn)

說(shuō)明:首頁(yè)導(dǎo)航菜單冤吨,是通過(guò)異步加載實(shí)現(xiàn)的。

好處:只有當(dāng)展開(kāi)導(dǎo)航菜單時(shí)饶套,才會(huì)發(fā)送請(qǐng)求漩蟆,從而節(jié)約cpu資源。

2.1.實(shí)現(xiàn)流程

image.png

需要解決的問(wèn)題:

(1)在rest系統(tǒng)中發(fā)布接口妓蛮,封裝導(dǎo)航菜單成json格式數(shù)據(jù)怠李。

(2)在portal系統(tǒng)中,遠(yuǎn)程請(qǐng)求接口(跨域請(qǐng)求)仔引。

2.2.跨越請(qǐng)求

2.2.1.什么是跨域(兩個(gè)不同系統(tǒng)之間的訪問(wèn)扔仓、調(diào)用)

(1)域名不同,即兩個(gè)不同的應(yīng)用咖耘。

image.png

(2)域名相同翘簇,但是端口不同,即同一個(gè)應(yīng)用中的不同子系統(tǒng)儿倒。

image.png

2.2.2.Ajax跨域請(qǐng)求的缺陷

在ego-rest系統(tǒng)使用靜態(tài)數(shù)據(jù)版保,模擬Ajax的跨域問(wèn)題。

2.2.2.1.第一步:在ego-rest中添加category.json文件夫否。(已實(shí)現(xiàn))

2.2.2.2.第二步:在ego-portal中發(fā)送ajax請(qǐng)求

(1)創(chuàng)建testJsonp.jsp頁(yè)面

<%@ page language="java" contentType="text/html; charset=UTF-8"     

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"      "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script type="text/javascript" src="/js/jquery-1.6.4.js"></script>

<title>Insert title here</title>

</head>

<body>

<textarea id="text" style="width: 1200px; height: 200px;"></textarea>

<input type="button" value="測(cè)試異步跨越" onclick="testajax()" />

<script type="text/javascript">

    function testajax(){

       $.ajax({

           url:"http://localhost:8081/category.json",

           type: "GET",

           success: function (data) {

              $("#text").val(JSON.stringify(data));

           }

       });

    }

</script>

</body>

</html>

(2)修改PageController彻犁,新增訪問(wèn)非首頁(yè)的方法。

@RequestMapping("/{page}")     

public String showPage(@PathVariable("page")String page){

    return page;

}

2.2.2.3.第三步:測(cè)試Ajax跨越

(1)重啟啟動(dòng)ego-portal系統(tǒng)凰慈,訪問(wèn)testJsonp.jsp

image.png

(2)點(diǎn)擊按鈕汞幢,發(fā)送異步請(qǐng)求

image.png

測(cè)試發(fā)現(xiàn),Ajax跨越請(qǐng)求失敗了微谓。

2.2.3.解決方案:jsonp跨域

在前面的測(cè)試中森篷,我們發(fā)現(xiàn)Ajax跨越請(qǐng)求時(shí)输钩,json數(shù)據(jù)被瀏覽器禁用了。

原因:瀏覽器禁止遠(yuǎn)程加載Json數(shù)據(jù)仲智。(瀏覽器安全機(jī)制)

如何解決呢买乃?

答:使用Jsonp方式。

2.2.3.1.Jsonp原理

Jsonp實(shí)現(xiàn)的前提:

瀏覽器允許跨越加載同源數(shù)據(jù)钓辆。

即在JavaScript腳本中發(fā)送請(qǐng)求剪验,就可以遠(yuǎn)程加載js格式數(shù)據(jù)。

請(qǐng)求原理:

(1)異步請(qǐng)求的時(shí)候前联,加上一個(gè)名為callback的回調(diào)函數(shù)

(2)在接口中功戚,將返回的json格式數(shù)據(jù),偽裝成js腳本格式似嗤。

(3)得到j(luò)s格式數(shù)據(jù)后疫铜,提取里面的json數(shù)據(jù)。

image.png

2.2.3.2.測(cè)試Jsonp

(1)修改testJsonp.jsp双谆,指定異步請(qǐng)求為jsonp方式。

<script type="text/javascript">     

    function testajax(){

       $.ajax({

           url:"http://localhost:8081/category.json",

           type: "GET",

           dataType: "jsonp",   //jsonp請(qǐng)求

           jsonp:"callbackFunction",  //請(qǐng)求參數(shù)名

           jsonpCallback:"showData",  //回調(diào)函數(shù)名稱(chēng)

           success: function (data) {

              $("#text").val(JSON.stringify(data));

           }

       });

    }

</script>

(2)在ego-rest工程中席揽,修改category.json文件顽馋,將返回?cái)?shù)據(jù)包裝成js腳本。

image.png

(3)再次發(fā)送ajax異步請(qǐng)求幌羞,使用jsonp方式

image.png

結(jié)論:
(1)jsonp是ajax技術(shù)中的一種異步請(qǐng)求方式寸谜。
(2)jsonp能實(shí)現(xiàn)跨越請(qǐng)求。
(3)jsonp跨越時(shí)属桦,需要指定一個(gè)回調(diào)函數(shù)熊痴,并使用該函數(shù)將返回的數(shù)據(jù)偽裝成js腳本。
(4)獲取返回的js腳本后聂宾,jsonp自動(dòng)提取其中的json數(shù)據(jù)果善。

2.3.首頁(yè)導(dǎo)航菜單實(shí)現(xiàn)

思路:

(1)在rest工程中,開(kāi)發(fā)接口系谐,返回js格式數(shù)據(jù)巾陕。(參考category.json)

(2)在portal工程中,修改jsonp請(qǐng)求路徑纪他。請(qǐng)求rest接口鄙煤。

2.3.1.第一部分:在rest工程中開(kāi)發(fā)導(dǎo)航菜單接口

2.3.1.1.第一步:定義導(dǎo)航菜單POJO

導(dǎo)航菜單結(jié)構(gòu)分析。(使用JsonViewer工具查看category.json)

image.png

結(jié)論:
(1)需要定義兩個(gè)POJO:菜單POJO茶袒、父目錄節(jié)點(diǎn)POJO

(2)導(dǎo)航菜單的數(shù)據(jù)梯刚,是一次加載出來(lái)的。

創(chuàng)建菜單Menu類(lèi)薪寓。(ego-base中創(chuàng)建)

package cn.gzsxt.base.pojo;     

import java.util.List;

/**

* 自定義導(dǎo)航菜單

* @author ccnulyq

*

*/

public class Menu {

    private List<?> data;  //目錄節(jié)點(diǎn)

    public List<?> getData() {

       return data;

    }

    public void setData(List<?> data) {

       this.data = data;

    }

    public Menu() {

       super();

    }

}

創(chuàng)建父目錄節(jié)點(diǎn)MenuNode類(lèi)

package cn.gzsxt.base.pojo;     

import java.util.List;

/**

* 自定義目錄節(jié)點(diǎn)結(jié)構(gòu)

* @author ccnulyq

*

*/

public class MenuNode {

    private String u;    //目錄的鏈接

    private String n;    //目錄的名稱(chēng)

    private List<?> i;   //當(dāng)請(qǐng)目錄的子目錄

    public MenuNode() {

       super();

    }

// 補(bǔ)全get亡资、set方法

}

(3)重新編譯ego-base工程澜共,安裝到本地倉(cāng)庫(kù)。(maven clean沟于、maven install)

2.3.1.2.第二步:創(chuàng)建ItemCatService接口及其實(shí)現(xiàn)類(lèi)

package cn.gzsxt.rest.service.impl;     

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import cn.gzsxt.base.mapper.ItemCatMapper;

import cn.gzsxt.base.pojo.ItemCat;

import cn.gzsxt.base.vo.Menu;

import cn.gzsxt.base.vo.MenuNode;

import cn.gzsxt.rest.service.ItemCatService;

@Service

public class ItemCatServiceImpl implements ItemCatService{

    @Autowired

    private ItemCatMapper itemCatMapper;

    @Override

    public Menu initMenu() {

       Menu menu = new Menu();

       //從返回值Menu的形式上來(lái)看咳胃,就是把一級(jí)目錄查詢(xún)出來(lái)即可。因此定義一個(gè)查詢(xún)方法旷太,通過(guò)parent_id=0查詢(xún)一級(jí)目錄

       List nodes = getNodesByParantId(0L);

       menu.setData(nodes);

       return menu;

    }

    //根據(jù)父目錄的id展懈,查詢(xún)子目錄

    private List getNodesByParantId(long parentId) {

       Map<String, Object> params = new HashMap<>();

       params.put("parent_id", parentId);

       List<ItemCat> selectByMap = itemCatMapper.selectByMap(params);

       List nodes = new ArrayList<>();

       MenuNode node = null;

       for (ItemCat itemCat : selectByMap) {

           if(1==itemCat.getIsParent()){

              node = new MenuNode();

              node.setU("/products/"+itemCat.getId()+".html");          //u : "/products/1.html"

              node.setN("<a      href='/products/"+itemCat.getId()+".html'>"+itemCat.getName()+"</a>");     //n : "<a href='/products/1.html'>圖書(shū)、音像供璧、電子書(shū)刊</a>"

              node.setI(getNodesByParantId(itemCat.getId()));  

              nodes.add(node);

           }else{

              nodes.add("/products/"+itemCat.getId()+".html|"+itemCat.getName());          //[3] : "/products/6.html|多媒體圖書(shū)"

           }

       }

       return nodes;

    }

}

2.3.1.3.第三步:創(chuàng)建ItemCatController類(lèi)

說(shuō)明:需要將返回值存崖,包裝成js腳本數(shù)據(jù)。

(1)方式一:手動(dòng)封裝

package cn.gzsxt.rest.controller;     

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.MediaType;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import cn.gzsxt.base.utils.JsonUtils;

import cn.gzsxt.base.vo.Menu;

import cn.gzsxt.rest.service.ItemCatService;

@Controller

public class ItemCatController {

    @Autowired

    private ItemCatService catService;

    /*

     * jsonp方法下睡毒,返回值来惧,要使用回調(diào)函數(shù)來(lái)偽裝js腳本

     * @return

     */

    @RequestMapping(value="/item/all",produces=MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8")

    @ResponseBody

    public String getMenu(String callback){

       Menu menu = catService.initMenu();

       String jsonMenu = JsonUtils.objectToJson(menu);

       String jsMenu = callback+"("+jsonMenu+")";

       return jsMenu;

    }

}

(2)方式二:使用MappingJacksonValue對(duì)象封裝

//使用MappingJacksonValue對(duì)象包裝返回結(jié)果,并設(shè)置jsonp的回調(diào)方法

    @RequestMapping("/item/all")

    @ResponseBody

    public MappingJacksonValue queryAll(String callback) {

       //查詢(xún)分類(lèi)列表

       Menu menu = catService.getMenu();

       //包裝jsonp

       MappingJacksonValue jacksonValue = new      MappingJacksonValue(menu);

       //設(shè)置包裝的回調(diào)方法名

       jacksonValue.setJsonpFunction(callback);

       return jacksonValue;

    }

2.3.1.4.第四步:測(cè)試接口

在瀏覽器訪問(wèn)演顾。

地址:http://localhost:8081/rest/item/all?callback=category.getDataService

image.png

2.3.2.第二部分:在portal工程中調(diào)用導(dǎo)航菜單接口

2.3.2.1.第一步:指定請(qǐng)求方式為jsonp

(1)修改lib-v1.js文件供搀,指定導(dǎo)航菜單接口地址。

image.png

(2)修改lib-v1.js文件钠至,指定請(qǐng)求方式為jsonp葛虐。

image.png

2.3.2.2.第二步:測(cè)試導(dǎo)航菜單

(1)重啟portal工程

(2)訪問(wèn)首頁(yè),請(qǐng)求導(dǎo)航菜單

image.png

導(dǎo)航菜單開(kāi)發(fā)成功C蘧S炱辍!

3.CMS系統(tǒng)

3.1.概念

CMS系統(tǒng)即為內(nèi)容管理系統(tǒng)宪卿。(Content Management System)

所謂的內(nèi)容的诵,就是出現(xiàn)在網(wǎng)頁(yè)中的圖片、文字佑钾、鏈接等西疤。CMS系統(tǒng)就是用來(lái)維護(hù)網(wǎng)頁(yè)中的內(nèi)容的,實(shí)現(xiàn)網(wǎng)頁(yè)中的內(nèi)容動(dòng)態(tài)休溶、可變瘪阁。

比如廣告位的投放,秒殺欄邮偎、排行榜實(shí)時(shí)更新等管跺,都需要通過(guò)CMS系統(tǒng)來(lái)實(shí)現(xiàn)。

3.2.CMS系統(tǒng)實(shí)現(xiàn)

image.png

3.2.1.思路

(1)禾进、將網(wǎng)頁(yè)中的內(nèi)容分類(lèi)

按照網(wǎng)頁(yè)的特性分類(lèi)豁跑,然后將每一類(lèi)網(wǎng)頁(yè)劃分成一個(gè)一個(gè)獨(dú)立的區(qū)域。

image.png

(2)在每一個(gè)內(nèi)容分類(lèi)下管理泻云、維護(hù)各自的內(nèi)容列表艇拍。

image.png

3.2.2.數(shù)據(jù)庫(kù)表關(guān)系

CMS系統(tǒng)主要涉及兩種表:

(1)內(nèi)容分類(lèi)表:tb_content_category(作用:定位)

(2)內(nèi)容表:tb_content

表之間的對(duì)應(yīng)關(guān)系為1-N

image.png

3.2.3.內(nèi)容分類(lèi)實(shí)現(xiàn)

3.2.3.1.需求

在后臺(tái)管理頁(yè)面狐蜕,點(diǎn)擊內(nèi)容分類(lèi)管理菜單,初始化內(nèi)容分類(lèi)樹(shù)結(jié)構(gòu)卸夕。該樹(shù)結(jié)構(gòu)可以添加层释、修改、刪除節(jié)點(diǎn)快集。

image.png

3.2.3.2.思路

(1)初始化內(nèi)容分類(lèi)導(dǎo)航樹(shù)贡羔。(這里使用easyui-tree)

(2)對(duì)異步樹(shù)進(jìn)行維護(hù)。(添加節(jié)點(diǎn)个初、刪除節(jié)點(diǎn)乖寒、更新節(jié)點(diǎn))

3.2.3.3.第一部分:初始化內(nèi)容分類(lèi)導(dǎo)航樹(shù)

3.2.3.3.1.第一步:初始化easyui異步樹(shù)插件

image.png

3.2.3.3.2.第二步:確定代碼結(jié)構(gòu)

<colgroup><col style="width: 103px;"><col style="width: 323px;"></colgroup>
| 

Controller

 | 

表現(xiàn)層,負(fù)責(zé)交互院溺、綁定參數(shù)楣嘁、響應(yīng)視圖

 |
| 

Service

 | 

業(yè)務(wù)層,負(fù)責(zé)業(yè)務(wù)邏輯實(shí)現(xiàn)(封裝樹(shù)結(jié)構(gòu))

 |
| 

Mapper

 | 

持久層珍逸,逆向工程生成逐虚,不需要開(kāi)發(fā)。

 |

3.2.3.3.3.第三步:確定請(qǐng)求響應(yīng)格式

<colgroup><col style="width: 85px;"><col style="width: 381px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/category/list

 |
| 

請(qǐng)求方式

 | 

GET請(qǐng)求

 |
| 

請(qǐng)求參數(shù)

 | 

id=nodeId(首次加載生成一級(jí)目錄時(shí)谆膳,默認(rèn)id=0)

 |
| 

響應(yīng)格式

 | 

List<EUTreeNode> (id,text,state:open|closed)

 |
3.2.3.3.4.第四步:創(chuàng)建ContentCategory類(lèi)

在公共工程ego-base中創(chuàng)建痊班。

package cn.gzsxt.base.pojo;     

import java.util.Date;

import com.baomidou.mybatisplus.annotations.TableField;

import com.baomidou.mybatisplus.annotations.TableId;

import com.baomidou.mybatisplus.annotations.TableName;

import com.baomidou.mybatisplus.enums.IdType;

@TableName(value="tb_content_category")

public class ContentCategory {

    @TableId(value="id",type=IdType.AUTO)

    private Long id;

    @TableField(value="parent_id")

    private Long parentId;

    private String name;

    private int status;

    @TableField(value="sort_order")

    private int sortOrdert;

    @TableField(value="is_parent")

    private byte isParent;

    private Date created;

    private Date updated;

    public ContentCategory() {

       super();

    }

    // 補(bǔ)全get、set方法

}
3.2.3.3.5.第五步:創(chuàng)建ContentCategoryMapper接口

在公共工程ego-base中創(chuàng)建摹量。

package cn.gzsxt.base.mapper;     

import com.baomidou.mybatisplus.mapper.BaseMapper;

import cn.gzsxt.base.pojo.ContentCategory;

public interface ContentCategoryMapper extends      BaseMapper<ContentCategory>{

}
3.2.3.3.6.第六步:創(chuàng)建ContentCategoryService接口及其實(shí)現(xiàn)類(lèi)
package cn.gzsxt.manager.service.impl;     

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import cn.gzsxt.base.mapper.ContentCategoryMapper;

import cn.gzsxt.base.pojo.ContentCategory;

import cn.gzsxt.base.vo.EUTreeNode;

import cn.gzsxt.base.vo.EgoResult;

import cn.gzsxt.manager.service.ContentCategoryService;

@Service

public class ContentCategoryServiceImpl implements      ContentCategoryService{

    @Autowired

    private ContentCategoryMapper mapper;

    @Override

    public List<EUTreeNode> selectByParentId(Long parentId) {

       //定義返回值

       List<EUTreeNode> nodes = new ArrayList<>();

       //封裝查詢(xún)條件,執(zhí)行查詢(xún)

       Map<String,Object> columnMap = new HashMap<>();

       columnMap.put("parent_id", parentId);

       List<ContentCategory> selectByMap =      mapper.selectByMap(columnMap);

       EUTreeNode node = null;

       for (ContentCategory c : selectByMap) {

           node = new EUTreeNode();

           node.setId(c.getId());

           node.setText(c.getName());

           //三目運(yùn)算符

           node.setState(1==c.getIsParent()?"closed":"open");   

           nodes.add(node);

       }

       return nodes;

    }

}
3.2.3.3.7.第七步:創(chuàng)建ContentCategoryController類(lèi)
package cn.gzsxt.manager.controller;     

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

import cn.gzsxt.base.vo.EUTreeNode;

import cn.gzsxt.manager.service.ContentCategoryService;

@Controller

@RequestMapping("/content/category")

public class ContentCategoryController {

    @Autowired

    private ContentCategoryService service;

    @RequestMapping(value="/list",method=RequestMethod.GET)

    @ResponseBody

    public List<EUTreeNode>      selectByParentId(@RequestParam(name="id",defaultValue="0")Long      parentId){

       return service.selectByParentId(parentId);

    }

}
3.2.3.3.8.第八步:測(cè)試

(1)重新編譯ego-manager工程馒胆。(clean缨称、install)

(2)重新啟動(dòng)ego-manager。

(3)訪問(wèn)內(nèi)容分類(lèi)管理

3.2.3.4.第二部分:添加內(nèi)容分類(lèi)節(jié)點(diǎn)

3.2.3.4.1.第一步:前端js實(shí)現(xiàn)
image.png
3.2.3.4.2.第二步:確定代碼結(jié)構(gòu)
<colgroup><col style="width: 105px;"><col style="width: 346px;"></colgroup>
| 

Controller

 | 

視圖層祝迂,接收參數(shù)睦尽,將新增加的節(jié)點(diǎn)響應(yīng)出去

 |
| 

Service

 | 

業(yè)務(wù)層,新增節(jié)點(diǎn)型雳、更新父節(jié)點(diǎn)

 |
| 

Mapper

 | 

持久層当凡,逆向工程生成,不需要開(kāi)發(fā)纠俭。

 |
3.2.3.4.3.第三步:確定請(qǐng)求響應(yīng)格式
<colgroup><col style="width: 89px;"><col style="width: 339px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/category/create

 |
| 

請(qǐng)求方式

 | 

POST

 |
| 

請(qǐng)求參數(shù)

 | 

parentId:node.parentId,   name:node.text

 |
| 

響應(yīng)格式

 | 

{status:200,data:node}  (EgoResult類(lèi)型)

 |
3.2.3.4.4.第四步:修改ContentCategoryService及其實(shí)現(xiàn)類(lèi)沿量,新增save方法

注意:先在ContentCategoryService接口中定義save方法

@Transactional(rollbackFor=Exception.class)

    @Override

    public EgoResult save(Long parentId, String name) {

       ContentCategory temp = new ContentCategory();

       temp.setParentId(parentId);

       temp.setName(name);

       temp.setIsParent((byte) 0);

       temp.setSortOrdert(1);

       temp.setCreated(new Date());

       temp.setStatus(1);

       temp.setUpdated(temp.getCreated());

       //mybatis-plus保存對(duì)象的時(shí)候,已經(jīng)實(shí)現(xiàn)了對(duì)象的id自動(dòng)同步冤荆。前提:數(shù)據(jù)庫(kù)id是自增朴则。

       mapper.insert(temp);

       /*

        * 判斷當(dāng)前添加節(jié)點(diǎn)的父節(jié)點(diǎn)是否是目錄節(jié)點(diǎn)。

        *

        * 如果不是钓简,則要修改其狀態(tài)為父目錄結(jié)構(gòu)

        */

       ContentCategory category = mapper.selectById(parentId);

       if(0==category.getIsParent()){

           category.setIsParent((byte) 1);

           mapper.updateById(category);

       }

       return EgoResult.ok(temp);

    }
3.2.3.4.5.第五步:修改ContentCategoryController類(lèi)乌妒,定義新增內(nèi)容分類(lèi)接口
@RequestMapping(value="/create",method=RequestMethod.POST)

    @ResponseBody

    public EgoResult create(Long parentId,String name){   

       EgoResult result = catService.save(name, parentId);

       return result;

    }
3.2.3.4.6.第六步:測(cè)試

(1)重新編譯ego-base工程汹想。(clean、install)

(2)重新啟動(dòng)ego-manager撤蚊。

(3)新增內(nèi)容分類(lèi)節(jié)點(diǎn)古掏。

3.2.3.5.第三部分:更新內(nèi)容分類(lèi)

3.2.3.5.1.第一步:前端js實(shí)現(xiàn)
image.png
3.2.3.5.2.第二步:確定請(qǐng)求響應(yīng)格式
<colgroup><col style="width: 87px;"><col style="width: 342px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/category/updata

 |
| 

請(qǐng)求方式

 | 

POST

 |
| 

請(qǐng)求參數(shù)

 | 

id:node.id,   name:node.text

 |
| 

響應(yīng)格式

 | 

{status:200,data:node}  (EgoResult類(lèi)型)

 |
3.2.3.5.3.第三步:修改ContentCategoryService及其接口,新增update方法侦啸。

注意:先在service接口中定義方法槽唾。

@Override

    public EgoResult updateNode(String name, Long id) {

       ContentCategory contentCat = new ContentCategory();

       contentCat.setName(name);

       contentCat.setId(id);

       contentCatMapper.updateById(contentCat);

       return EgoResult.ok();

    }
3.2.3.5.4.第四步:修改ContentController類(lèi),定義更新的接口
@RequestMapping(value="/update",method=RequestMethod.POST)

    @ResponseBody

    public EgoResult updateNode(Long id,String name){

       EgoResult result = catService.updateNode(name, id);

       return result;

    }
3.2.3.5.5.第五步:測(cè)試

(1)重新編譯ego-manager工程匹中。(clean夏漱、install)

(2)重新啟動(dòng)ego-manager。

(3)更新內(nèi)容分類(lèi)節(jié)點(diǎn)顶捷。

3.2.3.6.第四部分:刪除內(nèi)容分類(lèi)

3.2.3.6.1.第一步:前端js實(shí)現(xiàn)
image.png
3.2.3.6.2.第二步:確定請(qǐng)求響應(yīng)格式
<colgroup><col style="width: 90px;"><col style="width: 337px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/category/delete

 |
| 

請(qǐng)求方式

 | 

POST

 |
| 

請(qǐng)求參數(shù)

 | 

id:node.id,   parentId:node.parentId

 |
| 

響應(yīng)格式

 | 

{status:200,data:node}  (EgoResult類(lèi)型)

 |
3.2.3.6.3.第三步:修改ContentCategoryService及其實(shí)現(xiàn)類(lèi)挂绰,新增delete方法
    @Transactional     

    @Override

    public EgoResult deleteNode(Long id, Long parentId) {

       // 第一步:判斷parent_id是否有值

       if (parentId == null) {

           parentId =      contentCategoryMapper.selectById(id).getParentId();

       }

       // 第二步:判斷該節(jié)點(diǎn)是否是它的父節(jié)點(diǎn)的最后一個(gè)節(jié)點(diǎn)。如果是服赎。那么需要將它的父節(jié)點(diǎn)修改為葉節(jié)點(diǎn)

       EntityWrapper<ContentCategory> wrapper = new      EntityWrapper<>();

       wrapper.eq("parent_id", parentId);

       //過(guò)濾只查詢(xún)有效的狀態(tài)

       wrapper.eq("status", 1);

       List<ContentCategory> categories =      contentCategoryMapper.selectList(wrapper);

       if (categories.size() == 1) {

           ContentCategory parentCategory =      contentCategoryMapper.selectById(parentId);

           // 父節(jié)點(diǎn)修改為葉節(jié)點(diǎn)

           parentCategory.setIsParent((byte) 0);

           parentCategory.setUpdated(new Date());

           contentCategoryMapper.updateById(parentCategory);

       }

       // 第三步:修改當(dāng)前節(jié)點(diǎn)的狀態(tài)值葵蒂,修改為刪除狀態(tài)

       ContentCategory category =      contentCategoryMapper.selectById(id);

       category.setStatus(2);

       category.setUpdated(new Date());

       contentCategoryMapper.updateById(category);

       return EgoResult.ok();

    }
3.2.3.6.4.第四步:修改ContentCategoryController類(lèi),定義delete接口
@RequestMapping(value="/delete",method=RequestMethod.POST)

    @ResponseBody

    public EgoResult deleteNode(Long id,Long parentId){

       EgoResult result = catService.deleteNode(id, parentId);

       return result;

    }

3.2.4.內(nèi)容管理實(shí)現(xiàn)

3.2.4.1.需求

根據(jù)內(nèi)容分類(lèi)id重虑,查詢(xún)數(shù)據(jù)庫(kù)表tb_content践付,獲取內(nèi)容列表。

內(nèi)容分類(lèi)樹(shù)使用easyui-tree組件缺厉,內(nèi)容列表使用easyui-datagrid組件永高。

image.png

3.2.4.2.思路

(1)實(shí)現(xiàn)內(nèi)容列表查詢(xún)。

(2)在內(nèi)容分類(lèi)節(jié)點(diǎn)下提针,維護(hù)內(nèi)容列表命爬。

3.2.4.3.第一部分:內(nèi)容列表實(shí)現(xiàn)

3.2.4.3.1.第一步:加載easyui-datagrid插件

(1)初始化分類(lèi)導(dǎo)航樹(shù)(后臺(tái)java已實(shí)現(xiàn),見(jiàn)2.2.1.3.2章節(jié))

image.png

(2)選中內(nèi)容分類(lèi)節(jié)點(diǎn)

image.png

(3)查詢(xún)?cè)摴?jié)點(diǎn)下的內(nèi)容列表

image.png
3.2.4.3.2.第二步:確定代碼結(jié)構(gòu)
<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
| 

Controller

 | 

獲取分類(lèi)ID辐脖,分頁(yè)信息饲宛,響應(yīng)列表數(shù)據(jù)

 |
| 

Service

 | 

分頁(yè)查詢(xún)邏輯

 |
| 

Mapper

 | 

逆向工程生成,不需要開(kāi)發(fā)

 |
3.2.4.3.3.第三步:確定請(qǐng)求響應(yīng)結(jié)構(gòu)
<colgroup><col style="width: 89px;"><col style="width: 534px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/query/list

 |
| 

請(qǐng)求方式

 | 

GET

 |
| 

請(qǐng)求參數(shù)

 | 

{categoryId:0  ,  page:1  ,  rows:20}

 |
| 

響應(yīng)格式

 | 

{total:20,rows:dataList}  (參見(jiàn)ego-base中的EUDataGridRestult類(lèi))

 |
3.2.4.3.4.第四步:創(chuàng)建Content類(lèi)

在ego-base工程中創(chuàng)建嗜价!

package cn.gzsxt.base.pojo;     

import java.util.Date;

import com.baomidou.mybatisplus.annotations.TableField;

import com.baomidou.mybatisplus.annotations.TableId;

import com.baomidou.mybatisplus.annotations.TableName;

import com.baomidou.mybatisplus.enums.IdType;

@TableName(value="tb_content")

public class Content {

    @TableId(value="id",type=IdType.AUTO)

    private Long id;

    @TableField(value="category_id")

    private long categoryId;

    private String title;

    @TableField(value="sub_title")

    private String subTitle;

    @TableField(value="title_desc")

    private String titleDesc;

    private String url;

    private String pic;

    private String pic2;

    private String content;

    private Date created;

    private Date updated;

    public Content() {

       super();

    }

    // 補(bǔ)全get艇抠、set方法

}
3.2.4.3.5.第五步:創(chuàng)建ContentMapper接口

在ego-base工程中創(chuàng)建!

package cn.gzsxt.base.mapper;     

import com.baomidou.mybatisplus.mapper.BaseMapper;

import cn.gzsxt.base.pojo.Content;

public interface ContentMapper extends BaseMapper<Content>{

}
3.2.4.3.6.第六步:創(chuàng)建ContentService接口及其實(shí)現(xiàn)類(lèi)
package cn.gzsxt.manager.service.impl;     

import java.util.Arrays;

import java.util.Date;

import java.util.List;

import org.apache.ibatis.session.RowBounds;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;

import cn.gzsxt.base.mapper.ContentMapper;

import cn.gzsxt.base.pojo.Content;

import cn.gzsxt.base.vo.EUDataGridResult;

import cn.gzsxt.base.vo.EgoResult;

import cn.gzsxt.manager.service.ContentService;

@Service

public class ContentServiceImpl implements ContentService{

    @Autowired

    private ContentMapper mapper;

    @Override

    public EUDataGridResult listByCatIdAndPage(Long categoryId, int      page, int rows) {

       EUDataGridResult result = new EUDataGridResult();

       /*

        * offset 偏移量  即limit函數(shù)中的start

        * limit  容量

        */

       RowBounds rowBounds = new RowBounds((page-1)*rows, rows);

       EntityWrapper<Content> wrapper = new EntityWrapper<>();

       wrapper.eq("category_id", categoryId);

List<Content> selectPage = mapper.selectPage(rowBounds,      wrapper);

       Integer count = mapper.selectCount(wrapper);

       result.setTotal(count);

       result.setRows(selectPage);

       return result;

    }

}
3.2.4.3.7.第七步:創(chuàng)建ContentController類(lèi)
package cn.gzsxt.manager.controller;     

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.ResponseBody;

import cn.gzsxt.base.pojo.Content;

import cn.gzsxt.base.vo.EUDataGridResult;

import cn.gzsxt.base.vo.EgoResult;

import cn.gzsxt.manager.service.ContentService;

@Controller

@RequestMapping("/content")

public class ContentController {

    @Autowired

    private ContentService service;

    @RequestMapping(value="/query/list")

    @ResponseBody

    public EUDataGridResult selectByCatIdAndPage(Long      categoryId,Integer page,Integer rows){

       EUDataGridResult result =      service.listByCatIdAndPage(categoryId, page, rows);

       return result;

    }

}
3.2.4.3.8.第八步:測(cè)試

(1)重新編譯ego-manager工程久锥。(clean家淤、install)

(2)重新啟動(dòng)ego-manager。

(3)查看內(nèi)容列表瑟由。成功C焦摹!!

image.png

3.2.4.4.第二部分:新增內(nèi)容

3.2.4.4.1.第一步:前端js實(shí)現(xiàn)
image.png
3.2.4.4.2.第二步:確定代碼結(jié)構(gòu)
<colgroup><col style="width: 130px;"><col style="width: 226px;"></colgroup>
| 

Controller

 | 

接收表單數(shù)據(jù)绿鸣,響應(yīng)保存結(jié)果

 |
| 

Service

 | 

保存邏輯實(shí)現(xiàn)

 |
| 

Mapper

 | 

逆向工程生成

 |
3.2.4.4.3.第三步:確定請(qǐng)求響應(yīng)格式
<colgroup><col style="width: 130px;"><col style="width: 250px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/save

 |
| 

請(qǐng)求方式

 | 

POST

 |
| 

請(qǐng)求參數(shù)

 | 

Content類(lèi)

 |
| 

響應(yīng)格式

 | 

{status:200}  (EgoResult類(lèi)型)

 |
3.2.4.4.4.第四步:修改ContentService接口及其實(shí)現(xiàn)類(lèi)疚沐,新增save方法
@Override

public EgoResult addContent(Content content) throws Exception {

     //把圖片信息保存至數(shù)據(jù)庫(kù)

     content.setCreated(new Date());

     content.setUpdated(new Date());

     //把內(nèi)容信息添加到數(shù)據(jù)庫(kù)

     mapper.insert(content);

     return EgoResult.ok();

}
3.2.4.4.5.第五步:修改ContentController類(lèi),定義save接口
@RequestMapping("/save")

@ResponseBody

public EgoResult addContent(Content content) throws Exception {

     EgoResult result = service.addContent(content);

     return result;

    }

3.2.4.5.第三部分:更新內(nèi)容

3.2.4.5.1.第一步:前端js實(shí)現(xiàn)
image.png
3.2.4.5.2.第二步:確定請(qǐng)求響應(yīng)格式
<colgroup><col style="width: 130px;"><col style="width: 250px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/edit

 |
| 

請(qǐng)求方式

 | 

POST

 |
| 

請(qǐng)求參數(shù)

 | 

Content類(lèi) 

 |
| 

響應(yīng)格式

 | 

{status:200}  (EgoResult類(lèi)型)

 |
3.2.4.5.3.第三步:修改ContentService接口及其實(shí)現(xiàn)類(lèi)潮模,新增update方法
@Override

    public EgoResult update(Content content) {

       mapper.updateById(content);

       return EgoResult.ok();

    }
3.2.4.5.4.第四步:修改ContentController類(lèi)亮蛔,新增update接口
@RequestMapping("/edit")

    @ResponseBody

    public EgoResult update(Content Content){

       EgoResult result = service.update(Content);

       return result;

    }

3.2.4.6.第四部分:刪除內(nèi)容

3.2.4.6.1.第一步:前端js實(shí)現(xiàn)
image.png

獲取所有要?jiǎng)h除的內(nèi)容的id,封裝到數(shù)組中擎厢。

image.png
3.2.4.6.2.第二步:確定請(qǐng)求響應(yīng)格式
<colgroup><col style="width: 130px;"><col style="width: 250px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/content/delete

 |
| 

請(qǐng)求方式

 | 

POST

 |
| 

請(qǐng)求參數(shù)

 | 

Ids[]:{1,2,3}  數(shù)組類(lèi)型

 |
| 

響應(yīng)格式

 | 

{status:200}  (EgoResult類(lèi)型)

 |
3.2.4.6.3.第三步:修改ContentService接口及其實(shí)現(xiàn)類(lèi)究流,新增delete方法
@Override

    public EgoResult delete(Integer[] ids) {      

       List<Integer> idss = Arrays.asList(ids);

        mapper.deleteBatchIds(idss);

       return EgoResult.ok();

    }
3.2.4.6.4.第四步:修改ContentController類(lèi),新增delete接口
@RequestMapping("/delete")

    @ResponseBody

    public EgoResult delete(Integer[] ids){

       EgoResult result = service.delete(ids);

       return result;

    }

4.首頁(yè)大廣告實(shí)現(xiàn)

4.1.需求

訪問(wèn)門(mén)戶(hù)系統(tǒng)首頁(yè)动遭,在大廣位區(qū)域展示大廣告位對(duì)應(yīng)的內(nèi)容芬探。

4.2.實(shí)現(xiàn)流程

(1)、在CMS系統(tǒng)中維護(hù)大廣告位的內(nèi)容厘惦。

(2)偷仿、在REST系統(tǒng)中查詢(xún)大廣告位的內(nèi)容列表,以接口的形式對(duì)外提供服務(wù)宵蕉。

(3)酝静、在portal門(mén)戶(hù)系統(tǒng)中遠(yuǎn)程訪問(wèn)REST系統(tǒng)。

image.png
11.第一部分:REST系統(tǒng)接口實(shí)現(xiàn)

需求:

根據(jù)內(nèi)容分類(lèi)id羡玛,查詢(xún)tb_content表别智,獲得大廣告位內(nèi)容列表。

4.3.1.第一步:確定代碼結(jié)構(gòu)

<colgroup><col style="width: 130px;"><col style="width: 418px;"></colgroup>
| 

Controller

 | 

定義接口規(guī)則(請(qǐng)求路徑稼稿、請(qǐng)求方式薄榛、參數(shù)、響應(yīng)值類(lèi)型)

 |
| 

Service

 | 

定義查詢(xún)邏輯

 |
| 

Mapper

 | 

查詢(xún)數(shù)據(jù)庫(kù)

 |

4.3.2.第二步:定義接口規(guī)則

<colgroup><col style="width: 130px;"><col style="width: 226px;"></colgroup>
| 

請(qǐng)求路徑

 | 

/rest/content/category/{cid}

 |
| 

請(qǐng)求方式

 | 

GET

 |
| 

請(qǐng)求參數(shù)

 | 

/{cid}  路徑變量

 |
| 

響應(yīng)類(lèi)型

 | 

EgoResult

 |
| 

示例

 | 

demo

 |

4.3.3.第三步:創(chuàng)建ContentService接口及其實(shí)現(xiàn)類(lèi)

package cn.gzsxt.rest.service.impl;     

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import cn.gzsxt.base.mapper.ContentMapper;

import cn.gzsxt.base.pojo.Content;

import cn.gzsxt.base.utils.JsonUtils;

import cn.gzsxt.rest.service.ContentService;

@Service

public class ContentServiceImpl implements ContentService{

    @Autowired

    private ContentMapper mapper;

    @Override

    public EgoResult getContentByCatId(Long catId) {

Map<String, Object> columnMap = new HashMap<>();

       columnMap.put("category_id", catId);

       List<Content> list = mapper.selectByMap(columnMap);

       return EgoResult.ok(list);

    }

}

4.3.4.第四步:創(chuàng)建ContentController類(lèi)

@RestController     

@RequestMapping("/content")

public class ContentController {

    @Autowired

    private ContentService contentService;

    @RequestMapping("/category/{cid}")

    public EgoResult getContentList(@PathVariable Long cid) {

       EgoResult result = contentService.getContentByCatId(cid);

       return result;

    }

}

4.4.第二部分:遠(yuǎn)程接口調(diào)用方式HttpClient

問(wèn)題:現(xiàn)在我們已經(jīng)開(kāi)發(fā)好了接口了让歼,那該如何調(diào)用這個(gè)接口呢敞恋?

答:使用Httpclient客戶(hù)端。

4.4.1.Httpclient簡(jiǎn)介

4.4.1.1.什么是httpclient

HttpClient 是 Apache Jakarta Common 下的子項(xiàng)目是越,用來(lái)提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶(hù)端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議敦捧。實(shí)現(xiàn)了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)

下載地址:http://hc.apache.org/

4.4.1.2.httpclient作用

在java代碼中膘魄,發(fā)送Http請(qǐng)求。通常用來(lái)實(shí)現(xiàn)遠(yuǎn)程接口調(diào)用营密。

4.4.2.HttpClient測(cè)試

說(shuō)明:在ego-base中測(cè)試

在ego-base工程中添加httpclient的pom依賴(lài)。

<dependency>     

       <groupId>org.apache.httpcomponents</groupId>

       <artifactId>httpclient</artifactId>

</dependency>

4.4.2.1.執(zhí)行GET請(qǐng)求

public static void doGet(){     

        // 創(chuàng)建Httpclient對(duì)象

        CloseableHttpClient httpclient = HttpClients.createDefault();

        // 創(chuàng)建http GET請(qǐng)求

        HttpGet httpGet = new HttpGet("http://www.oschina.net/");

        CloseableHttpResponse response = null;

        try {

            // 執(zhí)行請(qǐng)求

            response = httpclient.execute(httpGet);

            System.out.println(response.getStatusLine());

            // 判斷返回狀態(tài)是否為200

            if (response.getStatusLine().getStatusCode() == 200) {

                String content =      EntityUtils.toString(response.getEntity(), "UTF-8");

                System.out.println("內(nèi)容長(zhǎng)度:" + content.length());

            }

        }catch(Exception e){

           e.printStackTrace();

        } finally {

            if (response != null) {

                try {

                  response.close();

              } catch (IOException e) {

                  e.printStackTrace();

              }

            }

            try {

              httpclient.close();

           } catch (IOException e) {

              e.printStackTrace();

           }

        }

4.4.2.2.執(zhí)行GET帶參數(shù)

public static void doGetParam(){     

        // 創(chuàng)建Httpclient對(duì)象

       CloseableHttpClient httpclient = HttpClients.createDefault();

       CloseableHttpResponse response = null;

       try {

        // 定義請(qǐng)求的參數(shù)

        URI uri = new      URIBuilder("http://www.baidu.com/s").setParameter("wd", "數(shù)據(jù)庫(kù)").build();

        System.out.println(uri);

        // 創(chuàng)建http GET請(qǐng)求

        HttpGet httpGet = new HttpGet(uri);

            // 執(zhí)行請(qǐng)求

            response = httpclient.execute(httpGet);

            // 判斷返回狀態(tài)是否為200

            if (response.getStatusLine().getStatusCode() == 200) {

                String content =      EntityUtils.toString(response.getEntity(), "UTF-8");

                System.out.println(content);

            }

        }catch(Exception e){

           e.printStackTrace();

        }finally {

            if (response != null) {

                try {

                  response.close();

              } catch (IOException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

              }

            }

            try {

              httpclient.close();

           } catch (IOException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }

        }

    }

4.4.2.3.執(zhí)行post請(qǐng)求

public static void doPost(){     

        // 創(chuàng)建Httpclient對(duì)象

        CloseableHttpClient httpclient =      HttpClientBuilder.create().setRedirectStrategy(new      LaxRedirectStrategy()).build();

        // 創(chuàng)建http POST請(qǐng)求

        HttpPost httpPost = new HttpPost("http://www.oschina.net/");

        CloseableHttpResponse response = null;

        try {

            // 執(zhí)行請(qǐng)求

            response = httpclient.execute(httpPost);

            System.out.println(response.getStatusLine());

            // 判斷返回狀態(tài)是否為200

            if (response.getStatusLine().getStatusCode() == 200) {

                String content =      EntityUtils.toString(response.getEntity(), "UTF-8");

                System.out.println(content);

            }

        }catch(Exception e){

           e.printStackTrace();

        }finally {

            if (response != null) {

                try {

                  response.close();

              } catch (IOException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

              }

            }

            try {

              httpclient.close();

           } catch (IOException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }

        }

    }

4.4.2.4.執(zhí)行post帶參數(shù)

public static void doPostParam() throws Exception{     

        // 創(chuàng)建Httpclient對(duì)象

        CloseableHttpClient httpclient =      HttpClientBuilder.create().setRedirectStrategy(new      LaxRedirectStrategy()).build();

        // 創(chuàng)建http POST請(qǐng)求

        HttpPost httpPost = new      HttpPost("http://www.oschina.net/search");

        // 設(shè)置2個(gè)post參數(shù),一個(gè)是scope呢岗、一個(gè)是q

        List<NameValuePair> parameters = new      ArrayList<NameValuePair>();

        parameters.add(new BasicNameValuePair("scope", "project"));

        parameters.add(new BasicNameValuePair("q", "java"));

        // 構(gòu)造一個(gè)form表單式的實(shí)體

        UrlEncodedFormEntity formEntity = new      UrlEncodedFormEntity(parameters);

        // 將請(qǐng)求實(shí)體設(shè)置到httpPost對(duì)象中

        httpPost.setEntity(formEntity);

        CloseableHttpResponse response = null;

        try {

            // 執(zhí)行請(qǐng)求

            response = httpclient.execute(httpPost);

            System.out.println(response.getStatusLine());

            // 判斷返回狀態(tài)是否為200

            if (response.getStatusLine().getStatusCode() == 200) {

                String content =      EntityUtils.toString(response.getEntity(), "UTF-8");

                System.out.println(content);

            }

        } finally {

            if (response != null) {

                response.close();

            }

            httpclient.close();

        }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子后豫,更是在濱河造成了極大的恐慌悉尾,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挫酿,死亡現(xiàn)場(chǎng)離奇詭異构眯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)早龟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)惫霸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人葱弟,你說(shuō)我怎么就攤上這事壹店。” “怎么了芝加?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵硅卢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我妖混,道長(zhǎng)老赤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任制市,我火速辦了婚禮抬旺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祥楣。我一直安慰自己开财,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布误褪。 她就那樣靜靜地躺著责鳍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兽间。 梳的紋絲不亂的頭發(fā)上历葛,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音嘀略,去河邊找鬼恤溶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛帜羊,可吹牛的內(nèi)容都是我干的咒程。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼讼育,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼帐姻!你這毒婦竟也來(lái)了稠集?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饥瓷,失蹤者是張志新(化名)和其女友劉穎剥纷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扛伍,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筷畦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刺洒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鳖宾。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逆航,靈堂內(nèi)的尸體忽然破棺而出鼎文,到底是詐尸還是另有隱情,我是刑警寧澤因俐,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布拇惋,位于F島的核電站,受9級(jí)特大地震影響抹剩,放射性物質(zhì)發(fā)生泄漏撑帖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一澳眷、第九天 我趴在偏房一處隱蔽的房頂上張望胡嘿。 院中可真熱鬧,春花似錦钳踊、人聲如沸衷敌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缴罗。三九已至,卻和暖如春祭埂,著一層夾襖步出監(jiān)牢的瞬間面氓,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工蛆橡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舌界,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓航罗,卻偏偏與公主長(zhǎng)得像禀横,于是被迫代替她去往敵國(guó)和親屁药。 傳聞我的和親對(duì)象是個(gè)殘疾皇子粥血,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344